From ab7ad308dfbf3d4587d88b5133b44c201b4569e2 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Tue, 27 Jun 2023 15:32:42 +0900 Subject: [PATCH v2] Fix dependencies under ALTER TABLE SET ACCESS METHOD --- src/backend/commands/cluster.c | 18 +++++++++++++++ src/test/regress/expected/create_am.out | 29 +++++++++++++++++++++++++ src/test/regress/sql/create_am.sql | 18 +++++++++++++++ 3 files changed, 65 insertions(+) diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c index 3bfabb6d10..88432a9518 100644 --- a/src/backend/commands/cluster.c +++ b/src/backend/commands/cluster.c @@ -1070,6 +1070,8 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class, relfilenumber2; RelFileNumber swaptemp; char swptmpchr; + Oid relam1, + relam2; /* We need writable copies of both pg_class tuples. */ relRelation = table_open(RelationRelationId, RowExclusiveLock); @@ -1086,6 +1088,8 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class, relfilenumber1 = relform1->relfilenode; relfilenumber2 = relform2->relfilenode; + relam1 = relform1->relam; + relam2 = relform2->relam; if (RelFileNumberIsValid(relfilenumber1) && RelFileNumberIsValid(relfilenumber2)) @@ -1257,6 +1261,20 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class, CacheInvalidateRelcacheByTuple(reltup2); } + /* + * Now that pg_class has been updated with its relevant information for + * the swap, update the dependency of the relation to point to its new + * table AM, if it has changed. + */ + if (relam1 != relam2) + { + changeDependencyFor(RelationRelationId, + r1, + AccessMethodRelationId, + relam1, + relam2); + } + /* * Post alter hook for modified relations. The change to r2 is always * internal, but r1 depends on the invocation context. diff --git a/src/test/regress/expected/create_am.out b/src/test/regress/expected/create_am.out index e9a9283d7a..4eec292e65 100644 --- a/src/test/regress/expected/create_am.out +++ b/src/test/regress/expected/create_am.out @@ -240,6 +240,35 @@ SELECT amname FROM pg_class c, pg_am am heap (1 row) +-- Switching to heap2 adds new dependency entry to the AM. +ALTER TABLE heaptable SET ACCESS METHOD heap2; +SELECT pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid,refobjid,refobjsubid) as objref, + deptype + FROM pg_depend + WHERE classid = 'pg_class'::regclass AND + objid = 'heaptable'::regclass + ORDER BY 1, 2; + obj | objref | deptype +-----------------+---------------------+--------- + table heaptable | access method heap2 | n + table heaptable | schema public | n +(2 rows) + +-- Switching to heap should not have a dependency entry to the AM. +ALTER TABLE heaptable SET ACCESS METHOD heap; +SELECT pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid,refobjid,refobjsubid) as objref, + deptype + FROM pg_depend + WHERE classid = 'pg_class'::regclass AND + objid = 'heaptable'::regclass + ORDER BY 1, 2; + obj | objref | deptype +-----------------+---------------+--------- + table heaptable | schema public | n +(1 row) + ALTER TABLE heaptable SET ACCESS METHOD heap2; SELECT amname FROM pg_class c, pg_am am WHERE c.relam = am.oid AND c.oid = 'heaptable'::regclass; diff --git a/src/test/regress/sql/create_am.sql b/src/test/regress/sql/create_am.sql index 256884c959..f1c809b8e0 100644 --- a/src/test/regress/sql/create_am.sql +++ b/src/test/regress/sql/create_am.sql @@ -166,6 +166,24 @@ CREATE TABLE heaptable USING heap AS SELECT a, repeat(a::text, 100) FROM generate_series(1,9) AS a; SELECT amname FROM pg_class c, pg_am am WHERE c.relam = am.oid AND c.oid = 'heaptable'::regclass; +-- Switching to heap2 adds new dependency entry to the AM. +ALTER TABLE heaptable SET ACCESS METHOD heap2; +SELECT pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid,refobjid,refobjsubid) as objref, + deptype + FROM pg_depend + WHERE classid = 'pg_class'::regclass AND + objid = 'heaptable'::regclass + ORDER BY 1, 2; +-- Switching to heap should not have a dependency entry to the AM. +ALTER TABLE heaptable SET ACCESS METHOD heap; +SELECT pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid,refobjid,refobjsubid) as objref, + deptype + FROM pg_depend + WHERE classid = 'pg_class'::regclass AND + objid = 'heaptable'::regclass + ORDER BY 1, 2; ALTER TABLE heaptable SET ACCESS METHOD heap2; SELECT amname FROM pg_class c, pg_am am WHERE c.relam = am.oid AND c.oid = 'heaptable'::regclass; -- 2.40.1