diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/utils/adt/float.c | 24 | ||||
-rw-r--r-- | src/backend/utils/misc/guc.c | 7 | ||||
-rw-r--r-- | src/backend/utils/misc/postgresql.conf.sample | 3 |
3 files changed, 28 insertions, 6 deletions
diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c index eb111ee2dbf..37c202d21ca 100644 --- a/src/backend/utils/adt/float.c +++ b/src/backend/utils/adt/float.c @@ -21,6 +21,7 @@ #include "catalog/pg_type.h" #include "common/int.h" +#include "common/shortest_dec.h" #include "libpq/pqformat.h" #include "miscadmin.h" #include "utils/array.h" @@ -30,8 +31,15 @@ #include "utils/timestamp.h" -/* Configurable GUC parameter */ -int extra_float_digits = 0; /* Added to DBL_DIG or FLT_DIG */ +/* + * Configurable GUC parameter + * + * If >0, use shortest-decimal format for output; this is both the default and + * allows for compatibility with clients that explicitly set a value here to + * get round-trip-accurate results. If 0 or less, then use the old, slow, + * decimal rounding method. + */ +int extra_float_digits = 1; /* Cached constants for degree-based trig functions */ static bool degree_consts_set = false; @@ -282,6 +290,12 @@ float4out(PG_FUNCTION_ARGS) char *ascii = (char *) palloc(32); int ndig = FLT_DIG + extra_float_digits; + if (extra_float_digits > 0) + { + float_to_shortest_decimal_buf(num, ascii); + PG_RETURN_CSTRING(ascii); + } + (void) pg_strfromd(ascii, 32, ndig, num); PG_RETURN_CSTRING(ascii); } @@ -498,6 +512,12 @@ float8out_internal(double num) char *ascii = (char *) palloc(32); int ndig = DBL_DIG + extra_float_digits; + if (extra_float_digits > 0) + { + double_to_shortest_decimal_buf(num, ascii); + return ascii; + } + (void) pg_strfromd(ascii, 32, ndig, num); return ascii; } diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 3a4a113b625..156d147c85b 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -2667,11 +2667,12 @@ static struct config_int ConfigureNamesInt[] = {"extra_float_digits", PGC_USERSET, CLIENT_CONN_LOCALE, gettext_noop("Sets the number of digits displayed for floating-point values."), gettext_noop("This affects real, double precision, and geometric data types. " - "The parameter value is added to the standard number of digits " - "(FLT_DIG or DBL_DIG as appropriate).") + "A zero or negative parameter value is added to the standard " + "number of digits (FLT_DIG or DBL_DIG as appropriate). " + "Any value greater than zero selects precise output mode.") }, &extra_float_digits, - 0, -15, 3, + 1, -15, 3, NULL, NULL, NULL }, diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index ad6c436f93f..194f3120964 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -651,7 +651,8 @@ # India # You can create your own file in # share/timezonesets/. -#extra_float_digits = 0 # min -15, max 3 +#extra_float_digits = 1 # min -15, max 3; any value >0 actually + # selects precise output mode #client_encoding = sql_ascii # actually, defaults to database # encoding |