Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit a923af3

Browse files
committed
Fix build_grouping_chain() to not clobber its input lists.
There's no good reason for stomping on the input data; it makes the logic in this function no simpler, in fact probably the reverse. And it makes it impossible to separate path generation from plan generation, as I'm working towards doing; that will require more than one traversal of these lists.
1 parent 6a61d1f commit a923af3

File tree

1 file changed

+54
-62
lines changed

1 file changed

+54
-62
lines changed

src/backend/optimizer/plan/planner.c

+54-62
Original file line numberDiff line numberDiff line change
@@ -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
*/
24792470
static Plan *
24802471
build_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

Comments
 (0)