From b3071c2c4bf29e09b996ecdf581056fd665b3f17 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathan@postgresql.org>
Date: Mon, 8 Jul 2024 21:52:13 -0500
Subject: [PATCH v8 11/11] parallelize user defined encoding conversions check
 in pg_upgrade

---
 src/bin/pg_upgrade/check.c | 102 +++++++++++++++++++------------------
 1 file changed, 53 insertions(+), 49 deletions(-)

diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c
index 4156257843..6910d18713 100644
--- a/src/bin/pg_upgrade/check.c
+++ b/src/bin/pg_upgrade/check.c
@@ -1652,15 +1652,51 @@ check_for_pg_role_prefix(ClusterInfo *cluster)
 		check_ok();
 }
 
+static void
+user_defined_encoding_conversions_process(DbInfo *dbinfo, PGresult *res, void *arg)
+{
+	FILE	  **script = (FILE **) arg;
+	bool		db_used = false;
+	int			ntups = PQntuples(res);
+	char		output_path[MAXPGPATH];
+	int			i_conoid = PQfnumber(res, "conoid");
+	int			i_conname = PQfnumber(res, "conname");
+	int			i_nspname = PQfnumber(res, "nspname");
+
+	if (!ntups)
+		return;
+
+	snprintf(output_path, sizeof(output_path), "%s/%s",
+			 log_opts.basedir,
+			 "encoding_conversions.txt");
+
+	for (int rowno = 0; rowno < ntups; rowno++)
+	{
+		if (*script == NULL &&
+			(*script = fopen_priv(output_path, "w")) == NULL)
+			pg_fatal("could not open file \"%s\": %m", output_path);
+		if (!db_used)
+		{
+			fprintf(*script, "In database: %s\n", dbinfo->db_name);
+			db_used = true;
+		}
+		fprintf(*script, "  (oid=%s) %s.%s\n",
+				PQgetvalue(res, rowno, i_conoid),
+				PQgetvalue(res, rowno, i_nspname),
+				PQgetvalue(res, rowno, i_conname));
+	}
+}
+
 /*
  * Verify that no user-defined encoding conversions exist.
  */
 static void
 check_for_user_defined_encoding_conversions(ClusterInfo *cluster)
 {
-	int			dbnum;
 	FILE	   *script = NULL;
 	char		output_path[MAXPGPATH];
+	AsyncTask  *task = async_task_create();
+	const char *query;
 
 	prep_status("Checking for user-defined encoding conversions");
 
@@ -1668,55 +1704,23 @@ check_for_user_defined_encoding_conversions(ClusterInfo *cluster)
 			 log_opts.basedir,
 			 "encoding_conversions.txt");
 
-	/* Find any user defined encoding conversions */
-	for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
-	{
-		PGresult   *res;
-		bool		db_used = false;
-		int			ntups;
-		int			rowno;
-		int			i_conoid,
-					i_conname,
-					i_nspname;
-		DbInfo	   *active_db = &cluster->dbarr.dbs[dbnum];
-		PGconn	   *conn = connectToServer(cluster, active_db->db_name);
-
-		/*
-		 * The query below hardcodes FirstNormalObjectId as 16384 rather than
-		 * interpolating that C #define into the query because, if that
-		 * #define is ever changed, the cutoff we want to use is the value
-		 * used by pre-version 14 servers, not that of some future version.
-		 */
-		res = executeQueryOrDie(conn,
-								"SELECT c.oid as conoid, c.conname, n.nspname "
-								"FROM pg_catalog.pg_conversion c, "
-								"     pg_catalog.pg_namespace n "
-								"WHERE c.connamespace = n.oid AND "
-								"      c.oid >= 16384");
-		ntups = PQntuples(res);
-		i_conoid = PQfnumber(res, "conoid");
-		i_conname = PQfnumber(res, "conname");
-		i_nspname = PQfnumber(res, "nspname");
-		for (rowno = 0; rowno < ntups; rowno++)
-		{
-			if (script == NULL &&
-				(script = fopen_priv(output_path, "w")) == NULL)
-				pg_fatal("could not open file \"%s\": %m", output_path);
-			if (!db_used)
-			{
-				fprintf(script, "In database: %s\n", active_db->db_name);
-				db_used = true;
-			}
-			fprintf(script, "  (oid=%s) %s.%s\n",
-					PQgetvalue(res, rowno, i_conoid),
-					PQgetvalue(res, rowno, i_nspname),
-					PQgetvalue(res, rowno, i_conname));
-		}
-
-		PQclear(res);
+	/*
+	 * The query below hardcodes FirstNormalObjectId as 16384 rather than
+	 * interpolating that C #define into the query because, if that #define is
+	 * ever changed, the cutoff we want to use is the value used by
+	 * pre-version 14 servers, not that of some future version.
+	 */
+	query = "SELECT c.oid as conoid, c.conname, n.nspname "
+		"FROM pg_catalog.pg_conversion c, "
+		"     pg_catalog.pg_namespace n "
+		"WHERE c.connamespace = n.oid AND "
+		"      c.oid >= 16384";
 
-		PQfinish(conn);
-	}
+	async_task_add_step(task, query,
+						user_defined_encoding_conversions_process, true,
+						&script);
+	async_task_run(task, cluster);
+	async_task_free(task);
 
 	if (script)
 	{
-- 
2.39.3 (Apple Git-146)

