diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index 9befe012a9..143941bb1b 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -617,6 +617,12 @@ heapam_relation_set_new_filenode(Relation rel, smgrclose(srel); } +static void +heapam_relation_reset_filenode(Relation rel) +{ + RelationDropStorage(rel); +} + static void heapam_relation_nontransactional_truncate(Relation rel) { @@ -2572,6 +2578,7 @@ static const TableAmRoutine heapam_methods = { .index_delete_tuples = heap_index_delete_tuples, .relation_set_new_filenode = heapam_relation_set_new_filenode, + .relation_reset_filenode = heapam_relation_reset_filenode, .relation_nontransactional_truncate = heapam_relation_nontransactional_truncate, .relation_copy_data = heapam_relation_copy_data, .relation_copy_for_cluster = heapam_relation_copy_for_cluster, diff --git a/src/backend/access/table/tableamapi.c b/src/backend/access/table/tableamapi.c index 325ecdc122..30e070383c 100644 --- a/src/backend/access/table/tableamapi.c +++ b/src/backend/access/table/tableamapi.c @@ -83,6 +83,7 @@ GetTableAmRoutine(Oid amhandler) Assert(routine->tuple_lock != NULL); Assert(routine->relation_set_new_filenode != NULL); + Assert(routine->relation_reset_filenode != NULL); Assert(routine->relation_nontransactional_truncate != NULL); Assert(routine->relation_copy_data != NULL); Assert(routine->relation_copy_for_cluster != NULL); diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 83746d3fd9..2a6670cc60 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -1997,7 +1997,28 @@ heap_drop_with_catalog(Oid relid) * Schedule unlinking of the relation's physical files at commit. */ if (RELKIND_HAS_STORAGE(rel->rd_rel->relkind)) - RelationDropStorage(rel); + switch (rel->rd_rel->relkind) + { + case RELKIND_VIEW: + case RELKIND_COMPOSITE_TYPE: + case RELKIND_FOREIGN_TABLE: + case RELKIND_PARTITIONED_TABLE: + case RELKIND_PARTITIONED_INDEX: + Assert(false); + break; + + case RELKIND_INDEX: + case RELKIND_SEQUENCE: + RelationDropStorage(rel); + break; + + case RELKIND_RELATION: + case RELKIND_TOASTVALUE: + case RELKIND_MATVIEW: + table_relation_reset_filenode(rel); + break; + + } /* * Close relcache entry, but *keep* AccessExclusiveLock on the relation diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index 9f1e4a1ac9..c56ae46ffc 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -579,6 +579,14 @@ typedef struct TableAmRoutine TransactionId *freezeXid, MultiXactId *minmulti); + /* + * This callback needs to schedule the removal of all associations with the + * relation `rel` since the relation is about to be dropped. + * + * See also table_relation_reset_filenode(). + */ + void (*relation_reset_filenode) (Relation rel); + /* * This callback needs to remove all contents from `rel`'s current * relfilenode. No provisions for transactional behaviour need to be made. @@ -1597,6 +1605,18 @@ table_relation_set_new_filenode(Relation rel, freezeXid, minmulti); } +/* + * Schedule the removal of all association with storage for the relation. + * + * This is used when a relation is about to be dropped and removed from the + * catalog. + */ +static inline void +table_relation_reset_filenode(Relation rel) +{ + rel->rd_tableam->relation_reset_filenode(rel); +} + /* * Remove all table contents from `rel`, in a non-transactional manner. * Non-transactional meaning that there's no need to support rollbacks. This