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/backend/nodes | |
| 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/backend/nodes')
| -rw-r--r-- | src/backend/nodes/copyfuncs.c | 2 | ||||
| -rw-r--r-- | src/backend/nodes/equalfuncs.c | 2 | ||||
| -rw-r--r-- | src/backend/nodes/list.c | 16 | ||||
| -rw-r--r-- | src/backend/nodes/outfuncs.c | 2 | ||||
| -rw-r--r-- | src/backend/nodes/readfuncs.c | 1 |
5 files changed, 23 insertions, 0 deletions
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index da91cbd2b1e..bda379ba91d 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -3135,6 +3135,7 @@ _copyQuery(const Query *from) COPY_NODE_FIELD(onConflict); COPY_NODE_FIELD(returningList); COPY_NODE_FIELD(groupClause); + COPY_SCALAR_FIELD(groupDistinct); COPY_NODE_FIELD(groupingSets); COPY_NODE_FIELD(havingQual); COPY_NODE_FIELD(windowClause); @@ -3221,6 +3222,7 @@ _copySelectStmt(const SelectStmt *from) COPY_NODE_FIELD(fromClause); COPY_NODE_FIELD(whereClause); COPY_NODE_FIELD(groupClause); + COPY_SCALAR_FIELD(groupDistinct); COPY_NODE_FIELD(havingClause); COPY_NODE_FIELD(windowClause); COPY_NODE_FIELD(valuesLists); diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index c2d73626fcc..bc5e9e52fe4 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -977,6 +977,7 @@ _equalQuery(const Query *a, const Query *b) COMPARE_NODE_FIELD(onConflict); COMPARE_NODE_FIELD(returningList); COMPARE_NODE_FIELD(groupClause); + COMPARE_SCALAR_FIELD(groupDistinct); COMPARE_NODE_FIELD(groupingSets); COMPARE_NODE_FIELD(havingQual); COMPARE_NODE_FIELD(windowClause); @@ -1053,6 +1054,7 @@ _equalSelectStmt(const SelectStmt *a, const SelectStmt *b) COMPARE_NODE_FIELD(fromClause); COMPARE_NODE_FIELD(whereClause); COMPARE_NODE_FIELD(groupClause); + COMPARE_SCALAR_FIELD(groupDistinct); COMPARE_NODE_FIELD(havingClause); COMPARE_NODE_FIELD(windowClause); COMPARE_NODE_FIELD(valuesLists); diff --git a/src/backend/nodes/list.c b/src/backend/nodes/list.c index dbf6b30233a..94fb236dafe 100644 --- a/src/backend/nodes/list.c +++ b/src/backend/nodes/list.c @@ -1507,6 +1507,22 @@ list_sort(List *list, list_sort_comparator cmp) } /* + * list_sort comparator for sorting a list into ascending int order. + */ +int +list_int_cmp(const ListCell *p1, const ListCell *p2) +{ + int v1 = lfirst_int(p1); + int v2 = lfirst_int(p2); + + if (v1 < v2) + return -1; + if (v1 > v2) + return 1; + return 0; +} + +/* * list_sort comparator for sorting a list into ascending OID order. */ int diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 6493a03ff80..5054490c58f 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -2771,6 +2771,7 @@ _outSelectStmt(StringInfo str, const SelectStmt *node) WRITE_NODE_FIELD(fromClause); WRITE_NODE_FIELD(whereClause); WRITE_NODE_FIELD(groupClause); + WRITE_BOOL_FIELD(groupDistinct); WRITE_NODE_FIELD(havingClause); WRITE_NODE_FIELD(windowClause); WRITE_NODE_FIELD(valuesLists); @@ -2996,6 +2997,7 @@ _outQuery(StringInfo str, const Query *node) WRITE_NODE_FIELD(onConflict); WRITE_NODE_FIELD(returningList); WRITE_NODE_FIELD(groupClause); + WRITE_BOOL_FIELD(groupDistinct); WRITE_NODE_FIELD(groupingSets); WRITE_NODE_FIELD(havingQual); WRITE_NODE_FIELD(windowClause); diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index c5e136e9c3c..9b8f81c5231 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -271,6 +271,7 @@ _readQuery(void) READ_NODE_FIELD(onConflict); READ_NODE_FIELD(returningList); READ_NODE_FIELD(groupClause); + READ_BOOL_FIELD(groupDistinct); READ_NODE_FIELD(groupingSets); READ_NODE_FIELD(havingQual); READ_NODE_FIELD(windowClause); |
