aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/execScan.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/execScan.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/execScan.c')
-rw-r--r--src/backend/executor/execScan.c60
1 files changed, 29 insertions, 31 deletions
diff --git a/src/backend/executor/execScan.c b/src/backend/executor/execScan.c
index a3f66d20cad..d000a4cf50a 100644
--- a/src/backend/executor/execScan.c
+++ b/src/backend/executor/execScan.c
@@ -12,7 +12,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execScan.c,v 1.13 2000/07/17 03:04:53 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execScan.c,v 1.14 2000/08/24 03:29:03 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -50,11 +50,10 @@ ExecScan(Scan *node,
{
CommonScanState *scanstate;
EState *estate;
+ ExprContext *econtext;
List *qual;
- bool isDone;
+ ExprDoneCond isDone;
TupleTableSlot *resultSlot;
- ExprContext *econtext;
- ProjectionInfo *projInfo;
/* ----------------
* Fetch data from node
@@ -66,13 +65,6 @@ ExecScan(Scan *node,
qual = node->plan.qual;
/* ----------------
- * Reset per-tuple memory context to free any expression evaluation
- * storage allocated in the previous tuple cycle.
- * ----------------
- */
- ResetExprContext(econtext);
-
- /* ----------------
* Check to see if we're still projecting out tuples from a previous
* scan tuple (because there is a function-returning-set in the
* projection expressions). If so, try to project another one.
@@ -80,14 +72,21 @@ ExecScan(Scan *node,
*/
if (scanstate->cstate.cs_TupFromTlist)
{
- projInfo = scanstate->cstate.cs_ProjInfo;
- resultSlot = ExecProject(projInfo, &isDone);
- if (!isDone)
+ resultSlot = ExecProject(scanstate->cstate.cs_ProjInfo, &isDone);
+ if (isDone == ExprMultipleResult)
return resultSlot;
/* Done with that source tuple... */
scanstate->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);
+
/*
* get a tuple from the access method loop until we obtain a tuple
* which passes the qualification.
@@ -121,8 +120,6 @@ ExecScan(Scan *node,
/* ----------------
* check that the current tuple satisfies the qual-clause
- * if our qualification succeeds then we may
- * leave the loop.
*
* check for non-nil qual here to avoid a function call to
* ExecQual() when the qual is nil ... saves only a few cycles,
@@ -130,7 +127,22 @@ ExecScan(Scan *node,
* ----------------
*/
if (!qual || ExecQual(qual, econtext, false))
- break;
+ {
+ /* ----------------
+ * Found a satisfactory scan tuple.
+ *
+ * Form a projection tuple, store it in the result tuple
+ * slot and return it --- unless we find we can project no
+ * tuples from this scan tuple, in which case continue scan.
+ * ----------------
+ */
+ resultSlot = ExecProject(scanstate->cstate.cs_ProjInfo, &isDone);
+ if (isDone != ExprEndResult)
+ {
+ scanstate->cstate.cs_TupFromTlist = (isDone == ExprMultipleResult);
+ return resultSlot;
+ }
+ }
/* ----------------
* Tuple fails qual, so free per-tuple memory and try again.
@@ -138,18 +150,4 @@ ExecScan(Scan *node,
*/
ResetExprContext(econtext);
}
-
- /* ----------------
- * Found a satisfactory scan tuple.
- *
- * Form a projection tuple, store it in the result tuple
- * slot and return it.
- * ----------------
- */
- projInfo = scanstate->cstate.cs_ProjInfo;
-
- resultSlot = ExecProject(projInfo, &isDone);
- scanstate->cstate.cs_TupFromTlist = !isDone;
-
- return resultSlot;
}