PostgreSQL Source Code  git master
dest.c
Go to the documentation of this file.
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"
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
51 {
52  return true;
53 }
54 
55 static void
56 donothingStartup(DestReceiver *self, int operation, TupleDesc typeinfo)
57 {
58 }
59 
60 static void
62 {
63  /* this is used for both shutdown and destroy methods */
64 }
65 
66 /* ----------------
67  * static DestReceiver structs for dest types needing no local state
68  * ----------------
69  */
72  DestNone
73 };
74 
77  DestDebug
78 };
79 
83 };
84 
87  DestSPI
88 };
89 
90 /* Globally available receiver for DestNone */
92 
93 
94 /* ----------------
95  * BeginCommand - initialize the destination at start of command
96  * ----------------
97  */
98 void
99 BeginCommand(const char *commandTag, CommandDest dest)
100 {
101  /* Nothing to do at present */
102 }
103 
104 /* ----------------
105  * CreateDestReceiver - return appropriate receiver function set for dest
106  * ----------------
107  */
108 DestReceiver *
110 {
111  switch (dest)
112  {
113  case DestRemote:
114  case DestRemoteExecute:
115  return printtup_create_DR(dest);
116 
117  case DestRemoteSimple:
118  return &printsimpleDR;
119 
120  case DestNone:
121  return &donothingDR;
122 
123  case DestDebug:
124  return &debugtupDR;
125 
126  case DestSPI:
127  return &spi_printtupDR;
128 
129  case DestTuplestore:
131 
132  case DestIntoRel:
133  return CreateIntoRelDestReceiver(NULL);
134 
135  case DestCopyOut:
136  return CreateCopyDestReceiver();
137 
138  case DestSQLFunction:
140 
141  case DestTransientRel:
143 
144  case DestTupleQueue:
145  return CreateTupleQueueDestReceiver(NULL);
146  }
147 
148  /* should never get here */
149  return &donothingDR;
150 }
151 
152 /* ----------------
153  * EndCommand - clean up the destination at end of command
154  * ----------------
155  */
156 void
157 EndCommand(const char *commandTag, CommandDest dest)
158 {
159  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  pq_putmessage('C', commandTag, strlen(commandTag) + 1);
170  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  break;
182  }
183 }
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
199 {
200  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  */
211  pq_putemptymessage('I');
212  else
213  pq_putmessage('I', "", 1);
214  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  break;
226  }
227 }
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
242 {
243  switch (dest)
244  {
245  case DestRemote:
246  case DestRemoteExecute:
247  case DestRemoteSimple:
249  {
251 
252  pq_beginmessage(&buf, 'Z');
254  pq_endmessage(&buf);
255  }
256  else
257  pq_putemptymessage('Z');
258  /* Flush output at end of cycle in any case. */
259  pq_flush();
260  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  break;
272  }
273 }
#define pq_flush()
Definition: libpq.h:39
CommandDest
Definition: dest.h:86
Definition: dest.h:93
static DestReceiver debugtupDR
Definition: dest.c:75
void pq_putemptymessage(char msgtype)
Definition: pqformat.c:390
void BeginCommand(const char *commandTag, CommandDest dest)
Definition: dest.c:99
static void pq_sendbyte(StringInfo buf, int8 byt)
Definition: pqformat.h:164
#define PG_PROTOCOL_MAJOR(v)
Definition: pqcomm.h:104
DestReceiver * None_Receiver
Definition: dest.c:91
char TransactionBlockStatusCode(void)
Definition: xact.c:4479
bool printsimple(TupleTableSlot *slot, DestReceiver *self)
Definition: printsimple.c:59
void pq_beginmessage(StringInfo buf, char msgtype)
Definition: pqformat.c:87
static bool donothingReceive(TupleTableSlot *slot, DestReceiver *self)
Definition: dest.c:50
void EndCommand(const char *commandTag, CommandDest dest)
Definition: dest.c:157
Definition: dest.h:88
static char * buf
Definition: pg_test_fsync.c:67
DestReceiver * printtup_create_DR(CommandDest dest)
Definition: printtup.c:78
DestReceiver * CreateDestReceiver(CommandDest dest)
Definition: dest.c:109
Definition: dest.h:89
static DestReceiver donothingDR
Definition: dest.c:70
void spi_dest_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: spi.c:1657
DestReceiver * CreateIntoRelDestReceiver(IntoClause *intoClause)
Definition: createas.c:423
static DestReceiver spi_printtupDR
Definition: dest.c:85
void printsimple_startup(DestReceiver *self, int operation, TupleDesc tupdesc)
Definition: printsimple.c:31
DestReceiver * CreateSQLFunctionDestReceiver(void)
Definition: functions.c:1895
#define InvalidOid
Definition: postgres_ext.h:36
static void donothingStartup(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: dest.c:56
bool debugtup(TupleTableSlot *slot, DestReceiver *self)
Definition: printtup.c:606
DestReceiver * CreateTuplestoreDestReceiver(void)
DestReceiver * CreateTransientRelDestReceiver(Oid transientoid)
Definition: matview.c:443
void ReadyForQuery(CommandDest dest)
Definition: dest.c:241
void pq_endmessage(StringInfo buf)
Definition: pqformat.c:298
DestReceiver * CreateCopyDestReceiver(void)
Definition: copy.c:4850
#define pq_putmessage(msgtype, s, len)
Definition: libpq.h:42
DestReceiver * CreateTupleQueueDestReceiver(shm_mq_handle *handle)
Definition: tqueue.c:115
void debugStartup(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: printtup.c:588
ProtocolVersion FrontendProtocol
Definition: globals.c:27
static DestReceiver printsimpleDR
Definition: dest.c:80
static void donothingCleanup(DestReceiver *self)
Definition: dest.c:61
bool spi_printtup(TupleTableSlot *slot, DestReceiver *self)
Definition: spi.c:1704
void NullCommand(CommandDest dest)
Definition: dest.c:198