<term><option><optional>--dbname=</optional><replaceable class="parameter">dbname</replaceable></option></term>
       <listitem>
        <para>
-        Specifies the name of the database to be clustered.
-        If this is not specified and <option>-a</option> (or
-        <option>--all</option>) is not used, the database name is read
+        Specifies the name of the database to be clustered,
+        when <option>-a</option>/<option>--all</option> is not used.
+        If this is not specified, the database name is read
         from the environment variable <envar>PGDATABASE</envar>.  If
         that is not set, the user name specified for the connection is
         used.  The <replaceable>dbname</replaceable> can be a <link
       <term><option>--maintenance-db=<replaceable class="parameter">dbname</replaceable></option></term>
       <listitem>
        <para>
-         Specifies the name of the database to connect to discover what other
-         databases should be clustered. If not specified, the
-         <literal>postgres</literal> database will be used,
-         and if that does not exist, <literal>template1</literal> will be used.
+        Specifies the name of the database to connect to to discover which
+        databases should be clustered,
+        when <option>-a</option>/<option>--all</option> is used.
+        If not specified, the <literal>postgres</literal> database will be used,
+        or if that does not exist, <literal>template1</literal> will be used.
+        This can be a <link linkend="libpq-connstring">connection
+        string</link>.  If so, connection string parameters will override any
+        conflicting command line options.  Also, connection string parameters
+        other than the database name itself will be re-used when connecting
+        to other databases.
        </para>
       </listitem>
      </varlistentry>
 
          database will be used; if that does not exist (or if it is the name
          of the new database being created), <literal>template1</literal> will
          be used.
+         This can be a <link linkend="libpq-connstring">connection
+         string</link>.  If so, connection string parameters will override any
+         conflicting command line options.
        </para>
       </listitem>
      </varlistentry>
 
          target database. If not specified, the <literal>postgres</literal>
          database will be used; if that does not exist (or is the database
          being dropped), <literal>template1</literal> will be used.
+         This can be a <link linkend="libpq-connstring">connection
+         string</link>.  If so, connection string parameters will override any
+         conflicting command line options.
        </para>
       </listitem>
      </varlistentry>
 
       <term><option><optional>--dbname=</optional><replaceable class="parameter">dbname</replaceable></option></term>
       <listitem>
        <para>
-        Specifies the name of the database to be reindexed.
-        If this is not specified and <option>-a</option> (or
-        <option>--all</option>) is not used, the database name is read
+        Specifies the name of the database to be reindexed,
+        when <option>-a</option>/<option>--all</option> is not used.
+        If this is not specified, the database name is read
         from the environment variable <envar>PGDATABASE</envar>.  If
         that is not set, the user name specified for the connection is
         used.  The <replaceable>dbname</replaceable> can be a <link
       <term><option>--maintenance-db=<replaceable class="parameter">dbname</replaceable></option></term>
       <listitem>
        <para>
-         Specifies the name of the database to connect to discover what other
-         databases should be reindexed. If not specified, the
-         <literal>postgres</literal> database will be used,
-         and if that does not exist, <literal>template1</literal> will be used.
+        Specifies the name of the database to connect to to discover which
+        databases should be reindexed,
+        when <option>-a</option>/<option>--all</option> is used.
+        If not specified, the <literal>postgres</literal> database will be used,
+        or if that does not exist, <literal>template1</literal> will be used.
+        This can be a <link linkend="libpq-connstring">connection
+        string</link>.  If so, connection string parameters will override any
+        conflicting command line options.  Also, connection string parameters
+        other than the database name itself will be re-used when connecting
+        to other databases.
        </para>
       </listitem>
      </varlistentry>
 
       <term><option><optional>--dbname=</optional><replaceable class="parameter">dbname</replaceable></option></term>
       <listitem>
        <para>
-        Specifies the name of the database to be cleaned or analyzed.
-        If this is not specified and <option>-a</option> (or
-        <option>--all</option>) is not used, the database name is read
+        Specifies the name of the database to be cleaned or analyzed,
+        when <option>-a</option>/<option>--all</option> is not used.
+        If this is not specified, the database name is read
         from the environment variable <envar>PGDATABASE</envar>.  If
         that is not set, the user name specified for the connection is
         used.  The <replaceable>dbname</replaceable> can be a <link
       <term><option>--maintenance-db=<replaceable class="parameter">dbname</replaceable></option></term>
       <listitem>
        <para>
-         Specifies the name of the database to connect to discover what other
-         databases should be vacuumed. If not specified, the
-         <literal>postgres</literal> database will be used,
-         and if that does not exist, <literal>template1</literal> will be used.
+        Specifies the name of the database to connect to to discover which
+        databases should be vacuumed,
+        when <option>-a</option>/<option>--all</option> is used.
+        If not specified, the <literal>postgres</literal> database will be used,
+        or if that does not exist, <literal>template1</literal> will be used.
+        This can be a <link linkend="libpq-connstring">connection
+        string</link>.  If so, connection string parameters will override any
+        conflicting command line options.  Also, connection string parameters
+        other than the database name itself will be re-used when connecting
+        to other databases.
        </para>
       </listitem>
      </varlistentry>
 
 #include "fe_utils/string_utils.h"
 
 
-static void cluster_one_database(const char *dbname, bool verbose, const char *table,
-                                const char *host, const char *port,
-                                const char *username, enum trivalue prompt_password,
-                                const char *progname, bool echo);
-static void cluster_all_databases(bool verbose, const char *maintenance_db,
-                                 const char *host, const char *port,
-                                 const char *username, enum trivalue prompt_password,
-                                 const char *progname, bool echo, bool quiet);
-
+static void cluster_one_database(const ConnParams *cparams, const char *table,
+                                const char *progname, bool verbose, bool echo);
+static void cluster_all_databases(ConnParams *cparams, const char *progname,
+                                 bool verbose, bool echo, bool quiet);
 static void help(const char *progname);
 
 
    char       *port = NULL;
    char       *username = NULL;
    enum trivalue prompt_password = TRI_DEFAULT;
+   ConnParams  cparams;
    bool        echo = false;
    bool        quiet = false;
    bool        alldb = false;
        exit(1);
    }
 
+   /* fill cparams except for dbname, which is set below */
+   cparams.pghost = host;
+   cparams.pgport = port;
+   cparams.pguser = username;
+   cparams.prompt_password = prompt_password;
+   cparams.override_dbname = NULL;
+
    setup_cancel_handler(NULL);
 
    if (alldb)
            exit(1);
        }
 
-       cluster_all_databases(verbose, maintenance_db, host, port, username, prompt_password,
-                             progname, echo, quiet);
+       cparams.dbname = maintenance_db;
+
+       cluster_all_databases(&cparams, progname, verbose, echo, quiet);
    }
    else
    {
                dbname = get_user_name_or_exit(progname);
        }
 
+       cparams.dbname = dbname;
+
        if (tables.head != NULL)
        {
            SimpleStringListCell *cell;
 
            for (cell = tables.head; cell; cell = cell->next)
            {
-               cluster_one_database(dbname, verbose, cell->val,
-                                    host, port, username, prompt_password,
-                                    progname, echo);
+               cluster_one_database(&cparams, cell->val,
+                                    progname, verbose, echo);
            }
        }
        else
-           cluster_one_database(dbname, verbose, NULL,
-                                host, port, username, prompt_password,
-                                progname, echo);
+           cluster_one_database(&cparams, NULL,
+                                progname, verbose, echo);
    }
 
    exit(0);
 
 
 static void
-cluster_one_database(const char *dbname, bool verbose, const char *table,
-                    const char *host, const char *port,
-                    const char *username, enum trivalue prompt_password,
-                    const char *progname, bool echo)
+cluster_one_database(const ConnParams *cparams, const char *table,
+                    const char *progname, bool verbose, bool echo)
 {
    PQExpBufferData sql;
 
    PGconn     *conn;
 
-   conn = connectDatabase(dbname, host, port, username, prompt_password,
-                          progname, echo, false, false);
+   conn = connectDatabase(cparams, progname, echo, false, false);
 
    initPQExpBuffer(&sql);
 
 
 
 static void
-cluster_all_databases(bool verbose, const char *maintenance_db,
-                     const char *host, const char *port,
-                     const char *username, enum trivalue prompt_password,
-                     const char *progname, bool echo, bool quiet)
+cluster_all_databases(ConnParams *cparams, const char *progname,
+                     bool verbose, bool echo, bool quiet)
 {
    PGconn     *conn;
    PGresult   *result;
-   PQExpBufferData connstr;
    int         i;
 
-   conn = connectMaintenanceDatabase(maintenance_db, host, port, username,
-                                     prompt_password, progname, echo);
+   conn = connectMaintenanceDatabase(cparams, progname, echo);
    result = executeQuery(conn, "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;", echo);
    PQfinish(conn);
 
-   initPQExpBuffer(&connstr);
    for (i = 0; i < PQntuples(result); i++)
    {
        char       *dbname = PQgetvalue(result, i, 0);
            fflush(stdout);
        }
 
-       resetPQExpBuffer(&connstr);
-       appendPQExpBufferStr(&connstr, "dbname=");
-       appendConnStrVal(&connstr, dbname);
+       cparams->override_dbname = dbname;
 
-       cluster_one_database(connstr.data, verbose, NULL,
-                            host, port, username, prompt_password,
-                            progname, echo);
+       cluster_one_database(cparams, NULL, progname, verbose, echo);
    }
-   termPQExpBuffer(&connstr);
 
    PQclear(result);
 }
 
  * Make a database connection with the given parameters.
  *
  * An interactive password prompt is automatically issued if needed and
- * allowed by prompt_password.
+ * allowed by cparams->prompt_password.
  *
  * If allow_password_reuse is true, we will try to re-use any password
  * given during previous calls to this routine.  (Callers should not pass
  * as before, else we might create password exposure hazards.)
  */
 PGconn *
-connectDatabase(const char *dbname, const char *pghost,
-               const char *pgport, const char *pguser,
-               enum trivalue prompt_password, const char *progname,
+connectDatabase(const ConnParams *cparams, const char *progname,
                bool echo, bool fail_ok, bool allow_password_reuse)
 {
    PGconn     *conn;
    bool        new_pass;
    static char *password = NULL;
 
+   /* Callers must supply at least dbname; other params can be NULL */
+   Assert(cparams->dbname);
+
    if (!allow_password_reuse && password)
    {
        free(password);
        password = NULL;
    }
 
-   if (!password && prompt_password == TRI_YES)
+   if (cparams->prompt_password == TRI_YES && password == NULL)
        password = simple_prompt("Password: ", false);
 
    /*
     */
    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] = pguser;
-       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->pguser;
+       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;
        conn = PQconnectdbParams(keywords, values, true);
        if (!conn)
        {
            pg_log_error("could not connect to database %s: out of memory",
-                        dbname);
+                        cparams->dbname);
            exit(1);
        }
 
         */
        if (PQstatus(conn) == CONNECTION_BAD &&
            PQconnectionNeedsPassword(conn) &&
-           prompt_password != TRI_NO)
+           cparams->prompt_password != TRI_NO)
        {
            PQfinish(conn);
            if (password)
            return NULL;
        }
        pg_log_error("could not connect to database %s: %s",
-                    dbname, PQerrorMessage(conn));
+                    cparams->dbname, PQerrorMessage(conn));
        exit(1);
    }
 
+   /* Start strict; callers may override this. */
    PQclear(executeQuery(conn, ALWAYS_SECURE_SEARCH_PATH_SQL, echo));
 
    return conn;
 
 /*
  * Try to connect to the appropriate maintenance database.
+ *
+ * This differs from connectDatabase only in that it has a rule for
+ * inserting a default "dbname" if none was given (which is why cparams
+ * is not const).  Note that cparams->dbname should typically come from
+ * a --maintenance-db command line parameter.
  */
 PGconn *
-connectMaintenanceDatabase(const char *maintenance_db,
-                          const char *pghost, const char *pgport,
-                          const char *pguser, enum trivalue prompt_password,
+connectMaintenanceDatabase(ConnParams *cparams,
                           const char *progname, bool echo)
 {
    PGconn     *conn;
 
    /* If a maintenance database name was specified, just connect to it. */
-   if (maintenance_db)
-       return connectDatabase(maintenance_db, pghost, pgport, pguser,
-                              prompt_password, progname, echo, false, false);
+   if (cparams->dbname)
+       return connectDatabase(cparams, progname, echo, false, false);
 
    /* Otherwise, try postgres first and then template1. */
-   conn = connectDatabase("postgres", pghost, pgport, pguser, prompt_password,
-                          progname, echo, true, false);
+   cparams->dbname = "postgres";
+   conn = connectDatabase(cparams, progname, echo, true, false);
    if (!conn)
-       conn = connectDatabase("template1", pghost, pgport, pguser,
-                              prompt_password, progname, echo, false, false);
-
+   {
+       cparams->dbname = "template1";
+       conn = connectDatabase(cparams, progname, echo, false, false);
+   }
    return conn;
 }
 
 
    TRI_YES
 };
 
+/* Parameters needed by connectDatabase/connectMaintenanceDatabase */
+typedef struct _connParams
+{
+   /* These fields record the actual command line parameters */
+   const char *dbname;         /* this may be a connstring! */
+   const char *pghost;
+   const char *pgport;
+   const char *pguser;
+   enum trivalue prompt_password;
+   /* If not NULL, this overrides the dbname obtained from command line */
+   /* (but *only* the DB name, not anything else in the connstring) */
+   const char *override_dbname;
+} ConnParams;
+
 typedef void (*help_handler) (const char *progname);
 
 extern void handle_help_version_opts(int argc, char *argv[],
                                     const char *fixed_progname,
                                     help_handler hlp);
 
-extern PGconn *connectDatabase(const char *dbname, const char *pghost,
-                              const char *pgport, const char *pguser,
-                              enum trivalue prompt_password, const char *progname,
-                              bool echo, bool fail_ok, bool allow_password_reuse);
+extern PGconn *connectDatabase(const ConnParams *cparams,
+                              const char *progname,
+                              bool echo, bool fail_ok,
+                              bool allow_password_reuse);
 
-extern PGconn *connectMaintenanceDatabase(const char *maintenance_db,
-                                         const char *pghost, const char *pgport,
-                                         const char *pguser, enum trivalue prompt_password,
+extern PGconn *connectMaintenanceDatabase(ConnParams *cparams,
                                          const char *progname, bool echo);
 
 extern void disconnectDatabase(PGconn *conn);
 
    char       *port = NULL;
    char       *username = NULL;
    enum trivalue prompt_password = TRI_DEFAULT;
+   ConnParams  cparams;
    bool        echo = false;
    char       *owner = NULL;
    char       *tablespace = NULL;
    if (maintenance_db == NULL && strcmp(dbname, "postgres") == 0)
        maintenance_db = "template1";
 
-   conn = connectMaintenanceDatabase(maintenance_db, host, port, username,
-                                     prompt_password, progname, echo);
+   cparams.dbname = maintenance_db;
+   cparams.pghost = host;
+   cparams.pgport = port;
+   cparams.pguser = username;
+   cparams.prompt_password = prompt_password;
+   cparams.override_dbname = NULL;
+
+   conn = connectMaintenanceDatabase(&cparams, progname, echo);
 
    initPQExpBuffer(&sql);
 
 
    char       *username = NULL;
    SimpleStringList roles = {NULL, NULL};
    enum trivalue prompt_password = TRI_DEFAULT;
+   ConnParams  cparams;
    bool        echo = false;
    bool        interactive = false;
    int         conn_limit = -2;    /* less than minimum valid value */
    if (login == 0)
        login = TRI_YES;
 
-   conn = connectDatabase("postgres", host, port, username, prompt_password,
-                          progname, echo, false, false);
+   cparams.dbname = NULL;      /* this program lacks any dbname option... */
+   cparams.pghost = host;
+   cparams.pgport = port;
+   cparams.pguser = username;
+   cparams.prompt_password = prompt_password;
+   cparams.override_dbname = NULL;
+
+   conn = connectMaintenanceDatabase(&cparams, progname, echo);
 
    initPQExpBuffer(&sql);
 
 
    char       *port = NULL;
    char       *username = NULL;
    enum trivalue prompt_password = TRI_DEFAULT;
+   ConnParams  cparams;
    bool        echo = false;
    bool        interactive = false;
    bool        force = false;
    if (maintenance_db == NULL && strcmp(dbname, "postgres") == 0)
        maintenance_db = "template1";
 
-   conn = connectMaintenanceDatabase(maintenance_db,
-                                     host, port, username, prompt_password,
-                                     progname, echo);
+   cparams.dbname = maintenance_db;
+   cparams.pghost = host;
+   cparams.pgport = port;
+   cparams.pguser = username;
+   cparams.prompt_password = prompt_password;
+   cparams.override_dbname = NULL;
+
+   conn = connectMaintenanceDatabase(&cparams, progname, echo);
 
    if (echo)
        printf("%s\n", sql.data);
 
    char       *port = NULL;
    char       *username = NULL;
    enum trivalue prompt_password = TRI_DEFAULT;
+   ConnParams  cparams;
    bool        echo = false;
    bool        interactive = false;
 
            exit(0);
    }
 
+   cparams.dbname = NULL;      /* this program lacks any dbname option... */
+   cparams.pghost = host;
+   cparams.pgport = port;
+   cparams.pguser = username;
+   cparams.prompt_password = prompt_password;
+   cparams.override_dbname = NULL;
+
+   conn = connectMaintenanceDatabase(&cparams, progname, echo);
+
    initPQExpBuffer(&sql);
    appendPQExpBuffer(&sql, "DROP ROLE %s%s;",
                      (if_exists ? "IF EXISTS " : ""), fmtId(dropuser));
 
-   conn = connectDatabase("postgres", host, port, username, prompt_password,
-                          progname, echo, false, false);
-
    if (echo)
        printf("%s\n", sql.data);
    result = PQexec(conn, sql.data);
 
                                                  ReindexType type,
                                                  SimpleStringList *user_list,
                                                  bool echo);
-static void reindex_one_database(const char *dbname, ReindexType type,
-                                SimpleStringList *user_list, const char *host,
-                                const char *port, const char *username,
-                                enum trivalue prompt_password, const char *progname,
+static void reindex_one_database(const ConnParams *cparams, ReindexType type,
+                                SimpleStringList *user_list,
+                                const char *progname,
                                 bool echo, bool verbose, bool concurrently,
                                 int concurrentCons);
-static void reindex_all_databases(const char *maintenance_db,
-                                 const char *host, const char *port,
-                                 const char *username, enum trivalue prompt_password,
+static void reindex_all_databases(ConnParams *cparams,
                                  const char *progname, bool echo,
                                  bool quiet, bool verbose, bool concurrently,
                                  int concurrentCons);
    const char *port = NULL;
    const char *username = NULL;
    enum trivalue prompt_password = TRI_DEFAULT;
+   ConnParams  cparams;
    bool        syscatalog = false;
    bool        alldb = false;
    bool        echo = false;
        exit(1);
    }
 
+   /* fill cparams except for dbname, which is set below */
+   cparams.pghost = host;
+   cparams.pgport = port;
+   cparams.pguser = username;
+   cparams.prompt_password = prompt_password;
+   cparams.override_dbname = NULL;
+
    setup_cancel_handler(NULL);
 
    if (alldb)
            exit(1);
        }
 
-       reindex_all_databases(maintenance_db, host, port, username,
-                             prompt_password, progname, echo, quiet, verbose,
+       cparams.dbname = maintenance_db;
+
+       reindex_all_databases(&cparams, progname, echo, quiet, verbose,
                              concurrently, concurrentCons);
    }
    else if (syscatalog)
                dbname = get_user_name_or_exit(progname);
        }
 
-       reindex_one_database(dbname, REINDEX_SYSTEM, NULL, host,
-                            port, username, prompt_password, progname,
-                            echo, verbose, concurrently, 1);
+       cparams.dbname = dbname;
+
+       reindex_one_database(&cparams, REINDEX_SYSTEM, NULL,
+                            progname, echo, verbose,
+                            concurrently, 1);
    }
    else
    {
                dbname = get_user_name_or_exit(progname);
        }
 
+       cparams.dbname = dbname;
+
        if (schemas.head != NULL)
-           reindex_one_database(dbname, REINDEX_SCHEMA, &schemas, host,
-                                port, username, prompt_password, progname,
-                                echo, verbose, concurrently, concurrentCons);
+           reindex_one_database(&cparams, REINDEX_SCHEMA, &schemas,
+                                progname, echo, verbose,
+                                concurrently, concurrentCons);
 
        if (indexes.head != NULL)
-           reindex_one_database(dbname, REINDEX_INDEX, &indexes, host,
-                                port, username, prompt_password, progname,
-                                echo, verbose, concurrently, 1);
+           reindex_one_database(&cparams, REINDEX_INDEX, &indexes,
+                                progname, echo, verbose,
+                                concurrently, 1);
 
        if (tables.head != NULL)
-           reindex_one_database(dbname, REINDEX_TABLE, &tables, host,
-                                port, username, prompt_password, progname,
-                                echo, verbose, concurrently,
-                                concurrentCons);
+           reindex_one_database(&cparams, REINDEX_TABLE, &tables,
+                                progname, echo, verbose,
+                                concurrently, concurrentCons);
 
        /*
         * reindex database only if neither index nor table nor schema is
         * specified
         */
        if (indexes.head == NULL && tables.head == NULL && schemas.head == NULL)
-           reindex_one_database(dbname, REINDEX_DATABASE, NULL, host,
-                                port, username, prompt_password, progname,
-                                echo, verbose, concurrently, concurrentCons);
+           reindex_one_database(&cparams, REINDEX_DATABASE, NULL,
+                                progname, echo, verbose,
+                                concurrently, concurrentCons);
    }
 
    exit(0);
 }
 
 static void
-reindex_one_database(const char *dbname, ReindexType type,
-                    SimpleStringList *user_list, const char *host,
-                    const char *port, const char *username,
-                    enum trivalue prompt_password, const char *progname, bool echo,
+reindex_one_database(const ConnParams *cparams, ReindexType type,
+                    SimpleStringList *user_list,
+                    const char *progname, bool echo,
                     bool verbose, bool concurrently, int concurrentCons)
 {
    PGconn     *conn;
    bool        failed = false;
    int         items_count = 0;
 
-   conn = connectDatabase(dbname, host, port, username, prompt_password,
-                          progname, echo, false, false);
+   conn = connectDatabase(cparams, progname, echo, false, false);
 
    if (concurrently && PQserverVersion(conn) < 120000)
    {
 
    Assert(process_list != NULL);
 
-   slots = ParallelSlotsSetup(dbname, host, port, username, prompt_password,
-                              progname, echo, conn, concurrentCons);
+   slots = ParallelSlotsSetup(cparams, progname, echo, conn, concurrentCons);
 
    cell = process_list->head;
    do
 }
 
 static void
-reindex_all_databases(const char *maintenance_db,
-                     const char *host, const char *port,
-                     const char *username, enum trivalue prompt_password,
+reindex_all_databases(ConnParams *cparams,
                      const char *progname, bool echo, bool quiet, bool verbose,
                      bool concurrently, int concurrentCons)
 {
    PGconn     *conn;
    PGresult   *result;
-   PQExpBufferData connstr;
    int         i;
 
-   conn = connectMaintenanceDatabase(maintenance_db, host, port, username,
-                                     prompt_password, progname, echo);
+   conn = connectMaintenanceDatabase(cparams, progname, echo);
    result = executeQuery(conn, "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;", echo);
    PQfinish(conn);
 
-   initPQExpBuffer(&connstr);
    for (i = 0; i < PQntuples(result); i++)
    {
        char       *dbname = PQgetvalue(result, i, 0);
            fflush(stdout);
        }
 
-       resetPQExpBuffer(&connstr);
-       appendPQExpBufferStr(&connstr, "dbname=");
-       appendConnStrVal(&connstr, dbname);
+       cparams->override_dbname = dbname;
 
-       reindex_one_database(connstr.data, REINDEX_DATABASE, NULL, host,
-                            port, username, prompt_password,
+       reindex_one_database(cparams, REINDEX_DATABASE, NULL,
                             progname, echo, verbose, concurrently,
                             concurrentCons);
    }
-   termPQExpBuffer(&connstr);
 
    PQclear(result);
 }
 
  * set.
  */
 ParallelSlot *
-ParallelSlotsSetup(const char *dbname, const char *host, const char *port,
-                  const char *username, bool prompt_password,
+ParallelSlotsSetup(const ConnParams *cparams,
                   const char *progname, bool echo,
                   PGconn *conn, int numslots)
 {
    {
        for (i = 1; i < numslots; i++)
        {
-           conn = connectDatabase(dbname, host, port, username, prompt_password,
-                                  progname, echo, false, true);
+           conn = connectDatabase(cparams, progname, echo, false, true);
 
            /*
             * Fail and exit immediately if trying to use a socket in an
 
 #ifndef SCRIPTS_PARALLEL_H
 #define SCRIPTS_PARALLEL_H
 
+#include "common.h"
 #include "libpq-fe.h"
 
 
 
 extern ParallelSlot *ParallelSlotsGetIdle(ParallelSlot *slots, int numslots);
 
-extern ParallelSlot *ParallelSlotsSetup(const char *dbname, const char *host,
-                                       const char *port,
-                                       const char *username,
-                                       bool prompt_password,
+extern ParallelSlot *ParallelSlotsSetup(const ConnParams *cparams,
                                        const char *progname, bool echo,
                                        PGconn *conn, int numslots);
 
 
 } vacuumingOptions;
 
 
-static void vacuum_one_database(const char *dbname, vacuumingOptions *vacopts,
+static void vacuum_one_database(const ConnParams *cparams,
+                               vacuumingOptions *vacopts,
                                int stage,
                                SimpleStringList *tables,
-                               const char *host, const char *port,
-                               const char *username, enum trivalue prompt_password,
                                int concurrentCons,
                                const char *progname, bool echo, bool quiet);
 
-static void vacuum_all_databases(vacuumingOptions *vacopts,
+static void vacuum_all_databases(ConnParams *cparams,
+                                vacuumingOptions *vacopts,
                                 bool analyze_in_stages,
-                                const char *maintenance_db,
-                                const char *host, const char *port,
-                                const char *username, enum trivalue prompt_password,
                                 int concurrentCons,
                                 const char *progname, bool echo, bool quiet);
 
    char       *port = NULL;
    char       *username = NULL;
    enum trivalue prompt_password = TRI_DEFAULT;
+   ConnParams  cparams;
    bool        echo = false;
    bool        quiet = false;
    vacuumingOptions vacopts;
        }
    }
 
+   /* fill cparams except for dbname, which is set below */
+   cparams.pghost = host;
+   cparams.pgport = port;
+   cparams.pguser = username;
+   cparams.prompt_password = prompt_password;
+   cparams.override_dbname = NULL;
+
    setup_cancel_handler(NULL);
 
    /* Avoid opening extra connections. */
            exit(1);
        }
 
-       vacuum_all_databases(&vacopts,
+       cparams.dbname = maintenance_db;
+
+       vacuum_all_databases(&cparams, &vacopts,
                             analyze_in_stages,
-                            maintenance_db,
-                            host, port, username, prompt_password,
                             concurrentCons,
                             progname, echo, quiet);
    }
                dbname = get_user_name_or_exit(progname);
        }
 
+       cparams.dbname = dbname;
+
        if (analyze_in_stages)
        {
            int         stage;
 
            for (stage = 0; stage < ANALYZE_NUM_STAGES; stage++)
            {
-               vacuum_one_database(dbname, &vacopts,
+               vacuum_one_database(&cparams, &vacopts,
                                    stage,
                                    &tables,
-                                   host, port, username, prompt_password,
                                    concurrentCons,
                                    progname, echo, quiet);
            }
        }
        else
-           vacuum_one_database(dbname, &vacopts,
+           vacuum_one_database(&cparams, &vacopts,
                                ANALYZE_NO_STAGE,
                                &tables,
-                               host, port, username, prompt_password,
                                concurrentCons,
                                progname, echo, quiet);
    }
  * a list of tables from the database.
  */
 static void
-vacuum_one_database(const char *dbname, vacuumingOptions *vacopts,
+vacuum_one_database(const ConnParams *cparams,
+                   vacuumingOptions *vacopts,
                    int stage,
                    SimpleStringList *tables,
-                   const char *host, const char *port,
-                   const char *username, enum trivalue prompt_password,
                    int concurrentCons,
                    const char *progname, bool echo, bool quiet)
 {
    Assert(stage == ANALYZE_NO_STAGE ||
           (stage >= 0 && stage < ANALYZE_NUM_STAGES));
 
-   conn = connectDatabase(dbname, host, port, username, prompt_password,
-                          progname, echo, false, true);
+   conn = connectDatabase(cparams, progname, echo, false, true);
 
    if (vacopts->disable_page_skipping && PQserverVersion(conn) < 90600)
    {
     * for the first slot.  If not in parallel mode, the first slot in the
     * array contains the connection.
     */
-   slots = ParallelSlotsSetup(dbname, host, port, username, prompt_password,
-                              progname, echo, conn, concurrentCons);
+   slots = ParallelSlotsSetup(cparams, progname, echo, conn, concurrentCons);
 
    /*
     * Prepare all the connections to run the appropriate analyze stage, if
  * quickly everywhere before generating more detailed ones.
  */
 static void
-vacuum_all_databases(vacuumingOptions *vacopts,
+vacuum_all_databases(ConnParams *cparams,
+                    vacuumingOptions *vacopts,
                     bool analyze_in_stages,
-                    const char *maintenance_db, const char *host,
-                    const char *port, const char *username,
-                    enum trivalue prompt_password,
                     int concurrentCons,
                     const char *progname, bool echo, bool quiet)
 {
    PGconn     *conn;
    PGresult   *result;
-   PQExpBufferData connstr;
    int         stage;
    int         i;
 
-   conn = connectMaintenanceDatabase(maintenance_db, host, port, username,
-                                     prompt_password, progname, echo);
+   conn = connectMaintenanceDatabase(cparams, progname, echo);
    result = executeQuery(conn,
                          "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;",
                          echo);
    PQfinish(conn);
 
-   initPQExpBuffer(&connstr);
    if (analyze_in_stages)
    {
        /*
        {
            for (i = 0; i < PQntuples(result); i++)
            {
-               resetPQExpBuffer(&connstr);
-               appendPQExpBufferStr(&connstr, "dbname=");
-               appendConnStrVal(&connstr, PQgetvalue(result, i, 0));
+               cparams->override_dbname = PQgetvalue(result, i, 0);
 
-               vacuum_one_database(connstr.data, vacopts,
+               vacuum_one_database(cparams, vacopts,
                                    stage,
                                    NULL,
-                                   host, port, username, prompt_password,
                                    concurrentCons,
                                    progname, echo, quiet);
            }
    {
        for (i = 0; i < PQntuples(result); i++)
        {
-           resetPQExpBuffer(&connstr);
-           appendPQExpBufferStr(&connstr, "dbname=");
-           appendConnStrVal(&connstr, PQgetvalue(result, i, 0));
+           cparams->override_dbname = PQgetvalue(result, i, 0);
 
-           vacuum_one_database(connstr.data, vacopts,
+           vacuum_one_database(cparams, vacopts,
                                ANALYZE_NO_STAGE,
                                NULL,
-                               host, port, username, prompt_password,
                                concurrentCons,
                                progname, echo, quiet);
        }
    }
-   termPQExpBuffer(&connstr);
 
    PQclear(result);
 }