aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor')
-rw-r--r--src/backend/executor/execMain.c102
-rw-r--r--src/backend/executor/functions.c14
-rw-r--r--src/backend/executor/spi.c60
3 files changed, 74 insertions, 102 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 6e1145ac779..18b81849ac9 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -19,7 +19,7 @@
* query plan and ExecutorEnd() should always be called at the end of
* execution of a plan.
*
- * ExecutorRun accepts 'feature' and 'count' arguments that specify whether
+ * ExecutorRun accepts direction and count arguments that specify whether
* the plan is to be executed forwards, backwards, and for how many tuples.
*
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
@@ -27,7 +27,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.149 2001/10/25 05:49:27 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.150 2002/02/27 19:34:48 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -88,7 +88,7 @@ static void ExecCheckRTEPerms(RangeTblEntry *rte, CmdType operation);
* query plan
*
* returns a TupleDesc which describes the attributes of the tuples to
- * be returned by the query.
+ * be returned by the query. (Same value is saved in queryDesc)
*
* NB: the CurrentMemoryContext when this is called must be the context
* to be used as the per-query context for the query plan. ExecutorRun()
@@ -137,6 +137,8 @@ ExecutorStart(QueryDesc *queryDesc, EState *estate)
queryDesc->plantree,
estate);
+ queryDesc->tupDesc = result;
+
return result;
}
@@ -149,25 +151,23 @@ ExecutorStart(QueryDesc *queryDesc, EState *estate)
*
* ExecutorStart must have been called already.
*
- * the different features supported are:
- * EXEC_RUN: retrieve all tuples in the forward direction
- * EXEC_FOR: retrieve 'count' number of tuples in the forward dir
- * EXEC_BACK: retrieve 'count' number of tuples in the backward dir
- * EXEC_RETONE: return one tuple but don't 'retrieve' it
- * used in postquel function processing
+ * If direction is NoMovementScanDirection then nothing is done
+ * except to start up/shut down the destination. Otherwise,
+ * we retrieve up to 'count' tuples in the specified direction.
*
* Note: count = 0 is interpreted as "no limit".
*
* ----------------------------------------------------------------
*/
TupleTableSlot *
-ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature, long count)
+ExecutorRun(QueryDesc *queryDesc, EState *estate,
+ ScanDirection direction, long count)
{
CmdType operation;
Plan *plan;
- TupleTableSlot *result;
CommandDest dest;
DestReceiver *destfunc;
+ TupleTableSlot *result;
/*
* sanity checks
@@ -181,69 +181,33 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature, long count)
operation = queryDesc->operation;
plan = queryDesc->plantree;
dest = queryDesc->dest;
- destfunc = DestToFunction(dest);
- estate->es_processed = 0;
- estate->es_lastoid = InvalidOid;
/*
- * FIXME: the dest setup function ought to be handed the tuple desc
- * for the tuples to be output, but I'm not quite sure how to get that
- * info at this point. For now, passing NULL is OK because no
- * existing dest setup function actually uses the pointer.
+ * startup tuple receiver
*/
- (*destfunc->setup) (destfunc, (TupleDesc) NULL);
-
- switch (feature)
- {
- case EXEC_RUN:
- result = ExecutePlan(estate,
- plan,
- operation,
- count,
- ForwardScanDirection,
- destfunc);
- break;
-
- case EXEC_FOR:
- result = ExecutePlan(estate,
- plan,
- operation,
- count,
- ForwardScanDirection,
- destfunc);
- break;
-
- /*
- * retrieve next n "backward" tuples
- */
- case EXEC_BACK:
- result = ExecutePlan(estate,
- plan,
- operation,
- count,
- BackwardScanDirection,
- destfunc);
- break;
+ estate->es_processed = 0;
+ estate->es_lastoid = InvalidOid;
- /*
- * return one tuple but don't "retrieve" it. (this is used by
- * the rule manager..) -cim 9/14/89
- */
- case EXEC_RETONE:
- result = ExecutePlan(estate,
- plan,
- operation,
- ONE_TUPLE,
- ForwardScanDirection,
- destfunc);
- break;
+ destfunc = DestToFunction(dest);
+ (*destfunc->setup) (destfunc, (int) operation,
+ queryDesc->portalName, queryDesc->tupDesc);
- default:
- elog(DEBUG, "ExecutorRun: Unknown feature %d", feature);
- result = NULL;
- break;
- }
+ /*
+ * run plan
+ */
+ if (direction == NoMovementScanDirection)
+ result = NULL;
+ else
+ result = ExecutePlan(estate,
+ plan,
+ operation,
+ count,
+ direction,
+ destfunc);
+ /*
+ * shutdown receiver
+ */
(*destfunc->cleanup) (destfunc);
return result;
@@ -916,7 +880,7 @@ EndPlan(Plan *plan, EState *estate)
*
* processes the query plan to retrieve 'numberTuples' tuples in the
* direction specified.
- * Retrieves all tuples if tupleCount is 0
+ * Retrieves all tuples if numberTuples is 0
*
* result is either a slot containing the last tuple in the case
* of a RETRIEVE or NULL otherwise.
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c
index c38b8077f52..885d93a2aff 100644
--- a/src/backend/executor/functions.c
+++ b/src/backend/executor/functions.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.48 2002/02/26 22:47:05 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.49 2002/02/27 19:34:51 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -111,9 +111,8 @@ init_execution_state(char *src, Oid *argOidVect, int nargs)
nextes->next = NULL;
nextes->status = F_EXEC_START;
- nextes->qd = CreateQueryDesc(queryTree,
- planTree,
- None);
+
+ nextes->qd = CreateQueryDesc(queryTree, planTree, None, NULL);
estate = CreateExecutorState();
if (nargs > 0)
@@ -268,7 +267,7 @@ postquel_start(execution_state *es)
static TupleTableSlot *
postquel_getnext(execution_state *es)
{
- int feature;
+ long count;
if (es->qd->operation == CMD_UTILITY)
{
@@ -281,9 +280,10 @@ postquel_getnext(execution_state *es)
return (TupleTableSlot *) NULL;
}
- feature = (LAST_POSTQUEL_COMMAND(es)) ? EXEC_RETONE : EXEC_RUN;
+ /* If it's not the last command, just run it to completion */
+ count = (LAST_POSTQUEL_COMMAND(es)) ? 1L : 0L;
- return ExecutorRun(es->qd, es->estate, feature, 0L);
+ return ExecutorRun(es->qd, es->estate, ForwardScanDirection, count);
}
static void
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
index 05044d6cd39..c8c65b1cee4 100644
--- a/src/backend/executor/spi.c
+++ b/src/backend/executor/spi.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.66 2002/02/26 22:47:05 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.67 2002/02/27 19:34:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -779,7 +779,7 @@ SPI_cursor_open(char *name, void *plan, Datum *Values, char *Nulls)
queryTree->isBinary = false;
/* Create the QueryDesc object and the executor state */
- queryDesc = CreateQueryDesc(queryTree, planTree, SPI);
+ queryDesc = CreateQueryDesc(queryTree, planTree, SPI, NULL);
eState = CreateExecutorState();
/* If the plan has parameters, put them into the executor state */
@@ -1023,7 +1023,7 @@ _SPI_execute(char *src, int tcount, _SPI_plan *plan)
else if (plan == NULL)
{
qdesc = CreateQueryDesc(queryTree, planTree,
- islastquery ? SPI : None);
+ islastquery ? SPI : None, NULL);
state = CreateExecutorState();
res = _SPI_pquery(qdesc, state, islastquery ? tcount : 0);
if (res < 0 || islastquery)
@@ -1033,7 +1033,7 @@ _SPI_execute(char *src, int tcount, _SPI_plan *plan)
else
{
qdesc = CreateQueryDesc(queryTree, planTree,
- islastquery ? SPI : None);
+ islastquery ? SPI : None, NULL);
res = _SPI_pquery(qdesc, NULL, islastquery ? tcount : 0);
if (res < 0)
return res;
@@ -1094,7 +1094,7 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, char *Nulls, int tcount)
else
{
qdesc = CreateQueryDesc(queryTree, planTree,
- islastquery ? SPI : None);
+ islastquery ? SPI : None, NULL);
state = CreateExecutorState();
if (nargs > 0)
{
@@ -1132,7 +1132,6 @@ _SPI_pquery(QueryDesc *queryDesc, EState *state, int tcount)
Query *parseTree = queryDesc->parsetree;
int operation = queryDesc->operation;
CommandDest dest = queryDesc->dest;
- TupleDesc tupdesc;
bool isRetrieveIntoPortal = false;
bool isRetrieveIntoRelation = false;
char *intoName = NULL;
@@ -1174,11 +1173,13 @@ _SPI_pquery(QueryDesc *queryDesc, EState *state, int tcount)
if (state == NULL) /* plan preparation */
return res;
+
#ifdef SPI_EXECUTOR_STATS
if (ShowExecutorStats)
ResetUsage();
#endif
- tupdesc = ExecutorStart(queryDesc, state);
+
+ ExecutorStart(queryDesc, state);
/*
* Don't work currently --- need to rearrange callers so that we
@@ -1188,7 +1189,7 @@ _SPI_pquery(QueryDesc *queryDesc, EState *state, int tcount)
if (isRetrieveIntoPortal)
elog(FATAL, "SPI_select: retrieve into portal not implemented");
- ExecutorRun(queryDesc, state, EXEC_FOR, (long) tcount);
+ ExecutorRun(queryDesc, state, ForwardScanDirection, (long) tcount);
_SPI_current->processed = state->es_processed;
save_lastoid = state->es_lastoid;
@@ -1230,6 +1231,7 @@ _SPI_cursor_operation(Portal portal, bool forward, int count,
QueryDesc *querydesc;
EState *estate;
MemoryContext oldcontext;
+ ScanDirection direction;
CommandId savedId;
CommandDest olddest;
@@ -1268,29 +1270,35 @@ _SPI_cursor_operation(Portal portal, bool forward, int count,
/* Run the executor like PerformPortalFetch and remember states */
if (forward)
{
- if (!portal->atEnd)
- {
- ExecutorRun(querydesc, estate, EXEC_FOR, (long) count);
- _SPI_current->processed = estate->es_processed;
- if (estate->es_processed > 0)
- portal->atStart = false;
- if (count <= 0 || (int) estate->es_processed < count)
- portal->atEnd = true;
- }
+ if (portal->atEnd)
+ direction = NoMovementScanDirection;
+ else
+ direction = ForwardScanDirection;
+
+ ExecutorRun(querydesc, estate, direction, (long) count);
+
+ if (estate->es_processed > 0)
+ portal->atStart = false; /* OK to back up now */
+ if (count <= 0 || (int) estate->es_processed < count)
+ portal->atEnd = true; /* we retrieved 'em all */
}
else
{
- if (!portal->atStart)
- {
- ExecutorRun(querydesc, estate, EXEC_BACK, (long) count);
- _SPI_current->processed = estate->es_processed;
- if (estate->es_processed > 0)
- portal->atEnd = false;
- if (count <= 0 || estate->es_processed < count)
- portal->atStart = true;
- }
+ if (portal->atStart)
+ direction = NoMovementScanDirection;
+ else
+ direction = BackwardScanDirection;
+
+ ExecutorRun(querydesc, estate, direction, (long) count);
+
+ if (estate->es_processed > 0)
+ portal->atEnd = false; /* OK to go forward now */
+ if (count <= 0 || (int) estate->es_processed < count)
+ portal->atStart = true; /* we retrieved 'em all */
}
+ _SPI_current->processed = estate->es_processed;
+
/*
* Restore outer command ID.
*/