reorder_grouping_sets(List *groupingsets, List *sortclause)
{
ListCell *lc;
- ListCell *lc2;
List *previous = NIL;
List *result = NIL;
List *new_elems = list_difference_int(candidate, previous);
GroupingSetData *gs = makeNode(GroupingSetData);
- if (list_length(new_elems) > 0)
+ while (list_length(sortclause) > list_length(previous) &&
+ list_length(new_elems) > 0)
{
- while (list_length(sortclause) > list_length(previous))
- {
- SortGroupClause *sc = list_nth(sortclause, list_length(previous));
- int ref = sc->tleSortGroupRef;
+ SortGroupClause *sc = list_nth(sortclause, list_length(previous));
+ int ref = sc->tleSortGroupRef;
- if (list_member_int(new_elems, ref))
- {
- previous = lappend_int(previous, ref);
- new_elems = list_delete_int(new_elems, ref);
- }
- else
- {
- /* diverged from the sortclause; give up on it */
- sortclause = NIL;
- break;
- }
+ if (list_member_int(new_elems, ref))
+ {
+ previous = lappend_int(previous, ref);
+ new_elems = list_delete_int(new_elems, ref);
}
-
- foreach(lc2, new_elems)
+ else
{
- previous = lappend_int(previous, lfirst_int(lc2));
+ /* diverged from the sortclause; give up on it */
+ sortclause = NIL;
+ break;
}
}
+ /*
+ * Safe to use list_concat (which shares cells of the second arg)
+ * because we know that new_elems does not share cells with anything.
+ */
+ previous = list_concat(previous, new_elems);
+
gs->set = list_copy(previous);
result = lcons(gs, result);
- list_free(new_elems);
}
list_free(previous);
| | 9
(12 rows)
+-- Test reordering of grouping sets
+explain (costs off)
+select * from gstest1 group by grouping sets((a,b,v),(v)) order by v,b,a;
+ QUERY PLAN
+------------------------------------------------------------------------------
+ GroupAggregate
+ Group Key: "*VALUES*".column3, "*VALUES*".column2, "*VALUES*".column1
+ Group Key: "*VALUES*".column3
+ -> Sort
+ Sort Key: "*VALUES*".column3, "*VALUES*".column2, "*VALUES*".column1
+ -> Values Scan on "*VALUES*"
+(6 rows)
+
-- Agg level check. This query should error out.
select (select grouping(a,b) from gstest2) from gstest2 group by a,b;
ERROR: arguments to GROUPING must be grouping expressions of the associated query level
from (values (1),(2)) v(x), gstest_data(v.x)
group by cube (a,b) order by a,b;
+-- Test reordering of grouping sets
+explain (costs off)
+select * from gstest1 group by grouping sets((a,b,v),(v)) order by v,b,a;
-- Agg level check. This query should error out.
select (select grouping(a,b) from gstest2) from gstest2 group by a,b;