* transformGroupClause - * transform a GROUP BY clause * * GROUP BY items will be added to the targetlist (as resjunk columns) * if not already present, so the targetlist must be passed by reference. * * This is also used for window PARTITION BY clauses (which act almost the * same, but are always interpreted per SQL99 rules). * * Grouping sets make this a lot more complex than it was.
| 2716 | * useSQL99 SQL99 rather than SQL92 syntax |
| 2717 | */ |
| 2718 | List * |
| 2719 | transformGroupClause(ParseState *pstate, List *grouplist, List **groupingSets, |
| 2720 | List **targetlist, List *sortClause, |
| 2721 | ParseExprKind exprKind, bool useSQL99) |
| 2722 | { |
| 2723 | List *result = NIL; |
| 2724 | List *flat_grouplist; |
| 2725 | List *gsets = NIL; |
| 2726 | ListCell *gl; |
| 2727 | bool hasGroupingSets = false; |
| 2728 | Bitmapset *seen_local = NULL; |
| 2729 | |
| 2730 | /* |
| 2731 | * Recursively flatten implicit RowExprs. (Technically this is only needed |
| 2732 | * for GROUP BY, per the syntax rules for grouping sets, but we do it |
| 2733 | * anyway.) |
| 2734 | */ |
| 2735 | flat_grouplist = (List *) flatten_grouping_sets((Node *) grouplist, |
| 2736 | true, |
| 2737 | &hasGroupingSets); |
| 2738 | |
| 2739 | /* |
| 2740 | * If the list is now empty, but hasGroupingSets is true, it's because we |
| 2741 | * elided redundant empty grouping sets. Restore a single empty grouping |
| 2742 | * set to leave a canonical form: GROUP BY () |
| 2743 | */ |
| 2744 | |
| 2745 | if (flat_grouplist == NIL && hasGroupingSets) |
| 2746 | { |
| 2747 | flat_grouplist = list_make1(makeGroupingSet(GROUPING_SET_EMPTY, |
| 2748 | NIL, |
| 2749 | exprLocation((Node *) grouplist))); |
| 2750 | } |
| 2751 | |
| 2752 | foreach(gl, flat_grouplist) |
| 2753 | { |
| 2754 | Node *gexpr = (Node *) lfirst(gl); |
| 2755 | |
| 2756 | if (IsA(gexpr, GroupingSet)) |
| 2757 | { |
| 2758 | GroupingSet *gset = (GroupingSet *) gexpr; |
| 2759 | |
| 2760 | switch (gset->kind) |
| 2761 | { |
| 2762 | case GROUPING_SET_EMPTY: |
| 2763 | gsets = lappend(gsets, gset); |
| 2764 | break; |
| 2765 | case GROUPING_SET_SIMPLE: |
| 2766 | /* can't happen */ |
| 2767 | Assert(false); |
| 2768 | break; |
| 2769 | case GROUPING_SET_SETS: |
| 2770 | case GROUPING_SET_CUBE: |
| 2771 | case GROUPING_SET_ROLLUP: |
| 2772 | gsets = lappend(gsets, |
| 2773 | transformGroupingSet(&result, |
| 2774 | pstate, gset, |
| 2775 | targetlist, sortClause, |
no test coverage detected