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