PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
explain_dr.c File Reference
#include "postgres.h"
#include "commands/explain.h"
#include "commands/explain_dr.h"
#include "libpq/pqformat.h"
#include "libpq/protocol.h"
#include "utils/lsyscache.h"
Include dependency graph for explain_dr.c:

Go to the source code of this file.

Data Structures

struct  SerializeDestReceiver
 

Typedefs

typedef struct SerializeDestReceiver SerializeDestReceiver
 

Functions

static void serialize_prepare_info (SerializeDestReceiver *receiver, TupleDesc typeinfo, int nattrs)
 
static bool serializeAnalyzeReceive (TupleTableSlot *slot, DestReceiver *self)
 
static void serializeAnalyzeStartup (DestReceiver *self, int operation, TupleDesc typeinfo)
 
static void serializeAnalyzeShutdown (DestReceiver *self)
 
static void serializeAnalyzeDestroy (DestReceiver *self)
 
DestReceiverCreateExplainSerializeDestReceiver (ExplainState *es)
 
SerializeMetrics GetSerializationMetrics (DestReceiver *dest)
 

Typedef Documentation

◆ SerializeDestReceiver

Function Documentation

◆ CreateExplainSerializeDestReceiver()

DestReceiver * CreateExplainSerializeDestReceiver ( ExplainState es)

Definition at line 273 of file explain_dr.c.

274{
276
278
284
285 self->es = es;
286
287 return (DestReceiver *) self;
288}
@ DestExplainSerialize
Definition: dest.h:99
static void serializeAnalyzeStartup(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: explain_dr.c:207
static void serializeAnalyzeDestroy(DestReceiver *self)
Definition: explain_dr.c:264
static bool serializeAnalyzeReceive(TupleTableSlot *slot, DestReceiver *self)
Definition: explain_dr.c:104
static void serializeAnalyzeShutdown(DestReceiver *self)
Definition: explain_dr.c:243
void * palloc0(Size size)
Definition: mcxt.c:1347
ExplainState * es
Definition: explain_dr.c:34
DestReceiver pub
Definition: explain_dr.c:33
void(* rStartup)(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: dest.h:121
void(* rShutdown)(DestReceiver *self)
Definition: dest.h:124
bool(* receiveSlot)(TupleTableSlot *slot, DestReceiver *self)
Definition: dest.h:118
void(* rDestroy)(DestReceiver *self)
Definition: dest.h:126
CommandDest mydest
Definition: dest.h:128

References DestExplainSerialize, SerializeDestReceiver::es, _DestReceiver::mydest, palloc0(), SerializeDestReceiver::pub, _DestReceiver::rDestroy, _DestReceiver::receiveSlot, _DestReceiver::rShutdown, _DestReceiver::rStartup, serializeAnalyzeDestroy(), serializeAnalyzeReceive(), serializeAnalyzeShutdown(), and serializeAnalyzeStartup().

Referenced by CreateDestReceiver(), and ExplainOnePlan().

◆ GetSerializationMetrics()

SerializeMetrics GetSerializationMetrics ( DestReceiver dest)

Definition at line 298 of file explain_dr.c.

299{
300 SerializeMetrics empty;
301
302 if (dest->mydest == DestExplainSerialize)
303 return ((SerializeDestReceiver *) dest)->metrics;
304
305 memset(&empty, 0, sizeof(SerializeMetrics));
307
308 return empty;
309}
#define INSTR_TIME_SET_ZERO(t)
Definition: instr_time.h:172
instr_time timeSpent
Definition: explain_dr.h:25

References generate_unaccent_rules::dest, DestExplainSerialize, INSTR_TIME_SET_ZERO, and SerializeMetrics::timeSpent.

Referenced by ExplainOnePlan().

◆ serialize_prepare_info()

static void serialize_prepare_info ( SerializeDestReceiver receiver,
TupleDesc  typeinfo,
int  nattrs 
)
static

Definition at line 51 of file explain_dr.c.

53{
54 /* get rid of any old data */
55 if (receiver->finfos)
56 pfree(receiver->finfos);
57 receiver->finfos = NULL;
58
59 receiver->attrinfo = typeinfo;
60 receiver->nattrs = nattrs;
61 if (nattrs <= 0)
62 return;
63
64 receiver->finfos = (FmgrInfo *) palloc0(nattrs * sizeof(FmgrInfo));
65
66 for (int i = 0; i < nattrs; i++)
67 {
68 FmgrInfo *finfo = receiver->finfos + i;
69 Form_pg_attribute attr = TupleDescAttr(typeinfo, i);
70 Oid typoutput;
71 Oid typsend;
72 bool typisvarlena;
73
74 if (receiver->format == 0)
75 {
76 /* wire protocol format text */
77 getTypeOutputInfo(attr->atttypid,
78 &typoutput,
79 &typisvarlena);
80 fmgr_info(typoutput, finfo);
81 }
82 else if (receiver->format == 1)
83 {
84 /* wire protocol format binary */
85 getTypeBinaryOutputInfo(attr->atttypid,
86 &typsend,
87 &typisvarlena);
88 fmgr_info(typsend, finfo);
89 }
90 else
92 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
93 errmsg("unsupported format code: %d", receiver->format)));
94 }
95}
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition: fmgr.c:127
int i
Definition: isn.c:74
void getTypeBinaryOutputInfo(Oid type, Oid *typSend, bool *typIsVarlena)
Definition: lsyscache.c:3012
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2946
void pfree(void *pointer)
Definition: mcxt.c:1524
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
unsigned int Oid
Definition: postgres_ext.h:32
Definition: fmgr.h:57
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:154

References SerializeDestReceiver::attrinfo, ereport, errcode(), errmsg(), ERROR, SerializeDestReceiver::finfos, fmgr_info(), SerializeDestReceiver::format, getTypeBinaryOutputInfo(), getTypeOutputInfo(), i, SerializeDestReceiver::nattrs, palloc0(), pfree(), and TupleDescAttr().

Referenced by serializeAnalyzeReceive().

◆ serializeAnalyzeDestroy()

static void serializeAnalyzeDestroy ( DestReceiver self)
static

Definition at line 264 of file explain_dr.c.

265{
266 pfree(self);
267}

References pfree().

Referenced by CreateExplainSerializeDestReceiver().

◆ serializeAnalyzeReceive()

static bool serializeAnalyzeReceive ( TupleTableSlot slot,
DestReceiver self 
)
static

Definition at line 104 of file explain_dr.c.

105{
106 TupleDesc typeinfo = slot->tts_tupleDescriptor;
108 MemoryContext oldcontext;
109 StringInfo buf = &myState->buf;
110 int natts = typeinfo->natts;
112 end;
113 BufferUsage instr_start;
114
115 /* only measure time, buffers if requested */
116 if (myState->es->timing)
118 if (myState->es->buffers)
119 instr_start = pgBufferUsage;
120
121 /* Set or update my derived attribute info, if needed */
122 if (myState->attrinfo != typeinfo || myState->nattrs != natts)
123 serialize_prepare_info(myState, typeinfo, natts);
124
125 /* Make sure the tuple is fully deconstructed */
126 slot_getallattrs(slot);
127
128 /* Switch into per-row context so we can recover memory below */
129 oldcontext = MemoryContextSwitchTo(myState->tmpcontext);
130
131 /*
132 * Prepare a DataRow message (note buffer is in per-query context)
133 *
134 * Note that we fill a StringInfo buffer the same as printtup() does, so
135 * as to capture the costs of manipulating the strings accurately.
136 */
138
139 pq_sendint16(buf, natts);
140
141 /*
142 * send the attributes of this tuple
143 */
144 for (int i = 0; i < natts; i++)
145 {
146 FmgrInfo *finfo = myState->finfos + i;
147 Datum attr = slot->tts_values[i];
148
149 if (slot->tts_isnull[i])
150 {
151 pq_sendint32(buf, -1);
152 continue;
153 }
154
155 if (myState->format == 0)
156 {
157 /* Text output */
158 char *outputstr;
159
160 outputstr = OutputFunctionCall(finfo, attr);
161 pq_sendcountedtext(buf, outputstr, strlen(outputstr));
162 }
163 else
164 {
165 /* Binary output */
166 bytea *outputbytes;
167
168 outputbytes = SendFunctionCall(finfo, attr);
169 pq_sendint32(buf, VARSIZE(outputbytes) - VARHDRSZ);
170 pq_sendbytes(buf, VARDATA(outputbytes),
171 VARSIZE(outputbytes) - VARHDRSZ);
172 }
173 }
174
175 /*
176 * We mustn't call pq_endmessage_reuse(), since that would actually send
177 * the data to the client. Just count the data, instead. We can leave
178 * the buffer alone; it'll be reset on the next iteration (as would also
179 * happen in printtup()).
180 */
181 myState->metrics.bytesSent += buf->len;
182
183 /* Return to caller's context, and flush row's temporary memory */
184 MemoryContextSwitchTo(oldcontext);
186
187 /* Update timing data */
188 if (myState->es->timing)
189 {
192 }
193
194 /* Update buffer metrics */
195 if (myState->es->buffers)
198 &instr_start);
199
200 return true;
201}
#define VARHDRSZ
Definition: c.h:663
static void serialize_prepare_info(SerializeDestReceiver *receiver, TupleDesc typeinfo, int nattrs)
Definition: explain_dr.c:51
bytea * SendFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1744
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1683
return str start
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:122
#define INSTR_TIME_ACCUM_DIFF(x, y, z)
Definition: instr_time.h:184
BufferUsage pgBufferUsage
Definition: instrument.c:20
void BufferUsageAccumDiff(BufferUsage *dst, const BufferUsage *add, const BufferUsage *sub)
Definition: instrument.c:248
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:383
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
static char * buf
Definition: pg_test_fsync.c:72
uintptr_t Datum
Definition: postgres.h:69
void pq_sendbytes(StringInfo buf, const void *data, int datalen)
Definition: pqformat.c:126
void pq_beginmessage_reuse(StringInfo buf, char msgtype)
Definition: pqformat.c:109
void pq_sendcountedtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:142
static void pq_sendint32(StringInfo buf, uint32 i)
Definition: pqformat.h:144
static void pq_sendint16(StringInfo buf, uint16 i)
Definition: pqformat.h:136
#define PqMsg_DataRow
Definition: protocol.h:43
bool timing
Definition: explain.h:53
bool buffers
Definition: explain.h:51
SerializeMetrics metrics
Definition: explain_dr.c:41
StringInfoData buf
Definition: explain_dr.c:40
MemoryContext tmpcontext
Definition: explain_dr.c:39
uint64 bytesSent
Definition: explain_dr.h:24
BufferUsage bufferUsage
Definition: explain_dr.h:26
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:123
bool * tts_isnull
Definition: tuptable.h:127
Datum * tts_values
Definition: tuptable.h:125
Definition: c.h:658
static void slot_getallattrs(TupleTableSlot *slot)
Definition: tuptable.h:368
#define VARDATA(PTR)
Definition: varatt.h:278
#define VARSIZE(PTR)
Definition: varatt.h:279

References SerializeDestReceiver::attrinfo, SerializeDestReceiver::buf, buf, ExplainState::buffers, SerializeMetrics::bufferUsage, BufferUsageAccumDiff(), SerializeMetrics::bytesSent, SerializeDestReceiver::es, SerializeDestReceiver::finfos, SerializeDestReceiver::format, i, INSTR_TIME_ACCUM_DIFF, INSTR_TIME_SET_CURRENT, MemoryContextReset(), MemoryContextSwitchTo(), SerializeDestReceiver::metrics, SerializeDestReceiver::nattrs, TupleDescData::natts, OutputFunctionCall(), pgBufferUsage, pq_beginmessage_reuse(), pq_sendbytes(), pq_sendcountedtext(), pq_sendint16(), pq_sendint32(), PqMsg_DataRow, SendFunctionCall(), serialize_prepare_info(), slot_getallattrs(), start, SerializeMetrics::timeSpent, ExplainState::timing, SerializeDestReceiver::tmpcontext, TupleTableSlot::tts_isnull, TupleTableSlot::tts_tupleDescriptor, TupleTableSlot::tts_values, VARDATA, VARHDRSZ, and VARSIZE.

Referenced by CreateExplainSerializeDestReceiver().

◆ serializeAnalyzeShutdown()

static void serializeAnalyzeShutdown ( DestReceiver self)
static

Definition at line 243 of file explain_dr.c.

244{
245 SerializeDestReceiver *receiver = (SerializeDestReceiver *) self;
246
247 if (receiver->finfos)
248 pfree(receiver->finfos);
249 receiver->finfos = NULL;
250
251 if (receiver->buf.data)
252 pfree(receiver->buf.data);
253 receiver->buf.data = NULL;
254
255 if (receiver->tmpcontext)
257 receiver->tmpcontext = NULL;
258}
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:454

References SerializeDestReceiver::buf, StringInfoData::data, SerializeDestReceiver::finfos, MemoryContextDelete(), pfree(), and SerializeDestReceiver::tmpcontext.

Referenced by CreateExplainSerializeDestReceiver().

◆ serializeAnalyzeStartup()

static void serializeAnalyzeStartup ( DestReceiver self,
int  operation,
TupleDesc  typeinfo 
)
static

Definition at line 207 of file explain_dr.c.

208{
209 SerializeDestReceiver *receiver = (SerializeDestReceiver *) self;
210
211 Assert(receiver->es != NULL);
212
213 switch (receiver->es->serialize)
214 {
216 Assert(false);
217 break;
219 receiver->format = 0; /* wire protocol format text */
220 break;
222 receiver->format = 1; /* wire protocol format binary */
223 break;
224 }
225
226 /* Create per-row temporary memory context */
228 "SerializeTupleReceive",
230
231 /* The output buffer is re-used across rows, as in printtup.c */
232 initStringInfo(&receiver->buf);
233
234 /* Initialize results counters */
235 memset(&receiver->metrics, 0, sizeof(SerializeMetrics));
237}
@ EXPLAIN_SERIALIZE_TEXT
Definition: explain.h:23
@ EXPLAIN_SERIALIZE_NONE
Definition: explain.h:22
@ EXPLAIN_SERIALIZE_BINARY
Definition: explain.h:24
Assert(PointerIsAligned(start, uint64))
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:160
void initStringInfo(StringInfo str)
Definition: stringinfo.c:97
ExplainSerializeOption serialize
Definition: explain.h:58

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert(), SerializeDestReceiver::buf, CurrentMemoryContext, SerializeDestReceiver::es, EXPLAIN_SERIALIZE_BINARY, EXPLAIN_SERIALIZE_NONE, EXPLAIN_SERIALIZE_TEXT, SerializeDestReceiver::format, initStringInfo(), INSTR_TIME_SET_ZERO, SerializeDestReceiver::metrics, ExplainState::serialize, SerializeMetrics::timeSpent, and SerializeDestReceiver::tmpcontext.

Referenced by CreateExplainSerializeDestReceiver().