PostgreSQL Source Code git master
Data Structures | Functions | Variables
pg_overexplain.c File Reference
#include "postgres.h"
#include "catalog/pg_class.h"
#include "commands/defrem.h"
#include "commands/explain.h"
#include "commands/explain_format.h"
#include "commands/explain_state.h"
#include "fmgr.h"
#include "parser/parsetree.h"
#include "storage/lock.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
Include dependency graph for pg_overexplain.c:

Go to the source code of this file.

Data Structures

 

Functions

  PG_MODULE_MAGIC_EXT (.name="pg_overexplain",.version=PG_VERSION)
 
 
static void  overexplain_debug_handler (ExplainState *es, DefElem *opt, ParseState *pstate)
 
 
static void  overexplain_per_node_hook (PlanState *planstate, List *ancestors, const char *relationship, const char *plan_name, ExplainState *es)
 
static void  overexplain_per_plan_hook (PlannedStmt *plannedstmt, IntoClause *into, ExplainState *es, const char *queryString, ParamListInfo params, QueryEnvironment *queryEnv)
 
static void  overexplain_debug (PlannedStmt *plannedstmt, ExplainState *es)
 
static void  overexplain_range_table (PlannedStmt *plannedstmt, ExplainState *es)
 
static void  overexplain_alias (const char *qlabel, Alias *alias, ExplainState *es)
 
static void  overexplain_bitmapset (const char *qlabel, Bitmapset *bms, ExplainState *es)
 
static void  overexplain_intlist (const char *qlabel, List *list, ExplainState *es)
 
void  _PG_init (void)
 

Variables

static int  es_extension_id
 
 
 

Function Documentation

_PG_init()

void _PG_init ( void  )

Definition at line 68 of file pg_overexplain.c.

69{
70 /* Get an ID that we can use to cache data in an ExplainState. */
71 es_extension_id = GetExplainExtensionId("pg_overexplain");
72
73 /* Register the new EXPLAIN options implemented by this module. */
77
78 /* Use the per-node and per-plan hooks to make our options do something. */
83}
explain_per_node_hook_type explain_per_node_hook
Definition: explain.c:57
explain_per_plan_hook_type explain_per_plan_hook
Definition: explain.c:56
int GetExplainExtensionId(const char *extension_name)
Definition: explain_state.c:220
void RegisterExtensionExplainOption(const char *option_name, ExplainOptionHandler handler)
Definition: explain_state.c:317
static void overexplain_per_plan_hook(PlannedStmt *plannedstmt, IntoClause *into, ExplainState *es, const char *queryString, ParamListInfo params, QueryEnvironment *queryEnv)
static explain_per_plan_hook_type prev_explain_per_plan_hook
Definition: pg_overexplain.c:62
static explain_per_node_hook_type prev_explain_per_node_hook
Definition: pg_overexplain.c:61
static void overexplain_per_node_hook(PlanState *planstate, List *ancestors, const char *relationship, const char *plan_name, ExplainState *es)
static void overexplain_debug_handler(ExplainState *es, DefElem *opt, ParseState *pstate)
static int es_extension_id
Definition: pg_overexplain.c:60
static void overexplain_range_table_handler(ExplainState *es, DefElem *opt, ParseState *pstate)

References es_extension_id, explain_per_node_hook, explain_per_plan_hook, GetExplainExtensionId(), overexplain_debug_handler(), overexplain_per_node_hook(), overexplain_per_plan_hook(), overexplain_range_table_handler(), prev_explain_per_node_hook, prev_explain_per_plan_hook, and RegisterExtensionExplainOption().

overexplain_alias()

static void overexplain_alias ( const char *  qlabel,
Aliasalias,
ExplainStatees 
)
static

Definition at line 694 of file pg_overexplain.c.

695{
697 bool first = true;
698
699 Assert(alias != NULL);
700
703
704 foreach_node(String, cn, alias->colnames)
705 {
706 appendStringInfo(&buf, "%s%s",
707 first ? "" : ", ",
708 quote_identifier(cn->sval));
709 first = false;
710 }
711
713 ExplainPropertyText(qlabel, buf.data, es);
714 pfree(buf.data);
715}
void ExplainPropertyText(const char *qlabel, const char *value, ExplainState *es)
Assert(PointerIsAligned(start, uint64))
void pfree(void *pointer)
Definition: mcxt.c:1594
#define foreach_node(type, var, lst)
Definition: pg_list.h:496
static char * buf
Definition: pg_test_fsync.c:72
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:13035
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:145
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:242
void initStringInfo(StringInfo str)
Definition: stringinfo.c:97
char * aliasname
Definition: primnodes.h:51
List * colnames
Definition: primnodes.h:52
Definition: value.h:64

References Alias::aliasname, appendStringInfo(), appendStringInfoChar(), Assert(), buf, Alias::colnames, ExplainPropertyText(), foreach_node, initStringInfo(), pfree(), and quote_identifier().

Referenced by overexplain_range_table().

overexplain_bitmapset()

static void overexplain_bitmapset ( const char *  qlabel,
Bitmapsetbms,
ExplainStatees 
)
static

Definition at line 723 of file pg_overexplain.c.

724{
725 int x = -1;
726
728
729 if (bms_is_empty(bms))
730 {
731 ExplainPropertyText(qlabel, "none", es);
732 return;
733 }
734
736 while ((x = bms_next_member(bms, x)) >= 0)
737 appendStringInfo(&buf, " %d", x);
738 Assert(buf.data[0] == ' ');
739 ExplainPropertyText(qlabel, buf.data + 1, es);
740 pfree(buf.data);
741}
int bms_next_member(const Bitmapset *a, int prevbit)
Definition: bitmapset.c:1306
#define bms_is_empty(a)
Definition: bitmapset.h:118
x
int x
Definition: isn.c:75

References appendStringInfo(), Assert(), bms_is_empty, bms_next_member(), buf, ExplainPropertyText(), initStringInfo(), pfree(), and x.

Referenced by overexplain_debug(), overexplain_per_node_hook(), and overexplain_range_table().

overexplain_debug()

static void overexplain_debug ( PlannedStmtplannedstmt,
ExplainStatees 
)
static

Definition at line 297 of file pg_overexplain.c.

298{
299 char *commandType = NULL;
300 StringInfoData flags;
301
302 /* Even in text mode, we want to set this output apart as its own group. */
303 ExplainOpenGroup("PlannedStmt", "PlannedStmt", true, es);
304 if (es->format == EXPLAIN_FORMAT_TEXT)
305 {
307 appendStringInfoString(es->str, "PlannedStmt:\n");
308 es->indent++;
309 }
310
311 /* Print the command type. */
312 switch (plannedstmt->commandType)
313 {
314 case CMD_UNKNOWN:
315 commandType = "unknown";
316 break;
317 case CMD_SELECT:
318 commandType = "select";
319 break;
320 case CMD_UPDATE:
321 commandType = "update";
322 break;
323 case CMD_INSERT:
324 commandType = "insert";
325 break;
326 case CMD_DELETE:
327 commandType = "delete";
328 break;
329 case CMD_MERGE:
330 commandType = "merge";
331 break;
332 case CMD_UTILITY:
333 commandType = "utility";
334 break;
335 case CMD_NOTHING:
336 commandType = "nothing";
337 break;
338 }
339 ExplainPropertyText("Command Type", commandType, es);
340
341 /* Print various properties as a comma-separated list of flags. */
342 initStringInfo(&flags);
343 if (plannedstmt->hasReturning)
344 appendStringInfoString(&flags, ", hasReturning");
345 if (plannedstmt->hasModifyingCTE)
346 appendStringInfoString(&flags, ", hasModifyingCTE");
347 if (plannedstmt->canSetTag)
348 appendStringInfoString(&flags, ", canSetTag");
349 if (plannedstmt->transientPlan)
350 appendStringInfoString(&flags, ", transientPlan");
351 if (plannedstmt->dependsOnRole)
352 appendStringInfoString(&flags, ", dependsOnRole");
353 if (plannedstmt->parallelModeNeeded)
354 appendStringInfoString(&flags, ", parallelModeNeeded");
355 if (flags.len == 0)
356 appendStringInfoString(&flags, ", none");
357 ExplainPropertyText("Flags", flags.data + 2, es);
358
359 /* Various lists of integers. */
360 overexplain_bitmapset("Subplans Needing Rewind",
361 plannedstmt->rewindPlanIDs, es);
362 overexplain_intlist("Relation OIDs",
363 plannedstmt->relationOids, es);
364 overexplain_intlist("Executor Parameter Types",
365 plannedstmt->paramExecTypes, es);
366
367 /*
368 * Print the statement location. (If desired, we could alternatively print
369 * stmt_location and stmt_len as two separate fields.)
370 */
371 if (plannedstmt->stmt_location == -1)
372 ExplainPropertyText("Parse Location", "Unknown", es);
373 else if (plannedstmt->stmt_len == 0)
374 ExplainPropertyText("Parse Location",
375 psprintf("%d to end", plannedstmt->stmt_location),
376 es);
377 else
378 ExplainPropertyText("Parse Location",
379 psprintf("%d for %d bytes",
380 plannedstmt->stmt_location,
381 plannedstmt->stmt_len),
382 es);
383
384 /* Done with this group. */
385 if (es->format == EXPLAIN_FORMAT_TEXT)
386 es->indent--;
387 ExplainCloseGroup("PlannedStmt", "PlannedStmt", true, es);
388}
void ExplainOpenGroup(const char *objtype, const char *labelname, bool labeled, ExplainState *es)
void ExplainIndentText(ExplainState *es)
void ExplainCloseGroup(const char *objtype, const char *labelname, bool labeled, ExplainState *es)
@ EXPLAIN_FORMAT_TEXT
Definition: explain_state.h:29
@ CMD_MERGE
Definition: nodes.h:279
@ CMD_UTILITY
Definition: nodes.h:280
@ CMD_INSERT
Definition: nodes.h:277
@ CMD_DELETE
Definition: nodes.h:278
@ CMD_UNKNOWN
Definition: nodes.h:274
@ CMD_UPDATE
Definition: nodes.h:276
@ CMD_SELECT
Definition: nodes.h:275
@ CMD_NOTHING
Definition: nodes.h:282
static void overexplain_bitmapset(const char *qlabel, Bitmapset *bms, ExplainState *es)
static void overexplain_intlist(const char *qlabel, List *list, ExplainState *es)
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:230
StringInfo str
Definition: explain_state.h:46
ExplainFormat format
Definition: explain_state.h:59
bool hasModifyingCTE
Definition: plannodes.h:83
bool canSetTag
Definition: plannodes.h:86
Bitmapset * rewindPlanIDs
Definition: plannodes.h:135
ParseLoc stmt_len
Definition: plannodes.h:156
bool hasReturning
Definition: plannodes.h:80
ParseLoc stmt_location
Definition: plannodes.h:154
bool transientPlan
Definition: plannodes.h:89
List * relationOids
Definition: plannodes.h:141
bool dependsOnRole
Definition: plannodes.h:92
CmdType commandType
Definition: plannodes.h:68
List * paramExecTypes
Definition: plannodes.h:147
bool parallelModeNeeded
Definition: plannodes.h:95
char * data
Definition: stringinfo.h:48

References appendStringInfoString(), PlannedStmt::canSetTag, CMD_DELETE, CMD_INSERT, CMD_MERGE, CMD_NOTHING, CMD_SELECT, CMD_UNKNOWN, CMD_UPDATE, CMD_UTILITY, PlannedStmt::commandType, StringInfoData::data, PlannedStmt::dependsOnRole, EXPLAIN_FORMAT_TEXT, ExplainCloseGroup(), ExplainIndentText(), ExplainOpenGroup(), ExplainPropertyText(), ExplainState::format, PlannedStmt::hasModifyingCTE, PlannedStmt::hasReturning, ExplainState::indent, initStringInfo(), StringInfoData::len, overexplain_bitmapset(), overexplain_intlist(), PlannedStmt::parallelModeNeeded, PlannedStmt::paramExecTypes, psprintf(), PlannedStmt::relationOids, PlannedStmt::rewindPlanIDs, PlannedStmt::stmt_len, PlannedStmt::stmt_location, ExplainState::str, and PlannedStmt::transientPlan.

Referenced by overexplain_per_plan_hook().

overexplain_debug_handler()

static void overexplain_debug_handler ( ExplainStatees,
DefElemopt,
ParseStatepstate 
)
static

Definition at line 109 of file pg_overexplain.c.

110{
112
113 options->debug = defGetBoolean(opt);
114}
bool defGetBoolean(DefElem *def)
Definition: define.c:94
static overexplain_options * overexplain_ensure_options(ExplainState *es)
Definition: pg_overexplain.c:90
Definition: oid2name.c:30

References defGetBoolean(), and overexplain_ensure_options().

Referenced by _PG_init().

overexplain_ensure_options()

static overexplain_options * overexplain_ensure_options ( ExplainStatees )
static

Definition at line 90 of file pg_overexplain.c.

91{
93
95
96 if (options == NULL)
97 {
100 }
101
102 return options;
103}
void * GetExplainExtensionState(ExplainState *es, int extension_id)
Definition: explain_state.c:258
void SetExplainExtensionState(ExplainState *es, int extension_id, void *opaque)
Definition: explain_state.c:277
void * palloc0(Size size)
Definition: mcxt.c:1395
static char ** options
Definition: pg_recvlogical.c:59

References es_extension_id, GetExplainExtensionState(), options, palloc0(), and SetExplainExtensionState().

Referenced by overexplain_debug_handler(), and overexplain_range_table_handler().

overexplain_intlist()

static void overexplain_intlist ( const char *  qlabel,
Listlist,
ExplainStatees 
)
static

Definition at line 749 of file pg_overexplain.c.

750{
752
754
755 if (list == NIL)
756 {
757 ExplainPropertyText(qlabel, "none", es);
758 return;
759 }
760
761 if (IsA(list, IntList))
762 {
764 appendStringInfo(&buf, " %d", i);
765 }
766 else if (IsA(list, OidList))
767 {
768 foreach_oid(o, list)
769 appendStringInfo(&buf, " %u", o);
770 }
771 else if (IsA(list, XidList))
772 {
774 appendStringInfo(&buf, " %u", x);
775 }
776 else
777 {
778 appendStringInfoString(&buf, " not an integer list");
779 Assert(false);
780 }
781
782 if (buf.len > 0)
783 ExplainPropertyText(qlabel, buf.data + 1, es);
784
785 pfree(buf.data);
786}
i
int i
Definition: isn.c:77
#define IsA(nodeptr, _type_)
Definition: nodes.h:164
#define NIL
Definition: pg_list.h:68
#define foreach_xid(var, lst)
Definition: pg_list.h:472
#define foreach_oid(var, lst)
Definition: pg_list.h:471
#define foreach_int(var, lst)
Definition: pg_list.h:470

References appendStringInfo(), appendStringInfoString(), Assert(), buf, ExplainPropertyText(), foreach_int, foreach_oid, foreach_xid, i, initStringInfo(), IsA, sort-test::list, NIL, pfree(), and x.

Referenced by overexplain_debug(), and overexplain_range_table().

overexplain_per_node_hook()

static void overexplain_per_node_hook ( PlanStateplanstate,
Listancestors,
const char *  relationship,
const char *  plan_name,
ExplainStatees 
)
static

Definition at line 134 of file pg_overexplain.c.

137{
139 Plan *plan = planstate->plan;
140
142 (*prev_explain_per_node_hook) (planstate, ancestors, relationship,
143 plan_name, es);
144
146 if (options == NULL)
147 return;
148
149 /*
150 * If the "debug" option was given, display miscellaneous fields from the
151 * "Plan" node that would not otherwise be displayed.
152 */
153 if (options->debug)
154 {
155 /*
156 * Normal EXPLAIN will display "Disabled: true" if the node is
157 * disabled; but that is based on noticing that plan->disabled_nodes
158 * is higher than the sum of its children; here, we display the raw
159 * value, for debugging purposes.
160 */
161 ExplainPropertyInteger("Disabled Nodes", NULL, plan->disabled_nodes,
162 es);
163
164 /*
165 * Normal EXPLAIN will display the parallel_aware flag; here, we show
166 * the parallel_safe flag as well.
167 */
168 ExplainPropertyBool("Parallel Safe", plan->parallel_safe, es);
169
170 /*
171 * The plan node ID isn't normally displayed, since it is only useful
172 * for debugging.
173 */
174 ExplainPropertyInteger("Plan Node ID", NULL, plan->plan_node_id, es);
175
176 /*
177 * It is difficult to explain what extParam and allParam mean in plain
178 * language, so we simply display these fields labelled with the
179 * structure member name. For compactness, the text format omits the
180 * display of this information when the bitmapset is empty.
181 */
182 if (es->format != EXPLAIN_FORMAT_TEXT || !bms_is_empty(plan->extParam))
183 overexplain_bitmapset("extParam", plan->extParam, es);
184 if (es->format != EXPLAIN_FORMAT_TEXT || !bms_is_empty(plan->allParam))
185 overexplain_bitmapset("allParam", plan->allParam, es);
186 }
187
188 /*
189 * If the "range_table" option was specified, display information about
190 * the range table indexes for this node.
191 */
192 if (options->range_table)
193 {
194 switch (nodeTag(plan))
195 {
196 case T_SeqScan:
197 case T_SampleScan:
198 case T_IndexScan:
199 case T_IndexOnlyScan:
200 case T_BitmapHeapScan:
201 case T_TidScan:
202 case T_TidRangeScan:
203 case T_SubqueryScan:
204 case T_FunctionScan:
205 case T_TableFuncScan:
206 case T_ValuesScan:
207 case T_CteScan:
208 case T_NamedTuplestoreScan:
209 case T_WorkTableScan:
210 ExplainPropertyInteger("Scan RTI", NULL,
211 ((Scan *) plan)->scanrelid, es);
212 break;
213 case T_ForeignScan:
214 overexplain_bitmapset("Scan RTIs",
215 ((ForeignScan *) plan)->fs_base_relids,
216 es);
217 break;
218 case T_CustomScan:
219 overexplain_bitmapset("Scan RTIs",
220 ((CustomScan *) plan)->custom_relids,
221 es);
222 break;
223 case T_ModifyTable:
224 ExplainPropertyInteger("Nominal RTI", NULL,
225 ((ModifyTable *) plan)->nominalRelation, es);
226 ExplainPropertyInteger("Exclude Relation RTI", NULL,
227 ((ModifyTable *) plan)->exclRelRTI, es);
228 break;
229 case T_Append:
230 overexplain_bitmapset("Append RTIs",
231 ((Append *) plan)->apprelids,
232 es);
233 break;
234 case T_MergeAppend:
235 overexplain_bitmapset("Append RTIs",
236 ((MergeAppend *) plan)->apprelids,
237 es);
238 break;
239 case T_Result:
240
241 /*
242 * 'relids' is only meaningful when plan->lefttree is NULL,
243 * but if somehow it ends up set when plan->lefttree is not
244 * NULL, print it anyway.
245 */
246 if (plan->lefttree == NULL ||
247 ((Result *) plan)->relids != NULL)
249 ((Result *) plan)->relids,
250 es);
251 default:
252 break;
253 }
254 }
255}
void ExplainPropertyInteger(const char *qlabel, const char *unit, int64 value, ExplainState *es)
void ExplainPropertyBool(const char *qlabel, bool value, ExplainState *es)
#define nodeTag(nodeptr)
Definition: nodes.h:139
#define plan(x)
Definition: pg_regress.c:161
Definition: plannodes.h:382
Plan * plan
Definition: execnodes.h:1159
Definition: plannodes.h:177
Definition: plannodes.h:287
Definition: plannodes.h:511

References bms_is_empty, es_extension_id, EXPLAIN_FORMAT_TEXT, ExplainPropertyBool(), ExplainPropertyInteger(), ExplainState::format, GetExplainExtensionState(), nodeTag, options, overexplain_bitmapset(), PlanState::plan, plan, and prev_explain_per_node_hook.

Referenced by _PG_init().

overexplain_per_plan_hook()

static void overexplain_per_plan_hook ( PlannedStmtplannedstmt,
IntoClauseinto,
ExplainStatees,
const char *  queryString,
ParamListInfo  params,
QueryEnvironmentqueryEnv 
)
static

Definition at line 264 of file pg_overexplain.c.

270{
272
274 (*prev_explain_per_plan_hook) (plannedstmt, into, es, queryString,
275 params, queryEnv);
276
278 if (options == NULL)
279 return;
280
281 if (options->debug)
282 overexplain_debug(plannedstmt, es);
283
284 if (options->range_table)
285 overexplain_range_table(plannedstmt, es);
286}
static void overexplain_range_table(PlannedStmt *plannedstmt, ExplainState *es)
static void overexplain_debug(PlannedStmt *plannedstmt, ExplainState *es)

References es_extension_id, GetExplainExtensionState(), options, overexplain_debug(), overexplain_range_table(), and prev_explain_per_plan_hook.

Referenced by _PG_init().

overexplain_range_table()

static void overexplain_range_table ( PlannedStmtplannedstmt,
ExplainStatees 
)
static

Definition at line 395 of file pg_overexplain.c.

396{
397 Index rti;
398
399 /* Open group, one entry per RangeTblEntry */
400 ExplainOpenGroup("Range Table", "Range Table", false, es);
401
402 /* Iterate over the range table */
403 for (rti = 1; rti <= list_length(plannedstmt->rtable); ++rti)
404 {
405 RangeTblEntry *rte = rt_fetch(rti, plannedstmt->rtable);
406 char *kind = NULL;
407 char *relkind;
408
409 /* NULL entries are possible; skip them */
410 if (rte == NULL)
411 continue;
412
413 /* Translate rtekind to a string */
414 switch (rte->rtekind)
415 {
416 case RTE_RELATION:
417 kind = "relation";
418 break;
419 case RTE_SUBQUERY:
420 kind = "subquery";
421 break;
422 case RTE_JOIN:
423 kind = "join";
424 break;
425 case RTE_FUNCTION:
426 kind = "function";
427 break;
428 case RTE_TABLEFUNC:
429 kind = "tablefunc";
430 break;
431 case RTE_VALUES:
432 kind = "values";
433 break;
434 case RTE_CTE:
435 kind = "cte";
436 break;
438 kind = "namedtuplestore";
439 break;
440 case RTE_RESULT:
441 kind = "result";
442 break;
443 case RTE_GROUP:
444 kind = "group";
445 break;
446 }
447
448 /* Begin group for this specific RTE */
449 ExplainOpenGroup("Range Table Entry", NULL, true, es);
450
451 /*
452 * In text format, the summary line displays the range table index and
453 * rtekind, plus indications if rte->inh and/or rte->inFromCl are set.
454 * In other formats, we display those as separate properties.
455 */
456 if (es->format == EXPLAIN_FORMAT_TEXT)
457 {
459 appendStringInfo(es->str, "RTI %u (%s%s%s):\n", rti, kind,
460 rte->inh ? ", inherited" : "",
461 rte->inFromCl ? ", in-from-clause" : "");
462 es->indent++;
463 }
464 else
465 {
466 ExplainPropertyUInteger("RTI", NULL, rti, es);
467 ExplainPropertyText("Kind", kind, es);
468 ExplainPropertyBool("Inherited", rte->inh, es);
469 ExplainPropertyBool("In From Clause", rte->inFromCl, es);
470 }
471
472 /* rte->alias is optional; rte->eref is requested */
473 if (rte->alias != NULL)
474 overexplain_alias("Alias", rte->alias, es);
475 overexplain_alias("Eref", rte->eref, es);
476
477 /*
478 * We adhere to the usual EXPLAIN convention that schema names are
479 * displayed only in verbose mode, and we emit nothing if there is no
480 * relation OID.
481 */
482 if (rte->relid != 0)
483 {
484 const char *relname;
485 const char *qualname;
486
488
489 if (es->verbose)
490 {
491 Oid nspoid = get_rel_namespace(rte->relid);
492 char *nspname;
493
494 nspname = get_namespace_name_or_temp(nspoid);
495 qualname = psprintf("%s.%s", quote_identifier(nspname),
496 relname);
497 }
498 else
499 qualname = relname;
500
501 ExplainPropertyText("Relation", qualname, es);
502 }
503
504 /* Translate relkind, if any, to a string */
505 switch (rte->relkind)
506 {
507 case RELKIND_RELATION:
508 relkind = "relation";
509 break;
510 case RELKIND_INDEX:
511 relkind = "index";
512 break;
513 case RELKIND_SEQUENCE:
514 relkind = "sequence";
515 break;
516 case RELKIND_TOASTVALUE:
517 relkind = "toastvalue";
518 break;
519 case RELKIND_VIEW:
520 relkind = "view";
521 break;
522 case RELKIND_MATVIEW:
523 relkind = "matview";
524 break;
525 case RELKIND_COMPOSITE_TYPE:
526 relkind = "composite_type";
527 break;
528 case RELKIND_FOREIGN_TABLE:
529 relkind = "foreign_table";
530 break;
531 case RELKIND_PARTITIONED_TABLE:
532 relkind = "partitioned_table";
533 break;
534 case RELKIND_PARTITIONED_INDEX:
535 relkind = "partitioned_index";
536 break;
537 case '0円':
538 relkind = NULL;
539 break;
540 default:
541 relkind = psprintf("%c", rte->relkind);
542 break;
543 }
544
545 /* If there is a relkind, show it */
546 if (relkind != NULL)
547 ExplainPropertyText("Relation Kind", relkind, es);
548
549 /* If there is a lock mode, show it */
550 if (rte->rellockmode != 0)
551 ExplainPropertyText("Relation Lock Mode",
553 rte->rellockmode), es);
554
555 /*
556 * If there is a perminfoindex, show it. We don't try to display
557 * information from the RTEPermissionInfo node here because they are
558 * just indexes plannedstmt->permInfos which could be separately
559 * dumped if someone wants to add EXPLAIN (PERMISSIONS) or similar.
560 */
561 if (rte->perminfoindex != 0)
562 ExplainPropertyInteger("Permission Info Index", NULL,
563 rte->perminfoindex, es);
564
565 /*
566 * add_rte_to_flat_rtable will clear rte->tablesample and
567 * rte->subquery in the finished plan, so skip those fields.
568 *
569 * However, the security_barrier flag is not shown by the core code,
570 * so let's print it here.
571 */
572 if (es->format != EXPLAIN_FORMAT_TEXT || rte->security_barrier)
573 ExplainPropertyBool("Security Barrier", rte->security_barrier, es);
574
575 /*
576 * If this is a join, print out the fields that are specifically valid
577 * for joins.
578 */
579 if (rte->rtekind == RTE_JOIN)
580 {
581 char *jointype;
582
583 switch (rte->jointype)
584 {
585 case JOIN_INNER:
586 jointype = "Inner";
587 break;
588 case JOIN_LEFT:
589 jointype = "Left";
590 break;
591 case JOIN_FULL:
592 jointype = "Full";
593 break;
594 case JOIN_RIGHT:
595 jointype = "Right";
596 break;
597 case JOIN_SEMI:
598 jointype = "Semi";
599 break;
600 case JOIN_ANTI:
601 jointype = "Anti";
602 break;
603 case JOIN_RIGHT_SEMI:
604 jointype = "Right Semi";
605 break;
606 case JOIN_RIGHT_ANTI:
607 jointype = "Right Anti";
608 break;
609 default:
610 jointype = "???";
611 break;
612 }
613
614 /* Join type */
615 ExplainPropertyText("Join Type", jointype, es);
616
617 /* # of JOIN USING columns */
618 if (es->format != EXPLAIN_FORMAT_TEXT || rte->joinmergedcols != 0)
619 ExplainPropertyInteger("JOIN USING Columns", NULL,
620 rte->joinmergedcols, es);
621
622 /*
623 * add_rte_to_flat_rtable will clear joinaliasvars, joinleftcols,
624 * joinrightcols, and join_using_alias here, so skip those fields.
625 */
626 }
627
628 /*
629 * add_rte_to_flat_rtable will clear functions, tablefunc, and
630 * values_lists, but we can display funcordinality.
631 */
632 if (rte->rtekind == RTE_FUNCTION)
633 ExplainPropertyBool("WITH ORDINALITY", rte->funcordinality, es);
634
635 /*
636 * If this is a CTE, print out CTE-related properties.
637 */
638 if (rte->rtekind == RTE_CTE)
639 {
640 ExplainPropertyText("CTE Name", rte->ctename, es);
641 ExplainPropertyUInteger("CTE Levels Up", NULL, rte->ctelevelsup,
642 es);
643 ExplainPropertyBool("CTE Self-Reference", rte->self_reference, es);
644 }
645
646 /*
647 * add_rte_to_flat_rtable will clear coltypes, coltypmods, and
648 * colcollations, so skip those fields.
649 *
650 * If this is an ephemeral named relation, print out ENR-related
651 * properties.
652 */
653 if (rte->rtekind == RTE_NAMEDTUPLESTORE)
654 {
655 ExplainPropertyText("ENR Name", rte->enrname, es);
656 ExplainPropertyFloat("ENR Tuples", NULL, rte->enrtuples, 0, es);
657 }
658
659 /*
660 * add_rte_to_flat_rtable will clear groupexprs and securityQuals, so
661 * skip that field. We have handled inFromCl above, so the only thing
662 * left to handle here is rte->lateral.
663 */
664 if (es->format != EXPLAIN_FORMAT_TEXT || rte->lateral)
665 ExplainPropertyBool("Lateral", rte->lateral, es);
666
667 /* Done with this RTE */
668 if (es->format == EXPLAIN_FORMAT_TEXT)
669 es->indent--;
670 ExplainCloseGroup("Range Table Entry", NULL, true, es);
671 }
672
673 /* Print PlannedStmt fields that contain RTIs. */
674 if (es->format != EXPLAIN_FORMAT_TEXT ||
675 !bms_is_empty(plannedstmt->unprunableRelids))
676 overexplain_bitmapset("Unprunable RTIs", plannedstmt->unprunableRelids,
677 es);
678 if (es->format != EXPLAIN_FORMAT_TEXT ||
679 plannedstmt->resultRelations != NIL)
680 overexplain_intlist("Result RTIs", plannedstmt->resultRelations, es);
681
682 /* Close group, we're all done */
683 ExplainCloseGroup("Range Table", "Range Table", false, es);
684}
unsigned int Index
Definition: c.h:619
void ExplainPropertyUInteger(const char *qlabel, const char *unit, uint64 value, ExplainState *es)
void ExplainPropertyFloat(const char *qlabel, const char *unit, double value, int ndigits, ExplainState *es)
const char * GetLockmodeName(LOCKMETHODID lockmethodid, LOCKMODE mode)
Definition: lock.c:4255
#define DEFAULT_LOCKMETHOD
Definition: lock.h:127
char * get_rel_name(Oid relid)
Definition: lsyscache.c:2095
Oid get_rel_namespace(Oid relid)
Definition: lsyscache.c:2119
char * get_namespace_name_or_temp(Oid nspid)
Definition: lsyscache.c:3557
@ JOIN_SEMI
Definition: nodes.h:317
@ JOIN_FULL
Definition: nodes.h:305
@ JOIN_INNER
Definition: nodes.h:303
@ JOIN_RIGHT
Definition: nodes.h:306
@ JOIN_RIGHT_SEMI
Definition: nodes.h:319
@ JOIN_LEFT
Definition: nodes.h:304
@ JOIN_RIGHT_ANTI
Definition: nodes.h:320
@ JOIN_ANTI
Definition: nodes.h:318
@ RTE_JOIN
Definition: parsenodes.h:1045
@ RTE_CTE
Definition: parsenodes.h:1049
@ RTE_NAMEDTUPLESTORE
Definition: parsenodes.h:1050
@ RTE_VALUES
Definition: parsenodes.h:1048
@ RTE_SUBQUERY
Definition: parsenodes.h:1044
@ RTE_RESULT
Definition: parsenodes.h:1051
@ RTE_FUNCTION
Definition: parsenodes.h:1046
@ RTE_TABLEFUNC
Definition: parsenodes.h:1047
@ RTE_GROUP
Definition: parsenodes.h:1054
@ RTE_RELATION
Definition: parsenodes.h:1043
#define rt_fetch(rangetable_index, rangetable)
Definition: parsetree.h:31
NameData relname
Definition: pg_class.h:38
static int list_length(const List *l)
Definition: pg_list.h:152
static void overexplain_alias(const char *qlabel, Alias *alias, ExplainState *es)
unsigned int Oid
Definition: postgres_ext.h:32
bool verbose
Definition: explain_state.h:48
List * resultRelations
Definition: plannodes.h:124
Bitmapset * unprunableRelids
Definition: plannodes.h:115
List * rtable
Definition: plannodes.h:109
char * ctename
Definition: parsenodes.h:1227
Index ctelevelsup
Definition: parsenodes.h:1229
bool funcordinality
Definition: parsenodes.h:1210
char * enrname
Definition: parsenodes.h:1262
JoinType jointype
Definition: parsenodes.h:1182
RTEKind rtekind
Definition: parsenodes.h:1078

References appendStringInfo(), bms_is_empty, RangeTblEntry::ctelevelsup, RangeTblEntry::ctename, DEFAULT_LOCKMETHOD, RangeTblEntry::enrname, EXPLAIN_FORMAT_TEXT, ExplainCloseGroup(), ExplainIndentText(), ExplainOpenGroup(), ExplainPropertyBool(), ExplainPropertyFloat(), ExplainPropertyInteger(), ExplainPropertyText(), ExplainPropertyUInteger(), ExplainState::format, RangeTblEntry::funcordinality, get_namespace_name_or_temp(), get_rel_name(), get_rel_namespace(), GetLockmodeName(), ExplainState::indent, RangeTblEntry::inh, JOIN_ANTI, JOIN_FULL, JOIN_INNER, JOIN_LEFT, JOIN_RIGHT, JOIN_RIGHT_ANTI, JOIN_RIGHT_SEMI, JOIN_SEMI, RangeTblEntry::jointype, list_length(), NIL, overexplain_alias(), overexplain_bitmapset(), overexplain_intlist(), psprintf(), quote_identifier(), relname, PlannedStmt::resultRelations, rt_fetch, PlannedStmt::rtable, RTE_CTE, RTE_FUNCTION, RTE_GROUP, RTE_JOIN, RTE_NAMEDTUPLESTORE, RTE_RELATION, RTE_RESULT, RTE_SUBQUERY, RTE_TABLEFUNC, RTE_VALUES, RangeTblEntry::rtekind, ExplainState::str, PlannedStmt::unprunableRelids, and ExplainState::verbose.

Referenced by overexplain_per_plan_hook().

overexplain_range_table_handler()

static void overexplain_range_table_handler ( ExplainStatees,
DefElemopt,
ParseStatepstate 
)
static

Definition at line 120 of file pg_overexplain.c.

122{
124
125 options->range_table = defGetBoolean(opt);
126}

References defGetBoolean(), and overexplain_ensure_options().

Referenced by _PG_init().

PG_MODULE_MAGIC_EXT()

PG_MODULE_MAGIC_EXT ( .  name = "pg_overexplain",
version = PG_VERSION 
)

Variable Documentation

es_extension_id

int es_extension_id
static

Definition at line 60 of file pg_overexplain.c.

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

prev_explain_per_node_hook

explain_per_node_hook_type prev_explain_per_node_hook
static

Definition at line 61 of file pg_overexplain.c.

Referenced by _PG_init(), and overexplain_per_node_hook().

prev_explain_per_plan_hook

explain_per_plan_hook_type prev_explain_per_plan_hook
static

Definition at line 62 of file pg_overexplain.c.

Referenced by _PG_init(), and overexplain_per_plan_hook().

AltStyle によって変換されたページ (->オリジナル) /