]> granicus.if.org Git - postgresql/blob - src/backend/executor/tstoreReceiver.c
c4d16ef5e9846081e799b42f1bef7313501fb6ca
[postgresql] / src / backend / executor / tstoreReceiver.c
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.3 2003/05/02 20:54:34 tgl 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 /*
32  * Prepare to receive tuples from executor.
33  *
34  * XXX: As currently implemented, this routine is a hack: there should
35  * be no tie between this code and the portal system. Instead, the
36  * receiver function that is part of DestFunction should be passed a
37  * QueryDesc, so that the call site of ExecutorRun can "sub-class"
38  * QueryDesc and pass in any necessary addition information (in this
39  * case, the Tuplestore to use).
40  */
41 static void
42 tstoreSetupReceiver(DestReceiver *self, int operation,
43                                         const char *portalname, TupleDesc typeinfo)
44 {
45         TStoreState *myState = (TStoreState *) self;
46
47         /* Should only be called within a suitably-prepped portal */
48         if (CurrentPortal == NULL ||
49                 CurrentPortal->holdStore == NULL)
50                 elog(ERROR, "Tuplestore destination used in wrong context");
51
52         /* Debug check: make sure portal's result tuple desc is correct */
53         Assert(CurrentPortal->tupDesc != NULL);
54         Assert(equalTupleDescs(CurrentPortal->tupDesc, typeinfo));
55
56         myState->tstore = CurrentPortal->holdStore;
57         myState->cxt = CurrentPortal->holdContext;
58 }
59
60 /*
61  * Receive a tuple from the executor and store it in the tuplestore.
62  */
63 static void
64 tstoreReceiveTuple(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self)
65 {
66         TStoreState *myState = (TStoreState *) self;
67         MemoryContext oldcxt = MemoryContextSwitchTo(myState->cxt);
68
69         tuplestore_puttuple(myState->tstore, tuple);
70
71         MemoryContextSwitchTo(oldcxt);
72 }
73
74 /*
75  * Clean up
76  */
77 static void
78 tstoreCleanupReceiver(DestReceiver *self)
79 {
80         /* do nothing */
81 }
82
83 /*
84  * Initially create a DestReceiver object.
85  */
86 DestReceiver *
87 tstoreReceiverCreateDR(void)
88 {
89         TStoreState *self = (TStoreState *) palloc(sizeof(TStoreState));
90
91         self->pub.receiveTuple = tstoreReceiveTuple;
92         self->pub.setup = tstoreSetupReceiver;
93         self->pub.cleanup = tstoreCleanupReceiver;
94
95         self->tstore = NULL;
96         self->cxt = NULL;
97
98         return (DestReceiver *) self;
99 }