From 684cb243e9895fe9f658a78f9f8376cd8a895264 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Mon, 22 Mar 2021 17:43:24 -0400 Subject: [PATCH v23 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