From 360f476550248d65ab9918a7a38c950c3c2f5b0e Mon Sep 17 00:00:00 2001
From: "Chao Li (HighGo Inc.)"
Date: Thu, 31 Jul 2025 17:02:32 +0800
Subject: [PATCH v3] 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 | 8 +++++++-
doc/src/sgml/rules.sgml | 1 +
src/backend/tcop/postgres.c | 7 +++++++
src/backend/utils/misc/guc_tables.c | 10 ++++++++++
src/backend/utils/misc/postgresql.conf.sample | 1 +
src/include/utils/guc.h | 1 +
6 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 20ccb2d6b54..4370e8307f2 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -7382,6 +7382,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
@@ -7421,7 +7426,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 8467d961fd0..282dcd722d4 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 0cecd464902..d356830f756 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_tables.c b/src/backend/utils/misc/guc_tables.c
index d14b1678e7f..f4e0b6a5274 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;
@@ -1385,6 +1386,15 @@ struct config_bool ConfigureNamesBool[] =
NULL, NULL, NULL
},
#endif /* DEBUG_NODE_TESTS_ENABLED */
+ {
+ {"debug_print_raw_parse", PGC_USERSET, LOGGING_WHAT,
+ gettext_noop("Logs each query's raw parse tree."),
+ NULL
+ },
+ &Debug_print_raw_parse,
+ false,
+ NULL, NULL, NULL
+ },
{
{"debug_print_parse", PGC_USERSET, LOGGING_WHAT,
gettext_noop("Logs each query's parse tree."),
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index a9d8293474a..26c08693564 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 f619100467d..d06ddade7f0 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;
--
2.39.5 (Apple Git-154)