Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit135b601

Browse files
michaelpqpull[bot]
authored andcommitted
Fix pg_depend entry to AMs after ALTER TABLE .. SET ACCESS METHOD
ALTER TABLE .. SET ACCESS METHOD was not registering a dependency to thenew access method with the relation altered in its rewrite phase, makingpossible the drop of an access method even if there are relations thatdepend on it. During the rewrite, a temporary relation is created tobuild the new relation files before swapping the new and old files, and,while the temporary relation was registering a correct dependency to thenew AM, the old relation did not do that. A dependency on the accessmethod is added when the relation files are swapped, which is the pointwhere pg_class is updated.Materialized views and tables use the same code path, hence both wereimpacted.Backpatch down to 15, where this command has been introduced.Reported-by: Alexander LakhinReviewed-by: Nathan Bossart, Andres FreundDiscussion:https://postgr.es/m/18000-9145c25b1af475ca@postgresql.orgBackpatch-through: 15
1 parent12ea2d6 commit135b601

File tree

3 files changed

+76
-0
lines changed

3 files changed

+76
-0
lines changed

‎src/backend/commands/cluster.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,6 +1070,8 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class,
10701070
relfilenumber2;
10711071
RelFileNumberswaptemp;
10721072
charswptmpchr;
1073+
Oidrelam1,
1074+
relam2;
10731075

10741076
/* We need writable copies of both pg_class tuples. */
10751077
relRelation=table_open(RelationRelationId,RowExclusiveLock);
@@ -1086,6 +1088,8 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class,
10861088

10871089
relfilenumber1=relform1->relfilenode;
10881090
relfilenumber2=relform2->relfilenode;
1091+
relam1=relform1->relam;
1092+
relam2=relform2->relam;
10891093

10901094
if (RelFileNumberIsValid(relfilenumber1)&&
10911095
RelFileNumberIsValid(relfilenumber2))
@@ -1257,6 +1261,31 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class,
12571261
CacheInvalidateRelcacheByTuple(reltup2);
12581262
}
12591263

1264+
/*
1265+
* Now that pg_class has been updated with its relevant information for
1266+
* the swap, update the dependency of the relations to point to their new
1267+
* table AM, if it has changed.
1268+
*/
1269+
if (relam1!=relam2)
1270+
{
1271+
if (changeDependencyFor(RelationRelationId,
1272+
r1,
1273+
AccessMethodRelationId,
1274+
relam1,
1275+
relam2)!=1)
1276+
elog(ERROR,"failed to change access method dependency for relation \"%s.%s\"",
1277+
get_namespace_name(get_rel_namespace(r1)),
1278+
get_rel_name(r1));
1279+
if (changeDependencyFor(RelationRelationId,
1280+
r2,
1281+
AccessMethodRelationId,
1282+
relam2,
1283+
relam1)!=1)
1284+
elog(ERROR,"failed to change access method dependency for relation \"%s.%s\"",
1285+
get_namespace_name(get_rel_namespace(r2)),
1286+
get_rel_name(r2));
1287+
}
1288+
12601289
/*
12611290
* Post alter hook for modified relations. The change to r2 is always
12621291
* internal, but r1 depends on the invocation context.

‎src/test/regress/expected/create_am.out

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,35 @@ SELECT amname FROM pg_class c, pg_am am
240240
heap
241241
(1 row)
242242

243+
-- Switching to heap2 adds new dependency entry to the AM.
244+
ALTER TABLE heaptable SET ACCESS METHOD heap2;
245+
SELECT pg_describe_object(classid, objid, objsubid) as obj,
246+
pg_describe_object(refclassid, refobjid, refobjsubid) as objref,
247+
deptype
248+
FROM pg_depend
249+
WHERE classid = 'pg_class'::regclass AND
250+
objid = 'heaptable'::regclass
251+
ORDER BY 1, 2;
252+
obj | objref | deptype
253+
-----------------+---------------------+---------
254+
table heaptable | access method heap2 | n
255+
table heaptable | schema public | n
256+
(2 rows)
257+
258+
-- Switching to heap should not have a dependency entry to the AM.
259+
ALTER TABLE heaptable SET ACCESS METHOD heap;
260+
SELECT pg_describe_object(classid, objid, objsubid) as obj,
261+
pg_describe_object(refclassid, refobjid, refobjsubid) as objref,
262+
deptype
263+
FROM pg_depend
264+
WHERE classid = 'pg_class'::regclass AND
265+
objid = 'heaptable'::regclass
266+
ORDER BY 1, 2;
267+
obj | objref | deptype
268+
-----------------+---------------+---------
269+
table heaptable | schema public | n
270+
(1 row)
271+
243272
ALTER TABLE heaptable SET ACCESS METHOD heap2;
244273
SELECT amname FROM pg_class c, pg_am am
245274
WHERE c.relam = am.oid AND c.oid = 'heaptable'::regclass;

‎src/test/regress/sql/create_am.sql

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,24 @@ CREATE TABLE heaptable USING heap AS
166166
SELECT a, repeat(a::text,100)FROM generate_series(1,9)AS a;
167167
SELECT amnameFROM pg_class c, pg_am am
168168
WHEREc.relam=am.oidANDc.oid='heaptable'::regclass;
169+
-- Switching to heap2 adds new dependency entry to the AM.
170+
ALTERTABLE heaptableSET ACCESS METHOD heap2;
171+
SELECT pg_describe_object(classid, objid, objsubid)as obj,
172+
pg_describe_object(refclassid, refobjid, refobjsubid)as objref,
173+
deptype
174+
FROM pg_depend
175+
WHERE classid='pg_class'::regclassAND
176+
objid='heaptable'::regclass
177+
ORDER BY1,2;
178+
-- Switching to heap should not have a dependency entry to the AM.
179+
ALTERTABLE heaptableSET ACCESS METHOD heap;
180+
SELECT pg_describe_object(classid, objid, objsubid)as obj,
181+
pg_describe_object(refclassid, refobjid, refobjsubid)as objref,
182+
deptype
183+
FROM pg_depend
184+
WHERE classid='pg_class'::regclassAND
185+
objid='heaptable'::regclass
186+
ORDER BY1,2;
169187
ALTERTABLE heaptableSET ACCESS METHOD heap2;
170188
SELECT amnameFROM pg_class c, pg_am am
171189
WHEREc.relam=am.oidANDc.oid='heaptable'::regclass;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp