diff --git a/src/backend/nodes/gen_node_support.pl b/src/backend/nodes/gen_node_support.pl index b707a09f56..81b8c184a9 100644 --- a/src/backend/nodes/gen_node_support.pl +++ b/src/backend/nodes/gen_node_support.pl @@ -983,29 +983,29 @@ _read${n}(void) } elsif ($t eq 'double') { - print $off "\tWRITE_FLOAT_FIELD($f, \"%.6f\");\n"; + print $off "\tWRITE_FLOAT_FIELD($f);\n"; print $rff "\tREAD_FLOAT_FIELD($f);\n" unless $no_read; } elsif ($t eq 'Cardinality') { - print $off "\tWRITE_FLOAT_FIELD($f, \"%.0f\");\n"; + print $off "\tWRITE_FLOAT_FIELD($f);\n"; print $rff "\tREAD_FLOAT_FIELD($f);\n" unless $no_read; } elsif ($t eq 'Cost') { - print $off "\tWRITE_FLOAT_FIELD($f, \"%.2f\");\n"; + print $off "\tWRITE_FLOAT_FIELD($f);\n"; print $rff "\tREAD_FLOAT_FIELD($f);\n" unless $no_read; } elsif ($t eq 'QualCost') { - print $off "\tWRITE_FLOAT_FIELD($f.startup, \"%.2f\");\n"; - print $off "\tWRITE_FLOAT_FIELD($f.per_tuple, \"%.2f\");\n"; + print $off "\tWRITE_FLOAT_FIELD($f.startup);\n"; + print $off "\tWRITE_FLOAT_FIELD($f.per_tuple);\n"; print $rff "\tREAD_FLOAT_FIELD($f.startup);\n" unless $no_read; print $rff "\tREAD_FLOAT_FIELD($f.per_tuple);\n" unless $no_read; } elsif ($t eq 'Selectivity') { - print $off "\tWRITE_FLOAT_FIELD($f, \"%.4f\");\n"; + print $off "\tWRITE_FLOAT_FIELD($f);\n"; print $rff "\tREAD_FLOAT_FIELD($f);\n" unless $no_read; } elsif ($t eq 'char*') diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 63dda75ae5..64c65f060b 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -17,6 +17,7 @@ #include #include "access/attnum.h" +#include "common/shortest_dec.h" #include "lib/stringinfo.h" #include "miscadmin.h" #include "nodes/bitmapset.h" @@ -25,6 +26,7 @@ #include "utils/datum.h" static void outChar(StringInfo str, char c); +static void outDouble(StringInfo str, double d); /* @@ -69,9 +71,10 @@ static void outChar(StringInfo str, char c); appendStringInfo(str, " :" CppAsString(fldname) " %d", \ (int) node->fldname) -/* Write a float field --- caller must give format to define precision */ -#define WRITE_FLOAT_FIELD(fldname,format) \ - appendStringInfo(str, " :" CppAsString(fldname) " " format, node->fldname) +/* Write a float field (actually, they're double) */ +#define WRITE_FLOAT_FIELD(fldname) \ + (appendStringInfo(str, " :" CppAsString(fldname) " "), \ + outDouble(str, node->fldname)) /* Write a boolean field */ #define WRITE_BOOL_FIELD(fldname) \ @@ -198,6 +201,18 @@ outChar(StringInfo str, char c) outToken(str, in); } +/* + * Convert a double value, attempting to ensure the value is preserved exactly. + */ +static void +outDouble(StringInfo str, double d) +{ + char buf[DOUBLE_SHORTEST_DECIMAL_LEN]; + + double_to_shortest_decimal_buf(d, buf); + appendStringInfoString(str, buf); +} + /* * common implementation for scalar-array-writing functions * @@ -525,7 +540,7 @@ _outRangeTblEntry(StringInfo str, const RangeTblEntry *node) break; case RTE_NAMEDTUPLESTORE: WRITE_STRING_FIELD(enrname); - WRITE_FLOAT_FIELD(enrtuples, "%.0f"); + WRITE_FLOAT_FIELD(enrtuples); WRITE_OID_FIELD(relid); WRITE_NODE_FIELD(coltypes); WRITE_NODE_FIELD(coltypmods);