summaryrefslogtreecommitdiff
path: root/src/backend/commands
diff options
context:
space:
mode:
authorRobert Haas2025-03-18 13:09:34 +0000
committerRobert Haas2025-03-18 13:28:01 +0000
commit4fd02bf7cf94c3b6807dcf0b13e076de94f1e4ff (patch)
tree56c34e32e6b83c07fc41fa11cc3a08ca403f791e /src/backend/commands
parentf76892c9ff7e5f2dcb4073310d1a5273f47d1d9d (diff)
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 <[email protected]> Reviewed-by: Andrei Lepikhov <[email protected]> Reviewed-by: Tom Lane <[email protected]> Reviewed-by: Sami Imseih <[email protected]>
Diffstat (limited to 'src/backend/commands')
-rw-r--r--src/backend/commands/explain.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index ab3898ff1eb..22616cf7add 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -52,6 +52,9 @@ ExplainOneQuery_hook_type ExplainOneQuery_hook = NULL;
/* Hook for plugins to get control in explain_get_index_name() */
explain_get_index_name_hook_type explain_get_index_name_hook = NULL;
+/* per-plan and per-node hooks for plugins to print additional info */
+explain_per_plan_hook_type explain_per_plan_hook = NULL;
+explain_per_node_hook_type explain_per_node_hook = NULL;
/*
* Various places within need to convert bytes to kilobytes. Round these up
@@ -654,6 +657,11 @@ ExplainOnePlan(PlannedStmt *plannedstmt, CachedPlan *cplan,
if (es->serialize != EXPLAIN_SERIALIZE_NONE)
ExplainPrintSerialize(es, &serializeMetrics);
+ /* Allow plugins to print additional information */
+ if (explain_per_plan_hook)
+ (*explain_per_plan_hook) (plannedstmt, into, es, queryString,
+ params, queryEnv);
+
/*
* Close down the query and free resources. Include time for this in the
* total execution time (although it should be pretty minimal).
@@ -2318,6 +2326,11 @@ ExplainNode(PlanState *planstate, List *ancestors,
ExplainFlushWorkersState(es);
es->workers_state = save_workers_state;
+ /* Allow plugins to print additional information */
+ if (explain_per_node_hook)
+ (*explain_per_node_hook) (planstate, ancestors, relationship,
+ plan_name, es);
+
/*
* If partition pruning was done during executor initialization, the
* number of child plans we'll display below will be less than the number