Skip to content

Commit 4fd02bf

Browse files
committed
Add some new hooks so extensions can add details to EXPLAIN.
Specifically, add a per-node hook that is called after the per-node information has been displayed but before we display children, and a per-query hook that is called after existing query-level information is printed. This assumes that extension-added information should always go at the end rather than the beginning or the middle, but that seems like an acceptable limitation for simplicity. It also assumes that extensions will only want to add information, not remove or reformat existing details; those also seem like acceptable restrictions, at least for now. If multiple EXPLAIN extensions are used, the order in which any additional details are printed is likely to depend on the order in which the modules are loaded. That seems OK, since the user may have opinions about the order in which output should appear, and the extension author can't really know whether their stuff is more or less important to a particular user than some other extension. Discussion: http://postgr.es/m/CA+TgmoYSzg58hPuBmei46o8D3SKX+SZoO4K_aGQGwiRzvRApLg@mail.gmail.com Reviewed-by: Srinath Reddy <srinath2133@gmail.com> Reviewed-by: Andrei Lepikhov <lepihov@gmail.com> Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Reviewed-by: Sami Imseih <samimseih@gmail.com>
1 parent f76892c commit 4fd02bf

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

src/backend/commands/explain.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ ExplainOneQuery_hook_type ExplainOneQuery_hook = NULL;
5252
/* Hook for plugins to get control in explain_get_index_name() */
5353
explain_get_index_name_hook_type explain_get_index_name_hook = NULL;
5454

55+
/* per-plan and per-node hooks for plugins to print additional info */
56+
explain_per_plan_hook_type explain_per_plan_hook = NULL;
57+
explain_per_node_hook_type explain_per_node_hook = NULL;
5558

5659
/*
5760
* Various places within need to convert bytes to kilobytes. Round these up
@@ -654,6 +657,11 @@ ExplainOnePlan(PlannedStmt *plannedstmt, CachedPlan *cplan,
654657
if (es->serialize != EXPLAIN_SERIALIZE_NONE)
655658
ExplainPrintSerialize(es, &serializeMetrics);
656659

660+
/* Allow plugins to print additional information */
661+
if (explain_per_plan_hook)
662+
(*explain_per_plan_hook) (plannedstmt, into, es, queryString,
663+
params, queryEnv);
664+
657665
/*
658666
* Close down the query and free resources. Include time for this in the
659667
* total execution time (although it should be pretty minimal).
@@ -2318,6 +2326,11 @@ ExplainNode(PlanState *planstate, List *ancestors,
23182326
ExplainFlushWorkersState(es);
23192327
es->workers_state = save_workers_state;
23202328

2329+
/* Allow plugins to print additional information */
2330+
if (explain_per_node_hook)
2331+
(*explain_per_node_hook) (planstate, ancestors, relationship,
2332+
plan_name, es);
2333+
23212334
/*
23222335
* If partition pruning was done during executor initialization, the
23232336
* number of child plans we'll display below will be less than the number

src/include/commands/explain.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,23 @@ typedef void (*ExplainOneQuery_hook_type) (Query *query,
2828
QueryEnvironment *queryEnv);
2929
extern PGDLLIMPORT ExplainOneQuery_hook_type ExplainOneQuery_hook;
3030

31+
/* Hook for EXPLAIN plugins to print extra information for each plan */
32+
typedef void (*explain_per_plan_hook_type) (PlannedStmt *plannedstmt,
33+
IntoClause *into,
34+
struct ExplainState *es,
35+
const char *queryString,
36+
ParamListInfo params,
37+
QueryEnvironment *queryEnv);
38+
extern PGDLLIMPORT explain_per_plan_hook_type explain_per_plan_hook;
39+
40+
/* Hook for EXPLAIN plugins to print extra fields on individual plan nodes */
41+
typedef void (*explain_per_node_hook_type) (PlanState *planstate,
42+
List *ancestors,
43+
const char *relationship,
44+
const char *plan_name,
45+
struct ExplainState *es);
46+
extern PGDLLIMPORT explain_per_node_hook_type explain_per_node_hook;
47+
3148
/* Hook for plugins to get control in explain_get_index_name() */
3249
typedef const char *(*explain_get_index_name_hook_type) (Oid indexId);
3350
extern PGDLLIMPORT explain_get_index_name_hook_type explain_get_index_name_hook;

0 commit comments

Comments
 (0)