@@ -43,7 +43,8 @@ static void vacuum_one_database(const char *dbname, vacuumingOptions *vacopts,
4343const char * host ,const char * port ,
4444const char * username ,enum trivalue prompt_password ,
4545int concurrentCons ,
46- const char * progname ,bool echo ,bool quiet );
46+ const char * progname ,bool echo ,bool quiet ,
47+ char * * password );
4748
4849static void vacuum_all_databases (vacuumingOptions * vacopts ,
4950bool analyze_in_stages ,
@@ -275,6 +276,8 @@ main(int argc, char *argv[])
275276}
276277else
277278{
279+ char * password = NULL ;
280+
278281if (dbname == NULL )
279282{
280283if (getenv ("PGDATABASE" ))
@@ -296,7 +299,8 @@ main(int argc, char *argv[])
296299& tables ,
297300host ,port ,username ,prompt_password ,
298301concurrentCons ,
299- progname ,echo ,quiet );
302+ progname ,echo ,quiet ,
303+ & password );
300304}
301305}
302306else
@@ -305,7 +309,10 @@ main(int argc, char *argv[])
305309& tables ,
306310host ,port ,username ,prompt_password ,
307311concurrentCons ,
308- progname ,echo ,quiet );
312+ progname ,echo ,quiet ,
313+ & password );
314+
315+ pg_free (password );
309316}
310317
311318exit (0 );
@@ -323,15 +330,21 @@ main(int argc, char *argv[])
323330 * If concurrentCons is > 1, multiple connections are used to vacuum tables
324331 * in parallel. In this case and if the table list is empty, we first obtain
325332 * a list of tables from the database.
333+ *
334+ * 'password' is both an input and output parameter. If one is not passed,
335+ * then whatever is used in a connection is returned so that caller can
336+ * reuse it in future connections.
326337 */
327338static void
328339vacuum_one_database (const char * dbname ,vacuumingOptions * vacopts ,
329340int stage ,
330341SimpleStringList * tables ,
331342const char * host ,const char * port ,
332- const char * username ,enum trivalue prompt_password ,
343+ const char * username ,
344+ enum trivalue prompt_password ,
333345int concurrentCons ,
334- const char * progname ,bool echo ,bool quiet )
346+ const char * progname ,bool echo ,bool quiet ,
347+ char * * password )
335348{
336349PQExpBufferData sql ;
337350PGconn * conn ;
@@ -365,8 +378,15 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts,
365378fflush (stdout );
366379}
367380
368- conn = connectDatabase (dbname ,host ,port ,username ,prompt_password ,
369- progname , false);
381+ conn = connectDatabase (dbname ,host ,port ,username ,* password ,
382+ prompt_password ,progname , false);
383+
384+ /*
385+ * If no password was not specified by caller and the connection required
386+ * one, remember it; this suppresses further password prompts.
387+ */
388+ if (PQconnectionUsedPassword (conn )&& * password == NULL )
389+ * password = pg_strdup (PQpass (conn ));
370390
371391initPQExpBuffer (& sql );
372392
@@ -424,10 +444,20 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts,
424444init_slot (slots ,conn );
425445if (parallel )
426446{
447+ const char * pqpass ;
448+
449+ /*
450+ * If a password was supplied for the initial connection, use it for
451+ * subsequent ones too. (Note that since we're connecting to the same
452+ * database with the same user, there's no need to update the stored
453+ * password any further.)
454+ */
455+ pqpass = PQpass (conn );
456+
427457for (i = 1 ;i < concurrentCons ;i ++ )
428458{
429- conn = connectDatabase (dbname ,host ,port ,username ,prompt_password ,
430- progname , false);
459+ conn = connectDatabase (dbname ,host ,port ,username ,pqpass ,
460+ prompt_password , progname , false);
431461init_slot (slots + i ,conn );
432462}
433463}
@@ -542,12 +572,23 @@ vacuum_all_databases(vacuumingOptions *vacopts,
542572PGresult * result ;
543573int stage ;
544574int i ;
575+ char * password = NULL ;
545576
546577conn = connectMaintenanceDatabase (maintenance_db ,host ,port ,
547578username ,prompt_password ,progname );
579+
548580result = executeQuery (conn ,
549581"SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;" ,
550582progname ,echo );
583+
584+ /*
585+ * Remember the password for further connections. If no password was
586+ * required for the maintenance db connection, this gets updated for the
587+ * first connection that does.
588+ */
589+ if (PQconnectionUsedPassword (conn ))
590+ password = pg_strdup (PQpass (conn ));
591+
551592PQfinish (conn );
552593
553594if (analyze_in_stages )
@@ -572,7 +613,8 @@ vacuum_all_databases(vacuumingOptions *vacopts,
572613NULL ,
573614host ,port ,username ,prompt_password ,
574615concurrentCons ,
575- progname ,echo ,quiet );
616+ progname ,echo ,quiet ,
617+ & password );
576618}
577619}
578620}
@@ -588,11 +630,13 @@ vacuum_all_databases(vacuumingOptions *vacopts,
588630NULL ,
589631host ,port ,username ,prompt_password ,
590632concurrentCons ,
591- progname ,echo ,quiet );
633+ progname ,echo ,quiet ,
634+ & password );
592635}
593636}
594637
595638PQclear (result );
639+ pg_free (password );
596640}
597641
598642/*