]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Some RELKIND macro refactoring
authorPeter Eisentraut <peter@eisentraut.org>
Fri, 3 Dec 2021 12:38:26 +0000 (13:38 +0100)
committerPeter Eisentraut <peter@eisentraut.org>
Fri, 3 Dec 2021 13:08:19 +0000 (14:08 +0100)
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

14 files changed:
contrib/amcheck/verify_heapam.c
contrib/pg_surgery/heap_surgery.c
contrib/pg_visibility/pg_visibility.c
contrib/pgstattuple/pgstattuple.c
src/backend/catalog/heap.c
src/backend/catalog/index.c
src/backend/commands/indexcmds.c
src/backend/commands/tablecmds.c
src/backend/optimizer/util/plancat.c
src/backend/storage/buffer/bufmgr.c
src/backend/utils/adt/partitionfuncs.c
src/backend/utils/cache/relcache.c
src/bin/pg_dump/pg_dump.c
src/include/catalog/pg_class.h

index bae5340111c90c9c44f62fe27272039009c84b97..a23d0182fc06316cc561c821877ff3230bcf3d6d 100644 (file)
@@ -306,9 +306,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) &&
                ctx.rel->rd_rel->relkind != RELKIND_SEQUENCE)
                ereport(ERROR,
                                (errcode(ERRCODE_WRONG_OBJECT_TYPE),
index 7edfe4f326f5bc5a1cb843f5737ee1b85da11007..f06385e8d3e1904f6193c905056364752a01f16d 100644 (file)
@@ -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\"",
index b5362edcee5ba0f445fd7c0e30177c0265726982..a206c0abd8d375c84dc497cb6dd4c92335e54fb5 100644 (file)
@@ -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",
index f408e6d84dbc38a799faa09c349fc42ced945bda..c9b8f01f9b48e9dd9c3fa749977c086c0bebe5f2 100644 (file)
@@ -252,14 +252,13 @@ pgstat_relation(Relation rel, FunctionCallInfo fcinfo)
                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                                 errmsg("cannot access temporary tables of other sessions")));
 
-       switch (rel->rd_rel->relkind)
+       if (RELKIND_HAS_TABLE_AM(rel->rd_rel->relkind) ||
+               rel->rd_rel->relkind == RELKIND_SEQUENCE)
        {
-               case RELKIND_RELATION:
-               case RELKIND_MATVIEW:
-               case RELKIND_TOASTVALUE:
-               case RELKIND_SEQUENCE:
                        return pgstat_heap(rel, fcinfo);
-               case RELKIND_INDEX:
+       }
+       else if (rel->rd_rel->relkind == RELKIND_INDEX)
+       {
                        switch (rel->rd_rel->relam)
                        {
                                case BTREE_AM_OID:
@@ -288,9 +287,9 @@ pgstat_relation(Relation rel, FunctionCallInfo fcinfo)
                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                                         errmsg("index \"%s\" (%s) is not supported",
                                                        RelationGetRelationName(rel), err)));
-                       break;
-
-               default:
+       }
+       else
+       {
                        ereport(ERROR,
                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                                         errmsg("cannot get tuple-level statistics for relation \"%s\"",
index 8bbf23e4526c11148a79ee9d28b2be706fc0733b..eadc3ff76bab60198f08caeeb4ec189a40829ead 100644 (file)
@@ -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);
index c255806e38cc19a69ea1731dd01d9b0862ca5061..27f0385ae0c91bba3bf663da35949a8cec6a5c33 100644 (file)
@@ -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);
 
        /*
index c14ca27c5edf20d092bf98a9bf33d98ce14e0971..8d3104821ee0453329b85c8eab0b242edb959124 100644 (file)
@@ -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)
index c35f09998c4253bbe6e0245dcd696ad60d3e94e3..c82127130696b8583f68ed5e461af12cca0cf63c 100644 (file)
@@ -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);
        }
 
index c5194fdbbf23b5fc97e6b32a9335d77ff91e42c0..564a38a13e976112c5a3db73e0188080c591dbac 100644 (file)
@@ -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;
        }
 }
 
index 08ebabfe96a1788e1e337cc52943ef489214cdd8..16de918e2e1fb9f37ba55f38e149c6f5a1f924ba 100644 (file)
@@ -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 */
 }
index 03660d5db6c76fbba19225e1d1e64a07779c903f..61aeab75dd3a295eb0c0af8e0ee9ea32ee8e0fee 100644 (file)
@@ -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)
index e1ea079e9e36348241cf94d197448ff9fbcdd79e..2b32edebe78a32f3e1190bb9adf71abe83a98b4c 100644 (file)
@@ -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);
index 01ffa5bf3a8a59f17c0aa3b985cc6e22404c0e37..c590003f18b7d079313163ab8128c8bee3110808 100644 (file)
@@ -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,
index fef9945ed8fff5c9e3041207e8388b33a7506dcc..93338d267c14b4ca9f7a86e4f2507c0899a70bd0 100644 (file)
@@ -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 */