diff options
Diffstat (limited to 'src/backend/executor/tstoreReceiver.c')
-rw-r--r-- | src/backend/executor/tstoreReceiver.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/backend/executor/tstoreReceiver.c b/src/backend/executor/tstoreReceiver.c new file mode 100644 index 00000000000..fe82cc8c92c --- /dev/null +++ b/src/backend/executor/tstoreReceiver.c @@ -0,0 +1,89 @@ +/*------------------------------------------------------------------------- + * + * tstore_receiver.c + * an implementation of DestReceiver that stores the result tuples in + * a Tuplestore + * + * + * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * $Header: /cvsroot/pgsql/src/backend/executor/tstoreReceiver.c,v 1.1 2003/03/27 16:53:15 momjian Exp $ + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "executor/tstoreReceiver.h" +#include "utils/memutils.h" +#include "utils/portal.h" + +typedef struct +{ + DestReceiver pub; + Tuplestorestate *tstore; + MemoryContext cxt; +} TStoreState; + +/* + * Receive a tuple from the executor and store it in the tuplestore. + * + * 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) +{ + TStoreState *myState = (TStoreState *) self; + Portal portal; + + if (operation != CMD_SELECT) + elog(ERROR, "Unexpected operation type: %d", operation); + + portal = GetPortalByName(portalname); + + if (portal == NULL) + elog(ERROR, "Specified portal does not exist: %s", portalname); + + myState->tstore = portal->holdStore; + myState->cxt = portal->holdContext; +} + +static void +tstoreReceiveTuple(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self) +{ + TStoreState *myState = (TStoreState *) self; + MemoryContext oldcxt = MemoryContextSwitchTo(myState->cxt); + + tuplestore_puttuple(myState->tstore, tuple); + + MemoryContextSwitchTo(oldcxt); +} + +static void +tstoreCleanupReceiver(DestReceiver *self) +{ + ; /* do nothing */ +} + +DestReceiver * +tstoreReceiverCreateDR(void) +{ + TStoreState *self = (TStoreState *) palloc(sizeof(TStoreState)); + + self->pub.receiveTuple = tstoreReceiveTuple; + self->pub.setup = tstoreSetupReceiver; + self->pub.cleanup = tstoreCleanupReceiver; + + self->tstore = NULL; + self->cxt = NULL; + + return (DestReceiver *) self; +} |