@@ -88,7 +88,7 @@ static Plan *create_unique_plan(PlannerInfo *root, UniquePath *best_path,
8888 int flags );
8989static Gather * create_gather_plan (PlannerInfo * root , GatherPath * best_path );
9090static Plan * create_projection_plan (PlannerInfo * root , ProjectionPath * best_path );
91- static Plan * inject_projection_plan (Plan * subplan , List * tlist );
91+ static Plan * inject_projection_plan (Plan * subplan , List * tlist , bool parallel_safe );
9292static Sort * create_sort_plan (PlannerInfo * root , SortPath * best_path , int flags );
9393static Group * create_group_plan (PlannerInfo * root , GroupPath * best_path );
9494static Unique * create_upper_unique_plan (PlannerInfo * root , UpperUniquePath * best_path ,
@@ -920,6 +920,9 @@ create_gating_plan(PlannerInfo *root, Path *path, Plan *plan,
920920 */
921921 copy_plan_costsize (gplan , plan );
922922
923+ /* Gating quals could be unsafe, so better use the Path's safety flag */
924+ gplan -> parallel_safe = path -> parallel_safe ;
925+
923926 return gplan ;
924927}
925928
@@ -1313,7 +1316,8 @@ create_unique_plan(PlannerInfo *root, UniquePath *best_path, int flags)
13131316 */
13141317 if (!is_projection_capable_plan (subplan ) &&
13151318 !tlist_same_exprs (newtlist , subplan -> targetlist ))
1316- subplan = inject_projection_plan (subplan , newtlist );
1319+ subplan = inject_projection_plan (subplan , newtlist ,
1320+ best_path -> path .parallel_safe );
13171321 else
13181322 subplan -> targetlist = newtlist ;
13191323 }
@@ -1572,7 +1576,8 @@ create_projection_plan(PlannerInfo *root, ProjectionPath *best_path)
15721576 plan -> total_cost = best_path -> path .total_cost ;
15731577 plan -> plan_rows = best_path -> path .rows ;
15741578 plan -> plan_width = best_path -> path .pathtarget -> width ;
1575- /* ... but be careful not to munge subplan's parallel-aware flag */
1579+ plan -> parallel_safe = best_path -> path .parallel_safe ;
1580+ /* ... but don't change subplan's parallel_aware flag */
15761581 }
15771582 else
15781583 {
@@ -1592,9 +1597,12 @@ create_projection_plan(PlannerInfo *root, ProjectionPath *best_path)
15921597 * This is used in a few places where we decide on-the-fly that we need a
15931598 * projection step as part of the tree generated for some Path node.
15941599 * We should try to get rid of this in favor of doing it more honestly.
1600+ *
1601+ * One reason it's ugly is we have to be told the right parallel_safe marking
1602+ * to apply (since the tlist might be unsafe even if the child plan is safe).
15951603 */
15961604static Plan *
1597- inject_projection_plan (Plan * subplan , List * tlist )
1605+ inject_projection_plan (Plan * subplan , List * tlist , bool parallel_safe )
15981606{
15991607 Plan * plan ;
16001608
@@ -1608,6 +1616,7 @@ inject_projection_plan(Plan *subplan, List *tlist)
16081616 * consistent not more so. Hence, just copy the subplan's cost.
16091617 */
16101618 copy_plan_costsize (plan , subplan );
1619+ plan -> parallel_safe = parallel_safe ;
16111620
16121621 return plan ;
16131622}
@@ -1984,6 +1993,7 @@ create_minmaxagg_plan(PlannerInfo *root, MinMaxAggPath *best_path)
19841993 plan -> plan_rows = 1 ;
19851994 plan -> plan_width = mminfo -> path -> pathtarget -> width ;
19861995 plan -> parallel_aware = false;
1996+ plan -> parallel_safe = mminfo -> path -> parallel_safe ;
19871997
19881998 /* Convert the plan into an InitPlan in the outer query. */
19891999 SS_make_initplan_from_plan (root , subroot , plan , mminfo -> param );
@@ -2829,6 +2839,7 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
28292839 clamp_row_est (apath -> bitmapselectivity * apath -> path .parent -> tuples );
28302840 plan -> plan_width = 0 ; /* meaningless */
28312841 plan -> parallel_aware = false;
2842+ plan -> parallel_safe = apath -> path .parallel_safe ;
28322843 * qual = subquals ;
28332844 * indexqual = subindexquals ;
28342845 * indexECs = subindexECs ;
@@ -2892,6 +2903,7 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
28922903 clamp_row_est (opath -> bitmapselectivity * opath -> path .parent -> tuples );
28932904 plan -> plan_width = 0 ; /* meaningless */
28942905 plan -> parallel_aware = false;
2906+ plan -> parallel_safe = opath -> path .parallel_safe ;
28952907 }
28962908
28972909 /*
@@ -2936,6 +2948,7 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
29362948 clamp_row_est (ipath -> indexselectivity * ipath -> path .parent -> tuples );
29372949 plan -> plan_width = 0 ; /* meaningless */
29382950 plan -> parallel_aware = false;
2951+ plan -> parallel_safe = ipath -> path .parallel_safe ;
29392952 * qual = get_actual_clauses (ipath -> indexclauses );
29402953 * indexqual = get_actual_clauses (ipath -> indexquals );
29412954 foreach (l , ipath -> indexinfo -> indpred )
@@ -4834,7 +4847,7 @@ order_qual_clauses(PlannerInfo *root, List *clauses)
48344847/*
48354848 * Copy cost and size info from a Path node to the Plan node created from it.
48364849 * The executor usually won't use this info, but it's needed by EXPLAIN.
4837- * Also copy the parallel-aware flag , which the executor *will* use.
4850+ * Also copy the parallel-related flags , which the executor *will* use.
48384851 */
48394852static void
48404853copy_generic_path_info (Plan * dest , Path * src )
@@ -4844,6 +4857,7 @@ copy_generic_path_info(Plan *dest, Path *src)
48444857 dest -> plan_rows = src -> rows ;
48454858 dest -> plan_width = src -> pathtarget -> width ;
48464859 dest -> parallel_aware = src -> parallel_aware ;
4860+ dest -> parallel_safe = src -> parallel_safe ;
48474861}
48484862
48494863/*
@@ -4859,6 +4873,8 @@ copy_plan_costsize(Plan *dest, Plan *src)
48594873 dest -> plan_width = src -> plan_width ;
48604874 /* Assume the inserted node is not parallel-aware. */
48614875 dest -> parallel_aware = false;
4876+ /* Assume the inserted node is parallel-safe, if child plan is. */
4877+ dest -> parallel_safe = src -> parallel_safe ;
48624878}
48634879
48644880/*
@@ -4888,6 +4904,7 @@ label_sort_with_costsize(PlannerInfo *root, Sort *plan, double limit_tuples)
48884904 plan -> plan .plan_rows = lefttree -> plan_rows ;
48894905 plan -> plan .plan_width = lefttree -> plan_width ;
48904906 plan -> plan .parallel_aware = false;
4907+ plan -> plan .parallel_safe = lefttree -> parallel_safe ;
48914908}
48924909
48934910/*
@@ -5696,7 +5713,8 @@ prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys,
56965713 {
56975714 /* copy needed so we don't modify input's tlist below */
56985715 tlist = copyObject (tlist );
5699- lefttree = inject_projection_plan (lefttree , tlist );
5716+ lefttree = inject_projection_plan (lefttree , tlist ,
5717+ lefttree -> parallel_safe );
57005718 }
57015719
57025720 /* Don't bother testing is_projection_capable_plan again */
@@ -5975,6 +5993,7 @@ materialize_finished_plan(Plan *subplan)
59755993 matplan -> plan_rows = subplan -> plan_rows ;
59765994 matplan -> plan_width = subplan -> plan_width ;
59775995 matplan -> parallel_aware = false;
5996+ matplan -> parallel_safe = subplan -> parallel_safe ;
59785997
59795998 return matplan ;
59805999}
0 commit comments