@@ -108,10 +108,6 @@ static double get_number_of_groups(PlannerInfo *root,
108108 double path_rows ,
109109 List * rollup_lists ,
110110 List * rollup_groupclauses );
111- static void set_grouped_rel_consider_parallel (PlannerInfo * root ,
112- RelOptInfo * grouped_rel ,
113- PathTarget * target ,
114- const AggClauseCosts * agg_costs );
115111static Size estimate_hashagg_tablesize (Path * path ,
116112 const AggClauseCosts * agg_costs ,
117113 double dNumGroups );
@@ -255,29 +251,14 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
255251 /*
256252 * glob->parallelModeNeeded should tell us whether it's necessary to
257253 * impose the parallel mode restrictions, but we don't actually want to
258- * impose them unless we choose a parallel plan, so that people who
259- * mislabel their functions but don't use parallelism anyway aren't
260- * harmed. But when force_parallel_mode is set, we enable the restrictions
261- * whenever possible for testing purposes.
262- *
263- * glob->wholePlanParallelSafe should tell us whether it's OK to stick a
264- * Gather node on top of the entire plan. However, it only needs to be
265- * accurate when force_parallel_mode is 'on' or 'regress', so we don't
266- * bother doing the work otherwise. The value we set here is just a
267- * preliminary guess; it may get changed from true to false later, but not
268- * vice versa.
254+ * impose them unless we choose a parallel plan, so it is normally set
255+ * only if a parallel plan is chosen (see create_gather_plan). That way,
256+ * people who mislabel their functions but don't use parallelism anyway
257+ * aren't harmed. But when force_parallel_mode is set, we enable the
258+ * restrictions whenever possible for testing purposes.
269259 */
270- if (force_parallel_mode == FORCE_PARALLEL_OFF || !glob -> parallelModeOK )
271- {
272- glob -> parallelModeNeeded = false;
273- glob -> wholePlanParallelSafe = false; /* either false or don't care */
274- }
275- else
276- {
277- glob -> parallelModeNeeded = true;
278- glob -> wholePlanParallelSafe =
279- !has_parallel_hazard ((Node * ) parse , false);
280- }
260+ glob -> parallelModeNeeded = glob -> parallelModeOK &&
261+ (force_parallel_mode != FORCE_PARALLEL_OFF );
281262
282263 /* Determine what fraction of the plan is likely to be scanned */
283264 if (cursorOptions & CURSOR_OPT_FAST_PLAN )
@@ -327,20 +308,11 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
327308 top_plan = materialize_finished_plan (top_plan );
328309 }
329310
330- /*
331- * At present, we don't copy subplans to workers. The presence of a
332- * subplan in one part of the plan doesn't preclude the use of parallelism
333- * in some other part of the plan, but it does preclude the possibility of
334- * regarding the entire plan parallel-safe.
335- */
336- if (glob -> subplans != NULL )
337- glob -> wholePlanParallelSafe = false;
338-
339311 /*
340312 * Optionally add a Gather node for testing purposes, provided this is
341313 * actually a safe thing to do.
342314 */
343- if (glob -> wholePlanParallelSafe &&
315+ if (best_path -> parallel_safe &&
344316 force_parallel_mode != FORCE_PARALLEL_OFF )
345317 {
346318 Gather * gather = makeNode (Gather );
@@ -1925,6 +1897,21 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
19251897 */
19261898 final_rel = fetch_upper_rel (root , UPPERREL_FINAL , NULL );
19271899
1900+ /*
1901+ * If the input rel is marked consider_parallel and there's nothing that's
1902+ * not parallel-safe in the LIMIT clause, then the final_rel can be marked
1903+ * consider_parallel as well. Note that if the query has rowMarks or is
1904+ * not a SELECT, consider_parallel will be false for every relation in the
1905+ * query.
1906+ */
1907+ if (current_rel -> consider_parallel &&
1908+ !has_parallel_hazard (parse -> limitOffset , false) &&
1909+ !has_parallel_hazard (parse -> limitCount , false))
1910+ final_rel -> consider_parallel = true;
1911+
1912+ /*
1913+ * Generate paths for the final rel.
1914+ */
19281915 foreach (lc , current_rel -> pathlist )
19291916 {
19301917 Path * path = (Path * ) lfirst (lc );
@@ -3203,56 +3190,6 @@ get_number_of_groups(PlannerInfo *root,
32033190 return dNumGroups ;
32043191}
32053192
3206- /*
3207- * set_grouped_rel_consider_parallel
3208- * Determine if it's safe to generate partial paths for grouping.
3209- */
3210- static void
3211- set_grouped_rel_consider_parallel (PlannerInfo * root , RelOptInfo * grouped_rel ,
3212- PathTarget * target ,
3213- const AggClauseCosts * agg_costs )
3214- {
3215- Query * parse = root -> parse ;
3216-
3217- Assert (grouped_rel -> reloptkind == RELOPT_UPPER_REL );
3218-
3219- /*
3220- * If there are no aggregates or GROUP BY clause, then no parallel
3221- * aggregation is possible. At present, it doesn't matter whether
3222- * consider_parallel gets set in this case, because none of the upper rels
3223- * on top of this one try to set the flag or examine it, so we just bail
3224- * out as quickly as possible. We might need to be more clever here in
3225- * the future.
3226- */
3227- if (!parse -> hasAggs && parse -> groupClause == NIL )
3228- return ;
3229-
3230- /*
3231- * Similarly, bail out quickly if GROUPING SETS are present; we can't
3232- * support those at present.
3233- */
3234- if (parse -> groupingSets )
3235- return ;
3236-
3237- /*
3238- * If parallel-restricted functions are present in the target list or the
3239- * HAVING clause, we cannot safely go parallel.
3240- */
3241- if (has_parallel_hazard ((Node * ) target -> exprs , false) ||
3242- has_parallel_hazard ((Node * ) parse -> havingQual , false))
3243- return ;
3244-
3245- /*
3246- * If we have any non-partial-capable aggregates, or if any of them can't
3247- * be serialized, we can't go parallel.
3248- */
3249- if (agg_costs -> hasNonPartial || agg_costs -> hasNonSerial )
3250- return ;
3251-
3252- /* OK, consider parallelization */
3253- grouped_rel -> consider_parallel = true;
3254- }
3255-
32563193/*
32573194 * estimate_hashagg_tablesize
32583195 * estimate the number of bytes that a hash aggregate hashtable will
@@ -3314,12 +3251,23 @@ create_grouping_paths(PlannerInfo *root,
33143251 double dNumPartialGroups = 0 ;
33153252 bool can_hash ;
33163253 bool can_sort ;
3254+ bool try_parallel_aggregation ;
33173255
33183256 ListCell * lc ;
33193257
33203258 /* For now, do all work in the (GROUP_AGG, NULL) upperrel */
33213259 grouped_rel = fetch_upper_rel (root , UPPERREL_GROUP_AGG , NULL );
33223260
3261+ /*
3262+ * If the input relation is not parallel-safe, then the grouped relation
3263+ * can't be parallel-safe, either. Otherwise, it's parallel-safe if the
3264+ * target list and HAVING quals are parallel-safe.
3265+ */
3266+ if (input_rel -> consider_parallel &&
3267+ !has_parallel_hazard ((Node * ) target -> exprs , false) &&
3268+ !has_parallel_hazard ((Node * ) parse -> havingQual , false))
3269+ grouped_rel -> consider_parallel = true;
3270+
33233271 /*
33243272 * Check for degenerate grouping.
33253273 */
@@ -3407,15 +3355,6 @@ create_grouping_paths(PlannerInfo *root,
34073355 rollup_lists ,
34083356 rollup_groupclauses );
34093357
3410- /*
3411- * Partial paths in the input rel could allow us to perform aggregation in
3412- * parallel. set_grouped_rel_consider_parallel() will determine if it's
3413- * going to be safe to do so.
3414- */
3415- if (input_rel -> partial_pathlist != NIL )
3416- set_grouped_rel_consider_parallel (root , grouped_rel ,
3417- target , & agg_costs );
3418-
34193358 /*
34203359 * Determine whether it's possible to perform sort-based implementations
34213360 * of grouping. (Note that if groupClause is empty,
@@ -3447,6 +3386,46 @@ create_grouping_paths(PlannerInfo *root,
34473386 agg_costs .numOrderedAggs == 0 &&
34483387 grouping_is_hashable (parse -> groupClause ));
34493388
3389+ /*
3390+ * If grouped_rel->consider_parallel is true, then paths that we generate
3391+ * for this grouping relation could be run inside of a worker, but that
3392+ * doesn't mean we can actually use the PartialAggregate/FinalizeAggregate
3393+ * execution strategy. Figure that out.
3394+ */
3395+ if (!grouped_rel -> consider_parallel )
3396+ {
3397+ /* Not even parallel-safe. */
3398+ try_parallel_aggregation = false;
3399+ }
3400+ else if (input_rel -> partial_pathlist == NIL )
3401+ {
3402+ /* Nothing to use as input for partial aggregate. */
3403+ try_parallel_aggregation = false;
3404+ }
3405+ else if (!parse -> hasAggs && parse -> groupClause == NIL )
3406+ {
3407+ /*
3408+ * We don't know how to do parallel aggregation unless we have either
3409+ * some aggregates or a grouping clause.
3410+ */
3411+ try_parallel_aggregation = false;
3412+ }
3413+ else if (parse -> groupingSets )
3414+ {
3415+ /* We don't know how to do grouping sets in parallel. */
3416+ try_parallel_aggregation = false;
3417+ }
3418+ else if (agg_costs .hasNonPartial || agg_costs .hasNonSerial )
3419+ {
3420+ /* Insufficient support for partial mode. */
3421+ try_parallel_aggregation = false;
3422+ }
3423+ else
3424+ {
3425+ /* Everything looks good. */
3426+ try_parallel_aggregation = true;
3427+ }
3428+
34503429 /*
34513430 * Before generating paths for grouped_rel, we first generate any possible
34523431 * partial paths; that way, later code can easily consider both parallel
@@ -3455,7 +3434,7 @@ create_grouping_paths(PlannerInfo *root,
34553434 * Gather node on top is insufficient to create a final path, as would be
34563435 * the case for a scan/join rel.
34573436 */
3458- if (grouped_rel -> consider_parallel )
3437+ if (try_parallel_aggregation )
34593438 {
34603439 Path * cheapest_partial_path = linitial (input_rel -> partial_pathlist );
34613440
@@ -3498,7 +3477,7 @@ create_grouping_paths(PlannerInfo *root,
34983477
34993478 if (can_sort )
35003479 {
3501- /* Checked in set_grouped_rel_consider_parallel() */
3480+ /* This was checked before setting try_parallel_aggregation */
35023481 Assert (parse -> hasAggs || parse -> groupClause );
35033482
35043483 /*
@@ -3831,6 +3810,16 @@ create_window_paths(PlannerInfo *root,
38313810 /* For now, do all work in the (WINDOW, NULL) upperrel */
38323811 window_rel = fetch_upper_rel (root , UPPERREL_WINDOW , NULL );
38333812
3813+ /*
3814+ * If the input relation is not parallel-safe, then the window relation
3815+ * can't be parallel-safe, either. Otherwise, we need to examine the
3816+ * target list and active windows for non-parallel-safe constructs.
3817+ */
3818+ if (input_rel -> consider_parallel &&
3819+ !has_parallel_hazard ((Node * ) output_target -> exprs , false) &&
3820+ !has_parallel_hazard ((Node * ) activeWindows , false))
3821+ window_rel -> consider_parallel = true;
3822+
38343823 /*
38353824 * Consider computing window functions starting from the existing
38363825 * cheapest-total path (which will likely require a sort) as well as any
@@ -3986,6 +3975,15 @@ create_distinct_paths(PlannerInfo *root,
39863975 /* For now, do all work in the (DISTINCT, NULL) upperrel */
39873976 distinct_rel = fetch_upper_rel (root , UPPERREL_DISTINCT , NULL );
39883977
3978+ /*
3979+ * We don't compute anything at this level, so distinct_rel will be
3980+ * parallel-safe if the input rel is parallel-safe. In particular, if
3981+ * there is a DISTINCT ON (...) clause, any path for the input_rel will
3982+ * output those expressions, and will not be parallel-safe unless those
3983+ * expressions are parallel-safe.
3984+ */
3985+ distinct_rel -> consider_parallel = input_rel -> consider_parallel ;
3986+
39893987 /* Estimate number of distinct rows there will be */
39903988 if (parse -> groupClause || parse -> groupingSets || parse -> hasAggs ||
39913989 root -> hasHavingQual )
@@ -4169,6 +4167,15 @@ create_ordered_paths(PlannerInfo *root,
41694167 /* For now, do all work in the (ORDERED, NULL) upperrel */
41704168 ordered_rel = fetch_upper_rel (root , UPPERREL_ORDERED , NULL );
41714169
4170+ /*
4171+ * If the input relation is not parallel-safe, then the ordered relation
4172+ * can't be parallel-safe, either. Otherwise, it's parallel-safe if the
4173+ * target list is parallel-safe.
4174+ */
4175+ if (input_rel -> consider_parallel &&
4176+ !has_parallel_hazard ((Node * ) target -> exprs , false))
4177+ ordered_rel -> consider_parallel = true;
4178+
41724179 foreach (lc , input_rel -> pathlist )
41734180 {
41744181 Path * path = (Path * ) lfirst (lc );
0 commit comments