diff options
-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 10ecc2976e8..65a9b0d802a 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -431,12 +431,10 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams) 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 1dc956c3f0d..2adeaf67811 100644 --- a/src/backend/optimizer/plan/setrefs.c +++ b/src/backend/optimizer/plan/setrefs.c @@ -1159,7 +1159,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 344e9bd3795..67b51b86852 100644 --- a/src/backend/optimizer/plan/subselect.c +++ b/src/backend/optimizer/plan/subselect.c @@ -2093,7 +2093,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) @@ -2149,8 +2149,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 ffc03238c56..bbb04d239da 100644 --- a/src/backend/optimizer/util/pathnode.c +++ b/src/backend/optimizer/util/pathnode.c @@ -3232,7 +3232,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 */ |