Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitff0b18c

Browse files
committed
Fix PARAM_EXEC assignment mechanism to be safe in the presence of WITH.
The planner previously assumed that parameter Vars having the same absolutequery level, varno, and varattno could safely be assigned the same runtimePARAM_EXEC slot, even though they might be different Vars appearing indifferent subqueries. This was (probably) safe before the introduction ofCTEs, but the lazy-evalution mechanism used for CTEs means that a CTE canbe executed during execution of some other subquery, causing the lifespanof Params at the same syntactic nesting level as the CTE to overlap withuse of the same slots inside the CTE. In 9.1 we created additional hazardsby using the same parameter-assignment technology for nestloop inner scanparameters, but it was broken before that, as illustrated by the addedregression test.To fix, restructure the planner's management of PlannerParamItems so thatitems having different semantic lifespans are kept rigorously separated.This will probably result in complex queries using more runtime PARAM_EXECslots than before, but the slots are cheap enough that this hardly matters.Also, stop generating PlannerParamItems containing Params for subqueryoutputs: all we really need to do is reserve the PARAM_EXEC slot number,and that now only takes incrementing a counter. The planning code issimpler and probably faster than before, as well as being more correct.Per report from Vik Reykja.Back-patch of commit46c508f into allbranches that support WITH.
1 parente40b20a commitff0b18c

File tree

10 files changed

+247
-179
lines changed

10 files changed

+247
-179
lines changed

‎src/backend/nodes/outfuncs.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1659,7 +1659,6 @@ _outPlannerGlobal(StringInfo str, PlannerGlobal *node)
16591659
WRITE_NODE_TYPE("PLANNERGLOBAL");
16601660

16611661
/* NB: this isn't a complete set of fields */
1662-
WRITE_NODE_FIELD(paramlist);
16631662
WRITE_NODE_FIELD(subplans);
16641663
WRITE_NODE_FIELD(subrtables);
16651664
WRITE_NODE_FIELD(subrowmarks);
@@ -1669,6 +1668,7 @@ _outPlannerGlobal(StringInfo str, PlannerGlobal *node)
16691668
WRITE_NODE_FIELD(resultRelations);
16701669
WRITE_NODE_FIELD(relationOids);
16711670
WRITE_NODE_FIELD(invalItems);
1671+
WRITE_INT_FIELD(nParamExec);
16721672
WRITE_UINT_FIELD(lastPHId);
16731673
WRITE_UINT_FIELD(lastRowMarkId);
16741674
WRITE_BOOL_FIELD(transientPlan);
@@ -1683,6 +1683,7 @@ _outPlannerInfo(StringInfo str, PlannerInfo *node)
16831683
WRITE_NODE_FIELD(parse);
16841684
WRITE_NODE_FIELD(glob);
16851685
WRITE_UINT_FIELD(query_level);
1686+
WRITE_NODE_FIELD(plan_params);
16861687
WRITE_NODE_FIELD(join_rel_list);
16871688
WRITE_INT_FIELD(join_cur_level);
16881689
WRITE_NODE_FIELD(init_plans);
@@ -1927,7 +1928,7 @@ _outPlannerParamItem(StringInfo str, PlannerParamItem *node)
19271928
WRITE_NODE_TYPE("PLANNERPARAMITEM");
19281929

19291930
WRITE_NODE_FIELD(item);
1930-
WRITE_UINT_FIELD(abslevel);
1931+
WRITE_INT_FIELD(paramId);
19311932
}
19321933

19331934
/*****************************************************************************

‎src/backend/optimizer/path/allpaths.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,9 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel,
786786
else
787787
tuple_fraction=root->tuple_fraction;
788788

789+
/* plan_params should not be in use in current query level */
790+
Assert(root->plan_params==NIL);
791+
789792
/* Generate the plan for the subquery */
790793
rel->subplan=subquery_planner(root->glob,subquery,
791794
root,
@@ -794,6 +797,13 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel,
794797
rel->subrtable=subroot->parse->rtable;
795798
rel->subrowmark=subroot->rowMarks;
796799

800+
/*
801+
* Since we don't yet support LATERAL, it should not be possible for the
802+
* sub-query to have requested parameters of this level.
803+
*/
804+
if (root->plan_params)
805+
elog(ERROR,"unexpected outer reference in subquery in FROM");
806+
797807
/* Mark rel with estimated output rows, width, etc */
798808
set_subquery_size_estimates(root,rel,subroot);
799809

‎src/backend/optimizer/plan/createplan.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,9 @@ create_plan(PlannerInfo *root, Path *best_path)
185185
{
186186
Plan*plan;
187187

188+
/* plan_params should not be in use in current query level */
189+
Assert(root->plan_params==NIL);
190+
188191
/* Initialize this module's private workspace in PlannerInfo */
189192
root->curOuterRels=NULL;
190193
root->curOuterParams=NIL;
@@ -196,6 +199,12 @@ create_plan(PlannerInfo *root, Path *best_path)
196199
if (root->curOuterParams!=NIL)
197200
elog(ERROR,"failed to assign all NestLoopParams to plan nodes");
198201

202+
/*
203+
* Reset plan_params to ensure param IDs used for nestloop params are not
204+
* re-used later
205+
*/
206+
root->plan_params=NIL;
207+
199208
returnplan;
200209
}
201210

‎src/backend/optimizer/plan/planner.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,6 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
156156
glob=makeNode(PlannerGlobal);
157157

158158
glob->boundParams=boundParams;
159-
glob->paramlist=NIL;
160159
glob->subplans=NIL;
161160
glob->subrtables=NIL;
162161
glob->subrowmarks=NIL;
@@ -166,6 +165,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
166165
glob->resultRelations=NIL;
167166
glob->relationOids=NIL;
168167
glob->invalItems=NIL;
168+
glob->nParamExec=0;
169169
glob->lastPHId=0;
170170
glob->lastRowMarkId=0;
171171
glob->transientPlan= false;
@@ -254,7 +254,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
254254
result->rowMarks=glob->finalrowmarks;
255255
result->relationOids=glob->relationOids;
256256
result->invalItems=glob->invalItems;
257-
result->nParamExec=list_length(glob->paramlist);
257+
result->nParamExec=glob->nParamExec;
258258

259259
returnresult;
260260
}
@@ -306,6 +306,7 @@ subquery_planner(PlannerGlobal *glob, Query *parse,
306306
root->glob=glob;
307307
root->query_level=parent_root ?parent_root->query_level+1 :1;
308308
root->parent_root=parent_root;
309+
root->plan_params=NIL;
309310
root->planner_cxt=CurrentMemoryContext;
310311
root->init_plans=NIL;
311312
root->cte_plan_ids=NIL;
@@ -577,7 +578,7 @@ subquery_planner(PlannerGlobal *glob, Query *parse,
577578
* and attach the initPlans to the top plan node.
578579
*/
579580
if (list_length(glob->subplans)!=num_old_subplans||
580-
root->glob->paramlist!=NIL)
581+
root->glob->nParamExec>0)
581582
SS_finalize_plan(root,plan, true);
582583

583584
/* Return internal info if caller wants it */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp