]> granicus.if.org Git - postgresql/blob - src/backend/tcop/dest.c
Update copyright for the year 2010.
[postgresql] / src / backend / tcop / dest.c
1 /*-------------------------------------------------------------------------
2  *
3  * dest.c
4  *        support for communication destinations
5  *
6  *
7  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  * IDENTIFICATION
11  *        $PostgreSQL: pgsql/src/backend/tcop/dest.c,v 1.76 2010/01/02 16:57:52 momjian Exp $
12  *
13  *-------------------------------------------------------------------------
14  */
15 /*
16  *       INTERFACE ROUTINES
17  *              BeginCommand - initialize the destination at start of command
18  *              CreateDestReceiver - create tuple receiver object for destination
19  *              EndCommand - clean up the destination at end of command
20  *              NullCommand - tell dest that an empty query string was recognized
21  *              ReadyForQuery - tell dest that we are ready for a new query
22  *
23  *       NOTES
24  *              These routines do the appropriate work before and after
25  *              tuples are returned by a query to keep the backend and the
26  *              "destination" portals synchronized.
27  */
28
29 #include "postgres.h"
30
31 #include "access/printtup.h"
32 #include "access/xact.h"
33 #include "commands/copy.h"
34 #include "executor/executor.h"
35 #include "executor/functions.h"
36 #include "executor/tstoreReceiver.h"
37 #include "libpq/libpq.h"
38 #include "libpq/pqformat.h"
39 #include "utils/portal.h"
40
41
42 /* ----------------
43  *              dummy DestReceiver functions
44  * ----------------
45  */
46 static void
47 donothingReceive(TupleTableSlot *slot, DestReceiver *self)
48 {
49 }
50
51 static void
52 donothingStartup(DestReceiver *self, int operation, TupleDesc typeinfo)
53 {
54 }
55
56 static void
57 donothingCleanup(DestReceiver *self)
58 {
59         /* this is used for both shutdown and destroy methods */
60 }
61
62 /* ----------------
63  *              static DestReceiver structs for dest types needing no local state
64  * ----------------
65  */
66 static DestReceiver donothingDR = {
67         donothingReceive, donothingStartup, donothingCleanup, donothingCleanup,
68         DestNone
69 };
70
71 static DestReceiver debugtupDR = {
72         debugtup, debugStartup, donothingCleanup, donothingCleanup,
73         DestDebug
74 };
75
76 static DestReceiver spi_printtupDR = {
77         spi_printtup, spi_dest_startup, donothingCleanup, donothingCleanup,
78         DestSPI
79 };
80
81 /* Globally available receiver for DestNone */
82 DestReceiver *None_Receiver = &donothingDR;
83
84
85 /* ----------------
86  *              BeginCommand - initialize the destination at start of command
87  * ----------------
88  */
89 void
90 BeginCommand(const char *commandTag, CommandDest dest)
91 {
92         /* Nothing to do at present */
93 }
94
95 /* ----------------
96  *              CreateDestReceiver - return appropriate receiver function set for dest
97  * ----------------
98  */
99 DestReceiver *
100 CreateDestReceiver(CommandDest dest)
101 {
102         switch (dest)
103         {
104                 case DestRemote:
105                 case DestRemoteExecute:
106                         return printtup_create_DR(dest);
107
108                 case DestNone:
109                         return &donothingDR;
110
111                 case DestDebug:
112                         return &debugtupDR;
113
114                 case DestSPI:
115                         return &spi_printtupDR;
116
117                 case DestTuplestore:
118                         return CreateTuplestoreDestReceiver();
119
120                 case DestIntoRel:
121                         return CreateIntoRelDestReceiver();
122
123                 case DestCopyOut:
124                         return CreateCopyDestReceiver();
125
126                 case DestSQLFunction:
127                         return CreateSQLFunctionDestReceiver();
128         }
129
130         /* should never get here */
131         return &donothingDR;
132 }
133
134 /* ----------------
135  *              EndCommand - clean up the destination at end of command
136  * ----------------
137  */
138 void
139 EndCommand(const char *commandTag, CommandDest dest)
140 {
141         switch (dest)
142         {
143                 case DestRemote:
144                 case DestRemoteExecute:
145                         pq_puttextmessage('C', commandTag);
146                         break;
147
148                 case DestNone:
149                 case DestDebug:
150                 case DestSPI:
151                 case DestTuplestore:
152                 case DestIntoRel:
153                 case DestCopyOut:
154                 case DestSQLFunction:
155                         break;
156         }
157 }
158
159 /* ----------------
160  *              NullCommand - tell dest that an empty query string was recognized
161  *
162  *              In FE/BE protocol version 1.0, this hack is necessary to support
163  *              libpq's crufty way of determining whether a multiple-command
164  *              query string is done.  In protocol 2.0 it's probably not really
165  *              necessary to distinguish empty queries anymore, but we still do it
166  *              for backwards compatibility with 1.0.  In protocol 3.0 it has some
167  *              use again, since it ensures that there will be a recognizable end
168  *              to the response to an Execute message.
169  * ----------------
170  */
171 void
172 NullCommand(CommandDest dest)
173 {
174         switch (dest)
175         {
176                 case DestRemote:
177                 case DestRemoteExecute:
178
179                         /*
180                          * tell the fe that we saw an empty query string.  In protocols
181                          * before 3.0 this has a useless empty-string message body.
182                          */
183                         if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
184                                 pq_putemptymessage('I');
185                         else
186                                 pq_puttextmessage('I', "");
187                         break;
188
189                 case DestNone:
190                 case DestDebug:
191                 case DestSPI:
192                 case DestTuplestore:
193                 case DestIntoRel:
194                 case DestCopyOut:
195                 case DestSQLFunction:
196                         break;
197         }
198 }
199
200 /* ----------------
201  *              ReadyForQuery - tell dest that we are ready for a new query
202  *
203  *              The ReadyForQuery message is sent in protocol versions 2.0 and up
204  *              so that the FE can tell when we are done processing a query string.
205  *              In versions 3.0 and up, it also carries a transaction state indicator.
206  *
207  *              Note that by flushing the stdio buffer here, we can avoid doing it
208  *              most other places and thus reduce the number of separate packets sent.
209  * ----------------
210  */
211 void
212 ReadyForQuery(CommandDest dest)
213 {
214         switch (dest)
215         {
216                 case DestRemote:
217                 case DestRemoteExecute:
218                         if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
219                         {
220                                 StringInfoData buf;
221
222                                 pq_beginmessage(&buf, 'Z');
223                                 pq_sendbyte(&buf, TransactionBlockStatusCode());
224                                 pq_endmessage(&buf);
225                         }
226                         else if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 2)
227                                 pq_putemptymessage('Z');
228                         /* Flush output at end of cycle in any case. */
229                         pq_flush();
230                         break;
231
232                 case DestNone:
233                 case DestDebug:
234                 case DestSPI:
235                 case DestTuplestore:
236                 case DestIntoRel:
237                 case DestCopyOut:
238                 case DestSQLFunction:
239                         break;
240         }
241 }