Attached patches introduce more macros to group some RELKIND_* macros:
- RELKIND_HAS_PARTITIONS()
- RELKIND_HAS_TABLESPACE()
- RELKIND_HAS_TABLE_AM()
- RELKIND_HAS_INDEX_AM()
I collected those mainly while working on the relkind error messages
patch [0]. I think they improve the self-documentation of the code in
many places that are currently just random collections or endless
streams of RELKIND macros.
Some may recall the previous thread [1] that made a similar proposal.
The result here was that those macros were too thinly sliced and not
generally useful enough. My proposal is completely separate from that.
[0]:
https://www.postgresql.org/message-id/flat/dc35a398-37d0-75ce-07ea-1dd71d98f...@2ndquadrant.com
[1]:
https://www.postgresql.org/message-id/flat/CAFjFpRcfzs%2Byst6YBCseD_orEcDNuAr9GUTraZ5GC%3DAvCYh55Q%40mail.gmail.com
From 356e2e5c56b9856693a5df24038abd0361d97d92 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Mon, 16 Aug 2021 14:25:59 +0200
Subject: [PATCH v1 1/2] pg_dump: Remove redundant relkind checks
It is checked in flagInhTables() which relkinds can have parents.
After that, those entries will have numParents==0, so we don't need to
check the relkind again.
---
src/bin/pg_dump/common.c | 8 +-------
src/bin/pg_dump/pg_dump.c | 7 +------
2 files changed, 2 insertions(+), 13 deletions(-)
diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c
index 1f24e79665..7b85718075 100644
--- a/src/bin/pg_dump/common.c
+++ b/src/bin/pg_dump/common.c
@@ -501,13 +501,7 @@ flagInhAttrs(DumpOptions *dopt, TableInfo *tblinfo, int
numTables)
int numParents;
TableInfo **parents;
- /* Some kinds never have parents */
- if (tbinfo->relkind == RELKIND_SEQUENCE ||
- tbinfo->relkind == RELKIND_VIEW ||
- tbinfo->relkind == RELKIND_MATVIEW)
- continue;
-
- /* Don't bother computing anything for non-target tables,
either */
+ /* Don't bother computing anything for non-target tables */
if (!tbinfo->dobj.dump)
continue;
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 90ac445bcd..d114377bde 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -2725,12 +2725,7 @@ guessConstraintInheritance(TableInfo *tblinfo, int
numTables)
TableInfo **parents;
TableInfo *parent;
- /* Sequences and views never have parents */
- if (tbinfo->relkind == RELKIND_SEQUENCE ||
- tbinfo->relkind == RELKIND_VIEW)
- continue;
-
- /* Don't bother computing anything for non-target tables,
either */
+ /* Don't bother computing anything for non-target tables */
if (!(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
continue;
--
2.32.0
From 0656f3959518bfa1bd03e8bea3028ccf69b1edad Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
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