PostgreSQL Source Code git master
Loading...
Searching...
No Matches
explain_dr.c File Reference
#include "postgres.h"
#include "commands/explain.h"
#include "commands/explain_dr.h"
#include "commands/explain_state.h"
#include "libpq/pqformat.h"
#include "libpq/protocol.h"
#include "utils/lsyscache.h"
#include "varatt.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 275 of file explain_dr.c.

276{
278
280
286
287 self->es = es;
288
289 return (DestReceiver *) self;
290}
@ DestExplainSerialize
Definition dest.h:99
static void serializeAnalyzeStartup(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition explain_dr.c:209
static void serializeAnalyzeDestroy(DestReceiver *self)
Definition explain_dr.c:266
static bool serializeAnalyzeReceive(TupleTableSlot *slot, DestReceiver *self)
Definition explain_dr.c:106
static void serializeAnalyzeShutdown(DestReceiver *self)
Definition explain_dr.c:245
#define palloc0_object(type)
Definition fe_memutils.h:75
ExplainState * es
Definition explain_dr.c:36
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_object, 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 300 of file explain_dr.c.

301{
302 SerializeMetrics empty;
303
304 if (dest->mydest == DestExplainSerialize)
305 return ((SerializeDestReceiver *) dest)->metrics;
306
307 memset(&empty, 0, sizeof(SerializeMetrics));
309
310 return empty;
311}
#define INSTR_TIME_SET_ZERO(t)
Definition instr_time.h:172
static int fb(int x)
instr_time timeSpent
Definition explain_dr.h:26

References DestExplainSerialize, fb(), 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 53 of file explain_dr.c.

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

References ereport, errcode(), errmsg(), ERROR, fb(), fmgr_info(), getTypeBinaryOutputInfo(), getTypeOutputInfo(), i, palloc0(), pfree(), and TupleDescAttr().

Referenced by serializeAnalyzeReceive().

◆ serializeAnalyzeDestroy()

static void serializeAnalyzeDestroy ( DestReceiver self)
static

Definition at line 266 of file explain_dr.c.

267{
268 pfree(self);
269}

References pfree().

Referenced by CreateExplainSerializeDestReceiver().

◆ serializeAnalyzeReceive()

static bool serializeAnalyzeReceive ( TupleTableSlot slot,
DestReceiver self 
)
static

Definition at line 106 of file explain_dr.c.

107{
110 MemoryContext oldcontext;
111 StringInfo buf = &myState->buf;
112 int natts = typeinfo->natts;
114 end;
116
117 /* only measure time, buffers if requested */
118 if (myState->es->timing)
120 if (myState->es->buffers)
122
123 /* Set or update my derived attribute info, if needed */
124 if (myState->attrinfo != typeinfo || myState->nattrs != natts)
126
127 /* Make sure the tuple is fully deconstructed */
128 slot_getallattrs(slot);
129
130 /* Switch into per-row context so we can recover memory below */
131 oldcontext = MemoryContextSwitchTo(myState->tmpcontext);
132
133 /*
134 * Prepare a DataRow message (note buffer is in per-query context)
135 *
136 * Note that we fill a StringInfo buffer the same as printtup() does, so
137 * as to capture the costs of manipulating the strings accurately.
138 */
140
141 pq_sendint16(buf, natts);
142
143 /*
144 * send the attributes of this tuple
145 */
146 for (int i = 0; i < natts; i++)
147 {
148 FmgrInfo *finfo = myState->finfos + i;
149 Datum attr = slot->tts_values[i];
150
151 if (slot->tts_isnull[i])
152 {
153 pq_sendint32(buf, -1);
154 continue;
155 }
156
157 if (myState->format == 0)
158 {
159 /* Text output */
160 char *outputstr;
161
162 outputstr = OutputFunctionCall(finfo, attr);
164 }
165 else
166 {
167 /* Binary output */
169
170 outputbytes = SendFunctionCall(finfo, attr);
174 }
175 }
176
177 /*
178 * We mustn't call pq_endmessage_reuse(), since that would actually send
179 * the data to the client. Just count the data, instead. We can leave
180 * the buffer alone; it'll be reset on the next iteration (as would also
181 * happen in printtup()).
182 */
183 myState->metrics.bytesSent += buf->len;
184
185 /* Return to caller's context, and flush row's temporary memory */
186 MemoryContextSwitchTo(oldcontext);
187 MemoryContextReset(myState->tmpcontext);
188
189 /* Update timing data */
190 if (myState->es->timing)
191 {
193 INSTR_TIME_ACCUM_DIFF(myState->metrics.timeSpent, end, start);
194 }
195
196 /* Update buffer metrics */
197 if (myState->es->buffers)
198 BufferUsageAccumDiff(&myState->metrics.bufferUsage,
200 &instr_start);
201
202 return true;
203}
#define VARHDRSZ
Definition c.h:711
static void serialize_prepare_info(SerializeDestReceiver *receiver, TupleDesc typeinfo, int nattrs)
Definition explain_dr.c:53
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:245
void MemoryContextReset(MemoryContext context)
Definition mcxt.c:403
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124
static char buf[DEFAULT_XLOG_SEG_SIZE]
uint64_t Datum
Definition postgres.h:70
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
TupleDesc tts_tupleDescriptor
Definition tuptable.h:122
bool * tts_isnull
Definition tuptable.h:126
Datum * tts_values
Definition tuptable.h:124
Definition c.h:706
static void slot_getallattrs(TupleTableSlot *slot)
Definition tuptable.h:371
static Size VARSIZE(const void *PTR)
Definition varatt.h:298
static char * VARDATA(const void *PTR)
Definition varatt.h:305

References buf, BufferUsageAccumDiff(), fb(), i, INSTR_TIME_ACCUM_DIFF, INSTR_TIME_SET_CURRENT, MemoryContextReset(), MemoryContextSwitchTo(), OutputFunctionCall(), pgBufferUsage, pq_beginmessage_reuse(), pq_sendbytes(), pq_sendcountedtext(), pq_sendint16(), pq_sendint32(), PqMsg_DataRow, SendFunctionCall(), serialize_prepare_info(), slot_getallattrs(), start, 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 245 of file explain_dr.c.

246{
248
249 if (receiver->finfos)
250 pfree(receiver->finfos);
251 receiver->finfos = NULL;
252
253 if (receiver->buf.data)
254 pfree(receiver->buf.data);
255 receiver->buf.data = NULL;
256
257 if (receiver->tmpcontext)
258 MemoryContextDelete(receiver->tmpcontext);
259 receiver->tmpcontext = NULL;
260}
void MemoryContextDelete(MemoryContext context)
Definition mcxt.c:472

References fb(), MemoryContextDelete(), and pfree().

Referenced by CreateExplainSerializeDestReceiver().

◆ serializeAnalyzeStartup()

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

Definition at line 209 of file explain_dr.c.

210{
212
213 Assert(receiver->es != NULL);
214
215 switch (receiver->es->serialize)
216 {
218 Assert(false);
219 break;
221 receiver->format = 0; /* wire protocol format text */
222 break;
224 receiver->format = 1; /* wire protocol format binary */
225 break;
226 }
227
228 /* Create per-row temporary memory context */
230 "SerializeTupleReceive",
232
233 /* The output buffer is re-used across rows, as in printtup.c */
235
236 /* Initialize results counters */
237 memset(&receiver->metrics, 0, sizeof(SerializeMetrics));
238 INSTR_TIME_SET_ZERO(receiver->metrics.timeSpent);
239}
#define Assert(condition)
Definition c.h:873
@ EXPLAIN_SERIALIZE_TEXT
@ EXPLAIN_SERIALIZE_NONE
@ EXPLAIN_SERIALIZE_BINARY
MemoryContext CurrentMemoryContext
Definition mcxt.c:160
#define AllocSetContextCreate
Definition memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition memutils.h:160
void initStringInfo(StringInfo str)
Definition stringinfo.c:97

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert, CurrentMemoryContext, EXPLAIN_SERIALIZE_BINARY, EXPLAIN_SERIALIZE_NONE, EXPLAIN_SERIALIZE_TEXT, fb(), initStringInfo(), and INSTR_TIME_SET_ZERO.

Referenced by CreateExplainSerializeDestReceiver().