From 8430936be7427a628ca7e2bd1d3d15b3f17424be Mon Sep 17 00:00:00 2001
From: Julien Rouhaud
Date: Sun, 8 Mar 2020 14:34:44 +0100
Subject: [PATCH v19 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.
Author: Julien Rouhaud
Reviewed-by: Bruce Momjian
Discussion: https://postgr.es/m/CA+8PKvQnMfOE-c3YLRwxOsCYXQDyP8VXs6CDtMZp1V4=D4LuFA@mail.gmail.com
---
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 cfcd38b70b..6239bf1d10 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -7581,9 +7581,9 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
Enables or disables in core query identifier computation. A query
identifier 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 doesn't suit your need. In this case, in core
diff --git a/doc/src/sgml/ref/explain.sgml b/doc/src/sgml/ref/explain.sgml
index c4512332a0..135dff6d3d 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 compute, see for more details. This parameter
+ defaults to FALSE.
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index afc45429ba..9794c4e794 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"
@@ -163,6 +164,8 @@ ExplainQuery(ParseState *pstate, ExplainStmt *stmt,
{
ExplainState *es = NewExplainState();
TupOutputState *tstate;
+ JumbleState *jstate = NULL;
+ Query *query;
List *rewritten;
ListCell *lc;
bool timing_set = false;
@@ -239,6 +242,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
@@ -598,6 +608,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 791eba8511..1f8a3ead52 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
@@ -470,3 +470,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