Hi,

There have been mentions of turning Form_pg_class->relkind into an enum,
so that we can have compilers provide some more help with
switch(relkind) blocks.  Here's a quick experiment with that.

The most annoying part of this is that query-generating code uses
CppAsString2() to turn the char values into strings.  Making that code
use the enum values directly is quite messy, so before spending real
time into making that correct, I just added some ugly #define
RELKIND_x_STR macros, to substitute the uses of the other construct.
This is not intended to be final form.  This is 0001+0002, both
mechanical[1].

0003 is the backend-side change.  This looks generally reasonable,
though I'm annoyed that I couldn't find a way to coerce the compiler
into telling me if I had missed some spot.  I didn't change any
switch(relkind) blocks (except one in pg_overexplain which causes a
compiler warning for trying to use the non-existent '\0' value), but I
played with a couple of them by removing the default clauses and indeed
we now get warnings for missing cases.

Of course, pg_class.relkind itself (the on-disk catalog) continues to be
a single char with the same values as before.

Does this look more or less a direction we'd like to go in?

[1] git grep --files-with-matches 'CppAsString2(RELKIND' | xargs -n1 perl -pi 
-e 's/CppAsString2\((RELKIND[^)]*)\)/$1_STR/g'

-- 
Álvaro Herrera         PostgreSQL Developer  —  https://www.EnterpriseDB.com/
"Investigación es lo que hago cuando no sé lo que estoy haciendo"
(Wernher von Braun)
>From c19b754def5950bff939d0d3affaa8f7d65e38b3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <[email protected]>
Date: Mon, 2 Feb 2026 00:46:35 +0100
Subject: [PATCH 1/3] add RELKIND_x_STR macros

---
 src/include/catalog/pg_class.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index 89ab34c8349..4afff1e8a4e 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -175,6 +175,19 @@ MAKE_SYSCACHE(RELNAMENSP, pg_class_relname_nsp_index, 128);
 #define		  RELKIND_PARTITIONED_TABLE 'p' /* partitioned table */
 #define		  RELKIND_PARTITIONED_INDEX 'I' /* partitioned index */
 
+/* annoying defines for client-side C string construction */
+#define RELKIND_RELATION_STR			"'r'"
+#define RELKIND_INDEX_STR				"'i'"
+#define RELKIND_SEQUENCE_STR			"'S'"
+#define RELKIND_TOASTVALUE_STR			"'t'"
+#define RELKIND_VIEW_STR				"'v'"
+#define RELKIND_MATVIEW_STR				"'m'"
+#define RELKIND_COMPOSITE_TYPE_STR		"'c'"
+#define RELKIND_FOREIGN_TABLE_STR		"'f'"
+#define RELKIND_PARTITIONED_TABLE_STR	"'p'"
+#define RELKIND_PARTITIONED_INDEX_STR	"'I'"
+
+
 #define		  RELPERSISTENCE_PERMANENT	'p' /* regular table */
 #define		  RELPERSISTENCE_UNLOGGED	'u' /* unlogged permanent table */
 #define		  RELPERSISTENCE_TEMP		't' /* temporary table */
-- 
2.47.3

>From e27226bf56aab5655525daf2b486e789547d2407 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <[email protected]>
Date: Mon, 2 Feb 2026 00:45:58 +0100
Subject: [PATCH 2/3] replace CppAsString2(RELKIND_x) with RELKIND_x_STR

---
 contrib/oid2name/oid2name.c             | 18 +++---
 contrib/postgres_fdw/postgres_fdw.c     | 10 +--
 contrib/vacuumlo/vacuumlo.c             |  2 +-
 src/backend/commands/subscriptioncmds.c |  4 +-
 src/backend/utils/adt/xml.c             | 12 ++--
 src/bin/initdb/initdb.c                 | 20 +++---
 src/bin/pg_amcheck/pg_amcheck.c         | 32 ++++-----
 src/bin/pg_dump/pg_dump.c               | 36 +++++------
 src/bin/pg_upgrade/check.c              |  6 +-
 src/bin/pg_upgrade/info.c               |  6 +-
 src/bin/pg_upgrade/pg_upgrade.c         | 12 ++--
 src/bin/psql/describe.c                 | 74 ++++++++++-----------
 src/bin/psql/tab-complete.in.c          | 86 ++++++++++++-------------
 src/bin/scripts/reindexdb.c             |  8 +--
 src/bin/scripts/vacuuming.c             | 14 ++--
 15 files changed, 170 insertions(+), 170 deletions(-)

diff --git a/contrib/oid2name/oid2name.c b/contrib/oid2name/oid2name.c
index 51802907138..463bdfae320 100644
--- a/contrib/oid2name/oid2name.c
+++ b/contrib/oid2name/oid2name.c
@@ -477,8 +477,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 (" RELKIND_RELATION_STR ","
+			 RELKIND_MATVIEW_STR "%s%s) AND "
 			 "	%s"
 			 "		t.oid = CASE"
 			 "			WHEN reltablespace <> 0 THEN reltablespace"
@@ -486,8 +486,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 ? "," RELKIND_INDEX_STR "," RELKIND_SEQUENCE_STR : "",
+			 opts->systables ? "," RELKIND_TOASTVALUE_STR : "",
 			 opts->systables ? "" : "n.nspname NOT IN ('pg_catalog', 'information_schema') AND n.nspname !~ '^pg_toast' AND");
 
 	sql_exec(conn, todo, opts->quiet);
@@ -548,11 +548,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 (" RELKIND_RELATION_STR ","
+					RELKIND_MATVIEW_STR ","
+					RELKIND_INDEX_STR ","
+					RELKIND_SEQUENCE_STR ","
+					RELKIND_TOASTVALUE_STR ") AND\n"
 					"		t.oid = CASE\n"
 					"			WHEN reltablespace <> 0 THEN reltablespace\n"
 					"			ELSE dattablespace\n"
diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c
index 3572689e33b..e0457bb1253 100644
--- a/contrib/postgres_fdw/postgres_fdw.c
+++ b/contrib/postgres_fdw/postgres_fdw.c
@@ -5496,11 +5496,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) ") "
+						   RELKIND_RELATION_STR ","
+						   RELKIND_VIEW_STR ","
+						   RELKIND_FOREIGN_TABLE_STR ","
+						   RELKIND_MATVIEW_STR ","
+						   RELKIND_PARTITIONED_TABLE_STR ") "
 						   "  AND n.nspname = ");
 	deparseStringLiteral(&buf, stmt->remote_schema);
 
diff --git a/contrib/vacuumlo/vacuumlo.c b/contrib/vacuumlo/vacuumlo.c
index 8102569466b..343dae9bc20 100644
--- a/contrib/vacuumlo/vacuumlo.c
+++ b/contrib/vacuumlo/vacuumlo.c
@@ -198,7 +198,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 ('" RELKIND_RELATION_STR "', " RELKIND_MATVIEW_STR ")");
 	strcat(buf, "      AND s.nspname !~ '^pg_'");
 	res = PQexec(conn, buf);
 	if (PQresultStatus(res) != PGRES_TUPLES_OK)
diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c
index 0b3c8499b49..33e3c25a50c 100644
--- a/src/backend/commands/subscriptioncmds.c
+++ b/src/backend/commands/subscriptioncmds.c
@@ -2921,7 +2921,7 @@ fetch_relation_list(WalReceiverConn *wrconn, List *publications)
 		if (server_version >= 190000)
 			appendStringInfo(&cmd,
 							 "UNION ALL\n"
-							 "  SELECT DISTINCT s.schemaname, s.sequencename, " CppAsString2(RELKIND_SEQUENCE) "::\"char\" AS relkind, NULL::int2vector AS attrs\n"
+							 "  SELECT DISTINCT s.schemaname, s.sequencename, " RELKIND_SEQUENCE_STR "::\"char\" AS relkind, NULL::int2vector AS attrs\n"
 							 "  FROM pg_catalog.pg_publication_sequences s\n"
 							 "  WHERE s.pubname IN ( %s )",
 							 pub_names.data);
@@ -2929,7 +2929,7 @@ fetch_relation_list(WalReceiverConn *wrconn, List *publications)
 	else
 	{
 		tableRow[3] = NAMEARRAYOID;
-		appendStringInfoString(&cmd, "SELECT DISTINCT t.schemaname, t.tablename, " CppAsString2(RELKIND_RELATION) "::\"char\" AS relkind \n");
+		appendStringInfoString(&cmd, "SELECT DISTINCT t.schemaname, t.tablename, " RELKIND_RELATION_STR "::\"char\" AS relkind \n");
 
 		/* Get column lists for each relation if the publisher supports it */
 		if (check_columnlist)
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c
index f69dc68286c..7de019a7402 100644
--- a/src/backend/utils/adt/xml.c
+++ b/src/backend/utils/adt/xml.c
@@ -2857,9 +2857,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) ")"
+					 RELKIND_RELATION_STR ","
+					 RELKIND_MATVIEW_STR ","
+					 RELKIND_VIEW_STR ")"
 					 " AND pg_catalog.has_table_privilege (oid, 'SELECT')"
 					 " ORDER BY relname;", nspid);
 
@@ -2889,9 +2889,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) ")"
+							 RELKIND_RELATION_STR ","
+							 RELKIND_MATVIEW_STR ","
+							 RELKIND_VIEW_STR ")"
 							 " AND pg_catalog.has_table_privilege(pg_class.oid, 'SELECT')"
 							 " AND relnamespace IN (" XML_VISIBLE_SCHEMAS ");");
 }
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index a3980e5535f..11bfdd31cbf 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -1806,12 +1806,12 @@ setup_privileges(FILE *cmdfd)
 				  "  SET relacl = (SELECT array_agg(a.acl) FROM "
 				  " (SELECT E'=r/\"%s\"' as acl "
 				  "  UNION SELECT unnest(pg_catalog.acldefault("
-				  "    CASE WHEN relkind = " CppAsString2(RELKIND_SEQUENCE) " THEN 's' "
+				  "    CASE WHEN relkind = " RELKIND_SEQUENCE_STR " 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 (" RELKIND_RELATION_STR ", "
+				  RELKIND_VIEW_STR ", " RELKIND_MATVIEW_STR ", "
+				  RELKIND_SEQUENCE_STR ")"
 				  "  AND relacl IS NULL;\n\n",
 				  escape_quotes(username));
 	PG_CMD_PUTS("GRANT USAGE ON SCHEMA pg_catalog, public TO PUBLIC;\n\n");
@@ -1828,9 +1828,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 (" RELKIND_RELATION_STR ", "
+				RELKIND_VIEW_STR ", " RELKIND_MATVIEW_STR ", "
+				RELKIND_SEQUENCE_STR ");\n\n");
 	PG_CMD_PUTS("INSERT INTO pg_init_privs "
 				"  (objoid, classoid, objsubid, initprivs, privtype)"
 				"    SELECT"
@@ -1844,9 +1844,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 (" RELKIND_RELATION_STR ", "
+				RELKIND_VIEW_STR ", " RELKIND_MATVIEW_STR ", "
+				RELKIND_SEQUENCE_STR ");\n\n");
 	PG_CMD_PUTS("INSERT INTO pg_init_privs "
 				"  (objoid, classoid, objsubid, initprivs, privtype)"
 				"    SELECT"
diff --git a/src/bin/pg_amcheck/pg_amcheck.c b/src/bin/pg_amcheck/pg_amcheck.c
index 03e24a2577c..72bfcd2c813 100644
--- a/src/bin/pg_amcheck/pg_amcheck.c
+++ b/src/bin/pg_amcheck/pg_amcheck.c
@@ -1976,28 +1976,28 @@ compile_relation_list_one_db(PGconn *conn, SimplePtrList *relations,
 		appendPQExpBuffer(&sql,
 						  " AND c.relam = %u "
 						  "AND c.relkind IN ("
-						  CppAsString2(RELKIND_RELATION) ", "
-						  CppAsString2(RELKIND_SEQUENCE) ", "
-						  CppAsString2(RELKIND_MATVIEW) ", "
-						  CppAsString2(RELKIND_TOASTVALUE) ") "
+						  RELKIND_RELATION_STR ", "
+						  RELKIND_SEQUENCE_STR ", "
+						  RELKIND_MATVIEW_STR ", "
+						  RELKIND_TOASTVALUE_STR ") "
 						  "AND c.relnamespace != %u",
 						  HEAP_TABLE_AM_OID, PG_TOAST_NAMESPACE);
 	else
 		appendPQExpBuffer(&sql,
 						  " AND c.relam IN (%u, %u)"
 						  "AND c.relkind IN ("
-						  CppAsString2(RELKIND_RELATION) ", "
-						  CppAsString2(RELKIND_SEQUENCE) ", "
-						  CppAsString2(RELKIND_MATVIEW) ", "
-						  CppAsString2(RELKIND_TOASTVALUE) ", "
-						  CppAsString2(RELKIND_INDEX) ") "
+						  RELKIND_RELATION_STR ", "
+						  RELKIND_SEQUENCE_STR ", "
+						  RELKIND_MATVIEW_STR ", "
+						  RELKIND_TOASTVALUE_STR ", "
+						  RELKIND_INDEX_STR ") "
 						  "AND ((c.relam = %u AND c.relkind IN ("
-						  CppAsString2(RELKIND_RELATION) ", "
-						  CppAsString2(RELKIND_SEQUENCE) ", "
-						  CppAsString2(RELKIND_MATVIEW) ", "
-						  CppAsString2(RELKIND_TOASTVALUE) ")) OR "
+						  RELKIND_RELATION_STR ", "
+						  RELKIND_SEQUENCE_STR ", "
+						  RELKIND_MATVIEW_STR ", "
+						  RELKIND_TOASTVALUE_STR ")) OR "
 						  "(c.relam = %u AND c.relkind = "
-						  CppAsString2(RELKIND_INDEX) "))",
+						  RELKIND_INDEX_STR "))",
 						  HEAP_TABLE_AM_OID, BTREE_AM_OID,
 						  HEAP_TABLE_AM_OID, BTREE_AM_OID);
 
@@ -2058,7 +2058,7 @@ compile_relation_list_one_db(PGconn *conn, SimplePtrList *relations,
 								 "\nWHERE true");
 		appendPQExpBuffer(&sql,
 						  " AND c.relam = %u "
-						  "AND c.relkind = " CppAsString2(RELKIND_INDEX),
+						  "AND c.relkind = " RELKIND_INDEX_STR,
 						  BTREE_AM_OID);
 		if (opts.no_toast_expansion)
 			appendPQExpBuffer(&sql,
@@ -2095,7 +2095,7 @@ compile_relation_list_one_db(PGconn *conn, SimplePtrList *relations,
 								 "\nWHERE true");
 		appendPQExpBuffer(&sql,
 						  " AND c.relam = %u"
-						  " AND c.relkind = " CppAsString2(RELKIND_INDEX) ")",
+						  " AND c.relkind = " RELKIND_INDEX_STR ")",
 						  BTREE_AM_OID);
 	}
 
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 2bebefd0ba2..cdccccc1820 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -3158,14 +3158,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 = " RELKIND_MATVIEW_STR
 						 " 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 (" RELKIND_MATVIEW_STR ","
+						 RELKIND_VIEW_STR ") "
 						 "WHERE d1.classid = 'pg_class'::regclass "
 						 "UNION "
 						 "SELECT w.objid, d3.refobjid, c3.relkind "
@@ -3175,12 +3175,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 (" RELKIND_MATVIEW_STR ","
+						 RELKIND_VIEW_STR ") "
 						 ") "
 						 "SELECT 'pg_class'::regclass::oid AS classid, objid, refobjid "
 						 "FROM w "
-						 "WHERE refrelkind = " CppAsString2(RELKIND_MATVIEW));
+						 "WHERE refrelkind = " RELKIND_MATVIEW_STR);
 
 	res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
@@ -7279,9 +7279,9 @@ getTables(Archive *fout, int *numTables)
 						 "c.relhastriggers, c.relpersistence, "
 						 "c.reloftype, "
 						 "c.relacl, "
-						 "acldefault(CASE WHEN c.relkind = " CppAsString2(RELKIND_SEQUENCE)
+						 "acldefault(CASE WHEN c.relkind = " RELKIND_SEQUENCE_STR
 						 " THEN 's'::\"char\" ELSE 'r'::\"char\" END, c.relowner) AS acldefault, "
-						 "CASE WHEN c.relkind = " CppAsString2(RELKIND_FOREIGN_TABLE) " THEN "
+						 "CASE WHEN c.relkind = " RELKIND_FOREIGN_TABLE_STR " THEN "
 						 "(SELECT ftserver FROM pg_catalog.pg_foreign_table WHERE ftrelid = c.oid) "
 						 "ELSE 0 END AS foreignserver, "
 						 "c.relfrozenxid, tc.relfrozenxid AS tfrozenxid, "
@@ -7367,7 +7367,7 @@ getTables(Archive *fout, int *numTables)
 	appendPQExpBufferStr(query,
 						 "\nFROM pg_class c\n"
 						 "LEFT JOIN pg_depend d ON "
-						 "(c.relkind = " CppAsString2(RELKIND_SEQUENCE) " AND "
+						 "(c.relkind = " RELKIND_SEQUENCE_STR " AND "
 						 "d.classid = 'pg_class'::regclass AND d.objid = c.oid AND "
 						 "d.objsubid = 0 AND "
 						 "d.refclassid = 'pg_class'::regclass AND d.deptype IN ('a', 'i'))\n"
@@ -7387,8 +7387,8 @@ getTables(Archive *fout, int *numTables)
 	 */
 	appendPQExpBufferStr(query,
 						 "LEFT JOIN pg_class tc ON (c.reltoastrelid = tc.oid"
-						 " AND tc.relkind = " CppAsString2(RELKIND_TOASTVALUE)
-						 " AND c.relkind <> " CppAsString2(RELKIND_PARTITIONED_TABLE) ")\n");
+						 " AND tc.relkind = " RELKIND_TOASTVALUE_STR
+						 " AND c.relkind <> " RELKIND_PARTITIONED_TABLE_STR ")\n");
 
 	/*
 	 * Restrict to interesting relkinds (in particular, not indexes).  Not all
@@ -7402,13 +7402,13 @@ getTables(Archive *fout, int *numTables)
 	 */
 	appendPQExpBufferStr(query,
 						 "WHERE c.relkind IN ("
-						 CppAsString2(RELKIND_RELATION) ", "
-						 CppAsString2(RELKIND_SEQUENCE) ", "
-						 CppAsString2(RELKIND_VIEW) ", "
-						 CppAsString2(RELKIND_COMPOSITE_TYPE) ", "
-						 CppAsString2(RELKIND_MATVIEW) ", "
-						 CppAsString2(RELKIND_FOREIGN_TABLE) ", "
-						 CppAsString2(RELKIND_PARTITIONED_TABLE) ")\n"
+						 RELKIND_RELATION_STR ", "
+						 RELKIND_SEQUENCE_STR ", "
+						 RELKIND_VIEW_STR ", "
+						 RELKIND_COMPOSITE_TYPE_STR ", "
+						 RELKIND_MATVIEW_STR ", "
+						 RELKIND_FOREIGN_TABLE_STR ", "
+						 RELKIND_PARTITIONED_TABLE_STR ")\n"
 						 "ORDER BY c.oid");
 
 	res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c
index a8d20a92a98..5d053563657 100644
--- a/src/bin/pg_upgrade/check.c
+++ b/src/bin/pg_upgrade/check.c
@@ -372,9 +372,9 @@ data_type_check_query(int checknum)
 					"		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 "
+					RELKIND_RELATION_STR ", "
+					RELKIND_MATVIEW_STR ", "
+					RELKIND_INDEX_STR ") AND "
 					"		c.relnamespace = n.oid AND "
 	/* exclude possible orphaned temp tables */
 					"		n.nspname !~ '^pg_temp_' AND "
diff --git a/src/bin/pg_upgrade/info.c b/src/bin/pg_upgrade/info.c
index 47e8d1039a2..89bda44fcf9 100644
--- a/src/bin/pg_upgrade/info.c
+++ b/src/bin/pg_upgrade/info.c
@@ -508,8 +508,8 @@ get_rel_infos_query(void)
 					  "  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) "%s) AND "
+					  "  WHERE relkind IN (" RELKIND_RELATION_STR ", "
+					  RELKIND_MATVIEW_STR "%s) AND "
 	/* exclude possible orphaned temp tables */
 					  "    ((n.nspname !~ '^pg_temp_' AND "
 					  "      n.nspname !~ '^pg_toast_temp_' AND "
@@ -519,7 +519,7 @@ get_rel_infos_query(void)
 					  "     (n.nspname = 'pg_catalog' AND "
 					  "      relname IN ('pg_largeobject'%s) ))), ",
 					  (user_opts.transfer_mode == TRANSFER_MODE_SWAP) ?
-					  ", " CppAsString2(RELKIND_SEQUENCE) : "",
+					  ", " RELKIND_SEQUENCE_STR : "",
 					  FirstNormalObjectId,
 					  (GET_MAJOR_VERSION(old_cluster.major_version) >= 1600) ?
 					  ", 'pg_largeobject_metadata'" : "");
diff --git a/src/bin/pg_upgrade/pg_upgrade.c b/src/bin/pg_upgrade/pg_upgrade.c
index 2127d297bfe..e94f02fd369 100644
--- a/src/bin/pg_upgrade/pg_upgrade.c
+++ b/src/bin/pg_upgrade/pg_upgrade.c
@@ -990,9 +990,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) ")",
+									  RELKIND_RELATION_STR ", "
+									  RELKIND_MATVIEW_STR ", "
+									  RELKIND_TOASTVALUE_STR ")",
 									  old_cluster.controldata.chkpnt_nxtxid));
 
 		/* set pg_class.relminmxid */
@@ -1001,9 +1001,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) ")",
+								  RELKIND_RELATION_STR ", "
+								  RELKIND_MATVIEW_STR ", "
+								  RELKIND_TOASTVALUE_STR ")",
 								  old_cluster.controldata.chkpnt_nxtmulti));
 		PQfinish(conn);
 
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 3584c4e1428..f02a8df8875 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -689,7 +689,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 = " RELKIND_COMPOSITE_TYPE_STR
 						 " FROM pg_catalog.pg_class c "
 						 "WHERE c.oid = t.typrelid))\n");
 
@@ -1063,12 +1063,12 @@ permissionsList(const char *pattern, bool showSystem)
 					  "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 " RELKIND_RELATION_STR " THEN '%s'"
+					  " WHEN " RELKIND_VIEW_STR " THEN '%s'"
+					  " WHEN " RELKIND_MATVIEW_STR " THEN '%s'"
+					  " WHEN " RELKIND_SEQUENCE_STR " THEN '%s'"
+					  " WHEN " RELKIND_FOREIGN_TABLE_STR " THEN '%s'"
+					  " WHEN " RELKIND_PARTITIONED_TABLE_STR " THEN '%s'"
 					  " END as \"%s\",\n"
 					  "  ",
 					  gettext_noop("Schema"),
@@ -1164,12 +1164,12 @@ permissionsList(const char *pattern, bool showSystem)
 	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");
+						 RELKIND_RELATION_STR ","
+						 RELKIND_VIEW_STR ","
+						 RELKIND_MATVIEW_STR ","
+						 RELKIND_SEQUENCE_STR ","
+						 RELKIND_FOREIGN_TABLE_STR ","
+						 RELKIND_PARTITIONED_TABLE_STR ")\n");
 
 	if (!showSystem && !pattern)
 		appendPQExpBufferStr(&buf, "      AND n.nspname <> 'pg_catalog'\n"
@@ -3471,8 +3471,8 @@ describeOneTableDetails(const char *schemaname,
 						  "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)
+						  "  AND c.relkind != " RELKIND_PARTITIONED_TABLE_STR
+						  " AND c.relkind != " RELKIND_PARTITIONED_INDEX_STR
 						  "\nORDER BY inhseqno;",
 						  oid);
 
@@ -4067,15 +4067,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 " CppAsString2(RELKIND_TOASTVALUE) " THEN '%s'"
-					  " WHEN " CppAsString2(RELKIND_FOREIGN_TABLE) " THEN '%s'"
-					  " WHEN " CppAsString2(RELKIND_PARTITIONED_TABLE) " THEN '%s'"
-					  " WHEN " CppAsString2(RELKIND_PARTITIONED_INDEX) " THEN '%s'"
+					  " WHEN " RELKIND_RELATION_STR " THEN '%s'"
+					  " WHEN " RELKIND_VIEW_STR " THEN '%s'"
+					  " WHEN " RELKIND_MATVIEW_STR " THEN '%s'"
+					  " WHEN " RELKIND_INDEX_STR " THEN '%s'"
+					  " WHEN " RELKIND_SEQUENCE_STR " THEN '%s'"
+					  " WHEN " RELKIND_TOASTVALUE_STR " THEN '%s'"
+					  " WHEN " RELKIND_FOREIGN_TABLE_STR " THEN '%s'"
+					  " WHEN " RELKIND_PARTITIONED_TABLE_STR " THEN '%s'"
+					  " WHEN " RELKIND_PARTITIONED_INDEX_STR " THEN '%s'"
 					  " END as \"%s\",\n"
 					  "  pg_catalog.pg_get_userbyid(c.relowner) as \"%s\"",
 					  gettext_noop("Schema"),
@@ -4157,25 +4157,25 @@ 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, RELKIND_RELATION_STR ","
+							 RELKIND_PARTITIONED_TABLE_STR ",");
 		/* with 'S' or a pattern, allow 't' to match TOAST tables too */
 		if (showSystem || pattern)
-			appendPQExpBufferStr(&buf, CppAsString2(RELKIND_TOASTVALUE) ",");
+			appendPQExpBufferStr(&buf, RELKIND_TOASTVALUE_STR ",");
 	}
 	if (showViews)
-		appendPQExpBufferStr(&buf, CppAsString2(RELKIND_VIEW) ",");
+		appendPQExpBufferStr(&buf, RELKIND_VIEW_STR ",");
 	if (showMatViews)
-		appendPQExpBufferStr(&buf, CppAsString2(RELKIND_MATVIEW) ",");
+		appendPQExpBufferStr(&buf, RELKIND_MATVIEW_STR ",");
 	if (showIndexes)
-		appendPQExpBufferStr(&buf, CppAsString2(RELKIND_INDEX) ","
-							 CppAsString2(RELKIND_PARTITIONED_INDEX) ",");
+		appendPQExpBufferStr(&buf, RELKIND_INDEX_STR ","
+							 RELKIND_PARTITIONED_INDEX_STR ",");
 	if (showSeq)
-		appendPQExpBufferStr(&buf, CppAsString2(RELKIND_SEQUENCE) ",");
+		appendPQExpBufferStr(&buf, RELKIND_SEQUENCE_STR ",");
 	if (showSystem || pattern)
 		appendPQExpBufferStr(&buf, "'s',"); /* was RELKIND_SPECIAL */
 	if (showForeign)
-		appendPQExpBufferStr(&buf, CppAsString2(RELKIND_FOREIGN_TABLE) ",");
+		appendPQExpBufferStr(&buf, RELKIND_FOREIGN_TABLE_STR ",");
 
 	appendPQExpBufferStr(&buf, "''");	/* dummy */
 	appendPQExpBufferStr(&buf, ")\n");
@@ -4348,8 +4348,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 " RELKIND_PARTITIONED_TABLE_STR " THEN '%s'"
+						  " WHEN " RELKIND_PARTITIONED_INDEX_STR " THEN '%s'"
 						  " END as \"%s\"",
 						  gettext_noop("partitioned table"),
 						  gettext_noop("partitioned index"),
@@ -4449,9 +4449,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, RELKIND_PARTITIONED_TABLE_STR ",");
 	if (showIndexes)
-		appendPQExpBufferStr(&buf, CppAsString2(RELKIND_PARTITIONED_INDEX) ",");
+		appendPQExpBufferStr(&buf, RELKIND_PARTITIONED_INDEX_STR ",");
 	appendPQExpBufferStr(&buf, "''");	/* dummy */
 	appendPQExpBufferStr(&buf, ")\n");
 
diff --git a/src/bin/psql/tab-complete.in.c b/src/bin/psql/tab-complete.in.c
index 8b91bc00062..5434a1273b2 100644
--- a/src/bin/psql/tab-complete.in.c
+++ b/src/bin/psql/tab-complete.in.c
@@ -146,7 +146,7 @@ typedef struct SchemaQuery
 	 * Selection condition --- only rows meeting this condition are candidates
 	 * to display.  If catname mentions multiple tables, include the necessary
 	 * join condition here.  For example, this might look like "c.relkind = "
-	 * CppAsString2(RELKIND_RELATION).  Write NULL (not an empty string) if
+	 * RELKIND_RELATION_STR.  Write NULL (not an empty string) if
 	 * not needed.
 	 */
 	const char *selcondition;
@@ -591,7 +591,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 = " RELKIND_COMPOSITE_TYPE_STR
 	"     FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)) "
 	"AND t.typname !~ '^_'",
 	.viscondition = "pg_catalog.pg_type_is_visible(t.oid)",
@@ -603,7 +603,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 = " RELKIND_COMPOSITE_TYPE_STR
 	" FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid) "
 	"AND t.typname !~ '^_'",
 	.viscondition = "pg_catalog.pg_type_is_visible(t.oid)",
@@ -679,7 +679,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 (" RELKIND_SEQUENCE_STR ")",
 	.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
 	.namespace = "c.relnamespace",
 	.result = "c.relname",
@@ -687,7 +687,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 (" RELKIND_FOREIGN_TABLE_STR ")",
 	.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
 	.namespace = "c.relnamespace",
 	.result = "c.relname",
@@ -696,8 +696,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 (" RELKIND_RELATION_STR ", "
+	RELKIND_PARTITIONED_TABLE_STR ")",
 	.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
 	.namespace = "c.relnamespace",
 	.result = "c.relname",
@@ -705,7 +705,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 (" RELKIND_PARTITIONED_TABLE_STR ")",
 	.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
 	.namespace = "c.relnamespace",
 	.result = "c.relname",
@@ -714,8 +714,8 @@ static const SchemaQuery Query_for_list_of_partitioned_tables = {
 static const SchemaQuery Query_for_list_of_tables_for_constraint = {
 	.catname = "pg_catalog.pg_class c, pg_catalog.pg_constraint con",
 	.selcondition = "c.oid=con.conrelid and c.relkind IN ("
-	CppAsString2(RELKIND_RELATION) ", "
-	CppAsString2(RELKIND_PARTITIONED_TABLE) ")",
+	RELKIND_RELATION_STR ", "
+	RELKIND_PARTITIONED_TABLE_STR ")",
 	.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
 	.namespace = "c.relnamespace",
 	.result = "c.relname",
@@ -783,7 +783,7 @@ static const SchemaQuery Query_for_list_of_ts_templates = {
 
 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 (" RELKIND_VIEW_STR ")",
 	.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
 	.namespace = "c.relnamespace",
 	.result = "c.relname",
@@ -791,7 +791,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 (" RELKIND_MATVIEW_STR ")",
 	.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
 	.namespace = "c.relnamespace",
 	.result = "c.relname",
@@ -800,8 +800,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 (" RELKIND_INDEX_STR ", "
+	RELKIND_PARTITIONED_INDEX_STR ")",
 	.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
 	.namespace = "c.relnamespace",
 	.result = "c.relname",
@@ -809,7 +809,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 = " RELKIND_PARTITIONED_INDEX_STR,
 	.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
 	.namespace = "c.relnamespace",
 	.result = "c.relname",
@@ -827,8 +827,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 (" RELKIND_PARTITIONED_TABLE_STR
+	", " RELKIND_PARTITIONED_INDEX_STR ")",
 	.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
 	.namespace = "c.relnamespace",
 	.result = "c.relname",
@@ -845,10 +845,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 (" RELKIND_RELATION_STR ", "
+	RELKIND_FOREIGN_TABLE_STR ", "
+	RELKIND_VIEW_STR ", "
+	RELKIND_PARTITIONED_TABLE_STR ")",
 	.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
 	.namespace = "c.relnamespace",
 	.result = "c.relname",
@@ -858,9 +858,9 @@ static const SchemaQuery Query_for_list_of_updatables = {
 static const SchemaQuery Query_for_list_of_mergetargets = {
 	.catname = "pg_catalog.pg_class c",
 	.selcondition =
-	"c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
-	CppAsString2(RELKIND_VIEW) ", "
-	CppAsString2(RELKIND_PARTITIONED_TABLE) ") ",
+	"c.relkind IN (" RELKIND_RELATION_STR ", "
+	RELKIND_VIEW_STR ", "
+	RELKIND_PARTITIONED_TABLE_STR ") ",
 	.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
 	.namespace = "c.relnamespace",
 	.result = "c.relname",
@@ -870,12 +870,12 @@ static const SchemaQuery Query_for_list_of_mergetargets = {
 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 (" RELKIND_RELATION_STR ", "
+	RELKIND_SEQUENCE_STR ", "
+	RELKIND_VIEW_STR ", "
+	RELKIND_MATVIEW_STR ", "
+	RELKIND_FOREIGN_TABLE_STR ", "
+	RELKIND_PARTITIONED_TABLE_STR ")",
 	.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
 	.namespace = "c.relnamespace",
 	.result = "c.relname",
@@ -885,9 +885,9 @@ static const SchemaQuery Query_for_list_of_selectables = {
 static const SchemaQuery Query_for_list_of_truncatables = {
 	.catname = "pg_catalog.pg_class c",
 	.selcondition =
-	"c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
-	CppAsString2(RELKIND_FOREIGN_TABLE) ", "
-	CppAsString2(RELKIND_PARTITIONED_TABLE) ")",
+	"c.relkind IN (" RELKIND_RELATION_STR ", "
+	RELKIND_FOREIGN_TABLE_STR ", "
+	RELKIND_PARTITIONED_TABLE_STR ")",
 	.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
 	.namespace = "c.relnamespace",
 	.result = "c.relname",
@@ -900,10 +900,10 @@ static const SchemaQuery Query_for_list_of_truncatables = {
 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 (" RELKIND_RELATION_STR ", "
+	RELKIND_PARTITIONED_TABLE_STR ", "
+	RELKIND_MATVIEW_STR ", "
+	RELKIND_FOREIGN_TABLE_STR ")",
 	.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
 	.namespace = "c.relnamespace",
 	.result = "c.relname",
@@ -921,9 +921,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 (" RELKIND_RELATION_STR ", "
+	RELKIND_PARTITIONED_TABLE_STR ", "
+	RELKIND_MATVIEW_STR ")",
 	.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
 	.namespace = "c.relnamespace",
 	.result = "c.relname",
@@ -939,9 +939,9 @@ static const SchemaQuery Query_for_list_of_indexables = {
 static const SchemaQuery Query_for_list_of_clusterables = {
 	.catname = "pg_catalog.pg_class c",
 	.selcondition =
-	"c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
-	CppAsString2(RELKIND_PARTITIONED_TABLE) ", "
-	CppAsString2(RELKIND_MATVIEW) ")",
+	"c.relkind IN (" RELKIND_RELATION_STR ", "
+	RELKIND_PARTITIONED_TABLE_STR ", "
+	RELKIND_MATVIEW_STR ")",
 	.viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
 	.namespace = "c.relnamespace",
 	.result = "c.relname",
diff --git a/src/bin/scripts/reindexdb.c b/src/bin/scripts/reindexdb.c
index b15745256ff..e63dda7a7a1 100644
--- a/src/bin/scripts/reindexdb.c
+++ b/src/bin/scripts/reindexdb.c
@@ -651,8 +651,8 @@ get_parallel_tables_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"
+								 RELKIND_RELATION_STR ", "
+								 RELKIND_MATVIEW_STR ")\n"
 								 "   AND c.relpersistence != "
 								 CppAsString2(RELPERSISTENCE_TEMP) "\n"
 								 " ORDER BY c.relpages DESC;");
@@ -674,8 +674,8 @@ get_parallel_tables_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"
+									 RELKIND_RELATION_STR ", "
+									 RELKIND_MATVIEW_STR ")\n"
 									 "   AND c.relpersistence != "
 									 CppAsString2(RELPERSISTENCE_TEMP) "\n"
 									 " AND ns.nspname IN (");
diff --git a/src/bin/scripts/vacuuming.c b/src/bin/scripts/vacuuming.c
index faac9089a01..9c59cd31c50 100644
--- a/src/bin/scripts/vacuuming.c
+++ b/src/bin/scripts/vacuuming.c
@@ -598,8 +598,8 @@ retrieve_objects(PGconn *conn, vacuumingOptions *vacopts,
 						 " JOIN pg_catalog.pg_namespace ns"
 						 " ON c.relnamespace OPERATOR(pg_catalog.=) ns.oid\n"
 						 " CROSS JOIN LATERAL (SELECT c.relkind IN ("
-						 CppAsString2(RELKIND_PARTITIONED_TABLE) ", "
-						 CppAsString2(RELKIND_PARTITIONED_INDEX) ")) as p (inherited)\n"
+						 RELKIND_PARTITIONED_TABLE_STR ", "
+						 RELKIND_PARTITIONED_INDEX_STR ")) as p (inherited)\n"
 						 " LEFT JOIN pg_catalog.pg_class t"
 						 " ON c.reltoastrelid OPERATOR(pg_catalog.=) t.oid\n");
 
@@ -659,14 +659,14 @@ retrieve_objects(PGconn *conn, vacuumingOptions *vacopts,
 		if (vacopts->mode == MODE_ANALYZE)
 			appendPQExpBufferStr(&catalog_query,
 								 " AND c.relkind OPERATOR(pg_catalog.=) ANY (array["
-								 CppAsString2(RELKIND_RELATION) ", "
-								 CppAsString2(RELKIND_MATVIEW) ", "
-								 CppAsString2(RELKIND_PARTITIONED_TABLE) "])\n");
+								 RELKIND_RELATION_STR ", "
+								 RELKIND_MATVIEW_STR ", "
+								 RELKIND_PARTITIONED_TABLE_STR "])\n");
 		else
 			appendPQExpBufferStr(&catalog_query,
 								 " AND c.relkind OPERATOR(pg_catalog.=) ANY (array["
-								 CppAsString2(RELKIND_RELATION) ", "
-								 CppAsString2(RELKIND_MATVIEW) "])\n");
+								 RELKIND_RELATION_STR ", "
+								 RELKIND_MATVIEW_STR "])\n");
 	}
 
 	/*
-- 
2.47.3

>From 64ab49d9ff8b59ff93a4b76c4f70fb162b386724 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <[email protected]>
Date: Fri, 31 Oct 2025 14:07:45 +0100
Subject: [PATCH 3/3] Initial steps to making relkind an enum

---
 contrib/pg_overexplain/pg_overexplain.c      |  4 +---
 contrib/pg_prewarm/pg_prewarm.c              |  2 +-
 contrib/postgres_fdw/postgres_fdw.c          |  2 +-
 contrib/sepgsql/dml.c                        |  2 +-
 contrib/sepgsql/relation.c                   | 14 +++++------
 src/backend/access/common/reloptions.c       |  2 +-
 src/backend/catalog/aclchk.c                 |  6 ++---
 src/backend/catalog/heap.c                   | 14 +++++------
 src/backend/catalog/index.c                  |  2 +-
 src/backend/catalog/objectaddress.c          |  2 +-
 src/backend/catalog/pg_class.c               |  2 +-
 src/backend/catalog/pg_publication.c         |  6 ++---
 src/backend/catalog/pg_subscription.c        |  4 ++--
 src/backend/commands/copyto.c                |  2 +-
 src/backend/commands/createas.c              |  2 +-
 src/backend/commands/indexcmds.c             | 12 +++++-----
 src/backend/commands/lockcmds.c              |  4 ++--
 src/backend/commands/policy.c                |  2 +-
 src/backend/commands/publicationcmds.c       |  2 +-
 src/backend/commands/subscriptioncmds.c      |  8 +++----
 src/backend/commands/tablecmds.c             | 16 ++++++-------
 src/backend/commands/trigger.c               |  2 +-
 src/backend/executor/nodeModifyTable.c       |  4 ++--
 src/backend/nodes/gen_node_support.pl        |  3 ++-
 src/backend/optimizer/util/appendinfo.c      |  2 +-
 src/backend/replication/pgoutput/pgoutput.c  |  2 +-
 src/backend/statistics/stat_utils.c          |  2 +-
 src/backend/tcop/utility.c                   |  2 +-
 src/backend/utils/activity/pgstat_relation.c |  2 +-
 src/backend/utils/adt/acl.c                  |  6 ++---
 src/backend/utils/adt/partitionfuncs.c       |  4 ++--
 src/backend/utils/adt/ruleutils.c            |  2 +-
 src/backend/utils/cache/lsyscache.c          |  6 ++---
 src/backend/utils/cache/relcache.c           |  2 +-
 src/bin/pg_dump/pg_backup_archiver.c         |  2 +-
 src/bin/pg_dump/pg_backup_archiver.h         |  5 ++--
 src/bin/pg_dump/pg_dump.c                    | 10 ++++----
 src/bin/pg_dump/pg_dump.h                    |  6 ++---
 src/bin/pgbench/pgbench.c                    |  2 +-
 src/bin/psql/describe.c                      |  6 ++---
 src/include/access/reloptions.h              |  3 ++-
 src/include/catalog/heap.h                   |  7 +++---
 src/include/catalog/objectaddress.h          |  2 +-
 src/include/catalog/pg_class.h               | 25 +++++++++++---------
 src/include/catalog/pg_publication.h         |  2 +-
 src/include/commands/tablecmds.h             |  2 +-
 src/include/nodes/parsenodes.h               |  3 ++-
 src/include/replication/logicalproto.h       |  2 +-
 src/include/utils/lsyscache.h                |  3 ++-
 src/include/utils/relcache.h                 |  3 ++-
 50 files changed, 120 insertions(+), 112 deletions(-)

diff --git a/contrib/pg_overexplain/pg_overexplain.c b/contrib/pg_overexplain/pg_overexplain.c
index 316ffd1c87f..d575d462d97 100644
--- a/contrib/pg_overexplain/pg_overexplain.c
+++ b/contrib/pg_overexplain/pg_overexplain.c
@@ -534,10 +534,8 @@ overexplain_range_table(PlannedStmt *plannedstmt, ExplainState *es)
 			case RELKIND_PARTITIONED_INDEX:
 				relkind = "partitioned_index";
 				break;
-			case '\0':
-				relkind = NULL;
-				break;
 			default:
+				pg_unreachable();
 				relkind = psprintf("%c", rte->relkind);
 				break;
 		}
diff --git a/contrib/pg_prewarm/pg_prewarm.c b/contrib/pg_prewarm/pg_prewarm.c
index c2716086693..f320a0e3831 100644
--- a/contrib/pg_prewarm/pg_prewarm.c
+++ b/contrib/pg_prewarm/pg_prewarm.c
@@ -73,7 +73,7 @@ pg_prewarm(PG_FUNCTION_ARGS)
 	char	   *ttype;
 	PrewarmType ptype;
 	AclResult	aclresult;
-	char		relkind;
+	Relkind		relkind;
 	Oid			privOid;
 
 	/* Basic sanity checking. */
diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c
index e0457bb1253..5ff70f7ddfa 100644
--- a/contrib/postgres_fdw/postgres_fdw.c
+++ b/contrib/postgres_fdw/postgres_fdw.c
@@ -4951,7 +4951,7 @@ postgresGetAnalyzeInfoForForeignTable(Relation relation, bool *can_tablesample)
 	StringInfoData sql;
 	PGresult   *res;
 	double		reltuples;
-	char		relkind;
+	Relkind		relkind;
 
 	/* assume the remote relation does not support TABLESAMPLE */
 	*can_tablesample = false;
diff --git a/contrib/sepgsql/dml.c b/contrib/sepgsql/dml.c
index b44d09e447f..4f5864b22da 100644
--- a/contrib/sepgsql/dml.c
+++ b/contrib/sepgsql/dml.c
@@ -150,7 +150,7 @@ check_relation_privileges(Oid relOid,
 	char	   *audit_name;
 	Bitmapset  *columns;
 	int			index;
-	char		relkind = get_rel_relkind(relOid);
+	Relkind		relkind = get_rel_relkind(relOid);
 	bool		result = true;
 
 	/*
diff --git a/contrib/sepgsql/relation.c b/contrib/sepgsql/relation.c
index 5c61e1f4c81..a77a8b5a846 100644
--- a/contrib/sepgsql/relation.c
+++ b/contrib/sepgsql/relation.c
@@ -52,7 +52,7 @@ sepgsql_attribute_post_create(Oid relOid, AttrNumber attnum)
 	ObjectAddress object;
 	Form_pg_attribute attForm;
 	StringInfoData audit_name;
-	char		relkind = get_rel_relkind(relOid);
+	Relkind		relkind = get_rel_relkind(relOid);
 
 	/*
 	 * Only attributes within regular relations or partition relations have
@@ -134,7 +134,7 @@ sepgsql_attribute_drop(Oid relOid, AttrNumber attnum)
 {
 	ObjectAddress object;
 	char	   *audit_name;
-	char		relkind = get_rel_relkind(relOid);
+	Relkind		relkind = get_rel_relkind(relOid);
 
 	if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE)
 		return;
@@ -167,7 +167,7 @@ sepgsql_attribute_relabel(Oid relOid, AttrNumber attnum,
 {
 	ObjectAddress object;
 	char	   *audit_name;
-	char		relkind = get_rel_relkind(relOid);
+	Relkind		relkind = get_rel_relkind(relOid);
 
 	if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE)
 		ereport(ERROR,
@@ -210,7 +210,7 @@ sepgsql_attribute_setattr(Oid relOid, AttrNumber attnum)
 {
 	ObjectAddress object;
 	char	   *audit_name;
-	char		relkind = get_rel_relkind(relOid);
+	Relkind		relkind = get_rel_relkind(relOid);
 
 	if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE)
 		return;
@@ -418,7 +418,7 @@ sepgsql_relation_drop(Oid relOid)
 	ObjectAddress object;
 	char	   *audit_name;
 	uint16_t	tclass = 0;
-	char		relkind = get_rel_relkind(relOid);
+	Relkind		relkind = get_rel_relkind(relOid);
 
 	switch (relkind)
 	{
@@ -526,7 +526,7 @@ sepgsql_relation_truncate(Oid relOid)
 	ObjectAddress object;
 	char	   *audit_name;
 	uint16_t	tclass = 0;
-	char		relkind = get_rel_relkind(relOid);
+	Relkind		relkind = get_rel_relkind(relOid);
 
 	switch (relkind)
 	{
@@ -565,7 +565,7 @@ sepgsql_relation_relabel(Oid relOid, const char *seclabel)
 {
 	ObjectAddress object;
 	char	   *audit_name;
-	char		relkind = get_rel_relkind(relOid);
+	Relkind		relkind = get_rel_relkind(relOid);
 	uint16_t	tclass = 0;
 
 	if (relkind == RELKIND_RELATION || relkind == RELKIND_PARTITIONED_TABLE)
diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c
index 237ab8d0ed9..00b3588cded 100644
--- a/src/backend/access/common/reloptions.c
+++ b/src/backend/access/common/reloptions.c
@@ -2149,7 +2149,7 @@ view_reloptions(Datum reloptions, bool validate)
  * Parse options for heaps, views and toast tables.
  */
 bytea *
-heap_reloptions(char relkind, Datum reloptions, bool validate)
+heap_reloptions(Relkind relkind, Datum reloptions, bool validate)
 {
 	StdRdOptions *rdopts;
 
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index a431fc0926f..18a43e15509 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -123,7 +123,7 @@ static void SetDefaultACL(InternalDefaultACL *iacls);
 static List *objectNamesToOids(ObjectType objtype, List *objnames,
 							   bool is_grant);
 static List *objectsInSchemaToOids(ObjectType objtype, List *nspnames);
-static List *getRelationsInNamespace(Oid namespaceId, char relkind);
+static List *getRelationsInNamespace(Oid namespaceId, Relkind relkind);
 static void expand_col_privileges(List *colnames, Oid table_oid,
 								  AclMode this_privileges,
 								  AclMode *col_privileges,
@@ -875,7 +875,7 @@ objectsInSchemaToOids(ObjectType objtype, List *nspnames)
  * Return Oid list of relations in given namespace filtered by relation kind
  */
 static List *
-getRelationsInNamespace(Oid namespaceId, char relkind)
+getRelationsInNamespace(Oid namespaceId, Relkind relkind)
 {
 	List	   *relations = NIL;
 	ScanKeyData key[2];
@@ -890,7 +890,7 @@ getRelationsInNamespace(Oid namespaceId, char relkind)
 	ScanKeyInit(&key[1],
 				Anum_pg_class_relkind,
 				BTEqualStrategyNumber, F_CHAREQ,
-				CharGetDatum(relkind));
+				CharGetDatum((char) relkind));
 
 	rel = table_open(RelationRelationId, AccessShareLock);
 	scan = table_beginscan_catalog(rel, 2, key);
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 606434823cf..fa17893855d 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -89,7 +89,7 @@ static void AddNewRelationTuple(Relation pg_class_desc,
 								Oid new_type_oid,
 								Oid reloftype,
 								Oid relowner,
-								char relkind,
+								Relkind relkind,
 								TransactionId relfrozenxid,
 								TransactionId relminmxid,
 								Datum relacl,
@@ -289,7 +289,7 @@ heap_create(const char *relname,
 			RelFileNumber relfilenumber,
 			Oid accessmtd,
 			TupleDesc tupDesc,
-			char relkind,
+			Relkind relkind,
 			char relpersistence,
 			bool shared_relation,
 			bool mapped_relation,
@@ -449,7 +449,7 @@ heap_create(const char *relname,
  * --------------------------------
  */
 void
-CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind,
+CheckAttributeNamesTypes(TupleDesc tupdesc, Relkind relkind,
 						 int flags)
 {
 	int			i;
@@ -833,7 +833,7 @@ InsertPgAttributeTuples(Relation pg_attribute_rel,
 static void
 AddNewAttributeTuples(Oid new_rel_oid,
 					  TupleDesc tupdesc,
-					  char relkind)
+					  Relkind relkind)
 {
 	Relation	rel;
 	CatalogIndexState indstate;
@@ -939,7 +939,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relhasindex - 1] = BoolGetDatum(rd_rel->relhasindex);
 	values[Anum_pg_class_relisshared - 1] = BoolGetDatum(rd_rel->relisshared);
 	values[Anum_pg_class_relpersistence - 1] = CharGetDatum(rd_rel->relpersistence);
-	values[Anum_pg_class_relkind - 1] = CharGetDatum(rd_rel->relkind);
+	values[Anum_pg_class_relkind - 1] = CharGetDatum((char) rd_rel->relkind);
 	values[Anum_pg_class_relnatts - 1] = Int16GetDatum(rd_rel->relnatts);
 	values[Anum_pg_class_relchecks - 1] = Int16GetDatum(rd_rel->relchecks);
 	values[Anum_pg_class_relhasrules - 1] = BoolGetDatum(rd_rel->relhasrules);
@@ -987,7 +987,7 @@ AddNewRelationTuple(Relation pg_class_desc,
 					Oid new_type_oid,
 					Oid reloftype,
 					Oid relowner,
-					char relkind,
+					Relkind relkind,
 					TransactionId relfrozenxid,
 					TransactionId relminmxid,
 					Datum relacl,
@@ -1129,7 +1129,7 @@ heap_create_with_catalog(const char *relname,
 						 Oid accessmtd,
 						 TupleDesc tupdesc,
 						 List *cooked_constraints,
-						 char relkind,
+						 Relkind relkind,
 						 char relpersistence,
 						 bool shared_relation,
 						 bool mapped_relation,
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 43de42ce39e..ede4546ecee 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -757,7 +757,7 @@ index_create(Relation heapRelation,
 	bool		invalid = (flags & INDEX_CREATE_INVALID) != 0;
 	bool		concurrent = (flags & INDEX_CREATE_CONCURRENT) != 0;
 	bool		partitioned = (flags & INDEX_CREATE_PARTITIONED) != 0;
-	char		relkind;
+	Relkind		relkind;
 	TransactionId relfrozenxid;
 	MultiXactId relminmxid;
 	bool		create_storage = !RelFileNumberIsValid(relFileNumber);
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index 02af64b82c6..93b6e26d067 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -6182,7 +6182,7 @@ strlist_to_textarray(List *list)
  * message saying "table" than fail entirely.
  */
 ObjectType
-get_relkind_objtype(char relkind)
+get_relkind_objtype(Relkind relkind)
 {
 	switch (relkind)
 	{
diff --git a/src/backend/catalog/pg_class.c b/src/backend/catalog/pg_class.c
index 38cf89f09fa..a841ed20868 100644
--- a/src/backend/catalog/pg_class.c
+++ b/src/backend/catalog/pg_class.c
@@ -21,7 +21,7 @@
  * operation.
  */
 int
-errdetail_relkind_not_supported(char relkind)
+errdetail_relkind_not_supported(Relkind relkind)
 {
 	switch (relkind)
 	{
diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c
index 9a4791c573e..624ebd59697 100644
--- a/src/backend/catalog/pg_publication.c
+++ b/src/backend/catalog/pg_publication.c
@@ -866,7 +866,7 @@ GetAllTablesPublications(void)
  * publication.
  */
 List *
-GetAllPublicationRelations(char relkind, bool pubviaroot)
+GetAllPublicationRelations(Relkind relkind, bool pubviaroot)
 {
 	Relation	classRel;
 	ScanKeyData key[1];
@@ -881,7 +881,7 @@ GetAllPublicationRelations(char relkind, bool pubviaroot)
 	ScanKeyInit(&key[0],
 				Anum_pg_class_relkind,
 				BTEqualStrategyNumber, F_CHAREQ,
-				CharGetDatum(relkind));
+				CharGetDatum((char) relkind));
 
 	scan = table_beginscan_catalog(classRel, 1, key);
 
@@ -1016,7 +1016,7 @@ GetSchemaPublicationRelations(Oid schemaid, PublicationPartOpt pub_partopt)
 	{
 		Form_pg_class relForm = (Form_pg_class) GETSTRUCT(tuple);
 		Oid			relid = relForm->oid;
-		char		relkind;
+		Relkind		relkind;
 
 		if (!is_publishable_class(relid, relForm))
 			continue;
diff --git a/src/backend/catalog/pg_subscription.c b/src/backend/catalog/pg_subscription.c
index 2b103245290..988e80c2c31 100644
--- a/src/backend/catalog/pg_subscription.c
+++ b/src/backend/catalog/pg_subscription.c
@@ -537,7 +537,7 @@ HasSubscriptionTables(Oid subid)
 	while (HeapTupleIsValid(tup = systable_getnext(scan)))
 	{
 		Form_pg_subscription_rel subrel;
-		char		relkind;
+		Relkind		relkind;
 
 		subrel = (Form_pg_subscription_rel) GETSTRUCT(tup);
 		relkind = get_rel_relkind(subrel->srrelid);
@@ -600,7 +600,7 @@ GetSubscriptionRelations(Oid subid, bool tables, bool sequences,
 		SubscriptionRelState *relstate;
 		Datum		d;
 		bool		isnull;
-		char		relkind;
+		Relkind		relkind;
 
 		subrel = (Form_pg_subscription_rel) GETSTRUCT(tup);
 
diff --git a/src/backend/commands/copyto.c b/src/backend/commands/copyto.c
index 4ab4a3893d5..8d7530ea03b 100644
--- a/src/backend/commands/copyto.c
+++ b/src/backend/commands/copyto.c
@@ -692,7 +692,7 @@ BeginCopyTo(ParseState *pstate,
 
 			foreach_oid(child, children)
 			{
-				char		relkind = get_rel_relkind(child);
+				Relkind		relkind = get_rel_relkind(child);
 
 				if (relkind == RELKIND_FOREIGN_TABLE)
 				{
diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c
index 270e9bf3110..b05161a9aab 100644
--- a/src/backend/commands/createas.c
+++ b/src/backend/commands/createas.c
@@ -83,7 +83,7 @@ create_ctas_internal(List *attrList, IntoClause *into)
 {
 	CreateStmt *create = makeNode(CreateStmt);
 	bool		is_matview;
-	char		relkind;
+	Relkind		relkind;
 	Datum		toast_options;
 	const char *const validnsps[] = HEAP_RELOPT_NAMESPACES;
 	ObjectAddress intoRelationAddr;
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 635679cc1f2..dfb15f91931 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -133,7 +133,7 @@ typedef struct ReindexErrorInfo
 {
 	char	   *relname;
 	char	   *relnamespace;
-	char		relkind;
+	Relkind		relkind;
 } ReindexErrorInfo;
 
 /*
@@ -2947,7 +2947,7 @@ ReindexIndex(const ReindexStmt *stmt, const ReindexParams *params, bool isTopLev
 	struct ReindexIndexCallbackState state;
 	Oid			indOid;
 	char		persistence;
-	char		relkind;
+	Relkind		relkind;
 
 	/*
 	 * Find and lock index, and check permissions on table; use callback to
@@ -2998,7 +2998,7 @@ static void
 RangeVarCallbackForReindexIndex(const RangeVar *relation,
 								Oid relId, Oid oldRelId, void *arg)
 {
-	char		relkind;
+	Relkind		relkind;
 	struct ReindexIndexCallbackState *state = arg;
 	LOCKMODE	table_lockmode;
 	Oid			table_oid;
@@ -3373,7 +3373,7 @@ static void
 ReindexPartitions(const ReindexStmt *stmt, Oid relid, const ReindexParams *params, bool isTopLevel)
 {
 	List	   *partitions = NIL;
-	char		relkind = get_rel_relkind(relid);
+	Relkind		relkind = get_rel_relkind(relid);
 	char	   *relname = get_rel_name(relid);
 	char	   *relnamespace = get_namespace_name(get_rel_namespace(relid));
 	MemoryContext reindex_context;
@@ -3474,7 +3474,7 @@ ReindexMultipleInternal(const ReindexStmt *stmt, const List *relids, const Reind
 	foreach(l, relids)
 	{
 		Oid			relid = lfirst_oid(l);
-		char		relkind;
+		Relkind		relkind;
 		char		relpersistence;
 
 		StartTransactionCommand();
@@ -3608,7 +3608,7 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein
 			   *lc2;
 	MemoryContext private_context;
 	MemoryContext oldcontext;
-	char		relkind;
+	Relkind		relkind;
 	char	   *relationName = NULL;
 	char	   *relationNamespace = NULL;
 	PGRUsage	ru0;
diff --git a/src/backend/commands/lockcmds.c b/src/backend/commands/lockcmds.c
index f66b8f17b9b..416fb4fe7fe 100644
--- a/src/backend/commands/lockcmds.c
+++ b/src/backend/commands/lockcmds.c
@@ -72,7 +72,7 @@ RangeVarCallbackForLockTable(const RangeVar *rv, Oid relid, Oid oldrelid,
 							 void *arg)
 {
 	LOCKMODE	lockmode = *(LOCKMODE *) arg;
-	char		relkind;
+	Relkind		relkind;
 	char		relpersistence;
 	AclResult	aclresult;
 
@@ -190,7 +190,7 @@ LockViewRecurse_walker(Node *node, LockViewRecurse_context *context)
 			AclResult	aclresult;
 
 			Oid			relid = rte->relid;
-			char		relkind = rte->relkind;
+			Relkind		relkind = rte->relkind;
 			char	   *relname = get_rel_name(relid);
 
 			/* Currently, we only allow plain tables or views to be locked. */
diff --git a/src/backend/commands/policy.c b/src/backend/commands/policy.c
index 21b8eebe32d..3aee2444a80 100644
--- a/src/backend/commands/policy.c
+++ b/src/backend/commands/policy.c
@@ -66,7 +66,7 @@ RangeVarCallbackForPolicy(const RangeVar *rv, Oid relid, Oid oldrelid,
 {
 	HeapTuple	tuple;
 	Form_pg_class classform;
-	char		relkind;
+	Relkind		relkind;
 
 	tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
 	if (!HeapTupleIsValid(tuple))
diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c
index fc3a4c19e65..d8bb521f62e 100644
--- a/src/backend/commands/publicationcmds.c
+++ b/src/backend/commands/publicationcmds.c
@@ -1057,7 +1057,7 @@ AlterPublicationOptions(ParseState *pstate, AlterPublicationStmt *stmt,
 		{
 			Oid			relid = lfirst_oid(lc);
 			HeapTuple	rftuple;
-			char		relkind;
+			Relkind		relkind;
 			char	   *relname;
 			bool		has_rowfilter;
 			bool		has_collist;
diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c
index 33e3c25a50c..8403c4850a6 100644
--- a/src/backend/commands/subscriptioncmds.c
+++ b/src/backend/commands/subscriptioncmds.c
@@ -113,7 +113,7 @@ typedef struct SubOpts
 typedef struct PublicationRelKind
 {
 	RangeVar   *rv;
-	char		relkind;
+	Relkind		relkind;
 } PublicationRelKind;
 
 static List *fetch_relation_list(WalReceiverConn *wrconn, List *publications);
@@ -821,7 +821,7 @@ CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt,
 			foreach_ptr(PublicationRelKind, pubrelinfo, pubrels)
 			{
 				Oid			relid;
-				char		relkind;
+				Relkind		relkind;
 				RangeVar   *rv = pubrelinfo->rv;
 
 				relid = RangeVarGetRelid(rv, AccessShareLock, false);
@@ -1014,7 +1014,7 @@ AlterSubscription_refresh(Subscription *sub, bool copy_data,
 		{
 			RangeVar   *rv = pubrelinfo->rv;
 			Oid			relid;
-			char		relkind;
+			Relkind		relkind;
 
 			relid = RangeVarGetRelid(rv, AccessShareLock, false);
 			relkind = get_rel_relkind(relid);
@@ -2958,7 +2958,7 @@ fetch_relation_list(WalReceiverConn *wrconn, List *publications)
 		char	   *nspname;
 		char	   *relname;
 		bool		isnull;
-		char		relkind;
+		Relkind		relkind;
 		PublicationRelKind *relinfo = palloc_object(PublicationRelKind);
 
 		nspname = TextDatumGetCString(slot_getattr(slot, 1, &isnull));
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index f976c0e5c7e..7cdc6fa2e2a 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -170,7 +170,7 @@ typedef struct AlteredTableInfo
 {
 	/* Information saved before any work commences: */
 	Oid			relid;			/* Relation to work on */
-	char		relkind;		/* Its relkind */
+	Relkind		relkind;		/* Its relkind */
 	TupleDesc	oldDesc;		/* Pre-modification tuple descriptor */
 
 	/*
@@ -766,7 +766,7 @@ static void ATExecSplitPartition(List **wqueue, AlteredTableInfo *tab,
  * ----------------------------------------------------------------
  */
 ObjectAddress
-DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
+DefineRelation(CreateStmt *stmt, Relkind relkind, Oid ownerId,
 			   ObjectAddress *typaddress, const char *queryString)
 {
 	char		relname[NAMEDATALEN];
@@ -1534,7 +1534,7 @@ void
 RemoveRelations(DropStmt *drop)
 {
 	ObjectAddresses *objects;
-	char		relkind;
+	Relkind		relkind;
 	ListCell   *cell;
 	int			flags = 0;
 	LOCKMODE	lockmode = AccessExclusiveLock;
@@ -3792,7 +3792,7 @@ SetRelationTableSpace(Relation rel,
 static void
 renameatt_check(Oid myrelid, Form_pg_class classform, bool recursing)
 {
-	char		relkind = classform->relkind;
+	Relkind		relkind = classform->relkind;
 
 	if (classform->reloftype && !recursing)
 		ereport(ERROR,
@@ -4219,7 +4219,7 @@ RenameRelation(RenameStmt *stmt)
 	for (;;)
 	{
 		LOCKMODE	lockmode;
-		char		relkind;
+		Relkind		relkind;
 		bool		obj_is_index;
 
 		lockmode = is_index_stmt ? ShareUpdateExclusiveLock : AccessExclusiveLock;
@@ -7257,7 +7257,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
 	Form_pg_class relform;
 	Form_pg_attribute attribute;
 	int			newattnum;
-	char		relkind;
+	Relkind		relkind;
 	Expr	   *defval;
 	List	   *children;
 	ListCell   *child;
@@ -19522,7 +19522,7 @@ void
 RangeVarCallbackMaintainsTable(const RangeVar *relation,
 							   Oid relId, Oid oldRelId, void *arg)
 {
-	char		relkind;
+	Relkind		relkind;
 	AclResult	aclresult;
 
 	/* Nothing to do if the relation was not found. */
@@ -19619,7 +19619,7 @@ RangeVarCallbackForAlterRelation(const RangeVar *rv, Oid relid, Oid oldrelid,
 	HeapTuple	tuple;
 	Form_pg_class classform;
 	AclResult	aclresult;
-	char		relkind;
+	Relkind		relkind;
 
 	tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
 	if (!HeapTupleIsValid(tuple))
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 8df915f63fb..7bf826aa4aa 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -6178,7 +6178,7 @@ AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo,
 	TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
 	AfterTriggerEventData new_event;
 	AfterTriggerSharedData new_shared;
-	char		relkind = rel->rd_rel->relkind;
+	Relkind		relkind = rel->rd_rel->relkind;
 	int			tgtype_event;
 	int			tgtype_level;
 	int			i;
diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c
index f5e9d369940..4981aeba196 100644
--- a/src/backend/executor/nodeModifyTable.c
+++ b/src/backend/executor/nodeModifyTable.c
@@ -4351,7 +4351,7 @@ ExecModifyTable(PlanState *pstate)
 		if (operation == CMD_UPDATE || operation == CMD_DELETE ||
 			operation == CMD_MERGE)
 		{
-			char		relkind;
+			Relkind		relkind;
 			Datum		datum;
 			bool		isNull;
 
@@ -4869,7 +4869,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
 		if (operation == CMD_UPDATE || operation == CMD_DELETE ||
 			operation == CMD_MERGE)
 		{
-			char		relkind;
+			Relkind		relkind;
 
 			relkind = resultRelInfo->ri_RelationDesc->rd_rel->relkind;
 			if (relkind == RELKIND_RELATION ||
diff --git a/src/backend/nodes/gen_node_support.pl b/src/backend/nodes/gen_node_support.pl
index 4308751f787..2e141fa3dcb 100644
--- a/src/backend/nodes/gen_node_support.pl
+++ b/src/backend/nodes/gen_node_support.pl
@@ -136,7 +136,8 @@ my @nodetag_only;
 # types that are copied by straight assignment
 my @scalar_types = qw(
   bits32 bool char double int int8 int16 int32 int64 long uint8 uint16 uint32 uint64
-  AclMode AttrNumber Cardinality Cost Index Oid RelFileNumber Selectivity Size StrategyNumber SubTransactionId TimeLineID XLogRecPtr
+  AclMode AttrNumber Cardinality Cost Index Oid RelFileNumber Relkind
+  Selectivity Size StrategyNumber SubTransactionId TimeLineID XLogRecPtr
 );
 
 # collect enum types
diff --git a/src/backend/optimizer/util/appendinfo.c b/src/backend/optimizer/util/appendinfo.c
index 689840d6564..c5396116738 100644
--- a/src/backend/optimizer/util/appendinfo.c
+++ b/src/backend/optimizer/util/appendinfo.c
@@ -956,7 +956,7 @@ add_row_identity_columns(PlannerInfo *root, Index rtindex,
 						 Relation target_relation)
 {
 	CmdType		commandType = root->parse->commandType;
-	char		relkind = target_relation->rd_rel->relkind;
+	Relkind		relkind = target_relation->rd_rel->relkind;
 	Var		   *var;
 
 	Assert(commandType == CMD_UPDATE || commandType == CMD_DELETE || commandType == CMD_MERGE);
diff --git a/src/backend/replication/pgoutput/pgoutput.c b/src/backend/replication/pgoutput/pgoutput.c
index e016f64e0b3..4f1152f7f48 100644
--- a/src/backend/replication/pgoutput/pgoutput.c
+++ b/src/backend/replication/pgoutput/pgoutput.c
@@ -2100,7 +2100,7 @@ get_rel_sync_entry(PGOutputData *data, Relation relation)
 		Oid			publish_as_relid = relid;
 		int			publish_ancestor_level = 0;
 		bool		am_partition = get_rel_relispartition(relid);
-		char		relkind = get_rel_relkind(relid);
+		Relkind		relkind = get_rel_relkind(relid);
 		List	   *rel_publications = NIL;
 
 		/* Reload publications if needed before use. */
diff --git a/src/backend/statistics/stat_utils.c b/src/backend/statistics/stat_utils.c
index 9c680f1cb37..9a9fcda6edd 100644
--- a/src/backend/statistics/stat_utils.c
+++ b/src/backend/statistics/stat_utils.c
@@ -148,7 +148,7 @@ RangeVarCallbackForStats(const RangeVar *relation,
 	Oid			table_oid = relId;
 	HeapTuple	tuple;
 	Form_pg_class form;
-	char		relkind;
+	Relkind		relkind;
 
 	/*
 	 * If we previously locked some other index's heap, and the name we're
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 34dd6e18df5..240c663e11b 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -1501,7 +1501,7 @@ ProcessUtilitySlow(ParseState *pstate,
 						foreach(lc, inheritors)
 						{
 							Oid			partrelid = lfirst_oid(lc);
-							char		relkind = get_rel_relkind(partrelid);
+							Relkind		relkind = get_rel_relkind(partrelid);
 
 							if (relkind != RELKIND_RELATION &&
 								relkind != RELKIND_MATVIEW &&
diff --git a/src/backend/utils/activity/pgstat_relation.c b/src/backend/utils/activity/pgstat_relation.c
index bc8c43b96aa..33be4c05994 100644
--- a/src/backend/utils/activity/pgstat_relation.c
+++ b/src/backend/utils/activity/pgstat_relation.c
@@ -90,7 +90,7 @@ pgstat_copy_relation_stats(Relation dst, Relation src)
 void
 pgstat_init_relation(Relation rel)
 {
-	char		relkind = rel->rd_rel->relkind;
+	Relkind		relkind = rel->rd_rel->relkind;
 
 	/*
 	 * We only count stats for relations with storage and partitioned tables
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index 3a6905f9546..e4e2f18fd62 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -2170,7 +2170,7 @@ has_sequence_privilege_name_id(PG_FUNCTION_ARGS)
 	Oid			roleid;
 	AclMode		mode;
 	AclResult	aclresult;
-	char		relkind;
+	Relkind		relkind;
 	bool		is_missing = false;
 
 	roleid = get_role_oid_or_public(NameStr(*username));
@@ -2206,7 +2206,7 @@ has_sequence_privilege_id(PG_FUNCTION_ARGS)
 	Oid			roleid;
 	AclMode		mode;
 	AclResult	aclresult;
-	char		relkind;
+	Relkind		relkind;
 	bool		is_missing = false;
 
 	roleid = GetUserId();
@@ -2269,7 +2269,7 @@ has_sequence_privilege_id_id(PG_FUNCTION_ARGS)
 	text	   *priv_type_text = PG_GETARG_TEXT_PP(2);
 	AclMode		mode;
 	AclResult	aclresult;
-	char		relkind;
+	Relkind		relkind;
 	bool		is_missing = false;
 
 	mode = convert_sequence_priv_string(priv_type_text);
diff --git a/src/backend/utils/adt/partitionfuncs.c b/src/backend/utils/adt/partitionfuncs.c
index e9db027aa2e..dff0ff2bb4c 100644
--- a/src/backend/utils/adt/partitionfuncs.c
+++ b/src/backend/utils/adt/partitionfuncs.c
@@ -33,7 +33,7 @@
 static bool
 check_rel_can_be_partition(Oid relid)
 {
-	char		relkind;
+	Relkind		relkind;
 	bool		relispartition;
 
 	/* Check if relation exists */
@@ -109,7 +109,7 @@ pg_partition_tree(PG_FUNCTION_ARGS)
 		HeapTuple	tuple;
 		Oid			parentid = InvalidOid;
 		Oid			relid = list_nth_oid(partitions, funcctx->call_cntr);
-		char		relkind = get_rel_relkind(relid);
+		Relkind		relkind = get_rel_relkind(relid);
 		int			level = 0;
 		List	   *ancestors = get_partition_ancestors(relid);
 		ListCell   *lc;
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index b5a7ad9066e..ddd05ea2f86 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -1060,7 +1060,7 @@ pg_get_triggerdef_worker(Oid trigid, bool pretty)
 	if (!isnull)
 	{
 		Node	   *qual;
-		char		relkind;
+		Relkind		relkind;
 		deparse_context context;
 		deparse_namespace dpns;
 		RangeTblEntry *oldrte;
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index b924a2d900b..09fe81880e7 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2149,7 +2149,7 @@ get_rel_type_id(Oid relid)
  *
  *		Returns the relkind associated with a given relation.
  */
-char
+Relkind
 get_rel_relkind(Oid relid)
 {
 	HeapTuple	tp;
@@ -2158,9 +2158,9 @@ get_rel_relkind(Oid relid)
 	if (HeapTupleIsValid(tp))
 	{
 		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
-		char		result;
+		Relkind		result;
 
-		result = reltup->relkind;
+		result = (Relkind) reltup->relkind;
 		ReleaseSysCache(tp);
 		return result;
 	}
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 6b634c9fff1..e794f4b942f 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -3517,7 +3517,7 @@ RelationBuildLocalRelation(const char *relname,
 						   bool shared_relation,
 						   bool mapped_relation,
 						   char relpersistence,
-						   char relkind)
+						   Relkind relkind)
 {
 	Relation	rel;
 	MemoryContext oldcxt;
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index 35d3a07915d..12f917994f6 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -2687,7 +2687,7 @@ WriteToc(ArchiveHandle *AH)
 		WriteStr(AH, te->namespace);
 		WriteStr(AH, te->tablespace);
 		WriteStr(AH, te->tableam);
-		WriteInt(AH, te->relkind);
+		WriteInt(AH, (char) te->relkind);
 		WriteStr(AH, te->owner);
 		WriteStr(AH, "false");
 
diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h
index 325b53fc9bd..cb17aab4374 100644
--- a/src/bin/pg_dump/pg_backup_archiver.h
+++ b/src/bin/pg_dump/pg_backup_archiver.h
@@ -26,6 +26,7 @@
 
 #include <time.h>
 
+#include "catalog/pg_class.h"
 #include "libpq-fe.h"
 #include "pg_backup.h"
 #include "pqexpbuffer.h"
@@ -359,7 +360,7 @@ struct _tocEntry
 	char	   *tablespace;		/* null if not in a tablespace; empty string
 								 * means use database default */
 	char	   *tableam;		/* table access method, only for TABLE tags */
-	char		relkind;		/* relation kind, only for TABLE tags */
+	Relkind		relkind;		/* relation kind, only for TABLE tags */
 	char	   *owner;
 	char	   *desc;
 	char	   *defn;
@@ -404,7 +405,7 @@ typedef struct _archiveOpts
 	const char *namespace;
 	const char *tablespace;
 	const char *tableam;
-	char		relkind;
+	Relkind		relkind;
 	const char *owner;
 	const char *description;
 	teSection	section;
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index cdccccc1820..0c2cfb5abea 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -100,7 +100,7 @@ typedef struct
 typedef struct
 {
 	Oid			oid;			/* object OID */
-	char		relkind;		/* object kind */
+	Relkind		relkind;		/* object kind */
 	RelFileNumber relfilenumber;	/* object filenode */
 	Oid			toast_oid;		/* toast table OID */
 	RelFileNumber toast_relfilenumber;	/* toast table filenode */
@@ -356,7 +356,7 @@ static void addBoundaryDependencies(DumpableObject **dobjs, int numObjs,
 
 static void addConstrChildIdxDeps(DumpableObject *dobj, const IndxInfo *refidx);
 static void getDomainConstraints(Archive *fout, TypeInfo *tyinfo);
-static void getTableData(DumpOptions *dopt, TableInfo *tblinfo, int numTables, char relkind);
+static void getTableData(DumpOptions *dopt, TableInfo *tblinfo, int numTables, Relkind relkind);
 static void makeTableDataInfo(DumpOptions *dopt, TableInfo *tbinfo);
 static void buildMatViewRefreshDependencies(Archive *fout);
 static void getTableDataFKConstraints(void);
@@ -3031,7 +3031,7 @@ refreshMatViewData(Archive *fout, const TableDataInfo *tdinfo)
  *	  set up dumpable objects representing the contents of tables
  */
 static void
-getTableData(DumpOptions *dopt, TableInfo *tblinfo, int numTables, char relkind)
+getTableData(DumpOptions *dopt, TableInfo *tblinfo, int numTables, Relkind relkind)
 {
 	int			i;
 
@@ -5856,7 +5856,7 @@ collectBinaryUpgradeClassOids(Archive *fout)
 	for (int i = 0; i < nbinaryUpgradeClassOids; i++)
 	{
 		binaryUpgradeClassOids[i].oid = atooid(PQgetvalue(res, i, 0));
-		binaryUpgradeClassOids[i].relkind = *PQgetvalue(res, i, 1);
+		binaryUpgradeClassOids[i].relkind = (Relkind) *PQgetvalue(res, i, 1);
 		binaryUpgradeClassOids[i].relfilenumber = atooid(PQgetvalue(res, i, 2));
 		binaryUpgradeClassOids[i].toast_oid = atooid(PQgetvalue(res, i, 3));
 		binaryUpgradeClassOids[i].toast_relfilenumber = atooid(PQgetvalue(res, i, 4));
@@ -7121,7 +7121,7 @@ getFuncs(Archive *fout)
 static RelStatsInfo *
 getRelationStatistics(Archive *fout, DumpableObject *rel, int32 relpages,
 					  char *reltuples, int32 relallvisible,
-					  int32 relallfrozen, char relkind,
+					  int32 relallfrozen, Relkind relkind,
 					  char **indAttNames, int nindAttNames)
 {
 	if (!fout->dopt->dumpStatistics)
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index 4c4b14e5fc7..99283983fac 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -215,7 +215,7 @@ typedef struct _typeInfo
 	Oid			typelem;
 	Oid			typrelid;
 	Oid			typarray;
-	char		typrelkind;		/* 'r', 'v', 'c', etc */
+	Relkind		typrelkind;		/* 'r', 'v', 'c', etc */
 	char		typtype;		/* 'b', 'c', etc */
 	bool		isArray;		/* true if auto-generated array type */
 	bool		isMultirange;	/* true if auto-generated multirange type */
@@ -307,7 +307,7 @@ typedef struct _tableInfo
 	DumpableObject dobj;
 	DumpableAcl dacl;
 	const char *rolname;
-	char		relkind;
+	Relkind		relkind;
 	char		relpersistence; /* relation persistence */
 	bool		relispopulated; /* relation is populated */
 	char		relreplident;	/* replica identifier */
@@ -452,7 +452,7 @@ typedef struct _relStatsInfo
 	char	   *reltuples;
 	int32		relallvisible;
 	int32		relallfrozen;
-	char		relkind;		/* 'r', 'm', 'i', etc */
+	Relkind		relkind;		/* 'r', 'm', 'i', etc */
 
 	/*
 	 * indAttNames/nindAttNames are populated only if the relation is an index
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 58735871c17..5920da28014 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -862,7 +862,7 @@ get_table_relkind(PGconn *con, const char *table)
 {
 	PGresult   *res;
 	char	   *val;
-	char		relkind;
+	Relkind		relkind;
 	const char *params[1] = {table};
 	const char *sql =
 		"SELECT relkind FROM pg_catalog.pg_class WHERE oid=$1::pg_catalog.regclass";
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index f02a8df8875..9d1322ae891 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -41,7 +41,7 @@ static bool describeOneTableDetails(const char *schemaname,
 									const char *relationname,
 									const char *oid,
 									bool verbose);
-static void add_tablespace_footer(printTableContent *const cont, char relkind,
+static void add_tablespace_footer(printTableContent *const cont, Relkind relkind,
 								  Oid tablespace, const bool newline);
 static void add_role_attribute(PQExpBuffer buf, const char *const str);
 static bool listTSParsersVerbose(const char *pattern);
@@ -1603,7 +1603,7 @@ describeOneTableDetails(const char *schemaname,
 	struct
 	{
 		int16		checks;
-		char		relkind;
+		Relkind		relkind;
 		bool		hasindex;
 		bool		hasrules;
 		bool		hastriggers;
@@ -3678,7 +3678,7 @@ error_return:
  * footer.
  */
 static void
-add_tablespace_footer(printTableContent *const cont, char relkind,
+add_tablespace_footer(printTableContent *const cont, Relkind relkind,
 					  Oid tablespace, const bool newline)
 {
 	/* relkinds for which we support tablespaces */
diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h
index 0bd17b30ca7..eb7671f6ba5 100644
--- a/src/include/access/reloptions.h
+++ b/src/include/access/reloptions.h
@@ -22,6 +22,7 @@
 #include "access/amapi.h"
 #include "access/htup.h"
 #include "access/tupdesc.h"
+#include "catalog/pg_class.h"
 #include "nodes/pg_list.h"
 #include "storage/lock.h"
 
@@ -248,7 +249,7 @@ extern void *build_local_reloptions(local_relopts *relopts, Datum options,
 
 extern bytea *default_reloptions(Datum reloptions, bool validate,
 								 relopt_kind kind);
-extern bytea *heap_reloptions(char relkind, Datum reloptions, bool validate);
+extern bytea *heap_reloptions(Relkind relkind, Datum reloptions, bool validate);
 extern bytea *view_reloptions(Datum reloptions, bool validate);
 extern bytea *partitioned_table_reloptions(Datum reloptions, bool validate);
 extern bytea *index_reloptions(amoptions_function amoptions, Datum reloptions,
diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h
index 624c415dadb..41ad4a57391 100644
--- a/src/include/catalog/heap.h
+++ b/src/include/catalog/heap.h
@@ -16,6 +16,7 @@
 
 #include "catalog/indexing.h"
 #include "catalog/objectaddress.h"
+#include "catalog/pg_class.h"
 #include "parser/parse_node.h"
 
 
@@ -55,7 +56,7 @@ extern Relation heap_create(const char *relname,
 							RelFileNumber relfilenumber,
 							Oid accessmtd,
 							TupleDesc tupDesc,
-							char relkind,
+							Relkind relkind,
 							char relpersistence,
 							bool shared_relation,
 							bool mapped_relation,
@@ -74,7 +75,7 @@ extern Oid	heap_create_with_catalog(const char *relname,
 									 Oid accessmtd,
 									 TupleDesc tupdesc,
 									 List *cooked_constraints,
-									 char relkind,
+									 Relkind relkind,
 									 char relpersistence,
 									 bool shared_relation,
 									 bool mapped_relation,
@@ -144,7 +145,7 @@ extern const FormData_pg_attribute *SystemAttributeDefinition(AttrNumber attno);
 
 extern const FormData_pg_attribute *SystemAttributeByName(const char *attname);
 
-extern void CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind,
+extern void CheckAttributeNamesTypes(TupleDesc tupdesc, Relkind relkind,
 									 int flags);
 
 extern void CheckAttributeType(const char *attname,
diff --git a/src/include/catalog/objectaddress.h b/src/include/catalog/objectaddress.h
index e2fe9db1161..77d444ba8d6 100644
--- a/src/include/catalog/objectaddress.h
+++ b/src/include/catalog/objectaddress.h
@@ -88,6 +88,6 @@ extern char *getObjectIdentityParts(const ObjectAddress *object,
 									bool missing_ok);
 extern struct ArrayType *strlist_to_textarray(List *list);
 
-extern ObjectType get_relkind_objtype(char relkind);
+extern ObjectType get_relkind_objtype(Relkind relkind);
 
 #endif							/* OBJECTADDRESS_H */
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index 4afff1e8a4e..cd0d034f3d6 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -164,16 +164,19 @@ MAKE_SYSCACHE(RELNAMENSP, pg_class_relname_nsp_index, 128);
 
 #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_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;
 
 /* annoying defines for client-side C string construction */
 #define RELKIND_RELATION_STR			"'r'"
@@ -246,6 +249,6 @@ MAKE_SYSCACHE(RELNAMENSP, pg_class_relname_nsp_index, 128);
 
 #endif							/* EXPOSE_TO_CLIENT_CODE */
 
-extern int	errdetail_relkind_not_supported(char relkind);
+extern int	errdetail_relkind_not_supported(Relkind relkind);
 
 #endif							/* PG_CLASS_H */
diff --git a/src/include/catalog/pg_publication.h b/src/include/catalog/pg_publication.h
index 368becca899..dc6a6d3d379 100644
--- a/src/include/catalog/pg_publication.h
+++ b/src/include/catalog/pg_publication.h
@@ -170,7 +170,7 @@ typedef enum PublicationPartOpt
 
 extern List *GetPublicationRelations(Oid pubid, PublicationPartOpt pub_partopt);
 extern List *GetAllTablesPublications(void);
-extern List *GetAllPublicationRelations(char relkind, bool pubviaroot);
+extern List *GetAllPublicationRelations(Relkind relkind, bool pubviaroot);
 extern List *GetPublicationSchemas(Oid pubid);
 extern List *GetSchemaPublications(Oid schemaid);
 extern List *GetSchemaPublicationRelations(Oid schemaid,
diff --git a/src/include/commands/tablecmds.h b/src/include/commands/tablecmds.h
index ed38b311ddf..e65c2b45008 100644
--- a/src/include/commands/tablecmds.h
+++ b/src/include/commands/tablecmds.h
@@ -25,7 +25,7 @@ typedef struct AlterTableUtilityContext AlterTableUtilityContext;	/* avoid inclu
 																	 * tcop/utility.h here */
 
 
-extern ObjectAddress DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
+extern ObjectAddress DefineRelation(CreateStmt *stmt, Relkind relkind, Oid ownerId,
 									ObjectAddress *typaddress, const char *queryString);
 
 extern TupleDesc BuildDescForRelation(const List *columns);
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 646d6ced763..0d69eff8c83 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -22,6 +22,7 @@
 #ifndef PARSENODES_H
 #define PARSENODES_H
 
+#include "catalog/pg_class.h"
 #include "common/relpath.h"
 #include "nodes/bitmapset.h"
 #include "nodes/lockoptions.h"
@@ -1147,7 +1148,7 @@ typedef struct RangeTblEntry
 	/* inheritance requested? */
 	bool		inh;
 	/* relation kind (see pg_class.relkind) */
-	char		relkind pg_node_attr(query_jumble_ignore);
+	Relkind		relkind pg_node_attr(query_jumble_ignore);
 	/* lock level that query requires on the rel */
 	int			rellockmode pg_node_attr(query_jumble_ignore);
 	/* index of RTEPermissionInfo entry, or 0 */
diff --git a/src/include/replication/logicalproto.h b/src/include/replication/logicalproto.h
index 058a955e20c..e5539ffd46e 100644
--- a/src/include/replication/logicalproto.h
+++ b/src/include/replication/logicalproto.h
@@ -111,7 +111,7 @@ typedef struct LogicalRepRelation
 	char	  **attnames;		/* column names */
 	Oid		   *atttyps;		/* column types */
 	char		replident;		/* replica identity */
-	char		relkind;		/* remote relation kind */
+	Relkind		relkind;		/* remote relation kind */
 	Bitmapset  *attkeys;		/* Bitmap of key columns */
 } LogicalRepRelation;
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 5655aca4c14..d7e1f6132db 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -16,6 +16,7 @@
 #include "access/attnum.h"
 #include "access/cmptype.h"
 #include "access/htup.h"
+#include "catalog/pg_class.h"
 #include "nodes/pg_list.h"
 
 /* avoid including subscripting.h here */
@@ -142,7 +143,7 @@ extern Oid	get_relname_relid(const char *relname, Oid relnamespace);
 extern char *get_rel_name(Oid relid);
 extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
-extern char get_rel_relkind(Oid relid);
+extern Relkind get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
diff --git a/src/include/utils/relcache.h b/src/include/utils/relcache.h
index 2700224939a..ced2c62580a 100644
--- a/src/include/utils/relcache.h
+++ b/src/include/utils/relcache.h
@@ -15,6 +15,7 @@
 #define RELCACHE_H
 
 #include "access/tupdesc.h"
+#include "catalog/pg_class.h"
 #include "common/relpath.h"
 #include "nodes/bitmapset.h"
 
@@ -120,7 +121,7 @@ extern Relation RelationBuildLocalRelation(const char *relname,
 										   bool shared_relation,
 										   bool mapped_relation,
 										   char relpersistence,
-										   char relkind);
+										   Relkind relkind);
 
 /*
  * Routines to manage assignment of new relfilenumber to a relation
-- 
2.47.3

Reply via email to