v2-0002-Refactoring-relkind-handling.patch
application/octet-stream
Filename: v2-0002-Refactoring-relkind-handling.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch v2-0002
Subject: Refactoring relkind handling
| File | + | − |
|---|---|---|
| contrib/oid2name/oid2name.c | 9 | 9 |
| contrib/pageinspect/rawpage.c | 41 | 25 |
| contrib/pgrowlocks/pgrowlocks.c | 27 | 11 |
| contrib/pgstattuple/pgstatapprox.c | 21 | 7 |
| contrib/pgstattuple/pgstatindex.c | 21 | 9 |
| contrib/pgstattuple/pgstattuple.c | 2 | 1 |
| contrib/pg_visibility/pg_visibility.c | 21 | 7 |
| contrib/postgres_fdw/postgres_fdw.c | 5 | 5 |
| contrib/sepgsql/dml.c | 46 | 7 |
| contrib/sepgsql/label.c | 39 | 12 |
| contrib/sepgsql/relation.c | 277 | 110 |
| contrib/vacuumlo/vacuumlo.c | 1 | 1 |
| src/backend/access/common/reloptions.c | 14 | 3 |
| src/backend/access/heap/heapam.c | 61 | 25 |
| src/backend/access/heap/heapam_handler.c | 21 | 6 |
| src/backend/access/heap/heaptoast.c | 36 | 4 |
| src/backend/access/index/indexam.c | 22 | 6 |
| src/backend/access/table/tableam.c | 35 | 21 |
| src/backend/access/table/table.c | 78 | 33 |
| src/backend/catalog/aclchk.c | 277 | 134 |
| src/backend/catalog/dependency.c | 30 | 16 |
| src/backend/catalog/heap.c | 236 | 95 |
| src/backend/catalog/index.c | 93 | 17 |
| src/backend/catalog/objectaddress.c | 129 | 36 |
| src/backend/catalog/partition.c | 19 | 2 |
| src/backend/catalog/pg_depend.c | 41 | 10 |
| src/backend/catalog/pg_publication.c | 41 | 12 |
| src/backend/catalog/pg_type.c | 19 | 4 |
| src/backend/catalog/toasting.c | 38 | 8 |
| src/backend/commands/analyze.c | 141 | 86 |
| src/backend/commands/cluster.c | 116 | 38 |
| src/backend/commands/comment.c | 21 | 10 |
| src/backend/commands/copy.c | 143 | 68 |
| src/backend/commands/extension.c | 2 | 2 |
| src/backend/commands/indexcmds.c | 144 | 46 |
| src/backend/commands/lockcmds.c | 82 | 18 |
| src/backend/commands/policy.c | 62 | 16 |
| src/backend/commands/publicationcmds.c | 42 | 26 |
| src/backend/commands/seclabel.c | 21 | 10 |
| src/backend/commands/sequence.c | 21 | 8 |
| src/backend/commands/statscmds.c | 21 | 8 |
| src/backend/commands/tablecmds.c | 1755 | 816 |
| src/backend/commands/trigger.c | 295 | 154 |
| src/backend/commands/typecmds.c | 19 | 4 |
| src/backend/commands/vacuum.c | 80 | 27 |
| src/backend/executor/execMain.c | 81 | 38 |
| src/backend/executor/execReplication.c | 30 | 15 |
| src/backend/executor/nodeModifyTable.c | 101 | 67 |
| src/backend/optimizer/path/allpaths.c | 122 | 48 |
| src/backend/optimizer/plan/planner.c | 102 | 44 |
| src/backend/optimizer/util/inherit.c | 161 | 89 |
| src/backend/optimizer/util/plancat.c | 60 | 14 |
| src/backend/parser/parse_utilcmd.c | 136 | 51 |
| src/backend/partitioning/partbounds.c | 38 | 12 |
| src/backend/postmaster/autovacuum.c | 77 | 15 |
| src/backend/replication/basebackup.c | 3 | 3 |
| src/backend/replication/logical/reorderbuffer.c | 17 | 2 |
| src/backend/replication/logical/tablesync.c | 31 | 17 |
| src/backend/replication/logical/worker.c | 115 | 50 |
| src/backend/replication/slot.c | 26 | 26 |
| src/backend/rewrite/rewriteDefine.c | 113 | 72 |
| src/backend/rewrite/rewriteHandler.c | 293 | 170 |
| src/backend/rewrite/rowsecurity.c | 17 | 3 |
| src/backend/storage/buffer/bufmgr.c | 8 | 3 |
| src/backend/storage/lmgr/proc.c | 14 | 13 |
| src/backend/storage/lmgr/spin.c | 1 | 1 |
| src/backend/tcop/utility.c | 55 | 27 |
| src/backend/utils/adt/amutils.c | 17 | 4 |
| src/backend/utils/adt/dbsize.c | 7 | 7 |
| src/backend/utils/adt/partitionfuncs.c | 38 | 6 |
| src/backend/utils/adt/tid.c | 34 | 4 |
| src/backend/utils/adt/xml.c | 6 | 6 |
| src/backend/utils/cache/partcache.c | 17 | 2 |
| src/backend/utils/cache/relcache.c | 241 | 107 |
| src/bin/initdb/initdb.c | 10 | 10 |
| src/bin/pg_dump/common.c | 34 | 8 |
| src/bin/pg_dump/pg_backup_tar.c | 1 | 1 |
| src/bin/pg_dump/pg_dump.c | 149 | 45 |
| src/bin/pg_dump/pg_dump_sort.c | 124 | 45 |
| src/bin/pg_upgrade/info.c | 2 | 2 |
| src/bin/pg_upgrade/pg_upgrade.c | 6 | 6 |
| src/bin/pg_upgrade/version.c | 3 | 3 |
| src/bin/psql/command.c | 14 | 5 |
| src/bin/psql/describe.c | 1205 | 1063 |
| src/bin/psql/tab-complete.c | 33 | 33 |
| src/bin/scripts/reindexdb.c | 4 | 4 |
| src/bin/scripts/vacuumdb.c | 2 | 2 |
| src/include/catalog/pg_class.h | 28 | 10 |
| src/include/nodes/execnodes.h | 2 | 2 |
| src/include/storage/proc.h | 1 | 1 |
| src/include/utils/builtins.h | 5 | 5 |
| src/pl/plpgsql/src/pl_comp.c | 17 | 8 |
| src/test/regress/regress.c | 11 | 11 |
| src/tools/findoidjoins/findoidjoins.c | 3 | 3 |
From 41a970951670dd413c0e066512ae79c3c16533a6 Mon Sep 17 00:00:00 2001
From: Mark Dilger <mark.dilger@enterprisedb.com>
Date: Wed, 1 Jul 2020 08:12:27 -0700
Subject: [PATCH v2 2/2] Refactoring relkind handling
Cleaning up the #define RELKIND_XXX stuff using a new RelKind enum
and special macros while keeping the relkind fields as type 'char'.
---
contrib/oid2name/oid2name.c | 18 +-
contrib/pageinspect/rawpage.c | 66 +-
contrib/pg_visibility/pg_visibility.c | 28 +-
contrib/pgrowlocks/pgrowlocks.c | 38 +-
contrib/pgstattuple/pgstatapprox.c | 28 +-
contrib/pgstattuple/pgstatindex.c | 30 +-
contrib/pgstattuple/pgstattuple.c | 3 +-
contrib/postgres_fdw/postgres_fdw.c | 10 +-
contrib/sepgsql/dml.c | 53 +-
contrib/sepgsql/label.c | 51 +-
contrib/sepgsql/relation.c | 387 ++-
contrib/vacuumlo/vacuumlo.c | 2 +-
src/backend/access/common/reloptions.c | 17 +-
src/backend/access/heap/heapam.c | 86 +-
src/backend/access/heap/heapam_handler.c | 27 +-
src/backend/access/heap/heaptoast.c | 40 +-
src/backend/access/index/indexam.c | 28 +-
src/backend/access/table/table.c | 111 +-
src/backend/access/table/tableam.c | 56 +-
src/backend/catalog/aclchk.c | 411 ++-
src/backend/catalog/dependency.c | 46 +-
src/backend/catalog/heap.c | 331 ++-
src/backend/catalog/index.c | 110 +-
src/backend/catalog/objectaddress.c | 165 +-
src/backend/catalog/partition.c | 21 +-
src/backend/catalog/pg_depend.c | 51 +-
src/backend/catalog/pg_publication.c | 53 +-
src/backend/catalog/pg_type.c | 23 +-
src/backend/catalog/toasting.c | 46 +-
src/backend/commands/analyze.c | 227 +-
src/backend/commands/cluster.c | 154 +-
src/backend/commands/comment.c | 31 +-
src/backend/commands/copy.c | 211 +-
src/backend/commands/extension.c | 4 +-
src/backend/commands/indexcmds.c | 190 +-
src/backend/commands/lockcmds.c | 100 +-
src/backend/commands/policy.c | 78 +-
src/backend/commands/publicationcmds.c | 68 +-
src/backend/commands/seclabel.c | 31 +-
src/backend/commands/sequence.c | 29 +-
src/backend/commands/statscmds.c | 29 +-
src/backend/commands/tablecmds.c | 2571 +++++++++++------
src/backend/commands/trigger.c | 449 ++-
src/backend/commands/typecmds.c | 23 +-
src/backend/commands/vacuum.c | 107 +-
src/backend/executor/execMain.c | 119 +-
src/backend/executor/execReplication.c | 45 +-
src/backend/executor/nodeModifyTable.c | 168 +-
src/backend/optimizer/path/allpaths.c | 170 +-
src/backend/optimizer/plan/planner.c | 146 +-
src/backend/optimizer/util/inherit.c | 250 +-
src/backend/optimizer/util/plancat.c | 74 +-
src/backend/parser/parse_utilcmd.c | 187 +-
src/backend/partitioning/partbounds.c | 50 +-
src/backend/postmaster/autovacuum.c | 92 +-
src/backend/replication/basebackup.c | 6 +-
.../replication/logical/reorderbuffer.c | 19 +-
src/backend/replication/logical/tablesync.c | 48 +-
src/backend/replication/logical/worker.c | 165 +-
src/backend/replication/slot.c | 52 +-
src/backend/rewrite/rewriteDefine.c | 185 +-
src/backend/rewrite/rewriteHandler.c | 463 +--
src/backend/rewrite/rowsecurity.c | 20 +-
src/backend/storage/buffer/bufmgr.c | 11 +-
src/backend/storage/lmgr/proc.c | 27 +-
src/backend/storage/lmgr/spin.c | 2 +-
src/backend/tcop/utility.c | 82 +-
src/backend/utils/adt/amutils.c | 21 +-
src/backend/utils/adt/dbsize.c | 14 +-
src/backend/utils/adt/partitionfuncs.c | 44 +-
src/backend/utils/adt/tid.c | 38 +-
src/backend/utils/adt/xml.c | 12 +-
src/backend/utils/cache/partcache.c | 19 +-
src/backend/utils/cache/relcache.c | 348 ++-
src/bin/initdb/initdb.c | 20 +-
src/bin/pg_dump/common.c | 42 +-
src/bin/pg_dump/pg_backup_tar.c | 2 +-
src/bin/pg_dump/pg_dump.c | 194 +-
src/bin/pg_dump/pg_dump_sort.c | 169 +-
src/bin/pg_upgrade/info.c | 4 +-
src/bin/pg_upgrade/pg_upgrade.c | 12 +-
src/bin/pg_upgrade/version.c | 6 +-
src/bin/psql/command.c | 19 +-
src/bin/psql/describe.c | 2268 ++++++++-------
src/bin/psql/tab-complete.c | 66 +-
src/bin/scripts/reindexdb.c | 8 +-
src/bin/scripts/vacuumdb.c | 4 +-
src/include/catalog/pg_class.h | 38 +-
src/include/nodes/execnodes.h | 4 +-
src/include/storage/proc.h | 2 +-
src/include/utils/builtins.h | 10 +-
src/pl/plpgsql/src/pl_comp.c | 25 +-
src/test/regress/regress.c | 22 +-
src/tools/findoidjoins/findoidjoins.c | 6 +-
94 files changed, 8280 insertions(+), 4156 deletions(-)
diff --git a/contrib/oid2name/oid2name.c b/contrib/oid2name/oid2name.c
index c7d0f9025a..cff14f7c47 100644
--- a/contrib/oid2name/oid2name.c
+++ b/contrib/oid2name/oid2name.c
@@ -481,8 +481,8 @@ sql_exec_dumpalltables(PGconn *conn, struct options *opts)
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace "
" LEFT JOIN pg_catalog.pg_database d ON d.datname = pg_catalog.current_database(),"
" pg_catalog.pg_tablespace t "
- "WHERE relkind IN (" CppAsString2(RELKIND_RELATION) ","
- CppAsString2(RELKIND_MATVIEW) "%s%s) AND "
+ "WHERE relkind IN (" RelKindAsString(RELKIND_RELATION) ","
+ RelKindAsString(RELKIND_MATVIEW) "%s%s) AND "
" %s"
" t.oid = CASE"
" WHEN reltablespace <> 0 THEN reltablespace"
@@ -490,8 +490,8 @@ sql_exec_dumpalltables(PGconn *conn, struct options *opts)
" END "
"ORDER BY relname",
opts->extended ? addfields : "",
- opts->indexes ? "," CppAsString2(RELKIND_INDEX) "," CppAsString2(RELKIND_SEQUENCE) : "",
- opts->systables ? "," CppAsString2(RELKIND_TOASTVALUE) : "",
+ opts->indexes ? "," RelKindAsString(RELKIND_INDEX) "," RelKindAsString(RELKIND_SEQUENCE) : "",
+ opts->systables ? "," RelKindAsString(RELKIND_TOASTVALUE) : "",
opts->systables ? "" : "n.nspname NOT IN ('pg_catalog', 'information_schema') AND n.nspname !~ '^pg_toast' AND");
sql_exec(conn, todo, opts->quiet);
@@ -551,11 +551,11 @@ sql_exec_searchtables(PGconn *conn, struct options *opts)
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace\n"
" LEFT JOIN pg_catalog.pg_database d ON d.datname = pg_catalog.current_database(),\n"
" pg_catalog.pg_tablespace t\n"
- "WHERE relkind IN (" CppAsString2(RELKIND_RELATION) ","
- CppAsString2(RELKIND_MATVIEW) ","
- CppAsString2(RELKIND_INDEX) ","
- CppAsString2(RELKIND_SEQUENCE) ","
- CppAsString2(RELKIND_TOASTVALUE) ") AND\n"
+ "WHERE relkind IN (" RelKindAsString(RELKIND_RELATION) ","
+ RelKindAsString(RELKIND_MATVIEW) ","
+ RelKindAsString(RELKIND_INDEX) ","
+ RelKindAsString(RELKIND_SEQUENCE) ","
+ RelKindAsString(RELKIND_TOASTVALUE) ") AND\n"
" t.oid = CASE\n"
" WHEN reltablespace <> 0 THEN reltablespace\n"
" ELSE dattablespace\n"
diff --git a/contrib/pageinspect/rawpage.c b/contrib/pageinspect/rawpage.c
index c0181506a5..b7082f5cdb 100644
--- a/contrib/pageinspect/rawpage.c
+++ b/contrib/pageinspect/rawpage.c
@@ -108,31 +108,47 @@ get_raw_page_internal(text *relname, ForkNumber forknum, BlockNumber blkno)
rel = relation_openrv(relrv, AccessShareLock);
/* Check that this relation has storage */
- if (rel->rd_rel->relkind == RELKIND_VIEW)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot get raw page from view \"%s\"",
- RelationGetRelationName(rel))));
- if (rel->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot get raw page from composite type \"%s\"",
- RelationGetRelationName(rel))));
- if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot get raw page from foreign table \"%s\"",
- RelationGetRelationName(rel))));
- if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot get raw page from partitioned table \"%s\"",
- RelationGetRelationName(rel))));
- if (rel->rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot get raw page from partitioned index \"%s\"",
- RelationGetRelationName(rel))));
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_VIEW:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot get raw page from view \"%s\"",
+ RelationGetRelationName(rel))));
+ break;
+ case RELKIND_COMPOSITE_TYPE:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot get raw page from composite type \"%s\"",
+ RelationGetRelationName(rel))));
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot get raw page from foreign table \"%s\"",
+ RelationGetRelationName(rel))));
+ break;
+ case RELKIND_PARTITIONED_TABLE:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot get raw page from partitioned table \"%s\"",
+ RelationGetRelationName(rel))));
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot get raw page from partitioned index \"%s\"",
+ RelationGetRelationName(rel))));
+ break;
+ case RELKIND_SEQUENCE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
/*
* Reject attempts to read non-local temporary relations; we would be
diff --git a/contrib/pg_visibility/pg_visibility.c b/contrib/pg_visibility/pg_visibility.c
index 68d580ed1e..30bcf49379 100644
--- a/contrib/pg_visibility/pg_visibility.c
+++ b/contrib/pg_visibility/pg_visibility.c
@@ -778,11 +778,25 @@ 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)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table, materialized view, or TOAST table",
- RelationGetRelationName(rel))));
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a table, materialized view, or TOAST table",
+ RelationGetRelationName(rel))));
+ break;
+ }
}
diff --git a/contrib/pgrowlocks/pgrowlocks.c b/contrib/pgrowlocks/pgrowlocks.c
index 714398831b..a5a123d421 100644
--- a/contrib/pgrowlocks/pgrowlocks.c
+++ b/contrib/pgrowlocks/pgrowlocks.c
@@ -111,17 +111,33 @@ pgrowlocks(PG_FUNCTION_ARGS)
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("only heap AM is supported")));
- if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is a partitioned table",
- RelationGetRelationName(rel)),
- errdetail("Partitioned tables do not contain rows.")));
- else if (rel->rd_rel->relkind != RELKIND_RELATION)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table",
- RelationGetRelationName(rel))));
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_RELATION:
+ break;
+ case RELKIND_PARTITIONED_TABLE:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is a partitioned table",
+ RelationGetRelationName(rel)),
+ errdetail("Partitioned tables do not contain rows.")));
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a table",
+ RelationGetRelationName(rel))));
+ break;
+ }
/*
* check permissions: must have SELECT on table or be in
diff --git a/contrib/pgstattuple/pgstatapprox.c b/contrib/pgstattuple/pgstatapprox.c
index dbc0fa11f6..c14edf2aad 100644
--- a/contrib/pgstattuple/pgstatapprox.c
+++ b/contrib/pgstattuple/pgstatapprox.c
@@ -281,13 +281,27 @@ pgstattuple_approx_internal(Oid relid, FunctionCallInfo fcinfo)
* We support only relation kinds with a visibility map and a free space
* map.
*/
- if (!(rel->rd_rel->relkind == RELKIND_RELATION ||
- rel->rd_rel->relkind == RELKIND_MATVIEW ||
- rel->rd_rel->relkind == RELKIND_TOASTVALUE))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("\"%s\" is not a table, materialized view, or TOAST table",
- RelationGetRelationName(rel))));
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("\"%s\" is not a table, materialized view, or TOAST table",
+ RelationGetRelationName(rel))));
+ break;
+ }
if (rel->rd_rel->relam != HEAP_TABLE_AM_OID)
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
diff --git a/contrib/pgstattuple/pgstatindex.c b/contrib/pgstattuple/pgstatindex.c
index b1ce0d77d7..b6c1a16d15 100644
--- a/contrib/pgstattuple/pgstatindex.c
+++ b/contrib/pgstattuple/pgstatindex.c
@@ -758,13 +758,25 @@ GetHashPageStats(Page page, HashIndexStat *stats)
static void
check_relation_relkind(Relation rel)
{
- if (rel->rd_rel->relkind != RELKIND_RELATION &&
- rel->rd_rel->relkind != RELKIND_INDEX &&
- rel->rd_rel->relkind != RELKIND_MATVIEW &&
- rel->rd_rel->relkind != RELKIND_SEQUENCE &&
- rel->rd_rel->relkind != RELKIND_TOASTVALUE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table, index, materialized view, sequence, or TOAST table",
- RelationGetRelationName(rel))));
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a table, index, materialized view, sequence, or TOAST table",
+ RelationGetRelationName(rel))));
+ break;
+ }
}
diff --git a/contrib/pgstattuple/pgstattuple.c b/contrib/pgstattuple/pgstattuple.c
index 69179d4104..897805d575 100644
--- a/contrib/pgstattuple/pgstattuple.c
+++ b/contrib/pgstattuple/pgstattuple.c
@@ -252,7 +252,7 @@ pgstat_relation(Relation rel, FunctionCallInfo fcinfo)
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot access temporary tables of other sessions")));
- switch (rel->rd_rel->relkind)
+ switch ((RelKind) rel->rd_rel->relkind)
{
case RELKIND_RELATION:
case RELKIND_MATVIEW:
@@ -300,6 +300,7 @@ pgstat_relation(Relation rel, FunctionCallInfo fcinfo)
case RELKIND_PARTITIONED_INDEX:
err = "partitioned index";
break;
+ case RELKIND_NULL:
default:
err = "unknown";
break;
diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c
index 9fc53cad68..77e28757ef 100644
--- a/contrib/postgres_fdw/postgres_fdw.c
+++ b/contrib/postgres_fdw/postgres_fdw.c
@@ -4842,11 +4842,11 @@ postgresImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid)
appendStringInfoString(&buf,
"WHERE c.relkind IN ("
- CppAsString2(RELKIND_RELATION) ","
- CppAsString2(RELKIND_VIEW) ","
- CppAsString2(RELKIND_FOREIGN_TABLE) ","
- CppAsString2(RELKIND_MATVIEW) ","
- CppAsString2(RELKIND_PARTITIONED_TABLE) ") "
+ RelKindAsString(RELKIND_RELATION) ","
+ RelKindAsString(RELKIND_VIEW) ","
+ RelKindAsString(RELKIND_FOREIGN_TABLE) ","
+ RelKindAsString(RELKIND_MATVIEW) ","
+ RelKindAsString(RELKIND_PARTITIONED_TABLE) ") "
" AND n.nspname = ");
deparseStringLiteral(&buf, stmt->remote_schema);
diff --git a/contrib/sepgsql/dml.c b/contrib/sepgsql/dml.c
index 53f6f41c5c..a1d5986619 100644
--- a/contrib/sepgsql/dml.c
+++ b/contrib/sepgsql/dml.c
@@ -167,10 +167,27 @@ check_relation_privileges(Oid relOid,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("SELinux: hardwired security policy violation")));
- if (relkind == RELKIND_TOASTVALUE)
- ereport(ERROR,
- (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("SELinux: hardwired security policy violation")));
+ switch ((RelKind) relkind)
+ {
+ case RELKIND_TOASTVALUE:
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("SELinux: hardwired security policy violation")));
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
+
}
/*
@@ -180,7 +197,7 @@ check_relation_privileges(Oid relOid,
object.objectId = relOid;
object.objectSubId = 0;
audit_name = getObjectIdentity(&object);
- switch (relkind)
+ switch ((RelKind) relkind)
{
case RELKIND_RELATION:
case RELKIND_PARTITIONED_TABLE:
@@ -210,6 +227,13 @@ check_relation_privileges(Oid relOid,
abort_on_violation);
break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
default:
/* nothing to be checked */
break;
@@ -219,8 +243,23 @@ check_relation_privileges(Oid relOid,
/*
* Only columns owned by relations shall be checked
*/
- if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE)
- return true;
+ switch ((RelKind) relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ return true;
+ }
/*
* Check permissions on the columns
diff --git a/contrib/sepgsql/label.c b/contrib/sepgsql/label.c
index 147ab67f32..697f556f58 100644
--- a/contrib/sepgsql/label.c
+++ b/contrib/sepgsql/label.c
@@ -763,15 +763,28 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)
case RelationRelationId:
relForm = (Form_pg_class) GETSTRUCT(tuple);
- if (relForm->relkind == RELKIND_RELATION ||
- relForm->relkind == RELKIND_PARTITIONED_TABLE)
- objtype = SELABEL_DB_TABLE;
- else if (relForm->relkind == RELKIND_SEQUENCE)
- objtype = SELABEL_DB_SEQUENCE;
- else if (relForm->relkind == RELKIND_VIEW)
- objtype = SELABEL_DB_VIEW;
- else
- continue; /* no need to assign security label */
+ switch ((RelKind) relForm->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ objtype = SELABEL_DB_TABLE;
+ break;
+ case RELKIND_SEQUENCE:
+ objtype = SELABEL_DB_SEQUENCE;
+ break;
+ case RELKIND_VIEW:
+ objtype = SELABEL_DB_VIEW;
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ continue; /* no need to assign security label */
+ }
namespace_name = get_namespace_name(relForm->relnamespace);
objname = quote_object_name(database_name,
@@ -788,9 +801,23 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)
case AttributeRelationId:
attForm = (Form_pg_attribute) GETSTRUCT(tuple);
- if (get_rel_relkind(attForm->attrelid) != RELKIND_RELATION &&
- get_rel_relkind(attForm->attrelid) != RELKIND_PARTITIONED_TABLE)
- continue; /* no need to assign security label */
+ switch ((RelKind) get_rel_relkind(attForm->attrelid))
+ {
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ continue; /* no need to assign security label */
+ }
objtype = SELABEL_DB_COLUMN;
diff --git a/contrib/sepgsql/relation.c b/contrib/sepgsql/relation.c
index 380bc6094d..27262f47c1 100644
--- a/contrib/sepgsql/relation.c
+++ b/contrib/sepgsql/relation.c
@@ -59,8 +59,23 @@ sepgsql_attribute_post_create(Oid relOid, AttrNumber attnum)
* Only attributes within regular relations or partition relations have
* individual security labels.
*/
- if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE)
- return;
+ switch ((RelKind) relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ return;
+ }
/*
* Compute a default security label of the new column underlying the
@@ -137,8 +152,23 @@ sepgsql_attribute_drop(Oid relOid, AttrNumber attnum)
char *audit_name;
char relkind = get_rel_relkind(relOid);
- if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE)
- return;
+ switch ((RelKind) relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ return;
+ }
/*
* check db_column:{drop} permission
@@ -170,10 +200,26 @@ sepgsql_attribute_relabel(Oid relOid, AttrNumber attnum,
char *audit_name;
char relkind = get_rel_relkind(relOid);
- if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot set security label on non-regular columns")));
+ switch ((RelKind) relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot set security label on non-regular columns")));
+ break;
+ }
object.classId = RelationRelationId;
object.objectId = relOid;
@@ -213,8 +259,25 @@ sepgsql_attribute_setattr(Oid relOid, AttrNumber attnum)
char *audit_name;
char relkind = get_rel_relkind(relOid);
- if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE)
- return;
+ switch ((RelKind) relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ return;
+ }
/*
* check db_column:{setattr} permission
@@ -275,9 +338,26 @@ sepgsql_relation_post_create(Oid relOid)
classForm = (Form_pg_class) GETSTRUCT(tuple);
/* ignore indexes on toast tables */
- if (classForm->relkind == RELKIND_INDEX &&
- classForm->relnamespace == PG_TOAST_NAMESPACE)
- goto out;
+ switch ((RelKind) classForm->relkind)
+ {
+ case RELKIND_INDEX:
+ if (classForm->relnamespace == PG_TOAST_NAMESPACE)
+ goto out;
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
+
/*
* check db_schema:{add_name} permission of the namespace
@@ -291,7 +371,7 @@ sepgsql_relation_post_create(Oid relOid)
getObjectIdentity(&object),
true);
- switch (classForm->relkind)
+ switch ((RelKind) classForm->relkind)
{
case RELKIND_RELATION:
case RELKIND_PARTITIONED_TABLE:
@@ -307,6 +387,12 @@ sepgsql_relation_post_create(Oid relOid)
/* deal with indexes specially; no need for tclass */
sepgsql_index_modify(relOid);
goto out;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
default:
/* ignore other relkinds */
goto out;
@@ -348,59 +434,75 @@ sepgsql_relation_post_create(Oid relOid)
/*
* We also assign a default security label on columns of a new table.
*/
- if (classForm->relkind == RELKIND_RELATION ||
- classForm->relkind == RELKIND_PARTITIONED_TABLE)
+ switch ((RelKind) classForm->relkind)
{
- Relation arel;
- ScanKeyData akey;
- SysScanDesc ascan;
- HeapTuple atup;
- Form_pg_attribute attForm;
-
- arel = table_open(AttributeRelationId, AccessShareLock);
-
- ScanKeyInit(&akey,
- Anum_pg_attribute_attrelid,
- BTEqualStrategyNumber, F_OIDEQ,
- ObjectIdGetDatum(relOid));
-
- ascan = systable_beginscan(arel, AttributeRelidNumIndexId, true,
- SnapshotSelf, 1, &akey);
-
- while (HeapTupleIsValid(atup = systable_getnext(ascan)))
- {
- attForm = (Form_pg_attribute) GETSTRUCT(atup);
-
- resetStringInfo(&audit_name);
- appendStringInfo(&audit_name, "%s.%s.%s",
- quote_identifier(nsp_name),
- quote_identifier(NameStr(classForm->relname)),
- quote_identifier(NameStr(attForm->attname)));
-
- ccontext = sepgsql_compute_create(scontext,
- rcontext,
- SEPG_CLASS_DB_COLUMN,
- NameStr(attForm->attname));
-
- /*
- * check db_column:{create} permission
- */
- sepgsql_avc_check_perms_label(ccontext,
- SEPG_CLASS_DB_COLUMN,
- SEPG_DB_COLUMN__CREATE,
- audit_name.data,
- true);
-
- object.classId = RelationRelationId;
- object.objectId = relOid;
- object.objectSubId = attForm->attnum;
- SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, ccontext);
-
- pfree(ccontext);
- }
- systable_endscan(ascan);
- table_close(arel, AccessShareLock);
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ {
+ Relation arel;
+ ScanKeyData akey;
+ SysScanDesc ascan;
+ HeapTuple atup;
+ Form_pg_attribute attForm;
+
+ arel = table_open(AttributeRelationId, AccessShareLock);
+
+ ScanKeyInit(&akey,
+ Anum_pg_attribute_attrelid,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(relOid));
+
+ ascan = systable_beginscan(arel, AttributeRelidNumIndexId, true,
+ SnapshotSelf, 1, &akey);
+
+ while (HeapTupleIsValid(atup = systable_getnext(ascan)))
+ {
+ attForm = (Form_pg_attribute) GETSTRUCT(atup);
+
+ resetStringInfo(&audit_name);
+ appendStringInfo(&audit_name, "%s.%s.%s",
+ quote_identifier(nsp_name),
+ quote_identifier(NameStr(classForm->relname)),
+ quote_identifier(NameStr(attForm->attname)));
+
+ ccontext = sepgsql_compute_create(scontext,
+ rcontext,
+ SEPG_CLASS_DB_COLUMN,
+ NameStr(attForm->attname));
+
+ /*
+ * check db_column:{create} permission
+ */
+ sepgsql_avc_check_perms_label(ccontext,
+ SEPG_CLASS_DB_COLUMN,
+ SEPG_DB_COLUMN__CREATE,
+ audit_name.data,
+ true);
+
+ object.classId = RelationRelationId;
+ object.objectId = relOid;
+ object.objectSubId = attForm->attnum;
+ SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, ccontext);
+
+ pfree(ccontext);
+ }
+ systable_endscan(ascan);
+ table_close(arel, AccessShareLock);
+ }
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
+
pfree(rcontext);
out:
@@ -421,7 +523,7 @@ sepgsql_relation_drop(Oid relOid)
uint16_t tclass = 0;
char relkind = get_rel_relkind(relOid);
- switch (relkind)
+ switch ((RelKind) relkind)
{
case RELKIND_RELATION:
case RELKIND_PARTITIONED_TABLE:
@@ -439,6 +541,12 @@ sepgsql_relation_drop(Oid relOid)
return;
/* other indexes are handled specially below; no need for tclass */
break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
default:
/* ignore other relkinds */
return;
@@ -460,10 +568,23 @@ sepgsql_relation_drop(Oid relOid)
pfree(audit_name);
/* deal with indexes specially */
- if (relkind == RELKIND_INDEX)
+ switch ((RelKind) relkind)
{
- sepgsql_index_modify(relOid);
- return;
+ case RELKIND_INDEX:
+ sepgsql_index_modify(relOid);
+ return;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
/*
@@ -484,35 +605,51 @@ sepgsql_relation_drop(Oid relOid)
/*
* check db_column:{drop} permission
*/
- if (relkind == RELKIND_RELATION || relkind == RELKIND_PARTITIONED_TABLE)
+ switch ((RelKind) relkind)
{
- Form_pg_attribute attForm;
- CatCList *attrList;
- HeapTuple atttup;
- int i;
-
- attrList = SearchSysCacheList1(ATTNUM, ObjectIdGetDatum(relOid));
- for (i = 0; i < attrList->n_members; i++)
- {
- atttup = &attrList->members[i]->tuple;
- attForm = (Form_pg_attribute) GETSTRUCT(atttup);
-
- if (attForm->attisdropped)
- continue;
-
- object.classId = RelationRelationId;
- object.objectId = relOid;
- object.objectSubId = attForm->attnum;
- audit_name = getObjectIdentity(&object);
-
- sepgsql_avc_check_perms(&object,
- SEPG_CLASS_DB_COLUMN,
- SEPG_DB_COLUMN__DROP,
- audit_name,
- true);
- pfree(audit_name);
- }
- ReleaseCatCacheList(attrList);
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ {
+ Form_pg_attribute attForm;
+ CatCList *attrList;
+ HeapTuple atttup;
+ int i;
+
+ attrList = SearchSysCacheList1(ATTNUM, ObjectIdGetDatum(relOid));
+ for (i = 0; i < attrList->n_members; i++)
+ {
+ atttup = &attrList->members[i]->tuple;
+ attForm = (Form_pg_attribute) GETSTRUCT(atttup);
+
+ if (attForm->attisdropped)
+ continue;
+
+ object.classId = RelationRelationId;
+ object.objectId = relOid;
+ object.objectSubId = attForm->attnum;
+ audit_name = getObjectIdentity(&object);
+
+ sepgsql_avc_check_perms(&object,
+ SEPG_CLASS_DB_COLUMN,
+ SEPG_DB_COLUMN__DROP,
+ audit_name,
+ true);
+ pfree(audit_name);
+ }
+ ReleaseCatCacheList(attrList);
+ }
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
}
@@ -529,12 +666,21 @@ sepgsql_relation_truncate(Oid relOid)
uint16_t tclass = 0;
char relkind = get_rel_relkind(relOid);
- switch (relkind)
+ switch ((RelKind) relkind)
{
case RELKIND_RELATION:
case RELKIND_PARTITIONED_TABLE:
tclass = SEPG_CLASS_DB_TABLE;
break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
default:
/* ignore other relkinds */
return;
@@ -569,17 +715,32 @@ sepgsql_relation_relabel(Oid relOid, const char *seclabel)
char relkind = get_rel_relkind(relOid);
uint16_t tclass = 0;
- if (relkind == RELKIND_RELATION || relkind == RELKIND_PARTITIONED_TABLE)
- tclass = SEPG_CLASS_DB_TABLE;
- else if (relkind == RELKIND_SEQUENCE)
- tclass = SEPG_CLASS_DB_SEQUENCE;
- else if (relkind == RELKIND_VIEW)
- tclass = SEPG_CLASS_DB_VIEW;
- else
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot set security labels on relations except "
- "for tables, sequences or views")));
+ switch ((RelKind) relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ tclass = SEPG_CLASS_DB_TABLE;
+ break;
+ case RELKIND_SEQUENCE:
+ tclass = SEPG_CLASS_DB_SEQUENCE;
+ break;
+ case RELKIND_VIEW:
+ tclass = SEPG_CLASS_DB_VIEW;
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot set security labels on relations except "
+ "for tables, sequences or views")));
+ break;
+ }
object.classId = RelationRelationId;
object.objectId = relOid;
@@ -626,7 +787,7 @@ sepgsql_relation_setattr(Oid relOid)
char *audit_name;
uint16_t tclass;
- switch (get_rel_relkind(relOid))
+ switch ((RelKind) get_rel_relkind(relOid))
{
case RELKIND_RELATION:
case RELKIND_PARTITIONED_TABLE:
@@ -642,6 +803,12 @@ sepgsql_relation_setattr(Oid relOid)
/* deal with indexes specially */
sepgsql_index_modify(relOid);
return;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
default:
/* other relkinds don't need additional work */
return;
diff --git a/contrib/vacuumlo/vacuumlo.c b/contrib/vacuumlo/vacuumlo.c
index 92bdf71356..e07f8be8e3 100644
--- a/contrib/vacuumlo/vacuumlo.c
+++ b/contrib/vacuumlo/vacuumlo.c
@@ -203,7 +203,7 @@ vacuumlo(const char *database, const struct _param *param)
strcat(buf, " AND a.atttypid = t.oid ");
strcat(buf, " AND c.relnamespace = s.oid ");
strcat(buf, " AND t.typname in ('oid', 'lo') ");
- strcat(buf, " AND c.relkind in (" CppAsString2(RELKIND_RELATION) ", " CppAsString2(RELKIND_MATVIEW) ")");
+ strcat(buf, " AND c.relkind in (" RelKindAsString(RELKIND_RELATION) ", " RelKindAsString(RELKIND_MATVIEW) ")");
strcat(buf, " AND s.nspname !~ '^pg_'");
res = PQexec(conn, buf);
if (PQresultStatus(res) != PGRES_TUPLES_OK)
diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c
index 8ccc228a8c..d16e401060 100644
--- a/src/backend/access/common/reloptions.c
+++ b/src/backend/access/common/reloptions.c
@@ -1372,7 +1372,7 @@ extractRelOptions(HeapTuple tuple, TupleDesc tupdesc,
classForm = (Form_pg_class) GETSTRUCT(tuple);
/* Parse into appropriate format; don't error out here */
- switch (classForm->relkind)
+ switch ((RelKind) classForm->relkind)
{
case RELKIND_RELATION:
case RELKIND_TOASTVALUE:
@@ -1392,6 +1392,9 @@ extractRelOptions(HeapTuple tuple, TupleDesc tupdesc,
case RELKIND_FOREIGN_TABLE:
options = NULL;
break;
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_NULL:
default:
Assert(false); /* can't get here */
options = NULL; /* keep compiler quiet */
@@ -1997,7 +2000,7 @@ heap_reloptions(char relkind, Datum reloptions, bool validate)
{
StdRdOptions *rdopts;
- switch (relkind)
+ switch ((RelKind) relkind)
{
case RELKIND_TOASTVALUE:
rdopts = (StdRdOptions *)
@@ -2013,13 +2016,21 @@ heap_reloptions(char relkind, Datum reloptions, bool validate)
case RELKIND_RELATION:
case RELKIND_MATVIEW:
return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP);
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
default:
/* other relkinds are not supported */
return NULL;
}
+ return NULL; /* keep compiler happy */
}
-
/*
* Parse options for indexes.
*
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 537913d1bb..d6f91d5f93 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -2040,17 +2040,28 @@ heap_prepare_insert(Relation relation, HeapTuple tup, TransactionId xid,
* If the new tuple is too big for storage or contains already toasted
* out-of-line attributes from some other relation, invoke the toaster.
*/
- if (relation->rd_rel->relkind != RELKIND_RELATION &&
- relation->rd_rel->relkind != RELKIND_MATVIEW)
+ switch ((RelKind) relation->rd_rel->relkind)
{
- /* toast table entries should never be recursively toasted */
- Assert(!HeapTupleHasExternal(tup));
- return tup;
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ if (HeapTupleHasExternal(tup) || tup->t_len > TOAST_TUPLE_THRESHOLD)
+ return heap_toast_insert_or_update(relation, tup, NULL, options);
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ /* toast table entries should never be recursively toasted */
+ Assert(!HeapTupleHasExternal(tup));
+ break;
}
- else if (HeapTupleHasExternal(tup) || tup->t_len > TOAST_TUPLE_THRESHOLD)
- return heap_toast_insert_or_update(relation, tup, NULL, options);
- else
- return tup;
+ return tup;
}
/*
@@ -2773,14 +2784,27 @@ l1:
* because we need to look at the contents of the tuple, but it's OK to
* release the content lock on the buffer first.
*/
- if (relation->rd_rel->relkind != RELKIND_RELATION &&
- relation->rd_rel->relkind != RELKIND_MATVIEW)
+ switch ((RelKind) relation->rd_rel->relkind)
{
- /* toast table entries should never be recursively toasted */
- Assert(!HeapTupleHasExternal(&tp));
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ if (HeapTupleHasExternal(&tp))
+ heap_toast_delete(relation, &tp, false);
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ /* toast table entries should never be recursively toasted */
+ Assert(!HeapTupleHasExternal(&tp));
+ break;
}
- else if (HeapTupleHasExternal(&tp))
- heap_toast_delete(relation, &tp, false);
/*
* Mark tuple for invalidation from system caches at next command
@@ -3362,18 +3386,30 @@ l2:
* We need to invoke the toaster if there are already any out-of-line
* toasted values present, or if the new tuple is over-threshold.
*/
- if (relation->rd_rel->relkind != RELKIND_RELATION &&
- relation->rd_rel->relkind != RELKIND_MATVIEW)
+ switch ((RelKind) relation->rd_rel->relkind)
{
- /* toast table entries should never be recursively toasted */
- Assert(!HeapTupleHasExternal(&oldtup));
- Assert(!HeapTupleHasExternal(newtup));
- need_toast = false;
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ need_toast = (HeapTupleHasExternal(&oldtup) ||
+ HeapTupleHasExternal(newtup) ||
+ newtup->t_len > TOAST_TUPLE_THRESHOLD);
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ /* toast table entries should never be recursively toasted */
+ Assert(!HeapTupleHasExternal(&oldtup));
+ Assert(!HeapTupleHasExternal(newtup));
+ need_toast = false;
+ break;
}
- else
- need_toast = (HeapTupleHasExternal(&oldtup) ||
- HeapTupleHasExternal(newtup) ||
- newtup->t_len > TOAST_TUPLE_THRESHOLD);
pagefree = PageGetHeapFreeSpace(page);
diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c
index 56b35622f1..ba2ef7d45d 100644
--- a/src/backend/access/heap/heapam_handler.c
+++ b/src/backend/access/heap/heapam_handler.c
@@ -600,12 +600,27 @@ heapam_relation_set_new_filenode(Relation rel,
*/
if (persistence == RELPERSISTENCE_UNLOGGED)
{
- Assert(rel->rd_rel->relkind == RELKIND_RELATION ||
- rel->rd_rel->relkind == RELKIND_MATVIEW ||
- rel->rd_rel->relkind == RELKIND_TOASTVALUE);
- smgrcreate(srel, INIT_FORKNUM, false);
- log_smgrcreate(newrnode, INIT_FORKNUM);
- smgrimmedsync(srel, INIT_FORKNUM);
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ smgrcreate(srel, INIT_FORKNUM, false);
+ log_smgrcreate(newrnode, INIT_FORKNUM);
+ smgrimmedsync(srel, INIT_FORKNUM);
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ Assert(false);
+ break;
+ }
}
smgrclose(srel);
diff --git a/src/backend/access/heap/heaptoast.c b/src/backend/access/heap/heaptoast.c
index 584f101dd9..2d442aa2f0 100644
--- a/src/backend/access/heap/heaptoast.c
+++ b/src/backend/access/heap/heaptoast.c
@@ -50,8 +50,24 @@ heap_toast_delete(Relation rel, HeapTuple oldtup, bool is_speculative)
* We should only ever be called for tuples of plain relations or
* materialized views --- recursing on a toast rel is bad news.
*/
- Assert(rel->rd_rel->relkind == RELKIND_RELATION ||
- rel->rd_rel->relkind == RELKIND_MATVIEW);
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ Assert(false);
+ break;
+ }
/*
* Get the tuple descriptor and break down the tuple into fields.
@@ -122,8 +138,24 @@ heap_toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
* We should only ever be called for tuples of plain relations or
* materialized views --- recursing on a toast rel is bad news.
*/
- Assert(rel->rd_rel->relkind == RELKIND_RELATION ||
- rel->rd_rel->relkind == RELKIND_MATVIEW);
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ Assert(false);
+ break;
+ }
/*
* Get the tuple descriptor and break down the tuple(s) into fields.
diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c
index 6b9750c244..f830ef7951 100644
--- a/src/backend/access/index/indexam.c
+++ b/src/backend/access/index/indexam.c
@@ -135,12 +135,28 @@ 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)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not an index",
- RelationGetRelationName(r))));
+ switch ((RelKind) r->rd_rel->relkind)
+ {
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ break;
+
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not an index",
+ RelationGetRelationName(r))));
+ break;
+ }
return r;
}
diff --git a/src/backend/access/table/table.c b/src/backend/access/table/table.c
index 1aa01a54b3..fde36e8477 100644
--- a/src/backend/access/table/table.c
+++ b/src/backend/access/table/table.c
@@ -42,17 +42,32 @@ table_open(Oid relationId, LOCKMODE lockmode)
r = relation_open(relationId, lockmode);
- if (r->rd_rel->relkind == RELKIND_INDEX ||
- r->rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is an index",
- RelationGetRelationName(r))));
- else if (r->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is a composite type",
- RelationGetRelationName(r))));
+ switch ((RelKind) r->rd_rel->relkind)
+ {
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is an index",
+ RelationGetRelationName(r))));
+ break;
+ case RELKIND_COMPOSITE_TYPE:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is a composite type",
+ RelationGetRelationName(r))));
+ break;
+ case RELKIND_SEQUENCE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
return r;
}
@@ -71,17 +86,32 @@ table_openrv(const RangeVar *relation, LOCKMODE lockmode)
r = relation_openrv(relation, lockmode);
- if (r->rd_rel->relkind == RELKIND_INDEX ||
- r->rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is an index",
- RelationGetRelationName(r))));
- else if (r->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is a composite type",
- RelationGetRelationName(r))));
+ switch ((RelKind) r->rd_rel->relkind)
+ {
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is an index",
+ RelationGetRelationName(r))));
+ break;
+ case RELKIND_COMPOSITE_TYPE:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is a composite type",
+ RelationGetRelationName(r))));
+ break;
+ case RELKIND_SEQUENCE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
return r;
}
@@ -104,17 +134,32 @@ table_openrv_extended(const RangeVar *relation, LOCKMODE lockmode,
if (r)
{
- if (r->rd_rel->relkind == RELKIND_INDEX ||
- r->rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is an index",
- RelationGetRelationName(r))));
- else if (r->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is a composite type",
- RelationGetRelationName(r))));
+ switch ((RelKind) r->rd_rel->relkind)
+ {
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is an index",
+ RelationGetRelationName(r))));
+ break;
+ case RELKIND_COMPOSITE_TYPE:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is a composite type",
+ RelationGetRelationName(r))));
+ break;
+ case RELKIND_SEQUENCE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
}
return r;
diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c
index 4b2bb29559..e4a11ddd64 100644
--- a/src/backend/access/table/tableam.c
+++ b/src/backend/access/table/tableam.c
@@ -47,28 +47,42 @@ table_slot_callbacks(Relation relation)
if (relation->rd_tableam)
tts_cb = relation->rd_tableam->slot_callbacks(relation);
- else if (relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
- {
- /*
- * Historically FDWs expect to store heap tuples in slots. Continue
- * handing them one, to make it less painful to adapt FDWs to new
- * versions. The cost of a heap slot over a virtual slot is pretty
- * small.
- */
- tts_cb = &TTSOpsHeapTuple;
- }
else
- {
- /*
- * These need to be supported, as some parts of the code (like COPY)
- * need to create slots for such relations too. It seems better to
- * centralize the knowledge that a heap slot is the right thing in
- * that case here.
- */
- Assert(relation->rd_rel->relkind == RELKIND_VIEW ||
- relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
- tts_cb = &TTSOpsVirtual;
- }
+ switch ((RelKind) relation->rd_rel->relkind)
+ {
+ case RELKIND_FOREIGN_TABLE:
+
+ /*
+ * Historically FDWs expect to store heap tuples in slots.
+ * Continue handing them one, to make it less painful to adapt
+ * FDWs to new versions. The cost of a heap slot over a
+ * virtual slot is pretty small.
+ */
+ tts_cb = &TTSOpsHeapTuple;
+ break;
+ case RELKIND_VIEW:
+ case RELKIND_PARTITIONED_TABLE:
+
+ /*
+ * These need to be supported, as some parts of the code (like
+ * COPY) need to create slots for such relations too. It seems
+ * better to centralize the knowledge that a heap slot is the
+ * right thing in that case here.
+ */
+ tts_cb = &TTSOpsVirtual;
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ Assert(false);
+ break;
+ }
return tts_cb;
}
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index c626161408..a80e759a80 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -1765,36 +1765,65 @@ ExecGrant_Relation(InternalGrant *istmt)
elog(ERROR, "cache lookup failed for relation %u", relOid);
pg_class_tuple = (Form_pg_class) GETSTRUCT(tuple);
- /* Not sensible to grant on an index */
- if (pg_class_tuple->relkind == RELKIND_INDEX ||
- pg_class_tuple->relkind == RELKIND_PARTITIONED_INDEX)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is an index",
- NameStr(pg_class_tuple->relname))));
+ switch ((RelKind) pg_class_tuple->relkind)
+ {
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ /* Not sensible to grant on an index */
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is an index",
+ NameStr(pg_class_tuple->relname))));
- /* Composite types aren't tables either */
- if (pg_class_tuple->relkind == RELKIND_COMPOSITE_TYPE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is a composite type",
- NameStr(pg_class_tuple->relname))));
+ case RELKIND_COMPOSITE_TYPE:
+ /* Composite types aren't tables either */
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is a composite type",
+ NameStr(pg_class_tuple->relname))));
+
+ case RELKIND_SEQUENCE:
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ /* Used GRANT SEQUENCE on a non-sequence? */
+ if (istmt->objtype == OBJECT_SEQUENCE)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a sequence",
+ NameStr(pg_class_tuple->relname))));
+ break;
+ }
- /* Used GRANT SEQUENCE on a non-sequence? */
- if (istmt->objtype == OBJECT_SEQUENCE &&
- pg_class_tuple->relkind != RELKIND_SEQUENCE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a sequence",
- NameStr(pg_class_tuple->relname))));
/* Adjust the default permissions based on object type */
if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
{
- if (pg_class_tuple->relkind == RELKIND_SEQUENCE)
- this_privileges = ACL_ALL_RIGHTS_SEQUENCE;
- else
- this_privileges = ACL_ALL_RIGHTS_RELATION;
+ switch ((RelKind) pg_class_tuple->relkind)
+ {
+ case RELKIND_SEQUENCE:
+ this_privileges = ACL_ALL_RIGHTS_SEQUENCE;
+ break;
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ this_privileges = ACL_ALL_RIGHTS_RELATION;
+ break;
+ }
}
else
this_privileges = istmt->privileges;
@@ -1807,42 +1836,54 @@ ExecGrant_Relation(InternalGrant *istmt)
*/
if (istmt->objtype == OBJECT_TABLE)
{
- if (pg_class_tuple->relkind == RELKIND_SEQUENCE)
+ switch ((RelKind) pg_class_tuple->relkind)
{
- /*
- * For backward compatibility, just throw a warning for
- * invalid sequence permissions when using the non-sequence
- * GRANT syntax.
- */
- if (this_privileges & ~((AclMode) ACL_ALL_RIGHTS_SEQUENCE))
- {
- /*
- * Mention the object name because the user needs to know
- * which operations succeeded. This is required because
- * WARNING allows the command to continue.
- */
- ereport(WARNING,
- (errcode(ERRCODE_INVALID_GRANT_OPERATION),
- errmsg("sequence \"%s\" only supports USAGE, SELECT, and UPDATE privileges",
- NameStr(pg_class_tuple->relname))));
- this_privileges &= (AclMode) ACL_ALL_RIGHTS_SEQUENCE;
- }
- }
- else
- {
- if (this_privileges & ~((AclMode) ACL_ALL_RIGHTS_RELATION))
- {
+ case RELKIND_SEQUENCE:
+
/*
- * USAGE is the only permission supported by sequences but
- * not by non-sequences. Don't mention the object name
- * because we didn't in the combined TABLE | SEQUENCE
- * check.
+ * For backward compatibility, just throw a warning for
+ * invalid sequence permissions when using the
+ * non-sequence GRANT syntax.
*/
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_GRANT_OPERATION),
- errmsg("invalid privilege type %s for table",
- "USAGE")));
- }
+ if (this_privileges & ~((AclMode) ACL_ALL_RIGHTS_SEQUENCE))
+ {
+ /*
+ * Mention the object name because the user needs to
+ * know which operations succeeded. This is required
+ * because WARNING allows the command to continue.
+ */
+ ereport(WARNING,
+ (errcode(ERRCODE_INVALID_GRANT_OPERATION),
+ errmsg("sequence \"%s\" only supports USAGE, SELECT, and UPDATE privileges",
+ NameStr(pg_class_tuple->relname))));
+ this_privileges &= (AclMode) ACL_ALL_RIGHTS_SEQUENCE;
+ }
+ break;
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ if (this_privileges & ~((AclMode) ACL_ALL_RIGHTS_RELATION))
+ {
+ /*
+ * USAGE is the only permission supported by sequences
+ * but not by non-sequences. Don't mention the object
+ * name because we didn't in the combined TABLE |
+ * SEQUENCE check.
+ */
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_GRANT_OPERATION),
+ errmsg("invalid privilege type %s for table",
+ "USAGE")));
+ }
+ break;
}
}
@@ -1881,12 +1922,21 @@ ExecGrant_Relation(InternalGrant *istmt)
&isNull);
if (isNull)
{
- switch (pg_class_tuple->relkind)
+ switch ((RelKind) pg_class_tuple->relkind)
{
case RELKIND_SEQUENCE:
old_acl = acldefault(OBJECT_SEQUENCE, ownerId);
break;
- default:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
old_acl = acldefault(OBJECT_TABLE, ownerId);
break;
}
@@ -1925,11 +1975,21 @@ ExecGrant_Relation(InternalGrant *istmt)
old_acl, ownerId,
&grantorId, &avail_goptions);
- switch (pg_class_tuple->relkind)
+ switch ((RelKind) pg_class_tuple->relkind)
{
case RELKIND_SEQUENCE:
objtype = OBJECT_SEQUENCE;
break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
default:
objtype = OBJECT_TABLE;
break;
@@ -2009,20 +2069,36 @@ ExecGrant_Relation(InternalGrant *istmt)
errmsg("invalid privilege type %s for column",
privilege_to_string(this_privileges))));
- if (pg_class_tuple->relkind == RELKIND_SEQUENCE &&
- this_privileges & ~((AclMode) ACL_SELECT))
+ switch ((RelKind) pg_class_tuple->relkind)
{
- /*
- * The only column privilege allowed on sequences is SELECT.
- * This is a warning not error because we do it that way for
- * relation-level privileges.
- */
- ereport(WARNING,
- (errcode(ERRCODE_INVALID_GRANT_OPERATION),
- errmsg("sequence \"%s\" only supports SELECT column privileges",
- NameStr(pg_class_tuple->relname))));
+ case RELKIND_SEQUENCE:
+ if (this_privileges & ~((AclMode) ACL_SELECT))
+ {
+ /*
+ * The only column privilege allowed on sequences is
+ * SELECT. This is a warning not error because we do
+ * it that way for relation-level privileges.
+ */
+ ereport(WARNING,
+ (errcode(ERRCODE_INVALID_GRANT_OPERATION),
+ errmsg("sequence \"%s\" only supports SELECT column privileges",
+ NameStr(pg_class_tuple->relname))));
- this_privileges &= (AclMode) ACL_SELECT;
+ this_privileges &= (AclMode) ACL_SELECT;
+ }
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
expand_col_privileges(col_privs->cols, relOid,
@@ -3824,11 +3900,21 @@ pg_class_aclmask(Oid table_oid, Oid roleid,
if (isNull)
{
/* No ACL, so build default ACL */
- switch (classForm->relkind)
+ switch ((RelKind) classForm->relkind)
{
case RELKIND_SEQUENCE:
acl = acldefault(OBJECT_SEQUENCE, ownerId);
break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
default:
acl = acldefault(OBJECT_TABLE, ownerId);
break;
@@ -5519,58 +5605,85 @@ recordExtObjInitPriv(Oid objoid, Oid classoid)
* composite types. (These cases are unreachable given the
* restrictions in ALTER EXTENSION ADD, but let's check anyway.)
*/
- if (pg_class_tuple->relkind == RELKIND_INDEX ||
- pg_class_tuple->relkind == RELKIND_PARTITIONED_INDEX ||
- pg_class_tuple->relkind == RELKIND_COMPOSITE_TYPE)
+ switch ((RelKind) pg_class_tuple->relkind)
{
- ReleaseSysCache(tuple);
- return;
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ ReleaseSysCache(tuple);
+ return;
+ case RELKIND_SEQUENCE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
/*
* If this isn't a sequence then it's possibly going to have
* column-level ACLs associated with it.
*/
- if (pg_class_tuple->relkind != RELKIND_SEQUENCE)
+ switch ((RelKind) pg_class_tuple->relkind)
{
- AttrNumber curr_att;
- AttrNumber nattrs = pg_class_tuple->relnatts;
-
- for (curr_att = 1; curr_att <= nattrs; curr_att++)
- {
- HeapTuple attTuple;
- Datum attaclDatum;
-
- attTuple = SearchSysCache2(ATTNUM,
- ObjectIdGetDatum(objoid),
- Int16GetDatum(curr_att));
-
- if (!HeapTupleIsValid(attTuple))
- continue;
-
- /* ignore dropped columns */
- if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
+ case RELKIND_SEQUENCE:
+ break;
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
{
- ReleaseSysCache(attTuple);
- continue;
- }
-
- attaclDatum = SysCacheGetAttr(ATTNUM, attTuple,
- Anum_pg_attribute_attacl,
- &isNull);
+ AttrNumber curr_att;
+ AttrNumber nattrs = pg_class_tuple->relnatts;
- /* no need to do anything for a NULL ACL */
- if (isNull)
- {
- ReleaseSysCache(attTuple);
- continue;
+ for (curr_att = 1; curr_att <= nattrs; curr_att++)
+ {
+ HeapTuple attTuple;
+ Datum attaclDatum;
+
+ attTuple = SearchSysCache2(ATTNUM,
+ ObjectIdGetDatum(objoid),
+ Int16GetDatum(curr_att));
+
+ if (!HeapTupleIsValid(attTuple))
+ continue;
+
+ /* ignore dropped columns */
+ if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
+ {
+ ReleaseSysCache(attTuple);
+ continue;
+ }
+
+ attaclDatum = SysCacheGetAttr(ATTNUM, attTuple,
+ Anum_pg_attribute_attacl,
+ &isNull);
+
+ /* no need to do anything for a NULL ACL */
+ if (isNull)
+ {
+ ReleaseSysCache(attTuple);
+ continue;
+ }
+
+ recordExtensionInitPrivWorker(objoid, classoid, curr_att,
+ DatumGetAclP(attaclDatum));
+
+ ReleaseSysCache(attTuple);
+ }
}
-
- recordExtensionInitPrivWorker(objoid, classoid, curr_att,
- DatumGetAclP(attaclDatum));
-
- ReleaseSysCache(attTuple);
- }
+ break;
}
aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl,
@@ -5813,40 +5926,70 @@ removeExtObjInitPriv(Oid objoid, Oid classoid)
* composite types. (These cases are unreachable given the
* restrictions in ALTER EXTENSION DROP, but let's check anyway.)
*/
- if (pg_class_tuple->relkind == RELKIND_INDEX ||
- pg_class_tuple->relkind == RELKIND_PARTITIONED_INDEX ||
- pg_class_tuple->relkind == RELKIND_COMPOSITE_TYPE)
+ switch ((RelKind) pg_class_tuple->relkind)
{
- ReleaseSysCache(tuple);
- return;
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ ReleaseSysCache(tuple);
+ return;
+ case RELKIND_SEQUENCE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
/*
* If this isn't a sequence then it's possibly going to have
* column-level ACLs associated with it.
*/
- if (pg_class_tuple->relkind != RELKIND_SEQUENCE)
+ switch ((RelKind) pg_class_tuple->relkind)
{
- AttrNumber curr_att;
- AttrNumber nattrs = pg_class_tuple->relnatts;
+ case RELKIND_SEQUENCE:
+ break;
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ {
+ AttrNumber curr_att;
+ AttrNumber nattrs = pg_class_tuple->relnatts;
- for (curr_att = 1; curr_att <= nattrs; curr_att++)
- {
- HeapTuple attTuple;
+ for (curr_att = 1; curr_att <= nattrs; curr_att++)
+ {
+ HeapTuple attTuple;
- attTuple = SearchSysCache2(ATTNUM,
- ObjectIdGetDatum(objoid),
- Int16GetDatum(curr_att));
+ attTuple = SearchSysCache2(ATTNUM,
+ ObjectIdGetDatum(objoid),
+ Int16GetDatum(curr_att));
- if (!HeapTupleIsValid(attTuple))
- continue;
+ if (!HeapTupleIsValid(attTuple))
+ continue;
- /* when removing, remove all entries, even dropped columns */
+ /*
+ * when removing, remove all entries, even dropped
+ * columns
+ */
- recordExtensionInitPrivWorker(objoid, classoid, curr_att, NULL);
+ recordExtensionInitPrivWorker(objoid, classoid, curr_att, NULL);
- ReleaseSysCache(attTuple);
- }
+ ReleaseSysCache(attTuple);
+ }
+ }
+ break;
}
ReleaseSysCache(tuple);
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index b33a2f94af..51af304fa6 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -1395,22 +1395,36 @@ doDeletion(const ObjectAddress *object, int flags)
{
char relKind = get_rel_relkind(object->objectId);
- if (relKind == RELKIND_INDEX ||
- relKind == RELKIND_PARTITIONED_INDEX)
+ switch ((RelKind) relKind)
{
- bool concurrent = ((flags & PERFORM_DELETION_CONCURRENTLY) != 0);
- bool concurrent_lock_mode = ((flags & PERFORM_DELETION_CONCURRENT_LOCK) != 0);
-
- Assert(object->objectSubId == 0);
- index_drop(object->objectId, concurrent, concurrent_lock_mode);
- }
- else
- {
- if (object->objectSubId != 0)
- RemoveAttributeById(object->objectId,
- object->objectSubId);
- else
- heap_drop_with_catalog(object->objectId);
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ {
+ bool concurrent = ((flags & PERFORM_DELETION_CONCURRENTLY) != 0);
+ bool concurrent_lock_mode = ((flags & PERFORM_DELETION_CONCURRENT_LOCK) != 0);
+
+ Assert(object->objectSubId == 0);
+ index_drop(object->objectId, concurrent, concurrent_lock_mode);
+ }
+ break;
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ {
+ if (object->objectSubId != 0)
+ RemoveAttributeById(object->objectId,
+ object->objectSubId);
+ else
+ heap_drop_with_catalog(object->objectId);
+ }
+ break;
}
/*
@@ -1419,8 +1433,8 @@ doDeletion(const ObjectAddress *object, int flags)
*/
if (relKind == RELKIND_SEQUENCE)
DeleteSequenceTuple(object->objectId);
- break;
}
+ break;
case OCLASS_PROC:
RemoveFunctionById(object->objectId);
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 3c83fe6bab..9af088b47c 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -335,7 +335,7 @@ heap_create(const char *relname,
*relminmxid = InvalidMultiXactId;
/* Handle reltablespace for specific relkinds. */
- switch (relkind)
+ switch ((RelKind) relkind)
{
case RELKIND_VIEW:
case RELKIND_COMPOSITE_TYPE:
@@ -360,6 +360,14 @@ heap_create(const char *relname,
*/
reltablespace = InvalidOid;
break;
+
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
default:
break;
}
@@ -415,21 +423,12 @@ heap_create(const char *relname,
{
RelationOpenSmgr(rel);
- switch (rel->rd_rel->relkind)
+ switch ((RelKind) 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:
@@ -437,6 +436,14 @@ heap_create(const char *relname,
relpersistence,
relfrozenxid, relminmxid);
break;
+ case RELKIND_VIEW:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_NULL:
+ default:
+ Assert(false);
}
}
@@ -506,18 +513,32 @@ CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind,
* Skip this for a view or type relation, since those don't have system
* attributes.
*/
- if (relkind != RELKIND_VIEW && relkind != RELKIND_COMPOSITE_TYPE)
+ switch ((RelKind) relkind)
{
- for (i = 0; i < natts; i++)
- {
- Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
+ case RELKIND_VIEW:
+ case RELKIND_COMPOSITE_TYPE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ for (i = 0; i < natts; i++)
+ {
+ Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
- if (SystemAttributeByName(NameStr(attr->attname)) != NULL)
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_COLUMN),
- errmsg("column name \"%s\" conflicts with a system column name",
- NameStr(attr->attname))));
- }
+ if (SystemAttributeByName(NameStr(attr->attname)) != NULL)
+ ereport(ERROR,
+ (errcode(ERRCODE_DUPLICATE_COLUMN),
+ errmsg("column name \"%s\" conflicts with a system column name",
+ NameStr(attr->attname))));
+ }
+ break;
}
/*
@@ -842,19 +863,33 @@ AddNewAttributeTuples(Oid new_rel_oid,
* all for a view or type relation. We don't bother with making datatype
* dependencies here, since presumably all these types are pinned.
*/
- if (relkind != RELKIND_VIEW && relkind != RELKIND_COMPOSITE_TYPE)
+ switch ((RelKind) relkind)
{
- for (i = 0; i < (int) lengthof(SysAtt); i++)
- {
- FormData_pg_attribute attStruct;
+ case RELKIND_VIEW:
+ case RELKIND_COMPOSITE_TYPE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ for (i = 0; i < (int) lengthof(SysAtt); i++)
+ {
+ FormData_pg_attribute attStruct;
- memcpy(&attStruct, SysAtt[i], sizeof(FormData_pg_attribute));
+ memcpy(&attStruct, SysAtt[i], sizeof(FormData_pg_attribute));
- /* Fill in the correct relation OID in the copied tuple */
- attStruct.attrelid = new_rel_oid;
+ /* Fill in the correct relation OID in the copied tuple */
+ attStruct.attrelid = new_rel_oid;
- InsertPgAttributeTuple(rel, &attStruct, (Datum) 0, indstate);
- }
+ InsertPgAttributeTuple(rel, &attStruct, (Datum) 0, indstate);
+ }
+ break;
}
/*
@@ -972,7 +1007,7 @@ AddNewRelationTuple(Relation pg_class_desc,
*/
new_rel_reltup = new_rel_desc->rd_rel;
- switch (relkind)
+ switch ((RelKind) relkind)
{
case RELKIND_RELATION:
case RELKIND_MATVIEW:
@@ -989,6 +1024,12 @@ AddNewRelationTuple(Relation pg_class_desc,
new_rel_reltup->reltuples = 1;
new_rel_reltup->relallvisible = 0;
break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
default:
/* Views, etc, have no disk storage */
new_rel_reltup->relpages = 0;
@@ -1221,7 +1262,7 @@ heap_create_with_catalog(const char *relname,
*/
if (use_user_acl)
{
- switch (relkind)
+ switch ((RelKind) relkind)
{
case RELKIND_RELATION:
case RELKIND_VIEW:
@@ -1235,6 +1276,11 @@ heap_create_with_catalog(const char *relname,
relacl = get_user_default_acl(OBJECT_SEQUENCE, ownerid,
relnamespace);
break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
default:
relacl = NULL;
break;
@@ -1273,13 +1319,27 @@ heap_create_with_catalog(const char *relname,
* during initdb). We do not create them where the use of a relation as
* such is an implementation detail: toast tables, sequences and indexes.
*/
- if (IsUnderPostmaster && (relkind == RELKIND_RELATION ||
- relkind == RELKIND_VIEW ||
- relkind == RELKIND_MATVIEW ||
- relkind == RELKIND_FOREIGN_TABLE ||
- relkind == RELKIND_COMPOSITE_TYPE ||
- relkind == RELKIND_PARTITIONED_TABLE))
- new_array_oid = AssignTypeArrayOid();
+ if (IsUnderPostmaster)
+ {
+ switch ((RelKind) relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_VIEW:
+ case RELKIND_MATVIEW:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_PARTITIONED_TABLE:
+ new_array_oid = AssignTypeArrayOid();
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_INDEX:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
+ }
/*
* Since defining a relation also defines a complex type, we add a new
@@ -1385,51 +1445,67 @@ heap_create_with_catalog(const char *relname,
* Also, skip this in bootstrap mode, since we don't make dependencies
* while bootstrapping.
*/
- if (relkind != RELKIND_COMPOSITE_TYPE &&
- relkind != RELKIND_TOASTVALUE &&
- !IsBootstrapProcessingMode())
+ switch ((RelKind) relkind)
{
- ObjectAddress myself,
- referenced;
-
- myself.classId = RelationRelationId;
- myself.objectId = relid;
- myself.objectSubId = 0;
-
- referenced.classId = NamespaceRelationId;
- referenced.objectId = relnamespace;
- referenced.objectSubId = 0;
- recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
-
- recordDependencyOnOwner(RelationRelationId, relid, ownerid);
-
- recordDependencyOnNewAcl(RelationRelationId, relid, 0, ownerid, relacl);
-
- recordDependencyOnCurrentExtension(&myself, false);
-
- if (reloftypeid)
- {
- referenced.classId = TypeRelationId;
- referenced.objectId = reloftypeid;
- referenced.objectSubId = 0;
- recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
- }
-
- /*
- * Make a dependency link to force the relation to be deleted if its
- * access method is. Do this only for relation and materialized views.
- *
- * 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)
- {
- referenced.classId = AccessMethodRelationId;
- referenced.objectId = accessmtd;
- referenced.objectSubId = 0;
- recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
- }
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_TOASTVALUE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ if (!IsBootstrapProcessingMode())
+ {
+ ObjectAddress myself,
+ referenced;
+
+ myself.classId = RelationRelationId;
+ myself.objectId = relid;
+ myself.objectSubId = 0;
+
+ referenced.classId = NamespaceRelationId;
+ referenced.objectId = relnamespace;
+ referenced.objectSubId = 0;
+ recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+
+ recordDependencyOnOwner(RelationRelationId, relid, ownerid);
+
+ recordDependencyOnNewAcl(RelationRelationId, relid, 0, ownerid, relacl);
+
+ recordDependencyOnCurrentExtension(&myself, false);
+
+ if (reloftypeid)
+ {
+ referenced.classId = TypeRelationId;
+ referenced.objectId = reloftypeid;
+ referenced.objectSubId = 0;
+ recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+ }
+
+ /*
+ * Make a dependency link to force the relation to be deleted
+ * if its access method is. Do this only for relation and
+ * materialized views.
+ *
+ * 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)
+ {
+ referenced.classId = AccessMethodRelationId;
+ referenced.objectId = accessmtd;
+ referenced.objectSubId = 0;
+ recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+ }
+ }
+ break;
}
/* Post creation hook for new relation */
@@ -2388,12 +2464,28 @@ StoreRelCheck(Relation rel, const char *ccname, Node *expr,
* Partitioned tables do not contain any rows themselves, so a NO INHERIT
* constraint makes no sense.
*/
- if (is_no_inherit &&
- rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
- errmsg("cannot add NO INHERIT constraint to partitioned table \"%s\"",
- RelationGetRelationName(rel))));
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ if (is_no_inherit)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
+ errmsg("cannot add NO INHERIT constraint to partitioned table \"%s\"",
+ RelationGetRelationName(rel))));
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
/*
* Create the Check Constraint
@@ -3259,8 +3351,23 @@ heap_truncate_one_rel(Relation rel)
* Truncate the relation. Partitioned tables have no storage, so there is
* nothing to do for them here.
*/
- if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- return;
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ return;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
/* Truncate the underlying relation */
table_relation_nontransactional_truncate(rel);
@@ -3313,9 +3420,26 @@ heap_truncate_check_FKs(List *relations, bool tempTables)
{
Relation rel = lfirst(cell);
- if (rel->rd_rel->relhastriggers ||
- rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- oids = lappend_oid(oids, RelationGetRelid(rel));
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ if (!rel->rd_rel->relhastriggers)
+ break;
+ /* fallthrough */
+ case RELKIND_PARTITIONED_TABLE:
+ oids = lappend_oid(oids, RelationGetRelid(rel));
+ break;
+ }
}
/*
@@ -3538,7 +3662,24 @@ StorePartitionKey(Relation rel,
ObjectAddress myself;
ObjectAddress referenced;
- Assert(rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ Assert(false);
+ break;
+ }
/* Copy the partition attribute numbers, opclass OIDs into arrays */
partattrs_vec = buildint2vector(partattrs, partnatts);
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index cdc01c49c9..16b753258d 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -2220,8 +2220,24 @@ 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)
- RelationDropStorage(userIndexRelation);
+ switch ((RelKind) userIndexRelation->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_INDEX:
+ break;
+ case RELKIND_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ RelationDropStorage(userIndexRelation);
+ break;
+ }
/*
* Close and flush the index's relcache entry, to ensure relcache doesn't
@@ -2748,7 +2764,23 @@ index_update_stats(Relation rel,
rd_rel = (Form_pg_class) GETSTRUCT(tuple);
/* Should this be a more comprehensive test? */
- Assert(rd_rel->relkind != RELKIND_PARTITIONED_INDEX);
+ switch ((RelKind) rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_INDEX:
+ Assert(false);
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_INDEX:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
/* Apply required updates, if any, to copied tuple */
@@ -2764,10 +2796,25 @@ index_update_stats(Relation rel,
BlockNumber relpages = RelationGetNumberOfBlocks(rel);
BlockNumber relallvisible;
- if (rd_rel->relkind != RELKIND_INDEX)
- visibilitymap_count(rel, &relallvisible, NULL);
- else /* don't bother for indexes */
- relallvisible = 0;
+ switch ((RelKind) rd_rel->relkind)
+ {
+ case RELKIND_INDEX:
+ relallvisible = 0;
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ visibilitymap_count(rel, &relallvisible, NULL);
+ break;
+ }
if (rd_rel->relpages != (int32) relpages)
{
@@ -3478,9 +3525,25 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
* The case of reindexing partitioned tables and indexes is handled
* differently by upper layers, so this case shouldn't arise.
*/
- if (iRel->rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
- elog(ERROR, "unsupported relation kind for index \"%s\"",
- RelationGetRelationName(iRel));
+ switch ((RelKind) iRel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_INDEX:
+ elog(ERROR, "unsupported relation kind for index \"%s\"",
+ RelationGetRelationName(iRel));
+ break;
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
/*
* Don't allow reindex on temp tables of other backends ... their local
@@ -3694,14 +3757,27 @@ reindex_relation(Oid relid, int flags, int options)
* (REINDEX SCHEMA) and happen to come across a partitioned table. The
* partitions may be reindexed on their own anyway.
*/
- if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
+ switch ((RelKind) rel->rd_rel->relkind)
{
- ereport(WARNING,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("REINDEX of partitioned tables is not yet implemented, skipping \"%s\"",
- RelationGetRelationName(rel))));
- table_close(rel, ShareLock);
- return false;
+ case RELKIND_PARTITIONED_TABLE:
+ ereport(WARNING,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("REINDEX of partitioned tables is not yet implemented, skipping \"%s\"",
+ RelationGetRelationName(rel))));
+ table_close(rel, ShareLock);
+ return false;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
toast_relid = rel->rd_rel->reltoastrelid;
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index 534df8e802..4d8c1ca4c5 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -97,7 +97,8 @@
*/
typedef struct
{
- const char *class_descr; /* string describing the catalog, for internal error messages */
+ const char *class_descr; /* string describing the catalog, for internal
+ * error messages */
Oid class_oid; /* oid of catalog */
Oid oid_index_oid; /* oid of index on system oid column */
int oid_catcache_id; /* id of catcache on system oid column */
@@ -1342,48 +1343,136 @@ get_relation_by_qualified_name(ObjectType objtype, List *object,
switch (objtype)
{
case OBJECT_INDEX:
- if (relation->rd_rel->relkind != RELKIND_INDEX &&
- relation->rd_rel->relkind != RELKIND_PARTITIONED_INDEX)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not an index",
- RelationGetRelationName(relation))));
+ switch ((RelKind) relation->rd_rel->relkind)
+ {
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ break;
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not an index",
+ RelationGetRelationName(relation))));
+ }
break;
case OBJECT_SEQUENCE:
- if (relation->rd_rel->relkind != RELKIND_SEQUENCE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a sequence",
- RelationGetRelationName(relation))));
+ switch ((RelKind) relation->rd_rel->relkind)
+ {
+ case RELKIND_SEQUENCE:
+ break;
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a sequence",
+ RelationGetRelationName(relation))));
+ }
break;
case OBJECT_TABLE:
- if (relation->rd_rel->relkind != RELKIND_RELATION &&
- relation->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table",
- RelationGetRelationName(relation))));
+ switch ((RelKind) relation->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ break;
+ case RELKIND_SEQUENCE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a table",
+ RelationGetRelationName(relation))));
+ }
break;
case OBJECT_VIEW:
- if (relation->rd_rel->relkind != RELKIND_VIEW)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a view",
- RelationGetRelationName(relation))));
+ switch ((RelKind) relation->rd_rel->relkind)
+ {
+ case RELKIND_VIEW:
+ break;
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_SEQUENCE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a view",
+ RelationGetRelationName(relation))));
+ }
break;
case OBJECT_MATVIEW:
- if (relation->rd_rel->relkind != RELKIND_MATVIEW)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a materialized view",
- RelationGetRelationName(relation))));
+ switch ((RelKind) relation->rd_rel->relkind)
+ {
+ case RELKIND_MATVIEW:
+ break;
+ case RELKIND_VIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_SEQUENCE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a materialized view",
+ RelationGetRelationName(relation))));
+ }
break;
case OBJECT_FOREIGN_TABLE:
- if (relation->rd_rel->relkind != RELKIND_FOREIGN_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a foreign table",
- RelationGetRelationName(relation))));
+ switch ((RelKind) relation->rd_rel->relkind)
+ {
+ case RELKIND_FOREIGN_TABLE:
+ break;
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_SEQUENCE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a foreign table",
+ RelationGetRelationName(relation))));
+ }
break;
default:
elog(ERROR, "unrecognized objtype: %d", (int) objtype);
@@ -3795,7 +3884,7 @@ getRelationDescription(StringInfo buffer, Oid relid)
relname = quote_qualified_identifier(nspname, NameStr(relForm->relname));
- switch (relForm->relkind)
+ switch ((RelKind) relForm->relkind)
{
case RELKIND_RELATION:
case RELKIND_PARTITIONED_TABLE:
@@ -3831,6 +3920,7 @@ getRelationDescription(StringInfo buffer, Oid relid)
appendStringInfo(buffer, _("foreign table %s"),
relname);
break;
+ case RELKIND_NULL:
default:
/* shouldn't get here */
appendStringInfo(buffer, _("relation %s"),
@@ -4276,7 +4366,7 @@ getRelationTypeDescription(StringInfo buffer, Oid relid, int32 objectSubId)
elog(ERROR, "cache lookup failed for relation %u", relid);
relForm = (Form_pg_class) GETSTRUCT(relTup);
- switch (relForm->relkind)
+ switch ((RelKind) relForm->relkind)
{
case RELKIND_RELATION:
case RELKIND_PARTITIONED_TABLE:
@@ -4304,6 +4394,7 @@ getRelationTypeDescription(StringInfo buffer, Oid relid, int32 objectSubId)
case RELKIND_FOREIGN_TABLE:
appendStringInfoString(buffer, "foreign table");
break;
+ case RELKIND_NULL:
default:
/* shouldn't get here */
appendStringInfoString(buffer, "relation");
@@ -5451,7 +5542,7 @@ strlist_to_textarray(List *list)
ObjectType
get_relkind_objtype(char relkind)
{
- switch (relkind)
+ switch ((RelKind) relkind)
{
case RELKIND_RELATION:
case RELKIND_PARTITIONED_TABLE:
@@ -5469,6 +5560,8 @@ get_relkind_objtype(char relkind)
return OBJECT_FOREIGN_TABLE;
case RELKIND_TOASTVALUE:
return OBJECT_TABLE;
+ case RELKIND_NULL:
+ case RELKIND_COMPOSITE_TYPE:
default:
/* Per above, don't raise an error */
return OBJECT_TABLE;
diff --git a/src/backend/catalog/partition.c b/src/backend/catalog/partition.c
index 239ac017fa..65c4b96289 100644
--- a/src/backend/catalog/partition.c
+++ b/src/backend/catalog/partition.c
@@ -235,8 +235,25 @@ has_partition_attrs(Relation rel, Bitmapset *attnums, bool *used_in_expr)
ListCell *partexprs_item;
int i;
- if (attnums == NULL || rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
- return false;
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ if (attnums == NULL)
+ return false;
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ return false;
+ }
key = RelationGetPartitionKey(rel);
partnatts = get_partition_natts(key);
diff --git a/src/backend/catalog/pg_depend.c b/src/backend/catalog/pg_depend.c
index 21cfdcace9..2ba55bc6b3 100644
--- a/src/backend/catalog/pg_depend.c
+++ b/src/backend/catalog/pg_depend.c
@@ -837,14 +837,31 @@ getOwnedSequences_internal(Oid relid, AttrNumber attnum, char deptype)
* must be what we are looking for. (We need the relkind test because
* indexes can also have auto dependencies on columns.)
*/
- if (deprec->classid == RelationRelationId &&
- deprec->objsubid == 0 &&
- deprec->refobjsubid != 0 &&
- (deprec->deptype == DEPENDENCY_AUTO || deprec->deptype == DEPENDENCY_INTERNAL) &&
- get_rel_relkind(deprec->objid) == RELKIND_SEQUENCE)
+ switch ((RelKind) get_rel_relkind(deprec->objid))
{
- if (!deptype || deprec->deptype == deptype)
- result = lappend_oid(result, deprec->objid);
+ case RELKIND_SEQUENCE:
+ if (deprec->classid == RelationRelationId &&
+ deprec->objsubid == 0 &&
+ deprec->refobjsubid != 0 &&
+ (deprec->deptype == DEPENDENCY_AUTO ||
+ deprec->deptype == DEPENDENCY_INTERNAL) &&
+ (!deptype || deprec->deptype == deptype))
+ {
+ result = lappend_oid(result, deprec->objid);
+ }
+ break;
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
}
@@ -940,9 +957,23 @@ get_constraint_index(Oid constraintId)
* This is pure paranoia; there shouldn't be any other relkinds
* dependent on a constraint.
*/
- if (relkind != RELKIND_INDEX &&
- relkind != RELKIND_PARTITIONED_INDEX)
- continue;
+ switch ((RelKind) relkind)
+ {
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ break;
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ continue;
+ }
indexId = deprec->objid;
break;
diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c
index 09946be788..336de8e97f 100644
--- a/src/backend/catalog/pg_publication.c
+++ b/src/backend/catalog/pg_publication.c
@@ -50,13 +50,27 @@ static void
check_publication_add_relation(Relation targetrel)
{
/* Must be a regular or partitioned table */
- if (RelationGetForm(targetrel)->relkind != RELKIND_RELATION &&
- RelationGetForm(targetrel)->relkind != RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("\"%s\" is not a table",
- RelationGetRelationName(targetrel)),
- errdetail("Only tables can be added to publications.")));
+ switch ((RelKind) RelationGetForm(targetrel)->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("\"%s\" is not a table",
+ RelationGetRelationName(targetrel)),
+ errdetail("Only tables can be added to publications.")));
+ }
/* Can't be system table */
if (IsCatalogRelation(targetrel))
@@ -97,11 +111,26 @@ check_publication_add_relation(Relation targetrel)
static bool
is_publishable_class(Oid relid, Form_pg_class reltuple)
{
- return (reltuple->relkind == RELKIND_RELATION ||
- reltuple->relkind == RELKIND_PARTITIONED_TABLE) &&
- !IsCatalogRelationOid(relid) &&
- reltuple->relpersistence == RELPERSISTENCE_PERMANENT &&
- relid >= FirstNormalObjectId;
+ switch ((RelKind) reltuple->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ return (!IsCatalogRelationOid(relid) &&
+ reltuple->relpersistence == RELPERSISTENCE_PERMANENT &&
+ relid >= FirstNormalObjectId);
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ return false;
+ }
}
/*
diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c
index 79ffe317dd..bca5c5b1fa 100644
--- a/src/backend/catalog/pg_type.c
+++ b/src/backend/catalog/pg_type.c
@@ -658,10 +658,25 @@ GenerateTypeDependencies(HeapTuple typeTuple,
{
ObjectAddressSet(referenced, RelationRelationId, typeForm->typrelid);
- if (relationKind != RELKIND_COMPOSITE_TYPE)
- recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL);
- else
- recordDependencyOn(&referenced, &myself, DEPENDENCY_INTERNAL);
+ switch ((RelKind) relationKind)
+ {
+ case RELKIND_COMPOSITE_TYPE:
+ recordDependencyOn(&referenced, &myself, DEPENDENCY_INTERNAL);
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL);
+ break;
+ }
}
/*
diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c
index 3f7ab8d389..d878d07660 100644
--- a/src/backend/catalog/toasting.c
+++ b/src/backend/catalog/toasting.c
@@ -99,12 +99,27 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid)
rel = table_openrv(makeRangeVar(NULL, relName, -1), AccessExclusiveLock);
- if (rel->rd_rel->relkind != RELKIND_RELATION &&
- rel->rd_rel->relkind != RELKIND_MATVIEW)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table or materialized view",
- relName)));
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a table or materialized view",
+ relName)));
+ break;
+ }
/* create_toast_table does all the work */
if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0,
@@ -394,8 +409,23 @@ needs_toast_table(Relation rel)
/*
* No need to create a TOAST table for partitioned tables.
*/
- if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- return false;
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ return false;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
/*
* We cannot allow toasting a shared relation after initdb (because
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index 924ef37c81..1a64bc22e9 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -196,54 +196,75 @@ analyze_rel(Oid relid, RangeVar *relation,
/*
* Check that it's of an analyzable relkind, and set up appropriately.
*/
- if (onerel->rd_rel->relkind == RELKIND_RELATION ||
- onerel->rd_rel->relkind == RELKIND_MATVIEW)
+ switch ((RelKind) onerel->rd_rel->relkind)
{
- /* Regular table, so we'll use the regular row acquisition function */
- acquirefunc = acquire_sample_rows;
- /* Also get regular table's size */
- relpages = RelationGetNumberOfBlocks(onerel);
- }
- else if (onerel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
- {
- /*
- * For a foreign table, call the FDW's hook function to see whether it
- * supports analysis.
- */
- FdwRoutine *fdwroutine;
- bool ok = false;
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ {
+ /*
+ * Regular table, so we'll use the regular row acquisition
+ * function
+ */
+ acquirefunc = acquire_sample_rows;
+ /* Also get regular table's size */
+ relpages = RelationGetNumberOfBlocks(onerel);
+ }
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ {
+ /*
+ * For a foreign table, call the FDW's hook function to see
+ * whether it supports analysis.
+ */
+ FdwRoutine *fdwroutine;
+ bool ok = false;
- fdwroutine = GetFdwRoutineForRelation(onerel, false);
+ fdwroutine = GetFdwRoutineForRelation(onerel, false);
- if (fdwroutine->AnalyzeForeignTable != NULL)
- ok = fdwroutine->AnalyzeForeignTable(onerel,
- &acquirefunc,
- &relpages);
+ if (fdwroutine->AnalyzeForeignTable != NULL)
+ ok = fdwroutine->AnalyzeForeignTable(onerel,
+ &acquirefunc,
+ &relpages);
- if (!ok)
- {
- ereport(WARNING,
- (errmsg("skipping \"%s\" --- cannot analyze this foreign table",
- RelationGetRelationName(onerel))));
- relation_close(onerel, ShareUpdateExclusiveLock);
- return;
- }
- }
- else if (onerel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- {
- /*
- * For partitioned tables, we want to do the recursive ANALYZE below.
- */
- }
- else
- {
- /* No need for a WARNING if we already complained during VACUUM */
- if (!(params->options & VACOPT_VACUUM))
- ereport(WARNING,
- (errmsg("skipping \"%s\" --- cannot analyze non-tables or special system tables",
- RelationGetRelationName(onerel))));
- relation_close(onerel, ShareUpdateExclusiveLock);
- return;
+ if (!ok)
+ {
+ ereport(WARNING,
+ (errmsg("skipping \"%s\" --- cannot analyze this foreign table",
+ RelationGetRelationName(onerel))));
+ relation_close(onerel, ShareUpdateExclusiveLock);
+ return;
+ }
+ }
+ break;
+ case RELKIND_PARTITIONED_TABLE:
+ {
+ /*
+ * For partitioned tables, we want to do the recursive ANALYZE
+ * below.
+ */
+ }
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ {
+ /*
+ * No need for a WARNING if we already complained during
+ * VACUUM
+ */
+ if (!(params->options & VACOPT_VACUUM))
+ ereport(WARNING,
+ (errmsg("skipping \"%s\" --- cannot analyze non-tables or special system tables",
+ RelationGetRelationName(onerel))));
+ relation_close(onerel, ShareUpdateExclusiveLock);
+ return;
+ }
+ break;
}
/*
@@ -259,9 +280,25 @@ analyze_rel(Oid relid, RangeVar *relation,
* Do the normal non-recursive ANALYZE. We can skip this for partitioned
* tables, which don't contain any rows.
*/
- if (onerel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
- do_analyze_rel(onerel, params, va_cols, acquirefunc,
- relpages, false, in_outer_xact, elevel);
+ switch ((RelKind) onerel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ do_analyze_rel(onerel, params, va_cols, acquirefunc,
+ relpages, false, in_outer_xact, elevel);
+ break;
+ }
/*
* If there are child tables, do recursive ANALYZE.
@@ -1283,49 +1320,67 @@ acquire_inherited_sample_rows(Relation onerel, int elevel,
}
/* Check table type (MATVIEW can't happen, but might as well allow) */
- if (childrel->rd_rel->relkind == RELKIND_RELATION ||
- childrel->rd_rel->relkind == RELKIND_MATVIEW)
- {
- /* Regular table, so use the regular row acquisition function */
- acquirefunc = acquire_sample_rows;
- relpages = RelationGetNumberOfBlocks(childrel);
- }
- else if (childrel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
+ switch ((RelKind) childrel->rd_rel->relkind)
{
- /*
- * For a foreign table, call the FDW's hook function to see
- * whether it supports analysis.
- */
- FdwRoutine *fdwroutine;
- bool ok = false;
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ {
+ /*
+ * Regular table, so use the regular row acquisition
+ * function
+ */
+ acquirefunc = acquire_sample_rows;
+ relpages = RelationGetNumberOfBlocks(childrel);
+ }
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ {
+ /*
+ * For a foreign table, call the FDW's hook function to
+ * see whether it supports analysis.
+ */
+ FdwRoutine *fdwroutine;
+ bool ok = false;
- fdwroutine = GetFdwRoutineForRelation(childrel, false);
+ fdwroutine = GetFdwRoutineForRelation(childrel, false);
- if (fdwroutine->AnalyzeForeignTable != NULL)
- ok = fdwroutine->AnalyzeForeignTable(childrel,
- &acquirefunc,
- &relpages);
+ if (fdwroutine->AnalyzeForeignTable != NULL)
+ ok = fdwroutine->AnalyzeForeignTable(childrel,
+ &acquirefunc,
+ &relpages);
- if (!ok)
- {
- /* ignore, but release the lock on it */
- Assert(childrel != onerel);
- table_close(childrel, AccessShareLock);
- continue;
- }
- }
- else
- {
- /*
- * ignore, but release the lock on it. don't try to unlock the
- * passed-in relation
- */
- Assert(childrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
- if (childrel != onerel)
- table_close(childrel, AccessShareLock);
- else
- table_close(childrel, NoLock);
- continue;
+ if (!ok)
+ {
+ /* ignore, but release the lock on it */
+ Assert(childrel != onerel);
+ table_close(childrel, AccessShareLock);
+ continue;
+ }
+ }
+ break;
+ case RELKIND_PARTITIONED_TABLE:
+ {
+ /*
+ * ignore, but release the lock on it. don't try to
+ * unlock the passed-in relation
+ */
+ if (childrel != onerel)
+ table_close(childrel, AccessShareLock);
+ else
+ table_close(childrel, NoLock);
+ continue;
+ }
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ Assert(false);
+ break;
}
/* OK, we'll process this child */
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index 04d12a7ece..d1ac9a51e4 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -127,10 +127,26 @@ cluster(ClusterStmt *stmt, bool isTopLevel)
/*
* Reject clustering a partitioned table.
*/
- if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot cluster a partitioned table")));
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot cluster a partitioned table")));
+ break;
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
if (stmt->indexname == NULL)
{
@@ -383,12 +399,28 @@ cluster_rel(Oid tableOid, Oid indexOid, int options)
* multi-relation request -- for example, CLUSTER was run on the entire
* database.
*/
- if (OldHeap->rd_rel->relkind == RELKIND_MATVIEW &&
- !RelationIsPopulated(OldHeap))
+ switch ((RelKind) OldHeap->rd_rel->relkind)
{
- relation_close(OldHeap, AccessExclusiveLock);
- pgstat_progress_end_command();
- return;
+ case RELKIND_MATVIEW:
+ if (!RelationIsPopulated(OldHeap))
+ {
+ relation_close(OldHeap, AccessExclusiveLock);
+ pgstat_progress_end_command();
+ return;
+ }
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
/*
@@ -484,10 +516,26 @@ mark_index_clustered(Relation rel, Oid indexOid, bool is_internal)
ListCell *index;
/* Disallow applying to a partitioned table */
- if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot mark index clustered in partitioned table")));
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot mark index clustered in partitioned table")));
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
/*
* If the index is already marked clustered, no need to do anything.
@@ -1103,12 +1151,26 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class,
*/
/* set rel1's frozen Xid and minimum MultiXid */
- if (relform1->relkind != RELKIND_INDEX)
+ switch ((RelKind) relform1->relkind)
{
- Assert(!TransactionIdIsValid(frozenXid) ||
- TransactionIdIsNormal(frozenXid));
- relform1->relfrozenxid = frozenXid;
- relform1->relminmxid = cutoffMulti;
+ case RELKIND_INDEX:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ Assert(!TransactionIdIsValid(frozenXid) ||
+ TransactionIdIsNormal(frozenXid));
+ relform1->relfrozenxid = frozenXid;
+ relform1->relminmxid = cutoffMulti;
+ break;
}
/* swap size statistics too, since new rel has freshly-updated stats */
@@ -1267,27 +1329,43 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class,
* valid index. The swap can actually be safely done only if the relations
* have indexes.
*/
- if (swap_toast_by_content &&
- relform1->relkind == RELKIND_TOASTVALUE &&
- relform2->relkind == RELKIND_TOASTVALUE)
+ switch ((RelKind) relform1->relkind)
{
- Oid toastIndex1,
- toastIndex2;
-
- /* Get valid index for each relation */
- toastIndex1 = toast_get_valid_index(r1,
- AccessExclusiveLock);
- toastIndex2 = toast_get_valid_index(r2,
- AccessExclusiveLock);
-
- swap_relation_files(toastIndex1,
- toastIndex2,
- target_is_pg_class,
- swap_toast_by_content,
- is_internal,
- InvalidTransactionId,
- InvalidMultiXactId,
- mapped_tables);
+ case RELKIND_TOASTVALUE:
+ if (swap_toast_by_content &&
+ relform2->relkind == RELKIND_TOASTVALUE)
+ {
+ Oid toastIndex1,
+ toastIndex2;
+
+ /* Get valid index for each relation */
+ toastIndex1 = toast_get_valid_index(r1,
+ AccessExclusiveLock);
+ toastIndex2 = toast_get_valid_index(r2,
+ AccessExclusiveLock);
+
+ swap_relation_files(toastIndex1,
+ toastIndex2,
+ target_is_pg_class,
+ swap_toast_by_content,
+ is_internal,
+ InvalidTransactionId,
+ InvalidMultiXactId,
+ mapped_tables);
+ }
+ break;
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
/* Clean up. */
diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c
index 0ff9ca9f2c..400b14cc54 100644
--- a/src/backend/commands/comment.c
+++ b/src/backend/commands/comment.c
@@ -90,16 +90,27 @@ CommentObject(CommentStmt *stmt)
* versions, so dumping per-column comments could create reload
* failures.
*/
- if (relation->rd_rel->relkind != RELKIND_RELATION &&
- relation->rd_rel->relkind != RELKIND_VIEW &&
- relation->rd_rel->relkind != RELKIND_MATVIEW &&
- relation->rd_rel->relkind != RELKIND_COMPOSITE_TYPE &&
- relation->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
- relation->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table, view, materialized view, composite type, or foreign table",
- RelationGetRelationName(relation))));
+ switch ((RelKind) relation->rd_rel->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_VIEW:
+ case RELKIND_MATVIEW:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_INDEX:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a table, view, materialized view, composite type, or foreign table",
+ RelationGetRelationName(relation))));
+ break;
+ }
break;
default:
break;
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 3e199bdfd0..01a5261506 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -1831,42 +1831,58 @@ BeginCopyTo(ParseState *pstate,
bool pipe = (filename == NULL);
MemoryContext oldcontext;
- if (rel != NULL && rel->rd_rel->relkind != RELKIND_RELATION)
+ if (rel != NULL)
{
- if (rel->rd_rel->relkind == RELKIND_VIEW)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot copy from view \"%s\"",
- RelationGetRelationName(rel)),
- errhint("Try the COPY (SELECT ...) TO variant.")));
- else if (rel->rd_rel->relkind == RELKIND_MATVIEW)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot copy from materialized view \"%s\"",
- RelationGetRelationName(rel)),
- errhint("Try the COPY (SELECT ...) TO variant.")));
- else if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot copy from foreign table \"%s\"",
- RelationGetRelationName(rel)),
- errhint("Try the COPY (SELECT ...) TO variant.")));
- else if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot copy from sequence \"%s\"",
- RelationGetRelationName(rel))));
- else if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot copy from partitioned table \"%s\"",
- RelationGetRelationName(rel)),
- errhint("Try the COPY (SELECT ...) TO variant.")));
- else
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot copy from non-table relation \"%s\"",
- RelationGetRelationName(rel))));
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_RELATION:
+ break;
+ case RELKIND_SEQUENCE:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot copy from sequence \"%s\"",
+ RelationGetRelationName(rel))));
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot copy from foreign table \"%s\"",
+ RelationGetRelationName(rel)),
+ errhint("Try the COPY (SELECT ...) TO variant.")));
+ break;
+ case RELKIND_MATVIEW:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot copy from materialized view \"%s\"",
+ RelationGetRelationName(rel)),
+ errhint("Try the COPY (SELECT ...) TO variant.")));
+ break;
+ case RELKIND_PARTITIONED_TABLE:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot copy from partitioned table \"%s\"",
+ RelationGetRelationName(rel)),
+ errhint("Try the COPY (SELECT ...) TO variant.")));
+ break;
+ case RELKIND_VIEW:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot copy from view \"%s\"",
+ RelationGetRelationName(rel)),
+ errhint("Try the COPY (SELECT ...) TO variant.")));
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot copy from non-table relation \"%s\"",
+ RelationGetRelationName(rel))));
+ break;
+ }
}
cstate = BeginCopy(pstate, false, rel, query, queryRelId, attnamelist,
@@ -2390,8 +2406,24 @@ CopyMultiInsertInfoInit(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri,
* Buffers for partitioned tables will just be setup when we need to send
* tuples their way for the first time.
*/
- if (rri->ri_RelationDesc->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
- CopyMultiInsertInfoSetupBuffer(miinfo, rri);
+ switch ((RelKind) rri->ri_RelationDesc->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ CopyMultiInsertInfoSetupBuffer(miinfo, rri);
+ break;
+ }
}
/*
@@ -2675,33 +2707,46 @@ CopyFrom(CopyState cstate)
* an INSTEAD OF INSERT row trigger. (Currently, such triggers are only
* allowed on views, so we only hint about them in the view case.)
*/
- if (cstate->rel->rd_rel->relkind != RELKIND_RELATION &&
- cstate->rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
- cstate->rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE &&
- !(cstate->rel->trigdesc &&
+ if (!(cstate->rel->trigdesc &&
cstate->rel->trigdesc->trig_insert_instead_row))
{
- if (cstate->rel->rd_rel->relkind == RELKIND_VIEW)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot copy to view \"%s\"",
- RelationGetRelationName(cstate->rel)),
- errhint("To enable copying to a view, provide an INSTEAD OF INSERT trigger.")));
- else if (cstate->rel->rd_rel->relkind == RELKIND_MATVIEW)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot copy to materialized view \"%s\"",
- RelationGetRelationName(cstate->rel))));
- else if (cstate->rel->rd_rel->relkind == RELKIND_SEQUENCE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot copy to sequence \"%s\"",
- RelationGetRelationName(cstate->rel))));
- else
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot copy to non-table relation \"%s\"",
- RelationGetRelationName(cstate->rel))));
+ switch ((RelKind) cstate->rel->rd_rel->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_VIEW:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot copy to view \"%s\"",
+ RelationGetRelationName(cstate->rel)),
+ errhint("To enable copying to a view, provide an INSTEAD OF INSERT trigger.")));
+ break;
+ case RELKIND_MATVIEW:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot copy to materialized view \"%s\"",
+ RelationGetRelationName(cstate->rel))));
+ break;
+ case RELKIND_SEQUENCE:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot copy to sequence \"%s\"",
+ RelationGetRelationName(cstate->rel))));
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot copy to non-table relation \"%s\"",
+ RelationGetRelationName(cstate->rel))));
+ break;
+ }
}
/*
@@ -2736,11 +2781,25 @@ CopyFrom(CopyState cstate)
* tuples to a small number of partitions. It seems better just to
* raise an ERROR for partitioned tables.
*/
- if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
+ switch ((RelKind) cstate->rel->rd_rel->relkind)
{
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot perform COPY FREEZE on a partitioned table")));
+ case RELKIND_PARTITIONED_TABLE:
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot perform COPY FREEZE on a partitioned table")));
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
/*
@@ -2825,8 +2884,24 @@ CopyFrom(CopyState cstate)
* If the named relation is a partitioned table, initialize state for
* CopyFrom tuple routing.
*/
- if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- proute = ExecSetupPartitionTupleRouting(estate, NULL, cstate->rel);
+ switch ((RelKind) cstate->rel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ proute = ExecSetupPartitionTupleRouting(estate, NULL, cstate->rel);
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
if (cstate->whereClause)
cstate->qualexpr = ExecInitQual(castNode(List, cstate->whereClause),
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index 472e69fdaf..a8375d3b5d 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -3280,8 +3280,8 @@ ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt,
case OBJECT_SUBSCRIPTION:
case OBJECT_TABLESPACE:
ereport(ERROR,
- (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("cannot add an object of this type to an extension")));
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("cannot add an object of this type to an extension")));
break;
default:
/* OK */
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 2baca12c5f..194e1836cb 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -615,7 +615,7 @@ DefineIndex(Oid relationId,
namespaceId = RelationGetNamespace(rel);
/* Ensure that it makes sense to index this kind of relation */
- switch (rel->rd_rel->relkind)
+ switch ((RelKind) rel->rd_rel->relkind)
{
case RELKIND_RELATION:
case RELKIND_MATVIEW:
@@ -633,6 +633,13 @@ DefineIndex(Oid relationId,
errmsg("cannot create index on foreign table \"%s\"",
RelationGetRelationName(rel))));
break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
default:
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
@@ -1190,18 +1197,33 @@ DefineIndex(Oid relationId,
* those if a regular index, or fail if trying to create a
* constraint index.
*/
- if (childrel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
+ switch ((RelKind) childrel->rd_rel->relkind)
{
- if (stmt->unique || stmt->primary)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot create unique index on partitioned table \"%s\"",
- RelationGetRelationName(rel)),
- errdetail("Table \"%s\" contains partitions that are foreign tables.",
- RelationGetRelationName(rel))));
-
- table_close(childrel, lockmode);
- continue;
+ case RELKIND_FOREIGN_TABLE:
+ {
+ if (stmt->unique || stmt->primary)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot create unique index on partitioned table \"%s\"",
+ RelationGetRelationName(rel)),
+ errdetail("Table \"%s\" contains partitions that are foreign tables.",
+ RelationGetRelationName(rel))));
+
+ table_close(childrel, lockmode);
+ continue;
+ }
+ break;
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
childidxs = RelationGetIndexList(childrel);
@@ -2451,10 +2473,23 @@ ReindexIndex(RangeVar *indexRelation, int options, bool concurrent)
*/
irel = index_open(indOid, NoLock);
- if (irel->rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
+ switch ((RelKind) irel->rd_rel->relkind)
{
- ReindexPartitionedIndex(irel);
- return;
+ case RELKIND_PARTITIONED_INDEX:
+ ReindexPartitionedIndex(irel);
+ return;
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
persistence = irel->rd_rel->relpersistence;
@@ -2510,11 +2545,25 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation,
relkind = get_rel_relkind(relId);
if (!relkind)
return;
- if (relkind != RELKIND_INDEX &&
- relkind != RELKIND_PARTITIONED_INDEX)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not an index", relation->relname)));
+ switch ((RelKind) relkind)
+ {
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ break;
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not an index", relation->relname)));
+ }
/* Check permissions */
if (!pg_class_ownercheck(relId, GetUserId()))
@@ -2694,9 +2743,23 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind,
* partitioned tables, and expand that afterwards into relids,
* ignoring any duplicates.
*/
- if (classtuple->relkind != RELKIND_RELATION &&
- classtuple->relkind != RELKIND_MATVIEW)
- continue;
+ switch ((RelKind) classtuple->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ continue;
+ }
/* Skip temp tables of other backends; we can't reindex them at all */
if (classtuple->relpersistence == RELPERSISTENCE_TEMP &&
@@ -2867,7 +2930,7 @@ ReindexRelationConcurrently(Oid relationOid, int options)
* Extract the list of indexes that are going to be rebuilt based on the
* relation Oid given by caller.
*/
- switch (relkind)
+ switch ((RelKind) relkind)
{
case RELKIND_RELATION:
case RELKIND_MATVIEW:
@@ -3017,6 +3080,12 @@ ReindexRelationConcurrently(Oid relationOid, int options)
errmsg("REINDEX of partitioned tables is not yet implemented, skipping \"%s\"",
get_rel_name(relationOid))));
return false;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
default:
/* Return error if type of relation is not supported */
ereport(ERROR,
@@ -3443,30 +3512,43 @@ ReindexRelationConcurrently(Oid relationOid, int options)
/* Log what we did */
if (options & REINDEXOPT_VERBOSE)
{
- if (relkind == RELKIND_INDEX)
- ereport(INFO,
- (errmsg("index \"%s.%s\" was reindexed",
- relationNamespace, relationName),
- errdetail("%s.",
- pg_rusage_show(&ru0))));
- else
+ switch ((RelKind) relkind)
{
- foreach(lc, newIndexIds)
- {
- Oid indOid = lfirst_oid(lc);
-
+ case RELKIND_INDEX:
ereport(INFO,
(errmsg("index \"%s.%s\" was reindexed",
- get_namespace_name(get_rel_namespace(indOid)),
- get_rel_name(indOid))));
- /* Don't show rusage here, since it's not per index. */
- }
+ relationNamespace, relationName),
+ errdetail("%s.",
+ pg_rusage_show(&ru0))));
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ foreach(lc, newIndexIds)
+ {
+ Oid indOid = lfirst_oid(lc);
+
+ ereport(INFO,
+ (errmsg("index \"%s.%s\" was reindexed",
+ get_namespace_name(get_rel_namespace(indOid)),
+ get_rel_name(indOid))));
+ /* Don't show rusage here, since it's not per index. */
+ }
- ereport(INFO,
- (errmsg("table \"%s.%s\" was reindexed",
- relationNamespace, relationName),
- errdetail("%s.",
- pg_rusage_show(&ru0))));
+ ereport(INFO,
+ (errmsg("table \"%s.%s\" was reindexed",
+ relationNamespace, relationName),
+ errdetail("%s.",
+ pg_rusage_show(&ru0))));
+ break;
}
}
@@ -3508,8 +3590,24 @@ IndexSetParentIndex(Relation partitionIdx, Oid parentOid)
bool fix_dependencies;
/* Make sure this is an index */
- Assert(partitionIdx->rd_rel->relkind == RELKIND_INDEX ||
- partitionIdx->rd_rel->relkind == RELKIND_PARTITIONED_INDEX);
+ switch ((RelKind) partitionIdx->rd_rel->relkind)
+ {
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ break; /* ok */
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ Assert(false);
+ break;
+ }
/*
* Scan pg_inherits for rows linking our index to some parent.
diff --git a/src/backend/commands/lockcmds.c b/src/backend/commands/lockcmds.c
index d8cafc42bb..deb885adf8 100644
--- a/src/backend/commands/lockcmds.c
+++ b/src/backend/commands/lockcmds.c
@@ -56,10 +56,26 @@ LockTableCommand(LockStmt *lockstmt)
RangeVarCallbackForLockTable,
(void *) &lockstmt->mode);
- if (get_rel_relkind(reloid) == RELKIND_VIEW)
- LockViewRecurse(reloid, lockstmt->mode, lockstmt->nowait, NIL);
- else if (recurse)
- LockTableRecurse(reloid, lockstmt->mode, lockstmt->nowait);
+ switch ((RelKind) get_rel_relkind(reloid))
+ {
+ case RELKIND_VIEW:
+ LockViewRecurse(reloid, lockstmt->mode, lockstmt->nowait, NIL);
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ if (recurse)
+ LockTableRecurse(reloid, lockstmt->mode, lockstmt->nowait);
+ break;
+ }
}
}
@@ -84,12 +100,27 @@ RangeVarCallbackForLockTable(const RangeVar *rv, Oid relid, Oid oldrelid,
* check */
/* Currently, we only allow plain tables or views to be locked */
- if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE &&
- relkind != RELKIND_VIEW)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table or view",
- rv->relname)));
+ switch ((RelKind) relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_VIEW:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a table or view",
+ rv->relname)));
+ break;
+ }
/*
* Make note if a temporary relation has been accessed in this
@@ -201,10 +232,27 @@ LockViewRecurse_walker(Node *node, LockViewRecurse_context *context)
strcmp(rte->eref->aliasname, "new") == 0))
continue;
- /* Currently, we only allow plain tables or views to be locked. */
- if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE &&
- relkind != RELKIND_VIEW)
- continue;
+ switch ((RelKind) relkind)
+ {
+ /*
+ * Currently, we only allow plain tables or views to be
+ * locked.
+ */
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_VIEW:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ continue;
+ }
/* Check infinite recursion in the view definition. */
if (list_member_oid(context->ancestor_views, relid))
@@ -227,10 +275,26 @@ LockViewRecurse_walker(Node *node, LockViewRecurse_context *context)
errmsg("could not obtain lock on relation \"%s\"",
relname)));
- if (relkind == RELKIND_VIEW)
- LockViewRecurse(relid, context->lockmode, context->nowait, context->ancestor_views);
- else if (rte->inh)
- LockTableRecurse(relid, context->lockmode, context->nowait);
+ switch ((RelKind) relkind)
+ {
+ case RELKIND_VIEW:
+ LockViewRecurse(relid, context->lockmode, context->nowait, context->ancestor_views);
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ if (rte->inh)
+ LockTableRecurse(relid, context->lockmode, context->nowait);
+ break;
+ }
}
return query_tree_walker(query,
diff --git a/src/backend/commands/policy.c b/src/backend/commands/policy.c
index 4b4e469493..f96459bc93 100644
--- a/src/backend/commands/policy.c
+++ b/src/backend/commands/policy.c
@@ -89,10 +89,26 @@ RangeVarCallbackForPolicy(const RangeVar *rv, Oid relid, Oid oldrelid,
rv->relname)));
/* Relation type MUST be a table. */
- if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table", rv->relname)));
+ switch ((RelKind) relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a table", rv->relname)));
+ break;
+ }
ReleaseSysCache(tuple);
}
@@ -388,12 +404,27 @@ RemovePolicyById(Oid policy_id)
relid = ((Form_pg_policy) GETSTRUCT(tuple))->polrelid;
rel = table_open(relid, AccessExclusiveLock);
- if (rel->rd_rel->relkind != RELKIND_RELATION &&
- rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table",
- RelationGetRelationName(rel))));
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a table",
+ RelationGetRelationName(rel))));
+ break;
+ }
if (!allowSystemTableMods && IsSystemRelation(rel))
ereport(ERROR,
@@ -478,12 +509,27 @@ RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id)
rel = relation_open(relid, AccessExclusiveLock);
- if (rel->rd_rel->relkind != RELKIND_RELATION &&
- rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table",
- RelationGetRelationName(rel))));
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a table",
+ RelationGetRelationName(rel))));
+ break;
+ }
if (!allowSystemTableMods && IsSystemRelation(rel))
ereport(ERROR,
diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c
index eabbc7473b..b340fd9b9c 100644
--- a/src/backend/commands/publicationcmds.c
+++ b/src/backend/commands/publicationcmds.c
@@ -548,33 +548,49 @@ OpenTableList(List *tables)
* children other than its partitions, which need not be explicitly
* added to the publication.
*/
- if (recurse && rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
+ switch ((RelKind) rel->rd_rel->relkind)
{
- List *children;
- ListCell *child;
-
- children = find_all_inheritors(myrelid, ShareUpdateExclusiveLock,
- NULL);
-
- foreach(child, children)
- {
- Oid childrelid = lfirst_oid(child);
-
- /* Allow query cancel in case this takes a long time */
- CHECK_FOR_INTERRUPTS();
-
- /*
- * Skip duplicates if user specified both parent and child
- * tables.
- */
- if (list_member_oid(relids, childrelid))
- continue;
-
- /* find_all_inheritors already got lock */
- rel = table_open(childrelid, NoLock);
- rels = lappend(rels, rel);
- relids = lappend_oid(relids, childrelid);
- }
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ if (recurse)
+ {
+ List *children;
+ ListCell *child;
+
+ children = find_all_inheritors(myrelid, ShareUpdateExclusiveLock,
+ NULL);
+
+ foreach(child, children)
+ {
+ Oid childrelid = lfirst_oid(child);
+
+ /* Allow query cancel in case this takes a long time */
+ CHECK_FOR_INTERRUPTS();
+
+ /*
+ * Skip duplicates if user specified both parent and
+ * child tables.
+ */
+ if (list_member_oid(relids, childrelid))
+ continue;
+
+ /* find_all_inheritors already got lock */
+ rel = table_open(childrelid, NoLock);
+ rels = lappend(rels, rel);
+ relids = lappend_oid(relids, childrelid);
+ }
+ }
}
}
diff --git a/src/backend/commands/seclabel.c b/src/backend/commands/seclabel.c
index ee036e9087..77bd351b96 100644
--- a/src/backend/commands/seclabel.c
+++ b/src/backend/commands/seclabel.c
@@ -180,16 +180,27 @@ ExecSecLabelStmt(SecLabelStmt *stmt)
* materialized views, composite types, and foreign tables (which
* are the only relkinds for which pg_dump will dump labels).
*/
- if (relation->rd_rel->relkind != RELKIND_RELATION &&
- relation->rd_rel->relkind != RELKIND_VIEW &&
- relation->rd_rel->relkind != RELKIND_MATVIEW &&
- relation->rd_rel->relkind != RELKIND_COMPOSITE_TYPE &&
- relation->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
- relation->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table, view, materialized view, composite type, or foreign table",
- RelationGetRelationName(relation))));
+ switch ((RelKind) relation->rd_rel->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_VIEW:
+ case RELKIND_MATVIEW:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_INDEX:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a table, view, materialized view, composite type, or foreign table",
+ RelationGetRelationName(relation))));
+ break;
+ }
break;
default:
break;
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index 6aab73bfd4..6652bcff7f 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -1675,14 +1675,27 @@ process_owned_by(Relation seqrel, List *owned_by, bool for_identity)
tablerel = relation_openrv(rel, AccessShareLock);
/* Must be a regular or foreign table */
- if (!(tablerel->rd_rel->relkind == RELKIND_RELATION ||
- tablerel->rd_rel->relkind == RELKIND_FOREIGN_TABLE ||
- tablerel->rd_rel->relkind == RELKIND_VIEW ||
- tablerel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE))
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("referenced relation \"%s\" is not a table or foreign table",
- RelationGetRelationName(tablerel))));
+ switch ((RelKind) tablerel->rd_rel->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("referenced relation \"%s\" is not a table or foreign table",
+ RelationGetRelationName(tablerel))));
+ break;
+ }
/* We insist on same owner and schema */
if (seqrel->rd_rel->relowner != tablerel->rd_rel->relowner)
diff --git a/src/backend/commands/statscmds.c b/src/backend/commands/statscmds.c
index 974828545c..d0976ae826 100644
--- a/src/backend/commands/statscmds.c
+++ b/src/backend/commands/statscmds.c
@@ -122,14 +122,27 @@ CreateStatistics(CreateStatsStmt *stmt)
rel = relation_openrv((RangeVar *) rln, ShareUpdateExclusiveLock);
/* Restrict to allowed relation types */
- if (rel->rd_rel->relkind != RELKIND_RELATION &&
- rel->rd_rel->relkind != RELKIND_MATVIEW &&
- rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
- rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("relation \"%s\" is not a table, foreign table, or materialized view",
- RelationGetRelationName(rel))));
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("relation \"%s\" is not a table, foreign table, or materialized view",
+ RelationGetRelationName(rel))));
+ break;
+ }
/* You must own the relation to create stats on it */
if (!pg_class_ownercheck(RelationGetRelid(rel), stxowner))
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 1105c5b8ec..0dd3b07c77 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -619,8 +619,24 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
if (stmt->partspec != NULL)
{
- if (relkind != RELKIND_RELATION)
- elog(ERROR, "unexpected relkind: %d", (int) relkind);
+ switch ((RelKind) relkind)
+ {
+ case RELKIND_RELATION:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ elog(ERROR, "unexpected relkind: %d", (int) relkind);
+ break;
+ }
relkind = RELKIND_PARTITIONED_TABLE;
partitioned = true;
@@ -746,7 +762,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps,
true, false);
- switch (relkind)
+ switch ((RelKind) relkind)
{
case RELKIND_VIEW:
(void) view_reloptions(reloptions, true);
@@ -754,6 +770,15 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
case RELKIND_PARTITIONED_TABLE:
(void) partitioned_table_reloptions(reloptions, true);
break;
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
default:
(void) heap_reloptions(relkind, reloptions, true);
}
@@ -866,10 +891,25 @@ 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)
- accessMethod = default_table_access_method;
+ else
+ switch ((RelKind) relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_MATVIEW:
+ accessMethod = default_table_access_method;
+ break;
+ case RELKIND_VIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_INDEX:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
/* look up the access method, verify it is for a table */
if (accessMethod != NULL)
@@ -956,11 +996,26 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
* We are going to try to validate the partition bound specification
* against the partition key of parentRel, so it better have one.
*/
- if (parent->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("\"%s\" is not partitioned",
- RelationGetRelationName(parent))));
+ switch ((RelKind) parent->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_INDEX:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("\"%s\" is not partitioned",
+ RelationGetRelationName(parent))));
+ }
/*
* The partition constraint of the default partition depends on the
@@ -1104,20 +1159,34 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
IndexStmt *idxstmt;
Oid constraintOid;
- if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
+ switch ((RelKind) rel->rd_rel->relkind)
{
- if (idxRel->rd_index->indisunique)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot create foreign partition of partitioned table \"%s\"",
- RelationGetRelationName(parent)),
- errdetail("Table \"%s\" contains indexes that are unique.",
- RelationGetRelationName(parent))));
- else
- {
- index_close(idxRel, AccessShareLock);
- continue;
- }
+ case RELKIND_FOREIGN_TABLE:
+ if (idxRel->rd_index->indisunique)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot create foreign partition of partitioned table \"%s\"",
+ RelationGetRelationName(parent)),
+ errdetail("Table \"%s\" contains indexes that are unique.",
+ RelationGetRelationName(parent))));
+ else
+ {
+ index_close(idxRel, AccessShareLock);
+ continue;
+ }
+ break;
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_SEQUENCE:
+ case RELKIND_INDEX:
+ case RELKIND_NULL:
+ default:
+ break;
}
attmap = build_attrmap_by_name(RelationGetDescr(rel),
@@ -1448,12 +1517,27 @@ RangeVarCallbackForDropRelation(const RangeVar *rel, Oid relOid, Oid oldRelOid,
* the relation is RELKIND_PARTITIONED_TABLE. An equivalent problem
* exists with indexes.
*/
- if (classform->relkind == RELKIND_PARTITIONED_TABLE)
- expected_relkind = RELKIND_RELATION;
- else if (classform->relkind == RELKIND_PARTITIONED_INDEX)
- expected_relkind = RELKIND_INDEX;
- else
- expected_relkind = classform->relkind;
+ switch ((RelKind) classform->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ expected_relkind = RELKIND_RELATION;
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ expected_relkind = RELKIND_INDEX;
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_SEQUENCE:
+ case RELKIND_INDEX:
+ case RELKIND_NULL:
+ default:
+ expected_relkind = classform->relkind;
+ break;
+ }
if (relkind != expected_relkind)
DropErrorMsgWrongType(rel->relname, classform->relkind, relkind);
@@ -1470,26 +1554,43 @@ RangeVarCallbackForDropRelation(const RangeVar *rel, Oid relOid, Oid oldRelOid,
* only concerns indexes of toast relations that became invalid during a
* REINDEX CONCURRENTLY process.
*/
- if (IsSystemClass(relOid, classform) && relkind == RELKIND_INDEX)
+ switch ((RelKind) relkind)
{
- HeapTuple locTuple;
- Form_pg_index indexform;
- bool indisvalid;
+ case RELKIND_INDEX:
+ if (IsSystemClass(relOid, classform))
+ {
+ HeapTuple locTuple;
+ Form_pg_index indexform;
+ bool indisvalid;
- locTuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(relOid));
- if (!HeapTupleIsValid(locTuple))
- {
- ReleaseSysCache(tuple);
- return;
- }
+ locTuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(relOid));
+ if (!HeapTupleIsValid(locTuple))
+ {
+ ReleaseSysCache(tuple);
+ return;
+ }
- indexform = (Form_pg_index) GETSTRUCT(locTuple);
- indisvalid = indexform->indisvalid;
- ReleaseSysCache(locTuple);
+ indexform = (Form_pg_index) GETSTRUCT(locTuple);
+ indisvalid = indexform->indisvalid;
+ ReleaseSysCache(locTuple);
- /* Mark object as being an invalid index of system catalogs */
- if (!indisvalid)
- invalid_system_index = true;
+ /* Mark object as being an invalid index of system catalogs */
+ if (!indisvalid)
+ invalid_system_index = true;
+ }
+ break;
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_SEQUENCE:
+ case RELKIND_NULL:
+ default:
+ break;
}
/* In the case of an invalid index, it is fine to bypass this check */
@@ -1508,12 +1609,28 @@ RangeVarCallbackForDropRelation(const RangeVar *rel, Oid relOid, Oid oldRelOid,
* we do it the other way around. No error if we don't find a pg_index
* entry, though --- the relation may have been dropped.
*/
- if ((relkind == RELKIND_INDEX || relkind == RELKIND_PARTITIONED_INDEX) &&
- relOid != oldRelOid)
+ switch ((RelKind) relkind)
{
- state->heapOid = IndexGetRelation(relOid, true);
- if (OidIsValid(state->heapOid))
- LockRelationOid(state->heapOid, heap_lockmode);
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ if (relOid != oldRelOid)
+ {
+ state->heapOid = IndexGetRelation(relOid, true);
+ if (OidIsValid(state->heapOid))
+ LockRelationOid(state->heapOid, heap_lockmode);
+ }
+ break;
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_SEQUENCE:
+ case RELKIND_NULL:
+ default:
+ break;
}
/*
@@ -1635,11 +1752,28 @@ ExecuteTruncate(TruncateStmt *stmt)
relids_logged = lappend_oid(relids_logged, childrelid);
}
}
- else if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot truncate only a partitioned table"),
- errhint("Do not specify the ONLY keyword, or use TRUNCATE ONLY on the partitions directly.")));
+ else
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot truncate only a partitioned table"),
+ errhint("Do not specify the ONLY keyword, or use TRUNCATE ONLY on the partitions directly.")));
+ break;
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_SEQUENCE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
}
ExecuteTruncateGuts(rels, relids, relids_logged,
@@ -1815,9 +1949,24 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged,
{
Relation rel = (Relation) lfirst(cell);
- /* Skip partitioned tables as there is nothing to do */
- if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- continue;
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ /* Skip partitioned tables as there is nothing to do */
+ case RELKIND_PARTITIONED_TABLE:
+ continue;
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_SEQUENCE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
/*
* Normally, we need a transaction-safe truncation here. However, if
@@ -1969,11 +2118,25 @@ truncate_check_rel(Oid relid, Form_pg_class reltuple)
* the latter are only being included here for the following checks; no
* physical truncation will occur in their case.)
*/
- if (reltuple->relkind != RELKIND_RELATION &&
- reltuple->relkind != RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table", relname)));
+ switch ((RelKind) reltuple->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_SEQUENCE:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a table", relname)));
+ }
if (!allowSystemTableMods && IsSystemClass(relid, reltuple))
ereport(ERROR,
@@ -2235,26 +2398,39 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
* We do not allow partitioned tables and partitions to participate in
* regular inheritance.
*/
- if (relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE &&
- !is_partition)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot inherit from partitioned table \"%s\"",
- RelationGetRelationName(relation))));
+ switch ((RelKind) relation->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ if (!is_partition)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot inherit from partitioned table \"%s\"",
+ RelationGetRelationName(relation))));
+ break;
+ case RELKIND_RELATION:
+ case RELKIND_FOREIGN_TABLE:
+ break;
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_SEQUENCE:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("inherited relation \"%s\" is not a table or foreign table",
+ RelationGetRelationName(relation))));
+ }
+
if (relation->rd_rel->relispartition && !is_partition)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("cannot inherit from partition \"%s\"",
RelationGetRelationName(relation))));
- if (relation->rd_rel->relkind != RELKIND_RELATION &&
- relation->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
- relation->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("inherited relation \"%s\" is not a table or foreign table",
- RelationGetRelationName(relation))));
-
/*
* If the parent is permanent, so must be all of its partitions. Note
* that inheritance allows that case.
@@ -2996,18 +3172,26 @@ renameatt_check(Oid myrelid, Form_pg_class classform, bool recursing)
* change names that are hardcoded into the system, hence the following
* restriction.
*/
- if (relkind != RELKIND_RELATION &&
- relkind != RELKIND_VIEW &&
- relkind != RELKIND_MATVIEW &&
- relkind != RELKIND_COMPOSITE_TYPE &&
- relkind != RELKIND_INDEX &&
- relkind != RELKIND_PARTITIONED_INDEX &&
- relkind != RELKIND_FOREIGN_TABLE &&
- relkind != RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table, view, materialized view, composite type, index, or foreign table",
- NameStr(classform->relname))));
+ switch ((RelKind) relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_VIEW:
+ case RELKIND_MATVIEW:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_TOASTVALUE:
+ case RELKIND_SEQUENCE:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a table, view, materialized view, composite type, index, or foreign table",
+ NameStr(classform->relname))));
+ }
/*
* permissions checking. only the owner of a class can change its schema.
@@ -3105,17 +3289,33 @@ renameatt_internal(Oid myrelid,
}
/* rename attributes in typed tables of composite type */
- if (targetrelation->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
+ switch ((RelKind) targetrelation->rd_rel->relkind)
{
- List *child_oids;
- ListCell *lo;
+ case RELKIND_COMPOSITE_TYPE:
+ {
+ List *child_oids;
+ ListCell *lo;
- child_oids = find_typed_table_dependencies(targetrelation->rd_rel->reltype,
- RelationGetRelationName(targetrelation),
- behavior);
+ child_oids = find_typed_table_dependencies(targetrelation->rd_rel->reltype,
+ RelationGetRelationName(targetrelation),
+ behavior);
- foreach(lo, child_oids)
- renameatt_internal(lfirst_oid(lo), oldattname, newattname, true, true, 0, behavior);
+ foreach(lo, child_oids)
+ renameatt_internal(lfirst_oid(lo), oldattname, newattname, true, true, 0, behavior);
+ }
+ break;
+ case RELKIND_RELATION:
+ case RELKIND_VIEW:
+ case RELKIND_MATVIEW:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_SEQUENCE:
+ case RELKIND_NULL:
+ default:
+ break;
}
attrelation = table_open(AttributeRelationId, RowExclusiveLock);
@@ -3489,13 +3689,28 @@ RenameRelationInternal(Oid myrelid, const char *newrelname, bool is_internal, bo
/*
* Also rename the associated constraint, if any.
*/
- if (targetrelation->rd_rel->relkind == RELKIND_INDEX ||
- targetrelation->rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
+ switch ((RelKind) targetrelation->rd_rel->relkind)
{
- Oid constraintId = get_index_constraint(myrelid);
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ {
+ Oid constraintId = get_index_constraint(myrelid);
- if (OidIsValid(constraintId))
- RenameConstraintById(constraintId, newrelname);
+ if (OidIsValid(constraintId))
+ RenameConstraintById(constraintId, newrelname);
+ }
+ break;
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_RELATION:
+ case RELKIND_VIEW:
+ case RELKIND_MATVIEW:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_SEQUENCE:
+ case RELKIND_NULL:
+ default:
+ break;
}
/*
@@ -3542,14 +3757,29 @@ CheckTableNotInUse(Relation rel, const char *stmt)
errmsg("cannot %s \"%s\" because it is being used by active queries in this session",
stmt, RelationGetRelationName(rel))));
- if (rel->rd_rel->relkind != RELKIND_INDEX &&
- rel->rd_rel->relkind != RELKIND_PARTITIONED_INDEX &&
- AfterTriggerPendingOnRel(RelationGetRelid(rel)))
- ereport(ERROR,
- (errcode(ERRCODE_OBJECT_IN_USE),
- /* translator: first %s is a SQL command, eg ALTER TABLE */
- errmsg("cannot %s \"%s\" because it has pending trigger events",
- stmt, RelationGetRelationName(rel))));
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ break;
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_RELATION:
+ case RELKIND_VIEW:
+ case RELKIND_MATVIEW:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_SEQUENCE:
+ case RELKIND_NULL:
+ default:
+ if (AfterTriggerPendingOnRel(RelationGetRelid(rel)))
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_IN_USE),
+ /* translator: first %s is a SQL command, eg ALTER TABLE */
+ errmsg("cannot %s \"%s\" because it has pending trigger events",
+ stmt, RelationGetRelationName(rel))));
+ break;
+ }
}
/*
@@ -4364,11 +4594,27 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode,
* not modify anything about it that will change its toasting
* requirement, so no need to check.
*/
- if (((tab->relkind == RELKIND_RELATION ||
- tab->relkind == RELKIND_PARTITIONED_TABLE) &&
- tab->partition_constraint == NULL) ||
- tab->relkind == RELKIND_MATVIEW)
- AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode);
+ switch ((RelKind) tab->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ if (tab->partition_constraint != NULL)
+ break;
+ /* fallthrough */
+ case RELKIND_MATVIEW:
+ AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode);
+ break;
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_VIEW:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_SEQUENCE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
}
}
@@ -4546,15 +4792,29 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
break;
case AT_SetTableSpace: /* SET TABLESPACE */
- /*
- * Only do this for partitioned tables and indexes, for which this
- * is just a catalog change. Other relation types which have
- * storage are handled by Phase 3.
- */
- if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ||
- rel->rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
- ATExecSetTableSpaceNoStorage(rel, tab->newTableSpace);
-
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ /*
+ * Only do this for partitioned tables and indexes, for
+ * which this is just a catalog change. Other relation
+ * types which have storage are handled by Phase 3.
+ */
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_PARTITIONED_INDEX:
+ ATExecSetTableSpaceNoStorage(rel, tab->newTableSpace);
+ break;
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_VIEW:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_SEQUENCE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
break;
case AT_SetRelOptions: /* SET (...) */
case AT_ResetRelOptions: /* RESET (...) */
@@ -4645,11 +4905,26 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
cmd = ATParseTransformCmd(wqueue, tab, rel, cmd, false, lockmode,
cur_pass, context);
Assert(cmd != NULL);
- if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- ATExecAttachPartition(wqueue, rel, (PartitionCmd *) cmd->def);
- else
- ATExecAttachPartitionIdx(wqueue, rel,
- ((PartitionCmd *) cmd->def)->name);
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ ATExecAttachPartition(wqueue, rel, (PartitionCmd *) cmd->def);
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_VIEW:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_SEQUENCE:
+ case RELKIND_NULL:
+ default:
+ ATExecAttachPartitionIdx(wqueue, rel,
+ ((PartitionCmd *) cmd->def)->name);
+ break;
+ }
break;
case AT_DetachPartition:
cmd = ATParseTransformCmd(wqueue, tab, rel, cmd, false, lockmode,
@@ -5477,7 +5752,7 @@ ATSimplePermissions(Relation rel, int allowed_targets)
{
int actual_target;
- switch (rel->rd_rel->relkind)
+ switch ((RelKind) rel->rd_rel->relkind)
{
case RELKIND_RELATION:
case RELKIND_PARTITIONED_TABLE:
@@ -5501,6 +5776,9 @@ ATSimplePermissions(Relation rel, int allowed_targets)
case RELKIND_FOREIGN_TABLE:
actual_target = ATT_FOREIGN_TABLE;
break;
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
default:
actual_target = 0;
break;
@@ -5600,35 +5878,49 @@ ATSimpleRecursion(List **wqueue, Relation rel,
* and partitioned tables have children, so no need to search for other
* relkinds.
*/
- if (recurse &&
- (rel->rd_rel->relkind == RELKIND_RELATION ||
- rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE ||
- rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE))
+ switch ((RelKind) rel->rd_rel->relkind)
{
- Oid relid = RelationGetRelid(rel);
- ListCell *child;
- List *children;
-
- children = find_all_inheritors(relid, lockmode, NULL);
+ case RELKIND_RELATION:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ if (recurse)
+ {
+ Oid relid = RelationGetRelid(rel);
+ ListCell *child;
+ List *children;
- /*
- * find_all_inheritors does the recursive search of the inheritance
- * hierarchy, so all we have to do is process all of the relids in the
- * list that it returns.
- */
- foreach(child, children)
- {
- Oid childrelid = lfirst_oid(child);
- Relation childrel;
+ children = find_all_inheritors(relid, lockmode, NULL);
- if (childrelid == relid)
- continue;
- /* find_all_inheritors already got lock */
- childrel = relation_open(childrelid, NoLock);
- CheckTableNotInUse(childrel, "ALTER TABLE");
- ATPrepCmd(wqueue, childrel, cmd, false, true, lockmode, context);
- relation_close(childrel, NoLock);
- }
+ /*
+ * find_all_inheritors does the recursive search of the
+ * inheritance hierarchy, so all we have to do is process all
+ * of the relids in the list that it returns.
+ */
+ foreach(child, children)
+ {
+ Oid childrelid = lfirst_oid(child);
+ Relation childrel;
+
+ if (childrelid == relid)
+ continue;
+ /* find_all_inheritors already got lock */
+ childrel = relation_open(childrelid, NoLock);
+ CheckTableNotInUse(childrel, "ALTER TABLE");
+ ATPrepCmd(wqueue, childrel, cmd, false, true, lockmode, context);
+ relation_close(childrel, NoLock);
+ }
+ }
+ break;
+ case RELKIND_VIEW:
+ case RELKIND_MATVIEW:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
}
}
@@ -5773,47 +6065,62 @@ find_composite_type_dependencies(Oid typeOid, Relation origRelation,
rel = relation_open(pg_depend->objid, AccessShareLock);
att = TupleDescAttr(rel->rd_att, pg_depend->objsubid - 1);
- if (rel->rd_rel->relkind == RELKIND_RELATION ||
- rel->rd_rel->relkind == RELKIND_MATVIEW ||
- rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- {
- if (origTypeName)
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot alter type \"%s\" because column \"%s.%s\" uses it",
- origTypeName,
- RelationGetRelationName(rel),
- NameStr(att->attname))));
- else if (origRelation->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot alter type \"%s\" because column \"%s.%s\" uses it",
- RelationGetRelationName(origRelation),
- RelationGetRelationName(rel),
- NameStr(att->attname))));
- else if (origRelation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot alter foreign table \"%s\" because column \"%s.%s\" uses its row type",
- RelationGetRelationName(origRelation),
- RelationGetRelationName(rel),
- NameStr(att->attname))));
- else
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot alter table \"%s\" because column \"%s.%s\" uses its row type",
- RelationGetRelationName(origRelation),
- RelationGetRelationName(rel),
- NameStr(att->attname))));
- }
- else if (OidIsValid(rel->rd_rel->reltype))
+ switch ((RelKind) rel->rd_rel->relkind)
{
- /*
- * A view or composite type itself isn't a problem, but we must
- * recursively check for indirect dependencies via its rowtype.
- */
- find_composite_type_dependencies(rel->rd_rel->reltype,
- origRelation, origTypeName);
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ {
+ if (origTypeName)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot alter type \"%s\" because column \"%s.%s\" uses it",
+ origTypeName,
+ RelationGetRelationName(rel),
+ NameStr(att->attname))));
+ else if (origRelation->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot alter type \"%s\" because column \"%s.%s\" uses it",
+ RelationGetRelationName(origRelation),
+ RelationGetRelationName(rel),
+ NameStr(att->attname))));
+ else if (origRelation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot alter foreign table \"%s\" because column \"%s.%s\" uses its row type",
+ RelationGetRelationName(origRelation),
+ RelationGetRelationName(rel),
+ NameStr(att->attname))));
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot alter table \"%s\" because column \"%s.%s\" uses its row type",
+ RelationGetRelationName(origRelation),
+ RelationGetRelationName(rel),
+ NameStr(att->attname))));
+ }
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ if (OidIsValid(rel->rd_rel->reltype))
+ {
+ /*
+ * A view or composite type itself isn't a problem, but we
+ * must recursively check for indirect dependencies via
+ * its rowtype.
+ */
+ find_composite_type_dependencies(rel->rd_rel->reltype,
+ origRelation, origTypeName);
+ }
+ break;
}
relation_close(rel, AccessShareLock);
@@ -5934,8 +6241,24 @@ ATPrepAddColumn(List **wqueue, Relation rel, bool recurse, bool recursing,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("cannot add column to typed table")));
- if (rel->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
- ATTypedTableRecursion(wqueue, rel, cmd, lockmode, context);
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_COMPOSITE_TYPE:
+ ATTypedTableRecursion(wqueue, rel, cmd, lockmode, context);
+ break;
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
if (recurse && !is_view)
cmd->subtype = AT_AddColumnRecurse;
@@ -6455,16 +6778,32 @@ ATPrepDropNotNull(Relation rel, bool recurse, bool recursing)
* If the parent is a partitioned table, like check constraints, we do not
* support removing the NOT NULL while partitions exist.
*/
- if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
+ switch ((RelKind) rel->rd_rel->relkind)
{
- PartitionDesc partdesc = RelationGetPartitionDesc(rel);
+ case RELKIND_PARTITIONED_TABLE:
+ {
+ PartitionDesc partdesc = RelationGetPartitionDesc(rel);
- Assert(partdesc != NULL);
- if (partdesc->nparts > 0 && !recurse && !recursing)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
- errmsg("cannot remove constraint from only the partitioned table when partitions exist"),
- errhint("Do not specify the ONLY keyword.")));
+ Assert(partdesc != NULL);
+ if (partdesc->nparts > 0 && !recurse && !recursing)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
+ errmsg("cannot remove constraint from only the partitioned table when partitions exist"),
+ errhint("Do not specify the ONLY keyword.")));
+ }
+ break;
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
}
}
@@ -6614,17 +6953,33 @@ ATPrepSetNotNull(List **wqueue, Relation rel,
* apply ALTER TABLE ... CHECK NOT NULL to every child. Otherwise, use
* normal recursion logic.
*/
- if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE &&
- !recurse)
+ switch ((RelKind) rel->rd_rel->relkind)
{
- AlterTableCmd *newcmd = makeNode(AlterTableCmd);
+ case RELKIND_PARTITIONED_TABLE:
+ if (!recurse)
+ {
+ AlterTableCmd *newcmd = makeNode(AlterTableCmd);
- newcmd->subtype = AT_CheckNotNull;
- newcmd->name = pstrdup(cmd->name);
- ATSimpleRecursion(wqueue, rel, newcmd, true, lockmode, context);
+ newcmd->subtype = AT_CheckNotNull;
+ newcmd->name = pstrdup(cmd->name);
+ ATSimpleRecursion(wqueue, rel, newcmd, true, lockmode, context);
+ break;
+ }
+ /* fallthrough */
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode, context);
+ break;
}
- else
- ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode, context);
}
/*
@@ -7249,12 +7604,27 @@ ATExecSetStatistics(Relation rel, const char *colName, int16 colNum, Node *newVa
* We allow referencing columns by numbers only for indexes, since table
* column numbers could contain gaps if columns are later dropped.
*/
- if (rel->rd_rel->relkind != RELKIND_INDEX &&
- rel->rd_rel->relkind != RELKIND_PARTITIONED_INDEX &&
- !colName)
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot refer to non-index column by number")));
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ break;
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ if (!colName)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot refer to non-index column by number")));
+ break;
+ }
Assert(IsA(newValue, Integer));
newtarget = intVal(newValue);
@@ -7310,20 +7680,35 @@ ATExecSetStatistics(Relation rel, const char *colName, int16 colNum, Node *newVa
errmsg("cannot alter system column \"%s\"",
colName)));
- if (rel->rd_rel->relkind == RELKIND_INDEX ||
- rel->rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
+ switch ((RelKind) rel->rd_rel->relkind)
{
- if (attnum > rel->rd_index->indnkeyatts)
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot alter statistics on included column \"%s\" of index \"%s\"",
- NameStr(attrtuple->attname), RelationGetRelationName(rel))));
- else if (rel->rd_index->indkey.values[attnum - 1] != 0)
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot alter statistics on non-expression column \"%s\" of index \"%s\"",
- NameStr(attrtuple->attname), RelationGetRelationName(rel)),
- errhint("Alter statistics on table column instead.")));
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ {
+ if (attnum > rel->rd_index->indnkeyatts)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot alter statistics on included column \"%s\" of index \"%s\"",
+ NameStr(attrtuple->attname), RelationGetRelationName(rel))));
+ else if (rel->rd_index->indkey.values[attnum - 1] != 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot alter statistics on non-expression column \"%s\" of index \"%s\"",
+ NameStr(attrtuple->attname), RelationGetRelationName(rel)),
+ errhint("Alter statistics on table column instead.")));
+ }
+ break;
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
}
attrtuple->attstattarget = newtarget;
@@ -7566,8 +7951,24 @@ ATPrepDropColumn(List **wqueue, Relation rel, bool recurse, bool recursing,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("cannot drop column from typed table")));
- if (rel->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
- ATTypedTableRecursion(wqueue, rel, cmd, lockmode, context);
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_COMPOSITE_TYPE:
+ ATTypedTableRecursion(wqueue, rel, cmd, lockmode, context);
+ break;
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
if (recurse)
cmd->subtype = AT_DropColumnRecurse;
@@ -7676,15 +8077,32 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
Relation attr_rel;
ListCell *child;
- /*
- * In case of a partitioned table, the column must be dropped from the
- * partitions as well.
- */
- if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE && !recurse)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
- errmsg("cannot drop column from only the partitioned table when partitions exist"),
- errhint("Do not specify the ONLY keyword.")));
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ /*
+ * In case of a partitioned table, the column must be dropped
+ * from the partitions as well.
+ */
+ case RELKIND_PARTITIONED_TABLE:
+ if (!recurse)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
+ errmsg("cannot drop column from only the partitioned table when partitions exist"),
+ errhint("Do not specify the ONLY keyword.")));
+ break;
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
attr_rel = table_open(AttributeRelationId, RowExclusiveLock);
foreach(child, children)
@@ -7861,10 +8279,26 @@ ATExecAddIndexConstraint(AlteredTableInfo *tab, Relation rel,
* Doing this on partitioned tables is not a simple feature to implement,
* so let's punt for now.
*/
- if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("ALTER TABLE / ADD CONSTRAINT USING INDEX is not supported on partitioned tables")));
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("ALTER TABLE / ADD CONSTRAINT USING INDEX is not supported on partitioned tables")));
+ break;
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
indexRel = index_open(index_oid, AccessShareLock);
@@ -8218,30 +8652,44 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
* Validity checks (permission checks wait till we have the column
* numbers)
*/
- if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
+ switch ((RelKind) rel->rd_rel->relkind)
{
- if (!recurse)
+ case RELKIND_PARTITIONED_TABLE:
+ {
+ if (!recurse)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot use ONLY for foreign key on partitioned table \"%s\" referencing relation \"%s\"",
+ RelationGetRelationName(rel),
+ RelationGetRelationName(pkrel))));
+ if (fkconstraint->skip_validation && !fkconstraint->initially_valid)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot add NOT VALID foreign key on partitioned table \"%s\" referencing relation \"%s\"",
+ RelationGetRelationName(rel),
+ RelationGetRelationName(pkrel)),
+ errdetail("This feature is not yet supported on partitioned tables.")));
+ }
+ break;
+ case RELKIND_RELATION:
+ break;
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot use ONLY for foreign key on partitioned table \"%s\" referencing relation \"%s\"",
- RelationGetRelationName(rel),
+ errmsg("referenced relation \"%s\" is not a table",
RelationGetRelationName(pkrel))));
- if (fkconstraint->skip_validation && !fkconstraint->initially_valid)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot add NOT VALID foreign key on partitioned table \"%s\" referencing relation \"%s\"",
- RelationGetRelationName(rel),
- RelationGetRelationName(pkrel)),
- errdetail("This feature is not yet supported on partitioned tables.")));
+ break;
}
- if (pkrel->rd_rel->relkind != RELKIND_RELATION &&
- pkrel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("referenced relation \"%s\" is not a table",
- RelationGetRelationName(pkrel))));
-
if (!allowSystemTableMods && IsSystemRelation(pkrel))
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
@@ -8640,12 +9088,26 @@ addFkRecurseReferenced(List **wqueue, Constraint *fkconstraint, Relation rel,
* Verify relkind for each referenced partition. At the top level, this
* is redundant with a previous check, but we need it when recursing.
*/
- if (pkrel->rd_rel->relkind != RELKIND_RELATION &&
- pkrel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("referenced relation \"%s\" is not a table",
- RelationGetRelationName(pkrel))));
+ switch ((RelKind) pkrel->rd_rel->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("referenced relation \"%s\" is not a table",
+ RelationGetRelationName(pkrel))));
+ }
/*
* Caller supplies us with a constraint name; however, it may be used in
@@ -8675,7 +9137,23 @@ addFkRecurseReferenced(List **wqueue, Constraint *fkconstraint, Relation rel,
/*
* always inherit for partitioned tables, never for legacy inheritance
*/
- connoinherit = rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE;
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ connoinherit = false;
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ connoinherit = true;
+ }
}
/*
@@ -8730,69 +9208,84 @@ addFkRecurseReferenced(List **wqueue, Constraint *fkconstraint, Relation rel,
/* make new constraint visible, in case we add more */
CommandCounterIncrement();
- /*
- * If the referenced table is a plain relation, create the action triggers
- * that enforce the constraint.
- */
- if (pkrel->rd_rel->relkind == RELKIND_RELATION)
- {
- createForeignKeyActionTriggers(rel, RelationGetRelid(pkrel),
- fkconstraint,
- constrOid, indexOid);
- }
-
- /*
- * If the referenced table is partitioned, recurse on ourselves to handle
- * each partition. We need one pg_constraint row created for each
- * partition in addition to the pg_constraint row for the parent table.
- */
- if (pkrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
+ switch ((RelKind) pkrel->rd_rel->relkind)
{
- PartitionDesc pd = RelationGetPartitionDesc(pkrel);
-
- for (int i = 0; i < pd->nparts; i++)
- {
- Relation partRel;
- AttrMap *map;
- AttrNumber *mapped_pkattnum;
- Oid partIndexId;
-
- partRel = table_open(pd->oids[i], ShareRowExclusiveLock);
+ /*
+ * If the referenced table is a plain relation, create the action
+ * triggers that enforce the constraint.
+ */
+ case RELKIND_RELATION:
+ createForeignKeyActionTriggers(rel, RelationGetRelid(pkrel),
+ fkconstraint,
+ constrOid, indexOid);
+ break;
/*
- * Map the attribute numbers in the referenced side of the FK
- * definition to match the partition's column layout.
+ * If the referenced table is partitioned, recurse on ourselves to
+ * handle each partition. We need one pg_constraint row created
+ * for each partition in addition to the pg_constraint row for the
+ * parent table.
*/
- map = build_attrmap_by_name_if_req(RelationGetDescr(partRel),
- RelationGetDescr(pkrel));
- if (map)
- {
- mapped_pkattnum = palloc(sizeof(AttrNumber) * numfks);
- for (int j = 0; j < numfks; j++)
- mapped_pkattnum[j] = map->attnums[pkattnum[j] - 1];
- }
- else
- mapped_pkattnum = pkattnum;
-
- /* do the deed */
- partIndexId = index_get_partition(partRel, indexOid);
- if (!OidIsValid(partIndexId))
- elog(ERROR, "index for %u not found in partition %s",
- indexOid, RelationGetRelationName(partRel));
- addFkRecurseReferenced(wqueue, fkconstraint, rel, partRel,
- partIndexId, constrOid, numfks,
- mapped_pkattnum, fkattnum,
- pfeqoperators, ppeqoperators, ffeqoperators,
- old_check_ok);
-
- /* Done -- clean up (but keep the lock) */
- table_close(partRel, NoLock);
- if (map)
+ case RELKIND_PARTITIONED_TABLE:
{
- pfree(mapped_pkattnum);
- free_attrmap(map);
+ PartitionDesc pd = RelationGetPartitionDesc(pkrel);
+
+ for (int i = 0; i < pd->nparts; i++)
+ {
+ Relation partRel;
+ AttrMap *map;
+ AttrNumber *mapped_pkattnum;
+ Oid partIndexId;
+
+ partRel = table_open(pd->oids[i], ShareRowExclusiveLock);
+
+ /*
+ * Map the attribute numbers in the referenced side of the
+ * FK definition to match the partition's column layout.
+ */
+ map = build_attrmap_by_name_if_req(RelationGetDescr(partRel),
+ RelationGetDescr(pkrel));
+ if (map)
+ {
+ mapped_pkattnum = palloc(sizeof(AttrNumber) * numfks);
+ for (int j = 0; j < numfks; j++)
+ mapped_pkattnum[j] = map->attnums[pkattnum[j] - 1];
+ }
+ else
+ mapped_pkattnum = pkattnum;
+
+ /* do the deed */
+ partIndexId = index_get_partition(partRel, indexOid);
+ if (!OidIsValid(partIndexId))
+ elog(ERROR, "index for %u not found in partition %s",
+ indexOid, RelationGetRelationName(partRel));
+ addFkRecurseReferenced(wqueue, fkconstraint, rel, partRel,
+ partIndexId, constrOid, numfks,
+ mapped_pkattnum, fkattnum,
+ pfeqoperators, ppeqoperators, ffeqoperators,
+ old_check_ok);
+
+ /* Done -- clean up (but keep the lock) */
+ table_close(partRel, NoLock);
+ if (map)
+ {
+ pfree(mapped_pkattnum);
+ free_attrmap(map);
+ }
+ }
}
- }
+ break;
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
}
return address;
@@ -8836,177 +9329,196 @@ addFkRecurseReferencing(List **wqueue, Constraint *fkconstraint, Relation rel,
{
AssertArg(OidIsValid(parentConstr));
- if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("foreign key constraints are not supported on foreign tables")));
-
- /*
- * If the referencing relation is a plain table, add the check triggers to
- * it and, if necessary, schedule it to be checked in Phase 3.
- *
- * If the relation is partitioned, drill down to do it to its partitions.
- */
- if (rel->rd_rel->relkind == RELKIND_RELATION)
+ switch ((RelKind) rel->rd_rel->relkind)
{
- createForeignKeyCheckTriggers(RelationGetRelid(rel),
- RelationGetRelid(pkrel),
- fkconstraint,
- parentConstr,
- indexOid);
-
- /*
- * Tell Phase 3 to check that the constraint is satisfied by existing
- * rows. We can skip this during table creation, when requested
- * explicitly by specifying NOT VALID in an ADD FOREIGN KEY command,
- * and when we're recreating a constraint following a SET DATA TYPE
- * operation that did not impugn its validity.
- */
- if (wqueue && !old_check_ok && !fkconstraint->skip_validation)
- {
- NewConstraint *newcon;
- AlteredTableInfo *tab;
+ /*
+ * If the referencing relation is a plain table, add the check
+ * triggers to it and, if necessary, schedule it to be checked in
+ * Phase 3.
+ *
+ * If the relation is partitioned, drill down to do it to its
+ * partitions.
+ */
+ case RELKIND_RELATION:
+ {
+ createForeignKeyCheckTriggers(RelationGetRelid(rel),
+ RelationGetRelid(pkrel),
+ fkconstraint,
+ parentConstr,
+ indexOid);
- tab = ATGetQueueEntry(wqueue, rel);
+ /*
+ * Tell Phase 3 to check that the constraint is satisfied by
+ * existing rows. We can skip this during table creation, when
+ * requested explicitly by specifying NOT VALID in an ADD
+ * FOREIGN KEY command, and when we're recreating a constraint
+ * following a SET DATA TYPE operation that did not impugn its
+ * validity.
+ */
+ if (wqueue && !old_check_ok && !fkconstraint->skip_validation)
+ {
+ NewConstraint *newcon;
+ AlteredTableInfo *tab;
- newcon = (NewConstraint *) palloc0(sizeof(NewConstraint));
- newcon->name = get_constraint_name(parentConstr);
- newcon->contype = CONSTR_FOREIGN;
- newcon->refrelid = RelationGetRelid(pkrel);
- newcon->refindid = indexOid;
- newcon->conid = parentConstr;
- newcon->qual = (Node *) fkconstraint;
+ tab = ATGetQueueEntry(wqueue, rel);
- tab->constraints = lappend(tab->constraints, newcon);
- }
- }
- else if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- {
- PartitionDesc pd = RelationGetPartitionDesc(rel);
+ newcon = (NewConstraint *) palloc0(sizeof(NewConstraint));
+ newcon->name = get_constraint_name(parentConstr);
+ newcon->contype = CONSTR_FOREIGN;
+ newcon->refrelid = RelationGetRelid(pkrel);
+ newcon->refindid = indexOid;
+ newcon->conid = parentConstr;
+ newcon->qual = (Node *) fkconstraint;
- /*
- * Recurse to take appropriate action on each partition; either we
- * find an existing constraint to reparent to ours, or we create a new
- * one.
- */
- for (int i = 0; i < pd->nparts; i++)
- {
- Oid partitionId = pd->oids[i];
- Relation partition = table_open(partitionId, lockmode);
- List *partFKs;
- AttrMap *attmap;
- AttrNumber mapped_fkattnum[INDEX_MAX_KEYS];
- bool attached;
- char *conname;
- Oid constrOid;
- ObjectAddress address,
- referenced;
- ListCell *cell;
-
- CheckTableNotInUse(partition, "ALTER TABLE");
-
- attmap = build_attrmap_by_name(RelationGetDescr(partition),
- RelationGetDescr(rel));
- for (int j = 0; j < numfks; j++)
- mapped_fkattnum[j] = attmap->attnums[fkattnum[j] - 1];
-
- /* Check whether an existing constraint can be repurposed */
- partFKs = copyObject(RelationGetFKeyList(partition));
- attached = false;
- foreach(cell, partFKs)
- {
- ForeignKeyCacheInfo *fk;
-
- fk = lfirst_node(ForeignKeyCacheInfo, cell);
- if (tryAttachPartitionForeignKey(fk,
- partitionId,
- parentConstr,
- numfks,
- mapped_fkattnum,
- pkattnum,
- pfeqoperators))
- {
- attached = true;
- break;
+ tab->constraints = lappend(tab->constraints, newcon);
}
}
- if (attached)
+ break;
+ case RELKIND_PARTITIONED_TABLE:
{
- table_close(partition, NoLock);
- continue;
- }
+ PartitionDesc pd = RelationGetPartitionDesc(rel);
- /*
- * No luck finding a good constraint to reuse; create our own.
- */
- if (ConstraintNameIsUsed(CONSTRAINT_RELATION,
- RelationGetRelid(partition),
- fkconstraint->conname))
- conname = ChooseConstraintName(RelationGetRelationName(partition),
- ChooseForeignKeyConstraintNameAddition(fkconstraint->fk_attrs),
- "fkey",
- RelationGetNamespace(partition), NIL);
- else
- conname = fkconstraint->conname;
- constrOid =
- CreateConstraintEntry(conname,
- RelationGetNamespace(partition),
- CONSTRAINT_FOREIGN,
- fkconstraint->deferrable,
- fkconstraint->initdeferred,
- fkconstraint->initially_valid,
- parentConstr,
- partitionId,
- mapped_fkattnum,
- numfks,
- numfks,
- InvalidOid,
- indexOid,
- RelationGetRelid(pkrel),
- pkattnum,
- pfeqoperators,
- ppeqoperators,
- ffeqoperators,
- numfks,
- fkconstraint->fk_upd_action,
- fkconstraint->fk_del_action,
- fkconstraint->fk_matchtype,
- NULL,
- NULL,
- NULL,
- false,
- 1,
- false,
- false);
+ /*
+ * Recurse to take appropriate action on each partition;
+ * either we find an existing constraint to reparent to ours,
+ * or we create a new one.
+ */
+ for (int i = 0; i < pd->nparts; i++)
+ {
+ Oid partitionId = pd->oids[i];
+ Relation partition = table_open(partitionId, lockmode);
+ List *partFKs;
+ AttrMap *attmap;
+ AttrNumber mapped_fkattnum[INDEX_MAX_KEYS];
+ bool attached;
+ char *conname;
+ Oid constrOid;
+ ObjectAddress address,
+ referenced;
+ ListCell *cell;
+
+ CheckTableNotInUse(partition, "ALTER TABLE");
+
+ attmap = build_attrmap_by_name(RelationGetDescr(partition),
+ RelationGetDescr(rel));
+ for (int j = 0; j < numfks; j++)
+ mapped_fkattnum[j] = attmap->attnums[fkattnum[j] - 1];
+
+ /* Check whether an existing constraint can be repurposed */
+ partFKs = copyObject(RelationGetFKeyList(partition));
+ attached = false;
+ foreach(cell, partFKs)
+ {
+ ForeignKeyCacheInfo *fk;
+
+ fk = lfirst_node(ForeignKeyCacheInfo, cell);
+ if (tryAttachPartitionForeignKey(fk,
+ partitionId,
+ parentConstr,
+ numfks,
+ mapped_fkattnum,
+ pkattnum,
+ pfeqoperators))
+ {
+ attached = true;
+ break;
+ }
+ }
+ if (attached)
+ {
+ table_close(partition, NoLock);
+ continue;
+ }
- /*
- * Give this constraint partition-type dependencies on the parent
- * constraint as well as the table.
- */
- ObjectAddressSet(address, ConstraintRelationId, constrOid);
- ObjectAddressSet(referenced, ConstraintRelationId, parentConstr);
- recordDependencyOn(&address, &referenced, DEPENDENCY_PARTITION_PRI);
- ObjectAddressSet(referenced, RelationRelationId, partitionId);
- recordDependencyOn(&address, &referenced, DEPENDENCY_PARTITION_SEC);
+ /*
+ * No luck finding a good constraint to reuse; create our
+ * own.
+ */
+ if (ConstraintNameIsUsed(CONSTRAINT_RELATION,
+ RelationGetRelid(partition),
+ fkconstraint->conname))
+ conname = ChooseConstraintName(RelationGetRelationName(partition),
+ ChooseForeignKeyConstraintNameAddition(fkconstraint->fk_attrs),
+ "fkey",
+ RelationGetNamespace(partition), NIL);
+ else
+ conname = fkconstraint->conname;
+ constrOid =
+ CreateConstraintEntry(conname,
+ RelationGetNamespace(partition),
+ CONSTRAINT_FOREIGN,
+ fkconstraint->deferrable,
+ fkconstraint->initdeferred,
+ fkconstraint->initially_valid,
+ parentConstr,
+ partitionId,
+ mapped_fkattnum,
+ numfks,
+ numfks,
+ InvalidOid,
+ indexOid,
+ RelationGetRelid(pkrel),
+ pkattnum,
+ pfeqoperators,
+ ppeqoperators,
+ ffeqoperators,
+ numfks,
+ fkconstraint->fk_upd_action,
+ fkconstraint->fk_del_action,
+ fkconstraint->fk_matchtype,
+ NULL,
+ NULL,
+ NULL,
+ false,
+ 1,
+ false,
+ false);
- /* Make all this visible before recursing */
- CommandCounterIncrement();
+ /*
+ * Give this constraint partition-type dependencies on the
+ * parent constraint as well as the table.
+ */
+ ObjectAddressSet(address, ConstraintRelationId, constrOid);
+ ObjectAddressSet(referenced, ConstraintRelationId, parentConstr);
+ recordDependencyOn(&address, &referenced, DEPENDENCY_PARTITION_PRI);
+ ObjectAddressSet(referenced, RelationRelationId, partitionId);
+ recordDependencyOn(&address, &referenced, DEPENDENCY_PARTITION_SEC);
- /* call ourselves to finalize the creation and we're done */
- addFkRecurseReferencing(wqueue, fkconstraint, partition, pkrel,
- indexOid,
- constrOid,
- numfks,
- pkattnum,
- mapped_fkattnum,
- pfeqoperators,
- ppeqoperators,
- ffeqoperators,
- old_check_ok,
- lockmode);
-
- table_close(partition, NoLock);
- }
+ /* Make all this visible before recursing */
+ CommandCounterIncrement();
+
+ /* call ourselves to finalize the creation and we're done */
+ addFkRecurseReferencing(wqueue, fkconstraint, partition, pkrel,
+ indexOid,
+ constrOid,
+ numfks,
+ pkattnum,
+ mapped_fkattnum,
+ pfeqoperators,
+ ppeqoperators,
+ ffeqoperators,
+ old_check_ok,
+ lockmode);
+
+ table_close(partition, NoLock);
+ }
+ }
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("foreign key constraints are not supported on foreign tables")));
+ break;
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
}
}
@@ -9229,10 +9741,26 @@ CloneFkReferencing(List **wqueue, Relation parentRel, Relation partRel)
if (clone == NIL)
return;
- if (partRel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("foreign key constraints are not supported on foreign tables")));
+ switch ((RelKind) partRel->rd_rel->relkind)
+ {
+ case RELKIND_FOREIGN_TABLE:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("foreign key constraints are not supported on foreign tables")));
+ break;
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
/*
* The constraint key may differ, if the columns in the partition are
@@ -9282,9 +9810,25 @@ CloneFkReferencing(List **wqueue, Relation parentRel, Relation partRel)
* relation, that means to lock all partitions.
*/
pkrel = table_open(constrForm->confrelid, ShareRowExclusiveLock);
- if (pkrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- (void) find_all_inheritors(RelationGetRelid(pkrel),
- ShareRowExclusiveLock, NULL);
+ switch ((RelKind) pkrel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ (void) find_all_inheritors(RelationGetRelid(pkrel),
+ ShareRowExclusiveLock, NULL);
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
DeconstructFkConstraintRow(tuple, &numfks, conkey, confkey,
conpfeqop, conppeqop, conffeqop);
@@ -10249,9 +10793,23 @@ validateCheckConstraint(Relation rel, HeapTuple constrtup)
* VALIDATE CONSTRAINT is a no-op for foreign tables and partitioned
* tables.
*/
- if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE ||
- rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- return;
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ return;
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
constrForm = (Form_pg_constraint) GETSTRUCT(constrtup);
@@ -10705,11 +11263,27 @@ ATExecDropConstraint(Relation rel, const char *constrName,
* For partitioned tables, non-CHECK inherited constraints are dropped via
* the dependency mechanism, so we're done here.
*/
- if (contype != CONSTRAINT_CHECK &&
- rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
+ switch ((RelKind) rel->rd_rel->relkind)
{
- table_close(conrel, RowExclusiveLock);
- return;
+ case RELKIND_PARTITIONED_TABLE:
+ if (contype != CONSTRAINT_CHECK)
+ {
+ table_close(conrel, RowExclusiveLock);
+ return;
+ }
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
}
/*
@@ -10727,12 +11301,28 @@ ATExecDropConstraint(Relation rel, const char *constrName,
* recurse, it's a user error. It doesn't make sense to have a constraint
* be defined only on the parent, especially if it's a partitioned table.
*/
- if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE &&
- children != NIL && !recurse)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
- errmsg("cannot remove constraint from only the partitioned table when partitions exist"),
- errhint("Do not specify the ONLY keyword.")));
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ if (children != NIL && !recurse)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
+ errmsg("cannot remove constraint from only the partitioned table when partitions exist"),
+ errhint("Do not specify the ONLY keyword.")));
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
foreach(child, children)
{
@@ -10924,87 +11514,106 @@ ATPrepAlterColumnType(List **wqueue,
list_make1_oid(rel->rd_rel->reltype),
0);
- if (tab->relkind == RELKIND_RELATION ||
- tab->relkind == RELKIND_PARTITIONED_TABLE)
+ switch ((RelKind) tab->relkind)
{
- /*
- * Set up an expression to transform the old data value to the new
- * type. If a USING option was given, use the expression as
- * transformed by transformAlterTableStmt, else just take the old
- * value and try to coerce it. We do this first so that type
- * incompatibility can be detected before we waste effort, and because
- * we need the expression to be parsed against the original table row
- * type.
- */
- if (!transform)
- {
- transform = (Node *) makeVar(1, attnum,
- attTup->atttypid, attTup->atttypmod,
- attTup->attcollation,
- 0);
- }
-
- transform = coerce_to_target_type(pstate,
- transform, exprType(transform),
- targettype, targettypmod,
- COERCION_ASSIGNMENT,
- COERCE_IMPLICIT_CAST,
- -1);
- if (transform == NULL)
- {
- /* error text depends on whether USING was specified or not */
- if (def->cooked_default != NULL)
- ereport(ERROR,
- (errcode(ERRCODE_DATATYPE_MISMATCH),
- errmsg("result of USING clause for column \"%s\""
- " cannot be cast automatically to type %s",
- colName, format_type_be(targettype)),
- errhint("You might need to add an explicit cast.")));
- else
- ereport(ERROR,
- (errcode(ERRCODE_DATATYPE_MISMATCH),
- errmsg("column \"%s\" cannot be cast automatically to type %s",
- colName, format_type_be(targettype)),
- /* translator: USING is SQL, don't translate it */
- errhint("You might need to specify \"USING %s::%s\".",
- quote_identifier(colName),
- format_type_with_typemod(targettype,
- targettypmod))));
- }
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ {
+ /*
+ * Set up an expression to transform the old data value to the
+ * new type. If a USING option was given, use the expression
+ * as transformed by transformAlterTableStmt, else just take
+ * the old value and try to coerce it. We do this first so
+ * that type incompatibility can be detected before we waste
+ * effort, and because we need the expression to be parsed
+ * against the original table row type.
+ */
+ if (!transform)
+ {
+ transform = (Node *) makeVar(1, attnum,
+ attTup->atttypid, attTup->atttypmod,
+ attTup->attcollation,
+ 0);
+ }
- /* Fix collations after all else */
- assign_expr_collations(pstate, transform);
+ transform = coerce_to_target_type(pstate,
+ transform, exprType(transform),
+ targettype, targettypmod,
+ COERCION_ASSIGNMENT,
+ COERCE_IMPLICIT_CAST,
+ -1);
+ if (transform == NULL)
+ {
+ /*
+ * error text depends on whether USING was specified or
+ * not
+ */
+ if (def->cooked_default != NULL)
+ ereport(ERROR,
+ (errcode(ERRCODE_DATATYPE_MISMATCH),
+ errmsg("result of USING clause for column \"%s\""
+ " cannot be cast automatically to type %s",
+ colName, format_type_be(targettype)),
+ errhint("You might need to add an explicit cast.")));
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_DATATYPE_MISMATCH),
+ errmsg("column \"%s\" cannot be cast automatically to type %s",
+ colName, format_type_be(targettype)),
+ /* translator: USING is SQL, don't translate it */
+ errhint("You might need to specify \"USING %s::%s\".",
+ quote_identifier(colName),
+ format_type_with_typemod(targettype,
+ targettypmod))));
+ }
- /* Plan the expr now so we can accurately assess the need to rewrite. */
- transform = (Node *) expression_planner((Expr *) transform);
+ /* Fix collations after all else */
+ assign_expr_collations(pstate, transform);
- /*
- * Add a work queue item to make ATRewriteTable update the column
- * contents.
- */
- newval = (NewColumnValue *) palloc0(sizeof(NewColumnValue));
- newval->attnum = attnum;
- newval->expr = (Expr *) transform;
- newval->is_generated = false;
+ /*
+ * Plan the expr now so we can accurately assess the need to
+ * rewrite.
+ */
+ transform = (Node *) expression_planner((Expr *) transform);
- tab->newvals = lappend(tab->newvals, newval);
- if (ATColumnChangeRequiresRewrite(transform, attnum))
- tab->rewrite |= AT_REWRITE_COLUMN_REWRITE;
- }
- else if (transform)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table",
- RelationGetRelationName(rel))));
+ /*
+ * Add a work queue item to make ATRewriteTable update the
+ * column contents.
+ */
+ newval = (NewColumnValue *) palloc0(sizeof(NewColumnValue));
+ newval->attnum = attnum;
+ newval->expr = (Expr *) transform;
+ newval->is_generated = false;
+
+ tab->newvals = lappend(tab->newvals, newval);
+ if (ATColumnChangeRequiresRewrite(transform, attnum))
+ tab->rewrite |= AT_REWRITE_COLUMN_REWRITE;
+ }
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_COMPOSITE_TYPE:
- if (tab->relkind == RELKIND_COMPOSITE_TYPE ||
- tab->relkind == RELKIND_FOREIGN_TABLE)
- {
- /*
- * For composite types, do this check now. Tables will check it later
- * when the table is being rewritten.
- */
- find_composite_type_dependencies(rel->rd_rel->reltype, rel, NULL);
+ /*
+ * For composite types, do this check now. Tables will check it
+ * later when the table is being rewritten.
+ */
+ if (!transform)
+ find_composite_type_dependencies(rel->rd_rel->reltype, rel, NULL);
+ /* fallthrough */
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ if (transform)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a table",
+ RelationGetRelationName(rel))));
+ break;
}
ReleaseSysCache(tuple);
@@ -11108,8 +11717,24 @@ ATPrepAlterColumnType(List **wqueue,
errmsg("type of inherited column \"%s\" must be changed in child tables too",
colName)));
- if (tab->relkind == RELKIND_COMPOSITE_TYPE)
- ATTypedTableRecursion(wqueue, rel, cmd, lockmode, context);
+ switch ((RelKind) tab->relkind)
+ {
+ case RELKIND_COMPOSITE_TYPE:
+ ATTypedTableRecursion(wqueue, rel, cmd, lockmode, context);
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
}
/*
@@ -11326,44 +11951,53 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
{
char relKind = get_rel_relkind(foundObject.objectId);
- if (relKind == RELKIND_INDEX ||
- relKind == RELKIND_PARTITIONED_INDEX)
- {
- Assert(foundObject.objectSubId == 0);
- RememberIndexForRebuilding(foundObject.objectId, tab);
- }
- else if (relKind == RELKIND_SEQUENCE)
- {
- /*
- * This must be a SERIAL column's sequence. We need
- * not do anything to it.
- */
- Assert(foundObject.objectSubId == 0);
- }
- else if (relKind == RELKIND_RELATION &&
- foundObject.objectSubId != 0 &&
- get_attgenerated(foundObject.objectId, foundObject.objectSubId))
- {
- /*
- * Changing the type of a column that is used by a
- * generated column is not allowed by SQL standard. It
- * might be doable with some thinking and effort.
- */
- ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("cannot alter type of a column used by a generated column"),
- errdetail("Column \"%s\" is used by generated column \"%s\".",
- colName, get_attname(foundObject.objectId, foundObject.objectSubId, false))));
- }
- else
+ switch ((RelKind) relKind)
{
- /* Not expecting any other direct dependencies... */
- elog(ERROR, "unexpected object depending on column: %s",
- getObjectDescription(&foundObject));
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ Assert(foundObject.objectSubId == 0);
+ RememberIndexForRebuilding(foundObject.objectId, tab);
+ break;
+ case RELKIND_SEQUENCE:
+
+ /*
+ * This must be a SERIAL column's sequence. We
+ * need not do anything to it.
+ */
+ Assert(foundObject.objectSubId == 0);
+ break;
+ case RELKIND_RELATION:
+ if (foundObject.objectSubId != 0 &&
+ get_attgenerated(foundObject.objectId, foundObject.objectSubId))
+ {
+ /*
+ * Changing the type of a column that is used
+ * by a generated column is not allowed by SQL
+ * standard. It might be doable with some
+ * thinking and effort.
+ */
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("cannot alter type of a column used by a generated column"),
+ errdetail("Column \"%s\" is used by generated column \"%s\".",
+ colName, get_attname(foundObject.objectId, foundObject.objectSubId, false))));
+ }
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ /* Not expecting any other direct dependencies... */
+ elog(ERROR, "unexpected object depending on column: %s",
+ getObjectDescription(&foundObject));
+ break;
}
- break;
}
-
+ break;
case OCLASS_CONSTRAINT:
Assert(foundObject.objectSubId == 0);
RememberConstraintForRebuilding(foundObject.objectId, tab);
@@ -12196,13 +12830,28 @@ TryReuseIndex(Oid oldId, IndexStmt *stmt)
{
Relation irel = index_open(oldId, NoLock);
- /* If it's a partitioned index, there is no storage to share. */
- if (irel->rd_rel->relkind != RELKIND_PARTITIONED_INDEX)
+ switch ((RelKind) irel->rd_rel->relkind)
{
- stmt->oldNode = irel->rd_node.relNode;
- stmt->oldCreateSubid = irel->rd_createSubid;
- stmt->oldFirstRelfilenodeSubid = irel->rd_firstRelfilenodeSubid;
+ case RELKIND_PARTITIONED_INDEX:
+ /* If it's a partitioned index, there is no storage to share. */
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ stmt->oldNode = irel->rd_node.relNode;
+ stmt->oldCreateSubid = irel->rd_createSubid;
+ stmt->oldFirstRelfilenodeSubid = irel->rd_firstRelfilenodeSubid;
+ break;
}
+
index_close(irel, NoLock);
}
}
@@ -12397,7 +13046,7 @@ ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, LOCKMODE lock
tuple_class = (Form_pg_class) GETSTRUCT(tuple);
/* Can we change the ownership of this tuple? */
- switch (tuple_class->relkind)
+ switch ((RelKind) tuple_class->relkind)
{
case RELKIND_RELATION:
case RELKIND_VIEW:
@@ -12467,6 +13116,7 @@ ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, LOCKMODE lock
if (recursing)
break;
/* FALL THRU */
+ case RELKIND_NULL:
default:
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
@@ -12554,41 +13204,82 @@ ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, LOCKMODE lock
* none, because it's tracked for the pg_type entry instead of here;
* indexes and TOAST tables don't have their own entries either.
*/
- if (tuple_class->relkind != RELKIND_COMPOSITE_TYPE &&
- tuple_class->relkind != RELKIND_INDEX &&
- tuple_class->relkind != RELKIND_PARTITIONED_INDEX &&
- tuple_class->relkind != RELKIND_TOASTVALUE)
- changeDependencyOnOwner(RelationRelationId, relationOid,
- newOwnerId);
+ switch ((RelKind) tuple_class->relkind)
+ {
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_TOASTVALUE:
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_NULL:
+ default:
+ changeDependencyOnOwner(RelationRelationId, relationOid,
+ newOwnerId);
+ break;
+ }
/*
* Also change the ownership of the table's row type, if it has one
*/
- if (tuple_class->relkind != RELKIND_INDEX &&
- tuple_class->relkind != RELKIND_PARTITIONED_INDEX)
- AlterTypeOwnerInternal(tuple_class->reltype, newOwnerId);
+ switch ((RelKind) tuple_class->relkind)
+ {
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ AlterTypeOwnerInternal(tuple_class->reltype, newOwnerId);
+ break;
+ }
/*
* If we are operating on a table or materialized view, also change
* the ownership of any indexes and sequences that belong to the
* relation, as well as its toast table (if it has one).
*/
- if (tuple_class->relkind == RELKIND_RELATION ||
- tuple_class->relkind == RELKIND_PARTITIONED_TABLE ||
- tuple_class->relkind == RELKIND_MATVIEW ||
- tuple_class->relkind == RELKIND_TOASTVALUE)
+ switch ((RelKind) tuple_class->relkind)
{
- List *index_oid_list;
- ListCell *i;
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ {
+ List *index_oid_list;
+ ListCell *i;
- /* Find all the indexes belonging to this relation */
- index_oid_list = RelationGetIndexList(target_rel);
+ /* Find all the indexes belonging to this relation */
+ index_oid_list = RelationGetIndexList(target_rel);
- /* For each index, recursively change its ownership */
- foreach(i, index_oid_list)
- ATExecChangeOwner(lfirst_oid(i), newOwnerId, true, lockmode);
+ /* For each index, recursively change its ownership */
+ foreach(i, index_oid_list)
+ ATExecChangeOwner(lfirst_oid(i), newOwnerId, true, lockmode);
- list_free(index_oid_list);
+ list_free(index_oid_list);
+ }
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_NULL:
+ default:
+ break;
}
/* If it has a toast table, recurse to change its ownership */
@@ -12721,11 +13412,24 @@ change_owner_recurse_to_sequences(Oid relationOid, Oid newOwnerId, LOCKMODE lock
seqRel = relation_open(depForm->objid, lockmode);
/* skip non-sequence relations */
- if (RelationGetForm(seqRel)->relkind != RELKIND_SEQUENCE)
+ switch ((RelKind) RelationGetForm(seqRel)->relkind)
{
- /* No need to keep the lock */
- relation_close(seqRel, lockmode);
- continue;
+ case RELKIND_SEQUENCE:
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ /* No need to keep the lock */
+ relation_close(seqRel, lockmode);
+ continue;
}
/* We don't need to close the sequence while we alter it. */
@@ -12867,7 +13571,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation,
operation == AT_ResetRelOptions);
/* Validate */
- switch (rel->rd_rel->relkind)
+ switch ((RelKind) rel->rd_rel->relkind)
{
case RELKIND_RELATION:
case RELKIND_TOASTVALUE:
@@ -12879,11 +13583,47 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation,
break;
case RELKIND_VIEW:
(void) view_reloptions(newOptions, true);
+
+ /* Special-case validation of view options */
+ {
+ Query *view_query = get_view_query(rel);
+ List *view_options = untransformRelOptions(newOptions);
+ ListCell *cell;
+ bool check_option = false;
+
+ foreach(cell, view_options)
+ {
+ DefElem *defel = (DefElem *) lfirst(cell);
+
+ if (strcmp(defel->defname, "check_option") == 0)
+ check_option = true;
+ }
+
+ /*
+ * If the check option is specified, look to see if the view
+ * is actually auto-updatable or not.
+ */
+ if (check_option)
+ {
+ const char *view_updatable_error =
+ view_query_is_auto_updatable(view_query, true);
+
+ if (view_updatable_error)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("WITH CHECK OPTION is supported only on automatically updatable views"),
+ errhint("%s", _(view_updatable_error))));
+ }
+ }
break;
case RELKIND_INDEX:
case RELKIND_PARTITIONED_INDEX:
(void) index_reloptions(rel->rd_indam->amoptions, newOptions, true);
break;
+ case RELKIND_NULL:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_SEQUENCE:
default:
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
@@ -12892,39 +13632,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation,
break;
}
- /* Special-case validation of view options */
- if (rel->rd_rel->relkind == RELKIND_VIEW)
- {
- Query *view_query = get_view_query(rel);
- List *view_options = untransformRelOptions(newOptions);
- ListCell *cell;
- bool check_option = false;
-
- foreach(cell, view_options)
- {
- DefElem *defel = (DefElem *) lfirst(cell);
-
- if (strcmp(defel->defname, "check_option") == 0)
- check_option = true;
- }
-
- /*
- * If the check option is specified, look to see if the view is
- * actually auto-updatable or not.
- */
- if (check_option)
- {
- const char *view_updatable_error =
- view_query_is_auto_updatable(view_query, true);
-
- if (view_updatable_error)
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("WITH CHECK OPTION is supported only on automatically updatable views"),
- errhint("%s", _(view_updatable_error))));
- }
- }
-
/*
* All we need do here is update the pg_class row; the new options will be
* propagated into relcaches during post-commit cache inval.
@@ -13109,16 +13816,26 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode)
newrnode.spcNode = newTableSpace;
/* hand off to AM to actually create the new filenode and copy the data */
- if (rel->rd_rel->relkind == RELKIND_INDEX)
+ switch ((RelKind) rel->rd_rel->relkind)
{
- index_copy_data(rel, newrnode);
- }
- else
- {
- Assert(rel->rd_rel->relkind == RELKIND_RELATION ||
- rel->rd_rel->relkind == RELKIND_MATVIEW ||
- rel->rd_rel->relkind == RELKIND_TOASTVALUE);
- table_relation_copy_data(rel, &newrnode);
+ case RELKIND_INDEX:
+ index_copy_data(rel, newrnode);
+ break;
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ table_relation_copy_data(rel, &newrnode);
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_NULL:
+ default:
+ Assert(false);
+ break;
}
/*
@@ -13489,10 +14206,26 @@ ATPrepAddInherit(Relation child_rel)
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("cannot change inheritance of a partition")));
- if (child_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot change inheritance of partitioned table")));
+ switch ((RelKind) child_rel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot change inheritance of partitioned table")));
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
}
/*
@@ -13541,11 +14274,27 @@ ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode)
errmsg("cannot inherit to temporary relation of another session")));
/* Prevent partitioned tables from becoming inheritance parents */
- if (parent_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot inherit from partitioned table \"%s\"",
- parent->relname)));
+ switch ((RelKind) parent_rel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot inherit from partitioned table \"%s\"",
+ parent->relname)));
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
/* Likewise for partitions */
if (parent_rel->rd_rel->relispartition)
@@ -13749,8 +14498,24 @@ MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel)
parent_natts = tupleDesc->natts;
/* If parent_rel is a partitioned table, child_rel must be a partition */
- if (parent_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- child_is_partition = true;
+ switch ((RelKind) parent_rel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ child_is_partition = true;
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
for (parent_attno = 1; parent_attno <= parent_natts; parent_attno++)
{
@@ -13858,8 +14623,24 @@ MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel)
tuple_desc = RelationGetDescr(catalog_relation);
/* If parent_rel is a partitioned table, child_rel must be a partition */
- if (parent_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- child_is_partition = true;
+ switch ((RelKind) parent_rel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ child_is_partition = true;
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
/* Outer loop scans through the parent's constraint definitions */
ScanKeyInit(&parent_key,
@@ -14040,8 +14821,24 @@ RemoveInheritance(Relation child_rel, Relation parent_rel)
bool child_is_partition = false;
/* If parent_rel is a partitioned table, child_rel must be a partition */
- if (parent_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- child_is_partition = true;
+ switch ((RelKind) parent_rel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ child_is_partition = true;
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
found = DeleteInheritsTuple(RelationGetRelid(child_rel),
RelationGetRelid(parent_rel));
@@ -14952,20 +15749,36 @@ AlterTableNamespace(AlterObjectSchemaStmt *stmt, Oid *oldschema)
oldNspOid = RelationGetNamespace(rel);
- /* If it's an owned sequence, disallow moving it by itself. */
- if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
+ switch ((RelKind) rel->rd_rel->relkind)
{
- Oid tableId;
- int32 colId;
+ /* If it's an owned sequence, disallow moving it by itself. */
+ case RELKIND_SEQUENCE:
+ {
+ Oid tableId;
+ int32 colId;
- if (sequenceIsOwned(relid, DEPENDENCY_AUTO, &tableId, &colId) ||
- sequenceIsOwned(relid, DEPENDENCY_INTERNAL, &tableId, &colId))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot move an owned sequence into another schema"),
- errdetail("Sequence \"%s\" is linked to table \"%s\".",
- RelationGetRelationName(rel),
- get_rel_name(tableId))));
+ if (sequenceIsOwned(relid, DEPENDENCY_AUTO, &tableId, &colId) ||
+ sequenceIsOwned(relid, DEPENDENCY_INTERNAL, &tableId, &colId))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move an owned sequence into another schema"),
+ errdetail("Sequence \"%s\" is linked to table \"%s\".",
+ RelationGetRelationName(rel),
+ get_rel_name(tableId))));
+ }
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
}
/* Get and lock schema OID and check its permissions. */
@@ -15014,15 +15827,27 @@ AlterTableNamespaceInternal(Relation rel, Oid oldNspOid, Oid nspOid,
nspOid, false, false, objsMoved);
/* Fix other dependent stuff */
- if (rel->rd_rel->relkind == RELKIND_RELATION ||
- rel->rd_rel->relkind == RELKIND_MATVIEW ||
- rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
+ switch ((RelKind) rel->rd_rel->relkind)
{
- AlterIndexNamespaces(classRel, rel, oldNspOid, nspOid, objsMoved);
- AlterSeqNamespaces(classRel, rel, oldNspOid, nspOid,
- objsMoved, AccessExclusiveLock);
- AlterConstraintNamespaces(RelationGetRelid(rel), oldNspOid, nspOid,
- false, objsMoved);
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ AlterIndexNamespaces(classRel, rel, oldNspOid, nspOid, objsMoved);
+ AlterSeqNamespaces(classRel, rel, oldNspOid, nspOid,
+ objsMoved, AccessExclusiveLock);
+ AlterConstraintNamespaces(RelationGetRelid(rel), oldNspOid, nspOid,
+ false, objsMoved);
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
}
table_close(classRel, RowExclusiveLock);
@@ -15193,11 +16018,24 @@ AlterSeqNamespaces(Relation classRel, Relation rel,
seqRel = relation_open(depForm->objid, lockmode);
/* skip non-sequence relations */
- if (RelationGetForm(seqRel)->relkind != RELKIND_SEQUENCE)
+ switch ((RelKind) RelationGetForm(seqRel)->relkind)
{
- /* No need to keep the lock */
- relation_close(seqRel, lockmode);
- continue;
+ case RELKIND_SEQUENCE:
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ /* No need to keep the lock */
+ relation_close(seqRel, lockmode);
+ continue;
}
/* Fix the pg_class and pg_depend entries */
@@ -15477,11 +16315,26 @@ RangeVarCallbackOwnsTable(const RangeVar *relation,
relkind = get_rel_relkind(relId);
if (!relkind)
return;
- if (relkind != RELKIND_RELATION && relkind != RELKIND_TOASTVALUE &&
- relkind != RELKIND_MATVIEW && relkind != RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table or materialized view", relation->relname)));
+ switch ((RelKind) relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a table or materialized view", relation->relname)));
+ break;
+ }
/* Check permissions */
if (!pg_class_ownercheck(relId, GetUserId()))
@@ -15654,17 +16507,28 @@ RangeVarCallbackForAlterRelation(const RangeVar *rv, Oid relid, Oid oldrelid,
* Don't allow ALTER TABLE .. SET SCHEMA on relations that can't be moved
* to a different schema, such as indexes and TOAST tables.
*/
- if (IsA(stmt, AlterObjectSchemaStmt) &&
- relkind != RELKIND_RELATION &&
- relkind != RELKIND_VIEW &&
- relkind != RELKIND_MATVIEW &&
- relkind != RELKIND_SEQUENCE &&
- relkind != RELKIND_FOREIGN_TABLE &&
- relkind != RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table, view, materialized view, sequence, or foreign table",
- rv->relname)));
+ switch ((RelKind) relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_VIEW:
+ case RELKIND_MATVIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ if (IsA(stmt, AlterObjectSchemaStmt))
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a table, view, materialized view, sequence, or foreign table",
+ rv->relname)));
+ break;
+ }
ReleaseSysCache(tuple);
}
@@ -16139,44 +17003,60 @@ QueuePartitionConstraintValidation(List **wqueue, Relation scanrel,
* validation item now; for partitioned tables, recurse to process each
* partition.
*/
- if (scanrel->rd_rel->relkind == RELKIND_RELATION)
+ switch ((RelKind) scanrel->rd_rel->relkind)
{
- AlteredTableInfo *tab;
+ case RELKIND_RELATION:
+ {
+ AlteredTableInfo *tab;
- /* Grab a work queue entry. */
- tab = ATGetQueueEntry(wqueue, scanrel);
- Assert(tab->partition_constraint == NULL);
- tab->partition_constraint = (Expr *) linitial(partConstraint);
- tab->validate_default = validate_default;
- }
- else if (scanrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- {
- PartitionDesc partdesc = RelationGetPartitionDesc(scanrel);
- int i;
+ /* Grab a work queue entry. */
+ tab = ATGetQueueEntry(wqueue, scanrel);
+ Assert(tab->partition_constraint == NULL);
+ tab->partition_constraint = (Expr *) linitial(partConstraint);
+ tab->validate_default = validate_default;
+ }
+ break;
+ case RELKIND_PARTITIONED_TABLE:
+ {
+ PartitionDesc partdesc = RelationGetPartitionDesc(scanrel);
+ int i;
- for (i = 0; i < partdesc->nparts; i++)
- {
- Relation part_rel;
- List *thisPartConstraint;
+ for (i = 0; i < partdesc->nparts; i++)
+ {
+ Relation part_rel;
+ List *thisPartConstraint;
- /*
- * This is the minimum lock we need to prevent deadlocks.
- */
- part_rel = table_open(partdesc->oids[i], AccessExclusiveLock);
+ /*
+ * This is the minimum lock we need to prevent deadlocks.
+ */
+ part_rel = table_open(partdesc->oids[i], AccessExclusiveLock);
- /*
- * Adjust the constraint for scanrel so that it matches this
- * partition's attribute numbers.
- */
- thisPartConstraint =
- map_partition_varattnos(partConstraint, 1,
- part_rel, scanrel);
-
- QueuePartitionConstraintValidation(wqueue, part_rel,
- thisPartConstraint,
- validate_default);
- table_close(part_rel, NoLock); /* keep lock till commit */
- }
+ /*
+ * Adjust the constraint for scanrel so that it matches
+ * this partition's attribute numbers.
+ */
+ thisPartConstraint =
+ map_partition_varattnos(partConstraint, 1,
+ part_rel, scanrel);
+
+ QueuePartitionConstraintValidation(wqueue, part_rel,
+ thisPartConstraint,
+ validate_default);
+ table_close(part_rel, NoLock); /* keep lock till commit */
+ }
+ }
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
}
}
@@ -16260,11 +17140,29 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
ObjectIdGetDatum(RelationGetRelid(attachrel)));
scan = systable_beginscan(catalog, InheritsParentIndexId, true, NULL,
1, &skey);
- if (HeapTupleIsValid(systable_getnext(scan)) &&
- attachrel->rd_rel->relkind == RELKIND_RELATION)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot attach inheritance parent as partition")));
+
+ switch ((RelKind) attachrel->rd_rel->relkind)
+ {
+ case RELKIND_RELATION:
+ if (HeapTupleIsValid(systable_getnext(scan)))
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot attach inheritance parent as partition")));
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
+
systable_endscan(scan);
table_close(catalog, AccessShareLock);
@@ -16510,26 +17408,38 @@ AttachPartitionEnsureIndexes(Relation rel, Relation attachrel)
* before starting work, to avoid wasting the effort of building a few
* non-unique indexes before coming across a unique one.
*/
- if (attachrel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
+ switch ((RelKind) attachrel->rd_rel->relkind)
{
- foreach(cell, idxes)
- {
- Oid idx = lfirst_oid(cell);
- Relation idxRel = index_open(idx, AccessShareLock);
-
- if (idxRel->rd_index->indisunique ||
- idxRel->rd_index->indisprimary)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot attach foreign table \"%s\" as partition of partitioned table \"%s\"",
- RelationGetRelationName(attachrel),
- RelationGetRelationName(rel)),
- errdetail("Table \"%s\" contains unique indexes.",
- RelationGetRelationName(rel))));
- index_close(idxRel, AccessShareLock);
- }
+ case RELKIND_FOREIGN_TABLE:
+ foreach(cell, idxes)
+ {
+ Oid idx = lfirst_oid(cell);
+ Relation idxRel = index_open(idx, AccessShareLock);
- goto out;
+ if (idxRel->rd_index->indisunique ||
+ idxRel->rd_index->indisprimary)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot attach foreign table \"%s\" as partition of partitioned table \"%s\"",
+ RelationGetRelationName(attachrel),
+ RelationGetRelationName(rel)),
+ errdetail("Table \"%s\" contains unique indexes.",
+ RelationGetRelationName(rel))));
+ index_close(idxRel, AccessShareLock);
+ }
+ goto out;
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
}
/*
@@ -16549,10 +17459,23 @@ AttachPartitionEnsureIndexes(Relation rel, Relation attachrel)
* Ignore indexes in the partitioned table other than partitioned
* indexes.
*/
- if (idxRel->rd_rel->relkind != RELKIND_PARTITIONED_INDEX)
+ switch ((RelKind) idxRel->rd_rel->relkind)
{
- index_close(idxRel, AccessShareLock);
- continue;
+ case RELKIND_PARTITIONED_INDEX:
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ index_close(idxRel, AccessShareLock);
+ continue;
}
/* construct an indexinfo to compare existing indexes against */
@@ -17089,11 +18012,27 @@ RangeVarCallbackForAttachIndex(const RangeVar *rv, Oid relOid, Oid oldRelOid,
if (!HeapTupleIsValid(tuple))
return; /* concurrently dropped, so nothing to do */
classform = (Form_pg_class) GETSTRUCT(tuple);
- if (classform->relkind != RELKIND_PARTITIONED_INDEX &&
- classform->relkind != RELKIND_INDEX)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("\"%s\" is not an index", rv->relname)));
+
+ switch ((RelKind) classform->relkind)
+ {
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("\"%s\" is not an index", rv->relname)));
+ break;
+ }
ReleaseSysCache(tuple);
/*
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 672fccff5b..3920760e5a 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -194,106 +194,122 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
* Triggers must be on tables or views, and there are additional
* relation-type-specific restrictions.
*/
- if (rel->rd_rel->relkind == RELKIND_RELATION)
+ switch ((RelKind) rel->rd_rel->relkind)
{
- /* Tables can't have INSTEAD OF triggers */
- if (stmt->timing != TRIGGER_TYPE_BEFORE &&
- stmt->timing != TRIGGER_TYPE_AFTER)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is a table",
- RelationGetRelationName(rel)),
- errdetail("Tables cannot have INSTEAD OF triggers.")));
- }
- else if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- {
- /* Partitioned tables can't have INSTEAD OF triggers */
- if (stmt->timing != TRIGGER_TYPE_BEFORE &&
- stmt->timing != TRIGGER_TYPE_AFTER)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is a table",
- RelationGetRelationName(rel)),
- errdetail("Tables cannot have INSTEAD OF triggers.")));
+ case RELKIND_RELATION:
+ {
+ /* Tables can't have INSTEAD OF triggers */
+ if (stmt->timing != TRIGGER_TYPE_BEFORE &&
+ stmt->timing != TRIGGER_TYPE_AFTER)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is a table",
+ RelationGetRelationName(rel)),
+ errdetail("Tables cannot have INSTEAD OF triggers.")));
+ }
+ break;
+ case RELKIND_PARTITIONED_TABLE:
+ {
+ /* Partitioned tables can't have INSTEAD OF triggers */
+ if (stmt->timing != TRIGGER_TYPE_BEFORE &&
+ stmt->timing != TRIGGER_TYPE_AFTER)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is a table",
+ RelationGetRelationName(rel)),
+ errdetail("Tables cannot have INSTEAD OF triggers.")));
- /*
- * FOR EACH ROW triggers have further restrictions
- */
- if (stmt->row)
- {
- /*
- * Disallow use of transition tables.
- *
- * Note that we have another restriction about transition tables
- * in partitions; search for 'has_superclass' below for an
- * explanation. The check here is just to protect from the fact
- * that if we allowed it here, the creation would succeed for a
- * partitioned table with no partitions, but would be blocked by
- * the other restriction when the first partition was created,
- * which is very unfriendly behavior.
- */
- if (stmt->transitionRels != NIL)
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("\"%s\" is a partitioned table",
- RelationGetRelationName(rel)),
- errdetail("Triggers on partitioned tables cannot have transition tables.")));
- }
- }
- else if (rel->rd_rel->relkind == RELKIND_VIEW)
- {
- /*
- * Views can have INSTEAD OF triggers (which we check below are
- * row-level), or statement-level BEFORE/AFTER triggers.
- */
- if (stmt->timing != TRIGGER_TYPE_INSTEAD && stmt->row)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is a view",
- RelationGetRelationName(rel)),
- errdetail("Views cannot have row-level BEFORE or AFTER triggers.")));
- /* Disallow TRUNCATE triggers on VIEWs */
- if (TRIGGER_FOR_TRUNCATE(stmt->events))
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is a view",
- RelationGetRelationName(rel)),
- errdetail("Views cannot have TRUNCATE triggers.")));
- }
- else if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
- {
- if (stmt->timing != TRIGGER_TYPE_BEFORE &&
- stmt->timing != TRIGGER_TYPE_AFTER)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is a foreign table",
- RelationGetRelationName(rel)),
- errdetail("Foreign tables cannot have INSTEAD OF triggers.")));
+ /*
+ * FOR EACH ROW triggers have further restrictions
+ */
+ if (stmt->row)
+ {
+ /*
+ * Disallow use of transition tables.
+ *
+ * Note that we have another restriction about transition
+ * tables in partitions; search for 'has_superclass' below
+ * for an explanation. The check here is just to protect
+ * from the fact that if we allowed it here, the creation
+ * would succeed for a partitioned table with no
+ * partitions, but would be blocked by the other
+ * restriction when the first partition was created, which
+ * is very unfriendly behavior.
+ */
+ if (stmt->transitionRels != NIL)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("\"%s\" is a partitioned table",
+ RelationGetRelationName(rel)),
+ errdetail("Triggers on partitioned tables cannot have transition tables.")));
+ }
+ }
+ break;
+ case RELKIND_VIEW:
+ {
+ /*
+ * Views can have INSTEAD OF triggers (which we check below
+ * are row-level), or statement-level BEFORE/AFTER triggers.
+ */
+ if (stmt->timing != TRIGGER_TYPE_INSTEAD && stmt->row)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is a view",
+ RelationGetRelationName(rel)),
+ errdetail("Views cannot have row-level BEFORE or AFTER triggers.")));
+ /* Disallow TRUNCATE triggers on VIEWs */
+ if (TRIGGER_FOR_TRUNCATE(stmt->events))
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is a view",
+ RelationGetRelationName(rel)),
+ errdetail("Views cannot have TRUNCATE triggers.")));
+ }
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ {
+ if (stmt->timing != TRIGGER_TYPE_BEFORE &&
+ stmt->timing != TRIGGER_TYPE_AFTER)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is a foreign table",
+ RelationGetRelationName(rel)),
+ errdetail("Foreign tables cannot have INSTEAD OF triggers.")));
- if (TRIGGER_FOR_TRUNCATE(stmt->events))
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is a foreign table",
- RelationGetRelationName(rel)),
- errdetail("Foreign tables cannot have TRUNCATE triggers.")));
+ if (TRIGGER_FOR_TRUNCATE(stmt->events))
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is a foreign table",
+ RelationGetRelationName(rel)),
+ errdetail("Foreign tables cannot have TRUNCATE triggers.")));
- /*
- * We disallow constraint triggers to protect the assumption that
- * triggers on FKs can't be deferred. See notes with AfterTriggers
- * data structures, below.
- */
- if (stmt->isconstraint)
+ /*
+ * We disallow constraint triggers to protect the assumption
+ * that triggers on FKs can't be deferred. See notes with
+ * AfterTriggers data structures, below.
+ */
+ if (stmt->isconstraint)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is a foreign table",
+ RelationGetRelationName(rel)),
+ errdetail("Foreign tables cannot have constraint triggers.")));
+ }
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is a foreign table",
- RelationGetRelationName(rel)),
- errdetail("Foreign tables cannot have constraint triggers.")));
+ errmsg("\"%s\" is not a table or view",
+ RelationGetRelationName(rel))));
+ break;
}
- else
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table or view",
- RelationGetRelationName(rel))));
if (!allowSystemTableMods && IsSystemRelation(rel))
ereport(ERROR,
@@ -345,8 +361,26 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
*
* For that, we'd better hold lock on all of them ahead of time.
*/
- partition_recurse = !isInternal && stmt->row &&
- rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE;
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ partition_recurse = !isInternal && stmt->row;
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ partition_recurse = false;
+ break;
+ }
+
if (partition_recurse)
list_free(find_all_inheritors(RelationGetRelid(rel),
ShareRowExclusiveLock, NULL));
@@ -416,19 +450,34 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
* adjustments will be needed below.
*/
- if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is a foreign table",
- RelationGetRelationName(rel)),
- errdetail("Triggers on foreign tables cannot have transition tables.")));
-
- if (rel->rd_rel->relkind == RELKIND_VIEW)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is a view",
- RelationGetRelationName(rel)),
- errdetail("Triggers on views cannot have transition tables.")));
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_FOREIGN_TABLE:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is a foreign table",
+ RelationGetRelationName(rel)),
+ errdetail("Triggers on foreign tables cannot have transition tables.")));
+ break;
+ case RELKIND_VIEW:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is a view",
+ RelationGetRelationName(rel)),
+ errdetail("Triggers on views cannot have transition tables.")));
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
/*
* We currently don't allow row-level triggers with transition
@@ -1191,14 +1240,27 @@ RemoveTriggerById(Oid trigOid)
rel = table_open(relid, AccessExclusiveLock);
- if (rel->rd_rel->relkind != RELKIND_RELATION &&
- rel->rd_rel->relkind != RELKIND_VIEW &&
- rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
- rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table, view, or foreign table",
- RelationGetRelationName(rel))));
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_VIEW:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a table, view, or foreign table",
+ RelationGetRelationName(rel))));
+ break;
+ }
if (!allowSystemTableMods && IsSystemRelation(rel))
ereport(ERROR,
@@ -1298,13 +1360,27 @@ RangeVarCallbackForRenameTrigger(const RangeVar *rv, Oid relid, Oid oldrelid,
form = (Form_pg_class) GETSTRUCT(tuple);
/* only tables and views can have triggers */
- if (form->relkind != RELKIND_RELATION && form->relkind != RELKIND_VIEW &&
- form->relkind != RELKIND_FOREIGN_TABLE &&
- form->relkind != RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table, view, or foreign table",
- rv->relname)));
+ switch ((RelKind) form->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_VIEW:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a table, view, or foreign table",
+ rv->relname)));
+ break;
+ }
/* you must own the table to rename one of its triggers */
if (!pg_class_ownercheck(relid, GetUserId()))
@@ -1534,21 +1610,37 @@ EnableDisableTrigger(Relation rel, const char *tgname,
* When altering FOR EACH ROW triggers on a partitioned table, do
* the same on the partitions as well.
*/
- if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE &&
- (TRIGGER_FOR_ROW(oldtrig->tgtype)))
+ switch ((RelKind) rel->rd_rel->relkind)
{
- PartitionDesc partdesc = RelationGetPartitionDesc(rel);
- int i;
-
- for (i = 0; i < partdesc->nparts; i++)
- {
- Relation part;
-
- part = relation_open(partdesc->oids[i], lockmode);
- EnableDisableTrigger(part, NameStr(oldtrig->tgname),
- fires_when, skip_system, lockmode);
- table_close(part, NoLock); /* keep lock till commit */
- }
+ case RELKIND_PARTITIONED_TABLE:
+ if (TRIGGER_FOR_ROW(oldtrig->tgtype))
+ {
+ PartitionDesc partdesc = RelationGetPartitionDesc(rel);
+ int i;
+
+ for (i = 0; i < partdesc->nparts; i++)
+ {
+ Relation part;
+
+ part = relation_open(partdesc->oids[i], lockmode);
+ EnableDisableTrigger(part, NameStr(oldtrig->tgname),
+ fires_when, skip_system, lockmode);
+ table_close(part, NoLock); /* keep lock till commit */
+ }
+ }
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
}
changed = true;
@@ -4167,12 +4259,26 @@ afterTriggerInvokeEvents(AfterTriggerEventList *events,
ExecDropSingleTupleTableSlot(slot2);
slot1 = slot2 = NULL;
}
- if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
+ switch ((RelKind) rel->rd_rel->relkind)
{
- slot1 = MakeSingleTupleTableSlot(rel->rd_att,
- &TTSOpsMinimalTuple);
- slot2 = MakeSingleTupleTableSlot(rel->rd_att,
- &TTSOpsMinimalTuple);
+ case RELKIND_FOREIGN_TABLE:
+ slot1 = MakeSingleTupleTableSlot(rel->rd_att,
+ &TTSOpsMinimalTuple);
+ slot2 = MakeSingleTupleTableSlot(rel->rd_att,
+ &TTSOpsMinimalTuple);
+ break;
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
}
if (trigdesc == NULL) /* should not happen */
elog(ERROR, "relation %u has no triggers",
@@ -5566,9 +5672,27 @@ AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo,
break;
}
- if (!(relkind == RELKIND_FOREIGN_TABLE && row_trigger))
- new_event.ate_flags = (row_trigger && event == TRIGGER_EVENT_UPDATE) ?
- AFTER_TRIGGER_2CTID : AFTER_TRIGGER_1CTID;
+ switch ((RelKind) relkind)
+ {
+ case RELKIND_FOREIGN_TABLE:
+ if (row_trigger)
+ break;
+ /* fallthrough */
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ new_event.ate_flags = (row_trigger && event == TRIGGER_EVENT_UPDATE) ?
+ AFTER_TRIGGER_2CTID : AFTER_TRIGGER_1CTID;
+ break;
+ }
/* else, we'll initialize ate_flags for each trigger */
tgtype_level = (row_trigger ? TRIGGER_TYPE_ROW : TRIGGER_TYPE_STATEMENT);
@@ -5586,16 +5710,33 @@ AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo,
modifiedCols, oldslot, newslot))
continue;
- if (relkind == RELKIND_FOREIGN_TABLE && row_trigger)
+ switch ((RelKind) relkind)
{
- if (fdw_tuplestore == NULL)
- {
- fdw_tuplestore = GetCurrentFDWTuplestore();
- new_event.ate_flags = AFTER_TRIGGER_FDW_FETCH;
- }
- else
- /* subsequent event for the same tuple */
- new_event.ate_flags = AFTER_TRIGGER_FDW_REUSE;
+ case RELKIND_FOREIGN_TABLE:
+ if (row_trigger)
+ {
+ if (fdw_tuplestore == NULL)
+ {
+ fdw_tuplestore = GetCurrentFDWTuplestore();
+ new_event.ate_flags = AFTER_TRIGGER_FDW_FETCH;
+ }
+ else
+ /* subsequent event for the same tuple */
+ new_event.ate_flags = AFTER_TRIGGER_FDW_REUSE;
+ }
+ break;
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
}
/*
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 9e5938b10e..4771b8517f 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -2918,11 +2918,26 @@ get_rels_with_domain(Oid domainOid, LOCKMODE lockmode)
* a suitable expression index, this should also check expression
* index columns.
*/
- if (rel->rd_rel->relkind != RELKIND_RELATION &&
- rel->rd_rel->relkind != RELKIND_MATVIEW)
+ switch ((RelKind) rel->rd_rel->relkind)
{
- relation_close(rel, lockmode);
- continue;
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ {
+ relation_close(rel, lockmode);
+ continue;
+ }
+ break;
}
/* Build the RelToCheck entry with enough space for all atts */
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index d32de23e62..15c9bcb142 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -881,10 +881,23 @@ get_all_vacuum_rels(int options)
* to be performed, caller will decide whether to process or ignore
* them.
*/
- if (classForm->relkind != RELKIND_RELATION &&
- classForm->relkind != RELKIND_MATVIEW &&
- classForm->relkind != RELKIND_PARTITIONED_TABLE)
- continue;
+ switch ((RelKind) classForm->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ continue;
+ }
/*
* Build VacuumRelation(s) specifying the table OIDs to be processed.
@@ -1383,13 +1396,27 @@ vac_update_datfrozenxid(void)
* Only consider relations able to hold unfrozen XIDs (anything else
* should have InvalidTransactionId in relfrozenxid anyway).
*/
- if (classForm->relkind != RELKIND_RELATION &&
- classForm->relkind != RELKIND_MATVIEW &&
- classForm->relkind != RELKIND_TOASTVALUE)
+ switch ((RelKind) classForm->relkind)
{
- Assert(!TransactionIdIsValid(classForm->relfrozenxid));
- Assert(!MultiXactIdIsValid(classForm->relminmxid));
- continue;
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ {
+ Assert(!TransactionIdIsValid(classForm->relfrozenxid));
+ Assert(!MultiXactIdIsValid(classForm->relminmxid));
+ continue;
+ }
+ break;
}
/*
@@ -1762,18 +1789,31 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params)
/*
* Check that it's of a vacuumable relkind.
*/
- if (onerel->rd_rel->relkind != RELKIND_RELATION &&
- onerel->rd_rel->relkind != RELKIND_MATVIEW &&
- onerel->rd_rel->relkind != RELKIND_TOASTVALUE &&
- onerel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
+ switch ((RelKind) onerel->rd_rel->relkind)
{
- ereport(WARNING,
- (errmsg("skipping \"%s\" --- cannot vacuum non-tables or special system tables",
- RelationGetRelationName(onerel))));
- relation_close(onerel, lmode);
- PopActiveSnapshot();
- CommitTransactionCommand();
- return false;
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ {
+ ereport(WARNING,
+ (errmsg("skipping \"%s\" --- cannot vacuum non-tables or special system tables",
+ RelationGetRelationName(onerel))));
+ relation_close(onerel, lmode);
+ PopActiveSnapshot();
+ CommitTransactionCommand();
+ return false;
+ }
+ break;
}
/*
@@ -1796,13 +1836,26 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params)
* useful work is on their child partitions, which have been queued up for
* us separately.
*/
- if (onerel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
+ switch ((RelKind) onerel->rd_rel->relkind)
{
- relation_close(onerel, lmode);
- PopActiveSnapshot();
- CommitTransactionCommand();
- /* It's OK to proceed with ANALYZE on this table */
- return true;
+ case RELKIND_PARTITIONED_TABLE:
+ relation_close(onerel, lmode);
+ PopActiveSnapshot();
+ CommitTransactionCommand();
+ /* It's OK to proceed with ANALYZE on this table */
+ return true;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
}
/*
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 4fdffad6f3..dc2f1908bb 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -1079,7 +1079,7 @@ CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation)
TriggerDesc *trigDesc = resultRel->trigdesc;
FdwRoutine *fdwroutine;
- switch (resultRel->rd_rel->relkind)
+ switch ((RelKind) resultRel->rd_rel->relkind)
{
case RELKIND_RELATION:
case RELKIND_PARTITIONED_TABLE:
@@ -1193,6 +1193,10 @@ CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation)
break;
}
break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_NULL:
default:
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
@@ -1213,7 +1217,7 @@ CheckValidRowMarkRel(Relation rel, RowMarkType markType)
{
FdwRoutine *fdwroutine;
- switch (rel->rd_rel->relkind)
+ switch ((RelKind) rel->rd_rel->relkind)
{
case RELKIND_RELATION:
case RELKIND_PARTITIONED_TABLE:
@@ -1257,6 +1261,10 @@ CheckValidRowMarkRel(Relation rel, RowMarkType markType)
errmsg("cannot lock rows in foreign table \"%s\"",
RelationGetRelationName(rel))));
break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_NULL:
default:
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
@@ -1308,10 +1316,26 @@ InitResultRelInfo(ResultRelInfo *resultRelInfo,
resultRelInfo->ri_TrigWhenExprs = NULL;
resultRelInfo->ri_TrigInstrument = NULL;
}
- if (resultRelationDesc->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
- resultRelInfo->ri_FdwRoutine = GetFdwRoutineForRelation(resultRelationDesc, true);
- else
- resultRelInfo->ri_FdwRoutine = NULL;
+
+ switch ((RelKind) resultRelationDesc->rd_rel->relkind)
+ {
+ case RELKIND_FOREIGN_TABLE:
+ resultRelInfo->ri_FdwRoutine = GetFdwRoutineForRelation(resultRelationDesc, true);
+ break;
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ resultRelInfo->ri_FdwRoutine = NULL;
+ break;
+ }
/* The following fields are set later if needed */
resultRelInfo->ri_FdwState = NULL;
@@ -2614,42 +2638,61 @@ EvalPlanQualFetchRowMark(EPQState *epqstate, Index rti, TupleTableSlot *slot)
return false;
/* fetch requests on foreign tables must be passed to their FDW */
- if (erm->relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
+ switch ((RelKind) erm->relation->rd_rel->relkind)
{
- FdwRoutine *fdwroutine;
- bool updated = false;
+ case RELKIND_FOREIGN_TABLE:
+ {
+ FdwRoutine *fdwroutine;
+ bool updated = false;
- fdwroutine = GetFdwRoutineForRelation(erm->relation, false);
- /* this should have been checked already, but let's be safe */
- if (fdwroutine->RefetchForeignRow == NULL)
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot lock rows in foreign table \"%s\"",
- RelationGetRelationName(erm->relation))));
+ fdwroutine = GetFdwRoutineForRelation(erm->relation, false);
- fdwroutine->RefetchForeignRow(epqstate->recheckestate,
- erm,
- datum,
- slot,
- &updated);
- if (TupIsNull(slot))
- elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck");
+ /*
+ * this should have been checked already, but let's be
+ * safe
+ */
+ if (fdwroutine->RefetchForeignRow == NULL)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot lock rows in foreign table \"%s\"",
+ RelationGetRelationName(erm->relation))));
- /*
- * Ideally we'd insist on updated == false here, but that assumes
- * that FDWs can track that exactly, which they might not be able
- * to. So just ignore the flag.
- */
- return true;
- }
- else
- {
- /* ordinary table, fetch the tuple */
- if (!table_tuple_fetch_row_version(erm->relation,
- (ItemPointer) DatumGetPointer(datum),
- SnapshotAny, slot))
- elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck");
- return true;
+ fdwroutine->RefetchForeignRow(epqstate->recheckestate,
+ erm,
+ datum,
+ slot,
+ &updated);
+ if (TupIsNull(slot))
+ elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck");
+
+ /*
+ * Ideally we'd insist on updated == false here, but that
+ * assumes that FDWs can track that exactly, which they
+ * might not be able to. So just ignore the flag.
+ */
+ return true;
+ }
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ {
+ /* ordinary table, fetch the tuple */
+ if (!table_tuple_fetch_row_version(erm->relation,
+ (ItemPointer) DatumGetPointer(datum),
+ SnapshotAny, slot))
+ elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck");
+ return true;
+ }
+ break;
}
}
else
diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c
index 8f474faed0..7a56b2d282 100644
--- a/src/backend/executor/execReplication.c
+++ b/src/backend/executor/execReplication.c
@@ -607,19 +607,34 @@ CheckSubscriptionRelkind(char relkind, const char *nspname,
/*
* Give a more specific error for foreign tables.
*/
- if (relkind == RELKIND_FOREIGN_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot use relation \"%s.%s\" as logical replication target",
- nspname, relname),
- errdetail("\"%s.%s\" is a foreign table.",
- nspname, relname)));
-
- if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot use relation \"%s.%s\" as logical replication target",
- nspname, relname),
- errdetail("\"%s.%s\" is not a table.",
- nspname, relname)));
+ switch ((RelKind) relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot use relation \"%s.%s\" as logical replication target",
+ nspname, relname),
+ errdetail("\"%s.%s\" is a foreign table.",
+ nspname, relname)));
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot use relation \"%s.%s\" as logical replication target",
+ nspname, relname),
+ errdetail("\"%s.%s\" is not a table.",
+ nspname, relname)));
+ break;
+ }
}
diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c
index 20a4c474cc..d22817c759 100644
--- a/src/backend/executor/nodeModifyTable.c
+++ b/src/backend/executor/nodeModifyTable.c
@@ -2177,56 +2177,77 @@ ExecModifyTable(PlanState *pstate)
bool isNull;
relkind = resultRelInfo->ri_RelationDesc->rd_rel->relkind;
- if (relkind == RELKIND_RELATION || relkind == RELKIND_MATVIEW)
+ switch ((RelKind) relkind)
{
- datum = ExecGetJunkAttribute(slot,
- junkfilter->jf_junkAttNo,
- &isNull);
- /* shouldn't ever get a null result... */
- if (isNull)
- elog(ERROR, "ctid is NULL");
-
- tupleid = (ItemPointer) DatumGetPointer(datum);
- tuple_ctid = *tupleid; /* be sure we don't free ctid!! */
- tupleid = &tuple_ctid;
- }
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ {
+ datum = ExecGetJunkAttribute(slot,
+ junkfilter->jf_junkAttNo,
+ &isNull);
+ /* shouldn't ever get a null result... */
+ if (isNull)
+ elog(ERROR, "ctid is NULL");
+
+ tupleid = (ItemPointer) DatumGetPointer(datum);
+ tuple_ctid = *tupleid; /* be sure we don't free
+ * ctid!! */
+ tupleid = &tuple_ctid;
+ }
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
- /*
- * Use the wholerow attribute, when available, to reconstruct
- * the old relation tuple.
- *
- * Foreign table updates have a wholerow attribute when the
- * relation has a row-level trigger. Note that the wholerow
- * attribute does not carry system columns. Foreign table
- * triggers miss seeing those, except that we know enough here
- * to set t_tableOid. Quite separately from this, the FDW may
- * fetch its own junk attrs to identify the row.
- *
- * Other relevant relkinds, currently limited to views, always
- * have a wholerow attribute.
- */
- else if (AttributeNumberIsValid(junkfilter->jf_junkAttNo))
- {
- datum = ExecGetJunkAttribute(slot,
- junkfilter->jf_junkAttNo,
- &isNull);
- /* shouldn't ever get a null result... */
- if (isNull)
- elog(ERROR, "wholerow is NULL");
-
- oldtupdata.t_data = DatumGetHeapTupleHeader(datum);
- oldtupdata.t_len =
- HeapTupleHeaderGetDatumLength(oldtupdata.t_data);
- ItemPointerSetInvalid(&(oldtupdata.t_self));
- /* Historically, view triggers see invalid t_tableOid. */
- oldtupdata.t_tableOid =
- (relkind == RELKIND_VIEW) ? InvalidOid :
- RelationGetRelid(resultRelInfo->ri_RelationDesc);
-
- oldtuple = &oldtupdata;
+ /*
+ * Use the wholerow attribute, when available, to
+ * reconstruct the old relation tuple.
+ *
+ * Foreign table updates have a wholerow attribute
+ * when the relation has a row-level trigger. Note
+ * that the wholerow attribute does not carry system
+ * columns. Foreign table triggers miss seeing those,
+ * except that we know enough here to set t_tableOid.
+ * Quite separately from this, the FDW may fetch its
+ * own junk attrs to identify the row.
+ *
+ * Other relevant relkinds, currently limited to
+ * views, always have a wholerow attribute.
+ */
+ if (AttributeNumberIsValid(junkfilter->jf_junkAttNo))
+ {
+ datum = ExecGetJunkAttribute(slot,
+ junkfilter->jf_junkAttNo,
+ &isNull);
+ /* shouldn't ever get a null result... */
+ if (isNull)
+ elog(ERROR, "wholerow is NULL");
+
+ oldtupdata.t_data = DatumGetHeapTupleHeader(datum);
+ oldtupdata.t_len =
+ HeapTupleHeaderGetDatumLength(oldtupdata.t_data);
+ ItemPointerSetInvalid(&(oldtupdata.t_self));
+
+ /*
+ * Historically, view triggers see invalid
+ * t_tableOid.
+ */
+ oldtupdata.t_tableOid =
+ (relkind == RELKIND_VIEW) ? InvalidOid :
+ RelationGetRelid(resultRelInfo->ri_RelationDesc);
+
+ oldtuple = &oldtupdata;
+ }
+ else
+ Assert(relkind == RELKIND_FOREIGN_TABLE);
}
- else
- Assert(relkind == RELKIND_FOREIGN_TABLE);
}
/*
@@ -2697,27 +2718,40 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
char relkind;
relkind = resultRelInfo->ri_RelationDesc->rd_rel->relkind;
- if (relkind == RELKIND_RELATION ||
- relkind == RELKIND_MATVIEW ||
- relkind == RELKIND_PARTITIONED_TABLE)
+ switch ((RelKind) relkind)
{
- j->jf_junkAttNo = ExecFindJunkAttribute(j, "ctid");
- if (!AttributeNumberIsValid(j->jf_junkAttNo))
- elog(ERROR, "could not find junk ctid column");
- }
- else if (relkind == RELKIND_FOREIGN_TABLE)
- {
- /*
- * When there is a row-level trigger, there should be
- * a wholerow attribute.
- */
- j->jf_junkAttNo = ExecFindJunkAttribute(j, "wholerow");
- }
- else
- {
- j->jf_junkAttNo = ExecFindJunkAttribute(j, "wholerow");
- if (!AttributeNumberIsValid(j->jf_junkAttNo))
- elog(ERROR, "could not find junk wholerow column");
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ {
+ j->jf_junkAttNo = ExecFindJunkAttribute(j, "ctid");
+ if (!AttributeNumberIsValid(j->jf_junkAttNo))
+ elog(ERROR, "could not find junk ctid column");
+ }
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ {
+ /*
+ * When there is a row-level trigger, there
+ * should be a wholerow attribute.
+ */
+ j->jf_junkAttNo = ExecFindJunkAttribute(j, "wholerow");
+ }
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ {
+ j->jf_junkAttNo = ExecFindJunkAttribute(j, "wholerow");
+ if (!AttributeNumberIsValid(j->jf_junkAttNo))
+ elog(ERROR, "could not find junk wholerow column");
+ }
+ break;
}
}
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index d984da25d7..6d2b587153 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -387,29 +387,42 @@ set_rel_size(PlannerInfo *root, RelOptInfo *rel,
switch (rel->rtekind)
{
case RTE_RELATION:
- if (rte->relkind == RELKIND_FOREIGN_TABLE)
+ switch ((RelKind) rte->relkind)
{
- /* Foreign table */
- set_foreign_size(root, rel, rte);
- }
- else if (rte->relkind == RELKIND_PARTITIONED_TABLE)
- {
- /*
- * We could get here if asked to scan a partitioned table
- * with ONLY. In that case we shouldn't scan any of the
- * partitions, so mark it as a dummy rel.
- */
- set_dummy_rel_pathlist(rel);
- }
- else if (rte->tablesample != NULL)
- {
- /* Sampled relation */
- set_tablesample_rel_size(root, rel, rte);
- }
- else
- {
- /* Plain relation */
- set_plain_rel_size(root, rel, rte);
+ case RELKIND_FOREIGN_TABLE:
+ /* Foreign table */
+ set_foreign_size(root, rel, rte);
+ break;
+ case RELKIND_PARTITIONED_TABLE:
+
+ /*
+ * We could get here if asked to scan a partitioned
+ * table with ONLY. In that case we shouldn't scan
+ * any of the partitions, so mark it as a dummy rel.
+ */
+ set_dummy_rel_pathlist(rel);
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ if (rte->tablesample != NULL)
+ {
+ /* Sampled relation */
+ set_tablesample_rel_size(root, rel, rte);
+ }
+ else
+ {
+ /* Plain relation */
+ set_plain_rel_size(root, rel, rte);
+ }
+ break;
}
break;
case RTE_SUBQUERY:
@@ -484,20 +497,34 @@ set_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
switch (rel->rtekind)
{
case RTE_RELATION:
- if (rte->relkind == RELKIND_FOREIGN_TABLE)
- {
- /* Foreign table */
- set_foreign_pathlist(root, rel, rte);
- }
- else if (rte->tablesample != NULL)
+ switch ((RelKind) rte->relkind)
{
- /* Sampled relation */
- set_tablesample_rel_pathlist(root, rel, rte);
- }
- else
- {
- /* Plain relation */
- set_plain_rel_pathlist(root, rel, rte);
+ case RELKIND_FOREIGN_TABLE:
+ /* Foreign table */
+ set_foreign_pathlist(root, rel, rte);
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ if (rte->tablesample != NULL)
+ {
+ /* Sampled relation */
+ set_tablesample_rel_pathlist(root, rel, rte);
+ }
+ else
+ {
+ /* Plain relation */
+ set_plain_rel_pathlist(root, rel, rte);
+ }
+ break;
}
break;
case RTE_SUBQUERY:
@@ -643,13 +670,27 @@ set_rel_consider_parallel(PlannerInfo *root, RelOptInfo *rel,
* up with a separate connection, and these connections might not
* be appropriately coordinated between workers and the leader.
*/
- if (rte->relkind == RELKIND_FOREIGN_TABLE)
+ switch ((RelKind) rte->relkind)
{
- Assert(rel->fdwroutine);
- if (!rel->fdwroutine->IsForeignScanParallelSafe)
- return;
- if (!rel->fdwroutine->IsForeignScanParallelSafe(root, rel, rte))
- return;
+ case RELKIND_FOREIGN_TABLE:
+ Assert(rel->fdwroutine);
+ if (!rel->fdwroutine->IsForeignScanParallelSafe)
+ return;
+ if (!rel->fdwroutine->IsForeignScanParallelSafe(root, rel, rte))
+ return;
+ break;
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
}
/*
@@ -960,19 +1001,52 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
* that when we've created Paths for all the children, the root
* partitioned table's list will contain all such indexes.
*/
- if (rte->relkind == RELKIND_PARTITIONED_TABLE)
- rel->partitioned_child_rels = list_make1_int(rti);
+ switch ((RelKind) rte->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ rel->partitioned_child_rels = list_make1_int(rti);
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
/*
* If this is a partitioned baserel, set the consider_partitionwise_join
* flag; currently, we only consider partitionwise joins with the baserel
* if its targetlist doesn't contain a whole-row Var.
*/
- if (enable_partitionwise_join &&
- rel->reloptkind == RELOPT_BASEREL &&
- rte->relkind == RELKIND_PARTITIONED_TABLE &&
- rel->attr_needed[InvalidAttrNumber - rel->min_attr] == NULL)
- rel->consider_partitionwise_join = true;
+ switch ((RelKind) rte->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ if (enable_partitionwise_join &&
+ rel->reloptkind == RELOPT_BASEREL &&
+ rte->relkind == RELKIND_PARTITIONED_TABLE &&
+ rel->attr_needed[InvalidAttrNumber - rel->min_attr] == NULL)
+ rel->consider_partitionwise_join = true;
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
/*
* Initialize to compute size estimates for whole append relation.
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 4131019fc9..de8c1073fa 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -1280,10 +1280,24 @@ inheritance_planner(PlannerInfo *root)
*/
parent_rte = rt_fetch(top_parentRTindex, parse->rtable);
Assert(parent_rte->inh);
- if (parent_rte->relkind == RELKIND_PARTITIONED_TABLE)
+ switch ((RelKind) parent_rte->relkind)
{
- nominalRelation = top_parentRTindex;
- rootRelation = top_parentRTindex;
+ case RELKIND_PARTITIONED_TABLE:
+ nominalRelation = top_parentRTindex;
+ rootRelation = top_parentRTindex;
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
/*
@@ -2338,11 +2352,25 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
* If target is a partition root table, we need to mark the
* ModifyTable node appropriately for that.
*/
- if (rt_fetch(parse->resultRelation, parse->rtable)->relkind ==
- RELKIND_PARTITIONED_TABLE)
- rootRelation = parse->resultRelation;
- else
- rootRelation = 0;
+ switch ((RelKind) rt_fetch(parse->resultRelation, parse->rtable)->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ rootRelation = parse->resultRelation;
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ rootRelation = 0;
+ break;
+ }
/*
* Set up the WITH CHECK OPTION and RETURNING lists-of-lists, if
@@ -2765,45 +2793,58 @@ select_rowmark_type(RangeTblEntry *rte, LockClauseStrength strength)
/* If it's not a table at all, use ROW_MARK_COPY */
return ROW_MARK_COPY;
}
- else if (rte->relkind == RELKIND_FOREIGN_TABLE)
- {
- /* Let the FDW select the rowmark type, if it wants to */
- FdwRoutine *fdwroutine = GetFdwRoutineByRelId(rte->relid);
-
- if (fdwroutine->GetForeignRowMarkType != NULL)
- return fdwroutine->GetForeignRowMarkType(rte, strength);
- /* Otherwise, use ROW_MARK_COPY by default */
- return ROW_MARK_COPY;
- }
else
- {
- /* Regular table, apply the appropriate lock type */
- switch (strength)
+ switch ((RelKind) rte->relkind)
{
- case LCS_NONE:
+ case RELKIND_FOREIGN_TABLE:
+ {
+ /* Let the FDW select the rowmark type, if it wants to */
+ FdwRoutine *fdwroutine = GetFdwRoutineByRelId(rte->relid);
- /*
- * We don't need a tuple lock, only the ability to re-fetch
- * the row.
- */
- return ROW_MARK_REFERENCE;
- break;
- case LCS_FORKEYSHARE:
- return ROW_MARK_KEYSHARE;
- break;
- case LCS_FORSHARE:
- return ROW_MARK_SHARE;
- break;
- case LCS_FORNOKEYUPDATE:
- return ROW_MARK_NOKEYEXCLUSIVE;
- break;
- case LCS_FORUPDATE:
- return ROW_MARK_EXCLUSIVE;
+ if (fdwroutine->GetForeignRowMarkType != NULL)
+ return fdwroutine->GetForeignRowMarkType(rte, strength);
+ /* Otherwise, use ROW_MARK_COPY by default */
+ return ROW_MARK_COPY;
+ }
break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ /* Regular table, apply the appropriate lock type */
+ switch (strength)
+ {
+ case LCS_NONE:
+
+ /*
+ * We don't need a tuple lock, only the ability to
+ * re-fetch the row.
+ */
+ return ROW_MARK_REFERENCE;
+ break;
+ case LCS_FORKEYSHARE:
+ return ROW_MARK_KEYSHARE;
+ break;
+ case LCS_FORSHARE:
+ return ROW_MARK_SHARE;
+ break;
+ case LCS_FORNOKEYUPDATE:
+ return ROW_MARK_NOKEYEXCLUSIVE;
+ break;
+ case LCS_FORUPDATE:
+ return ROW_MARK_EXCLUSIVE;
+ break;
+ }
+ elog(ERROR, "unrecognized LockClauseStrength %d", (int) strength);
+ return ROW_MARK_EXCLUSIVE; /* keep compiler quiet */
}
- elog(ERROR, "unrecognized LockClauseStrength %d", (int) strength);
- return ROW_MARK_EXCLUSIVE; /* keep compiler quiet */
- }
}
/*
@@ -3142,8 +3183,25 @@ remove_useless_groupby_columns(PlannerInfo *root)
* may cause duplicate rows. This cannot happen with partitioned
* tables, however.
*/
- if (rte->inh && rte->relkind != RELKIND_PARTITIONED_TABLE)
- continue;
+ switch ((RelKind) rte->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ if (rte->inh)
+ continue;
+ break;
+ }
/* Nothing to do unless this rel has multiple Vars in GROUP BY */
relattnos = groupbyattnos[relid];
diff --git a/src/backend/optimizer/util/inherit.c b/src/backend/optimizer/util/inherit.c
index 3132fd35a5..1199b21154 100644
--- a/src/backend/optimizer/util/inherit.c
+++ b/src/backend/optimizer/util/inherit.c
@@ -129,88 +129,113 @@ expand_inherited_rtentry(PlannerInfo *root, RelOptInfo *rel,
}
/* Scan the inheritance set and expand it */
- if (oldrelation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
+ switch ((RelKind) oldrelation->rd_rel->relkind)
{
- /*
- * Partitioned table, so set up for partitioning.
- */
- Assert(rte->relkind == RELKIND_PARTITIONED_TABLE);
-
- /*
- * Recursively expand and lock the partitions. While at it, also
- * extract the partition key columns of all the partitioned tables.
- */
- expand_partitioned_rtentry(root, rel, rte, rti,
- oldrelation, oldrc, lockmode);
- }
- else
- {
- /*
- * Ordinary table, so process traditional-inheritance children. (Note
- * that partitioned tables are not allowed to have inheritance
- * children, so it's not possible for both cases to apply.)
- */
- List *inhOIDs;
- ListCell *l;
-
- /* Scan for all members of inheritance set, acquire needed locks */
- inhOIDs = find_all_inheritors(parentOID, lockmode, NULL);
-
- /*
- * We used to special-case the situation where the table no longer has
- * any children, by clearing rte->inh and exiting. That no longer
- * works, because this function doesn't get run until after decisions
- * have been made that depend on rte->inh. We have to treat such
- * situations as normal inheritance. The table itself should always
- * have been found, though.
- */
- Assert(inhOIDs != NIL);
- Assert(linitial_oid(inhOIDs) == parentOID);
-
- /* Expand simple_rel_array and friends to hold child objects. */
- expand_planner_arrays(root, list_length(inhOIDs));
-
- /*
- * Expand inheritance children in the order the OIDs were returned by
- * find_all_inheritors.
- */
- foreach(l, inhOIDs)
- {
- Oid childOID = lfirst_oid(l);
- Relation newrelation;
- RangeTblEntry *childrte;
- Index childRTindex;
-
- /* Open rel if needed; we already have required locks */
- if (childOID != parentOID)
- newrelation = table_open(childOID, NoLock);
- else
- newrelation = oldrelation;
-
- /*
- * It is possible that the parent table has children that are temp
- * tables of other backends. We cannot safely access such tables
- * (because of buffering issues), and the best thing to do seems
- * to be to silently ignore them.
- */
- if (childOID != parentOID && RELATION_IS_OTHER_TEMP(newrelation))
+ case RELKIND_PARTITIONED_TABLE:
{
- table_close(newrelation, lockmode);
- continue;
+ /*
+ * Partitioned table, so set up for partitioning.
+ */
+ Assert(rte->relkind == RELKIND_PARTITIONED_TABLE);
+
+ /*
+ * Recursively expand and lock the partitions. While at it,
+ * also extract the partition key columns of all the
+ * partitioned tables.
+ */
+ expand_partitioned_rtentry(root, rel, rte, rti,
+ oldrelation, oldrc, lockmode);
}
-
- /* Create RTE and AppendRelInfo, plus PlanRowMark if needed. */
- expand_single_inheritance_child(root, rte, rti, oldrelation,
- oldrc, newrelation,
- &childrte, &childRTindex);
-
- /* Create the otherrel RelOptInfo too. */
- (void) build_simple_rel(root, childRTindex, rel);
-
- /* Close child relations, but keep locks */
- if (childOID != parentOID)
- table_close(newrelation, NoLock);
- }
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ {
+ /*
+ * Ordinary table, so process traditional-inheritance
+ * children. (Note that partitioned tables are not allowed to
+ * have inheritance children, so it's not possible for both
+ * cases to apply.)
+ */
+ List *inhOIDs;
+ ListCell *l;
+
+ /*
+ * Scan for all members of inheritance set, acquire needed
+ * locks
+ */
+ inhOIDs = find_all_inheritors(parentOID, lockmode, NULL);
+
+ /*
+ * We used to special-case the situation where the table no
+ * longer has any children, by clearing rte->inh and exiting.
+ * That no longer works, because this function doesn't get run
+ * until after decisions have been made that depend on
+ * rte->inh. We have to treat such situations as normal
+ * inheritance. The table itself should always have been
+ * found, though.
+ */
+ Assert(inhOIDs != NIL);
+ Assert(linitial_oid(inhOIDs) == parentOID);
+
+ /* Expand simple_rel_array and friends to hold child objects. */
+ expand_planner_arrays(root, list_length(inhOIDs));
+
+ /*
+ * Expand inheritance children in the order the OIDs were
+ * returned by find_all_inheritors.
+ */
+ foreach(l, inhOIDs)
+ {
+ Oid childOID = lfirst_oid(l);
+ Relation newrelation;
+ RangeTblEntry *childrte;
+ Index childRTindex;
+
+ /* Open rel if needed; we already have required locks */
+ if (childOID != parentOID)
+ newrelation = table_open(childOID, NoLock);
+ else
+ newrelation = oldrelation;
+
+ /*
+ * It is possible that the parent table has children that
+ * are temp tables of other backends. We cannot safely
+ * access such tables (because of buffering issues), and
+ * the best thing to do seems to be to silently ignore
+ * them.
+ */
+ if (childOID != parentOID && RELATION_IS_OTHER_TEMP(newrelation))
+ {
+ table_close(newrelation, lockmode);
+ continue;
+ }
+
+ /*
+ * Create RTE and AppendRelInfo, plus PlanRowMark if
+ * needed.
+ */
+ expand_single_inheritance_child(root, rte, rti, oldrelation,
+ oldrc, newrelation,
+ &childrte, &childRTindex);
+
+ /* Create the otherrel RelOptInfo too. */
+ (void) build_simple_rel(root, childRTindex, rel);
+
+ /* Close child relations, but keep locks */
+ if (childOID != parentOID)
+ table_close(newrelation, NoLock);
+ }
+ }
+ break;
}
/*
@@ -380,10 +405,26 @@ expand_partitioned_rtentry(PlannerInfo *root, RelOptInfo *relinfo,
childrelinfo->relids);
/* If this child is itself partitioned, recurse */
- if (childrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- expand_partitioned_rtentry(root, childrelinfo,
- childrte, childRTindex,
- childrel, top_parentrc, lockmode);
+ switch ((RelKind) childrel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ expand_partitioned_rtentry(root, childrelinfo,
+ childrte, childRTindex,
+ childrel, top_parentrc, lockmode);
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
/* Close child relation, but keep locks */
table_close(childrel, NoLock);
@@ -448,13 +489,26 @@ expand_single_inheritance_child(PlannerInfo *root, RangeTblEntry *parentrte,
childrte->relid = childOID;
childrte->relkind = childrel->rd_rel->relkind;
/* A partitioned child will need to be expanded further. */
- if (childrte->relkind == RELKIND_PARTITIONED_TABLE)
+ switch ((RelKind) childrte->relkind)
{
- Assert(childOID != parentOID);
- childrte->inh = true;
+ case RELKIND_PARTITIONED_TABLE:
+ Assert(childOID != parentOID);
+ childrte->inh = true;
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ childrte->inh = false;
+ break;
}
- else
- childrte->inh = false;
childrte->requiredPerms = 0;
childrte->securityQuals = NIL;
@@ -578,7 +632,25 @@ expand_single_inheritance_child(PlannerInfo *root, RangeTblEntry *parentrte,
* that the executor ignores them (except their existence means that
* the child tables will be locked using the appropriate mode).
*/
- childrc->isParent = (childrte->relkind == RELKIND_PARTITIONED_TABLE);
+ switch ((RelKind) childrte->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ childrc->isParent = true;
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ childrc->isParent = false;
+ break;
+ }
/* Include child's rowmark type in top parent's allMarkTypes */
top_parentrc->allMarkTypes |= childrc->allMarkTypes;
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index 25545029d7..13232d797a 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -215,10 +215,23 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
* Ignore partitioned indexes, since they are not usable for
* queries.
*/
- if (indexRelation->rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
+ switch ((RelKind) indexRelation->rd_rel->relkind)
{
- index_close(indexRelation, NoLock);
- continue;
+ case RELKIND_PARTITIONED_INDEX:
+ index_close(indexRelation, NoLock);
+ continue;
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
/*
@@ -442,15 +455,26 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
rel->statlist = get_relation_statistics(rel, relation);
/* Grab foreign-table info using the relcache, while we have it */
- if (relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
+ switch ((RelKind) relation->rd_rel->relkind)
{
- rel->serverid = GetForeignServerIdByRelId(RelationGetRelid(relation));
- rel->fdwroutine = GetFdwRoutineForRelation(relation, true);
- }
- else
- {
- rel->serverid = InvalidOid;
- rel->fdwroutine = NULL;
+ case RELKIND_FOREIGN_TABLE:
+ rel->serverid = GetForeignServerIdByRelId(RelationGetRelid(relation));
+ rel->fdwroutine = GetFdwRoutineForRelation(relation, true);
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ rel->serverid = InvalidOid;
+ rel->fdwroutine = NULL;
+ break;
}
/* Collect info about relation's foreign keys, if relevant */
@@ -460,8 +484,25 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
* Collect info about relation's partitioning scheme, if any. Only
* inheritance parents may be partitioned.
*/
- if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- set_relation_partition_info(root, rel, relation);
+ switch ((RelKind) relation->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ if (inhparent)
+ set_relation_partition_info(root, rel, relation);
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
table_close(relation, NoLock);
@@ -955,7 +996,7 @@ estimate_rel_size(Relation rel, int32 *attr_widths,
BlockNumber relallvisible;
double density;
- switch (rel->rd_rel->relkind)
+ switch ((RelKind) rel->rd_rel->relkind)
{
case RELKIND_RELATION:
case RELKIND_MATVIEW:
@@ -1063,6 +1104,11 @@ estimate_rel_size(Relation rel, int32 *attr_widths,
*tuples = rel->rd_rel->reltuples;
*allvisfrac = 0;
break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
default:
/* else it has no disk storage; probably shouldn't get here? */
*pages = 0;
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index 25abc544fc..011f9829a9 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -944,37 +944,59 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
relation = relation_openrv(table_like_clause->relation, AccessShareLock);
- if (relation->rd_rel->relkind != RELKIND_RELATION &&
- relation->rd_rel->relkind != RELKIND_VIEW &&
- relation->rd_rel->relkind != RELKIND_MATVIEW &&
- relation->rd_rel->relkind != RELKIND_COMPOSITE_TYPE &&
- relation->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
- relation->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table, view, materialized view, composite type, or foreign table",
- RelationGetRelationName(relation))));
+ switch ((RelKind) relation->rd_rel->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_VIEW:
+ case RELKIND_MATVIEW:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_INDEX:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a table, view, materialized view, composite type, or foreign table",
+ RelationGetRelationName(relation))));
+ break;
+ }
cancel_parser_errposition_callback(&pcbstate);
/*
* Check for privileges
*/
- if (relation->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
- {
- aclresult = pg_type_aclcheck(relation->rd_rel->reltype, GetUserId(),
- ACL_USAGE);
- if (aclresult != ACLCHECK_OK)
- aclcheck_error(aclresult, OBJECT_TYPE,
- RelationGetRelationName(relation));
- }
- else
+ switch ((RelKind) relation->rd_rel->relkind)
{
- aclresult = pg_class_aclcheck(RelationGetRelid(relation), GetUserId(),
- ACL_SELECT);
- if (aclresult != ACLCHECK_OK)
- aclcheck_error(aclresult, get_relkind_objtype(relation->rd_rel->relkind),
- RelationGetRelationName(relation));
+ case RELKIND_COMPOSITE_TYPE:
+ aclresult = pg_type_aclcheck(relation->rd_rel->reltype, GetUserId(),
+ ACL_USAGE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, OBJECT_TYPE,
+ RelationGetRelationName(relation));
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ aclresult = pg_class_aclcheck(RelationGetRelid(relation), GetUserId(),
+ ACL_SELECT);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, get_relkind_objtype(relation->rd_rel->relkind),
+ RelationGetRelationName(relation));
+ break;
}
tupleDesc = RelationGetDescr(relation);
@@ -2306,13 +2328,27 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
rel = table_openrv(inh, AccessShareLock);
/* check user requested inheritance from valid relkind */
- if (rel->rd_rel->relkind != RELKIND_RELATION &&
- rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
- rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("inherited relation \"%s\" is not a table or foreign table",
- inh->relname)));
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("inherited relation \"%s\" is not a table or foreign table",
+ inh->relname)));
+ break;
+ }
for (count = 0; count < rel->rd_att->natts; count++)
{
Form_pg_attribute inhattr = TupleDescAttr(rel->rd_att,
@@ -2448,13 +2484,27 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
rel = table_openrv(inh, AccessShareLock);
/* check user requested inheritance from valid relkind */
- if (rel->rd_rel->relkind != RELKIND_RELATION &&
- rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
- rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("inherited relation \"%s\" is not a table or foreign table",
- inh->relname)));
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("inherited relation \"%s\" is not a table or foreign table",
+ inh->relname)));
+ break;
+ }
for (count = 0; count < rel->rd_att->natts; count++)
{
Form_pg_attribute inhattr = TupleDescAttr(rel->rd_att,
@@ -2763,10 +2813,27 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString,
*/
rel = table_openrv(stmt->relation, AccessExclusiveLock);
- if (rel->rd_rel->relkind == RELKIND_MATVIEW)
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("rules on materialized views are not supported")));
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_MATVIEW:
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("rules on materialized views are not supported")));
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
+
/* Set up pstate */
pstate = make_parsestate(NULL);
@@ -3097,15 +3164,26 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt,
/* Set up CreateStmtContext */
cxt.pstate = pstate;
- if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
+ switch ((RelKind) rel->rd_rel->relkind)
{
- cxt.stmtType = "ALTER FOREIGN TABLE";
- cxt.isforeign = true;
- }
- else
- {
- cxt.stmtType = "ALTER TABLE";
- cxt.isforeign = false;
+ case RELKIND_FOREIGN_TABLE:
+ cxt.stmtType = "ALTER FOREIGN TABLE";
+ cxt.isforeign = true;
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ cxt.stmtType = "ALTER TABLE";
+ cxt.isforeign = false;
+ break;
}
cxt.relation = stmt->relation;
cxt.rel = rel;
@@ -3722,7 +3800,7 @@ transformPartitionCmd(CreateStmtContext *cxt, PartitionCmd *cmd)
{
Relation parentRel = cxt->rel;
- switch (parentRel->rd_rel->relkind)
+ switch ((RelKind) parentRel->rd_rel->relkind)
{
case RELKIND_PARTITIONED_TABLE:
/* transform the partition bound, if any */
@@ -3757,6 +3835,13 @@ transformPartitionCmd(CreateStmtContext *cxt, PartitionCmd *cmd)
errmsg("index \"%s\" is not partitioned",
RelationGetRelationName(parentRel))));
break;
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
default:
/* parser shouldn't let this case through */
elog(ERROR, "\"%s\" is not a partitioned table or index",
diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c
index 7553d55987..c872ab1825 100644
--- a/src/backend/partitioning/partbounds.c
+++ b/src/backend/partitioning/partbounds.c
@@ -3137,11 +3137,26 @@ check_default_partition_contents(Relation parent, Relation default_rel,
* Scan the default partition and its subpartitions, and check for rows
* that do not satisfy the revised partition constraints.
*/
- if (default_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- all_parts = find_all_inheritors(RelationGetRelid(default_rel),
- AccessExclusiveLock, NULL);
- else
- all_parts = list_make1_oid(RelationGetRelid(default_rel));
+ switch ((RelKind) default_rel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ all_parts = find_all_inheritors(RelationGetRelid(default_rel),
+ AccessExclusiveLock, NULL);
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ all_parts = list_make1_oid(RelationGetRelid(default_rel));
+ break;
+ }
foreach(lc, all_parts)
{
@@ -3196,19 +3211,30 @@ check_default_partition_contents(Relation parent, Relation default_rel,
* Only RELKIND_RELATION relations (i.e. leaf partitions) need to be
* scanned.
*/
- if (part_rel->rd_rel->relkind != RELKIND_RELATION)
+ switch ((RelKind) part_rel->rd_rel->relkind)
{
- if (part_rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
+ case RELKIND_RELATION:
+ break;
+ case RELKIND_FOREIGN_TABLE:
ereport(WARNING,
(errcode(ERRCODE_CHECK_VIOLATION),
errmsg("skipped scanning foreign table \"%s\" which is a partition of default partition \"%s\"",
RelationGetRelationName(part_rel),
RelationGetRelationName(default_rel))));
-
- if (RelationGetRelid(default_rel) != RelationGetRelid(part_rel))
- table_close(part_rel, NoLock);
-
- continue;
+ /* fallthrough */
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ if (RelationGetRelid(default_rel) != RelationGetRelid(part_rel))
+ table_close(part_rel, NoLock);
+ continue;
}
estate = CreateExecutorState();
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index 9c7d4b0c60..9b43c68ed6 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2058,9 +2058,23 @@ do_autovacuum(void)
bool doanalyze;
bool wraparound;
- if (classForm->relkind != RELKIND_RELATION &&
- classForm->relkind != RELKIND_MATVIEW)
- continue;
+ switch ((RelKind) classForm->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ continue;
+ }
relid = classForm->oid;
@@ -2720,9 +2734,24 @@ extract_autovac_opts(HeapTuple tup, TupleDesc pg_class_desc)
bytea *relopts;
AutoVacOpts *av;
- Assert(((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_RELATION ||
- ((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_MATVIEW ||
- ((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_TOASTVALUE);
+ switch ((RelKind) ((Form_pg_class) GETSTRUCT(tup))->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ Assert(false);
+ break;
+ }
relopts = extractRelOptions(tup, pg_class_desc, NULL);
if (relopts == NULL)
@@ -2800,17 +2829,34 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
* main table reloptions if the toast table itself doesn't have.
*/
avopts = extract_autovac_opts(classTup, pg_class_desc);
- if (classForm->relkind == RELKIND_TOASTVALUE &&
- avopts == NULL && table_toast_map != NULL)
+ switch ((RelKind) classForm->relkind)
{
- av_relation *hentry;
- bool found;
+ case RELKIND_TOASTVALUE:
+ if (avopts == NULL && table_toast_map != NULL)
+ {
+ av_relation *hentry;
+ bool found;
- hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found);
- if (found && hentry->ar_hasrelopts)
- avopts = &hentry->ar_reloptions;
+ hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found);
+ if (found && hentry->ar_hasrelopts)
+ avopts = &hentry->ar_reloptions;
+ }
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
+
/* fetch the pgstat table entry */
tabentry = get_pgstat_tabentry_relid(relid, classForm->relisshared,
shared, dbentry);
@@ -2820,8 +2866,24 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
&dovacuum, &doanalyze, &wraparound);
/* ignore ANALYZE for toast tables */
- if (classForm->relkind == RELKIND_TOASTVALUE)
- doanalyze = false;
+ switch ((RelKind) classForm->relkind)
+ {
+ case RELKIND_TOASTVALUE:
+ doanalyze = false;
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
/* OK, it needs something done */
if (doanalyze || dovacuum)
diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c
index 096b0fcef0..fc9321c1ae 100644
--- a/src/backend/replication/basebackup.c
+++ b/src/backend/replication/basebackup.c
@@ -414,7 +414,7 @@ perform_base_backup(basebackup_options *opt)
if (ti->path == NULL)
{
struct stat statbuf;
- bool sendtblspclinks = true;
+ bool sendtblspclinks = true;
/* In the main tar, include the backup_label first... */
sendFileWithContent(BACKUP_LABEL_FILE, labelfile->data,
@@ -1777,8 +1777,8 @@ sendFile(const char *readfilename, const char *tarfilename,
}
/*
- * Pad to a block boundary, per tar format requirements. (This small
- * piece of data is probably not worth throttling, and is not checksummed
+ * Pad to a block boundary, per tar format requirements. (This small piece
+ * of data is probably not worth throttling, and is not checksummed
* because it's not actually part of the file.)
*/
pad = tarPaddingBytesRequired(len);
diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c
index 642a1c767f..08310078c5 100644
--- a/src/backend/replication/logical/reorderbuffer.c
+++ b/src/backend/replication/logical/reorderbuffer.c
@@ -1643,8 +1643,23 @@ ReorderBufferCommit(ReorderBuffer *rb, TransactionId xid,
* understand, so it doesn't make sense to handle the few
* cases we do.
*/
- if (relation->rd_rel->relkind == RELKIND_SEQUENCE)
- goto change_done;
+ switch ((RelKind) relation->rd_rel->relkind)
+ {
+ case RELKIND_SEQUENCE:
+ goto change_done;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
/* user-triggered change */
if (!IsToastRelation(relation))
diff --git a/src/backend/replication/logical/tablesync.c b/src/backend/replication/logical/tablesync.c
index c27d970589..f0419386d9 100644
--- a/src/backend/replication/logical/tablesync.c
+++ b/src/backend/replication/logical/tablesync.c
@@ -765,24 +765,38 @@ copy_table(Relation rel)
/* Start copy on the publisher. */
initStringInfo(&cmd);
- if (lrel.relkind == RELKIND_RELATION)
- appendStringInfo(&cmd, "COPY %s TO STDOUT",
- quote_qualified_identifier(lrel.nspname, lrel.relname));
- else
+ switch ((RelKind) lrel.relkind)
{
- /*
- * For non-tables, we need to do COPY (SELECT ...), but we can't just
- * do SELECT * because we need to not copy generated columns.
- */
- appendStringInfo(&cmd, "COPY (SELECT ");
- for (int i = 0; i < lrel.natts; i++)
- {
- appendStringInfoString(&cmd, quote_identifier(lrel.attnames[i]));
- if (i < lrel.natts - 1)
- appendStringInfoString(&cmd, ", ");
- }
- appendStringInfo(&cmd, " FROM %s) TO STDOUT",
- quote_qualified_identifier(lrel.nspname, lrel.relname));
+ case RELKIND_RELATION:
+ appendStringInfo(&cmd, "COPY %s TO STDOUT",
+ quote_qualified_identifier(lrel.nspname, lrel.relname));
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+
+ /*
+ * For non-tables, we need to do COPY (SELECT ...), but we can't
+ * just do SELECT * because we need to not copy generated columns.
+ */
+ appendStringInfo(&cmd, "COPY (SELECT ");
+ for (int i = 0; i < lrel.natts; i++)
+ {
+ appendStringInfoString(&cmd, quote_identifier(lrel.attnames[i]));
+ if (i < lrel.natts - 1)
+ appendStringInfoString(&cmd, ", ");
+ }
+ appendStringInfo(&cmd, " FROM %s) TO STDOUT",
+ quote_qualified_identifier(lrel.nspname, lrel.relname));
+ break;
}
res = walrcv_exec(wrconn, cmd.data, 0, NULL);
pfree(cmd.data);
diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c
index a752a1224d..bc047c0b1e 100644
--- a/src/backend/replication/logical/worker.c
+++ b/src/backend/replication/logical/worker.c
@@ -646,12 +646,27 @@ apply_handle_insert(StringInfo s)
MemoryContextSwitchTo(oldctx);
/* For a partitioned table, insert the tuple into a partition. */
- if (rel->localrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- apply_handle_tuple_routing(estate->es_result_relation_info, estate,
- remoteslot, NULL, rel, CMD_INSERT);
- else
- apply_handle_insert_internal(estate->es_result_relation_info, estate,
- remoteslot);
+ switch ((RelKind) rel->localrel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ apply_handle_tuple_routing(estate->es_result_relation_info, estate,
+ remoteslot, NULL, rel, CMD_INSERT);
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ apply_handle_insert_internal(estate->es_result_relation_info, estate,
+ remoteslot);
+ break;
+ }
PopActiveSnapshot();
@@ -781,12 +796,27 @@ apply_handle_update(StringInfo s)
MemoryContextSwitchTo(oldctx);
/* For a partitioned table, apply update to correct partition. */
- if (rel->localrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- apply_handle_tuple_routing(estate->es_result_relation_info, estate,
- remoteslot, &newtup, rel, CMD_UPDATE);
- else
- apply_handle_update_internal(estate->es_result_relation_info, estate,
- remoteslot, &newtup, rel);
+ switch ((RelKind) rel->localrel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ apply_handle_tuple_routing(estate->es_result_relation_info, estate,
+ remoteslot, &newtup, rel, CMD_UPDATE);
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ apply_handle_update_internal(estate->es_result_relation_info, estate,
+ remoteslot, &newtup, rel);
+ break;
+ }
PopActiveSnapshot();
@@ -904,12 +934,27 @@ apply_handle_delete(StringInfo s)
MemoryContextSwitchTo(oldctx);
/* For a partitioned table, apply delete to correct partition. */
- if (rel->localrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- apply_handle_tuple_routing(estate->es_result_relation_info, estate,
- remoteslot, NULL, rel, CMD_DELETE);
- else
- apply_handle_delete_internal(estate->es_result_relation_info, estate,
- remoteslot, &rel->remoterel);
+ switch ((RelKind) rel->localrel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ apply_handle_tuple_routing(estate->es_result_relation_info, estate,
+ remoteslot, NULL, rel, CMD_DELETE);
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ apply_handle_delete_internal(estate->es_result_relation_info, estate,
+ remoteslot, &rel->remoterel);
+ break;
+ }
PopActiveSnapshot();
@@ -1273,41 +1318,61 @@ apply_handle_truncate(StringInfo s)
* Truncate partitions if we got a message to truncate a partitioned
* table.
*/
- if (rel->localrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
+ switch ((RelKind) rel->localrel->rd_rel->relkind)
{
- ListCell *child;
- List *children = find_all_inheritors(rel->localreloid,
- RowExclusiveLock,
- NULL);
-
- foreach(child, children)
- {
- Oid childrelid = lfirst_oid(child);
- Relation childrel;
-
- if (list_member_oid(relids, childrelid))
- continue;
-
- /* find_all_inheritors already got lock */
- childrel = table_open(childrelid, NoLock);
-
- /*
- * Ignore temp tables of other backends. See similar code in
- * ExecuteTruncate().
- */
- if (RELATION_IS_OTHER_TEMP(childrel))
+ case RELKIND_PARTITIONED_TABLE:
{
- table_close(childrel, RowExclusiveLock);
- continue;
- }
+ ListCell *child;
+ List *children = find_all_inheritors(rel->localreloid,
+ RowExclusiveLock,
+ NULL);
- rels = lappend(rels, childrel);
- part_rels = lappend(part_rels, childrel);
- relids = lappend_oid(relids, childrelid);
- /* Log this relation only if needed for logical decoding */
- if (RelationIsLogicallyLogged(childrel))
- relids_logged = lappend_oid(relids_logged, childrelid);
- }
+ foreach(child, children)
+ {
+ Oid childrelid = lfirst_oid(child);
+ Relation childrel;
+
+ if (list_member_oid(relids, childrelid))
+ continue;
+
+ /* find_all_inheritors already got lock */
+ childrel = table_open(childrelid, NoLock);
+
+ /*
+ * Ignore temp tables of other backends. See similar
+ * code in ExecuteTruncate().
+ */
+ if (RELATION_IS_OTHER_TEMP(childrel))
+ {
+ table_close(childrel, RowExclusiveLock);
+ continue;
+ }
+
+ rels = lappend(rels, childrel);
+ part_rels = lappend(part_rels, childrel);
+ relids = lappend_oid(relids, childrelid);
+
+ /*
+ * Log this relation only if needed for logical
+ * decoding
+ */
+ if (RelationIsLogicallyLogged(childrel))
+ relids_logged = lappend_oid(relids_logged, childrelid);
+ }
+ }
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
}
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index 57bbb6288c..54ae4af52b 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -100,8 +100,8 @@ int max_replication_slots = 0; /* the maximum number of replication
* slots */
static ReplicationSlot *SearchNamedReplicationSlot(const char *name);
-static int ReplicationSlotAcquireInternal(ReplicationSlot *slot,
- const char *name, SlotAcquireBehavior behavior);
+static int ReplicationSlotAcquireInternal(ReplicationSlot *slot,
+ const char *name, SlotAcquireBehavior behavior);
static void ReplicationSlotDropAcquired(void);
static void ReplicationSlotDropPtr(ReplicationSlot *slot);
@@ -335,7 +335,7 @@ static ReplicationSlot *
SearchNamedReplicationSlot(const char *name)
{
int i;
- ReplicationSlot *slot = NULL;
+ ReplicationSlot *slot = NULL;
Assert(LWLockHeldByMeInMode(ReplicationSlotControlLock,
LW_SHARED));
@@ -434,8 +434,8 @@ retry:
/*
* If we found the slot but it's already active in another process, we
- * either error out, return the PID of the owning process, or retry
- * after a short wait, as caller specified.
+ * either error out, return the PID of the owning process, or retry after
+ * a short wait, as caller specified.
*/
if (active_pid != MyProcPid)
{
@@ -454,7 +454,7 @@ retry:
goto retry;
}
else if (behavior == SAB_Block)
- ConditionVariableCancelSleep(); /* no sleep needed after all */
+ ConditionVariableCancelSleep(); /* no sleep needed after all */
/* Let everybody know we've modified this slot */
ConditionVariableBroadcast(&s->active_cv);
@@ -1143,8 +1143,8 @@ restart:
ReplicationSlot *s = &ReplicationSlotCtl->replication_slots[i];
XLogRecPtr restart_lsn = InvalidXLogRecPtr;
NameData slotname;
- int wspid;
- int last_signaled_pid = 0;
+ int wspid;
+ int last_signaled_pid = 0;
if (!s->in_use)
continue;
@@ -1167,20 +1167,20 @@ restart:
/*
* Try to mark this slot as used by this process.
*
- * Note that ReplicationSlotAcquireInternal(SAB_Inquire)
- * should not cancel the prepared condition variable
- * if this slot is active in other process. Because in this case
- * we have to wait on that CV for the process owning
- * the slot to be terminated, later.
+ * Note that ReplicationSlotAcquireInternal(SAB_Inquire) should
+ * not cancel the prepared condition variable if this slot is
+ * active in other process. Because in this case we have to wait
+ * on that CV for the process owning the slot to be terminated,
+ * later.
*/
wspid = ReplicationSlotAcquireInternal(s, NULL, SAB_Inquire);
/*
- * Exit the loop if we successfully acquired the slot or
- * the slot was dropped during waiting for the owning process
- * to be terminated. For example, the latter case is likely to
- * happen when the slot is temporary because it's automatically
- * dropped by the termination of the owning process.
+ * Exit the loop if we successfully acquired the slot or the slot
+ * was dropped during waiting for the owning process to be
+ * terminated. For example, the latter case is likely to happen
+ * when the slot is temporary because it's automatically dropped
+ * by the termination of the owning process.
*/
if (wspid <= 0)
break;
@@ -1188,13 +1188,13 @@ restart:
/*
* Signal to terminate the process that owns the slot.
*
- * There is the race condition where other process may own
- * the slot after the process using it was terminated and before
- * this process owns it. To handle this case, we signal again
- * if the PID of the owning process is changed than the last.
+ * There is the race condition where other process may own the
+ * slot after the process using it was terminated and before this
+ * process owns it. To handle this case, we signal again if the
+ * PID of the owning process is changed than the last.
*
- * XXX This logic assumes that the same PID is not reused
- * very quickly.
+ * XXX This logic assumes that the same PID is not reused very
+ * quickly.
*/
if (last_signaled_pid != wspid)
{
@@ -1211,8 +1211,8 @@ restart:
ConditionVariableCancelSleep();
/*
- * Do nothing here and start from scratch if the slot has
- * already been dropped.
+ * Do nothing here and start from scratch if the slot has already been
+ * dropped.
*/
if (wspid == -1)
goto restart;
diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c
index 9989df1107..93cde08936 100644
--- a/src/backend/rewrite/rewriteDefine.c
+++ b/src/backend/rewrite/rewriteDefine.c
@@ -262,14 +262,27 @@ DefineQueryRewrite(const char *rulename,
* Internal callers can target materialized views, but transformRuleStmt()
* blocks them for users. Don't mention them in the error message.
*/
- if (event_relation->rd_rel->relkind != RELKIND_RELATION &&
- event_relation->rd_rel->relkind != RELKIND_MATVIEW &&
- event_relation->rd_rel->relkind != RELKIND_VIEW &&
- event_relation->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table or view",
- RelationGetRelationName(event_relation))));
+ switch ((RelKind) event_relation->rd_rel->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a table or view",
+ RelationGetRelationName(event_relation))));
+ break;
+ }
if (!allowSystemTableMods && IsSystemRelation(event_relation))
ereport(ERROR,
@@ -421,69 +434,83 @@ DefineQueryRewrite(const char *rulename,
* views is just a kluge to allow dump/reload of views that
* participate in circular dependencies.)
*/
- if (event_relation->rd_rel->relkind != RELKIND_VIEW &&
- event_relation->rd_rel->relkind != RELKIND_MATVIEW)
+ switch ((RelKind) event_relation->rd_rel->relkind)
{
- TableScanDesc scanDesc;
- Snapshot snapshot;
- TupleTableSlot *slot;
-
- if (event_relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
+ case RELKIND_VIEW:
+ case RELKIND_MATVIEW:
+ break;
+ case RELKIND_PARTITIONED_TABLE:
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("cannot convert partitioned table \"%s\" to a view",
RelationGetRelationName(event_relation))));
-
- if (event_relation->rd_rel->relispartition)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot convert partition \"%s\" to a view",
- RelationGetRelationName(event_relation))));
-
- snapshot = RegisterSnapshot(GetLatestSnapshot());
- scanDesc = table_beginscan(event_relation, snapshot, 0, NULL);
- slot = table_slot_create(event_relation, NULL);
- if (table_scan_getnextslot(scanDesc, ForwardScanDirection, slot))
- ereport(ERROR,
- (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
- errmsg("could not convert table \"%s\" to a view because it is not empty",
- RelationGetRelationName(event_relation))));
- ExecDropSingleTupleTableSlot(slot);
- table_endscan(scanDesc);
- UnregisterSnapshot(snapshot);
-
- if (event_relation->rd_rel->relhastriggers)
- ereport(ERROR,
- (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
- errmsg("could not convert table \"%s\" to a view because it has triggers",
- RelationGetRelationName(event_relation)),
- errhint("In particular, the table cannot be involved in any foreign key relationships.")));
-
- if (event_relation->rd_rel->relhasindex)
- ereport(ERROR,
- (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
- errmsg("could not convert table \"%s\" to a view because it has indexes",
- RelationGetRelationName(event_relation))));
-
- if (event_relation->rd_rel->relhassubclass)
- ereport(ERROR,
- (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
- errmsg("could not convert table \"%s\" to a view because it has child tables",
- RelationGetRelationName(event_relation))));
-
- if (event_relation->rd_rel->relrowsecurity)
- ereport(ERROR,
- (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
- errmsg("could not convert table \"%s\" to a view because it has row security enabled",
- RelationGetRelationName(event_relation))));
-
- if (relation_has_policies(event_relation))
- ereport(ERROR,
- (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
- errmsg("could not convert table \"%s\" to a view because it has row security policies",
- RelationGetRelationName(event_relation))));
-
- RelisBecomingView = true;
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ {
+ TableScanDesc scanDesc;
+ Snapshot snapshot;
+ TupleTableSlot *slot;
+
+ if (event_relation->rd_rel->relispartition)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot convert partition \"%s\" to a view",
+ RelationGetRelationName(event_relation))));
+
+ snapshot = RegisterSnapshot(GetLatestSnapshot());
+ scanDesc = table_beginscan(event_relation, snapshot, 0, NULL);
+ slot = table_slot_create(event_relation, NULL);
+ if (table_scan_getnextslot(scanDesc, ForwardScanDirection, slot))
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("could not convert table \"%s\" to a view because it is not empty",
+ RelationGetRelationName(event_relation))));
+ ExecDropSingleTupleTableSlot(slot);
+ table_endscan(scanDesc);
+ UnregisterSnapshot(snapshot);
+
+ if (event_relation->rd_rel->relhastriggers)
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("could not convert table \"%s\" to a view because it has triggers",
+ RelationGetRelationName(event_relation)),
+ errhint("In particular, the table cannot be involved in any foreign key relationships.")));
+
+ if (event_relation->rd_rel->relhasindex)
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("could not convert table \"%s\" to a view because it has indexes",
+ RelationGetRelationName(event_relation))));
+
+ if (event_relation->rd_rel->relhassubclass)
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("could not convert table \"%s\" to a view because it has child tables",
+ RelationGetRelationName(event_relation))));
+
+ if (event_relation->rd_rel->relrowsecurity)
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("could not convert table \"%s\" to a view because it has row security enabled",
+ RelationGetRelationName(event_relation))));
+
+ if (relation_has_policies(event_relation))
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("could not convert table \"%s\" to a view because it has row security policies",
+ RelationGetRelationName(event_relation))));
+
+ RelisBecomingView = true;
+ }
+ break;
}
}
else
@@ -920,12 +947,26 @@ RangeVarCallbackForRenameRule(const RangeVar *rv, Oid relid, Oid oldrelid,
form = (Form_pg_class) GETSTRUCT(tuple);
/* only tables and views can have rules */
- if (form->relkind != RELKIND_RELATION &&
- form->relkind != RELKIND_VIEW &&
- form->relkind != RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table or view", rv->relname)));
+ switch ((RelKind) form->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_VIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a table or view", rv->relname)));
+ break;
+ }
if (!allowSystemTableMods && IsSystemClass(relid, form))
ereport(ERROR,
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index fe777c3103..76c0b40b79 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -902,25 +902,42 @@ rewriteTargetListIU(List *targetList,
* For an UPDATE on a trigger-updatable view, provide a dummy entry
* whenever there is no explicit assignment.
*/
- if (new_tle == NULL && commandType == CMD_UPDATE &&
- target_relation->rd_rel->relkind == RELKIND_VIEW &&
- view_has_instead_trigger(target_relation, CMD_UPDATE))
+ switch ((RelKind) target_relation->rd_rel->relkind)
{
- Node *new_expr;
-
- new_expr = (Node *) makeVar(result_rti,
- attrno,
- att_tup->atttypid,
- att_tup->atttypmod,
- att_tup->attcollation,
- 0);
+ case RELKIND_VIEW:
+ if (new_tle == NULL && commandType == CMD_UPDATE &&
+ view_has_instead_trigger(target_relation, CMD_UPDATE))
+ {
+ Node *new_expr;
- new_tle = makeTargetEntry((Expr *) new_expr,
- attrno,
- pstrdup(NameStr(att_tup->attname)),
- false);
+ new_expr = (Node *) makeVar(result_rti,
+ attrno,
+ att_tup->atttypid,
+ att_tup->atttypmod,
+ att_tup->attcollation,
+ 0);
+
+ new_tle = makeTargetEntry((Expr *) new_expr,
+ attrno,
+ pstrdup(NameStr(att_tup->attname)),
+ false);
+ }
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
}
+
if (new_tle)
new_tlist = lappend(new_tlist, new_tle);
}
@@ -1316,39 +1333,54 @@ rewriteValuesRTE(Query *parsetree, RangeTblEntry *rte, int rti,
* skip this check in that case --- it isn't an auto-updatable view.
*/
isAutoUpdatableView = false;
- if (!force_nulls &&
- target_relation->rd_rel->relkind == RELKIND_VIEW &&
- !view_has_instead_trigger(target_relation, CMD_INSERT))
+ switch ((RelKind) target_relation->rd_rel->relkind)
{
- List *locks;
- bool hasUpdate;
- bool found;
- ListCell *l;
+ case RELKIND_VIEW:
+ if (!force_nulls && !view_has_instead_trigger(target_relation, CMD_INSERT))
+ {
+ List *locks;
+ bool hasUpdate;
+ bool found;
+ ListCell *l;
- /* Look for an unconditional DO INSTEAD rule */
- locks = matchLocks(CMD_INSERT, target_relation->rd_rules,
- parsetree->resultRelation, parsetree, &hasUpdate);
+ /* Look for an unconditional DO INSTEAD rule */
+ locks = matchLocks(CMD_INSERT, target_relation->rd_rules,
+ parsetree->resultRelation, parsetree, &hasUpdate);
- found = false;
- foreach(l, locks)
- {
- RewriteRule *rule_lock = (RewriteRule *) lfirst(l);
+ found = false;
+ foreach(l, locks)
+ {
+ RewriteRule *rule_lock = (RewriteRule *) lfirst(l);
- if (rule_lock->isInstead &&
- rule_lock->qual == NULL)
- {
- found = true;
- break;
- }
- }
+ if (rule_lock->isInstead &&
+ rule_lock->qual == NULL)
+ {
+ found = true;
+ break;
+ }
+ }
- /*
- * If we didn't find an unconditional DO INSTEAD rule, assume that the
- * view is auto-updatable. If it isn't, rewriteTargetView() will
- * throw an error.
- */
- if (!found)
- isAutoUpdatableView = true;
+ /*
+ * If we didn't find an unconditional DO INSTEAD rule, assume
+ * that the view is auto-updatable. If it isn't,
+ * rewriteTargetView() will throw an error.
+ */
+ if (!found)
+ isAutoUpdatableView = true;
+ }
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
}
newValues = NIL;
@@ -1450,55 +1482,72 @@ rewriteTargetListUD(Query *parsetree, RangeTblEntry *target_rte,
const char *attrname;
TargetEntry *tle;
- if (target_relation->rd_rel->relkind == RELKIND_RELATION ||
- target_relation->rd_rel->relkind == RELKIND_MATVIEW ||
- target_relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- {
- /*
- * Emit CTID so that executor can find the row to update or delete.
- */
- var = makeVar(parsetree->resultRelation,
- SelfItemPointerAttributeNumber,
- TIDOID,
- -1,
- InvalidOid,
- 0);
-
- attrname = "ctid";
- }
- else if (target_relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
+ switch ((RelKind) target_relation->rd_rel->relkind)
{
- /*
- * Let the foreign table's FDW add whatever junk TLEs it wants.
- */
- FdwRoutine *fdwroutine;
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ {
+ /*
+ * Emit CTID so that executor can find the row to update or
+ * delete.
+ */
+ var = makeVar(parsetree->resultRelation,
+ SelfItemPointerAttributeNumber,
+ TIDOID,
+ -1,
+ InvalidOid,
+ 0);
+
+ attrname = "ctid";
+ }
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ {
+ /*
+ * Let the foreign table's FDW add whatever junk TLEs it
+ * wants.
+ */
+ FdwRoutine *fdwroutine;
- fdwroutine = GetFdwRoutineForRelation(target_relation, false);
+ fdwroutine = GetFdwRoutineForRelation(target_relation, false);
- if (fdwroutine->AddForeignUpdateTargets != NULL)
- fdwroutine->AddForeignUpdateTargets(parsetree, target_rte,
- target_relation);
+ if (fdwroutine->AddForeignUpdateTargets != NULL)
+ fdwroutine->AddForeignUpdateTargets(parsetree, target_rte,
+ target_relation);
- /*
- * If we have a row-level trigger corresponding to the operation, emit
- * a whole-row Var so that executor will have the "old" row to pass to
- * the trigger. Alas, this misses system columns.
- */
- if (target_relation->trigdesc &&
- ((parsetree->commandType == CMD_UPDATE &&
- (target_relation->trigdesc->trig_update_after_row ||
- target_relation->trigdesc->trig_update_before_row)) ||
- (parsetree->commandType == CMD_DELETE &&
- (target_relation->trigdesc->trig_delete_after_row ||
- target_relation->trigdesc->trig_delete_before_row))))
- {
- var = makeWholeRowVar(target_rte,
- parsetree->resultRelation,
- 0,
- false);
+ /*
+ * If we have a row-level trigger corresponding to the
+ * operation, emit a whole-row Var so that executor will have
+ * the "old" row to pass to the trigger. Alas, this misses
+ * system columns.
+ */
+ if (target_relation->trigdesc &&
+ ((parsetree->commandType == CMD_UPDATE &&
+ (target_relation->trigdesc->trig_update_after_row ||
+ target_relation->trigdesc->trig_update_before_row)) ||
+ (parsetree->commandType == CMD_DELETE &&
+ (target_relation->trigdesc->trig_delete_after_row ||
+ target_relation->trigdesc->trig_delete_before_row))))
+ {
+ var = makeWholeRowVar(target_rte,
+ parsetree->resultRelation,
+ 0,
+ false);
- attrname = "wholerow";
- }
+ attrname = "wholerow";
+ }
+ }
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
if (var != NULL)
@@ -1909,8 +1958,23 @@ fireRIRrules(Query *parsetree, List *activeRIRs)
* In that case this test would need to be postponed till after we've
* opened the rel, so that we could check its state.
*/
- if (rte->relkind == RELKIND_MATVIEW)
- continue;
+ switch ((RelKind) rte->relkind)
+ {
+ case RELKIND_MATVIEW:
+ continue;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
/*
* In INSERT ... ON CONFLICT, ignore the EXCLUDED pseudo-relation;
@@ -2032,10 +2096,25 @@ fireRIRrules(Query *parsetree, List *activeRIRs)
++rt_index;
/* Only normal relations can have RLS policies */
- if (rte->rtekind != RTE_RELATION ||
- (rte->relkind != RELKIND_RELATION &&
- rte->relkind != RELKIND_PARTITIONED_TABLE))
+ if (rte->rtekind != RTE_RELATION)
continue;
+ switch ((RelKind) rte->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ continue;
+ }
rel = table_open(rte->relid, NoLock);
@@ -2498,12 +2577,25 @@ view_query_is_auto_updatable(Query *viewquery, bool check_cols)
return gettext_noop("Views that do not select from a single table or view are not automatically updatable.");
base_rte = rt_fetch(rtr->rtindex, viewquery->rtable);
- if (base_rte->rtekind != RTE_RELATION ||
- (base_rte->relkind != RELKIND_RELATION &&
- base_rte->relkind != RELKIND_FOREIGN_TABLE &&
- base_rte->relkind != RELKIND_VIEW &&
- base_rte->relkind != RELKIND_PARTITIONED_TABLE))
- return gettext_noop("Views that do not select from a single table or view are not automatically updatable.");
+ switch ((RelKind) base_rte->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ if (base_rte->rtekind == RTE_RELATION)
+ break;
+ /* fallthrough */
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ return gettext_noop("Views that do not select from a single table or view are not automatically updatable.");
+ }
if (base_rte->tablesample)
return gettext_noop("Views containing TABLESAMPLE are not automatically updatable.");
@@ -2677,11 +2769,23 @@ relation_is_updatable(Oid reloid,
}
/* If the relation is a table, it is always updatable */
- if (rel->rd_rel->relkind == RELKIND_RELATION ||
- rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
+ switch ((RelKind) rel->rd_rel->relkind)
{
- relation_close(rel, AccessShareLock);
- return ALL_EVENTS;
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ relation_close(rel, AccessShareLock);
+ return ALL_EVENTS;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
}
/* Look for unconditional DO INSTEAD rules, and note supported events */
@@ -2730,84 +2834,103 @@ relation_is_updatable(Oid reloid,
}
}
- /* If this is a foreign table, check which update events it supports */
- if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
+ switch ((RelKind) rel->rd_rel->relkind)
{
- FdwRoutine *fdwroutine = GetFdwRoutineForRelation(rel, false);
-
- if (fdwroutine->IsForeignRelUpdatable != NULL)
- events |= fdwroutine->IsForeignRelUpdatable(rel);
- else
- {
- /* Assume presence of executor functions is sufficient */
- if (fdwroutine->ExecForeignInsert != NULL)
- events |= (1 << CMD_INSERT);
- if (fdwroutine->ExecForeignUpdate != NULL)
- events |= (1 << CMD_UPDATE);
- if (fdwroutine->ExecForeignDelete != NULL)
- events |= (1 << CMD_DELETE);
- }
+ /*
+ * If this is a foreign table, check which update events it
+ * supports
+ */
+ case RELKIND_FOREIGN_TABLE:
+ {
+ FdwRoutine *fdwroutine = GetFdwRoutineForRelation(rel, false);
- relation_close(rel, AccessShareLock);
- return events;
- }
+ if (fdwroutine->IsForeignRelUpdatable != NULL)
+ events |= fdwroutine->IsForeignRelUpdatable(rel);
+ else
+ {
+ /* Assume presence of executor functions is sufficient */
+ if (fdwroutine->ExecForeignInsert != NULL)
+ events |= (1 << CMD_INSERT);
+ if (fdwroutine->ExecForeignUpdate != NULL)
+ events |= (1 << CMD_UPDATE);
+ if (fdwroutine->ExecForeignDelete != NULL)
+ events |= (1 << CMD_DELETE);
+ }
- /* Check if this is an automatically updatable view */
- if (rel->rd_rel->relkind == RELKIND_VIEW)
- {
- Query *viewquery = get_view_query(rel);
+ relation_close(rel, AccessShareLock);
+ return events;
+ }
+ break;
+ /* Check if this is an automatically updatable view */
+ case RELKIND_VIEW:
+ {
+ Query *viewquery = get_view_query(rel);
- if (view_query_is_auto_updatable(viewquery, false) == NULL)
- {
- Bitmapset *updatable_cols;
- int auto_events;
- RangeTblRef *rtr;
- RangeTblEntry *base_rte;
- Oid baseoid;
+ if (view_query_is_auto_updatable(viewquery, false) == NULL)
+ {
+ Bitmapset *updatable_cols;
+ int auto_events;
+ RangeTblRef *rtr;
+ RangeTblEntry *base_rte;
+ Oid baseoid;
- /*
- * Determine which of the view's columns are updatable. If there
- * are none within the set of columns we are looking at, then the
- * view doesn't support INSERT/UPDATE, but it may still support
- * DELETE.
- */
- view_cols_are_auto_updatable(viewquery, NULL,
- &updatable_cols, NULL);
+ /*
+ * Determine which of the view's columns are updatable. If
+ * there are none within the set of columns we are looking
+ * at, then the view doesn't support INSERT/UPDATE, but it
+ * may still support DELETE.
+ */
+ view_cols_are_auto_updatable(viewquery, NULL,
+ &updatable_cols, NULL);
- if (include_cols != NULL)
- updatable_cols = bms_int_members(updatable_cols, include_cols);
+ if (include_cols != NULL)
+ updatable_cols = bms_int_members(updatable_cols, include_cols);
- if (bms_is_empty(updatable_cols))
- auto_events = (1 << CMD_DELETE); /* May support DELETE */
- else
- auto_events = ALL_EVENTS; /* May support all events */
+ if (bms_is_empty(updatable_cols))
+ auto_events = (1 << CMD_DELETE); /* May support DELETE */
+ else
+ auto_events = ALL_EVENTS; /* May support all events */
- /*
- * The base relation must also support these update commands.
- * Tables are always updatable, but for any other kind of base
- * relation we must do a recursive check limited to the columns
- * referenced by the locally updatable columns in this view.
- */
- rtr = (RangeTblRef *) linitial(viewquery->jointree->fromlist);
- base_rte = rt_fetch(rtr->rtindex, viewquery->rtable);
- Assert(base_rte->rtekind == RTE_RELATION);
+ /*
+ * The base relation must also support these update
+ * commands. Tables are always updatable, but for any
+ * other kind of base relation we must do a recursive
+ * check limited to the columns referenced by the locally
+ * updatable columns in this view.
+ */
+ rtr = (RangeTblRef *) linitial(viewquery->jointree->fromlist);
+ base_rte = rt_fetch(rtr->rtindex, viewquery->rtable);
+ Assert(base_rte->rtekind == RTE_RELATION);
- if (base_rte->relkind != RELKIND_RELATION &&
- base_rte->relkind != RELKIND_PARTITIONED_TABLE)
- {
- baseoid = base_rte->relid;
- outer_reloids = lappend_oid(outer_reloids,
- RelationGetRelid(rel));
- include_cols = adjust_view_column_set(updatable_cols,
- viewquery->targetList);
- auto_events &= relation_is_updatable(baseoid,
- outer_reloids,
- include_triggers,
- include_cols);
- outer_reloids = list_delete_last(outer_reloids);
+ if (base_rte->relkind != RELKIND_RELATION &&
+ base_rte->relkind != RELKIND_PARTITIONED_TABLE)
+ {
+ baseoid = base_rte->relid;
+ outer_reloids = lappend_oid(outer_reloids,
+ RelationGetRelid(rel));
+ include_cols = adjust_view_column_set(updatable_cols,
+ viewquery->targetList);
+ auto_events &= relation_is_updatable(baseoid,
+ outer_reloids,
+ include_triggers,
+ include_cols);
+ outer_reloids = list_delete_last(outer_reloids);
+ }
+ events |= auto_events;
+ }
}
- events |= auto_events;
- }
+ break;
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
}
/* If we reach here, the relation may support some update commands */
diff --git a/src/backend/rewrite/rowsecurity.c b/src/backend/rewrite/rowsecurity.c
index 0fe2f9ca83..2002cf9a20 100644
--- a/src/backend/rewrite/rowsecurity.c
+++ b/src/backend/rewrite/rowsecurity.c
@@ -123,9 +123,23 @@ get_row_security_policies(Query *root, RangeTblEntry *rte, int rt_index,
*hasSubLinks = false;
/* If this is not a normal relation, just return immediately */
- if (rte->relkind != RELKIND_RELATION &&
- rte->relkind != RELKIND_PARTITIONED_TABLE)
- return;
+ switch ((RelKind) rte->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ return;
+ }
/* Switch to checkAsUser if it's set */
user_id = rte->checkAsUser ? rte->checkAsUser : GetUserId();
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 29c920800a..6eb28a2210 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -2819,7 +2819,7 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln)
BlockNumber
RelationGetNumberOfBlocksInFork(Relation relation, ForkNumber forkNum)
{
- switch (relation->rd_rel->relkind)
+ switch ((RelKind) relation->rd_rel->relkind)
{
case RELKIND_SEQUENCE:
case RELKIND_INDEX:
@@ -2846,12 +2846,17 @@ RelationGetNumberOfBlocksInFork(Relation relation, ForkNumber forkNum)
return (szbytes + (BLCKSZ - 1)) / BLCKSZ;
}
case RELKIND_VIEW:
+ elog(FATAL, "RELKIND_VIEW in RelationGetNumberOfBlocksInFork");
case RELKIND_COMPOSITE_TYPE:
+ elog(FATAL, "RELKIND_COMPOSITE_TYPE in RelationGetNumberOfBlocksInFork");
case RELKIND_FOREIGN_TABLE:
+ elog(FATAL, "RELKIND_FOREIGN_TABLE in RelationGetNumberOfBlocksInFork");
case RELKIND_PARTITIONED_TABLE:
+ elog(FATAL, "RELKIND_PARTITIONED_TABLE in RelationGetNumberOfBlocksInFork");
+ case RELKIND_NULL:
default:
- Assert(false);
- break;
+ elog(FATAL, "Unexpected relkind %d in RelationGetNumberOfBlocksInFork",
+ (int) relation->rd_rel->relkind);
}
return 0; /* keep compiler quiet */
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index e57fcd2538..615670ff41 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -1236,8 +1236,8 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
/*
* Set timer so we can wake up after awhile and check for a deadlock. If a
* deadlock is detected, the handler sets MyProc->waitStatus =
- * PROC_WAIT_STATUS_ERROR, allowing us to know that we must report failure rather
- * than success.
+ * PROC_WAIT_STATUS_ERROR, allowing us to know that we must report failure
+ * rather than success.
*
* By delaying the check until we've waited for a bit, we can avoid
* running the rather expensive deadlock-check code in most cases.
@@ -1302,9 +1302,9 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
}
/*
- * waitStatus could change from PROC_WAIT_STATUS_WAITING to something else
- * asynchronously. Read it just once per loop to prevent surprising
- * behavior (such as missing log messages).
+ * waitStatus could change from PROC_WAIT_STATUS_WAITING to something
+ * else asynchronously. Read it just once per loop to prevent
+ * surprising behavior (such as missing log messages).
*/
myWaitStatus = *((volatile ProcWaitStatus *) &MyProc->waitStatus);
@@ -1504,11 +1504,12 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
/*
* Currently, the deadlock checker always kicks its own
- * process, which means that we'll only see PROC_WAIT_STATUS_ERROR when
- * deadlock_state == DS_HARD_DEADLOCK, and there's no need to
- * print redundant messages. But for completeness and
- * future-proofing, print a message if it looks like someone
- * else kicked us off the lock.
+ * process, which means that we'll only see
+ * PROC_WAIT_STATUS_ERROR when deadlock_state ==
+ * DS_HARD_DEADLOCK, and there's no need to print redundant
+ * messages. But for completeness and future-proofing, print
+ * a message if it looks like someone else kicked us off the
+ * lock.
*/
if (deadlock_state != DS_HARD_DEADLOCK)
ereport(LOG,
@@ -1737,9 +1738,9 @@ CheckDeadLock(void)
* preserve the flexibility to kill some other transaction than the
* one detecting the deadlock.)
*
- * RemoveFromWaitQueue sets MyProc->waitStatus to PROC_WAIT_STATUS_ERROR, so
- * ProcSleep will report an error after we return from the signal
- * handler.
+ * RemoveFromWaitQueue sets MyProc->waitStatus to
+ * PROC_WAIT_STATUS_ERROR, so ProcSleep will report an error after we
+ * return from the signal handler.
*/
Assert(MyProc->waitLock != NULL);
RemoveFromWaitQueue(MyProc, LockTagHashCode(&(MyProc->waitLock->tag)));
diff --git a/src/backend/storage/lmgr/spin.c b/src/backend/storage/lmgr/spin.c
index 9f7eae9339..6d76b95c27 100644
--- a/src/backend/storage/lmgr/spin.c
+++ b/src/backend/storage/lmgr/spin.c
@@ -37,7 +37,7 @@
#define NUM_EMULATION_SEMAPHORES (NUM_SPINLOCK_SEMAPHORES + NUM_ATOMICS_SEMAPHORES)
#else
#define NUM_EMULATION_SEMAPHORES (NUM_SPINLOCK_SEMAPHORES)
-#endif /* DISABLE_ATOMICS */
+#endif /* DISABLE_ATOMICS */
PGSemaphore *SpinlockSemaArray;
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 9b0c376c8c..538d237258 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -1436,34 +1436,62 @@ ProcessUtilitySlow(ParseState *pstate,
* partitions are something we can put an index on, to
* avoid building some indexes only to fail later.
*/
- if (stmt->relation->inh &&
- get_rel_relkind(relid) == RELKIND_PARTITIONED_TABLE)
+ switch ((RelKind) get_rel_relkind(relid))
{
- ListCell *lc;
- List *inheritors = NIL;
-
- inheritors = find_all_inheritors(relid, lockmode, NULL);
- foreach(lc, inheritors)
- {
- char relkind = get_rel_relkind(lfirst_oid(lc));
-
- if (relkind != RELKIND_RELATION &&
- relkind != RELKIND_MATVIEW &&
- relkind != RELKIND_PARTITIONED_TABLE &&
- relkind != RELKIND_FOREIGN_TABLE)
- elog(ERROR, "unexpected relkind \"%c\" on partition \"%s\"",
- relkind, stmt->relation->relname);
-
- if (relkind == RELKIND_FOREIGN_TABLE &&
- (stmt->unique || stmt->primary))
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot create unique index on partitioned table \"%s\"",
- stmt->relation->relname),
- errdetail("Table \"%s\" contains partitions that are foreign tables.",
- stmt->relation->relname)));
- }
- list_free(inheritors);
+ case RELKIND_PARTITIONED_TABLE:
+ if (stmt->relation->inh)
+ {
+ ListCell *lc;
+ List *inheritors = NIL;
+
+ inheritors = find_all_inheritors(relid, lockmode, NULL);
+ foreach(lc, inheritors)
+ {
+ char relkind = get_rel_relkind(lfirst_oid(lc));
+
+ switch ((RelKind) relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ if (stmt->unique || stmt->primary)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot create unique index on partitioned table \"%s\"",
+ stmt->relation->relname),
+ errdetail("Table \"%s\" contains partitions that are foreign tables.",
+ stmt->relation->relname)));
+ break;
+ case RELKIND_NULL:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ elog(ERROR, "unexpected relkind \"%c\" on partition \"%s\"",
+ relkind, stmt->relation->relname);
+ break;
+ }
+
+ }
+ list_free(inheritors);
+ }
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
/* Run parse analysis ... */
diff --git a/src/backend/utils/adt/amutils.c b/src/backend/utils/adt/amutils.c
index 220cd8fc52..92fd125649 100644
--- a/src/backend/utils/adt/amutils.c
+++ b/src/backend/utils/adt/amutils.c
@@ -175,11 +175,24 @@ 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)
+ switch ((RelKind) rd_rel->relkind)
{
- ReleaseSysCache(tuple);
- PG_RETURN_NULL();
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ break;
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ ReleaseSysCache(tuple);
+ PG_RETURN_NULL();
+ break;
}
amoid = rd_rel->relam;
natts = rd_rel->relnatts;
diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c
index 2320c06a9b..9fe10a2f22 100644
--- a/src/backend/utils/adt/dbsize.c
+++ b/src/backend/utils/adt/dbsize.c
@@ -878,7 +878,7 @@ pg_relation_filenode(PG_FUNCTION_ARGS)
{
if (relform->relfilenode)
result = relform->relfilenode;
- else /* Consult the relation mapper */
+ else /* Consult the relation mapper */
result = RelationMapOidToFilenode(relid,
relform->relisshared);
}
@@ -957,17 +957,17 @@ pg_relation_filepath(PG_FUNCTION_ARGS)
rnode.dbNode = MyDatabaseId;
if (relform->relfilenode)
rnode.relNode = relform->relfilenode;
- else /* Consult the relation mapper */
+ else /* Consult the relation mapper */
rnode.relNode = RelationMapOidToFilenode(relid,
relform->relisshared);
}
else
{
- /* no storage, return NULL */
- rnode.relNode = InvalidOid;
- /* some compilers generate warnings without these next two lines */
- rnode.dbNode = InvalidOid;
- rnode.spcNode = InvalidOid;
+ /* no storage, return NULL */
+ rnode.relNode = InvalidOid;
+ /* some compilers generate warnings without these next two lines */
+ rnode.dbNode = InvalidOid;
+ rnode.spcNode = InvalidOid;
}
if (!OidIsValid(rnode.relNode))
diff --git a/src/backend/utils/adt/partitionfuncs.c b/src/backend/utils/adt/partitionfuncs.c
index c1120403fd..549bd64f6b 100644
--- a/src/backend/utils/adt/partitionfuncs.c
+++ b/src/backend/utils/adt/partitionfuncs.c
@@ -45,10 +45,25 @@ 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)
- return false;
+ switch ((RelKind) relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_PARTITIONED_INDEX:
+ break;
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ if (!relispartition)
+ return false;
+ break;
+ }
return true;
}
@@ -143,8 +158,25 @@ pg_partition_tree(PG_FUNCTION_ARGS)
nulls[1] = true;
/* isleaf */
- values[2] = BoolGetDatum(relkind != RELKIND_PARTITIONED_TABLE &&
- relkind != RELKIND_PARTITIONED_INDEX);
+ switch ((RelKind) relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_PARTITIONED_INDEX:
+ values[2] = BoolGetDatum(false);
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_VIEW:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ values[2] = BoolGetDatum(true);
+ break;
+ }
/* level */
if (relid != rootrelid)
diff --git a/src/backend/utils/adt/tid.c b/src/backend/utils/adt/tid.c
index 509a0fdffc..821f91eb07 100644
--- a/src/backend/utils/adt/tid.c
+++ b/src/backend/utils/adt/tid.c
@@ -381,8 +381,23 @@ currtid_byreloid(PG_FUNCTION_ARGS)
aclcheck_error(aclresult, get_relkind_objtype(rel->rd_rel->relkind),
RelationGetRelationName(rel));
- if (rel->rd_rel->relkind == RELKIND_VIEW)
- return currtid_for_view(rel, tid);
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_VIEW:
+ return currtid_for_view(rel, tid);
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
if (!RELKIND_HAS_STORAGE(rel->rd_rel->relkind))
elog(ERROR, "cannot look at latest visible tid for relation \"%s.%s\"",
@@ -423,8 +438,23 @@ currtid_byrelname(PG_FUNCTION_ARGS)
aclcheck_error(aclresult, get_relkind_objtype(rel->rd_rel->relkind),
RelationGetRelationName(rel));
- if (rel->rd_rel->relkind == RELKIND_VIEW)
- return currtid_for_view(rel, tid);
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_VIEW:
+ return currtid_for_view(rel, tid);
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
if (!RELKIND_HAS_STORAGE(rel->rd_rel->relkind))
elog(ERROR, "cannot look at latest visible tid for relation \"%s.%s\"",
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c
index 4c299057a6..c2711075ef 100644
--- a/src/backend/utils/adt/xml.c
+++ b/src/backend/utils/adt/xml.c
@@ -2475,9 +2475,9 @@ schema_get_xml_visible_tables(Oid nspid)
initStringInfo(&query);
appendStringInfo(&query, "SELECT oid FROM pg_catalog.pg_class"
" WHERE relnamespace = %u AND relkind IN ("
- CppAsString2(RELKIND_RELATION) ","
- CppAsString2(RELKIND_MATVIEW) ","
- CppAsString2(RELKIND_VIEW) ")"
+ RelKindAsString(RELKIND_RELATION) ","
+ RelKindAsString(RELKIND_MATVIEW) ","
+ RelKindAsString(RELKIND_VIEW) ")"
" AND pg_catalog.has_table_privilege (oid, 'SELECT')"
" ORDER BY relname;", nspid);
@@ -2507,9 +2507,9 @@ database_get_xml_visible_tables(void)
/* At the moment there is no order required here. */
return query_to_oid_list("SELECT oid FROM pg_catalog.pg_class"
" WHERE relkind IN ("
- CppAsString2(RELKIND_RELATION) ","
- CppAsString2(RELKIND_MATVIEW) ","
- CppAsString2(RELKIND_VIEW) ")"
+ RelKindAsString(RELKIND_RELATION) ","
+ RelKindAsString(RELKIND_MATVIEW) ","
+ RelKindAsString(RELKIND_VIEW) ")"
" AND pg_catalog.has_table_privilege(pg_class.oid, 'SELECT')"
" AND relnamespace IN (" XML_VISIBLE_SCHEMAS ");");
}
diff --git a/src/backend/utils/cache/partcache.c b/src/backend/utils/cache/partcache.c
index acf8a44f30..a5eef66f4e 100644
--- a/src/backend/utils/cache/partcache.c
+++ b/src/backend/utils/cache/partcache.c
@@ -53,8 +53,23 @@ static List *generate_partition_qual(Relation rel);
PartitionKey
RelationGetPartitionKey(Relation rel)
{
- if (rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
- return NULL;
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ return NULL;
+ }
if (unlikely(rel->rd_partkey == NULL))
RelationBuildPartitionKey(rel);
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0b9eb00d2d..aa8f69224d 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -448,7 +448,7 @@ RelationParseRelOptions(Relation relation, HeapTuple tuple)
* Look up any AM-specific parse function; fall out if relkind should not
* have options.
*/
- switch (relation->rd_rel->relkind)
+ switch ((RelKind) relation->rd_rel->relkind)
{
case RELKIND_RELATION:
case RELKIND_TOASTVALUE:
@@ -461,6 +461,10 @@ RelationParseRelOptions(Relation relation, HeapTuple tuple)
case RELKIND_PARTITIONED_INDEX:
amoptsfn = relation->rd_indam->amoptions;
break;
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_NULL:
default:
return;
}
@@ -1181,7 +1185,7 @@ RelationBuildDesc(Oid targetRelId, bool insertIt)
/*
* initialize access method information
*/
- switch (relation->rd_rel->relkind)
+ switch ((RelKind) relation->rd_rel->relkind)
{
case RELKIND_INDEX:
case RELKIND_PARTITIONED_INDEX:
@@ -1202,6 +1206,8 @@ RelationBuildDesc(Oid targetRelId, bool insertIt)
case RELKIND_COMPOSITE_TYPE:
case RELKIND_FOREIGN_TABLE:
case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_NULL:
+ default:
Assert(relation->rd_rel->relam == InvalidOid);
break;
}
@@ -1746,38 +1752,53 @@ RelationInitTableAccessMethod(Relation relation)
HeapTuple tuple;
Form_pg_am aform;
- if (relation->rd_rel->relkind == RELKIND_SEQUENCE)
- {
- /*
- * Sequences are currently accessed like heap tables, but it doesn't
- * seem prudent to show that in the catalog. So just overwrite it
- * here.
- */
- relation->rd_amhandler = HEAP_TABLE_AM_HANDLER_OID;
- }
- else if (IsCatalogRelation(relation))
- {
- /*
- * Avoid doing a syscache lookup for catalog tables.
- */
- Assert(relation->rd_rel->relam == HEAP_TABLE_AM_OID);
- relation->rd_amhandler = HEAP_TABLE_AM_HANDLER_OID;
- }
- else
+ switch ((RelKind) relation->rd_rel->relkind)
{
- /*
- * Look up the table 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",
- relation->rd_rel->relam);
- aform = (Form_pg_am) GETSTRUCT(tuple);
- relation->rd_amhandler = aform->amhandler;
- ReleaseSysCache(tuple);
+ case RELKIND_SEQUENCE:
+
+ /*
+ * Sequences are currently accessed like heap tables, but it
+ * doesn't seem prudent to show that in the catalog. So just
+ * overwrite it here.
+ */
+ relation->rd_amhandler = HEAP_TABLE_AM_HANDLER_OID;
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ if (IsCatalogRelation(relation))
+ {
+ /*
+ * Avoid doing a syscache lookup for catalog tables.
+ */
+ Assert(relation->rd_rel->relam == HEAP_TABLE_AM_OID);
+ relation->rd_amhandler = HEAP_TABLE_AM_HANDLER_OID;
+ }
+ else
+ {
+ /*
+ * Look up the table 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",
+ relation->rd_rel->relam);
+ aform = (Form_pg_am) GETSTRUCT(tuple);
+ relation->rd_amhandler = aform->amhandler;
+ ReleaseSysCache(tuple);
+ }
+ break;
}
/*
@@ -2023,11 +2044,25 @@ RelationIdGetRelation(Oid relationId)
* and we don't want to use the full-blown procedure because it's
* a headache for indexes that reload itself depends on.
*/
- if (rd->rd_rel->relkind == RELKIND_INDEX ||
- rd->rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
- RelationReloadIndexInfo(rd);
- else
- RelationClearRelation(rd, true);
+ switch ((RelKind) rd->rd_rel->relkind)
+ {
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ RelationReloadIndexInfo(rd);
+ break;
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ RelationClearRelation(rd, true);
+ break;
+ }
/*
* Normally entries need to be valid here, but before the relcache
@@ -2284,46 +2319,60 @@ RelationReloadNailed(Relation relation)
if (!IsTransactionState() || relation->rd_refcnt <= 1)
return;
- if (relation->rd_rel->relkind == RELKIND_INDEX)
+ switch ((RelKind) relation->rd_rel->relkind)
{
- /*
- * If it's a nailed-but-not-mapped index, then we need to re-read the
- * pg_class row to see if its relfilenode changed.
- */
- RelationReloadIndexInfo(relation);
- }
- else
- {
- /*
- * Reload a non-index entry. We can't easily do so if relcaches
- * aren't yet built, but that's fine because at that stage the
- * attributes that need to be current (like relfrozenxid) aren't yet
- * accessed. To ensure the entry will later be revalidated, we leave
- * it in invalid state, but allow use (cf. RelationIdGetRelation()).
- */
- if (criticalRelcachesBuilt)
- {
- HeapTuple pg_class_tuple;
- Form_pg_class relp;
+ case RELKIND_INDEX:
/*
- * NB: Mark the entry as valid before starting to scan, to avoid
- * self-recursion when re-building pg_class.
+ * If it's a nailed-but-not-mapped index, then we need to re-read
+ * the pg_class row to see if its relfilenode changed.
*/
- relation->rd_isvalid = true;
-
- pg_class_tuple = ScanPgRelation(RelationGetRelid(relation),
- true, false);
- relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);
- memcpy(relation->rd_rel, relp, CLASS_TUPLE_SIZE);
- heap_freetuple(pg_class_tuple);
+ RelationReloadIndexInfo(relation);
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
/*
- * Again mark as valid, to protect against concurrently arriving
- * invalidations.
+ * Reload a non-index entry. We can't easily do so if relcaches
+ * aren't yet built, but that's fine because at that stage the
+ * attributes that need to be current (like relfrozenxid) aren't
+ * yet accessed. To ensure the entry will later be revalidated,
+ * we leave it in invalid state, but allow use (cf.
+ * RelationIdGetRelation()).
*/
- relation->rd_isvalid = true;
- }
+ if (criticalRelcachesBuilt)
+ {
+ HeapTuple pg_class_tuple;
+ Form_pg_class relp;
+
+ /*
+ * NB: Mark the entry as valid before starting to scan, to
+ * avoid self-recursion when re-building pg_class.
+ */
+ relation->rd_isvalid = true;
+
+ pg_class_tuple = ScanPgRelation(RelationGetRelid(relation),
+ true, false);
+ relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);
+ memcpy(relation->rd_rel, relp, CLASS_TUPLE_SIZE);
+ heap_freetuple(pg_class_tuple);
+
+ /*
+ * Again mark as valid, to protect against concurrently
+ * arriving invalidations.
+ */
+ relation->rd_isvalid = true;
+ }
+ break;
}
}
@@ -2470,14 +2519,28 @@ RelationClearRelation(Relation relation, bool rebuild)
* re-read the pg_class row to handle possible physical relocation of the
* index, and we check for pg_index updates too.
*/
- if ((relation->rd_rel->relkind == RELKIND_INDEX ||
- relation->rd_rel->relkind == RELKIND_PARTITIONED_INDEX) &&
- relation->rd_refcnt > 0 &&
- relation->rd_indexcxt != NULL)
+ switch ((RelKind) relation->rd_rel->relkind)
{
- if (IsTransactionState())
- RelationReloadIndexInfo(relation);
- return;
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ if (relation->rd_refcnt > 0 && relation->rd_indexcxt != NULL)
+ {
+ if (IsTransactionState())
+ RelationReloadIndexInfo(relation);
+ return;
+ }
+ break;
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
/*
@@ -3478,10 +3541,25 @@ RelationBuildLocalRelation(const char *relname,
}
/* if it's a materialized view, it's not populated initially */
- if (relkind == RELKIND_MATVIEW)
- rel->rd_rel->relispopulated = false;
- else
- rel->rd_rel->relispopulated = true;
+ switch ((RelKind) relkind)
+ {
+ case RELKIND_MATVIEW:
+ rel->rd_rel->relispopulated = false;
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ rel->rd_rel->relispopulated = true;
+ break;
+ }
/* set replica identity -- system catalogs and non-tables don't have one */
if (!IsCatalogNamespace(relnamespace) &&
@@ -3521,11 +3599,23 @@ RelationBuildLocalRelation(const char *relname,
rel->rd_rel->relam = accessmtd;
- if (relkind == RELKIND_RELATION ||
- relkind == RELKIND_SEQUENCE ||
- relkind == RELKIND_TOASTVALUE ||
- relkind == RELKIND_MATVIEW)
- RelationInitTableAccessMethod(rel);
+ switch ((RelKind) relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_MATVIEW:
+ RelationInitTableAccessMethod(rel);
+ break;
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
/*
* Okay to insert into the relcache hash table.
@@ -3618,7 +3708,7 @@ RelationSetNewRelfilenode(Relation relation, char persistence)
newrnode = relation->rd_node;
newrnode.relNode = newrelfilenode;
- switch (relation->rd_rel->relkind)
+ switch ((RelKind) relation->rd_rel->relkind)
{
case RELKIND_INDEX:
case RELKIND_SEQUENCE:
@@ -3630,7 +3720,6 @@ RelationSetNewRelfilenode(Relation relation, char persistence)
smgrclose(srel);
}
break;
-
case RELKIND_RELATION:
case RELKIND_TOASTVALUE:
case RELKIND_MATVIEW:
@@ -3638,7 +3727,12 @@ RelationSetNewRelfilenode(Relation relation, char persistence)
persistence,
&freezeXid, &minmulti);
break;
-
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
default:
/* we shouldn't be called for anything else */
elog(ERROR, "relation \"%s\" does not have storage",
@@ -3688,11 +3782,25 @@ RelationSetNewRelfilenode(Relation relation, char persistence)
classform->relfilenode = newrelfilenode;
/* relpages etc. never change for sequences */
- if (relation->rd_rel->relkind != RELKIND_SEQUENCE)
+ switch ((RelKind) relation->rd_rel->relkind)
{
- classform->relpages = 0; /* it's empty until further notice */
- classform->reltuples = 0;
- classform->relallvisible = 0;
+ case RELKIND_SEQUENCE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ classform->relpages = 0; /* it's empty until further notice */
+ classform->reltuples = 0;
+ classform->relallvisible = 0;
+ break;
}
classform->relfrozenxid = freezeXid;
classform->relminmxid = minmulti;
@@ -4085,16 +4193,29 @@ 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))
+ switch ((RelKind) relation->rd_rel->relkind)
{
- RelationInitTableAccessMethod(relation);
- Assert(relation->rd_tableam != NULL);
+ case RELKIND_RELATION:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_MATVIEW:
+ if (relation->rd_tableam == NULL)
+ {
+ RelationInitTableAccessMethod(relation);
+ Assert(relation->rd_tableam != NULL);
- restart = true;
+ restart = true;
+ }
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
/* Release hold on the relation */
@@ -5863,11 +5984,24 @@ 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)
- RelationInitTableAccessMethod(rel);
+ switch ((RelKind) rel->rd_rel->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_SEQUENCE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_MATVIEW:
+ RelationInitTableAccessMethod(rel);
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
Assert(rel->rd_index == NULL);
Assert(rel->rd_indextuple == NULL);
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 786672b1b6..3b0cf8a234 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -1743,12 +1743,12 @@ setup_privileges(FILE *cmdfd)
" SET relacl = (SELECT array_agg(a.acl) FROM "
" (SELECT E'=r/\"$POSTGRES_SUPERUSERNAME\"' as acl "
" UNION SELECT unnest(pg_catalog.acldefault("
- " CASE WHEN relkind = " CppAsString2(RELKIND_SEQUENCE) " THEN 's' "
+ " CASE WHEN relkind = " RelKindAsString(RELKIND_SEQUENCE) " THEN 's' "
" ELSE 'r' END::\"char\"," CppAsString2(BOOTSTRAP_SUPERUSERID) "::oid))"
" ) as a) "
- " WHERE relkind IN (" CppAsString2(RELKIND_RELATION) ", "
- CppAsString2(RELKIND_VIEW) ", " CppAsString2(RELKIND_MATVIEW) ", "
- CppAsString2(RELKIND_SEQUENCE) ")"
+ " WHERE relkind IN (" RelKindAsString(RELKIND_RELATION) ", "
+ RelKindAsString(RELKIND_VIEW) ", " RelKindAsString(RELKIND_MATVIEW) ", "
+ RelKindAsString(RELKIND_SEQUENCE) ")"
" AND relacl IS NULL;\n\n",
"GRANT USAGE ON SCHEMA pg_catalog TO PUBLIC;\n\n",
"GRANT CREATE, USAGE ON SCHEMA public TO PUBLIC;\n\n",
@@ -1765,9 +1765,9 @@ setup_privileges(FILE *cmdfd)
" pg_class"
" WHERE"
" relacl IS NOT NULL"
- " AND relkind IN (" CppAsString2(RELKIND_RELATION) ", "
- CppAsString2(RELKIND_VIEW) ", " CppAsString2(RELKIND_MATVIEW) ", "
- CppAsString2(RELKIND_SEQUENCE) ");\n\n",
+ " AND relkind IN (" RelKindAsString(RELKIND_RELATION) ", "
+ RelKindAsString(RELKIND_VIEW) ", " RelKindAsString(RELKIND_MATVIEW) ", "
+ RelKindAsString(RELKIND_SEQUENCE) ");\n\n",
"INSERT INTO pg_init_privs "
" (objoid, classoid, objsubid, initprivs, privtype)"
" SELECT"
@@ -1781,9 +1781,9 @@ setup_privileges(FILE *cmdfd)
" JOIN pg_attribute ON (pg_class.oid = pg_attribute.attrelid)"
" WHERE"
" pg_attribute.attacl IS NOT NULL"
- " AND pg_class.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
- CppAsString2(RELKIND_VIEW) ", " CppAsString2(RELKIND_MATVIEW) ", "
- CppAsString2(RELKIND_SEQUENCE) ");\n\n",
+ " AND pg_class.relkind IN (" RelKindAsString(RELKIND_RELATION) ", "
+ RelKindAsString(RELKIND_VIEW) ", " RelKindAsString(RELKIND_MATVIEW) ", "
+ RelKindAsString(RELKIND_SEQUENCE) ");\n\n",
"INSERT INTO pg_init_privs "
" (objoid, classoid, objsubid, initprivs, privtype)"
" SELECT"
diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c
index 4ea59f5494..cc85c9ef15 100644
--- a/src/bin/pg_dump/common.c
+++ b/src/bin/pg_dump/common.c
@@ -283,10 +283,23 @@ flagInhTables(Archive *fout, TableInfo *tblinfo, int numTables,
bool mark_parents = true;
/* Some kinds never have parents */
- if (tblinfo[i].relkind == RELKIND_SEQUENCE ||
- tblinfo[i].relkind == RELKIND_VIEW ||
- tblinfo[i].relkind == RELKIND_MATVIEW)
- continue;
+ switch ((RelKind) tblinfo[i].relkind)
+ {
+ case RELKIND_SEQUENCE:
+ case RELKIND_VIEW:
+ case RELKIND_MATVIEW:
+ continue;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
/*
* Normally, we don't bother computing anything for non-target tables,
@@ -449,10 +462,23 @@ flagInhAttrs(DumpOptions *dopt, TableInfo *tblinfo, int numTables)
TableInfo **parents;
/* Some kinds never have parents */
- if (tbinfo->relkind == RELKIND_SEQUENCE ||
- tbinfo->relkind == RELKIND_VIEW ||
- tbinfo->relkind == RELKIND_MATVIEW)
- continue;
+ switch ((RelKind) tbinfo->relkind)
+ {
+ case RELKIND_SEQUENCE:
+ case RELKIND_VIEW:
+ case RELKIND_MATVIEW:
+ continue;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
/* Don't bother computing anything for non-target tables, either */
if (!tbinfo->dobj.dump)
diff --git a/src/bin/pg_dump/pg_backup_tar.c b/src/bin/pg_dump/pg_backup_tar.c
index b4f5942959..0b04578b9a 100644
--- a/src/bin/pg_dump/pg_backup_tar.c
+++ b/src/bin/pg_dump/pg_backup_tar.c
@@ -1191,7 +1191,7 @@ _tarPositionTo(ArchiveHandle *AH, const char *filename)
/* Header doesn't match, so read to next header */
len = th->fileLen;
len += tarPaddingBytesRequired(th->fileLen);
- blks = len / TAR_BLOCK_SIZE; /* # of tar blocks */
+ blks = len / TAR_BLOCK_SIZE; /* # of tar blocks */
for (i = 0; i < blks; i++)
_tarReadRaw(AH, &header[0], TAR_BLOCK_SIZE, NULL, ctx->tarFH);
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index a41a3db876..9fcdf0ddbc 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -2399,17 +2399,35 @@ makeTableDataInfo(DumpOptions *dopt, TableInfo *tbinfo)
return;
/* Skip VIEWs (no data to dump) */
- if (tbinfo->relkind == RELKIND_VIEW)
- return;
- /* Skip FOREIGN TABLEs (no data to dump) unless requested explicitly */
- if (tbinfo->relkind == RELKIND_FOREIGN_TABLE &&
- (foreign_servers_include_oids.head == NULL ||
- !simple_oid_list_member(&foreign_servers_include_oids,
- tbinfo->foreign_server)))
- return;
- /* Skip partitioned tables (data in partitions) */
- if (tbinfo->relkind == RELKIND_PARTITIONED_TABLE)
- return;
+ switch ((RelKind) tbinfo->relkind)
+ {
+ case RELKIND_VIEW:
+ return;
+
+ /*
+ * Skip FOREIGN TABLEs (no data to dump) unless requested
+ * explicitly
+ */
+ case RELKIND_FOREIGN_TABLE:
+ if (foreign_servers_include_oids.head == NULL ||
+ !simple_oid_list_member(&foreign_servers_include_oids,
+ tbinfo->foreign_server))
+ return;
+ break;
+ /* Skip partitioned tables (data in partitions) */
+ case RELKIND_PARTITIONED_TABLE:
+ return;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
/* Don't dump data in unlogged tables, if so requested */
if (tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED &&
@@ -2424,12 +2442,27 @@ makeTableDataInfo(DumpOptions *dopt, TableInfo *tbinfo)
/* OK, let's dump it */
tdinfo = (TableDataInfo *) pg_malloc(sizeof(TableDataInfo));
- if (tbinfo->relkind == RELKIND_MATVIEW)
- tdinfo->dobj.objType = DO_REFRESH_MATVIEW;
- else if (tbinfo->relkind == RELKIND_SEQUENCE)
- tdinfo->dobj.objType = DO_SEQUENCE_SET;
- else
- tdinfo->dobj.objType = DO_TABLE_DATA;
+ switch ((RelKind) tbinfo->relkind)
+ {
+ case RELKIND_MATVIEW:
+ tdinfo->dobj.objType = DO_REFRESH_MATVIEW;
+ break;
+ case RELKIND_SEQUENCE:
+ tdinfo->dobj.objType = DO_SEQUENCE_SET;
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ tdinfo->dobj.objType = DO_TABLE_DATA;
+ break;
+ }
/*
* Note: use tableoid 0 so that this object won't be mistaken for
@@ -2476,14 +2509,14 @@ buildMatViewRefreshDependencies(Archive *fout)
"SELECT d1.objid, d2.refobjid, c2.relkind AS refrelkind "
"FROM pg_depend d1 "
"JOIN pg_class c1 ON c1.oid = d1.objid "
- "AND c1.relkind = " CppAsString2(RELKIND_MATVIEW)
+ "AND c1.relkind = " RelKindAsString(RELKIND_MATVIEW)
" JOIN pg_rewrite r1 ON r1.ev_class = d1.objid "
"JOIN pg_depend d2 ON d2.classid = 'pg_rewrite'::regclass "
"AND d2.objid = r1.oid "
"AND d2.refobjid <> d1.objid "
"JOIN pg_class c2 ON c2.oid = d2.refobjid "
- "AND c2.relkind IN (" CppAsString2(RELKIND_MATVIEW) ","
- CppAsString2(RELKIND_VIEW) ") "
+ "AND c2.relkind IN (" RelKindAsString(RELKIND_MATVIEW) ","
+ RelKindAsString(RELKIND_VIEW) ") "
"WHERE d1.classid = 'pg_class'::regclass "
"UNION "
"SELECT w.objid, d3.refobjid, c3.relkind "
@@ -2493,12 +2526,12 @@ buildMatViewRefreshDependencies(Archive *fout)
"AND d3.objid = r3.oid "
"AND d3.refobjid <> w.refobjid "
"JOIN pg_class c3 ON c3.oid = d3.refobjid "
- "AND c3.relkind IN (" CppAsString2(RELKIND_MATVIEW) ","
- CppAsString2(RELKIND_VIEW) ") "
+ "AND c3.relkind IN (" RelKindAsString(RELKIND_MATVIEW) ","
+ RelKindAsString(RELKIND_VIEW) ") "
") "
"SELECT 'pg_class'::regclass::oid AS classid, objid, refobjid "
"FROM w "
- "WHERE refrelkind = " CppAsString2(RELKIND_MATVIEW));
+ "WHERE refrelkind = " RelKindAsString(RELKIND_MATVIEW));
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
@@ -2637,9 +2670,23 @@ guessConstraintInheritance(TableInfo *tblinfo, int numTables)
TableInfo *parent;
/* Sequences and views never have parents */
- if (tbinfo->relkind == RELKIND_SEQUENCE ||
- tbinfo->relkind == RELKIND_VIEW)
- continue;
+ switch ((RelKind) tbinfo->relkind)
+ {
+ case RELKIND_SEQUENCE:
+ case RELKIND_VIEW:
+ continue;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
/* Don't bother computing anything for non-target tables, either */
if (!(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
@@ -4068,9 +4115,23 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables)
/*
* Only regular and partitioned tables can be added to publications.
*/
- if (tbinfo->relkind != RELKIND_RELATION &&
- tbinfo->relkind != RELKIND_PARTITIONED_TABLE)
- continue;
+ switch ((RelKind) tbinfo->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ continue;
+ }
/*
* Ignore publication membership of tables whose definitions are not
@@ -6157,7 +6218,7 @@ getTables(Archive *fout, int *numTables)
buildACLQueries(acl_subquery, racl_subquery, initacl_subquery,
initracl_subquery, "c.relacl", "c.relowner",
- "CASE WHEN c.relkind = " CppAsString2(RELKIND_SEQUENCE)
+ "CASE WHEN c.relkind = " RelKindAsString(RELKIND_SEQUENCE)
" THEN 's' ELSE 'r' END::\"char\"",
dopt->binary_upgrade);
@@ -6786,10 +6847,25 @@ getTables(Archive *fout, int *numTables)
/*
* Decide whether we want to dump this table.
*/
- if (tblinfo[i].relkind == RELKIND_COMPOSITE_TYPE)
- tblinfo[i].dobj.dump = DUMP_COMPONENT_NONE;
- else
- selectDumpableTable(&tblinfo[i], fout);
+ switch ((RelKind) tblinfo[i].relkind)
+ {
+ case RELKIND_COMPOSITE_TYPE:
+ tblinfo[i].dobj.dump = DUMP_COMPONENT_NONE;
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ selectDumpableTable(&tblinfo[i], fout);
+ break;
+ }
/*
* If the table-level and all column-level ACLs for this table are
@@ -6836,16 +6912,31 @@ getTables(Archive *fout, int *numTables)
* We only need to lock the table for certain components; see
* pg_dump.h
*/
- if (tblinfo[i].dobj.dump &&
- (tblinfo[i].relkind == RELKIND_RELATION ||
- tblinfo->relkind == RELKIND_PARTITIONED_TABLE) &&
- (tblinfo[i].dobj.dump & DUMP_COMPONENTS_REQUIRING_LOCK))
+ switch ((RelKind) tblinfo[i].relkind)
{
- resetPQExpBuffer(query);
- appendPQExpBuffer(query,
- "LOCK TABLE %s IN ACCESS SHARE MODE",
- fmtQualifiedDumpable(&tblinfo[i]));
- ExecuteSqlStatement(fout, query->data);
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
+ if (tblinfo[i].dobj.dump &&
+ (tblinfo[i].dobj.dump & DUMP_COMPONENTS_REQUIRING_LOCK))
+ {
+ resetPQExpBuffer(query);
+ appendPQExpBuffer(query,
+ "LOCK TABLE %s IN ACCESS SHARE MODE",
+ fmtQualifiedDumpable(&tblinfo[i]));
+ ExecuteSqlStatement(fout, query->data);
+ }
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
/* Emit notice if join for owner failed */
@@ -15749,7 +15840,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
char *srvname = NULL;
char *foreign = "";
- switch (tbinfo->relkind)
+ switch ((RelKind) tbinfo->relkind)
{
case RELKIND_FOREIGN_TABLE:
{
@@ -15788,8 +15879,21 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
case RELKIND_MATVIEW:
reltypename = "MATERIALIZED VIEW";
break;
- default:
+ case RELKIND_RELATION:
+ case RELKIND_PARTITIONED_TABLE:
reltypename = "TABLE";
+ break;
+ case RELKIND_SEQUENCE:
+ case RELKIND_VIEW:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ Assert(false);
+ reltypename = "XXX";
+ break;
}
numParents = tbinfo->numParents;
diff --git a/src/bin/pg_dump/pg_dump_sort.c b/src/bin/pg_dump/pg_dump_sort.c
index 654e2ec514..1e1da953c8 100644
--- a/src/bin/pg_dump/pg_dump_sort.c
+++ b/src/bin/pg_dump/pg_dump_sort.c
@@ -801,8 +801,24 @@ repairMatViewBoundaryMultiLoop(DumpableObject *boundaryobj,
{
TableInfo *nextinfo = (TableInfo *) nextobj;
- if (nextinfo->relkind == RELKIND_MATVIEW)
- nextinfo->postponed_def = true;
+ switch ((RelKind) nextinfo->relkind)
+ {
+ case RELKIND_MATVIEW:
+ nextinfo->postponed_def = true;
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
+ }
}
}
@@ -928,30 +944,61 @@ repairDependencyLoop(DumpableObject **loop,
return;
}
- /* View (including matview) and its ON SELECT rule */
- if (nLoop == 2 &&
- loop[0]->objType == DO_TABLE &&
- loop[1]->objType == DO_RULE &&
- (((TableInfo *) loop[0])->relkind == RELKIND_VIEW ||
- ((TableInfo *) loop[0])->relkind == RELKIND_MATVIEW) &&
- ((RuleInfo *) loop[1])->ev_type == '1' &&
- ((RuleInfo *) loop[1])->is_instead &&
- ((RuleInfo *) loop[1])->ruletable == (TableInfo *) loop[0])
+ switch ((RelKind) ((TableInfo *) loop[0])->relkind)
{
- repairViewRuleLoop(loop[0], loop[1]);
- return;
+ case RELKIND_VIEW:
+ case RELKIND_MATVIEW:
+ /* View (including matview) and its ON SELECT rule */
+ if (nLoop == 2 &&
+ loop[0]->objType == DO_TABLE &&
+ loop[1]->objType == DO_RULE &&
+ ((RuleInfo *) loop[1])->ev_type == '1' &&
+ ((RuleInfo *) loop[1])->is_instead &&
+ ((RuleInfo *) loop[1])->ruletable == (TableInfo *) loop[0])
+ {
+ repairViewRuleLoop(loop[0], loop[1]);
+ return;
+ }
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
}
- if (nLoop == 2 &&
- loop[1]->objType == DO_TABLE &&
- loop[0]->objType == DO_RULE &&
- (((TableInfo *) loop[1])->relkind == RELKIND_VIEW ||
- ((TableInfo *) loop[1])->relkind == RELKIND_MATVIEW) &&
- ((RuleInfo *) loop[0])->ev_type == '1' &&
- ((RuleInfo *) loop[0])->is_instead &&
- ((RuleInfo *) loop[0])->ruletable == (TableInfo *) loop[1])
+
+ switch ((RelKind) ((TableInfo *) loop[1])->relkind)
{
- repairViewRuleLoop(loop[1], loop[0]);
- return;
+ case RELKIND_VIEW:
+ case RELKIND_MATVIEW:
+ if (nLoop == 2 &&
+ loop[1]->objType == DO_TABLE &&
+ loop[0]->objType == DO_RULE &&
+ ((RuleInfo *) loop[0])->ev_type == '1' &&
+ ((RuleInfo *) loop[0])->is_instead &&
+ ((RuleInfo *) loop[0])->ruletable == (TableInfo *) loop[1])
+ {
+ repairViewRuleLoop(loop[1], loop[0]);
+ return;
+ }
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
}
/* Indirect loop involving view (but not matview) and ON SELECT rule */
@@ -959,20 +1006,36 @@ repairDependencyLoop(DumpableObject **loop,
{
for (i = 0; i < nLoop; i++)
{
- if (loop[i]->objType == DO_TABLE &&
- ((TableInfo *) loop[i])->relkind == RELKIND_VIEW)
+ switch ((RelKind) ((TableInfo *) loop[i])->relkind)
{
- for (j = 0; j < nLoop; j++)
- {
- if (loop[j]->objType == DO_RULE &&
- ((RuleInfo *) loop[j])->ev_type == '1' &&
- ((RuleInfo *) loop[j])->is_instead &&
- ((RuleInfo *) loop[j])->ruletable == (TableInfo *) loop[i])
+ case RELKIND_VIEW:
+ if (loop[i]->objType == DO_TABLE)
{
- repairViewRuleMultiLoop(loop[i], loop[j]);
- return;
+ for (j = 0; j < nLoop; j++)
+ {
+ if (loop[j]->objType == DO_RULE &&
+ ((RuleInfo *) loop[j])->ev_type == '1' &&
+ ((RuleInfo *) loop[j])->is_instead &&
+ ((RuleInfo *) loop[j])->ruletable == (TableInfo *) loop[i])
+ {
+ repairViewRuleMultiLoop(loop[i], loop[j]);
+ return;
+ }
+ }
}
- }
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
}
}
}
@@ -982,20 +1045,36 @@ repairDependencyLoop(DumpableObject **loop,
{
for (i = 0; i < nLoop; i++)
{
- if (loop[i]->objType == DO_TABLE &&
- ((TableInfo *) loop[i])->relkind == RELKIND_MATVIEW)
+ switch ((RelKind) ((TableInfo *) loop[i])->relkind)
{
- for (j = 0; j < nLoop; j++)
- {
- if (loop[j]->objType == DO_PRE_DATA_BOUNDARY)
+ case RELKIND_MATVIEW:
+ if (loop[i]->objType == DO_TABLE)
{
- DumpableObject *nextobj;
-
- nextobj = (j < nLoop - 1) ? loop[j + 1] : loop[0];
- repairMatViewBoundaryMultiLoop(loop[j], nextobj);
- return;
+ for (j = 0; j < nLoop; j++)
+ {
+ if (loop[j]->objType == DO_PRE_DATA_BOUNDARY)
+ {
+ DumpableObject *nextobj;
+
+ nextobj = (j < nLoop - 1) ? loop[j + 1] : loop[0];
+ repairMatViewBoundaryMultiLoop(loop[j], nextobj);
+ return;
+ }
+ }
}
- }
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
}
}
diff --git a/src/bin/pg_upgrade/info.c b/src/bin/pg_upgrade/info.c
index 7e524ea192..d67da370c5 100644
--- a/src/bin/pg_upgrade/info.c
+++ b/src/bin/pg_upgrade/info.c
@@ -446,8 +446,8 @@ get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo)
" SELECT c.oid, 0::oid, 0::oid "
" FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n "
" ON c.relnamespace = n.oid "
- " WHERE relkind IN (" CppAsString2(RELKIND_RELATION) ", "
- CppAsString2(RELKIND_MATVIEW) ") AND "
+ " WHERE relkind IN (" RelKindAsString(RELKIND_RELATION) ", "
+ RelKindAsString(RELKIND_MATVIEW) ") AND "
/* exclude possible orphaned temp tables */
" ((n.nspname !~ '^pg_temp_' AND "
" n.nspname !~ '^pg_toast_temp_' AND "
diff --git a/src/bin/pg_upgrade/pg_upgrade.c b/src/bin/pg_upgrade/pg_upgrade.c
index 70194eb096..996bf8bf70 100644
--- a/src/bin/pg_upgrade/pg_upgrade.c
+++ b/src/bin/pg_upgrade/pg_upgrade.c
@@ -643,9 +643,9 @@ set_frozenxids(bool minmxid_only)
"SET relfrozenxid = '%u' "
/* only heap, materialized view, and TOAST are vacuumed */
"WHERE relkind IN ("
- CppAsString2(RELKIND_RELATION) ", "
- CppAsString2(RELKIND_MATVIEW) ", "
- CppAsString2(RELKIND_TOASTVALUE) ")",
+ RelKindAsString(RELKIND_RELATION) ", "
+ RelKindAsString(RELKIND_MATVIEW) ", "
+ RelKindAsString(RELKIND_TOASTVALUE) ")",
old_cluster.controldata.chkpnt_nxtxid));
/* set pg_class.relminmxid */
@@ -654,9 +654,9 @@ set_frozenxids(bool minmxid_only)
"SET relminmxid = '%u' "
/* only heap, materialized view, and TOAST are vacuumed */
"WHERE relkind IN ("
- CppAsString2(RELKIND_RELATION) ", "
- CppAsString2(RELKIND_MATVIEW) ", "
- CppAsString2(RELKIND_TOASTVALUE) ")",
+ RelKindAsString(RELKIND_RELATION) ", "
+ RelKindAsString(RELKIND_MATVIEW) ", "
+ RelKindAsString(RELKIND_TOASTVALUE) ")",
old_cluster.controldata.chkpnt_nxtmulti));
PQfinish(conn);
diff --git a/src/bin/pg_upgrade/version.c b/src/bin/pg_upgrade/version.c
index 4e5d27f76e..5fb158c093 100644
--- a/src/bin/pg_upgrade/version.c
+++ b/src/bin/pg_upgrade/version.c
@@ -176,9 +176,9 @@ check_for_data_type_usage(ClusterInfo *cluster, const char *typename,
" NOT a.attisdropped AND "
" a.atttypid IN (SELECT oid FROM oids) AND "
" c.relkind IN ("
- CppAsString2(RELKIND_RELATION) ", "
- CppAsString2(RELKIND_MATVIEW) ", "
- CppAsString2(RELKIND_INDEX) ") AND "
+ RelKindAsString(RELKIND_RELATION) ", "
+ RelKindAsString(RELKIND_MATVIEW) ", "
+ RelKindAsString(RELKIND_INDEX) ") AND "
" c.relnamespace = n.oid AND "
/* exclude possible orphaned temp tables */
" n.nspname !~ '^pg_temp_' AND "
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 560eacc7f0..5e0f7f92c6 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -4942,16 +4942,25 @@ get_create_object_cmd(EditableObjectType obj_type, Oid oid,
* does not, so editing a matview definition in this way
* is impossible.
*/
- switch (relkind[0])
+ switch ((RelKind) relkind[0])
{
-#ifdef NOT_USED
+ case RELKIND_VIEW:
+ appendPQExpBufferStr(buf, "CREATE OR REPLACE VIEW ");
+ break;
case RELKIND_MATVIEW:
+#ifdef NOT_USED
appendPQExpBufferStr(buf, "CREATE OR REPLACE MATERIALIZED VIEW ");
break;
#endif
- case RELKIND_VIEW:
- appendPQExpBufferStr(buf, "CREATE OR REPLACE VIEW ");
- break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
default:
pg_log_error("\"%s.%s\" is not a view",
nspname, relname);
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index cd39b913cd..67675cc0c3 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -734,7 +734,7 @@ describeTypes(const char *pattern, bool verbose, bool showSystem)
* composite types
*/
appendPQExpBufferStr(&buf, "WHERE (t.typrelid = 0 ");
- appendPQExpBufferStr(&buf, "OR (SELECT c.relkind = " CppAsString2(RELKIND_COMPOSITE_TYPE)
+ appendPQExpBufferStr(&buf, "OR (SELECT c.relkind = " RelKindAsString(RELKIND_COMPOSITE_TYPE)
" FROM pg_catalog.pg_class c "
"WHERE c.oid = t.typrelid))\n");
@@ -943,12 +943,12 @@ permissionsList(const char *pattern)
"SELECT n.nspname as \"%s\",\n"
" c.relname as \"%s\",\n"
" CASE c.relkind"
- " WHEN " CppAsString2(RELKIND_RELATION) " THEN '%s'"
- " WHEN " CppAsString2(RELKIND_VIEW) " THEN '%s'"
- " WHEN " CppAsString2(RELKIND_MATVIEW) " THEN '%s'"
- " WHEN " CppAsString2(RELKIND_SEQUENCE) " THEN '%s'"
- " WHEN " CppAsString2(RELKIND_FOREIGN_TABLE) " THEN '%s'"
- " WHEN " CppAsString2(RELKIND_PARTITIONED_TABLE) " THEN '%s'"
+ " WHEN " RelKindAsString(RELKIND_RELATION) " THEN '%s'"
+ " WHEN " RelKindAsString(RELKIND_VIEW) " THEN '%s'"
+ " WHEN " RelKindAsString(RELKIND_MATVIEW) " THEN '%s'"
+ " WHEN " RelKindAsString(RELKIND_SEQUENCE) " THEN '%s'"
+ " WHEN " RelKindAsString(RELKIND_FOREIGN_TABLE) " THEN '%s'"
+ " WHEN " RelKindAsString(RELKIND_PARTITIONED_TABLE) " THEN '%s'"
" END as \"%s\",\n"
" ",
gettext_noop("Schema"),
@@ -1040,12 +1040,12 @@ permissionsList(const char *pattern)
appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_class c\n"
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace\n"
"WHERE c.relkind IN ("
- CppAsString2(RELKIND_RELATION) ","
- CppAsString2(RELKIND_VIEW) ","
- CppAsString2(RELKIND_MATVIEW) ","
- CppAsString2(RELKIND_SEQUENCE) ","
- CppAsString2(RELKIND_FOREIGN_TABLE) ","
- CppAsString2(RELKIND_PARTITIONED_TABLE) ")\n");
+ RelKindAsString(RELKIND_RELATION) ","
+ RelKindAsString(RELKIND_VIEW) ","
+ RelKindAsString(RELKIND_MATVIEW) ","
+ RelKindAsString(RELKIND_SEQUENCE) ","
+ RelKindAsString(RELKIND_FOREIGN_TABLE) ","
+ RelKindAsString(RELKIND_PARTITIONED_TABLE) ")\n");
/*
* Unless a schema pattern is specified, we suppress system and temp
@@ -1692,134 +1692,148 @@ describeOneTableDetails(const char *schemaname,
/*
* If it's a sequence, deal with it here separately.
*/
- if (tableinfo.relkind == RELKIND_SEQUENCE)
+ switch ((RelKind) tableinfo.relkind)
{
- PGresult *result = NULL;
- printQueryOpt myopt = pset.popt;
- char *footers[2] = {NULL, NULL};
-
- if (pset.sversion >= 100000)
- {
- printfPQExpBuffer(&buf,
- "SELECT pg_catalog.format_type(seqtypid, NULL) AS \"%s\",\n"
- " seqstart AS \"%s\",\n"
- " seqmin AS \"%s\",\n"
- " seqmax AS \"%s\",\n"
- " seqincrement AS \"%s\",\n"
- " CASE WHEN seqcycle THEN '%s' ELSE '%s' END AS \"%s\",\n"
- " seqcache AS \"%s\"\n",
- gettext_noop("Type"),
- gettext_noop("Start"),
- gettext_noop("Minimum"),
- gettext_noop("Maximum"),
- gettext_noop("Increment"),
- gettext_noop("yes"),
- gettext_noop("no"),
- gettext_noop("Cycles?"),
- gettext_noop("Cache"));
- appendPQExpBuffer(&buf,
- "FROM pg_catalog.pg_sequence\n"
- "WHERE seqrelid = '%s';",
- oid);
- }
- else
- {
- printfPQExpBuffer(&buf,
- "SELECT 'bigint' AS \"%s\",\n"
- " start_value AS \"%s\",\n"
- " min_value AS \"%s\",\n"
- " max_value AS \"%s\",\n"
- " increment_by AS \"%s\",\n"
- " CASE WHEN is_cycled THEN '%s' ELSE '%s' END AS \"%s\",\n"
- " cache_value AS \"%s\"\n",
- gettext_noop("Type"),
- gettext_noop("Start"),
- gettext_noop("Minimum"),
- gettext_noop("Maximum"),
- gettext_noop("Increment"),
- gettext_noop("yes"),
- gettext_noop("no"),
- gettext_noop("Cycles?"),
- gettext_noop("Cache"));
- appendPQExpBuffer(&buf, "FROM %s", fmtId(schemaname));
- /* must be separate because fmtId isn't reentrant */
- appendPQExpBuffer(&buf, ".%s;", fmtId(relationname));
- }
+ case RELKIND_SEQUENCE:
+ {
+ PGresult *result = NULL;
+ printQueryOpt myopt = pset.popt;
+ char *footers[2] = {NULL, NULL};
- res = PSQLexec(buf.data);
- if (!res)
- goto error_return;
+ if (pset.sversion >= 100000)
+ {
+ printfPQExpBuffer(&buf,
+ "SELECT pg_catalog.format_type(seqtypid, NULL) AS \"%s\",\n"
+ " seqstart AS \"%s\",\n"
+ " seqmin AS \"%s\",\n"
+ " seqmax AS \"%s\",\n"
+ " seqincrement AS \"%s\",\n"
+ " CASE WHEN seqcycle THEN '%s' ELSE '%s' END AS \"%s\",\n"
+ " seqcache AS \"%s\"\n",
+ gettext_noop("Type"),
+ gettext_noop("Start"),
+ gettext_noop("Minimum"),
+ gettext_noop("Maximum"),
+ gettext_noop("Increment"),
+ gettext_noop("yes"),
+ gettext_noop("no"),
+ gettext_noop("Cycles?"),
+ gettext_noop("Cache"));
+ appendPQExpBuffer(&buf,
+ "FROM pg_catalog.pg_sequence\n"
+ "WHERE seqrelid = '%s';",
+ oid);
+ }
+ else
+ {
+ printfPQExpBuffer(&buf,
+ "SELECT 'bigint' AS \"%s\",\n"
+ " start_value AS \"%s\",\n"
+ " min_value AS \"%s\",\n"
+ " max_value AS \"%s\",\n"
+ " increment_by AS \"%s\",\n"
+ " CASE WHEN is_cycled THEN '%s' ELSE '%s' END AS \"%s\",\n"
+ " cache_value AS \"%s\"\n",
+ gettext_noop("Type"),
+ gettext_noop("Start"),
+ gettext_noop("Minimum"),
+ gettext_noop("Maximum"),
+ gettext_noop("Increment"),
+ gettext_noop("yes"),
+ gettext_noop("no"),
+ gettext_noop("Cycles?"),
+ gettext_noop("Cache"));
+ appendPQExpBuffer(&buf, "FROM %s", fmtId(schemaname));
+ /* must be separate because fmtId isn't reentrant */
+ appendPQExpBuffer(&buf, ".%s;", fmtId(relationname));
+ }
- /* Footer information about a sequence */
+ res = PSQLexec(buf.data);
+ if (!res)
+ goto error_return;
+
+ /* Footer information about a sequence */
+
+ /* Get the column that owns this sequence */
+ printfPQExpBuffer(&buf, "SELECT pg_catalog.quote_ident(nspname) || '.' ||"
+ "\n pg_catalog.quote_ident(relname) || '.' ||"
+ "\n pg_catalog.quote_ident(attname),"
+ "\n d.deptype"
+ "\nFROM pg_catalog.pg_class c"
+ "\nINNER JOIN pg_catalog.pg_depend d ON c.oid=d.refobjid"
+ "\nINNER JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace"
+ "\nINNER JOIN pg_catalog.pg_attribute a ON ("
+ "\n a.attrelid=c.oid AND"
+ "\n a.attnum=d.refobjsubid)"
+ "\nWHERE d.classid='pg_catalog.pg_class'::pg_catalog.regclass"
+ "\n AND d.refclassid='pg_catalog.pg_class'::pg_catalog.regclass"
+ "\n AND d.objid='%s'"
+ "\n AND d.deptype IN ('a', 'i')",
+ oid);
- /* Get the column that owns this sequence */
- printfPQExpBuffer(&buf, "SELECT pg_catalog.quote_ident(nspname) || '.' ||"
- "\n pg_catalog.quote_ident(relname) || '.' ||"
- "\n pg_catalog.quote_ident(attname),"
- "\n d.deptype"
- "\nFROM pg_catalog.pg_class c"
- "\nINNER JOIN pg_catalog.pg_depend d ON c.oid=d.refobjid"
- "\nINNER JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace"
- "\nINNER JOIN pg_catalog.pg_attribute a ON ("
- "\n a.attrelid=c.oid AND"
- "\n a.attnum=d.refobjsubid)"
- "\nWHERE d.classid='pg_catalog.pg_class'::pg_catalog.regclass"
- "\n AND d.refclassid='pg_catalog.pg_class'::pg_catalog.regclass"
- "\n AND d.objid='%s'"
- "\n AND d.deptype IN ('a', 'i')",
- oid);
+ result = PSQLexec(buf.data);
- result = PSQLexec(buf.data);
+ /*
+ * If we get no rows back, don't show anything (obviously). We
+ * should never get more than one row back, but if we do, just
+ * ignore it and don't print anything.
+ */
+ if (!result)
+ goto error_return;
+ else if (PQntuples(result) == 1)
+ {
+ switch (PQgetvalue(result, 0, 1)[0])
+ {
+ case 'a':
+ footers[0] = psprintf(_("Owned by: %s"),
+ PQgetvalue(result, 0, 0));
+ break;
+ case 'i':
+ footers[0] = psprintf(_("Sequence for identity column: %s"),
+ PQgetvalue(result, 0, 0));
+ break;
+ }
+ }
+ PQclear(result);
- /*
- * If we get no rows back, don't show anything (obviously). We should
- * never get more than one row back, but if we do, just ignore it and
- * don't print anything.
- */
- if (!result)
- goto error_return;
- else if (PQntuples(result) == 1)
- {
- switch (PQgetvalue(result, 0, 1)[0])
- {
- case 'a':
- footers[0] = psprintf(_("Owned by: %s"),
- PQgetvalue(result, 0, 0));
- break;
- case 'i':
- footers[0] = psprintf(_("Sequence for identity column: %s"),
- PQgetvalue(result, 0, 0));
- break;
- }
- }
- PQclear(result);
+ printfPQExpBuffer(&title, _("Sequence \"%s.%s\""),
+ schemaname, relationname);
- printfPQExpBuffer(&title, _("Sequence \"%s.%s\""),
- schemaname, relationname);
+ myopt.footers = footers;
+ myopt.topt.default_footer = false;
+ myopt.title = title.data;
+ myopt.translate_header = true;
- myopt.footers = footers;
- myopt.topt.default_footer = false;
- myopt.title = title.data;
- myopt.translate_header = true;
+ printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
- printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
+ if (footers[0])
+ free(footers[0]);
- if (footers[0])
- free(footers[0]);
+ retval = true;
+ goto error_return; /* not an error, just return early */
+ }
+ break;
- retval = true;
- goto error_return; /* not an error, just return early */
+ /*
+ * Identify whether we should print collation, nullable, default
+ * vals
+ */
+ case RELKIND_RELATION:
+ case RELKIND_VIEW:
+ case RELKIND_MATVIEW:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_PARTITIONED_TABLE:
+ show_column_details = true;
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_INDEX:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
}
- /* Identify whether we should print collation, nullable, default vals */
- if (tableinfo.relkind == RELKIND_RELATION ||
- tableinfo.relkind == RELKIND_VIEW ||
- tableinfo.relkind == RELKIND_MATVIEW ||
- tableinfo.relkind == RELKIND_FOREIGN_TABLE ||
- tableinfo.relkind == RELKIND_COMPOSITE_TYPE ||
- tableinfo.relkind == RELKIND_PARTITIONED_TABLE)
- show_column_details = true;
-
/*
* Get per-column info
*
@@ -1861,58 +1875,91 @@ describeOneTableDetails(const char *schemaname,
appendPQExpBufferStr(&buf, ",\n ''::pg_catalog.char AS attgenerated");
attgenerated_col = cols++;
}
- if (tableinfo.relkind == RELKIND_INDEX ||
- tableinfo.relkind == RELKIND_PARTITIONED_INDEX)
- {
- if (pset.sversion >= 110000)
- {
- appendPQExpBuffer(&buf, ",\n CASE WHEN a.attnum <= (SELECT i.indnkeyatts FROM pg_catalog.pg_index i WHERE i.indexrelid = '%s') THEN '%s' ELSE '%s' END AS is_key",
- oid,
- gettext_noop("yes"),
- gettext_noop("no"));
- isindexkey_col = cols++;
- }
- appendPQExpBufferStr(&buf, ",\n pg_catalog.pg_get_indexdef(a.attrelid, a.attnum, TRUE) AS indexdef");
- indexdef_col = cols++;
- }
- /* FDW options for foreign table column, only for 9.2 or later */
- if (tableinfo.relkind == RELKIND_FOREIGN_TABLE && pset.sversion >= 90200)
+ switch ((RelKind) tableinfo.relkind)
{
- appendPQExpBufferStr(&buf, ",\n CASE WHEN attfdwoptions IS NULL THEN '' ELSE "
- " '(' || pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(option_name) || ' ' || pg_catalog.quote_literal(option_value) FROM "
- " pg_catalog.pg_options_to_table(attfdwoptions)), ', ') || ')' END AS attfdwoptions");
- fdwopts_col = cols++;
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ if (pset.sversion >= 110000)
+ {
+ appendPQExpBuffer(&buf, ",\n CASE WHEN a.attnum <= (SELECT i.indnkeyatts FROM pg_catalog.pg_index i WHERE i.indexrelid = '%s') THEN '%s' ELSE '%s' END AS is_key",
+ oid,
+ gettext_noop("yes"),
+ gettext_noop("no"));
+ isindexkey_col = cols++;
+ }
+ appendPQExpBufferStr(&buf, ",\n pg_catalog.pg_get_indexdef(a.attrelid, a.attnum, TRUE) AS indexdef");
+ indexdef_col = cols++;
+ break;
+ case RELKIND_FOREIGN_TABLE:
+ /* FDW options for foreign table column, only for 9.2 or later */
+ if (pset.sversion >= 90200)
+ {
+ appendPQExpBufferStr(&buf, ",\n CASE WHEN attfdwoptions IS NULL THEN '' ELSE "
+ " '(' || pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(option_name) || ' ' || pg_catalog.quote_literal(option_value) FROM "
+ " pg_catalog.pg_options_to_table(attfdwoptions)), ', ') || ')' END AS attfdwoptions");
+ fdwopts_col = cols++;
+ }
+ break;
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_MATVIEW:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
+
if (verbose)
{
appendPQExpBufferStr(&buf, ",\n a.attstorage");
attstorage_col = cols++;
/* stats target, if relevant to relkind */
- if (tableinfo.relkind == RELKIND_RELATION ||
- tableinfo.relkind == RELKIND_INDEX ||
- tableinfo.relkind == RELKIND_PARTITIONED_INDEX ||
- tableinfo.relkind == RELKIND_MATVIEW ||
- tableinfo.relkind == RELKIND_FOREIGN_TABLE ||
- tableinfo.relkind == RELKIND_PARTITIONED_TABLE)
+ switch ((RelKind) tableinfo.relkind)
{
- appendPQExpBufferStr(&buf, ",\n CASE WHEN a.attstattarget=-1 THEN NULL ELSE a.attstattarget END AS attstattarget");
- attstattarget_col = cols++;
+ case RELKIND_RELATION:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ appendPQExpBufferStr(&buf, ",\n CASE WHEN a.attstattarget=-1 THEN NULL ELSE a.attstattarget END AS attstattarget");
+ attstattarget_col = cols++;
+ break;
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
/*
* In 9.0+, we have column comments for: relations, views, composite
* types, and foreign tables (cf. CommentObject() in comment.c).
*/
- if (tableinfo.relkind == RELKIND_RELATION ||
- tableinfo.relkind == RELKIND_VIEW ||
- tableinfo.relkind == RELKIND_MATVIEW ||
- tableinfo.relkind == RELKIND_FOREIGN_TABLE ||
- tableinfo.relkind == RELKIND_COMPOSITE_TYPE ||
- tableinfo.relkind == RELKIND_PARTITIONED_TABLE)
+ switch ((RelKind) tableinfo.relkind)
{
- appendPQExpBufferStr(&buf, ",\n pg_catalog.col_description(a.attrelid, a.attnum)");
- attdescr_col = cols++;
+ case RELKIND_RELATION:
+ case RELKIND_VIEW:
+ case RELKIND_MATVIEW:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_PARTITIONED_TABLE:
+ appendPQExpBufferStr(&buf, ",\n pg_catalog.col_description(a.attrelid, a.attnum)");
+ attdescr_col = cols++;
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_INDEX:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
}
}
@@ -1926,7 +1973,7 @@ describeOneTableDetails(const char *schemaname,
numrows = PQntuples(res);
/* Make title */
- switch (tableinfo.relkind)
+ switch ((RelKind) tableinfo.relkind)
{
case RELKIND_RELATION:
if (tableinfo.relpersistence == 'u')
@@ -1964,11 +2011,6 @@ describeOneTableDetails(const char *schemaname,
printfPQExpBuffer(&title, _("Partitioned index \"%s.%s\""),
schemaname, relationname);
break;
- case 's':
- /* not used as of 8.2, but keep it for backwards compatibility */
- printfPQExpBuffer(&title, _("Special relation \"%s.%s\""),
- schemaname, relationname);
- break;
case RELKIND_TOASTVALUE:
printfPQExpBuffer(&title, _("TOAST table \"%s.%s\""),
schemaname, relationname);
@@ -1989,10 +2031,23 @@ describeOneTableDetails(const char *schemaname,
printfPQExpBuffer(&title, _("Partitioned table \"%s.%s\""),
schemaname, relationname);
break;
+ case RELKIND_SEQUENCE:
+ case RELKIND_NULL:
default:
- /* untranslated unknown relkind */
- printfPQExpBuffer(&title, "?%c? \"%s.%s\"",
- tableinfo.relkind, schemaname, relationname);
+
+ /*
+ * 's' is not used as of 8.2, but we keep it for backwards
+ * compatibility. We cannot handle 's' as a case value without
+ * adding it to enum RelKind, but that would trigger warnings and
+ * errors elsewhere. Handle it here, instead.
+ */
+ if ((RelKind) tableinfo.relkind == 's')
+ printfPQExpBuffer(&title, _("Special relation \"%s.%s\""),
+ schemaname, relationname);
+ else
+ /* untranslated unknown relkind */
+ printfPQExpBuffer(&title, "?%c? \"%s.%s\"",
+ tableinfo.relkind, schemaname, relationname);
break;
}
@@ -2150,742 +2205,806 @@ describeOneTableDetails(const char *schemaname,
PQclear(result);
}
- if (tableinfo.relkind == RELKIND_PARTITIONED_TABLE)
+ switch ((RelKind) tableinfo.relkind)
{
- /* Footer information for a partitioned table (partitioning parent) */
- PGresult *result;
-
- printfPQExpBuffer(&buf,
- "SELECT pg_catalog.pg_get_partkeydef('%s'::pg_catalog.oid);",
- oid);
- result = PSQLexec(buf.data);
- if (!result)
- goto error_return;
+ case RELKIND_PARTITIONED_TABLE:
+ {
+ /*
+ * Footer information for a partitioned table (partitioning
+ * parent)
+ */
+ PGresult *result;
- if (PQntuples(result) == 1)
- {
- char *partkeydef = PQgetvalue(result, 0, 0);
+ printfPQExpBuffer(&buf,
+ "SELECT pg_catalog.pg_get_partkeydef('%s'::pg_catalog.oid);",
+ oid);
+ result = PSQLexec(buf.data);
+ if (!result)
+ goto error_return;
- printfPQExpBuffer(&tmpbuf, _("Partition key: %s"), partkeydef);
- printTableAddFooter(&cont, tmpbuf.data);
- }
- PQclear(result);
- }
+ if (PQntuples(result) == 1)
+ {
+ char *partkeydef = PQgetvalue(result, 0, 0);
- if (tableinfo.relkind == RELKIND_TOASTVALUE)
- {
- /* For a TOAST table, print name of owning table */
- PGresult *result;
+ printfPQExpBuffer(&tmpbuf, _("Partition key: %s"), partkeydef);
+ printTableAddFooter(&cont, tmpbuf.data);
+ }
+ PQclear(result);
+ }
+ break;
- printfPQExpBuffer(&buf,
- "SELECT n.nspname, c.relname\n"
- "FROM pg_catalog.pg_class c"
- " JOIN pg_catalog.pg_namespace n"
- " ON n.oid = c.relnamespace\n"
- "WHERE reltoastrelid = '%s';", oid);
- result = PSQLexec(buf.data);
- if (!result)
- goto error_return;
+ case RELKIND_TOASTVALUE:
+ {
+ /* For a TOAST table, print name of owning table */
+ PGresult *result;
- if (PQntuples(result) == 1)
- {
- char *schemaname = PQgetvalue(result, 0, 0);
- char *relname = PQgetvalue(result, 0, 1);
+ printfPQExpBuffer(&buf,
+ "SELECT n.nspname, c.relname\n"
+ "FROM pg_catalog.pg_class c"
+ " JOIN pg_catalog.pg_namespace n"
+ " ON n.oid = c.relnamespace\n"
+ "WHERE reltoastrelid = '%s';", oid);
+ result = PSQLexec(buf.data);
+ if (!result)
+ goto error_return;
+
+ if (PQntuples(result) == 1)
+ {
+ char *schemaname = PQgetvalue(result, 0, 0);
+ char *relname = PQgetvalue(result, 0, 1);
- printfPQExpBuffer(&tmpbuf, _("Owning table: \"%s.%s\""),
- schemaname, relname);
- printTableAddFooter(&cont, tmpbuf.data);
- }
- PQclear(result);
+ printfPQExpBuffer(&tmpbuf, _("Owning table: \"%s.%s\""),
+ schemaname, relname);
+ printTableAddFooter(&cont, tmpbuf.data);
+ }
+ PQclear(result);
+ }
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_MATVIEW:
+ case RELKIND_RELATION:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
- if (tableinfo.relkind == RELKIND_INDEX ||
- tableinfo.relkind == RELKIND_PARTITIONED_INDEX)
+ switch ((RelKind) tableinfo.relkind)
{
- /* Footer information about an index */
- PGresult *result;
-
- printfPQExpBuffer(&buf,
- "SELECT i.indisunique, i.indisprimary, i.indisclustered, ");
- if (pset.sversion >= 80200)
- appendPQExpBufferStr(&buf, "i.indisvalid,\n");
- else
- appendPQExpBufferStr(&buf, "true AS indisvalid,\n");
- if (pset.sversion >= 90000)
- appendPQExpBufferStr(&buf,
- " (NOT i.indimmediate) AND "
- "EXISTS (SELECT 1 FROM pg_catalog.pg_constraint "
- "WHERE conrelid = i.indrelid AND "
- "conindid = i.indexrelid AND "
- "contype IN ('p','u','x') AND "
- "condeferrable) AS condeferrable,\n"
- " (NOT i.indimmediate) AND "
- "EXISTS (SELECT 1 FROM pg_catalog.pg_constraint "
- "WHERE conrelid = i.indrelid AND "
- "conindid = i.indexrelid AND "
- "contype IN ('p','u','x') AND "
- "condeferred) AS condeferred,\n");
- else
- appendPQExpBufferStr(&buf,
- " false AS condeferrable, false AS condeferred,\n");
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_INDEX:
+ {
+ /* Footer information about an index */
+ PGresult *result;
- if (pset.sversion >= 90400)
- appendPQExpBufferStr(&buf, "i.indisreplident,\n");
- else
- appendPQExpBufferStr(&buf, "false AS indisreplident,\n");
+ printfPQExpBuffer(&buf,
+ "SELECT i.indisunique, i.indisprimary, i.indisclustered, ");
+ if (pset.sversion >= 80200)
+ appendPQExpBufferStr(&buf, "i.indisvalid,\n");
+ else
+ appendPQExpBufferStr(&buf, "true AS indisvalid,\n");
+ if (pset.sversion >= 90000)
+ appendPQExpBufferStr(&buf,
+ " (NOT i.indimmediate) AND "
+ "EXISTS (SELECT 1 FROM pg_catalog.pg_constraint "
+ "WHERE conrelid = i.indrelid AND "
+ "conindid = i.indexrelid AND "
+ "contype IN ('p','u','x') AND "
+ "condeferrable) AS condeferrable,\n"
+ " (NOT i.indimmediate) AND "
+ "EXISTS (SELECT 1 FROM pg_catalog.pg_constraint "
+ "WHERE conrelid = i.indrelid AND "
+ "conindid = i.indexrelid AND "
+ "contype IN ('p','u','x') AND "
+ "condeferred) AS condeferred,\n");
+ else
+ appendPQExpBufferStr(&buf,
+ " false AS condeferrable, false AS condeferred,\n");
- appendPQExpBuffer(&buf, " a.amname, c2.relname, "
- "pg_catalog.pg_get_expr(i.indpred, i.indrelid, true)\n"
- "FROM pg_catalog.pg_index i, pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_am a\n"
- "WHERE i.indexrelid = c.oid AND c.oid = '%s' AND c.relam = a.oid\n"
- "AND i.indrelid = c2.oid;",
- oid);
+ if (pset.sversion >= 90400)
+ appendPQExpBufferStr(&buf, "i.indisreplident,\n");
+ else
+ appendPQExpBufferStr(&buf, "false AS indisreplident,\n");
- result = PSQLexec(buf.data);
- if (!result)
- goto error_return;
- else if (PQntuples(result) != 1)
- {
- PQclear(result);
- goto error_return;
- }
- else
- {
- char *indisunique = PQgetvalue(result, 0, 0);
- char *indisprimary = PQgetvalue(result, 0, 1);
- char *indisclustered = PQgetvalue(result, 0, 2);
- char *indisvalid = PQgetvalue(result, 0, 3);
- char *deferrable = PQgetvalue(result, 0, 4);
- char *deferred = PQgetvalue(result, 0, 5);
- char *indisreplident = PQgetvalue(result, 0, 6);
- char *indamname = PQgetvalue(result, 0, 7);
- char *indtable = PQgetvalue(result, 0, 8);
- char *indpred = PQgetvalue(result, 0, 9);
-
- if (strcmp(indisprimary, "t") == 0)
- printfPQExpBuffer(&tmpbuf, _("primary key, "));
- else if (strcmp(indisunique, "t") == 0)
- printfPQExpBuffer(&tmpbuf, _("unique, "));
- else
- resetPQExpBuffer(&tmpbuf);
- appendPQExpBuffer(&tmpbuf, "%s, ", indamname);
+ appendPQExpBuffer(&buf, " a.amname, c2.relname, "
+ "pg_catalog.pg_get_expr(i.indpred, i.indrelid, true)\n"
+ "FROM pg_catalog.pg_index i, pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_am a\n"
+ "WHERE i.indexrelid = c.oid AND c.oid = '%s' AND c.relam = a.oid\n"
+ "AND i.indrelid = c2.oid;",
+ oid);
- /* we assume here that index and table are in same schema */
- appendPQExpBuffer(&tmpbuf, _("for table \"%s.%s\""),
- schemaname, indtable);
+ result = PSQLexec(buf.data);
+ if (!result)
+ goto error_return;
+ else if (PQntuples(result) != 1)
+ {
+ PQclear(result);
+ goto error_return;
+ }
+ else
+ {
+ char *indisunique = PQgetvalue(result, 0, 0);
+ char *indisprimary = PQgetvalue(result, 0, 1);
+ char *indisclustered = PQgetvalue(result, 0, 2);
+ char *indisvalid = PQgetvalue(result, 0, 3);
+ char *deferrable = PQgetvalue(result, 0, 4);
+ char *deferred = PQgetvalue(result, 0, 5);
+ char *indisreplident = PQgetvalue(result, 0, 6);
+ char *indamname = PQgetvalue(result, 0, 7);
+ char *indtable = PQgetvalue(result, 0, 8);
+ char *indpred = PQgetvalue(result, 0, 9);
+
+ if (strcmp(indisprimary, "t") == 0)
+ printfPQExpBuffer(&tmpbuf, _("primary key, "));
+ else if (strcmp(indisunique, "t") == 0)
+ printfPQExpBuffer(&tmpbuf, _("unique, "));
+ else
+ resetPQExpBuffer(&tmpbuf);
+ appendPQExpBuffer(&tmpbuf, "%s, ", indamname);
- if (strlen(indpred))
- appendPQExpBuffer(&tmpbuf, _(", predicate (%s)"), indpred);
+ /* we assume here that index and table are in same schema */
+ appendPQExpBuffer(&tmpbuf, _("for table \"%s.%s\""),
+ schemaname, indtable);
- if (strcmp(indisclustered, "t") == 0)
- appendPQExpBufferStr(&tmpbuf, _(", clustered"));
+ if (strlen(indpred))
+ appendPQExpBuffer(&tmpbuf, _(", predicate (%s)"), indpred);
- if (strcmp(indisvalid, "t") != 0)
- appendPQExpBufferStr(&tmpbuf, _(", invalid"));
+ if (strcmp(indisclustered, "t") == 0)
+ appendPQExpBufferStr(&tmpbuf, _(", clustered"));
- if (strcmp(deferrable, "t") == 0)
- appendPQExpBufferStr(&tmpbuf, _(", deferrable"));
+ if (strcmp(indisvalid, "t") != 0)
+ appendPQExpBufferStr(&tmpbuf, _(", invalid"));
- if (strcmp(deferred, "t") == 0)
- appendPQExpBufferStr(&tmpbuf, _(", initially deferred"));
+ if (strcmp(deferrable, "t") == 0)
+ appendPQExpBufferStr(&tmpbuf, _(", deferrable"));
- if (strcmp(indisreplident, "t") == 0)
- appendPQExpBufferStr(&tmpbuf, _(", replica identity"));
+ if (strcmp(deferred, "t") == 0)
+ appendPQExpBufferStr(&tmpbuf, _(", initially deferred"));
- printTableAddFooter(&cont, tmpbuf.data);
+ if (strcmp(indisreplident, "t") == 0)
+ appendPQExpBufferStr(&tmpbuf, _(", replica identity"));
- /*
- * If it's a partitioned index, we'll print the tablespace below
- */
- if (tableinfo.relkind == RELKIND_INDEX)
- add_tablespace_footer(&cont, tableinfo.relkind,
- tableinfo.tablespace, true);
- }
+ printTableAddFooter(&cont, tmpbuf.data);
- PQclear(result);
- }
- /* If you add relkinds here, see also "Finish printing..." stanza below */
- else if (tableinfo.relkind == RELKIND_RELATION ||
- tableinfo.relkind == RELKIND_MATVIEW ||
- tableinfo.relkind == RELKIND_FOREIGN_TABLE ||
- tableinfo.relkind == RELKIND_PARTITIONED_TABLE ||
- tableinfo.relkind == RELKIND_PARTITIONED_INDEX ||
- tableinfo.relkind == RELKIND_TOASTVALUE)
- {
- /* Footer information about a table */
- PGresult *result = NULL;
- int tuples = 0;
+ /*
+ * If it's a partitioned index, we'll print the tablespace
+ * below
+ */
+ if (tableinfo.relkind == RELKIND_INDEX)
+ add_tablespace_footer(&cont, tableinfo.relkind,
+ tableinfo.tablespace, true);
+ }
- /* print indexes */
- if (tableinfo.hasindex)
- {
- printfPQExpBuffer(&buf,
- "SELECT c2.relname, i.indisprimary, i.indisunique, i.indisclustered, ");
- if (pset.sversion >= 80200)
- appendPQExpBufferStr(&buf, "i.indisvalid, ");
- else
- appendPQExpBufferStr(&buf, "true as indisvalid, ");
- appendPQExpBufferStr(&buf, "pg_catalog.pg_get_indexdef(i.indexrelid, 0, true),\n ");
- if (pset.sversion >= 90000)
- appendPQExpBufferStr(&buf,
- "pg_catalog.pg_get_constraintdef(con.oid, true), "
- "contype, condeferrable, condeferred");
- else
- appendPQExpBufferStr(&buf,
- "null AS constraintdef, null AS contype, "
- "false AS condeferrable, false AS condeferred");
- if (pset.sversion >= 90400)
- appendPQExpBufferStr(&buf, ", i.indisreplident");
- else
- appendPQExpBufferStr(&buf, ", false AS indisreplident");
- if (pset.sversion >= 80000)
- appendPQExpBufferStr(&buf, ", c2.reltablespace");
- appendPQExpBufferStr(&buf,
- "\nFROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i\n");
- if (pset.sversion >= 90000)
- appendPQExpBufferStr(&buf,
- " LEFT JOIN pg_catalog.pg_constraint con ON (conrelid = i.indrelid AND conindid = i.indexrelid AND contype IN ('p','u','x'))\n");
- appendPQExpBuffer(&buf,
- "WHERE c.oid = '%s' AND c.oid = i.indrelid AND i.indexrelid = c2.oid\n"
- "ORDER BY i.indisprimary DESC, c2.relname;",
- oid);
- result = PSQLexec(buf.data);
- if (!result)
- goto error_return;
- else
- tuples = PQntuples(result);
+ PQclear(result);
+ }
+ break;
- if (tuples > 0)
+ /*
+ * If you add relkinds here, see also "Finish printing..." stanza
+ * below
+ */
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_TOASTVALUE:
{
- printTableAddFooter(&cont, _("Indexes:"));
- for (i = 0; i < tuples; i++)
- {
- /* untranslated index name */
- printfPQExpBuffer(&buf, " \"%s\"",
- PQgetvalue(result, i, 0));
+ /* Footer information about a table */
+ PGresult *result = NULL;
+ int tuples = 0;
- /* If exclusion constraint, print the constraintdef */
- if (strcmp(PQgetvalue(result, i, 7), "x") == 0)
- {
- appendPQExpBuffer(&buf, " %s",
- PQgetvalue(result, i, 6));
- }
+ /* print indexes */
+ if (tableinfo.hasindex)
+ {
+ printfPQExpBuffer(&buf,
+ "SELECT c2.relname, i.indisprimary, i.indisunique, i.indisclustered, ");
+ if (pset.sversion >= 80200)
+ appendPQExpBufferStr(&buf, "i.indisvalid, ");
else
- {
- const char *indexdef;
- const char *usingpos;
+ appendPQExpBufferStr(&buf, "true as indisvalid, ");
+ appendPQExpBufferStr(&buf, "pg_catalog.pg_get_indexdef(i.indexrelid, 0, true),\n ");
+ if (pset.sversion >= 90000)
+ appendPQExpBufferStr(&buf,
+ "pg_catalog.pg_get_constraintdef(con.oid, true), "
+ "contype, condeferrable, condeferred");
+ else
+ appendPQExpBufferStr(&buf,
+ "null AS constraintdef, null AS contype, "
+ "false AS condeferrable, false AS condeferred");
+ if (pset.sversion >= 90400)
+ appendPQExpBufferStr(&buf, ", i.indisreplident");
+ else
+ appendPQExpBufferStr(&buf, ", false AS indisreplident");
+ if (pset.sversion >= 80000)
+ appendPQExpBufferStr(&buf, ", c2.reltablespace");
+ appendPQExpBufferStr(&buf,
+ "\nFROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i\n");
+ if (pset.sversion >= 90000)
+ appendPQExpBufferStr(&buf,
+ " LEFT JOIN pg_catalog.pg_constraint con ON (conrelid = i.indrelid AND conindid = i.indexrelid AND contype IN ('p','u','x'))\n");
+ appendPQExpBuffer(&buf,
+ "WHERE c.oid = '%s' AND c.oid = i.indrelid AND i.indexrelid = c2.oid\n"
+ "ORDER BY i.indisprimary DESC, c2.relname;",
+ oid);
+ result = PSQLexec(buf.data);
+ if (!result)
+ goto error_return;
+ else
+ tuples = PQntuples(result);
- /* Label as primary key or unique (but not both) */
- if (strcmp(PQgetvalue(result, i, 1), "t") == 0)
- appendPQExpBufferStr(&buf, " PRIMARY KEY,");
- else if (strcmp(PQgetvalue(result, i, 2), "t") == 0)
+ if (tuples > 0)
+ {
+ printTableAddFooter(&cont, _("Indexes:"));
+ for (i = 0; i < tuples; i++)
{
- if (strcmp(PQgetvalue(result, i, 7), "u") == 0)
- appendPQExpBufferStr(&buf, " UNIQUE CONSTRAINT,");
+ /* untranslated index name */
+ printfPQExpBuffer(&buf, " \"%s\"",
+ PQgetvalue(result, i, 0));
+
+ /*
+ * If exclusion constraint, print the
+ * constraintdef
+ */
+ if (strcmp(PQgetvalue(result, i, 7), "x") == 0)
+ {
+ appendPQExpBuffer(&buf, " %s",
+ PQgetvalue(result, i, 6));
+ }
else
- appendPQExpBufferStr(&buf, " UNIQUE,");
- }
+ {
+ const char *indexdef;
+ const char *usingpos;
+
+ /*
+ * Label as primary key or unique (but not
+ * both)
+ */
+ if (strcmp(PQgetvalue(result, i, 1), "t") == 0)
+ appendPQExpBufferStr(&buf, " PRIMARY KEY,");
+ else if (strcmp(PQgetvalue(result, i, 2), "t") == 0)
+ {
+ if (strcmp(PQgetvalue(result, i, 7), "u") == 0)
+ appendPQExpBufferStr(&buf, " UNIQUE CONSTRAINT,");
+ else
+ appendPQExpBufferStr(&buf, " UNIQUE,");
+ }
+
+ /* Everything after "USING" is echoed verbatim */
+ indexdef = PQgetvalue(result, i, 5);
+ usingpos = strstr(indexdef, " USING ");
+ if (usingpos)
+ indexdef = usingpos + 7;
+ appendPQExpBuffer(&buf, " %s", indexdef);
+
+ /* Need these for deferrable PK/UNIQUE indexes */
+ if (strcmp(PQgetvalue(result, i, 8), "t") == 0)
+ appendPQExpBufferStr(&buf, " DEFERRABLE");
+
+ if (strcmp(PQgetvalue(result, i, 9), "t") == 0)
+ appendPQExpBufferStr(&buf, " INITIALLY DEFERRED");
+ }
- /* Everything after "USING" is echoed verbatim */
- indexdef = PQgetvalue(result, i, 5);
- usingpos = strstr(indexdef, " USING ");
- if (usingpos)
- indexdef = usingpos + 7;
- appendPQExpBuffer(&buf, " %s", indexdef);
+ /* Add these for all cases */
+ if (strcmp(PQgetvalue(result, i, 3), "t") == 0)
+ appendPQExpBufferStr(&buf, " CLUSTER");
- /* Need these for deferrable PK/UNIQUE indexes */
- if (strcmp(PQgetvalue(result, i, 8), "t") == 0)
- appendPQExpBufferStr(&buf, " DEFERRABLE");
+ if (strcmp(PQgetvalue(result, i, 4), "t") != 0)
+ appendPQExpBufferStr(&buf, " INVALID");
- if (strcmp(PQgetvalue(result, i, 9), "t") == 0)
- appendPQExpBufferStr(&buf, " INITIALLY DEFERRED");
- }
+ if (strcmp(PQgetvalue(result, i, 10), "t") == 0)
+ appendPQExpBufferStr(&buf, " REPLICA IDENTITY");
- /* Add these for all cases */
- if (strcmp(PQgetvalue(result, i, 3), "t") == 0)
- appendPQExpBufferStr(&buf, " CLUSTER");
+ printTableAddFooter(&cont, buf.data);
- if (strcmp(PQgetvalue(result, i, 4), "t") != 0)
- appendPQExpBufferStr(&buf, " INVALID");
+ /* Print tablespace of the index on the same line */
+ if (pset.sversion >= 80000)
+ add_tablespace_footer(&cont, RELKIND_INDEX,
+ atooid(PQgetvalue(result, i, 11)),
+ false);
+ }
+ }
+ PQclear(result);
+ }
- if (strcmp(PQgetvalue(result, i, 10), "t") == 0)
- appendPQExpBufferStr(&buf, " REPLICA IDENTITY");
+ /* print table (and column) check constraints */
+ if (tableinfo.checks)
+ {
+ printfPQExpBuffer(&buf,
+ "SELECT r.conname, "
+ "pg_catalog.pg_get_constraintdef(r.oid, true)\n"
+ "FROM pg_catalog.pg_constraint r\n"
+ "WHERE r.conrelid = '%s' AND r.contype = 'c'\n"
+ "ORDER BY 1;",
+ oid);
+ result = PSQLexec(buf.data);
+ if (!result)
+ goto error_return;
+ else
+ tuples = PQntuples(result);
- printTableAddFooter(&cont, buf.data);
+ if (tuples > 0)
+ {
+ printTableAddFooter(&cont, _("Check constraints:"));
+ for (i = 0; i < tuples; i++)
+ {
+ /* untranslated constraint name and def */
+ printfPQExpBuffer(&buf, " \"%s\" %s",
+ PQgetvalue(result, i, 0),
+ PQgetvalue(result, i, 1));
- /* Print tablespace of the index on the same line */
- if (pset.sversion >= 80000)
- add_tablespace_footer(&cont, RELKIND_INDEX,
- atooid(PQgetvalue(result, i, 11)),
- false);
+ printTableAddFooter(&cont, buf.data);
+ }
+ }
+ PQclear(result);
}
- }
- PQclear(result);
- }
-
- /* print table (and column) check constraints */
- if (tableinfo.checks)
- {
- printfPQExpBuffer(&buf,
- "SELECT r.conname, "
- "pg_catalog.pg_get_constraintdef(r.oid, true)\n"
- "FROM pg_catalog.pg_constraint r\n"
- "WHERE r.conrelid = '%s' AND r.contype = 'c'\n"
- "ORDER BY 1;",
- oid);
- result = PSQLexec(buf.data);
- if (!result)
- goto error_return;
- else
- tuples = PQntuples(result);
- if (tuples > 0)
- {
- printTableAddFooter(&cont, _("Check constraints:"));
- for (i = 0; i < tuples; i++)
+ /*
+ * Print foreign-key constraints (there are none if no
+ * triggers, except if the table is partitioned, in which case
+ * the triggers appear in the partitions)
+ */
+ if (tableinfo.hastriggers ||
+ tableinfo.relkind == RELKIND_PARTITIONED_TABLE)
{
- /* untranslated constraint name and def */
- printfPQExpBuffer(&buf, " \"%s\" %s",
- PQgetvalue(result, i, 0),
- PQgetvalue(result, i, 1));
-
- printTableAddFooter(&cont, buf.data);
- }
- }
- PQclear(result);
- }
+ if (pset.sversion >= 120000 &&
+ (tableinfo.ispartition || tableinfo.relkind == RELKIND_PARTITIONED_TABLE))
+ {
+ /*
+ * Put the constraints defined in this table first,
+ * followed by the constraints defined in ancestor
+ * partitioned tables.
+ */
+ printfPQExpBuffer(&buf,
+ "SELECT conrelid = '%s'::pg_catalog.regclass AS sametable,\n"
+ " conname,\n"
+ " pg_catalog.pg_get_constraintdef(oid, true) AS condef,\n"
+ " conrelid::pg_catalog.regclass AS ontable\n"
+ " FROM pg_catalog.pg_constraint,\n"
+ " pg_catalog.pg_partition_ancestors('%s')\n"
+ " WHERE conrelid = relid AND contype = 'f' AND conparentid = 0\n"
+ "ORDER BY sametable DESC, conname;",
+ oid, oid);
+ }
+ else
+ {
+ printfPQExpBuffer(&buf,
+ "SELECT true as sametable, conname,\n"
+ " pg_catalog.pg_get_constraintdef(r.oid, true) as condef,\n"
+ " conrelid::pg_catalog.regclass AS ontable\n"
+ "FROM pg_catalog.pg_constraint r\n"
+ "WHERE r.conrelid = '%s' AND r.contype = 'f'\n",
+ oid);
+
+ if (pset.sversion >= 120000)
+ appendPQExpBufferStr(&buf, " AND conparentid = 0\n");
+ appendPQExpBufferStr(&buf, "ORDER BY conname");
+ }
- /*
- * Print foreign-key constraints (there are none if no triggers,
- * except if the table is partitioned, in which case the triggers
- * appear in the partitions)
- */
- if (tableinfo.hastriggers ||
- tableinfo.relkind == RELKIND_PARTITIONED_TABLE)
- {
- if (pset.sversion >= 120000 &&
- (tableinfo.ispartition || tableinfo.relkind == RELKIND_PARTITIONED_TABLE))
- {
- /*
- * Put the constraints defined in this table first, followed
- * by the constraints defined in ancestor partitioned tables.
- */
- printfPQExpBuffer(&buf,
- "SELECT conrelid = '%s'::pg_catalog.regclass AS sametable,\n"
- " conname,\n"
- " pg_catalog.pg_get_constraintdef(oid, true) AS condef,\n"
- " conrelid::pg_catalog.regclass AS ontable\n"
- " FROM pg_catalog.pg_constraint,\n"
- " pg_catalog.pg_partition_ancestors('%s')\n"
- " WHERE conrelid = relid AND contype = 'f' AND conparentid = 0\n"
- "ORDER BY sametable DESC, conname;",
- oid, oid);
- }
- else
- {
- printfPQExpBuffer(&buf,
- "SELECT true as sametable, conname,\n"
- " pg_catalog.pg_get_constraintdef(r.oid, true) as condef,\n"
- " conrelid::pg_catalog.regclass AS ontable\n"
- "FROM pg_catalog.pg_constraint r\n"
- "WHERE r.conrelid = '%s' AND r.contype = 'f'\n",
- oid);
+ result = PSQLexec(buf.data);
+ if (!result)
+ goto error_return;
+ else
+ tuples = PQntuples(result);
- if (pset.sversion >= 120000)
- appendPQExpBufferStr(&buf, " AND conparentid = 0\n");
- appendPQExpBufferStr(&buf, "ORDER BY conname");
- }
+ if (tuples > 0)
+ {
+ int i_sametable = PQfnumber(result, "sametable"),
+ i_conname = PQfnumber(result, "conname"),
+ i_condef = PQfnumber(result, "condef"),
+ i_ontable = PQfnumber(result, "ontable");
- result = PSQLexec(buf.data);
- if (!result)
- goto error_return;
- else
- tuples = PQntuples(result);
+ printTableAddFooter(&cont, _("Foreign-key constraints:"));
+ for (i = 0; i < tuples; i++)
+ {
+ /*
+ * Print untranslated constraint name and
+ * definition. Use a "TABLE tab" prefix when the
+ * constraint is defined in a parent partitioned
+ * table.
+ */
+ if (strcmp(PQgetvalue(result, i, i_sametable), "f") == 0)
+ printfPQExpBuffer(&buf, " TABLE \"%s\" CONSTRAINT \"%s\" %s",
+ PQgetvalue(result, i, i_ontable),
+ PQgetvalue(result, i, i_conname),
+ PQgetvalue(result, i, i_condef));
+ else
+ printfPQExpBuffer(&buf, " \"%s\" %s",
+ PQgetvalue(result, i, i_conname),
+ PQgetvalue(result, i, i_condef));
- if (tuples > 0)
- {
- int i_sametable = PQfnumber(result, "sametable"),
- i_conname = PQfnumber(result, "conname"),
- i_condef = PQfnumber(result, "condef"),
- i_ontable = PQfnumber(result, "ontable");
+ printTableAddFooter(&cont, buf.data);
+ }
+ }
+ PQclear(result);
+ }
- printTableAddFooter(&cont, _("Foreign-key constraints:"));
- for (i = 0; i < tuples; i++)
+ /* print incoming foreign-key references */
+ if (tableinfo.hastriggers ||
+ tableinfo.relkind == RELKIND_PARTITIONED_TABLE)
{
- /*
- * Print untranslated constraint name and definition. Use
- * a "TABLE tab" prefix when the constraint is defined in
- * a parent partitioned table.
- */
- if (strcmp(PQgetvalue(result, i, i_sametable), "f") == 0)
- printfPQExpBuffer(&buf, " TABLE \"%s\" CONSTRAINT \"%s\" %s",
- PQgetvalue(result, i, i_ontable),
- PQgetvalue(result, i, i_conname),
- PQgetvalue(result, i, i_condef));
+ if (pset.sversion >= 120000)
+ {
+ printfPQExpBuffer(&buf,
+ "SELECT conname, conrelid::pg_catalog.regclass AS ontable,\n"
+ " pg_catalog.pg_get_constraintdef(oid, true) AS condef\n"
+ " FROM pg_catalog.pg_constraint c\n"
+ " WHERE confrelid IN (SELECT pg_catalog.pg_partition_ancestors('%s')\n"
+ " UNION ALL VALUES ('%s'::pg_catalog.regclass))\n"
+ " AND contype = 'f' AND conparentid = 0\n"
+ "ORDER BY conname;",
+ oid, oid);
+ }
else
- printfPQExpBuffer(&buf, " \"%s\" %s",
- PQgetvalue(result, i, i_conname),
- PQgetvalue(result, i, i_condef));
+ {
+ printfPQExpBuffer(&buf,
+ "SELECT conname, conrelid::pg_catalog.regclass AS ontable,\n"
+ " pg_catalog.pg_get_constraintdef(oid, true) AS condef\n"
+ " FROM pg_catalog.pg_constraint\n"
+ " WHERE confrelid = %s AND contype = 'f'\n"
+ "ORDER BY conname;",
+ oid);
+ }
- printTableAddFooter(&cont, buf.data);
- }
- }
- PQclear(result);
- }
+ result = PSQLexec(buf.data);
+ if (!result)
+ goto error_return;
+ else
+ tuples = PQntuples(result);
- /* print incoming foreign-key references */
- if (tableinfo.hastriggers ||
- tableinfo.relkind == RELKIND_PARTITIONED_TABLE)
- {
- if (pset.sversion >= 120000)
- {
- printfPQExpBuffer(&buf,
- "SELECT conname, conrelid::pg_catalog.regclass AS ontable,\n"
- " pg_catalog.pg_get_constraintdef(oid, true) AS condef\n"
- " FROM pg_catalog.pg_constraint c\n"
- " WHERE confrelid IN (SELECT pg_catalog.pg_partition_ancestors('%s')\n"
- " UNION ALL VALUES ('%s'::pg_catalog.regclass))\n"
- " AND contype = 'f' AND conparentid = 0\n"
- "ORDER BY conname;",
- oid, oid);
- }
- else
- {
- printfPQExpBuffer(&buf,
- "SELECT conname, conrelid::pg_catalog.regclass AS ontable,\n"
- " pg_catalog.pg_get_constraintdef(oid, true) AS condef\n"
- " FROM pg_catalog.pg_constraint\n"
- " WHERE confrelid = %s AND contype = 'f'\n"
- "ORDER BY conname;",
- oid);
- }
+ if (tuples > 0)
+ {
+ int i_conname = PQfnumber(result, "conname"),
+ i_ontable = PQfnumber(result, "ontable"),
+ i_condef = PQfnumber(result, "condef");
- result = PSQLexec(buf.data);
- if (!result)
- goto error_return;
- else
- tuples = PQntuples(result);
+ printTableAddFooter(&cont, _("Referenced by:"));
+ for (i = 0; i < tuples; i++)
+ {
+ printfPQExpBuffer(&buf, " TABLE \"%s\" CONSTRAINT \"%s\" %s",
+ PQgetvalue(result, i, i_ontable),
+ PQgetvalue(result, i, i_conname),
+ PQgetvalue(result, i, i_condef));
- if (tuples > 0)
- {
- int i_conname = PQfnumber(result, "conname"),
- i_ontable = PQfnumber(result, "ontable"),
- i_condef = PQfnumber(result, "condef");
+ printTableAddFooter(&cont, buf.data);
+ }
+ }
+ PQclear(result);
+ }
- printTableAddFooter(&cont, _("Referenced by:"));
- for (i = 0; i < tuples; i++)
+ /* print any row-level policies */
+ if (pset.sversion >= 90500)
{
- printfPQExpBuffer(&buf, " TABLE \"%s\" CONSTRAINT \"%s\" %s",
- PQgetvalue(result, i, i_ontable),
- PQgetvalue(result, i, i_conname),
- PQgetvalue(result, i, i_condef));
+ printfPQExpBuffer(&buf, "SELECT pol.polname,");
+ if (pset.sversion >= 100000)
+ appendPQExpBufferStr(&buf,
+ " pol.polpermissive,\n");
+ else
+ appendPQExpBufferStr(&buf,
+ " 't' as polpermissive,\n");
+ appendPQExpBuffer(&buf,
+ " CASE WHEN pol.polroles = '{0}' THEN NULL ELSE pg_catalog.array_to_string(array(select rolname from pg_catalog.pg_roles where oid = any (pol.polroles) order by 1),',') END,\n"
+ " pg_catalog.pg_get_expr(pol.polqual, pol.polrelid),\n"
+ " pg_catalog.pg_get_expr(pol.polwithcheck, pol.polrelid),\n"
+ " CASE pol.polcmd\n"
+ " WHEN 'r' THEN 'SELECT'\n"
+ " WHEN 'a' THEN 'INSERT'\n"
+ " WHEN 'w' THEN 'UPDATE'\n"
+ " WHEN 'd' THEN 'DELETE'\n"
+ " END AS cmd\n"
+ "FROM pg_catalog.pg_policy pol\n"
+ "WHERE pol.polrelid = '%s' ORDER BY 1;",
+ oid);
+
+ result = PSQLexec(buf.data);
+ if (!result)
+ goto error_return;
+ else
+ tuples = PQntuples(result);
- printTableAddFooter(&cont, buf.data);
- }
- }
- PQclear(result);
- }
+ /*
+ * Handle cases where RLS is enabled and there are
+ * policies, or there aren't policies, or RLS isn't
+ * enabled but there are policies
+ */
+ if (tableinfo.rowsecurity && !tableinfo.forcerowsecurity && tuples > 0)
+ printTableAddFooter(&cont, _("Policies:"));
- /* print any row-level policies */
- if (pset.sversion >= 90500)
- {
- printfPQExpBuffer(&buf, "SELECT pol.polname,");
- if (pset.sversion >= 100000)
- appendPQExpBufferStr(&buf,
- " pol.polpermissive,\n");
- else
- appendPQExpBufferStr(&buf,
- " 't' as polpermissive,\n");
- appendPQExpBuffer(&buf,
- " CASE WHEN pol.polroles = '{0}' THEN NULL ELSE pg_catalog.array_to_string(array(select rolname from pg_catalog.pg_roles where oid = any (pol.polroles) order by 1),',') END,\n"
- " pg_catalog.pg_get_expr(pol.polqual, pol.polrelid),\n"
- " pg_catalog.pg_get_expr(pol.polwithcheck, pol.polrelid),\n"
- " CASE pol.polcmd\n"
- " WHEN 'r' THEN 'SELECT'\n"
- " WHEN 'a' THEN 'INSERT'\n"
- " WHEN 'w' THEN 'UPDATE'\n"
- " WHEN 'd' THEN 'DELETE'\n"
- " END AS cmd\n"
- "FROM pg_catalog.pg_policy pol\n"
- "WHERE pol.polrelid = '%s' ORDER BY 1;",
- oid);
+ if (tableinfo.rowsecurity && tableinfo.forcerowsecurity && tuples > 0)
+ printTableAddFooter(&cont, _("Policies (forced row security enabled):"));
- result = PSQLexec(buf.data);
- if (!result)
- goto error_return;
- else
- tuples = PQntuples(result);
+ if (tableinfo.rowsecurity && !tableinfo.forcerowsecurity && tuples == 0)
+ printTableAddFooter(&cont, _("Policies (row security enabled): (none)"));
- /*
- * Handle cases where RLS is enabled and there are policies, or
- * there aren't policies, or RLS isn't enabled but there are
- * policies
- */
- if (tableinfo.rowsecurity && !tableinfo.forcerowsecurity && tuples > 0)
- printTableAddFooter(&cont, _("Policies:"));
+ if (tableinfo.rowsecurity && tableinfo.forcerowsecurity && tuples == 0)
+ printTableAddFooter(&cont, _("Policies (forced row security enabled): (none)"));
- if (tableinfo.rowsecurity && tableinfo.forcerowsecurity && tuples > 0)
- printTableAddFooter(&cont, _("Policies (forced row security enabled):"));
+ if (!tableinfo.rowsecurity && tuples > 0)
+ printTableAddFooter(&cont, _("Policies (row security disabled):"));
- if (tableinfo.rowsecurity && !tableinfo.forcerowsecurity && tuples == 0)
- printTableAddFooter(&cont, _("Policies (row security enabled): (none)"));
+ /* Might be an empty set - that's ok */
+ for (i = 0; i < tuples; i++)
+ {
+ printfPQExpBuffer(&buf, " POLICY \"%s\"",
+ PQgetvalue(result, i, 0));
- if (tableinfo.rowsecurity && tableinfo.forcerowsecurity && tuples == 0)
- printTableAddFooter(&cont, _("Policies (forced row security enabled): (none)"));
+ if (*(PQgetvalue(result, i, 1)) == 'f')
+ appendPQExpBufferStr(&buf, " AS RESTRICTIVE");
- if (!tableinfo.rowsecurity && tuples > 0)
- printTableAddFooter(&cont, _("Policies (row security disabled):"));
+ if (!PQgetisnull(result, i, 5))
+ appendPQExpBuffer(&buf, " FOR %s",
+ PQgetvalue(result, i, 5));
- /* Might be an empty set - that's ok */
- for (i = 0; i < tuples; i++)
- {
- printfPQExpBuffer(&buf, " POLICY \"%s\"",
- PQgetvalue(result, i, 0));
+ if (!PQgetisnull(result, i, 2))
+ {
+ appendPQExpBuffer(&buf, "\n TO %s",
+ PQgetvalue(result, i, 2));
+ }
- if (*(PQgetvalue(result, i, 1)) == 'f')
- appendPQExpBufferStr(&buf, " AS RESTRICTIVE");
+ if (!PQgetisnull(result, i, 3))
+ appendPQExpBuffer(&buf, "\n USING (%s)",
+ PQgetvalue(result, i, 3));
- if (!PQgetisnull(result, i, 5))
- appendPQExpBuffer(&buf, " FOR %s",
- PQgetvalue(result, i, 5));
+ if (!PQgetisnull(result, i, 4))
+ appendPQExpBuffer(&buf, "\n WITH CHECK (%s)",
+ PQgetvalue(result, i, 4));
- if (!PQgetisnull(result, i, 2))
- {
- appendPQExpBuffer(&buf, "\n TO %s",
- PQgetvalue(result, i, 2));
- }
+ printTableAddFooter(&cont, buf.data);
- if (!PQgetisnull(result, i, 3))
- appendPQExpBuffer(&buf, "\n USING (%s)",
- PQgetvalue(result, i, 3));
+ }
+ PQclear(result);
+ }
- if (!PQgetisnull(result, i, 4))
- appendPQExpBuffer(&buf, "\n WITH CHECK (%s)",
- PQgetvalue(result, i, 4));
+ /* print any extended statistics */
+ if (pset.sversion >= 100000)
+ {
+ printfPQExpBuffer(&buf,
+ "SELECT oid, "
+ "stxrelid::pg_catalog.regclass, "
+ "stxnamespace::pg_catalog.regnamespace AS nsp, "
+ "stxname,\n"
+ " (SELECT pg_catalog.string_agg(pg_catalog.quote_ident(attname),', ')\n"
+ " FROM pg_catalog.unnest(stxkeys) s(attnum)\n"
+ " JOIN pg_catalog.pg_attribute a ON (stxrelid = a.attrelid AND\n"
+ " a.attnum = s.attnum AND NOT attisdropped)) AS columns,\n"
+ " 'd' = any(stxkind) AS ndist_enabled,\n"
+ " 'f' = any(stxkind) AS deps_enabled,\n"
+ " 'm' = any(stxkind) AS mcv_enabled\n"
+ "FROM pg_catalog.pg_statistic_ext stat "
+ "WHERE stxrelid = '%s'\n"
+ "ORDER BY 1;",
+ oid);
+
+ result = PSQLexec(buf.data);
+ if (!result)
+ goto error_return;
+ else
+ tuples = PQntuples(result);
- printTableAddFooter(&cont, buf.data);
+ if (tuples > 0)
+ {
+ printTableAddFooter(&cont, _("Statistics objects:"));
- }
- PQclear(result);
- }
+ for (i = 0; i < tuples; i++)
+ {
+ bool gotone = false;
- /* print any extended statistics */
- if (pset.sversion >= 100000)
- {
- printfPQExpBuffer(&buf,
- "SELECT oid, "
- "stxrelid::pg_catalog.regclass, "
- "stxnamespace::pg_catalog.regnamespace AS nsp, "
- "stxname,\n"
- " (SELECT pg_catalog.string_agg(pg_catalog.quote_ident(attname),', ')\n"
- " FROM pg_catalog.unnest(stxkeys) s(attnum)\n"
- " JOIN pg_catalog.pg_attribute a ON (stxrelid = a.attrelid AND\n"
- " a.attnum = s.attnum AND NOT attisdropped)) AS columns,\n"
- " 'd' = any(stxkind) AS ndist_enabled,\n"
- " 'f' = any(stxkind) AS deps_enabled,\n"
- " 'm' = any(stxkind) AS mcv_enabled\n"
- "FROM pg_catalog.pg_statistic_ext stat "
- "WHERE stxrelid = '%s'\n"
- "ORDER BY 1;",
- oid);
+ printfPQExpBuffer(&buf, " ");
- result = PSQLexec(buf.data);
- if (!result)
- goto error_return;
- else
- tuples = PQntuples(result);
+ /*
+ * statistics object name (qualified with
+ * namespace)
+ */
+ appendPQExpBuffer(&buf, "\"%s\".\"%s\" (",
+ PQgetvalue(result, i, 2),
+ PQgetvalue(result, i, 3));
- if (tuples > 0)
- {
- printTableAddFooter(&cont, _("Statistics objects:"));
+ /* options */
+ if (strcmp(PQgetvalue(result, i, 5), "t") == 0)
+ {
+ appendPQExpBufferStr(&buf, "ndistinct");
+ gotone = true;
+ }
- for (i = 0; i < tuples; i++)
- {
- bool gotone = false;
+ if (strcmp(PQgetvalue(result, i, 6), "t") == 0)
+ {
+ appendPQExpBuffer(&buf, "%sdependencies", gotone ? ", " : "");
+ gotone = true;
+ }
- printfPQExpBuffer(&buf, " ");
+ if (strcmp(PQgetvalue(result, i, 7), "t") == 0)
+ {
+ appendPQExpBuffer(&buf, "%smcv", gotone ? ", " : "");
+ }
- /* statistics object name (qualified with namespace) */
- appendPQExpBuffer(&buf, "\"%s\".\"%s\" (",
- PQgetvalue(result, i, 2),
- PQgetvalue(result, i, 3));
+ appendPQExpBuffer(&buf, ") ON %s FROM %s",
+ PQgetvalue(result, i, 4),
+ PQgetvalue(result, i, 1));
- /* options */
- if (strcmp(PQgetvalue(result, i, 5), "t") == 0)
- {
- appendPQExpBufferStr(&buf, "ndistinct");
- gotone = true;
+ printTableAddFooter(&cont, buf.data);
+ }
}
+ PQclear(result);
+ }
- if (strcmp(PQgetvalue(result, i, 6), "t") == 0)
+ /* print rules */
+ if (tableinfo.hasrules && tableinfo.relkind != RELKIND_MATVIEW)
+ {
+ if (pset.sversion >= 80300)
{
- appendPQExpBuffer(&buf, "%sdependencies", gotone ? ", " : "");
- gotone = true;
+ printfPQExpBuffer(&buf,
+ "SELECT r.rulename, trim(trailing ';' from pg_catalog.pg_get_ruledef(r.oid, true)), "
+ "ev_enabled\n"
+ "FROM pg_catalog.pg_rewrite r\n"
+ "WHERE r.ev_class = '%s' ORDER BY 1;",
+ oid);
}
-
- if (strcmp(PQgetvalue(result, i, 7), "t") == 0)
+ else
{
- appendPQExpBuffer(&buf, "%smcv", gotone ? ", " : "");
+ printfPQExpBuffer(&buf,
+ "SELECT r.rulename, trim(trailing ';' from pg_catalog.pg_get_ruledef(r.oid, true)), "
+ "'O' AS ev_enabled\n"
+ "FROM pg_catalog.pg_rewrite r\n"
+ "WHERE r.ev_class = '%s' ORDER BY 1;",
+ oid);
}
+ result = PSQLexec(buf.data);
+ if (!result)
+ goto error_return;
+ else
+ tuples = PQntuples(result);
- appendPQExpBuffer(&buf, ") ON %s FROM %s",
- PQgetvalue(result, i, 4),
- PQgetvalue(result, i, 1));
-
- printTableAddFooter(&cont, buf.data);
- }
- }
- PQclear(result);
- }
-
- /* print rules */
- if (tableinfo.hasrules && tableinfo.relkind != RELKIND_MATVIEW)
- {
- if (pset.sversion >= 80300)
- {
- printfPQExpBuffer(&buf,
- "SELECT r.rulename, trim(trailing ';' from pg_catalog.pg_get_ruledef(r.oid, true)), "
- "ev_enabled\n"
- "FROM pg_catalog.pg_rewrite r\n"
- "WHERE r.ev_class = '%s' ORDER BY 1;",
- oid);
- }
- else
- {
- printfPQExpBuffer(&buf,
- "SELECT r.rulename, trim(trailing ';' from pg_catalog.pg_get_ruledef(r.oid, true)), "
- "'O' AS ev_enabled\n"
- "FROM pg_catalog.pg_rewrite r\n"
- "WHERE r.ev_class = '%s' ORDER BY 1;",
- oid);
- }
- result = PSQLexec(buf.data);
- if (!result)
- goto error_return;
- else
- tuples = PQntuples(result);
-
- if (tuples > 0)
- {
- bool have_heading;
- int category;
-
- for (category = 0; category < 4; category++)
- {
- have_heading = false;
-
- for (i = 0; i < tuples; i++)
+ if (tuples > 0)
{
- const char *ruledef;
- bool list_rule = false;
+ bool have_heading;
+ int category;
- switch (category)
+ for (category = 0; category < 4; category++)
{
- case 0:
- if (*PQgetvalue(result, i, 2) == 'O')
- list_rule = true;
- break;
- case 1:
- if (*PQgetvalue(result, i, 2) == 'D')
- list_rule = true;
- break;
- case 2:
- if (*PQgetvalue(result, i, 2) == 'A')
- list_rule = true;
- break;
- case 3:
- if (*PQgetvalue(result, i, 2) == 'R')
- list_rule = true;
- break;
- }
- if (!list_rule)
- continue;
+ have_heading = false;
- if (!have_heading)
- {
- switch (category)
+ for (i = 0; i < tuples; i++)
{
- case 0:
- printfPQExpBuffer(&buf, _("Rules:"));
- break;
- case 1:
- printfPQExpBuffer(&buf, _("Disabled rules:"));
- break;
- case 2:
- printfPQExpBuffer(&buf, _("Rules firing always:"));
- break;
- case 3:
- printfPQExpBuffer(&buf, _("Rules firing on replica only:"));
- break;
+ const char *ruledef;
+ bool list_rule = false;
+
+ switch (category)
+ {
+ case 0:
+ if (*PQgetvalue(result, i, 2) == 'O')
+ list_rule = true;
+ break;
+ case 1:
+ if (*PQgetvalue(result, i, 2) == 'D')
+ list_rule = true;
+ break;
+ case 2:
+ if (*PQgetvalue(result, i, 2) == 'A')
+ list_rule = true;
+ break;
+ case 3:
+ if (*PQgetvalue(result, i, 2) == 'R')
+ list_rule = true;
+ break;
+ }
+ if (!list_rule)
+ continue;
+
+ if (!have_heading)
+ {
+ switch (category)
+ {
+ case 0:
+ printfPQExpBuffer(&buf, _("Rules:"));
+ break;
+ case 1:
+ printfPQExpBuffer(&buf, _("Disabled rules:"));
+ break;
+ case 2:
+ printfPQExpBuffer(&buf, _("Rules firing always:"));
+ break;
+ case 3:
+ printfPQExpBuffer(&buf, _("Rules firing on replica only:"));
+ break;
+ }
+ printTableAddFooter(&cont, buf.data);
+ have_heading = true;
+ }
+
+ /*
+ * Everything after "CREATE RULE" is echoed
+ * verbatim
+ */
+ ruledef = PQgetvalue(result, i, 1);
+ ruledef += 12;
+ printfPQExpBuffer(&buf, " %s", ruledef);
+ printTableAddFooter(&cont, buf.data);
}
- printTableAddFooter(&cont, buf.data);
- have_heading = true;
}
-
- /* Everything after "CREATE RULE" is echoed verbatim */
- ruledef = PQgetvalue(result, i, 1);
- ruledef += 12;
- printfPQExpBuffer(&buf, " %s", ruledef);
- printTableAddFooter(&cont, buf.data);
}
+ PQclear(result);
}
- }
- PQclear(result);
- }
- /* print any publications */
- if (pset.sversion >= 100000)
- {
- printfPQExpBuffer(&buf,
- "SELECT pubname\n"
- "FROM pg_catalog.pg_publication p\n"
- "JOIN pg_catalog.pg_publication_rel pr ON p.oid = pr.prpubid\n"
- "WHERE pr.prrelid = '%s'\n"
- "UNION ALL\n"
- "SELECT pubname\n"
- "FROM pg_catalog.pg_publication p\n"
- "WHERE p.puballtables AND pg_catalog.pg_relation_is_publishable('%s')\n"
- "ORDER BY 1;",
- oid, oid);
-
- result = PSQLexec(buf.data);
- if (!result)
- goto error_return;
- else
- tuples = PQntuples(result);
+ /* print any publications */
+ if (pset.sversion >= 100000)
+ {
+ printfPQExpBuffer(&buf,
+ "SELECT pubname\n"
+ "FROM pg_catalog.pg_publication p\n"
+ "JOIN pg_catalog.pg_publication_rel pr ON p.oid = pr.prpubid\n"
+ "WHERE pr.prrelid = '%s'\n"
+ "UNION ALL\n"
+ "SELECT pubname\n"
+ "FROM pg_catalog.pg_publication p\n"
+ "WHERE p.puballtables AND pg_catalog.pg_relation_is_publishable('%s')\n"
+ "ORDER BY 1;",
+ oid, oid);
+
+ result = PSQLexec(buf.data);
+ if (!result)
+ goto error_return;
+ else
+ tuples = PQntuples(result);
- if (tuples > 0)
- printTableAddFooter(&cont, _("Publications:"));
+ if (tuples > 0)
+ printTableAddFooter(&cont, _("Publications:"));
- /* Might be an empty set - that's ok */
- for (i = 0; i < tuples; i++)
- {
- printfPQExpBuffer(&buf, " \"%s\"",
- PQgetvalue(result, i, 0));
+ /* Might be an empty set - that's ok */
+ for (i = 0; i < tuples; i++)
+ {
+ printfPQExpBuffer(&buf, " \"%s\"",
+ PQgetvalue(result, i, 0));
- printTableAddFooter(&cont, buf.data);
+ printTableAddFooter(&cont, buf.data);
+ }
+ PQclear(result);
+ }
}
- PQclear(result);
- }
+ break;
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
/* Get view_def if table is a view or materialized view */
- if ((tableinfo.relkind == RELKIND_VIEW ||
- tableinfo.relkind == RELKIND_MATVIEW) && verbose)
+ switch ((RelKind) tableinfo.relkind)
{
- PGresult *result;
+ case RELKIND_VIEW:
+ case RELKIND_MATVIEW:
+ if (verbose)
+ {
+ PGresult *result;
- printfPQExpBuffer(&buf,
- "SELECT pg_catalog.pg_get_viewdef('%s'::pg_catalog.oid, true);",
- oid);
- result = PSQLexec(buf.data);
- if (!result)
- goto error_return;
+ printfPQExpBuffer(&buf,
+ "SELECT pg_catalog.pg_get_viewdef('%s'::pg_catalog.oid, true);",
+ oid);
+ result = PSQLexec(buf.data);
+ if (!result)
+ goto error_return;
- if (PQntuples(result) > 0)
- view_def = pg_strdup(PQgetvalue(result, 0, 0));
+ if (PQntuples(result) > 0)
+ view_def = pg_strdup(PQgetvalue(result, 0, 0));
- PQclear(result);
+ PQclear(result);
+ }
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_RELATION:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ break;
}
if (view_def)
@@ -3086,224 +3205,235 @@ describeOneTableDetails(const char *schemaname,
/*
* Finish printing the footer information about a table.
*/
- if (tableinfo.relkind == RELKIND_RELATION ||
- tableinfo.relkind == RELKIND_MATVIEW ||
- tableinfo.relkind == RELKIND_FOREIGN_TABLE ||
- tableinfo.relkind == RELKIND_PARTITIONED_TABLE ||
- tableinfo.relkind == RELKIND_PARTITIONED_INDEX ||
- tableinfo.relkind == RELKIND_TOASTVALUE)
+ switch ((RelKind) tableinfo.relkind)
{
- bool is_partitioned;
- PGresult *result;
- int tuples;
-
- /* simplify some repeated tests below */
- is_partitioned = (tableinfo.relkind == RELKIND_PARTITIONED_TABLE ||
- tableinfo.relkind == RELKIND_PARTITIONED_INDEX);
-
- /* print foreign server name */
- if (tableinfo.relkind == RELKIND_FOREIGN_TABLE)
- {
- char *ftoptions;
-
- /* Footer information about foreign table */
- printfPQExpBuffer(&buf,
- "SELECT s.srvname,\n"
- " pg_catalog.array_to_string(ARRAY(\n"
- " SELECT pg_catalog.quote_ident(option_name)"
- " || ' ' || pg_catalog.quote_literal(option_value)\n"
- " FROM pg_catalog.pg_options_to_table(ftoptions)), ', ')\n"
- "FROM pg_catalog.pg_foreign_table f,\n"
- " pg_catalog.pg_foreign_server s\n"
- "WHERE f.ftrelid = '%s' AND s.oid = f.ftserver;",
- oid);
- result = PSQLexec(buf.data);
- if (!result)
- goto error_return;
- else if (PQntuples(result) != 1)
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_TOASTVALUE:
{
- PQclear(result);
- goto error_return;
- }
+ bool is_partitioned;
+ PGresult *result;
+ int tuples;
- /* Print server name */
- printfPQExpBuffer(&buf, _("Server: %s"),
- PQgetvalue(result, 0, 0));
- printTableAddFooter(&cont, buf.data);
+ /* simplify some repeated tests below */
+ is_partitioned = (tableinfo.relkind == RELKIND_PARTITIONED_TABLE ||
+ tableinfo.relkind == RELKIND_PARTITIONED_INDEX);
- /* Print per-table FDW options, if any */
- ftoptions = PQgetvalue(result, 0, 1);
- if (ftoptions && ftoptions[0] != '\0')
- {
- printfPQExpBuffer(&buf, _("FDW options: (%s)"), ftoptions);
- printTableAddFooter(&cont, buf.data);
- }
- PQclear(result);
- }
+ /* print foreign server name */
+ if (tableinfo.relkind == RELKIND_FOREIGN_TABLE)
+ {
+ char *ftoptions;
+
+ /* Footer information about foreign table */
+ printfPQExpBuffer(&buf,
+ "SELECT s.srvname,\n"
+ " pg_catalog.array_to_string(ARRAY(\n"
+ " SELECT pg_catalog.quote_ident(option_name)"
+ " || ' ' || pg_catalog.quote_literal(option_value)\n"
+ " FROM pg_catalog.pg_options_to_table(ftoptions)), ', ')\n"
+ "FROM pg_catalog.pg_foreign_table f,\n"
+ " pg_catalog.pg_foreign_server s\n"
+ "WHERE f.ftrelid = '%s' AND s.oid = f.ftserver;",
+ oid);
+ result = PSQLexec(buf.data);
+ if (!result)
+ goto error_return;
+ else if (PQntuples(result) != 1)
+ {
+ PQclear(result);
+ goto error_return;
+ }
- /* print tables inherited from (exclude partitioned parents) */
- printfPQExpBuffer(&buf,
- "SELECT c.oid::pg_catalog.regclass\n"
- "FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i\n"
- "WHERE c.oid = i.inhparent AND i.inhrelid = '%s'\n"
- " AND c.relkind != " CppAsString2(RELKIND_PARTITIONED_TABLE)
- " AND c.relkind != " CppAsString2(RELKIND_PARTITIONED_INDEX)
- "\nORDER BY inhseqno;",
- oid);
+ /* Print server name */
+ printfPQExpBuffer(&buf, _("Server: %s"),
+ PQgetvalue(result, 0, 0));
+ printTableAddFooter(&cont, buf.data);
- result = PSQLexec(buf.data);
- if (!result)
- goto error_return;
- else
- {
- const char *s = _("Inherits");
- int sw = pg_wcswidth(s, strlen(s), pset.encoding);
+ /* Print per-table FDW options, if any */
+ ftoptions = PQgetvalue(result, 0, 1);
+ if (ftoptions && ftoptions[0] != '\0')
+ {
+ printfPQExpBuffer(&buf, _("FDW options: (%s)"), ftoptions);
+ printTableAddFooter(&cont, buf.data);
+ }
+ PQclear(result);
+ }
- tuples = PQntuples(result);
+ /* print tables inherited from (exclude partitioned parents) */
+ printfPQExpBuffer(&buf,
+ "SELECT c.oid::pg_catalog.regclass\n"
+ "FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i\n"
+ "WHERE c.oid = i.inhparent AND i.inhrelid = '%s'\n"
+ " AND c.relkind != " RelKindAsString(RELKIND_PARTITIONED_TABLE)
+ " AND c.relkind != " RelKindAsString(RELKIND_PARTITIONED_INDEX)
+ "\nORDER BY inhseqno;",
+ oid);
- for (i = 0; i < tuples; i++)
- {
- if (i == 0)
- printfPQExpBuffer(&buf, "%s: %s",
- s, PQgetvalue(result, i, 0));
+ result = PSQLexec(buf.data);
+ if (!result)
+ goto error_return;
else
- printfPQExpBuffer(&buf, "%*s %s",
- sw, "", PQgetvalue(result, i, 0));
- if (i < tuples - 1)
- appendPQExpBufferChar(&buf, ',');
+ {
+ const char *s = _("Inherits");
+ int sw = pg_wcswidth(s, strlen(s), pset.encoding);
- printTableAddFooter(&cont, buf.data);
- }
+ tuples = PQntuples(result);
- PQclear(result);
- }
+ for (i = 0; i < tuples; i++)
+ {
+ if (i == 0)
+ printfPQExpBuffer(&buf, "%s: %s",
+ s, PQgetvalue(result, i, 0));
+ else
+ printfPQExpBuffer(&buf, "%*s %s",
+ sw, "", PQgetvalue(result, i, 0));
+ if (i < tuples - 1)
+ appendPQExpBufferChar(&buf, ',');
- /* print child tables (with additional info if partitions) */
- if (pset.sversion >= 100000)
- printfPQExpBuffer(&buf,
- "SELECT c.oid::pg_catalog.regclass, c.relkind,"
- " pg_catalog.pg_get_expr(c.relpartbound, c.oid)\n"
- "FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i\n"
- "WHERE c.oid = i.inhrelid AND i.inhparent = '%s'\n"
- "ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT',"
- " c.oid::pg_catalog.regclass::pg_catalog.text;",
- oid);
- else if (pset.sversion >= 80300)
- printfPQExpBuffer(&buf,
- "SELECT c.oid::pg_catalog.regclass, c.relkind, NULL\n"
- "FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i\n"
- "WHERE c.oid = i.inhrelid AND i.inhparent = '%s'\n"
- "ORDER BY c.oid::pg_catalog.regclass::pg_catalog.text;",
- oid);
- else
- printfPQExpBuffer(&buf,
- "SELECT c.oid::pg_catalog.regclass, c.relkind, NULL\n"
- "FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i\n"
- "WHERE c.oid = i.inhrelid AND i.inhparent = '%s'\n"
- "ORDER BY c.relname;",
- oid);
+ printTableAddFooter(&cont, buf.data);
+ }
- result = PSQLexec(buf.data);
- if (!result)
- goto error_return;
- tuples = PQntuples(result);
+ PQclear(result);
+ }
- /*
- * For a partitioned table with no partitions, always print the number
- * of partitions as zero, even when verbose output is expected.
- * Otherwise, we will not print "Partitions" section for a partitioned
- * table without any partitions.
- */
- if (is_partitioned && tuples == 0)
- {
- printfPQExpBuffer(&buf, _("Number of partitions: %d"), tuples);
- printTableAddFooter(&cont, buf.data);
- }
- else if (!verbose)
- {
- /* print the number of child tables, if any */
- if (tuples > 0)
- {
- if (is_partitioned)
- printfPQExpBuffer(&buf, _("Number of partitions: %d (Use \\d+ to list them.)"), tuples);
+ /* print child tables (with additional info if partitions) */
+ if (pset.sversion >= 100000)
+ printfPQExpBuffer(&buf,
+ "SELECT c.oid::pg_catalog.regclass, c.relkind,"
+ " pg_catalog.pg_get_expr(c.relpartbound, c.oid)\n"
+ "FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i\n"
+ "WHERE c.oid = i.inhrelid AND i.inhparent = '%s'\n"
+ "ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT',"
+ " c.oid::pg_catalog.regclass::pg_catalog.text;",
+ oid);
+ else if (pset.sversion >= 80300)
+ printfPQExpBuffer(&buf,
+ "SELECT c.oid::pg_catalog.regclass, c.relkind, NULL\n"
+ "FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i\n"
+ "WHERE c.oid = i.inhrelid AND i.inhparent = '%s'\n"
+ "ORDER BY c.oid::pg_catalog.regclass::pg_catalog.text;",
+ oid);
else
- printfPQExpBuffer(&buf, _("Number of child tables: %d (Use \\d+ to list them.)"), tuples);
- printTableAddFooter(&cont, buf.data);
- }
- }
- else
- {
- /* display the list of child tables */
- const char *ct = is_partitioned ? _("Partitions") : _("Child tables");
- int ctw = pg_wcswidth(ct, strlen(ct), pset.encoding);
-
- for (i = 0; i < tuples; i++)
- {
- char child_relkind = *PQgetvalue(result, i, 1);
+ printfPQExpBuffer(&buf,
+ "SELECT c.oid::pg_catalog.regclass, c.relkind, NULL\n"
+ "FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i\n"
+ "WHERE c.oid = i.inhrelid AND i.inhparent = '%s'\n"
+ "ORDER BY c.relname;",
+ oid);
+
+ result = PSQLexec(buf.data);
+ if (!result)
+ goto error_return;
+ tuples = PQntuples(result);
- if (i == 0)
- printfPQExpBuffer(&buf, "%s: %s",
- ct, PQgetvalue(result, i, 0));
+ /*
+ * For a partitioned table with no partitions, always print
+ * the number of partitions as zero, even when verbose output
+ * is expected. Otherwise, we will not print "Partitions"
+ * section for a partitioned table without any partitions.
+ */
+ if (is_partitioned && tuples == 0)
+ {
+ printfPQExpBuffer(&buf, _("Number of partitions: %d"), tuples);
+ printTableAddFooter(&cont, buf.data);
+ }
+ else if (!verbose)
+ {
+ /* print the number of child tables, if any */
+ if (tuples > 0)
+ {
+ if (is_partitioned)
+ printfPQExpBuffer(&buf, _("Number of partitions: %d (Use \\d+ to list them.)"), tuples);
+ else
+ printfPQExpBuffer(&buf, _("Number of child tables: %d (Use \\d+ to list them.)"), tuples);
+ printTableAddFooter(&cont, buf.data);
+ }
+ }
else
- printfPQExpBuffer(&buf, "%*s %s",
- ctw, "", PQgetvalue(result, i, 0));
- if (!PQgetisnull(result, i, 2))
- appendPQExpBuffer(&buf, " %s", PQgetvalue(result, i, 2));
- if (child_relkind == RELKIND_PARTITIONED_TABLE ||
- child_relkind == RELKIND_PARTITIONED_INDEX)
- appendPQExpBufferStr(&buf, ", PARTITIONED");
- if (i < tuples - 1)
- appendPQExpBufferChar(&buf, ',');
+ {
+ /* display the list of child tables */
+ const char *ct = is_partitioned ? _("Partitions") : _("Child tables");
+ int ctw = pg_wcswidth(ct, strlen(ct), pset.encoding);
- printTableAddFooter(&cont, buf.data);
- }
- }
- PQclear(result);
+ for (i = 0; i < tuples; i++)
+ {
+ char child_relkind = *PQgetvalue(result, i, 1);
+
+ if (i == 0)
+ printfPQExpBuffer(&buf, "%s: %s",
+ ct, PQgetvalue(result, i, 0));
+ else
+ printfPQExpBuffer(&buf, "%*s %s",
+ ctw, "", PQgetvalue(result, i, 0));
+ if (!PQgetisnull(result, i, 2))
+ appendPQExpBuffer(&buf, " %s", PQgetvalue(result, i, 2));
+ if (child_relkind == RELKIND_PARTITIONED_TABLE ||
+ child_relkind == RELKIND_PARTITIONED_INDEX)
+ appendPQExpBufferStr(&buf, ", PARTITIONED");
+ if (i < tuples - 1)
+ appendPQExpBufferChar(&buf, ',');
- /* Table type */
- if (tableinfo.reloftype)
- {
- printfPQExpBuffer(&buf, _("Typed table of type: %s"), tableinfo.reloftype);
- printTableAddFooter(&cont, buf.data);
- }
+ printTableAddFooter(&cont, buf.data);
+ }
+ }
+ PQclear(result);
- if (verbose &&
- (tableinfo.relkind == RELKIND_RELATION ||
- tableinfo.relkind == RELKIND_MATVIEW) &&
+ /* Table type */
+ if (tableinfo.reloftype)
+ {
+ printfPQExpBuffer(&buf, _("Typed table of type: %s"), tableinfo.reloftype);
+ printTableAddFooter(&cont, buf.data);
+ }
- /*
- * No need to display default values; we already display a REPLICA
- * IDENTITY marker on indexes.
- */
- tableinfo.relreplident != 'i' &&
- ((strcmp(schemaname, "pg_catalog") != 0 && tableinfo.relreplident != 'd') ||
- (strcmp(schemaname, "pg_catalog") == 0 && tableinfo.relreplident != 'n')))
- {
- const char *s = _("Replica Identity");
+ if (verbose &&
+ (tableinfo.relkind == RELKIND_RELATION ||
+ tableinfo.relkind == RELKIND_MATVIEW) &&
- printfPQExpBuffer(&buf, "%s: %s",
- s,
- tableinfo.relreplident == 'f' ? "FULL" :
- tableinfo.relreplident == 'n' ? "NOTHING" :
- "???");
+ /*
+ * No need to display default values; we already display a
+ * REPLICA IDENTITY marker on indexes.
+ */
+ tableinfo.relreplident != 'i' &&
+ ((strcmp(schemaname, "pg_catalog") != 0 && tableinfo.relreplident != 'd') ||
+ (strcmp(schemaname, "pg_catalog") == 0 && tableinfo.relreplident != 'n')))
+ {
+ const char *s = _("Replica Identity");
- printTableAddFooter(&cont, buf.data);
- }
+ printfPQExpBuffer(&buf, "%s: %s",
+ s,
+ tableinfo.relreplident == 'f' ? "FULL" :
+ tableinfo.relreplident == 'n' ? "NOTHING" :
+ "???");
- /* OIDs, if verbose and not a materialized view */
- if (verbose && tableinfo.relkind != RELKIND_MATVIEW && tableinfo.hasoids)
- printTableAddFooter(&cont, _("Has OIDs: yes"));
+ printTableAddFooter(&cont, buf.data);
+ }
- /* Tablespace info */
- add_tablespace_footer(&cont, tableinfo.relkind, tableinfo.tablespace,
- true);
+ /* OIDs, if verbose and not a materialized view */
+ if (verbose && tableinfo.relkind != RELKIND_MATVIEW && tableinfo.hasoids)
+ printTableAddFooter(&cont, _("Has OIDs: yes"));
- /* Access method info */
- if (verbose && tableinfo.relam != NULL && !pset.hide_tableam)
- {
- printfPQExpBuffer(&buf, _("Access method: %s"), tableinfo.relam);
- printTableAddFooter(&cont, buf.data);
- }
+ /* Tablespace info */
+ add_tablespace_footer(&cont, tableinfo.relkind, tableinfo.tablespace,
+ true);
+
+ /* Access method info */
+ if (verbose && tableinfo.relam != NULL && !pset.hide_tableam)
+ {
+ printfPQExpBuffer(&buf, _("Access method: %s"), tableinfo.relam);
+ printTableAddFooter(&cont, buf.data);
+ }
+ }
+ break;
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_INDEX:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
/* reloptions, if verbose */
@@ -3348,59 +3478,71 @@ add_tablespace_footer(printTableContent *const cont, char relkind,
Oid tablespace, const bool newline)
{
/* relkinds for which we support tablespaces */
- if (relkind == RELKIND_RELATION ||
- relkind == RELKIND_MATVIEW ||
- relkind == RELKIND_INDEX ||
- relkind == RELKIND_PARTITIONED_TABLE ||
- relkind == RELKIND_PARTITIONED_INDEX ||
- relkind == RELKIND_TOASTVALUE)
+ switch ((RelKind) relkind)
{
- /*
- * We ignore the database default tablespace so that users not using
- * tablespaces don't need to know about them. This case also covers
- * pre-8.0 servers, for which tablespace will always be 0.
- */
- if (tablespace != 0)
- {
- PGresult *result = NULL;
- PQExpBufferData buf;
-
- initPQExpBuffer(&buf);
- printfPQExpBuffer(&buf,
- "SELECT spcname FROM pg_catalog.pg_tablespace\n"
- "WHERE oid = '%u';", tablespace);
- result = PSQLexec(buf.data);
- if (!result)
- {
- termPQExpBuffer(&buf);
- return;
- }
- /* Should always be the case, but.... */
- if (PQntuples(result) > 0)
+ case RELKIND_RELATION:
+ case RELKIND_MATVIEW:
+ case RELKIND_INDEX:
+ case RELKIND_PARTITIONED_TABLE:
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_TOASTVALUE:
{
- if (newline)
- {
- /* Add the tablespace as a new footer */
- printfPQExpBuffer(&buf, _("Tablespace: \"%s\""),
- PQgetvalue(result, 0, 0));
- printTableAddFooter(cont, buf.data);
- }
- else
+ /*
+ * We ignore the database default tablespace so that users not
+ * using tablespaces don't need to know about them. This case
+ * also covers pre-8.0 servers, for which tablespace will
+ * always be 0.
+ */
+ if (tablespace != 0)
{
- /* Append the tablespace to the latest footer */
- printfPQExpBuffer(&buf, "%s", cont->footer->data);
-
- /*-------
- translator: before this string there's an index description like
- '"foo_pkey" PRIMARY KEY, btree (a)' */
- appendPQExpBuffer(&buf, _(", tablespace \"%s\""),
- PQgetvalue(result, 0, 0));
- printTableSetFooter(cont, buf.data);
+ PGresult *result = NULL;
+ PQExpBufferData buf;
+
+ initPQExpBuffer(&buf);
+ printfPQExpBuffer(&buf,
+ "SELECT spcname FROM pg_catalog.pg_tablespace\n"
+ "WHERE oid = '%u';", tablespace);
+ result = PSQLexec(buf.data);
+ if (!result)
+ {
+ termPQExpBuffer(&buf);
+ return;
+ }
+ /* Should always be the case, but.... */
+ if (PQntuples(result) > 0)
+ {
+ if (newline)
+ {
+ /* Add the tablespace as a new footer */
+ printfPQExpBuffer(&buf, _("Tablespace: \"%s\""),
+ PQgetvalue(result, 0, 0));
+ printTableAddFooter(cont, buf.data);
+ }
+ else
+ {
+ /* Append the tablespace to the latest footer */
+ printfPQExpBuffer(&buf, "%s", cont->footer->data);
+
+ /*-------
+ translator: before this string there's an index description like
+ '"foo_pkey" PRIMARY KEY, btree (a)' */
+ appendPQExpBuffer(&buf, _(", tablespace \"%s\""),
+ PQgetvalue(result, 0, 0));
+ printTableSetFooter(cont, buf.data);
+ }
+ }
+ PQclear(result);
+ termPQExpBuffer(&buf);
}
}
- PQclear(result);
- termPQExpBuffer(&buf);
- }
+ break;
+ case RELKIND_SEQUENCE:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_VIEW:
+ case RELKIND_NULL:
+ default:
+ break;
}
}
@@ -3694,15 +3836,15 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
"SELECT n.nspname as \"%s\",\n"
" c.relname as \"%s\",\n"
" CASE c.relkind"
- " WHEN " CppAsString2(RELKIND_RELATION) " THEN '%s'"
- " WHEN " CppAsString2(RELKIND_VIEW) " THEN '%s'"
- " WHEN " CppAsString2(RELKIND_MATVIEW) " THEN '%s'"
- " WHEN " CppAsString2(RELKIND_INDEX) " THEN '%s'"
- " WHEN " CppAsString2(RELKIND_SEQUENCE) " THEN '%s'"
+ " WHEN " RelKindAsString(RELKIND_RELATION) " THEN '%s'"
+ " WHEN " RelKindAsString(RELKIND_VIEW) " THEN '%s'"
+ " WHEN " RelKindAsString(RELKIND_MATVIEW) " THEN '%s'"
+ " WHEN " RelKindAsString(RELKIND_INDEX) " THEN '%s'"
+ " WHEN " RelKindAsString(RELKIND_SEQUENCE) " THEN '%s'"
" WHEN 's' THEN '%s'"
- " WHEN " CppAsString2(RELKIND_FOREIGN_TABLE) " THEN '%s'"
- " WHEN " CppAsString2(RELKIND_PARTITIONED_TABLE) " THEN '%s'"
- " WHEN " CppAsString2(RELKIND_PARTITIONED_INDEX) " THEN '%s'"
+ " WHEN " RelKindAsString(RELKIND_FOREIGN_TABLE) " THEN '%s'"
+ " WHEN " RelKindAsString(RELKIND_PARTITIONED_TABLE) " THEN '%s'"
+ " WHEN " RelKindAsString(RELKIND_PARTITIONED_INDEX) " THEN '%s'"
" END as \"%s\",\n"
" pg_catalog.pg_get_userbyid(c.relowner) as \"%s\"",
gettext_noop("Schema"),
@@ -3779,21 +3921,21 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
appendPQExpBufferStr(&buf, "\nWHERE c.relkind IN (");
if (showTables)
- appendPQExpBufferStr(&buf, CppAsString2(RELKIND_RELATION) ","
- CppAsString2(RELKIND_PARTITIONED_TABLE) ",");
+ appendPQExpBufferStr(&buf, RelKindAsString(RELKIND_RELATION) ","
+ RelKindAsString(RELKIND_PARTITIONED_TABLE) ",");
if (showViews)
- appendPQExpBufferStr(&buf, CppAsString2(RELKIND_VIEW) ",");
+ appendPQExpBufferStr(&buf, RelKindAsString(RELKIND_VIEW) ",");
if (showMatViews)
- appendPQExpBufferStr(&buf, CppAsString2(RELKIND_MATVIEW) ",");
+ appendPQExpBufferStr(&buf, RelKindAsString(RELKIND_MATVIEW) ",");
if (showIndexes)
- appendPQExpBufferStr(&buf, CppAsString2(RELKIND_INDEX) ","
- CppAsString2(RELKIND_PARTITIONED_INDEX) ",");
+ appendPQExpBufferStr(&buf, RelKindAsString(RELKIND_INDEX) ","
+ RelKindAsString(RELKIND_PARTITIONED_INDEX) ",");
if (showSeq)
- appendPQExpBufferStr(&buf, CppAsString2(RELKIND_SEQUENCE) ",");
+ appendPQExpBufferStr(&buf, RelKindAsString(RELKIND_SEQUENCE) ",");
if (showSystem || pattern)
appendPQExpBufferStr(&buf, "'s',"); /* was RELKIND_SPECIAL */
if (showForeign)
- appendPQExpBufferStr(&buf, CppAsString2(RELKIND_FOREIGN_TABLE) ",");
+ appendPQExpBufferStr(&buf, RelKindAsString(RELKIND_FOREIGN_TABLE) ",");
appendPQExpBufferStr(&buf, "''"); /* dummy */
appendPQExpBufferStr(&buf, ")\n");
@@ -3921,8 +4063,8 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
{
appendPQExpBuffer(&buf,
",\n CASE c.relkind"
- " WHEN " CppAsString2(RELKIND_PARTITIONED_TABLE) " THEN '%s'"
- " WHEN " CppAsString2(RELKIND_PARTITIONED_INDEX) " THEN '%s'"
+ " WHEN " RelKindAsString(RELKIND_PARTITIONED_TABLE) " THEN '%s'"
+ " WHEN " RelKindAsString(RELKIND_PARTITIONED_INDEX) " THEN '%s'"
" END as \"%s\"",
gettext_noop("partitioned table"),
gettext_noop("partitioned index"),
@@ -4012,9 +4154,9 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
appendPQExpBufferStr(&buf, "\nWHERE c.relkind IN (");
if (showTables)
- appendPQExpBufferStr(&buf, CppAsString2(RELKIND_PARTITIONED_TABLE) ",");
+ appendPQExpBufferStr(&buf, RelKindAsString(RELKIND_PARTITIONED_TABLE) ",");
if (showIndexes)
- appendPQExpBufferStr(&buf, CppAsString2(RELKIND_PARTITIONED_INDEX) ",");
+ appendPQExpBufferStr(&buf, RelKindAsString(RELKIND_PARTITIONED_INDEX) ",");
appendPQExpBufferStr(&buf, "''"); /* dummy */
appendPQExpBufferStr(&buf, ")\n");
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index eb018854a5..c56beb579b 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -354,7 +354,7 @@ static const SchemaQuery Query_for_list_of_datatypes = {
.catname = "pg_catalog.pg_type t",
/* selcondition --- ignore table rowtypes and array types */
.selcondition = "(t.typrelid = 0 "
- " OR (SELECT c.relkind = " CppAsString2(RELKIND_COMPOSITE_TYPE)
+ " OR (SELECT c.relkind = " RelKindAsString(RELKIND_COMPOSITE_TYPE)
" FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)) "
"AND t.typname !~ '^_'",
.viscondition = "pg_catalog.pg_type_is_visible(t.oid)",
@@ -366,7 +366,7 @@ static const SchemaQuery Query_for_list_of_datatypes = {
static const SchemaQuery Query_for_list_of_composite_datatypes = {
.catname = "pg_catalog.pg_type t",
/* selcondition --- only get composite types */
- .selcondition = "(SELECT c.relkind = " CppAsString2(RELKIND_COMPOSITE_TYPE)
+ .selcondition = "(SELECT c.relkind = " RelKindAsString(RELKIND_COMPOSITE_TYPE)
" FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid) "
"AND t.typname !~ '^_'",
.viscondition = "pg_catalog.pg_type_is_visible(t.oid)",
@@ -425,7 +425,7 @@ static const SchemaQuery Query_for_list_of_routines = {
static const SchemaQuery Query_for_list_of_sequences = {
.catname = "pg_catalog.pg_class c",
- .selcondition = "c.relkind IN (" CppAsString2(RELKIND_SEQUENCE) ")",
+ .selcondition = "c.relkind IN (" RelKindAsString(RELKIND_SEQUENCE) ")",
.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
.namespace = "c.relnamespace",
.result = "pg_catalog.quote_ident(c.relname)",
@@ -433,7 +433,7 @@ static const SchemaQuery Query_for_list_of_sequences = {
static const SchemaQuery Query_for_list_of_foreign_tables = {
.catname = "pg_catalog.pg_class c",
- .selcondition = "c.relkind IN (" CppAsString2(RELKIND_FOREIGN_TABLE) ")",
+ .selcondition = "c.relkind IN (" RelKindAsString(RELKIND_FOREIGN_TABLE) ")",
.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
.namespace = "c.relnamespace",
.result = "pg_catalog.quote_ident(c.relname)",
@@ -442,8 +442,8 @@ static const SchemaQuery Query_for_list_of_foreign_tables = {
static const SchemaQuery Query_for_list_of_tables = {
.catname = "pg_catalog.pg_class c",
.selcondition =
- "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
- CppAsString2(RELKIND_PARTITIONED_TABLE) ")",
+ "c.relkind IN (" RelKindAsString(RELKIND_RELATION) ", "
+ RelKindAsString(RELKIND_PARTITIONED_TABLE) ")",
.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
.namespace = "c.relnamespace",
.result = "pg_catalog.quote_ident(c.relname)",
@@ -451,7 +451,7 @@ static const SchemaQuery Query_for_list_of_tables = {
static const SchemaQuery Query_for_list_of_partitioned_tables = {
.catname = "pg_catalog.pg_class c",
- .selcondition = "c.relkind IN (" CppAsString2(RELKIND_PARTITIONED_TABLE) ")",
+ .selcondition = "c.relkind IN (" RelKindAsString(RELKIND_PARTITIONED_TABLE) ")",
.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
.namespace = "c.relnamespace",
.result = "pg_catalog.quote_ident(c.relname)",
@@ -459,7 +459,7 @@ static const SchemaQuery Query_for_list_of_partitioned_tables = {
static const SchemaQuery Query_for_list_of_views = {
.catname = "pg_catalog.pg_class c",
- .selcondition = "c.relkind IN (" CppAsString2(RELKIND_VIEW) ")",
+ .selcondition = "c.relkind IN (" RelKindAsString(RELKIND_VIEW) ")",
.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
.namespace = "c.relnamespace",
.result = "pg_catalog.quote_ident(c.relname)",
@@ -467,7 +467,7 @@ static const SchemaQuery Query_for_list_of_views = {
static const SchemaQuery Query_for_list_of_matviews = {
.catname = "pg_catalog.pg_class c",
- .selcondition = "c.relkind IN (" CppAsString2(RELKIND_MATVIEW) ")",
+ .selcondition = "c.relkind IN (" RelKindAsString(RELKIND_MATVIEW) ")",
.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
.namespace = "c.relnamespace",
.result = "pg_catalog.quote_ident(c.relname)",
@@ -476,8 +476,8 @@ static const SchemaQuery Query_for_list_of_matviews = {
static const SchemaQuery Query_for_list_of_indexes = {
.catname = "pg_catalog.pg_class c",
.selcondition =
- "c.relkind IN (" CppAsString2(RELKIND_INDEX) ", "
- CppAsString2(RELKIND_PARTITIONED_INDEX) ")",
+ "c.relkind IN (" RelKindAsString(RELKIND_INDEX) ", "
+ RelKindAsString(RELKIND_PARTITIONED_INDEX) ")",
.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
.namespace = "c.relnamespace",
.result = "pg_catalog.quote_ident(c.relname)",
@@ -485,7 +485,7 @@ static const SchemaQuery Query_for_list_of_indexes = {
static const SchemaQuery Query_for_list_of_partitioned_indexes = {
.catname = "pg_catalog.pg_class c",
- .selcondition = "c.relkind = " CppAsString2(RELKIND_PARTITIONED_INDEX),
+ .selcondition = "c.relkind = " RelKindAsString(RELKIND_PARTITIONED_INDEX),
.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
.namespace = "c.relnamespace",
.result = "pg_catalog.quote_ident(c.relname)",
@@ -503,8 +503,8 @@ static const SchemaQuery Query_for_list_of_relations = {
/* partitioned relations */
static const SchemaQuery Query_for_list_of_partitioned_relations = {
.catname = "pg_catalog.pg_class c",
- .selcondition = "c.relkind IN (" CppAsString2(RELKIND_PARTITIONED_TABLE)
- ", " CppAsString2(RELKIND_PARTITIONED_INDEX) ")",
+ .selcondition = "c.relkind IN (" RelKindAsString(RELKIND_PARTITIONED_TABLE)
+ ", " RelKindAsString(RELKIND_PARTITIONED_INDEX) ")",
.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
.namespace = "c.relnamespace",
.result = "pg_catalog.quote_ident(c.relname)",
@@ -521,10 +521,10 @@ static const SchemaQuery Query_for_list_of_operator_families = {
static const SchemaQuery Query_for_list_of_updatables = {
.catname = "pg_catalog.pg_class c",
.selcondition =
- "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
- CppAsString2(RELKIND_FOREIGN_TABLE) ", "
- CppAsString2(RELKIND_VIEW) ", "
- CppAsString2(RELKIND_PARTITIONED_TABLE) ")",
+ "c.relkind IN (" RelKindAsString(RELKIND_RELATION) ", "
+ RelKindAsString(RELKIND_FOREIGN_TABLE) ", "
+ RelKindAsString(RELKIND_VIEW) ", "
+ RelKindAsString(RELKIND_PARTITIONED_TABLE) ")",
.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
.namespace = "c.relnamespace",
.result = "pg_catalog.quote_ident(c.relname)",
@@ -534,12 +534,12 @@ static const SchemaQuery Query_for_list_of_updatables = {
static const SchemaQuery Query_for_list_of_selectables = {
.catname = "pg_catalog.pg_class c",
.selcondition =
- "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
- CppAsString2(RELKIND_SEQUENCE) ", "
- CppAsString2(RELKIND_VIEW) ", "
- CppAsString2(RELKIND_MATVIEW) ", "
- CppAsString2(RELKIND_FOREIGN_TABLE) ", "
- CppAsString2(RELKIND_PARTITIONED_TABLE) ")",
+ "c.relkind IN (" RelKindAsString(RELKIND_RELATION) ", "
+ RelKindAsString(RELKIND_SEQUENCE) ", "
+ RelKindAsString(RELKIND_VIEW) ", "
+ RelKindAsString(RELKIND_MATVIEW) ", "
+ RelKindAsString(RELKIND_FOREIGN_TABLE) ", "
+ RelKindAsString(RELKIND_PARTITIONED_TABLE) ")",
.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
.namespace = "c.relnamespace",
.result = "pg_catalog.quote_ident(c.relname)",
@@ -552,10 +552,10 @@ static const SchemaQuery Query_for_list_of_selectables = {
static const SchemaQuery Query_for_list_of_analyzables = {
.catname = "pg_catalog.pg_class c",
.selcondition =
- "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
- CppAsString2(RELKIND_PARTITIONED_TABLE) ", "
- CppAsString2(RELKIND_MATVIEW) ", "
- CppAsString2(RELKIND_FOREIGN_TABLE) ")",
+ "c.relkind IN (" RelKindAsString(RELKIND_RELATION) ", "
+ RelKindAsString(RELKIND_PARTITIONED_TABLE) ", "
+ RelKindAsString(RELKIND_MATVIEW) ", "
+ RelKindAsString(RELKIND_FOREIGN_TABLE) ")",
.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
.namespace = "c.relnamespace",
.result = "pg_catalog.quote_ident(c.relname)",
@@ -565,9 +565,9 @@ static const SchemaQuery Query_for_list_of_analyzables = {
static const SchemaQuery Query_for_list_of_indexables = {
.catname = "pg_catalog.pg_class c",
.selcondition =
- "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
- CppAsString2(RELKIND_PARTITIONED_TABLE) ", "
- CppAsString2(RELKIND_MATVIEW) ")",
+ "c.relkind IN (" RelKindAsString(RELKIND_RELATION) ", "
+ RelKindAsString(RELKIND_PARTITIONED_TABLE) ", "
+ RelKindAsString(RELKIND_MATVIEW) ")",
.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
.namespace = "c.relnamespace",
.result = "pg_catalog.quote_ident(c.relname)",
@@ -577,8 +577,8 @@ static const SchemaQuery Query_for_list_of_indexables = {
static const SchemaQuery Query_for_list_of_vacuumables = {
.catname = "pg_catalog.pg_class c",
.selcondition =
- "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
- CppAsString2(RELKIND_MATVIEW) ")",
+ "c.relkind IN (" RelKindAsString(RELKIND_RELATION) ", "
+ RelKindAsString(RELKIND_MATVIEW) ")",
.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
.namespace = "c.relnamespace",
.result = "pg_catalog.quote_ident(c.relname)",
diff --git a/src/bin/scripts/reindexdb.c b/src/bin/scripts/reindexdb.c
index b7b19ccc1c..1b921a1483 100644
--- a/src/bin/scripts/reindexdb.c
+++ b/src/bin/scripts/reindexdb.c
@@ -621,8 +621,8 @@ get_parallel_object_list(PGconn *conn, ReindexType type,
" ON c.relnamespace = ns.oid\n"
" WHERE ns.nspname != 'pg_catalog'\n"
" AND c.relkind IN ("
- CppAsString2(RELKIND_RELATION) ", "
- CppAsString2(RELKIND_MATVIEW) ")\n"
+ RelKindAsString(RELKIND_RELATION) ", "
+ RelKindAsString(RELKIND_MATVIEW) ")\n"
" ORDER BY c.relpages DESC;");
break;
@@ -643,8 +643,8 @@ get_parallel_object_list(PGconn *conn, ReindexType type,
" JOIN pg_catalog.pg_namespace ns"
" ON c.relnamespace = ns.oid\n"
" WHERE c.relkind IN ("
- CppAsString2(RELKIND_RELATION) ", "
- CppAsString2(RELKIND_MATVIEW) ")\n"
+ RelKindAsString(RELKIND_RELATION) ", "
+ RelKindAsString(RELKIND_MATVIEW) ")\n"
" AND ns.nspname IN (");
for (cell = user_list->head; cell; cell = cell->next)
diff --git a/src/bin/scripts/vacuumdb.c b/src/bin/scripts/vacuumdb.c
index 6a3c941158..9a90e820f4 100644
--- a/src/bin/scripts/vacuumdb.c
+++ b/src/bin/scripts/vacuumdb.c
@@ -573,8 +573,8 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts,
if (!tables_listed)
{
appendPQExpBufferStr(&catalog_query, " WHERE c.relkind OPERATOR(pg_catalog.=) ANY (array["
- CppAsString2(RELKIND_RELATION) ", "
- CppAsString2(RELKIND_MATVIEW) "])\n");
+ RelKindAsString(RELKIND_RELATION) ", "
+ RelKindAsString(RELKIND_MATVIEW) "])\n");
has_where = true;
}
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index 78b33b2a7f..6e9955fe6a 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -154,16 +154,34 @@ typedef FormData_pg_class *Form_pg_class;
#ifdef EXPOSE_TO_CLIENT_CODE
-#define RELKIND_RELATION 'r' /* ordinary table */
-#define RELKIND_INDEX 'i' /* secondary index */
-#define RELKIND_SEQUENCE 'S' /* sequence object */
-#define RELKIND_TOASTVALUE 't' /* for out-of-line values */
-#define RELKIND_VIEW 'v' /* view */
-#define RELKIND_MATVIEW 'm' /* materialized view */
-#define RELKIND_COMPOSITE_TYPE 'c' /* composite type */
-#define RELKIND_FOREIGN_TABLE 'f' /* foreign table */
-#define RELKIND_PARTITIONED_TABLE 'p' /* partitioned table */
-#define RELKIND_PARTITIONED_INDEX 'I' /* partitioned index */
+typedef enum RelKind
+{
+ RELKIND_RELATION = 'r', /* ordinary table */
+ RELKIND_INDEX = 'i', /* secondary index */
+ RELKIND_SEQUENCE = 'S', /* sequence object */
+ RELKIND_TOASTVALUE = 't', /* for out-of-line values */
+ RELKIND_VIEW = 'v', /* view */
+ RELKIND_MATVIEW = 'm', /* materialized view */
+ RELKIND_COMPOSITE_TYPE = 'c', /* composite type */
+ RELKIND_FOREIGN_TABLE = 'f', /* foreign table */
+ RELKIND_PARTITIONED_TABLE = 'p', /* partitioned table */
+ RELKIND_PARTITIONED_INDEX = 'I', /* partitioned index */
+ RELKIND_NULL = '\0' /* unset */
+} RelKind;
+
+#define chr_RELKIND_RELATION 'r'
+#define chr_RELKIND_INDEX 'i'
+#define chr_RELKIND_SEQUENCE 'S'
+#define chr_RELKIND_TOASTVALUE 't'
+#define chr_RELKIND_VIEW 'v'
+#define chr_RELKIND_MATVIEW 'm'
+#define chr_RELKIND_COMPOSITE_TYPE 'c'
+#define chr_RELKIND_FOREIGN_TABLE 'f'
+#define chr_RELKIND_PARTITIONED_TABLE 'p'
+#define chr_RELKIND_PARTITIONED_INDEX 'I'
+#define chr_RELKIND_NULL '\0'
+
+#define RelKindAsString(x) CppAsString2(chr_##x)
#define RELPERSISTENCE_PERMANENT 'p' /* regular table */
#define RELPERSISTENCE_UNLOGGED 'u' /* unlogged permanent table */
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index f5dfa32d55..a9a2bf1fb6 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2110,7 +2110,7 @@ typedef struct AggregateInstrumentation
Size hash_mem_peak; /* peak hash table memory usage */
uint64 hash_disk_used; /* kB of disk space used */
int hash_batches_used; /* batches used during entire execution */
-} AggregateInstrumentation;
+} AggregateInstrumentation;
/* ----------------
* Shared memory container for per-worker aggregate information
@@ -2120,7 +2120,7 @@ typedef struct SharedAggInfo
{
int num_workers;
AggregateInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER];
-} SharedAggInfo;
+} SharedAggInfo;
/* ---------------------
* AggState information
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index b20e2ad4f6..65602a8763 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -81,7 +81,7 @@ typedef enum
PROC_WAIT_STATUS_OK,
PROC_WAIT_STATUS_WAITING,
PROC_WAIT_STATUS_ERROR,
-} ProcWaitStatus;
+} ProcWaitStatus;
/*
* Each backend has a PGPROC struct in shared memory. There is also a list of
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index f8595642da..e92617111d 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -47,11 +47,11 @@ extern int namestrcmp(Name name, const char *str);
extern int32 pg_atoi(const char *s, int size, int c);
extern int16 pg_strtoint16(const char *s);
extern int32 pg_strtoint32(const char *s);
-extern int pg_itoa(int16 i, char *a);
-extern int pg_ultoa_n(uint32 l, char *a);
-extern int pg_ulltoa_n(uint64 l, char *a);
-extern int pg_ltoa(int32 l, char *a);
-extern int pg_lltoa(int64 ll, char *a);
+extern int pg_itoa(int16 i, char *a);
+extern int pg_ultoa_n(uint32 l, char *a);
+extern int pg_ulltoa_n(uint64 l, char *a);
+extern int pg_ltoa(int32 l, char *a);
+extern int pg_lltoa(int64 ll, char *a);
extern char *pg_ultostr_zeropad(char *str, uint32 value, int32 minwidth);
extern char *pg_ultostr(char *str, uint32 value);
extern uint64 pg_strtouint64(const char *str, char **endptr, int base);
diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c
index 828ff5a288..6a13603bb5 100644
--- a/src/pl/plpgsql/src/pl_comp.c
+++ b/src/pl/plpgsql/src/pl_comp.c
@@ -1723,14 +1723,23 @@ plpgsql_parse_cwordtype(List *idents)
* It must be a relation, sequence, view, materialized view, composite
* type, or foreign table
*/
- if (classStruct->relkind != RELKIND_RELATION &&
- classStruct->relkind != RELKIND_SEQUENCE &&
- classStruct->relkind != RELKIND_VIEW &&
- classStruct->relkind != RELKIND_MATVIEW &&
- classStruct->relkind != RELKIND_COMPOSITE_TYPE &&
- classStruct->relkind != RELKIND_FOREIGN_TABLE &&
- classStruct->relkind != RELKIND_PARTITIONED_TABLE)
- goto done;
+ switch ((RelKind) classStruct->relkind)
+ {
+ case RELKIND_RELATION:
+ case RELKIND_SEQUENCE:
+ case RELKIND_VIEW:
+ case RELKIND_MATVIEW:
+ case RELKIND_COMPOSITE_TYPE:
+ case RELKIND_FOREIGN_TABLE:
+ case RELKIND_PARTITIONED_TABLE:
+ break;
+ case RELKIND_PARTITIONED_INDEX:
+ case RELKIND_INDEX:
+ case RELKIND_TOASTVALUE:
+ case RELKIND_NULL:
+ default:
+ goto done;
+ }
/*
* Fetch the named table field and its type
diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c
index 02397f2eb1..87453751b0 100644
--- a/src/test/regress/regress.c
+++ b/src/test/regress/regress.c
@@ -816,7 +816,7 @@ test_spinlock(void)
char data_before[4];
slock_t lock;
char data_after[4];
- } struct_w_lock;
+ } struct_w_lock;
memcpy(struct_w_lock.data_before, "abcd", 4);
memcpy(struct_w_lock.data_after, "ef12", 4);
@@ -864,28 +864,28 @@ test_spinlock(void)
}
/*
- * Ensure that allocating more than INT32_MAX emulated spinlocks
- * works. That's interesting because the spinlock emulation uses a 32bit
- * integer to map spinlocks onto semaphores. There've been bugs...
+ * Ensure that allocating more than INT32_MAX emulated spinlocks works.
+ * That's interesting because the spinlock emulation uses a 32bit integer
+ * to map spinlocks onto semaphores. There've been bugs...
*/
#ifndef HAVE_SPINLOCKS
{
/*
- * Initialize enough spinlocks to advance counter close to
- * wraparound. It's too expensive to perform acquire/release for each,
- * as those may be syscalls when the spinlock emulation is used (and
- * even just atomic TAS would be expensive).
+ * Initialize enough spinlocks to advance counter close to wraparound.
+ * It's too expensive to perform acquire/release for each, as those
+ * may be syscalls when the spinlock emulation is used (and even just
+ * atomic TAS would be expensive).
*/
for (uint32 i = 0; i < INT32_MAX - 100000; i++)
{
- slock_t lock;
+ slock_t lock;
SpinLockInit(&lock);
}
for (uint32 i = 0; i < 200000; i++)
{
- slock_t lock;
+ slock_t lock;
SpinLockInit(&lock);
@@ -915,7 +915,7 @@ test_spinlock(void)
static void
test_atomic_spin_nest(void)
{
- slock_t lock;
+ slock_t lock;
#define NUM_TEST_ATOMICS (NUM_SPINLOCK_SEMAPHORES + NUM_ATOMICS_SEMAPHORES + 27)
pg_atomic_uint32 atomics32[NUM_TEST_ATOMICS];
pg_atomic_uint64 atomics64[NUM_TEST_ATOMICS];
diff --git a/src/tools/findoidjoins/findoidjoins.c b/src/tools/findoidjoins/findoidjoins.c
index 5239332ea7..3961804b10 100644
--- a/src/tools/findoidjoins/findoidjoins.c
+++ b/src/tools/findoidjoins/findoidjoins.c
@@ -62,7 +62,7 @@ main(int argc, char **argv)
"SELECT c.relname, (SELECT nspname FROM "
"pg_catalog.pg_namespace n WHERE n.oid = c.relnamespace) AS nspname "
"FROM pg_catalog.pg_class c "
- "WHERE c.relkind = " CppAsString2(RELKIND_RELATION)
+ "WHERE c.relkind = " RelKindAsString(RELKIND_RELATION)
" AND c.oid < '%u'"
" AND EXISTS(SELECT * FROM pg_attribute a"
" WHERE a.attrelid = c.oid AND a.attname = 'oid' "
@@ -88,7 +88,7 @@ main(int argc, char **argv)
"FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a "
"WHERE a.attnum > 0"
" AND a.attname != 'oid'"
- " AND c.relkind = " CppAsString2(RELKIND_RELATION)
+ " AND c.relkind = " RelKindAsString(RELKIND_RELATION)
" AND c.oid < '%u'"
" AND a.attrelid = c.oid"
" AND a.atttypid IN ('pg_catalog.oid'::regtype, "
@@ -166,7 +166,7 @@ main(int argc, char **argv)
"a.attname "
"FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a "
"WHERE a.attnum > 0"
- " AND c.relkind = " CppAsString2(RELKIND_RELATION)
+ " AND c.relkind = " RelKindAsString(RELKIND_RELATION)
" AND a.attrelid = c.oid"
" AND a.atttypid IN ('pg_catalog.oid[]'::regtype, "
" 'pg_catalog.oidvector'::regtype, "
--
2.21.1 (Apple Git-122.3)