From af25bc03e17eb0aba195e42506b1a15f47178e44 Mon Sep 17 00:00:00 2001 From: Andrew Dunstan Date: Mon, 18 Feb 2019 07:22:00 -0500 Subject: [PATCH] Provide an extra-float-digits setting for pg_dump / pg_dumpall Changes made by commit 02ddd49 mean that dumps made against pre version 12 instances are no longer comparable with those made against version 12 or later instances. This makes cross-version upgrade testing fail in the buildfarm. Experimentation has shown that the error is cured if the dumps are made when extra_float_digits is set to 0. Hence this patch allows for it to be explicitly set rather than relying on pg_dump's builtin default (3 in almost all cases). This feature might have other uses, but should not normally be used. Discussion: https://postgr.es/m/c76f7051-8fd3-ec10-7579-1f8842305b85@2ndQuadrant.com --- doc/src/sgml/ref/pg_dump.sgml | 11 +++++++++++ doc/src/sgml/ref/pg_dumpall.sgml | 11 +++++++++++ src/bin/pg_dump/pg_dump.c | 31 ++++++++++++++++++++++++++++--- src/bin/pg_dump/pg_dumpall.c | 7 +++++++ 4 files changed, 57 insertions(+), 3 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 9e0bb93f08..033eae9b46 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -745,6 +745,17 @@ PostgreSQL documentation + + + + + Use the specified value of extra_float_digits when dumping + floating-point data, instead of the maximum available precision. + Routine dumps made for backup purposes should not use this option. + + + + diff --git a/doc/src/sgml/ref/pg_dumpall.sgml b/doc/src/sgml/ref/pg_dumpall.sgml index c51a130f43..b3372a641f 100644 --- a/doc/src/sgml/ref/pg_dumpall.sgml +++ b/doc/src/sgml/ref/pg_dumpall.sgml @@ -300,6 +300,17 @@ PostgreSQL documentation + + + + + Use the specified value of extra_float_digits when dumping + floating-point data, instead of the maximum available precision. + Routine dumps made for backup purposes should not use this option. + + + + diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 9edc7b9a02..a08bc4ecae 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -134,6 +134,10 @@ char g_comment_end[10]; static const CatalogId nilCatalogId = {0, 0}; +/* override for standard extra_float_digits setting */ +static bool have_extra_float_digits = false; +static int extra_float_digits; + /* * Macro for producing quoted, schema-qualified name of a dumpable object. */ @@ -357,6 +361,7 @@ main(int argc, char **argv) {"disable-triggers", no_argument, &dopt.disable_triggers, 1}, {"enable-row-security", no_argument, &dopt.enable_row_security, 1}, {"exclude-table-data", required_argument, NULL, 4}, + {"extra-float-digits", required_argument, NULL, 8}, {"if-exists", no_argument, &dopt.if_exists, 1}, {"inserts", no_argument, &dopt.dump_inserts, 1}, {"lock-wait-timeout", required_argument, NULL, 2}, @@ -557,6 +562,16 @@ main(int argc, char **argv) dosync = false; break; + case 8: + have_extra_float_digits = true; + extra_float_digits = atoi(optarg); + if (extra_float_digits < -15 || extra_float_digits > 3) + { + write_msg(NULL, "extra_float_digits must be in range -15..3\n"); + exit_nicely(1); + } + break; + default: fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit_nicely(1); @@ -965,6 +980,7 @@ help(const char *progname) printf(_(" --enable-row-security enable row security (dump only content user has\n" " access to)\n")); printf(_(" --exclude-table-data=TABLE do NOT dump data for the named table(s)\n")); + printf(_(" --extra-float-digits=NUM override default setting for extra_float_digits\n")); printf(_(" --if-exists use IF EXISTS when dropping objects\n")); printf(_(" --inserts dump data as INSERT commands, rather than COPY\n")); printf(_(" --load-via-partition-root load partitions via the root table\n")); @@ -1059,10 +1075,19 @@ setup_connection(Archive *AH, const char *dumpencoding, ExecuteSqlStatement(AH, "SET INTERVALSTYLE = POSTGRES"); /* - * Set extra_float_digits so that we can dump float data exactly (given - * correctly implemented float I/O code, anyway) + * Use an explicitly specified extra_float_digits if it has been + * provided. Otherwise, set extra_float_digits so that we can dump float + * data exactly (given correctly implemented float I/O code, anyway). */ - if (AH->remoteVersion >= 90000) + if (have_extra_float_digits) + { + PQExpBuffer q = createPQExpBuffer(); + appendPQExpBuffer(q, "SET extra_float_digits TO %d", + extra_float_digits); + ExecuteSqlStatement(AH, q->data); + destroyPQExpBuffer(q); + } + else if (AH->remoteVersion >= 90000) ExecuteSqlStatement(AH, "SET extra_float_digits TO 3"); else ExecuteSqlStatement(AH, "SET extra_float_digits TO 2"); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index 5d40d19596..44c3350887 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -123,6 +123,7 @@ main(int argc, char *argv[]) {"column-inserts", no_argument, &column_inserts, 1}, {"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1}, {"disable-triggers", no_argument, &disable_triggers, 1}, + {"extra-float-digits", required_argument, NULL, 5}, {"if-exists", no_argument, &if_exists, 1}, {"inserts", no_argument, &inserts, 1}, {"lock-wait-timeout", required_argument, NULL, 2}, @@ -318,6 +319,11 @@ main(int argc, char *argv[]) appendPQExpBufferStr(pgdumpopts, " --no-sync"); break; + case 5: + appendPQExpBufferStr(pgdumpopts, " --extra-float-digits "); + appendShellString(pgdumpopts, optarg); + break; + default: fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit_nicely(1); @@ -614,6 +620,7 @@ help(void) printf(_(" --column-inserts dump data as INSERT commands with column names\n")); printf(_(" --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n")); printf(_(" --disable-triggers disable triggers during data-only restore\n")); + printf(_(" --extra-float-digits=NUM override default setting for extra_float_digits\n")); printf(_(" --if-exists use IF EXISTS when dropping objects\n")); printf(_(" --inserts dump data as INSERT commands, rather than COPY\n")); printf(_(" --load-via-partition-root load partitions via the root table\n"));