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

Go to the source code of this file.

Data Structures

struct  ExplainExtensionOption
 

Functions

ExplainStateNewExplainState (void)
 
void ParseExplainOptionList (ExplainState *es, List *options, ParseState *pstate)
 
int GetExplainExtensionId (const char *extension_name)
 
void * GetExplainExtensionState (ExplainState *es, int extension_id)
 
void SetExplainExtensionState (ExplainState *es, int extension_id, void *opaque)
 
void RegisterExtensionExplainOption (const char *option_name, ExplainOptionHandler handler)
 
bool ApplyExtensionExplainOption (ExplainState *es, DefElem *opt, ParseState *pstate)
 

Variables

explain_validate_options_hook_type explain_validate_options_hook = NULL
 
static const char ** ExplainExtensionNameArray = NULL
 
static int ExplainExtensionNamesAssigned = 0
 
static int ExplainExtensionNamesAllocated = 0
 
static ExplainExtensionOptionExplainExtensionOptionArray = NULL
 
static int ExplainExtensionOptionsAssigned = 0
 
static int ExplainExtensionOptionsAllocated = 0
 

Function Documentation

◆ ApplyExtensionExplainOption()

bool ApplyExtensionExplainOption ( ExplainState es,
DefElem opt,
ParseState pstate 
)

Definition at line 365 of file explain_state.c.

366{
367 for (int i = 0; i < ExplainExtensionOptionsAssigned; ++i)
368 {
369 if (strcmp(ExplainExtensionOptionArray[i].option_name,
370 opt->defname) == 0)
371 {
373 return true;
374 }
375 }
376
377 return false;
378}
static ExplainExtensionOption * ExplainExtensionOptionArray
Definition: explain_state.c:53
static int ExplainExtensionOptionsAssigned
Definition: explain_state.c:54
int i
Definition: isn.c:77
char * defname
Definition: parsenodes.h:826
ExplainOptionHandler option_handler
Definition: explain_state.c:46

References DefElem::defname, ExplainExtensionOptionArray, ExplainExtensionOptionsAssigned, i, and ExplainExtensionOption::option_handler.

Referenced by ParseExplainOptionList().

◆ GetExplainExtensionId()

int GetExplainExtensionId ( const char *  extension_name)

Definition at line 220 of file explain_state.c.

221{
222 /* Search for an existing extension by this name; if found, return ID. */
223 for (int i = 0; i < ExplainExtensionNamesAssigned; ++i)
224 if (strcmp(ExplainExtensionNameArray[i], extension_name) == 0)
225 return i;
226
227 /* If there is no array yet, create one. */
228 if (ExplainExtensionNameArray == NULL)
229 {
231 ExplainExtensionNameArray = (const char **)
234 * sizeof(char *));
235 }
236
237 /* If there's an array but it's currently full, expand it. */
239 {
241
242 ExplainExtensionNameArray = (const char **)
243 repalloc(ExplainExtensionNameArray, i * sizeof(char *));
245 }
246
247 /* Assign and return new ID. */
250}
static const char ** ExplainExtensionNameArray
Definition: explain_state.c:49
static int ExplainExtensionNamesAssigned
Definition: explain_state.c:50
static int ExplainExtensionNamesAllocated
Definition: explain_state.c:51
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1181
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1544
MemoryContext TopMemoryContext
Definition: mcxt.c:149
static uint32 pg_nextpower2_32(uint32 num)
Definition: pg_bitutils.h:189

References ExplainExtensionNameArray, ExplainExtensionNamesAllocated, ExplainExtensionNamesAssigned, i, MemoryContextAlloc(), pg_nextpower2_32(), repalloc(), and TopMemoryContext.

Referenced by _PG_init().

◆ GetExplainExtensionState()

void * GetExplainExtensionState ( ExplainState es,
int  extension_id 
)

Definition at line 258 of file explain_state.c.

259{
260 Assert(extension_id >= 0);
261
262 if (extension_id >= es->extension_state_allocated)
263 return NULL;
264
265 return es->extension_state[extension_id];
266}
Assert(PointerIsAligned(start, uint64))
int extension_state_allocated
Definition: explain_state.h:76
void ** extension_state
Definition: explain_state.h:75

References Assert(), ExplainState::extension_state, and ExplainState::extension_state_allocated.

Referenced by overexplain_ensure_options(), overexplain_per_node_hook(), and overexplain_per_plan_hook().

◆ NewExplainState()

ExplainState * NewExplainState ( void  )

Definition at line 61 of file explain_state.c.

62{
64
65 /* Set default options (most fields can be left as zeroes). */
66 es->costs = true;
67 /* Prepare output buffer. */
68 es->str = makeStringInfo();
69
70 return es;
71}
void * palloc0(Size size)
Definition: mcxt.c:1347
StringInfo makeStringInfo(void)
Definition: stringinfo.c:72
StringInfo str
Definition: explain_state.h:46

References ExplainState::costs, makeStringInfo(), palloc0(), and ExplainState::str.

Referenced by explain_ExecutorEnd(), and ExplainQuery().

◆ ParseExplainOptionList()

void ParseExplainOptionList ( ExplainState es,
List options,
ParseState pstate 
)

Definition at line 77 of file explain_state.c.

78{
79 ListCell *lc;
80 bool timing_set = false;
81 bool buffers_set = false;
82 bool summary_set = false;
83
84 /* Parse options list. */
85 foreach(lc, options)
86 {
87 DefElem *opt = (DefElem *) lfirst(lc);
88
89 if (strcmp(opt->defname, "analyze") == 0)
90 es->analyze = defGetBoolean(opt);
91 else if (strcmp(opt->defname, "verbose") == 0)
92 es->verbose = defGetBoolean(opt);
93 else if (strcmp(opt->defname, "costs") == 0)
94 es->costs = defGetBoolean(opt);
95 else if (strcmp(opt->defname, "buffers") == 0)
96 {
97 buffers_set = true;
98 es->buffers = defGetBoolean(opt);
99 }
100 else if (strcmp(opt->defname, "wal") == 0)
101 es->wal = defGetBoolean(opt);
102 else if (strcmp(opt->defname, "settings") == 0)
103 es->settings = defGetBoolean(opt);
104 else if (strcmp(opt->defname, "generic_plan") == 0)
105 es->generic = defGetBoolean(opt);
106 else if (strcmp(opt->defname, "timing") == 0)
107 {
108 timing_set = true;
109 es->timing = defGetBoolean(opt);
110 }
111 else if (strcmp(opt->defname, "summary") == 0)
112 {
113 summary_set = true;
114 es->summary = defGetBoolean(opt);
115 }
116 else if (strcmp(opt->defname, "memory") == 0)
117 es->memory = defGetBoolean(opt);
118 else if (strcmp(opt->defname, "serialize") == 0)
119 {
120 if (opt->arg)
121 {
122 char *p = defGetString(opt);
123
124 if (strcmp(p, "off") == 0 || strcmp(p, "none") == 0)
126 else if (strcmp(p, "text") == 0)
128 else if (strcmp(p, "binary") == 0)
130 else
132 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
133 errmsg("unrecognized value for EXPLAIN option \"%s\": \"%s\"",
134 opt->defname, p),
135 parser_errposition(pstate, opt->location)));
136 }
137 else
138 {
139 /* SERIALIZE without an argument is taken as 'text' */
141 }
142 }
143 else if (strcmp(opt->defname, "format") == 0)
144 {
145 char *p = defGetString(opt);
146
147 if (strcmp(p, "text") == 0)
149 else if (strcmp(p, "xml") == 0)
151 else if (strcmp(p, "json") == 0)
153 else if (strcmp(p, "yaml") == 0)
155 else
157 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
158 errmsg("unrecognized value for EXPLAIN option \"%s\": \"%s\"",
159 opt->defname, p),
160 parser_errposition(pstate, opt->location)));
161 }
162 else if (!ApplyExtensionExplainOption(es, opt, pstate))
164 (errcode(ERRCODE_SYNTAX_ERROR),
165 errmsg("unrecognized EXPLAIN option \"%s\"",
166 opt->defname),
167 parser_errposition(pstate, opt->location)));
168 }
169
170 /* check that WAL is used with EXPLAIN ANALYZE */
171 if (es->wal && !es->analyze)
173 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
174 errmsg("EXPLAIN option %s requires ANALYZE", "WAL")));
175
176 /* if the timing was not set explicitly, set default value */
177 es->timing = (timing_set) ? es->timing : es->analyze;
178
179 /* if the buffers was not set explicitly, set default value */
180 es->buffers = (buffers_set) ? es->buffers : es->analyze;
181
182 /* check that timing is used with EXPLAIN ANALYZE */
183 if (es->timing && !es->analyze)
185 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
186 errmsg("EXPLAIN option %s requires ANALYZE", "TIMING")));
187
188 /* check that serialize is used with EXPLAIN ANALYZE */
189 if (es->serialize != EXPLAIN_SERIALIZE_NONE && !es->analyze)
191 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
192 errmsg("EXPLAIN option %s requires ANALYZE", "SERIALIZE")));
193
194 /* check that GENERIC_PLAN is not used with EXPLAIN ANALYZE */
195 if (es->generic && es->analyze)
197 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
198 errmsg("EXPLAIN options ANALYZE and GENERIC_PLAN cannot be used together")));
199
200 /* if the summary was not set explicitly, set default value */
201 es->summary = (summary_set) ? es->summary : es->analyze;
202
203 /* plugin specific option validation */
205 (*explain_validate_options_hook) (es, options, pstate);
206}
char * defGetString(DefElem *def)
Definition: define.c:35
bool defGetBoolean(DefElem *def)
Definition: define.c:94
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
explain_validate_options_hook_type explain_validate_options_hook
Definition: explain_state.c:41
bool ApplyExtensionExplainOption(ExplainState *es, DefElem *opt, ParseState *pstate)
@ EXPLAIN_SERIALIZE_TEXT
Definition: explain_state.h:23
@ EXPLAIN_SERIALIZE_NONE
Definition: explain_state.h:22
@ EXPLAIN_SERIALIZE_BINARY
Definition: explain_state.h:24
@ EXPLAIN_FORMAT_XML
Definition: explain_state.h:30
@ EXPLAIN_FORMAT_YAML
Definition: explain_state.h:32
@ EXPLAIN_FORMAT_TEXT
Definition: explain_state.h:29
@ EXPLAIN_FORMAT_JSON
Definition: explain_state.h:31
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:81
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:106
#define lfirst(lc)
Definition: pg_list.h:172
static char ** options
ParseLoc location
Definition: parsenodes.h:830
Node * arg
Definition: parsenodes.h:827
ExplainFormat format
Definition: explain_state.h:59
ExplainSerializeOption serialize
Definition: explain_state.h:58

References ExplainState::analyze, ApplyExtensionExplainOption(), DefElem::arg, ExplainState::buffers, ExplainState::costs, defGetBoolean(), defGetString(), DefElem::defname, ereport, errcode(), errmsg(), ERROR, EXPLAIN_FORMAT_JSON, EXPLAIN_FORMAT_TEXT, EXPLAIN_FORMAT_XML, EXPLAIN_FORMAT_YAML, EXPLAIN_SERIALIZE_BINARY, EXPLAIN_SERIALIZE_NONE, EXPLAIN_SERIALIZE_TEXT, explain_validate_options_hook, ExplainState::format, ExplainState::generic, if(), lfirst, DefElem::location, ExplainState::memory, options, parser_errposition(), ExplainState::serialize, ExplainState::settings, ExplainState::summary, ExplainState::timing, ExplainState::verbose, and ExplainState::wal.

Referenced by ExplainQuery().

◆ RegisterExtensionExplainOption()

void RegisterExtensionExplainOption ( const char *  option_name,
ExplainOptionHandler  handler 
)

Definition at line 316 of file explain_state.c.

318{
320
321 /* Search for an existing option by this name; if found, update handler. */
322 for (int i = 0; i < ExplainExtensionOptionsAssigned; ++i)
323 {
324 if (strcmp(ExplainExtensionOptionArray[i].option_name,
325 option_name) == 0)
326 {
328 return;
329 }
330 }
331
332 /* If there is no array yet, create one. */
333 if (ExplainExtensionOptionArray == NULL)
334 {
339 * sizeof(char *));
340 }
341
342 /* If there's an array but it's currently full, expand it. */
344 {
346
348 repalloc(ExplainExtensionOptionArray, i * sizeof(char *));
350 }
351
352 /* Assign and return new ID. */
354 exopt->option_name = option_name;
355 exopt->option_handler = handler;
356}
static int ExplainExtensionOptionsAllocated
Definition: explain_state.c:55
const char * option_name
Definition: explain_state.c:45

References ExplainExtensionOptionArray, ExplainExtensionOptionsAllocated, ExplainExtensionOptionsAssigned, i, MemoryContextAlloc(), ExplainExtensionOption::option_handler, ExplainExtensionOption::option_name, pg_nextpower2_32(), repalloc(), and TopMemoryContext.

Referenced by _PG_init().

◆ SetExplainExtensionState()

void SetExplainExtensionState ( ExplainState es,
int  extension_id,
void *  opaque 
)

Definition at line 277 of file explain_state.c.

278{
279 Assert(extension_id >= 0);
280
281 /* If there is no array yet, create one. */
282 if (es->extension_state == NULL)
283 {
285 es->extension_state =
286 palloc0(es->extension_state_allocated * sizeof(void *));
287 }
288
289 /* If there's an array but it's currently full, expand it. */
290 if (extension_id >= es->extension_state_allocated)
291 {
292 int i;
293
295 es->extension_state = (void **)
297 es->extension_state_allocated * sizeof(void *),
298 i * sizeof(void *));
300 }
301
302 es->extension_state[extension_id] = opaque;
303}
void * repalloc0(void *pointer, Size oldsize, Size size)
Definition: mcxt.c:1622

References Assert(), ExplainState::extension_state, ExplainState::extension_state_allocated, i, palloc0(), pg_nextpower2_32(), and repalloc0().

Referenced by overexplain_ensure_options().

Variable Documentation

◆ explain_validate_options_hook

explain_validate_options_hook_type explain_validate_options_hook = NULL

Definition at line 41 of file explain_state.c.

Referenced by ParseExplainOptionList().

◆ ExplainExtensionNameArray

const char** ExplainExtensionNameArray = NULL
static

Definition at line 49 of file explain_state.c.

Referenced by GetExplainExtensionId().

◆ ExplainExtensionNamesAllocated

int ExplainExtensionNamesAllocated = 0
static

Definition at line 51 of file explain_state.c.

Referenced by GetExplainExtensionId().

◆ ExplainExtensionNamesAssigned

int ExplainExtensionNamesAssigned = 0
static

Definition at line 50 of file explain_state.c.

Referenced by GetExplainExtensionId().

◆ ExplainExtensionOptionArray

ExplainExtensionOption* ExplainExtensionOptionArray = NULL
static

Definition at line 53 of file explain_state.c.

Referenced by ApplyExtensionExplainOption(), and RegisterExtensionExplainOption().

◆ ExplainExtensionOptionsAllocated

int ExplainExtensionOptionsAllocated = 0
static

Definition at line 55 of file explain_state.c.

Referenced by RegisterExtensionExplainOption().

◆ ExplainExtensionOptionsAssigned

int ExplainExtensionOptionsAssigned = 0
static

Definition at line 54 of file explain_state.c.

Referenced by ApplyExtensionExplainOption(), and RegisterExtensionExplainOption().