@@ -43,7 +43,8 @@ static void vacuum_one_database(const char *dbname, vacuumingOptions *vacopts,
4343 const char * host , const char * port ,
4444 const char * username , enum trivalue prompt_password ,
4545 int 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 ,
4950 bool analyze_in_stages ,
@@ -275,6 +276,8 @@ main(int argc, char *argv[])
275276 }
276277 else
277278 {
279+ char * password = NULL ;
280+
278281 if (dbname == NULL )
279282 {
280283 if (getenv ("PGDATABASE" ))
@@ -296,7 +299,8 @@ main(int argc, char *argv[])
296299 & tables ,
297300 host , port , username , prompt_password ,
298301 concurrentCons ,
299- progname , echo , quiet );
302+ progname , echo , quiet ,
303+ & password );
300304 }
301305 }
302306 else
@@ -305,7 +309,10 @@ main(int argc, char *argv[])
305309 & tables ,
306310 host , port , username , prompt_password ,
307311 concurrentCons ,
308- progname , echo , quiet );
312+ progname , echo , quiet ,
313+ & password );
314+
315+ pg_free (password );
309316 }
310317
311318 exit (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 ,
329340 int stage ,
330341 SimpleStringList * tables ,
331342 const char * host , const char * port ,
332- const char * username , enum trivalue prompt_password ,
343+ const char * username ,
344+ enum trivalue prompt_password ,
333345 int concurrentCons ,
334- const char * progname , bool echo , bool quiet )
346+ const char * progname , bool echo , bool quiet ,
347+ char * * password )
335348{
336349 PQExpBufferData sql ;
337350 PGconn * conn ;
@@ -365,8 +378,15 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts,
365378 fflush (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
371391 initPQExpBuffer (& sql );
372392
@@ -424,10 +444,20 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts,
424444 init_slot (slots , conn );
425445 if (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+
427457 for (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);
431461 init_slot (slots + i , conn );
432462 }
433463 }
@@ -542,12 +572,23 @@ vacuum_all_databases(vacuumingOptions *vacopts,
542572 PGresult * result ;
543573 int stage ;
544574 int i ;
575+ char * password = NULL ;
545576
546577 conn = connectMaintenanceDatabase (maintenance_db , host , port ,
547578 username , prompt_password , progname );
579+
548580 result = executeQuery (conn ,
549581 "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;" ,
550582 progname , 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+
551592 PQfinish (conn );
552593
553594 if (analyze_in_stages )
@@ -572,7 +613,8 @@ vacuum_all_databases(vacuumingOptions *vacopts,
572613 NULL ,
573614 host , port , username , prompt_password ,
574615 concurrentCons ,
575- progname , echo , quiet );
616+ progname , echo , quiet ,
617+ & password );
576618 }
577619 }
578620 }
@@ -588,11 +630,13 @@ vacuum_all_databases(vacuumingOptions *vacopts,
588630 NULL ,
589631 host , port , username , prompt_password ,
590632 concurrentCons ,
591- progname , echo , quiet );
633+ progname , echo , quiet ,
634+ & password );
592635 }
593636 }
594637
595638 PQclear (result );
639+ pg_free (password );
596640}
597641
598642/*
0 commit comments