@@ -2035,13 +2035,6 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
20352035 & agg_costs ,
20362036 numGroups ,
20372037 result_plan );
2038-
2039- /*
2040- * these are destroyed by build_grouping_chain, so make sure
2041- * we don't try and touch them again
2042- */
2043- rollup_groupclauses = NIL ;
2044- rollup_lists = NIL ;
20452038 }
20462039 else if (parse -> groupClause )
20472040 {
@@ -2461,10 +2454,10 @@ remap_groupColIdx(PlannerInfo *root, List *groupClause)
24612454
24622455/*
24632456 * Build Agg and Sort nodes to implement sorted grouping with one or more
2464- * grouping sets. ( A plain GROUP BY or just the presence of aggregates counts
2457+ * grouping sets. A plain GROUP BY or just the presence of aggregates counts
24652458 * for this purpose as a single grouping set; the calling code is responsible
2466- * for providing a non-empty rollup_groupclauses list for such cases, though
2467- * rollup_lists may be null.)
2459+ * for providing a single-element rollup_groupclauses list for such cases,
2460+ * though rollup_lists may be nil.
24682461 *
24692462 * The last entry in rollup_groupclauses (which is the one the input is sorted
24702463 * on, if at all) is the one used for the returned Agg node. Any additional
@@ -2473,8 +2466,6 @@ remap_groupColIdx(PlannerInfo *root, List *groupClause)
24732466 * participate in the plan directly, but they are both a convenient way to
24742467 * represent the required data and a convenient way to account for the costs
24752468 * of execution.
2476- *
2477- * rollup_groupclauses and rollup_lists are destroyed by this function.
24782469 */
24792470static Plan *
24802471build_grouping_chain (PlannerInfo * root ,
@@ -2514,62 +2505,71 @@ build_grouping_chain(PlannerInfo *root,
25142505 * Generate the side nodes that describe the other sort and group
25152506 * operations besides the top one.
25162507 */
2517- while (list_length (rollup_groupclauses ) > 1 )
2508+ if (list_length (rollup_groupclauses ) > 1 )
25182509 {
2519- List * groupClause = linitial (rollup_groupclauses );
2520- List * gsets = linitial (rollup_lists );
2521- AttrNumber * new_grpColIdx ;
2522- Plan * sort_plan ;
2523- Plan * agg_plan ;
2524-
2525- Assert (groupClause );
2526- Assert (gsets );
2527-
2528- new_grpColIdx = remap_groupColIdx (root , groupClause );
2510+ ListCell * lc ,
2511+ * lc2 ;
25292512
2530- sort_plan = (Plan * )
2531- make_sort_from_groupcols (root ,
2532- groupClause ,
2533- new_grpColIdx ,
2534- result_plan );
2535-
2536- /*
2537- * sort_plan includes the cost of result_plan over again, which is not
2538- * what we want (since it's not actually running that plan). So
2539- * correct the cost figures.
2540- */
2513+ Assert (list_length (rollup_groupclauses ) == list_length (rollup_lists ));
2514+ forboth (lc , rollup_groupclauses , lc2 , rollup_lists )
2515+ {
2516+ List * groupClause = (List * ) lfirst (lc );
2517+ List * gsets = (List * ) lfirst (lc2 );
2518+ AttrNumber * new_grpColIdx ;
2519+ Plan * sort_plan ;
2520+ Plan * agg_plan ;
2521+
2522+ /* We want to iterate over all but the last rollup list elements */
2523+ if (lnext (lc ) == NULL )
2524+ break ;
25412525
2542- sort_plan -> startup_cost -= result_plan -> total_cost ;
2543- sort_plan -> total_cost -= result_plan -> total_cost ;
2526+ new_grpColIdx = remap_groupColIdx (root , groupClause );
25442527
2545- agg_plan = (Plan * ) make_agg (root ,
2546- tlist ,
2547- (List * ) parse -> havingQual ,
2548- AGG_SORTED ,
2549- agg_costs ,
2550- list_length (linitial (gsets )),
2551- new_grpColIdx ,
2552- extract_grouping_ops (groupClause ),
2553- gsets ,
2554- numGroups ,
2555- sort_plan );
2528+ sort_plan = (Plan * )
2529+ make_sort_from_groupcols (root ,
2530+ groupClause ,
2531+ new_grpColIdx ,
2532+ result_plan );
25562533
2557- sort_plan -> lefttree = NULL ;
2534+ /*
2535+ * sort_plan includes the cost of result_plan, which is not what
2536+ * we want (since we'll not actually run that plan again). So
2537+ * correct the cost figures.
2538+ */
2539+ sort_plan -> startup_cost -= result_plan -> total_cost ;
2540+ sort_plan -> total_cost -= result_plan -> total_cost ;
2541+
2542+ agg_plan = (Plan * ) make_agg (root ,
2543+ tlist ,
2544+ (List * ) parse -> havingQual ,
2545+ AGG_SORTED ,
2546+ agg_costs ,
2547+ list_length (linitial (gsets )),
2548+ new_grpColIdx ,
2549+ extract_grouping_ops (groupClause ),
2550+ gsets ,
2551+ numGroups ,
2552+ sort_plan );
25582553
2559- chain = lappend (chain , agg_plan );
2554+ /*
2555+ * Nuke stuff we don't need to avoid bloating debug output.
2556+ */
2557+ sort_plan -> targetlist = NIL ;
2558+ sort_plan -> lefttree = NULL ;
25602559
2561- if ( rollup_lists )
2562- rollup_lists = list_delete_first ( rollup_lists ) ;
2560+ agg_plan -> targetlist = NIL ;
2561+ agg_plan -> qual = NIL ;
25632562
2564- rollup_groupclauses = list_delete_first (rollup_groupclauses );
2563+ chain = lappend (chain , agg_plan );
2564+ }
25652565 }
25662566
25672567 /*
25682568 * Now make the final Agg node
25692569 */
25702570 {
2571- List * groupClause = linitial (rollup_groupclauses );
2572- List * gsets = rollup_lists ? linitial (rollup_lists ) : NIL ;
2571+ List * groupClause = ( List * ) llast (rollup_groupclauses );
2572+ List * gsets = rollup_lists ? ( List * ) llast (rollup_lists ) : NIL ;
25732573 int numGroupCols ;
25742574 ListCell * lc ;
25752575
@@ -2601,14 +2601,6 @@ build_grouping_chain(PlannerInfo *root,
26012601 Plan * subplan = lfirst (lc );
26022602
26032603 result_plan -> total_cost += subplan -> total_cost ;
2604-
2605- /*
2606- * Nuke stuff we don't need to avoid bloating debug output.
2607- */
2608-
2609- subplan -> targetlist = NIL ;
2610- subplan -> qual = NIL ;
2611- subplan -> lefttree -> targetlist = NIL ;
26122604 }
26132605 }
26142606
0 commit comments