diff options
Diffstat (limited to 'src/backend/nodes')
-rw-r--r-- | src/backend/nodes/copyfuncs.c | 38 | ||||
-rw-r--r-- | src/backend/nodes/equalfuncs.c | 32 | ||||
-rw-r--r-- | src/backend/nodes/list.c | 26 | ||||
-rw-r--r-- | src/backend/nodes/makefuncs.c | 15 | ||||
-rw-r--r-- | src/backend/nodes/nodeFuncs.c | 51 | ||||
-rw-r--r-- | src/backend/nodes/outfuncs.c | 32 | ||||
-rw-r--r-- | src/backend/nodes/readfuncs.c | 37 |
7 files changed, 231 insertions, 0 deletions
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index bdc7e61935c..fa7d2865c1e 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -839,6 +839,8 @@ _copyAgg(const Agg *from) COPY_POINTER_FIELD(grpOperators, from->numCols * sizeof(Oid)); } COPY_SCALAR_FIELD(numGroups); + COPY_NODE_FIELD(groupingSets); + COPY_NODE_FIELD(chain); return newnode; } @@ -1209,6 +1211,23 @@ _copyAggref(const Aggref *from) } /* + * _copyGroupingFunc + */ +static GroupingFunc * +_copyGroupingFunc(const GroupingFunc *from) +{ + GroupingFunc *newnode = makeNode(GroupingFunc); + + COPY_NODE_FIELD(args); + COPY_NODE_FIELD(refs); + COPY_NODE_FIELD(cols); + COPY_SCALAR_FIELD(agglevelsup); + COPY_LOCATION_FIELD(location); + + return newnode; +} + +/* * _copyWindowFunc */ static WindowFunc * @@ -2152,6 +2171,18 @@ _copySortGroupClause(const SortGroupClause *from) return newnode; } +static GroupingSet * +_copyGroupingSet(const GroupingSet *from) +{ + GroupingSet *newnode = makeNode(GroupingSet); + + COPY_SCALAR_FIELD(kind); + COPY_NODE_FIELD(content); + COPY_LOCATION_FIELD(location); + + return newnode; +} + static WindowClause * _copyWindowClause(const WindowClause *from) { @@ -2676,6 +2707,7 @@ _copyQuery(const Query *from) COPY_NODE_FIELD(onConflict); COPY_NODE_FIELD(returningList); COPY_NODE_FIELD(groupClause); + COPY_NODE_FIELD(groupingSets); COPY_NODE_FIELD(havingQual); COPY_NODE_FIELD(windowClause); COPY_NODE_FIELD(distinctClause); @@ -4309,6 +4341,9 @@ copyObject(const void *from) case T_Aggref: retval = _copyAggref(from); break; + case T_GroupingFunc: + retval = _copyGroupingFunc(from); + break; case T_WindowFunc: retval = _copyWindowFunc(from); break; @@ -4878,6 +4913,9 @@ copyObject(const void *from) case T_SortGroupClause: retval = _copySortGroupClause(from); break; + case T_GroupingSet: + retval = _copyGroupingSet(from); + break; case T_WindowClause: retval = _copyWindowClause(from); break; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index d483221fb7a..d7928a99176 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -208,6 +208,21 @@ _equalAggref(const Aggref *a, const Aggref *b) } static bool +_equalGroupingFunc(const GroupingFunc *a, const GroupingFunc *b) +{ + COMPARE_NODE_FIELD(args); + + /* + * We must not compare the refs or cols field + */ + + COMPARE_SCALAR_FIELD(agglevelsup); + COMPARE_LOCATION_FIELD(location); + + return true; +} + +static bool _equalWindowFunc(const WindowFunc *a, const WindowFunc *b) { COMPARE_SCALAR_FIELD(winfnoid); @@ -896,6 +911,7 @@ _equalQuery(const Query *a, const Query *b) COMPARE_NODE_FIELD(onConflict); COMPARE_NODE_FIELD(returningList); COMPARE_NODE_FIELD(groupClause); + COMPARE_NODE_FIELD(groupingSets); COMPARE_NODE_FIELD(havingQual); COMPARE_NODE_FIELD(windowClause); COMPARE_NODE_FIELD(distinctClause); @@ -2427,6 +2443,16 @@ _equalSortGroupClause(const SortGroupClause *a, const SortGroupClause *b) } static bool +_equalGroupingSet(const GroupingSet *a, const GroupingSet *b) +{ + COMPARE_SCALAR_FIELD(kind); + COMPARE_NODE_FIELD(content); + COMPARE_LOCATION_FIELD(location); + + return true; +} + +static bool _equalWindowClause(const WindowClause *a, const WindowClause *b) { COMPARE_STRING_FIELD(name); @@ -2693,6 +2719,9 @@ equal(const void *a, const void *b) case T_Aggref: retval = _equalAggref(a, b); break; + case T_GroupingFunc: + retval = _equalGroupingFunc(a, b); + break; case T_WindowFunc: retval = _equalWindowFunc(a, b); break; @@ -3249,6 +3278,9 @@ equal(const void *a, const void *b) case T_SortGroupClause: retval = _equalSortGroupClause(a, b); break; + case T_GroupingSet: + retval = _equalGroupingSet(a, b); + break; case T_WindowClause: retval = _equalWindowClause(a, b); break; diff --git a/src/backend/nodes/list.c b/src/backend/nodes/list.c index 94cab476eb0..a6737514ef1 100644 --- a/src/backend/nodes/list.c +++ b/src/backend/nodes/list.c @@ -823,6 +823,32 @@ list_intersection(const List *list1, const List *list2) } /* + * As list_intersection but operates on lists of integers. + */ +List * +list_intersection_int(const List *list1, const List *list2) +{ + List *result; + const ListCell *cell; + + if (list1 == NIL || list2 == NIL) + return NIL; + + Assert(IsIntegerList(list1)); + Assert(IsIntegerList(list2)); + + result = NIL; + foreach(cell, list1) + { + if (list_member_int(list2, lfirst_int(cell))) + result = lappend_int(result, lfirst_int(cell)); + } + + check_list_invariants(result); + return result; +} + +/* * Return a list that contains all the cells in list1 that are not in * list2. The returned list is freshly allocated via palloc(), but the * cells themselves point to the same objects as the cells of the diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c index 6fdf44d5736..a9b58eb31fc 100644 --- a/src/backend/nodes/makefuncs.c +++ b/src/backend/nodes/makefuncs.c @@ -554,3 +554,18 @@ makeFuncCall(List *name, List *args, int location) n->location = location; return n; } + +/* + * makeGroupingSet + * + */ +GroupingSet * +makeGroupingSet(GroupingSetKind kind, List *content, int location) +{ + GroupingSet *n = makeNode(GroupingSet); + + n->kind = kind; + n->content = content; + n->location = location; + return n; +} diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c index 42d62d32d93..41763931339 100644 --- a/src/backend/nodes/nodeFuncs.c +++ b/src/backend/nodes/nodeFuncs.c @@ -54,6 +54,9 @@ exprType(const Node *expr) case T_Aggref: type = ((const Aggref *) expr)->aggtype; break; + case T_GroupingFunc: + type = INT4OID; + break; case T_WindowFunc: type = ((const WindowFunc *) expr)->wintype; break; @@ -750,6 +753,9 @@ exprCollation(const Node *expr) case T_Aggref: coll = ((const Aggref *) expr)->aggcollid; break; + case T_GroupingFunc: + coll = InvalidOid; + break; case T_WindowFunc: coll = ((const WindowFunc *) expr)->wincollid; break; @@ -986,6 +992,9 @@ exprSetCollation(Node *expr, Oid collation) case T_Aggref: ((Aggref *) expr)->aggcollid = collation; break; + case T_GroupingFunc: + Assert(!OidIsValid(collation)); + break; case T_WindowFunc: ((WindowFunc *) expr)->wincollid = collation; break; @@ -1202,6 +1211,9 @@ exprLocation(const Node *expr) /* function name should always be the first thing */ loc = ((const Aggref *) expr)->location; break; + case T_GroupingFunc: + loc = ((const GroupingFunc *) expr)->location; + break; case T_WindowFunc: /* function name should always be the first thing */ loc = ((const WindowFunc *) expr)->location; @@ -1491,6 +1503,9 @@ exprLocation(const Node *expr) /* XMLSERIALIZE keyword should always be the first thing */ loc = ((const XmlSerialize *) expr)->location; break; + case T_GroupingSet: + loc = ((const GroupingSet *) expr)->location; + break; case T_WithClause: loc = ((const WithClause *) expr)->location; break; @@ -1685,6 +1700,15 @@ expression_tree_walker(Node *node, return true; } break; + case T_GroupingFunc: + { + GroupingFunc *grouping = (GroupingFunc *) node; + + if (expression_tree_walker((Node *) grouping->args, + walker, context)) + return true; + } + break; case T_WindowFunc: { WindowFunc *expr = (WindowFunc *) node; @@ -2243,6 +2267,29 @@ expression_tree_mutator(Node *node, return (Node *) newnode; } break; + case T_GroupingFunc: + { + GroupingFunc *grouping = (GroupingFunc *) node; + GroupingFunc *newnode; + + FLATCOPY(newnode, grouping, GroupingFunc); + MUTATE(newnode->args, grouping->args, List *); + + /* + * We assume here that mutating the arguments does not change + * the semantics, i.e. that the arguments are not mutated in a + * way that makes them semantically different from their + * previously matching expressions in the GROUP BY clause. + * + * If a mutator somehow wanted to do this, it would have to + * handle the refs and cols lists itself as appropriate. + */ + newnode->refs = list_copy(grouping->refs); + newnode->cols = list_copy(grouping->cols); + + return (Node *) newnode; + } + break; case T_WindowFunc: { WindowFunc *wfunc = (WindowFunc *) node; @@ -2962,6 +3009,8 @@ raw_expression_tree_walker(Node *node, break; case T_RangeVar: return walker(((RangeVar *) node)->alias, context); + case T_GroupingFunc: + return walker(((GroupingFunc *) node)->args, context); case T_SubLink: { SubLink *sublink = (SubLink *) node; @@ -3287,6 +3336,8 @@ raw_expression_tree_walker(Node *node, /* for now, constraints are ignored */ } break; + case T_GroupingSet: + return walker(((GroupingSet *) node)->content, context); case T_LockingClause: return walker(((LockingClause *) node)->lockedRels, context); case T_XmlSerialize: diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 7918553da0a..66fee3ef61d 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -679,6 +679,9 @@ _outAgg(StringInfo str, const Agg *node) appendStringInfo(str, " %u", node->grpOperators[i]); WRITE_LONG_FIELD(numGroups); + + WRITE_NODE_FIELD(groupingSets); + WRITE_NODE_FIELD(chain); } static void @@ -1004,6 +1007,18 @@ _outAggref(StringInfo str, const Aggref *node) } static void +_outGroupingFunc(StringInfo str, const GroupingFunc *node) +{ + WRITE_NODE_TYPE("GROUPINGFUNC"); + + WRITE_NODE_FIELD(args); + WRITE_NODE_FIELD(refs); + WRITE_NODE_FIELD(cols); + WRITE_INT_FIELD(agglevelsup); + WRITE_LOCATION_FIELD(location); +} + +static void _outWindowFunc(StringInfo str, const WindowFunc *node) { WRITE_NODE_TYPE("WINDOWFUNC"); @@ -2364,6 +2379,7 @@ _outQuery(StringInfo str, const Query *node) WRITE_NODE_FIELD(onConflict); WRITE_NODE_FIELD(returningList); WRITE_NODE_FIELD(groupClause); + WRITE_NODE_FIELD(groupingSets); WRITE_NODE_FIELD(havingQual); WRITE_NODE_FIELD(windowClause); WRITE_NODE_FIELD(distinctClause); @@ -2399,6 +2415,16 @@ _outSortGroupClause(StringInfo str, const SortGroupClause *node) } static void +_outGroupingSet(StringInfo str, const GroupingSet *node) +{ + WRITE_NODE_TYPE("GROUPINGSET"); + + WRITE_ENUM_FIELD(kind, GroupingSetKind); + WRITE_NODE_FIELD(content); + WRITE_LOCATION_FIELD(location); +} + +static void _outWindowClause(StringInfo str, const WindowClause *node) { WRITE_NODE_TYPE("WINDOWCLAUSE"); @@ -3087,6 +3113,9 @@ _outNode(StringInfo str, const void *obj) case T_Aggref: _outAggref(str, obj); break; + case T_GroupingFunc: + _outGroupingFunc(str, obj); + break; case T_WindowFunc: _outWindowFunc(str, obj); break; @@ -3349,6 +3378,9 @@ _outNode(StringInfo str, const void *obj) case T_SortGroupClause: _outSortGroupClause(str, obj); break; + case T_GroupingSet: + _outGroupingSet(str, obj); + break; case T_WindowClause: _outWindowClause(str, obj); break; diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index c8fb894a75a..6fd9d46ee79 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -217,6 +217,7 @@ _readQuery(void) READ_NODE_FIELD(onConflict); READ_NODE_FIELD(returningList); READ_NODE_FIELD(groupClause); + READ_NODE_FIELD(groupingSets); READ_NODE_FIELD(havingQual); READ_NODE_FIELD(windowClause); READ_NODE_FIELD(distinctClause); @@ -293,6 +294,21 @@ _readSortGroupClause(void) } /* + * _readGroupingSet + */ +static GroupingSet * +_readGroupingSet(void) +{ + READ_LOCALS(GroupingSet); + + READ_ENUM_FIELD(kind, GroupingSetKind); + READ_NODE_FIELD(content); + READ_LOCATION_FIELD(location); + + READ_DONE(); +} + +/* * _readWindowClause */ static WindowClause * @@ -552,6 +568,23 @@ _readAggref(void) } /* + * _readGroupingFunc + */ +static GroupingFunc * +_readGroupingFunc(void) +{ + READ_LOCALS(GroupingFunc); + + READ_NODE_FIELD(args); + READ_NODE_FIELD(refs); + READ_NODE_FIELD(cols); + READ_INT_FIELD(agglevelsup); + READ_LOCATION_FIELD(location); + + READ_DONE(); +} + +/* * _readWindowFunc */ static WindowFunc * @@ -1386,6 +1419,8 @@ parseNodeString(void) return_value = _readWithCheckOption(); else if (MATCH("SORTGROUPCLAUSE", 15)) return_value = _readSortGroupClause(); + else if (MATCH("GROUPINGSET", 11)) + return_value = _readGroupingSet(); else if (MATCH("WINDOWCLAUSE", 12)) return_value = _readWindowClause(); else if (MATCH("ROWMARKCLAUSE", 13)) @@ -1412,6 +1447,8 @@ parseNodeString(void) return_value = _readParam(); else if (MATCH("AGGREF", 6)) return_value = _readAggref(); + else if (MATCH("GROUPINGFUNC", 12)) + return_value = _readGroupingFunc(); else if (MATCH("WINDOWFUNC", 10)) return_value = _readWindowFunc(); else if (MATCH("ARRAYREF", 8)) |