From 0656f3959518bfa1bd03e8bea3028ccf69b1edad Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 16 Aug 2021 14:30:26 +0200 Subject: [PATCH v1 2/2] Some RELKIND macro refactoring Add more macros to group some RELKIND_* macros: - RELKIND_HAS_PARTITIONS() - RELKIND_HAS_TABLESPACE() - RELKIND_HAS_TABLE_AM() - RELKIND_HAS_INDEX_AM() --- contrib/amcheck/verify_heapam.c | 4 +- contrib/pg_surgery/heap_surgery.c | 4 +- contrib/pg_visibility/pg_visibility.c | 4 +- src/backend/access/index/indexam.c | 3 +- src/backend/catalog/heap.c | 146 +++++++++---------------- src/backend/catalog/index.c | 2 +- src/backend/commands/indexcmds.c | 9 +- src/backend/commands/tablecmds.c | 8 +- src/backend/storage/buffer/bufmgr.c | 42 +++---- src/backend/utils/adt/amutils.c | 3 +- src/backend/utils/adt/partitionfuncs.c | 7 +- src/backend/utils/cache/relcache.c | 89 +++++---------- src/bin/pg_dump/pg_dump.c | 17 ++- src/include/catalog/pg_class.h | 33 ++++++ 14 files changed, 153 insertions(+), 218 deletions(-) diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 226271923a..1e9624b84d 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -303,9 +303,7 @@ verify_heapam(PG_FUNCTION_ARGS) /* * Check that a relation's relkind and access method are both supported. */ - if (ctx.rel->rd_rel->relkind != RELKIND_RELATION && - ctx.rel->rd_rel->relkind != RELKIND_MATVIEW && - ctx.rel->rd_rel->relkind != RELKIND_TOASTVALUE) + if (!RELKIND_HAS_TABLE_AM(ctx.rel->rd_rel->relkind)) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("cannot check relation \"%s\"", diff --git a/contrib/pg_surgery/heap_surgery.c b/contrib/pg_surgery/heap_surgery.c index 7edfe4f326..f06385e8d3 100644 --- a/contrib/pg_surgery/heap_surgery.c +++ b/contrib/pg_surgery/heap_surgery.c @@ -103,9 +103,7 @@ heap_force_common(FunctionCallInfo fcinfo, HeapTupleForceOption heap_force_opt) /* * Check target relation. */ - if (rel->rd_rel->relkind != RELKIND_RELATION && - rel->rd_rel->relkind != RELKIND_MATVIEW && - rel->rd_rel->relkind != RELKIND_TOASTVALUE) + if (!RELKIND_HAS_TABLE_AM(rel->rd_rel->relkind)) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("cannot operate on relation \"%s\"", diff --git a/contrib/pg_visibility/pg_visibility.c b/contrib/pg_visibility/pg_visibility.c index b5362edcee..a206c0abd8 100644 --- a/contrib/pg_visibility/pg_visibility.c +++ b/contrib/pg_visibility/pg_visibility.c @@ -776,9 +776,7 @@ tuple_all_visible(HeapTuple tup, TransactionId OldestXmin, Buffer buffer) static void check_relation_relkind(Relation rel) { - if (rel->rd_rel->relkind != RELKIND_RELATION && - rel->rd_rel->relkind != RELKIND_MATVIEW && - rel->rd_rel->relkind != RELKIND_TOASTVALUE) + if (!RELKIND_HAS_TABLE_AM(rel->rd_rel->relkind)) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("relation \"%s\" is of wrong relation kind", diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c index 5e22479b7a..2debc9cb7c 100644 --- a/src/backend/access/index/indexam.c +++ b/src/backend/access/index/indexam.c @@ -135,8 +135,7 @@ index_open(Oid relationId, LOCKMODE lockmode) r = relation_open(relationId, lockmode); - if (r->rd_rel->relkind != RELKIND_INDEX && - r->rd_rel->relkind != RELKIND_PARTITIONED_INDEX) + if (!RELKIND_HAS_INDEX_AM(r->rd_rel->relkind)) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("\"%s\" is not an index", diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 83746d3fd9..1fc6ca9904 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -336,35 +336,12 @@ heap_create(const char *relname, *relfrozenxid = InvalidTransactionId; *relminmxid = InvalidMultiXactId; - /* Handle reltablespace for specific relkinds. */ - switch (relkind) - { - case RELKIND_VIEW: - case RELKIND_COMPOSITE_TYPE: - case RELKIND_FOREIGN_TABLE: - - /* - * Force reltablespace to zero if the relation has no physical - * storage. This is mainly just for cleanliness' sake. - * - * Partitioned tables and indexes don't have physical storage - * either, but we want to keep their tablespace settings so that - * their children can inherit it. - */ - reltablespace = InvalidOid; - break; - - case RELKIND_SEQUENCE: - - /* - * Force reltablespace to zero for sequences, since we don't - * support moving them around into different tablespaces. - */ - reltablespace = InvalidOid; - break; - default: - break; - } + /* + * Force reltablespace to zero if the relation kind does not support + * tablespaces. This is mainly just for cleanliness' sake. + */ + if (!RELKIND_HAS_TABLESPACE(relkind)) + reltablespace = InvalidOid; /* * Decide whether to create storage. If caller passed a valid relfilenode, @@ -415,29 +392,15 @@ heap_create(const char *relname, */ if (create_storage) { - 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: - RelationCreateStorage(rel->rd_node, relpersistence); - break; - - case RELKIND_RELATION: - case RELKIND_TOASTVALUE: - case RELKIND_MATVIEW: - table_relation_set_new_filenode(rel, &rel->rd_node, - relpersistence, - relfrozenxid, relminmxid); - break; - } + if (rel->rd_rel->relkind == RELKIND_INDEX || + rel->rd_rel->relkind == RELKIND_SEQUENCE) + RelationCreateStorage(rel->rd_node, relpersistence); + else if (RELKIND_HAS_TABLE_AM(rel->rd_rel->relkind)) + table_relation_set_new_filenode(rel, &rel->rd_node, + relpersistence, + relfrozenxid, relminmxid); + else + Assert(false); } /* @@ -1011,29 +974,16 @@ AddNewRelationTuple(Relation pg_class_desc, */ new_rel_reltup = new_rel_desc->rd_rel; - switch (relkind) + /* The relation is empty */ + new_rel_reltup->relpages = 0; + new_rel_reltup->reltuples = -1; + new_rel_reltup->relallvisible = 0; + + /* Sequences always have a known size */ + if (relkind == RELKIND_SEQUENCE) { - case RELKIND_RELATION: - case RELKIND_MATVIEW: - case RELKIND_INDEX: - case RELKIND_TOASTVALUE: - /* The relation is real, but as yet empty */ - new_rel_reltup->relpages = 0; - new_rel_reltup->reltuples = -1; - new_rel_reltup->relallvisible = 0; - break; - case RELKIND_SEQUENCE: - /* Sequences always have a known size */ - new_rel_reltup->relpages = 1; - new_rel_reltup->reltuples = 1; - new_rel_reltup->relallvisible = 0; - break; - default: - /* Views, etc, have no disk storage */ - new_rel_reltup->relpages = 0; - new_rel_reltup->reltuples = -1; - new_rel_reltup->relallvisible = 0; - break; + new_rel_reltup->relpages = 1; + new_rel_reltup->reltuples = 1; } new_rel_reltup->relfrozenxid = relfrozenxid; @@ -1171,6 +1121,8 @@ heap_create_with_catalog(const char *relname, TransactionId relfrozenxid; MultiXactId relminmxid; + Assert(!RELKIND_HAS_INDEX_AM(relkind)); + pg_class_desc = table_open(RelationRelationId, RowExclusiveLock); /* @@ -1231,29 +1183,30 @@ heap_create_with_catalog(const char *relname, if (!OidIsValid(relid)) { /* Use binary-upgrade override for pg_class.oid/relfilenode? */ - if (IsBinaryUpgrade && - (relkind == RELKIND_RELATION || relkind == RELKIND_SEQUENCE || - relkind == RELKIND_VIEW || relkind == RELKIND_MATVIEW || - relkind == RELKIND_COMPOSITE_TYPE || relkind == RELKIND_FOREIGN_TABLE || - relkind == RELKIND_PARTITIONED_TABLE)) + if (IsBinaryUpgrade) { - if (!OidIsValid(binary_upgrade_next_heap_pg_class_oid)) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("pg_class heap OID value not set when in binary upgrade mode"))); + if (relkind == RELKIND_TOASTVALUE) + { + /* There might be no TOAST table, so we have to test for it. */ + if (OidIsValid(binary_upgrade_next_toast_pg_class_oid)) + { + relid = binary_upgrade_next_toast_pg_class_oid; + binary_upgrade_next_toast_pg_class_oid = InvalidOid; + } + } + else + { + if (!OidIsValid(binary_upgrade_next_heap_pg_class_oid)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("pg_class heap OID value not set when in binary upgrade mode"))); - relid = binary_upgrade_next_heap_pg_class_oid; - binary_upgrade_next_heap_pg_class_oid = InvalidOid; - } - /* There might be no TOAST table, so we have to test for it. */ - else if (IsBinaryUpgrade && - OidIsValid(binary_upgrade_next_toast_pg_class_oid) && - relkind == RELKIND_TOASTVALUE) - { - relid = binary_upgrade_next_toast_pg_class_oid; - binary_upgrade_next_toast_pg_class_oid = InvalidOid; + relid = binary_upgrade_next_heap_pg_class_oid; + binary_upgrade_next_heap_pg_class_oid = InvalidOid; + } } - else + + if (!relid) relid = GetNewRelFileNode(reltablespace, pg_class_desc, relpersistence); } @@ -1464,13 +1417,12 @@ heap_create_with_catalog(const char *relname, /* * Make a dependency link to force the relation to be deleted if its - * access method is. Do this only for relation and materialized views. + * access method is. * * No need to add an explicit dependency for the toast table, as the * main table depends on it. */ - if (relkind == RELKIND_RELATION || - relkind == RELKIND_MATVIEW) + if (RELKIND_HAS_TABLE_AM(relkind) && relkind != RELKIND_TOASTVALUE) { ObjectAddressSet(referenced, AccessMethodRelationId, accessmtd); add_exact_object_address(&referenced, addrs); diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 26bfa74ce7..fda930fcb0 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -2283,7 +2283,7 @@ index_drop(Oid indexId, bool concurrent, bool concurrent_lock_mode) /* * Schedule physical removal of the files (if any) */ - if (userIndexRelation->rd_rel->relkind != RELKIND_PARTITIONED_INDEX) + if (RELKIND_HAS_STORAGE(userIndexRelation->rd_rel->relkind)) RelationDropStorage(userIndexRelation); /* diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index c14ca27c5e..8d3104821e 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -2954,8 +2954,7 @@ reindex_error_callback(void *arg) { ReindexErrorInfo *errinfo = (ReindexErrorInfo *) arg; - Assert(errinfo->relkind == RELKIND_PARTITIONED_INDEX || - errinfo->relkind == RELKIND_PARTITIONED_TABLE); + Assert(RELKIND_HAS_PARTITIONS(errinfo->relkind)); if (errinfo->relkind == RELKIND_PARTITIONED_TABLE) errcontext("while reindexing partitioned table \"%s.%s\"", @@ -2984,8 +2983,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel) ErrorContextCallback errcallback; ReindexErrorInfo errinfo; - Assert(relkind == RELKIND_PARTITIONED_INDEX || - relkind == RELKIND_PARTITIONED_TABLE); + Assert(RELKIND_HAS_PARTITIONS(relkind)); /* * Check if this runs in a transaction block, with an error callback to @@ -3118,8 +3116,7 @@ ReindexMultipleInternal(List *relids, ReindexParams *params) * Partitioned tables and indexes can never be processed directly, and * a list of their leaves should be built first. */ - Assert(relkind != RELKIND_PARTITIONED_INDEX && - relkind != RELKIND_PARTITIONED_TABLE); + Assert(!RELKIND_HAS_PARTITIONS(relkind)); if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 && relpersistence != RELPERSISTENCE_TEMP) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index b18de38e73..a96bcc9422 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -917,9 +917,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, errmsg("specifying a table access method is not supported on a partitioned table"))); } - else if (relkind == RELKIND_RELATION || - relkind == RELKIND_TOASTVALUE || - relkind == RELKIND_MATVIEW) + else if (RELKIND_HAS_TABLE_AM(relkind)) accessMethod = default_table_access_method; /* look up the access method, verify it is for a table */ @@ -13960,9 +13958,7 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode) } else { - Assert(rel->rd_rel->relkind == RELKIND_RELATION || - rel->rd_rel->relkind == RELKIND_MATVIEW || - rel->rd_rel->relkind == RELKIND_TOASTVALUE); + Assert(RELKIND_HAS_TABLE_AM(rel->rd_rel->relkind)); table_relation_copy_data(rel, &newrnode); } diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 3b485de067..ca177d9cdd 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -2925,37 +2925,27 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln) BlockNumber RelationGetNumberOfBlocksInFork(Relation relation, ForkNumber forkNum) { - switch (relation->rd_rel->relkind) + if (RELKIND_HAS_INDEX_AM(relation->rd_rel->relkind) || + relation->rd_rel->relkind == RELKIND_SEQUENCE) { - case RELKIND_SEQUENCE: - case RELKIND_INDEX: - case RELKIND_PARTITIONED_INDEX: return smgrnblocks(RelationGetSmgr(relation), forkNum); + } + else if (RELKIND_HAS_TABLE_AM(relation->rd_rel->relkind)) + { + /* + * Not every table AM uses BLCKSZ wide fixed size blocks. + * Therefore tableam returns the size in bytes - but for the + * purpose of this routine, we want the number of blocks. + * Therefore divide, rounding up. + */ + uint64 szbytes; - case RELKIND_RELATION: - case RELKIND_TOASTVALUE: - case RELKIND_MATVIEW: - { - /* - * Not every table AM uses BLCKSZ wide fixed size blocks. - * Therefore tableam returns the size in bytes - but for the - * purpose of this routine, we want the number of blocks. - * Therefore divide, rounding up. - */ - uint64 szbytes; - - szbytes = table_relation_size(relation, forkNum); + szbytes = table_relation_size(relation, forkNum); - return (szbytes + (BLCKSZ - 1)) / BLCKSZ; - } - case RELKIND_VIEW: - case RELKIND_COMPOSITE_TYPE: - case RELKIND_FOREIGN_TABLE: - case RELKIND_PARTITIONED_TABLE: - default: - Assert(false); - break; + return (szbytes + (BLCKSZ - 1)) / BLCKSZ; } + else + Assert(false); return 0; /* keep compiler quiet */ } diff --git a/src/backend/utils/adt/amutils.c b/src/backend/utils/adt/amutils.c index 569412fcac..aa1e8d74cb 100644 --- a/src/backend/utils/adt/amutils.c +++ b/src/backend/utils/adt/amutils.c @@ -175,8 +175,7 @@ indexam_property(FunctionCallInfo fcinfo, if (!HeapTupleIsValid(tuple)) PG_RETURN_NULL(); rd_rel = (Form_pg_class) GETSTRUCT(tuple); - if (rd_rel->relkind != RELKIND_INDEX && - rd_rel->relkind != RELKIND_PARTITIONED_INDEX) + if (!RELKIND_HAS_INDEX_AM(rd_rel->relkind)) { ReleaseSysCache(tuple); PG_RETURN_NULL(); diff --git a/src/backend/utils/adt/partitionfuncs.c b/src/backend/utils/adt/partitionfuncs.c index 03660d5db6..61aeab75dd 100644 --- a/src/backend/utils/adt/partitionfuncs.c +++ b/src/backend/utils/adt/partitionfuncs.c @@ -45,9 +45,7 @@ check_rel_can_be_partition(Oid relid) relispartition = get_rel_relispartition(relid); /* Only allow relation types that can appear in partition trees. */ - if (!relispartition && - relkind != RELKIND_PARTITIONED_TABLE && - relkind != RELKIND_PARTITIONED_INDEX) + if (!relispartition && !RELKIND_HAS_PARTITIONS(relkind)) return false; return true; @@ -143,8 +141,7 @@ pg_partition_tree(PG_FUNCTION_ARGS) nulls[1] = true; /* isleaf */ - values[2] = BoolGetDatum(relkind != RELKIND_PARTITIONED_TABLE && - relkind != RELKIND_PARTITIONED_INDEX); + values[2] = BoolGetDatum(!RELKIND_HAS_PARTITIONS(relkind)); /* level */ if (relid != rootrelid) diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 13d9994af3..4a68f1740e 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -1167,30 +1167,12 @@ RelationBuildDesc(Oid targetRelId, bool insertIt) /* * initialize access method information */ - switch (relation->rd_rel->relkind) - { - case RELKIND_INDEX: - case RELKIND_PARTITIONED_INDEX: - Assert(relation->rd_rel->relam != InvalidOid); - RelationInitIndexAccessInfo(relation); - break; - case RELKIND_RELATION: - case RELKIND_TOASTVALUE: - case RELKIND_MATVIEW: - Assert(relation->rd_rel->relam != InvalidOid); - RelationInitTableAccessMethod(relation); - break; - case RELKIND_SEQUENCE: - Assert(relation->rd_rel->relam == InvalidOid); - RelationInitTableAccessMethod(relation); - break; - case RELKIND_VIEW: - case RELKIND_COMPOSITE_TYPE: - case RELKIND_FOREIGN_TABLE: - case RELKIND_PARTITIONED_TABLE: - Assert(relation->rd_rel->relam == InvalidOid); - break; - } + if (RELKIND_HAS_INDEX_AM(relation->rd_rel->relkind)) + RelationInitIndexAccessInfo(relation); + else if (RELKIND_HAS_TABLE_AM(relation->rd_rel->relkind) || relation->rd_rel->relkind == RELKIND_SEQUENCE) + RelationInitTableAccessMethod(relation); + else + Assert(relation->rd_rel->relam == InvalidOid); /* extract reloptions if any */ RelationParseRelOptions(relation, pg_class_tuple); @@ -1393,6 +1375,7 @@ RelationInitIndexAccessInfo(Relation relation) /* * Look up the index's access method, save the OID of its handler function */ + Assert(relation->rd_rel->relam != InvalidOid); tuple = SearchSysCache1(AMOID, ObjectIdGetDatum(relation->rd_rel->relam)); if (!HeapTupleIsValid(tuple)) elog(ERROR, "cache lookup failed for access method %u", @@ -1752,6 +1735,7 @@ RelationInitTableAccessMethod(Relation relation) * seem prudent to show that in the catalog. So just overwrite it * here. */ + Assert(relation->rd_rel->relam == InvalidOid); relation->rd_amhandler = F_HEAP_TABLEAM_HANDLER; } else if (IsCatalogRelation(relation)) @@ -3545,10 +3529,7 @@ RelationBuildLocalRelation(const char *relname, */ MemoryContextSwitchTo(oldcxt); - if (relkind == RELKIND_RELATION || - relkind == RELKIND_SEQUENCE || - relkind == RELKIND_TOASTVALUE || - relkind == RELKIND_MATVIEW) + if (RELKIND_HAS_TABLE_AM(relkind) || relkind == RELKIND_SEQUENCE) RelationInitTableAccessMethod(rel); /* @@ -3637,32 +3618,26 @@ RelationSetNewRelfilenode(Relation relation, char persistence) newrnode = relation->rd_node; newrnode.relNode = newrelfilenode; - switch (relation->rd_rel->relkind) + if (relation->rd_rel->relkind == RELKIND_INDEX || + relation->rd_rel->relkind == RELKIND_SEQUENCE) { - case RELKIND_INDEX: - case RELKIND_SEQUENCE: - { - /* handle these directly, at least for now */ - SMgrRelation srel; - - srel = RelationCreateStorage(newrnode, persistence); - smgrclose(srel); - } - break; - - case RELKIND_RELATION: - case RELKIND_TOASTVALUE: - case RELKIND_MATVIEW: - table_relation_set_new_filenode(relation, &newrnode, - persistence, - &freezeXid, &minmulti); - break; + /* handle these directly, at least for now */ + SMgrRelation srel; - default: - /* we shouldn't be called for anything else */ - elog(ERROR, "relation \"%s\" does not have storage", - RelationGetRelationName(relation)); - break; + srel = RelationCreateStorage(newrnode, persistence); + smgrclose(srel); + } + else if (RELKIND_HAS_TABLE_AM(relation->rd_rel->relkind)) + { + table_relation_set_new_filenode(relation, &newrnode, + persistence, + &freezeXid, &minmulti); + } + else + { + /* we shouldn't be called for anything else */ + elog(ERROR, "relation \"%s\" does not have storage", + RelationGetRelationName(relation)); } /* @@ -4104,10 +4079,7 @@ RelationCacheInitializePhase3(void) /* Reload tableam data if needed */ if (relation->rd_tableam == NULL && - (relation->rd_rel->relkind == RELKIND_RELATION || - relation->rd_rel->relkind == RELKIND_SEQUENCE || - relation->rd_rel->relkind == RELKIND_TOASTVALUE || - relation->rd_rel->relkind == RELKIND_MATVIEW)) + (RELKIND_HAS_TABLE_AM(relation->rd_rel->relkind) || relation->rd_rel->relkind == RELKIND_SEQUENCE)) { RelationInitTableAccessMethod(relation); Assert(relation->rd_tableam != NULL); @@ -6010,10 +5982,7 @@ load_relcache_init_file(bool shared) nailed_rels++; /* Load table AM data */ - if (rel->rd_rel->relkind == RELKIND_RELATION || - rel->rd_rel->relkind == RELKIND_SEQUENCE || - rel->rd_rel->relkind == RELKIND_TOASTVALUE || - rel->rd_rel->relkind == RELKIND_MATVIEW) + if (RELKIND_HAS_TABLE_AM(rel->rd_rel->relkind) || rel->rd_rel->relkind == RELKIND_SEQUENCE) RelationInitTableAccessMethod(rel); Assert(rel->rd_index == NULL); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d114377bde..f546601356 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -16561,17 +16561,26 @@ dumpTableSchema(Archive *fout, const TableInfo *tbinfo) if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) { + char *tablespace = NULL; char *tableam = NULL; - if (tbinfo->relkind == RELKIND_RELATION || - tbinfo->relkind == RELKIND_MATVIEW) + /* + * _selectTablespace() relies on tablespace-enabled objects in the + * default tablespace to have a tablespace of "" (empty string) versus + * non-tablespace-enabled objects to have a tablespace of NULL. + * getTables() sets tbinfo->reltablespace to "" for the default + * tablespace (not NULL). + */ + if (RELKIND_HAS_TABLESPACE(tbinfo->relkind)) + tablespace = tbinfo->reltablespace; + + if (RELKIND_HAS_TABLE_AM(tbinfo->relkind)) tableam = tbinfo->amname; ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId, ARCHIVE_OPTS(.tag = tbinfo->dobj.name, .namespace = tbinfo->dobj.namespace->dobj.name, - .tablespace = (tbinfo->relkind == RELKIND_VIEW) ? - NULL : tbinfo->reltablespace, + .tablespace = tablespace, .tableam = tableam, .owner = tbinfo->rolname, .description = reltypename, diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h index fef9945ed8..1118fb5669 100644 --- a/src/include/catalog/pg_class.h +++ b/src/include/catalog/pg_class.h @@ -198,6 +198,39 @@ DECLARE_INDEX(pg_class_tblspc_relfilenode_index, 3455, ClassTblspcRelfilenodeInd (relkind) == RELKIND_TOASTVALUE || \ (relkind) == RELKIND_MATVIEW) +#define RELKIND_HAS_PARTITIONS(relkind) \ + ((relkind) == RELKIND_PARTITIONED_TABLE || \ + (relkind) == RELKIND_PARTITIONED_INDEX) + +/* + * Relation kinds that support tablespaces: All relation kinds with storage + * support tablespaces, except that we don't support moving sequences around + * into different tablespaces. Partitioned tables and indexes don't have + * physical storage, but they have a tablespace settings so that their + * children can inherit it. + */ +#define RELKIND_HAS_TABLESPACE(relkind) \ + ((RELKIND_HAS_STORAGE(relkind) || RELKIND_HAS_PARTITIONS(relkind)) \ + && (relkind) != RELKIND_SEQUENCE) + +/* + * Relation kinds with a table access method (rd_tableam). Although sequences + * use the heap table AM, they are enough of a special case in most uses that + * they are not included here. + */ +#define RELKIND_HAS_TABLE_AM(relkind) \ + ((relkind) == RELKIND_RELATION || \ + (relkind) == RELKIND_TOASTVALUE || \ + (relkind) == RELKIND_MATVIEW) + +/* + * Relation kinds with an index access method (rd_amhandler). Note that + * partitioned indexes have an index AM, unlike partitioned tables. + */ +#define RELKIND_HAS_INDEX_AM(relkind) \ + ((relkind) == RELKIND_INDEX || \ + (relkind) == RELKIND_PARTITIONED_INDEX) + extern int errdetail_relkind_not_supported(char relkind); #endif /* EXPOSE_TO_CLIENT_CODE */ -- 2.32.0