mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-02-23 19:39:53 +08:00
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 374c7a2290
, 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
This commit is contained in:
parent
70b9adb98e
commit
49a23441ca
@ -1471,9 +1471,11 @@ heap_create_with_catalog(const char *relname,
|
||||
* access method is.
|
||||
*
|
||||
* No need to add an explicit dependency for the toast table, as the
|
||||
* main table depends on it.
|
||||
* main table depends on it. Partitioned tables may not have an
|
||||
* access method set.
|
||||
*/
|
||||
if (RELKIND_HAS_TABLE_AM(relkind) && relkind != RELKIND_TOASTVALUE)
|
||||
if ((RELKIND_HAS_TABLE_AM(relkind) && relkind != RELKIND_TOASTVALUE) ||
|
||||
(relkind == RELKIND_PARTITIONED_TABLE && OidIsValid(accessmtd)))
|
||||
{
|
||||
ObjectAddressSet(referenced, AccessMethodRelationId, accessmtd);
|
||||
add_exact_object_address(&referenced, addrs);
|
||||
|
@ -343,6 +343,20 @@ ALTER MATERIALIZED VIEW heapmv SET ACCESS METHOD heap, SET ACCESS METHOD heap2;
|
||||
ERROR: cannot have multiple SET ACCESS METHOD subcommands
|
||||
DROP MATERIALIZED VIEW heapmv;
|
||||
DROP TABLE heaptable;
|
||||
-- Partitioned table with USING
|
||||
CREATE TABLE am_partitioned(x INT, y INT) PARTITION BY hash (x) USING heap2;
|
||||
SELECT pg_describe_object(classid, objid, objsubid) AS obj,
|
||||
pg_describe_object(refclassid, refobjid, refobjsubid) as refobj
|
||||
FROM pg_depend, pg_am
|
||||
WHERE pg_depend.refclassid = 'pg_am'::regclass
|
||||
AND pg_am.oid = pg_depend.refobjid
|
||||
AND pg_depend.objid = 'am_partitioned'::regclass;
|
||||
obj | refobj
|
||||
----------------------+---------------------
|
||||
table am_partitioned | access method heap2
|
||||
(1 row)
|
||||
|
||||
DROP TABLE am_partitioned;
|
||||
-- Partition hierarchies with access methods
|
||||
BEGIN;
|
||||
SET LOCAL default_table_access_method = 'heap';
|
||||
|
@ -217,6 +217,16 @@ ALTER MATERIALIZED VIEW heapmv SET ACCESS METHOD heap, SET ACCESS METHOD heap2;
|
||||
DROP MATERIALIZED VIEW heapmv;
|
||||
DROP TABLE heaptable;
|
||||
|
||||
-- Partitioned table with USING
|
||||
CREATE TABLE am_partitioned(x INT, y INT) PARTITION BY hash (x) USING heap2;
|
||||
SELECT pg_describe_object(classid, objid, objsubid) AS obj,
|
||||
pg_describe_object(refclassid, refobjid, refobjsubid) as refobj
|
||||
FROM pg_depend, pg_am
|
||||
WHERE pg_depend.refclassid = 'pg_am'::regclass
|
||||
AND pg_am.oid = pg_depend.refobjid
|
||||
AND pg_depend.objid = 'am_partitioned'::regclass;
|
||||
DROP TABLE am_partitioned;
|
||||
|
||||
-- Partition hierarchies with access methods
|
||||
BEGIN;
|
||||
SET LOCAL default_table_access_method = 'heap';
|
||||
|
Loading…
Reference in New Issue
Block a user