aboutsummaryrefslogtreecommitdiff
path: root/src/backend/nodes
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/nodes')
-rw-r--r--src/backend/nodes/copyfuncs.c38
-rw-r--r--src/backend/nodes/equalfuncs.c32
-rw-r--r--src/backend/nodes/list.c26
-rw-r--r--src/backend/nodes/makefuncs.c15
-rw-r--r--src/backend/nodes/nodeFuncs.c51
-rw-r--r--src/backend/nodes/outfuncs.c32
-rw-r--r--src/backend/nodes/readfuncs.c37
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))