diff -ru postgresql-9.2.24/src/bin/pg_dump/pg_backup_archiver.c postgresql-9.2.24_new/src/bin/pg_dump/pg_backup_archiver.c --- postgresql-9.2.24/src/bin/pg_dump/pg_backup_archiver.c 2017-11-06 23:17:39.000000000 +0100 +++ postgresql-9.2.24_new/src/bin/pg_dump/pg_backup_archiver.c 2021-04-13 08:08:24.730000000 +0200 @@ -368,9 +368,7 @@ AHX->minRemoteVersion = 0; AHX->maxRemoteVersion = 999999; - 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 @@ -640,16 +638,8 @@ /* If we created a DB, connect to it... */ if (strcmp(te->desc, "DATABASE") == 0) { - PQExpBufferData connstr; - - initPQExpBuffer(&connstr); - appendPQExpBufferStr(&connstr, "dbname="); - appendConnStrVal(&connstr, te->tag); - /* Abandon struct, but keep its buffer until process exit. */ - ahlog(AH, 1, "connecting to new database \"%s\"\n", te->tag); _reconnectToDB(AH, te->tag); - ropt->dbname = connstr.data; } } @@ -778,7 +768,7 @@ /* 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; opts->number_of_jobs = 1; @@ -2155,8 +2145,6 @@ else AH->format = fmt; - AH->promptPassword = TRI_DEFAULT; - switch (AH->format) { case archCustom: @@ -2764,7 +2752,7 @@ _reconnectToDB(ArchiveHandle *AH, const char *dbname) { if (RestoringToDB(AH)) - ReconnectToServer(AH, dbname, NULL); + ReconnectToServer(AH, dbname); else { if (dbname) @@ -2777,7 +2765,13 @@ termPQExpBuffer(&connectbuf); } else + { + PQExpBufferData connectbuf; + initPQExpBuffer(&connectbuf); ahprintf(AH, "%s\n", "\\connect -\n"); + appendPsqlMetaConnect(&connectbuf, dbname); + termPQExpBuffer(&connectbuf); + } } /* @@ -2798,7 +2792,8 @@ AH->currWithOids = -1; /* re-establish fixed state */ - _doSetFixedOutputState(AH); + if (AH->mode == archModeRead) + _doSetFixedOutputState(AH); } /* @@ -3775,9 +3770,7 @@ /* * 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); _doSetFixedOutputState(AH); @@ -4092,11 +4085,10 @@ /* * We need our own database connection, too */ - ConnectDatabase((Archive *) AH, ropt->dbname, - ropt->pghost, ropt->pgport, ropt->username, - ropt->promptPassword); + ConnectDatabase((Archive *) AH, &AH->ropt->cparams, true); - _doSetFixedOutputState(AH); + if (AH->mode == archModeRead) + _doSetFixedOutputState(AH); /* Restore the TOC item */ retval = restore_toc_entry(AH, te, ropt, true); diff -ru postgresql-9.2.24/src/bin/pg_dump/pg_backup_archiver.h postgresql-9.2.24_new/src/bin/pg_dump/pg_backup_archiver.h --- postgresql-9.2.24/src/bin/pg_dump/pg_backup_archiver.h 2017-11-06 23:17:39.000000000 +0100 +++ postgresql-9.2.24_new/src/bin/pg_dump/pg_backup_archiver.h 2021-04-13 08:08:24.730000000 +0200 @@ -234,7 +234,6 @@ /* Stuff for direct DB connection */ char *archdbname; /* DB name *read* from archive */ - enum trivalue promptPassword; char *savedPassword; /* password for ropt->username, if known */ PGconn *connection; int connectToDB; /* Flag to indicate if direct DB connection is @@ -372,7 +371,7 @@ extern bool isValidTarHeader(char *header); -extern int ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *newUser); +extern void ReconnectToServer(ArchiveHandle *AH, const char *dbname); extern void DropBlobIfExists(ArchiveHandle *AH, Oid oid); int ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH); diff -ru postgresql-9.2.24/src/bin/pg_dump/pg_backup_db.c postgresql-9.2.24_new/src/bin/pg_dump/pg_backup_db.c --- postgresql-9.2.24/src/bin/pg_dump/pg_backup_db.c 2017-11-06 23:17:39.000000000 +0100 +++ postgresql-9.2.24_new/src/bin/pg_dump/pg_backup_db.c 2021-04-13 08:08:54.527000000 +0200 @@ -10,9 +10,12 @@ *------------------------------------------------------------------------- */ -#include "pg_backup_db.h" +#include "postgres_fe.h" + #include "dumpmem.h" #include "dumputils.h" +#include "pg_backup_archiver.h" +#include "pg_backup_db.h" #include #include @@ -27,7 +30,6 @@ static const char *modulename = gettext_noop("archiver (db)"); 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 int @@ -74,160 +76,37 @@ /* * 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. If - * both the database and the user match the existing connection already, - * nothing will be done. - * - * Returns 1 in any case. - */ -int -ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *username) -{ - 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; - - /* Let's see if the request is already satisfied */ - if (strcmp(newdbname, PQdb(AH->connection)) == 0 && - strcmp(newusername, PQuser(AH->connection)) == 0) - return 1; - - newConn = _connectDB(AH, newdbname, newusername); - - PQfinish(AH->connection); - AH->connection = newConn; - - return 1; -} - -/* - * 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 + * else the one associated with the archive handle * start of the run. */ -static PGconn * -_connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser) +void +ReconnectToServer(ArchiveHandle *AH, const char *dbname) { - PQExpBufferData connstr; - PGconn *newConn; - const char *newdb; - const char *newuser; - char *password = AH->savedPassword; - bool new_pass; - - if (!reqdb) - newdb = PQdb(AH->connection); - else - newdb = reqdb; - - if (!requser || strlen(requser) == 0) - newuser = PQuser(AH->connection); - else - newuser = requser; - - ahlog(AH, 1, "connecting to database \"%s\" as user \"%s\"\n", - newdb, newuser); - - if (AH->promptPassword == TRI_YES && password == NULL) - { - password = simple_prompt("Password: ", 100, false); - if (password == NULL) - exit_horribly(modulename, "out of memory\n"); - } - - initPQExpBuffer(&connstr); - appendPQExpBuffer(&connstr, "dbname="); - appendConnStrVal(&connstr, newdb); + PGconn *oldConn = AH->connection; + RestoreOptions *ropt = AH->ropt; - do - { -#define PARAMS_ARRAY_SIZE 7 - const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords)); - const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values)); - - 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); - - free(keywords); - free(values); - - if (!newConn) - exit_horribly(modulename, "failed to reconnect to database\n"); - - if (PQstatus(newConn) == CONNECTION_BAD) - { - if (!PQconnectionNeedsPassword(newConn)) - exit_horribly(modulename, "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 (password) - free(password); - - if (AH->promptPassword != TRI_NO) - password = simple_prompt("Password: ", 100, false); - else - exit_horribly(modulename, "connection needs password\n"); - - if (password == NULL) - exit_horribly(modulename, "out of memory\n"); - new_pass = true; - } - } while (new_pass); - - AH->savedPassword = password; - - termPQExpBuffer(&connstr); - - /* check for version mismatch */ - _check_database_version(AH); - - PQsetNoticeProcessor(newConn, notice_processor, NULL); - - return newConn; + if (dbname) + ropt->cparams.override_dbname = pg_strdup(dbname); + /* + * 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 */ + + ConnectDatabase((Archive *) AH, &ropt->cparams, true); + + PQfinish(oldConn); } /* - * Make a database connection with the given parameters. The - * connection handle is returned, the parameters are stored in AHX. + * 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 @@ -235,26 +114,26 @@ */ void ConnectDatabase(Archive *AHX, - const char *dbname, - const char *pghost, - const char *pgport, - const char *username, - enum trivalue prompt_password) + const ConnParams *cparams, + bool isReconnect) { ArchiveHandle *AH = (ArchiveHandle *) AHX; + enum trivalue prompt_password; char *password = AH->savedPassword; bool new_pass; if (AH->connection) exit_horribly(modulename, "already connected to a database\n"); + /* Never prompt for a password during a reconnection */ + prompt_password = isReconnect ? TRI_NO : cparams->promptPassword; + if (prompt_password == TRI_YES && password == NULL) { password = simple_prompt("Password: ", 100, false); if (password == NULL) exit_horribly(modulename, "out of memory\n"); } - AH->promptPassword = prompt_password; /* * Start the connection. Loop until we have a password if requested by @@ -263,53 +142,70 @@ do { #define PARAMS_ARRAY_SIZE 7 - const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords)); - const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values)); - - 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; - - new_pass = false; - AH->connection = PQconnectdbParams(keywords, values, true); - - free(keywords); - free(values); - - if (!AH->connection) - exit_horribly(modulename, "failed to connect to database\n"); - - if (PQstatus(AH->connection) == CONNECTION_BAD && - PQconnectionNeedsPassword(AH->connection) && - password == NULL && - prompt_password != TRI_NO) - { - PQfinish(AH->connection); - password = simple_prompt("Password: ", 100, false); - if (password == NULL) - exit_horribly(modulename, "out of memory\n"); - new_pass = true; - } + 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; + + new_pass = false; + AH->connection = PQconnectdbParams(keywords, values, true); + + + if (!AH->connection) + exit_horribly(modulename, "failed to connect to database\n"); + + if (PQstatus(AH->connection) == CONNECTION_BAD && + PQconnectionNeedsPassword(AH->connection) && + password == NULL && + prompt_password != TRI_NO) + { + PQfinish(AH->connection); + password = simple_prompt("Password: ", 100, false); + if (password == NULL) + exit_horribly(modulename, "out of memory\n"); + new_pass = true; + } } while (new_pass); AH->savedPassword = password; /* check to see that the backend connection was successfully made */ if (PQstatus(AH->connection) == CONNECTION_BAD) - exit_horribly(modulename, "connection to database \"%s\" failed: %s", - PQdb(AH->connection) ? PQdb(AH->connection) : "", - PQerrorMessage(AH->connection)); + { + if (isReconnect) + exit_horribly(modulename, "reconnection to database \"%s\" failed: %s", + PQdb(AH->connection) ? PQdb(AH->connection) : "", + PQerrorMessage(AH->connection)); + else + exit_horribly(modulename, "connection to database \"%s\" failed: %s", + PQdb(AH->connection) ? PQdb(AH->connection) : "", + PQerrorMessage(AH->connection)); + } + /* check for version mismatch */ _check_database_version(AH); diff -ru postgresql-9.2.24/src/bin/pg_dump/pg_backup.h postgresql-9.2.24_new/src/bin/pg_dump/pg_backup.h --- postgresql-9.2.24/src/bin/pg_dump/pg_backup.h 2017-11-06 23:17:39.000000000 +0100 +++ postgresql-9.2.24_new/src/bin/pg_dump/pg_backup.h 2021-04-13 08:08:24.728000000 +0200 @@ -94,6 +94,20 @@ typedef int (*DataDumperPtr) (Archive *AH, void *userArg); +/* 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; + enum 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 */ @@ -130,10 +144,7 @@ char *triggerNames; int useDB; - char *dbname; /* subject to expand_dbname */ - char *pgport; - char *pghost; - char *username; + ConnParams cparams; int noDataForFailedTables; enum trivalue promptPassword; int exit_on_error; @@ -152,11 +163,8 @@ */ extern void ConnectDatabase(Archive *AH, - const char *dbname, - const char *pghost, - const char *pgport, - const char *username, - enum trivalue prompt_password); + const ConnParams *cparams, + bool isReconnect); extern void DisconnectDatabase(Archive *AHX); extern PGconn *GetConnection(Archive *AHX); diff -ru postgresql-9.2.24/src/bin/pg_dump/pg_dump.c postgresql-9.2.24_new/src/bin/pg_dump/pg_dump.c --- postgresql-9.2.24/src/bin/pg_dump/pg_dump.c 2017-11-06 23:17:39.000000000 +0100 +++ postgresql-9.2.24_new/src/bin/pg_dump/pg_dump.c 2021-04-13 08:08:54.530000000 +0200 @@ -276,10 +276,7 @@ int c; const char *filename = NULL; const char *format = "p"; - const char *dbname = NULL; - const char *pghost = NULL; - const char *pgport = NULL; - const char *username = NULL; + ConnParams cparams; const char *dumpencoding = NULL; bool oids = false; TableInfo *tblinfo; @@ -288,7 +285,6 @@ int numObjs; DumpableObject *boundaryObjs; int i; - enum trivalue prompt_password = TRI_DEFAULT; int compressLevel = -1; int plainText = 0; int outputClean = 0; @@ -307,7 +303,12 @@ static int disable_triggers = 0; static int outputNoTablespaces = 0; static int use_setsessauth = 0; - + cparams.pghost = NULL; + cparams.pgport = NULL; + cparams.username = NULL; + cparams.dbname = NULL; + cparams.override_dbname = NULL; + static struct option long_options[] = { {"data-only", no_argument, NULL, 'a'}, {"blobs", no_argument, NULL, 'b'}, @@ -427,7 +428,7 @@ break; case 'h': /* server host */ - pghost = optarg; + cparams.pghost = optarg; break; case 'i': @@ -452,7 +453,7 @@ break; case 'p': /* server port */ - pgport = optarg; + cparams.pgport = optarg; break; case 'R': @@ -477,7 +478,7 @@ break; case 'U': - username = optarg; + cparams.username = optarg; break; case 'v': /* verbose */ @@ -485,11 +486,11 @@ break; case 'w': - prompt_password = TRI_NO; + cparams.promptPassword = TRI_NO; break; case 'W': - prompt_password = TRI_YES; + cparams.promptPassword = TRI_YES; break; case 'x': /* skip ACL dump */ @@ -532,8 +533,8 @@ } /* Get database name from command line */ - if (optind < argc) - dbname = argv[optind++]; + if (optind < argc && cparams.dbname == NULL) + cparams.dbname = argv[optind++]; /* Complain if any arguments remain */ if (optind < argc) @@ -605,7 +606,7 @@ * Open the database using the Archiver, so it knows about it. Errors mean * death. */ - ConnectDatabase(fout, dbname, pghost, pgport, username, prompt_password); + ConnectDatabase(fout, &cparams, false); setup_connection(fout, dumpencoding, use_role); /* @@ -791,9 +792,15 @@ for (i = 0; i < numObjs; i++) dumpDumpableObject(fout, dobjs[i]); + ropt=malloc(sizeof(RestoreOptions)); /* * Set up options info to ensure we dump what we want. */ + ropt->cparams.dbname = cparams.dbname ? pg_strdup(cparams.dbname) : NULL; + ropt->cparams.pgport = cparams.pgport ? pg_strdup(cparams.pgport) : NULL; + ropt->cparams.pghost = cparams.pghost ? pg_strdup(cparams.pghost) : NULL; + ropt->cparams.username = cparams.username ? pg_strdup(cparams.username) : NULL; + ropt->cparams.promptPassword = cparams.promptPassword; ropt = NewRestoreOptions(); ropt->filename = filename; ropt->dropSchema = outputClean; @@ -837,6 +844,7 @@ RestoreArchive(fout); CloseArchive(fout); + free(ropt); exit_nicely(0); } diff -ru postgresql-9.2.24/src/bin/pg_dump/pg_restore.c postgresql-9.2.24_new/src/bin/pg_dump/pg_restore.c --- postgresql-9.2.24/src/bin/pg_dump/pg_restore.c 2017-11-06 23:17:39.000000000 +0100 +++ postgresql-9.2.24_new/src/bin/pg_dump/pg_restore.c 2021-04-13 08:08:24.736000000 +0200 @@ -162,7 +162,7 @@ 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; @@ -176,7 +176,7 @@ break; case 'h': if (strlen(optarg) != 0) - opts->pghost = pg_strdup(optarg); + opts->cparams.pghost = pg_strdup(optarg); break; case 'i': /* ignored, deprecated option */ @@ -204,7 +204,7 @@ 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 */ @@ -238,7 +238,7 @@ break; case 'U': - opts->username = optarg; + opts->cparams.username = optarg; break; case 'v': /* verbose */ @@ -246,11 +246,11 @@ 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 */ @@ -300,7 +300,7 @@ } /* Should get at most one of -d and -f, else user is confused */ - if (opts->dbname) + if (opts->cparams.dbname) { if (opts->filename) { diff -ru postgresql-9.2.24/src/bin/scripts/clusterdb.c postgresql-9.2.24_new/src/bin/scripts/clusterdb.c --- postgresql-9.2.24/src/bin/scripts/clusterdb.c 2017-11-06 23:17:39.000000000 +0100 +++ postgresql-9.2.24_new/src/bin/scripts/clusterdb.c 2021-04-13 08:08:24.736000000 +0200 @@ -14,14 +14,10 @@ #include "dumputils.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); @@ -55,6 +51,7 @@ char *port = NULL; char *username = NULL; enum trivalue prompt_password = TRI_DEFAULT; + ConnParams cparams; bool echo = false; bool quiet = false; bool alldb = false; @@ -130,6 +127,13 @@ 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(); if (alldb) @@ -147,8 +151,9 @@ 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 { @@ -162,9 +167,9 @@ dbname = get_user_name(progname); } - cluster_one_database(dbname, verbose, table, - host, port, username, prompt_password, - progname, echo); + cparams.dbname = dbname; + + cluster_one_database(&cparams, table, progname, verbose, echo); } exit(0); @@ -172,10 +177,8 @@ 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; @@ -190,8 +193,7 @@ appendPQExpBuffer(&sql, " %s", table); appendPQExpBuffer(&sql, ";\n"); - conn = connectDatabase(dbname, host, port, username, prompt_password, - progname, false); + conn = connectDatabase(cparams, progname, echo, false, false); if (!executeMaintenanceCommand(conn, sql.data, echo)) { if (table) @@ -209,22 +211,17 @@ 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); + conn = connectMaintenanceDatabase(cparams, progname, echo); result = executeQuery(conn, "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;", progname, echo); PQfinish(conn); - initPQExpBuffer(&connstr); for (i = 0; i < PQntuples(result); i++) { char *dbname = PQgetvalue(result, i, 0); @@ -235,15 +232,10 @@ fflush(stdout); } - resetPQExpBuffer(&connstr); - appendPQExpBuffer(&connstr, "dbname="); - appendConnStrVal(&connstr, dbname); - - cluster_one_database(connstr.data, verbose, NULL, - host, port, username, prompt_password, - progname, echo); + cparams->override_dbname = dbname; + + cluster_one_database(cparams, NULL, progname, verbose, echo); } - termPQExpBuffer(&connstr); PQclear(result); } diff -ru postgresql-9.2.24/src/bin/scripts/common.c postgresql-9.2.24_new/src/bin/scripts/common.c --- postgresql-9.2.24/src/bin/scripts/common.c 2017-11-06 23:17:39.000000000 +0100 +++ postgresql-9.2.24_new/src/bin/scripts/common.c 2021-04-13 08:08:54.530000000 +0200 @@ -91,15 +91,14 @@ * interactive password prompt is automatically issued if required. */ PGconn * -connectDatabase(const char *dbname, const char *pghost, const char *pgport, - const char *pguser, enum trivalue prompt_password, - const char *progname, bool fail_ok) +connectDatabase(const ConnParams *cparams, const char *progname, + bool echo, bool fail_ok, bool allow_password_reuse) { PGconn *conn; char *password = NULL; bool new_pass; - if (prompt_password == TRI_YES) + if (cparams->prompt_password == TRI_YES) password = simple_prompt("Password: ", 100, false); /* @@ -109,47 +108,50 @@ do { #define PARAMS_ARRAY_SIZE 7 - const char **keywords = malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords)); - const char **values = malloc(PARAMS_ARRAY_SIZE * sizeof(*values)); - - if (!keywords || !values) + 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) { - fprintf(stderr, _("%s: out of memory\n"), progname); - exit(1); + keywords[i] = "dbname"; + values[i++] = cparams->override_dbname; } - - 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; + keywords[i] = "fallback_application_name"; + values[i++] = progname; + keywords[i] = NULL; + values[i++] = NULL; new_pass = false; conn = PQconnectdbParams(keywords, values, true); - free(keywords); - free(values); if (!conn) { fprintf(stderr, _("%s: could not connect to database %s\n"), - progname, dbname); + progname, cparams->dbname); exit(1); } if (PQstatus(conn) == CONNECTION_BAD && - PQconnectionNeedsPassword(conn) && - password == NULL && - prompt_password != TRI_NO) + PQconnectionNeedsPassword(conn) && + password == NULL && + cparams->prompt_password != TRI_NO) { PQfinish(conn); password = simple_prompt("Password: ", 100, false); @@ -169,7 +171,7 @@ return NULL; } fprintf(stderr, _("%s: could not connect to database %s: %s"), - progname, dbname, PQerrorMessage(conn)); + progname, cparams->dbname, PQerrorMessage(conn)); exit(1); } @@ -178,26 +180,29 @@ /* * 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, - const char *progname) +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, 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, true); + cparams->dbname = "postgres"; + conn = connectDatabase(cparams, progname, echo, true, false); if (!conn) - conn = connectDatabase("template1", pghost, pgport, pguser, - prompt_password, progname, false); + { + cparams->dbname = "template1"; + conn = connectDatabase(cparams, progname, echo, false, false); + } return conn; } diff -ru postgresql-9.2.24/src/bin/scripts/common.h postgresql-9.2.24_new/src/bin/scripts/common.h --- postgresql-9.2.24/src/bin/scripts/common.h 2017-11-06 23:17:39.000000000 +0100 +++ postgresql-9.2.24_new/src/bin/scripts/common.h 2021-04-13 08:08:24.737000000 +0200 @@ -20,6 +20,20 @@ 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 const char *get_user_name(const char *progname); @@ -28,14 +42,13 @@ 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 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 PGconn *connectDatabase(const ConnParams *cparams, + const char *progname, + bool echo, bool fail_ok, + bool allow_password_reuse); + +extern PGconn *connectMaintenanceDatabase(ConnParams *cparams, + const char *progname, bool echo); extern PGresult *executeQuery(PGconn *conn, const char *query, const char *progname, bool echo); diff -ru postgresql-9.2.24/src/bin/scripts/createdb.c postgresql-9.2.24_new/src/bin/scripts/createdb.c --- postgresql-9.2.24/src/bin/scripts/createdb.c 2017-11-06 23:17:39.000000000 +0100 +++ postgresql-9.2.24_new/src/bin/scripts/createdb.c 2021-04-13 08:08:24.737000000 +0200 @@ -50,6 +50,7 @@ char *port = NULL; char *username = NULL; enum trivalue prompt_password = TRI_DEFAULT; + ConnParams cparams; bool echo = false; char *owner = NULL; char *tablespace = NULL; @@ -201,8 +202,14 @@ if (maintenance_db == NULL && strcmp(dbname, "postgres") == 0) maintenance_db = "template1"; - conn = connectMaintenanceDatabase(maintenance_db, host, port, username, - prompt_password, progname); + 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", sql.data); diff -ru postgresql-9.2.24/src/bin/scripts/createlang.c postgresql-9.2.24_new/src/bin/scripts/createlang.c --- postgresql-9.2.24/src/bin/scripts/createlang.c 2017-11-06 23:17:39.000000000 +0100 +++ postgresql-9.2.24_new/src/bin/scripts/createlang.c 2021-04-13 08:08:24.737000000 +0200 @@ -42,6 +42,7 @@ char *port = NULL; char *username = NULL; enum trivalue prompt_password = TRI_DEFAULT; + ConnParams cparams; bool echo = false; char *langname = NULL; @@ -130,6 +131,13 @@ dbname = get_user_name(progname); } + cparams.dbname = dbname; + cparams.pghost = host; + cparams.pgport = port; + cparams.pguser = username; + cparams.prompt_password = prompt_password; + cparams.override_dbname = NULL; + initPQExpBuffer(&sql); /* @@ -140,8 +148,8 @@ printQueryOpt popt; static const bool translate_columns[] = {false, true}; - conn = connectDatabase(dbname, host, port, username, prompt_password, - progname, false); + conn = connectDatabase(&cparams, + progname, echo, false, false); printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", " "(CASE WHEN lanpltrusted THEN '%s' ELSE '%s' END) as \"%s\" " @@ -178,8 +186,8 @@ if (*p >= 'A' && *p <= 'Z') *p += ('a' - 'A'); - conn = connectDatabase(dbname, host, port, username, prompt_password, - progname, false); + conn = connectDatabase(&cparams, + progname, echo, false, false); /* * Make sure the language isn't already installed diff -ru postgresql-9.2.24/src/bin/scripts/createuser.c postgresql-9.2.24_new/src/bin/scripts/createuser.c --- postgresql-9.2.24/src/bin/scripts/createuser.c 2017-11-06 23:17:39.000000000 +0100 +++ postgresql-9.2.24_new/src/bin/scripts/createuser.c 2021-04-13 08:08:24.738000000 +0200 @@ -58,6 +58,7 @@ char *port = NULL; char *username = NULL; enum trivalue prompt_password = TRI_DEFAULT; + ConnParams cparams; bool echo = false; bool interactive = false; char *conn_limit = NULL; @@ -245,8 +246,14 @@ if (login == 0) login = TRI_YES; - conn = connectDatabase("postgres", host, port, username, prompt_password, - progname, 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); diff -ru postgresql-9.2.24/src/bin/scripts/dropdb.c postgresql-9.2.24_new/src/bin/scripts/dropdb.c --- postgresql-9.2.24/src/bin/scripts/dropdb.c 2017-11-06 23:17:39.000000000 +0100 +++ postgresql-9.2.24_new/src/bin/scripts/dropdb.c 2021-04-13 08:08:24.738000000 +0200 @@ -46,6 +46,7 @@ char *port = NULL; char *username = NULL; enum trivalue prompt_password = TRI_DEFAULT; + ConnParams cparams; bool echo = false; bool interactive = false; @@ -128,8 +129,14 @@ if (maintenance_db == NULL && strcmp(dbname, "postgres") == 0) maintenance_db = "template1"; - conn = connectMaintenanceDatabase(maintenance_db, - host, port, username, prompt_password, progname); + 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", sql.data); diff -ru postgresql-9.2.24/src/bin/scripts/droplang.c postgresql-9.2.24_new/src/bin/scripts/droplang.c --- postgresql-9.2.24/src/bin/scripts/droplang.c 2017-11-06 23:17:39.000000000 +0100 +++ postgresql-9.2.24_new/src/bin/scripts/droplang.c 2021-04-13 08:08:24.738000000 +0200 @@ -44,6 +44,7 @@ char *port = NULL; char *username = NULL; enum trivalue prompt_password = TRI_DEFAULT; + ConnParams cparams; bool echo = false; char *langname = NULL; char *p; @@ -129,6 +130,13 @@ dbname = get_user_name(progname); } + cparams.dbname = dbname; + cparams.pghost = host; + cparams.pgport = port; + cparams.pguser = username; + cparams.prompt_password = prompt_password; + cparams.override_dbname = NULL; + initPQExpBuffer(&sql); /* @@ -139,8 +147,8 @@ printQueryOpt popt; static const bool translate_columns[] = {false, true}; - conn = connectDatabase(dbname, host, port, username, prompt_password, - progname, false); + conn = connectDatabase(&cparams, + progname, echo, false, false); printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", " "(CASE WHEN lanpltrusted THEN '%s' ELSE '%s' END) as \"%s\" " @@ -179,8 +187,8 @@ if (*p >= 'A' && *p <= 'Z') *p += ('a' - 'A'); - conn = connectDatabase(dbname, host, port, username, prompt_password, - progname, false); + conn = connectDatabase(&cparams, + progname, echo, false, false); /* * Force schema search path to be just pg_catalog, so that we don't have diff -ru postgresql-9.2.24/src/bin/scripts/dropuser.c postgresql-9.2.24_new/src/bin/scripts/dropuser.c --- postgresql-9.2.24/src/bin/scripts/dropuser.c 2017-11-06 23:17:39.000000000 +0100 +++ postgresql-9.2.24_new/src/bin/scripts/dropuser.c 2021-04-13 08:08:24.738000000 +0200 @@ -44,6 +44,7 @@ char *port = NULL; char *username = NULL; enum trivalue prompt_password = TRI_DEFAULT; + ConnParams cparams; bool echo = false; bool interactive = false; @@ -124,13 +125,19 @@ 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;\n", (if_exists ? "IF EXISTS " : ""), fmtId(dropuser)); - conn = connectDatabase("postgres", host, port, username, prompt_password, - progname, false); - if (echo) printf("%s", sql.data); result = PQexec(conn, sql.data); diff -ru postgresql-9.2.24/src/bin/scripts/reindexdb.c postgresql-9.2.24_new/src/bin/scripts/reindexdb.c --- postgresql-9.2.24/src/bin/scripts/reindexdb.c 2017-11-06 23:17:39.000000000 +0100 +++ postgresql-9.2.24_new/src/bin/scripts/reindexdb.c 2021-04-13 08:08:24.739000000 +0200 @@ -14,20 +14,15 @@ #include "dumputils.h" -static void reindex_one_database(const char *name, const char *dbname, - const char *type, const char *host, - const char *port, const char *username, - enum trivalue prompt_password, const char *progname, - bool echo); -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); -static void reindex_system_catalogs(const char *dbname, - const char *host, const char *port, - const char *username, enum trivalue prompt_password, - const char *progname, bool echo); +static void reindex_one_database(const ConnParams *cparams, + const char *type, const char *name, + const char *progname, + bool echo); +static void reindex_all_databases(ConnParams *cparams, + const char *progname, bool echo, + bool quiet); +static void reindex_system_catalogs(const ConnParams *cparams, + const char *progname, bool echo); static void help(const char *progname); int @@ -60,6 +55,7 @@ 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; @@ -140,6 +136,13 @@ 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(); if (alldb) @@ -165,8 +168,9 @@ exit(1); } - reindex_all_databases(maintenance_db, host, port, username, - prompt_password, progname, echo, quiet); + cparams.dbname = maintenance_db; + + reindex_all_databases(&cparams, progname, echo, quiet); } else if (syscatalog) { @@ -191,8 +195,9 @@ dbname = get_user_name(progname); } - reindex_system_catalogs(dbname, host, port, username, prompt_password, - progname, echo); + cparams.dbname = dbname; + + reindex_system_catalogs(&cparams, progname, echo); } else { @@ -206,32 +211,34 @@ dbname = get_user_name(progname); } + cparams.dbname = dbname; + if (index) - reindex_one_database(index, dbname, "INDEX", host, port, - username, prompt_password, progname, echo); + reindex_one_database(&cparams, "INDEX", table, + progname, echo); if (table) - reindex_one_database(table, dbname, "TABLE", host, port, - username, prompt_password, progname, echo); + reindex_one_database(&cparams, "TABLE", table, + progname, echo); /* reindex database only if index or table is not specified */ if (index == NULL && table == NULL) - reindex_one_database(NULL, dbname, "DATABASE", host, port, - username, prompt_password, progname, echo); + reindex_one_database(&cparams, "DATABASE", table, + progname, echo); } exit(0); } static void -reindex_one_database(const char *name, const char *dbname, const char *type, - const char *host, const char *port, const char *username, - enum trivalue prompt_password, const char *progname, bool echo) +reindex_one_database(const ConnParams *cparams, + const char *type, const char *name, + const char *progname, + bool echo) { PQExpBufferData sql; PGconn *conn; - conn = connectDatabase(dbname, host, port, username, prompt_password, - progname, false); + conn = connectDatabase(cparams, progname, echo, false, false); initPQExpBuffer(&sql); @@ -264,22 +271,17 @@ } 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) +reindex_all_databases(ConnParams *cparams, const char *progname, bool echo, bool quiet) { PGconn *conn; PGresult *result; PQExpBufferData connstr; int i; - conn = connectMaintenanceDatabase(maintenance_db, host, port, username, - prompt_password, progname); + conn = connectMaintenanceDatabase(cparams, progname, echo); result = executeQuery(conn, "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;", progname, echo); PQfinish(conn); - initPQExpBuffer(&connstr); for (i = 0; i < PQntuples(result); i++) { char *dbname = PQgetvalue(result, i, 0); @@ -293,26 +295,22 @@ resetPQExpBuffer(&connstr); appendPQExpBuffer(&connstr, "dbname="); appendConnStrVal(&connstr, dbname); + cparams->override_dbname = dbname; - reindex_one_database(NULL, connstr.data, "DATABASE", host, - port, username, prompt_password, - progname, echo); + reindex_one_database(cparams, "DATABASE", NULL, progname, echo); } - termPQExpBuffer(&connstr); PQclear(result); } static void -reindex_system_catalogs(const char *dbname, const char *host, const char *port, - const char *username, enum trivalue prompt_password, - const char *progname, bool echo) +reindex_system_catalogs(const ConnParams *cparams, + const char *progname, bool echo) { PGconn *conn; PQExpBufferData sql; - conn = connectDatabase(dbname, host, port, username, prompt_password, - progname, false); + conn = connectDatabase(cparams, progname, echo, false, false); initPQExpBuffer(&sql); diff -ru postgresql-9.2.24/src/bin/scripts/vacuumdb.c postgresql-9.2.24_new/src/bin/scripts/vacuumdb.c --- postgresql-9.2.24/src/bin/scripts/vacuumdb.c 2017-11-06 23:17:39.000000000 +0100 +++ postgresql-9.2.24_new/src/bin/scripts/vacuumdb.c 2021-04-13 08:08:24.739000000 +0200 @@ -15,16 +15,13 @@ #include "dumputils.h" -static void vacuum_one_database(const char *dbname, bool full, bool verbose, +static void vacuum_one_database(const ConnParams *cparams, bool full, bool verbose, bool and_analyze, bool analyze_only, bool freeze, - const char *table, const char *host, const char *port, - const char *username, enum trivalue prompt_password, - const char *progname, bool echo); -static void vacuum_all_databases(bool full, bool verbose, bool and_analyze, + const char *table, const char *progname, bool echo); + +static void vacuum_all_databases(ConnParams *cparams, 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); static void help(const char *progname); @@ -63,6 +60,7 @@ char *port = NULL; char *username = NULL; enum trivalue prompt_password = TRI_DEFAULT; + ConnParams cparams; bool echo = false; bool quiet = false; bool and_analyze = false; @@ -172,6 +170,13 @@ /* allow 'and_analyze' with 'analyze_only' */ } + /* 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(); if (alldb) @@ -189,9 +194,10 @@ exit(1); } - vacuum_all_databases(full, verbose, and_analyze, analyze_only, freeze, - maintenance_db, host, port, username, - prompt_password, progname, echo, quiet); + cparams.dbname = maintenance_db; + + vacuum_all_databases(&cparams, full, verbose, and_analyze, analyze_only, freeze, + progname, echo, quiet); } else { @@ -205,9 +211,10 @@ dbname = get_user_name(progname); } - vacuum_one_database(dbname, full, verbose, and_analyze, analyze_only, + cparams.dbname = dbname; + + vacuum_one_database(&cparams, full, verbose, and_analyze, analyze_only, freeze, table, - host, port, username, prompt_password, progname, echo); } @@ -216,10 +223,8 @@ static void -vacuum_one_database(const char *dbname, bool full, bool verbose, bool and_analyze, +vacuum_one_database(const ConnParams *cparams, bool full, bool verbose, bool and_analyze, bool analyze_only, bool freeze, const char *table, - const char *host, const char *port, - const char *username, enum trivalue prompt_password, const char *progname, bool echo) { PQExpBufferData sql; @@ -228,8 +233,7 @@ initPQExpBuffer(&sql); - conn = connectDatabase(dbname, host, port, username, prompt_password, - progname, false); + conn = connectDatabase(cparams, progname, echo, false, true); if (analyze_only) { @@ -302,19 +306,15 @@ 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) +vacuum_all_databases(ConnParams *cparams, bool full, bool verbose, bool and_analyze, bool analyze_only, + bool freeze, const char *progname, bool echo, bool quiet) { PGconn *conn; PGresult *result; PQExpBufferData connstr; int i; - conn = connectMaintenanceDatabase(maintenance_db, host, port, - username, prompt_password, progname); + conn = connectMaintenanceDatabase(cparams, progname, echo); result = executeQuery(conn, "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;", progname, echo); PQfinish(conn); @@ -329,13 +329,10 @@ fflush(stdout); } - resetPQExpBuffer(&connstr); - appendPQExpBuffer(&connstr, "dbname="); - appendConnStrVal(&connstr, PQgetvalue(result, i, 0)); - - vacuum_one_database(connstr.data, full, verbose, and_analyze, - analyze_only, - freeze, NULL, host, port, username, prompt_password, + cparams->override_dbname = PQgetvalue(result, i, 0); + + vacuum_one_database(cparams, full, verbose, and_analyze, + analyze_only, freeze, NULL, progname, echo); } termPQExpBuffer(&connstr);