diff --git a/doc/src/sgml/ref/clusterdb.sgml b/doc/src/sgml/ref/clusterdb.sgml
index c80cbac517..1573145b92 100644
--- a/doc/src/sgml/ref/clusterdb.sgml
+++ b/doc/src/sgml/ref/clusterdb.sgml
@@ -229,6 +229,18 @@ PostgreSQL documentation
+
+
+
+
+
+ Specifies the name of the database to connect to discover what other
+ databases should be clustered. If not specified, the
+ postgres database will be used,
+ and if that does not exist, template1 will be used.
+
+
+
diff --git a/doc/src/sgml/ref/createdb.sgml b/doc/src/sgml/ref/createdb.sgml
index 1516f3396d..cbbc5c0545 100644
--- a/doc/src/sgml/ref/createdb.sgml
+++ b/doc/src/sgml/ref/createdb.sgml
@@ -276,6 +276,19 @@ PostgreSQL documentation
+
+
+
+
+
+ Specifies the name of the database to connect to when creating the
+ new database. If not specified, the postgres
+ database will be used; if that does not exist (or if it is the name
+ of the new database being created), template1 will
+ be used.
+
+
+
diff --git a/doc/src/sgml/ref/dropdb.sgml b/doc/src/sgml/ref/dropdb.sgml
index aedfa58075..ba781cce52 100644
--- a/doc/src/sgml/ref/dropdb.sgml
+++ b/doc/src/sgml/ref/dropdb.sgml
@@ -196,6 +196,18 @@ PostgreSQL documentation
+
+
+
+
+
+ Specifies the name of the database to connect to in order to drop the
+ target database. If not specified, the postgres
+ database will be used; if that does not exist (or is the database
+ being dropped), template1 will be used.
+
+
+
diff --git a/doc/src/sgml/ref/reindexdb.sgml b/doc/src/sgml/ref/reindexdb.sgml
index 7b0263c5a1..9caaa95266 100644
--- a/doc/src/sgml/ref/reindexdb.sgml
+++ b/doc/src/sgml/ref/reindexdb.sgml
@@ -243,6 +243,18 @@ PostgreSQL documentation
+
+
+
+
+
+ Specifies the name of the database to connect to discover what other
+ databases should be vacuumed. If not specified, the
+ postgres database will be used,
+ and if that does not exist, template1 will be used.
+
+
+
diff --git a/doc/src/sgml/ref/vacuumdb.sgml b/doc/src/sgml/ref/vacuumdb.sgml
index 4effa4188a..89d634747d 100644
--- a/doc/src/sgml/ref/vacuumdb.sgml
+++ b/doc/src/sgml/ref/vacuumdb.sgml
@@ -284,6 +284,18 @@ PostgreSQL documentation
+
+
+
+
+
+ Specifies the name of the database to connect to discover what other
+ databases should be vacuumed. If not specified, the
+ postgres database will be used,
+ and if that does not exist, template1 will be used.
+
+
+
diff --git a/src/bin/scripts/clusterdb.c b/src/bin/scripts/clusterdb.c
index 3742091e2a..fc88692b4e 100644
--- a/src/bin/scripts/clusterdb.c
+++ b/src/bin/scripts/clusterdb.c
@@ -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 .\n"));
}
diff --git a/src/bin/scripts/common.c b/src/bin/scripts/common.c
index 9a7cc2c264..99be4ae83a 100644
--- a/src/bin/scripts/common.c
+++ b/src/bin/scripts/common.c
@@ -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.
diff --git a/src/bin/scripts/common.h b/src/bin/scripts/common.h
index caa9e81f45..9ebd72873d 100644
--- a/src/bin/scripts/common.h
+++ b/src/bin/scripts/common.h
@@ -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,
diff --git a/src/bin/scripts/createdb.c b/src/bin/scripts/createdb.c
index d7c3928eb6..6410541258 100644
--- a/src/bin/scripts/createdb.c
+++ b/src/bin/scripts/createdb.c
@@ -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 .\n"));
}
diff --git a/src/bin/scripts/createlang.c b/src/bin/scripts/createlang.c
index 2f667e864a..a0720de339 100644
--- a/src/bin/scripts/createlang.c
+++ b/src/bin/scripts/createlang.c
@@ -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
diff --git a/src/bin/scripts/createuser.c b/src/bin/scripts/createuser.c
index d6e05dd793..4ed400a2bd 100644
--- a/src/bin/scripts/createuser.c
+++ b/src/bin/scripts/createuser.c
@@ -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);
diff --git a/src/bin/scripts/dropdb.c b/src/bin/scripts/dropdb.c
index 0e6749efec..621c0aecc0 100644
--- a/src/bin/scripts/dropdb.c
+++ b/src/bin/scripts/dropdb.c
@@ -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 .\n"));
}
diff --git a/src/bin/scripts/droplang.c b/src/bin/scripts/droplang.c
index f136a760ff..d04b4dd973 100644
--- a/src/bin/scripts/droplang.c
+++ b/src/bin/scripts/droplang.c
@@ -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
diff --git a/src/bin/scripts/dropuser.c b/src/bin/scripts/dropuser.c
index bfd5b1cfd5..f67fb0bcb8 100644
--- a/src/bin/scripts/dropuser.c
+++ b/src/bin/scripts/dropuser.c
@@ -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);
diff --git a/src/bin/scripts/reindexdb.c b/src/bin/scripts/reindexdb.c
index caeed7511e..9ff15d85d6 100644
--- a/src/bin/scripts/reindexdb.c
+++ b/src/bin/scripts/reindexdb.c
@@ -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 .\n"));
}
diff --git a/src/bin/scripts/vacuumdb.c b/src/bin/scripts/vacuumdb.c
index 7457e6d304..a82e10a2a2 100644
--- a/src/bin/scripts/vacuumdb.c
+++ b/src/bin/scripts/vacuumdb.c
@@ -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 .\n"));
}