Age Owner TLA Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * dest.c
4 : * support for communication destinations
5 : *
6 : *
7 : * Portions Copyright (c) 1996-2023, 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
6598 tgl 50 CBC 659942 : donothingReceive(TupleTableSlot *slot, DestReceiver *self)
51 : {
2498 rhaas 52 659942 : return true;
53 : }
54 :
55 : static void
7276 tgl 56 21660 : donothingStartup(DestReceiver *self, int operation, TupleDesc typeinfo)
57 : {
8838 58 21660 : }
59 :
60 : static void
8720 bruce 61 323264 : donothingCleanup(DestReceiver *self)
62 : {
63 : /* this is used for both shutdown and destroy methods */
8838 tgl 64 323264 : }
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
1133 alvherre 103 492490 : BeginCommand(CommandTag commandTag, CommandDest dest)
104 : {
105 : /* Nothing to do at present */
8838 tgl 106 492490 : }
107 :
108 : /* ----------------
109 : * CreateDestReceiver - return appropriate receiver function set for dest
110 : * ----------------
111 : */
112 : DestReceiver *
5243 113 608596 : 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 :
8838 120 608596 : switch (dest)
121 : {
6366 alvherre 122 248357 : case DestRemote:
123 : case DestRemoteExecute:
5243 tgl 124 248357 : return printtup_create_DR(dest);
125 :
2266 rhaas 126 1717 : case DestRemoteSimple:
1636 andres 127 1717 : return unconstify(DestReceiver *, &printsimpleDR);
128 :
6366 alvherre 129 632 : case DestNone:
1636 andres 130 632 : return unconstify(DestReceiver *, &donothingDR);
131 :
6366 alvherre 132 238461 : case DestDebug:
1636 andres 133 238461 : return unconstify(DestReceiver *, &debugtupDR);
134 :
6366 alvherre 135 61956 : case DestSPI:
1636 andres 136 61956 : return unconstify(DestReceiver *, &spi_printtupDR);
137 :
6366 alvherre 138 20283 : case DestTuplestore:
5243 tgl 139 20283 : return CreateTuplestoreDestReceiver();
140 :
6084 tgl 141 UBC 0 : case DestIntoRel:
4038 142 0 : return CreateIntoRelDestReceiver(NULL);
143 :
6066 tgl 144 CBC 156 : case DestCopyOut:
145 156 : return CreateCopyDestReceiver();
146 :
5273 147 37034 : case DestSQLFunction:
148 37034 : return CreateSQLFunctionDestReceiver();
149 :
3689 kgrittn 150 UBC 0 : case DestTransientRel:
151 0 : return CreateTransientRelDestReceiver(InvalidOid);
152 :
2760 rhaas 153 0 : case DestTupleQueue:
154 0 : return CreateTupleQueueDestReceiver(NULL);
155 : }
156 :
157 : /* should never get here */
1636 andres 158 0 : pg_unreachable();
159 : }
160 :
161 : /* ----------------
162 : * EndCommand - clean up the destination at end of command
163 : * ----------------
164 : */
165 : void
1133 alvherre 166 CBC 475513 : EndCommand(const QueryCompletion *qc, CommandDest dest, bool force_undecorated_output)
167 : {
168 : char completionTag[COMPLETION_TAG_BUFSIZE];
169 : Size len;
1133 alvherre 170 ECB :
9345 bruce 171 GIC 475513 : switch (dest)
9345 bruce 172 ECB : {
6366 alvherre 173 GIC 237052 : case DestRemote:
174 : case DestRemoteExecute:
175 : case DestRemoteSimple:
4790 bruce 176 ECB :
114 drowley 177 GNC 237052 : len = BuildQueryCompletionString(completionTag, qc,
178 : force_undecorated_output);
179 237052 : pq_putmessage('C', completionTag, len + 1);
180 :
6366 alvherre 181 CBC 475513 : case DestNone:
182 : case DestDebug:
6366 alvherre 183 ECB : case DestSPI:
184 : case DestTuplestore:
185 : case DestIntoRel:
186 : case DestCopyOut:
187 : case DestSQLFunction:
188 : case DestTransientRel:
189 : case DestTupleQueue:
9344 bruce 190 GIC 475513 : break;
191 : }
9770 scrappy 192 475513 : }
193 :
935 alvherre 194 ECB : /* ----------------
195 : * EndReplicationCommand - stripped down version of EndCommand
196 : *
197 : * For use by replication commands.
198 : * ----------------
199 : */
200 : void
935 alvherre 201 GIC 2015 : EndReplicationCommand(const char *commandTag)
202 : {
935 alvherre 203 CBC 2015 : pq_putmessage('C', commandTag, strlen(commandTag) + 1);
204 2015 : }
205 :
9770 scrappy 206 EUB : /* ----------------
207 : * NullCommand - tell dest that an empty query string was recognized
208 : *
209 : * This ensures that there will be a recognizable end to the response
210 : * to an Execute message in the extended query protocol.
211 : * ----------------
212 : */
213 : void
9770 scrappy 214 GIC 169 : NullCommand(CommandDest dest)
9770 scrappy 215 EUB : {
9345 bruce 216 GIC 169 : switch (dest)
9345 bruce 217 ECB : {
6366 alvherre 218 GIC 169 : case DestRemote:
219 : case DestRemoteExecute:
220 : case DestRemoteSimple:
221 :
222 : /* Tell the FE that we saw an empty query string */
766 heikki.linnakangas 223 169 : pq_putemptymessage('I');
9104 bruce 224 169 : break;
225 :
6366 alvherre 226 UIC 0 : case DestNone:
227 : case DestDebug:
228 : case DestSPI:
229 : case DestTuplestore:
230 : case DestIntoRel:
6066 tgl 231 ECB : case DestCopyOut:
232 : case DestSQLFunction:
3689 kgrittn 233 : case DestTransientRel:
234 : case DestTupleQueue:
9104 bruce 235 LBC 0 : break;
236 : }
9104 bruce 237 GIC 169 : }
238 :
239 : /* ----------------
240 : * ReadyForQuery - tell dest that we are ready for a new query
9104 bruce 241 ECB : *
2371 tgl 242 : * The ReadyForQuery message is sent so that the FE can tell when
243 : * we are done processing a query string.
244 : * In versions 3.0 and up, it also carries a transaction state indicator.
245 : *
9104 bruce 246 : * Note that by flushing the stdio buffer here, we can avoid doing it
247 : * most other places and thus reduce the number of separate packets sent.
248 : * ----------------
249 : */
250 : void
9104 bruce 251 GIC 462595 : ReadyForQuery(CommandDest dest)
252 : {
9345 253 462595 : switch (dest)
254 : {
6366 alvherre 255 250486 : case DestRemote:
256 : case DestRemoteExecute:
257 : case DestRemoteSimple:
7288 tgl 258 ECB : {
259 : StringInfoData buf;
260 :
7288 tgl 261 GIC 250486 : pq_beginmessage(&buf, 'Z');
262 250486 : pq_sendbyte(&buf, TransactionBlockStatusCode());
263 250486 : pq_endmessage(&buf);
264 : }
265 : /* Flush output at end of cycle in any case. */
8838 266 250486 : pq_flush();
9344 bruce 267 250486 : break;
268 :
6366 alvherre 269 212109 : case DestNone:
270 : case DestDebug:
271 : case DestSPI:
272 : case DestTuplestore:
273 : case DestIntoRel:
274 : case DestCopyOut:
275 : case DestSQLFunction:
276 : case DestTransientRel:
277 : case DestTupleQueue:
9344 bruce 278 212109 : break;
279 : }
9770 scrappy 280 462595 : }
|