aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeGroup.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2008-09-08 00:22:56 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2008-09-08 00:22:56 +0000
commita26c7e3d71d65381bc60b0d0b30f03cd738fb0e9 (patch)
tree40b2c5d312c2c99cc1d52af323e652036a79ac2e /src/backend/executor/nodeGroup.c
parent8818f3793e88e183e8eaff21fbb6762e6e73f663 (diff)
downloadpostgresql-a26c7e3d71d65381bc60b0d0b30f03cd738fb0e9.tar.gz
postgresql-a26c7e3d71d65381bc60b0d0b30f03cd738fb0e9.zip
Support set-returning functions in the target lists of Agg and Group plan
nodes. This is a pretty ugly feature but since we don't yet have a plausible substitute, we'd better support it everywhere. Per gripe from Jeff Davis.
Diffstat (limited to 'src/backend/executor/nodeGroup.c')
-rw-r--r--src/backend/executor/nodeGroup.c41
1 files changed, 38 insertions, 3 deletions
diff --git a/src/backend/executor/nodeGroup.c b/src/backend/executor/nodeGroup.c
index 414e0b93f70..31566f1fb52 100644
--- a/src/backend/executor/nodeGroup.c
+++ b/src/backend/executor/nodeGroup.c
@@ -15,7 +15,7 @@
* locate group boundaries.
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/nodeGroup.c,v 1.70 2008/01/01 19:45:49 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/nodeGroup.c,v 1.71 2008/09/08 00:22:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -50,6 +50,23 @@ ExecGroup(GroupState *node)
grpColIdx = ((Group *) node->ss.ps.plan)->grpColIdx;
/*
+ * Check to see if we're still projecting out tuples from a previous group
+ * tuple (because there is a function-returning-set in the projection
+ * expressions). If so, try to project another one.
+ */
+ if (node->ss.ps.ps_TupFromTlist)
+ {
+ TupleTableSlot *result;
+ ExprDoneCond isDone;
+
+ result = ExecProject(node->ss.ps.ps_ProjInfo, &isDone);
+ if (isDone == ExprMultipleResult)
+ return result;
+ /* Done with that source tuple... */
+ node->ss.ps.ps_TupFromTlist = false;
+ }
+
+ /*
* The ScanTupleSlot holds the (copied) first tuple of each group.
*/
firsttupleslot = node->ss.ss_ScanTupleSlot;
@@ -90,7 +107,16 @@ ExecGroup(GroupState *node)
/*
* Form and return a projection tuple using the first input tuple.
*/
- return ExecProject(node->ss.ps.ps_ProjInfo, NULL);
+ TupleTableSlot *result;
+ ExprDoneCond isDone;
+
+ result = ExecProject(node->ss.ps.ps_ProjInfo, &isDone);
+
+ if (isDone != ExprEndResult)
+ {
+ node->ss.ps.ps_TupFromTlist = (isDone == ExprMultipleResult);
+ return result;
+ }
}
}
@@ -142,7 +168,16 @@ ExecGroup(GroupState *node)
/*
* Form and return a projection tuple using the first input tuple.
*/
- return ExecProject(node->ss.ps.ps_ProjInfo, NULL);
+ TupleTableSlot *result;
+ ExprDoneCond isDone;
+
+ result = ExecProject(node->ss.ps.ps_ProjInfo, &isDone);
+
+ if (isDone != ExprEndResult)
+ {
+ node->ss.ps.ps_TupFromTlist = (isDone == ExprMultipleResult);
+ return result;
+ }
}
}