diff options
| author | Tomas Vondra | 2021-03-18 16:45:38 +0000 |
|---|---|---|
| committer | Tomas Vondra | 2021-03-18 17:22:18 +0000 |
| commit | be45be9c33a85e72cdaeb9967e9f6d2d00199e09 (patch) | |
| tree | c728067c32404e7475ebf4c66561d7edf2dd35b3 /src/include | |
| parent | cd91de0d17952b5763466cfa663e98318f26d357 (diff) | |
Implement GROUP BY DISTINCT
With grouping sets, it's possible that some of the grouping sets are
duplicate. This is especially common with CUBE and ROLLUP clauses. For
example GROUP BY CUBE (a,b), CUBE (b,c) is equivalent to
GROUP BY GROUPING SETS (
(a, b, c),
(a, b, c),
(a, b, c),
(a, b),
(a, b),
(a, b),
(a),
(a),
(a),
(c, a),
(c, a),
(c, a),
(c),
(b, c),
(b),
()
)
Some of the grouping sets are calculated multiple times, which is mostly
unnecessary. This commit implements a new GROUP BY DISTINCT feature, as
defined in the SQL standard, which eliminates the duplicate sets.
Author: Vik Fearing
Reviewed-by: Erik Rijkers, Georgios Kokolatos, Tomas Vondra
Discussion: https://postgr.es/m/bf3805a8-d7d1-ae61-fece-761b7ff41ecc@postgresfriends.org
Diffstat (limited to 'src/include')
| -rw-r--r-- | src/include/nodes/parsenodes.h | 10 | ||||
| -rw-r--r-- | src/include/nodes/pg_list.h | 1 | ||||
| -rw-r--r-- | src/include/parser/parse_agg.h | 2 |
3 files changed, 12 insertions, 1 deletions
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 236832a2ca..3a81d4f267 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -62,6 +62,14 @@ typedef enum SortByNulls SORTBY_NULLS_LAST } SortByNulls; +/* Options for [ ALL | DISTINCT ] */ +typedef enum SetQuantifier +{ + SET_QUANTIFIER_DEFAULT, + SET_QUANTIFIER_ALL, + SET_QUANTIFIER_DISTINCT +} SetQuantifier; + /* * Grantable rights are encoded so that we can OR them together in a bitmask. * The present representation of AclItem limits us to 16 distinct rights, @@ -146,6 +154,7 @@ typedef struct Query List *returningList; /* return-values list (of TargetEntry) */ List *groupClause; /* a list of SortGroupClause's */ + bool groupDistinct; /* is the group by clause distinct? */ List *groupingSets; /* a list of GroupingSet's if present */ @@ -1629,6 +1638,7 @@ typedef struct SelectStmt List *fromClause; /* the FROM clause */ Node *whereClause; /* WHERE qualification */ List *groupClause; /* GROUP BY clauses */ + bool groupDistinct; /* Is this GROUP BY DISTINCT? */ Node *havingClause; /* HAVING conditional-expression */ List *windowClause; /* WINDOW window_name AS (...), ... */ diff --git a/src/include/nodes/pg_list.h b/src/include/nodes/pg_list.h index 404e03f132..30f98c4595 100644 --- a/src/include/nodes/pg_list.h +++ b/src/include/nodes/pg_list.h @@ -604,6 +604,7 @@ extern pg_nodiscard List *list_copy_deep(const List *oldlist); typedef int (*list_sort_comparator) (const ListCell *a, const ListCell *b); extern void list_sort(List *list, list_sort_comparator cmp); +extern int list_int_cmp(const ListCell *p1, const ListCell *p2); extern int list_oid_cmp(const ListCell *p1, const ListCell *p2); #endif /* PG_LIST_H */ diff --git a/src/include/parser/parse_agg.h b/src/include/parser/parse_agg.h index 0a2546c3ea..4dea01752a 100644 --- a/src/include/parser/parse_agg.h +++ b/src/include/parser/parse_agg.h @@ -26,7 +26,7 @@ extern void transformWindowFuncCall(ParseState *pstate, WindowFunc *wfunc, extern void parseCheckAggregates(ParseState *pstate, Query *qry); -extern List *expand_grouping_sets(List *groupingSets, int limit); +extern List *expand_grouping_sets(List *groupingSets, bool groupDistinct, int limit); extern int get_aggregate_argtypes(Aggref *aggref, Oid *inputTypes); |
