diff options
Diffstat (limited to 'src/backend/executor')
-rw-r--r-- | src/backend/executor/execMain.c | 102 | ||||
-rw-r--r-- | src/backend/executor/functions.c | 14 | ||||
-rw-r--r-- | src/backend/executor/spi.c | 60 |
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. */ |