63 #define X_CLOSE_IMMEDIATE 2
64 #define X_NOWHITESPACE 4
70 #define BYTES_TO_KILOBYTES(b) (((b) + 1023) / 1024)
85 const char *relationship,
const char *plan_name,
118 int nkeys,
int nPresortedKeys,
AttrNumber *keycols,
119 Oid *sortOperators,
Oid *collations,
bool *nullsFirst,
122 Oid sortOperator,
Oid collation,
bool nullsFirst);
201 bool timing_set =
false;
202 bool summary_set =
false;
205 foreach(lc,
stmt->options)
209 if (strcmp(opt->
defname,
"analyze") == 0)
211 else if (strcmp(opt->
defname,
"verbose") == 0)
213 else if (strcmp(opt->
defname,
"costs") == 0)
215 else if (strcmp(opt->
defname,
"buffers") == 0)
217 else if (strcmp(opt->
defname,
"wal") == 0)
219 else if (strcmp(opt->
defname,
"settings") == 0)
221 else if (strcmp(opt->
defname,
"generic_plan") == 0)
223 else if (strcmp(opt->
defname,
"timing") == 0)
228 else if (strcmp(opt->
defname,
"summary") == 0)
233 else if (strcmp(opt->
defname,
"memory") == 0)
235 else if (strcmp(opt->
defname,
"serialize") == 0)
241 if (strcmp(p,
"off") == 0 || strcmp(p,
"none") == 0)
243 else if (strcmp(p,
"text") == 0)
245 else if (strcmp(p,
"binary") == 0)
249 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
250 errmsg(
"unrecognized value for EXPLAIN option \"%s\": \"%s\"",
260 else if (strcmp(opt->
defname,
"format") == 0)
264 if (strcmp(p,
"text") == 0)
266 else if (strcmp(p,
"xml") == 0)
268 else if (strcmp(p,
"json") == 0)
270 else if (strcmp(p,
"yaml") == 0)
274 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
275 errmsg(
"unrecognized value for EXPLAIN option \"%s\": \"%s\"",
281 (
errcode(ERRCODE_SYNTAX_ERROR),
282 errmsg(
"unrecognized EXPLAIN option \"%s\"",
290 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
291 errmsg(
"EXPLAIN option WAL requires ANALYZE")));
299 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
300 errmsg(
"EXPLAIN option TIMING requires ANALYZE")));
305 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
306 errmsg(
"EXPLAIN option SERIALIZE requires ANALYZE")));
311 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
312 errmsg(
"EXPLAIN options ANALYZE and GENERIC_PLAN cannot be used together")));
322 (*post_parse_analyze_hook) (pstate, query, jstate);
335 if (rewritten ==
NIL)
349 foreach(l, rewritten)
356 if (
lnext(rewritten, l) != NULL)
402 Oid result_type = TEXTOID;
405 foreach(lc,
stmt->options)
409 if (strcmp(opt->
defname,
"format") == 0)
413 if (strcmp(p,
"xml") == 0)
414 result_type = XMLOID;
415 else if (strcmp(p,
"json") == 0)
416 result_type = JSONOID;
418 result_type = TEXTOID;
452 (*ExplainOneQuery_hook) (query, cursorOptions, into, es,
453 queryString, params, queryEnv);
456 queryString, params, queryEnv);
489 "explain analyze planner context",
519 &planduration, (es->
buffers ? &bufusage : NULL),
520 es->
memory ? &mem_counters : NULL);
540 if (utilityStmt == NULL)
563 elog(
ERROR,
"unexpected object type: %d",
572 queryString, params, queryEnv);
591 queryString, params, queryEnv);
595 queryString, params, queryEnv);
607 "Utility statements have no plan structure\n");
635 double totaltime = 0;
637 int instrument_option = 0;
684 dest, params, queryEnv, instrument_option);
756 if (es->
summary && planduration)
832 for (
int i = 0;
i < num;
i++)
854 for (
int i = 0;
i < num;
i++)
979 routerels !=
NIL || targrels !=
NIL);
980 foreach(l, resultrels)
986 foreach(l, routerels)
1061 "Inlining", jit_flags &
PGJIT_INLINE ?
"true" :
"false",
1062 "Optimization", jit_flags &
PGJIT_OPT3 ?
"true" :
"false",
1063 "Expressions", jit_flags &
PGJIT_EXPR ?
"true" :
"false",
1064 "Deforming", jit_flags &
PGJIT_DEFORM ?
"true" :
"false");
1070 "Timing: %s %.3f ms (%s %.3f ms), %s %.3f ms, %s %.3f ms, %s %.3f ms, %s %.3f ms\n",
1210 if (params == NULL || params->
numParams <= 0 || maxlen == 0)
1214 if (
str &&
str[0] !=
'\0')
1234 char *conname = NULL;
1259 if (es->
verbose || conname == NULL)
1322 case T_IndexOnlyScan:
1323 case T_BitmapHeapScan:
1325 case T_TidRangeScan:
1326 case T_SubqueryScan:
1327 case T_FunctionScan:
1328 case T_TableFuncScan:
1331 case T_NamedTuplestoreScan:
1332 case T_WorkTableScan:
1389 const char *relationship,
const char *plan_name,
1395 const char *strategy = NULL;
1396 const char *partialmode = NULL;
1397 const char *operation = NULL;
1398 const char *custom_name = NULL;
1400 int save_indent = es->
indent;
1416 pname = sname =
"Result";
1419 pname = sname =
"ProjectSet";
1422 sname =
"ModifyTable";
1426 pname = operation =
"Insert";
1429 pname = operation =
"Update";
1432 pname = operation =
"Delete";
1435 pname = operation =
"Merge";
1443 pname = sname =
"Append";
1446 pname = sname =
"Merge Append";
1448 case T_RecursiveUnion:
1449 pname = sname =
"Recursive Union";
1452 pname = sname =
"BitmapAnd";
1455 pname = sname =
"BitmapOr";
1458 pname = sname =
"Nested Loop";
1462 sname =
"Merge Join";
1466 sname =
"Hash Join";
1469 pname = sname =
"Seq Scan";
1472 pname = sname =
"Sample Scan";
1475 pname = sname =
"Gather";
1478 pname = sname =
"Gather Merge";
1481 pname = sname =
"Index Scan";
1483 case T_IndexOnlyScan:
1484 pname = sname =
"Index Only Scan";
1486 case T_BitmapIndexScan:
1487 pname = sname =
"Bitmap Index Scan";
1489 case T_BitmapHeapScan:
1490 pname = sname =
"Bitmap Heap Scan";
1493 pname = sname =
"Tid Scan";
1495 case T_TidRangeScan:
1496 pname = sname =
"Tid Range Scan";
1498 case T_SubqueryScan:
1499 pname = sname =
"Subquery Scan";
1501 case T_FunctionScan:
1502 pname = sname =
"Function Scan";
1504 case T_TableFuncScan:
1505 pname = sname =
"Table Function Scan";
1508 pname = sname =
"Values Scan";
1511 pname = sname =
"CTE Scan";
1513 case T_NamedTuplestoreScan:
1514 pname = sname =
"Named Tuplestore Scan";
1516 case T_WorkTableScan:
1517 pname = sname =
"WorkTable Scan";
1520 sname =
"Foreign Scan";
1524 pname =
"Foreign Scan";
1525 operation =
"Select";
1528 pname =
"Foreign Insert";
1529 operation =
"Insert";
1532 pname =
"Foreign Update";
1533 operation =
"Update";
1536 pname =
"Foreign Delete";
1537 operation =
"Delete";
1545 sname =
"Custom Scan";
1548 pname =
psprintf(
"Custom Scan (%s)", custom_name);
1553 pname = sname =
"Materialize";
1556 pname = sname =
"Memoize";
1559 pname = sname =
"Sort";
1561 case T_IncrementalSort:
1562 pname = sname =
"Incremental Sort";
1565 pname = sname =
"Group";
1571 sname =
"Aggregate";
1575 pname =
"Aggregate";
1579 pname =
"GroupAggregate";
1580 strategy =
"Sorted";
1583 pname =
"HashAggregate";
1584 strategy =
"Hashed";
1587 pname =
"MixedAggregate";
1591 pname =
"Aggregate ???";
1598 partialmode =
"Partial";
1599 pname =
psprintf(
"%s %s", partialmode, pname);
1603 partialmode =
"Finalize";
1604 pname =
psprintf(
"%s %s", partialmode, pname);
1607 partialmode =
"Simple";
1611 pname = sname =
"WindowAgg";
1614 pname = sname =
"Unique";
1622 strategy =
"Sorted";
1625 pname =
"HashSetOp";
1626 strategy =
"Hashed";
1629 pname =
"SetOp ???";
1635 pname = sname =
"LockRows";
1638 pname = sname =
"Limit";
1641 pname = sname =
"Hash";
1644 pname = sname =
"???";
1649 relationship ? NULL :
"Plan",
1666 if (
plan->parallel_aware)
1668 if (
plan->async_capable)
1696 case T_BitmapHeapScan:
1698 case T_TidRangeScan:
1699 case T_SubqueryScan:
1700 case T_FunctionScan:
1701 case T_TableFuncScan:
1704 case T_WorkTableScan:
1709 if (((
Scan *)
plan)->scanrelid > 0)
1722 case T_IndexOnlyScan:
1732 case T_BitmapIndexScan:
1735 const char *indexname =
1752 const char *jointype;
1775 jointype =
"Right Semi";
1778 jointype =
"Right Anti";
1801 const char *setopcmd;
1806 setopcmd =
"Intersect";
1809 setopcmd =
"Intersect All";
1812 setopcmd =
"Except";
1815 setopcmd =
"Except All";
1836 plan->startup_cost,
plan->total_cost,
1837 plan->plan_rows,
plan->plan_width);
1877 " (actual time=%.3f..%.3f rows=%.0f loops=%.0f)",
1878 startup_ms, total_ms, rows, nloops);
1881 " (actual rows=%.0f loops=%.0f)",
1917 if (
plan->disabled_nodes != 0)
1929 double nloops = instrument->
nloops;
1936 startup_ms = 1000.0 * instrument->
startup / nloops;
1937 total_ms = 1000.0 * instrument->
total / nloops;
1938 rows = instrument->
ntuples / nloops;
1947 "actual time=%.3f..%.3f rows=%.0f loops=%.0f\n",
1948 startup_ms, total_ms, rows, nloops);
1951 "actual rows=%.0f loops=%.0f\n",
1997 "Index Cond", planstate, ancestors, es);
2002 "Order By", planstate, ancestors, es);
2008 case T_IndexOnlyScan:
2010 "Index Cond", planstate, ancestors, es);
2015 "Order By", planstate, ancestors, es);
2024 case T_BitmapIndexScan:
2026 "Index Cond", planstate, ancestors, es);
2028 case T_BitmapHeapScan:
2030 "Recheck Cond", planstate, ancestors, es);
2042 planstate, ancestors, es);
2048 case T_NamedTuplestoreScan:
2049 case T_WorkTableScan:
2050 case T_SubqueryScan:
2073 nworkers = ((
GatherState *) planstate)->nworkers_launched;
2103 case T_FunctionScan:
2117 "Function Call", planstate, ancestors,
2125 case T_TableFuncScan:
2131 "Table Function Call", planstate, ancestors,
2158 case T_TidRangeScan:
2196 "Join Filter", planstate, ancestors, es);
2207 "Merge Cond", planstate, ancestors, es);
2209 "Join Filter", planstate, ancestors, es);
2220 "Hash Cond", planstate, ancestors, es);
2222 "Join Filter", planstate, ancestors, es);
2245 "Run Condition", planstate, ancestors, es);
2259 case T_IncrementalSort:
2271 "One-Time Filter", planstate, ancestors, es);
2291 case T_RecursiveUnion:
2333 double nloops = instrument->
nloops;
2377 haschildren = planstate->
initPlan ||
2432 case T_SubqueryScan:
2434 "Subquery", NULL, es);
2457 es->
indent = save_indent;
2460 relationship ? NULL :
"Plan",
2509 foreach(lc,
plan->targetlist)
2577 show_qual(qual, qlabel, planstate, ancestors, useprefix, es);
2591 show_qual(qual, qlabel, planstate, ancestors, useprefix, es);
2603 plan->numCols, 0,
plan->sortColIdx,
2604 plan->sortOperators,
plan->collations,
2619 plan->sort.numCols,
plan->nPresortedCols,
2620 plan->sort.sortColIdx,
2621 plan->sort.sortOperators,
plan->sort.collations,
2622 plan->sort.nullsFirst,
2636 plan->numCols, 0,
plan->sortColIdx,
2637 plan->sortOperators,
plan->collations,
2656 if (
plan->groupingSets)
2685 context, useprefix, ancestors, es);
2687 foreach(lc, agg->
chain)
2693 context, useprefix, ancestors, es);
2710 const char *keyname;
2711 const char *keysetname;
2715 keyname =
"Hash Key";
2716 keysetname =
"Hash Keys";
2720 keyname =
"Group Key";
2721 keysetname =
"Group Keys";
2729 sortnode->
numCols, 0, sortnode->sortColIdx,
2730 sortnode->sortOperators, sortnode->collations,
2731 sortnode->nullsFirst,
2752 elog(
ERROR,
"no tlist entry for key %d", keyresno);
2757 result =
lappend(result, exprstr);
2799 int nkeys,
int nPresortedKeys,
AttrNumber *keycols,
2800 Oid *sortOperators,
Oid *collations,
bool *nullsFirst,
2822 for (keyno = 0; keyno < nkeys; keyno++)
2831 elog(
ERROR,
"no tlist entry for key %d", keyresno);
2838 if (sortOperators != NULL)
2841 sortOperators[keyno],
2846 if (keyno < nPresortedKeys)
2847 resultPresorted =
lappend(resultPresorted, exprstr);
2851 if (nPresortedKeys > 0)
2861 Oid sortOperator,
Oid collation,
bool nullsFirst)
2864 bool reverse =
false;
2881 if (collname == NULL)
2882 elog(
ERROR,
"cache lookup failed for collation %u", collation);
2887 if (sortOperator == typentry->
gt_opr)
2892 else if (sortOperator != typentry->
lt_opr)
2897 elog(
ERROR,
"cache lookup failed for operator %u", sortOperator);
2904 if (nullsFirst && !reverse)
2908 else if (!nullsFirst && reverse)
2961 foreach(lc, tsc->
args)
3016 const char *sortMethod;
3017 const char *spaceType;
3023 spaceUsed = stats.spaceUsed;
3029 sortMethod, spaceType, spaceUsed);
3055 const char *sortMethod;
3056 const char *spaceType;
3074 sortMethod, spaceType, spaceUsed);
3128 foreach(methodCell, methodNames)
3138 const char *spaceTypeName;
3142 spaceTypeName, avgSpace,
3150 const char *spaceTypeName;
3154 spaceTypeName, avgSpace,
3172 const char *spaceTypeName;
3189 const char *spaceTypeName;
3249 bool indent_first_line;
3277 indent_first_line, es);
3345 if (hinstrument.
nbatch > 0)
3367 "Buckets: %d (originally %d) Batches: %d (originally %d) Memory Usage: " UINT64_FORMAT "kB\n",
3378 "Buckets: %d Batches: %d Memory Usage: " UINT64_FORMAT "kB\n",
3392 char *maxStorageType;
3401 if (!es->
analyze || tupstore == NULL)
3415 char *maxStorageType;
3424 if (!es->
analyze || tupstore == NULL)
3438 char *maxStorageType;
3443 if (!es->
analyze || tupstore == NULL)
3457 char *maxStorageType;
3462 if (!es->
analyze || tupstore == NULL)
3476 char *maxStorageType,
3494 if (tempSpaceUsed > maxSpaceUsed)
3495 maxStorageType = tempStorageType;
3497 maxSpaceUsed += tempSpaceUsed;
3680 bool gotone =
false;
3724 uint64 hash_disk_used;
3725 int hash_batches_used;
3743 hash_batches_used, memPeakKb);
3746 if (hash_batches_used > 1)
3754 hash_batches_used, es);
3797 if (planstate->
pstate != NULL)
3901 result = (*explain_get_index_name_hook) (indexId);
3909 elog(
ERROR,
"cache lookup failed for index %u", indexId);
3925 bool has_shared_timing;
3926 bool has_local_timing;
3927 bool has_temp_timing;
3935 has_shared = (
usage->shared_blks_hit > 0 ||
3936 usage->shared_blks_read > 0 ||
3937 usage->shared_blks_dirtied > 0 ||
3938 usage->shared_blks_written > 0);
3939 has_local = (
usage->local_blks_hit > 0 ||
3940 usage->local_blks_read > 0 ||
3941 usage->local_blks_dirtied > 0 ||
3942 usage->local_blks_written > 0);
3943 has_temp = (
usage->temp_blks_read > 0 ||
3944 usage->temp_blks_written > 0);
3952 return has_shared || has_local || has_temp || has_shared_timing ||
3953 has_local_timing || has_temp_timing;
3964 bool has_shared = (
usage->shared_blks_hit > 0 ||
3965 usage->shared_blks_read > 0 ||
3966 usage->shared_blks_dirtied > 0 ||
3967 usage->shared_blks_written > 0);
3968 bool has_local = (
usage->local_blks_hit > 0 ||
3969 usage->local_blks_read > 0 ||
3970 usage->local_blks_dirtied > 0 ||
3971 usage->local_blks_written > 0);
3972 bool has_temp = (
usage->temp_blks_read > 0 ||
3973 usage->temp_blks_written > 0);
3982 if (has_shared || has_local || has_temp)
3990 if (
usage->shared_blks_hit > 0)
3992 (
long long)
usage->shared_blks_hit);
3993 if (
usage->shared_blks_read > 0)
3995 (
long long)
usage->shared_blks_read);
3996 if (
usage->shared_blks_dirtied > 0)
3998 (
long long)
usage->shared_blks_dirtied);
3999 if (
usage->shared_blks_written > 0)
4001 (
long long)
usage->shared_blks_written);
4002 if (has_local || has_temp)
4008 if (
usage->local_blks_hit > 0)
4010 (
long long)
usage->local_blks_hit);
4011 if (
usage->local_blks_read > 0)
4013 (
long long)
usage->local_blks_read);
4014 if (
usage->local_blks_dirtied > 0)
4016 (
long long)
usage->local_blks_dirtied);
4017 if (
usage->local_blks_written > 0)
4019 (
long long)
usage->local_blks_written);
4026 if (
usage->temp_blks_read > 0)
4028 (
long long)
usage->temp_blks_read);
4029 if (
usage->temp_blks_written > 0)
4031 (
long long)
usage->temp_blks_written);
4037 if (has_shared_timing || has_local_timing || has_temp_timing)
4042 if (has_shared_timing)
4051 if (has_local_timing || has_temp_timing)
4054 if (has_local_timing)
4063 if (has_temp_timing)
4066 if (has_temp_timing)
4082 usage->shared_blks_hit, es);
4084 usage->shared_blks_read, es);
4086 usage->shared_blks_dirtied, es);
4088 usage->shared_blks_written, es);
4090 usage->local_blks_hit, es);
4092 usage->local_blks_read, es);
4094 usage->local_blks_dirtied, es);
4096 usage->local_blks_written, es);
4098 usage->temp_blks_read, es);
4100 usage->temp_blks_written, es);
4134 if ((
usage->wal_records > 0) || (
usage->wal_fpi > 0) ||
4135 (
usage->wal_bytes > 0))
4140 if (
usage->wal_records > 0)
4142 (
long long)
usage->wal_records);
4143 if (
usage->wal_fpi > 0)
4145 (
long long)
usage->wal_fpi);
4146 if (
usage->wal_bytes > 0)
4155 usage->wal_records, es);
4157 usage->wal_fpi, es);
4159 usage->wal_bytes, es);
4178 memUsedkB, memAllocatedkB);
4206 const char *scandir;
4208 switch (indexorderdir)
4211 scandir =
"Backward";
4214 scandir =
"Forward";
4253 char *objectname = NULL;
4254 char *
namespace = NULL;
4255 const char *objecttag = NULL;
4261 if (refname == NULL)
4262 refname = rte->eref->aliasname;
4269 case T_IndexOnlyScan:
4270 case T_BitmapHeapScan:
4272 case T_TidRangeScan:
4281 objecttag =
"Relation Name";
4283 case T_FunctionScan:
4310 objecttag =
"Function Name";
4313 case T_TableFuncScan:
4321 objectname =
"xmltable";
4324 objectname =
"json_table";
4327 elog(
ERROR,
"invalid TableFunc type %d",
4330 objecttag =
"Table Function Name";
4339 Assert(!rte->self_reference);
4340 objectname = rte->ctename;
4341 objecttag =
"CTE Name";
4343 case T_NamedTuplestoreScan:
4345 objectname = rte->enrname;
4346 objecttag =
"Tuplestore Name";
4348 case T_WorkTableScan:
4351 Assert(rte->self_reference);
4352 objectname = rte->ctename;
4353 objecttag =
"CTE Name";
4362 if (
namespace != NULL)
4365 else if (objectname != NULL)
4367 if (objectname == NULL || strcmp(refname, objectname) != 0)
4372 if (objecttag != NULL && objectname != NULL)
4374 if (
namespace != NULL)
4393 const char *operation;
4394 const char *foperation;
4403 operation =
"Insert";
4404 foperation =
"Foreign Insert";
4407 operation =
"Update";
4408 foperation =
"Foreign Update";
4411 operation =
"Delete";
4412 foperation =
"Foreign Delete";
4415 operation =
"Merge";
4417 foperation =
"Foreign Merge";
4421 foperation =
"Foreign ???";
4426 labeltargets = (mtstate->
mt_nrels > 1 ||
4451 fdwroutine ? foperation : operation);
4468 fdwroutine != NULL &&
4496 idxNames =
lappend(idxNames, indexname);
4503 "NOTHING" :
"UPDATE",
4517 &mtstate->
ps, ancestors, es);
4533 insert_path = total - other_path;
4536 insert_path, 0, es);
4550 double skipped_path;
4559 skipped_path = total - insert_path - update_path - delete_path;
4560 Assert(skipped_path >= 0);
4568 if (insert_path > 0)
4570 if (update_path > 0)
4572 if (delete_path > 0)
4574 if (skipped_path > 0)
4606 for (
j = 0;
j < nplans;
j++)
4608 "Member", NULL, es);
4623 nchildren - nplans, es);
4663 ancestors =
lcons(sp, ancestors);
4720 Assert(n >= 0 && n < wstate->num_workers);
4782 Assert(n >= 0 && n < wstate->num_workers);