From de22c8c0060512d1a9add03b6eb4265767fb061b Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathan@postgresql.org>
Date: Wed, 28 Jun 2023 15:12:58 -0700
Subject: [PATCH v2 2/3] clusterdb: allow specifying tables to process in all
 databases

---
 src/bin/scripts/clusterdb.c            | 28 +++++++++++++++++---------
 src/bin/scripts/t/011_clusterdb_all.pl | 11 ++++++++++
 2 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/src/bin/scripts/clusterdb.c b/src/bin/scripts/clusterdb.c
index 65428031c7..89f1e733fe 100644
--- a/src/bin/scripts/clusterdb.c
+++ b/src/bin/scripts/clusterdb.c
@@ -21,8 +21,9 @@
 
 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 cluster_all_databases(ConnParams *cparams, SimpleStringList *tables,
+								  const char *progname, bool verbose, bool echo,
+								  bool quiet);
 static void help(const char *progname);
 
 
@@ -147,12 +148,10 @@ main(int argc, char *argv[])
 		if (dbname)
 			pg_fatal("cannot cluster all databases and a specific one at the same time");
 
-		if (tables.head != NULL)
-			pg_fatal("cannot cluster specific table(s) in all databases");
-
 		cparams.dbname = maintenance_db;
 
-		cluster_all_databases(&cparams, progname, verbose, echo, quiet);
+		cluster_all_databases(&cparams, &tables,
+							  progname, verbose, echo, quiet);
 	}
 	else
 	{
@@ -226,8 +225,9 @@ cluster_one_database(const ConnParams *cparams, const char *table,
 
 
 static void
-cluster_all_databases(ConnParams *cparams, const char *progname,
-					  bool verbose, bool echo, bool quiet)
+cluster_all_databases(ConnParams *cparams, SimpleStringList *tables,
+					  const char *progname, bool verbose, bool echo,
+					  bool quiet)
 {
 	PGconn	   *conn;
 	PGresult   *result;
@@ -251,7 +251,17 @@ cluster_all_databases(ConnParams *cparams, const char *progname,
 
 		cparams->override_dbname = dbname;
 
-		cluster_one_database(cparams, NULL, progname, verbose, echo);
+		if (tables->head != NULL)
+		{
+			SimpleStringListCell *cell;
+
+			for (cell = tables->head; cell; cell = cell->next)
+				cluster_one_database(cparams, cell->val,
+									 progname, verbose, echo);
+		}
+		else
+			cluster_one_database(cparams, NULL,
+								 progname, verbose, echo);
 	}
 
 	PQclear(result);
diff --git a/src/bin/scripts/t/011_clusterdb_all.pl b/src/bin/scripts/t/011_clusterdb_all.pl
index 35f0b18f50..e1c06203a1 100644
--- a/src/bin/scripts/t/011_clusterdb_all.pl
+++ b/src/bin/scripts/t/011_clusterdb_all.pl
@@ -35,4 +35,15 @@ $node->command_fails_like([ 'clusterdb', '-d', 'regression_invalid'],
   qr/FATAL:  cannot connect to invalid database "regression_invalid"/,
   'clusterdb cannot target invalid database');
 
+$node->safe_psql('postgres',
+	'CREATE TABLE test1 (a int); CREATE INDEX test1x ON test1 (a); CLUSTER test1 USING test1x'
+);
+$node->safe_psql('template1',
+	'CREATE TABLE test1 (a int); CREATE INDEX test1x ON test1 (a); CLUSTER test1 USING test1x'
+);
+$node->issues_sql_like(
+	[ 'clusterdb', '-a', '-t', 'test1' ],
+	qr/statement: CLUSTER public\.test1/s,
+	'cluster specific table in all databases');
+
 done_testing();
-- 
2.25.1

