aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeResult.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2000-08-24 03:29:15 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2000-08-24 03:29:15 +0000
commit782c16c6a154e760bf1608d633488538cd52da93 (patch)
tree902da787593da21a979bd2f74b0b44acf9c427b0 /src/backend/executor/nodeResult.c
parent87523ab8db34859ae3fb980a3fab9f29dfc4c97a (diff)
downloadpostgresql-782c16c6a154e760bf1608d633488538cd52da93.tar.gz
postgresql-782c16c6a154e760bf1608d633488538cd52da93.zip
SQL-language functions are now callable in ordinary fmgr contexts ...
for example, an SQL function can be used in a functional index. (I make no promises about speed, but it'll work ;-).) Clean up and simplify handling of functions returning sets.
Diffstat (limited to 'src/backend/executor/nodeResult.c')
-rw-r--r--src/backend/executor/nodeResult.c39
1 files changed, 22 insertions, 17 deletions
diff --git a/src/backend/executor/nodeResult.c b/src/backend/executor/nodeResult.c
index 770cc47ccc4..e36037de710 100644
--- a/src/backend/executor/nodeResult.c
+++ b/src/backend/executor/nodeResult.c
@@ -34,7 +34,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeResult.c,v 1.15 2000/07/17 03:04:53 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeResult.c,v 1.16 2000/08/24 03:29:03 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -67,8 +67,7 @@ ExecResult(Result *node)
TupleTableSlot *resultSlot;
Plan *outerPlan;
ExprContext *econtext;
- bool isDone;
- ProjectionInfo *projInfo;
+ ExprDoneCond isDone;
/* ----------------
* initialize the result node's state
@@ -78,13 +77,6 @@ ExecResult(Result *node)
econtext = resstate->cstate.cs_ExprContext;
/* ----------------
- * Reset per-tuple memory context to free any expression evaluation
- * storage allocated in the previous tuple cycle.
- * ----------------
- */
- ResetExprContext(econtext);
-
- /* ----------------
* check constant qualifications like (2 > 1), if not already done
* ----------------
*/
@@ -111,20 +103,28 @@ ExecResult(Result *node)
if (resstate->cstate.cs_TupFromTlist)
{
resultSlot = ExecProject(resstate->cstate.cs_ProjInfo, &isDone);
- if (!isDone)
+ if (isDone == ExprMultipleResult)
return resultSlot;
/* Done with that source tuple... */
resstate->cstate.cs_TupFromTlist = false;
}
/* ----------------
+ * Reset per-tuple memory context to free any expression evaluation
+ * storage allocated in the previous tuple cycle. Note this can't
+ * happen until we're done projecting out tuples from a scan tuple.
+ * ----------------
+ */
+ ResetExprContext(econtext);
+
+ /* ----------------
* if rs_done is true then it means that we were asked to return
* a constant tuple and we already did the last time ExecResult()
* was called, OR that we failed the constant qual check.
* Either way, now we are through.
* ----------------
*/
- if (!resstate->rs_done)
+ while (!resstate->rs_done)
{
outerPlan = outerPlan(node);
@@ -159,13 +159,18 @@ ExecResult(Result *node)
}
/* ----------------
- * form the result tuple using ExecProject(), and return it.
+ * form the result tuple using ExecProject(), and return it
+ * --- unless the projection produces an empty set, in which case
+ * we must loop back to see if there are more outerPlan tuples.
* ----------------
*/
- projInfo = resstate->cstate.cs_ProjInfo;
- resultSlot = ExecProject(projInfo, &isDone);
- resstate->cstate.cs_TupFromTlist = !isDone;
- return resultSlot;
+ resultSlot = ExecProject(resstate->cstate.cs_ProjInfo, &isDone);
+
+ if (isDone != ExprEndResult)
+ {
+ resstate->cstate.cs_TupFromTlist = (isDone == ExprMultipleResult);
+ return resultSlot;
+ }
}
return NULL;