aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/optimizer/plan/planner.c8
-rw-r--r--src/backend/optimizer/plan/setrefs.c14
-rw-r--r--src/backend/optimizer/plan/subselect.c8
-rw-r--r--src/backend/optimizer/util/pathnode.c2
4 files changed, 22 insertions, 10 deletions
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index a1873ce26d4..502ccbcea23 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -436,12 +436,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 b56666398ea..1812db7f2fd 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -1542,7 +1542,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 052263aea6d..5f12b2ef9b0 100644
--- a/src/backend/optimizer/plan/subselect.c
+++ b/src/backend/optimizer/plan/subselect.c
@@ -2126,7 +2126,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)
@@ -2182,8 +2182,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 65a191ebfda..5f5596841c8 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -3348,7 +3348,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 */