From a26c7e3d71d65381bc60b0d0b30f03cd738fb0e9 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 8 Sep 2008 00:22:56 +0000 Subject: 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. --- src/backend/executor/nodeGroup.c | 41 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) (limited to 'src/backend/executor/nodeGroup.c') 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 $ * *------------------------------------------------------------------------- */ @@ -49,6 +49,23 @@ ExecGroup(GroupState *node) numCols = ((Group *) node->ss.ps.plan)->numCols; 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. */ @@ -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; + } } } -- cgit v1.2.3