Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * dest.c
4 : * support for communication destinations
5 : *
6 : *
7 : * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
8 : * Portions Copyright (c) 1994, Regents of the University of California
9 : *
10 : * IDENTIFICATION
11 : * src/backend/tcop/dest.c
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/printsimple.h"
32 : #include "access/printtup.h"
33 : #include "access/xact.h"
34 : #include "commands/copy.h"
35 : #include "commands/createas.h"
36 : #include "commands/matview.h"
37 : #include "executor/functions.h"
38 : #include "executor/tqueue.h"
39 : #include "executor/tstoreReceiver.h"
40 : #include "libpq/libpq.h"
41 : #include "libpq/pqformat.h"
42 : #include "utils/portal.h"
43 :
44 :
45 : /* ----------------
46 : * dummy DestReceiver functions
47 : * ----------------
48 : */
49 : static bool
50 31051 : donothingReceive(TupleTableSlot *slot, DestReceiver *self)
51 : {
52 31051 : return true;
53 : }
54 :
55 : static void
56 30 : donothingStartup(DestReceiver *self, int operation, TupleDesc typeinfo)
57 : {
58 30 : }
59 :
60 : static void
61 5125 : donothingCleanup(DestReceiver *self)
62 : {
63 : /* this is used for both shutdown and destroy methods */
64 5125 : }
65 :
66 : /* ----------------
67 : * static DestReceiver structs for dest types needing no local state
68 : * ----------------
69 : */
70 : static DestReceiver donothingDR = {
71 : donothingReceive, donothingStartup, donothingCleanup, donothingCleanup,
72 : DestNone
73 : };
74 :
75 : static DestReceiver debugtupDR = {
76 : debugtup, debugStartup, donothingCleanup, donothingCleanup,
77 : DestDebug
78 : };
79 :
80 : static DestReceiver printsimpleDR = {
81 : printsimple, printsimple_startup, donothingCleanup, donothingCleanup,
82 : DestRemoteSimple
83 : };
84 :
85 : static DestReceiver spi_printtupDR = {
86 : spi_printtup, spi_dest_startup, donothingCleanup, donothingCleanup,
87 : DestSPI
88 : };
89 :
90 : /* Globally available receiver for DestNone */
91 : DestReceiver *None_Receiver = &donothingDR;
92 :
93 :
94 : /* ----------------
95 : * BeginCommand - initialize the destination at start of command
96 : * ----------------
97 : */
98 : void
99 27446 : BeginCommand(const char *commandTag, CommandDest dest)
100 : {
101 : /* Nothing to do at present */
102 27446 : }
103 :
104 : /* ----------------
105 : * CreateDestReceiver - return appropriate receiver function set for dest
106 : * ----------------
107 : */
108 : DestReceiver *
109 38974 : CreateDestReceiver(CommandDest dest)
110 : {
111 38974 : switch (dest)
112 : {
113 : case DestRemote:
114 : case DestRemoteExecute:
115 25341 : return printtup_create_DR(dest);
116 :
117 : case DestRemoteSimple:
118 0 : return &printsimpleDR;
119 :
120 : case DestNone:
121 1 : return &donothingDR;
122 :
123 : case DestDebug:
124 1023 : return &debugtupDR;
125 :
126 : case DestSPI:
127 5709 : return &spi_printtupDR;
128 :
129 : case DestTuplestore:
130 1668 : return CreateTuplestoreDestReceiver();
131 :
132 : case DestIntoRel:
133 0 : return CreateIntoRelDestReceiver(NULL);
134 :
135 : case DestCopyOut:
136 33 : return CreateCopyDestReceiver();
137 :
138 : case DestSQLFunction:
139 5199 : return CreateSQLFunctionDestReceiver();
140 :
141 : case DestTransientRel:
142 0 : return CreateTransientRelDestReceiver(InvalidOid);
143 :
144 : case DestTupleQueue:
145 0 : return CreateTupleQueueDestReceiver(NULL);
146 : }
147 :
148 : /* should never get here */
149 0 : return &donothingDR;
150 : }
151 :
152 : /* ----------------
153 : * EndCommand - clean up the destination at end of command
154 : * ----------------
155 : */
156 : void
157 24327 : EndCommand(const char *commandTag, CommandDest dest)
158 : {
159 24327 : switch (dest)
160 : {
161 : case DestRemote:
162 : case DestRemoteExecute:
163 : case DestRemoteSimple:
164 :
165 : /*
166 : * We assume the commandTag is plain ASCII and therefore requires
167 : * no encoding conversion.
168 : */
169 23304 : pq_putmessage('C', commandTag, strlen(commandTag) + 1);
170 23304 : break;
171 :
172 : case DestNone:
173 : case DestDebug:
174 : case DestSPI:
175 : case DestTuplestore:
176 : case DestIntoRel:
177 : case DestCopyOut:
178 : case DestSQLFunction:
179 : case DestTransientRel:
180 : case DestTupleQueue:
181 1023 : break;
182 : }
183 24327 : }
184 :
185 : /* ----------------
186 : * NullCommand - tell dest that an empty query string was recognized
187 : *
188 : * In FE/BE protocol version 1.0, this hack is necessary to support
189 : * libpq's crufty way of determining whether a multiple-command
190 : * query string is done. In protocol 2.0 it's probably not really
191 : * necessary to distinguish empty queries anymore, but we still do it
192 : * for backwards compatibility with 1.0. In protocol 3.0 it has some
193 : * use again, since it ensures that there will be a recognizable end
194 : * to the response to an Execute message.
195 : * ----------------
196 : */
197 : void
198 5 : NullCommand(CommandDest dest)
199 : {
200 5 : switch (dest)
201 : {
202 : case DestRemote:
203 : case DestRemoteExecute:
204 : case DestRemoteSimple:
205 :
206 : /*
207 : * tell the fe that we saw an empty query string. In protocols
208 : * before 3.0 this has a useless empty-string message body.
209 : */
210 5 : if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
211 5 : pq_putemptymessage('I');
212 : else
213 0 : pq_putmessage('I', "", 1);
214 5 : break;
215 :
216 : case DestNone:
217 : case DestDebug:
218 : case DestSPI:
219 : case DestTuplestore:
220 : case DestIntoRel:
221 : case DestCopyOut:
222 : case DestSQLFunction:
223 : case DestTransientRel:
224 : case DestTupleQueue:
225 0 : break;
226 : }
227 5 : }
228 :
229 : /* ----------------
230 : * ReadyForQuery - tell dest that we are ready for a new query
231 : *
232 : * The ReadyForQuery message is sent so that the FE can tell when
233 : * we are done processing a query string.
234 : * In versions 3.0 and up, it also carries a transaction state indicator.
235 : *
236 : * Note that by flushing the stdio buffer here, we can avoid doing it
237 : * most other places and thus reduce the number of separate packets sent.
238 : * ----------------
239 : */
240 : void
241 27544 : ReadyForQuery(CommandDest dest)
242 : {
243 27544 : switch (dest)
244 : {
245 : case DestRemote:
246 : case DestRemoteExecute:
247 : case DestRemoteSimple:
248 27020 : if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
249 : {
250 : StringInfoData buf;
251 :
252 27020 : pq_beginmessage(&buf, 'Z');
253 27020 : pq_sendbyte(&buf, TransactionBlockStatusCode());
254 27020 : pq_endmessage(&buf);
255 : }
256 : else
257 0 : pq_putemptymessage('Z');
258 : /* Flush output at end of cycle in any case. */
259 27020 : pq_flush();
260 27020 : break;
261 :
262 : case DestNone:
263 : case DestDebug:
264 : case DestSPI:
265 : case DestTuplestore:
266 : case DestIntoRel:
267 : case DestCopyOut:
268 : case DestSQLFunction:
269 : case DestTransientRel:
270 : case DestTupleQueue:
271 524 : break;
272 : }
273 27544 : }
|