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-2026, 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_dr.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
7669 tgl@sss.pgh.pa.us 50 :CBC 660030 : donothingReceive(TupleTableSlot *slot, DestReceiver *self)
51 : : {
3569 rhaas@postgresql.org 52 : 660030 : return true;
53 : : }
54 : :
55 : : static void
8347 tgl@sss.pgh.pa.us 56 : 1792 : donothingStartup(DestReceiver *self, int operation, TupleDesc typeinfo)
57 : : {
9909 58 : 1792 : }
59 : :
60 : : static void
9791 bruce@momjian.us 61 : 502516 : donothingCleanup(DestReceiver *self)
62 : : {
63 : : /* this is used for both shutdown and destroy methods */
9909 tgl@sss.pgh.pa.us 64 : 502516 : }
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
2204 alvherre@alvh.no-ip. 103 : 382125 : BeginCommand(CommandTag commandTag, CommandDest dest)
104 : : {
105 : : /* Nothing to do at present */
9909 tgl@sss.pgh.pa.us 106 : 382125 : }
107 : :
108 : : /* ----------------
109 : : * CreateDestReceiver - return appropriate receiver function set for dest
110 : : * ----------------
111 : : */
112 : : DestReceiver *
6314 113 : 931802 : 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 : :
9909 120 [ + + + + : 931802 : switch (dest)
+ + - + +
- - - - ]
121 : : {
7437 alvherre@alvh.no-ip. 122 : 339986 : case DestRemote:
123 : : case DestRemoteExecute:
6314 tgl@sss.pgh.pa.us 124 : 339986 : return printtup_create_DR(dest);
125 : :
3337 rhaas@postgresql.org 126 : 2434 : case DestRemoteSimple:
2707 andres@anarazel.de 127 : 2434 : return unconstify(DestReceiver *, &printsimpleDR);
128 : :
7437 alvherre@alvh.no-ip. 129 : 592 : case DestNone:
2707 andres@anarazel.de 130 : 592 : return unconstify(DestReceiver *, &donothingDR);
131 : :
7437 alvherre@alvh.no-ip. 132 : 34997 : case DestDebug:
2707 andres@anarazel.de 133 : 34997 : return unconstify(DestReceiver *, &debugtupDR);
134 : :
7437 alvherre@alvh.no-ip. 135 : 482592 : case DestSPI:
2707 andres@anarazel.de 136 : 482592 : return unconstify(DestReceiver *, &spi_printtupDR);
137 : :
7437 alvherre@alvh.no-ip. 138 : 27262 : case DestTuplestore:
6314 tgl@sss.pgh.pa.us 139 : 27262 : return CreateTuplestoreDestReceiver();
140 : :
7155 tgl@sss.pgh.pa.us 141 :UBC 0 : case DestIntoRel:
5109 142 : 0 : return CreateIntoRelDestReceiver(NULL);
143 : :
7137 tgl@sss.pgh.pa.us 144 :CBC 231 : case DestCopyOut:
145 : 231 : return CreateCopyDestReceiver();
146 : :
6344 147 : 43708 : case DestSQLFunction:
148 : 43708 : return CreateSQLFunctionDestReceiver();
149 : :
4760 kgrittn@postgresql.o 150 :UBC 0 : case DestTransientRel:
151 : 0 : return CreateTransientRelDestReceiver(InvalidOid);
152 : :
3831 rhaas@postgresql.org 153 : 0 : case DestTupleQueue:
154 : 0 : return CreateTupleQueueDestReceiver(NULL);
155 : :
711 tgl@sss.pgh.pa.us 156 : 0 : case DestExplainSerialize:
157 : 0 : return CreateExplainSerializeDestReceiver(NULL);
158 : : }
159 : :
160 : : /* should never get here */
2707 andres@anarazel.de 161 : 0 : pg_unreachable();
162 : : }
163 : :
164 : : /* ----------------
165 : : * EndCommand - clean up the destination at end of command
166 : : * ----------------
167 : : */
168 : : void
2204 alvherre@alvh.no-ip. 169 :CBC 360172 : EndCommand(const QueryCompletion *qc, CommandDest dest, bool force_undecorated_output)
170 : : {
171 : : char completionTag[COMPLETION_TAG_BUFSIZE];
172 : : Size len;
173 : :
10416 bruce@momjian.us 174 [ + + - ]: 360172 : switch (dest)
175 : : {
7437 alvherre@alvh.no-ip. 176 : 325175 : case DestRemote:
177 : : case DestRemoteExecute:
178 : : case DestRemoteSimple:
179 : :
1185 drowley@postgresql.o 180 : 325175 : len = BuildQueryCompletionString(completionTag, qc,
181 : : force_undecorated_output);
929 nathan@postgresql.or 182 : 325175 : pq_putmessage(PqMsg_CommandComplete, completionTag, len + 1);
20 peter@eisentraut.org 183 :GNC 325175 : break;
184 : :
7437 alvherre@alvh.no-ip. 185 :CBC 34997 : case DestNone:
186 : : case DestDebug:
187 : : case DestSPI:
188 : : case DestTuplestore:
189 : : case DestIntoRel:
190 : : case DestCopyOut:
191 : : case DestSQLFunction:
192 : : case DestTransientRel:
193 : : case DestTupleQueue:
194 : : case DestExplainSerialize:
10415 bruce@momjian.us 195 : 34997 : break;
196 : : }
10841 scrappy@hub.org 197 : 360172 : }
198 : :
199 : : /* ----------------
200 : : * EndReplicationCommand - stripped down version of EndCommand
201 : : *
202 : : * For use by replication commands.
203 : : * ----------------
204 : : */
205 : : void
2006 alvherre@alvh.no-ip. 206 : 2881 : EndReplicationCommand(const char *commandTag)
207 : : {
929 nathan@postgresql.or 208 : 2881 : pq_putmessage(PqMsg_CommandComplete, commandTag, strlen(commandTag) + 1);
2006 alvherre@alvh.no-ip. 209 : 2881 : }
210 : :
211 : : /* ----------------
212 : : * NullCommand - tell dest that an empty query string was recognized
213 : : *
214 : : * This ensures that there will be a recognizable end to the response
215 : : * to an Execute message in the extended query protocol.
216 : : * ----------------
217 : : */
218 : : void
10841 scrappy@hub.org 219 : 1027 : NullCommand(CommandDest dest)
220 : : {
10416 bruce@momjian.us 221 [ + + - ]: 1027 : switch (dest)
222 : : {
7437 alvherre@alvh.no-ip. 223 : 1026 : case DestRemote:
224 : : case DestRemoteExecute:
225 : : case DestRemoteSimple:
226 : :
227 : : /* Tell the FE that we saw an empty query string */
936 nathan@postgresql.or 228 : 1026 : pq_putemptymessage(PqMsg_EmptyQueryResponse);
10175 bruce@momjian.us 229 : 1026 : break;
230 : :
7437 alvherre@alvh.no-ip. 231 : 1 : case DestNone:
232 : : case DestDebug:
233 : : case DestSPI:
234 : : case DestTuplestore:
235 : : case DestIntoRel:
236 : : case DestCopyOut:
237 : : case DestSQLFunction:
238 : : case DestTransientRel:
239 : : case DestTupleQueue:
240 : : case DestExplainSerialize:
10175 bruce@momjian.us 241 : 1 : break;
242 : : }
243 : 1027 : }
244 : :
245 : : /* ----------------
246 : : * ReadyForQuery - tell dest that we are ready for a new query
247 : : *
248 : : * The ReadyForQuery message is sent so that the FE can tell when
249 : : * we are done processing a query string.
250 : : * In versions 3.0 and up, it also carries a transaction state indicator.
251 : : *
252 : : * Note that by flushing the stdio buffer here, we can avoid doing it
253 : : * most other places and thus reduce the number of separate packets sent.
254 : : * ----------------
255 : : */
256 : : void
257 : 377989 : ReadyForQuery(CommandDest dest)
258 : : {
10416 259 [ + + - ]: 377989 : switch (dest)
260 : : {
7437 alvherre@alvh.no-ip. 261 : 347039 : case DestRemote:
262 : : case DestRemoteExecute:
263 : : case DestRemoteSimple:
264 : : {
265 : : StringInfoData buf;
266 : :
936 nathan@postgresql.or 267 : 347039 : pq_beginmessage(&buf, PqMsg_ReadyForQuery);
8359 tgl@sss.pgh.pa.us 268 : 347039 : pq_sendbyte(&buf, TransactionBlockStatusCode());
269 : 347039 : pq_endmessage(&buf);
270 : : }
271 : : /* Flush output at end of cycle in any case. */
9909 272 : 347039 : pq_flush();
10415 bruce@momjian.us 273 : 347039 : break;
274 : :
7437 alvherre@alvh.no-ip. 275 : 30950 : case DestNone:
276 : : case DestDebug:
277 : : case DestSPI:
278 : : case DestTuplestore:
279 : : case DestIntoRel:
280 : : case DestCopyOut:
281 : : case DestSQLFunction:
282 : : case DestTransientRel:
283 : : case DestTupleQueue:
284 : : case DestExplainSerialize:
10415 bruce@momjian.us 285 : 30950 : break;
286 : : }
10841 scrappy@hub.org 287 : 377989 : }
|