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

Commit faab14e

Browse files
committed
Fix flattening of nested grouping sets.
Previously nested grouping set specifications accidentally weren't flattened, but instead contained the nested specification as a element in the outer list. Fix this by, as actually documented in comments, concatenating the nested set specification into the outer one. Also add tests to prevent this from breaking again. Author: Andrew Gierth, with tests from Jeevan Chalke Reported-By: Jeevan Chalke Discussion: CAM2+6=V5YvuxB+EyN4iH=GbD-XTA435TCNvnDFSD--YvXs+pww@mail.gmail.com Backpatch: 9.5, where grouping sets were introduced
1 parent 61444bf commit faab14e

File tree

3 files changed

+160
-3
lines changed

3 files changed

+160
-3
lines changed

src/backend/parser/parse_clause.c

+10-3
Original file line numberDiff line numberDiff line change
@@ -1812,7 +1812,7 @@ findTargetlistEntrySQL99(ParseState *pstate, Node *node, List **tlist,
18121812
* Inside a grouping set (ROLLUP, CUBE, or GROUPING SETS), we expect the
18131813
* content to be nested no more than 2 deep: i.e. ROLLUP((a,b),(c,d)) is
18141814
* ok, but ROLLUP((a,(b,c)),d) is flattened to ((a,b,c),d), which we then
1815-
* normalize to ((a,b,c),(d)).
1815+
* (later) normalize to ((a,b,c),(d)).
18161816
*
18171817
* CUBE or ROLLUP can be nested inside GROUPING SETS (but not the reverse),
18181818
* and we leave that alone if we find it. But if we see GROUPING SETS inside
@@ -1881,9 +1881,16 @@ flatten_grouping_sets(Node *expr, bool toplevel, bool *hasGroupingSets)
18811881

18821882
foreach(l2, gset->content)
18831883
{
1884-
Node *n2 = flatten_grouping_sets(lfirst(l2), false, NULL);
1884+
Node *n1 = lfirst(l2);
1885+
Node *n2 = flatten_grouping_sets(n1, false, NULL);
18851886

1886-
result_set = lappend(result_set, n2);
1887+
if (IsA(n1, GroupingSet) &&
1888+
((GroupingSet *)n1)->kind == GROUPING_SET_SETS)
1889+
{
1890+
result_set = list_concat(result_set, (List *) n2);
1891+
}
1892+
else
1893+
result_set = lappend(result_set, n2);
18871894
}
18881895

18891896
/*

src/test/regress/expected/groupingsets.out

+121
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,127 @@ select a, b, sum(c), sum(sum(c)) over (order by a,b) as rsum
145145
| | 12 | 36
146146
(6 rows)
147147

148+
-- nesting with grouping sets
149+
select sum(c) from gstest2
150+
group by grouping sets((), grouping sets((), grouping sets(())))
151+
order by 1 desc;
152+
sum
153+
-----
154+
12
155+
12
156+
12
157+
(3 rows)
158+
159+
select sum(c) from gstest2
160+
group by grouping sets((), grouping sets((), grouping sets(((a, b)))))
161+
order by 1 desc;
162+
sum
163+
-----
164+
12
165+
12
166+
8
167+
2
168+
2
169+
(5 rows)
170+
171+
select sum(c) from gstest2
172+
group by grouping sets(grouping sets(rollup(c), grouping sets(cube(c))))
173+
order by 1 desc;
174+
sum
175+
-----
176+
12
177+
12
178+
6
179+
6
180+
6
181+
6
182+
(6 rows)
183+
184+
select sum(c) from gstest2
185+
group by grouping sets(a, grouping sets(a, cube(b)))
186+
order by 1 desc;
187+
sum
188+
-----
189+
12
190+
10
191+
10
192+
8
193+
4
194+
2
195+
2
196+
(7 rows)
197+
198+
select sum(c) from gstest2
199+
group by grouping sets(grouping sets((a, (b))))
200+
order by 1 desc;
201+
sum
202+
-----
203+
8
204+
2
205+
2
206+
(3 rows)
207+
208+
select sum(c) from gstest2
209+
group by grouping sets(grouping sets((a, b)))
210+
order by 1 desc;
211+
sum
212+
-----
213+
8
214+
2
215+
2
216+
(3 rows)
217+
218+
select sum(c) from gstest2
219+
group by grouping sets(grouping sets(a, grouping sets(a), a))
220+
order by 1 desc;
221+
sum
222+
-----
223+
10
224+
10
225+
10
226+
2
227+
2
228+
2
229+
(6 rows)
230+
231+
select sum(c) from gstest2
232+
group by grouping sets(grouping sets(a, grouping sets(a, grouping sets(a), ((a)), a, grouping sets(a), (a)), a))
233+
order by 1 desc;
234+
sum
235+
-----
236+
10
237+
10
238+
10
239+
10
240+
10
241+
10
242+
10
243+
10
244+
2
245+
2
246+
2
247+
2
248+
2
249+
2
250+
2
251+
2
252+
(16 rows)
253+
254+
select sum(c) from gstest2
255+
group by grouping sets((a,(a,b)), grouping sets((a,(a,b)),a))
256+
order by 1 desc;
257+
sum
258+
-----
259+
10
260+
8
261+
8
262+
2
263+
2
264+
2
265+
2
266+
2
267+
(8 rows)
268+
148269
-- empty input: first is 0 rows, second 1, third 3 etc.
149270
select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),a);
150271
a | b | sum | count

src/test/regress/sql/groupingsets.sql

+29
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,35 @@ select grouping(a), a, array_agg(b),
7373
select a, b, sum(c), sum(sum(c)) over (order by a,b) as rsum
7474
from gstest2 group by rollup (a,b) order by rsum, a, b;
7575

76+
-- nesting with grouping sets
77+
select sum(c) from gstest2
78+
group by grouping sets((), grouping sets((), grouping sets(())))
79+
order by 1 desc;
80+
select sum(c) from gstest2
81+
group by grouping sets((), grouping sets((), grouping sets(((a, b)))))
82+
order by 1 desc;
83+
select sum(c) from gstest2
84+
group by grouping sets(grouping sets(rollup(c), grouping sets(cube(c))))
85+
order by 1 desc;
86+
select sum(c) from gstest2
87+
group by grouping sets(a, grouping sets(a, cube(b)))
88+
order by 1 desc;
89+
select sum(c) from gstest2
90+
group by grouping sets(grouping sets((a, (b))))
91+
order by 1 desc;
92+
select sum(c) from gstest2
93+
group by grouping sets(grouping sets((a, b)))
94+
order by 1 desc;
95+
select sum(c) from gstest2
96+
group by grouping sets(grouping sets(a, grouping sets(a), a))
97+
order by 1 desc;
98+
select sum(c) from gstest2
99+
group by grouping sets(grouping sets(a, grouping sets(a, grouping sets(a), ((a)), a, grouping sets(a), (a)), a))
100+
order by 1 desc;
101+
select sum(c) from gstest2
102+
group by grouping sets((a,(a,b)), grouping sets((a,(a,b)),a))
103+
order by 1 desc;
104+
76105
-- empty input: first is 0 rows, second 1, third 3 etc.
77106
select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),a);
78107
select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),());

0 commit comments

Comments
 (0)