YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/postgres/src/backend/tcop/dest.c
Line
Count
Source (jump to first uncovered line)
1
/*-------------------------------------------------------------------------
2
 *
3
 * dest.c
4
 *    support for communication destinations
5
 *
6
 *
7
 * Portions Copyright (c) 1996-2018, 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
donothingReceive(TupleTableSlot *slot, DestReceiver *self)
51
4.82M
{
52
4.82M
  return true;
53
4.82M
}
54
55
static void
56
donothingStartup(DestReceiver *self, int operation, TupleDesc typeinfo)
57
643
{
58
643
}
59
60
static void
61
donothingCleanup(DestReceiver *self)
62
22.4k
{
63
  /* this is used for both shutdown and destroy methods */
64
22.4k
}
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
BeginCommand(const char *commandTag, CommandDest dest)
100
678k
{
101
  /* Nothing to do at present */
102
678k
}
103
104
/* ----------------
105
 *    CreateDestReceiver - return appropriate receiver function set for dest
106
 * ----------------
107
 */
108
DestReceiver *
109
CreateDestReceiver(CommandDest dest)
110
769k
{
111
769k
  switch (dest)
112
769k
  {
113
144k
    case DestRemote:
114
675k
    case DestRemoteExecute:
115
675k
      return printtup_create_DR(dest);
116
117
0
    case DestRemoteSimple:
118
0
      return &printsimpleDR;
119
120
101
    case DestNone:
121
101
      return &donothingDR;
122
123
1.02k
    case DestDebug:
124
1.02k
      return &debugtupDR;
125
126
76.4k
    case DestSPI:
127
76.4k
      return &spi_printtupDR;
128
129
11.8k
    case DestTuplestore:
130
11.8k
      return CreateTuplestoreDestReceiver();
131
132
0
    case DestIntoRel:
133
0
      return CreateIntoRelDestReceiver(NULL);
134
135
46
    case DestCopyOut:
136
46
      return CreateCopyDestReceiver();
137
138
4.62k
    case DestSQLFunction:
139
4.62k
      return CreateSQLFunctionDestReceiver();
140
141
0
    case DestTransientRel:
142
0
      return CreateTransientRelDestReceiver(InvalidOid);
143
144
0
    case DestTupleQueue:
145
0
      return CreateTupleQueueDestReceiver(NULL);
146
769k
  }
147
148
  /* should never get here */
149
0
  return &donothingDR;
150
769k
}
151
152
/* ----------------
153
 *    EndCommand - clean up the destination at end of command
154
 * ----------------
155
 */
156
void
157
EndCommand(const char *commandTag, CommandDest dest)
158
563k
{
159
563k
  switch (dest)
160
563k
  {
161
123k
    case DestRemote:
162
562k
    case DestRemoteExecute:
163
562k
    case DestRemoteSimple:
164
165
      /*
166
       * We assume the commandTag is plain ASCII and therefore requires
167
       * no encoding conversion.
168
       */
169
562k
      pq_putmessage('C', commandTag, strlen(commandTag) + 1);
170
562k
      break;
171
172
0
    case DestNone:
173
1.02k
    case DestDebug:
174
1.02k
    case DestSPI:
175
1.02k
    case DestTuplestore:
176
1.02k
    case DestIntoRel:
177
1.02k
    case DestCopyOut:
178
1.02k
    case DestSQLFunction:
179
1.02k
    case DestTransientRel:
180
1.02k
    case DestTupleQueue:
181
1.02k
      break;
182
563k
  }
183
563k
}
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
NullCommand(CommandDest dest)
199
64
{
200
64
  switch (dest)
201
64
  {
202
10
    case DestRemote:
203
64
    case DestRemoteExecute:
204
64
    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
64
      if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
211
64
        pq_putemptymessage('I');
212
0
      else
213
0
        pq_putmessage('I', "", 1);
214
64
      break;
215
216
0
    case DestNone:
217
0
    case DestDebug:
218
0
    case DestSPI:
219
0
    case DestTuplestore:
220
0
    case DestIntoRel:
221
0
    case DestCopyOut:
222
0
    case DestSQLFunction:
223
0
    case DestTransientRel:
224
0
    case DestTupleQueue:
225
0
      break;
226
64
  }
227
64
}
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
ReadyForQuery(CommandDest dest)
242
588k
{
243
588k
  switch (dest)
244
588k
  {
245
587k
    case DestRemote:
246
587k
    case DestRemoteExecute:
247
587k
    case DestRemoteSimple:
248
587k
      if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
249
587k
      {
250
587k
        StringInfoData buf;
251
252
587k
        pq_beginmessage(&buf, 'Z');
253
587k
        pq_sendbyte(&buf, TransactionBlockStatusCode());
254
587k
        pq_endmessage(&buf);
255
587k
      }
256
25
      else
257
25
        pq_putemptymessage('Z');
258
      /* Flush output at end of cycle in any case. */
259
587k
      pq_flush();
260
587k
      break;
261
262
0
    case DestNone:
263
824
    case DestDebug:
264
824
    case DestSPI:
265
824
    case DestTuplestore:
266
824
    case DestIntoRel:
267
824
    case DestCopyOut:
268
824
    case DestSQLFunction:
269
824
    case DestTransientRel:
270
824
    case DestTupleQueue:
271
824
      break;
272
588k
  }
273
588k
}