aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeter Eisentraut <peter@eisentraut.org>2021-12-03 13:38:26 +0100
committerPeter Eisentraut <peter@eisentraut.org>2021-12-03 14:08:19 +0100
commit37b2764593c073ca61c2baebd7d85666e553928b (patch)
tree56de3f4f9040011f6dd6886adcb5b12a7ae692f8 /src
parent49422ad0cc88c91a38522b2a7b222c2f2c939f82 (diff)
downloadpostgresql-37b2764593c073ca61c2baebd7d85666e553928b.tar.gz
postgresql-37b2764593c073ca61c2baebd7d85666e553928b.zip
Some RELKIND macro refactoring
Add more macros to group some RELKIND_* macros: - RELKIND_HAS_PARTITIONS() - RELKIND_HAS_TABLESPACE() - RELKIND_HAS_TABLE_AM() Reviewed-by: Michael Paquier <michael@paquier.xyz> Reviewed-by: Alvaro Herrera <alvherre@alvh.no-ip.org> Discussion: https://www.postgresql.org/message-id/flat/a574c8f1-9c84-93ad-a9e5-65233d6fc00f%40enterprisedb.com
Diffstat (limited to 'src')
-rw-r--r--src/backend/catalog/heap.c156
-rw-r--r--src/backend/catalog/index.c2
-rw-r--r--src/backend/commands/indexcmds.c9
-rw-r--r--src/backend/commands/tablecmds.c8
-rw-r--r--src/backend/optimizer/util/plancat.c41
-rw-r--r--src/backend/storage/buffer/bufmgr.c43
-rw-r--r--src/backend/utils/adt/partitionfuncs.c7
-rw-r--r--src/backend/utils/cache/relcache.c90
-rw-r--r--src/bin/pg_dump/pg_dump.c17
-rw-r--r--src/include/catalog/pg_class.h25
10 files changed, 162 insertions, 236 deletions
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 8bbf23e4526..eadc3ff76ba 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,
@@ -409,35 +386,20 @@ heap_create(const char *relname,
/*
* Have the storage manager create the relation's disk file, if needed.
*
- * For relations the callback creates both the main and the init fork, for
- * indexes only the main fork is created. The other forks will be created
- * on demand.
+ * For tables, the AM callback creates both the main and the init fork.
+ * For others, only the main fork is created; the other forks will be
+ * created on demand.
*/
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 (RELKIND_HAS_TABLE_AM(rel->rd_rel->relkind))
+ table_relation_set_new_filenode(rel, &rel->rd_node,
+ relpersistence,
+ relfrozenxid, relminmxid);
+ else if (RELKIND_HAS_STORAGE(rel->rd_rel->relkind))
+ RelationCreateStorage(rel->rd_node, relpersistence);
+ else
+ Assert(false);
}
/*
@@ -1015,29 +977,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;
@@ -1235,29 +1184,37 @@ 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")));
+ /*
+ * Indexes are not supported here; they use
+ * binary_upgrade_next_index_pg_class_oid.
+ */
+ Assert(relkind != RELKIND_INDEX);
+ Assert(relkind != RELKIND_PARTITIONED_INDEX);
- 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;
+ 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;
+ }
}
- else
+
+ if (!OidIsValid(relid))
relid = GetNewRelFileNode(reltablespace, pg_class_desc,
relpersistence);
}
@@ -1468,13 +1425,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 c255806e38c..27f0385ae0c 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -2293,7 +2293,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 c14ca27c5ed..8d3104821ee 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 c35f09998c4..c8212713069 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -916,9 +916,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 */
@@ -13995,9 +13993,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/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index c5194fdbbf2..564a38a13e9 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -965,17 +965,13 @@ estimate_rel_size(Relation rel, int32 *attr_widths,
BlockNumber relallvisible;
double density;
- switch (rel->rd_rel->relkind)
+ if (RELKIND_HAS_TABLE_AM(rel->rd_rel->relkind))
{
- case RELKIND_RELATION:
- case RELKIND_MATVIEW:
- case RELKIND_TOASTVALUE:
table_relation_estimate_size(rel, attr_widths, pages, tuples,
allvisfrac);
- break;
-
- case RELKIND_INDEX:
-
+ }
+ else if (rel->rd_rel->relkind == RELKIND_INDEX)
+ {
/*
* XXX: It'd probably be good to move this into a callback,
* individual index types e.g. know if they have a metapage.
@@ -991,7 +987,7 @@ estimate_rel_size(Relation rel, int32 *attr_widths,
{
*tuples = 0;
*allvisfrac = 0;
- break;
+ return;
}
/* coerce values in pg_class to more desirable types */
@@ -1055,27 +1051,18 @@ estimate_rel_size(Relation rel, int32 *attr_widths,
*allvisfrac = 1;
else
*allvisfrac = (double) relallvisible / curpages;
- break;
-
- case RELKIND_SEQUENCE:
- /* Sequences always have a known size */
- *pages = 1;
- *tuples = 1;
- *allvisfrac = 0;
- break;
- case RELKIND_FOREIGN_TABLE:
- /* Just use whatever's in pg_class */
- /* Note that FDW must cope if reltuples is -1! */
+ }
+ else
+ {
+ /*
+ * Just use whatever's in pg_class. This covers foreign tables,
+ * sequences, and also relkinds without storage (shouldn't get
+ * here?); see initializations in AddNewRelationTuple(). Note
+ * that FDW must cope if reltuples is -1!
+ */
*pages = rel->rd_rel->relpages;
*tuples = rel->rd_rel->reltuples;
*allvisfrac = 0;
- break;
- default:
- /* else it has no disk storage; probably shouldn't get here? */
- *pages = 0;
- *tuples = 0;
- *allvisfrac = 0;
- break;
}
}
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 08ebabfe96a..16de918e2e1 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -2934,37 +2934,26 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln)
BlockNumber
RelationGetNumberOfBlocksInFork(Relation relation, ForkNumber forkNum)
{
- switch (relation->rd_rel->relkind)
+ if (RELKIND_HAS_TABLE_AM(relation->rd_rel->relkind))
{
- case RELKIND_SEQUENCE:
- case RELKIND_INDEX:
- return smgrnblocks(RelationGetSmgr(relation), forkNum);
-
- 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;
+ /*
+ * 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_INDEX:
- case RELKIND_PARTITIONED_TABLE:
- default:
- Assert(false);
- break;
+ return (szbytes + (BLCKSZ - 1)) / BLCKSZ;
+ }
+ else if (RELKIND_HAS_STORAGE(relation->rd_rel->relkind))
+ {
+ return smgrnblocks(RelationGetSmgr(relation), forkNum);
}
+ else
+ Assert(false);
return 0; /* keep compiler quiet */
}
diff --git a/src/backend/utils/adt/partitionfuncs.c b/src/backend/utils/adt/partitionfuncs.c
index 03660d5db6c..61aeab75dd3 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 e1ea079e9e3..2b32edebe78 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1203,30 +1203,14 @@ retry:
/*
* 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 (relation->rd_rel->relkind == RELKIND_INDEX ||
+ relation->rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
+ 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);
@@ -1444,6 +1428,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",
@@ -1803,6 +1788,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))
@@ -3638,10 +3624,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);
/*
@@ -3730,32 +3713,25 @@ RelationSetNewRelfilenode(Relation relation, char persistence)
newrnode = relation->rd_node;
newrnode.relNode = newrelfilenode;
- switch (relation->rd_rel->relkind)
+ if (RELKIND_HAS_TABLE_AM(relation->rd_rel->relkind))
{
- 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;
+ table_relation_set_new_filenode(relation, &newrnode,
+ persistence,
+ &freezeXid, &minmulti);
+ }
+ else if (RELKIND_HAS_STORAGE(relation->rd_rel->relkind))
+ {
+ /* 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
+ {
+ /* we shouldn't be called for anything else */
+ elog(ERROR, "relation \"%s\" does not have storage",
+ RelationGetRelationName(relation));
}
/*
@@ -4207,10 +4183,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);
@@ -6127,10 +6100,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 01ffa5bf3a8..c590003f18b 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -16480,17 +16480,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 fef9945ed8f..93338d267c1 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -198,6 +198,31 @@ 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)
+
extern int errdetail_relkind_not_supported(char relkind);
#endif /* EXPOSE_TO_CLIENT_CODE */