@@ -43,7 +43,8 @@ static void vacuum_one_database(const char *dbname, vacuumingOptions *vacopts,
43
43
const char * host , const char * port ,
44
44
const char * username , enum trivalue prompt_password ,
45
45
int concurrentCons ,
46
- const char * progname , bool echo , bool quiet );
46
+ const char * progname , bool echo , bool quiet ,
47
+ char * * password );
47
48
48
49
static void vacuum_all_databases (vacuumingOptions * vacopts ,
49
50
bool analyze_in_stages ,
@@ -275,6 +276,8 @@ main(int argc, char *argv[])
275
276
}
276
277
else
277
278
{
279
+ char * password = NULL ;
280
+
278
281
if (dbname == NULL )
279
282
{
280
283
if (getenv ("PGDATABASE" ))
@@ -296,7 +299,8 @@ main(int argc, char *argv[])
296
299
& tables ,
297
300
host , port , username , prompt_password ,
298
301
concurrentCons ,
299
- progname , echo , quiet );
302
+ progname , echo , quiet ,
303
+ & password );
300
304
}
301
305
}
302
306
else
@@ -305,7 +309,10 @@ main(int argc, char *argv[])
305
309
& tables ,
306
310
host , port , username , prompt_password ,
307
311
concurrentCons ,
308
- progname , echo , quiet );
312
+ progname , echo , quiet ,
313
+ & password );
314
+
315
+ pg_free (password );
309
316
}
310
317
311
318
exit (0 );
@@ -323,15 +330,21 @@ main(int argc, char *argv[])
323
330
* If concurrentCons is > 1, multiple connections are used to vacuum tables
324
331
* in parallel. In this case and if the table list is empty, we first obtain
325
332
* 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.
326
337
*/
327
338
static void
328
339
vacuum_one_database (const char * dbname , vacuumingOptions * vacopts ,
329
340
int stage ,
330
341
SimpleStringList * tables ,
331
342
const char * host , const char * port ,
332
- const char * username , enum trivalue prompt_password ,
343
+ const char * username ,
344
+ enum trivalue prompt_password ,
333
345
int concurrentCons ,
334
- const char * progname , bool echo , bool quiet )
346
+ const char * progname , bool echo , bool quiet ,
347
+ char * * password )
335
348
{
336
349
PQExpBufferData sql ;
337
350
PGconn * conn ;
@@ -365,8 +378,15 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts,
365
378
fflush (stdout );
366
379
}
367
380
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 ));
370
390
371
391
initPQExpBuffer (& sql );
372
392
@@ -424,10 +444,20 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts,
424
444
init_slot (slots , conn );
425
445
if (parallel )
426
446
{
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
+
427
457
for (i = 1 ; i < concurrentCons ; i ++ )
428
458
{
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);
431
461
init_slot (slots + i , conn );
432
462
}
433
463
}
@@ -542,12 +572,23 @@ vacuum_all_databases(vacuumingOptions *vacopts,
542
572
PGresult * result ;
543
573
int stage ;
544
574
int i ;
575
+ char * password = NULL ;
545
576
546
577
conn = connectMaintenanceDatabase (maintenance_db , host , port ,
547
578
username , prompt_password , progname );
579
+
548
580
result = executeQuery (conn ,
549
581
"SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;" ,
550
582
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
+
551
592
PQfinish (conn );
552
593
553
594
if (analyze_in_stages )
@@ -572,7 +613,8 @@ vacuum_all_databases(vacuumingOptions *vacopts,
572
613
NULL ,
573
614
host , port , username , prompt_password ,
574
615
concurrentCons ,
575
- progname , echo , quiet );
616
+ progname , echo , quiet ,
617
+ & password );
576
618
}
577
619
}
578
620
}
@@ -588,11 +630,13 @@ vacuum_all_databases(vacuumingOptions *vacopts,
588
630
NULL ,
589
631
host , port , username , prompt_password ,
590
632
concurrentCons ,
591
- progname , echo , quiet );
633
+ progname , echo , quiet ,
634
+ & password );
592
635
}
593
636
}
594
637
595
638
PQclear (result );
639
+ pg_free (password );
596
640
}
597
641
598
642
/*
0 commit comments