PostgreSQL Source Code git master
Loading...
Searching...
No Matches
explain_state.h File Reference
#include "nodes/parsenodes.h"
#include "nodes/plannodes.h"
#include "parser/parse_node.h"
#include "port/pg_bitutils.h"
Include dependency graph for explain_state.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ExplainWorkersState
 
struct  ExplainState
 

Typedefs

typedef enum ExplainSerializeOption ExplainSerializeOption
 
typedef enum ExplainFormat ExplainFormat
 
typedef struct ExplainWorkersState ExplainWorkersState
 
typedef struct ExplainState ExplainState
 
typedef void(* ExplainOptionHandler) (ExplainState *, DefElem *, ParseState *)
 
typedef bool(* ExplainOptionGUCCheckHandler) (const char *option_name, const char *option_value, NodeTag option_type)
 
typedef void(* explain_validate_options_hook_type) (ExplainState *es, List *options, ParseState *pstate)
 

Enumerations

enum  ExplainSerializeOption { EXPLAIN_SERIALIZE_NONE , EXPLAIN_SERIALIZE_TEXT , EXPLAIN_SERIALIZE_BINARY }
 
enum  ExplainFormat { EXPLAIN_FORMAT_TEXT , EXPLAIN_FORMAT_XML , EXPLAIN_FORMAT_JSON , EXPLAIN_FORMAT_YAML }
 

Functions

ExplainStateNewExplainState (void)
 
void ParseExplainOptionList (ExplainState *es, List *options, ParseState *pstate)
 
int GetExplainExtensionId (const char *extension_name)
 
voidGetExplainExtensionState (ExplainState *es, int extension_id)
 
void SetExplainExtensionState (ExplainState *es, int extension_id, void *opaque)
 
void RegisterExtensionExplainOption (const char *option_name, ExplainOptionHandler handler, ExplainOptionGUCCheckHandler guc_check_handler)
 
bool ApplyExtensionExplainOption (ExplainState *es, DefElem *opt, ParseState *pstate)
 
bool GUCCheckExplainExtensionOption (const char *option_name, const char *option_value, NodeTag option_type)
 
bool GUCCheckBooleanExplainOption (const char *option_name, const char *option_value, NodeTag option_type)
 

Variables

PGDLLIMPORT explain_validate_options_hook_type explain_validate_options_hook
 

Typedef Documentation

◆ explain_validate_options_hook_type

typedef void(* explain_validate_options_hook_type) (ExplainState *es, List *options, ParseState *pstate)

Definition at line 87 of file explain_state.h.

◆ ExplainFormat

◆ ExplainOptionGUCCheckHandler

typedef bool(* ExplainOptionGUCCheckHandler) (const char *option_name, const char *option_value, NodeTag option_type)

Definition at line 82 of file explain_state.h.

◆ ExplainOptionHandler

typedef void(* ExplainOptionHandler) (ExplainState *, DefElem *, ParseState *)

Definition at line 81 of file explain_state.h.

◆ ExplainSerializeOption

◆ ExplainState

◆ ExplainWorkersState

Enumeration Type Documentation

◆ ExplainFormat

Enumerator
EXPLAIN_FORMAT_TEXT 
EXPLAIN_FORMAT_XML 
EXPLAIN_FORMAT_JSON 
EXPLAIN_FORMAT_YAML 

Definition at line 28 of file explain_state.h.

29{
ExplainFormat
@ EXPLAIN_FORMAT_XML
@ EXPLAIN_FORMAT_YAML
@ EXPLAIN_FORMAT_TEXT
@ EXPLAIN_FORMAT_JSON

◆ ExplainSerializeOption

Enumerator
EXPLAIN_SERIALIZE_NONE 
EXPLAIN_SERIALIZE_TEXT 
EXPLAIN_SERIALIZE_BINARY 

Definition at line 21 of file explain_state.h.

22{
ExplainSerializeOption
@ EXPLAIN_SERIALIZE_TEXT
@ EXPLAIN_SERIALIZE_NONE
@ EXPLAIN_SERIALIZE_BINARY

Function Documentation

◆ ApplyExtensionExplainOption()

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

Definition at line 389 of file explain_state.c.

390{
391 for (int i = 0; i < ExplainExtensionOptionsAssigned; ++i)
392 {
393 if (strcmp(ExplainExtensionOptionArray[i].option_name,
394 opt->defname) == 0)
395 {
397 return true;
398 }
399 }
400
401 return false;
402}
static ExplainExtensionOption * ExplainExtensionOptionArray
static int ExplainExtensionOptionsAssigned
int i
Definition isn.c:77
static int fb(int x)
char * defname
Definition parsenodes.h:860
ExplainOptionHandler option_handler

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

Referenced by apply_extension_options(), and ParseExplainOptionList().

◆ GetExplainExtensionId()

int GetExplainExtensionId ( const char extension_name)
extern

Definition at line 232 of file explain_state.c.

233{
234 /* Search for an existing extension by this name; if found, return ID. */
235 for (int i = 0; i < ExplainExtensionNamesAssigned; ++i)
237 return i;
238
239 /* If there is no array yet, create one. */
241 {
243 ExplainExtensionNameArray = (const char **)
246 * sizeof(char *));
247 }
248
249 /* If there's an array but it's currently full, expand it. */
251 {
253
254 ExplainExtensionNameArray = (const char **)
255 repalloc(ExplainExtensionNameArray, i * sizeof(char *));
257 }
258
259 /* Assign and return new ID. */
262}
static const char ** ExplainExtensionNameArray
static int ExplainExtensionNamesAssigned
static int ExplainExtensionNamesAllocated
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition mcxt.c:1232
void * repalloc(void *pointer, Size size)
Definition mcxt.c:1632
MemoryContext TopMemoryContext
Definition mcxt.c:166
static uint32 pg_nextpower2_32(uint32 num)

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

Referenced by _PG_init().

◆ GetExplainExtensionState()

void * GetExplainExtensionState ( ExplainState es,
int  extension_id 
)
extern

◆ GUCCheckBooleanExplainOption()

bool GUCCheckBooleanExplainOption ( const char option_name,
const char option_value,
NodeTag  option_type 
)
extern

Definition at line 454 of file explain_state.c.

457{
458 bool valid = false;
459
460 if (option_value == NULL)
461 {
462 /* defGetBoolean treats no argument as valid */
463 valid = true;
464 }
465 else if (option_type == T_String)
466 {
467 /* defGetBoolean accepts exactly these string values */
468 if (pg_strcasecmp(option_value, "true") == 0 ||
469 pg_strcasecmp(option_value, "false") == 0 ||
470 pg_strcasecmp(option_value, "on") == 0 ||
471 pg_strcasecmp(option_value, "off") == 0)
472 valid = true;
473 }
474 else if (option_type == T_Integer)
475 {
476 long value;
477 char *end;
478
479 /*
480 * defGetBoolean accepts only 0 and 1, but those can be spelled in
481 * various ways (e.g. 01, 0x01).
482 */
483 errno = 0;
484 value = strtol(option_value, &end, 0);
485 if (errno == 0 && *end == '\0' && end != option_value &&
486 value == (int) value && (value == 0 || value == 1))
487 valid = true;
488 }
489
490 if (!valid)
491 {
492 GUC_check_errmsg("EXPLAIN option \"%s\" requires a Boolean value",
493 option_name);
494 return false;
495 }
496
497 return true;
498}
#define GUC_check_errmsg
Definition guc.h:503
static struct @177 value
int pg_strcasecmp(const char *s1, const char *s2)
static enum slash_option_type option_type

References fb(), GUC_check_errmsg, option_type, pg_strcasecmp(), and value.

Referenced by _PG_init().

◆ GUCCheckExplainExtensionOption()

bool GUCCheckExplainExtensionOption ( const char option_name,
const char option_value,
NodeTag  option_type 
)
extern

Definition at line 413 of file explain_state.c.

416{
417 for (int i = 0; i < ExplainExtensionOptionsAssigned; i++)
418 {
420
421 if (strcmp(exopt->option_name, option_name) == 0)
422 return exopt->guc_check_handler(option_name, option_value,
424 }
425
426 /* Unrecognized option name. */
427 GUC_check_errmsg("unrecognized EXPLAIN option \"%s\"", option_name);
428 return false;
429}
ExplainOptionGUCCheckHandler guc_check_handler

References ExplainExtensionOptionArray, ExplainExtensionOptionsAssigned, fb(), GUC_check_errmsg, ExplainExtensionOption::guc_check_handler, i, and option_type.

Referenced by check_log_extension_options().

◆ NewExplainState()

ExplainState * NewExplainState ( void  )
extern

Definition at line 64 of file explain_state.c.

65{
67
68 /* Set default options (most fields can be left as zeroes). */
69 es->costs = true;
70 /* Prepare output buffer. */
71 es->str = makeStringInfo();
72
73 return es;
74}
#define palloc0_object(type)
Definition fe_memutils.h:75
StringInfo makeStringInfo(void)
Definition stringinfo.c:72
StringInfo str

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

Referenced by explain_ExecutorEnd(), and ExplainQuery().

◆ ParseExplainOptionList()

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

Definition at line 80 of file explain_state.c.

81{
82 ListCell *lc;
83 bool timing_set = false;
84 bool buffers_set = false;
85 bool summary_set = false;
86
87 /* Parse options list. */
88 foreach(lc, options)
89 {
90 DefElem *opt = (DefElem *) lfirst(lc);
91
92 if (strcmp(opt->defname, "analyze") == 0)
93 es->analyze = defGetBoolean(opt);
94 else if (strcmp(opt->defname, "verbose") == 0)
95 es->verbose = defGetBoolean(opt);
96 else if (strcmp(opt->defname, "costs") == 0)
97 es->costs = defGetBoolean(opt);
98 else if (strcmp(opt->defname, "buffers") == 0)
99 {
100 buffers_set = true;
101 es->buffers = defGetBoolean(opt);
102 }
103 else if (strcmp(opt->defname, "wal") == 0)
104 es->wal = defGetBoolean(opt);
105 else if (strcmp(opt->defname, "settings") == 0)
106 es->settings = defGetBoolean(opt);
107 else if (strcmp(opt->defname, "generic_plan") == 0)
108 es->generic = defGetBoolean(opt);
109 else if (strcmp(opt->defname, "timing") == 0)
110 {
111 timing_set = true;
112 es->timing = defGetBoolean(opt);
113 }
114 else if (strcmp(opt->defname, "summary") == 0)
115 {
116 summary_set = true;
117 es->summary = defGetBoolean(opt);
118 }
119 else if (strcmp(opt->defname, "memory") == 0)
120 es->memory = defGetBoolean(opt);
121 else if (strcmp(opt->defname, "serialize") == 0)
122 {
123 if (opt->arg)
124 {
125 char *p = defGetString(opt);
126
127 if (strcmp(p, "off") == 0 || strcmp(p, "none") == 0)
129 else if (strcmp(p, "text") == 0)
131 else if (strcmp(p, "binary") == 0)
133 else
136 errmsg("unrecognized value for %s option \"%s\": \"%s\"",
137 "EXPLAIN", opt->defname, p),
138 parser_errposition(pstate, opt->location)));
139 }
140 else
141 {
142 /* SERIALIZE without an argument is taken as 'text' */
144 }
145 }
146 else if (strcmp(opt->defname, "format") == 0)
147 {
148 char *p = defGetString(opt);
149
150 if (strcmp(p, "text") == 0)
152 else if (strcmp(p, "xml") == 0)
154 else if (strcmp(p, "json") == 0)
156 else if (strcmp(p, "yaml") == 0)
158 else
161 errmsg("unrecognized value for %s option \"%s\": \"%s\"",
162 "EXPLAIN", opt->defname, p),
163 parser_errposition(pstate, opt->location)));
164 }
165 else if (strcmp(opt->defname, "io") == 0)
166 es->io = defGetBoolean(opt);
167 else if (!ApplyExtensionExplainOption(es, opt, pstate))
170 errmsg("unrecognized %s option \"%s\"",
171 "EXPLAIN", opt->defname),
172 parser_errposition(pstate, opt->location)));
173 }
174
175 /* check that WAL is used with EXPLAIN ANALYZE */
176 if (es->wal && !es->analyze)
179 errmsg("EXPLAIN option %s requires ANALYZE", "WAL")));
180
181 /* if the timing was not set explicitly, set default value */
182 es->timing = (timing_set) ? es->timing : es->analyze;
183
184 /* if the buffers was not set explicitly, set default value */
185 es->buffers = (buffers_set) ? es->buffers : es->analyze;
186
187 /* check that timing is used with EXPLAIN ANALYZE */
188 if (es->timing && !es->analyze)
191 errmsg("EXPLAIN option %s requires ANALYZE", "TIMING")));
192
193 /* check that IO is used with EXPLAIN ANALYZE */
194 if (es->io && !es->analyze)
197 errmsg("EXPLAIN option %s requires ANALYZE", "IO")));
198
199 /* check that serialize is used with EXPLAIN ANALYZE */
200 if (es->serialize != EXPLAIN_SERIALIZE_NONE && !es->analyze)
203 errmsg("EXPLAIN option %s requires ANALYZE", "SERIALIZE")));
204
205 /* check that GENERIC_PLAN is not used with EXPLAIN ANALYZE */
206 if (es->generic && es->analyze)
209 errmsg("%s options %s and %s cannot be used together",
210 "EXPLAIN", "ANALYZE", "GENERIC_PLAN")));
211
212 /* if the summary was not set explicitly, set default value */
213 es->summary = (summary_set) ? es->summary : es->analyze;
214
215 /* plugin specific option validation */
217 (*explain_validate_options_hook) (es, options, pstate);
218}
char * defGetString(DefElem *def)
Definition define.c:34
bool defGetBoolean(DefElem *def)
Definition define.c:93
int errcode(int sqlerrcode)
Definition elog.c:874
#define ERROR
Definition elog.h:40
#define ereport(elevel,...)
Definition elog.h:152
explain_validate_options_hook_type explain_validate_options_hook
bool ApplyExtensionExplainOption(ExplainState *es, DefElem *opt, ParseState *pstate)
static char * errmsg
int parser_errposition(ParseState *pstate, int location)
Definition parse_node.c:106
#define lfirst(lc)
Definition pg_list.h:172
static long analyze(struct nfa *nfa)
Definition regc_nfa.c:3051
ParseLoc location
Definition parsenodes.h:864
Node * arg
Definition parsenodes.h:861
ExplainFormat format
ExplainSerializeOption serialize

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, fb(), ExplainState::format, ExplainState::generic, ExplainState::io, lfirst, DefElem::location, ExplainState::memory, 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,
ExplainOptionGUCCheckHandler  guc_check_handler 
)
extern

Definition at line 332 of file explain_state.c.

335{
337
338 Assert(handler != NULL);
339 Assert(guc_check_handler != NULL);
340
341 /* Search for an existing option by this name; if found, update handler. */
342 for (int i = 0; i < ExplainExtensionOptionsAssigned; ++i)
343 {
344 if (strcmp(ExplainExtensionOptionArray[i].option_name,
345 option_name) == 0)
346 {
348
349 exopt->option_handler = handler;
350 exopt->guc_check_handler = guc_check_handler;
351 return;
352 }
353 }
354
355 /* If there is no array yet, create one. */
357 {
362 * sizeof(ExplainExtensionOption));
363 }
364
365 /* If there's an array but it's currently full, expand it. */
367 {
369
373 }
374
375 /* Assign and return new ID. */
377 exopt->option_name = option_name;
378 exopt->option_handler = handler;
379 exopt->guc_check_handler = guc_check_handler;
380}
static int ExplainExtensionOptionsAllocated

References Assert, ExplainExtensionOptionArray, ExplainExtensionOptionsAllocated, ExplainExtensionOptionsAssigned, fb(), 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 
)
extern

Definition at line 289 of file explain_state.c.

290{
291 Assert(extension_id >= 0);
292
293 /* If there is no array yet, create one. */
294 if (es->extension_state == NULL)
295 {
298 es->extension_state =
299 palloc0(es->extension_state_allocated * sizeof(void *));
300 }
301
302 /* If there's an array but it's currently full, expand it. */
304 {
305 int i;
306
310 }
311
312 es->extension_state[extension_id] = opaque;
313}
#define Max(x, y)
Definition c.h:1085
void * palloc0(Size size)
Definition mcxt.c:1417
#define repalloc0_array(pointer, type, oldcount, count)
Definition palloc.h:109

References Assert, ExplainState::extension_state, ExplainState::extension_state_allocated, fb(), i, Max, palloc0(), pg_nextpower2_32(), and repalloc0_array.

Referenced by overexplain_ensure_options(), and pg_plan_advice_explain_option_handler().

Variable Documentation

◆ explain_validate_options_hook

PGDLLIMPORT explain_validate_options_hook_type explain_validate_options_hook
extern

Definition at line 43 of file explain_state.c.

Referenced by ParseExplainOptionList().