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

Reply via email to