From 2aab5cf3e3486845039aeaf536cf7a6e728fa266 Mon Sep 17 00:00:00 2001 From: Justin Pryzby Date: Sat, 15 Feb 2020 14:13:06 -0600 Subject: [PATCH v4 3/7] Gross hack to put hash stats of subplans in the right(?) place --- src/backend/commands/explain.c | 46 +++++++++++++++------------ src/test/regress/expected/select_parallel.out | 4 +-- src/test/regress/expected/subselect.out | 8 ++--- 3 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index e262108..67a9840 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -66,7 +66,7 @@ static double elapsed_time(instr_time *starttime); static bool ExplainPreScanNode(PlanState *planstate, Bitmapset **rels_used); static void ExplainNode(PlanState *planstate, List *ancestors, const char *relationship, const char *plan_name, - ExplainState *es); + ExplainState *es, SubPlanState *subplanstate); static void show_plan_tlist(PlanState *planstate, List *ancestors, ExplainState *es); static void show_expression(Node *node, const char *qlabel, @@ -718,7 +718,7 @@ ExplainPrintPlan(ExplainState *es, QueryDesc *queryDesc) ps = outerPlanState(ps); es->hide_workers = true; } - ExplainNode(ps, NIL, NULL, NULL, es); + ExplainNode(ps, NIL, NULL, NULL, es, NULL); /* * If requested, include information about GUC parameters with values that @@ -1080,7 +1080,7 @@ ExplainPreScanNode(PlanState *planstate, Bitmapset **rels_used) static void ExplainNode(PlanState *planstate, List *ancestors, const char *relationship, const char *plan_name, - ExplainState *es) + ExplainState *es, SubPlanState *subplanstate) { Plan *plan = planstate->plan; const char *pname; /* node type name for text output */ @@ -1337,6 +1337,16 @@ ExplainNode(PlanState *planstate, List *ancestors, ExplainIndentText(es); appendStringInfo(es->str, "%s\n", plan_name); es->indent++; + + Assert(subplanstate != NULL); + /* Show hash stats for hashed subplan */ + if (subplanstate->hashtable) + show_tuplehash_info(&subplanstate->hashtable->instrument, es); + if (subplanstate->hashnulls) { + ExplainIndentText(es); + appendStringInfoString(es->str, "Null hashtable: "); + show_tuplehash_info(&subplanstate->hashnulls->instrument, es); + } } if (es->indent) { @@ -1365,6 +1375,13 @@ ExplainNode(PlanState *planstate, List *ancestors, if (custom_name) ExplainPropertyText("Custom Plan Provider", custom_name, es); ExplainPropertyBool("Parallel Aware", plan->parallel_aware, es); + if (subplanstate && subplanstate->hashtable) + show_tuplehash_info(&subplanstate->hashtable->instrument, es); + if (subplanstate && subplanstate->hashnulls) { + ExplainOpenGroup("Null hashtable", "Null hashtable", true, es); + show_tuplehash_info(&subplanstate->hashnulls->instrument, es); + ExplainCloseGroup("Null hashtable", "Null hashtable", true, es); + } } switch (nodeTag(plan)) @@ -2037,12 +2054,12 @@ ExplainNode(PlanState *planstate, List *ancestors, /* lefttree */ if (outerPlanState(planstate)) ExplainNode(outerPlanState(planstate), ancestors, - "Outer", NULL, es); + "Outer", NULL, es, NULL); /* righttree */ if (innerPlanState(planstate)) ExplainNode(innerPlanState(planstate), ancestors, - "Inner", NULL, es); + "Inner", NULL, es, NULL); /* special child plans */ switch (nodeTag(plan)) @@ -2074,7 +2091,7 @@ ExplainNode(PlanState *planstate, List *ancestors, break; case T_SubqueryScan: ExplainNode(((SubqueryScanState *) planstate)->subplan, ancestors, - "Subquery", NULL, es); + "Subquery", NULL, es, NULL); break; case T_CustomScan: ExplainCustomChildren((CustomScanState *) planstate, @@ -3473,7 +3490,7 @@ ExplainMemberNodes(PlanState **planstates, int nplans, for (j = 0; j < nplans; j++) ExplainNode(planstates[j], ancestors, - "Member", NULL, es); + "Member", NULL, es, NULL); } /* @@ -3531,18 +3548,7 @@ ExplainSubPlans(List *plans, List *ancestors, ancestors = lcons(sp, ancestors); ExplainNode(sps->planstate, ancestors, - relationship, sp->plan_name, es); - if (sps->hashtable) - show_tuplehash_info(&sps->hashtable->instrument, es); - if (sps->hashnulls) { - ExplainOpenGroup("Null hashtable", "Null hashtable", true, es); - if (es->format == EXPLAIN_FORMAT_TEXT) { - ExplainIndentText(es); - appendStringInfoString(es->str, "Null hashtable: "); - } - show_tuplehash_info(&sps->hashnulls->instrument, es); - ExplainCloseGroup("Null hashtable", "Null hashtable", true, es); - } + relationship, sp->plan_name, es, sps); ancestors = list_delete_first(ancestors); } @@ -3559,7 +3565,7 @@ ExplainCustomChildren(CustomScanState *css, List *ancestors, ExplainState *es) (list_length(css->custom_ps) != 1 ? "children" : "child"); foreach(cell, css->custom_ps) - ExplainNode((PlanState *) lfirst(cell), ancestors, label, NULL, es); + ExplainNode((PlanState *) lfirst(cell), ancestors, label, NULL, es, NULL); } /* diff --git a/src/test/regress/expected/select_parallel.out b/src/test/regress/expected/select_parallel.out index 783c1da..bc270e0 100644 --- a/src/test/regress/expected/select_parallel.out +++ b/src/test/regress/expected/select_parallel.out @@ -303,11 +303,11 @@ explain (costs off, timing off, summary off, analyze) -> Parallel Seq Scan on tenk1 (actual rows=2000 loops=5) Filter: (NOT (hashed SubPlan 1)) SubPlan 1 + Buckets: 16384 + Null hashtable: Buckets: 1024 -> Seq Scan on tenk2 (actual rows=8990 loops=5) Filter: (thousand > 100) Rows Removed by Filter: 1010 - Buckets: 16384 - Null hashtable: Buckets: 1024 (13 rows) select count(*) from tenk1 where (two, four) not in diff --git a/src/test/regress/expected/subselect.out b/src/test/regress/expected/subselect.out index 410daa0..a6b9595 100644 --- a/src/test/regress/expected/subselect.out +++ b/src/test/regress/expected/subselect.out @@ -788,11 +788,11 @@ select 'foo'::text in (select 'bar'::name union all select 'bar'::name); ---------------------------------------------- Result (actual rows=1 loops=1) SubPlan 1 + Buckets: 4 (originally 2) + Null hashtable: Buckets: 2 -> Append (actual rows=2 loops=1) -> Result (actual rows=1 loops=1) -> Result (actual rows=1 loops=1) - Buckets: 4 (originally 2) - Null hashtable: Buckets: 2 (7 rows) select 'foo'::text in (select 'bar'::name union all select 'bar'::name); @@ -999,10 +999,10 @@ select * from int4_tbl where -> Seq Scan on int4_tbl (actual rows=5 loops=1) -> Seq Scan on tenk1 b (actual rows=8000 loops=5) SubPlan 1 + Buckets: 16384 + Null hashtable: Buckets: 2 -> Index Only Scan using tenk1_unique1 on tenk1 a (actual rows=10000 loops=1) Heap Fetches: 0 - Buckets: 16384 - Null hashtable: Buckets: 2 (10 rows) select * from int4_tbl where -- 2.7.4