Skip to content

Commit c34eabf

Browse files
pg_upgrade: Parallelize postfix operator check.
This commit makes use of the new task framework in pg_upgrade to parallelize the check for user-defined postfix operators. This step will now process multiple databases concurrently when pg_upgrade's --jobs option is provided a value greater than 1. Reviewed-by: Daniel Gustafsson, Ilya Gladyshev Discussion: https://postgr.es/m/20240516211638.GA1688936%40nathanxps13
1 parent 9db3018 commit c34eabf

File tree

1 file changed

+75
-71
lines changed

1 file changed

+75
-71
lines changed

src/bin/pg_upgrade/check.c

Lines changed: 75 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,95 +1315,99 @@ check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
13151315
}
13161316

13171317
/*
1318-
* Verify that no user defined postfix operators exist.
1318+
* Callback function for processing result of query for
1319+
* check_for_user_defined_postfix_ops()'s UpgradeTask. If the query returned
1320+
* any rows (i.e., the check failed), write the details to the report file.
13191321
*/
13201322
static void
1321-
check_for_user_defined_postfix_ops(ClusterInfo *cluster)
1323+
process_user_defined_postfix_ops(DbInfo *dbinfo, PGresult *res, void *arg)
13221324
{
1323-
int dbnum;
1324-
FILE *script = NULL;
1325-
char output_path[MAXPGPATH];
1325+
UpgradeTaskReport *report = (UpgradeTaskReport *) arg;
1326+
int ntups = PQntuples(res);
1327+
bool db_used = false;
1328+
int i_oproid = PQfnumber(res, "oproid");
1329+
int i_oprnsp = PQfnumber(res, "oprnsp");
1330+
int i_oprname = PQfnumber(res, "oprname");
1331+
int i_typnsp = PQfnumber(res, "typnsp");
1332+
int i_typname = PQfnumber(res, "typname");
13261333

1327-
prep_status("Checking for user-defined postfix operators");
1334+
AssertVariableIsOfType(&process_user_defined_postfix_ops,
1335+
UpgradeTaskProcessCB);
13281336

1329-
snprintf(output_path, sizeof(output_path), "%s/%s",
1330-
log_opts.basedir,
1331-
"postfix_ops.txt");
1337+
if (!ntups)
1338+
return;
13321339

1333-
/* Find any user defined postfix operators */
1334-
for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
1340+
for (int rowno = 0; rowno < ntups; rowno++)
13351341
{
1336-
PGresult *res;
1337-
bool db_used = false;
1338-
int ntups;
1339-
int rowno;
1340-
int i_oproid,
1341-
i_oprnsp,
1342-
i_oprname,
1343-
i_typnsp,
1344-
i_typname;
1345-
DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
1346-
PGconn *conn = connectToServer(cluster, active_db->db_name);
1347-
1348-
/*
1349-
* The query below hardcodes FirstNormalObjectId as 16384 rather than
1350-
* interpolating that C #define into the query because, if that
1351-
* #define is ever changed, the cutoff we want to use is the value
1352-
* used by pre-version 14 servers, not that of some future version.
1353-
*/
1354-
res = executeQueryOrDie(conn,
1355-
"SELECT o.oid AS oproid, "
1356-
" n.nspname AS oprnsp, "
1357-
" o.oprname, "
1358-
" tn.nspname AS typnsp, "
1359-
" t.typname "
1360-
"FROM pg_catalog.pg_operator o, "
1361-
" pg_catalog.pg_namespace n, "
1362-
" pg_catalog.pg_type t, "
1363-
" pg_catalog.pg_namespace tn "
1364-
"WHERE o.oprnamespace = n.oid AND "
1365-
" o.oprleft = t.oid AND "
1366-
" t.typnamespace = tn.oid AND "
1367-
" o.oprright = 0 AND "
1368-
" o.oid >= 16384");
1369-
ntups = PQntuples(res);
1370-
i_oproid = PQfnumber(res, "oproid");
1371-
i_oprnsp = PQfnumber(res, "oprnsp");
1372-
i_oprname = PQfnumber(res, "oprname");
1373-
i_typnsp = PQfnumber(res, "typnsp");
1374-
i_typname = PQfnumber(res, "typname");
1375-
for (rowno = 0; rowno < ntups; rowno++)
1342+
if (report->file == NULL &&
1343+
(report->file = fopen_priv(report->path, "w")) == NULL)
1344+
pg_fatal("could not open file \"%s\": %m", report->path);
1345+
if (!db_used)
13761346
{
1377-
if (script == NULL &&
1378-
(script = fopen_priv(output_path, "w")) == NULL)
1379-
pg_fatal("could not open file \"%s\": %m", output_path);
1380-
if (!db_used)
1381-
{
1382-
fprintf(script, "In database: %s\n", active_db->db_name);
1383-
db_used = true;
1384-
}
1385-
fprintf(script, " (oid=%s) %s.%s (%s.%s, NONE)\n",
1386-
PQgetvalue(res, rowno, i_oproid),
1387-
PQgetvalue(res, rowno, i_oprnsp),
1388-
PQgetvalue(res, rowno, i_oprname),
1389-
PQgetvalue(res, rowno, i_typnsp),
1390-
PQgetvalue(res, rowno, i_typname));
1347+
fprintf(report->file, "In database: %s\n", dbinfo->db_name);
1348+
db_used = true;
13911349
}
1350+
fprintf(report->file, " (oid=%s) %s.%s (%s.%s, NONE)\n",
1351+
PQgetvalue(res, rowno, i_oproid),
1352+
PQgetvalue(res, rowno, i_oprnsp),
1353+
PQgetvalue(res, rowno, i_oprname),
1354+
PQgetvalue(res, rowno, i_typnsp),
1355+
PQgetvalue(res, rowno, i_typname));
1356+
}
1357+
}
13921358

1393-
PQclear(res);
1359+
/*
1360+
* Verify that no user defined postfix operators exist.
1361+
*/
1362+
static void
1363+
check_for_user_defined_postfix_ops(ClusterInfo *cluster)
1364+
{
1365+
UpgradeTaskReport report;
1366+
UpgradeTask *task = upgrade_task_create();
1367+
const char *query;
13941368

1395-
PQfinish(conn);
1396-
}
1369+
/*
1370+
* The query below hardcodes FirstNormalObjectId as 16384 rather than
1371+
* interpolating that C #define into the query because, if that #define is
1372+
* ever changed, the cutoff we want to use is the value used by
1373+
* pre-version 14 servers, not that of some future version.
1374+
*/
1375+
query = "SELECT o.oid AS oproid, "
1376+
" n.nspname AS oprnsp, "
1377+
" o.oprname, "
1378+
" tn.nspname AS typnsp, "
1379+
" t.typname "
1380+
"FROM pg_catalog.pg_operator o, "
1381+
" pg_catalog.pg_namespace n, "
1382+
" pg_catalog.pg_type t, "
1383+
" pg_catalog.pg_namespace tn "
1384+
"WHERE o.oprnamespace = n.oid AND "
1385+
" o.oprleft = t.oid AND "
1386+
" t.typnamespace = tn.oid AND "
1387+
" o.oprright = 0 AND "
1388+
" o.oid >= 16384";
13971389

1398-
if (script)
1390+
prep_status("Checking for user-defined postfix operators");
1391+
1392+
report.file = NULL;
1393+
snprintf(report.path, sizeof(report.path), "%s/%s",
1394+
log_opts.basedir,
1395+
"postfix_ops.txt");
1396+
1397+
upgrade_task_add_step(task, query, process_user_defined_postfix_ops,
1398+
true, &report);
1399+
upgrade_task_run(task, cluster);
1400+
upgrade_task_free(task);
1401+
1402+
if (report.file)
13991403
{
1400-
fclose(script);
1404+
fclose(report.file);
14011405
pg_log(PG_REPORT, "fatal");
14021406
pg_fatal("Your installation contains user-defined postfix operators, which are not\n"
14031407
"supported anymore. Consider dropping the postfix operators and replacing\n"
14041408
"them with prefix operators or function calls.\n"
14051409
"A list of user-defined postfix operators is in the file:\n"
1406-
" %s", output_path);
1410+
" %s", report.path);
14071411
}
14081412
else
14091413
check_ok();

0 commit comments

Comments
 (0)