Fix portability breakage in pg_dump.
authorTom Lane <[email protected]>
Sun, 11 Jan 2015 18:28:26 +0000 (13:28 -0500)
committerTom Lane <[email protected]>
Sun, 11 Jan 2015 18:28:26 +0000 (13:28 -0500)
Commit 0eea8047bf0e15b402b951e383e39236bdfe57d5 introduced some overly
optimistic assumptions about what could be in a local struct variable's
initializer.  (This might in fact be valid code according to C99, but I've
got at least one pre-C99 compiler that falls over on those nonconstant
address expressions.)  There is no reason whatsoever for main()'s workspace
to not be static, so revert long_options[] to a static and make the
DumpOptions struct static as well.

src/bin/pg_dump/pg_backup.h
src/bin/pg_dump/pg_backup_archiver.c
src/bin/pg_dump/pg_dump.c

index c2ebcd4f745d7a2b5b389a672f46108d5c11333f..a936ff81b9d900b2601003bef6390d077bedd02b 100644 (file)
@@ -269,6 +269,7 @@ extern void PrintTOCSummary(Archive *AH, RestoreOptions *ropt);
 extern RestoreOptions *NewRestoreOptions(void);
 
 extern DumpOptions *NewDumpOptions(void);
+extern void InitDumpOptions(DumpOptions *opts);
 extern DumpOptions *dumpOptionsFromRestoreOptions(RestoreOptions *ropt);
 
 /* Rearrange and filter TOC entries */
index 43065e84b2f267ff97f08d68a8a3ade3633e177b..9e6455861d92e90128b5603809cc63af4fc6e4be 100644 (file)
@@ -109,23 +109,27 @@ static void mark_create_done(ArchiveHandle *AH, TocEntry *te);
 static void inhibit_data_for_failed_table(ArchiveHandle *AH, TocEntry *te);
 
 /*
- * Allocate a new DumpOptions block.
- * This is mainly so we can initialize it, but also for future expansion.
- * We pg_malloc0 the structure, so we don't need to initialize whatever is
- * 0, NULL or false anyway.
+ * Allocate a new DumpOptions block containing all default values.
  */
 DumpOptions *
 NewDumpOptions(void)
 {
-   DumpOptions *opts;
+   DumpOptions *opts = (DumpOptions *) pg_malloc(sizeof(DumpOptions));
 
-   opts = (DumpOptions *) pg_malloc0(sizeof(DumpOptions));
+   InitDumpOptions(opts);
+   return opts;
+}
 
+/*
+ * Initialize a DumpOptions struct to all default values
+ */
+void
+InitDumpOptions(DumpOptions *opts)
+{
+   memset(opts, 0, sizeof(DumpOptions));
    /* set any fields that shouldn't default to zeroes */
    opts->include_everything = true;
    opts->dumpSections = DUMP_UNSECTIONED;
-
-   return opts;
 }
 
 /*
index 981fdf149ed2b30380e819435becd13d59a5216b..dc062e67eedd6106da434bb889aa207267c69f25 100644 (file)
@@ -279,9 +279,9 @@ main(int argc, char **argv)
    ArchiveFormat archiveFormat = archUnknown;
    ArchiveMode archiveMode;
 
-   DumpOptions *dopt = NewDumpOptions();
+   static DumpOptions dopt;
 
-   struct option long_options[] = {
+   static struct option long_options[] = {
        {"data-only", no_argument, NULL, 'a'},
        {"blobs", no_argument, NULL, 'b'},
        {"clean", no_argument, NULL, 'c'},
@@ -316,26 +316,26 @@ main(int argc, char **argv)
        /*
         * the following options don't have an equivalent short option letter
         */
-       {"attribute-inserts", no_argument, &dopt->column_inserts, 1},
-       {"binary-upgrade", no_argument, &dopt->binary_upgrade, 1},
-       {"column-inserts", no_argument, &dopt->column_inserts, 1},
-       {"disable-dollar-quoting", no_argument, &dopt->disable_dollar_quoting, 1},
-       {"disable-triggers", no_argument, &dopt->disable_triggers, 1},
-       {"enable-row-security", no_argument, &dopt->enable_row_security, 1},
+       {"attribute-inserts", no_argument, &dopt.column_inserts, 1},
+       {"binary-upgrade", no_argument, &dopt.binary_upgrade, 1},
+       {"column-inserts", no_argument, &dopt.column_inserts, 1},
+       {"disable-dollar-quoting", no_argument, &dopt.disable_dollar_quoting, 1},
+       {"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},
-       {"if-exists", no_argument, &dopt->if_exists, 1},
-       {"inserts", no_argument, &dopt->dump_inserts, 1},
+       {"if-exists", no_argument, &dopt.if_exists, 1},
+       {"inserts", no_argument, &dopt.dump_inserts, 1},
        {"lock-wait-timeout", required_argument, NULL, 2},
-       {"no-tablespaces", no_argument, &dopt->outputNoTablespaces, 1},
+       {"no-tablespaces", no_argument, &dopt.outputNoTablespaces, 1},
        {"quote-all-identifiers", no_argument, &quote_all_identifiers, 1},
        {"role", required_argument, NULL, 3},
        {"section", required_argument, NULL, 5},
-       {"serializable-deferrable", no_argument, &dopt->serializable_deferrable, 1},
+       {"serializable-deferrable", no_argument, &dopt.serializable_deferrable, 1},
        {"snapshot", required_argument, NULL, 6},
-       {"use-set-session-authorization", no_argument, &dopt->use_setsessauth, 1},
-       {"no-security-labels", no_argument, &dopt->no_security_labels, 1},
-       {"no-synchronized-snapshots", no_argument, &dopt->no_synchronized_snapshots, 1},
-       {"no-unlogged-table-data", no_argument, &dopt->no_unlogged_table_data, 1},
+       {"use-set-session-authorization", no_argument, &dopt.use_setsessauth, 1},
+       {"no-security-labels", no_argument, &dopt.no_security_labels, 1},
+       {"no-synchronized-snapshots", no_argument, &dopt.no_synchronized_snapshots, 1},
+       {"no-unlogged-table-data", no_argument, &dopt.no_unlogged_table_data, 1},
 
        {NULL, 0, NULL, 0}
    };
@@ -374,29 +374,31 @@ main(int argc, char **argv)
        }
    }
 
+   InitDumpOptions(&dopt);
+
    while ((c = getopt_long(argc, argv, "abcCd:E:f:F:h:ij:n:N:oOp:RsS:t:T:U:vwWxZ:",
                            long_options, &optindex)) != -1)
    {
        switch (c)
        {
            case 'a':           /* Dump data only */
-               dopt->dataOnly = true;
+               dopt.dataOnly = true;
                break;
 
            case 'b':           /* Dump blobs */
-               dopt->outputBlobs = true;
+               dopt.outputBlobs = true;
                break;
 
            case 'c':           /* clean (i.e., drop) schema prior to create */
-               dopt->outputClean = 1;
+               dopt.outputClean = 1;
                break;
 
            case 'C':           /* Create DB */
-               dopt->outputCreateDB = 1;
+               dopt.outputCreateDB = 1;
                break;
 
            case 'd':           /* database name */
-               dopt->dbname = pg_strdup(optarg);
+               dopt.dbname = pg_strdup(optarg);
                break;
 
            case 'E':           /* Dump encoding */
@@ -412,7 +414,7 @@ main(int argc, char **argv)
                break;
 
            case 'h':           /* server host */
-               dopt->pghost = pg_strdup(optarg);
+               dopt.pghost = pg_strdup(optarg);
                break;
 
            case 'i':
@@ -425,7 +427,7 @@ main(int argc, char **argv)
 
            case 'n':           /* include schema(s) */
                simple_string_list_append(&schema_include_patterns, optarg);
-               dopt->include_everything = false;
+               dopt.include_everything = false;
                break;
 
            case 'N':           /* exclude schema(s) */
@@ -433,15 +435,15 @@ main(int argc, char **argv)
                break;
 
            case 'o':           /* Dump oids */
-               dopt->oids = true;
+               dopt.oids = true;
                break;
 
            case 'O':           /* Don't reconnect to match owner */
-               dopt->outputNoOwner = 1;
+               dopt.outputNoOwner = 1;
                break;
 
            case 'p':           /* server port */
-               dopt->pgport = pg_strdup(optarg);
+               dopt.pgport = pg_strdup(optarg);
                break;
 
            case 'R':
@@ -449,16 +451,16 @@ main(int argc, char **argv)
                break;
 
            case 's':           /* dump schema only */
-               dopt->schemaOnly = true;
+               dopt.schemaOnly = true;
                break;
 
            case 'S':           /* Username for superuser in plain text output */
-               dopt->outputSuperuser = pg_strdup(optarg);
+               dopt.outputSuperuser = pg_strdup(optarg);
                break;
 
            case 't':           /* include table(s) */
                simple_string_list_append(&table_include_patterns, optarg);
-               dopt->include_everything = false;
+               dopt.include_everything = false;
                break;
 
            case 'T':           /* exclude table(s) */
@@ -466,7 +468,7 @@ main(int argc, char **argv)
                break;
 
            case 'U':
-               dopt->username = pg_strdup(optarg);
+               dopt.username = pg_strdup(optarg);
                break;
 
            case 'v':           /* verbose */
@@ -482,7 +484,7 @@ main(int argc, char **argv)
                break;
 
            case 'x':           /* skip ACL dump */
-               dopt->aclsSkip = true;
+               dopt.aclsSkip = true;
                break;
 
            case 'Z':           /* Compression Level */
@@ -494,7 +496,7 @@ main(int argc, char **argv)
                break;
 
            case 2:             /* lock-wait-timeout */
-               dopt->lockWaitTimeout = pg_strdup(optarg);
+               dopt.lockWaitTimeout = pg_strdup(optarg);
                break;
 
            case 3:             /* SET ROLE */
@@ -506,7 +508,7 @@ main(int argc, char **argv)
                break;
 
            case 5:             /* section */
-               set_dump_section(optarg, &dopt->dumpSections);
+               set_dump_section(optarg, &dopt.dumpSections);
                break;
 
            case 6:             /* snapshot */
@@ -523,8 +525,8 @@ main(int argc, char **argv)
     * Non-option argument specifies database name as long as it wasn't
     * already specified with -d / --dbname
     */
-   if (optind < argc && dopt->dbname == NULL)
-       dopt->dbname = argv[optind++];
+   if (optind < argc && dopt.dbname == NULL)
+       dopt.dbname = argv[optind++];
 
    /* Complain if any arguments remain */
    if (optind < argc)
@@ -537,29 +539,29 @@ main(int argc, char **argv)
    }
 
    /* --column-inserts implies --inserts */
-   if (dopt->column_inserts)
-       dopt->dump_inserts = 1;
+   if (dopt.column_inserts)
+       dopt.dump_inserts = 1;
 
-   if (dopt->dataOnly && dopt->schemaOnly)
+   if (dopt.dataOnly && dopt.schemaOnly)
    {
        write_msg(NULL, "options -s/--schema-only and -a/--data-only cannot be used together\n");
        exit_nicely(1);
    }
 
-   if (dopt->dataOnly && dopt->outputClean)
+   if (dopt.dataOnly && dopt.outputClean)
    {
        write_msg(NULL, "options -c/--clean and -a/--data-only cannot be used together\n");
        exit_nicely(1);
    }
 
-   if (dopt->dump_inserts && dopt->oids)
+   if (dopt.dump_inserts && dopt.oids)
    {
        write_msg(NULL, "options --inserts/--column-inserts and -o/--oids cannot be used together\n");
        write_msg(NULL, "(The INSERT command cannot set OIDs.)\n");
        exit_nicely(1);
    }
 
-   if (dopt->if_exists && !dopt->outputClean)
+   if (dopt.if_exists && !dopt.outputClean)
        exit_horribly(NULL, "option --if-exists requires option -c/--clean\n");
 
    /* Identify archive format to emit */
@@ -620,15 +622,15 @@ main(int argc, char **argv)
     * Open the database using the Archiver, so it knows about it. Errors mean
     * death.
     */
-   ConnectDatabase(fout, dopt->dbname, dopt->pghost, dopt->pgport, dopt->username, prompt_password);
-   setup_connection(fout, dopt, dumpencoding, dumpsnapshot, use_role);
+   ConnectDatabase(fout, dopt.dbname, dopt.pghost, dopt.pgport, dopt.username, prompt_password);
+   setup_connection(fout, &dopt, dumpencoding, dumpsnapshot, use_role);
 
    /*
     * Disable security label support if server version < v9.1.x (prevents
     * access to nonexistent pg_seclabel catalog)
     */
    if (fout->remoteVersion < 90100)
-       dopt->no_security_labels = 1;
+       dopt.no_security_labels = 1;
 
    /*
     * When running against 9.0 or later, check if we are in recovery mode,
@@ -644,7 +646,7 @@ main(int argc, char **argv)
             * On hot standby slaves, never try to dump unlogged table data,
             * since it will just throw an error.
             */
-           dopt->no_unlogged_table_data = true;
+           dopt.no_unlogged_table_data = true;
        }
        PQclear(res);
    }
@@ -659,7 +661,7 @@ main(int argc, char **argv)
 
    /* check the version for the synchronized snapshots feature */
    if (numWorkers > 1 && fout->remoteVersion < 90200
-       && !dopt->no_synchronized_snapshots)
+       && !dopt.no_synchronized_snapshots)
        exit_horribly(NULL,
         "Synchronized snapshots are not supported by this server version.\n"
          "Run with --no-synchronized-snapshots instead if you do not need\n"
@@ -714,27 +716,27 @@ main(int argc, char **argv)
     * Dumping blobs is now default unless we saw an inclusion switch or -s
     * ... but even if we did see one of these, -b turns it back on.
     */
-   if (dopt->include_everything && !dopt->schemaOnly)
-       dopt->outputBlobs = true;
+   if (dopt.include_everything && !dopt.schemaOnly)
+       dopt.outputBlobs = true;
 
    /*
     * Now scan the database and create DumpableObject structs for all the
     * objects we intend to dump.
     */
-   tblinfo = getSchemaData(fout, dopt, &numTables);
+   tblinfo = getSchemaData(fout, &dopt, &numTables);
 
    if (fout->remoteVersion < 80400)
        guessConstraintInheritance(tblinfo, numTables);
 
-   if (!dopt->schemaOnly)
+   if (!dopt.schemaOnly)
    {
-       getTableData(dopt, tblinfo, numTables, dopt->oids);
+       getTableData(&dopt, tblinfo, numTables, dopt.oids);
        buildMatViewRefreshDependencies(fout);
-       if (dopt->dataOnly)
+       if (dopt.dataOnly)
            getTableDataFKConstraints();
    }
 
-   if (dopt->outputBlobs)
+   if (dopt.outputBlobs)
        getBlobs(fout);
 
    /*
@@ -784,12 +786,12 @@ main(int argc, char **argv)
    dumpStdStrings(fout);
 
    /* The database item is always next, unless we don't want it at all */
-   if (dopt->include_everything && !dopt->dataOnly)
-       dumpDatabase(fout, dopt);
+   if (dopt.include_everything && !dopt.dataOnly)
+       dumpDatabase(fout, &dopt);
 
    /* Now the rearrangeable objects. */
    for (i = 0; i < numObjs; i++)
-       dumpDumpableObject(fout, dopt, dobjs[i]);
+       dumpDumpableObject(fout, &dopt, dobjs[i]);
 
    /*
     * Set up options info to ensure we dump what we want.
@@ -798,25 +800,25 @@ main(int argc, char **argv)
    ropt->filename = filename;
 
    /* if you change this list, see dumpOptionsFromRestoreOptions */
-   ropt->dropSchema = dopt->outputClean;
-   ropt->dataOnly = dopt->dataOnly;
-   ropt->schemaOnly = dopt->schemaOnly;
-   ropt->if_exists = dopt->if_exists;
-   ropt->column_inserts = dopt->column_inserts;
-   ropt->dumpSections = dopt->dumpSections;
-   ropt->aclsSkip = dopt->aclsSkip;
-   ropt->superuser = dopt->outputSuperuser;
-   ropt->createDB = dopt->outputCreateDB;
-   ropt->noOwner = dopt->outputNoOwner;
-   ropt->noTablespace = dopt->outputNoTablespaces;
-   ropt->disable_triggers = dopt->disable_triggers;
-   ropt->use_setsessauth = dopt->use_setsessauth;
-   ropt->disable_dollar_quoting = dopt->disable_dollar_quoting;
-   ropt->dump_inserts = dopt->dump_inserts;
-   ropt->no_security_labels = dopt->no_security_labels;
-   ropt->lockWaitTimeout = dopt->lockWaitTimeout;
-   ropt->include_everything = dopt->include_everything;
-   ropt->enable_row_security = dopt->enable_row_security;
+   ropt->dropSchema = dopt.outputClean;
+   ropt->dataOnly = dopt.dataOnly;
+   ropt->schemaOnly = dopt.schemaOnly;
+   ropt->if_exists = dopt.if_exists;
+   ropt->column_inserts = dopt.column_inserts;
+   ropt->dumpSections = dopt.dumpSections;
+   ropt->aclsSkip = dopt.aclsSkip;
+   ropt->superuser = dopt.outputSuperuser;
+   ropt->createDB = dopt.outputCreateDB;
+   ropt->noOwner = dopt.outputNoOwner;
+   ropt->noTablespace = dopt.outputNoTablespaces;
+   ropt->disable_triggers = dopt.disable_triggers;
+   ropt->use_setsessauth = dopt.use_setsessauth;
+   ropt->disable_dollar_quoting = dopt.disable_dollar_quoting;
+   ropt->dump_inserts = dopt.dump_inserts;
+   ropt->no_security_labels = dopt.no_security_labels;
+   ropt->lockWaitTimeout = dopt.lockWaitTimeout;
+   ropt->include_everything = dopt.include_everything;
+   ropt->enable_row_security = dopt.enable_row_security;
 
    if (compressLevel == -1)
        ropt->compression = 0;
@@ -845,7 +847,7 @@ main(int argc, char **argv)
    if (plainText)
        RestoreArchive(fout);
 
-   CloseArchive(fout, dopt);
+   CloseArchive(fout, &dopt);
 
    exit_nicely(0);
 }