@@ -2035,13 +2035,6 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
2035
2035
& agg_costs ,
2036
2036
numGroups ,
2037
2037
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 ;
2045
2038
}
2046
2039
else if (parse -> groupClause )
2047
2040
{
@@ -2461,10 +2454,10 @@ remap_groupColIdx(PlannerInfo *root, List *groupClause)
2461
2454
2462
2455
/*
2463
2456
* 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
2465
2458
* 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.
2468
2461
*
2469
2462
* The last entry in rollup_groupclauses (which is the one the input is sorted
2470
2463
* 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)
2473
2466
* participate in the plan directly, but they are both a convenient way to
2474
2467
* represent the required data and a convenient way to account for the costs
2475
2468
* of execution.
2476
- *
2477
- * rollup_groupclauses and rollup_lists are destroyed by this function.
2478
2469
*/
2479
2470
static Plan *
2480
2471
build_grouping_chain (PlannerInfo * root ,
@@ -2514,62 +2505,71 @@ build_grouping_chain(PlannerInfo *root,
2514
2505
* Generate the side nodes that describe the other sort and group
2515
2506
* operations besides the top one.
2516
2507
*/
2517
- while (list_length (rollup_groupclauses ) > 1 )
2508
+ if (list_length (rollup_groupclauses ) > 1 )
2518
2509
{
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 ;
2529
2512
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 ;
2541
2525
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 );
2544
2527
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 );
2556
2533
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 );
2558
2553
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 ;
2560
2559
2561
- if ( rollup_lists )
2562
- rollup_lists = list_delete_first ( rollup_lists ) ;
2560
+ agg_plan -> targetlist = NIL ;
2561
+ agg_plan -> qual = NIL ;
2563
2562
2564
- rollup_groupclauses = list_delete_first (rollup_groupclauses );
2563
+ chain = lappend (chain , agg_plan );
2564
+ }
2565
2565
}
2566
2566
2567
2567
/*
2568
2568
* Now make the final Agg node
2569
2569
*/
2570
2570
{
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 ;
2573
2573
int numGroupCols ;
2574
2574
ListCell * lc ;
2575
2575
@@ -2601,14 +2601,6 @@ build_grouping_chain(PlannerInfo *root,
2601
2601
Plan * subplan = lfirst (lc );
2602
2602
2603
2603
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 ;
2612
2604
}
2613
2605
}
2614
2606
0 commit comments