@@ -137,6 +137,7 @@ static Size estimate_hashagg_tablesize(Path *path,
137137static RelOptInfo * create_grouping_paths (PlannerInfo * root ,
138138 RelOptInfo * input_rel ,
139139 PathTarget * target ,
140+ bool target_parallel_safe ,
140141 const AggClauseCosts * agg_costs ,
141142 grouping_sets_data * gd );
142143static void consider_groupingsets_paths (PlannerInfo * root ,
@@ -152,6 +153,7 @@ static RelOptInfo *create_window_paths(PlannerInfo *root,
152153 RelOptInfo * input_rel ,
153154 PathTarget * input_target ,
154155 PathTarget * output_target ,
156+ bool output_target_parallel_safe ,
155157 List * tlist ,
156158 WindowFuncLists * wflists ,
157159 List * activeWindows );
@@ -168,6 +170,7 @@ static RelOptInfo *create_distinct_paths(PlannerInfo *root,
168170static RelOptInfo * create_ordered_paths (PlannerInfo * root ,
169171 RelOptInfo * input_rel ,
170172 PathTarget * target ,
173+ bool target_parallel_safe ,
171174 double limit_tuples );
172175static PathTarget * make_group_input_target (PlannerInfo * root ,
173176 PathTarget * final_target );
@@ -1583,6 +1586,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
15831586 PathTarget * final_target ;
15841587 List * final_targets ;
15851588 List * final_targets_contain_srfs ;
1589+ bool final_target_parallel_safe ;
15861590 RelOptInfo * current_rel ;
15871591 RelOptInfo * final_rel ;
15881592 ListCell * lc ;
@@ -1645,6 +1649,10 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
16451649 /* Also extract the PathTarget form of the setop result tlist */
16461650 final_target = current_rel -> cheapest_total_path -> pathtarget ;
16471651
1652+ /* And check whether it's parallel safe */
1653+ final_target_parallel_safe =
1654+ is_parallel_safe (root , (Node * ) final_target -> exprs );
1655+
16481656 /* The setop result tlist couldn't contain any SRFs */
16491657 Assert (!parse -> hasTargetSRFs );
16501658 final_targets = final_targets_contain_srfs = NIL ;
@@ -1676,12 +1684,15 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
16761684 PathTarget * sort_input_target ;
16771685 List * sort_input_targets ;
16781686 List * sort_input_targets_contain_srfs ;
1687+ bool sort_input_target_parallel_safe ;
16791688 PathTarget * grouping_target ;
16801689 List * grouping_targets ;
16811690 List * grouping_targets_contain_srfs ;
1691+ bool grouping_target_parallel_safe ;
16821692 PathTarget * scanjoin_target ;
16831693 List * scanjoin_targets ;
16841694 List * scanjoin_targets_contain_srfs ;
1695+ bool scanjoin_target_parallel_safe ;
16851696 bool have_grouping ;
16861697 AggClauseCosts agg_costs ;
16871698 WindowFuncLists * wflists = NULL ;
@@ -1805,30 +1816,46 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
18051816 * that were obtained within query_planner().
18061817 */
18071818 final_target = create_pathtarget (root , tlist );
1819+ final_target_parallel_safe =
1820+ is_parallel_safe (root , (Node * ) final_target -> exprs );
18081821
18091822 /*
18101823 * If ORDER BY was given, consider whether we should use a post-sort
18111824 * projection, and compute the adjusted target for preceding steps if
18121825 * so.
18131826 */
18141827 if (parse -> sortClause )
1828+ {
18151829 sort_input_target = make_sort_input_target (root ,
18161830 final_target ,
18171831 & have_postponed_srfs );
1832+ sort_input_target_parallel_safe =
1833+ is_parallel_safe (root , (Node * ) sort_input_target -> exprs );
1834+ }
18181835 else
1836+ {
18191837 sort_input_target = final_target ;
1838+ sort_input_target_parallel_safe = final_target_parallel_safe ;
1839+ }
18201840
18211841 /*
18221842 * If we have window functions to deal with, the output from any
18231843 * grouping step needs to be what the window functions want;
18241844 * otherwise, it should be sort_input_target.
18251845 */
18261846 if (activeWindows )
1847+ {
18271848 grouping_target = make_window_input_target (root ,
18281849 final_target ,
18291850 activeWindows );
1851+ grouping_target_parallel_safe =
1852+ is_parallel_safe (root , (Node * ) grouping_target -> exprs );
1853+ }
18301854 else
1855+ {
18311856 grouping_target = sort_input_target ;
1857+ grouping_target_parallel_safe = sort_input_target_parallel_safe ;
1858+ }
18321859
18331860 /*
18341861 * If we have grouping or aggregation to do, the topmost scan/join
@@ -1838,9 +1865,16 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
18381865 have_grouping = (parse -> groupClause || parse -> groupingSets ||
18391866 parse -> hasAggs || root -> hasHavingQual );
18401867 if (have_grouping )
1868+ {
18411869 scanjoin_target = make_group_input_target (root , final_target );
1870+ scanjoin_target_parallel_safe =
1871+ is_parallel_safe (root , (Node * ) grouping_target -> exprs );
1872+ }
18421873 else
1874+ {
18431875 scanjoin_target = grouping_target ;
1876+ scanjoin_target_parallel_safe = grouping_target_parallel_safe ;
1877+ }
18441878
18451879 /*
18461880 * If there are any SRFs in the targetlist, we must separate each of
@@ -1922,8 +1956,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
19221956 * for partial paths. But only parallel-safe expressions can be
19231957 * computed by partial paths.
19241958 */
1925- if (current_rel -> partial_pathlist &&
1926- is_parallel_safe (root , (Node * ) scanjoin_target -> exprs ))
1959+ if (current_rel -> partial_pathlist && scanjoin_target_parallel_safe )
19271960 {
19281961 /* Apply the scan/join target to each partial path */
19291962 foreach (lc , current_rel -> partial_pathlist )
@@ -1984,6 +2017,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
19842017 current_rel = create_grouping_paths (root ,
19852018 current_rel ,
19862019 grouping_target ,
2020+ grouping_target_parallel_safe ,
19872021 & agg_costs ,
19882022 gset_data );
19892023 /* Fix things up if grouping_target contains SRFs */
@@ -2003,6 +2037,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
20032037 current_rel ,
20042038 grouping_target ,
20052039 sort_input_target ,
2040+ sort_input_target_parallel_safe ,
20062041 tlist ,
20072042 wflists ,
20082043 activeWindows );
@@ -2036,6 +2071,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
20362071 current_rel = create_ordered_paths (root ,
20372072 current_rel ,
20382073 final_target ,
2074+ final_target_parallel_safe ,
20392075 have_postponed_srfs ? -1.0 :
20402076 limit_tuples );
20412077 /* Fix things up if final_target contains SRFs */
@@ -3623,6 +3659,7 @@ static RelOptInfo *
36233659create_grouping_paths (PlannerInfo * root ,
36243660 RelOptInfo * input_rel ,
36253661 PathTarget * target ,
3662+ bool target_parallel_safe ,
36263663 const AggClauseCosts * agg_costs ,
36273664 grouping_sets_data * gd )
36283665{
@@ -3652,8 +3689,7 @@ create_grouping_paths(PlannerInfo *root,
36523689 * target list and HAVING quals are parallel-safe. The partially grouped
36533690 * relation obeys the same rules.
36543691 */
3655- if (input_rel -> consider_parallel &&
3656- is_parallel_safe (root , (Node * ) target -> exprs ) &&
3692+ if (input_rel -> consider_parallel && target_parallel_safe &&
36573693 is_parallel_safe (root , (Node * ) parse -> havingQual ))
36583694 {
36593695 grouped_rel -> consider_parallel = true;
@@ -4230,6 +4266,7 @@ create_window_paths(PlannerInfo *root,
42304266 RelOptInfo * input_rel ,
42314267 PathTarget * input_target ,
42324268 PathTarget * output_target ,
4269+ bool output_target_parallel_safe ,
42334270 List * tlist ,
42344271 WindowFuncLists * wflists ,
42354272 List * activeWindows )
@@ -4245,8 +4282,7 @@ create_window_paths(PlannerInfo *root,
42454282 * can't be parallel-safe, either. Otherwise, we need to examine the
42464283 * target list and active windows for non-parallel-safe constructs.
42474284 */
4248- if (input_rel -> consider_parallel &&
4249- is_parallel_safe (root , (Node * ) output_target -> exprs ) &&
4285+ if (input_rel -> consider_parallel && output_target_parallel_safe &&
42504286 is_parallel_safe (root , (Node * ) activeWindows ))
42514287 window_rel -> consider_parallel = true;
42524288
@@ -4621,6 +4657,7 @@ static RelOptInfo *
46214657create_ordered_paths (PlannerInfo * root ,
46224658 RelOptInfo * input_rel ,
46234659 PathTarget * target ,
4660+ bool target_parallel_safe ,
46244661 double limit_tuples )
46254662{
46264663 Path * cheapest_input_path = input_rel -> cheapest_total_path ;
@@ -4635,8 +4672,7 @@ create_ordered_paths(PlannerInfo *root,
46354672 * can't be parallel-safe, either. Otherwise, it's parallel-safe if the
46364673 * target list is parallel-safe.
46374674 */
4638- if (input_rel -> consider_parallel &&
4639- is_parallel_safe (root , (Node * ) target -> exprs ))
4675+ if (input_rel -> consider_parallel && target_parallel_safe )
46404676 ordered_rel -> consider_parallel = true;
46414677
46424678 /*
0 commit comments