Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit acd6246

Browse files
committed
Don't lose precision for float fields of Nodes.
Historically we've been more worried about making the output of float fields look pretty than whether they'd be read back exactly. That won't work if we're to compare the read-back nodes for equality, so switch to using the Ryu code for float output. Author: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://www.postgresql.org/message-id/flat/4159834.1657405226@sss.pgh.pa.us
1 parent c07785d commit acd6246

File tree

2 files changed

+25
-10
lines changed

2 files changed

+25
-10
lines changed

src/backend/nodes/gen_node_support.pl

+6-6
Original file line numberDiff line numberDiff line change
@@ -983,29 +983,29 @@ sub elem
983983
}
984984
elsif ($t eq 'double')
985985
{
986-
print $off "\tWRITE_FLOAT_FIELD($f, \"%.6f\");\n";
986+
print $off "\tWRITE_FLOAT_FIELD($f);\n";
987987
print $rff "\tREAD_FLOAT_FIELD($f);\n" unless $no_read;
988988
}
989989
elsif ($t eq 'Cardinality')
990990
{
991-
print $off "\tWRITE_FLOAT_FIELD($f, \"%.0f\");\n";
991+
print $off "\tWRITE_FLOAT_FIELD($f);\n";
992992
print $rff "\tREAD_FLOAT_FIELD($f);\n" unless $no_read;
993993
}
994994
elsif ($t eq 'Cost')
995995
{
996-
print $off "\tWRITE_FLOAT_FIELD($f, \"%.2f\");\n";
996+
print $off "\tWRITE_FLOAT_FIELD($f);\n";
997997
print $rff "\tREAD_FLOAT_FIELD($f);\n" unless $no_read;
998998
}
999999
elsif ($t eq 'QualCost')
10001000
{
1001-
print $off "\tWRITE_FLOAT_FIELD($f.startup, \"%.2f\");\n";
1002-
print $off "\tWRITE_FLOAT_FIELD($f.per_tuple, \"%.2f\");\n";
1001+
print $off "\tWRITE_FLOAT_FIELD($f.startup);\n";
1002+
print $off "\tWRITE_FLOAT_FIELD($f.per_tuple);\n";
10031003
print $rff "\tREAD_FLOAT_FIELD($f.startup);\n" unless $no_read;
10041004
print $rff "\tREAD_FLOAT_FIELD($f.per_tuple);\n" unless $no_read;
10051005
}
10061006
elsif ($t eq 'Selectivity')
10071007
{
1008-
print $off "\tWRITE_FLOAT_FIELD($f, \"%.4f\");\n";
1008+
print $off "\tWRITE_FLOAT_FIELD($f);\n";
10091009
print $rff "\tREAD_FLOAT_FIELD($f);\n" unless $no_read;
10101010
}
10111011
elsif ($t eq 'char*')

src/backend/nodes/outfuncs.c

+19-4
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <ctype.h>
1818

1919
#include "access/attnum.h"
20+
#include "common/shortest_dec.h"
2021
#include "lib/stringinfo.h"
2122
#include "miscadmin.h"
2223
#include "nodes/bitmapset.h"
@@ -25,6 +26,7 @@
2526
#include "utils/datum.h"
2627

2728
static void outChar(StringInfo str, char c);
29+
static void outDouble(StringInfo str, double d);
2830

2931

3032
/*
@@ -69,9 +71,10 @@ static void outChar(StringInfo str, char c);
6971
appendStringInfo(str, " :" CppAsString(fldname) " %d", \
7072
(int) node->fldname)
7173

72-
/* Write a float field --- caller must give format to define precision */
73-
#define WRITE_FLOAT_FIELD(fldname,format) \
74-
appendStringInfo(str, " :" CppAsString(fldname) " " format, node->fldname)
74+
/* Write a float field (actually, they're double) */
75+
#define WRITE_FLOAT_FIELD(fldname) \
76+
(appendStringInfo(str, " :" CppAsString(fldname) " "), \
77+
outDouble(str, node->fldname))
7578

7679
/* Write a boolean field */
7780
#define WRITE_BOOL_FIELD(fldname) \
@@ -198,6 +201,18 @@ outChar(StringInfo str, char c)
198201
outToken(str, in);
199202
}
200203

204+
/*
205+
* Convert a double value, attempting to ensure the value is preserved exactly.
206+
*/
207+
static void
208+
outDouble(StringInfo str, double d)
209+
{
210+
char buf[DOUBLE_SHORTEST_DECIMAL_LEN];
211+
212+
double_to_shortest_decimal_buf(d, buf);
213+
appendStringInfoString(str, buf);
214+
}
215+
201216
/*
202217
* common implementation for scalar-array-writing functions
203218
*
@@ -525,7 +540,7 @@ _outRangeTblEntry(StringInfo str, const RangeTblEntry *node)
525540
break;
526541
case RTE_NAMEDTUPLESTORE:
527542
WRITE_STRING_FIELD(enrname);
528-
WRITE_FLOAT_FIELD(enrtuples, "%.0f");
543+
WRITE_FLOAT_FIELD(enrtuples);
529544
WRITE_OID_FIELD(relid);
530545
WRITE_NODE_FIELD(coltypes);
531546
WRITE_NODE_FIELD(coltypmods);

0 commit comments

Comments
 (0)