@@ -52,6 +52,8 @@ static PGconn *connectDatabase(const char *dbname, const char *connstr, const ch
5252static char * constructConnStr (const char * * keywords , const char * * values );
5353static PGresult * executeQuery (PGconn * conn , const char * query );
5454static void executeCommand (PGconn * conn , const char * query );
55+ static void expand_dbname_patterns (PGconn * conn , SimpleStringList * patterns ,
56+ SimpleStringList * names );
5557
5658static char pg_dump_bin [MAXPGPATH ];
5759static const char * progname ;
@@ -87,6 +89,9 @@ static char role_catalog[10];
8789static FILE * OPF ;
8890static char * filename = NULL ;
8991
92+ static SimpleStringList database_exclude_patterns = {NULL , NULL };
93+ static SimpleStringList database_exclude_names = {NULL , NULL };
94+
9095#define exit_nicely (code ) exit(code)
9196
9297int
@@ -123,6 +128,7 @@ main(int argc, char *argv[])
123128 {"column-inserts" , no_argument , & column_inserts , 1 },
124129 {"disable-dollar-quoting" , no_argument , & disable_dollar_quoting , 1 },
125130 {"disable-triggers" , no_argument , & disable_triggers , 1 },
131+ {"exclude-database" , required_argument , NULL , 6 },
126132 {"extra-float-digits" , required_argument , NULL , 5 },
127133 {"if-exists" , no_argument , & if_exists , 1 },
128134 {"inserts" , no_argument , & inserts , 1 },
@@ -324,6 +330,10 @@ main(int argc, char *argv[])
324330 appendShellString (pgdumpopts , optarg );
325331 break ;
326332
333+ case 6 :
334+ simple_string_list_append (& database_exclude_patterns , optarg );
335+ break ;
336+
327337 default :
328338 fprintf (stderr , _ ("Try \"%s --help\" for more information.\n" ), progname );
329339 exit_nicely (1 );
@@ -340,6 +350,16 @@ main(int argc, char *argv[])
340350 exit_nicely (1 );
341351 }
342352
353+ if (database_exclude_patterns .head != NULL &&
354+ (globals_only || roles_only || tablespaces_only ))
355+ {
356+ fprintf (stderr , _ ("%s: option --exclude-database cannot be used together with -g/--globals-only, -r/--roles-only or -t/--tablespaces-only\n" ),
357+ progname );
358+ fprintf (stderr , _ ("Try \"%s --help\" for more information.\n" ),
359+ progname );
360+ exit_nicely (1 );
361+ }
362+
343363 /* Make sure the user hasn't specified a mix of globals-only options */
344364 if (globals_only && roles_only )
345365 {
@@ -454,6 +474,12 @@ main(int argc, char *argv[])
454474 }
455475 }
456476
477+ /*
478+ * Get a list of database names that match the exclude patterns
479+ */
480+ expand_dbname_patterns (conn , & database_exclude_patterns ,
481+ & database_exclude_names );
482+
457483 /*
458484 * Open the output file if required, otherwise use stdout
459485 */
@@ -620,6 +646,7 @@ help(void)
620646 printf (_ (" --column-inserts dump data as INSERT commands with column names\n" ));
621647 printf (_ (" --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n" ));
622648 printf (_ (" --disable-triggers disable triggers during data-only restore\n" ));
649+ printf (_ (" --exclude-database=PATTERN exclude databases whose name matches PATTERN\n" ));
623650 printf (_ (" --extra-float-digits=NUM override default setting for extra_float_digits\n" ));
624651 printf (_ (" --if-exists use IF EXISTS when dropping objects\n" ));
625652 printf (_ (" --inserts dump data as INSERT commands, rather than COPY\n" ));
@@ -1358,6 +1385,48 @@ dumpUserConfig(PGconn *conn, const char *username)
13581385 destroyPQExpBuffer (buf );
13591386}
13601387
1388+ /*
1389+ * Find a list of database names that match the given patterns.
1390+ * See also expand_table_name_patterns() in pg_dump.c
1391+ */
1392+ static void
1393+ expand_dbname_patterns (PGconn * conn ,
1394+ SimpleStringList * patterns ,
1395+ SimpleStringList * names )
1396+ {
1397+ PQExpBuffer query ;
1398+ PGresult * res ;
1399+
1400+ if (patterns -> head == NULL )
1401+ return ; /* nothing to do */
1402+
1403+ query = createPQExpBuffer ();
1404+
1405+ /*
1406+ * The loop below runs multiple SELECTs, which might sometimes result in
1407+ * duplicate entries in the name list, but we don't care, since all
1408+ * we're going to do is test membership of the list.
1409+ */
1410+
1411+ for (SimpleStringListCell * cell = patterns -> head ; cell ; cell = cell -> next )
1412+ {
1413+ appendPQExpBuffer (query ,
1414+ "SELECT datname FROM pg_catalog.pg_database n\n" );
1415+ processSQLNamePattern (conn , query , cell -> val , false,
1416+ false, NULL , "datname" , NULL , NULL );
1417+
1418+ res = executeQuery (conn , query -> data );
1419+ for (int i = 0 ; i < PQntuples (res ); i ++ )
1420+ {
1421+ simple_string_list_append (names , PQgetvalue (res , i , 0 ));
1422+ }
1423+
1424+ PQclear (res );
1425+ resetPQExpBuffer (query );
1426+ }
1427+
1428+ destroyPQExpBuffer (query );
1429+ }
13611430
13621431/*
13631432 * Dump contents of databases.
@@ -1395,6 +1464,15 @@ dumpDatabases(PGconn *conn)
13951464 if (strcmp (dbname , "template0" ) == 0 )
13961465 continue ;
13971466
1467+ /* Skip any explicitly excluded database */
1468+ if (simple_string_list_member (& database_exclude_names , dbname ))
1469+ {
1470+ if (verbose )
1471+ fprintf (stderr , _ ("%s: excluding database \"%s\"...\n" ),
1472+ progname , dbname );
1473+ continue ;
1474+ }
1475+
13981476 if (verbose )
13991477 fprintf (stderr , _ ("%s: dumping database \"%s\"...\n" ), progname , dbname );
14001478
0 commit comments