|
| 1 | +/*------------------------------------------------------------------------- |
| 2 | + * |
| 3 | + * tstore_receiver.c |
| 4 | + * an implementation of DestReceiver that stores the result tuples in |
| 5 | + * a Tuplestore |
| 6 | + * |
| 7 | + * |
| 8 | + * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group |
| 9 | + * Portions Copyright (c) 1994, Regents of the University of California |
| 10 | + * |
| 11 | + * IDENTIFICATION |
| 12 | + * $Header: /cvsroot/pgsql/src/backend/executor/tstoreReceiver.c,v 1.1 2003/03/27 16:53:15 momjian Exp $ |
| 13 | + * |
| 14 | + *------------------------------------------------------------------------- |
| 15 | + */ |
| 16 | + |
| 17 | +#include "postgres.h" |
| 18 | + |
| 19 | +#include "executor/tstoreReceiver.h" |
| 20 | +#include "utils/memutils.h" |
| 21 | +#include "utils/portal.h" |
| 22 | + |
| 23 | +typedef struct |
| 24 | +{ |
| 25 | + DestReceiver pub; |
| 26 | + Tuplestorestate *tstore; |
| 27 | + MemoryContext cxt; |
| 28 | +} TStoreState; |
| 29 | + |
| 30 | +/* |
| 31 | + * Receive a tuple from the executor and store it in the tuplestore. |
| 32 | + * |
| 33 | + * XXX: As currently implemented, this routine is a hack: there should |
| 34 | + * be no tie between this code and the portal system. Instead, the |
| 35 | + * receiver function that is part of DestFunction should be passed a |
| 36 | + * QueryDesc, so that the call site of ExecutorRun can "sub-class" |
| 37 | + * QueryDesc and pass in any necessary addition information (in this |
| 38 | + * case, the Tuplestore to use). |
| 39 | + */ |
| 40 | +static void |
| 41 | +tstoreSetupReceiver(DestReceiver *self, int operation, |
| 42 | + const char *portalname, TupleDesc typeinfo) |
| 43 | +{ |
| 44 | + TStoreState *myState = (TStoreState *) self; |
| 45 | + Portal portal; |
| 46 | + |
| 47 | + if (operation != CMD_SELECT) |
| 48 | + elog(ERROR, "Unexpected operation type: %d", operation); |
| 49 | + |
| 50 | + portal = GetPortalByName(portalname); |
| 51 | + |
| 52 | + if (portal == NULL) |
| 53 | + elog(ERROR, "Specified portal does not exist: %s", portalname); |
| 54 | + |
| 55 | + myState->tstore = portal->holdStore; |
| 56 | + myState->cxt = portal->holdContext; |
| 57 | +} |
| 58 | + |
| 59 | +static void |
| 60 | +tstoreReceiveTuple(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self) |
| 61 | +{ |
| 62 | + TStoreState *myState = (TStoreState *) self; |
| 63 | + MemoryContext oldcxt = MemoryContextSwitchTo(myState->cxt); |
| 64 | + |
| 65 | + tuplestore_puttuple(myState->tstore, tuple); |
| 66 | + |
| 67 | + MemoryContextSwitchTo(oldcxt); |
| 68 | +} |
| 69 | + |
| 70 | +static void |
| 71 | +tstoreCleanupReceiver(DestReceiver *self) |
| 72 | +{ |
| 73 | + ; /* do nothing */ |
| 74 | +} |
| 75 | + |
| 76 | +DestReceiver * |
| 77 | +tstoreReceiverCreateDR(void) |
| 78 | +{ |
| 79 | + TStoreState *self = (TStoreState *) palloc(sizeof(TStoreState)); |
| 80 | + |
| 81 | + self->pub.receiveTuple = tstoreReceiveTuple; |
| 82 | + self->pub.setup = tstoreSetupReceiver; |
| 83 | + self->pub.cleanup = tstoreCleanupReceiver; |
| 84 | + |
| 85 | + self->tstore = NULL; |
| 86 | + self->cxt = NULL; |
| 87 | + |
| 88 | + return (DestReceiver *) self; |
| 89 | +} |
0 commit comments