diff options
Diffstat (limited to 'src/backend/executor')
-rw-r--r-- | src/backend/executor/execMain.c | 35 | ||||
-rw-r--r-- | src/backend/executor/execTuples.c | 64 | ||||
-rw-r--r-- | src/backend/executor/functions.c | 4 | ||||
-rw-r--r-- | src/backend/executor/spi.c | 50 | ||||
-rw-r--r-- | src/backend/executor/tstoreReceiver.c | 60 |
5 files changed, 125 insertions, 88 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 719c9456562..3d1b950e210 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -26,7 +26,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.207 2003/05/06 00:20:31 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.208 2003/05/06 20:26:26 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -72,9 +72,9 @@ static TupleTableSlot *ExecutePlan(EState *estate, PlanState *planstate, CmdType operation, long numberTuples, ScanDirection direction, - DestReceiver *destfunc); + DestReceiver *dest); static void ExecSelect(TupleTableSlot *slot, - DestReceiver *destfunc, + DestReceiver *dest, EState *estate); static void ExecInsert(TupleTableSlot *slot, ItemPointer tupleid, EState *estate); @@ -188,8 +188,7 @@ ExecutorRun(QueryDesc *queryDesc, { EState *estate; CmdType operation; - CommandDest dest; - DestReceiver *destfunc; + DestReceiver *dest; TupleTableSlot *result; MemoryContext oldcontext; @@ -218,11 +217,10 @@ ExecutorRun(QueryDesc *queryDesc, estate->es_processed = 0; estate->es_lastoid = InvalidOid; - destfunc = DestToFunction(dest); - (*destfunc->setup) (destfunc, operation, - queryDesc->portalName, - queryDesc->tupDesc, - queryDesc->planstate->plan->targetlist); + (*dest->startup) (dest, operation, + queryDesc->portalName, + queryDesc->tupDesc, + queryDesc->planstate->plan->targetlist); /* * run plan @@ -235,12 +233,12 @@ ExecutorRun(QueryDesc *queryDesc, operation, count, direction, - destfunc); + dest); /* * shutdown receiver */ - (*destfunc->cleanup) (destfunc); + (*dest->shutdown) (dest); MemoryContextSwitchTo(oldcontext); @@ -962,7 +960,7 @@ ExecutePlan(EState *estate, CmdType operation, long numberTuples, ScanDirection direction, - DestReceiver *destfunc) + DestReceiver *dest) { JunkFilter *junkfilter; TupleTableSlot *slot; @@ -1162,8 +1160,7 @@ lnext: ; { case CMD_SELECT: ExecSelect(slot, /* slot containing tuple */ - destfunc, /* destination's tuple-receiver - * obj */ + dest, /* destination's tuple-receiver obj */ estate); result = slot; break; @@ -1237,7 +1234,7 @@ lnext: ; */ static void ExecSelect(TupleTableSlot *slot, - DestReceiver *destfunc, + DestReceiver *dest, EState *estate) { HeapTuple tuple; @@ -1251,6 +1248,8 @@ ExecSelect(TupleTableSlot *slot, /* * insert the tuple into the "into relation" + * + * XXX this probably ought to be replaced by a separate destination */ if (estate->es_into_relation_descriptor != NULL) { @@ -1260,9 +1259,9 @@ ExecSelect(TupleTableSlot *slot, } /* - * send the tuple to the front end (or the screen) + * send the tuple to the destination */ - (*destfunc->receiveTuple) (tuple, attrtype, destfunc); + (*dest->receiveTuple) (tuple, attrtype, dest); IncrRetrieved(); (estate->es_processed)++; } diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c index c81dd33d36a..2e040f78903 100644 --- a/src/backend/executor/execTuples.c +++ b/src/backend/executor/execTuples.c @@ -15,7 +15,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.64 2003/05/06 00:20:31 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.65 2003/05/06 20:26:27 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -591,6 +591,49 @@ ExecTypeFromTL(List *targetList, bool hasoid) return typeInfo; } +/* ---------------------------------------------------------------- + * ExecCleanTypeFromTL + * + * Same as above, but resjunk columns are omitted from the result. + * ---------------------------------------------------------------- + */ +TupleDesc +ExecCleanTypeFromTL(List *targetList, bool hasoid) +{ + TupleDesc typeInfo; + List *tlitem; + int len; + int cleanresno; + + /* + * allocate a new typeInfo + */ + len = ExecCleanTargetListLength(targetList); + typeInfo = CreateTemplateTupleDesc(len, hasoid); + + /* + * scan list, generate type info for each entry + */ + cleanresno = 1; + foreach(tlitem, targetList) + { + TargetEntry *tle = lfirst(tlitem); + Resdom *resdom = tle->resdom; + + if (resdom->resjunk) + continue; + TupleDescInitEntry(typeInfo, + cleanresno++, + resdom->resname, + resdom->restype, + resdom->restypmod, + 0, + false); + } + + return typeInfo; +} + /* * TupleDescGetSlot - Initialize a slot based on the supplied tupledesc */ @@ -713,17 +756,17 @@ BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values) * Table Function capability. Currently used by EXPLAIN and SHOW ALL */ TupOutputState * -begin_tup_output_tupdesc(CommandDest dest, TupleDesc tupdesc) +begin_tup_output_tupdesc(DestReceiver *dest, TupleDesc tupdesc) { TupOutputState *tstate; tstate = (TupOutputState *) palloc(sizeof(TupOutputState)); tstate->metadata = TupleDescGetAttInMetadata(tupdesc); - tstate->destfunc = DestToFunction(dest); + tstate->dest = dest; - (*tstate->destfunc->setup) (tstate->destfunc, (int) CMD_SELECT, - NULL, tupdesc, NIL); + (*tstate->dest->startup) (tstate->dest, (int) CMD_SELECT, + NULL, tupdesc, NIL); return tstate; } @@ -741,9 +784,9 @@ do_tup_output(TupOutputState *tstate, char **values) HeapTuple tuple = BuildTupleFromCStrings(tstate->metadata, values); /* send the tuple to the receiver */ - (*tstate->destfunc->receiveTuple) (tuple, - tstate->metadata->tupdesc, - tstate->destfunc); + (*tstate->dest->receiveTuple) (tuple, + tstate->metadata->tupdesc, + tstate->dest); /* clean up */ heap_freetuple(tuple); } @@ -766,7 +809,7 @@ do_text_output_multiline(TupOutputState *tstate, char *text) if (eol) *eol++ = '\0'; else - eol = text +strlen(text); + eol = text + strlen(text); do_tup_output(tstate, &text); text = eol; @@ -776,7 +819,8 @@ do_text_output_multiline(TupOutputState *tstate, char *text) void end_tup_output(TupOutputState *tstate) { - (*tstate->destfunc->cleanup) (tstate->destfunc); + (*tstate->dest->shutdown) (tstate->dest); + /* note that destroying the dest is not ours to do */ /* XXX worth cleaning up the attinmetadata? */ pfree(tstate); } diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c index ba41828be34..e89e5f32d64 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.63 2003/05/06 00:20:31 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.64 2003/05/06 20:26:27 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -245,7 +245,7 @@ postquel_start(execution_state *es, SQLFunctionCachePtr fcache) { Assert(es->qd == NULL); es->qd = CreateQueryDesc(es->query, es->plan, - None, NULL, + None_Receiver, NULL, fcache->paramLI, false); /* Utility commands don't need Executor. */ diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index 74299ddf3ea..c3b3ec3530a 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.95 2003/05/06 00:20:31 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.96 2003/05/06 20:26:27 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -38,7 +38,7 @@ static int _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls, int tcount); static void _SPI_cursor_operation(Portal portal, bool forward, int count, - CommandDest dest); + DestReceiver *dest); static _SPI_plan *_SPI_copy_plan(_SPI_plan *plan, int location); @@ -841,7 +841,8 @@ SPI_cursor_find(const char *name) void SPI_cursor_fetch(Portal portal, bool forward, int count) { - _SPI_cursor_operation(portal, forward, count, SPI); + _SPI_cursor_operation(portal, forward, count, CreateDestReceiver(SPI)); + /* we know that the SPI receiver doesn't need a destroy call */ } @@ -853,7 +854,7 @@ SPI_cursor_fetch(Portal portal, bool forward, int count) void SPI_cursor_move(Portal portal, bool forward, int count) { - _SPI_cursor_operation(portal, forward, count, None); + _SPI_cursor_operation(portal, forward, count, None_Receiver); } @@ -874,13 +875,13 @@ SPI_cursor_close(Portal portal) /* =================== private functions =================== */ /* - * spi_dest_setup + * spi_dest_startup * Initialize to receive tuples from Executor into SPITupleTable * of current SPI procedure */ void -spi_dest_setup(DestReceiver *self, int operation, - const char *portalName, TupleDesc typeinfo, List *targetlist) +spi_dest_startup(DestReceiver *self, int operation, + const char *portalName, TupleDesc typeinfo, List *targetlist) { SPITupleTable *tuptable; MemoryContext oldcxt; @@ -891,12 +892,12 @@ spi_dest_setup(DestReceiver *self, int operation, * _SPI_connected */ if (_SPI_curid != _SPI_connected || _SPI_connected < 0) - elog(FATAL, "SPI: improper call to spi_dest_setup"); + elog(FATAL, "SPI: improper call to spi_dest_startup"); if (_SPI_current != &(_SPI_stack[_SPI_curid])) - elog(FATAL, "SPI: stack corrupted in spi_dest_setup"); + elog(FATAL, "SPI: stack corrupted in spi_dest_startup"); if (_SPI_current->tuptable != NULL) - elog(FATAL, "SPI: improper call to spi_dest_setup"); + elog(FATAL, "SPI: improper call to spi_dest_startup"); oldcxt = _SPI_procmem(); /* switch to procedure memory context */ @@ -1029,10 +1030,12 @@ _SPI_execute(const char *src, int tcount, _SPI_plan *plan) Query *queryTree = (Query *) lfirst(query_list_item); Plan *planTree; QueryDesc *qdesc; + DestReceiver *dest; planTree = pg_plan_query(queryTree); plan_list = lappend(plan_list, planTree); + dest = CreateDestReceiver(queryTree->canSetTag ? SPI : None); if (queryTree->commandType == CMD_UTILITY) { if (IsA(queryTree->utilityStmt, CopyStmt)) @@ -1051,14 +1054,13 @@ _SPI_execute(const char *src, int tcount, _SPI_plan *plan) res = SPI_OK_UTILITY; if (plan == NULL) { - ProcessUtility(queryTree->utilityStmt, None, NULL); + ProcessUtility(queryTree->utilityStmt, dest, NULL); CommandCounterIncrement(); } } else if (plan == NULL) { - qdesc = CreateQueryDesc(queryTree, planTree, - queryTree->canSetTag ? SPI : None, + qdesc = CreateQueryDesc(queryTree, planTree, dest, NULL, NULL, false); res = _SPI_pquery(qdesc, true, queryTree->canSetTag ? tcount : 0); @@ -1068,8 +1070,7 @@ _SPI_execute(const char *src, int tcount, _SPI_plan *plan) } else { - qdesc = CreateQueryDesc(queryTree, planTree, - queryTree->canSetTag ? SPI : None, + qdesc = CreateQueryDesc(queryTree, planTree, dest, NULL, NULL, false); res = _SPI_pquery(qdesc, false, 0); if (res < 0) @@ -1144,20 +1145,21 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls, Query *queryTree = (Query *) lfirst(query_list_item); Plan *planTree; QueryDesc *qdesc; + DestReceiver *dest; planTree = lfirst(plan_list); plan_list = lnext(plan_list); + dest = CreateDestReceiver(queryTree->canSetTag ? SPI : None); if (queryTree->commandType == CMD_UTILITY) { - ProcessUtility(queryTree->utilityStmt, None, NULL); + ProcessUtility(queryTree->utilityStmt, dest, NULL); res = SPI_OK_UTILITY; CommandCounterIncrement(); } else { - qdesc = CreateQueryDesc(queryTree, planTree, - queryTree->canSetTag ? SPI : None, + qdesc = CreateQueryDesc(queryTree, planTree, dest, NULL, paramLI, false); res = _SPI_pquery(qdesc, true, queryTree->canSetTag ? tcount : 0); @@ -1185,7 +1187,7 @@ _SPI_pquery(QueryDesc *queryDesc, bool runit, int tcount) if (queryDesc->parsetree->into != NULL) /* select into table */ { res = SPI_OK_SELINTO; - queryDesc->dest = None; /* don't output results anywhere */ + queryDesc->dest = None_Receiver; /* don't output results */ } break; case CMD_INSERT: @@ -1216,13 +1218,13 @@ _SPI_pquery(QueryDesc *queryDesc, bool runit, int tcount) _SPI_current->processed = queryDesc->estate->es_processed; save_lastoid = queryDesc->estate->es_lastoid; - if (operation == CMD_SELECT && queryDesc->dest == SPI) + if (operation == CMD_SELECT && queryDesc->dest->mydest == SPI) { if (_SPI_checktuples()) elog(FATAL, "SPI_select: # of processed tuples check failed"); } - if (queryDesc->dest == SPI) + if (queryDesc->dest->mydest == SPI) { SPI_processed = _SPI_current->processed; SPI_lastoid = save_lastoid; @@ -1253,7 +1255,7 @@ _SPI_pquery(QueryDesc *queryDesc, bool runit, int tcount) */ static void _SPI_cursor_operation(Portal portal, bool forward, int count, - CommandDest dest) + DestReceiver *dest) { /* Check that the portal is valid */ if (!PortalIsValid(portal)) @@ -1275,7 +1277,7 @@ _SPI_cursor_operation(Portal portal, bool forward, int count, (long) count, dest); - if (dest == SPI && _SPI_checktuples()) + if (dest->mydest == SPI && _SPI_checktuples()) elog(FATAL, "SPI_fetch: # of processed tuples check failed"); /* Put the result into place for access by caller */ @@ -1343,7 +1345,7 @@ _SPI_checktuples(void) SPITupleTable *tuptable = _SPI_current->tuptable; bool failed = false; - if (tuptable == NULL) /* spi_dest_setup was not called */ + if (tuptable == NULL) /* spi_dest_startup was not called */ failed = true; else if (processed != (tuptable->alloced - tuptable->free)) failed = true; diff --git a/src/backend/executor/tstoreReceiver.c b/src/backend/executor/tstoreReceiver.c index 05b0c1f2397..bcab8154a32 100644 --- a/src/backend/executor/tstoreReceiver.c +++ b/src/backend/executor/tstoreReceiver.c @@ -1,6 +1,6 @@ /*------------------------------------------------------------------------- * - * tstore_receiver.c + * tstoreReceiver.c * an implementation of DestReceiver that stores the result tuples in * a Tuplestore * @@ -9,7 +9,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/tstoreReceiver.c,v 1.4 2003/05/06 00:20:31 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/tstoreReceiver.c,v 1.5 2003/05/06 20:26:27 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -17,8 +17,7 @@ #include "postgres.h" #include "executor/tstoreReceiver.h" -#include "utils/memutils.h" -#include "utils/portal.h" + typedef struct { @@ -30,32 +29,13 @@ typedef struct /* * Prepare to receive tuples from executor. - * - * XXX: As currently implemented, this routine is a hack: there should - * be no tie between this code and the portal system. Instead, the - * receiver function that is part of DestFunction should be passed a - * QueryDesc, so that the call site of ExecutorRun can "sub-class" - * QueryDesc and pass in any necessary addition information (in this - * case, the Tuplestore to use). */ static void -tstoreSetupReceiver(DestReceiver *self, int operation, - const char *portalname, - TupleDesc typeinfo, List *targetlist) +tstoreStartupReceiver(DestReceiver *self, int operation, + const char *portalname, + TupleDesc typeinfo, List *targetlist) { - TStoreState *myState = (TStoreState *) self; - - /* Should only be called within a suitably-prepped portal */ - if (CurrentPortal == NULL || - CurrentPortal->holdStore == NULL) - elog(ERROR, "Tuplestore destination used in wrong context"); - - /* Debug check: make sure portal's result tuple desc is correct */ - Assert(CurrentPortal->tupDesc != NULL); - Assert(equalTupleDescs(CurrentPortal->tupDesc, typeinfo)); - - myState->tstore = CurrentPortal->holdStore; - myState->cxt = CurrentPortal->holdContext; + /* do nothing */ } /* @@ -73,28 +53,40 @@ tstoreReceiveTuple(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self) } /* - * Clean up + * Clean up at end of an executor run */ static void -tstoreCleanupReceiver(DestReceiver *self) +tstoreShutdownReceiver(DestReceiver *self) { /* do nothing */ } /* + * Destroy receiver when done with it + */ +static void +tstoreDestroyReceiver(DestReceiver *self) +{ + pfree(self); +} + +/* * Initially create a DestReceiver object. */ DestReceiver * -tstoreReceiverCreateDR(void) +CreateTuplestoreDestReceiver(Tuplestorestate *tStore, + MemoryContext tContext) { TStoreState *self = (TStoreState *) palloc(sizeof(TStoreState)); self->pub.receiveTuple = tstoreReceiveTuple; - self->pub.setup = tstoreSetupReceiver; - self->pub.cleanup = tstoreCleanupReceiver; + self->pub.startup = tstoreStartupReceiver; + self->pub.shutdown = tstoreShutdownReceiver; + self->pub.destroy = tstoreDestroyReceiver; + self->pub.mydest = Tuplestore; - self->tstore = NULL; - self->cxt = NULL; + self->tstore = tStore; + self->cxt = tContext; return (DestReceiver *) self; } |