From 6e2fe1c4ef044e3cee8e0f7bbc2501accdadb1ee Mon Sep 17 00:00:00 2001
From: Bruce Momjian
Date: Mon, 22 Mar 2021 17:43:24 -0400
Subject: [PATCH v24 3/3] Expose query identifier in verbose explain
If a query identifier has been computed, either by enabling compute_query_id or
using a third-party module, verbose explain will display it.
---
doc/src/sgml/config.sgml | 6 +++---
doc/src/sgml/ref/explain.sgml | 6 ++++--
src/backend/commands/explain.c | 18 ++++++++++++++++++
src/test/regress/expected/explain.out | 11 ++++++++++-
src/test/regress/sql/explain.sql | 5 ++++-
5 files changed, 39 insertions(+), 7 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 5f9eddb197..71b47729b8 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -7637,9 +7637,9 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
Enables in-core computation of a query identifier.
Query identifiers can be displayed in the pg_stat_activity
- view, or emitted in the log if configured via the parameter. The extension also requires a query
+ view, using EXPLAIN, or emitted in the log if
+ configured via the parameter.
+ The extension also requires a query
identifier to be computed. Note that an external module can
alternatively be used if the in-core query identifier computation
specification isn't acceptable. In this case, in-core computation
diff --git a/doc/src/sgml/ref/explain.sgml b/doc/src/sgml/ref/explain.sgml
index c4512332a0..4d758fb237 100644
--- a/doc/src/sgml/ref/explain.sgml
+++ b/doc/src/sgml/ref/explain.sgml
@@ -136,8 +136,10 @@ ROLLBACK;
the output column list for each node in the plan tree, schema-qualify
table and function names, always label variables in expressions with
their range table alias, and always print the name of each trigger for
- which statistics are displayed. This parameter defaults to
- FALSE.
+ which statistics are displayed. The query identifier will also be
+ displayed if one has been computed, see for more details. This parameter
+ defaults to FALSE.
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index ede8cec947..b62a76e7e5 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -24,6 +24,7 @@
#include "nodes/extensible.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
+#include "parser/analyze.h"
#include "parser/parsetree.h"
#include "rewrite/rewriteHandler.h"
#include "storage/bufmgr.h"
@@ -165,6 +166,8 @@ ExplainQuery(ParseState *pstate, ExplainStmt *stmt,
{
ExplainState *es = NewExplainState();
TupOutputState *tstate;
+ JumbleState *jstate = NULL;
+ Query *query;
List *rewritten;
ListCell *lc;
bool timing_set = false;
@@ -241,6 +244,13 @@ ExplainQuery(ParseState *pstate, ExplainStmt *stmt,
/* if the summary was not set explicitly, set default value */
es->summary = (summary_set) ? es->summary : es->analyze;
+ query = castNode(Query, stmt->query);
+ if (compute_query_id)
+ jstate = JumbleQuery(query, pstate->p_sourcetext);
+
+ if (post_parse_analyze_hook)
+ (*post_parse_analyze_hook) (pstate, query, jstate);
+
/*
* Parse analysis was done already, but we still have to run the rule
* rewriter. We do not do AcquireRewriteLocks: we assume the query either
@@ -600,6 +610,14 @@ ExplainOnePlan(PlannedStmt *plannedstmt, IntoClause *into, ExplainState *es,
/* Create textual dump of plan tree */
ExplainPrintPlan(es, queryDesc);
+ if (es->verbose && plannedstmt->queryId != UINT64CONST(0))
+ {
+ char buf[MAXINT8LEN+1];
+
+ pg_lltoa(plannedstmt->queryId, buf);
+ ExplainPropertyText("Query Identifier", buf, es);
+ }
+
/* Show buffer usage in planning */
if (bufusage)
{
diff --git a/src/test/regress/expected/explain.out b/src/test/regress/expected/explain.out
index b89b99fb02..4c578d4f5e 100644
--- a/src/test/regress/expected/explain.out
+++ b/src/test/regress/expected/explain.out
@@ -17,7 +17,7 @@ begin
for ln in execute $1
loop
-- Replace any numeric word with just 'N'
- ln := regexp_replace(ln, '\m\d+\M', 'N', 'g');
+ ln := regexp_replace(ln, '-?\m\d+\M', 'N', 'g');
-- In sort output, the above won't match units-suffixed numbers
ln := regexp_replace(ln, '\m\d+kB', 'NkB', 'g');
-- Ignore text-mode buffers output because it varies depending
@@ -477,3 +477,12 @@ select jsonb_pretty(
(1 row)
rollback;
+set compute_query_id = on;
+select explain_filter('explain (verbose) select 1');
+ explain_filter
+----------------------------------------
+ Result (cost=N.N..N.N rows=N width=N)
+ Output: N
+ Query Identifier: N
+(3 rows)
+
diff --git a/src/test/regress/sql/explain.sql b/src/test/regress/sql/explain.sql
index f2eab030d6..468caf4037 100644
--- a/src/test/regress/sql/explain.sql
+++ b/src/test/regress/sql/explain.sql
@@ -19,7 +19,7 @@ begin
for ln in execute $1
loop
-- Replace any numeric word with just 'N'
- ln := regexp_replace(ln, '\m\d+\M', 'N', 'g');
+ ln := regexp_replace(ln, '-?\m\d+\M', 'N', 'g');
-- In sort output, the above won't match units-suffixed numbers
ln := regexp_replace(ln, '\m\d+kB', 'NkB', 'g');
-- Ignore text-mode buffers output because it varies depending
@@ -103,3 +103,6 @@ select jsonb_pretty(
);
rollback;
+
+set compute_query_id = on;
+select explain_filter('explain (verbose) select 1');
--
2.30.1