Age Owner Branch data TLA Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * dest.c
4 : : * support for communication destinations
5 : : *
6 : : *
7 : : * Portions Copyright (c) 1996-2024, 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/explain.h"
37 : : #include "commands/matview.h"
38 : : #include "executor/functions.h"
39 : : #include "executor/tqueue.h"
40 : : #include "executor/tstoreReceiver.h"
41 : : #include "libpq/libpq.h"
42 : : #include "libpq/pqformat.h"
43 : :
44 : :
45 : : /* ----------------
46 : : * dummy DestReceiver functions
47 : : * ----------------
48 : : */
49 : : static bool
6969 tgl@sss.pgh.pa.us 50 :CBC 660201 : donothingReceive(TupleTableSlot *slot, DestReceiver *self)
51 : : {
2869 rhaas@postgresql.org 52 : 660201 : return true;
53 : : }
54 : :
55 : : static void
7647 tgl@sss.pgh.pa.us 56 : 21697 : donothingStartup(DestReceiver *self, int operation, TupleDesc typeinfo)
57 : : {
9209 58 : 21697 : }
59 : :
60 : : static void
9091 bruce@momjian.us 61 : 128233 : donothingCleanup(DestReceiver *self)
62 : : {
63 : : /* this is used for both shutdown and destroy methods */
9209 tgl@sss.pgh.pa.us 64 : 128233 : }
65 : :
66 : : /* ----------------
67 : : * static DestReceiver structs for dest types needing no local state
68 : : * ----------------
69 : : */
70 : : static const DestReceiver donothingDR = {
71 : : donothingReceive, donothingStartup, donothingCleanup, donothingCleanup,
72 : : DestNone
73 : : };
74 : :
75 : : static const DestReceiver debugtupDR = {
76 : : debugtup, debugStartup, donothingCleanup, donothingCleanup,
77 : : DestDebug
78 : : };
79 : :
80 : : static const DestReceiver printsimpleDR = {
81 : : printsimple, printsimple_startup, donothingCleanup, donothingCleanup,
82 : : DestRemoteSimple
83 : : };
84 : :
85 : : static const DestReceiver spi_printtupDR = {
86 : : spi_printtup, spi_dest_startup, donothingCleanup, donothingCleanup,
87 : : DestSPI
88 : : };
89 : :
90 : : /*
91 : : * Globally available receiver for DestNone.
92 : : *
93 : : * It's ok to cast the constness away as any modification of the none receiver
94 : : * would be a bug (which gets easier to catch this way).
95 : : */
96 : : DestReceiver *None_Receiver = (DestReceiver *) &donothingDR;
97 : :
98 : : /* ----------------
99 : : * BeginCommand - initialize the destination at start of command
100 : : * ----------------
101 : : */
102 : : void
1504 alvherre@alvh.no-ip. 103 : 316040 : BeginCommand(CommandTag commandTag, CommandDest dest)
104 : : {
105 : : /* Nothing to do at present */
9209 tgl@sss.pgh.pa.us 106 : 316040 : }
107 : :
108 : : /* ----------------
109 : : * CreateDestReceiver - return appropriate receiver function set for dest
110 : : * ----------------
111 : : */
112 : : DestReceiver *
5614 113 : 464775 : CreateDestReceiver(CommandDest dest)
114 : : {
115 : : /*
116 : : * It's ok to cast the constness away as any modification of the none
117 : : * receiver would be a bug (which gets easier to catch this way).
118 : : */
119 : :
9209 120 [ + + + + : 464775 : switch (dest)
+ + - + +
- - - - ]
121 : : {
6737 alvherre@alvh.no-ip. 122 : 280534 : case DestRemote:
123 : : case DestRemoteExecute:
5614 tgl@sss.pgh.pa.us 124 : 280534 : return printtup_create_DR(dest);
125 : :
2637 rhaas@postgresql.org 126 : 2060 : case DestRemoteSimple:
2007 andres@anarazel.de 127 : 2060 : return unconstify(DestReceiver *, &printsimpleDR);
128 : :
6737 alvherre@alvh.no-ip. 129 : 428 : case DestNone:
2007 andres@anarazel.de 130 : 428 : return unconstify(DestReceiver *, &donothingDR);
131 : :
6737 alvherre@alvh.no-ip. 132 : 29304 : case DestDebug:
2007 andres@anarazel.de 133 : 29304 : return unconstify(DestReceiver *, &debugtupDR);
134 : :
6737 alvherre@alvh.no-ip. 135 : 67278 : case DestSPI:
2007 andres@anarazel.de 136 : 67278 : return unconstify(DestReceiver *, &spi_printtupDR);
137 : :
6737 alvherre@alvh.no-ip. 138 : 22522 : case DestTuplestore:
5614 tgl@sss.pgh.pa.us 139 : 22522 : return CreateTuplestoreDestReceiver();
140 : :
6455 tgl@sss.pgh.pa.us 141 :UBC 0 : case DestIntoRel:
4409 142 : 0 : return CreateIntoRelDestReceiver(NULL);
143 : :
6437 tgl@sss.pgh.pa.us 144 :CBC 160 : case DestCopyOut:
145 : 160 : return CreateCopyDestReceiver();
146 : :
5644 147 : 62489 : case DestSQLFunction:
148 : 62489 : return CreateSQLFunctionDestReceiver();
149 : :
4060 kgrittn@postgresql.o 150 :UBC 0 : case DestTransientRel:
151 : 0 : return CreateTransientRelDestReceiver(InvalidOid);
152 : :
3131 rhaas@postgresql.org 153 : 0 : case DestTupleQueue:
154 : 0 : return CreateTupleQueueDestReceiver(NULL);
155 : :
11 tgl@sss.pgh.pa.us 156 :UNC 0 : case DestExplainSerialize:
157 : 0 : return CreateExplainSerializeDestReceiver(NULL);
158 : : }
159 : :
160 : : /* should never get here */
2007 andres@anarazel.de 161 :UBC 0 : pg_unreachable();
162 : : }
163 : :
164 : : /* ----------------
165 : : * EndCommand - clean up the destination at end of command
166 : : * ----------------
167 : : */
168 : : void
1504 alvherre@alvh.no-ip. 169 :CBC 296877 : EndCommand(const QueryCompletion *qc, CommandDest dest, bool force_undecorated_output)
170 : : {
171 : : char completionTag[COMPLETION_TAG_BUFSIZE];
172 : : Size len;
173 : :
9716 bruce@momjian.us 174 [ + + - ]: 296877 : switch (dest)
175 : : {
6737 alvherre@alvh.no-ip. 176 : 267573 : case DestRemote:
177 : : case DestRemoteExecute:
178 : : case DestRemoteSimple:
179 : :
485 drowley@postgresql.o 180 : 267573 : len = BuildQueryCompletionString(completionTag, qc,
181 : : force_undecorated_output);
229 nathan@postgresql.or 182 :GNC 267573 : pq_putmessage(PqMsg_CommandComplete, completionTag, len + 1);
183 : :
6737 alvherre@alvh.no-ip. 184 :CBC 296877 : case DestNone:
185 : : case DestDebug:
186 : : case DestSPI:
187 : : case DestTuplestore:
188 : : case DestIntoRel:
189 : : case DestCopyOut:
190 : : case DestSQLFunction:
191 : : case DestTransientRel:
192 : : case DestTupleQueue:
193 : : case DestExplainSerialize:
9715 bruce@momjian.us 194 : 296877 : break;
195 : : }
10141 scrappy@hub.org 196 : 296877 : }
197 : :
198 : : /* ----------------
199 : : * EndReplicationCommand - stripped down version of EndCommand
200 : : *
201 : : * For use by replication commands.
202 : : * ----------------
203 : : */
204 : : void
1306 alvherre@alvh.no-ip. 205 : 2417 : EndReplicationCommand(const char *commandTag)
206 : : {
229 nathan@postgresql.or 207 :GNC 2417 : pq_putmessage(PqMsg_CommandComplete, commandTag, strlen(commandTag) + 1);
1306 alvherre@alvh.no-ip. 208 :CBC 2417 : }
209 : :
210 : : /* ----------------
211 : : * NullCommand - tell dest that an empty query string was recognized
212 : : *
213 : : * This ensures that there will be a recognizable end to the response
214 : : * to an Execute message in the extended query protocol.
215 : : * ----------------
216 : : */
217 : : void
10141 scrappy@hub.org 218 : 215 : NullCommand(CommandDest dest)
219 : : {
9716 bruce@momjian.us 220 [ + - - ]: 215 : switch (dest)
221 : : {
6737 alvherre@alvh.no-ip. 222 : 215 : case DestRemote:
223 : : case DestRemoteExecute:
224 : : case DestRemoteSimple:
225 : :
226 : : /* Tell the FE that we saw an empty query string */
236 nathan@postgresql.or 227 :GNC 215 : pq_putemptymessage(PqMsg_EmptyQueryResponse);
9475 bruce@momjian.us 228 :CBC 215 : break;
229 : :
6737 alvherre@alvh.no-ip. 230 :UBC 0 : case DestNone:
231 : : case DestDebug:
232 : : case DestSPI:
233 : : case DestTuplestore:
234 : : case DestIntoRel:
235 : : case DestCopyOut:
236 : : case DestSQLFunction:
237 : : case DestTransientRel:
238 : : case DestTupleQueue:
239 : : case DestExplainSerialize:
9475 bruce@momjian.us 240 : 0 : break;
241 : : }
9475 bruce@momjian.us 242 :CBC 215 : }
243 : :
244 : : /* ----------------
245 : : * ReadyForQuery - tell dest that we are ready for a new query
246 : : *
247 : : * The ReadyForQuery message is sent so that the FE can tell when
248 : : * we are done processing a query string.
249 : : * In versions 3.0 and up, it also carries a transaction state indicator.
250 : : *
251 : : * Note that by flushing the stdio buffer here, we can avoid doing it
252 : : * most other places and thus reduce the number of separate packets sent.
253 : : * ----------------
254 : : */
255 : : void
256 : 311380 : ReadyForQuery(CommandDest dest)
257 : : {
9716 258 [ + + - ]: 311380 : switch (dest)
259 : : {
6737 alvherre@alvh.no-ip. 260 : 285175 : case DestRemote:
261 : : case DestRemoteExecute:
262 : : case DestRemoteSimple:
263 : : {
264 : : StringInfoData buf;
265 : :
236 nathan@postgresql.or 266 :GNC 285175 : pq_beginmessage(&buf, PqMsg_ReadyForQuery);
7659 tgl@sss.pgh.pa.us 267 :CBC 285175 : pq_sendbyte(&buf, TransactionBlockStatusCode());
268 : 285175 : pq_endmessage(&buf);
269 : : }
270 : : /* Flush output at end of cycle in any case. */
9209 271 : 285175 : pq_flush();
9715 bruce@momjian.us 272 : 285175 : break;
273 : :
6737 alvherre@alvh.no-ip. 274 : 26205 : case DestNone:
275 : : case DestDebug:
276 : : case DestSPI:
277 : : case DestTuplestore:
278 : : case DestIntoRel:
279 : : case DestCopyOut:
280 : : case DestSQLFunction:
281 : : case DestTransientRel:
282 : : case DestTupleQueue:
283 : : case DestExplainSerialize:
9715 bruce@momjian.us 284 : 26205 : break;
285 : : }
10141 scrappy@hub.org 286 : 311380 : }
|