Subject: Re: Improve readability by using designated initializers when possible

From: Peter Eisentraut <[email-masked]>
Date: Thu, 29 Feb 2024 12:41:38 +0100

On 27.02.24 08:57, Alvaro Herrera wrote:
> On 2024-Feb-27, Michael Paquier wrote:
> 
>> These would cause compilation failures.  Saying that, this is a very
>> nice cleanup, so I've fixed these and applied the patch after checking
>> that the one-one replacements were correct.
> 
> Oh, I thought we were going to get rid of ObjectClass altogether -- I
> mean, have getObjectClass() return ObjectAddress->classId, and then
> define the OCLASS values for each catalog OID [... tries to ...]  But
> this(*) doesn't work for two reasons:

I have long wondered what the point of ObjectClass is.  I find the extra 
layer of redirection, which is used only in small parts of the code, and 
the similarity to ObjectType confusing.  I happened to have a draft 
patch for its removal lying around, so I'll show it here, rebased over 
what has already been done in this thread.

> 1. some switches processing the OCLASS enum don't have "default:" cases.
> This is so that the compiler tells us when we fail to add support for
> some new object class (and it's been helpful).  If we were to

I think you can also handle that with some assertions and proper test 
coverage.  It's not even clear how strong this benefit is.  For example, 
in AlterObjectNamespace_oid(), you could still put a new OCLASS into the 
"ignore object types that don't have schema-qualified names" case, and 
it might or might not be wrong.  Also, there are already various OCLASS 
switches that do have a default case, so it's not even clear what the 
preferred coding style should be.

> 2. all users of getObjectClass would have to include the catalog header
> specific to every catalog it wants to handle; so tablecmds.c and
> dependency.c would have to include almost all catalog includes, for
> example.

This doesn't seem to be a problem in practice; see patch.
From c3acb638301b7a00d18baaf464c29f742734629a Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email-masked]>
Date: Thu, 29 Feb 2024 12:06:15 +0100
Subject: [PATCH] Remove ObjectClass

---
 src/backend/catalog/dependency.c    | 223 +++-----------------
 src/backend/catalog/objectaddress.c | 311 ++++++++++++----------------
 src/backend/commands/alter.c        |  73 ++-----
 src/backend/commands/tablecmds.c    |  60 ++----
 src/include/catalog/dependency.h    |  51 -----
 5 files changed, 188 insertions(+), 530 deletions(-)

diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index 192dedb3cb..d6a5d1d185 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -1351,9 +1351,9 @@ deleteOneObject(const ObjectAddress *object, Relation *depRel, int flags)
 static void
 doDeletion(const ObjectAddress *object, int flags)
 {
-	switch (getObjectClass(object))
+	switch (object->classId)
 	{
-		case OCLASS_CLASS:
+		case RelationRelationId:
 			{
 				char		relKind = get_rel_relkind(object->objectId);
 
@@ -1384,104 +1384,80 @@ doDeletion(const ObjectAddress *object, int flags)
 				break;
 			}
 
-		case OCLASS_PROC:
+		case ProcedureRelationId:
 			RemoveFunctionById(object->objectId);
 			break;
 
-		case OCLASS_TYPE:
+		case TypeRelationId:
 			RemoveTypeById(object->objectId);
 			break;
 
-		case OCLASS_CONSTRAINT:
+		case ConstraintRelationId:
 			RemoveConstraintById(object->objectId);
 			break;
 
-		case OCLASS_DEFAULT:
+		case AttrDefaultRelationId:
 			RemoveAttrDefaultById(object->objectId);
 			break;
 
-		case OCLASS_LARGEOBJECT:
+		case LargeObjectRelationId:
 			LargeObjectDrop(object->objectId);
 			break;
 
-		case OCLASS_OPERATOR:
+		case OperatorRelationId:
 			RemoveOperatorById(object->objectId);
 			break;
 
-		case OCLASS_REWRITE:
+		case RewriteRelationId:
 			RemoveRewriteRuleById(object->objectId);
 			break;
 
-		case OCLASS_TRIGGER:
+		case TriggerRelationId:
 			RemoveTriggerById(object->objectId);
 			break;
 
-		case OCLASS_STATISTIC_EXT:
+		case StatisticExtRelationId:
 			RemoveStatisticsById(object->objectId);
 			break;
 
-		case OCLASS_TSCONFIG:
+		case TSConfigRelationId:
 			RemoveTSConfigurationById(object->objectId);
 			break;
 
-		case OCLASS_EXTENSION:
+		case ExtensionRelationId:
 			RemoveExtensionById(object->objectId);
 			break;
 
-		case OCLASS_POLICY:
+		case PolicyRelationId:
 			RemovePolicyById(object->objectId);
 			break;
 
-		case OCLASS_PUBLICATION_NAMESPACE:
+		case PublicationNamespaceRelationId:
 			RemovePublicationSchemaById(object->objectId);
 			break;
 
-		case OCLASS_PUBLICATION_REL:
+		case PublicationRelRelationId:
 			RemovePublicationRelById(object->objectId);
 			break;
 
-		case OCLASS_PUBLICATION:
+		case PublicationRelationId:
 			RemovePublicationById(object->objectId);
 			break;
 
-		case OCLASS_CAST:
-		case OCLASS_COLLATION:
-		case OCLASS_CONVERSION:
-		case OCLASS_LANGUAGE:
-		case OCLASS_OPCLASS:
-		case OCLASS_OPFAMILY:
-		case OCLASS_AM:
-		case OCLASS_AMOP:
-		case OCLASS_AMPROC:
-		case OCLASS_SCHEMA:
-		case OCLASS_TSPARSER:
-		case OCLASS_TSDICT:
-		case OCLASS_TSTEMPLATE:
-		case OCLASS_FDW:
-		case OCLASS_FOREIGN_SERVER:
-		case OCLASS_USER_MAPPING:
-		case OCLASS_DEFACL:
-		case OCLASS_EVENT_TRIGGER:
-		case OCLASS_TRANSFORM:
-		case OCLASS_ROLE_MEMBERSHIP:
-			DropObjectById(object);
-			break;
-
 			/*
 			 * These global object types are not supported here.
 			 */
-		case OCLASS_ROLE:
-		case OCLASS_DATABASE:
-		case OCLASS_TBLSPACE:
-		case OCLASS_SUBSCRIPTION:
-		case OCLASS_PARAMETER_ACL:
-			elog(ERROR, "global objects cannot be deleted by doDeletion");
+		case AuthIdRelationId:
+		case DatabaseRelationId:
+		case TableSpaceRelationId:
+		case SubscriptionRelationId:
+		case ParameterAclRelationId:
+			elog(ERROR, "object in class %u cannot be deleted by doDeletion", object->classId);
 			break;
 
-			/*
-			 * There's intentionally no default: case here; we want the
-			 * compiler to warn if a new OCLASS hasn't been handled above.
-			 */
+		default:
+			DropObjectById(object);
+			break;
 	}
 }
 
@@ -2776,153 +2752,6 @@ free_object_addresses(ObjectAddresses *addrs)
 	pfree(addrs);
 }
 
-/*
- * Determine the class of a given object identified by objectAddress.
- *
- * We implement it as a function instead of an array because the OIDs aren't
- * consecutive.
- */
-ObjectClass
-getObjectClass(const ObjectAddress *object)
-{
-	/* only pg_class entries can have nonzero objectSubId */
-	if (object->classId != RelationRelationId &&
-		object->objectSubId != 0)
-		elog(ERROR, "invalid non-zero objectSubId for object class %u",
-			 object->classId);
-
-	switch (object->classId)
-	{
-		case RelationRelationId:
-			/* caller must check objectSubId */
-			return OCLASS_CLASS;
-
-		case ProcedureRelationId:
-			return OCLASS_PROC;
-
-		case TypeRelationId:
-			return OCLASS_TYPE;
-
-		case CastRelationId:
-			return OCLASS_CAST;
-
-		case CollationRelationId:
-			return OCLASS_COLLATION;
-
-		case ConstraintRelationId:
-			return OCLASS_CONSTRAINT;
-
-		case ConversionRelationId:
-			return OCLASS_CONVERSION;
-
-		case AttrDefaultRelationId:
-			return OCLASS_DEFAULT;
-
-		case LanguageRelationId:
-			return OCLASS_LANGUAGE;
-
-		case LargeObjectRelationId:
-			return OCLASS_LARGEOBJECT;
-
-		case OperatorRelationId:
-			return OCLASS_OPERATOR;
-
-		case OperatorClassRelationId:
-			return OCLASS_OPCLASS;
-
-		case OperatorFamilyRelationId:
-			return OCLASS_OPFAMILY;
-
-		case AccessMethodRelationId:
-			return OCLASS_AM;
-
-		case AccessMethodOperatorRelationId:
-			return OCLASS_AMOP;
-
-		case AccessMethodProcedureRelationId:
-			return OCLASS_AMPROC;
-
-		case RewriteRelationId:
-			return OCLASS_REWRITE;
-
-		case TriggerRelationId:
-			return OCLASS_TRIGGER;
-
-		case NamespaceRelationId:
-			return OCLASS_SCHEMA;
-
-		case StatisticExtRelationId:
-			return OCLASS_STATISTIC_EXT;
-
-		case TSParserRelationId:
-			return OCLASS_TSPARSER;
-
-		case TSDictionaryRelationId:
-			return OCLASS_TSDICT;
-
-		case TSTemplateRelationId:
-			return OCLASS_TSTEMPLATE;
-
-		case TSConfigRelationId:
-			return OCLASS_TSCONFIG;
-
-		case AuthIdRelationId:
-			return OCLASS_ROLE;
-
-		case AuthMemRelationId:
-			return OCLASS_ROLE_MEMBERSHIP;
-
-		case DatabaseRelationId:
-			return OCLASS_DATABASE;
-
-		case TableSpaceRelationId:
-			return OCLASS_TBLSPACE;
-
-		case ForeignDataWrapperRelationId:
-			return OCLASS_FDW;
-
-		case ForeignServerRelationId:
-			return OCLASS_FOREIGN_SERVER;
-
-		case UserMappingRelationId:
-			return OCLASS_USER_MAPPING;
-
-		case DefaultAclRelationId:
-			return OCLASS_DEFACL;
-
-		case ExtensionRelationId:
-			return OCLASS_EXTENSION;
-
-		case EventTriggerRelationId:
-			return OCLASS_EVENT_TRIGGER;
-
-		case ParameterAclRelationId:
-			return OCLASS_PARAMETER_ACL;
-
-		case PolicyRelationId:
-			return OCLASS_POLICY;
-
-		case PublicationNamespaceRelationId:
-			return OCLASS_PUBLICATION_NAMESPACE;
-
-		case PublicationRelationId:
-			return OCLASS_PUBLICATION;
-
-		case PublicationRelRelationId:
-			return OCLASS_PUBLICATION_REL;
-
-		case SubscriptionRelationId:
-			return OCLASS_SUBSCRIPTION;
-
-		case TransformRelationId:
-			return OCLASS_TRANSFORM;
-	}
-
-	/* shouldn't get here */
-	elog(ERROR, "unrecognized object class: %u", object->classId);
-	return OCLASS_CLASS;		/* keep compiler quiet */
-}
-
 /*
  * delete initial ACL for extension objects
  */
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index 8bb2924b9c..8a2a313df3 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -658,7 +658,6 @@ static const struct object_type_map
 
 			ObjectTypeMap[] =
 {
-	/* OCLASS_CLASS, all kinds of relations */
 	{
 		"table", OBJECT_TABLE
 	},
@@ -707,7 +706,6 @@ static const struct object_type_map
 	{
 		"foreign table column", OBJECT_COLUMN
 	},
-	/* OCLASS_PROC */
 	{
 		"aggregate", OBJECT_AGGREGATE
 	},
@@ -717,162 +715,123 @@ static const struct object_type_map
 	{
 		"procedure", OBJECT_PROCEDURE
 	},
-	/* OCLASS_TYPE */
 	{
 		"type", OBJECT_TYPE
 	},
-	/* OCLASS_CAST */
 	{
 		"cast", OBJECT_CAST
 	},
-	/* OCLASS_COLLATION */
 	{
 		"collation", OBJECT_COLLATION
 	},
-	/* OCLASS_CONSTRAINT */
 	{
 		"table constraint", OBJECT_TABCONSTRAINT
 	},
 	{
 		"domain constraint", OBJECT_DOMCONSTRAINT
 	},
-	/* OCLASS_CONVERSION */
 	{
 		"conversion", OBJECT_CONVERSION
 	},
-	/* OCLASS_DEFAULT */
 	{
 		"default value", OBJECT_DEFAULT
 	},
-	/* OCLASS_LANGUAGE */
 	{
 		"language", OBJECT_LANGUAGE
 	},
-	/* OCLASS_LARGEOBJECT */
 	{
 		"large object", OBJECT_LARGEOBJECT
 	},
-	/* OCLASS_OPERATOR */
 	{
 		"operator", OBJECT_OPERATOR
 	},
-	/* OCLASS_OPCLASS */
 	{
 		"operator class", OBJECT_OPCLASS
 	},
-	/* OCLASS_OPFAMILY */
 	{
 		"operator family", OBJECT_OPFAMILY
 	},
-	/* OCLASS_AM */
 	{
 		"access method", OBJECT_ACCESS_METHOD
 	},
-	/* OCLASS_AMOP */
 	{
 		"operator of access method", OBJECT_AMOP
 	},
-	/* OCLASS_AMPROC */
 	{
 		"function of access method", OBJECT_AMPROC
 	},
-	/* OCLASS_REWRITE */
 	{
 		"rule", OBJECT_RULE
 	},
-	/* OCLASS_TRIGGER */
 	{
 		"trigger", OBJECT_TRIGGER
 	},
-	/* OCLASS_SCHEMA */
 	{
 		"schema", OBJECT_SCHEMA
 	},
-	/* OCLASS_TSPARSER */
 	{
 		"text search parser", OBJECT_TSPARSER
 	},
-	/* OCLASS_TSDICT */
 	{
 		"text search dictionary", OBJECT_TSDICTIONARY
 	},
-	/* OCLASS_TSTEMPLATE */
 	{
 		"text search template", OBJECT_TSTEMPLATE
 	},
-	/* OCLASS_TSCONFIG */
 	{
 		"text search configuration", OBJECT_TSCONFIGURATION
 	},
-	/* OCLASS_ROLE */
 	{
 		"role", OBJECT_ROLE
 	},
-	/* OCLASS_ROLE_MEMBERSHIP */
 	{
 		"role membership", -1	/* unmapped */
 	},
-	/* OCLASS_DATABASE */
 	{
 		"database", OBJECT_DATABASE
 	},
-	/* OCLASS_TBLSPACE */
 	{
 		"tablespace", OBJECT_TABLESPACE
 	},
-	/* OCLASS_FDW */
 	{
 		"foreign-data wrapper", OBJECT_FDW
 	},
-	/* OCLASS_FOREIGN_SERVER */
 	{
 		"server", OBJECT_FOREIGN_SERVER
 	},
-	/* OCLASS_USER_MAPPING */
 	{
 		"user mapping", OBJECT_USER_MAPPING
 	},
-	/* OCLASS_DEFACL */
 	{
 		"default acl", OBJECT_DEFACL
 	},
-	/* OCLASS_EXTENSION */
 	{
 		"extension", OBJECT_EXTENSION
 	},
-	/* OCLASS_EVENT_TRIGGER */
 	{
 		"event trigger", OBJECT_EVENT_TRIGGER
 	},
-	/* OCLASS_PARAMETER_ACL */
 	{
 		"parameter ACL", OBJECT_PARAMETER_ACL
 	},
-	/* OCLASS_POLICY */
 	{
 		"policy", OBJECT_POLICY
 	},
-	/* OCLASS_PUBLICATION */
 	{
 		"publication", OBJECT_PUBLICATION
 	},
-	/* OCLASS_PUBLICATION_NAMESPACE */
 	{
 		"publication namespace", OBJECT_PUBLICATION_NAMESPACE
 	},
-	/* OCLASS_PUBLICATION_REL */
 	{
 		"publication relation", OBJECT_PUBLICATION_REL
 	},
-	/* OCLASS_SUBSCRIPTION */
 	{
 		"subscription", OBJECT_SUBSCRIPTION
 	},
-	/* OCLASS_TRANSFORM */
 	{
 		"transform", OBJECT_TRANSFORM
 	},
-	/* OCLASS_STATISTIC_EXT */
 	{
 		"statistics object", OBJECT_STATISTIC_EXT
 	}
@@ -2925,9 +2884,9 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 
 	initStringInfo(&buffer);
 
-	switch (getObjectClass(object))
+	switch (object->classId)
 	{
-		case OCLASS_CLASS:
+		case RelationRelationId:
 			if (object->objectSubId == 0)
 				getRelationDescription(&buffer, object->objectId, missing_ok);
 			else
@@ -2950,7 +2909,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 			}
 			break;
 
-		case OCLASS_PROC:
+		case ProcedureRelationId:
 			{
 				bits16		flags = FORMAT_PROC_INVALID_AS_NULL;
 				char	   *proname = format_procedure_extended(object->objectId,
@@ -2963,7 +2922,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_TYPE:
+		case TypeRelationId:
 			{
 				bits16		flags = FORMAT_TYPE_INVALID_AS_NULL;
 				char	   *typname = format_type_extended(object->objectId, -1,
@@ -2976,7 +2935,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_CAST:
+		case CastRelationId:
 			{
 				Relation	castDesc;
 				ScanKeyData skey[1];
@@ -3018,7 +2977,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_COLLATION:
+		case CollationRelationId:
 			{
 				HeapTuple	collTup;
 				Form_pg_collation coll;
@@ -3049,7 +3008,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_CONSTRAINT:
+		case ConstraintRelationId:
 			{
 				HeapTuple	conTup;
 				Form_pg_constraint con;
@@ -3087,7 +3046,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_CONVERSION:
+		case ConversionRelationId:
 			{
 				HeapTuple	conTup;
 				Form_pg_conversion conv;
@@ -3118,7 +3077,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_DEFAULT:
+		case AttrDefaultRelationId:
 			{
 				ObjectAddress colobject;
 
@@ -3138,7 +3097,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_LANGUAGE:
+		case LanguageRelationId:
 			{
 				char	   *langname = get_language_name(object->objectId,
 														 missing_ok);
@@ -3149,14 +3108,14 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_LARGEOBJECT:
+		case LargeObjectRelationId:
 			if (!LargeObjectExists(object->objectId))
 				break;
 			appendStringInfo(&buffer, _("large object %u"),
 							 object->objectId);
 			break;
 
-		case OCLASS_OPERATOR:
+		case OperatorRelationId:
 			{
 				bits16		flags = FORMAT_OPERATOR_INVALID_AS_NULL;
 				char	   *oprname = format_operator_extended(object->objectId,
@@ -3169,7 +3128,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_OPCLASS:
+		case OperatorClassRelationId:
 			{
 				HeapTuple	opcTup;
 				Form_pg_opclass opcForm;
@@ -3212,11 +3171,11 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_OPFAMILY:
+		case OperatorFamilyRelationId:
 			getOpFamilyDescription(&buffer, object->objectId, missing_ok);
 			break;
 
-		case OCLASS_AM:
+		case AccessMethodRelationId:
 			{
 				HeapTuple	tup;
 
@@ -3236,7 +3195,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_AMOP:
+		case AccessMethodOperatorRelationId:
 			{
 				Relation	amopDesc;
 				HeapTuple	tup;
@@ -3293,7 +3252,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_AMPROC:
+		case AccessMethodProcedureRelationId:
 			{
 				Relation	amprocDesc;
 				ScanKeyData skey[1];
@@ -3350,7 +3309,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_REWRITE:
+		case RewriteRelationId:
 			{
 				Relation	ruleDesc;
 				ScanKeyData skey[1];
@@ -3396,7 +3355,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_TRIGGER:
+		case TriggerRelationId:
 			{
 				Relation	trigDesc;
 				ScanKeyData skey[1];
@@ -3442,7 +3401,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_SCHEMA:
+		case NamespaceRelationId:
 			{
 				char	   *nspname;
 
@@ -3458,7 +3417,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_STATISTIC_EXT:
+		case StatisticExtRelationId:
 			{
 				HeapTuple	stxTup;
 				Form_pg_statistic_ext stxForm;
@@ -3490,7 +3449,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_TSPARSER:
+		case TSParserRelationId:
 			{
 				HeapTuple	tup;
 				Form_pg_ts_parser prsForm;
@@ -3520,7 +3479,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_TSDICT:
+		case TSDictionaryRelationId:
 			{
 				HeapTuple	tup;
 				Form_pg_ts_dict dictForm;
@@ -3551,7 +3510,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_TSTEMPLATE:
+		case TSTemplateRelationId:
 			{
 				HeapTuple	tup;
 				Form_pg_ts_template tmplForm;
@@ -3582,7 +3541,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_TSCONFIG:
+		case TSConfigRelationId:
 			{
 				HeapTuple	tup;
 				Form_pg_ts_config cfgForm;
@@ -3613,7 +3572,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_ROLE:
+		case AuthIdRelationId:
 			{
 				char	   *username = GetUserNameFromId(object->objectId,
 														 missing_ok);
@@ -3623,7 +3582,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_ROLE_MEMBERSHIP:
+		case AuthMemRelationId:
 			{
 				Relation	amDesc;
 				ScanKeyData skey[1];
@@ -3665,7 +3624,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_DATABASE:
+		case DatabaseRelationId:
 			{
 				char	   *datname;
 
@@ -3681,7 +3640,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_TBLSPACE:
+		case TableSpaceRelationId:
 			{
 				char	   *tblspace;
 
@@ -3697,7 +3656,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_FDW:
+		case ForeignDataWrapperRelationId:
 			{
 				ForeignDataWrapper *fdw;
 
@@ -3708,7 +3667,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_FOREIGN_SERVER:
+		case ForeignServerRelationId:
 			{
 				ForeignServer *srv;
 
@@ -3718,7 +3677,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_USER_MAPPING:
+		case UserMappingRelationId:
 			{
 				HeapTuple	tup;
 				Oid			useid;
@@ -3752,7 +3711,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_DEFACL:
+		case DefaultAclRelationId:
 			{
 				Relation	defaclrel;
 				ScanKeyData skey[1];
@@ -3860,7 +3819,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_EXTENSION:
+		case ExtensionRelationId:
 			{
 				char	   *extname;
 
@@ -3876,7 +3835,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_EVENT_TRIGGER:
+		case EventTriggerRelationId:
 			{
 				HeapTuple	tup;
 
@@ -3895,7 +3854,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_PARAMETER_ACL:
+		case ParameterAclRelationId:
 			{
 				HeapTuple	tup;
 				Datum		nameDatum;
@@ -3918,7 +3877,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_POLICY:
+		case PolicyRelationId:
 			{
 				Relation	policy_rel;
 				ScanKeyData skey[1];
@@ -3964,7 +3923,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_PUBLICATION:
+		case PublicationRelationId:
 			{
 				char	   *pubname = get_publication_name(object->objectId,
 														   missing_ok);
@@ -3974,7 +3933,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_PUBLICATION_NAMESPACE:
+		case PublicationNamespaceRelationId:
 			{
 				char	   *pubname;
 				char	   *nspname;
@@ -3990,7 +3949,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_PUBLICATION_REL:
+		case PublicationRelRelationId:
 			{
 				HeapTuple	tup;
 				char	   *pubname;
@@ -4021,7 +3980,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_SUBSCRIPTION:
+		case SubscriptionRelationId:
 			{
 				char	   *subname = get_subscription_name(object->objectId,
 															missing_ok);
@@ -4031,7 +3990,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				break;
 			}
 
-		case OCLASS_TRANSFORM:
+		case TransformRelationId:
 			{
 				HeapTuple	trfTup;
 				Form_pg_transform trfForm;
@@ -4055,16 +4014,14 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
 				ReleaseSysCache(trfTup);
 				break;
 			}
-
-			/*
-			 * There's intentionally no default: case here; we want the
-			 * compiler to warn if a new OCLASS hasn't been handled above.
-			 */
 	}
 
 	/* an empty buffer is equivalent to no object found */
 	if (buffer.len == 0)
+	{
+		Assert(missing_ok);
 		return NULL;
+	}
 
 	return buffer.data;
 }
@@ -4421,180 +4378,175 @@ getObjectTypeDescription(const ObjectAddress *object, bool missing_ok)
 
 	initStringInfo(&buffer);
 
-	switch (getObjectClass(object))
+	switch (object->classId)
 	{
-		case OCLASS_CLASS:
+		case RelationRelationId:
 			getRelationTypeDescription(&buffer, object->objectId,
 									   object->objectSubId,
 									   missing_ok);
 			break;
 
-		case OCLASS_PROC:
+		case ProcedureRelationId:
 			getProcedureTypeDescription(&buffer, object->objectId,
 										missing_ok);
 			break;
 
-		case OCLASS_TYPE:
+		case TypeRelationId:
 			appendStringInfoString(&buffer, "type");
 			break;
 
-		case OCLASS_CAST:
+		case CastRelationId:
 			appendStringInfoString(&buffer, "cast");
 			break;
 
-		case OCLASS_COLLATION:
+		case CollationRelationId:
 			appendStringInfoString(&buffer, "collation");
 			break;
 
-		case OCLASS_CONSTRAINT:
+		case ConstraintRelationId:
 			getConstraintTypeDescription(&buffer, object->objectId,
 										 missing_ok);
 			break;
 
-		case OCLASS_CONVERSION:
+		case ConversionRelationId:
 			appendStringInfoString(&buffer, "conversion");
 			break;
 
-		case OCLASS_DEFAULT:
+		case AttrDefaultRelationId:
 			appendStringInfoString(&buffer, "default value");
 			break;
 
-		case OCLASS_LANGUAGE:
+		case LanguageRelationId:
 			appendStringInfoString(&buffer, "language");
 			break;
 
-		case OCLASS_LARGEOBJECT:
+		case LargeObjectRelationId:
 			appendStringInfoString(&buffer, "large object");
 			break;
 
-		case OCLASS_OPERATOR:
+		case OperatorRelationId:
 			appendStringInfoString(&buffer, "operator");
 			break;
 
-		case OCLASS_OPCLASS:
+		case OperatorClassRelationId:
 			appendStringInfoString(&buffer, "operator class");
 			break;
 
-		case OCLASS_OPFAMILY:
+		case OperatorFamilyRelationId:
 			appendStringInfoString(&buffer, "operator family");
 			break;
 
-		case OCLASS_AM:
+		case AccessMethodRelationId:
 			appendStringInfoString(&buffer, "access method");
 			break;
 
-		case OCLASS_AMOP:
+		case AccessMethodOperatorRelationId:
 			appendStringInfoString(&buffer, "operator of access method");
 			break;
 
-		case OCLASS_AMPROC:
+		case AccessMethodProcedureRelationId:
 			appendStringInfoString(&buffer, "function of access method");
 			break;
 
-		case OCLASS_REWRITE:
+		case RewriteRelationId:
 			appendStringInfoString(&buffer, "rule");
 			break;
 
-		case OCLASS_TRIGGER:
+		case TriggerRelationId:
 			appendStringInfoString(&buffer, "trigger");
 			break;
 
-		case OCLASS_SCHEMA:
+		case NamespaceRelationId:
 			appendStringInfoString(&buffer, "schema");
 			break;
 
-		case OCLASS_STATISTIC_EXT:
+		case StatisticExtRelationId:
 			appendStringInfoString(&buffer, "statistics object");
 			break;
 
-		case OCLASS_TSPARSER:
+		case TSParserRelationId:
 			appendStringInfoString(&buffer, "text search parser");
 			break;
 
-		case OCLASS_TSDICT:
+		case TSDictionaryRelationId:
 			appendStringInfoString(&buffer, "text search dictionary");
 			break;
 
-		case OCLASS_TSTEMPLATE:
+		case TSTemplateRelationId:
 			appendStringInfoString(&buffer, "text search template");
 			break;
 
-		case OCLASS_TSCONFIG:
+		case TSConfigRelationId:
 			appendStringInfoString(&buffer, "text search configuration");
 			break;
 
-		case OCLASS_ROLE:
+		case AuthIdRelationId:
 			appendStringInfoString(&buffer, "role");
 			break;
 
-		case OCLASS_ROLE_MEMBERSHIP:
+		case AuthMemRelationId:
 			appendStringInfoString(&buffer, "role membership");
 			break;
 
-		case OCLASS_DATABASE:
+		case DatabaseRelationId:
 			appendStringInfoString(&buffer, "database");
 			break;
 
-		case OCLASS_TBLSPACE:
+		case TableSpaceRelationId:
 			appendStringInfoString(&buffer, "tablespace");
 			break;
 
-		case OCLASS_FDW:
+		case ForeignDataWrapperRelationId:
 			appendStringInfoString(&buffer, "foreign-data wrapper");
 			break;
 
-		case OCLASS_FOREIGN_SERVER:
+		case ForeignServerRelationId:
 			appendStringInfoString(&buffer, "server");
 			break;
 
-		case OCLASS_USER_MAPPING:
+		case UserMappingRelationId:
 			appendStringInfoString(&buffer, "user mapping");
 			break;
 
-		case OCLASS_DEFACL:
+		case DefaultAclRelationId:
 			appendStringInfoString(&buffer, "default acl");
 			break;
 
-		case OCLASS_EXTENSION:
+		case ExtensionRelationId:
 			appendStringInfoString(&buffer, "extension");
 			break;
 
-		case OCLASS_EVENT_TRIGGER:
+		case EventTriggerRelationId:
 			appendStringInfoString(&buffer, "event trigger");
 			break;
 
-		case OCLASS_PARAMETER_ACL:
+		case ParameterAclRelationId:
 			appendStringInfoString(&buffer, "parameter ACL");
 			break;
 
-		case OCLASS_POLICY:
+		case PolicyRelationId:
 			appendStringInfoString(&buffer, "policy");
 			break;
 
-		case OCLASS_PUBLICATION:
+		case PublicationRelationId:
 			appendStringInfoString(&buffer, "publication");
 			break;
 
-		case OCLASS_PUBLICATION_NAMESPACE:
+		case PublicationNamespaceRelationId:
 			appendStringInfoString(&buffer, "publication namespace");
 			break;
 
-		case OCLASS_PUBLICATION_REL:
+		case PublicationRelRelationId:
 			appendStringInfoString(&buffer, "publication relation");
 			break;
 
-		case OCLASS_SUBSCRIPTION:
+		case SubscriptionRelationId:
 			appendStringInfoString(&buffer, "subscription");
 			break;
 
-		case OCLASS_TRANSFORM:
+		case TransformRelationId:
 			appendStringInfoString(&buffer, "transform");
 			break;
-
-			/*
-			 * There's intentionally no default: case here; we want the
-			 * compiler to warn if a new OCLASS hasn't been handled above.
-			 */
 	}
 
 	/* the result can never be empty */
@@ -4780,9 +4732,9 @@ getObjectIdentityParts(const ObjectAddress *object,
 		*objargs = NIL;
 	}
 
-	switch (getObjectClass(object))
+	switch (object->classId)
 	{
-		case OCLASS_CLASS:
+		case RelationRelationId:
 			{
 				char	   *attr = NULL;
 
@@ -4815,7 +4767,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 			}
 			break;
 
-		case OCLASS_PROC:
+		case ProcedureRelationId:
 			{
 				bits16		flags = FORMAT_PROC_FORCE_QUALIFY | FORMAT_PROC_INVALID_AS_NULL;
 				char	   *proname = format_procedure_extended(object->objectId,
@@ -4831,7 +4783,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_TYPE:
+		case TypeRelationId:
 			{
 				bits16		flags = FORMAT_TYPE_INVALID_AS_NULL | FORMAT_TYPE_FORCE_QUALIFY;
 				char	   *typeout;
@@ -4847,7 +4799,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 			}
 			break;
 
-		case OCLASS_CAST:
+		case CastRelationId:
 			{
 				Relation	castRel;
 				HeapTuple	tup;
@@ -4884,7 +4836,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_COLLATION:
+		case CollationRelationId:
 			{
 				HeapTuple	collTup;
 				Form_pg_collation coll;
@@ -4911,7 +4863,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_CONSTRAINT:
+		case ConstraintRelationId:
 			{
 				HeapTuple	conTup;
 				Form_pg_constraint con;
@@ -4958,7 +4910,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_CONVERSION:
+		case ConversionRelationId:
 			{
 				HeapTuple	conTup;
 				Form_pg_conversion conForm;
@@ -4985,7 +4937,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_DEFAULT:
+		case AttrDefaultRelationId:
 			{
 				ObjectAddress colobject;
 
@@ -5006,7 +4958,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_LANGUAGE:
+		case LanguageRelationId:
 			{
 				HeapTuple	langTup;
 				Form_pg_language langForm;
@@ -5028,7 +4980,8 @@ getObjectIdentityParts(const ObjectAddress *object,
 				ReleaseSysCache(langTup);
 				break;
 			}
-		case OCLASS_LARGEOBJECT:
+
+		case LargeObjectRelationId:
 			if (!LargeObjectExists(object->objectId))
 				break;
 			appendStringInfo(&buffer, "%u",
@@ -5037,7 +4990,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				*objname = list_make1(psprintf("%u", object->objectId));
 			break;
 
-		case OCLASS_OPERATOR:
+		case OperatorRelationId:
 			{
 				bits16		flags = FORMAT_OPERATOR_FORCE_QUALIFY | FORMAT_OPERATOR_INVALID_AS_NULL;
 				char	   *oprname = format_operator_extended(object->objectId,
@@ -5052,7 +5005,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_OPCLASS:
+		case OperatorClassRelationId:
 			{
 				HeapTuple	opcTup;
 				Form_pg_opclass opcForm;
@@ -5093,12 +5046,12 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_OPFAMILY:
+		case OperatorFamilyRelationId:
 			getOpFamilyIdentity(&buffer, object->objectId, objname,
 								missing_ok);
 			break;
 
-		case OCLASS_AM:
+		case AccessMethodRelationId:
 			{
 				char	   *amname;
 
@@ -5116,7 +5069,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 			}
 			break;
 
-		case OCLASS_AMOP:
+		case AccessMethodOperatorRelationId:
 			{
 				Relation	amopDesc;
 				HeapTuple	tup;
@@ -5178,7 +5131,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_AMPROC:
+		case AccessMethodProcedureRelationId:
 			{
 				Relation	amprocDesc;
 				ScanKeyData skey[1];
@@ -5240,7 +5193,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_REWRITE:
+		case RewriteRelationId:
 			{
 				Relation	ruleDesc;
 				HeapTuple	tup;
@@ -5273,7 +5226,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_TRIGGER:
+		case TriggerRelationId:
 			{
 				Relation	trigDesc;
 				HeapTuple	tup;
@@ -5306,7 +5259,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_SCHEMA:
+		case NamespaceRelationId:
 			{
 				char	   *nspname;
 
@@ -5325,7 +5278,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_STATISTIC_EXT:
+		case StatisticExtRelationId:
 			{
 				HeapTuple	tup;
 				Form_pg_statistic_ext formStatistic;
@@ -5352,7 +5305,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 			}
 			break;
 
-		case OCLASS_TSPARSER:
+		case TSParserRelationId:
 			{
 				HeapTuple	tup;
 				Form_pg_ts_parser formParser;
@@ -5379,7 +5332,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_TSDICT:
+		case TSDictionaryRelationId:
 			{
 				HeapTuple	tup;
 				Form_pg_ts_dict formDict;
@@ -5406,7 +5359,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_TSTEMPLATE:
+		case TSTemplateRelationId:
 			{
 				HeapTuple	tup;
 				Form_pg_ts_template formTmpl;
@@ -5433,7 +5386,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_TSCONFIG:
+		case TSConfigRelationId:
 			{
 				HeapTuple	tup;
 				Form_pg_ts_config formCfg;
@@ -5460,7 +5413,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_ROLE:
+		case AuthIdRelationId:
 			{
 				char	   *username;
 
@@ -5474,7 +5427,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_ROLE_MEMBERSHIP:
+		case AuthMemRelationId:
 			{
 				Relation	authMemDesc;
 				ScanKeyData skey[1];
@@ -5517,7 +5470,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_DATABASE:
+		case DatabaseRelationId:
 			{
 				char	   *datname;
 
@@ -5536,7 +5489,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_TBLSPACE:
+		case TableSpaceRelationId:
 			{
 				char	   *tblspace;
 
@@ -5555,7 +5508,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_FDW:
+		case ForeignDataWrapperRelationId:
 			{
 				ForeignDataWrapper *fdw;
 
@@ -5570,7 +5523,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_FOREIGN_SERVER:
+		case ForeignServerRelationId:
 			{
 				ForeignServer *srv;
 
@@ -5586,7 +5539,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_USER_MAPPING:
+		case UserMappingRelationId:
 			{
 				HeapTuple	tup;
 				Oid			useid;
@@ -5626,7 +5579,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_DEFACL:
+		case DefaultAclRelationId:
 			{
 				Relation	defaclrel;
 				ScanKeyData skey[1];
@@ -5713,7 +5666,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_EXTENSION:
+		case ExtensionRelationId:
 			{
 				char	   *extname;
 
@@ -5731,7 +5684,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_EVENT_TRIGGER:
+		case EventTriggerRelationId:
 			{
 				HeapTuple	tup;
 				Form_pg_event_trigger trigForm;
@@ -5755,7 +5708,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_PARAMETER_ACL:
+		case ParameterAclRelationId:
 			{
 				HeapTuple	tup;
 				Datum		nameDatum;
@@ -5780,7 +5733,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_POLICY:
+		case PolicyRelationId:
 			{
 				Relation	polDesc;
 				HeapTuple	tup;
@@ -5813,7 +5766,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_PUBLICATION:
+		case PublicationRelationId:
 			{
 				char	   *pubname;
 
@@ -5828,7 +5781,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_PUBLICATION_NAMESPACE:
+		case PublicationNamespaceRelationId:
 			{
 				char	   *pubname;
 				char	   *nspname;
@@ -5852,7 +5805,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_PUBLICATION_REL:
+		case PublicationRelRelationId:
 			{
 				HeapTuple	tup;
 				char	   *pubname;
@@ -5881,7 +5834,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_SUBSCRIPTION:
+		case SubscriptionRelationId:
 			{
 				char	   *subname;
 
@@ -5896,7 +5849,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				break;
 			}
 
-		case OCLASS_TRANSFORM:
+		case TransformRelationId:
 			{
 				Relation	transformDesc;
 				HeapTuple	tup;
@@ -5952,8 +5905,8 @@ getObjectIdentityParts(const ObjectAddress *object,
 		 * cases above leave it as NIL.
 		 */
 		if (objname && *objname == NIL)
-			elog(ERROR, "requested object address for unsupported object class %d: text result \"%s\"",
-				 (int) getObjectClass(object), buffer.data);
+			elog(ERROR, "requested object address for unsupported object class %u: text result \"%s\"",
+				 object->classId, buffer.data);
 	}
 	else
 	{
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c
index b2e4260aef..5c131c86b2 100644
--- a/src/backend/commands/alter.c
+++ b/src/backend/commands/alter.c
@@ -33,6 +33,7 @@
 #include "catalog/pg_largeobject_metadata.h"
 #include "catalog/pg_namespace.h"
 #include "catalog/pg_opclass.h"
+#include "catalog/pg_operator.h"
 #include "catalog/pg_opfamily.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_statistic_ext.h"
@@ -608,8 +609,7 @@ ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt,
  * so it only needs to cover object types that can be members of an
  * extension, and it doesn't have to deal with certain special cases
  * such as not wanting to process array types --- those should never
- * be direct members of an extension anyway.  Nonetheless, we insist
- * on listing all OCLASS types in the switch.
+ * be direct members of an extension anyway.
  *
  * Returns the OID of the object's previous namespace, or InvalidOid if
  * object doesn't have a schema.
@@ -619,15 +619,10 @@ AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid,
 						 ObjectAddresses *objsMoved)
 {
 	Oid			oldNspOid = InvalidOid;
-	ObjectAddress dep;
 
-	dep.classId = classId;
-	dep.objectId = objid;
-	dep.objectSubId = 0;
-
-	switch (getObjectClass(&dep))
+	switch (classId)
 	{
-		case OCLASS_CLASS:
+		case RelationRelationId:
 			{
 				Relation	rel;
 
@@ -640,21 +635,21 @@ AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid,
 				break;
 			}
 
-		case OCLASS_TYPE:
+		case TypeRelationId:
 			oldNspOid = AlterTypeNamespace_oid(objid, nspOid, objsMoved);
 			break;
 
-		case OCLASS_PROC:
-		case OCLASS_COLLATION:
-		case OCLASS_CONVERSION:
-		case OCLASS_OPERATOR:
-		case OCLASS_OPCLASS:
-		case OCLASS_OPFAMILY:
-		case OCLASS_STATISTIC_EXT:
-		case OCLASS_TSPARSER:
-		case OCLASS_TSDICT:
-		case OCLASS_TSTEMPLATE:
-		case OCLASS_TSCONFIG:
+		case ProcedureRelationId:
+		case CollationRelationId:
+		case ConversionRelationId:
+		case OperatorRelationId:
+		case OperatorClassRelationId:
+		case OperatorFamilyRelationId:
+		case StatisticExtRelationId:
+		case TSParserRelationId:
+		case TSDictionaryRelationId:
+		case TSTemplateRelationId:
+		case TSConfigRelationId:
 			{
 				Relation	catalog;
 
@@ -667,41 +662,9 @@ AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid,
 			}
 			break;
 
-		case OCLASS_CAST:
-		case OCLASS_CONSTRAINT:
-		case OCLASS_DEFAULT:
-		case OCLASS_LANGUAGE:
-		case OCLASS_LARGEOBJECT:
-		case OCLASS_AM:
-		case OCLASS_AMOP:
-		case OCLASS_AMPROC:
-		case OCLASS_REWRITE:
-		case OCLASS_TRIGGER:
-		case OCLASS_SCHEMA:
-		case OCLASS_ROLE:
-		case OCLASS_ROLE_MEMBERSHIP:
-		case OCLASS_DATABASE:
-		case OCLASS_TBLSPACE:
-		case OCLASS_FDW:
-		case OCLASS_FOREIGN_SERVER:
-		case OCLASS_USER_MAPPING:
-		case OCLASS_DEFACL:
-		case OCLASS_EXTENSION:
-		case OCLASS_EVENT_TRIGGER:
-		case OCLASS_PARAMETER_ACL:
-		case OCLASS_POLICY:
-		case OCLASS_PUBLICATION:
-		case OCLASS_PUBLICATION_NAMESPACE:
-		case OCLASS_PUBLICATION_REL:
-		case OCLASS_SUBSCRIPTION:
-		case OCLASS_TRANSFORM:
+		default:
 			/* ignore object types that don't have schema-qualified names */
-			break;
-
-			/*
-			 * There's intentionally no default: case here; we want the
-			 * compiler to warn if a new OCLASS hasn't been handled above.
-			 */
+			Assert(get_object_attnum_namespace(classId) == InvalidAttrNumber);
 	}
 
 	return oldNspOid;
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index f798794556..8a5b399b98 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -43,6 +43,8 @@
 #include "catalog/pg_largeobject.h"
 #include "catalog/pg_namespace.h"
 #include "catalog/pg_opclass.h"
+#include "catalog/pg_policy.h"
+#include "catalog/pg_rewrite.h"
 #include "catalog/pg_statistic_ext.h"
 #include "catalog/pg_tablespace.h"
 #include "catalog/pg_trigger.h"
@@ -13835,9 +13837,9 @@ RememberAllDependentForRebuilding(AlteredTableInfo *tab, AlterTableType subtype,
 		foundObject.objectId = foundDep->objid;
 		foundObject.objectSubId = foundDep->objsubid;
 
-		switch (getObjectClass(&foundObject))
+		switch (foundObject.classId)
 		{
-			case OCLASS_CLASS:
+			case RelationRelationId:
 				{
 					char		relKind = get_rel_relkind(foundObject.objectId);
 
@@ -13864,12 +13866,12 @@ RememberAllDependentForRebuilding(AlteredTableInfo *tab, AlterTableType subtype,
 					break;
 				}
 
-			case OCLASS_CONSTRAINT:
+			case ConstraintRelationId:
 				Assert(foundObject.objectSubId == 0);
 				RememberConstraintForRebuilding(foundObject.objectId, tab);
 				break;
 
-			case OCLASS_REWRITE:
+			case RewriteRelationId:
 				/* XXX someday see if we can cope with revising views */
 				if (subtype == AT_AlterColumnType)
 					ereport(ERROR,
@@ -13880,7 +13882,7 @@ RememberAllDependentForRebuilding(AlteredTableInfo *tab, AlterTableType subtype,
 									   colName)));
 				break;
 
-			case OCLASS_TRIGGER:
+			case TriggerRelationId:
 
 				/*
 				 * A trigger can depend on a column because the column is
@@ -13900,7 +13902,7 @@ RememberAllDependentForRebuilding(AlteredTableInfo *tab, AlterTableType subtype,
 									   colName)));
 				break;
 
-			case OCLASS_POLICY:
+			case PolicyRelationId:
 
 				/*
 				 * A policy can depend on a column because the column is
@@ -13919,7 +13921,7 @@ RememberAllDependentForRebuilding(AlteredTableInfo *tab, AlterTableType subtype,
 									   colName)));
 				break;
 
-			case OCLASS_DEFAULT:
+			case AttrDefaultRelationId:
 				{
 					ObjectAddress col = GetAttrDefaultColumnAddress(foundObject.objectId);
 
@@ -13954,7 +13956,7 @@ RememberAllDependentForRebuilding(AlteredTableInfo *tab, AlterTableType subtype,
 					break;
 				}
 
-			case OCLASS_STATISTIC_EXT:
+			case StatisticExtRelationId:
 
 				/*
 				 * Give the extended-stats machinery a chance to fix anything
@@ -13963,53 +13965,15 @@ RememberAllDependentForRebuilding(AlteredTableInfo *tab, AlterTableType subtype,
 				RememberStatisticsForRebuilding(foundObject.objectId, tab);
 				break;
 
-			case OCLASS_PROC:
-			case OCLASS_TYPE:
-			case OCLASS_CAST:
-			case OCLASS_COLLATION:
-			case OCLASS_CONVERSION:
-			case OCLASS_LANGUAGE:
-			case OCLASS_LARGEOBJECT:
-			case OCLASS_OPERATOR:
-			case OCLASS_OPCLASS:
-			case OCLASS_OPFAMILY:
-			case OCLASS_AM:
-			case OCLASS_AMOP:
-			case OCLASS_AMPROC:
-			case OCLASS_SCHEMA:
-			case OCLASS_TSPARSER:
-			case OCLASS_TSDICT:
-			case OCLASS_TSTEMPLATE:
-			case OCLASS_TSCONFIG:
-			case OCLASS_ROLE:
-			case OCLASS_ROLE_MEMBERSHIP:
-			case OCLASS_DATABASE:
-			case OCLASS_TBLSPACE:
-			case OCLASS_FDW:
-			case OCLASS_FOREIGN_SERVER:
-			case OCLASS_USER_MAPPING:
-			case OCLASS_DEFACL:
-			case OCLASS_EXTENSION:
-			case OCLASS_EVENT_TRIGGER:
-			case OCLASS_PARAMETER_ACL:
-			case OCLASS_PUBLICATION:
-			case OCLASS_PUBLICATION_NAMESPACE:
-			case OCLASS_PUBLICATION_REL:
-			case OCLASS_SUBSCRIPTION:
-			case OCLASS_TRANSFORM:
+			default:
 
 				/*
-				 * We don't expect any of these sorts of objects to depend on
+				 * We don't expect any other sorts of objects to depend on
 				 * a column.
 				 */
 				elog(ERROR, "unexpected object depending on column: %s",
 					 getObjectDescription(&foundObject, false));
 				break;
-
-				/*
-				 * There's intentionally no default: case here; we want the
-				 * compiler to warn if a new OCLASS hasn't been handled above.
-				 */
 		}
 	}
 
diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h
index 436b081738..ec654010d4 100644
--- a/src/include/catalog/dependency.h
+++ b/src/include/catalog/dependency.h
@@ -81,55 +81,6 @@ typedef enum SharedDependencyType
 /* expansible list of ObjectAddresses (private in dependency.c) */
 typedef struct ObjectAddresses ObjectAddresses;
 
-/*
- * This enum covers all system catalogs whose OIDs can appear in
- * pg_depend.classId or pg_shdepend.classId.
- */
-typedef enum ObjectClass
-{
-	OCLASS_CLASS,				/* pg_class */
-	OCLASS_PROC,				/* pg_proc */
-	OCLASS_TYPE,				/* pg_type */
-	OCLASS_CAST,				/* pg_cast */
-	OCLASS_COLLATION,			/* pg_collation */
-	OCLASS_CONSTRAINT,			/* pg_constraint */
-	OCLASS_CONVERSION,			/* pg_conversion */
-	OCLASS_DEFAULT,				/* pg_attrdef */
-	OCLASS_LANGUAGE,			/* pg_language */
-	OCLASS_LARGEOBJECT,			/* pg_largeobject */
-	OCLASS_OPERATOR,			/* pg_operator */
-	OCLASS_OPCLASS,				/* pg_opclass */
-	OCLASS_OPFAMILY,			/* pg_opfamily */
-	OCLASS_AM,					/* pg_am */
-	OCLASS_AMOP,				/* pg_amop */
-	OCLASS_AMPROC,				/* pg_amproc */
-	OCLASS_REWRITE,				/* pg_rewrite */
-	OCLASS_TRIGGER,				/* pg_trigger */
-	OCLASS_SCHEMA,				/* pg_namespace */
-	OCLASS_STATISTIC_EXT,		/* pg_statistic_ext */
-	OCLASS_TSPARSER,			/* pg_ts_parser */
-	OCLASS_TSDICT,				/* pg_ts_dict */
-	OCLASS_TSTEMPLATE,			/* pg_ts_template */
-	OCLASS_TSCONFIG,			/* pg_ts_config */
-	OCLASS_ROLE,				/* pg_authid */
-	OCLASS_ROLE_MEMBERSHIP,		/* pg_auth_members */
-	OCLASS_DATABASE,			/* pg_database */
-	OCLASS_TBLSPACE,			/* pg_tablespace */
-	OCLASS_FDW,					/* pg_foreign_data_wrapper */
-	OCLASS_FOREIGN_SERVER,		/* pg_foreign_server */
-	OCLASS_USER_MAPPING,		/* pg_user_mapping */
-	OCLASS_DEFACL,				/* pg_default_acl */
-	OCLASS_EXTENSION,			/* pg_extension */
-	OCLASS_EVENT_TRIGGER,		/* pg_event_trigger */
-	OCLASS_PARAMETER_ACL,		/* pg_parameter_acl */
-	OCLASS_POLICY,				/* pg_policy */
-	OCLASS_PUBLICATION,			/* pg_publication */
-	OCLASS_PUBLICATION_NAMESPACE,	/* pg_publication_namespace */
-	OCLASS_PUBLICATION_REL,		/* pg_publication_rel */
-	OCLASS_SUBSCRIPTION,		/* pg_subscription */
-	OCLASS_TRANSFORM,			/* pg_transform */
-} ObjectClass;
-
 /* flag bits for performDeletion/performMultipleDeletions: */
 #define PERFORM_DELETION_INTERNAL			0x0001	/* internal action */
 #define PERFORM_DELETION_CONCURRENTLY		0x0002	/* concurrent drop */
@@ -162,8 +113,6 @@ extern void recordDependencyOnSingleRelExpr(const ObjectAddress *depender,
 											DependencyType self_behavior,
 											bool reverse_self);
 
-extern ObjectClass getObjectClass(const ObjectAddress *object);
-
 extern ObjectAddresses *new_object_addresses(void);
 
 extern void add_exact_object_address(const ObjectAddress *object,
-- 
2.43.2

---

From: Michael Paquier <[email-masked]>
Date: Fri, 1 Mar 2024 13:08:15 +0900

On Thu, Feb 29, 2024 at 12:41:38PM +0100, Peter Eisentraut wrote:
> layer of redirection, which is used only in small parts of the code, and the
> similarity to ObjectType confusing.  I happened to have a draft patch for
> its removal lying around, so I'll show it here, rebased over what has
> already been done in this thread.

The elimination of getObjectClass() seems like a good end goal IMO, so
the direction of the patch is interesting.  Would object_type_map and
ObjectProperty follow the same idea of relying on the catalogs OID
instead of the OBJECT_*?

Note that there are still two dependencies to getObjectClass() in
event_trigger.c and dependency.c.
--
Michael