Skip to content

Commit 40708ac

Browse files
committed
Add memory/disk usage for more executor nodes.
This commit is similar to 95d6e9a, expanding the idea to CTE scan, table function scan and recursive union scan nodes so that the maximum tuplestore memory or disk usage is shown with EXPLAIN ANALYZE command. Also adjust show_storage_info() so that it accepts storage type and storage size arguments instead of Tuplestorestate. This allows the node types to share the formatting code using show_storage_info(). Due to this show_material_info() and show_windowagg_info() are also modified. Reviewed-by: David Rowley Discussion: https://postgr.es/m/20240918.211246.1127161704188186085.ishii%40postgresql.org
1 parent 6aa4406 commit 40708ac

File tree

1 file changed

+97
-10
lines changed

1 file changed

+97
-10
lines changed

src/backend/commands/explain.c

Lines changed: 97 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ static void show_sort_group_keys(PlanState *planstate, const char *qlabel,
120120
List *ancestors, ExplainState *es);
121121
static void show_sortorder_options(StringInfo buf, Node *sortexpr,
122122
Oid sortOperator, Oid collation, bool nullsFirst);
123-
static void show_storage_info(Tuplestorestate *tupstore, ExplainState *es);
123+
static void show_storage_info(char *maxStorageType, int64 maxSpaceUsed,
124+
ExplainState *es);
124125
static void show_tablesample(TableSampleClause *tsc, PlanState *planstate,
125126
List *ancestors, ExplainState *es);
126127
static void show_sort_info(SortState *sortstate, ExplainState *es);
@@ -129,6 +130,11 @@ static void show_incremental_sort_info(IncrementalSortState *incrsortstate,
129130
static void show_hash_info(HashState *hashstate, ExplainState *es);
130131
static void show_material_info(MaterialState *mstate, ExplainState *es);
131132
static void show_windowagg_info(WindowAggState *winstate, ExplainState *es);
133+
static void show_ctescan_info(CteScanState *ctescanstate, ExplainState *es);
134+
static void show_table_func_scan_info(TableFuncScanState *tscanstate,
135+
ExplainState *es);
136+
static void show_recursive_union_info(RecursiveUnionState *rstate,
137+
ExplainState *es);
132138
static void show_memoize_info(MemoizeState *mstate, List *ancestors,
133139
ExplainState *es);
134140
static void show_hashagg_info(AggState *aggstate, ExplainState *es);
@@ -2046,6 +2052,8 @@ ExplainNode(PlanState *planstate, List *ancestors,
20462052
if (plan->qual)
20472053
show_instrumentation_count("Rows Removed by Filter", 1,
20482054
planstate, es);
2055+
if (IsA(plan, CteScan))
2056+
show_ctescan_info(castNode(CteScanState, planstate), es);
20492057
break;
20502058
case T_Gather:
20512059
{
@@ -2127,6 +2135,8 @@ ExplainNode(PlanState *planstate, List *ancestors,
21272135
if (plan->qual)
21282136
show_instrumentation_count("Rows Removed by Filter", 1,
21292137
planstate, es);
2138+
show_table_func_scan_info(castNode(TableFuncScanState,
2139+
planstate), es);
21302140
break;
21312141
case T_TidScan:
21322142
{
@@ -2278,6 +2288,10 @@ ExplainNode(PlanState *planstate, List *ancestors,
22782288
show_memoize_info(castNode(MemoizeState, planstate), ancestors,
22792289
es);
22802290
break;
2291+
case T_RecursiveUnion:
2292+
show_recursive_union_info(castNode(RecursiveUnionState,
2293+
planstate), es);
2294+
break;
22812295
default:
22822296
break;
22832297
}
@@ -2901,14 +2915,9 @@ show_sortorder_options(StringInfo buf, Node *sortexpr,
29012915
* Show information on storage method and maximum memory/disk space used.
29022916
*/
29032917
static void
2904-
show_storage_info(Tuplestorestate *tupstore, ExplainState *es)
2918+
show_storage_info(char *maxStorageType, int64 maxSpaceUsed, ExplainState *es)
29052919
{
2906-
char *maxStorageType;
2907-
int64 maxSpaceUsed,
2908-
maxSpaceUsedKB;
2909-
2910-
tuplestore_get_stats(tupstore, &maxStorageType, &maxSpaceUsed);
2911-
maxSpaceUsedKB = BYTES_TO_KILOBYTES(maxSpaceUsed);
2920+
int64 maxSpaceUsedKB = BYTES_TO_KILOBYTES(maxSpaceUsed);
29122921

29132922
if (es->format != EXPLAIN_FORMAT_TEXT)
29142923
{
@@ -3380,6 +3389,9 @@ show_hash_info(HashState *hashstate, ExplainState *es)
33803389
static void
33813390
show_material_info(MaterialState *mstate, ExplainState *es)
33823391
{
3392+
char *maxStorageType;
3393+
int64 maxSpaceUsed;
3394+
33833395
Tuplestorestate *tupstore = mstate->tuplestorestate;
33843396

33853397
/*
@@ -3389,7 +3401,8 @@ show_material_info(MaterialState *mstate, ExplainState *es)
33893401
if (!es->analyze || tupstore == NULL)
33903402
return;
33913403

3392-
show_storage_info(tupstore, es);
3404+
tuplestore_get_stats(tupstore, &maxStorageType, &maxSpaceUsed);
3405+
show_storage_info(maxStorageType, maxSpaceUsed, es);
33933406
}
33943407

33953408
/*
@@ -3399,6 +3412,9 @@ show_material_info(MaterialState *mstate, ExplainState *es)
33993412
static void
34003413
show_windowagg_info(WindowAggState *winstate, ExplainState *es)
34013414
{
3415+
char *maxStorageType;
3416+
int64 maxSpaceUsed;
3417+
34023418
Tuplestorestate *tupstore = winstate->buffer;
34033419

34043420
/*
@@ -3408,7 +3424,78 @@ show_windowagg_info(WindowAggState *winstate, ExplainState *es)
34083424
if (!es->analyze || tupstore == NULL)
34093425
return;
34103426

3411-
show_storage_info(tupstore, es);
3427+
tuplestore_get_stats(tupstore, &maxStorageType, &maxSpaceUsed);
3428+
show_storage_info(maxStorageType, maxSpaceUsed, es);
3429+
}
3430+
3431+
/*
3432+
* Show information on CTE Scan node, storage method and maximum memory/disk
3433+
* space used.
3434+
*/
3435+
static void
3436+
show_ctescan_info(CteScanState *ctescanstate, ExplainState *es)
3437+
{
3438+
char *maxStorageType;
3439+
int64 maxSpaceUsed;
3440+
3441+
Tuplestorestate *tupstore = ctescanstate->leader->cte_table;
3442+
3443+
if (!es->analyze || tupstore == NULL)
3444+
return;
3445+
3446+
tuplestore_get_stats(tupstore, &maxStorageType, &maxSpaceUsed);
3447+
show_storage_info(maxStorageType, maxSpaceUsed, es);
3448+
}
3449+
3450+
/*
3451+
* Show information on Table Function Scan node, storage method and maximum
3452+
* memory/disk space used.
3453+
*/
3454+
static void
3455+
show_table_func_scan_info(TableFuncScanState *tscanstate, ExplainState *es)
3456+
{
3457+
char *maxStorageType;
3458+
int64 maxSpaceUsed;
3459+
3460+
Tuplestorestate *tupstore = tscanstate->tupstore;
3461+
3462+
if (!es->analyze || tupstore == NULL)
3463+
return;
3464+
3465+
tuplestore_get_stats(tupstore, &maxStorageType, &maxSpaceUsed);
3466+
show_storage_info(maxStorageType, maxSpaceUsed, es);
3467+
}
3468+
3469+
/*
3470+
* Show information on Recursive Union node, storage method and maximum
3471+
* memory/disk space used.
3472+
*/
3473+
static void
3474+
show_recursive_union_info(RecursiveUnionState *rstate, ExplainState *es)
3475+
{
3476+
char *maxStorageType,
3477+
*tempStorageType;
3478+
int64 maxSpaceUsed,
3479+
tempSpaceUsed;
3480+
3481+
if (!es->analyze)
3482+
return;
3483+
3484+
/*
3485+
* Recursive union node uses two tuplestores. We employ the storage type
3486+
* from one of them which consumed more memory/disk than the other. The
3487+
* storage size is sum of the two.
3488+
*/
3489+
tuplestore_get_stats(rstate->working_table, &tempStorageType,
3490+
&tempSpaceUsed);
3491+
tuplestore_get_stats(rstate->intermediate_table, &maxStorageType,
3492+
&maxSpaceUsed);
3493+
3494+
if (tempSpaceUsed > maxSpaceUsed)
3495+
maxStorageType = tempStorageType;
3496+
3497+
maxSpaceUsed += tempSpaceUsed;
3498+
show_storage_info(maxStorageType, maxSpaceUsed, es);
34123499
}
34133500

34143501
/*

0 commit comments

Comments
 (0)