Unify drop-by-OID functions

Started by Peter Eisentrautover 5 years ago18 messages
#1Peter Eisentraut
peter.eisentraut@2ndquadrant.com
1 attachment(s)

[proposal for PG 14]

There are a number of Remove${Something}ById() functions that are
essentially identical in structure and only different in which catalog
they are working on. This patch refactors this to be one generic
function. The information about which oid column, index, etc. to use
was already available in ObjectProperty for most catalogs, in a few
cases it was easily added.

Conceivably, this could be taken further by categorizing more special
cases as ObjectProperty fields or something like that, but this seemed
like a good balance.

--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

Attachments:

0001-Unify-drop-by-OID-functions.patchtext/plain; charset=UTF-8; name=0001-Unify-drop-by-OID-functions.patch; x-mac-creator=0; x-mac-type=0Download
From a4d3112c9385e3f489f9327e58c0995f51e003f4 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Fri, 1 May 2020 13:29:38 +0200
Subject: [PATCH] Unify drop-by-OID functions

There are a number of Remove${Something}ById() functions that are
essentially identical in structure and only different in which catalog
they are working on.  Refactor this to be one generic function.  The
information about which oid column, index, etc. to use was already
available in ObjectProperty for most catalogs, in a few cases it was
easily added.
---
 src/backend/catalog/aclchk.c           |  33 -----
 src/backend/catalog/dependency.c       | 160 ++++++++++++-------------
 src/backend/catalog/objectaddress.c    |  99 ++++++++++++++-
 src/backend/catalog/pg_collation.c     |  36 ------
 src/backend/catalog/pg_conversion.c    |  33 -----
 src/backend/commands/amcmds.c          |  27 -----
 src/backend/commands/event_trigger.c   |  22 ----
 src/backend/commands/foreigncmds.c     |  71 -----------
 src/backend/commands/functioncmds.c    |  53 --------
 src/backend/commands/opclasscmds.c     |  99 ---------------
 src/backend/commands/proclang.c        |  22 ----
 src/backend/commands/publicationcmds.c |  23 ----
 src/backend/commands/schemacmds.c      |  23 ----
 src/backend/commands/tsearchcmds.c     |  71 -----------
 src/include/catalog/objectaddress.h    |   1 +
 src/include/catalog/pg_collation.h     |   1 -
 src/include/catalog/pg_conversion.h    |   1 -
 src/include/commands/defrem.h          |  13 --
 src/include/commands/event_trigger.h   |   1 -
 src/include/commands/proclang.h        |   1 -
 src/include/commands/publicationcmds.h |   1 -
 src/include/commands/schemacmds.h      |   2 -
 src/include/utils/acl.h                |   1 -
 23 files changed, 175 insertions(+), 619 deletions(-)

diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index cb2c4972ad..c626161408 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -1498,39 +1498,6 @@ RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid)
 }
 
 
-/*
- * Remove a pg_default_acl entry
- */
-void
-RemoveDefaultACLById(Oid defaclOid)
-{
-	Relation	rel;
-	ScanKeyData skey[1];
-	SysScanDesc scan;
-	HeapTuple	tuple;
-
-	rel = table_open(DefaultAclRelationId, RowExclusiveLock);
-
-	ScanKeyInit(&skey[0],
-				Anum_pg_default_acl_oid,
-				BTEqualStrategyNumber, F_OIDEQ,
-				ObjectIdGetDatum(defaclOid));
-
-	scan = systable_beginscan(rel, DefaultAclOidIndexId, true,
-							  NULL, 1, skey);
-
-	tuple = systable_getnext(scan);
-
-	if (!HeapTupleIsValid(tuple))
-		elog(ERROR, "could not find tuple for default ACL %u", defaclOid);
-
-	CatalogTupleDelete(rel, &tuple->t_self);
-
-	systable_endscan(scan);
-	table_close(rel, RowExclusiveLock);
-}
-
-
 /*
  * expand_col_privileges
  *
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index ffd52c1153..2d208d5ee2 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -66,9 +66,7 @@
 #include "commands/event_trigger.h"
 #include "commands/extension.h"
 #include "commands/policy.h"
-#include "commands/proclang.h"
 #include "commands/publicationcmds.h"
-#include "commands/schemacmds.h"
 #include "commands/seclabel.h"
 #include "commands/sequence.h"
 #include "commands/trigger.h"
@@ -1225,6 +1223,62 @@ reportDependentObjects(const ObjectAddresses *targetObjects,
 	pfree(logdetail.data);
 }
 
+/*
+ * Drop an object by OID.  Works for most catalogs, if no special processing
+ * is needed.
+ */
+static void
+DropGenericById(const ObjectAddress *object)
+{
+	int			cacheId;
+	Relation	rel;
+	HeapTuple	tup;
+
+	cacheId = get_object_catcache_oid(object->classId);
+
+	rel = table_open(object->classId, RowExclusiveLock);
+
+	/*
+	 * Use the system cache for the oid column, if one exists.
+	 */
+	if (cacheId >= 0)
+	{
+		tup = SearchSysCache1(cacheId, ObjectIdGetDatum(object->objectId));
+		if (!HeapTupleIsValid(tup))
+			elog(ERROR, "cache lookup failed for %s entry %u",
+				 get_object_class_descr(object->classId), object->objectId);
+
+		CatalogTupleDelete(rel, &tup->t_self);
+
+		ReleaseSysCache(tup);
+	}
+	else
+	{
+		ScanKeyData skey[1];
+		SysScanDesc scan;
+
+		ScanKeyInit(&skey[0],
+					get_object_attnum_oid(object->classId),
+					BTEqualStrategyNumber, F_OIDEQ,
+					ObjectIdGetDatum(object->objectId));
+
+		scan = systable_beginscan(rel, get_object_oid_index(object->classId), true,
+								  NULL, 1, skey);
+
+		/* we expect exactly one match */
+		tup = systable_getnext(scan);
+		if (!HeapTupleIsValid(tup))
+			elog(ERROR, "could not find tuple for class %u entry %u",
+				 object->classId, object->objectId);
+
+		CatalogTupleDelete(rel, &tup->t_self);
+
+		systable_endscan(scan);
+	}
+
+	table_close(rel, RowExclusiveLock);
+}
+
 /*
  * deleteOneObject: delete a single object for performDeletion.
  *
@@ -1378,30 +1432,14 @@ doDeletion(const ObjectAddress *object, int flags)
 			RemoveTypeById(object->objectId);
 			break;
 
-		case OCLASS_CAST:
-			DropCastById(object->objectId);
-			break;
-
-		case OCLASS_COLLATION:
-			RemoveCollationById(object->objectId);
-			break;
-
 		case OCLASS_CONSTRAINT:
 			RemoveConstraintById(object->objectId);
 			break;
 
-		case OCLASS_CONVERSION:
-			RemoveConversionById(object->objectId);
-			break;
-
 		case OCLASS_DEFAULT:
 			RemoveAttrDefaultById(object->objectId);
 			break;
 
-		case OCLASS_LANGUAGE:
-			DropProceduralLanguageById(object->objectId);
-			break;
-
 		case OCLASS_LARGEOBJECT:
 			LargeObjectDrop(object->objectId);
 			break;
@@ -1410,26 +1448,6 @@ doDeletion(const ObjectAddress *object, int flags)
 			RemoveOperatorById(object->objectId);
 			break;
 
-		case OCLASS_OPCLASS:
-			RemoveOpClassById(object->objectId);
-			break;
-
-		case OCLASS_OPFAMILY:
-			RemoveOpFamilyById(object->objectId);
-			break;
-
-		case OCLASS_AM:
-			RemoveAccessMethodById(object->objectId);
-			break;
-
-		case OCLASS_AMOP:
-			RemoveAmOpEntryById(object->objectId);
-			break;
-
-		case OCLASS_AMPROC:
-			RemoveAmProcEntryById(object->objectId);
-			break;
-
 		case OCLASS_REWRITE:
 			RemoveRewriteRuleById(object->objectId);
 			break;
@@ -1438,73 +1456,47 @@ doDeletion(const ObjectAddress *object, int flags)
 			RemoveTriggerById(object->objectId);
 			break;
 
-		case OCLASS_SCHEMA:
-			RemoveSchemaById(object->objectId);
-			break;
-
 		case OCLASS_STATISTIC_EXT:
 			RemoveStatisticsById(object->objectId);
 			break;
 
-		case OCLASS_TSPARSER:
-			RemoveTSParserById(object->objectId);
-			break;
-
-		case OCLASS_TSDICT:
-			RemoveTSDictionaryById(object->objectId);
-			break;
-
-		case OCLASS_TSTEMPLATE:
-			RemoveTSTemplateById(object->objectId);
-			break;
-
 		case OCLASS_TSCONFIG:
 			RemoveTSConfigurationById(object->objectId);
 			break;
 
-			/*
-			 * OCLASS_ROLE, OCLASS_DATABASE, OCLASS_TBLSPACE intentionally not
-			 * handled here
-			 */
-
-		case OCLASS_FDW:
-			RemoveForeignDataWrapperById(object->objectId);
-			break;
-
-		case OCLASS_FOREIGN_SERVER:
-			RemoveForeignServerById(object->objectId);
-			break;
-
-		case OCLASS_USER_MAPPING:
-			RemoveUserMappingById(object->objectId);
-			break;
-
-		case OCLASS_DEFACL:
-			RemoveDefaultACLById(object->objectId);
-			break;
-
 		case OCLASS_EXTENSION:
 			RemoveExtensionById(object->objectId);
 			break;
 
-		case OCLASS_EVENT_TRIGGER:
-			RemoveEventTriggerById(object->objectId);
-			break;
-
 		case OCLASS_POLICY:
 			RemovePolicyById(object->objectId);
 			break;
 
-		case OCLASS_PUBLICATION:
-			RemovePublicationById(object->objectId);
-			break;
-
 		case OCLASS_PUBLICATION_REL:
 			RemovePublicationRelById(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_PUBLICATION:
 		case OCLASS_TRANSFORM:
-			DropTransformById(object->objectId);
+			DropGenericById(object);
 			break;
 
 			/*
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index 84463f76fc..534df8e802 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -97,6 +97,7 @@
  */
 typedef struct
 {
+	const char *class_descr;	/* string describing the catalog, for internal error messages */
 	Oid			class_oid;		/* oid of catalog */
 	Oid			oid_index_oid;	/* oid of index on system oid column */
 	int			oid_catcache_id;	/* id of catcache on system oid column	*/
@@ -118,6 +119,7 @@ typedef struct
 static const ObjectPropertyType ObjectProperty[] =
 {
 	{
+		"access method",
 		AccessMethodRelationId,
 		AmOidIndexId,
 		AMOID,
@@ -131,6 +133,35 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"access method operator",
+		AccessMethodOperatorRelationId,
+		AccessMethodOperatorOidIndexId,
+		-1,
+		-1,
+		Anum_pg_amop_oid,
+		InvalidAttrNumber,
+		InvalidAttrNumber,
+		InvalidAttrNumber,
+		InvalidAttrNumber,
+		OBJECT_AMOP,
+		false
+	},
+	{
+		"access method procedure",
+		AccessMethodProcedureRelationId,
+		AccessMethodProcedureOidIndexId,
+		-1,
+		-1,
+		Anum_pg_amproc_oid,
+		InvalidAttrNumber,
+		InvalidAttrNumber,
+		InvalidAttrNumber,
+		InvalidAttrNumber,
+		OBJECT_AMPROC,
+		false
+	},
+	{
+		"cast",
 		CastRelationId,
 		CastOidIndexId,
 		-1,
@@ -144,6 +175,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		false
 	},
 	{
+		"collation",
 		CollationRelationId,
 		CollationOidIndexId,
 		COLLOID,
@@ -157,6 +189,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"constraint",
 		ConstraintRelationId,
 		ConstraintOidIndexId,
 		CONSTROID,
@@ -170,6 +203,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		false
 	},
 	{
+		"conversion",
 		ConversionRelationId,
 		ConversionOidIndexId,
 		CONVOID,
@@ -183,6 +217,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"database",
 		DatabaseRelationId,
 		DatabaseOidIndexId,
 		DATABASEOID,
@@ -196,6 +231,21 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"default ACL",
+		DefaultAclRelationId,
+		DefaultAclOidIndexId,
+		-1,
+		-1,
+		Anum_pg_default_acl_oid,
+		InvalidAttrNumber,
+		InvalidAttrNumber,
+		InvalidAttrNumber,
+		InvalidAttrNumber,
+		OBJECT_DEFACL,
+		false
+	},
+	{
+		"extension",
 		ExtensionRelationId,
 		ExtensionOidIndexId,
 		-1,
@@ -209,6 +259,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"foreign-data wrapper",
 		ForeignDataWrapperRelationId,
 		ForeignDataWrapperOidIndexId,
 		FOREIGNDATAWRAPPEROID,
@@ -222,6 +273,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"foreign server",
 		ForeignServerRelationId,
 		ForeignServerOidIndexId,
 		FOREIGNSERVEROID,
@@ -235,6 +287,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"function",
 		ProcedureRelationId,
 		ProcedureOidIndexId,
 		PROCOID,
@@ -248,6 +301,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		false
 	},
 	{
+		"language",
 		LanguageRelationId,
 		LanguageOidIndexId,
 		LANGOID,
@@ -261,6 +315,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"large object metadata",
 		LargeObjectMetadataRelationId,
 		LargeObjectMetadataOidIndexId,
 		-1,
@@ -274,6 +329,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		false
 	},
 	{
+		"operator class",
 		OperatorClassRelationId,
 		OpclassOidIndexId,
 		CLAOID,
@@ -287,6 +343,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"operator",
 		OperatorRelationId,
 		OperatorOidIndexId,
 		OPEROID,
@@ -300,6 +357,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		false
 	},
 	{
+		"operator family",
 		OperatorFamilyRelationId,
 		OpfamilyOidIndexId,
 		OPFAMILYOID,
@@ -313,6 +371,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"role",
 		AuthIdRelationId,
 		AuthIdOidIndexId,
 		AUTHOID,
@@ -326,6 +385,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"rule",
 		RewriteRelationId,
 		RewriteOidIndexId,
 		-1,
@@ -339,6 +399,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		false
 	},
 	{
+		"schema",
 		NamespaceRelationId,
 		NamespaceOidIndexId,
 		NAMESPACEOID,
@@ -352,6 +413,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"relation",
 		RelationRelationId,
 		ClassOidIndexId,
 		RELOID,
@@ -365,6 +427,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"tablespace",
 		TableSpaceRelationId,
 		TablespaceOidIndexId,
 		TABLESPACEOID,
@@ -378,6 +441,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"transform",
 		TransformRelationId,
 		TransformOidIndexId,
 		TRFOID,
@@ -385,6 +449,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		Anum_pg_transform_oid
 	},
 	{
+		"trigger",
 		TriggerRelationId,
 		TriggerOidIndexId,
 		-1,
@@ -398,6 +463,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		false
 	},
 	{
+		"policy",
 		PolicyRelationId,
 		PolicyOidIndexId,
 		-1,
@@ -411,6 +477,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		false
 	},
 	{
+		"event trigger",
 		EventTriggerRelationId,
 		EventTriggerOidIndexId,
 		EVENTTRIGGEROID,
@@ -424,6 +491,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"text search configuration",
 		TSConfigRelationId,
 		TSConfigOidIndexId,
 		TSCONFIGOID,
@@ -437,6 +505,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"text search dictionary",
 		TSDictionaryRelationId,
 		TSDictionaryOidIndexId,
 		TSDICTOID,
@@ -450,6 +519,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"text search parser",
 		TSParserRelationId,
 		TSParserOidIndexId,
 		TSPARSEROID,
@@ -463,6 +533,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"text search template",
 		TSTemplateRelationId,
 		TSTemplateOidIndexId,
 		TSTEMPLATEOID,
@@ -476,6 +547,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true,
 	},
 	{
+		"type",
 		TypeRelationId,
 		TypeOidIndexId,
 		TYPEOID,
@@ -489,6 +561,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"publication",
 		PublicationRelationId,
 		PublicationObjectIndexId,
 		PUBLICATIONOID,
@@ -502,6 +575,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"subscription",
 		SubscriptionRelationId,
 		SubscriptionObjectIndexId,
 		SUBSCRIPTIONOID,
@@ -515,6 +589,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"extented statistics",
 		StatisticExtRelationId,
 		StatisticExtOidIndexId,
 		STATEXTOID,
@@ -526,7 +601,21 @@ static const ObjectPropertyType ObjectProperty[] =
 		InvalidAttrNumber,		/* no ACL (same as relation) */
 		OBJECT_STATISTIC_EXT,
 		true
-	}
+	},
+	{
+		"user mapping",
+		UserMappingRelationId,
+		UserMappingOidIndexId,
+		USERMAPPINGOID,
+		-1,
+		Anum_pg_user_mapping_oid,
+		InvalidAttrNumber,
+		InvalidAttrNumber,
+		InvalidAttrNumber,
+		InvalidAttrNumber,
+		OBJECT_USER_MAPPING,
+		false
+	},
 };
 
 /*
@@ -2549,6 +2638,14 @@ read_objtype_from_string(const char *objtype)
 /*
  * Interfaces to reference fields of ObjectPropertyType
  */
+const char *
+get_object_class_descr(Oid class_id)
+{
+	const ObjectPropertyType *prop = get_object_property_data(class_id);
+
+	return prop->class_descr;
+}
+
 Oid
 get_object_oid_index(Oid class_id)
 {
diff --git a/src/backend/catalog/pg_collation.c b/src/backend/catalog/pg_collation.c
index 8559779a4f..5fdf1acb7e 100644
--- a/src/backend/catalog/pg_collation.c
+++ b/src/backend/catalog/pg_collation.c
@@ -203,39 +203,3 @@ CollationCreate(const char *collname, Oid collnamespace,
 
 	return oid;
 }
-
-/*
- * RemoveCollationById
- *
- * Remove a tuple from pg_collation by Oid. This function is solely
- * called inside catalog/dependency.c
- */
-void
-RemoveCollationById(Oid collationOid)
-{
-	Relation	rel;
-	ScanKeyData scanKeyData;
-	SysScanDesc scandesc;
-	HeapTuple	tuple;
-
-	rel = table_open(CollationRelationId, RowExclusiveLock);
-
-	ScanKeyInit(&scanKeyData,
-				Anum_pg_collation_oid,
-				BTEqualStrategyNumber, F_OIDEQ,
-				ObjectIdGetDatum(collationOid));
-
-	scandesc = systable_beginscan(rel, CollationOidIndexId, true,
-								  NULL, 1, &scanKeyData);
-
-	tuple = systable_getnext(scandesc);
-
-	if (HeapTupleIsValid(tuple))
-		CatalogTupleDelete(rel, &tuple->t_self);
-	else
-		elog(ERROR, "could not find tuple for collation %u", collationOid);
-
-	systable_endscan(scandesc);
-
-	table_close(rel, RowExclusiveLock);
-}
diff --git a/src/backend/catalog/pg_conversion.c b/src/backend/catalog/pg_conversion.c
index b38df4f696..28b676a1fa 100644
--- a/src/backend/catalog/pg_conversion.c
+++ b/src/backend/catalog/pg_conversion.c
@@ -142,39 +142,6 @@ ConversionCreate(const char *conname, Oid connamespace,
 	return myself;
 }
 
-/*
- * RemoveConversionById
- *
- * Remove a tuple from pg_conversion by Oid. This function is solely
- * called inside catalog/dependency.c
- */
-void
-RemoveConversionById(Oid conversionOid)
-{
-	Relation	rel;
-	HeapTuple	tuple;
-	TableScanDesc scan;
-	ScanKeyData scanKeyData;
-
-	ScanKeyInit(&scanKeyData,
-				Anum_pg_conversion_oid,
-				BTEqualStrategyNumber, F_OIDEQ,
-				ObjectIdGetDatum(conversionOid));
-
-	/* open pg_conversion */
-	rel = table_open(ConversionRelationId, RowExclusiveLock);
-
-	scan = table_beginscan_catalog(rel, 1, &scanKeyData);
-
-	/* search for the target tuple */
-	if (HeapTupleIsValid(tuple = heap_getnext(scan, ForwardScanDirection)))
-		CatalogTupleDelete(rel, &tuple->t_self);
-	else
-		elog(ERROR, "could not find tuple for conversion %u", conversionOid);
-	table_endscan(scan);
-	table_close(rel, RowExclusiveLock);
-}
-
 /*
  * FindDefaultConversion
  *
diff --git a/src/backend/commands/amcmds.c b/src/backend/commands/amcmds.c
index 7546378bbb..ebd0029562 100644
--- a/src/backend/commands/amcmds.c
+++ b/src/backend/commands/amcmds.c
@@ -112,33 +112,6 @@ CreateAccessMethod(CreateAmStmt *stmt)
 	return myself;
 }
 
-/*
- * Guts of access method deletion.
- */
-void
-RemoveAccessMethodById(Oid amOid)
-{
-	Relation	relation;
-	HeapTuple	tup;
-
-	if (!superuser())
-		ereport(ERROR,
-				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
-				 errmsg("must be superuser to drop access methods")));
-
-	relation = table_open(AccessMethodRelationId, RowExclusiveLock);
-
-	tup = SearchSysCache1(AMOID, ObjectIdGetDatum(amOid));
-	if (!HeapTupleIsValid(tup))
-		elog(ERROR, "cache lookup failed for access method %u", amOid);
-
-	CatalogTupleDelete(relation, &tup->t_self);
-
-	ReleaseSysCache(tup);
-
-	table_close(relation, RowExclusiveLock);
-}
-
 /*
  * get_am_type_oid
  *		Worker for various get_am_*_oid variants
diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c
index 91800d1fac..bf21bf77aa 100644
--- a/src/backend/commands/event_trigger.c
+++ b/src/backend/commands/event_trigger.c
@@ -361,28 +361,6 @@ filter_list_to_array(List *filterlist)
 										   -1, false, TYPALIGN_INT));
 }
 
-/*
- * Guts of event trigger deletion.
- */
-void
-RemoveEventTriggerById(Oid trigOid)
-{
-	Relation	tgrel;
-	HeapTuple	tup;
-
-	tgrel = table_open(EventTriggerRelationId, RowExclusiveLock);
-
-	tup = SearchSysCache1(EVENTTRIGGEROID, ObjectIdGetDatum(trigOid));
-	if (!HeapTupleIsValid(tup))
-		elog(ERROR, "cache lookup failed for event trigger %u", trigOid);
-
-	CatalogTupleDelete(tgrel, &tup->t_self);
-
-	ReleaseSysCache(tup);
-
-	table_close(tgrel, RowExclusiveLock);
-}
-
 /*
  * ALTER EVENT TRIGGER foo ENABLE|DISABLE|ENABLE ALWAYS|REPLICA
  */
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
index f197869752..81554b8b09 100644
--- a/src/backend/commands/foreigncmds.c
+++ b/src/backend/commands/foreigncmds.c
@@ -835,30 +835,6 @@ AlterForeignDataWrapper(AlterFdwStmt *stmt)
 }
 
 
-/*
- * Drop foreign-data wrapper by OID
- */
-void
-RemoveForeignDataWrapperById(Oid fdwId)
-{
-	HeapTuple	tp;
-	Relation	rel;
-
-	rel = table_open(ForeignDataWrapperRelationId, RowExclusiveLock);
-
-	tp = SearchSysCache1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdwId));
-
-	if (!HeapTupleIsValid(tp))
-		elog(ERROR, "cache lookup failed for foreign-data wrapper %u", fdwId);
-
-	CatalogTupleDelete(rel, &tp->t_self);
-
-	ReleaseSysCache(tp);
-
-	table_close(rel, RowExclusiveLock);
-}
-
-
 /*
  * Create a foreign server
  */
@@ -1085,30 +1061,6 @@ AlterForeignServer(AlterForeignServerStmt *stmt)
 }
 
 
-/*
- * Drop foreign server by OID
- */
-void
-RemoveForeignServerById(Oid srvId)
-{
-	HeapTuple	tp;
-	Relation	rel;
-
-	rel = table_open(ForeignServerRelationId, RowExclusiveLock);
-
-	tp = SearchSysCache1(FOREIGNSERVEROID, ObjectIdGetDatum(srvId));
-
-	if (!HeapTupleIsValid(tp))
-		elog(ERROR, "cache lookup failed for foreign server %u", srvId);
-
-	CatalogTupleDelete(rel, &tp->t_self);
-
-	ReleaseSysCache(tp);
-
-	table_close(rel, RowExclusiveLock);
-}
-
-
 /*
  * Common routine to check permission for user-mapping-related DDL
  * commands.  We allow server owners to operate on any mapping, and
@@ -1432,29 +1384,6 @@ RemoveUserMapping(DropUserMappingStmt *stmt)
 }
 
 
-/*
- * Drop user mapping by OID.  This is called to clean up dependencies.
- */
-void
-RemoveUserMappingById(Oid umId)
-{
-	HeapTuple	tp;
-	Relation	rel;
-
-	rel = table_open(UserMappingRelationId, RowExclusiveLock);
-
-	tp = SearchSysCache1(USERMAPPINGOID, ObjectIdGetDatum(umId));
-
-	if (!HeapTupleIsValid(tp))
-		elog(ERROR, "cache lookup failed for user mapping %u", umId);
-
-	CatalogTupleDelete(rel, &tp->t_self);
-
-	ReleaseSysCache(tp);
-
-	table_close(rel, RowExclusiveLock);
-}
-
 /*
  * Create a foreign table
  * call after DefineRelation().
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 694114aded..c40012abd8 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -1646,32 +1646,6 @@ CreateCast(CreateCastStmt *stmt)
 	return myself;
 }
 
-void
-DropCastById(Oid castOid)
-{
-	Relation	relation;
-	ScanKeyData scankey;
-	SysScanDesc scan;
-	HeapTuple	tuple;
-
-	relation = table_open(CastRelationId, RowExclusiveLock);
-
-	ScanKeyInit(&scankey,
-				Anum_pg_cast_oid,
-				BTEqualStrategyNumber, F_OIDEQ,
-				ObjectIdGetDatum(castOid));
-	scan = systable_beginscan(relation, CastOidIndexId, true,
-							  NULL, 1, &scankey);
-
-	tuple = systable_getnext(scan);
-	if (!HeapTupleIsValid(tuple))
-		elog(ERROR, "could not find tuple for cast %u", castOid);
-	CatalogTupleDelete(relation, &tuple->t_self);
-
-	systable_endscan(scan);
-	table_close(relation, RowExclusiveLock);
-}
-
 
 static void
 check_transform_function(Form_pg_proc procstruct)
@@ -1933,33 +1907,6 @@ get_transform_oid(Oid type_id, Oid lang_id, bool missing_ok)
 }
 
 
-void
-DropTransformById(Oid transformOid)
-{
-	Relation	relation;
-	ScanKeyData scankey;
-	SysScanDesc scan;
-	HeapTuple	tuple;
-
-	relation = table_open(TransformRelationId, RowExclusiveLock);
-
-	ScanKeyInit(&scankey,
-				Anum_pg_transform_oid,
-				BTEqualStrategyNumber, F_OIDEQ,
-				ObjectIdGetDatum(transformOid));
-	scan = systable_beginscan(relation, TransformOidIndexId, true,
-							  NULL, 1, &scankey);
-
-	tuple = systable_getnext(scan);
-	if (!HeapTupleIsValid(tuple))
-		elog(ERROR, "could not find tuple for transform %u", transformOid);
-	CatalogTupleDelete(relation, &tuple->t_self);
-
-	systable_endscan(scan);
-	table_close(relation, RowExclusiveLock);
-}
-
-
 /*
  * Subroutine for ALTER FUNCTION/AGGREGATE SET SCHEMA/RENAME
  *
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index 7322cbc154..36204808be 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -1656,105 +1656,6 @@ dropProcedures(List *opfamilyname, Oid amoid, Oid opfamilyoid,
 	}
 }
 
-/*
- * Deletion subroutines for use by dependency.c.
- */
-void
-RemoveOpFamilyById(Oid opfamilyOid)
-{
-	Relation	rel;
-	HeapTuple	tup;
-
-	rel = table_open(OperatorFamilyRelationId, RowExclusiveLock);
-
-	tup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfamilyOid));
-	if (!HeapTupleIsValid(tup)) /* should not happen */
-		elog(ERROR, "cache lookup failed for opfamily %u", opfamilyOid);
-
-	CatalogTupleDelete(rel, &tup->t_self);
-
-	ReleaseSysCache(tup);
-
-	table_close(rel, RowExclusiveLock);
-}
-
-void
-RemoveOpClassById(Oid opclassOid)
-{
-	Relation	rel;
-	HeapTuple	tup;
-
-	rel = table_open(OperatorClassRelationId, RowExclusiveLock);
-
-	tup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclassOid));
-	if (!HeapTupleIsValid(tup)) /* should not happen */
-		elog(ERROR, "cache lookup failed for opclass %u", opclassOid);
-
-	CatalogTupleDelete(rel, &tup->t_self);
-
-	ReleaseSysCache(tup);
-
-	table_close(rel, RowExclusiveLock);
-}
-
-void
-RemoveAmOpEntryById(Oid entryOid)
-{
-	Relation	rel;
-	HeapTuple	tup;
-	ScanKeyData skey[1];
-	SysScanDesc scan;
-
-	ScanKeyInit(&skey[0],
-				Anum_pg_amop_oid,
-				BTEqualStrategyNumber, F_OIDEQ,
-				ObjectIdGetDatum(entryOid));
-
-	rel = table_open(AccessMethodOperatorRelationId, RowExclusiveLock);
-
-	scan = systable_beginscan(rel, AccessMethodOperatorOidIndexId, true,
-							  NULL, 1, skey);
-
-	/* we expect exactly one match */
-	tup = systable_getnext(scan);
-	if (!HeapTupleIsValid(tup))
-		elog(ERROR, "could not find tuple for amop entry %u", entryOid);
-
-	CatalogTupleDelete(rel, &tup->t_self);
-
-	systable_endscan(scan);
-	table_close(rel, RowExclusiveLock);
-}
-
-void
-RemoveAmProcEntryById(Oid entryOid)
-{
-	Relation	rel;
-	HeapTuple	tup;
-	ScanKeyData skey[1];
-	SysScanDesc scan;
-
-	ScanKeyInit(&skey[0],
-				Anum_pg_amproc_oid,
-				BTEqualStrategyNumber, F_OIDEQ,
-				ObjectIdGetDatum(entryOid));
-
-	rel = table_open(AccessMethodProcedureRelationId, RowExclusiveLock);
-
-	scan = systable_beginscan(rel, AccessMethodProcedureOidIndexId, true,
-							  NULL, 1, skey);
-
-	/* we expect exactly one match */
-	tup = systable_getnext(scan);
-	if (!HeapTupleIsValid(tup))
-		elog(ERROR, "could not find tuple for amproc entry %u", entryOid);
-
-	CatalogTupleDelete(rel, &tup->t_self);
-
-	systable_endscan(scan);
-	table_close(rel, RowExclusiveLock);
-}
-
 /*
  * Subroutine for ALTER OPERATOR CLASS SET SCHEMA/RENAME
  *
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index 21ceeb7e9a..14153426bd 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -218,28 +218,6 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
 	return myself;
 }
 
-/*
- * Guts of language dropping.
- */
-void
-DropProceduralLanguageById(Oid langOid)
-{
-	Relation	rel;
-	HeapTuple	langTup;
-
-	rel = table_open(LanguageRelationId, RowExclusiveLock);
-
-	langTup = SearchSysCache1(LANGOID, ObjectIdGetDatum(langOid));
-	if (!HeapTupleIsValid(langTup)) /* should not happen */
-		elog(ERROR, "cache lookup failed for language %u", langOid);
-
-	CatalogTupleDelete(rel, &langTup->t_self);
-
-	ReleaseSysCache(langTup);
-
-	table_close(rel, RowExclusiveLock);
-}
-
 /*
  * get_language_oid - given a language name, look up the OID
  *
diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c
index 771268f70a..4d36976146 100644
--- a/src/backend/commands/publicationcmds.c
+++ b/src/backend/commands/publicationcmds.c
@@ -468,29 +468,6 @@ AlterPublication(AlterPublicationStmt *stmt)
 	table_close(rel, RowExclusiveLock);
 }
 
-/*
- * Drop publication by OID
- */
-void
-RemovePublicationById(Oid pubid)
-{
-	Relation	rel;
-	HeapTuple	tup;
-
-	rel = table_open(PublicationRelationId, RowExclusiveLock);
-
-	tup = SearchSysCache1(PUBLICATIONOID, ObjectIdGetDatum(pubid));
-
-	if (!HeapTupleIsValid(tup))
-		elog(ERROR, "cache lookup failed for publication %u", pubid);
-
-	CatalogTupleDelete(rel, &tup->t_self);
-
-	ReleaseSysCache(tup);
-
-	table_close(rel, RowExclusiveLock);
-}
-
 /*
  * Remove relation from publication by mapping OID.
  */
diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c
index 1e6e731eb5..3013862528 100644
--- a/src/backend/commands/schemacmds.c
+++ b/src/backend/commands/schemacmds.c
@@ -210,29 +210,6 @@ CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString,
 	return namespaceId;
 }
 
-/*
- * Guts of schema deletion.
- */
-void
-RemoveSchemaById(Oid schemaOid)
-{
-	Relation	relation;
-	HeapTuple	tup;
-
-	relation = table_open(NamespaceRelationId, RowExclusiveLock);
-
-	tup = SearchSysCache1(NAMESPACEOID,
-						  ObjectIdGetDatum(schemaOid));
-	if (!HeapTupleIsValid(tup)) /* should not happen */
-		elog(ERROR, "cache lookup failed for namespace %u", schemaOid);
-
-	CatalogTupleDelete(relation, &tup->t_self);
-
-	ReleaseSysCache(tup);
-
-	table_close(relation, RowExclusiveLock);
-}
-
 
 /*
  * Rename schema
diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c
index 9da8f7fd57..319a62012e 100644
--- a/src/backend/commands/tsearchcmds.c
+++ b/src/backend/commands/tsearchcmds.c
@@ -291,29 +291,6 @@ DefineTSParser(List *names, List *parameters)
 	return address;
 }
 
-/*
- * Guts of TS parser deletion.
- */
-void
-RemoveTSParserById(Oid prsId)
-{
-	Relation	relation;
-	HeapTuple	tup;
-
-	relation = table_open(TSParserRelationId, RowExclusiveLock);
-
-	tup = SearchSysCache1(TSPARSEROID, ObjectIdGetDatum(prsId));
-
-	if (!HeapTupleIsValid(tup))
-		elog(ERROR, "cache lookup failed for text search parser %u", prsId);
-
-	CatalogTupleDelete(relation, &tup->t_self);
-
-	ReleaseSysCache(tup);
-
-	table_close(relation, RowExclusiveLock);
-}
-
 /* ---------------------- TS Dictionary commands -----------------------*/
 
 /*
@@ -504,30 +481,6 @@ DefineTSDictionary(List *names, List *parameters)
 	return address;
 }
 
-/*
- * Guts of TS dictionary deletion.
- */
-void
-RemoveTSDictionaryById(Oid dictId)
-{
-	Relation	relation;
-	HeapTuple	tup;
-
-	relation = table_open(TSDictionaryRelationId, RowExclusiveLock);
-
-	tup = SearchSysCache1(TSDICTOID, ObjectIdGetDatum(dictId));
-
-	if (!HeapTupleIsValid(tup))
-		elog(ERROR, "cache lookup failed for text search dictionary %u",
-			 dictId);
-
-	CatalogTupleDelete(relation, &tup->t_self);
-
-	ReleaseSysCache(tup);
-
-	table_close(relation, RowExclusiveLock);
-}
-
 /*
  * ALTER TEXT SEARCH DICTIONARY
  */
@@ -820,30 +773,6 @@ DefineTSTemplate(List *names, List *parameters)
 	return address;
 }
 
-/*
- * Guts of TS template deletion.
- */
-void
-RemoveTSTemplateById(Oid tmplId)
-{
-	Relation	relation;
-	HeapTuple	tup;
-
-	relation = table_open(TSTemplateRelationId, RowExclusiveLock);
-
-	tup = SearchSysCache1(TSTEMPLATEOID, ObjectIdGetDatum(tmplId));
-
-	if (!HeapTupleIsValid(tup))
-		elog(ERROR, "cache lookup failed for text search template %u",
-			 tmplId);
-
-	CatalogTupleDelete(relation, &tup->t_self);
-
-	ReleaseSysCache(tup);
-
-	table_close(relation, RowExclusiveLock);
-}
-
 /* ---------------------- TS Configuration commands -----------------------*/
 
 /*
diff --git a/src/include/catalog/objectaddress.h b/src/include/catalog/objectaddress.h
index 7f15efd58a..144715d4f4 100644
--- a/src/include/catalog/objectaddress.h
+++ b/src/include/catalog/objectaddress.h
@@ -55,6 +55,7 @@ extern void check_object_ownership(Oid roleid,
 extern Oid	get_object_namespace(const ObjectAddress *address);
 
 extern bool is_objectclass_supported(Oid class_id);
+extern const char *get_object_class_descr(Oid class_id);
 extern Oid	get_object_oid_index(Oid class_id);
 extern int	get_object_catcache_oid(Oid class_id);
 extern int	get_object_catcache_name(Oid class_id);
diff --git a/src/include/catalog/pg_collation.h b/src/include/catalog/pg_collation.h
index 6955bb1273..27618b324d 100644
--- a/src/include/catalog/pg_collation.h
+++ b/src/include/catalog/pg_collation.h
@@ -68,6 +68,5 @@ extern Oid	CollationCreate(const char *collname, Oid collnamespace,
 							const char *collversion,
 							bool if_not_exists,
 							bool quiet);
-extern void RemoveCollationById(Oid collationOid);
 
 #endif							/* PG_COLLATION_H */
diff --git a/src/include/catalog/pg_conversion.h b/src/include/catalog/pg_conversion.h
index 0e7f13e1b6..cd80a042ff 100644
--- a/src/include/catalog/pg_conversion.h
+++ b/src/include/catalog/pg_conversion.h
@@ -65,7 +65,6 @@ extern ObjectAddress ConversionCreate(const char *conname, Oid connamespace,
 									  Oid conowner,
 									  int32 conforencoding, int32 contoencoding,
 									  Oid conproc, bool def);
-extern void RemoveConversionById(Oid conversionOid);
 extern Oid	FindDefaultConversion(Oid connamespace, int32 for_encoding,
 								  int32 to_encoding);
 
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index c77c9a6ed5..c26a102b17 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -56,9 +56,7 @@ extern ObjectAddress CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt
 extern void RemoveFunctionById(Oid funcOid);
 extern ObjectAddress AlterFunction(ParseState *pstate, AlterFunctionStmt *stmt);
 extern ObjectAddress CreateCast(CreateCastStmt *stmt);
-extern void DropCastById(Oid castOid);
 extern ObjectAddress CreateTransform(CreateTransformStmt *stmt);
-extern void DropTransformById(Oid transformOid);
 extern void IsThereFunctionInNamespace(const char *proname, int pronargs,
 									   oidvector *proargtypes, Oid nspOid);
 extern void ExecuteDoStmt(DoStmt *stmt, bool atomic);
@@ -98,10 +96,6 @@ extern ObjectAddress DefineAggregate(ParseState *pstate, List *name, List *args,
 extern ObjectAddress DefineOpClass(CreateOpClassStmt *stmt);
 extern ObjectAddress DefineOpFamily(CreateOpFamilyStmt *stmt);
 extern Oid	AlterOpFamily(AlterOpFamilyStmt *stmt);
-extern void RemoveOpClassById(Oid opclassOid);
-extern void RemoveOpFamilyById(Oid opfamilyOid);
-extern void RemoveAmOpEntryById(Oid entryOid);
-extern void RemoveAmProcEntryById(Oid entryOid);
 extern void IsThereOpClassInNamespace(const char *opcname, Oid opcmethod,
 									  Oid opcnamespace);
 extern void IsThereOpFamilyInNamespace(const char *opfname, Oid opfmethod,
@@ -111,14 +105,11 @@ extern Oid	get_opfamily_oid(Oid amID, List *opfamilyname, bool missing_ok);
 
 /* commands/tsearchcmds.c */
 extern ObjectAddress DefineTSParser(List *names, List *parameters);
-extern void RemoveTSParserById(Oid prsId);
 
 extern ObjectAddress DefineTSDictionary(List *names, List *parameters);
-extern void RemoveTSDictionaryById(Oid dictId);
 extern ObjectAddress AlterTSDictionary(AlterTSDictionaryStmt *stmt);
 
 extern ObjectAddress DefineTSTemplate(List *names, List *parameters);
-extern void RemoveTSTemplateById(Oid tmplId);
 
 extern ObjectAddress DefineTSConfiguration(List *names, List *parameters,
 										   ObjectAddress *copied);
@@ -135,14 +126,11 @@ extern ObjectAddress AlterForeignDataWrapperOwner(const char *name, Oid newOwner
 extern void AlterForeignDataWrapperOwner_oid(Oid fwdId, Oid newOwnerId);
 extern ObjectAddress CreateForeignDataWrapper(CreateFdwStmt *stmt);
 extern ObjectAddress AlterForeignDataWrapper(AlterFdwStmt *stmt);
-extern void RemoveForeignDataWrapperById(Oid fdwId);
 extern ObjectAddress CreateForeignServer(CreateForeignServerStmt *stmt);
 extern ObjectAddress AlterForeignServer(AlterForeignServerStmt *stmt);
-extern void RemoveForeignServerById(Oid srvId);
 extern ObjectAddress CreateUserMapping(CreateUserMappingStmt *stmt);
 extern ObjectAddress AlterUserMapping(AlterUserMappingStmt *stmt);
 extern Oid	RemoveUserMapping(DropUserMappingStmt *stmt);
-extern void RemoveUserMappingById(Oid umId);
 extern void CreateForeignTable(CreateForeignTableStmt *stmt, Oid relid);
 extern void ImportForeignSchema(ImportForeignSchemaStmt *stmt);
 extern Datum transformGenericOptions(Oid catalogId,
@@ -152,7 +140,6 @@ extern Datum transformGenericOptions(Oid catalogId,
 
 /* commands/amcmds.c */
 extern ObjectAddress CreateAccessMethod(CreateAmStmt *stmt);
-extern void RemoveAccessMethodById(Oid amOid);
 extern Oid	get_index_am_oid(const char *amname, bool missing_ok);
 extern Oid	get_table_am_oid(const char *amname, bool missing_ok);
 extern Oid	get_am_oid(const char *amname, bool missing_ok);
diff --git a/src/include/commands/event_trigger.h b/src/include/commands/event_trigger.h
index 28b352051b..407fd6a978 100644
--- a/src/include/commands/event_trigger.h
+++ b/src/include/commands/event_trigger.h
@@ -41,7 +41,6 @@ typedef struct EventTriggerData
 	((fcinfo)->context != NULL && IsA((fcinfo)->context, EventTriggerData))
 
 extern Oid	CreateEventTrigger(CreateEventTrigStmt *stmt);
-extern void RemoveEventTriggerById(Oid trigOid);
 extern Oid	get_event_trigger_oid(const char *trigname, bool missing_ok);
 
 extern Oid	AlterEventTrigger(AlterEventTrigStmt *stmt);
diff --git a/src/include/commands/proclang.h b/src/include/commands/proclang.h
index c70f8ec928..d566a121f0 100644
--- a/src/include/commands/proclang.h
+++ b/src/include/commands/proclang.h
@@ -17,7 +17,6 @@
 #include "nodes/parsenodes.h"
 
 extern ObjectAddress CreateProceduralLanguage(CreatePLangStmt *stmt);
-extern void DropProceduralLanguageById(Oid langOid);
 
 extern Oid	get_language_oid(const char *langname, bool missing_ok);
 
diff --git a/src/include/commands/publicationcmds.h b/src/include/commands/publicationcmds.h
index e713df0c31..c6b286245f 100644
--- a/src/include/commands/publicationcmds.h
+++ b/src/include/commands/publicationcmds.h
@@ -20,7 +20,6 @@
 
 extern ObjectAddress CreatePublication(CreatePublicationStmt *stmt);
 extern void AlterPublication(AlterPublicationStmt *stmt);
-extern void RemovePublicationById(Oid pubid);
 extern void RemovePublicationRelById(Oid proid);
 
 extern ObjectAddress AlterPublicationOwner(const char *name, Oid newOwnerId);
diff --git a/src/include/commands/schemacmds.h b/src/include/commands/schemacmds.h
index ac88a35399..e0139a8ea6 100644
--- a/src/include/commands/schemacmds.h
+++ b/src/include/commands/schemacmds.h
@@ -22,8 +22,6 @@ extern Oid	CreateSchemaCommand(CreateSchemaStmt *parsetree,
 								const char *queryString,
 								int stmt_location, int stmt_len);
 
-extern void RemoveSchemaById(Oid schemaOid);
-
 extern ObjectAddress RenameSchema(const char *oldname, const char *newname);
 extern ObjectAddress AlterSchemaOwner(const char *name, Oid newOwnerId);
 extern void AlterSchemaOwner_oid(Oid schemaOid, Oid newOwnerId);
diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h
index 732aa01dad..b263d92903 100644
--- a/src/include/utils/acl.h
+++ b/src/include/utils/acl.h
@@ -230,7 +230,6 @@ extern void ExecuteGrantStmt(GrantStmt *stmt);
 extern void ExecAlterDefaultPrivilegesStmt(ParseState *pstate, AlterDefaultPrivilegesStmt *stmt);
 
 extern void RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid);
-extern void RemoveDefaultACLById(Oid defaclOid);
 
 extern AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attnum,
 									Oid roleid, AclMode mask, AclMaskHow how);
-- 
2.26.2

#2Pavel Stehule
pavel.stehule@gmail.com
In reply to: Peter Eisentraut (#1)
Re: Unify drop-by-OID functions

pá 1. 5. 2020 v 16:39 odesílatel Peter Eisentraut <
peter.eisentraut@2ndquadrant.com> napsal:

[proposal for PG 14]

There are a number of Remove${Something}ById() functions that are
essentially identical in structure and only different in which catalog
they are working on. This patch refactors this to be one generic
function. The information about which oid column, index, etc. to use
was already available in ObjectProperty for most catalogs, in a few
cases it was easily added.

Conceivably, this could be taken further by categorizing more special
cases as ObjectProperty fields or something like that, but this seemed
like a good balance.

+1

nice

Pavel

Show quoted text

--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

#3Robert Haas
robertmhaas@gmail.com
In reply to: Pavel Stehule (#2)
Re: Unify drop-by-OID functions

On Fri, May 1, 2020 at 10:51 AM Pavel Stehule <pavel.stehule@gmail.com> wrote:

+1

+1 from me, too, but I have a few suggestions:

+DropGenericById(const ObjectAddress *object)

How about "Generic" -> "Object" or "Generic" -> "ObjectAddress"?

+ elog(ERROR, "cache lookup failed for %s entry %u",
+ elog(ERROR, "could not find tuple for class %u entry %u",

How about "entry" -> "with OID"?

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

#4Ranier Vilela
ranier.vf@gmail.com
In reply to: Peter Eisentraut (#1)
Re: Unify drop-by-OID functions

Em sex., 1 de mai. de 2020 às 11:39, Peter Eisentraut <
peter.eisentraut@2ndquadrant.com> escreveu:

[proposal for PG 14]

There are a number of Remove${Something}ById() functions that are
essentially identical in structure and only different in which catalog
they are working on. This patch refactors this to be one generic
function. The information about which oid column, index, etc. to use
was already available in ObjectProperty for most catalogs, in a few
cases it was easily added.

Conceivably, this could be taken further by categorizing more special
cases as ObjectProperty fields or something like that, but this seemed
like a good balance.

Very good.

I can suggest improvements?

1. In case Object is cached, delay open_table until the last moment, for
the row to be blocked as little as possible and close the table as quickly
as possible.
2. In case Object is cached and the tuple is invalid, do not open table.
3. Otherwise, is it possible to call systable_endscan, after table_close?

I think that lock resources, for as little time as possible, it is an
advantage..

+static void
+DropGenericById(const ObjectAddress *object)
+{
+ int cacheId;
+ Relation rel;
+ HeapTuple tup;
+
+ cacheId = get_object_catcache_oid(object->classId);
+
+ /*
+ * Use the system cache for the oid column, if one exists.
+ */
+ if (cacheId >= 0)
+ {
+ tup = SearchSysCache1(cacheId, ObjectIdGetDatum(object->objectId));
+ if (!HeapTupleIsValid(tup))
+ elog(ERROR, "cache lookup failed for %s entry %u",
+ get_object_class_descr(object->classId), object->objectId);
+
+        rel = table_open(object->classId, RowExclusiveLock);
+ CatalogTupleDelete(rel, &tup->t_self);
+        table_close(rel, RowExclusiveLock);
+
+ ReleaseSysCache(tup);
+ }
+ else
+ {
+ ScanKeyData skey[1];
+ SysScanDesc scan;
+
+ ScanKeyInit(&skey[0],
+ get_object_attnum_oid(object->classId),
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(object->objectId));
+
+        rel = table_open(object->classId, RowExclusiveLock);
+ scan = systable_beginscan(rel, get_object_oid_index(object->classId),
true,
+  NULL, 1, skey);
+
+ /* we expect exactly one match */
+ tup = systable_getnext(scan);
+ if (!HeapTupleIsValid(tup))
+ elog(ERROR, "could not find tuple for class %u entry %u",
+ object->classId, object->objectId);
+
+ CatalogTupleDelete(rel, &tup->t_self);
+ systable_endscan(scan);
+        table_close(rel, RowExclusiveLock);
+ }
+}
+

regards,
Ranier Vilela

#5Peter Eisentraut
peter.eisentraut@2ndquadrant.com
In reply to: Ranier Vilela (#4)
Re: Unify drop-by-OID functions

On 2020-05-01 23:31, Ranier Vilela wrote:

I can suggest improvements?

1. In case Object is cached, delay open_table until the last moment, for
the row to be blocked as little as possible and close the table as
quickly as possible.
2. In case Object is cached and the tuple is invalid, do not open table.
3. Otherwise, is it possible to call systable_endscan, after table_close?

What do you mean by "object is cached"?

In any case, this is a refactoring patch, so significant changes to the
internal logic would not really be in scope.

--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

#6Ranier Vilela
ranier.vf@gmail.com
In reply to: Peter Eisentraut (#5)
Re: Unify drop-by-OID functions

Em sáb., 2 de mai. de 2020 às 05:01, Peter Eisentraut <
peter.eisentraut@2ndquadrant.com> escreveu:

On 2020-05-01 23:31, Ranier Vilela wrote:

I can suggest improvements?

1. In case Object is cached, delay open_table until the last moment, for
the row to be blocked as little as possible and close the table as
quickly as possible.
2. In case Object is cached and the tuple is invalid, do not open table.
3. Otherwise, is it possible to call systable_endscan, after table_close?

What do you mean by "object is cached"?

Well, that's what I deduced from the cacheId variable name.

regards,
Ranier Vilela

#7Peter Eisentraut
peter.eisentraut@2ndquadrant.com
In reply to: Robert Haas (#3)
1 attachment(s)
Re: Unify drop-by-OID functions

On 2020-05-01 17:44, Robert Haas wrote:

On Fri, May 1, 2020 at 10:51 AM Pavel Stehule <pavel.stehule@gmail.com> wrote:

+1

+1 from me, too, but I have a few suggestions:

+DropGenericById(const ObjectAddress *object)

How about "Generic" -> "Object" or "Generic" -> "ObjectAddress"?

Changed to "Object", that also matches existing functions that operate
on an ObjectAddress.

+ elog(ERROR, "cache lookup failed for %s entry %u",
+ elog(ERROR, "could not find tuple for class %u entry %u",

How about "entry" -> "with OID"?

I changed these to just

"cache lookup failed for %s %u"
"could not find tuple for %s %u"

which matches the existing wording for the not-refactored cases. I
don't recall why I went and reworded them.

New patch attached. I'll park it until PG14 opens.

--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

Attachments:

v2-0001-Unify-drop-by-OID-functions.patchtext/plain; charset=UTF-8; name=v2-0001-Unify-drop-by-OID-functions.patch; x-mac-creator=0; x-mac-type=0Download
From 0916fd395efe65f280c3acdb2172953adbb34afa Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Mon, 4 May 2020 20:22:44 +0200
Subject: [PATCH v2] Unify drop-by-OID functions

There are a number of Remove${Something}ById() functions that are
essentially identical in structure and only different in which catalog
they are working on.  Refactor this to be one generic function.  The
information about which oid column, index, etc. to use was already
available in ObjectProperty for most catalogs, in a few cases it was
easily added.
---
 src/backend/catalog/aclchk.c           |  33 -----
 src/backend/catalog/dependency.c       | 160 ++++++++++++-------------
 src/backend/catalog/objectaddress.c    |  99 ++++++++++++++-
 src/backend/catalog/pg_collation.c     |  36 ------
 src/backend/catalog/pg_conversion.c    |  33 -----
 src/backend/commands/amcmds.c          |  27 -----
 src/backend/commands/event_trigger.c   |  22 ----
 src/backend/commands/foreigncmds.c     |  71 -----------
 src/backend/commands/functioncmds.c    |  53 --------
 src/backend/commands/opclasscmds.c     |  99 ---------------
 src/backend/commands/proclang.c        |  22 ----
 src/backend/commands/publicationcmds.c |  23 ----
 src/backend/commands/schemacmds.c      |  23 ----
 src/backend/commands/tsearchcmds.c     |  71 -----------
 src/include/catalog/objectaddress.h    |   1 +
 src/include/catalog/pg_collation.h     |   1 -
 src/include/catalog/pg_conversion.h    |   1 -
 src/include/commands/defrem.h          |  13 --
 src/include/commands/event_trigger.h   |   1 -
 src/include/commands/proclang.h        |   1 -
 src/include/commands/publicationcmds.h |   1 -
 src/include/commands/schemacmds.h      |   2 -
 src/include/utils/acl.h                |   1 -
 23 files changed, 175 insertions(+), 619 deletions(-)

diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index cb2c4972ad..c626161408 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -1498,39 +1498,6 @@ RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid)
 }
 
 
-/*
- * Remove a pg_default_acl entry
- */
-void
-RemoveDefaultACLById(Oid defaclOid)
-{
-	Relation	rel;
-	ScanKeyData skey[1];
-	SysScanDesc scan;
-	HeapTuple	tuple;
-
-	rel = table_open(DefaultAclRelationId, RowExclusiveLock);
-
-	ScanKeyInit(&skey[0],
-				Anum_pg_default_acl_oid,
-				BTEqualStrategyNumber, F_OIDEQ,
-				ObjectIdGetDatum(defaclOid));
-
-	scan = systable_beginscan(rel, DefaultAclOidIndexId, true,
-							  NULL, 1, skey);
-
-	tuple = systable_getnext(scan);
-
-	if (!HeapTupleIsValid(tuple))
-		elog(ERROR, "could not find tuple for default ACL %u", defaclOid);
-
-	CatalogTupleDelete(rel, &tuple->t_self);
-
-	systable_endscan(scan);
-	table_close(rel, RowExclusiveLock);
-}
-
-
 /*
  * expand_col_privileges
  *
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index ffd52c1153..502d3684b4 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -66,9 +66,7 @@
 #include "commands/event_trigger.h"
 #include "commands/extension.h"
 #include "commands/policy.h"
-#include "commands/proclang.h"
 #include "commands/publicationcmds.h"
-#include "commands/schemacmds.h"
 #include "commands/seclabel.h"
 #include "commands/sequence.h"
 #include "commands/trigger.h"
@@ -1225,6 +1223,62 @@ reportDependentObjects(const ObjectAddresses *targetObjects,
 	pfree(logdetail.data);
 }
 
+/*
+ * Drop an object by OID.  Works for most catalogs, if no special processing
+ * is needed.
+ */
+static void
+DropObjectById(const ObjectAddress *object)
+{
+	int			cacheId;
+	Relation	rel;
+	HeapTuple	tup;
+
+	cacheId = get_object_catcache_oid(object->classId);
+
+	rel = table_open(object->classId, RowExclusiveLock);
+
+	/*
+	 * Use the system cache for the oid column, if one exists.
+	 */
+	if (cacheId >= 0)
+	{
+		tup = SearchSysCache1(cacheId, ObjectIdGetDatum(object->objectId));
+		if (!HeapTupleIsValid(tup))
+			elog(ERROR, "cache lookup failed for %s %u",
+				 get_object_class_descr(object->classId), object->objectId);
+
+		CatalogTupleDelete(rel, &tup->t_self);
+
+		ReleaseSysCache(tup);
+	}
+	else
+	{
+		ScanKeyData skey[1];
+		SysScanDesc scan;
+
+		ScanKeyInit(&skey[0],
+					get_object_attnum_oid(object->classId),
+					BTEqualStrategyNumber, F_OIDEQ,
+					ObjectIdGetDatum(object->objectId));
+
+		scan = systable_beginscan(rel, get_object_oid_index(object->classId), true,
+								  NULL, 1, skey);
+
+		/* we expect exactly one match */
+		tup = systable_getnext(scan);
+		if (!HeapTupleIsValid(tup))
+			elog(ERROR, "could not find tuple for %s %u",
+				 get_object_class_descr(object->classId), object->objectId);
+
+		CatalogTupleDelete(rel, &tup->t_self);
+
+		systable_endscan(scan);
+	}
+
+	table_close(rel, RowExclusiveLock);
+}
+
 /*
  * deleteOneObject: delete a single object for performDeletion.
  *
@@ -1378,30 +1432,14 @@ doDeletion(const ObjectAddress *object, int flags)
 			RemoveTypeById(object->objectId);
 			break;
 
-		case OCLASS_CAST:
-			DropCastById(object->objectId);
-			break;
-
-		case OCLASS_COLLATION:
-			RemoveCollationById(object->objectId);
-			break;
-
 		case OCLASS_CONSTRAINT:
 			RemoveConstraintById(object->objectId);
 			break;
 
-		case OCLASS_CONVERSION:
-			RemoveConversionById(object->objectId);
-			break;
-
 		case OCLASS_DEFAULT:
 			RemoveAttrDefaultById(object->objectId);
 			break;
 
-		case OCLASS_LANGUAGE:
-			DropProceduralLanguageById(object->objectId);
-			break;
-
 		case OCLASS_LARGEOBJECT:
 			LargeObjectDrop(object->objectId);
 			break;
@@ -1410,26 +1448,6 @@ doDeletion(const ObjectAddress *object, int flags)
 			RemoveOperatorById(object->objectId);
 			break;
 
-		case OCLASS_OPCLASS:
-			RemoveOpClassById(object->objectId);
-			break;
-
-		case OCLASS_OPFAMILY:
-			RemoveOpFamilyById(object->objectId);
-			break;
-
-		case OCLASS_AM:
-			RemoveAccessMethodById(object->objectId);
-			break;
-
-		case OCLASS_AMOP:
-			RemoveAmOpEntryById(object->objectId);
-			break;
-
-		case OCLASS_AMPROC:
-			RemoveAmProcEntryById(object->objectId);
-			break;
-
 		case OCLASS_REWRITE:
 			RemoveRewriteRuleById(object->objectId);
 			break;
@@ -1438,73 +1456,47 @@ doDeletion(const ObjectAddress *object, int flags)
 			RemoveTriggerById(object->objectId);
 			break;
 
-		case OCLASS_SCHEMA:
-			RemoveSchemaById(object->objectId);
-			break;
-
 		case OCLASS_STATISTIC_EXT:
 			RemoveStatisticsById(object->objectId);
 			break;
 
-		case OCLASS_TSPARSER:
-			RemoveTSParserById(object->objectId);
-			break;
-
-		case OCLASS_TSDICT:
-			RemoveTSDictionaryById(object->objectId);
-			break;
-
-		case OCLASS_TSTEMPLATE:
-			RemoveTSTemplateById(object->objectId);
-			break;
-
 		case OCLASS_TSCONFIG:
 			RemoveTSConfigurationById(object->objectId);
 			break;
 
-			/*
-			 * OCLASS_ROLE, OCLASS_DATABASE, OCLASS_TBLSPACE intentionally not
-			 * handled here
-			 */
-
-		case OCLASS_FDW:
-			RemoveForeignDataWrapperById(object->objectId);
-			break;
-
-		case OCLASS_FOREIGN_SERVER:
-			RemoveForeignServerById(object->objectId);
-			break;
-
-		case OCLASS_USER_MAPPING:
-			RemoveUserMappingById(object->objectId);
-			break;
-
-		case OCLASS_DEFACL:
-			RemoveDefaultACLById(object->objectId);
-			break;
-
 		case OCLASS_EXTENSION:
 			RemoveExtensionById(object->objectId);
 			break;
 
-		case OCLASS_EVENT_TRIGGER:
-			RemoveEventTriggerById(object->objectId);
-			break;
-
 		case OCLASS_POLICY:
 			RemovePolicyById(object->objectId);
 			break;
 
-		case OCLASS_PUBLICATION:
-			RemovePublicationById(object->objectId);
-			break;
-
 		case OCLASS_PUBLICATION_REL:
 			RemovePublicationRelById(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_PUBLICATION:
 		case OCLASS_TRANSFORM:
-			DropTransformById(object->objectId);
+			DropObjectById(object);
 			break;
 
 			/*
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index 84463f76fc..534df8e802 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -97,6 +97,7 @@
  */
 typedef struct
 {
+	const char *class_descr;	/* string describing the catalog, for internal error messages */
 	Oid			class_oid;		/* oid of catalog */
 	Oid			oid_index_oid;	/* oid of index on system oid column */
 	int			oid_catcache_id;	/* id of catcache on system oid column	*/
@@ -118,6 +119,7 @@ typedef struct
 static const ObjectPropertyType ObjectProperty[] =
 {
 	{
+		"access method",
 		AccessMethodRelationId,
 		AmOidIndexId,
 		AMOID,
@@ -131,6 +133,35 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"access method operator",
+		AccessMethodOperatorRelationId,
+		AccessMethodOperatorOidIndexId,
+		-1,
+		-1,
+		Anum_pg_amop_oid,
+		InvalidAttrNumber,
+		InvalidAttrNumber,
+		InvalidAttrNumber,
+		InvalidAttrNumber,
+		OBJECT_AMOP,
+		false
+	},
+	{
+		"access method procedure",
+		AccessMethodProcedureRelationId,
+		AccessMethodProcedureOidIndexId,
+		-1,
+		-1,
+		Anum_pg_amproc_oid,
+		InvalidAttrNumber,
+		InvalidAttrNumber,
+		InvalidAttrNumber,
+		InvalidAttrNumber,
+		OBJECT_AMPROC,
+		false
+	},
+	{
+		"cast",
 		CastRelationId,
 		CastOidIndexId,
 		-1,
@@ -144,6 +175,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		false
 	},
 	{
+		"collation",
 		CollationRelationId,
 		CollationOidIndexId,
 		COLLOID,
@@ -157,6 +189,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"constraint",
 		ConstraintRelationId,
 		ConstraintOidIndexId,
 		CONSTROID,
@@ -170,6 +203,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		false
 	},
 	{
+		"conversion",
 		ConversionRelationId,
 		ConversionOidIndexId,
 		CONVOID,
@@ -183,6 +217,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"database",
 		DatabaseRelationId,
 		DatabaseOidIndexId,
 		DATABASEOID,
@@ -196,6 +231,21 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"default ACL",
+		DefaultAclRelationId,
+		DefaultAclOidIndexId,
+		-1,
+		-1,
+		Anum_pg_default_acl_oid,
+		InvalidAttrNumber,
+		InvalidAttrNumber,
+		InvalidAttrNumber,
+		InvalidAttrNumber,
+		OBJECT_DEFACL,
+		false
+	},
+	{
+		"extension",
 		ExtensionRelationId,
 		ExtensionOidIndexId,
 		-1,
@@ -209,6 +259,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"foreign-data wrapper",
 		ForeignDataWrapperRelationId,
 		ForeignDataWrapperOidIndexId,
 		FOREIGNDATAWRAPPEROID,
@@ -222,6 +273,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"foreign server",
 		ForeignServerRelationId,
 		ForeignServerOidIndexId,
 		FOREIGNSERVEROID,
@@ -235,6 +287,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"function",
 		ProcedureRelationId,
 		ProcedureOidIndexId,
 		PROCOID,
@@ -248,6 +301,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		false
 	},
 	{
+		"language",
 		LanguageRelationId,
 		LanguageOidIndexId,
 		LANGOID,
@@ -261,6 +315,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"large object metadata",
 		LargeObjectMetadataRelationId,
 		LargeObjectMetadataOidIndexId,
 		-1,
@@ -274,6 +329,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		false
 	},
 	{
+		"operator class",
 		OperatorClassRelationId,
 		OpclassOidIndexId,
 		CLAOID,
@@ -287,6 +343,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"operator",
 		OperatorRelationId,
 		OperatorOidIndexId,
 		OPEROID,
@@ -300,6 +357,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		false
 	},
 	{
+		"operator family",
 		OperatorFamilyRelationId,
 		OpfamilyOidIndexId,
 		OPFAMILYOID,
@@ -313,6 +371,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"role",
 		AuthIdRelationId,
 		AuthIdOidIndexId,
 		AUTHOID,
@@ -326,6 +385,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"rule",
 		RewriteRelationId,
 		RewriteOidIndexId,
 		-1,
@@ -339,6 +399,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		false
 	},
 	{
+		"schema",
 		NamespaceRelationId,
 		NamespaceOidIndexId,
 		NAMESPACEOID,
@@ -352,6 +413,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"relation",
 		RelationRelationId,
 		ClassOidIndexId,
 		RELOID,
@@ -365,6 +427,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"tablespace",
 		TableSpaceRelationId,
 		TablespaceOidIndexId,
 		TABLESPACEOID,
@@ -378,6 +441,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"transform",
 		TransformRelationId,
 		TransformOidIndexId,
 		TRFOID,
@@ -385,6 +449,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		Anum_pg_transform_oid
 	},
 	{
+		"trigger",
 		TriggerRelationId,
 		TriggerOidIndexId,
 		-1,
@@ -398,6 +463,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		false
 	},
 	{
+		"policy",
 		PolicyRelationId,
 		PolicyOidIndexId,
 		-1,
@@ -411,6 +477,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		false
 	},
 	{
+		"event trigger",
 		EventTriggerRelationId,
 		EventTriggerOidIndexId,
 		EVENTTRIGGEROID,
@@ -424,6 +491,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"text search configuration",
 		TSConfigRelationId,
 		TSConfigOidIndexId,
 		TSCONFIGOID,
@@ -437,6 +505,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"text search dictionary",
 		TSDictionaryRelationId,
 		TSDictionaryOidIndexId,
 		TSDICTOID,
@@ -450,6 +519,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"text search parser",
 		TSParserRelationId,
 		TSParserOidIndexId,
 		TSPARSEROID,
@@ -463,6 +533,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"text search template",
 		TSTemplateRelationId,
 		TSTemplateOidIndexId,
 		TSTEMPLATEOID,
@@ -476,6 +547,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true,
 	},
 	{
+		"type",
 		TypeRelationId,
 		TypeOidIndexId,
 		TYPEOID,
@@ -489,6 +561,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"publication",
 		PublicationRelationId,
 		PublicationObjectIndexId,
 		PUBLICATIONOID,
@@ -502,6 +575,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"subscription",
 		SubscriptionRelationId,
 		SubscriptionObjectIndexId,
 		SUBSCRIPTIONOID,
@@ -515,6 +589,7 @@ static const ObjectPropertyType ObjectProperty[] =
 		true
 	},
 	{
+		"extented statistics",
 		StatisticExtRelationId,
 		StatisticExtOidIndexId,
 		STATEXTOID,
@@ -526,7 +601,21 @@ static const ObjectPropertyType ObjectProperty[] =
 		InvalidAttrNumber,		/* no ACL (same as relation) */
 		OBJECT_STATISTIC_EXT,
 		true
-	}
+	},
+	{
+		"user mapping",
+		UserMappingRelationId,
+		UserMappingOidIndexId,
+		USERMAPPINGOID,
+		-1,
+		Anum_pg_user_mapping_oid,
+		InvalidAttrNumber,
+		InvalidAttrNumber,
+		InvalidAttrNumber,
+		InvalidAttrNumber,
+		OBJECT_USER_MAPPING,
+		false
+	},
 };
 
 /*
@@ -2549,6 +2638,14 @@ read_objtype_from_string(const char *objtype)
 /*
  * Interfaces to reference fields of ObjectPropertyType
  */
+const char *
+get_object_class_descr(Oid class_id)
+{
+	const ObjectPropertyType *prop = get_object_property_data(class_id);
+
+	return prop->class_descr;
+}
+
 Oid
 get_object_oid_index(Oid class_id)
 {
diff --git a/src/backend/catalog/pg_collation.c b/src/backend/catalog/pg_collation.c
index 8559779a4f..5fdf1acb7e 100644
--- a/src/backend/catalog/pg_collation.c
+++ b/src/backend/catalog/pg_collation.c
@@ -203,39 +203,3 @@ CollationCreate(const char *collname, Oid collnamespace,
 
 	return oid;
 }
-
-/*
- * RemoveCollationById
- *
- * Remove a tuple from pg_collation by Oid. This function is solely
- * called inside catalog/dependency.c
- */
-void
-RemoveCollationById(Oid collationOid)
-{
-	Relation	rel;
-	ScanKeyData scanKeyData;
-	SysScanDesc scandesc;
-	HeapTuple	tuple;
-
-	rel = table_open(CollationRelationId, RowExclusiveLock);
-
-	ScanKeyInit(&scanKeyData,
-				Anum_pg_collation_oid,
-				BTEqualStrategyNumber, F_OIDEQ,
-				ObjectIdGetDatum(collationOid));
-
-	scandesc = systable_beginscan(rel, CollationOidIndexId, true,
-								  NULL, 1, &scanKeyData);
-
-	tuple = systable_getnext(scandesc);
-
-	if (HeapTupleIsValid(tuple))
-		CatalogTupleDelete(rel, &tuple->t_self);
-	else
-		elog(ERROR, "could not find tuple for collation %u", collationOid);
-
-	systable_endscan(scandesc);
-
-	table_close(rel, RowExclusiveLock);
-}
diff --git a/src/backend/catalog/pg_conversion.c b/src/backend/catalog/pg_conversion.c
index b38df4f696..28b676a1fa 100644
--- a/src/backend/catalog/pg_conversion.c
+++ b/src/backend/catalog/pg_conversion.c
@@ -142,39 +142,6 @@ ConversionCreate(const char *conname, Oid connamespace,
 	return myself;
 }
 
-/*
- * RemoveConversionById
- *
- * Remove a tuple from pg_conversion by Oid. This function is solely
- * called inside catalog/dependency.c
- */
-void
-RemoveConversionById(Oid conversionOid)
-{
-	Relation	rel;
-	HeapTuple	tuple;
-	TableScanDesc scan;
-	ScanKeyData scanKeyData;
-
-	ScanKeyInit(&scanKeyData,
-				Anum_pg_conversion_oid,
-				BTEqualStrategyNumber, F_OIDEQ,
-				ObjectIdGetDatum(conversionOid));
-
-	/* open pg_conversion */
-	rel = table_open(ConversionRelationId, RowExclusiveLock);
-
-	scan = table_beginscan_catalog(rel, 1, &scanKeyData);
-
-	/* search for the target tuple */
-	if (HeapTupleIsValid(tuple = heap_getnext(scan, ForwardScanDirection)))
-		CatalogTupleDelete(rel, &tuple->t_self);
-	else
-		elog(ERROR, "could not find tuple for conversion %u", conversionOid);
-	table_endscan(scan);
-	table_close(rel, RowExclusiveLock);
-}
-
 /*
  * FindDefaultConversion
  *
diff --git a/src/backend/commands/amcmds.c b/src/backend/commands/amcmds.c
index 7546378bbb..ebd0029562 100644
--- a/src/backend/commands/amcmds.c
+++ b/src/backend/commands/amcmds.c
@@ -112,33 +112,6 @@ CreateAccessMethod(CreateAmStmt *stmt)
 	return myself;
 }
 
-/*
- * Guts of access method deletion.
- */
-void
-RemoveAccessMethodById(Oid amOid)
-{
-	Relation	relation;
-	HeapTuple	tup;
-
-	if (!superuser())
-		ereport(ERROR,
-				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
-				 errmsg("must be superuser to drop access methods")));
-
-	relation = table_open(AccessMethodRelationId, RowExclusiveLock);
-
-	tup = SearchSysCache1(AMOID, ObjectIdGetDatum(amOid));
-	if (!HeapTupleIsValid(tup))
-		elog(ERROR, "cache lookup failed for access method %u", amOid);
-
-	CatalogTupleDelete(relation, &tup->t_self);
-
-	ReleaseSysCache(tup);
-
-	table_close(relation, RowExclusiveLock);
-}
-
 /*
  * get_am_type_oid
  *		Worker for various get_am_*_oid variants
diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c
index 91800d1fac..bf21bf77aa 100644
--- a/src/backend/commands/event_trigger.c
+++ b/src/backend/commands/event_trigger.c
@@ -361,28 +361,6 @@ filter_list_to_array(List *filterlist)
 										   -1, false, TYPALIGN_INT));
 }
 
-/*
- * Guts of event trigger deletion.
- */
-void
-RemoveEventTriggerById(Oid trigOid)
-{
-	Relation	tgrel;
-	HeapTuple	tup;
-
-	tgrel = table_open(EventTriggerRelationId, RowExclusiveLock);
-
-	tup = SearchSysCache1(EVENTTRIGGEROID, ObjectIdGetDatum(trigOid));
-	if (!HeapTupleIsValid(tup))
-		elog(ERROR, "cache lookup failed for event trigger %u", trigOid);
-
-	CatalogTupleDelete(tgrel, &tup->t_self);
-
-	ReleaseSysCache(tup);
-
-	table_close(tgrel, RowExclusiveLock);
-}
-
 /*
  * ALTER EVENT TRIGGER foo ENABLE|DISABLE|ENABLE ALWAYS|REPLICA
  */
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
index f197869752..81554b8b09 100644
--- a/src/backend/commands/foreigncmds.c
+++ b/src/backend/commands/foreigncmds.c
@@ -835,30 +835,6 @@ AlterForeignDataWrapper(AlterFdwStmt *stmt)
 }
 
 
-/*
- * Drop foreign-data wrapper by OID
- */
-void
-RemoveForeignDataWrapperById(Oid fdwId)
-{
-	HeapTuple	tp;
-	Relation	rel;
-
-	rel = table_open(ForeignDataWrapperRelationId, RowExclusiveLock);
-
-	tp = SearchSysCache1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdwId));
-
-	if (!HeapTupleIsValid(tp))
-		elog(ERROR, "cache lookup failed for foreign-data wrapper %u", fdwId);
-
-	CatalogTupleDelete(rel, &tp->t_self);
-
-	ReleaseSysCache(tp);
-
-	table_close(rel, RowExclusiveLock);
-}
-
-
 /*
  * Create a foreign server
  */
@@ -1085,30 +1061,6 @@ AlterForeignServer(AlterForeignServerStmt *stmt)
 }
 
 
-/*
- * Drop foreign server by OID
- */
-void
-RemoveForeignServerById(Oid srvId)
-{
-	HeapTuple	tp;
-	Relation	rel;
-
-	rel = table_open(ForeignServerRelationId, RowExclusiveLock);
-
-	tp = SearchSysCache1(FOREIGNSERVEROID, ObjectIdGetDatum(srvId));
-
-	if (!HeapTupleIsValid(tp))
-		elog(ERROR, "cache lookup failed for foreign server %u", srvId);
-
-	CatalogTupleDelete(rel, &tp->t_self);
-
-	ReleaseSysCache(tp);
-
-	table_close(rel, RowExclusiveLock);
-}
-
-
 /*
  * Common routine to check permission for user-mapping-related DDL
  * commands.  We allow server owners to operate on any mapping, and
@@ -1432,29 +1384,6 @@ RemoveUserMapping(DropUserMappingStmt *stmt)
 }
 
 
-/*
- * Drop user mapping by OID.  This is called to clean up dependencies.
- */
-void
-RemoveUserMappingById(Oid umId)
-{
-	HeapTuple	tp;
-	Relation	rel;
-
-	rel = table_open(UserMappingRelationId, RowExclusiveLock);
-
-	tp = SearchSysCache1(USERMAPPINGOID, ObjectIdGetDatum(umId));
-
-	if (!HeapTupleIsValid(tp))
-		elog(ERROR, "cache lookup failed for user mapping %u", umId);
-
-	CatalogTupleDelete(rel, &tp->t_self);
-
-	ReleaseSysCache(tp);
-
-	table_close(rel, RowExclusiveLock);
-}
-
 /*
  * Create a foreign table
  * call after DefineRelation().
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 694114aded..c40012abd8 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -1646,32 +1646,6 @@ CreateCast(CreateCastStmt *stmt)
 	return myself;
 }
 
-void
-DropCastById(Oid castOid)
-{
-	Relation	relation;
-	ScanKeyData scankey;
-	SysScanDesc scan;
-	HeapTuple	tuple;
-
-	relation = table_open(CastRelationId, RowExclusiveLock);
-
-	ScanKeyInit(&scankey,
-				Anum_pg_cast_oid,
-				BTEqualStrategyNumber, F_OIDEQ,
-				ObjectIdGetDatum(castOid));
-	scan = systable_beginscan(relation, CastOidIndexId, true,
-							  NULL, 1, &scankey);
-
-	tuple = systable_getnext(scan);
-	if (!HeapTupleIsValid(tuple))
-		elog(ERROR, "could not find tuple for cast %u", castOid);
-	CatalogTupleDelete(relation, &tuple->t_self);
-
-	systable_endscan(scan);
-	table_close(relation, RowExclusiveLock);
-}
-
 
 static void
 check_transform_function(Form_pg_proc procstruct)
@@ -1933,33 +1907,6 @@ get_transform_oid(Oid type_id, Oid lang_id, bool missing_ok)
 }
 
 
-void
-DropTransformById(Oid transformOid)
-{
-	Relation	relation;
-	ScanKeyData scankey;
-	SysScanDesc scan;
-	HeapTuple	tuple;
-
-	relation = table_open(TransformRelationId, RowExclusiveLock);
-
-	ScanKeyInit(&scankey,
-				Anum_pg_transform_oid,
-				BTEqualStrategyNumber, F_OIDEQ,
-				ObjectIdGetDatum(transformOid));
-	scan = systable_beginscan(relation, TransformOidIndexId, true,
-							  NULL, 1, &scankey);
-
-	tuple = systable_getnext(scan);
-	if (!HeapTupleIsValid(tuple))
-		elog(ERROR, "could not find tuple for transform %u", transformOid);
-	CatalogTupleDelete(relation, &tuple->t_self);
-
-	systable_endscan(scan);
-	table_close(relation, RowExclusiveLock);
-}
-
-
 /*
  * Subroutine for ALTER FUNCTION/AGGREGATE SET SCHEMA/RENAME
  *
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index 7322cbc154..36204808be 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -1656,105 +1656,6 @@ dropProcedures(List *opfamilyname, Oid amoid, Oid opfamilyoid,
 	}
 }
 
-/*
- * Deletion subroutines for use by dependency.c.
- */
-void
-RemoveOpFamilyById(Oid opfamilyOid)
-{
-	Relation	rel;
-	HeapTuple	tup;
-
-	rel = table_open(OperatorFamilyRelationId, RowExclusiveLock);
-
-	tup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfamilyOid));
-	if (!HeapTupleIsValid(tup)) /* should not happen */
-		elog(ERROR, "cache lookup failed for opfamily %u", opfamilyOid);
-
-	CatalogTupleDelete(rel, &tup->t_self);
-
-	ReleaseSysCache(tup);
-
-	table_close(rel, RowExclusiveLock);
-}
-
-void
-RemoveOpClassById(Oid opclassOid)
-{
-	Relation	rel;
-	HeapTuple	tup;
-
-	rel = table_open(OperatorClassRelationId, RowExclusiveLock);
-
-	tup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclassOid));
-	if (!HeapTupleIsValid(tup)) /* should not happen */
-		elog(ERROR, "cache lookup failed for opclass %u", opclassOid);
-
-	CatalogTupleDelete(rel, &tup->t_self);
-
-	ReleaseSysCache(tup);
-
-	table_close(rel, RowExclusiveLock);
-}
-
-void
-RemoveAmOpEntryById(Oid entryOid)
-{
-	Relation	rel;
-	HeapTuple	tup;
-	ScanKeyData skey[1];
-	SysScanDesc scan;
-
-	ScanKeyInit(&skey[0],
-				Anum_pg_amop_oid,
-				BTEqualStrategyNumber, F_OIDEQ,
-				ObjectIdGetDatum(entryOid));
-
-	rel = table_open(AccessMethodOperatorRelationId, RowExclusiveLock);
-
-	scan = systable_beginscan(rel, AccessMethodOperatorOidIndexId, true,
-							  NULL, 1, skey);
-
-	/* we expect exactly one match */
-	tup = systable_getnext(scan);
-	if (!HeapTupleIsValid(tup))
-		elog(ERROR, "could not find tuple for amop entry %u", entryOid);
-
-	CatalogTupleDelete(rel, &tup->t_self);
-
-	systable_endscan(scan);
-	table_close(rel, RowExclusiveLock);
-}
-
-void
-RemoveAmProcEntryById(Oid entryOid)
-{
-	Relation	rel;
-	HeapTuple	tup;
-	ScanKeyData skey[1];
-	SysScanDesc scan;
-
-	ScanKeyInit(&skey[0],
-				Anum_pg_amproc_oid,
-				BTEqualStrategyNumber, F_OIDEQ,
-				ObjectIdGetDatum(entryOid));
-
-	rel = table_open(AccessMethodProcedureRelationId, RowExclusiveLock);
-
-	scan = systable_beginscan(rel, AccessMethodProcedureOidIndexId, true,
-							  NULL, 1, skey);
-
-	/* we expect exactly one match */
-	tup = systable_getnext(scan);
-	if (!HeapTupleIsValid(tup))
-		elog(ERROR, "could not find tuple for amproc entry %u", entryOid);
-
-	CatalogTupleDelete(rel, &tup->t_self);
-
-	systable_endscan(scan);
-	table_close(rel, RowExclusiveLock);
-}
-
 /*
  * Subroutine for ALTER OPERATOR CLASS SET SCHEMA/RENAME
  *
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index 21ceeb7e9a..14153426bd 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -218,28 +218,6 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
 	return myself;
 }
 
-/*
- * Guts of language dropping.
- */
-void
-DropProceduralLanguageById(Oid langOid)
-{
-	Relation	rel;
-	HeapTuple	langTup;
-
-	rel = table_open(LanguageRelationId, RowExclusiveLock);
-
-	langTup = SearchSysCache1(LANGOID, ObjectIdGetDatum(langOid));
-	if (!HeapTupleIsValid(langTup)) /* should not happen */
-		elog(ERROR, "cache lookup failed for language %u", langOid);
-
-	CatalogTupleDelete(rel, &langTup->t_self);
-
-	ReleaseSysCache(langTup);
-
-	table_close(rel, RowExclusiveLock);
-}
-
 /*
  * get_language_oid - given a language name, look up the OID
  *
diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c
index 771268f70a..4d36976146 100644
--- a/src/backend/commands/publicationcmds.c
+++ b/src/backend/commands/publicationcmds.c
@@ -468,29 +468,6 @@ AlterPublication(AlterPublicationStmt *stmt)
 	table_close(rel, RowExclusiveLock);
 }
 
-/*
- * Drop publication by OID
- */
-void
-RemovePublicationById(Oid pubid)
-{
-	Relation	rel;
-	HeapTuple	tup;
-
-	rel = table_open(PublicationRelationId, RowExclusiveLock);
-
-	tup = SearchSysCache1(PUBLICATIONOID, ObjectIdGetDatum(pubid));
-
-	if (!HeapTupleIsValid(tup))
-		elog(ERROR, "cache lookup failed for publication %u", pubid);
-
-	CatalogTupleDelete(rel, &tup->t_self);
-
-	ReleaseSysCache(tup);
-
-	table_close(rel, RowExclusiveLock);
-}
-
 /*
  * Remove relation from publication by mapping OID.
  */
diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c
index 1e6e731eb5..3013862528 100644
--- a/src/backend/commands/schemacmds.c
+++ b/src/backend/commands/schemacmds.c
@@ -210,29 +210,6 @@ CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString,
 	return namespaceId;
 }
 
-/*
- * Guts of schema deletion.
- */
-void
-RemoveSchemaById(Oid schemaOid)
-{
-	Relation	relation;
-	HeapTuple	tup;
-
-	relation = table_open(NamespaceRelationId, RowExclusiveLock);
-
-	tup = SearchSysCache1(NAMESPACEOID,
-						  ObjectIdGetDatum(schemaOid));
-	if (!HeapTupleIsValid(tup)) /* should not happen */
-		elog(ERROR, "cache lookup failed for namespace %u", schemaOid);
-
-	CatalogTupleDelete(relation, &tup->t_self);
-
-	ReleaseSysCache(tup);
-
-	table_close(relation, RowExclusiveLock);
-}
-
 
 /*
  * Rename schema
diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c
index 9da8f7fd57..319a62012e 100644
--- a/src/backend/commands/tsearchcmds.c
+++ b/src/backend/commands/tsearchcmds.c
@@ -291,29 +291,6 @@ DefineTSParser(List *names, List *parameters)
 	return address;
 }
 
-/*
- * Guts of TS parser deletion.
- */
-void
-RemoveTSParserById(Oid prsId)
-{
-	Relation	relation;
-	HeapTuple	tup;
-
-	relation = table_open(TSParserRelationId, RowExclusiveLock);
-
-	tup = SearchSysCache1(TSPARSEROID, ObjectIdGetDatum(prsId));
-
-	if (!HeapTupleIsValid(tup))
-		elog(ERROR, "cache lookup failed for text search parser %u", prsId);
-
-	CatalogTupleDelete(relation, &tup->t_self);
-
-	ReleaseSysCache(tup);
-
-	table_close(relation, RowExclusiveLock);
-}
-
 /* ---------------------- TS Dictionary commands -----------------------*/
 
 /*
@@ -504,30 +481,6 @@ DefineTSDictionary(List *names, List *parameters)
 	return address;
 }
 
-/*
- * Guts of TS dictionary deletion.
- */
-void
-RemoveTSDictionaryById(Oid dictId)
-{
-	Relation	relation;
-	HeapTuple	tup;
-
-	relation = table_open(TSDictionaryRelationId, RowExclusiveLock);
-
-	tup = SearchSysCache1(TSDICTOID, ObjectIdGetDatum(dictId));
-
-	if (!HeapTupleIsValid(tup))
-		elog(ERROR, "cache lookup failed for text search dictionary %u",
-			 dictId);
-
-	CatalogTupleDelete(relation, &tup->t_self);
-
-	ReleaseSysCache(tup);
-
-	table_close(relation, RowExclusiveLock);
-}
-
 /*
  * ALTER TEXT SEARCH DICTIONARY
  */
@@ -820,30 +773,6 @@ DefineTSTemplate(List *names, List *parameters)
 	return address;
 }
 
-/*
- * Guts of TS template deletion.
- */
-void
-RemoveTSTemplateById(Oid tmplId)
-{
-	Relation	relation;
-	HeapTuple	tup;
-
-	relation = table_open(TSTemplateRelationId, RowExclusiveLock);
-
-	tup = SearchSysCache1(TSTEMPLATEOID, ObjectIdGetDatum(tmplId));
-
-	if (!HeapTupleIsValid(tup))
-		elog(ERROR, "cache lookup failed for text search template %u",
-			 tmplId);
-
-	CatalogTupleDelete(relation, &tup->t_self);
-
-	ReleaseSysCache(tup);
-
-	table_close(relation, RowExclusiveLock);
-}
-
 /* ---------------------- TS Configuration commands -----------------------*/
 
 /*
diff --git a/src/include/catalog/objectaddress.h b/src/include/catalog/objectaddress.h
index 7f15efd58a..144715d4f4 100644
--- a/src/include/catalog/objectaddress.h
+++ b/src/include/catalog/objectaddress.h
@@ -55,6 +55,7 @@ extern void check_object_ownership(Oid roleid,
 extern Oid	get_object_namespace(const ObjectAddress *address);
 
 extern bool is_objectclass_supported(Oid class_id);
+extern const char *get_object_class_descr(Oid class_id);
 extern Oid	get_object_oid_index(Oid class_id);
 extern int	get_object_catcache_oid(Oid class_id);
 extern int	get_object_catcache_name(Oid class_id);
diff --git a/src/include/catalog/pg_collation.h b/src/include/catalog/pg_collation.h
index 6955bb1273..27618b324d 100644
--- a/src/include/catalog/pg_collation.h
+++ b/src/include/catalog/pg_collation.h
@@ -68,6 +68,5 @@ extern Oid	CollationCreate(const char *collname, Oid collnamespace,
 							const char *collversion,
 							bool if_not_exists,
 							bool quiet);
-extern void RemoveCollationById(Oid collationOid);
 
 #endif							/* PG_COLLATION_H */
diff --git a/src/include/catalog/pg_conversion.h b/src/include/catalog/pg_conversion.h
index 0e7f13e1b6..cd80a042ff 100644
--- a/src/include/catalog/pg_conversion.h
+++ b/src/include/catalog/pg_conversion.h
@@ -65,7 +65,6 @@ extern ObjectAddress ConversionCreate(const char *conname, Oid connamespace,
 									  Oid conowner,
 									  int32 conforencoding, int32 contoencoding,
 									  Oid conproc, bool def);
-extern void RemoveConversionById(Oid conversionOid);
 extern Oid	FindDefaultConversion(Oid connamespace, int32 for_encoding,
 								  int32 to_encoding);
 
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index c77c9a6ed5..c26a102b17 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -56,9 +56,7 @@ extern ObjectAddress CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt
 extern void RemoveFunctionById(Oid funcOid);
 extern ObjectAddress AlterFunction(ParseState *pstate, AlterFunctionStmt *stmt);
 extern ObjectAddress CreateCast(CreateCastStmt *stmt);
-extern void DropCastById(Oid castOid);
 extern ObjectAddress CreateTransform(CreateTransformStmt *stmt);
-extern void DropTransformById(Oid transformOid);
 extern void IsThereFunctionInNamespace(const char *proname, int pronargs,
 									   oidvector *proargtypes, Oid nspOid);
 extern void ExecuteDoStmt(DoStmt *stmt, bool atomic);
@@ -98,10 +96,6 @@ extern ObjectAddress DefineAggregate(ParseState *pstate, List *name, List *args,
 extern ObjectAddress DefineOpClass(CreateOpClassStmt *stmt);
 extern ObjectAddress DefineOpFamily(CreateOpFamilyStmt *stmt);
 extern Oid	AlterOpFamily(AlterOpFamilyStmt *stmt);
-extern void RemoveOpClassById(Oid opclassOid);
-extern void RemoveOpFamilyById(Oid opfamilyOid);
-extern void RemoveAmOpEntryById(Oid entryOid);
-extern void RemoveAmProcEntryById(Oid entryOid);
 extern void IsThereOpClassInNamespace(const char *opcname, Oid opcmethod,
 									  Oid opcnamespace);
 extern void IsThereOpFamilyInNamespace(const char *opfname, Oid opfmethod,
@@ -111,14 +105,11 @@ extern Oid	get_opfamily_oid(Oid amID, List *opfamilyname, bool missing_ok);
 
 /* commands/tsearchcmds.c */
 extern ObjectAddress DefineTSParser(List *names, List *parameters);
-extern void RemoveTSParserById(Oid prsId);
 
 extern ObjectAddress DefineTSDictionary(List *names, List *parameters);
-extern void RemoveTSDictionaryById(Oid dictId);
 extern ObjectAddress AlterTSDictionary(AlterTSDictionaryStmt *stmt);
 
 extern ObjectAddress DefineTSTemplate(List *names, List *parameters);
-extern void RemoveTSTemplateById(Oid tmplId);
 
 extern ObjectAddress DefineTSConfiguration(List *names, List *parameters,
 										   ObjectAddress *copied);
@@ -135,14 +126,11 @@ extern ObjectAddress AlterForeignDataWrapperOwner(const char *name, Oid newOwner
 extern void AlterForeignDataWrapperOwner_oid(Oid fwdId, Oid newOwnerId);
 extern ObjectAddress CreateForeignDataWrapper(CreateFdwStmt *stmt);
 extern ObjectAddress AlterForeignDataWrapper(AlterFdwStmt *stmt);
-extern void RemoveForeignDataWrapperById(Oid fdwId);
 extern ObjectAddress CreateForeignServer(CreateForeignServerStmt *stmt);
 extern ObjectAddress AlterForeignServer(AlterForeignServerStmt *stmt);
-extern void RemoveForeignServerById(Oid srvId);
 extern ObjectAddress CreateUserMapping(CreateUserMappingStmt *stmt);
 extern ObjectAddress AlterUserMapping(AlterUserMappingStmt *stmt);
 extern Oid	RemoveUserMapping(DropUserMappingStmt *stmt);
-extern void RemoveUserMappingById(Oid umId);
 extern void CreateForeignTable(CreateForeignTableStmt *stmt, Oid relid);
 extern void ImportForeignSchema(ImportForeignSchemaStmt *stmt);
 extern Datum transformGenericOptions(Oid catalogId,
@@ -152,7 +140,6 @@ extern Datum transformGenericOptions(Oid catalogId,
 
 /* commands/amcmds.c */
 extern ObjectAddress CreateAccessMethod(CreateAmStmt *stmt);
-extern void RemoveAccessMethodById(Oid amOid);
 extern Oid	get_index_am_oid(const char *amname, bool missing_ok);
 extern Oid	get_table_am_oid(const char *amname, bool missing_ok);
 extern Oid	get_am_oid(const char *amname, bool missing_ok);
diff --git a/src/include/commands/event_trigger.h b/src/include/commands/event_trigger.h
index 28b352051b..407fd6a978 100644
--- a/src/include/commands/event_trigger.h
+++ b/src/include/commands/event_trigger.h
@@ -41,7 +41,6 @@ typedef struct EventTriggerData
 	((fcinfo)->context != NULL && IsA((fcinfo)->context, EventTriggerData))
 
 extern Oid	CreateEventTrigger(CreateEventTrigStmt *stmt);
-extern void RemoveEventTriggerById(Oid trigOid);
 extern Oid	get_event_trigger_oid(const char *trigname, bool missing_ok);
 
 extern Oid	AlterEventTrigger(AlterEventTrigStmt *stmt);
diff --git a/src/include/commands/proclang.h b/src/include/commands/proclang.h
index c70f8ec928..d566a121f0 100644
--- a/src/include/commands/proclang.h
+++ b/src/include/commands/proclang.h
@@ -17,7 +17,6 @@
 #include "nodes/parsenodes.h"
 
 extern ObjectAddress CreateProceduralLanguage(CreatePLangStmt *stmt);
-extern void DropProceduralLanguageById(Oid langOid);
 
 extern Oid	get_language_oid(const char *langname, bool missing_ok);
 
diff --git a/src/include/commands/publicationcmds.h b/src/include/commands/publicationcmds.h
index e713df0c31..c6b286245f 100644
--- a/src/include/commands/publicationcmds.h
+++ b/src/include/commands/publicationcmds.h
@@ -20,7 +20,6 @@
 
 extern ObjectAddress CreatePublication(CreatePublicationStmt *stmt);
 extern void AlterPublication(AlterPublicationStmt *stmt);
-extern void RemovePublicationById(Oid pubid);
 extern void RemovePublicationRelById(Oid proid);
 
 extern ObjectAddress AlterPublicationOwner(const char *name, Oid newOwnerId);
diff --git a/src/include/commands/schemacmds.h b/src/include/commands/schemacmds.h
index ac88a35399..e0139a8ea6 100644
--- a/src/include/commands/schemacmds.h
+++ b/src/include/commands/schemacmds.h
@@ -22,8 +22,6 @@ extern Oid	CreateSchemaCommand(CreateSchemaStmt *parsetree,
 								const char *queryString,
 								int stmt_location, int stmt_len);
 
-extern void RemoveSchemaById(Oid schemaOid);
-
 extern ObjectAddress RenameSchema(const char *oldname, const char *newname);
 extern ObjectAddress AlterSchemaOwner(const char *name, Oid newOwnerId);
 extern void AlterSchemaOwner_oid(Oid schemaOid, Oid newOwnerId);
diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h
index 732aa01dad..b263d92903 100644
--- a/src/include/utils/acl.h
+++ b/src/include/utils/acl.h
@@ -230,7 +230,6 @@ extern void ExecuteGrantStmt(GrantStmt *stmt);
 extern void ExecAlterDefaultPrivilegesStmt(ParseState *pstate, AlterDefaultPrivilegesStmt *stmt);
 
 extern void RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid);
-extern void RemoveDefaultACLById(Oid defaclOid);
 
 extern AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attnum,
 									Oid roleid, AclMode mask, AclMaskHow how);
-- 
2.26.2

#8Robert Haas
robertmhaas@gmail.com
In reply to: Ranier Vilela (#4)
Re: Unify drop-by-OID functions

On Fri, May 1, 2020 at 5:32 PM Ranier Vilela <ranier.vf@gmail.com> wrote:

I can suggest improvements?

1. In case Object is cached, delay open_table until the last moment, for the row to be blocked as little as possible and close the table as quickly as possible.
2. In case Object is cached and the tuple is invalid, do not open table.
3. Otherwise, is it possible to call systable_endscan, after table_close?

I think that lock resources, for as little time as possible, it is an advantage..

Only if it's correct, which (3) definitely wouldn't be, and I'm
doubtful about (1) as well.

This reminds me: I think that the issues in
/messages/by-id/CA+TgmoYaFYRRdRZ94p_Qdt+1oONg6sMOvbkGHKVsFtONCrFkhw@mail.gmail.com
should be considered here - we should guarantee that there's a
snapshot registered continuously from before the call to
SearchSysCache1 until after the call to CatalogTupleDelete. In the
systable_beginscan case, we should be fine as long as the
systable_endscan follows the CatalogTupleDelete call.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

#9Ranier Vilela
ranier.vf@gmail.com
In reply to: Robert Haas (#8)
Re: Unify drop-by-OID functions

Em ter., 5 de mai. de 2020 às 13:06, Robert Haas <robertmhaas@gmail.com>
escreveu:

On Fri, May 1, 2020 at 5:32 PM Ranier Vilela <ranier.vf@gmail.com> wrote:

I can suggest improvements?

1. In case Object is cached, delay open_table until the last moment, for

the row to be blocked as little as possible and close the table as quickly
as possible.

2. In case Object is cached and the tuple is invalid, do not open table.
3. Otherwise, is it possible to call systable_endscan, after table_close?

I think that lock resources, for as little time as possible, it is an

advantage..

Only if it's correct, which (3) definitely wouldn't be, and I'm
doubtful about (1) as well.

Ok, so the question. If (3) is not safe, obvious we shouldn't use, and must
call table_close, after systable_endscan.
Now (1) and (2), I would have no hesitation in using it.
I work with ERP, and throughout the time, the later, lock resources and
release them soon, the better, for the performance of the system as a whole.
Even if it doesn't make much difference locally, using this process,
throughout the system, efficiency is noticeable.
Apparently, it is more code, but it is less resources used and for less
time.
And (2), if it is a case, frequently, no table would be blocked in this
function.

Simple examples.

Exemple 1:
FILE * f;
f = fopen("data.txt", "r");
if (f != NULL) {
char buf[512];
size_t result;
result = fread(&buf, sizeof(char), 512, f);
fclose(f); // we no longer need the resource, release.
if (result != 0) {
process(buf);
printf("buf=%s\n", buf);
}
}

Exemple 2:
FILE * f;
f = fopen("data.txt", "r");
if (f != NULL) {
char buf[512];
size_t result;
result = fread(&buf, sizeof(char), 512, f);
if (result != 0) {
process(buf);
printf("buf=%s\n", buf);
}
fclose(f); // resource blocked until the end.
}

regards,
Ranier Vilela

#10Robert Haas
robertmhaas@gmail.com
In reply to: Ranier Vilela (#9)
Re: Unify drop-by-OID functions

On Tue, May 5, 2020 at 1:22 PM Ranier Vilela <ranier.vf@gmail.com> wrote:

Ok, so the question. If (3) is not safe, obvious we shouldn't use, and must call table_close, after systable_endscan.
Now (1) and (2), I would have no hesitation in using it.
I work with ERP, and throughout the time, the later, lock resources and release them soon, the better, for the performance of the system as a whole.
Even if it doesn't make much difference locally, using this process, throughout the system, efficiency is noticeable.
Apparently, it is more code, but it is less resources used and for less time.
And (2), if it is a case, frequently, no table would be blocked in this function.

Nobody here is going to question the concept that it's better to use
resources for less time rather than more, but the wisdom of sticking
to well-established coding patterns instead of inventing altogether
new ones is also well-understood. There are often good reasons why the
code is written in the way that it is, and it's important to
understand those before proposing to change things.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

#11Ranier Vilela
ranier.vf@gmail.com
In reply to: Robert Haas (#10)
Re: Unify drop-by-OID functions

Em ter., 5 de mai. de 2020 às 14:29, Robert Haas <robertmhaas@gmail.com>
escreveu:

On Tue, May 5, 2020 at 1:22 PM Ranier Vilela <ranier.vf@gmail.com> wrote:

Ok, so the question. If (3) is not safe, obvious we shouldn't use, and

must call table_close, after systable_endscan.

Now (1) and (2), I would have no hesitation in using it.
I work with ERP, and throughout the time, the later, lock resources and

release them soon, the better, for the performance of the system as a whole.

Even if it doesn't make much difference locally, using this process,

throughout the system, efficiency is noticeable.

Apparently, it is more code, but it is less resources used and for less

time.

And (2), if it is a case, frequently, no table would be blocked in this

function.

Nobody here is going to question the concept that it's better to use
resources for less time rather than more, but the wisdom of sticking
to well-established coding patterns instead of inventing altogether
new ones is also well-understood. There are often good reasons why the
code is written in the way that it is, and it's important to
understand those before proposing to change things.

I see, the famous "cliché".

regards,
Ranier Vilela

Show quoted text

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

#12Robert Haas
robertmhaas@gmail.com
In reply to: Ranier Vilela (#11)
Re: Unify drop-by-OID functions

On Tue, May 5, 2020 at 1:43 PM Ranier Vilela <ranier.vf@gmail.com> wrote:

I see, the famous "cliché".

By using the word cliché, and by putting it in quotes, you seem to
suggest that you consider my argument dubious. However, I stand by it.
Code shouldn't be changed without understanding the reasons behind the
current coding. Doing so very often breaks things.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

#13Ranier Vilela
ranier.vf@gmail.com
In reply to: Robert Haas (#12)
Re: Unify drop-by-OID functions

Em ter., 5 de mai. de 2020 às 14:57, Robert Haas <robertmhaas@gmail.com>
escreveu:

On Tue, May 5, 2020 at 1:43 PM Ranier Vilela <ranier.vf@gmail.com> wrote:

I see, the famous "cliché".

By using the word cliché, and by putting it in quotes, you seem to
suggest that you consider my argument dubious. However, I stand by it.
Code shouldn't be changed without understanding the reasons behind the
current coding. Doing so very often breaks things.

Sorry Robert, It was not my intention. I didn't know that using quotes
would change your understanding.
Of course, I find your arguments very valid and valuable.
And I understand that there are many interrelated things, which can break
if done in the wrong order.
Maybe I used the wrong word, in this case, the cliché.
What I mean is, the cliché, does some strange things, like leaving
variables to be declared, assigned in and not used.
And in that specific case, leaving resources blocked, which perhaps, in my
humble opinion, could be released quickly.
I think the expected behavior is being the same, with the changes I
proposed, IMHO.

+static void
+DropObjectById(const ObjectAddress *object)
+{
+ int cacheId;
+ Relation rel;
+ HeapTuple tup;
+
+ cacheId = get_object_catcache_oid(object->classId);
+
+ /*
+ * Use the system cache for the oid column, if one exists.
+ */
+ if (cacheId >= 0)
+ {
+ tup = SearchSysCache1(cacheId, ObjectIdGetDatum(object->objectId));
+ if (!HeapTupleIsValid(tup))
+ elog(ERROR, "cache lookup failed for %s %u",
+ get_object_class_descr(object->classId), object->objectId);
+
+    rel = table_open(object->classId, RowExclusiveLock);
+ CatalogTupleDelete(rel, &tup->t_self);
+    table_close(rel, RowExclusiveLock);
+
+ ReleaseSysCache(tup);
+ }
+ else
+ {
+ ScanKeyData skey[1];
+ SysScanDesc scan;
+
+ ScanKeyInit(&skey[0],
+ get_object_attnum_oid(object->classId),
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(object->objectId));
+
+    rel = table_open(object->classId, RowExclusiveLock);
+ scan = systable_beginscan(rel, get_object_oid_index(object->classId),
true,
+  NULL, 1, skey);
+
+ /* we expect exactly one match */
+ tup = systable_getnext(scan);
+ if (!HeapTupleIsValid(tup))
+ elog(ERROR, "could not find tuple for %s %u",
+ get_object_class_descr(object->classId), object->objectId);
+
+ CatalogTupleDelete(rel, &tup->t_self);
+ systable_endscan(scan);
+
+    table_close(rel, RowExclusiveLock);
+ }
+}

And again, your opinion is very important to me.

best regards,
Ranier Vilela

#14Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Ranier Vilela (#13)
Re: Unify drop-by-OID functions

On 2020-May-05, Ranier Vilela wrote:

And in that specific case, leaving resources blocked, which perhaps, in my
humble opinion, could be released quickly.

I very much doubt that you can measure any difference at all between
these two codings of the function.

I agree with the principle you mention, of not holding resources for
long if they can be released earlier; but in this case the table_close
call occurs across a ReleaseSysCache() call, which is hardly of
significance. It's not like you have to wait for some other
transaction, or wait for I/O, or anything like that that would make it
measurable.

--
�lvaro Herrera https://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

#15Ranier Vilela
ranier.vf@gmail.com
In reply to: Alvaro Herrera (#14)
Re: Unify drop-by-OID functions

Em ter., 5 de mai. de 2020 às 18:11, Alvaro Herrera <
alvherre@2ndquadrant.com> escreveu:

On 2020-May-05, Ranier Vilela wrote:

And in that specific case, leaving resources blocked, which perhaps, in

my

humble opinion, could be released quickly.

I very much doubt that you can measure any difference at all between
these two codings of the function.

I agree with the principle you mention, of not holding resources for
long if they can be released earlier; but in this case the table_close
call occurs across a ReleaseSysCache() call, which is hardly of
significance. It's not like you have to wait for some other
transaction, or wait for I/O, or anything like that that would make it
measurable.

Locally it may not be as efficient, but it is a question, to follow the
good programming practices, among them, not to break anything, not to
block, and if it is not possible, release soon.
In at least one case, there will not even be a block, which is an
improvement.

Another version, that could, be, without using ERROR.

+static void
+DropObjectById(const ObjectAddress *object)
+{
+ int cacheId;
+ Relation rel;
+ HeapTuple tup;
+
+ cacheId = get_object_catcache_oid(object->classId);
+
+ /*
+ * Use the system cache for the oid column, if one exists.
+ */
+ if (cacheId >= 0)
+ {
+ tup = SearchSysCache1(cacheId, ObjectIdGetDatum(object->objectId));
+ if (HeapTupleIsValid(tup)) {
+        rel = table_open(object->classId, RowExclusiveLock);
+    CatalogTupleDelete(rel, &tup->t_self);
+        table_close(rel, RowExclusiveLock);
+    ReleaseSysCache(tup);
+       }
+       else
+ elog(LOG, "cache lookup failed for %s %u",
+ get_object_class_descr(object->classId), object->objectId);
+ }
+ else
+ {
+ ScanKeyData skey[1];
+ SysScanDesc scan;
+
+ ScanKeyInit(&skey[0],
+ get_object_attnum_oid(object->classId),
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(object->objectId));
+
+    rel = table_open(object->classId, RowExclusiveLock);
+ scan = systable_beginscan(rel, get_object_oid_index(object->classId),
true,
+  NULL, 1, skey);
+
+ /* we expect exactly one match */
+ tup = systable_getnext(scan);
+ if (HeapTupleIsValid(tup))
+    CatalogTupleDelete(rel, &tup->t_self);
+       else
+ elog(LOG, "could not find tuple for %s %u",
+ get_object_class_descr(object->classId), object->objectId);
+
+    systable_endscan(scan);
+    table_close(rel, RowExclusiveLock);
+ }
+}
+

regards,
Ranier Vilela

#16Ranier Vilela
ranier.vf@gmail.com
In reply to: Ranier Vilela (#15)
Re: Unify drop-by-OID functions

Only as a homework, is this function completely useless?

ItemPointerData
systable_scan_next(Relation heapRelation,
Oid indexId,
bool indexOK,
Snapshot snapshot,
int nkeys, ScanKey key)
{
SysScanDesc scan;
HeapTuple htup;
ItemPointerData tid;

scan = systable_beginscan(heapRelation, indexId, indexOK, snapshot,
nkeys, key);
htup = systable_getnext(scan);
if (HeapTupleIsValid(htup))
tid = &htup->t_self;
else
tid = NULL;
systable_endscan(scan);

return tid;
}

regards,
Ranier Vilela

#17Peter Eisentraut
peter.eisentraut@2ndquadrant.com
In reply to: Peter Eisentraut (#7)
Re: Unify drop-by-OID functions

On 2020-05-04 20:57, Peter Eisentraut wrote:

New patch attached. I'll park it until PG14 opens.

committed

--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

#18Peter Eisentraut
peter.eisentraut@2ndquadrant.com
In reply to: Robert Haas (#8)
Re: Unify drop-by-OID functions

On 2020-05-05 18:05, Robert Haas wrote:

This reminds me: I think that the issues in
/messages/by-id/CA+TgmoYaFYRRdRZ94p_Qdt+1oONg6sMOvbkGHKVsFtONCrFkhw@mail.gmail.com
should be considered here - we should guarantee that there's a
snapshot registered continuously from before the call to
SearchSysCache1 until after the call to CatalogTupleDelete. In the
systable_beginscan case, we should be fine as long as the
systable_endscan follows the CatalogTupleDelete call.

I considered this, but it seems independent of my patch. If there are
changes to be made, there are now fewer places to fix up.

--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services