mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-18 18:44:06 +08:00
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
This commit is contained in:
parent
c07785d458
commit
acd624644b
@ -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*')
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <ctype.h>
|
||||
|
||||
#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);
|
||||
|
Loading…
Reference in New Issue
Block a user