Re: BUG #16604: pg_dump with --jobs breaks SSL connections - Mailing list pgsql-bugs

From Tom Lane
Subject Re: BUG #16604: pg_dump with --jobs breaks SSL connections
Date
Msg-id 1732344.1600978388@sss.pgh.pa.us
Whole thread Raw
In response to Re: BUG #16604: pg_dump with --jobs breaks SSL connections  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: BUG #16604: pg_dump with --jobs breaks SSL connections  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-bugs
I wrote:
> I'm inclined to think that
> we should get rid of _connectDB, because it seems unnecessarily
> duplicative with ConnectDatabase.  But we'll need a bit more
> API refactoring than what I had.  New patch coming ...

A bit of refactoring later, I have the attached, which seems to
clean up all cases.  I got rid of some bits of dead code along
the way.

            regards, tom lane

diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h
index 1017abbbe5..a6a8e6f2fd 100644
--- a/src/bin/pg_dump/pg_backup.h
+++ b/src/bin/pg_dump/pg_backup.h
@@ -58,6 +58,20 @@ typedef enum _teSection
     SECTION_POST_DATA            /* stuff to be processed after data */
 } teSection;

+/* Parameters needed by ConnectDatabase; same for dump and restore */
+typedef struct _connParams
+{
+    /* These fields record the actual command line parameters */
+    char       *dbname;            /* this may be a connstring! */
+    char       *pgport;
+    char       *pghost;
+    char       *username;
+    trivalue    promptPassword;
+    /* If not NULL, this overrides the dbname obtained from command line */
+    /* (but *only* the DB name, not anything else in the connstring) */
+    char       *override_dbname;
+} ConnParams;
+
 typedef struct _restoreOptions
 {
     int            createDB;        /* Issue commands to create the database */
@@ -107,12 +121,9 @@ typedef struct _restoreOptions
     SimpleStringList tableNames;

     int            useDB;
-    char       *dbname;            /* subject to expand_dbname */
-    char       *pgport;
-    char       *pghost;
-    char       *username;
+    ConnParams    cparams;        /* parameters to use if useDB */
+
     int            noDataForFailedTables;
-    trivalue    promptPassword;
     int            exit_on_error;
     int            compression;
     int            suppressDumpWarnings;    /* Suppress output of WARNING entries
@@ -127,10 +138,7 @@ typedef struct _restoreOptions

 typedef struct _dumpOptions
 {
-    const char *dbname;            /* subject to expand_dbname */
-    const char *pghost;
-    const char *pgport;
-    const char *username;
+    ConnParams    cparams;

     int            binary_upgrade;

@@ -247,12 +255,9 @@ typedef void (*SetupWorkerPtrType) (Archive *AH);
  * Main archiver interface.
  */

-extern void ConnectDatabase(Archive *AH,
-                            const char *dbname,
-                            const char *pghost,
-                            const char *pgport,
-                            const char *username,
-                            trivalue prompt_password);
+extern void ConnectDatabase(Archive *AHX,
+                            const ConnParams *cparams,
+                            bool isReconnect);
 extern void DisconnectDatabase(Archive *AHX);
 extern PGconn *GetConnection(Archive *AHX);

diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index 3567e9f365..d61b290d2a 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -165,6 +165,7 @@ InitDumpOptions(DumpOptions *opts)
     memset(opts, 0, sizeof(DumpOptions));
     /* set any fields that shouldn't default to zeroes */
     opts->include_everything = true;
+    opts->cparams.promptPassword = TRI_DEFAULT;
     opts->dumpSections = DUMP_UNSECTIONED;
 }

@@ -178,6 +179,11 @@ dumpOptionsFromRestoreOptions(RestoreOptions *ropt)
     DumpOptions *dopt = NewDumpOptions();

     /* this is the inverse of what's at the end of pg_dump.c's main() */
+    dopt->cparams.dbname = ropt->cparams.dbname ? pg_strdup(ropt->cparams.dbname) : NULL;
+    dopt->cparams.pgport = ropt->cparams.pgport ? pg_strdup(ropt->cparams.pgport) : NULL;
+    dopt->cparams.pghost = ropt->cparams.pghost ? pg_strdup(ropt->cparams.pghost) : NULL;
+    dopt->cparams.username = ropt->cparams.username ? pg_strdup(ropt->cparams.username) : NULL;
+    dopt->cparams.promptPassword = ropt->cparams.promptPassword;
     dopt->outputClean = ropt->dropSchema;
     dopt->dataOnly = ropt->dataOnly;
     dopt->schemaOnly = ropt->schemaOnly;
@@ -410,9 +416,7 @@ RestoreArchive(Archive *AHX)
         AHX->minRemoteVersion = 0;
         AHX->maxRemoteVersion = 9999999;

-        ConnectDatabase(AHX, ropt->dbname,
-                        ropt->pghost, ropt->pgport, ropt->username,
-                        ropt->promptPassword);
+        ConnectDatabase(AHX, &ropt->cparams, false);

         /*
          * If we're talking to the DB directly, don't send comments since they
@@ -832,16 +836,8 @@ restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel)
         if (strcmp(te->desc, "DATABASE") == 0 ||
             strcmp(te->desc, "DATABASE PROPERTIES") == 0)
         {
-            PQExpBufferData connstr;
-
-            initPQExpBuffer(&connstr);
-            appendPQExpBufferStr(&connstr, "dbname=");
-            appendConnStrVal(&connstr, te->tag);
-            /* Abandon struct, but keep its buffer until process exit. */
-
             pg_log_info("connecting to new database \"%s\"", te->tag);
             _reconnectToDB(AH, te->tag);
-            ropt->dbname = connstr.data;
         }
     }

@@ -973,7 +969,7 @@ NewRestoreOptions(void)

     /* set any fields that shouldn't default to zeroes */
     opts->format = archUnknown;
-    opts->promptPassword = TRI_DEFAULT;
+    opts->cparams.promptPassword = TRI_DEFAULT;
     opts->dumpSections = DUMP_UNSECTIONED;

     return opts;
@@ -2345,8 +2341,6 @@ _allocAH(const char *FileSpec, const ArchiveFormat fmt,
     else
         AH->format = fmt;

-    AH->promptPassword = TRI_DEFAULT;
-
     switch (AH->format)
     {
         case archCustom:
@@ -3207,27 +3201,20 @@ _doSetSessionAuth(ArchiveHandle *AH, const char *user)
  * If we're currently restoring right into a database, this will
  * actually establish a connection. Otherwise it puts a \connect into
  * the script output.
- *
- * NULL dbname implies reconnecting to the current DB (pretty useless).
  */
 static void
 _reconnectToDB(ArchiveHandle *AH, const char *dbname)
 {
     if (RestoringToDB(AH))
-        ReconnectToServer(AH, dbname, NULL);
+        ReconnectToServer(AH, dbname);
     else
     {
-        if (dbname)
-        {
-            PQExpBufferData connectbuf;
+        PQExpBufferData connectbuf;

-            initPQExpBuffer(&connectbuf);
-            appendPsqlMetaConnect(&connectbuf, dbname);
-            ahprintf(AH, "%s\n", connectbuf.data);
-            termPQExpBuffer(&connectbuf);
-        }
-        else
-            ahprintf(AH, "%s\n", "\\connect -\n");
+        initPQExpBuffer(&connectbuf);
+        appendPsqlMetaConnect(&connectbuf, dbname);
+        ahprintf(AH, "%s\n", connectbuf.data);
+        termPQExpBuffer(&connectbuf);
     }

     /*
@@ -4159,9 +4146,7 @@ restore_toc_entries_postfork(ArchiveHandle *AH, TocEntry *pending_list)
     /*
      * Now reconnect the single parent connection.
      */
-    ConnectDatabase((Archive *) AH, ropt->dbname,
-                    ropt->pghost, ropt->pgport, ropt->username,
-                    ropt->promptPassword);
+    ConnectDatabase((Archive *) AH, &ropt->cparams, true);

     /* re-establish fixed state */
     _doSetFixedOutputState(AH);
@@ -4823,54 +4808,15 @@ CloneArchive(ArchiveHandle *AH)
     clone->public.n_errors = 0;

     /*
-     * Connect our new clone object to the database: In parallel restore the
-     * parent is already disconnected, because we can connect the worker
-     * processes independently to the database (no snapshot sync required). In
-     * parallel backup we clone the parent's existing connection.
+     * Connect our new clone object to the database, using the same connection
+     * parameters used for the original connection.
      */
-    if (AH->mode == archModeRead)
-    {
-        RestoreOptions *ropt = AH->public.ropt;
-
-        Assert(AH->connection == NULL);
-
-        /* this also sets clone->connection */
-        ConnectDatabase((Archive *) clone, ropt->dbname,
-                        ropt->pghost, ropt->pgport, ropt->username,
-                        ropt->promptPassword);
+    ConnectDatabase((Archive *) clone, &clone->public.ropt->cparams, true);

-        /* re-establish fixed state */
+    /* re-establish fixed state */
+    if (AH->mode == archModeRead)
         _doSetFixedOutputState(clone);
-    }
-    else
-    {
-        PQExpBufferData connstr;
-        char       *pghost;
-        char       *pgport;
-        char       *username;
-
-        Assert(AH->connection != NULL);
-
-        /*
-         * Even though we are technically accessing the parent's database
-         * object here, these functions are fine to be called like that
-         * because all just return a pointer and do not actually send/receive
-         * any data to/from the database.
-         */
-        initPQExpBuffer(&connstr);
-        appendPQExpBufferStr(&connstr, "dbname=");
-        appendConnStrVal(&connstr, PQdb(AH->connection));
-        pghost = PQhost(AH->connection);
-        pgport = PQport(AH->connection);
-        username = PQuser(AH->connection);
-
-        /* this also sets clone->connection */
-        ConnectDatabase((Archive *) clone, connstr.data,
-                        pghost, pgport, username, TRI_NO);
-
-        termPQExpBuffer(&connstr);
-        /* setupDumpWorker will fix up connection state */
-    }
+    /* in write case, setupDumpWorker will fix up connection state */

     /* Let the format-specific code have a chance too */
     clone->ClonePtr(clone);
diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h
index f9e6b42752..fb8d226d48 100644
--- a/src/bin/pg_dump/pg_backup_archiver.h
+++ b/src/bin/pg_dump/pg_backup_archiver.h
@@ -303,7 +303,6 @@ struct _archiveHandle

     /* Stuff for direct DB connection */
     char       *archdbname;        /* DB name *read* from archive */
-    trivalue    promptPassword;
     char       *savedPassword;    /* password for ropt->username, if known */
     char       *use_role;
     PGconn       *connection;
@@ -471,7 +470,7 @@ extern void InitArchiveFmt_Tar(ArchiveHandle *AH);

 extern bool isValidTarHeader(char *header);

-extern void ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *newUser);
+extern void ReconnectToServer(ArchiveHandle *AH, const char *dbname);
 extern void DropBlobIfExists(ArchiveHandle *AH, Oid oid);

 void        ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH);
diff --git a/src/bin/pg_dump/pg_backup_db.c b/src/bin/pg_dump/pg_backup_db.c
index 12899e26e2..5ba43441f5 100644
--- a/src/bin/pg_dump/pg_backup_db.c
+++ b/src/bin/pg_dump/pg_backup_db.c
@@ -27,7 +27,6 @@
 #include "pg_backup_utils.h"

 static void _check_database_version(ArchiveHandle *AH);
-static PGconn *_connectDB(ArchiveHandle *AH, const char *newdbname, const char *newUser);
 static void notice_processor(void *arg, const char *message);

 static void
@@ -73,211 +72,100 @@ _check_database_version(ArchiveHandle *AH)

 /*
  * Reconnect to the server.  If dbname is not NULL, use that database,
- * else the one associated with the archive handle.  If username is
- * not NULL, use that user name, else the one from the handle.
+ * else the one associated with the archive handle.
  */
 void
-ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *username)
+ReconnectToServer(ArchiveHandle *AH, const char *dbname)
 {
-    PGconn       *newConn;
-    const char *newdbname;
-    const char *newusername;
-
-    if (!dbname)
-        newdbname = PQdb(AH->connection);
-    else
-        newdbname = dbname;
-
-    if (!username)
-        newusername = PQuser(AH->connection);
-    else
-        newusername = username;
-
-    newConn = _connectDB(AH, newdbname, newusername);
-
-    /* Update ArchiveHandle's connCancel before closing old connection */
-    set_archive_cancel_info(AH, newConn);
-
-    PQfinish(AH->connection);
-    AH->connection = newConn;
-
-    /* Start strict; later phases may override this. */
-    PQclear(ExecuteSqlQueryForSingleRow((Archive *) AH,
-                                        ALWAYS_SECURE_SEARCH_PATH_SQL));
-}
-
-/*
- * Connect to the db again.
- *
- * Note: it's not really all that sensible to use a single-entry password
- * cache if the username keeps changing.  In current usage, however, the
- * username never does change, so one savedPassword is sufficient.  We do
- * update the cache on the off chance that the password has changed since the
- * start of the run.
- */
-static PGconn *
-_connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser)
-{
-    PQExpBufferData connstr;
-    PGconn       *newConn;
-    const char *newdb;
-    const char *newuser;
-    char       *password;
-    bool        new_pass;
-
-    if (!reqdb)
-        newdb = PQdb(AH->connection);
-    else
-        newdb = reqdb;
-
-    if (!requser || strlen(requser) == 0)
-        newuser = PQuser(AH->connection);
-    else
-        newuser = requser;
-
-    pg_log_info("connecting to database \"%s\" as user \"%s\"",
-                newdb, newuser);
-
-    password = AH->savedPassword;
-
-    if (AH->promptPassword == TRI_YES && password == NULL)
-        password = simple_prompt("Password: ", false);
-
-    initPQExpBuffer(&connstr);
-    appendPQExpBufferStr(&connstr, "dbname=");
-    appendConnStrVal(&connstr, newdb);
-
-    do
-    {
-        const char *keywords[7];
-        const char *values[7];
-
-        keywords[0] = "host";
-        values[0] = PQhost(AH->connection);
-        keywords[1] = "port";
-        values[1] = PQport(AH->connection);
-        keywords[2] = "user";
-        values[2] = newuser;
-        keywords[3] = "password";
-        values[3] = password;
-        keywords[4] = "dbname";
-        values[4] = connstr.data;
-        keywords[5] = "fallback_application_name";
-        values[5] = progname;
-        keywords[6] = NULL;
-        values[6] = NULL;
-
-        new_pass = false;
-        newConn = PQconnectdbParams(keywords, values, true);
-
-        if (!newConn)
-            fatal("could not reconnect to database");
-
-        if (PQstatus(newConn) == CONNECTION_BAD)
-        {
-            if (!PQconnectionNeedsPassword(newConn))
-                fatal("could not reconnect to database: %s",
-                      PQerrorMessage(newConn));
-            PQfinish(newConn);
-
-            if (password)
-                fprintf(stderr, "Password incorrect\n");
-
-            fprintf(stderr, "Connecting to %s as %s\n",
-                    newdb, newuser);
-
-            if (AH->promptPassword != TRI_NO)
-            {
-                if (password && password != AH->savedPassword)
-                    free(password);
-                password = simple_prompt("Password: ", false);
-            }
-            else
-                fatal("connection needs password");
-
-            new_pass = true;
-        }
-    } while (new_pass);
-
-    if (password && password != AH->savedPassword)
-        free(password);
+    PGconn       *oldConn = AH->connection;
+    RestoreOptions *ropt = AH->public.ropt;

     /*
-     * We want to remember connection's actual password, whether or not we got
-     * it by prompting.  So we don't just store the password variable.
+     * Save the dbname, if given, in override_dbname so that it will also
+     * affect any later reconnection attempt.
      */
-    if (PQconnectionUsedPassword(newConn))
-    {
-        if (AH->savedPassword)
-            free(AH->savedPassword);
-        AH->savedPassword = pg_strdup(PQpass(newConn));
-    }
-
-    termPQExpBuffer(&connstr);
+    if (dbname)
+        ropt->cparams.override_dbname = pg_strdup(dbname);

-    /* check for version mismatch */
-    _check_database_version(AH);
+    /*
+     * Note: we want to establish the new connection, and in particular update
+     * ArchiveHandle's connCancel, before closing old connection.  Otherwise
+     * an ill-timed SIGINT could try to access a dead connection.
+     */
+    AH->connection = NULL;        /* dodge error check in ConnectDatabase */

-    PQsetNoticeProcessor(newConn, notice_processor, NULL);
+    ConnectDatabase((Archive *) AH, &ropt->cparams, true);

-    return newConn;
+    PQfinish(oldConn);
 }

-
 /*
- * Make a database connection with the given parameters.  The
- * connection handle is returned, the parameters are stored in AHX.
- * An interactive password prompt is automatically issued if required.
+ * Make, or remake, a database connection with the given parameters.
+ *
+ * The resulting connection handle is stored in AHX->connection.
  *
+ * An interactive password prompt is automatically issued if required.
+ * We store the results of that in AHX->savedPassword.
  * Note: it's not really all that sensible to use a single-entry password
  * cache if the username keeps changing.  In current usage, however, the
  * username never does change, so one savedPassword is sufficient.
  */
 void
 ConnectDatabase(Archive *AHX,
-                const char *dbname,
-                const char *pghost,
-                const char *pgport,
-                const char *username,
-                trivalue prompt_password)
+                const ConnParams *cparams,
+                bool isReconnect)
 {
     ArchiveHandle *AH = (ArchiveHandle *) AHX;
+    trivalue    prompt_password;
     char       *password;
     bool        new_pass;

     if (AH->connection)
         fatal("already connected to a database");

+    /* Never prompt for a password during a reconnection */
+    prompt_password = isReconnect ? TRI_NO : cparams->promptPassword;
+
     password = AH->savedPassword;

     if (prompt_password == TRI_YES && password == NULL)
         password = simple_prompt("Password: ", false);

-    AH->promptPassword = prompt_password;
-
     /*
      * Start the connection.  Loop until we have a password if requested by
      * backend.
      */
     do
     {
-        const char *keywords[7];
-        const char *values[7];
-
-        keywords[0] = "host";
-        values[0] = pghost;
-        keywords[1] = "port";
-        values[1] = pgport;
-        keywords[2] = "user";
-        values[2] = username;
-        keywords[3] = "password";
-        values[3] = password;
-        keywords[4] = "dbname";
-        values[4] = dbname;
-        keywords[5] = "fallback_application_name";
-        values[5] = progname;
-        keywords[6] = NULL;
-        values[6] = NULL;
+        const char *keywords[8];
+        const char *values[8];
+        int            i = 0;
+
+        /*
+         * If dbname is a connstring, its entries can override the other
+         * values obtained from cparams; but in turn, override_dbname can
+         * override the dbname component of it.
+         */
+        keywords[i] = "host";
+        values[i++] = cparams->pghost;
+        keywords[i] = "port";
+        values[i++] = cparams->pgport;
+        keywords[i] = "user";
+        values[i++] = cparams->username;
+        keywords[i] = "password";
+        values[i++] = password;
+        keywords[i] = "dbname";
+        values[i++] = cparams->dbname;
+        if (cparams->override_dbname)
+        {
+            keywords[i] = "dbname";
+            values[i++] = cparams->override_dbname;
+        }
+        keywords[i] = "fallback_application_name";
+        values[i++] = progname;
+        keywords[i] = NULL;
+        values[i++] = NULL;
+        Assert(i <= lengthof(keywords));

         new_pass = false;
         AH->connection = PQconnectdbParams(keywords, values, true);
@@ -298,9 +186,16 @@ ConnectDatabase(Archive *AHX,

     /* check to see that the backend connection was successfully made */
     if (PQstatus(AH->connection) == CONNECTION_BAD)
-        fatal("connection to database \"%s\" failed: %s",
-              PQdb(AH->connection) ? PQdb(AH->connection) : "",
-              PQerrorMessage(AH->connection));
+    {
+        if (isReconnect)
+            fatal("reconnection to database \"%s\" failed: %s",
+                  PQdb(AH->connection) ? PQdb(AH->connection) : "",
+                  PQerrorMessage(AH->connection));
+        else
+            fatal("connection to database \"%s\" failed: %s",
+                  PQdb(AH->connection) ? PQdb(AH->connection) : "",
+                  PQerrorMessage(AH->connection));
+    }

     /* Start strict; later phases may override this. */
     PQclear(ExecuteSqlQueryForSingleRow((Archive *) AH,
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index f021bb72f4..76320468ba 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -314,7 +314,6 @@ main(int argc, char **argv)
     char       *use_role = NULL;
     long        rowsPerInsert;
     int            numWorkers = 1;
-    trivalue    prompt_password = TRI_DEFAULT;
     int            compressLevel = -1;
     int            plainText = 0;
     ArchiveFormat archiveFormat = archUnknown;
@@ -444,7 +443,7 @@ main(int argc, char **argv)
                 break;

             case 'd':            /* database name */
-                dopt.dbname = pg_strdup(optarg);
+                dopt.cparams.dbname = pg_strdup(optarg);
                 break;

             case 'E':            /* Dump encoding */
@@ -460,7 +459,7 @@ main(int argc, char **argv)
                 break;

             case 'h':            /* server host */
-                dopt.pghost = pg_strdup(optarg);
+                dopt.cparams.pghost = pg_strdup(optarg);
                 break;

             case 'j':            /* number of dump jobs */
@@ -481,7 +480,7 @@ main(int argc, char **argv)
                 break;

             case 'p':            /* server port */
-                dopt.pgport = pg_strdup(optarg);
+                dopt.cparams.pgport = pg_strdup(optarg);
                 break;

             case 'R':
@@ -506,7 +505,7 @@ main(int argc, char **argv)
                 break;

             case 'U':
-                dopt.username = pg_strdup(optarg);
+                dopt.cparams.username = pg_strdup(optarg);
                 break;

             case 'v':            /* verbose */
@@ -515,11 +514,11 @@ main(int argc, char **argv)
                 break;

             case 'w':
-                prompt_password = TRI_NO;
+                dopt.cparams.promptPassword = TRI_NO;
                 break;

             case 'W':
-                prompt_password = TRI_YES;
+                dopt.cparams.promptPassword = TRI_YES;
                 break;

             case 'x':            /* skip ACL dump */
@@ -613,8 +612,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.cparams.dbname == NULL)
+        dopt.cparams.dbname = argv[optind++];

     /* Complain if any arguments remain */
     if (optind < argc)
@@ -740,7 +739,7 @@ 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);
+    ConnectDatabase(fout, &dopt.cparams, false);
     setup_connection(fout, dumpencoding, dumpsnapshot, use_role);

     /*
@@ -918,6 +917,11 @@ main(int argc, char **argv)
     ropt->filename = filename;

     /* if you change this list, see dumpOptionsFromRestoreOptions */
+    ropt->cparams.dbname = dopt.cparams.dbname ? pg_strdup(dopt.cparams.dbname) : NULL;
+    ropt->cparams.pgport = dopt.cparams.pgport ? pg_strdup(dopt.cparams.pgport) : NULL;
+    ropt->cparams.pghost = dopt.cparams.pghost ? pg_strdup(dopt.cparams.pghost) : NULL;
+    ropt->cparams.username = dopt.cparams.username ? pg_strdup(dopt.cparams.username) : NULL;
+    ropt->cparams.promptPassword = dopt.cparams.promptPassword;
     ropt->dropSchema = dopt.outputClean;
     ropt->dataOnly = dopt.dataOnly;
     ropt->schemaOnly = dopt.schemaOnly;
diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c
index eebf0d300b..589b4aed53 100644
--- a/src/bin/pg_dump/pg_restore.c
+++ b/src/bin/pg_dump/pg_restore.c
@@ -163,7 +163,7 @@ main(int argc, char **argv)
                 opts->createDB = 1;
                 break;
             case 'd':
-                opts->dbname = pg_strdup(optarg);
+                opts->cparams.dbname = pg_strdup(optarg);
                 break;
             case 'e':
                 opts->exit_on_error = true;
@@ -177,7 +177,7 @@ main(int argc, char **argv)
                 break;
             case 'h':
                 if (strlen(optarg) != 0)
-                    opts->pghost = pg_strdup(optarg);
+                    opts->cparams.pghost = pg_strdup(optarg);
                 break;

             case 'j':            /* number of restore jobs */
@@ -206,7 +206,7 @@ main(int argc, char **argv)

             case 'p':
                 if (strlen(optarg) != 0)
-                    opts->pgport = pg_strdup(optarg);
+                    opts->cparams.pgport = pg_strdup(optarg);
                 break;
             case 'R':
                 /* no-op, still accepted for backwards compatibility */
@@ -240,7 +240,7 @@ main(int argc, char **argv)
                 break;

             case 'U':
-                opts->username = pg_strdup(optarg);
+                opts->cparams.username = pg_strdup(optarg);
                 break;

             case 'v':            /* verbose */
@@ -249,11 +249,11 @@ main(int argc, char **argv)
                 break;

             case 'w':
-                opts->promptPassword = TRI_NO;
+                opts->cparams.promptPassword = TRI_NO;
                 break;

             case 'W':
-                opts->promptPassword = TRI_YES;
+                opts->cparams.promptPassword = TRI_YES;
                 break;

             case 'x':            /* skip ACL dump */
@@ -303,14 +303,14 @@ main(int argc, char **argv)
     }

     /* Complain if neither -f nor -d was specified (except if dumping TOC) */
-    if (!opts->dbname && !opts->filename && !opts->tocSummary)
+    if (!opts->cparams.dbname && !opts->filename && !opts->tocSummary)
     {
         pg_log_error("one of -d/--dbname and -f/--file must be specified");
         exit_nicely(1);
     }

     /* Should get at most one of -d and -f, else user is confused */
-    if (opts->dbname)
+    if (opts->cparams.dbname)
     {
         if (opts->filename)
         {

pgsql-bugs by date:

Previous
From: Tom Lane
Date:
Subject: Re: BUG #16604: pg_dump with --jobs breaks SSL connections
Next
From: Michał Albrycht
Date:
Subject: Re: BUG #16634: Conflicting names of indexes for partitioned tables