Switch query fixing aclitems in ~15 from O(N^2) to O(N) in upgrade_adapt.sql
authorMichael Paquier <michael@paquier.xyz>
Sun, 25 Dec 2022 23:00:55 +0000 (08:00 +0900)
committerMichael Paquier <michael@paquier.xyz>
Sun, 25 Dec 2022 23:00:55 +0000 (08:00 +0900)
f4f2f2b was doing a sequential scan of pg_class before checking if a
relation had attributes dependent on aclitem as data typewhen building
the set of ALTER TABLE queries, but it would be costly on a regression
database.

While on it, make the query style more consistent with the rest.

Reported-by: Justin Pryzby
Discussion: https://postgr.es/m/20221223032724.GQ1153@telsasoft.com

src/bin/pg_upgrade/upgrade_adapt.sql

index 54920f54f512cf45c9c69f40a26b549cf8218ca9..a368a51ff5e8229b717164ec5a8ae0966355044b 100644 (file)
@@ -95,25 +95,21 @@ DROP OPERATOR public.#@%# (pg_catalog.int8, NONE);
 -- The internal format of "aclitem" has changed in 16, so replace it with
 -- text type in tables.
 \if :oldpgversion_le15
-DO $$
+DO $stmt$
   DECLARE
-    rec text;
-   col text;
+    rec record;
   BEGIN
   FOR rec in
-    SELECT oid::regclass::text
-    FROM pg_class
-    WHERE relname !~ '^pg_'
-      AND relkind IN ('r')
+    SELECT oid::regclass::text as rel, attname as col
+    FROM pg_class c, pg_attribute a
+    WHERE c.relname !~ '^pg_'
+      AND c.relkind IN ('r')
+      AND a.attrelid = c.oid
+      AND a.atttypid = 'aclitem'::regtype
     ORDER BY 1
   LOOP
-    FOR col in SELECT attname FROM pg_attribute
-      WHERE attrelid::regclass::text = rec
-      AND atttypid = 'aclitem'::regtype
-    LOOP
-      EXECUTE 'ALTER TABLE ' || quote_ident(rec) || ' ALTER COLUMN ' ||
-        quote_ident(col) || ' SET DATA TYPE text';
-    END LOOP;
+    EXECUTE 'ALTER TABLE ' || quote_ident(rec.rel) || ' ALTER COLUMN ' ||
+      quote_ident(rec.col) || ' SET DATA TYPE text';
   END LOOP;
-  END; $$;
+  END; $stmt$;
 \endif