From 102a1146b421dd0218d61586d2b4b65e5dc4cd86 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Mon, 8 Jul 2024 21:12:49 -0500 Subject: [PATCH v4 09/12] parallelize user defined postfix ops check in pg_upgrade --- src/bin/pg_upgrade/check.c | 134 +++++++++++++++++++------------------ 1 file changed, 69 insertions(+), 65 deletions(-) diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index beb3fc9433..6b61db65c5 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -1282,15 +1282,79 @@ check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster) check_ok(); } +static char * +user_defined_postfix_ops_query(DbInfo *dbinfo, void *arg) +{ + /* + * 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. + */ + return pg_strdup("SELECT o.oid AS oproid, " + " n.nspname AS oprnsp, " + " o.oprname, " + " tn.nspname AS typnsp, " + " t.typname " + "FROM pg_catalog.pg_operator o, " + " pg_catalog.pg_namespace n, " + " pg_catalog.pg_type t, " + " pg_catalog.pg_namespace tn " + "WHERE o.oprnamespace = n.oid AND " + " o.oprleft = t.oid AND " + " t.typnamespace = tn.oid AND " + " o.oprright = 0 AND " + " o.oid >= 16384"); +} + +static void +user_defined_postfix_ops_process(DbInfo *dbinfo, PGresult *res, void *arg) +{ + FILE **script = (FILE **) arg; + char output_path[MAXPGPATH]; + int ntups = PQntuples(res); + bool db_used = false; + int i_oproid = PQfnumber(res, "oproid"); + int i_oprnsp = PQfnumber(res, "oprnsp"); + int i_oprname = PQfnumber(res, "oprname"); + int i_typnsp = PQfnumber(res, "typnsp"); + int i_typname = PQfnumber(res, "typname"); + + if (!ntups) + return; + + snprintf(output_path, sizeof(output_path), "%s/%s", + log_opts.basedir, + "postfix_ops.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 (%s.%s, NONE)\n", + PQgetvalue(res, rowno, i_oproid), + PQgetvalue(res, rowno, i_oprnsp), + PQgetvalue(res, rowno, i_oprname), + PQgetvalue(res, rowno, i_typnsp), + PQgetvalue(res, rowno, i_typname)); + } +} + /* * Verify that no user defined postfix operators exist. */ static void check_for_user_defined_postfix_ops(ClusterInfo *cluster) { - int dbnum; FILE *script = NULL; char output_path[MAXPGPATH]; + AsyncTask *task = async_task_create(); prep_status("Checking for user-defined postfix operators"); @@ -1298,70 +1362,10 @@ check_for_user_defined_postfix_ops(ClusterInfo *cluster) log_opts.basedir, "postfix_ops.txt"); - /* Find any user defined postfix operators */ - for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++) - { - PGresult *res; - bool db_used = false; - int ntups; - int rowno; - int i_oproid, - i_oprnsp, - i_oprname, - i_typnsp, - i_typname; - 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 o.oid AS oproid, " - " n.nspname AS oprnsp, " - " o.oprname, " - " tn.nspname AS typnsp, " - " t.typname " - "FROM pg_catalog.pg_operator o, " - " pg_catalog.pg_namespace n, " - " pg_catalog.pg_type t, " - " pg_catalog.pg_namespace tn " - "WHERE o.oprnamespace = n.oid AND " - " o.oprleft = t.oid AND " - " t.typnamespace = tn.oid AND " - " o.oprright = 0 AND " - " o.oid >= 16384"); - ntups = PQntuples(res); - i_oproid = PQfnumber(res, "oproid"); - i_oprnsp = PQfnumber(res, "oprnsp"); - i_oprname = PQfnumber(res, "oprname"); - i_typnsp = PQfnumber(res, "typnsp"); - i_typname = PQfnumber(res, "typname"); - 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 (%s.%s, NONE)\n", - PQgetvalue(res, rowno, i_oproid), - PQgetvalue(res, rowno, i_oprnsp), - PQgetvalue(res, rowno, i_oprname), - PQgetvalue(res, rowno, i_typnsp), - PQgetvalue(res, rowno, i_typname)); - } - - PQclear(res); - - PQfinish(conn); - } + async_task_add_step(task, user_defined_postfix_ops_query, + user_defined_postfix_ops_process, true, &script); + async_task_run(task, cluster); + async_task_free(task); if (script) { -- 2.39.3 (Apple Git-146)