Skip to content

Commit bb584e8

Browse files
committed
Fix dependency of partitioned table and table AM with CREATE TABLE .. USING
A pg_depend entry between a partitioned table and its table access method was missing when using CREATE TABLE .. USING with an unpinned access method. DROP ACCESS METHOD could be used, while it should be blocked if CASCADE is not specified, even if there was a partitioned table that depends on the table access method. pg_class.relam would then hold an orphaned OID value still pointing to the AM dropped. The problem is fixed by adding a dependency between the partitioned table and its table access method if set when the relation is created. A test checking the contents of pg_depend in this case is added. Issue introduced in 374c7a2, that has added support for CREATE TABLE .. USING for partitioned tables. Reviewed-by: Alexander Lakhin Discussion: https://postgr.es/m/18674-1ef01eceec278fab@postgresql.org Backpatch-through: 17
1 parent e631ed8 commit bb584e8

File tree

3 files changed

+28
-2
lines changed

3 files changed

+28
-2
lines changed

src/backend/catalog/heap.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1470,9 +1470,11 @@ heap_create_with_catalog(const char *relname,
14701470
* access method is.
14711471
*
14721472
* No need to add an explicit dependency for the toast table, as the
1473-
* main table depends on it.
1473+
* main table depends on it. Partitioned tables may not have an
1474+
* access method set.
14741475
*/
1475-
if (RELKIND_HAS_TABLE_AM(relkind) && relkind != RELKIND_TOASTVALUE)
1476+
if ((RELKIND_HAS_TABLE_AM(relkind) && relkind != RELKIND_TOASTVALUE) ||
1477+
(relkind == RELKIND_PARTITIONED_TABLE && OidIsValid(accessmtd)))
14761478
{
14771479
ObjectAddressSet(referenced, AccessMethodRelationId, accessmtd);
14781480
add_exact_object_address(&referenced, addrs);

src/test/regress/expected/create_am.out

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,20 @@ ALTER MATERIALIZED VIEW heapmv SET ACCESS METHOD heap, SET ACCESS METHOD heap2;
343343
ERROR: cannot have multiple SET ACCESS METHOD subcommands
344344
DROP MATERIALIZED VIEW heapmv;
345345
DROP TABLE heaptable;
346+
-- Partitioned table with USING
347+
CREATE TABLE am_partitioned(x INT, y INT) PARTITION BY hash (x) USING heap2;
348+
SELECT pg_describe_object(classid, objid, objsubid) AS obj,
349+
pg_describe_object(refclassid, refobjid, refobjsubid) as refobj
350+
FROM pg_depend, pg_am
351+
WHERE pg_depend.refclassid = 'pg_am'::regclass
352+
AND pg_am.oid = pg_depend.refobjid
353+
AND pg_depend.objid = 'am_partitioned'::regclass;
354+
obj | refobj
355+
----------------------+---------------------
356+
table am_partitioned | access method heap2
357+
(1 row)
358+
359+
DROP TABLE am_partitioned;
346360
-- Partition hierarchies with access methods
347361
BEGIN;
348362
SET LOCAL default_table_access_method = 'heap';

src/test/regress/sql/create_am.sql

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,16 @@ ALTER MATERIALIZED VIEW heapmv SET ACCESS METHOD heap, SET ACCESS METHOD heap2;
217217
DROP MATERIALIZED VIEW heapmv;
218218
DROP TABLE heaptable;
219219

220+
-- Partitioned table with USING
221+
CREATE TABLE am_partitioned(x INT, y INT) PARTITION BY hash (x) USING heap2;
222+
SELECT pg_describe_object(classid, objid, objsubid) AS obj,
223+
pg_describe_object(refclassid, refobjid, refobjsubid) as refobj
224+
FROM pg_depend, pg_am
225+
WHERE pg_depend.refclassid = 'pg_am'::regclass
226+
AND pg_am.oid = pg_depend.refobjid
227+
AND pg_depend.objid = 'am_partitioned'::regclass;
228+
DROP TABLE am_partitioned;
229+
220230
-- Partition hierarchies with access methods
221231
BEGIN;
222232
SET LOCAL default_table_access_method = 'heap';

0 commit comments

Comments
 (0)