From 26edadde9996f6fe266b7eaf77ad202162aea26f Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Wed, 10 Aug 2022 23:40:52 +0200 Subject: [PATCH v1 5/7] Implement WRITE_READ_PARSE_PLAN_TREES for raw parse trees This requires a special node to print and restore the full precision of float values. --- src/backend/nodes/outfuncs.c | 14 ++++++++++++++ src/backend/tcop/postgres.c | 26 +++++++++++++++++++++----- src/include/nodes/nodes.h | 4 ++++ 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 24ea0487e7..acc4738581 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -15,6 +15,7 @@ #include "postgres.h" #include +#include #include "access/attnum.h" #include "lib/stringinfo.h" @@ -26,6 +27,9 @@ static void outChar(StringInfo str, char c); +#ifdef WRITE_READ_PARSE_PLAN_TREES +bool output_all_float_digits = false; +#endif /* * Macros to simplify output of different kinds of fields. Use these @@ -70,8 +74,18 @@ static void outChar(StringInfo str, char c); (int) node->fldname) /* Write a float field --- caller must give format to define precision */ +#ifdef WRITE_READ_PARSE_PLAN_TREES +#define WRITE_FLOAT_FIELD(fldname,format) \ + do { \ + if (output_all_float_digits) \ + appendStringInfo(str, " :" CppAsString(fldname) " %.*f", DBL_DIG + 3, node->fldname); \ + else \ + appendStringInfo(str, " :" CppAsString(fldname) " " format, node->fldname); \ + } while(0) +#else #define WRITE_FLOAT_FIELD(fldname,format) \ appendStringInfo(str, " :" CppAsString(fldname) " " format, node->fldname) +#endif /* Write a boolean field */ #define WRITE_BOOL_FIELD(fldname) \ diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 7bec4e4ff5..154e6dbeca 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -601,11 +601,27 @@ pg_parse_query(const char *query_string) } #endif - /* - * Currently, outfuncs/readfuncs support is missing for many raw parse - * tree nodes, so we don't try to implement WRITE_READ_PARSE_PLAN_TREES - * here. - */ +#ifdef WRITE_READ_PARSE_PLAN_TREES + /* Optional debugging check: pass raw parsetrees through outfuncs/readfuncs */ + { + char *str; + List *new_list; + + output_all_float_digits = true; + + str = nodeToString(raw_parsetree_list); + new_list = stringToNodeWithLocations(str); + pfree(str); + + output_all_float_digits = false; + + /* This checks both outfuncs/readfuncs and the equal() routines... */ + if (!equal(new_list, raw_parsetree_list)) + elog(WARNING, "outfuncs/readfuncs failed to produce an equal raw parse tree"); + else + raw_parsetree_list = new_list; + } +#endif TRACE_POSTGRESQL_QUERY_PARSE_DONE(query_string); diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index cdd6debfa0..6d6478bcb4 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -192,6 +192,10 @@ castNodeImpl(NodeTag type, void *ptr) struct Bitmapset; /* not to include bitmapset.h here */ struct StringInfoData; /* not to include stringinfo.h here */ +#ifdef WRITE_READ_PARSE_PLAN_TREES +extern bool output_all_float_digits; +#endif + extern void outNode(struct StringInfoData *str, const void *obj); extern void outToken(struct StringInfoData *str, const char *s); extern void outBitmapset(struct StringInfoData *str, -- 2.37.1