From bc01cc031aa1aed21c13391ddf60e7edd63f8868 Mon Sep 17 00:00:00 2001
From: "Chao Li (HighGo Inc.)"
Date: Thu, 31 Jul 2025 17:02:32 +0800
Subject: [PATCH] Add support for dumping raw parse tree with
debug_print_raw_parse
This patch introduces a small change to log the raw parse tree in the
same way we currently log the parse tree, rewritten tree, and plan tree.
While tracing some queries, I found that being able to inspect the raw
parse tree is also helpful for understanding query transformation.
Although the raw parse tree can be inspected via a debugger, having it
logged simplifies the workflow for those interested in this stage of
query processing, without requiring a debugging session.
To avoid unnecessary log noise for users not interested in this detail,
a new GUC option, "debug_print_raw_parse", has been added.
When starting the PostgreSQL process with "-d N", and N is 3 or higher,
debug_print_raw_parse is enabled automatically, alongside
debug_print_parse.
Author: Chao Li
Discussion: https://www.postgresql.org/message-id/CAEoWx2mcO0Gpo4vd8kPMAFWeJLSp0MeUUnaLdE1x0tSVd-VzUw%40mail.gmail.com
---
doc/src/sgml/config.sgml | 12 +++++++++---
doc/src/sgml/rules.sgml | 1 +
src/backend/tcop/postgres.c | 7 +++++++
src/backend/utils/misc/guc_parameters.dat | 6 ++++++
src/backend/utils/misc/guc_tables.c | 1 +
src/backend/utils/misc/postgresql.conf.sample | 1 +
src/include/utils/guc.h | 1 +
7 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 0a4b3e55ba5e..2a3685f474a9 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -7383,6 +7383,11 @@ local0.* /var/log/postgresql
+ debug_print_raw_parse (boolean)
+
+ debug_print_raw_parse configuration parameter
+
+
debug_print_parse (boolean)
debug_print_parse configuration parameter
@@ -7401,8 +7406,8 @@ local0.* /var/log/postgresql
These parameters enable various debugging output to be emitted.
- When set, they print the resulting parse tree, the query rewriter
- output, or the execution plan for each executed query.
+ When set, they print the resulting raw parse tree, the parse tree, the query
+ rewriter output, or the execution plan for each executed query.
These messages are emitted at LOG message level, so by
default they will appear in the server log but will not be sent to the
client. You can change that by adjusting
@@ -7422,7 +7427,8 @@ local0.* /var/log/postgresql
When set, debug_pretty_print indents the messages
- produced by debug_print_parse,
+ produced by debug_print_raw_parse,
+ debug_print_parse,
debug_print_rewritten, or
debug_print_plan. This results in more readable
but much longer output than the compact
format used when
diff --git a/doc/src/sgml/rules.sgml b/doc/src/sgml/rules.sgml
index 8467d961fd0a..282dcd722d49 100644
--- a/doc/src/sgml/rules.sgml
+++ b/doc/src/sgml/rules.sgml
@@ -60,6 +60,7 @@
SQL statement where the single parts that it is
built from are stored separately. These query trees can be shown
in the server log if you set the configuration parameters
+ debug_print_raw_parse,
debug_print_parse,
debug_print_rewritten, or
debug_print_plan. The rule actions are also
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 0cecd4649020..d356830f756b 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -649,6 +649,10 @@ pg_parse_query(const char *query_string)
TRACE_POSTGRESQL_QUERY_PARSE_DONE(query_string);
+ if (Debug_print_raw_parse)
+ elog_node_display(LOG, "raw parse tree", raw_parsetree_list,
+ Debug_pretty_print);
+
return raw_parsetree_list;
}
@@ -3697,7 +3701,10 @@ set_debug_options(int debug_flag, GucContext context, GucSource source)
if (debug_flag >= 2)
SetConfigOption("log_statement", "all", context, source);
if (debug_flag >= 3)
+ {
+ SetConfigOption("debug_print_raw_parse", "true", context, source);
SetConfigOption("debug_print_parse", "true", context, source);
+ }
if (debug_flag >= 4)
SetConfigOption("debug_print_plan", "true", context, source);
if (debug_flag >= 5)
diff --git a/src/backend/utils/misc/guc_parameters.dat b/src/backend/utils/misc/guc_parameters.dat
index a157cec3c4d0..0da01627cfec 100644
--- a/src/backend/utils/misc/guc_parameters.dat
+++ b/src/backend/utils/misc/guc_parameters.dat
@@ -414,6 +414,12 @@
ifdef => 'DEBUG_NODE_TESTS_ENABLED',
},
+{ name => 'debug_print_raw_parse', type => 'bool', context => 'PGC_USERSET', group => 'LOGGING_WHAT',
+ short_desc => 'Logs each query\'s raw parse tree.',
+ variable => 'Debug_print_raw_parse',
+ boot_val => 'false',
+},
+
{ name => 'debug_print_parse', type => 'bool', context => 'PGC_USERSET', group => 'LOGGING_WHAT',
short_desc => 'Logs each query\'s parse tree.',
variable => 'Debug_print_parse',
diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c
index 787933a9e5ac..00c8376cf4de 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -507,6 +507,7 @@ bool AllowAlterSystem = true;
bool log_duration = false;
bool Debug_print_plan = false;
bool Debug_print_parse = false;
+bool Debug_print_raw_parse = false;
bool Debug_print_rewritten = false;
bool Debug_pretty_print = true;
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index a9d8293474af..26c086935648 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -581,6 +581,7 @@
# - What to Log -
+#debug_print_raw_parse = off
#debug_print_parse = off
#debug_print_rewritten = off
#debug_print_plan = off
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index 72981053e610..756e80a2c2fc 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -247,6 +247,7 @@ typedef enum
/* GUC vars that are actually defined in guc_tables.c, rather than elsewhere */
extern PGDLLIMPORT bool Debug_print_plan;
extern PGDLLIMPORT bool Debug_print_parse;
+extern PGDLLIMPORT bool Debug_print_raw_parse;
extern PGDLLIMPORT bool Debug_print_rewritten;
extern PGDLLIMPORT bool Debug_pretty_print;