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

Commit68fa28f

Browse files
committed
Postpone extParam/allParam calculations until the very end of planning.
Until now we computed these Param ID sets at the end of subquery_planner,but that approach depends on subquery_planner returning a concrete Plantree. We would like to switch over to returning one or more Paths for asubquery, and in that representation the necessary details aren't fullyfleshed out (not to mention that we don't really want to do this work forPaths that end up getting discarded). Hence, refactor so that we cancompute the param ID sets at the end of planning, just beforeset_plan_references is run.The main change necessary to make this work is that we need to capturethe set of outer-level Param IDs available to the current query levelbefore exiting subquery_planner, since the outer levels' plan_params listsare transient. (That's not going to pose a problem for returning Paths,since all the work involved in producing that data is part of expressionpreprocessing, which will continue to happen before Paths are produced.)On the plus side, this change gets rid of several existing kluges.Eventually I'd like to get rid of SS_finalize_plan altogether in favor ofdoing this work during set_plan_references, but that will require somecomplex rejiggering because SS_finalize_plan needs to visit subplans andinitplans before the main plan. So leave that idea for another day.
1 parent4901b2f commit68fa28f

File tree

10 files changed

+293
-158
lines changed

10 files changed

+293
-158
lines changed

‎src/backend/nodes/outfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1799,6 +1799,7 @@ _outPlannerInfo(StringInfo str, const PlannerInfo *node)
17991799
WRITE_NODE_FIELD(glob);
18001800
WRITE_UINT_FIELD(query_level);
18011801
WRITE_NODE_FIELD(plan_params);
1802+
WRITE_BITMAPSET_FIELD(outer_params);
18021803
WRITE_BITMAPSET_FIELD(all_baserels);
18031804
WRITE_BITMAPSET_FIELD(nullable_baserels);
18041805
WRITE_NODE_FIELD(join_rel_list);

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

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4473,11 +4473,7 @@ make_material(Plan *lefttree)
44734473
* materialize_finished_plan: stick a Material node atop a completed plan
44744474
*
44754475
* There are a couple of places where we want to attach a Material node
4476-
* after completion of subquery_planner(). This currently requires hackery.
4477-
* Since subquery_planner has already run SS_finalize_plan on the subplan
4478-
* tree, we have to kluge up parameter lists for the Material node.
4479-
* Possibly this could be fixed by postponing SS_finalize_plan processing
4480-
* until setrefs.c is run?
4476+
* after completion of subquery_planner(), without any MaterialPath path.
44814477
*/
44824478
Plan*
44834479
materialize_finished_plan(Plan*subplan)
@@ -4498,10 +4494,6 @@ materialize_finished_plan(Plan *subplan)
44984494
matplan->plan_rows=subplan->plan_rows;
44994495
matplan->plan_width=subplan->plan_width;
45004496

4501-
/* parameter kluge --- see comments above */
4502-
matplan->extParam=bms_copy(subplan->extParam);
4503-
matplan->allParam=bms_copy(subplan->allParam);
4504-
45054497
returnmatplan;
45064498
}
45074499

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

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -416,13 +416,23 @@ build_minmax_path(PlannerInfo *root, MinMaxAggInfo *mminfo,
416416
* WHERE col IS NOT NULL AND existing-quals
417417
* ORDER BY col ASC/DESC
418418
* LIMIT 1)
419+
*
420+
* We cheat a bit here by building what is effectively a subplan query
421+
* level without taking the trouble to increment varlevelsup of outer
422+
* references. Therefore we don't increment the subroot's query_level nor
423+
* repoint its parent_root to the parent level. We can get away with that
424+
* because the plan will be an initplan and therefore cannot need any
425+
* parameters from the parent level. But see hackery in make_agg_subplan;
426+
* we might someday need to do this the hard way.
419427
*----------
420428
*/
421429
subroot= (PlannerInfo*)palloc(sizeof(PlannerInfo));
422430
memcpy(subroot,root,sizeof(PlannerInfo));
423431
subroot->parse=parse= (Query*)copyObject(root->parse);
424-
/* make sure subroot planning won't change root->init_plans contents */
425-
subroot->init_plans=list_copy(root->init_plans);
432+
/* reset subplan-related stuff */
433+
subroot->plan_params=NIL;
434+
subroot->outer_params=NULL;
435+
subroot->init_plans=NIL;
426436
/* There shouldn't be any OJ or LATERAL info to translate, as yet */
427437
Assert(subroot->join_info_list==NIL);
428438
Assert(subroot->lateral_info_list==NIL);
@@ -577,24 +587,31 @@ make_agg_subplan(PlannerInfo *root, MinMaxAggInfo *mminfo)
577587
subparse->limitCount,
578588
0,1);
579589

590+
/*
591+
* We have to do some of the same cleanup that subquery_planner() would
592+
* do, namely cope with params and initplans used within this plan tree.
593+
*
594+
* This is a little bit messy because although we initially created the
595+
* subroot by cloning the outer root, it really is a subplan and needs to
596+
* consider initplans belonging to the outer root as providing available
597+
* parameters. So temporarily change its parent_root pointer.
598+
* (Fortunately, SS_identify_outer_params doesn't care whether the depth
599+
* of parent_root nesting matches query_level.)
600+
*/
601+
subroot->parent_root=root;
602+
SS_identify_outer_params(subroot);
603+
subroot->parent_root=root->parent_root;
604+
605+
SS_attach_initplans(subroot,plan);
606+
580607
/*
581608
* Convert the plan into an InitPlan, and make a Param for its result.
582609
*/
583610
mminfo->param=
584-
SS_make_initplan_from_plan(subroot,plan,
611+
SS_make_initplan_from_plan(root,subroot,plan,
585612
exprType((Node*)mminfo->target),
586613
-1,
587614
exprCollation((Node*)mminfo->target));
588-
589-
/*
590-
* Make sure the initplan gets into the outer PlannerInfo, along with any
591-
* other initplans generated by the sub-planning run. We had to include
592-
* the outer PlannerInfo's pre-existing initplans into the inner one's
593-
* init_plans list earlier, so make sure we don't put back any duplicate
594-
* entries.
595-
*/
596-
root->init_plans=list_concat_unique_ptr(root->init_plans,
597-
subroot->init_plans);
598615
}
599616

600617
/*

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

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,25 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
239239
top_plan=materialize_finished_plan(top_plan);
240240
}
241241

242+
/*
243+
* If any Params were generated, run through the plan tree and compute
244+
* each plan node's extParam/allParam sets. Ideally we'd merge this into
245+
* set_plan_references' tree traversal, but for now it has to be separate
246+
* because we need to visit subplans before not after main plan.
247+
*/
248+
if (glob->nParamExec>0)
249+
{
250+
Assert(list_length(glob->subplans)==list_length(glob->subroots));
251+
forboth(lp,glob->subplans,lr,glob->subroots)
252+
{
253+
Plan*subplan= (Plan*)lfirst(lp);
254+
PlannerInfo*subroot= (PlannerInfo*)lfirst(lr);
255+
256+
SS_finalize_plan(subroot,subplan);
257+
}
258+
SS_finalize_plan(root,top_plan);
259+
}
260+
242261
/* final cleanup of the plan */
243262
Assert(glob->finalrtable==NIL);
244263
Assert(glob->finalrowmarks==NIL);
@@ -312,7 +331,6 @@ subquery_planner(PlannerGlobal *glob, Query *parse,
312331
boolhasRecursion,doubletuple_fraction,
313332
PlannerInfo**subroot)
314333
{
315-
intnum_old_subplans=list_length(glob->subplans);
316334
PlannerInfo*root;
317335
Plan*plan;
318336
List*newWithCheckOptions;
@@ -327,6 +345,7 @@ subquery_planner(PlannerGlobal *glob, Query *parse,
327345
root->query_level=parent_root ?parent_root->query_level+1 :1;
328346
root->parent_root=parent_root;
329347
root->plan_params=NIL;
348+
root->outer_params=NULL;
330349
root->planner_cxt=CurrentMemoryContext;
331350
root->init_plans=NIL;
332351
root->cte_plan_ids=NIL;
@@ -656,13 +675,17 @@ subquery_planner(PlannerGlobal *glob, Query *parse,
656675
}
657676

658677
/*
659-
* If any subplans were generated, or if there are any parameters to worry
660-
* about, build initPlan list and extParam/allParam sets for plan nodes,
661-
* and attach the initPlans to the top plan node.
678+
* Capture the set of outer-level param IDs we have access to, for use in
679+
* extParam/allParam calculations later.
680+
*/
681+
SS_identify_outer_params(root);
682+
683+
/*
684+
* If any initPlans were created in this query level, attach them to the
685+
* topmost plan node for the level, and increment that node's cost to
686+
* account for them.
662687
*/
663-
if (list_length(glob->subplans)!=num_old_subplans||
664-
root->glob->nParamExec>0)
665-
SS_finalize_plan(root,plan, true);
688+
SS_attach_initplans(root,plan);
666689

667690
/* Return internal info if caller wants it */
668691
if (subroot)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp