Make command-line tools smarter about finding a DB to connect to.
authorRobert Haas <[email protected]>
Tue, 6 Dec 2011 13:48:15 +0000 (08:48 -0500)
committerRobert Haas <[email protected]>
Tue, 6 Dec 2011 13:48:15 +0000 (08:48 -0500)
If unable to connect to "postgres", try "template1".  This allows things to
work more smoothly in the case where the postgres database has been
dropped.  And just in case that's not good enough, also allow the user to
specify a maintenance database to be used for the initial connection, to
cover the case where neither postgres nor template1 is suitable.

16 files changed:
doc/src/sgml/ref/clusterdb.sgml
doc/src/sgml/ref/createdb.sgml
doc/src/sgml/ref/dropdb.sgml
doc/src/sgml/ref/reindexdb.sgml
doc/src/sgml/ref/vacuumdb.sgml
src/bin/scripts/clusterdb.c
src/bin/scripts/common.c
src/bin/scripts/common.h
src/bin/scripts/createdb.c
src/bin/scripts/createlang.c
src/bin/scripts/createuser.c
src/bin/scripts/dropdb.c
src/bin/scripts/droplang.c
src/bin/scripts/dropuser.c
src/bin/scripts/reindexdb.c
src/bin/scripts/vacuumdb.c

index c80cbac5173eb2b90b38740f89c953684314c5b2..1573145b9234a0962dc5ec141186b21dbc09cd89 100644 (file)
@@ -229,6 +229,18 @@ PostgreSQL documentation
        </para>
       </listitem>
      </varlistentry>
+
+     <varlistentry>
+      <term><option>--maintenance-db=<replaceable class="parameter">dbname</replaceable></></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.
+       </para>
+      </listitem>
+     </varlistentry>
     </variablelist>
    </para>
  </refsect1>
index 1516f3396d6e2dc03890f8f01abd80417c6cf546..cbbc5c05455371a5e0efeb7bc2ef190b45d4c08f 100644 (file)
@@ -276,6 +276,19 @@ PostgreSQL documentation
        </para>
       </listitem>
      </varlistentry>
+
+     <varlistentry>
+      <term><option>--maintenance-db=<replaceable class="parameter">dbname</replaceable></></term>
+      <listitem>
+       <para>
+         Specifies the name of the database to connect to when creating the
+         new database. If not specified, the <literal>postgres</literal>
+         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.
+       </para>
+      </listitem>
+     </varlistentry>
     </variablelist>
    </para>
 
index aedfa580751babc774439bafd855c5743cb55937..ba781cce52b5bd05918ce1021add76617e6b3321 100644 (file)
@@ -196,6 +196,18 @@ PostgreSQL documentation
        </para>
       </listitem>
      </varlistentry>
+
+     <varlistentry>
+      <term><option>--maintenance-db=<replaceable class="parameter">dbname</replaceable></></term>
+      <listitem>
+       <para>
+         Specifies the name of the database to connect to in order to drop the
+         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.
+       </para>
+      </listitem>
+     </varlistentry>
    </variablelist>
   </para>
  </refsect1>
index 7b0263c5a1c27cb95e0d119fc10833db9ed02d83..9caaa952668642912d26deca7390d76944250939 100644 (file)
@@ -243,6 +243,18 @@ PostgreSQL documentation
        </para>
       </listitem>
      </varlistentry>
+
+     <varlistentry>
+      <term><option>--maintenance-db=<replaceable class="parameter">dbname</replaceable></></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.
+       </para>
+      </listitem>
+     </varlistentry>
     </variablelist>
    </para>
  </refsect1>
index 4effa4188a610412dd74aaa110054d516f491b14..89d634747dd1cfb8dc93473806a856f49d995ec0 100644 (file)
@@ -284,6 +284,18 @@ PostgreSQL documentation
        </para>
       </listitem>
      </varlistentry>
+
+     <varlistentry>
+      <term><option>--maintenance-db=<replaceable class="parameter">dbname</replaceable></></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.
+       </para>
+      </listitem>
+     </varlistentry>
     </variablelist>
    </para>
  </refsect1>
index 3742091e2a4d2741ff78d0885a70510fd71a8295..fc88692b4e345c27fcd706a3233172cbbd75c0ba 100644 (file)
@@ -18,7 +18,8 @@ static void cluster_one_database(const char *dbname, bool verbose, const char *t
                     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 *host, const char *port,
+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);
 
@@ -40,6 +41,7 @@ main(int argc, char *argv[])
        {"all", no_argument, NULL, 'a'},
        {"table", required_argument, NULL, 't'},
        {"verbose", no_argument, NULL, 'v'},
+       {"maintenance-db", required_argument, NULL, 2},
        {NULL, 0, NULL, 0}
    };
 
@@ -48,6 +50,7 @@ main(int argc, char *argv[])
    int         c;
 
    const char *dbname = NULL;
+   const char *maintenance_db = NULL;
    char       *host = NULL;
    char       *port = NULL;
    char       *username = NULL;
@@ -100,6 +103,9 @@ main(int argc, char *argv[])
            case 'v':
                verbose = true;
                break;
+           case 2:
+               maintenance_db = optarg;
+               break;
            default:
                fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
                exit(1);
@@ -137,7 +143,7 @@ main(int argc, char *argv[])
            exit(1);
        }
 
-       cluster_all_databases(verbose, host, port, username, prompt_password,
+       cluster_all_databases(verbose, maintenance_db, host, port, username, prompt_password,
                              progname, echo, quiet);
    }
    else
@@ -180,7 +186,8 @@ cluster_one_database(const char *dbname, bool verbose, const char *table,
        appendPQExpBuffer(&sql, " %s", table);
    appendPQExpBuffer(&sql, ";\n");
 
-   conn = connectDatabase(dbname, host, port, username, prompt_password, progname);
+   conn = connectDatabase(dbname, host, port, username, prompt_password,
+                          progname, false);
    if (!executeMaintenanceCommand(conn, sql.data, echo))
    {
        if (table)
@@ -198,7 +205,8 @@ cluster_one_database(const char *dbname, bool verbose, const char *table,
 
 
 static void
-cluster_all_databases(bool verbose, const char *host, const char *port,
+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)
 {
@@ -206,7 +214,8 @@ cluster_all_databases(bool verbose, const char *host, const char *port,
    PGresult   *result;
    int         i;
 
-   conn = connectDatabase("postgres", host, port, username, prompt_password, progname);
+   conn = connectMaintenanceDatabase(maintenance_db, host, port, username,
+                                     prompt_password, progname);
    result = executeQuery(conn, "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;", progname, echo);
    PQfinish(conn);
 
@@ -250,6 +259,7 @@ help(const char *progname)
    printf(_("  -U, --username=USERNAME   user name to connect as\n"));
    printf(_("  -w, --no-password         never prompt for password\n"));
    printf(_("  -W, --password            force password prompt\n"));
+   printf(_("  --maintenance-db=DBNAME   alternate maintenance database\n"));
    printf(_("\nRead the description of the SQL command CLUSTER for details.\n"));
    printf(_("\nReport bugs to <[email protected]>.\n"));
 }
index 9a7cc2c264cc6b31c7f232ecbe402ce63b3fe398..99be4ae83aecf643f4377a9d5d9cc48ea36761f4 100644 (file)
@@ -93,7 +93,7 @@ handle_help_version_opts(int argc, char *argv[],
 PGconn *
 connectDatabase(const char *dbname, const char *pghost, const char *pgport,
                const char *pguser, enum trivalue prompt_password,
-               const char *progname)
+               const char *progname, bool fail_ok)
 {
    PGconn     *conn;
    char       *password = NULL;
@@ -163,6 +163,11 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport,
    /* check to see that the backend connection was successfully made */
    if (PQstatus(conn) == CONNECTION_BAD)
    {
+       if (fail_ok)
+       {
+           PQfinish(conn);
+           return NULL;
+       }
        fprintf(stderr, _("%s: could not connect to database %s: %s"),
                progname, dbname, PQerrorMessage(conn));
        exit(1);
@@ -171,6 +176,41 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport,
    return conn;
 }
 
+/*
+ * Try to connect to the appropriate maintenance database.
+ */
+PGconn *
+connectMaintenanceDatabase(const char *maintenance_db, const char *pghost,
+                          const char *pgport, const char *pguser,
+                          enum trivalue prompt_password,
+                          const char *progname)
+{
+   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, false);
+
+   /* Otherwise, try postgres first and then template1. */
+   conn = connectDatabase("postgres", pghost, pgport, pguser, prompt_password,
+                          progname, true);
+   if (!conn)
+       conn = connectDatabase("template1", pghost, pgport, pguser,
+                              prompt_password, progname, true);
+
+   if (!conn)
+   {
+       fprintf(stderr, _("%s: could not connect to databases \"postgres\" or \"template1\"\n"
+                         "Please specify an alternative maintenance database.\n"),
+               progname);
+       fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
+               progname);
+       exit(1);
+   }
+
+   return conn;
+}
 
 /*
  * Run a query, return the results, exit program on failure.
index caa9e81f457f31b1a7a46cb46d2075a822352b70..9ebd72873d4040d71dc999f0d2ecde09042a2d17 100644 (file)
@@ -30,6 +30,11 @@ extern void handle_help_version_opts(int argc, char *argv[],
 
 extern PGconn *connectDatabase(const char *dbname, const char *pghost,
                const char *pgport, const char *pguser,
+               enum trivalue prompt_password, const char *progname,
+               bool fail_ok);
+
+extern PGconn *connectMaintenanceDatabase(const char *maintenance_db,
+               const char *pghost, const char *pgport, const char *pguser,
                enum trivalue prompt_password, const char *progname);
 
 extern PGresult *executeQuery(PGconn *conn, const char *query,
index d7c3928eb6e23135653d4905150a842378895e77..64105412589e145f2305c8144911789dc90e39b1 100644 (file)
@@ -35,6 +35,7 @@ main(int argc, char *argv[])
        {"lc-collate", required_argument, NULL, 1},
        {"lc-ctype", required_argument, NULL, 2},
        {"locale", required_argument, NULL, 'l'},
+       {"maintenance-db", required_argument, NULL, 3},
        {NULL, 0, NULL, 0}
    };
 
@@ -43,6 +44,7 @@ main(int argc, char *argv[])
    int         c;
 
    const char *dbname = NULL;
+   const char *maintenance_db = NULL;
    char       *comment = NULL;
    char       *host = NULL;
    char       *port = NULL;
@@ -110,6 +112,9 @@ main(int argc, char *argv[])
            case 'l':
                locale = optarg;
                break;
+           case 3:
+               maintenance_db = optarg;
+               break;
            default:
                fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
                exit(1);
@@ -192,13 +197,12 @@ main(int argc, char *argv[])
 
    appendPQExpBuffer(&sql, ";\n");
 
-   /*
-    * Connect to the 'postgres' database by default, except have the
-    * 'postgres' user use 'template1' so he can create the 'postgres'
-    * database.
-    */
-   conn = connectDatabase(strcmp(dbname, "postgres") == 0 ? "template1" : "postgres",
-                          host, port, username, prompt_password, progname);
+   /* No point in trying to use postgres db when creating postgres db. */
+   if (maintenance_db == NULL && strcmp(dbname, "postgres") == 0)
+       maintenance_db = "template1";
+
+   conn = connectMaintenanceDatabase(maintenance_db, host, port, username,
+                                     prompt_password, progname);
 
    if (echo)
        printf("%s", sql.data);
@@ -264,6 +268,7 @@ help(const char *progname)
    printf(_("  -U, --username=USERNAME      user name to connect as\n"));
    printf(_("  -w, --no-password            never prompt for password\n"));
    printf(_("  -W, --password               force password prompt\n"));
+   printf(_("  --maintenance-db=DBNAME      alternate maintenance database\n"));
    printf(_("\nBy default, a database with the same name as the current user is created.\n"));
    printf(_("\nReport bugs to <[email protected]>.\n"));
 }
index 2f667e864a573e3cf01edc350b56ad3399e8e736..a0720de33956a8e6fe95edcca5e10f7a77e88553 100644 (file)
@@ -132,7 +132,7 @@ main(int argc, char *argv[])
        static const bool translate_columns[] = {false, true};
 
        conn = connectDatabase(dbname, host, port, username, prompt_password,
-                              progname);
+                              progname, false);
 
        printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", "
                "(CASE WHEN lanpltrusted THEN '%s' ELSE '%s' END) as \"%s\" "
@@ -169,7 +169,8 @@ main(int argc, char *argv[])
        if (*p >= 'A' && *p <= 'Z')
            *p += ('a' - 'A');
 
-   conn = connectDatabase(dbname, host, port, username, prompt_password, progname);
+   conn = connectDatabase(dbname, host, port, username, prompt_password,
+                          progname, false);
 
    /*
     * Make sure the language isn't already installed
index d6e05dd793994b05df24a193daf75e4777df2b11..4ed400a2bd6f3a85e674854c6081b362e1830d80 100644 (file)
@@ -230,7 +230,8 @@ main(int argc, char *argv[])
    if (login == 0)
        login = TRI_YES;
 
-   conn = connectDatabase("postgres", host, port, username, prompt_password, progname);
+   conn = connectDatabase("postgres", host, port, username, prompt_password,
+                          progname, false);
 
    initPQExpBuffer(&sql);
 
index 0e6749efec0e2e1f23dcc5a1a5fb3d2882d58e50..621c0aecc03874293f9f73ef2b0d4dc7f37f9ecd 100644 (file)
@@ -32,6 +32,7 @@ main(int argc, char *argv[])
        {"echo", no_argument, NULL, 'e'},
        {"interactive", no_argument, NULL, 'i'},
        {"if-exists", no_argument, &if_exists, 1},
+       {"maintenance-db", required_argument, NULL, 2},
        {NULL, 0, NULL, 0}
    };
 
@@ -40,6 +41,7 @@ main(int argc, char *argv[])
    int         c;
 
    char       *dbname = NULL;
+   char       *maintenance_db = NULL;
    char       *host = NULL;
    char       *port = NULL;
    char       *username = NULL;
@@ -85,6 +87,9 @@ main(int argc, char *argv[])
            case 0:
                /* this covers the long options */
                break;
+           case 2:
+               maintenance_db = optarg;
+               break;
            default:
                fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
                exit(1);
@@ -119,11 +124,11 @@ main(int argc, char *argv[])
    appendPQExpBuffer(&sql, "DROP DATABASE %s%s;\n",
                      (if_exists ? "IF EXISTS " : ""), fmtId(dbname));
 
-   /*
-    * Connect to the 'postgres' database by default, except have the
-    * 'postgres' user use 'template1' so he can drop the 'postgres' database.
-    */
-   conn = connectDatabase(strcmp(dbname, "postgres") == 0 ? "template1" : "postgres",
+   /* Avoid trying to drop postgres db while we are connected to it. */
+   if (maintenance_db == NULL && strcmp(dbname, "postgres") == 0)
+       maintenance_db = "template1";
+
+   conn = connectMaintenanceDatabase(maintenance_db,
                           host, port, username, prompt_password, progname);
 
    if (echo)
@@ -161,5 +166,6 @@ help(const char *progname)
    printf(_("  -U, --username=USERNAME   user name to connect as\n"));
    printf(_("  -w, --no-password         never prompt for password\n"));
    printf(_("  -W, --password            force password prompt\n"));
+   printf(_("  --maintenance-db=DBNAME   alternate maintenance database\n"));
    printf(_("\nReport bugs to <[email protected]>.\n"));
 }
index f136a760ff052f1ce17cc2507535de4d126dadf8..d04b4dd9733a4ab43381fd5656ec466b93dad2af 100644 (file)
@@ -131,7 +131,7 @@ main(int argc, char *argv[])
        static const bool translate_columns[] = {false, true};
 
        conn = connectDatabase(dbname, host, port, username, prompt_password,
-                              progname);
+                              progname, false);
 
        printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", "
                "(CASE WHEN lanpltrusted THEN '%s' ELSE '%s' END) as \"%s\" "
@@ -170,7 +170,8 @@ main(int argc, char *argv[])
        if (*p >= 'A' && *p <= 'Z')
            *p += ('a' - 'A');
 
-   conn = connectDatabase(dbname, host, port, username, prompt_password, progname);
+   conn = connectDatabase(dbname, host, port, username, prompt_password,
+                          progname, false);
 
    /*
     * Force schema search path to be just pg_catalog, so that we don't have
index bfd5b1cfd5a551c482758505331dc82c537447ba..f67fb0bcb8faa6f35deee2364acd3bd56cd68746 100644 (file)
@@ -119,7 +119,8 @@ main(int argc, char *argv[])
    appendPQExpBuffer(&sql, "DROP ROLE %s%s;\n",
                      (if_exists ? "IF EXISTS " : ""), fmtId(dropuser));
 
-   conn = connectDatabase("postgres", host, port, username, prompt_password, progname);
+   conn = connectDatabase("postgres", host, port, username, prompt_password,
+                          progname, false);
 
    if (echo)
        printf("%s", sql.data);
index caeed7511ee25dd7a52d1cce0409677fe33c3982..9ff15d85d62e8b84cb1b034f966f2c67eef2a1c7 100644 (file)
@@ -19,7 +19,8 @@ static void reindex_one_database(const char *name, const char *dbname,
                     const char *port, const char *username,
                     enum trivalue prompt_password, const char *progname,
                     bool echo);
-static void reindex_all_databases(const char *host, const char *port,
+static void reindex_all_databases(const char *maintenance_db,
+                     const char *host, const char *port,
                      const char *username, enum trivalue prompt_password,
                      const char *progname, bool echo,
                      bool quiet);
@@ -45,6 +46,7 @@ main(int argc, char *argv[])
        {"system", no_argument, NULL, 's'},
        {"table", required_argument, NULL, 't'},
        {"index", required_argument, NULL, 'i'},
+       {"maintenance-db", required_argument, NULL, 2},
        {NULL, 0, NULL, 0}
    };
 
@@ -53,6 +55,7 @@ main(int argc, char *argv[])
    int         c;
 
    const char *dbname = NULL;
+   const char *maintenance_db = NULL;
    const char *host = NULL;
    const char *port = NULL;
    const char *username = NULL;
@@ -110,6 +113,9 @@ main(int argc, char *argv[])
            case 'i':
                index = optarg;
                break;
+           case 2:
+               maintenance_db = optarg;
+               break;
            default:
                fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
                exit(1);
@@ -154,8 +160,8 @@ main(int argc, char *argv[])
            exit(1);
        }
 
-       reindex_all_databases(host, port, username, prompt_password,
-                             progname, echo, quiet);
+       reindex_all_databases(maintenance_db, host, port, username,
+                             prompt_password, progname, echo, quiet);
    }
    else if (syscatalog)
    {
@@ -230,7 +236,8 @@ reindex_one_database(const char *name, const char *dbname, const char *type,
        appendPQExpBuffer(&sql, " DATABASE %s", fmtId(name));
    appendPQExpBuffer(&sql, ";\n");
 
-   conn = connectDatabase(dbname, host, port, username, prompt_password, progname);
+   conn = connectDatabase(dbname, host, port, username, prompt_password,
+                          progname, false);
 
    if (!executeMaintenanceCommand(conn, sql.data, echo))
    {
@@ -252,7 +259,8 @@ reindex_one_database(const char *name, const char *dbname, const char *type,
 }
 
 static void
-reindex_all_databases(const char *host, const char *port,
+reindex_all_databases(const char *maintenance_db,
+                     const char *host, const char *port,
                      const char *username, enum trivalue prompt_password,
                      const char *progname, bool echo, bool quiet)
 {
@@ -260,7 +268,8 @@ reindex_all_databases(const char *host, const char *port,
    PGresult   *result;
    int         i;
 
-   conn = connectDatabase("postgres", host, port, username, prompt_password, progname);
+   conn = connectMaintenanceDatabase(maintenance_db, host, port, username,
+                                     prompt_password, progname);
    result = executeQuery(conn, "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;", progname, echo);
    PQfinish(conn);
 
@@ -294,7 +303,8 @@ reindex_system_catalogs(const char *dbname, const char *host, const char *port,
 
    appendPQExpBuffer(&sql, "REINDEX SYSTEM %s;\n", dbname);
 
-   conn = connectDatabase(dbname, host, port, username, prompt_password, progname);
+   conn = connectDatabase(dbname, host, port, username, prompt_password,
+                          progname, false);
    if (!executeMaintenanceCommand(conn, sql.data, echo))
    {
        fprintf(stderr, _("%s: reindexing of system catalogs failed: %s"),
@@ -328,6 +338,7 @@ help(const char *progname)
    printf(_("  -U, --username=USERNAME   user name to connect as\n"));
    printf(_("  -w, --no-password         never prompt for password\n"));
    printf(_("  -W, --password            force password prompt\n"));
+   printf(_("  --maintenance-db=DBNAME   alternate maintenance database\n"));
    printf(_("\nRead the description of the SQL command REINDEX for details.\n"));
    printf(_("\nReport bugs to <[email protected]>.\n"));
 }
index 7457e6d3046cd256fbf0b81448afc73e7f9059db..a82e10a2a2777c7649f9c5b0eba8e7fd372d70de 100644 (file)
@@ -21,6 +21,7 @@ static void vacuum_one_database(const char *dbname, bool full, bool verbose,
                    const char *progname, bool echo);
 static void vacuum_all_databases(bool full, bool verbose, bool and_analyze,
                     bool analyze_only, bool freeze,
+                    const char *maintenance_db,
                     const char *host, const char *port,
                     const char *username, enum trivalue prompt_password,
                     const char *progname, bool echo, bool quiet);
@@ -47,6 +48,7 @@ main(int argc, char *argv[])
        {"table", required_argument, NULL, 't'},
        {"full", no_argument, NULL, 'f'},
        {"verbose", no_argument, NULL, 'v'},
+       {"maintenance-db", required_argument, NULL, 2},
        {NULL, 0, NULL, 0}
    };
 
@@ -55,6 +57,7 @@ main(int argc, char *argv[])
    int         c;
 
    const char *dbname = NULL;
+   const char *maintenance_db = NULL;
    char       *host = NULL;
    char       *port = NULL;
    char       *username = NULL;
@@ -123,6 +126,9 @@ main(int argc, char *argv[])
            case 'v':
                verbose = true;
                break;
+           case 2:
+               maintenance_db = optarg;
+               break;
            default:
                fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
                exit(1);
@@ -178,8 +184,8 @@ main(int argc, char *argv[])
        }
 
        vacuum_all_databases(full, verbose, and_analyze, analyze_only, freeze,
-                            host, port, username, prompt_password,
-                            progname, echo, quiet);
+                            maintenance_db, host, port, username,
+                            prompt_password, progname, echo, quiet);
    }
    else
    {
@@ -216,7 +222,8 @@ vacuum_one_database(const char *dbname, bool full, bool verbose, bool and_analyz
 
    initPQExpBuffer(&sql);
 
-   conn = connectDatabase(dbname, host, port, username, prompt_password, progname);
+   conn = connectDatabase(dbname, host, port, username, prompt_password,
+                          progname, false);
 
    if (analyze_only)
    {
@@ -290,7 +297,8 @@ vacuum_one_database(const char *dbname, bool full, bool verbose, bool and_analyz
 
 static void
 vacuum_all_databases(bool full, bool verbose, bool and_analyze, bool analyze_only,
-                    bool freeze, const char *host, const char *port,
+                    bool freeze, const char *maintenance_db,
+                    const char *host, const char *port,
                     const char *username, enum trivalue prompt_password,
                     const char *progname, bool echo, bool quiet)
 {
@@ -298,7 +306,8 @@ vacuum_all_databases(bool full, bool verbose, bool and_analyze, bool analyze_onl
    PGresult   *result;
    int         i;
 
-   conn = connectDatabase("postgres", host, port, username, prompt_password, progname);
+   conn = connectMaintenanceDatabase(maintenance_db, host, port,
+                          username, prompt_password, progname);
    result = executeQuery(conn, "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;", progname, echo);
    PQfinish(conn);
 
@@ -346,6 +355,7 @@ help(const char *progname)
    printf(_("  -U, --username=USERNAME   user name to connect as\n"));
    printf(_("  -w, --no-password         never prompt for password\n"));
    printf(_("  -W, --password            force password prompt\n"));
+   printf(_("  --maintenance-db=DBNAME   alternate maintenance database\n"));
    printf(_("\nRead the description of the SQL command VACUUM for details.\n"));
    printf(_("\nReport bugs to <[email protected]>.\n"));
 }