aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/utils/adt/float.c24
-rw-r--r--src/backend/utils/misc/guc.c7
-rw-r--r--src/backend/utils/misc/postgresql.conf.sample3
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