diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/optimizer/plan/planner.c | 8 | ||||
-rw-r--r-- | src/backend/optimizer/plan/setrefs.c | 14 | ||||
-rw-r--r-- | src/backend/optimizer/plan/subselect.c | 8 | ||||
-rw-r--r-- | src/backend/optimizer/util/pathnode.c | 2 |
4 files changed, 22 insertions, 10 deletions
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index c1535cbb3f2..c588693dc43 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -431,12 +431,10 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions, Gather *gather = makeNode(Gather); /* - * If there are any initPlans attached to the formerly-top plan node, - * move them up to the Gather node; same as we do for Material node in - * materialize_finished_plan. + * Top plan must not have any initPlans, else it shouldn't have been + * marked parallel-safe. */ - gather->plan.initPlan = top_plan->initPlan; - top_plan->initPlan = NIL; + Assert(top_plan->initPlan == NIL); gather->plan.targetlist = top_plan->targetlist; gather->plan.qual = NIL; diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c index 9cef92cab24..4830cd97a2c 100644 --- a/src/backend/optimizer/plan/setrefs.c +++ b/src/backend/optimizer/plan/setrefs.c @@ -1440,7 +1440,19 @@ trivial_subqueryscan(SubqueryScan *plan) static Plan * clean_up_removed_plan_level(Plan *parent, Plan *child) { - /* We have to be sure we don't lose any initplans */ + /* + * We have to be sure we don't lose any initplans, so move any that were + * attached to the parent plan to the child. If we do move any, the child + * is no longer parallel-safe. + */ + if (parent->initPlan) + child->parallel_safe = false; + + /* + * Attach plans this way so that parent's initplans are processed before + * any pre-existing initplans of the child. Probably doesn't matter, but + * let's preserve the ordering just in case. + */ child->initPlan = list_concat(parent->initPlan, child->initPlan); diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c index df4ca129191..19dd6deff65 100644 --- a/src/backend/optimizer/plan/subselect.c +++ b/src/backend/optimizer/plan/subselect.c @@ -2121,7 +2121,7 @@ SS_identify_outer_params(PlannerInfo *root) * This is separate from SS_attach_initplans because we might conditionally * create more initPlans during create_plan(), depending on which Path we * select. However, Paths that would generate such initPlans are expected - * to have included their cost already. + * to have included their cost and parallel-safety effects already. */ void SS_charge_for_initplans(PlannerInfo *root, RelOptInfo *final_rel) @@ -2177,8 +2177,10 @@ SS_charge_for_initplans(PlannerInfo *root, RelOptInfo *final_rel) * (In principle the initPlans could go in any node at or above where they're * referenced; but there seems no reason to put them any lower than the * topmost node, so we don't bother to track exactly where they came from.) - * We do not touch the plan node's cost; the initplans should have been - * accounted for in path costing. + * + * We do not touch the plan node's cost or parallel_safe flag. The initplans + * must have been accounted for in SS_charge_for_initplans, or by any later + * code that adds initplans via SS_make_initplan_from_plan. */ void SS_attach_initplans(PlannerInfo *root, Plan *plan) diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c index 43d54e8f3dc..5aa6c02c44d 100644 --- a/src/backend/optimizer/util/pathnode.c +++ b/src/backend/optimizer/util/pathnode.c @@ -3339,7 +3339,7 @@ create_minmaxagg_path(PlannerInfo *root, /* For now, assume we are above any joins, so no parameterization */ pathnode->path.param_info = NULL; pathnode->path.parallel_aware = false; - /* A MinMaxAggPath implies use of subplans, so cannot be parallel-safe */ + /* A MinMaxAggPath implies use of initplans, so cannot be parallel-safe */ pathnode->path.parallel_safe = false; pathnode->path.parallel_workers = 0; /* Result is one unordered row */ |