diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index a8847defba..41dde50d85 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -341,12 +341,9 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams) * Optionally add a Gather node for testing purposes, provided this is * actually a safe thing to do. (Note: we assume adding a Material node * above did not change the parallel safety of the plan, so we can still - * rely on best_path->parallel_safe. However, that flag doesn't account - * for subplans, which we are unable to transmit to workers presently.) + * rely on best_path->parallel_safe.) */ - if (force_parallel_mode != FORCE_PARALLEL_OFF && - best_path->parallel_safe && - glob->subplans == NIL) + if (force_parallel_mode != FORCE_PARALLEL_OFF && best_path->parallel_safe) { Gather *gather = makeNode(Gather); @@ -801,10 +798,10 @@ subquery_planner(PlannerGlobal *glob, Query *parse, SS_identify_outer_params(root); /* - * If any initPlans were created in this query level, increment the - * surviving Paths' costs to account for them. They won't actually get - * attached to the plan tree till create_plan() runs, but we want to be - * sure their costs are included now. + * If any initPlans were created in this query level, adjust the surviving + * Paths' costs and parallel-safety flags to account for them. The + * initPlans won't actually get attached to the plan tree till + * create_plan() runs, but we must include their effects now. */ final_rel = fetch_upper_rel(root, UPPERREL_FINAL, NULL); SS_charge_for_initplans(root, final_rel); diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c index 263ba45f9f..31717439b6 100644 --- a/src/backend/optimizer/plan/subselect.c +++ b/src/backend/optimizer/plan/subselect.c @@ -2128,11 +2128,13 @@ SS_identify_outer_params(PlannerInfo *root) } /* - * SS_charge_for_initplans - account for cost of initplans in Path costs + * SS_charge_for_initplans - account for initplans in Path costs & parallelism * * If any initPlans have been created in the current query level, they will * get attached to the Plan tree created from whichever Path we select from - * the given rel; so increment all the rel's Paths' costs to account for them. + * the given rel. Increment all that rel's Paths' costs to account for them, + * and make sure the paths get marked as parallel-unsafe, since we can't + * currently transmit initPlans to parallel workers. * * This is separate from SS_attach_initplans because we might conditionally * create more initPlans during create_plan(), depending on which Path we @@ -2164,7 +2166,7 @@ SS_charge_for_initplans(PlannerInfo *root, RelOptInfo *final_rel) } /* - * Now adjust the costs. + * Now adjust the costs and parallel_safe flags. */ foreach(lc, final_rel->pathlist) { @@ -2172,6 +2174,7 @@ SS_charge_for_initplans(PlannerInfo *root, RelOptInfo *final_rel) path->startup_cost += initplan_cost; path->total_cost += initplan_cost; + path->parallel_safe = false; } /* We needn't do set_cheapest() here, caller will do it */