get_whatever_oid, part 2

Started by Robert Haasover 15 years ago6 messages
#1Robert Haas
robertmhaas@gmail.com
1 attachment(s)

Per previous discussion:

http://archives.postgresql.org/pgsql-hackers/2010-05/msg01195.php
http://archives.postgresql.org/pgsql-hackers/2010-05/msg01577.php

Changes in this patch:

- Rename TSParserGetPrsid to get_tsparser_oid, TSDictionaryGetDictid
to get_tsdictionary_oid, TSTemplateGetTmplid to get_tstemplate_oid,
TSConfigGetCfgid to get_tsconfiguration_oid, FindConversionByName to
get_conversion_oid, and GetConstraintName to get_constraint_oid.
- Add new functions get_opclass_oid, get_opfamily_oid, get_rule_oid,
get_rule_oid_without_relid, get_trigger_oid, and get_cast_oid.
- Refactor existing code to use these functions wherever possible.

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

Attachments:

get_whatever_oid_part2.patchapplication/octet-stream; name=get_whatever_oid_part2.patchDownload
commit c49a450bfd3bb4da13cad18224edb2c6ad487943
Author: Robert Haas <robertmhaas@gmail.com>
Date:   Thu May 27 21:58:56 2010 -0400

    Standardize get_whatever_oid functions for other object types.
    
    Rename TSParserGetPrsid to get_tsparser_oid, TSDictionaryGetDictid to
    get_tsdictionary_oid, TSTemplateGetTmplid to get_tstemplate_oid,
    TSConfigGetCfgid to get_tsconfiguration_oid, FindConversionByName to
    get_conversion_oid, and GetConstraintName to get_constraint_oid.
    
    Add new functions get_opclass_oid, get_opfamily_oid, get_rule_oid,
    get_rule_oid_without_relid, get_trigger_oid, and get_cast_oid.
    
    Refactor existing code to use these functions wherever possible.

diff --git a/contrib/tsearch2/tsearch2.c b/contrib/tsearch2/tsearch2.c
index d421f77..e4e2014 100644
--- a/contrib/tsearch2/tsearch2.c
+++ b/contrib/tsearch2/tsearch2.c
@@ -190,7 +190,7 @@ tsa_set_curdict_byname(PG_FUNCTION_ARGS)
 	text	   *name = PG_GETARG_TEXT_PP(0);
 	Oid			dict_oid;
 
-	dict_oid = TSDictionaryGetDictid(stringToQualifiedNameList(text_to_cstring(name)), false);
+	dict_oid = get_tsdictionary_oid(stringToQualifiedNameList(text_to_cstring(name)), false);
 
 	current_dictionary_oid = dict_oid;
 
@@ -229,7 +229,7 @@ tsa_set_curprs_byname(PG_FUNCTION_ARGS)
 	text	   *name = PG_GETARG_TEXT_PP(0);
 	Oid			parser_oid;
 
-	parser_oid = TSParserGetPrsid(stringToQualifiedNameList(text_to_cstring(name)), false);
+	parser_oid = get_tsparser_oid(stringToQualifiedNameList(text_to_cstring(name)), false);
 
 	current_parser_oid = parser_oid;
 
@@ -562,6 +562,6 @@ static Oid
 GetCurrentParser(void)
 {
 	if (current_parser_oid == InvalidOid)
-		current_parser_oid = TSParserGetPrsid(stringToQualifiedNameList("pg_catalog.default"), false);
+		current_parser_oid = get_tsparser_oid(stringToQualifiedNameList("pg_catalog.default"), false);
 	return current_parser_oid;
 }
diff --git a/contrib/unaccent/unaccent.c b/contrib/unaccent/unaccent.c
index 0a29bba..d7b9c39 100644
--- a/contrib/unaccent/unaccent.c
+++ b/contrib/unaccent/unaccent.c
@@ -279,7 +279,7 @@ unaccent_dict(PG_FUNCTION_ARGS)
 
 	if (PG_NARGS() == 1)
 	{
-		dictOid = TSDictionaryGetDictid(stringToQualifiedNameList("unaccent"), false);
+		dictOid = get_tsdictionary_oid(stringToQualifiedNameList("unaccent"), false);
 		strArg = 0;
 	}
 	else
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 52acc23..71b140a 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -1692,12 +1692,12 @@ ConversionIsVisible(Oid conid)
 }
 
 /*
- * TSParserGetPrsid - find a TS parser by possibly qualified name
+ * get_tsparser_oid - find a TS parser by possibly qualified name
  *
- * If not found, returns InvalidOid if failOK, else throws error
+ * If not found, returns InvalidOid if missing_ok, else throws error
  */
 Oid
-TSParserGetPrsid(List *names, bool failOK)
+get_tsparser_oid(List *names, bool missing_ok)
 {
 	char	   *schemaname;
 	char	   *parser_name;
@@ -1736,7 +1736,7 @@ TSParserGetPrsid(List *names, bool failOK)
 		}
 	}
 
-	if (!OidIsValid(prsoid) && !failOK)
+	if (!OidIsValid(prsoid) && !missing_ok)
 		ereport(ERROR,
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 				 errmsg("text search parser \"%s\" does not exist",
@@ -1815,12 +1815,12 @@ TSParserIsVisible(Oid prsId)
 }
 
 /*
- * TSDictionaryGetDictid - find a TS dictionary by possibly qualified name
+ * get_tsdictionary_oid - find a TS dictionary by possibly qualified name
  *
  * If not found, returns InvalidOid if failOK, else throws error
  */
 Oid
-TSDictionaryGetDictid(List *names, bool failOK)
+get_tsdictionary_oid(List *names, bool missing_ok)
 {
 	char	   *schemaname;
 	char	   *dict_name;
@@ -1859,7 +1859,7 @@ TSDictionaryGetDictid(List *names, bool failOK)
 		}
 	}
 
-	if (!OidIsValid(dictoid) && !failOK)
+	if (!OidIsValid(dictoid) && !missing_ok)
 		ereport(ERROR,
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 				 errmsg("text search dictionary \"%s\" does not exist",
@@ -1939,12 +1939,12 @@ TSDictionaryIsVisible(Oid dictId)
 }
 
 /*
- * TSTemplateGetTmplid - find a TS template by possibly qualified name
+ * get_tstemplate_oid - find a TS template by possibly qualified name
  *
- * If not found, returns InvalidOid if failOK, else throws error
+ * If not found, returns InvalidOid if missing_ok, else throws error
  */
 Oid
-TSTemplateGetTmplid(List *names, bool failOK)
+get_tstemplate_oid(List *names, bool missing_ok)
 {
 	char	   *schemaname;
 	char	   *template_name;
@@ -1983,7 +1983,7 @@ TSTemplateGetTmplid(List *names, bool failOK)
 		}
 	}
 
-	if (!OidIsValid(tmploid) && !failOK)
+	if (!OidIsValid(tmploid) && !missing_ok)
 		ereport(ERROR,
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 				 errmsg("text search template \"%s\" does not exist",
@@ -2062,12 +2062,12 @@ TSTemplateIsVisible(Oid tmplId)
 }
 
 /*
- * TSConfigGetCfgid - find a TS config by possibly qualified name
+ * get_tsconfiguration_oid - find a TS config by possibly qualified name
  *
- * If not found, returns InvalidOid if failOK, else throws error
+ * If not found, returns InvalidOid if missing_ok, else throws error
  */
 Oid
-TSConfigGetCfgid(List *names, bool failOK)
+get_tsconfiguration_oid(List *names, bool missing_ok)
 {
 	char	   *schemaname;
 	char	   *config_name;
@@ -2106,7 +2106,7 @@ TSConfigGetCfgid(List *names, bool failOK)
 		}
 	}
 
-	if (!OidIsValid(cfgoid) && !failOK)
+	if (!OidIsValid(cfgoid) && !missing_ok)
 		ereport(ERROR,
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 				 errmsg("text search configuration \"%s\" does not exist",
@@ -2766,15 +2766,15 @@ PopOverrideSearchPath(void)
 
 
 /*
- * FindConversionByName - find a conversion by possibly qualified name
+ * get_conversion_oid - find a conversion by possibly qualified name
  */
 Oid
-FindConversionByName(List *name)
+get_conversion_oid(List *name, bool missing_ok)
 {
 	char	   *schemaname;
 	char	   *conversion_name;
 	Oid			namespaceId;
-	Oid			conoid;
+	Oid			conoid = InvalidOid;
 	ListCell   *l;
 
 	/* deconstruct the name list */
@@ -2784,9 +2784,9 @@ FindConversionByName(List *name)
 	{
 		/* use exact schema given */
 		namespaceId = LookupExplicitNamespace(schemaname);
-		return GetSysCacheOid2(CONNAMENSP,
-							   PointerGetDatum(conversion_name),
-							   ObjectIdGetDatum(namespaceId));
+		conoid = GetSysCacheOid2(CONNAMENSP,
+								 PointerGetDatum(conversion_name),
+								 ObjectIdGetDatum(namespaceId));
 	}
 	else
 	{
@@ -2809,7 +2809,12 @@ FindConversionByName(List *name)
 	}
 
 	/* Not found in path */
-	return InvalidOid;
+	if (!OidIsValid(conoid) && !missing_ok)
+		ereport(ERROR,
+				(errcode(ERRCODE_UNDEFINED_OBJECT),
+				 errmsg("conversion \"%s\" does not exist",
+						NameListToString(name))));
+	return conoid;
 }
 
 /*
diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c
index 2cfd453..256974b 100644
--- a/src/backend/catalog/pg_constraint.c
+++ b/src/backend/catalog/pg_constraint.c
@@ -727,12 +727,12 @@ AlterConstraintNamespaces(Oid ownerId, Oid oldNspId,
 }
 
 /*
- * GetConstraintByName
+ * get_constraint_oid
  *		Find a constraint on the specified relation with the specified name.
  *		Returns constraint's OID.
  */
 Oid
-GetConstraintByName(Oid relid, const char *conname)
+get_constraint_oid(Oid relid, const char *conname, bool missing_ok)
 {
 	Relation	pg_constraint;
 	HeapTuple	tuple;
@@ -773,7 +773,7 @@ GetConstraintByName(Oid relid, const char *conname)
 	systable_endscan(scan);
 
 	/* If no such constraint exists, complain */
-	if (!OidIsValid(conOid))
+	if (!OidIsValid(conOid) && !missing_ok)
 		ereport(ERROR,
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 				 errmsg("constraint \"%s\" for table \"%s\" does not exist",
diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c
index 2ec5019..4e4169a 100644
--- a/src/backend/commands/comment.c
+++ b/src/backend/commands/comment.c
@@ -45,12 +45,14 @@
 #include "commands/defrem.h"
 #include "commands/proclang.h"
 #include "commands/tablespace.h"
+#include "commands/trigger.h"
 #include "libpq/be-fsstubs.h"
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "parser/parse_func.h"
 #include "parser/parse_oper.h"
 #include "parser/parse_type.h"
+#include "rewrite/rewriteSupport.h"
 #include "utils/acl.h"
 #include "utils/builtins.h"
 #include "utils/fmgroids.h"
@@ -826,7 +828,6 @@ CommentRule(List *qualname, char *comment)
 	char	   *rulename;
 	RangeVar   *rel;
 	Relation	relation;
-	HeapTuple	tuple;
 	Oid			reloid;
 	Oid			ruleoid;
 
@@ -834,46 +835,8 @@ CommentRule(List *qualname, char *comment)
 	nnames = list_length(qualname);
 	if (nnames == 1)
 	{
-		/* Old-style: only a rule name is given */
-		Relation	RewriteRelation;
-		HeapScanDesc scanDesc;
-		ScanKeyData scanKeyData;
-
 		rulename = strVal(linitial(qualname));
-
-		/* Search pg_rewrite for such a rule */
-		ScanKeyInit(&scanKeyData,
-					Anum_pg_rewrite_rulename,
-					BTEqualStrategyNumber, F_NAMEEQ,
-					PointerGetDatum(rulename));
-
-		RewriteRelation = heap_open(RewriteRelationId, AccessShareLock);
-		scanDesc = heap_beginscan(RewriteRelation, SnapshotNow,
-								  1, &scanKeyData);
-
-		tuple = heap_getnext(scanDesc, ForwardScanDirection);
-		if (HeapTupleIsValid(tuple))
-		{
-			reloid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class;
-			ruleoid = HeapTupleGetOid(tuple);
-		}
-		else
-		{
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("rule \"%s\" does not exist", rulename)));
-			reloid = ruleoid = 0;		/* keep compiler quiet */
-		}
-
-		if (HeapTupleIsValid(tuple = heap_getnext(scanDesc,
-												  ForwardScanDirection)))
-			ereport(ERROR,
-					(errcode(ERRCODE_DUPLICATE_OBJECT),
-				   errmsg("there are multiple rules named \"%s\"", rulename),
-				errhint("Specify a relation name as well as a rule name.")));
-
-		heap_endscan(scanDesc);
-		heap_close(RewriteRelation, AccessShareLock);
+		ruleoid = get_rule_oid_without_relid(rulename, &reloid);
 
 		/* Open the owning relation to ensure it won't go away meanwhile */
 		relation = heap_open(reloid, AccessShareLock);
@@ -891,17 +854,7 @@ CommentRule(List *qualname, char *comment)
 		reloid = RelationGetRelid(relation);
 
 		/* Find the rule's pg_rewrite tuple, get its OID */
-		tuple = SearchSysCache2(RULERELNAME,
-								ObjectIdGetDatum(reloid),
-								PointerGetDatum(rulename));
-		if (!HeapTupleIsValid(tuple))
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("rule \"%s\" for relation \"%s\" does not exist",
-							rulename, RelationGetRelationName(relation))));
-		Assert(reloid == ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class);
-		ruleoid = HeapTupleGetOid(tuple);
-		ReleaseSysCache(tuple);
+		ruleoid = get_rule_oid(reloid, rulename, false);
 	}
 
 	/* Check object security */
@@ -1046,11 +999,7 @@ CommentTrigger(List *qualname, char *comment)
 	List	   *relname;
 	char	   *trigname;
 	RangeVar   *rel;
-	Relation	pg_trigger,
-				relation;
-	HeapTuple	triggertuple;
-	SysScanDesc scan;
-	ScanKeyData entry[2];
+	Relation	relation;
 	Oid			oid;
 
 	/* Separate relname and trig name */
@@ -1065,46 +1014,16 @@ CommentTrigger(List *qualname, char *comment)
 	relation = heap_openrv(rel, AccessShareLock);
 
 	/* Check object security */
-
 	if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
 					   RelationGetRelationName(relation));
 
-	/*
-	 * Fetch the trigger tuple from pg_trigger.  There can be only one because
-	 * of the unique index.
-	 */
-	pg_trigger = heap_open(TriggerRelationId, AccessShareLock);
-	ScanKeyInit(&entry[0],
-				Anum_pg_trigger_tgrelid,
-				BTEqualStrategyNumber, F_OIDEQ,
-				ObjectIdGetDatum(RelationGetRelid(relation)));
-	ScanKeyInit(&entry[1],
-				Anum_pg_trigger_tgname,
-				BTEqualStrategyNumber, F_NAMEEQ,
-				CStringGetDatum(trigname));
-	scan = systable_beginscan(pg_trigger, TriggerRelidNameIndexId, true,
-							  SnapshotNow, 2, entry);
-	triggertuple = systable_getnext(scan);
-
-	/* If no trigger exists for the relation specified, notify user */
-
-	if (!HeapTupleIsValid(triggertuple))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("trigger \"%s\" for table \"%s\" does not exist",
-						trigname, RelationGetRelationName(relation))));
-
-	oid = HeapTupleGetOid(triggertuple);
-
-	systable_endscan(scan);
+	oid = get_trigger_oid(RelationGetRelid(relation), trigname, false);
 
 	/* Call CreateComments() to create/drop the comments */
 	CreateComments(oid, TriggerRelationId, 0, comment);
 
 	/* Done, but hold lock on relation */
-
-	heap_close(pg_trigger, AccessShareLock);
 	heap_close(relation, NoLock);
 }
 
@@ -1143,7 +1062,7 @@ CommentConstraint(List *qualname, char *comment)
 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
 					   RelationGetRelationName(relation));
 
-	conOid = GetConstraintByName(RelationGetRelid(relation), conName);
+	conOid = get_constraint_oid(RelationGetRelid(relation), conName, false);
 
 	/* Call CreateComments() to create/drop the comments */
 	CreateComments(conOid, ConstraintRelationId, 0, comment);
@@ -1166,12 +1085,7 @@ CommentConversion(List *qualname, char *comment)
 {
 	Oid			conversionOid;
 
-	conversionOid = FindConversionByName(qualname);
-	if (!OidIsValid(conversionOid))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("conversion \"%s\" does not exist",
-						NameListToString(qualname))));
+	conversionOid = get_conversion_oid(qualname, false);
 
 	/* Check object security */
 	if (!pg_conversion_ownercheck(conversionOid, GetUserId()))
@@ -1228,65 +1142,23 @@ static void
 CommentOpClass(List *qualname, List *arguments, char *comment)
 {
 	char	   *amname;
-	char	   *schemaname;
-	char	   *opcname;
 	Oid			amID;
 	Oid			opcID;
-	HeapTuple	tuple;
 
 	Assert(list_length(arguments) == 1);
 	amname = strVal(linitial(arguments));
 
 	/*
-	 * Get the access method's OID.
+	 * Get the operator class OID.
 	 */
 	amID = get_am_oid(amname, false);
-
-	/*
-	 * Look up the opclass.
-	 */
-
-	/* deconstruct the name list */
-	DeconstructQualifiedName(qualname, &schemaname, &opcname);
-
-	if (schemaname)
-	{
-		/* Look in specific schema only */
-		Oid			namespaceId;
-
-		namespaceId = LookupExplicitNamespace(schemaname);
-		tuple = SearchSysCache3(CLAAMNAMENSP,
-								ObjectIdGetDatum(amID),
-								PointerGetDatum(opcname),
-								ObjectIdGetDatum(namespaceId));
-	}
-	else
-	{
-		/* Unqualified opclass name, so search the search path */
-		opcID = OpclassnameGetOpcid(amID, opcname);
-		if (!OidIsValid(opcID))
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
-							opcname, amname)));
-		tuple = SearchSysCache1(CLAOID, ObjectIdGetDatum(opcID));
-	}
-
-	if (!HeapTupleIsValid(tuple))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
-						NameListToString(qualname), amname)));
-
-	opcID = HeapTupleGetOid(tuple);
+	opcID = get_opclass_oid(amID, qualname, false);
 
 	/* Permission check: must own opclass */
 	if (!pg_opclass_ownercheck(opcID, GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPCLASS,
 					   NameListToString(qualname));
 
-	ReleaseSysCache(tuple);
-
 	/* Call CreateComments() to create/drop the comments */
 	CreateComments(opcID, OperatorClassRelationId, 0, comment);
 }
@@ -1304,65 +1176,21 @@ static void
 CommentOpFamily(List *qualname, List *arguments, char *comment)
 {
 	char	   *amname;
-	char	   *schemaname;
-	char	   *opfname;
 	Oid			amID;
 	Oid			opfID;
-	HeapTuple	tuple;
 
 	Assert(list_length(arguments) == 1);
 	amname = strVal(linitial(arguments));
 
-	/*
-	 * Get the access method's OID.
-	 */
+	/* Get the opfamily OID. */
 	amID = get_am_oid(amname, false);
-
-	/*
-	 * Look up the opfamily.
-	 */
-
-	/* deconstruct the name list */
-	DeconstructQualifiedName(qualname, &schemaname, &opfname);
-
-	if (schemaname)
-	{
-		/* Look in specific schema only */
-		Oid			namespaceId;
-
-		namespaceId = LookupExplicitNamespace(schemaname);
-		tuple = SearchSysCache3(OPFAMILYAMNAMENSP,
-								ObjectIdGetDatum(amID),
-								PointerGetDatum(opfname),
-								ObjectIdGetDatum(namespaceId));
-	}
-	else
-	{
-		/* Unqualified opfamily name, so search the search path */
-		opfID = OpfamilynameGetOpfid(amID, opfname);
-		if (!OidIsValid(opfID))
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator family \"%s\" does not exist for access method \"%s\"",
-							opfname, amname)));
-		tuple = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfID));
-	}
-
-	if (!HeapTupleIsValid(tuple))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("operator family \"%s\" does not exist for access method \"%s\"",
-						NameListToString(qualname), amname)));
-
-	opfID = HeapTupleGetOid(tuple);
+	opfID = get_opfamily_oid(amID, qualname, false);
 
 	/* Permission check: must own opfamily */
 	if (!pg_opfamily_ownercheck(opfID, GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPFAMILY,
 					   NameListToString(qualname));
 
-	ReleaseSysCache(tuple);
-
 	/* Call CreateComments() to create/drop the comments */
 	CreateComments(opfID, OperatorFamilyRelationId, 0, comment);
 }
@@ -1446,7 +1274,6 @@ CommentCast(List *qualname, List *arguments, char *comment)
 	TypeName   *targettype;
 	Oid			sourcetypeid;
 	Oid			targettypeid;
-	HeapTuple	tuple;
 	Oid			castOid;
 
 	Assert(list_length(qualname) == 1);
@@ -1459,18 +1286,8 @@ CommentCast(List *qualname, List *arguments, char *comment)
 	sourcetypeid = typenameTypeId(NULL, sourcetype, NULL);
 	targettypeid = typenameTypeId(NULL, targettype, NULL);
 
-	tuple = SearchSysCache2(CASTSOURCETARGET,
-							ObjectIdGetDatum(sourcetypeid),
-							ObjectIdGetDatum(targettypeid));
-	if (!HeapTupleIsValid(tuple))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("cast from type %s to type %s does not exist",
-						format_type_be(sourcetypeid),
-						format_type_be(targettypeid))));
-
 	/* Get the OID of the cast */
-	castOid = HeapTupleGetOid(tuple);
+	castOid = get_cast_oid(sourcetypeid, targettypeid, false);
 
 	/* Permission check */
 	if (!pg_type_ownercheck(sourcetypeid, GetUserId())
@@ -1481,8 +1298,6 @@ CommentCast(List *qualname, List *arguments, char *comment)
 						format_type_be(sourcetypeid),
 						format_type_be(targettypeid))));
 
-	ReleaseSysCache(tuple);
-
 	/* Call CreateComments() to create/drop the comments */
 	CreateComments(castOid, CastRelationId, 0, comment);
 }
@@ -1492,7 +1307,7 @@ CommentTSParser(List *qualname, char *comment)
 {
 	Oid			prsId;
 
-	prsId = TSParserGetPrsid(qualname, false);
+	prsId = get_tsparser_oid(qualname, false);
 
 	if (!superuser())
 		ereport(ERROR,
@@ -1507,7 +1322,7 @@ CommentTSDictionary(List *qualname, char *comment)
 {
 	Oid			dictId;
 
-	dictId = TSDictionaryGetDictid(qualname, false);
+	dictId = get_tsdictionary_oid(qualname, false);
 
 	if (!pg_ts_dict_ownercheck(dictId, GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSDICTIONARY,
@@ -1521,7 +1336,7 @@ CommentTSTemplate(List *qualname, char *comment)
 {
 	Oid			tmplId;
 
-	tmplId = TSTemplateGetTmplid(qualname, false);
+	tmplId = get_tstemplate_oid(qualname, false);
 
 	if (!superuser())
 		ereport(ERROR,
@@ -1536,7 +1351,7 @@ CommentTSConfiguration(List *qualname, char *comment)
 {
 	Oid			cfgId;
 
-	cfgId = TSConfigGetCfgid(qualname, false);
+	cfgId = get_tsconfiguration_oid(qualname, false);
 
 	if (!pg_ts_config_ownercheck(cfgId, GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSCONFIGURATION,
diff --git a/src/backend/commands/conversioncmds.c b/src/backend/commands/conversioncmds.c
index 57ddab0..350abf2 100644
--- a/src/backend/commands/conversioncmds.c
+++ b/src/backend/commands/conversioncmds.c
@@ -142,23 +142,13 @@ DropConversionsCommand(DropStmt *drop)
 		Form_pg_conversion con;
 		ObjectAddress object;
 
-		conversionOid = FindConversionByName(name);
+		conversionOid = get_conversion_oid(name, drop->missing_ok);
 
 		if (!OidIsValid(conversionOid))
 		{
-			if (!drop->missing_ok)
-			{
-				ereport(ERROR,
-						(errcode(ERRCODE_UNDEFINED_OBJECT),
-						 errmsg("conversion \"%s\" does not exist",
-								NameListToString(name))));
-			}
-			else
-			{
-				ereport(NOTICE,
-						(errmsg("conversion \"%s\" does not exist, skipping",
-								NameListToString(name))));
-			}
+			ereport(NOTICE,
+					(errmsg("conversion \"%s\" does not exist, skipping",
+							NameListToString(name))));
 			continue;
 		}
 
@@ -202,12 +192,7 @@ RenameConversion(List *name, const char *newname)
 
 	rel = heap_open(ConversionRelationId, RowExclusiveLock);
 
-	conversionOid = FindConversionByName(name);
-	if (!OidIsValid(conversionOid))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("conversion \"%s\" does not exist",
-						NameListToString(name))));
+	conversionOid = get_conversion_oid(name, false);
 
 	tup = SearchSysCacheCopy1(CONVOID, ObjectIdGetDatum(conversionOid));
 	if (!HeapTupleIsValid(tup)) /* should not happen */
@@ -255,12 +240,7 @@ AlterConversionOwner(List *name, Oid newOwnerId)
 
 	rel = heap_open(ConversionRelationId, RowExclusiveLock);
 
-	conversionOid = FindConversionByName(name);
-	if (!OidIsValid(conversionOid))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("conversion \"%s\" does not exist",
-						NameListToString(name))));
+	conversionOid = get_conversion_oid(name, false);
 
 	AlterConversionOwner_internal(rel, conversionOid, newOwnerId);
 
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 9a584ed..be256c1 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -1759,31 +1759,23 @@ DropCast(DropCastStmt *stmt)
 {
 	Oid			sourcetypeid;
 	Oid			targettypeid;
-	HeapTuple	tuple;
 	ObjectAddress object;
 
 	/* when dropping a cast, the types must exist even if you use IF EXISTS */
 	sourcetypeid = typenameTypeId(NULL, stmt->sourcetype, NULL);
 	targettypeid = typenameTypeId(NULL, stmt->targettype, NULL);
 
-	tuple = SearchSysCache2(CASTSOURCETARGET,
-							ObjectIdGetDatum(sourcetypeid),
-							ObjectIdGetDatum(targettypeid));
-	if (!HeapTupleIsValid(tuple))
+	object.classId = CastRelationId;
+	object.objectId = get_cast_oid(sourcetypeid, targettypeid,
+								   stmt->missing_ok);
+	object.objectSubId = 0;
+
+	if (!OidIsValid(object.objectId))
 	{
-		if (!stmt->missing_ok)
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("cast from type %s to type %s does not exist",
-							format_type_be(sourcetypeid),
-							format_type_be(targettypeid))));
-		else
-			ereport(NOTICE,
+		ereport(NOTICE,
 			 (errmsg("cast from type %s to type %s does not exist, skipping",
 					 format_type_be(sourcetypeid),
 					 format_type_be(targettypeid))));
-
-		return;
 	}
 
 	/* Permission check */
@@ -1798,15 +1790,31 @@ DropCast(DropCastStmt *stmt)
 	/*
 	 * Do the deletion
 	 */
-	object.classId = CastRelationId;
-	object.objectId = HeapTupleGetOid(tuple);
-	object.objectSubId = 0;
-
-	ReleaseSysCache(tuple);
-
 	performDeletion(&object, stmt->behavior);
 }
 
+/*
+ * get_cast_oid - given two type OIDs, look up a cast OID
+ *
+ * If missing_ok is false, throw an error if the cast is not found.  If
+ * true, just return InvalidOid.
+ */
+Oid
+get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok)
+{
+	Oid		oid;
+
+	oid = GetSysCacheOid2(CASTSOURCETARGET,
+						  ObjectIdGetDatum(sourcetypeid),
+						  ObjectIdGetDatum(targettypeid));
+	if (!OidIsValid(oid) && !missing_ok)
+		ereport(ERROR,
+				(errcode(ERRCODE_UNDEFINED_OBJECT),
+				 errmsg("cast from type %s to type %s does not exist",
+						format_type_be(sourcetypeid),
+						format_type_be(targettypeid))));
+	return oid;
+}
 
 void
 DropCastById(Oid castOid)
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index 234d133..3cb16d9 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -90,10 +90,11 @@ static void AlterOpFamilyOwner_internal(Relation rel, HeapTuple tuple,
  * Returns a syscache tuple reference, or NULL if not found.
  */
 static HeapTuple
-OpFamilyCacheLookup(Oid amID, List *opfamilyname)
+OpFamilyCacheLookup(Oid amID, List *opfamilyname, bool missing_ok)
 {
 	char	   *schemaname;
 	char	   *opfname;
+	HeapTuple	htup;
 
 	/* deconstruct the name list */
 	DeconstructQualifiedName(opfamilyname, &schemaname, &opfname);
@@ -104,7 +105,7 @@ OpFamilyCacheLookup(Oid amID, List *opfamilyname)
 		Oid			namespaceId;
 
 		namespaceId = LookupExplicitNamespace(schemaname);
-		return SearchSysCache3(OPFAMILYAMNAMENSP,
+		htup = SearchSysCache3(OPFAMILYAMNAMENSP,
 							   ObjectIdGetDatum(amID),
 							   PointerGetDatum(opfname),
 							   ObjectIdGetDatum(namespaceId));
@@ -115,9 +116,47 @@ OpFamilyCacheLookup(Oid amID, List *opfamilyname)
 		Oid			opfID = OpfamilynameGetOpfid(amID, opfname);
 
 		if (!OidIsValid(opfID))
-			return NULL;
-		return SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfID));
+			htup = NULL;
+		else
+			htup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfID));
+	}
+
+	if (!HeapTupleIsValid(htup) && !missing_ok)
+	{
+		HeapTuple amtup;
+
+		amtup = SearchSysCache1(AMOID, ObjectIdGetDatum(amID));
+		if (!HeapTupleIsValid(amtup))
+			elog(ERROR, "cache lookup failed for access method %u", amID);
+		ereport(ERROR,
+				(errcode(ERRCODE_UNDEFINED_OBJECT),
+				 errmsg("operator family \"%s\" does not exist for access method \"%s\"",
+				   NameListToString(opfamilyname),
+				   NameStr(((Form_pg_am) GETSTRUCT(amtup))->amname))));
 	}
+
+	return htup;
+}
+
+/*
+ * get_opfamily_oid
+ *    find an opfamily OID by possibly qualified name
+ *
+ * If not found, returns InvalidOid if missing_ok, else throws error.
+ */
+Oid
+get_opfamily_oid(Oid amID, List *opfamilyname, bool missing_ok)
+{
+	HeapTuple	htup;
+	Oid			opfID;
+
+	htup = OpFamilyCacheLookup(amID, opfamilyname, missing_ok);
+	if (!HeapTupleIsValid(htup))
+		return InvalidOid;
+	opfID = HeapTupleGetOid(htup);
+	ReleaseSysCache(htup);
+
+	return opfID;
 }
 
 /*
@@ -127,10 +166,11 @@ OpFamilyCacheLookup(Oid amID, List *opfamilyname)
  * Returns a syscache tuple reference, or NULL if not found.
  */
 static HeapTuple
-OpClassCacheLookup(Oid amID, List *opclassname)
+OpClassCacheLookup(Oid amID, List *opclassname, bool missing_ok)
 {
 	char	   *schemaname;
 	char	   *opcname;
+	HeapTuple	htup;
 
 	/* deconstruct the name list */
 	DeconstructQualifiedName(opclassname, &schemaname, &opcname);
@@ -141,7 +181,7 @@ OpClassCacheLookup(Oid amID, List *opclassname)
 		Oid			namespaceId;
 
 		namespaceId = LookupExplicitNamespace(schemaname);
-		return SearchSysCache3(CLAAMNAMENSP,
+		htup = SearchSysCache3(CLAAMNAMENSP,
 							   ObjectIdGetDatum(amID),
 							   PointerGetDatum(opcname),
 							   ObjectIdGetDatum(namespaceId));
@@ -152,9 +192,47 @@ OpClassCacheLookup(Oid amID, List *opclassname)
 		Oid			opcID = OpclassnameGetOpcid(amID, opcname);
 
 		if (!OidIsValid(opcID))
-			return NULL;
-		return SearchSysCache1(CLAOID, ObjectIdGetDatum(opcID));
+			htup = NULL;
+		else
+			htup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opcID));
+	}
+
+	if (!HeapTupleIsValid(htup) && !missing_ok)
+	{
+		HeapTuple amtup;
+
+		amtup = SearchSysCache1(AMOID, ObjectIdGetDatum(amID));
+		if (!HeapTupleIsValid(amtup))
+			elog(ERROR, "cache lookup failed for access method %u", amID);
+		ereport(ERROR,
+				(errcode(ERRCODE_UNDEFINED_OBJECT),
+				 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
+						NameListToString(opclassname),
+						NameStr(((Form_pg_am) GETSTRUCT(amtup))->amname))));
 	}
+
+	return htup;
+}
+
+/*
+ * get_opclass_oid
+ *    find an opclass OID by possibly qualified name
+ *
+ * If not found, returns InvalidOid if missing_ok, else throws error.
+ */
+Oid
+get_opclass_oid(Oid amID, List *opclassname, bool missing_ok)
+{
+	HeapTuple	htup;
+	Oid			opcID;
+
+	htup = OpClassCacheLookup(amID, opclassname, missing_ok);
+	if (!HeapTupleIsValid(htup))
+		return InvalidOid;
+	opcID = HeapTupleGetOid(htup);
+	ReleaseSysCache(htup);
+
+	return opcID;
 }
 
 /*
@@ -336,19 +414,7 @@ DefineOpClass(CreateOpClassStmt *stmt)
 	 */
 	if (stmt->opfamilyname)
 	{
-		tup = OpFamilyCacheLookup(amoid, stmt->opfamilyname);
-		if (!HeapTupleIsValid(tup))
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator family \"%s\" does not exist for access method \"%s\"",
-					   NameListToString(stmt->opfamilyname), stmt->amname)));
-		opfamilyoid = HeapTupleGetOid(tup);
-
-		/*
-		 * XXX given the superuser check above, there's no need for an
-		 * ownership check here
-		 */
-		ReleaseSysCache(tup);
+		opfamilyoid = get_opfamily_oid(amoid, stmt->opfamilyname, false);
 	}
 	else
 	{
@@ -782,14 +848,7 @@ AlterOpFamily(AlterOpFamilyStmt *stmt)
 	ReleaseSysCache(tup);
 
 	/* Look up the opfamily */
-	tup = OpFamilyCacheLookup(amoid, stmt->opfamilyname);
-	if (!HeapTupleIsValid(tup))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("operator family \"%s\" does not exist for access method \"%s\"",
-						NameListToString(stmt->opfamilyname), stmt->amname)));
-	opfamilyoid = HeapTupleGetOid(tup);
-	ReleaseSysCache(tup);
+	opfamilyoid = get_opfamily_oid(amoid, stmt->opfamilyname, false);
 
 	/*
 	 * Currently, we require superuser privileges to alter an opfamily.
@@ -1485,26 +1544,16 @@ RemoveOpClass(RemoveOpClassStmt *stmt)
 	HeapTuple	tuple;
 	ObjectAddress object;
 
-	/*
-	 * Get the access method's OID.
-	 */
+	/* Get the access method's OID. */
 	amID = get_am_oid(stmt->amname, false);
 
-	/*
-	 * Look up the opclass.
-	 */
-	tuple = OpClassCacheLookup(amID, stmt->opclassname);
+	/* Look up the opclass. */
+	tuple = OpClassCacheLookup(amID, stmt->opclassname, stmt->missing_ok);
 	if (!HeapTupleIsValid(tuple))
 	{
-		if (!stmt->missing_ok)
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
-						NameListToString(stmt->opclassname), stmt->amname)));
-		else
-			ereport(NOTICE,
-					(errmsg("operator class \"%s\" does not exist for access method \"%s\"",
-						NameListToString(stmt->opclassname), stmt->amname)));
+		ereport(NOTICE,
+				(errmsg("operator class \"%s\" does not exist for access method \"%s\"",
+					NameListToString(stmt->opclassname), stmt->amname)));
 		return;
 	}
 
@@ -1549,18 +1598,13 @@ RemoveOpFamily(RemoveOpFamilyStmt *stmt)
 	/*
 	 * Look up the opfamily.
 	 */
-	tuple = OpFamilyCacheLookup(amID, stmt->opfamilyname);
+	tuple = OpFamilyCacheLookup(amID, stmt->opfamilyname, stmt->missing_ok);
 	if (!HeapTupleIsValid(tuple))
 	{
-		if (!stmt->missing_ok)
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator family \"%s\" does not exist for access method \"%s\"",
-					   NameListToString(stmt->opfamilyname), stmt->amname)));
-		else
-			ereport(NOTICE,
-					(errmsg("operator family \"%s\" does not exist for access method \"%s\"",
-					   NameListToString(stmt->opfamilyname), stmt->amname)));
+		ereport(ERROR,
+				(errcode(ERRCODE_UNDEFINED_OBJECT),
+				 errmsg("operator family \"%s\" does not exist for access method \"%s\"",
+				   NameListToString(stmt->opfamilyname), stmt->amname)));
 		return;
 	}
 
@@ -1695,8 +1739,7 @@ RenameOpClass(List *name, const char *access_method, const char *newname)
 	Oid			opcOid;
 	Oid			amOid;
 	Oid			namespaceOid;
-	char	   *schemaname;
-	char	   *opcname;
+	HeapTuple	origtup;
 	HeapTuple	tup;
 	Relation	rel;
 	AclResult	aclresult;
@@ -1705,42 +1748,12 @@ RenameOpClass(List *name, const char *access_method, const char *newname)
 
 	rel = heap_open(OperatorClassRelationId, RowExclusiveLock);
 
-	/*
-	 * Look up the opclass
-	 */
-	DeconstructQualifiedName(name, &schemaname, &opcname);
-
-	if (schemaname)
-	{
-		namespaceOid = LookupExplicitNamespace(schemaname);
-
-		tup = SearchSysCacheCopy3(CLAAMNAMENSP,
-								  ObjectIdGetDatum(amOid),
-								  PointerGetDatum(opcname),
-								  ObjectIdGetDatum(namespaceOid));
-		if (!HeapTupleIsValid(tup))
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
-							opcname, access_method)));
-
-		opcOid = HeapTupleGetOid(tup);
-	}
-	else
-	{
-		opcOid = OpclassnameGetOpcid(amOid, opcname);
-		if (!OidIsValid(opcOid))
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
-							opcname, access_method)));
-
-		tup = SearchSysCacheCopy1(CLAOID, ObjectIdGetDatum(opcOid));
-		if (!HeapTupleIsValid(tup))		/* should not happen */
-			elog(ERROR, "cache lookup failed for opclass %u", opcOid);
-
-		namespaceOid = ((Form_pg_opclass) GETSTRUCT(tup))->opcnamespace;
-	}
+	/* Look up the opclass. */
+	origtup = OpClassCacheLookup(amOid, name, false);
+	tup = heap_copytuple(origtup);
+	ReleaseSysCache(origtup);
+	opcOid = HeapTupleGetOid(tup);
+	namespaceOid = ((Form_pg_opclass) GETSTRUCT(tup))->opcnamespace;
 
 	/* make sure the new name doesn't exist */
 	if (SearchSysCacheExists3(CLAAMNAMENSP,
@@ -1873,49 +1886,16 @@ AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId)
 	Oid			amOid;
 	Relation	rel;
 	HeapTuple	tup;
-	char	   *opcname;
-	char	   *schemaname;
+	HeapTuple	origtup;
 
 	amOid = get_am_oid(access_method, false);
 
 	rel = heap_open(OperatorClassRelationId, RowExclusiveLock);
 
-	/*
-	 * Look up the opclass
-	 */
-	DeconstructQualifiedName(name, &schemaname, &opcname);
-
-	if (schemaname)
-	{
-		Oid			namespaceOid;
-
-		namespaceOid = LookupExplicitNamespace(schemaname);
-
-		tup = SearchSysCacheCopy3(CLAAMNAMENSP,
-								  ObjectIdGetDatum(amOid),
-								  PointerGetDatum(opcname),
-								  ObjectIdGetDatum(namespaceOid));
-		if (!HeapTupleIsValid(tup))
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
-							opcname, access_method)));
-	}
-	else
-	{
-		Oid			opcOid;
-
-		opcOid = OpclassnameGetOpcid(amOid, opcname);
-		if (!OidIsValid(opcOid))
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
-							opcname, access_method)));
-
-		tup = SearchSysCacheCopy1(CLAOID, ObjectIdGetDatum(opcOid));
-		if (!HeapTupleIsValid(tup))		/* should not happen */
-			elog(ERROR, "cache lookup failed for opclass %u", opcOid);
-	}
+	/* Look up the opclass. */
+	origtup = OpClassCacheLookup(amOid, name, false);
+	tup = heap_copytuple(origtup);
+	ReleaseSysCache(origtup);
 
 	AlterOpClassOwner_internal(rel, tup, newOwnerId);
 
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 2cbc192..71724c8 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -960,46 +960,17 @@ void
 DropTrigger(Oid relid, const char *trigname, DropBehavior behavior,
 			bool missing_ok)
 {
-	Relation	tgrel;
-	ScanKeyData skey[2];
-	SysScanDesc tgscan;
-	HeapTuple	tup;
 	ObjectAddress object;
 
-	/*
-	 * Find the trigger, verify permissions, set up object address
-	 */
-	tgrel = heap_open(TriggerRelationId, AccessShareLock);
-
-	ScanKeyInit(&skey[0],
-				Anum_pg_trigger_tgrelid,
-				BTEqualStrategyNumber, F_OIDEQ,
-				ObjectIdGetDatum(relid));
-
-	ScanKeyInit(&skey[1],
-				Anum_pg_trigger_tgname,
-				BTEqualStrategyNumber, F_NAMEEQ,
-				CStringGetDatum(trigname));
-
-	tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
-								SnapshotNow, 2, skey);
-
-	tup = systable_getnext(tgscan);
+	object.classId = TriggerRelationId;
+	object.objectId = get_trigger_oid(relid, trigname, missing_ok);
+	object.objectSubId = 0;
 
-	if (!HeapTupleIsValid(tup))
+	if (!OidIsValid(object.objectId))
 	{
-		if (!missing_ok)
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("trigger \"%s\" for table \"%s\" does not exist",
-							trigname, get_rel_name(relid))));
-		else
-			ereport(NOTICE,
-					(errmsg("trigger \"%s\" for table \"%s\" does not exist, skipping",
-							trigname, get_rel_name(relid))));
-		/* cleanup */
-		systable_endscan(tgscan);
-		heap_close(tgrel, AccessShareLock);
+		ereport(NOTICE,
+				(errmsg("trigger \"%s\" for table \"%s\" does not exist, skipping",
+						trigname, get_rel_name(relid))));
 		return;
 	}
 
@@ -1007,13 +978,6 @@ DropTrigger(Oid relid, const char *trigname, DropBehavior behavior,
 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
 					   get_rel_name(relid));
 
-	object.classId = TriggerRelationId;
-	object.objectId = HeapTupleGetOid(tup);
-	object.objectSubId = 0;
-
-	systable_endscan(tgscan);
-	heap_close(tgrel, AccessShareLock);
-
 	/*
 	 * Do the deletion
 	 */
@@ -1093,6 +1057,59 @@ RemoveTriggerById(Oid trigOid)
 }
 
 /*
+ * get_trigger_oid - Look up a trigger by name to find its OID.
+ *
+ * If missing_ok is false, throw an error if trigger not found.  If
+ * true, just return InvalidOid.
+ */
+Oid
+get_trigger_oid(Oid relid, const char *trigname, bool missing_ok)
+{
+	Relation	tgrel;
+	ScanKeyData skey[2];
+	SysScanDesc tgscan;
+	HeapTuple	tup;
+	Oid			oid;
+
+	/*
+	 * Find the trigger, verify permissions, set up object address
+	 */
+	tgrel = heap_open(TriggerRelationId, AccessShareLock);
+
+	ScanKeyInit(&skey[0],
+				Anum_pg_trigger_tgrelid,
+				BTEqualStrategyNumber, F_OIDEQ,
+				ObjectIdGetDatum(relid));
+	ScanKeyInit(&skey[1],
+				Anum_pg_trigger_tgname,
+				BTEqualStrategyNumber, F_NAMEEQ,
+				CStringGetDatum(trigname));
+
+	tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
+								SnapshotNow, 2, skey);
+
+	tup = systable_getnext(tgscan);
+
+	if (!HeapTupleIsValid(tup))
+	{
+		if (!missing_ok)
+			ereport(ERROR,
+					(errcode(ERRCODE_UNDEFINED_OBJECT),
+					 errmsg("trigger \"%s\" for table \"%s\" does not exist",
+							trigname, get_rel_name(relid))));
+		oid = InvalidOid;
+	}
+	else
+	{
+		oid = HeapTupleGetOid(tup);
+	}
+
+	systable_endscan(tgscan);
+	heap_close(tgrel, AccessShareLock);
+	return oid;
+}
+
+/*
  *		renametrig		- changes the name of a trigger on a relation
  *
  *		trigger name is changed in trigger catalog.
diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c
index ba3de63..87b3105 100644
--- a/src/backend/commands/tsearchcmds.c
+++ b/src/backend/commands/tsearchcmds.c
@@ -295,7 +295,7 @@ RemoveTSParsers(DropStmt *drop)
 		Oid			prsOid;
 		ObjectAddress object;
 
-		prsOid = TSParserGetPrsid(names, true);
+		prsOid = get_tsparser_oid(names, true);
 
 		if (!OidIsValid(prsOid))
 		{
@@ -368,7 +368,7 @@ RenameTSParser(List *oldname, const char *newname)
 
 	rel = heap_open(TSParserRelationId, RowExclusiveLock);
 
-	prsId = TSParserGetPrsid(oldname, false);
+	prsId = get_tsparser_oid(oldname, false);
 
 	tup = SearchSysCacheCopy1(TSPARSEROID, ObjectIdGetDatum(prsId));
 
@@ -517,7 +517,7 @@ DefineTSDictionary(List *names, List *parameters)
 
 		if (pg_strcasecmp(defel->defname, "template") == 0)
 		{
-			templId = TSTemplateGetTmplid(defGetQualifiedName(defel), false);
+			templId = get_tstemplate_oid(defGetQualifiedName(defel), false);
 		}
 		else
 		{
@@ -582,7 +582,7 @@ RenameTSDictionary(List *oldname, const char *newname)
 
 	rel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
 
-	dictId = TSDictionaryGetDictid(oldname, false);
+	dictId = get_tsdictionary_oid(oldname, false);
 
 	tup = SearchSysCacheCopy1(TSDICTOID, ObjectIdGetDatum(dictId));
 
@@ -643,7 +643,7 @@ RemoveTSDictionaries(DropStmt *drop)
 		HeapTuple	tup;
 		Oid			namespaceId;
 
-		dictOid = TSDictionaryGetDictid(names, true);
+		dictOid = get_tsdictionary_oid(names, true);
 
 		if (!OidIsValid(dictOid))
 		{
@@ -731,7 +731,7 @@ AlterTSDictionary(AlterTSDictionaryStmt *stmt)
 	bool		repl_null[Natts_pg_ts_dict];
 	bool		repl_repl[Natts_pg_ts_dict];
 
-	dictId = TSDictionaryGetDictid(stmt->dictname, false);
+	dictId = get_tsdictionary_oid(stmt->dictname, false);
 
 	rel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
 
@@ -841,7 +841,7 @@ AlterTSDictionaryOwner(List *name, Oid newOwnerId)
 
 	rel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
 
-	dictId = TSDictionaryGetDictid(name, false);
+	dictId = get_tsdictionary_oid(name, false);
 
 	tup = SearchSysCacheCopy1(TSDICTOID, ObjectIdGetDatum(dictId));
 
@@ -1073,7 +1073,7 @@ RenameTSTemplate(List *oldname, const char *newname)
 
 	rel = heap_open(TSTemplateRelationId, RowExclusiveLock);
 
-	tmplId = TSTemplateGetTmplid(oldname, false);
+	tmplId = get_tstemplate_oid(oldname, false);
 
 	tup = SearchSysCacheCopy1(TSTEMPLATEOID, ObjectIdGetDatum(tmplId));
 
@@ -1126,7 +1126,7 @@ RemoveTSTemplates(DropStmt *drop)
 		Oid			tmplOid;
 		ObjectAddress object;
 
-		tmplOid = TSTemplateGetTmplid(names, true);
+		tmplOid = get_tstemplate_oid(names, true);
 
 		if (!OidIsValid(tmplOid))
 		{
@@ -1194,7 +1194,7 @@ GetTSConfigTuple(List *names)
 	HeapTuple	tup;
 	Oid			cfgId;
 
-	cfgId = TSConfigGetCfgid(names, true);
+	cfgId = get_tsconfiguration_oid(names, true);
 	if (!OidIsValid(cfgId))
 		return NULL;
 
@@ -1329,9 +1329,9 @@ DefineTSConfiguration(List *names, List *parameters)
 		DefElem    *defel = (DefElem *) lfirst(pl);
 
 		if (pg_strcasecmp(defel->defname, "parser") == 0)
-			prsOid = TSParserGetPrsid(defGetQualifiedName(defel), false);
+			prsOid = get_tsparser_oid(defGetQualifiedName(defel), false);
 		else if (pg_strcasecmp(defel->defname, "copy") == 0)
-			sourceOid = TSConfigGetCfgid(defGetQualifiedName(defel), false);
+			sourceOid = get_tsconfiguration_oid(defGetQualifiedName(defel), false);
 		else
 			ereport(ERROR,
 					(errcode(ERRCODE_SYNTAX_ERROR),
@@ -1461,7 +1461,7 @@ RenameTSConfiguration(List *oldname, const char *newname)
 
 	rel = heap_open(TSConfigRelationId, RowExclusiveLock);
 
-	cfgId = TSConfigGetCfgid(oldname, false);
+	cfgId = get_tsconfiguration_oid(oldname, false);
 
 	tup = SearchSysCacheCopy1(TSCONFIGOID, ObjectIdGetDatum(cfgId));
 
@@ -1626,7 +1626,7 @@ AlterTSConfigurationOwner(List *name, Oid newOwnerId)
 
 	rel = heap_open(TSConfigRelationId, RowExclusiveLock);
 
-	cfgId = TSConfigGetCfgid(name, false);
+	cfgId = get_tsconfiguration_oid(name, false);
 
 	tup = SearchSysCacheCopy1(TSCONFIGOID, ObjectIdGetDatum(cfgId));
 
@@ -1828,7 +1828,7 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
 	{
 		List	   *names = (List *) lfirst(c);
 
-		dictIds[i] = TSDictionaryGetDictid(names, false);
+		dictIds[i] = get_tsdictionary_oid(names, false);
 		i++;
 	}
 
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index 90d5c76..8745201 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -712,8 +712,8 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
 
 			/* Copy comment on constraint */
 			if ((inhRelation->options & CREATE_TABLE_LIKE_COMMENTS) &&
-				(comment = GetComment(GetConstraintByName(RelationGetRelid(relation),
-														  n->conname),
+				(comment = GetComment(get_constraint_oid(RelationGetRelid(relation),
+														  n->conname, false),
 									  ConstraintRelationId,
 									  0)) != NULL)
 			{
diff --git a/src/backend/rewrite/rewriteSupport.c b/src/backend/rewrite/rewriteSupport.c
index 27d21e3..ba503c4 100644
--- a/src/backend/rewrite/rewriteSupport.c
+++ b/src/backend/rewrite/rewriteSupport.c
@@ -17,9 +17,14 @@
 #include "access/heapam.h"
 #include "catalog/indexing.h"
 #include "catalog/pg_class.h"
+#include "catalog/pg_rewrite.h"
 #include "rewrite/rewriteSupport.h"
+#include "utils/fmgroids.h"
 #include "utils/inval.h"
+#include "utils/lsyscache.h"
+#include "utils/rel.h"
 #include "utils/syscache.h"
+#include "utils/tqual.h"
 
 
 /*
@@ -86,3 +91,82 @@ SetRelationRuleStatus(Oid relationId, bool relHasRules,
 	heap_freetuple(tuple);
 	heap_close(relationRelation, RowExclusiveLock);
 }
+
+/*
+ * Find rule oid.
+ *
+ * If missing_ok is false, throw an error if rule name not found.  If
+ * true, just return InvalidOid.
+ */
+Oid
+get_rule_oid(Oid relid, const char *rulename, bool missing_ok)
+{
+	HeapTuple	tuple;
+	Oid			ruleoid;
+
+	/* Find the rule's pg_rewrite tuple, get its OID */
+	tuple = SearchSysCache2(RULERELNAME,
+							ObjectIdGetDatum(relid),
+							PointerGetDatum(rulename));
+	if (!HeapTupleIsValid(tuple))
+	{
+		if (missing_ok)
+			return InvalidOid;
+		ereport(ERROR,
+				(errcode(ERRCODE_UNDEFINED_OBJECT),
+				 errmsg("rule \"%s\" for relation \"%s\" does not exist",
+						rulename, get_rel_name(relid))));
+	}
+	Assert(relid == ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class);
+	ruleoid = HeapTupleGetOid(tuple);
+	ReleaseSysCache(tuple);
+	return ruleoid;
+}
+
+/*
+ * Find rule oid, given only a rule name but no rel OID.
+ *
+ * If there's more than one, it's an error.  If there aren't any, that's an
+ * error, too.  In general, this should be avoided - it is provided to support
+ * syntax that is compatible with pre-7.3 versions of PG, where rule names
+ * were unique across the entire database.
+ */
+Oid
+get_rule_oid_without_relid(const char *rulename, Oid *reloid)
+{
+	Relation	RewriteRelation;
+	HeapScanDesc scanDesc;
+	ScanKeyData scanKeyData;
+	HeapTuple	htup;
+	Oid			ruleoid;
+
+	/* Search pg_rewrite for such a rule */
+	ScanKeyInit(&scanKeyData,
+				Anum_pg_rewrite_rulename,
+				BTEqualStrategyNumber, F_NAMEEQ,
+				CStringGetDatum(rulename));
+
+	RewriteRelation = heap_open(RewriteRelationId, AccessShareLock);
+	scanDesc = heap_beginscan(RewriteRelation, SnapshotNow, 1, &scanKeyData);
+
+	htup = heap_getnext(scanDesc, ForwardScanDirection);
+	if (!HeapTupleIsValid(htup))
+		ereport(ERROR,
+				(errcode(ERRCODE_UNDEFINED_OBJECT),
+				 errmsg("rule \"%s\" does not exist", rulename)));
+
+	ruleoid = HeapTupleGetOid(htup);
+	if (reloid != NULL)
+		*reloid = ((Form_pg_rewrite) GETSTRUCT(htup))->ev_class;
+
+	if (HeapTupleIsValid(htup = heap_getnext(scanDesc, ForwardScanDirection)))
+		ereport(ERROR,
+				(errcode(ERRCODE_DUPLICATE_OBJECT),
+				 errmsg("there are multiple rules named \"%s\"", rulename),
+				 errhint("Specify a relation name as well as a rule name.")));
+
+	heap_endscan(scanDesc);
+	heap_close(RewriteRelation, AccessShareLock);
+
+	return ruleoid;
+}
diff --git a/src/backend/tsearch/dict_thesaurus.c b/src/backend/tsearch/dict_thesaurus.c
index ee3c118..698a540 100644
--- a/src/backend/tsearch/dict_thesaurus.c
+++ b/src/backend/tsearch/dict_thesaurus.c
@@ -642,7 +642,7 @@ thesaurus_init(PG_FUNCTION_ARGS)
 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 				 errmsg("missing Dictionary parameter")));
 
-	d->subdictOid = TSDictionaryGetDictid(stringToQualifiedNameList(subdictname), false);
+	d->subdictOid = get_tsdictionary_oid(stringToQualifiedNameList(subdictname), false);
 	d->subdict = lookup_ts_dictionary_cache(d->subdictOid);
 
 	compileTheLexeme(d);
diff --git a/src/backend/tsearch/wparser.c b/src/backend/tsearch/wparser.c
index 0fed35c..2c41b34 100644
--- a/src/backend/tsearch/wparser.c
+++ b/src/backend/tsearch/wparser.c
@@ -134,7 +134,7 @@ ts_token_type_byname(PG_FUNCTION_ARGS)
 		Oid			prsId;
 
 		funcctx = SRF_FIRSTCALL_INIT();
-		prsId = TSParserGetPrsid(textToQualifiedNameList(prsname), false);
+		prsId = get_tsparser_oid(textToQualifiedNameList(prsname), false);
 		tt_setup_firstcall(funcctx, prsId);
 	}
 
@@ -282,7 +282,7 @@ ts_parse_byname(PG_FUNCTION_ARGS)
 		Oid			prsId;
 
 		funcctx = SRF_FIRSTCALL_INIT();
-		prsId = TSParserGetPrsid(textToQualifiedNameList(prsname), false);
+		prsId = get_tsparser_oid(textToQualifiedNameList(prsname), false);
 		prs_setup_firstcall(funcctx, prsId, txt);
 	}
 
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index 2450cc7..d30a184 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -1096,7 +1096,7 @@ regconfigin(PG_FUNCTION_ARGS)
 	 */
 	names = stringToQualifiedNameList(cfg_name_or_oid);
 
-	result = TSConfigGetCfgid(names, false);
+	result = get_tsconfiguration_oid(names, false);
 
 	PG_RETURN_OID(result);
 }
@@ -1206,7 +1206,7 @@ regdictionaryin(PG_FUNCTION_ARGS)
 	 */
 	names = stringToQualifiedNameList(dict_name_or_oid);
 
-	result = TSDictionaryGetDictid(names, false);
+	result = get_tsdictionary_oid(names, false);
 
 	PG_RETURN_OID(result);
 }
diff --git a/src/backend/utils/adt/tsvector_op.c b/src/backend/utils/adt/tsvector_op.c
index 78f08f4..4577874 100644
--- a/src/backend/utils/adt/tsvector_op.c
+++ b/src/backend/utils/adt/tsvector_op.c
@@ -1326,7 +1326,7 @@ tsvector_update_trigger(PG_FUNCTION_ARGS, bool config_column)
 					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 					 errmsg("text search configuration name \"%s\" must be schema-qualified",
 							trigger->tgargs[1])));
-		cfgId = TSConfigGetCfgid(names, false);
+		cfgId = get_tsconfiguration_oid(names, false);
 	}
 
 	/* initialize parse state */
diff --git a/src/backend/utils/cache/ts_cache.c b/src/backend/utils/cache/ts_cache.c
index 77d8e2f..e7c1240 100644
--- a/src/backend/utils/cache/ts_cache.c
+++ b/src/backend/utils/cache/ts_cache.c
@@ -581,7 +581,7 @@ getTSCurrentConfig(bool emitError)
 
 	/* Look up the config */
 	TSCurrentConfigCache =
-		TSConfigGetCfgid(stringToQualifiedNameList(TSCurrentConfig),
+		get_tsconfiguration_oid(stringToQualifiedNameList(TSCurrentConfig),
 						 !emitError);
 
 	return TSCurrentConfigCache;
@@ -601,7 +601,7 @@ assignTSCurrentConfig(const char *newval, bool doit, GucSource source)
 		Form_pg_ts_config cfg;
 		char	   *buf;
 
-		cfgId = TSConfigGetCfgid(stringToQualifiedNameList(newval), true);
+		cfgId = get_tsconfiguration_oid(stringToQualifiedNameList(newval), true);
 
 		if (!OidIsValid(cfgId))
 			return NULL;
diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h
index 0fd61a9..17510d8 100644
--- a/src/include/catalog/namespace.h
+++ b/src/include/catalog/namespace.h
@@ -74,16 +74,16 @@ extern bool OpfamilyIsVisible(Oid opfid);
 extern Oid	ConversionGetConid(const char *conname);
 extern bool ConversionIsVisible(Oid conid);
 
-extern Oid	TSParserGetPrsid(List *names, bool failOK);
+extern Oid	get_tsparser_oid(List *names, bool failOK);
 extern bool TSParserIsVisible(Oid prsId);
 
-extern Oid	TSDictionaryGetDictid(List *names, bool failOK);
+extern Oid	get_tsdictionary_oid(List *names, bool failOK);
 extern bool TSDictionaryIsVisible(Oid dictId);
 
-extern Oid	TSTemplateGetTmplid(List *names, bool failOK);
+extern Oid	get_tstemplate_oid(List *names, bool failOK);
 extern bool TSTemplateIsVisible(Oid tmplId);
 
-extern Oid	TSConfigGetCfgid(List *names, bool failOK);
+extern Oid	get_tsconfiguration_oid(List *names, bool failOK);
 extern bool TSConfigIsVisible(Oid cfgid);
 
 extern void DeconstructQualifiedName(List *names,
@@ -112,7 +112,7 @@ extern OverrideSearchPath *GetOverrideSearchPath(MemoryContext context);
 extern void PushOverrideSearchPath(OverrideSearchPath *newpath);
 extern void PopOverrideSearchPath(void);
 
-extern Oid	FindConversionByName(List *conname);
+extern Oid	get_conversion_oid(List *conname, bool missing_ok);
 extern Oid	FindDefaultConversionProc(int4 for_encoding, int4 to_encoding);
 
 /* initialization & transaction cleanup code */
diff --git a/src/include/catalog/pg_constraint.h b/src/include/catalog/pg_constraint.h
index c3dfcb0..83ca05f 100644
--- a/src/include/catalog/pg_constraint.h
+++ b/src/include/catalog/pg_constraint.h
@@ -237,6 +237,6 @@ extern char *ChooseConstraintName(const char *name1, const char *name2,
 
 extern void AlterConstraintNamespaces(Oid ownerId, Oid oldNspId,
 						  Oid newNspId, bool isType);
-extern Oid	GetConstraintByName(Oid relid, const char *conname);
+extern Oid	get_constraint_oid(Oid relid, const char *conname, bool missing_ok);
 
 #endif   /* PG_CONSTRAINT_H */
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index 54011a0..0518c9e 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -67,6 +67,7 @@ extern void DropCastById(Oid castOid);
 extern void AlterFunctionNamespace(List *name, List *argtypes, bool isagg,
 					   const char *newschema);
 extern void ExecuteDoStmt(DoStmt *stmt);
+extern Oid get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok);
 
 /* commands/operatorcmds.c */
 extern void DefineOperator(List *names, List *parameters);
@@ -75,6 +76,8 @@ extern void RemoveOperatorById(Oid operOid);
 extern void AlterOperatorOwner(List *name, TypeName *typeName1,
 				   TypeName *typename2, Oid newOwnerId);
 extern void AlterOperatorOwner_oid(Oid operOid, Oid newOwnerId);
+extern Oid get_opclass_oid(Oid amID, List *opclassname, bool missing_ok);
+extern Oid get_opfamily_oid(Oid amID, List *opfamilyname, bool missing_ok);
 
 /* commands/aggregatecmds.c */
 extern void DefineAggregate(List *name, List *args, bool oldstyle,
diff --git a/src/include/commands/trigger.h b/src/include/commands/trigger.h
index 98bc0c6..267a08e 100644
--- a/src/include/commands/trigger.h
+++ b/src/include/commands/trigger.h
@@ -111,6 +111,7 @@ extern Oid CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
 extern void DropTrigger(Oid relid, const char *trigname,
 			DropBehavior behavior, bool missing_ok);
 extern void RemoveTriggerById(Oid trigOid);
+extern Oid get_trigger_oid(Oid relid, const char *name, bool missing_ok);
 
 extern void renametrig(Oid relid, const char *oldname, const char *newname);
 
diff --git a/src/include/rewrite/rewriteSupport.h b/src/include/rewrite/rewriteSupport.h
index 7784d98..7dfe1fe 100644
--- a/src/include/rewrite/rewriteSupport.h
+++ b/src/include/rewrite/rewriteSupport.h
@@ -22,4 +22,7 @@ extern bool IsDefinedRewriteRule(Oid owningRel, const char *ruleName);
 extern void SetRelationRuleStatus(Oid relationId, bool relHasRules,
 					  bool relIsBecomingView);
 
+extern Oid get_rule_oid(Oid relid, const char *rulename, bool missing_ok);
+extern Oid get_rule_oid_without_relid(const char *rulename, Oid *relid);
+
 #endif   /* REWRITESUPPORT_H */
#2KaiGai Kohei
kaigai@ak.jp.nec.com
In reply to: Robert Haas (#1)
Re: get_whatever_oid, part 2

(2010/06/15 2:25), Robert Haas wrote:

Per previous discussion:

http://archives.postgresql.org/pgsql-hackers/2010-05/msg01195.php
http://archives.postgresql.org/pgsql-hackers/2010-05/msg01577.php

Changes in this patch:

- Rename TSParserGetPrsid to get_tsparser_oid, TSDictionaryGetDictid
to get_tsdictionary_oid, TSTemplateGetTmplid to get_tstemplate_oid,
TSConfigGetCfgid to get_tsconfiguration_oid, FindConversionByName to
get_conversion_oid, and GetConstraintName to get_constraint_oid.
- Add new functions get_opclass_oid, get_opfamily_oid, get_rule_oid,
get_rule_oid_without_relid, get_trigger_oid, and get_cast_oid.
- Refactor existing code to use these functions wherever possible.

I checked this patch. Then, I was surprised at we have such so many
code duplications. I believe this patch can effectively eliminate
these code duplications and it is worthful to apply.
However, here are some points to be fixed/revised.

1. [BUG] DropCast() does not handle missing_ok correctly.

| --- a/src/backend/commands/functioncmds.c
| +++ b/src/backend/commands/functioncmds.c
| @@ -1759,31 +1759,23 @@ DropCast(DropCastStmt *stmt)
| {
| Oid sourcetypeid;
| Oid targettypeid;
| - HeapTuple tuple;
| ObjectAddress object;
|
| /* when dropping a cast, the types must exist even if you use IF EXISTS */
| sourcetypeid = typenameTypeId(NULL, stmt->sourcetype, NULL);
| targettypeid = typenameTypeId(NULL, stmt->targettype, NULL);
|
| - tuple = SearchSysCache2(CASTSOURCETARGET,
| - ObjectIdGetDatum(sourcetypeid),
| - ObjectIdGetDatum(targettypeid));
| - if (!HeapTupleIsValid(tuple))
| + object.classId = CastRelationId;
| + object.objectId = get_cast_oid(sourcetypeid, targettypeid,
| + stmt->missing_ok);
| + object.objectSubId = 0;
| +
| + if (!OidIsValid(object.objectId))
| {
| - if (!stmt->missing_ok)
| - ereport(ERROR,
| - (errcode(ERRCODE_UNDEFINED_OBJECT),
| - errmsg("cast from type %s to type %s does not exist",
| - format_type_be(sourcetypeid),
| - format_type_be(targettypeid))));
| - else
| - ereport(NOTICE,
| + ereport(NOTICE,
| (errmsg("cast from type %s to type %s does not exist, skipping",
| format_type_be(sourcetypeid),
| format_type_be(targettypeid))));
| -
| - return;
| }
|
| /* Permission check */

You removed the 'return' on the path when get_cast_oid() with missing_ok = true
returned InvalidOid. It seems to me a bug to be fixed.

2. we can reduce more code duplications using get_opfamily_oid() and
get_opclass_oid().

I could find translations from a qualified name to schema/object names
at GetIndexOpClass(), RenameOpFamily() and AlterOpFamilyOwner().
The new APIs enable to eliminate code duplications here.

GetIndexOpClass() needs input type of the operator class, in addition
to its OID, but it can be obtained using get_opclass_input_type().
RenameOpFamily() and AlterOpFamilyOwner() need a copy of the operator
family tuple, in addition to its OID, but it can be obtained using
GetSysCacheCopy1(OPFAMILYOID).

3. Are OpClassCacheLookup() and OpFamilyCacheLookup() still needed?

The OpFamilyCacheLookup() is only called from RemoveOpFamily()
except for the get_opfamily_oid(), because it needs namespace OID
in addition to the OID of operator family.
If we have get_opfamily_namespace() in lsyscache.c, we can merge
get_opfamily_oid() and OpFamilyCacheLookup() completely?

The OpClassCacheLookup() is only called from RemoveOpClass(),
RenameOpClass() and AlterOpClassOwner(), because RemoveOpClass()
needs namespace OID in addition to the OID of operator class,
and rest of them want to copy the HeapTuple to update it.
If we have get_opclass_namespace() in lsyscache.c, RemoveOpClass()
can use get_opclass_oid() instead of OpClassCacheLookup().
And, we can use a pair of get_opclass_oid() and GetSysCacheCopy1()
instead of OpClassCacheLookup() and heap_copytuple() in the
RenameOpClass() and AlterOpClassOwner().

4. Name of the arguments incorrect.

| --- a/src/include/catalog/namespace.h
| +++ b/src/include/catalog/namespace.h
| @@ -74,16 +74,16 @@ extern bool OpfamilyIsVisible(Oid opfid);
| extern Oid ConversionGetConid(const char *conname);
| extern bool ConversionIsVisible(Oid conid);
|
| -extern Oid TSParserGetPrsid(List *names, bool failOK);
| +extern Oid get_tsparser_oid(List *names, bool failOK);
| extern bool TSParserIsVisible(Oid prsId);
|
| -extern Oid TSDictionaryGetDictid(List *names, bool failOK);
| +extern Oid get_tsdictionary_oid(List *names, bool failOK);
| extern bool TSDictionaryIsVisible(Oid dictId);
|
| -extern Oid TSTemplateGetTmplid(List *names, bool failOK);
| +extern Oid get_tstemplate_oid(List *names, bool failOK);
| extern bool TSTemplateIsVisible(Oid tmplId);
|
| -extern Oid TSConfigGetCfgid(List *names, bool failOK);
| +extern Oid get_tsconfiguration_oid(List *names, bool failOK);
| extern bool TSConfigIsVisible(Oid cfgid);
|
| extern void DeconstructQualifiedName(List *names,

It seems to me 'missing_ok', instead of 'failOK'. :D

Thanks,
--
KaiGai Kohei <kaigai@ak.jp.nec.com>

#3Robert Haas
robertmhaas@gmail.com
In reply to: KaiGai Kohei (#2)
1 attachment(s)
Re: get_whatever_oid, part 2

2010/7/5 KaiGai Kohei <kaigai@ak.jp.nec.com>:

I checked this patch. Then, I was surprised at we have such so many
code duplications. I believe this patch can effectively eliminate
these code duplications and it is worthful to apply.
However, here are some points to be fixed/revised.

1. [BUG] DropCast() does not handle missing_ok correctly.

You removed the 'return' on the path when get_cast_oid() with missing_ok = true
returned InvalidOid. It seems to me a bug to be fixed.

Good catch. Fixed.

2. we can reduce more code duplications using get_opfamily_oid() and
  get_opclass_oid().

I could find translations from a qualified name to schema/object names
at GetIndexOpClass(), RenameOpFamily() and AlterOpFamilyOwner().
The new APIs enable to eliminate code duplications here.

GetIndexOpClass() needs input type of the operator class, in addition
to its OID, but it can be obtained using get_opclass_input_type().
RenameOpFamily() and AlterOpFamilyOwner() need a copy of the operator
family tuple, in addition to its OID, but it can be obtained using
GetSysCacheCopy1(OPFAMILYOID).

I don't believe this is a good idea. We don't want to do extra
syscache lookups just so that we can make the code look nicer.

3. Are OpClassCacheLookup() and OpFamilyCacheLookup() still needed?

The OpFamilyCacheLookup() is only called from RemoveOpFamily()
except for the get_opfamily_oid(), because it needs namespace OID
in addition to the OID of operator family.
If we have get_opfamily_namespace() in lsyscache.c, we can merge
get_opfamily_oid() and OpFamilyCacheLookup() completely?

The OpClassCacheLookup() is only called from RemoveOpClass(),
RenameOpClass() and AlterOpClassOwner(), because RemoveOpClass()
needs namespace OID in addition to the OID of operator class,
and rest of them want to copy the HeapTuple to update it.
If we have get_opclass_namespace() in lsyscache.c, RemoveOpClass()
can use get_opclass_oid() instead of OpClassCacheLookup().
And, we can use a pair of get_opclass_oid() and GetSysCacheCopy1()
instead of OpClassCacheLookup() and heap_copytuple() in the
RenameOpClass() and AlterOpClassOwner().

Same thing here. I left that stuff alone on purpose.

4. Name of the arguments incorrect.

It seems to me 'missing_ok', instead of 'failOK'. :D

Yeah, that's an oversight on my part. Fixed.

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

Attachments:

get_whatever_oid_part2-v2.patchapplication/octet-stream; name=get_whatever_oid_part2-v2.patchDownload
diff --git a/contrib/tsearch2/tsearch2.c b/contrib/tsearch2/tsearch2.c
index d421f77..e4e2014 100644
--- a/contrib/tsearch2/tsearch2.c
+++ b/contrib/tsearch2/tsearch2.c
@@ -190,7 +190,7 @@ tsa_set_curdict_byname(PG_FUNCTION_ARGS)
 	text	   *name = PG_GETARG_TEXT_PP(0);
 	Oid			dict_oid;
 
-	dict_oid = TSDictionaryGetDictid(stringToQualifiedNameList(text_to_cstring(name)), false);
+	dict_oid = get_tsdictionary_oid(stringToQualifiedNameList(text_to_cstring(name)), false);
 
 	current_dictionary_oid = dict_oid;
 
@@ -229,7 +229,7 @@ tsa_set_curprs_byname(PG_FUNCTION_ARGS)
 	text	   *name = PG_GETARG_TEXT_PP(0);
 	Oid			parser_oid;
 
-	parser_oid = TSParserGetPrsid(stringToQualifiedNameList(text_to_cstring(name)), false);
+	parser_oid = get_tsparser_oid(stringToQualifiedNameList(text_to_cstring(name)), false);
 
 	current_parser_oid = parser_oid;
 
@@ -562,6 +562,6 @@ static Oid
 GetCurrentParser(void)
 {
 	if (current_parser_oid == InvalidOid)
-		current_parser_oid = TSParserGetPrsid(stringToQualifiedNameList("pg_catalog.default"), false);
+		current_parser_oid = get_tsparser_oid(stringToQualifiedNameList("pg_catalog.default"), false);
 	return current_parser_oid;
 }
diff --git a/contrib/unaccent/unaccent.c b/contrib/unaccent/unaccent.c
index 0a29bba..d7b9c39 100644
--- a/contrib/unaccent/unaccent.c
+++ b/contrib/unaccent/unaccent.c
@@ -279,7 +279,7 @@ unaccent_dict(PG_FUNCTION_ARGS)
 
 	if (PG_NARGS() == 1)
 	{
-		dictOid = TSDictionaryGetDictid(stringToQualifiedNameList("unaccent"), false);
+		dictOid = get_tsdictionary_oid(stringToQualifiedNameList("unaccent"), false);
 		strArg = 0;
 	}
 	else
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 52acc23..71b140a 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -1692,12 +1692,12 @@ ConversionIsVisible(Oid conid)
 }
 
 /*
- * TSParserGetPrsid - find a TS parser by possibly qualified name
+ * get_tsparser_oid - find a TS parser by possibly qualified name
  *
- * If not found, returns InvalidOid if failOK, else throws error
+ * If not found, returns InvalidOid if missing_ok, else throws error
  */
 Oid
-TSParserGetPrsid(List *names, bool failOK)
+get_tsparser_oid(List *names, bool missing_ok)
 {
 	char	   *schemaname;
 	char	   *parser_name;
@@ -1736,7 +1736,7 @@ TSParserGetPrsid(List *names, bool failOK)
 		}
 	}
 
-	if (!OidIsValid(prsoid) && !failOK)
+	if (!OidIsValid(prsoid) && !missing_ok)
 		ereport(ERROR,
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 				 errmsg("text search parser \"%s\" does not exist",
@@ -1815,12 +1815,12 @@ TSParserIsVisible(Oid prsId)
 }
 
 /*
- * TSDictionaryGetDictid - find a TS dictionary by possibly qualified name
+ * get_tsdictionary_oid - find a TS dictionary by possibly qualified name
  *
  * If not found, returns InvalidOid if failOK, else throws error
  */
 Oid
-TSDictionaryGetDictid(List *names, bool failOK)
+get_tsdictionary_oid(List *names, bool missing_ok)
 {
 	char	   *schemaname;
 	char	   *dict_name;
@@ -1859,7 +1859,7 @@ TSDictionaryGetDictid(List *names, bool failOK)
 		}
 	}
 
-	if (!OidIsValid(dictoid) && !failOK)
+	if (!OidIsValid(dictoid) && !missing_ok)
 		ereport(ERROR,
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 				 errmsg("text search dictionary \"%s\" does not exist",
@@ -1939,12 +1939,12 @@ TSDictionaryIsVisible(Oid dictId)
 }
 
 /*
- * TSTemplateGetTmplid - find a TS template by possibly qualified name
+ * get_tstemplate_oid - find a TS template by possibly qualified name
  *
- * If not found, returns InvalidOid if failOK, else throws error
+ * If not found, returns InvalidOid if missing_ok, else throws error
  */
 Oid
-TSTemplateGetTmplid(List *names, bool failOK)
+get_tstemplate_oid(List *names, bool missing_ok)
 {
 	char	   *schemaname;
 	char	   *template_name;
@@ -1983,7 +1983,7 @@ TSTemplateGetTmplid(List *names, bool failOK)
 		}
 	}
 
-	if (!OidIsValid(tmploid) && !failOK)
+	if (!OidIsValid(tmploid) && !missing_ok)
 		ereport(ERROR,
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 				 errmsg("text search template \"%s\" does not exist",
@@ -2062,12 +2062,12 @@ TSTemplateIsVisible(Oid tmplId)
 }
 
 /*
- * TSConfigGetCfgid - find a TS config by possibly qualified name
+ * get_tsconfiguration_oid - find a TS config by possibly qualified name
  *
- * If not found, returns InvalidOid if failOK, else throws error
+ * If not found, returns InvalidOid if missing_ok, else throws error
  */
 Oid
-TSConfigGetCfgid(List *names, bool failOK)
+get_tsconfiguration_oid(List *names, bool missing_ok)
 {
 	char	   *schemaname;
 	char	   *config_name;
@@ -2106,7 +2106,7 @@ TSConfigGetCfgid(List *names, bool failOK)
 		}
 	}
 
-	if (!OidIsValid(cfgoid) && !failOK)
+	if (!OidIsValid(cfgoid) && !missing_ok)
 		ereport(ERROR,
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 				 errmsg("text search configuration \"%s\" does not exist",
@@ -2766,15 +2766,15 @@ PopOverrideSearchPath(void)
 
 
 /*
- * FindConversionByName - find a conversion by possibly qualified name
+ * get_conversion_oid - find a conversion by possibly qualified name
  */
 Oid
-FindConversionByName(List *name)
+get_conversion_oid(List *name, bool missing_ok)
 {
 	char	   *schemaname;
 	char	   *conversion_name;
 	Oid			namespaceId;
-	Oid			conoid;
+	Oid			conoid = InvalidOid;
 	ListCell   *l;
 
 	/* deconstruct the name list */
@@ -2784,9 +2784,9 @@ FindConversionByName(List *name)
 	{
 		/* use exact schema given */
 		namespaceId = LookupExplicitNamespace(schemaname);
-		return GetSysCacheOid2(CONNAMENSP,
-							   PointerGetDatum(conversion_name),
-							   ObjectIdGetDatum(namespaceId));
+		conoid = GetSysCacheOid2(CONNAMENSP,
+								 PointerGetDatum(conversion_name),
+								 ObjectIdGetDatum(namespaceId));
 	}
 	else
 	{
@@ -2809,7 +2809,12 @@ FindConversionByName(List *name)
 	}
 
 	/* Not found in path */
-	return InvalidOid;
+	if (!OidIsValid(conoid) && !missing_ok)
+		ereport(ERROR,
+				(errcode(ERRCODE_UNDEFINED_OBJECT),
+				 errmsg("conversion \"%s\" does not exist",
+						NameListToString(name))));
+	return conoid;
 }
 
 /*
diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c
index 2cfd453..256974b 100644
--- a/src/backend/catalog/pg_constraint.c
+++ b/src/backend/catalog/pg_constraint.c
@@ -727,12 +727,12 @@ AlterConstraintNamespaces(Oid ownerId, Oid oldNspId,
 }
 
 /*
- * GetConstraintByName
+ * get_constraint_oid
  *		Find a constraint on the specified relation with the specified name.
  *		Returns constraint's OID.
  */
 Oid
-GetConstraintByName(Oid relid, const char *conname)
+get_constraint_oid(Oid relid, const char *conname, bool missing_ok)
 {
 	Relation	pg_constraint;
 	HeapTuple	tuple;
@@ -773,7 +773,7 @@ GetConstraintByName(Oid relid, const char *conname)
 	systable_endscan(scan);
 
 	/* If no such constraint exists, complain */
-	if (!OidIsValid(conOid))
+	if (!OidIsValid(conOid) && !missing_ok)
 		ereport(ERROR,
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 				 errmsg("constraint \"%s\" for table \"%s\" does not exist",
diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c
index 2ba2368..93e0b13 100644
--- a/src/backend/commands/comment.c
+++ b/src/backend/commands/comment.c
@@ -45,12 +45,14 @@
 #include "commands/defrem.h"
 #include "commands/proclang.h"
 #include "commands/tablespace.h"
+#include "commands/trigger.h"
 #include "libpq/be-fsstubs.h"
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "parser/parse_func.h"
 #include "parser/parse_oper.h"
 #include "parser/parse_type.h"
+#include "rewrite/rewriteSupport.h"
 #include "utils/acl.h"
 #include "utils/builtins.h"
 #include "utils/fmgroids.h"
@@ -826,7 +828,6 @@ CommentRule(List *qualname, char *comment)
 	char	   *rulename;
 	RangeVar   *rel;
 	Relation	relation;
-	HeapTuple	tuple;
 	Oid			reloid;
 	Oid			ruleoid;
 
@@ -834,46 +835,8 @@ CommentRule(List *qualname, char *comment)
 	nnames = list_length(qualname);
 	if (nnames == 1)
 	{
-		/* Old-style: only a rule name is given */
-		Relation	RewriteRelation;
-		HeapScanDesc scanDesc;
-		ScanKeyData scanKeyData;
-
 		rulename = strVal(linitial(qualname));
-
-		/* Search pg_rewrite for such a rule */
-		ScanKeyInit(&scanKeyData,
-					Anum_pg_rewrite_rulename,
-					BTEqualStrategyNumber, F_NAMEEQ,
-					PointerGetDatum(rulename));
-
-		RewriteRelation = heap_open(RewriteRelationId, AccessShareLock);
-		scanDesc = heap_beginscan(RewriteRelation, SnapshotNow,
-								  1, &scanKeyData);
-
-		tuple = heap_getnext(scanDesc, ForwardScanDirection);
-		if (HeapTupleIsValid(tuple))
-		{
-			reloid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class;
-			ruleoid = HeapTupleGetOid(tuple);
-		}
-		else
-		{
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("rule \"%s\" does not exist", rulename)));
-			reloid = ruleoid = 0;		/* keep compiler quiet */
-		}
-
-		if (HeapTupleIsValid(tuple = heap_getnext(scanDesc,
-												  ForwardScanDirection)))
-			ereport(ERROR,
-					(errcode(ERRCODE_DUPLICATE_OBJECT),
-				   errmsg("there are multiple rules named \"%s\"", rulename),
-				errhint("Specify a relation name as well as a rule name.")));
-
-		heap_endscan(scanDesc);
-		heap_close(RewriteRelation, AccessShareLock);
+		ruleoid = get_rule_oid_without_relid(rulename, &reloid);
 
 		/* Open the owning relation to ensure it won't go away meanwhile */
 		relation = heap_open(reloid, AccessShareLock);
@@ -891,17 +854,7 @@ CommentRule(List *qualname, char *comment)
 		reloid = RelationGetRelid(relation);
 
 		/* Find the rule's pg_rewrite tuple, get its OID */
-		tuple = SearchSysCache2(RULERELNAME,
-								ObjectIdGetDatum(reloid),
-								PointerGetDatum(rulename));
-		if (!HeapTupleIsValid(tuple))
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("rule \"%s\" for relation \"%s\" does not exist",
-							rulename, RelationGetRelationName(relation))));
-		Assert(reloid == ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class);
-		ruleoid = HeapTupleGetOid(tuple);
-		ReleaseSysCache(tuple);
+		ruleoid = get_rule_oid(reloid, rulename, false);
 	}
 
 	/* Check object security */
@@ -1046,11 +999,7 @@ CommentTrigger(List *qualname, char *comment)
 	List	   *relname;
 	char	   *trigname;
 	RangeVar   *rel;
-	Relation	pg_trigger,
-				relation;
-	HeapTuple	triggertuple;
-	SysScanDesc scan;
-	ScanKeyData entry[2];
+	Relation	relation;
 	Oid			oid;
 
 	/* Separate relname and trig name */
@@ -1065,46 +1014,16 @@ CommentTrigger(List *qualname, char *comment)
 	relation = heap_openrv(rel, AccessShareLock);
 
 	/* Check object security */
-
 	if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
 					   RelationGetRelationName(relation));
 
-	/*
-	 * Fetch the trigger tuple from pg_trigger.  There can be only one because
-	 * of the unique index.
-	 */
-	pg_trigger = heap_open(TriggerRelationId, AccessShareLock);
-	ScanKeyInit(&entry[0],
-				Anum_pg_trigger_tgrelid,
-				BTEqualStrategyNumber, F_OIDEQ,
-				ObjectIdGetDatum(RelationGetRelid(relation)));
-	ScanKeyInit(&entry[1],
-				Anum_pg_trigger_tgname,
-				BTEqualStrategyNumber, F_NAMEEQ,
-				CStringGetDatum(trigname));
-	scan = systable_beginscan(pg_trigger, TriggerRelidNameIndexId, true,
-							  SnapshotNow, 2, entry);
-	triggertuple = systable_getnext(scan);
-
-	/* If no trigger exists for the relation specified, notify user */
-
-	if (!HeapTupleIsValid(triggertuple))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("trigger \"%s\" for table \"%s\" does not exist",
-						trigname, RelationGetRelationName(relation))));
-
-	oid = HeapTupleGetOid(triggertuple);
-
-	systable_endscan(scan);
+	oid = get_trigger_oid(RelationGetRelid(relation), trigname, false);
 
 	/* Call CreateComments() to create/drop the comments */
 	CreateComments(oid, TriggerRelationId, 0, comment);
 
 	/* Done, but hold lock on relation */
-
-	heap_close(pg_trigger, AccessShareLock);
 	heap_close(relation, NoLock);
 }
 
@@ -1143,7 +1062,7 @@ CommentConstraint(List *qualname, char *comment)
 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
 					   RelationGetRelationName(relation));
 
-	conOid = GetConstraintByName(RelationGetRelid(relation), conName);
+	conOid = get_constraint_oid(RelationGetRelid(relation), conName, false);
 
 	/* Call CreateComments() to create/drop the comments */
 	CreateComments(conOid, ConstraintRelationId, 0, comment);
@@ -1166,12 +1085,7 @@ CommentConversion(List *qualname, char *comment)
 {
 	Oid			conversionOid;
 
-	conversionOid = FindConversionByName(qualname);
-	if (!OidIsValid(conversionOid))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("conversion \"%s\" does not exist",
-						NameListToString(qualname))));
+	conversionOid = get_conversion_oid(qualname, false);
 
 	/* Check object security */
 	if (!pg_conversion_ownercheck(conversionOid, GetUserId()))
@@ -1228,65 +1142,23 @@ static void
 CommentOpClass(List *qualname, List *arguments, char *comment)
 {
 	char	   *amname;
-	char	   *schemaname;
-	char	   *opcname;
 	Oid			amID;
 	Oid			opcID;
-	HeapTuple	tuple;
 
 	Assert(list_length(arguments) == 1);
 	amname = strVal(linitial(arguments));
 
 	/*
-	 * Get the access method's OID.
+	 * Get the operator class OID.
 	 */
 	amID = get_am_oid(amname, false);
-
-	/*
-	 * Look up the opclass.
-	 */
-
-	/* deconstruct the name list */
-	DeconstructQualifiedName(qualname, &schemaname, &opcname);
-
-	if (schemaname)
-	{
-		/* Look in specific schema only */
-		Oid			namespaceId;
-
-		namespaceId = LookupExplicitNamespace(schemaname);
-		tuple = SearchSysCache3(CLAAMNAMENSP,
-								ObjectIdGetDatum(amID),
-								PointerGetDatum(opcname),
-								ObjectIdGetDatum(namespaceId));
-	}
-	else
-	{
-		/* Unqualified opclass name, so search the search path */
-		opcID = OpclassnameGetOpcid(amID, opcname);
-		if (!OidIsValid(opcID))
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
-							opcname, amname)));
-		tuple = SearchSysCache1(CLAOID, ObjectIdGetDatum(opcID));
-	}
-
-	if (!HeapTupleIsValid(tuple))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
-						NameListToString(qualname), amname)));
-
-	opcID = HeapTupleGetOid(tuple);
+	opcID = get_opclass_oid(amID, qualname, false);
 
 	/* Permission check: must own opclass */
 	if (!pg_opclass_ownercheck(opcID, GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPCLASS,
 					   NameListToString(qualname));
 
-	ReleaseSysCache(tuple);
-
 	/* Call CreateComments() to create/drop the comments */
 	CreateComments(opcID, OperatorClassRelationId, 0, comment);
 }
@@ -1304,65 +1176,21 @@ static void
 CommentOpFamily(List *qualname, List *arguments, char *comment)
 {
 	char	   *amname;
-	char	   *schemaname;
-	char	   *opfname;
 	Oid			amID;
 	Oid			opfID;
-	HeapTuple	tuple;
 
 	Assert(list_length(arguments) == 1);
 	amname = strVal(linitial(arguments));
 
-	/*
-	 * Get the access method's OID.
-	 */
+	/* Get the opfamily OID. */
 	amID = get_am_oid(amname, false);
-
-	/*
-	 * Look up the opfamily.
-	 */
-
-	/* deconstruct the name list */
-	DeconstructQualifiedName(qualname, &schemaname, &opfname);
-
-	if (schemaname)
-	{
-		/* Look in specific schema only */
-		Oid			namespaceId;
-
-		namespaceId = LookupExplicitNamespace(schemaname);
-		tuple = SearchSysCache3(OPFAMILYAMNAMENSP,
-								ObjectIdGetDatum(amID),
-								PointerGetDatum(opfname),
-								ObjectIdGetDatum(namespaceId));
-	}
-	else
-	{
-		/* Unqualified opfamily name, so search the search path */
-		opfID = OpfamilynameGetOpfid(amID, opfname);
-		if (!OidIsValid(opfID))
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator family \"%s\" does not exist for access method \"%s\"",
-							opfname, amname)));
-		tuple = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfID));
-	}
-
-	if (!HeapTupleIsValid(tuple))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("operator family \"%s\" does not exist for access method \"%s\"",
-						NameListToString(qualname), amname)));
-
-	opfID = HeapTupleGetOid(tuple);
+	opfID = get_opfamily_oid(amID, qualname, false);
 
 	/* Permission check: must own opfamily */
 	if (!pg_opfamily_ownercheck(opfID, GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPFAMILY,
 					   NameListToString(qualname));
 
-	ReleaseSysCache(tuple);
-
 	/* Call CreateComments() to create/drop the comments */
 	CreateComments(opfID, OperatorFamilyRelationId, 0, comment);
 }
@@ -1423,7 +1251,6 @@ CommentCast(List *qualname, List *arguments, char *comment)
 	TypeName   *targettype;
 	Oid			sourcetypeid;
 	Oid			targettypeid;
-	HeapTuple	tuple;
 	Oid			castOid;
 
 	Assert(list_length(qualname) == 1);
@@ -1436,18 +1263,8 @@ CommentCast(List *qualname, List *arguments, char *comment)
 	sourcetypeid = typenameTypeId(NULL, sourcetype, NULL);
 	targettypeid = typenameTypeId(NULL, targettype, NULL);
 
-	tuple = SearchSysCache2(CASTSOURCETARGET,
-							ObjectIdGetDatum(sourcetypeid),
-							ObjectIdGetDatum(targettypeid));
-	if (!HeapTupleIsValid(tuple))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("cast from type %s to type %s does not exist",
-						format_type_be(sourcetypeid),
-						format_type_be(targettypeid))));
-
 	/* Get the OID of the cast */
-	castOid = HeapTupleGetOid(tuple);
+	castOid = get_cast_oid(sourcetypeid, targettypeid, false);
 
 	/* Permission check */
 	if (!pg_type_ownercheck(sourcetypeid, GetUserId())
@@ -1458,8 +1275,6 @@ CommentCast(List *qualname, List *arguments, char *comment)
 						format_type_be(sourcetypeid),
 						format_type_be(targettypeid))));
 
-	ReleaseSysCache(tuple);
-
 	/* Call CreateComments() to create/drop the comments */
 	CreateComments(castOid, CastRelationId, 0, comment);
 }
@@ -1469,7 +1284,7 @@ CommentTSParser(List *qualname, char *comment)
 {
 	Oid			prsId;
 
-	prsId = TSParserGetPrsid(qualname, false);
+	prsId = get_tsparser_oid(qualname, false);
 
 	if (!superuser())
 		ereport(ERROR,
@@ -1484,7 +1299,7 @@ CommentTSDictionary(List *qualname, char *comment)
 {
 	Oid			dictId;
 
-	dictId = TSDictionaryGetDictid(qualname, false);
+	dictId = get_tsdictionary_oid(qualname, false);
 
 	if (!pg_ts_dict_ownercheck(dictId, GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSDICTIONARY,
@@ -1498,7 +1313,7 @@ CommentTSTemplate(List *qualname, char *comment)
 {
 	Oid			tmplId;
 
-	tmplId = TSTemplateGetTmplid(qualname, false);
+	tmplId = get_tstemplate_oid(qualname, false);
 
 	if (!superuser())
 		ereport(ERROR,
@@ -1513,7 +1328,7 @@ CommentTSConfiguration(List *qualname, char *comment)
 {
 	Oid			cfgId;
 
-	cfgId = TSConfigGetCfgid(qualname, false);
+	cfgId = get_tsconfiguration_oid(qualname, false);
 
 	if (!pg_ts_config_ownercheck(cfgId, GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSCONFIGURATION,
diff --git a/src/backend/commands/conversioncmds.c b/src/backend/commands/conversioncmds.c
index 57ddab0..350abf2 100644
--- a/src/backend/commands/conversioncmds.c
+++ b/src/backend/commands/conversioncmds.c
@@ -142,23 +142,13 @@ DropConversionsCommand(DropStmt *drop)
 		Form_pg_conversion con;
 		ObjectAddress object;
 
-		conversionOid = FindConversionByName(name);
+		conversionOid = get_conversion_oid(name, drop->missing_ok);
 
 		if (!OidIsValid(conversionOid))
 		{
-			if (!drop->missing_ok)
-			{
-				ereport(ERROR,
-						(errcode(ERRCODE_UNDEFINED_OBJECT),
-						 errmsg("conversion \"%s\" does not exist",
-								NameListToString(name))));
-			}
-			else
-			{
-				ereport(NOTICE,
-						(errmsg("conversion \"%s\" does not exist, skipping",
-								NameListToString(name))));
-			}
+			ereport(NOTICE,
+					(errmsg("conversion \"%s\" does not exist, skipping",
+							NameListToString(name))));
 			continue;
 		}
 
@@ -202,12 +192,7 @@ RenameConversion(List *name, const char *newname)
 
 	rel = heap_open(ConversionRelationId, RowExclusiveLock);
 
-	conversionOid = FindConversionByName(name);
-	if (!OidIsValid(conversionOid))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("conversion \"%s\" does not exist",
-						NameListToString(name))));
+	conversionOid = get_conversion_oid(name, false);
 
 	tup = SearchSysCacheCopy1(CONVOID, ObjectIdGetDatum(conversionOid));
 	if (!HeapTupleIsValid(tup)) /* should not happen */
@@ -255,12 +240,7 @@ AlterConversionOwner(List *name, Oid newOwnerId)
 
 	rel = heap_open(ConversionRelationId, RowExclusiveLock);
 
-	conversionOid = FindConversionByName(name);
-	if (!OidIsValid(conversionOid))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("conversion \"%s\" does not exist",
-						NameListToString(name))));
+	conversionOid = get_conversion_oid(name, false);
 
 	AlterConversionOwner_internal(rel, conversionOid, newOwnerId);
 
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 9a584ed..781b72d 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -1759,30 +1759,23 @@ DropCast(DropCastStmt *stmt)
 {
 	Oid			sourcetypeid;
 	Oid			targettypeid;
-	HeapTuple	tuple;
 	ObjectAddress object;
 
 	/* when dropping a cast, the types must exist even if you use IF EXISTS */
 	sourcetypeid = typenameTypeId(NULL, stmt->sourcetype, NULL);
 	targettypeid = typenameTypeId(NULL, stmt->targettype, NULL);
 
-	tuple = SearchSysCache2(CASTSOURCETARGET,
-							ObjectIdGetDatum(sourcetypeid),
-							ObjectIdGetDatum(targettypeid));
-	if (!HeapTupleIsValid(tuple))
+	object.classId = CastRelationId;
+	object.objectId = get_cast_oid(sourcetypeid, targettypeid,
+								   stmt->missing_ok);
+	object.objectSubId = 0;
+
+	if (!OidIsValid(object.objectId))
 	{
-		if (!stmt->missing_ok)
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("cast from type %s to type %s does not exist",
-							format_type_be(sourcetypeid),
-							format_type_be(targettypeid))));
-		else
-			ereport(NOTICE,
+		ereport(NOTICE,
 			 (errmsg("cast from type %s to type %s does not exist, skipping",
 					 format_type_be(sourcetypeid),
 					 format_type_be(targettypeid))));
-
 		return;
 	}
 
@@ -1798,15 +1791,31 @@ DropCast(DropCastStmt *stmt)
 	/*
 	 * Do the deletion
 	 */
-	object.classId = CastRelationId;
-	object.objectId = HeapTupleGetOid(tuple);
-	object.objectSubId = 0;
-
-	ReleaseSysCache(tuple);
-
 	performDeletion(&object, stmt->behavior);
 }
 
+/*
+ * get_cast_oid - given two type OIDs, look up a cast OID
+ *
+ * If missing_ok is false, throw an error if the cast is not found.  If
+ * true, just return InvalidOid.
+ */
+Oid
+get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok)
+{
+	Oid		oid;
+
+	oid = GetSysCacheOid2(CASTSOURCETARGET,
+						  ObjectIdGetDatum(sourcetypeid),
+						  ObjectIdGetDatum(targettypeid));
+	if (!OidIsValid(oid) && !missing_ok)
+		ereport(ERROR,
+				(errcode(ERRCODE_UNDEFINED_OBJECT),
+				 errmsg("cast from type %s to type %s does not exist",
+						format_type_be(sourcetypeid),
+						format_type_be(targettypeid))));
+	return oid;
+}
 
 void
 DropCastById(Oid castOid)
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index d2d9f3a..046e14d 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -90,10 +90,11 @@ static void AlterOpFamilyOwner_internal(Relation rel, HeapTuple tuple,
  * Returns a syscache tuple reference, or NULL if not found.
  */
 static HeapTuple
-OpFamilyCacheLookup(Oid amID, List *opfamilyname)
+OpFamilyCacheLookup(Oid amID, List *opfamilyname, bool missing_ok)
 {
 	char	   *schemaname;
 	char	   *opfname;
+	HeapTuple	htup;
 
 	/* deconstruct the name list */
 	DeconstructQualifiedName(opfamilyname, &schemaname, &opfname);
@@ -104,7 +105,7 @@ OpFamilyCacheLookup(Oid amID, List *opfamilyname)
 		Oid			namespaceId;
 
 		namespaceId = LookupExplicitNamespace(schemaname);
-		return SearchSysCache3(OPFAMILYAMNAMENSP,
+		htup = SearchSysCache3(OPFAMILYAMNAMENSP,
 							   ObjectIdGetDatum(amID),
 							   PointerGetDatum(opfname),
 							   ObjectIdGetDatum(namespaceId));
@@ -115,9 +116,47 @@ OpFamilyCacheLookup(Oid amID, List *opfamilyname)
 		Oid			opfID = OpfamilynameGetOpfid(amID, opfname);
 
 		if (!OidIsValid(opfID))
-			return NULL;
-		return SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfID));
+			htup = NULL;
+		else
+			htup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfID));
+	}
+
+	if (!HeapTupleIsValid(htup) && !missing_ok)
+	{
+		HeapTuple amtup;
+
+		amtup = SearchSysCache1(AMOID, ObjectIdGetDatum(amID));
+		if (!HeapTupleIsValid(amtup))
+			elog(ERROR, "cache lookup failed for access method %u", amID);
+		ereport(ERROR,
+				(errcode(ERRCODE_UNDEFINED_OBJECT),
+				 errmsg("operator family \"%s\" does not exist for access method \"%s\"",
+				   NameListToString(opfamilyname),
+				   NameStr(((Form_pg_am) GETSTRUCT(amtup))->amname))));
 	}
+
+	return htup;
+}
+
+/*
+ * get_opfamily_oid
+ *    find an opfamily OID by possibly qualified name
+ *
+ * If not found, returns InvalidOid if missing_ok, else throws error.
+ */
+Oid
+get_opfamily_oid(Oid amID, List *opfamilyname, bool missing_ok)
+{
+	HeapTuple	htup;
+	Oid			opfID;
+
+	htup = OpFamilyCacheLookup(amID, opfamilyname, missing_ok);
+	if (!HeapTupleIsValid(htup))
+		return InvalidOid;
+	opfID = HeapTupleGetOid(htup);
+	ReleaseSysCache(htup);
+
+	return opfID;
 }
 
 /*
@@ -127,10 +166,11 @@ OpFamilyCacheLookup(Oid amID, List *opfamilyname)
  * Returns a syscache tuple reference, or NULL if not found.
  */
 static HeapTuple
-OpClassCacheLookup(Oid amID, List *opclassname)
+OpClassCacheLookup(Oid amID, List *opclassname, bool missing_ok)
 {
 	char	   *schemaname;
 	char	   *opcname;
+	HeapTuple	htup;
 
 	/* deconstruct the name list */
 	DeconstructQualifiedName(opclassname, &schemaname, &opcname);
@@ -141,7 +181,7 @@ OpClassCacheLookup(Oid amID, List *opclassname)
 		Oid			namespaceId;
 
 		namespaceId = LookupExplicitNamespace(schemaname);
-		return SearchSysCache3(CLAAMNAMENSP,
+		htup = SearchSysCache3(CLAAMNAMENSP,
 							   ObjectIdGetDatum(amID),
 							   PointerGetDatum(opcname),
 							   ObjectIdGetDatum(namespaceId));
@@ -152,9 +192,47 @@ OpClassCacheLookup(Oid amID, List *opclassname)
 		Oid			opcID = OpclassnameGetOpcid(amID, opcname);
 
 		if (!OidIsValid(opcID))
-			return NULL;
-		return SearchSysCache1(CLAOID, ObjectIdGetDatum(opcID));
+			htup = NULL;
+		else
+			htup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opcID));
+	}
+
+	if (!HeapTupleIsValid(htup) && !missing_ok)
+	{
+		HeapTuple amtup;
+
+		amtup = SearchSysCache1(AMOID, ObjectIdGetDatum(amID));
+		if (!HeapTupleIsValid(amtup))
+			elog(ERROR, "cache lookup failed for access method %u", amID);
+		ereport(ERROR,
+				(errcode(ERRCODE_UNDEFINED_OBJECT),
+				 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
+						NameListToString(opclassname),
+						NameStr(((Form_pg_am) GETSTRUCT(amtup))->amname))));
 	}
+
+	return htup;
+}
+
+/*
+ * get_opclass_oid
+ *    find an opclass OID by possibly qualified name
+ *
+ * If not found, returns InvalidOid if missing_ok, else throws error.
+ */
+Oid
+get_opclass_oid(Oid amID, List *opclassname, bool missing_ok)
+{
+	HeapTuple	htup;
+	Oid			opcID;
+
+	htup = OpClassCacheLookup(amID, opclassname, missing_ok);
+	if (!HeapTupleIsValid(htup))
+		return InvalidOid;
+	opcID = HeapTupleGetOid(htup);
+	ReleaseSysCache(htup);
+
+	return opcID;
 }
 
 /*
@@ -336,19 +414,7 @@ DefineOpClass(CreateOpClassStmt *stmt)
 	 */
 	if (stmt->opfamilyname)
 	{
-		tup = OpFamilyCacheLookup(amoid, stmt->opfamilyname);
-		if (!HeapTupleIsValid(tup))
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator family \"%s\" does not exist for access method \"%s\"",
-					   NameListToString(stmt->opfamilyname), stmt->amname)));
-		opfamilyoid = HeapTupleGetOid(tup);
-
-		/*
-		 * XXX given the superuser check above, there's no need for an
-		 * ownership check here
-		 */
-		ReleaseSysCache(tup);
+		opfamilyoid = get_opfamily_oid(amoid, stmt->opfamilyname, false);
 	}
 	else
 	{
@@ -773,14 +839,7 @@ AlterOpFamily(AlterOpFamilyStmt *stmt)
 	ReleaseSysCache(tup);
 
 	/* Look up the opfamily */
-	tup = OpFamilyCacheLookup(amoid, stmt->opfamilyname);
-	if (!HeapTupleIsValid(tup))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("operator family \"%s\" does not exist for access method \"%s\"",
-						NameListToString(stmt->opfamilyname), stmt->amname)));
-	opfamilyoid = HeapTupleGetOid(tup);
-	ReleaseSysCache(tup);
+	opfamilyoid = get_opfamily_oid(amoid, stmt->opfamilyname, false);
 
 	/*
 	 * Currently, we require superuser privileges to alter an opfamily.
@@ -1476,26 +1535,16 @@ RemoveOpClass(RemoveOpClassStmt *stmt)
 	HeapTuple	tuple;
 	ObjectAddress object;
 
-	/*
-	 * Get the access method's OID.
-	 */
+	/* Get the access method's OID. */
 	amID = get_am_oid(stmt->amname, false);
 
-	/*
-	 * Look up the opclass.
-	 */
-	tuple = OpClassCacheLookup(amID, stmt->opclassname);
+	/* Look up the opclass. */
+	tuple = OpClassCacheLookup(amID, stmt->opclassname, stmt->missing_ok);
 	if (!HeapTupleIsValid(tuple))
 	{
-		if (!stmt->missing_ok)
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
-						NameListToString(stmt->opclassname), stmt->amname)));
-		else
-			ereport(NOTICE,
-					(errmsg("operator class \"%s\" does not exist for access method \"%s\"",
-						NameListToString(stmt->opclassname), stmt->amname)));
+		ereport(NOTICE,
+				(errmsg("operator class \"%s\" does not exist for access method \"%s\"",
+					NameListToString(stmt->opclassname), stmt->amname)));
 		return;
 	}
 
@@ -1540,18 +1589,13 @@ RemoveOpFamily(RemoveOpFamilyStmt *stmt)
 	/*
 	 * Look up the opfamily.
 	 */
-	tuple = OpFamilyCacheLookup(amID, stmt->opfamilyname);
+	tuple = OpFamilyCacheLookup(amID, stmt->opfamilyname, stmt->missing_ok);
 	if (!HeapTupleIsValid(tuple))
 	{
-		if (!stmt->missing_ok)
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator family \"%s\" does not exist for access method \"%s\"",
-					   NameListToString(stmt->opfamilyname), stmt->amname)));
-		else
-			ereport(NOTICE,
-					(errmsg("operator family \"%s\" does not exist for access method \"%s\"",
-					   NameListToString(stmt->opfamilyname), stmt->amname)));
+		ereport(ERROR,
+				(errcode(ERRCODE_UNDEFINED_OBJECT),
+				 errmsg("operator family \"%s\" does not exist for access method \"%s\"",
+				   NameListToString(stmt->opfamilyname), stmt->amname)));
 		return;
 	}
 
@@ -1686,8 +1730,7 @@ RenameOpClass(List *name, const char *access_method, const char *newname)
 	Oid			opcOid;
 	Oid			amOid;
 	Oid			namespaceOid;
-	char	   *schemaname;
-	char	   *opcname;
+	HeapTuple	origtup;
 	HeapTuple	tup;
 	Relation	rel;
 	AclResult	aclresult;
@@ -1696,42 +1739,12 @@ RenameOpClass(List *name, const char *access_method, const char *newname)
 
 	rel = heap_open(OperatorClassRelationId, RowExclusiveLock);
 
-	/*
-	 * Look up the opclass
-	 */
-	DeconstructQualifiedName(name, &schemaname, &opcname);
-
-	if (schemaname)
-	{
-		namespaceOid = LookupExplicitNamespace(schemaname);
-
-		tup = SearchSysCacheCopy3(CLAAMNAMENSP,
-								  ObjectIdGetDatum(amOid),
-								  PointerGetDatum(opcname),
-								  ObjectIdGetDatum(namespaceOid));
-		if (!HeapTupleIsValid(tup))
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
-							opcname, access_method)));
-
-		opcOid = HeapTupleGetOid(tup);
-	}
-	else
-	{
-		opcOid = OpclassnameGetOpcid(amOid, opcname);
-		if (!OidIsValid(opcOid))
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
-							opcname, access_method)));
-
-		tup = SearchSysCacheCopy1(CLAOID, ObjectIdGetDatum(opcOid));
-		if (!HeapTupleIsValid(tup))		/* should not happen */
-			elog(ERROR, "cache lookup failed for opclass %u", opcOid);
-
-		namespaceOid = ((Form_pg_opclass) GETSTRUCT(tup))->opcnamespace;
-	}
+	/* Look up the opclass. */
+	origtup = OpClassCacheLookup(amOid, name, false);
+	tup = heap_copytuple(origtup);
+	ReleaseSysCache(origtup);
+	opcOid = HeapTupleGetOid(tup);
+	namespaceOid = ((Form_pg_opclass) GETSTRUCT(tup))->opcnamespace;
 
 	/* make sure the new name doesn't exist */
 	if (SearchSysCacheExists3(CLAAMNAMENSP,
@@ -1864,49 +1877,16 @@ AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId)
 	Oid			amOid;
 	Relation	rel;
 	HeapTuple	tup;
-	char	   *opcname;
-	char	   *schemaname;
+	HeapTuple	origtup;
 
 	amOid = get_am_oid(access_method, false);
 
 	rel = heap_open(OperatorClassRelationId, RowExclusiveLock);
 
-	/*
-	 * Look up the opclass
-	 */
-	DeconstructQualifiedName(name, &schemaname, &opcname);
-
-	if (schemaname)
-	{
-		Oid			namespaceOid;
-
-		namespaceOid = LookupExplicitNamespace(schemaname);
-
-		tup = SearchSysCacheCopy3(CLAAMNAMENSP,
-								  ObjectIdGetDatum(amOid),
-								  PointerGetDatum(opcname),
-								  ObjectIdGetDatum(namespaceOid));
-		if (!HeapTupleIsValid(tup))
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
-							opcname, access_method)));
-	}
-	else
-	{
-		Oid			opcOid;
-
-		opcOid = OpclassnameGetOpcid(amOid, opcname);
-		if (!OidIsValid(opcOid))
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
-							opcname, access_method)));
-
-		tup = SearchSysCacheCopy1(CLAOID, ObjectIdGetDatum(opcOid));
-		if (!HeapTupleIsValid(tup))		/* should not happen */
-			elog(ERROR, "cache lookup failed for opclass %u", opcOid);
-	}
+	/* Look up the opclass. */
+	origtup = OpClassCacheLookup(amOid, name, false);
+	tup = heap_copytuple(origtup);
+	ReleaseSysCache(origtup);
 
 	AlterOpClassOwner_internal(rel, tup, newOwnerId);
 
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 2cbc192..71724c8 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -960,46 +960,17 @@ void
 DropTrigger(Oid relid, const char *trigname, DropBehavior behavior,
 			bool missing_ok)
 {
-	Relation	tgrel;
-	ScanKeyData skey[2];
-	SysScanDesc tgscan;
-	HeapTuple	tup;
 	ObjectAddress object;
 
-	/*
-	 * Find the trigger, verify permissions, set up object address
-	 */
-	tgrel = heap_open(TriggerRelationId, AccessShareLock);
-
-	ScanKeyInit(&skey[0],
-				Anum_pg_trigger_tgrelid,
-				BTEqualStrategyNumber, F_OIDEQ,
-				ObjectIdGetDatum(relid));
-
-	ScanKeyInit(&skey[1],
-				Anum_pg_trigger_tgname,
-				BTEqualStrategyNumber, F_NAMEEQ,
-				CStringGetDatum(trigname));
-
-	tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
-								SnapshotNow, 2, skey);
-
-	tup = systable_getnext(tgscan);
+	object.classId = TriggerRelationId;
+	object.objectId = get_trigger_oid(relid, trigname, missing_ok);
+	object.objectSubId = 0;
 
-	if (!HeapTupleIsValid(tup))
+	if (!OidIsValid(object.objectId))
 	{
-		if (!missing_ok)
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("trigger \"%s\" for table \"%s\" does not exist",
-							trigname, get_rel_name(relid))));
-		else
-			ereport(NOTICE,
-					(errmsg("trigger \"%s\" for table \"%s\" does not exist, skipping",
-							trigname, get_rel_name(relid))));
-		/* cleanup */
-		systable_endscan(tgscan);
-		heap_close(tgrel, AccessShareLock);
+		ereport(NOTICE,
+				(errmsg("trigger \"%s\" for table \"%s\" does not exist, skipping",
+						trigname, get_rel_name(relid))));
 		return;
 	}
 
@@ -1007,13 +978,6 @@ DropTrigger(Oid relid, const char *trigname, DropBehavior behavior,
 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
 					   get_rel_name(relid));
 
-	object.classId = TriggerRelationId;
-	object.objectId = HeapTupleGetOid(tup);
-	object.objectSubId = 0;
-
-	systable_endscan(tgscan);
-	heap_close(tgrel, AccessShareLock);
-
 	/*
 	 * Do the deletion
 	 */
@@ -1093,6 +1057,59 @@ RemoveTriggerById(Oid trigOid)
 }
 
 /*
+ * get_trigger_oid - Look up a trigger by name to find its OID.
+ *
+ * If missing_ok is false, throw an error if trigger not found.  If
+ * true, just return InvalidOid.
+ */
+Oid
+get_trigger_oid(Oid relid, const char *trigname, bool missing_ok)
+{
+	Relation	tgrel;
+	ScanKeyData skey[2];
+	SysScanDesc tgscan;
+	HeapTuple	tup;
+	Oid			oid;
+
+	/*
+	 * Find the trigger, verify permissions, set up object address
+	 */
+	tgrel = heap_open(TriggerRelationId, AccessShareLock);
+
+	ScanKeyInit(&skey[0],
+				Anum_pg_trigger_tgrelid,
+				BTEqualStrategyNumber, F_OIDEQ,
+				ObjectIdGetDatum(relid));
+	ScanKeyInit(&skey[1],
+				Anum_pg_trigger_tgname,
+				BTEqualStrategyNumber, F_NAMEEQ,
+				CStringGetDatum(trigname));
+
+	tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
+								SnapshotNow, 2, skey);
+
+	tup = systable_getnext(tgscan);
+
+	if (!HeapTupleIsValid(tup))
+	{
+		if (!missing_ok)
+			ereport(ERROR,
+					(errcode(ERRCODE_UNDEFINED_OBJECT),
+					 errmsg("trigger \"%s\" for table \"%s\" does not exist",
+							trigname, get_rel_name(relid))));
+		oid = InvalidOid;
+	}
+	else
+	{
+		oid = HeapTupleGetOid(tup);
+	}
+
+	systable_endscan(tgscan);
+	heap_close(tgrel, AccessShareLock);
+	return oid;
+}
+
+/*
  *		renametrig		- changes the name of a trigger on a relation
  *
  *		trigger name is changed in trigger catalog.
diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c
index ba3de63..87b3105 100644
--- a/src/backend/commands/tsearchcmds.c
+++ b/src/backend/commands/tsearchcmds.c
@@ -295,7 +295,7 @@ RemoveTSParsers(DropStmt *drop)
 		Oid			prsOid;
 		ObjectAddress object;
 
-		prsOid = TSParserGetPrsid(names, true);
+		prsOid = get_tsparser_oid(names, true);
 
 		if (!OidIsValid(prsOid))
 		{
@@ -368,7 +368,7 @@ RenameTSParser(List *oldname, const char *newname)
 
 	rel = heap_open(TSParserRelationId, RowExclusiveLock);
 
-	prsId = TSParserGetPrsid(oldname, false);
+	prsId = get_tsparser_oid(oldname, false);
 
 	tup = SearchSysCacheCopy1(TSPARSEROID, ObjectIdGetDatum(prsId));
 
@@ -517,7 +517,7 @@ DefineTSDictionary(List *names, List *parameters)
 
 		if (pg_strcasecmp(defel->defname, "template") == 0)
 		{
-			templId = TSTemplateGetTmplid(defGetQualifiedName(defel), false);
+			templId = get_tstemplate_oid(defGetQualifiedName(defel), false);
 		}
 		else
 		{
@@ -582,7 +582,7 @@ RenameTSDictionary(List *oldname, const char *newname)
 
 	rel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
 
-	dictId = TSDictionaryGetDictid(oldname, false);
+	dictId = get_tsdictionary_oid(oldname, false);
 
 	tup = SearchSysCacheCopy1(TSDICTOID, ObjectIdGetDatum(dictId));
 
@@ -643,7 +643,7 @@ RemoveTSDictionaries(DropStmt *drop)
 		HeapTuple	tup;
 		Oid			namespaceId;
 
-		dictOid = TSDictionaryGetDictid(names, true);
+		dictOid = get_tsdictionary_oid(names, true);
 
 		if (!OidIsValid(dictOid))
 		{
@@ -731,7 +731,7 @@ AlterTSDictionary(AlterTSDictionaryStmt *stmt)
 	bool		repl_null[Natts_pg_ts_dict];
 	bool		repl_repl[Natts_pg_ts_dict];
 
-	dictId = TSDictionaryGetDictid(stmt->dictname, false);
+	dictId = get_tsdictionary_oid(stmt->dictname, false);
 
 	rel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
 
@@ -841,7 +841,7 @@ AlterTSDictionaryOwner(List *name, Oid newOwnerId)
 
 	rel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
 
-	dictId = TSDictionaryGetDictid(name, false);
+	dictId = get_tsdictionary_oid(name, false);
 
 	tup = SearchSysCacheCopy1(TSDICTOID, ObjectIdGetDatum(dictId));
 
@@ -1073,7 +1073,7 @@ RenameTSTemplate(List *oldname, const char *newname)
 
 	rel = heap_open(TSTemplateRelationId, RowExclusiveLock);
 
-	tmplId = TSTemplateGetTmplid(oldname, false);
+	tmplId = get_tstemplate_oid(oldname, false);
 
 	tup = SearchSysCacheCopy1(TSTEMPLATEOID, ObjectIdGetDatum(tmplId));
 
@@ -1126,7 +1126,7 @@ RemoveTSTemplates(DropStmt *drop)
 		Oid			tmplOid;
 		ObjectAddress object;
 
-		tmplOid = TSTemplateGetTmplid(names, true);
+		tmplOid = get_tstemplate_oid(names, true);
 
 		if (!OidIsValid(tmplOid))
 		{
@@ -1194,7 +1194,7 @@ GetTSConfigTuple(List *names)
 	HeapTuple	tup;
 	Oid			cfgId;
 
-	cfgId = TSConfigGetCfgid(names, true);
+	cfgId = get_tsconfiguration_oid(names, true);
 	if (!OidIsValid(cfgId))
 		return NULL;
 
@@ -1329,9 +1329,9 @@ DefineTSConfiguration(List *names, List *parameters)
 		DefElem    *defel = (DefElem *) lfirst(pl);
 
 		if (pg_strcasecmp(defel->defname, "parser") == 0)
-			prsOid = TSParserGetPrsid(defGetQualifiedName(defel), false);
+			prsOid = get_tsparser_oid(defGetQualifiedName(defel), false);
 		else if (pg_strcasecmp(defel->defname, "copy") == 0)
-			sourceOid = TSConfigGetCfgid(defGetQualifiedName(defel), false);
+			sourceOid = get_tsconfiguration_oid(defGetQualifiedName(defel), false);
 		else
 			ereport(ERROR,
 					(errcode(ERRCODE_SYNTAX_ERROR),
@@ -1461,7 +1461,7 @@ RenameTSConfiguration(List *oldname, const char *newname)
 
 	rel = heap_open(TSConfigRelationId, RowExclusiveLock);
 
-	cfgId = TSConfigGetCfgid(oldname, false);
+	cfgId = get_tsconfiguration_oid(oldname, false);
 
 	tup = SearchSysCacheCopy1(TSCONFIGOID, ObjectIdGetDatum(cfgId));
 
@@ -1626,7 +1626,7 @@ AlterTSConfigurationOwner(List *name, Oid newOwnerId)
 
 	rel = heap_open(TSConfigRelationId, RowExclusiveLock);
 
-	cfgId = TSConfigGetCfgid(name, false);
+	cfgId = get_tsconfiguration_oid(name, false);
 
 	tup = SearchSysCacheCopy1(TSCONFIGOID, ObjectIdGetDatum(cfgId));
 
@@ -1828,7 +1828,7 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
 	{
 		List	   *names = (List *) lfirst(c);
 
-		dictIds[i] = TSDictionaryGetDictid(names, false);
+		dictIds[i] = get_tsdictionary_oid(names, false);
 		i++;
 	}
 
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index 90d5c76..8745201 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -712,8 +712,8 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
 
 			/* Copy comment on constraint */
 			if ((inhRelation->options & CREATE_TABLE_LIKE_COMMENTS) &&
-				(comment = GetComment(GetConstraintByName(RelationGetRelid(relation),
-														  n->conname),
+				(comment = GetComment(get_constraint_oid(RelationGetRelid(relation),
+														  n->conname, false),
 									  ConstraintRelationId,
 									  0)) != NULL)
 			{
diff --git a/src/backend/rewrite/rewriteSupport.c b/src/backend/rewrite/rewriteSupport.c
index 27d21e3..ba503c4 100644
--- a/src/backend/rewrite/rewriteSupport.c
+++ b/src/backend/rewrite/rewriteSupport.c
@@ -17,9 +17,14 @@
 #include "access/heapam.h"
 #include "catalog/indexing.h"
 #include "catalog/pg_class.h"
+#include "catalog/pg_rewrite.h"
 #include "rewrite/rewriteSupport.h"
+#include "utils/fmgroids.h"
 #include "utils/inval.h"
+#include "utils/lsyscache.h"
+#include "utils/rel.h"
 #include "utils/syscache.h"
+#include "utils/tqual.h"
 
 
 /*
@@ -86,3 +91,82 @@ SetRelationRuleStatus(Oid relationId, bool relHasRules,
 	heap_freetuple(tuple);
 	heap_close(relationRelation, RowExclusiveLock);
 }
+
+/*
+ * Find rule oid.
+ *
+ * If missing_ok is false, throw an error if rule name not found.  If
+ * true, just return InvalidOid.
+ */
+Oid
+get_rule_oid(Oid relid, const char *rulename, bool missing_ok)
+{
+	HeapTuple	tuple;
+	Oid			ruleoid;
+
+	/* Find the rule's pg_rewrite tuple, get its OID */
+	tuple = SearchSysCache2(RULERELNAME,
+							ObjectIdGetDatum(relid),
+							PointerGetDatum(rulename));
+	if (!HeapTupleIsValid(tuple))
+	{
+		if (missing_ok)
+			return InvalidOid;
+		ereport(ERROR,
+				(errcode(ERRCODE_UNDEFINED_OBJECT),
+				 errmsg("rule \"%s\" for relation \"%s\" does not exist",
+						rulename, get_rel_name(relid))));
+	}
+	Assert(relid == ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class);
+	ruleoid = HeapTupleGetOid(tuple);
+	ReleaseSysCache(tuple);
+	return ruleoid;
+}
+
+/*
+ * Find rule oid, given only a rule name but no rel OID.
+ *
+ * If there's more than one, it's an error.  If there aren't any, that's an
+ * error, too.  In general, this should be avoided - it is provided to support
+ * syntax that is compatible with pre-7.3 versions of PG, where rule names
+ * were unique across the entire database.
+ */
+Oid
+get_rule_oid_without_relid(const char *rulename, Oid *reloid)
+{
+	Relation	RewriteRelation;
+	HeapScanDesc scanDesc;
+	ScanKeyData scanKeyData;
+	HeapTuple	htup;
+	Oid			ruleoid;
+
+	/* Search pg_rewrite for such a rule */
+	ScanKeyInit(&scanKeyData,
+				Anum_pg_rewrite_rulename,
+				BTEqualStrategyNumber, F_NAMEEQ,
+				CStringGetDatum(rulename));
+
+	RewriteRelation = heap_open(RewriteRelationId, AccessShareLock);
+	scanDesc = heap_beginscan(RewriteRelation, SnapshotNow, 1, &scanKeyData);
+
+	htup = heap_getnext(scanDesc, ForwardScanDirection);
+	if (!HeapTupleIsValid(htup))
+		ereport(ERROR,
+				(errcode(ERRCODE_UNDEFINED_OBJECT),
+				 errmsg("rule \"%s\" does not exist", rulename)));
+
+	ruleoid = HeapTupleGetOid(htup);
+	if (reloid != NULL)
+		*reloid = ((Form_pg_rewrite) GETSTRUCT(htup))->ev_class;
+
+	if (HeapTupleIsValid(htup = heap_getnext(scanDesc, ForwardScanDirection)))
+		ereport(ERROR,
+				(errcode(ERRCODE_DUPLICATE_OBJECT),
+				 errmsg("there are multiple rules named \"%s\"", rulename),
+				 errhint("Specify a relation name as well as a rule name.")));
+
+	heap_endscan(scanDesc);
+	heap_close(RewriteRelation, AccessShareLock);
+
+	return ruleoid;
+}
diff --git a/src/backend/tsearch/dict_thesaurus.c b/src/backend/tsearch/dict_thesaurus.c
index ee3c118..698a540 100644
--- a/src/backend/tsearch/dict_thesaurus.c
+++ b/src/backend/tsearch/dict_thesaurus.c
@@ -642,7 +642,7 @@ thesaurus_init(PG_FUNCTION_ARGS)
 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 				 errmsg("missing Dictionary parameter")));
 
-	d->subdictOid = TSDictionaryGetDictid(stringToQualifiedNameList(subdictname), false);
+	d->subdictOid = get_tsdictionary_oid(stringToQualifiedNameList(subdictname), false);
 	d->subdict = lookup_ts_dictionary_cache(d->subdictOid);
 
 	compileTheLexeme(d);
diff --git a/src/backend/tsearch/wparser.c b/src/backend/tsearch/wparser.c
index 0fed35c..2c41b34 100644
--- a/src/backend/tsearch/wparser.c
+++ b/src/backend/tsearch/wparser.c
@@ -134,7 +134,7 @@ ts_token_type_byname(PG_FUNCTION_ARGS)
 		Oid			prsId;
 
 		funcctx = SRF_FIRSTCALL_INIT();
-		prsId = TSParserGetPrsid(textToQualifiedNameList(prsname), false);
+		prsId = get_tsparser_oid(textToQualifiedNameList(prsname), false);
 		tt_setup_firstcall(funcctx, prsId);
 	}
 
@@ -282,7 +282,7 @@ ts_parse_byname(PG_FUNCTION_ARGS)
 		Oid			prsId;
 
 		funcctx = SRF_FIRSTCALL_INIT();
-		prsId = TSParserGetPrsid(textToQualifiedNameList(prsname), false);
+		prsId = get_tsparser_oid(textToQualifiedNameList(prsname), false);
 		prs_setup_firstcall(funcctx, prsId, txt);
 	}
 
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index 2450cc7..d30a184 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -1096,7 +1096,7 @@ regconfigin(PG_FUNCTION_ARGS)
 	 */
 	names = stringToQualifiedNameList(cfg_name_or_oid);
 
-	result = TSConfigGetCfgid(names, false);
+	result = get_tsconfiguration_oid(names, false);
 
 	PG_RETURN_OID(result);
 }
@@ -1206,7 +1206,7 @@ regdictionaryin(PG_FUNCTION_ARGS)
 	 */
 	names = stringToQualifiedNameList(dict_name_or_oid);
 
-	result = TSDictionaryGetDictid(names, false);
+	result = get_tsdictionary_oid(names, false);
 
 	PG_RETURN_OID(result);
 }
diff --git a/src/backend/utils/adt/tsvector_op.c b/src/backend/utils/adt/tsvector_op.c
index 78f08f4..4577874 100644
--- a/src/backend/utils/adt/tsvector_op.c
+++ b/src/backend/utils/adt/tsvector_op.c
@@ -1326,7 +1326,7 @@ tsvector_update_trigger(PG_FUNCTION_ARGS, bool config_column)
 					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 					 errmsg("text search configuration name \"%s\" must be schema-qualified",
 							trigger->tgargs[1])));
-		cfgId = TSConfigGetCfgid(names, false);
+		cfgId = get_tsconfiguration_oid(names, false);
 	}
 
 	/* initialize parse state */
diff --git a/src/backend/utils/cache/ts_cache.c b/src/backend/utils/cache/ts_cache.c
index 77d8e2f..e7c1240 100644
--- a/src/backend/utils/cache/ts_cache.c
+++ b/src/backend/utils/cache/ts_cache.c
@@ -581,7 +581,7 @@ getTSCurrentConfig(bool emitError)
 
 	/* Look up the config */
 	TSCurrentConfigCache =
-		TSConfigGetCfgid(stringToQualifiedNameList(TSCurrentConfig),
+		get_tsconfiguration_oid(stringToQualifiedNameList(TSCurrentConfig),
 						 !emitError);
 
 	return TSCurrentConfigCache;
@@ -601,7 +601,7 @@ assignTSCurrentConfig(const char *newval, bool doit, GucSource source)
 		Form_pg_ts_config cfg;
 		char	   *buf;
 
-		cfgId = TSConfigGetCfgid(stringToQualifiedNameList(newval), true);
+		cfgId = get_tsconfiguration_oid(stringToQualifiedNameList(newval), true);
 
 		if (!OidIsValid(cfgId))
 			return NULL;
diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h
index 0fd61a9..55f44f8 100644
--- a/src/include/catalog/namespace.h
+++ b/src/include/catalog/namespace.h
@@ -74,16 +74,16 @@ extern bool OpfamilyIsVisible(Oid opfid);
 extern Oid	ConversionGetConid(const char *conname);
 extern bool ConversionIsVisible(Oid conid);
 
-extern Oid	TSParserGetPrsid(List *names, bool failOK);
+extern Oid	get_tsparser_oid(List *names, bool missing_ok);
 extern bool TSParserIsVisible(Oid prsId);
 
-extern Oid	TSDictionaryGetDictid(List *names, bool failOK);
+extern Oid	get_tsdictionary_oid(List *names, bool missing_ok);
 extern bool TSDictionaryIsVisible(Oid dictId);
 
-extern Oid	TSTemplateGetTmplid(List *names, bool failOK);
+extern Oid	get_tstemplate_oid(List *names, bool missing_ok);
 extern bool TSTemplateIsVisible(Oid tmplId);
 
-extern Oid	TSConfigGetCfgid(List *names, bool failOK);
+extern Oid	get_tsconfiguration_oid(List *names, bool missing_ok);
 extern bool TSConfigIsVisible(Oid cfgid);
 
 extern void DeconstructQualifiedName(List *names,
@@ -112,7 +112,7 @@ extern OverrideSearchPath *GetOverrideSearchPath(MemoryContext context);
 extern void PushOverrideSearchPath(OverrideSearchPath *newpath);
 extern void PopOverrideSearchPath(void);
 
-extern Oid	FindConversionByName(List *conname);
+extern Oid	get_conversion_oid(List *conname, bool missing_ok);
 extern Oid	FindDefaultConversionProc(int4 for_encoding, int4 to_encoding);
 
 /* initialization & transaction cleanup code */
diff --git a/src/include/catalog/pg_constraint.h b/src/include/catalog/pg_constraint.h
index c3dfcb0..83ca05f 100644
--- a/src/include/catalog/pg_constraint.h
+++ b/src/include/catalog/pg_constraint.h
@@ -237,6 +237,6 @@ extern char *ChooseConstraintName(const char *name1, const char *name2,
 
 extern void AlterConstraintNamespaces(Oid ownerId, Oid oldNspId,
 						  Oid newNspId, bool isType);
-extern Oid	GetConstraintByName(Oid relid, const char *conname);
+extern Oid	get_constraint_oid(Oid relid, const char *conname, bool missing_ok);
 
 #endif   /* PG_CONSTRAINT_H */
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index 76aff43..2ee79cc 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -67,6 +67,7 @@ extern void DropCastById(Oid castOid);
 extern void AlterFunctionNamespace(List *name, List *argtypes, bool isagg,
 					   const char *newschema);
 extern void ExecuteDoStmt(DoStmt *stmt);
+extern Oid get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok);
 
 /* commands/operatorcmds.c */
 extern void DefineOperator(List *names, List *parameters);
@@ -75,6 +76,8 @@ extern void RemoveOperatorById(Oid operOid);
 extern void AlterOperatorOwner(List *name, TypeName *typeName1,
 				   TypeName *typename2, Oid newOwnerId);
 extern void AlterOperatorOwner_oid(Oid operOid, Oid newOwnerId);
+extern Oid get_opclass_oid(Oid amID, List *opclassname, bool missing_ok);
+extern Oid get_opfamily_oid(Oid amID, List *opfamilyname, bool missing_ok);
 
 /* commands/aggregatecmds.c */
 extern void DefineAggregate(List *name, List *args, bool oldstyle,
diff --git a/src/include/commands/trigger.h b/src/include/commands/trigger.h
index 98bc0c6..267a08e 100644
--- a/src/include/commands/trigger.h
+++ b/src/include/commands/trigger.h
@@ -111,6 +111,7 @@ extern Oid CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
 extern void DropTrigger(Oid relid, const char *trigname,
 			DropBehavior behavior, bool missing_ok);
 extern void RemoveTriggerById(Oid trigOid);
+extern Oid get_trigger_oid(Oid relid, const char *name, bool missing_ok);
 
 extern void renametrig(Oid relid, const char *oldname, const char *newname);
 
diff --git a/src/include/rewrite/rewriteSupport.h b/src/include/rewrite/rewriteSupport.h
index 7784d98..7dfe1fe 100644
--- a/src/include/rewrite/rewriteSupport.h
+++ b/src/include/rewrite/rewriteSupport.h
@@ -22,4 +22,7 @@ extern bool IsDefinedRewriteRule(Oid owningRel, const char *ruleName);
 extern void SetRelationRuleStatus(Oid relationId, bool relHasRules,
 					  bool relIsBecomingView);
 
+extern Oid get_rule_oid(Oid relid, const char *rulename, bool missing_ok);
+extern Oid get_rule_oid_without_relid(const char *rulename, Oid *relid);
+
 #endif   /* REWRITESUPPORT_H */
#4KaiGai Kohei
kaigai@ak.jp.nec.com
In reply to: Robert Haas (#3)
Re: get_whatever_oid, part 2

Sorry for the late responding.

It looks good to me that the point (1) and (4) are fixed.

The (2) and (3) are depending on individual subjective sense,
so it will be no problem, if we decide not to clean them up at
the same time.

Elsewhere, I noticed one other stuff related to naming convention.

The new internal APIs are basically named as:
get_(object class)_oid(<args...>);

At the part 1 patch, the object class was entirely matched with
name of the system catalog.
E.g, get_namespace_oid(), get_langeage_oid().
^^^^^^^^^ ^^^^^^^^
| |
+--> pg_namespace +--> pg_language

But some of APIs in the part 2 have different object class name
from their corresponding system catalog.

How about the following renamings?
- get_tsparser_oid() -> get_ts_parser_oid()
- get_tsdictionary_oid() -> get_ts_dict_oid()
- get_tstemplate_oid() -> get_ts_template_oid()
- get_tsconfiguration_oid() -> get_ts_config_oid()
- get_rule_oid() -> get_rewrite_oid()
- get_rule_oid_without_relid() -> get_rewrite_oid_without_relid()

But, it is also depending on my subjective sense.

Even if you disagree with the proposition, I'll mark it 'ready for
committer' on the next.

Thanks,

(2010/07/06 22:23), Robert Haas wrote:

2010/7/5 KaiGai Kohei<kaigai@ak.jp.nec.com>:

I checked this patch. Then, I was surprised at we have such so many
code duplications. I believe this patch can effectively eliminate
these code duplications and it is worthful to apply.
However, here are some points to be fixed/revised.

1. [BUG] DropCast() does not handle missing_ok correctly.

You removed the 'return' on the path when get_cast_oid() with missing_ok = true
returned InvalidOid. It seems to me a bug to be fixed.

Good catch. Fixed.

2. we can reduce more code duplications using get_opfamily_oid() and
get_opclass_oid().

I could find translations from a qualified name to schema/object names
at GetIndexOpClass(), RenameOpFamily() and AlterOpFamilyOwner().
The new APIs enable to eliminate code duplications here.

GetIndexOpClass() needs input type of the operator class, in addition
to its OID, but it can be obtained using get_opclass_input_type().
RenameOpFamily() and AlterOpFamilyOwner() need a copy of the operator
family tuple, in addition to its OID, but it can be obtained using
GetSysCacheCopy1(OPFAMILYOID).

I don't believe this is a good idea. We don't want to do extra
syscache lookups just so that we can make the code look nicer.

3. Are OpClassCacheLookup() and OpFamilyCacheLookup() still needed?

The OpFamilyCacheLookup() is only called from RemoveOpFamily()
except for the get_opfamily_oid(), because it needs namespace OID
in addition to the OID of operator family.
If we have get_opfamily_namespace() in lsyscache.c, we can merge
get_opfamily_oid() and OpFamilyCacheLookup() completely?

The OpClassCacheLookup() is only called from RemoveOpClass(),
RenameOpClass() and AlterOpClassOwner(), because RemoveOpClass()
needs namespace OID in addition to the OID of operator class,
and rest of them want to copy the HeapTuple to update it.
If we have get_opclass_namespace() in lsyscache.c, RemoveOpClass()
can use get_opclass_oid() instead of OpClassCacheLookup().
And, we can use a pair of get_opclass_oid() and GetSysCacheCopy1()
instead of OpClassCacheLookup() and heap_copytuple() in the
RenameOpClass() and AlterOpClassOwner().

Same thing here. I left that stuff alone on purpose.

4. Name of the arguments incorrect.

It seems to me 'missing_ok', instead of 'failOK'. :D

Yeah, that's an oversight on my part. Fixed.

--
KaiGai Kohei <kaigai@ak.jp.nec.com>

#5Robert Haas
robertmhaas@gmail.com
In reply to: KaiGai Kohei (#4)
1 attachment(s)
Re: get_whatever_oid, part 2

2010/7/8 KaiGai Kohei <kaigai@ak.jp.nec.com>:

At the part 1 patch, the object class was entirely matched with
name of the system catalog.
E.g, get_namespace_oid(), get_langeage_oid().
        ^^^^^^^^^            ^^^^^^^^
          |                      |
          +--> pg_namespace      +--> pg_language

But some of APIs in the part 2 have different object class name
from their corresponding system catalog.

How about the following renamings?
 - get_tsparser_oid() -> get_ts_parser_oid()
 - get_tsdictionary_oid() -> get_ts_dict_oid()
 - get_tstemplate_oid() -> get_ts_template_oid()
 - get_tsconfiguration_oid() -> get_ts_config_oid()
 - get_rule_oid() -> get_rewrite_oid()
 - get_rule_oid_without_relid() -> get_rewrite_oid_without_relid()

I like that idea. Done, attached.

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

Attachments:

get_whatever_oid_part2-v3.patchapplication/octet-stream; name=get_whatever_oid_part2-v3.patchDownload
diff --git a/contrib/tsearch2/tsearch2.c b/contrib/tsearch2/tsearch2.c
index d421f77..ad3d05d 100644
--- a/contrib/tsearch2/tsearch2.c
+++ b/contrib/tsearch2/tsearch2.c
@@ -190,7 +190,7 @@ tsa_set_curdict_byname(PG_FUNCTION_ARGS)
 	text	   *name = PG_GETARG_TEXT_PP(0);
 	Oid			dict_oid;
 
-	dict_oid = TSDictionaryGetDictid(stringToQualifiedNameList(text_to_cstring(name)), false);
+	dict_oid = get_ts_dict_oid(stringToQualifiedNameList(text_to_cstring(name)), false);
 
 	current_dictionary_oid = dict_oid;
 
@@ -229,7 +229,7 @@ tsa_set_curprs_byname(PG_FUNCTION_ARGS)
 	text	   *name = PG_GETARG_TEXT_PP(0);
 	Oid			parser_oid;
 
-	parser_oid = TSParserGetPrsid(stringToQualifiedNameList(text_to_cstring(name)), false);
+	parser_oid = get_ts_parser_oid(stringToQualifiedNameList(text_to_cstring(name)), false);
 
 	current_parser_oid = parser_oid;
 
@@ -562,6 +562,6 @@ static Oid
 GetCurrentParser(void)
 {
 	if (current_parser_oid == InvalidOid)
-		current_parser_oid = TSParserGetPrsid(stringToQualifiedNameList("pg_catalog.default"), false);
+		current_parser_oid = get_ts_parser_oid(stringToQualifiedNameList("pg_catalog.default"), false);
 	return current_parser_oid;
 }
diff --git a/contrib/unaccent/unaccent.c b/contrib/unaccent/unaccent.c
index 0a29bba..edceb8f 100644
--- a/contrib/unaccent/unaccent.c
+++ b/contrib/unaccent/unaccent.c
@@ -279,7 +279,7 @@ unaccent_dict(PG_FUNCTION_ARGS)
 
 	if (PG_NARGS() == 1)
 	{
-		dictOid = TSDictionaryGetDictid(stringToQualifiedNameList("unaccent"), false);
+		dictOid = get_ts_dict_oid(stringToQualifiedNameList("unaccent"), false);
 		strArg = 0;
 	}
 	else
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 52acc23..d0b87ef 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -1692,12 +1692,12 @@ ConversionIsVisible(Oid conid)
 }
 
 /*
- * TSParserGetPrsid - find a TS parser by possibly qualified name
+ * get_ts_parser_oid - find a TS parser by possibly qualified name
  *
- * If not found, returns InvalidOid if failOK, else throws error
+ * If not found, returns InvalidOid if missing_ok, else throws error
  */
 Oid
-TSParserGetPrsid(List *names, bool failOK)
+get_ts_parser_oid(List *names, bool missing_ok)
 {
 	char	   *schemaname;
 	char	   *parser_name;
@@ -1736,7 +1736,7 @@ TSParserGetPrsid(List *names, bool failOK)
 		}
 	}
 
-	if (!OidIsValid(prsoid) && !failOK)
+	if (!OidIsValid(prsoid) && !missing_ok)
 		ereport(ERROR,
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 				 errmsg("text search parser \"%s\" does not exist",
@@ -1815,12 +1815,12 @@ TSParserIsVisible(Oid prsId)
 }
 
 /*
- * TSDictionaryGetDictid - find a TS dictionary by possibly qualified name
+ * get_ts_dict_oid - find a TS dictionary by possibly qualified name
  *
  * If not found, returns InvalidOid if failOK, else throws error
  */
 Oid
-TSDictionaryGetDictid(List *names, bool failOK)
+get_ts_dict_oid(List *names, bool missing_ok)
 {
 	char	   *schemaname;
 	char	   *dict_name;
@@ -1859,7 +1859,7 @@ TSDictionaryGetDictid(List *names, bool failOK)
 		}
 	}
 
-	if (!OidIsValid(dictoid) && !failOK)
+	if (!OidIsValid(dictoid) && !missing_ok)
 		ereport(ERROR,
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 				 errmsg("text search dictionary \"%s\" does not exist",
@@ -1939,12 +1939,12 @@ TSDictionaryIsVisible(Oid dictId)
 }
 
 /*
- * TSTemplateGetTmplid - find a TS template by possibly qualified name
+ * get_ts_template_oid - find a TS template by possibly qualified name
  *
- * If not found, returns InvalidOid if failOK, else throws error
+ * If not found, returns InvalidOid if missing_ok, else throws error
  */
 Oid
-TSTemplateGetTmplid(List *names, bool failOK)
+get_ts_template_oid(List *names, bool missing_ok)
 {
 	char	   *schemaname;
 	char	   *template_name;
@@ -1983,7 +1983,7 @@ TSTemplateGetTmplid(List *names, bool failOK)
 		}
 	}
 
-	if (!OidIsValid(tmploid) && !failOK)
+	if (!OidIsValid(tmploid) && !missing_ok)
 		ereport(ERROR,
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 				 errmsg("text search template \"%s\" does not exist",
@@ -2062,12 +2062,12 @@ TSTemplateIsVisible(Oid tmplId)
 }
 
 /*
- * TSConfigGetCfgid - find a TS config by possibly qualified name
+ * get_ts_config_oid - find a TS config by possibly qualified name
  *
- * If not found, returns InvalidOid if failOK, else throws error
+ * If not found, returns InvalidOid if missing_ok, else throws error
  */
 Oid
-TSConfigGetCfgid(List *names, bool failOK)
+get_ts_config_oid(List *names, bool missing_ok)
 {
 	char	   *schemaname;
 	char	   *config_name;
@@ -2106,7 +2106,7 @@ TSConfigGetCfgid(List *names, bool failOK)
 		}
 	}
 
-	if (!OidIsValid(cfgoid) && !failOK)
+	if (!OidIsValid(cfgoid) && !missing_ok)
 		ereport(ERROR,
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 				 errmsg("text search configuration \"%s\" does not exist",
@@ -2766,15 +2766,15 @@ PopOverrideSearchPath(void)
 
 
 /*
- * FindConversionByName - find a conversion by possibly qualified name
+ * get_conversion_oid - find a conversion by possibly qualified name
  */
 Oid
-FindConversionByName(List *name)
+get_conversion_oid(List *name, bool missing_ok)
 {
 	char	   *schemaname;
 	char	   *conversion_name;
 	Oid			namespaceId;
-	Oid			conoid;
+	Oid			conoid = InvalidOid;
 	ListCell   *l;
 
 	/* deconstruct the name list */
@@ -2784,9 +2784,9 @@ FindConversionByName(List *name)
 	{
 		/* use exact schema given */
 		namespaceId = LookupExplicitNamespace(schemaname);
-		return GetSysCacheOid2(CONNAMENSP,
-							   PointerGetDatum(conversion_name),
-							   ObjectIdGetDatum(namespaceId));
+		conoid = GetSysCacheOid2(CONNAMENSP,
+								 PointerGetDatum(conversion_name),
+								 ObjectIdGetDatum(namespaceId));
 	}
 	else
 	{
@@ -2809,7 +2809,12 @@ FindConversionByName(List *name)
 	}
 
 	/* Not found in path */
-	return InvalidOid;
+	if (!OidIsValid(conoid) && !missing_ok)
+		ereport(ERROR,
+				(errcode(ERRCODE_UNDEFINED_OBJECT),
+				 errmsg("conversion \"%s\" does not exist",
+						NameListToString(name))));
+	return conoid;
 }
 
 /*
diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c
index 2cfd453..256974b 100644
--- a/src/backend/catalog/pg_constraint.c
+++ b/src/backend/catalog/pg_constraint.c
@@ -727,12 +727,12 @@ AlterConstraintNamespaces(Oid ownerId, Oid oldNspId,
 }
 
 /*
- * GetConstraintByName
+ * get_constraint_oid
  *		Find a constraint on the specified relation with the specified name.
  *		Returns constraint's OID.
  */
 Oid
-GetConstraintByName(Oid relid, const char *conname)
+get_constraint_oid(Oid relid, const char *conname, bool missing_ok)
 {
 	Relation	pg_constraint;
 	HeapTuple	tuple;
@@ -773,7 +773,7 @@ GetConstraintByName(Oid relid, const char *conname)
 	systable_endscan(scan);
 
 	/* If no such constraint exists, complain */
-	if (!OidIsValid(conOid))
+	if (!OidIsValid(conOid) && !missing_ok)
 		ereport(ERROR,
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 				 errmsg("constraint \"%s\" for table \"%s\" does not exist",
diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c
index 2ba2368..7c53ce5 100644
--- a/src/backend/commands/comment.c
+++ b/src/backend/commands/comment.c
@@ -45,12 +45,14 @@
 #include "commands/defrem.h"
 #include "commands/proclang.h"
 #include "commands/tablespace.h"
+#include "commands/trigger.h"
 #include "libpq/be-fsstubs.h"
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "parser/parse_func.h"
 #include "parser/parse_oper.h"
 #include "parser/parse_type.h"
+#include "rewrite/rewriteSupport.h"
 #include "utils/acl.h"
 #include "utils/builtins.h"
 #include "utils/fmgroids.h"
@@ -826,7 +828,6 @@ CommentRule(List *qualname, char *comment)
 	char	   *rulename;
 	RangeVar   *rel;
 	Relation	relation;
-	HeapTuple	tuple;
 	Oid			reloid;
 	Oid			ruleoid;
 
@@ -834,46 +835,8 @@ CommentRule(List *qualname, char *comment)
 	nnames = list_length(qualname);
 	if (nnames == 1)
 	{
-		/* Old-style: only a rule name is given */
-		Relation	RewriteRelation;
-		HeapScanDesc scanDesc;
-		ScanKeyData scanKeyData;
-
 		rulename = strVal(linitial(qualname));
-
-		/* Search pg_rewrite for such a rule */
-		ScanKeyInit(&scanKeyData,
-					Anum_pg_rewrite_rulename,
-					BTEqualStrategyNumber, F_NAMEEQ,
-					PointerGetDatum(rulename));
-
-		RewriteRelation = heap_open(RewriteRelationId, AccessShareLock);
-		scanDesc = heap_beginscan(RewriteRelation, SnapshotNow,
-								  1, &scanKeyData);
-
-		tuple = heap_getnext(scanDesc, ForwardScanDirection);
-		if (HeapTupleIsValid(tuple))
-		{
-			reloid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class;
-			ruleoid = HeapTupleGetOid(tuple);
-		}
-		else
-		{
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("rule \"%s\" does not exist", rulename)));
-			reloid = ruleoid = 0;		/* keep compiler quiet */
-		}
-
-		if (HeapTupleIsValid(tuple = heap_getnext(scanDesc,
-												  ForwardScanDirection)))
-			ereport(ERROR,
-					(errcode(ERRCODE_DUPLICATE_OBJECT),
-				   errmsg("there are multiple rules named \"%s\"", rulename),
-				errhint("Specify a relation name as well as a rule name.")));
-
-		heap_endscan(scanDesc);
-		heap_close(RewriteRelation, AccessShareLock);
+		ruleoid = get_rewrite_oid_without_relid(rulename, &reloid);
 
 		/* Open the owning relation to ensure it won't go away meanwhile */
 		relation = heap_open(reloid, AccessShareLock);
@@ -891,17 +854,7 @@ CommentRule(List *qualname, char *comment)
 		reloid = RelationGetRelid(relation);
 
 		/* Find the rule's pg_rewrite tuple, get its OID */
-		tuple = SearchSysCache2(RULERELNAME,
-								ObjectIdGetDatum(reloid),
-								PointerGetDatum(rulename));
-		if (!HeapTupleIsValid(tuple))
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("rule \"%s\" for relation \"%s\" does not exist",
-							rulename, RelationGetRelationName(relation))));
-		Assert(reloid == ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class);
-		ruleoid = HeapTupleGetOid(tuple);
-		ReleaseSysCache(tuple);
+		ruleoid = get_rewrite_oid(reloid, rulename, false);
 	}
 
 	/* Check object security */
@@ -1046,11 +999,7 @@ CommentTrigger(List *qualname, char *comment)
 	List	   *relname;
 	char	   *trigname;
 	RangeVar   *rel;
-	Relation	pg_trigger,
-				relation;
-	HeapTuple	triggertuple;
-	SysScanDesc scan;
-	ScanKeyData entry[2];
+	Relation	relation;
 	Oid			oid;
 
 	/* Separate relname and trig name */
@@ -1065,46 +1014,16 @@ CommentTrigger(List *qualname, char *comment)
 	relation = heap_openrv(rel, AccessShareLock);
 
 	/* Check object security */
-
 	if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
 					   RelationGetRelationName(relation));
 
-	/*
-	 * Fetch the trigger tuple from pg_trigger.  There can be only one because
-	 * of the unique index.
-	 */
-	pg_trigger = heap_open(TriggerRelationId, AccessShareLock);
-	ScanKeyInit(&entry[0],
-				Anum_pg_trigger_tgrelid,
-				BTEqualStrategyNumber, F_OIDEQ,
-				ObjectIdGetDatum(RelationGetRelid(relation)));
-	ScanKeyInit(&entry[1],
-				Anum_pg_trigger_tgname,
-				BTEqualStrategyNumber, F_NAMEEQ,
-				CStringGetDatum(trigname));
-	scan = systable_beginscan(pg_trigger, TriggerRelidNameIndexId, true,
-							  SnapshotNow, 2, entry);
-	triggertuple = systable_getnext(scan);
-
-	/* If no trigger exists for the relation specified, notify user */
-
-	if (!HeapTupleIsValid(triggertuple))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("trigger \"%s\" for table \"%s\" does not exist",
-						trigname, RelationGetRelationName(relation))));
-
-	oid = HeapTupleGetOid(triggertuple);
-
-	systable_endscan(scan);
+	oid = get_trigger_oid(RelationGetRelid(relation), trigname, false);
 
 	/* Call CreateComments() to create/drop the comments */
 	CreateComments(oid, TriggerRelationId, 0, comment);
 
 	/* Done, but hold lock on relation */
-
-	heap_close(pg_trigger, AccessShareLock);
 	heap_close(relation, NoLock);
 }
 
@@ -1143,7 +1062,7 @@ CommentConstraint(List *qualname, char *comment)
 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
 					   RelationGetRelationName(relation));
 
-	conOid = GetConstraintByName(RelationGetRelid(relation), conName);
+	conOid = get_constraint_oid(RelationGetRelid(relation), conName, false);
 
 	/* Call CreateComments() to create/drop the comments */
 	CreateComments(conOid, ConstraintRelationId, 0, comment);
@@ -1166,12 +1085,7 @@ CommentConversion(List *qualname, char *comment)
 {
 	Oid			conversionOid;
 
-	conversionOid = FindConversionByName(qualname);
-	if (!OidIsValid(conversionOid))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("conversion \"%s\" does not exist",
-						NameListToString(qualname))));
+	conversionOid = get_conversion_oid(qualname, false);
 
 	/* Check object security */
 	if (!pg_conversion_ownercheck(conversionOid, GetUserId()))
@@ -1228,65 +1142,23 @@ static void
 CommentOpClass(List *qualname, List *arguments, char *comment)
 {
 	char	   *amname;
-	char	   *schemaname;
-	char	   *opcname;
 	Oid			amID;
 	Oid			opcID;
-	HeapTuple	tuple;
 
 	Assert(list_length(arguments) == 1);
 	amname = strVal(linitial(arguments));
 
 	/*
-	 * Get the access method's OID.
+	 * Get the operator class OID.
 	 */
 	amID = get_am_oid(amname, false);
-
-	/*
-	 * Look up the opclass.
-	 */
-
-	/* deconstruct the name list */
-	DeconstructQualifiedName(qualname, &schemaname, &opcname);
-
-	if (schemaname)
-	{
-		/* Look in specific schema only */
-		Oid			namespaceId;
-
-		namespaceId = LookupExplicitNamespace(schemaname);
-		tuple = SearchSysCache3(CLAAMNAMENSP,
-								ObjectIdGetDatum(amID),
-								PointerGetDatum(opcname),
-								ObjectIdGetDatum(namespaceId));
-	}
-	else
-	{
-		/* Unqualified opclass name, so search the search path */
-		opcID = OpclassnameGetOpcid(amID, opcname);
-		if (!OidIsValid(opcID))
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
-							opcname, amname)));
-		tuple = SearchSysCache1(CLAOID, ObjectIdGetDatum(opcID));
-	}
-
-	if (!HeapTupleIsValid(tuple))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
-						NameListToString(qualname), amname)));
-
-	opcID = HeapTupleGetOid(tuple);
+	opcID = get_opclass_oid(amID, qualname, false);
 
 	/* Permission check: must own opclass */
 	if (!pg_opclass_ownercheck(opcID, GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPCLASS,
 					   NameListToString(qualname));
 
-	ReleaseSysCache(tuple);
-
 	/* Call CreateComments() to create/drop the comments */
 	CreateComments(opcID, OperatorClassRelationId, 0, comment);
 }
@@ -1304,65 +1176,21 @@ static void
 CommentOpFamily(List *qualname, List *arguments, char *comment)
 {
 	char	   *amname;
-	char	   *schemaname;
-	char	   *opfname;
 	Oid			amID;
 	Oid			opfID;
-	HeapTuple	tuple;
 
 	Assert(list_length(arguments) == 1);
 	amname = strVal(linitial(arguments));
 
-	/*
-	 * Get the access method's OID.
-	 */
+	/* Get the opfamily OID. */
 	amID = get_am_oid(amname, false);
-
-	/*
-	 * Look up the opfamily.
-	 */
-
-	/* deconstruct the name list */
-	DeconstructQualifiedName(qualname, &schemaname, &opfname);
-
-	if (schemaname)
-	{
-		/* Look in specific schema only */
-		Oid			namespaceId;
-
-		namespaceId = LookupExplicitNamespace(schemaname);
-		tuple = SearchSysCache3(OPFAMILYAMNAMENSP,
-								ObjectIdGetDatum(amID),
-								PointerGetDatum(opfname),
-								ObjectIdGetDatum(namespaceId));
-	}
-	else
-	{
-		/* Unqualified opfamily name, so search the search path */
-		opfID = OpfamilynameGetOpfid(amID, opfname);
-		if (!OidIsValid(opfID))
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator family \"%s\" does not exist for access method \"%s\"",
-							opfname, amname)));
-		tuple = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfID));
-	}
-
-	if (!HeapTupleIsValid(tuple))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("operator family \"%s\" does not exist for access method \"%s\"",
-						NameListToString(qualname), amname)));
-
-	opfID = HeapTupleGetOid(tuple);
+	opfID = get_opfamily_oid(amID, qualname, false);
 
 	/* Permission check: must own opfamily */
 	if (!pg_opfamily_ownercheck(opfID, GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPFAMILY,
 					   NameListToString(qualname));
 
-	ReleaseSysCache(tuple);
-
 	/* Call CreateComments() to create/drop the comments */
 	CreateComments(opfID, OperatorFamilyRelationId, 0, comment);
 }
@@ -1423,7 +1251,6 @@ CommentCast(List *qualname, List *arguments, char *comment)
 	TypeName   *targettype;
 	Oid			sourcetypeid;
 	Oid			targettypeid;
-	HeapTuple	tuple;
 	Oid			castOid;
 
 	Assert(list_length(qualname) == 1);
@@ -1436,18 +1263,8 @@ CommentCast(List *qualname, List *arguments, char *comment)
 	sourcetypeid = typenameTypeId(NULL, sourcetype, NULL);
 	targettypeid = typenameTypeId(NULL, targettype, NULL);
 
-	tuple = SearchSysCache2(CASTSOURCETARGET,
-							ObjectIdGetDatum(sourcetypeid),
-							ObjectIdGetDatum(targettypeid));
-	if (!HeapTupleIsValid(tuple))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("cast from type %s to type %s does not exist",
-						format_type_be(sourcetypeid),
-						format_type_be(targettypeid))));
-
 	/* Get the OID of the cast */
-	castOid = HeapTupleGetOid(tuple);
+	castOid = get_cast_oid(sourcetypeid, targettypeid, false);
 
 	/* Permission check */
 	if (!pg_type_ownercheck(sourcetypeid, GetUserId())
@@ -1458,8 +1275,6 @@ CommentCast(List *qualname, List *arguments, char *comment)
 						format_type_be(sourcetypeid),
 						format_type_be(targettypeid))));
 
-	ReleaseSysCache(tuple);
-
 	/* Call CreateComments() to create/drop the comments */
 	CreateComments(castOid, CastRelationId, 0, comment);
 }
@@ -1469,7 +1284,7 @@ CommentTSParser(List *qualname, char *comment)
 {
 	Oid			prsId;
 
-	prsId = TSParserGetPrsid(qualname, false);
+	prsId = get_ts_parser_oid(qualname, false);
 
 	if (!superuser())
 		ereport(ERROR,
@@ -1484,7 +1299,7 @@ CommentTSDictionary(List *qualname, char *comment)
 {
 	Oid			dictId;
 
-	dictId = TSDictionaryGetDictid(qualname, false);
+	dictId = get_ts_dict_oid(qualname, false);
 
 	if (!pg_ts_dict_ownercheck(dictId, GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSDICTIONARY,
@@ -1498,7 +1313,7 @@ CommentTSTemplate(List *qualname, char *comment)
 {
 	Oid			tmplId;
 
-	tmplId = TSTemplateGetTmplid(qualname, false);
+	tmplId = get_ts_template_oid(qualname, false);
 
 	if (!superuser())
 		ereport(ERROR,
@@ -1513,7 +1328,7 @@ CommentTSConfiguration(List *qualname, char *comment)
 {
 	Oid			cfgId;
 
-	cfgId = TSConfigGetCfgid(qualname, false);
+	cfgId = get_ts_config_oid(qualname, false);
 
 	if (!pg_ts_config_ownercheck(cfgId, GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSCONFIGURATION,
diff --git a/src/backend/commands/conversioncmds.c b/src/backend/commands/conversioncmds.c
index 57ddab0..350abf2 100644
--- a/src/backend/commands/conversioncmds.c
+++ b/src/backend/commands/conversioncmds.c
@@ -142,23 +142,13 @@ DropConversionsCommand(DropStmt *drop)
 		Form_pg_conversion con;
 		ObjectAddress object;
 
-		conversionOid = FindConversionByName(name);
+		conversionOid = get_conversion_oid(name, drop->missing_ok);
 
 		if (!OidIsValid(conversionOid))
 		{
-			if (!drop->missing_ok)
-			{
-				ereport(ERROR,
-						(errcode(ERRCODE_UNDEFINED_OBJECT),
-						 errmsg("conversion \"%s\" does not exist",
-								NameListToString(name))));
-			}
-			else
-			{
-				ereport(NOTICE,
-						(errmsg("conversion \"%s\" does not exist, skipping",
-								NameListToString(name))));
-			}
+			ereport(NOTICE,
+					(errmsg("conversion \"%s\" does not exist, skipping",
+							NameListToString(name))));
 			continue;
 		}
 
@@ -202,12 +192,7 @@ RenameConversion(List *name, const char *newname)
 
 	rel = heap_open(ConversionRelationId, RowExclusiveLock);
 
-	conversionOid = FindConversionByName(name);
-	if (!OidIsValid(conversionOid))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("conversion \"%s\" does not exist",
-						NameListToString(name))));
+	conversionOid = get_conversion_oid(name, false);
 
 	tup = SearchSysCacheCopy1(CONVOID, ObjectIdGetDatum(conversionOid));
 	if (!HeapTupleIsValid(tup)) /* should not happen */
@@ -255,12 +240,7 @@ AlterConversionOwner(List *name, Oid newOwnerId)
 
 	rel = heap_open(ConversionRelationId, RowExclusiveLock);
 
-	conversionOid = FindConversionByName(name);
-	if (!OidIsValid(conversionOid))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("conversion \"%s\" does not exist",
-						NameListToString(name))));
+	conversionOid = get_conversion_oid(name, false);
 
 	AlterConversionOwner_internal(rel, conversionOid, newOwnerId);
 
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 9a584ed..781b72d 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -1759,30 +1759,23 @@ DropCast(DropCastStmt *stmt)
 {
 	Oid			sourcetypeid;
 	Oid			targettypeid;
-	HeapTuple	tuple;
 	ObjectAddress object;
 
 	/* when dropping a cast, the types must exist even if you use IF EXISTS */
 	sourcetypeid = typenameTypeId(NULL, stmt->sourcetype, NULL);
 	targettypeid = typenameTypeId(NULL, stmt->targettype, NULL);
 
-	tuple = SearchSysCache2(CASTSOURCETARGET,
-							ObjectIdGetDatum(sourcetypeid),
-							ObjectIdGetDatum(targettypeid));
-	if (!HeapTupleIsValid(tuple))
+	object.classId = CastRelationId;
+	object.objectId = get_cast_oid(sourcetypeid, targettypeid,
+								   stmt->missing_ok);
+	object.objectSubId = 0;
+
+	if (!OidIsValid(object.objectId))
 	{
-		if (!stmt->missing_ok)
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("cast from type %s to type %s does not exist",
-							format_type_be(sourcetypeid),
-							format_type_be(targettypeid))));
-		else
-			ereport(NOTICE,
+		ereport(NOTICE,
 			 (errmsg("cast from type %s to type %s does not exist, skipping",
 					 format_type_be(sourcetypeid),
 					 format_type_be(targettypeid))));
-
 		return;
 	}
 
@@ -1798,15 +1791,31 @@ DropCast(DropCastStmt *stmt)
 	/*
 	 * Do the deletion
 	 */
-	object.classId = CastRelationId;
-	object.objectId = HeapTupleGetOid(tuple);
-	object.objectSubId = 0;
-
-	ReleaseSysCache(tuple);
-
 	performDeletion(&object, stmt->behavior);
 }
 
+/*
+ * get_cast_oid - given two type OIDs, look up a cast OID
+ *
+ * If missing_ok is false, throw an error if the cast is not found.  If
+ * true, just return InvalidOid.
+ */
+Oid
+get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok)
+{
+	Oid		oid;
+
+	oid = GetSysCacheOid2(CASTSOURCETARGET,
+						  ObjectIdGetDatum(sourcetypeid),
+						  ObjectIdGetDatum(targettypeid));
+	if (!OidIsValid(oid) && !missing_ok)
+		ereport(ERROR,
+				(errcode(ERRCODE_UNDEFINED_OBJECT),
+				 errmsg("cast from type %s to type %s does not exist",
+						format_type_be(sourcetypeid),
+						format_type_be(targettypeid))));
+	return oid;
+}
 
 void
 DropCastById(Oid castOid)
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index 6cc9722..57b5e55 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -90,10 +90,11 @@ static void AlterOpFamilyOwner_internal(Relation rel, HeapTuple tuple,
  * Returns a syscache tuple reference, or NULL if not found.
  */
 static HeapTuple
-OpFamilyCacheLookup(Oid amID, List *opfamilyname)
+OpFamilyCacheLookup(Oid amID, List *opfamilyname, bool missing_ok)
 {
 	char	   *schemaname;
 	char	   *opfname;
+	HeapTuple	htup;
 
 	/* deconstruct the name list */
 	DeconstructQualifiedName(opfamilyname, &schemaname, &opfname);
@@ -104,7 +105,7 @@ OpFamilyCacheLookup(Oid amID, List *opfamilyname)
 		Oid			namespaceId;
 
 		namespaceId = LookupExplicitNamespace(schemaname);
-		return SearchSysCache3(OPFAMILYAMNAMENSP,
+		htup = SearchSysCache3(OPFAMILYAMNAMENSP,
 							   ObjectIdGetDatum(amID),
 							   PointerGetDatum(opfname),
 							   ObjectIdGetDatum(namespaceId));
@@ -115,9 +116,47 @@ OpFamilyCacheLookup(Oid amID, List *opfamilyname)
 		Oid			opfID = OpfamilynameGetOpfid(amID, opfname);
 
 		if (!OidIsValid(opfID))
-			return NULL;
-		return SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfID));
+			htup = NULL;
+		else
+			htup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfID));
+	}
+
+	if (!HeapTupleIsValid(htup) && !missing_ok)
+	{
+		HeapTuple amtup;
+
+		amtup = SearchSysCache1(AMOID, ObjectIdGetDatum(amID));
+		if (!HeapTupleIsValid(amtup))
+			elog(ERROR, "cache lookup failed for access method %u", amID);
+		ereport(ERROR,
+				(errcode(ERRCODE_UNDEFINED_OBJECT),
+				 errmsg("operator family \"%s\" does not exist for access method \"%s\"",
+				   NameListToString(opfamilyname),
+				   NameStr(((Form_pg_am) GETSTRUCT(amtup))->amname))));
 	}
+
+	return htup;
+}
+
+/*
+ * get_opfamily_oid
+ *    find an opfamily OID by possibly qualified name
+ *
+ * If not found, returns InvalidOid if missing_ok, else throws error.
+ */
+Oid
+get_opfamily_oid(Oid amID, List *opfamilyname, bool missing_ok)
+{
+	HeapTuple	htup;
+	Oid			opfID;
+
+	htup = OpFamilyCacheLookup(amID, opfamilyname, missing_ok);
+	if (!HeapTupleIsValid(htup))
+		return InvalidOid;
+	opfID = HeapTupleGetOid(htup);
+	ReleaseSysCache(htup);
+
+	return opfID;
 }
 
 /*
@@ -127,10 +166,11 @@ OpFamilyCacheLookup(Oid amID, List *opfamilyname)
  * Returns a syscache tuple reference, or NULL if not found.
  */
 static HeapTuple
-OpClassCacheLookup(Oid amID, List *opclassname)
+OpClassCacheLookup(Oid amID, List *opclassname, bool missing_ok)
 {
 	char	   *schemaname;
 	char	   *opcname;
+	HeapTuple	htup;
 
 	/* deconstruct the name list */
 	DeconstructQualifiedName(opclassname, &schemaname, &opcname);
@@ -141,7 +181,7 @@ OpClassCacheLookup(Oid amID, List *opclassname)
 		Oid			namespaceId;
 
 		namespaceId = LookupExplicitNamespace(schemaname);
-		return SearchSysCache3(CLAAMNAMENSP,
+		htup = SearchSysCache3(CLAAMNAMENSP,
 							   ObjectIdGetDatum(amID),
 							   PointerGetDatum(opcname),
 							   ObjectIdGetDatum(namespaceId));
@@ -152,9 +192,47 @@ OpClassCacheLookup(Oid amID, List *opclassname)
 		Oid			opcID = OpclassnameGetOpcid(amID, opcname);
 
 		if (!OidIsValid(opcID))
-			return NULL;
-		return SearchSysCache1(CLAOID, ObjectIdGetDatum(opcID));
+			htup = NULL;
+		else
+			htup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opcID));
+	}
+
+	if (!HeapTupleIsValid(htup) && !missing_ok)
+	{
+		HeapTuple amtup;
+
+		amtup = SearchSysCache1(AMOID, ObjectIdGetDatum(amID));
+		if (!HeapTupleIsValid(amtup))
+			elog(ERROR, "cache lookup failed for access method %u", amID);
+		ereport(ERROR,
+				(errcode(ERRCODE_UNDEFINED_OBJECT),
+				 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
+						NameListToString(opclassname),
+						NameStr(((Form_pg_am) GETSTRUCT(amtup))->amname))));
 	}
+
+	return htup;
+}
+
+/*
+ * get_opclass_oid
+ *    find an opclass OID by possibly qualified name
+ *
+ * If not found, returns InvalidOid if missing_ok, else throws error.
+ */
+Oid
+get_opclass_oid(Oid amID, List *opclassname, bool missing_ok)
+{
+	HeapTuple	htup;
+	Oid			opcID;
+
+	htup = OpClassCacheLookup(amID, opclassname, missing_ok);
+	if (!HeapTupleIsValid(htup))
+		return InvalidOid;
+	opcID = HeapTupleGetOid(htup);
+	ReleaseSysCache(htup);
+
+	return opcID;
 }
 
 /*
@@ -336,19 +414,7 @@ DefineOpClass(CreateOpClassStmt *stmt)
 	 */
 	if (stmt->opfamilyname)
 	{
-		tup = OpFamilyCacheLookup(amoid, stmt->opfamilyname);
-		if (!HeapTupleIsValid(tup))
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator family \"%s\" does not exist for access method \"%s\"",
-					   NameListToString(stmt->opfamilyname), stmt->amname)));
-		opfamilyoid = HeapTupleGetOid(tup);
-
-		/*
-		 * XXX given the superuser check above, there's no need for an
-		 * ownership check here
-		 */
-		ReleaseSysCache(tup);
+		opfamilyoid = get_opfamily_oid(amoid, stmt->opfamilyname, false);
 	}
 	else
 	{
@@ -773,14 +839,7 @@ AlterOpFamily(AlterOpFamilyStmt *stmt)
 	ReleaseSysCache(tup);
 
 	/* Look up the opfamily */
-	tup = OpFamilyCacheLookup(amoid, stmt->opfamilyname);
-	if (!HeapTupleIsValid(tup))
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("operator family \"%s\" does not exist for access method \"%s\"",
-						NameListToString(stmt->opfamilyname), stmt->amname)));
-	opfamilyoid = HeapTupleGetOid(tup);
-	ReleaseSysCache(tup);
+	opfamilyoid = get_opfamily_oid(amoid, stmt->opfamilyname, false);
 
 	/*
 	 * Currently, we require superuser privileges to alter an opfamily.
@@ -1476,26 +1535,16 @@ RemoveOpClass(RemoveOpClassStmt *stmt)
 	HeapTuple	tuple;
 	ObjectAddress object;
 
-	/*
-	 * Get the access method's OID.
-	 */
+	/* Get the access method's OID. */
 	amID = get_am_oid(stmt->amname, false);
 
-	/*
-	 * Look up the opclass.
-	 */
-	tuple = OpClassCacheLookup(amID, stmt->opclassname);
+	/* Look up the opclass. */
+	tuple = OpClassCacheLookup(amID, stmt->opclassname, stmt->missing_ok);
 	if (!HeapTupleIsValid(tuple))
 	{
-		if (!stmt->missing_ok)
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
-						NameListToString(stmt->opclassname), stmt->amname)));
-		else
-			ereport(NOTICE,
-					(errmsg("operator class \"%s\" does not exist for access method \"%s\"",
-						NameListToString(stmt->opclassname), stmt->amname)));
+		ereport(NOTICE,
+				(errmsg("operator class \"%s\" does not exist for access method \"%s\"",
+					NameListToString(stmt->opclassname), stmt->amname)));
 		return;
 	}
 
@@ -1540,18 +1589,13 @@ RemoveOpFamily(RemoveOpFamilyStmt *stmt)
 	/*
 	 * Look up the opfamily.
 	 */
-	tuple = OpFamilyCacheLookup(amID, stmt->opfamilyname);
+	tuple = OpFamilyCacheLookup(amID, stmt->opfamilyname, stmt->missing_ok);
 	if (!HeapTupleIsValid(tuple))
 	{
-		if (!stmt->missing_ok)
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator family \"%s\" does not exist for access method \"%s\"",
-					   NameListToString(stmt->opfamilyname), stmt->amname)));
-		else
-			ereport(NOTICE,
-					(errmsg("operator family \"%s\" does not exist for access method \"%s\"",
-					   NameListToString(stmt->opfamilyname), stmt->amname)));
+		ereport(ERROR,
+				(errcode(ERRCODE_UNDEFINED_OBJECT),
+				 errmsg("operator family \"%s\" does not exist for access method \"%s\"",
+				   NameListToString(stmt->opfamilyname), stmt->amname)));
 		return;
 	}
 
@@ -1686,8 +1730,7 @@ RenameOpClass(List *name, const char *access_method, const char *newname)
 	Oid			opcOid;
 	Oid			amOid;
 	Oid			namespaceOid;
-	char	   *schemaname;
-	char	   *opcname;
+	HeapTuple	origtup;
 	HeapTuple	tup;
 	Relation	rel;
 	AclResult	aclresult;
@@ -1696,42 +1739,12 @@ RenameOpClass(List *name, const char *access_method, const char *newname)
 
 	rel = heap_open(OperatorClassRelationId, RowExclusiveLock);
 
-	/*
-	 * Look up the opclass
-	 */
-	DeconstructQualifiedName(name, &schemaname, &opcname);
-
-	if (schemaname)
-	{
-		namespaceOid = LookupExplicitNamespace(schemaname);
-
-		tup = SearchSysCacheCopy3(CLAAMNAMENSP,
-								  ObjectIdGetDatum(amOid),
-								  PointerGetDatum(opcname),
-								  ObjectIdGetDatum(namespaceOid));
-		if (!HeapTupleIsValid(tup))
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
-							opcname, access_method)));
-
-		opcOid = HeapTupleGetOid(tup);
-	}
-	else
-	{
-		opcOid = OpclassnameGetOpcid(amOid, opcname);
-		if (!OidIsValid(opcOid))
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
-							opcname, access_method)));
-
-		tup = SearchSysCacheCopy1(CLAOID, ObjectIdGetDatum(opcOid));
-		if (!HeapTupleIsValid(tup))		/* should not happen */
-			elog(ERROR, "cache lookup failed for opclass %u", opcOid);
-
-		namespaceOid = ((Form_pg_opclass) GETSTRUCT(tup))->opcnamespace;
-	}
+	/* Look up the opclass. */
+	origtup = OpClassCacheLookup(amOid, name, false);
+	tup = heap_copytuple(origtup);
+	ReleaseSysCache(origtup);
+	opcOid = HeapTupleGetOid(tup);
+	namespaceOid = ((Form_pg_opclass) GETSTRUCT(tup))->opcnamespace;
 
 	/* make sure the new name doesn't exist */
 	if (SearchSysCacheExists3(CLAAMNAMENSP,
@@ -1864,49 +1877,16 @@ AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId)
 	Oid			amOid;
 	Relation	rel;
 	HeapTuple	tup;
-	char	   *opcname;
-	char	   *schemaname;
+	HeapTuple	origtup;
 
 	amOid = get_am_oid(access_method, false);
 
 	rel = heap_open(OperatorClassRelationId, RowExclusiveLock);
 
-	/*
-	 * Look up the opclass
-	 */
-	DeconstructQualifiedName(name, &schemaname, &opcname);
-
-	if (schemaname)
-	{
-		Oid			namespaceOid;
-
-		namespaceOid = LookupExplicitNamespace(schemaname);
-
-		tup = SearchSysCacheCopy3(CLAAMNAMENSP,
-								  ObjectIdGetDatum(amOid),
-								  PointerGetDatum(opcname),
-								  ObjectIdGetDatum(namespaceOid));
-		if (!HeapTupleIsValid(tup))
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
-							opcname, access_method)));
-	}
-	else
-	{
-		Oid			opcOid;
-
-		opcOid = OpclassnameGetOpcid(amOid, opcname);
-		if (!OidIsValid(opcOid))
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
-							opcname, access_method)));
-
-		tup = SearchSysCacheCopy1(CLAOID, ObjectIdGetDatum(opcOid));
-		if (!HeapTupleIsValid(tup))		/* should not happen */
-			elog(ERROR, "cache lookup failed for opclass %u", opcOid);
-	}
+	/* Look up the opclass. */
+	origtup = OpClassCacheLookup(amOid, name, false);
+	tup = heap_copytuple(origtup);
+	ReleaseSysCache(origtup);
 
 	AlterOpClassOwner_internal(rel, tup, newOwnerId);
 
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 2cbc192..71724c8 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -960,46 +960,17 @@ void
 DropTrigger(Oid relid, const char *trigname, DropBehavior behavior,
 			bool missing_ok)
 {
-	Relation	tgrel;
-	ScanKeyData skey[2];
-	SysScanDesc tgscan;
-	HeapTuple	tup;
 	ObjectAddress object;
 
-	/*
-	 * Find the trigger, verify permissions, set up object address
-	 */
-	tgrel = heap_open(TriggerRelationId, AccessShareLock);
-
-	ScanKeyInit(&skey[0],
-				Anum_pg_trigger_tgrelid,
-				BTEqualStrategyNumber, F_OIDEQ,
-				ObjectIdGetDatum(relid));
-
-	ScanKeyInit(&skey[1],
-				Anum_pg_trigger_tgname,
-				BTEqualStrategyNumber, F_NAMEEQ,
-				CStringGetDatum(trigname));
-
-	tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
-								SnapshotNow, 2, skey);
-
-	tup = systable_getnext(tgscan);
+	object.classId = TriggerRelationId;
+	object.objectId = get_trigger_oid(relid, trigname, missing_ok);
+	object.objectSubId = 0;
 
-	if (!HeapTupleIsValid(tup))
+	if (!OidIsValid(object.objectId))
 	{
-		if (!missing_ok)
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_OBJECT),
-					 errmsg("trigger \"%s\" for table \"%s\" does not exist",
-							trigname, get_rel_name(relid))));
-		else
-			ereport(NOTICE,
-					(errmsg("trigger \"%s\" for table \"%s\" does not exist, skipping",
-							trigname, get_rel_name(relid))));
-		/* cleanup */
-		systable_endscan(tgscan);
-		heap_close(tgrel, AccessShareLock);
+		ereport(NOTICE,
+				(errmsg("trigger \"%s\" for table \"%s\" does not exist, skipping",
+						trigname, get_rel_name(relid))));
 		return;
 	}
 
@@ -1007,13 +978,6 @@ DropTrigger(Oid relid, const char *trigname, DropBehavior behavior,
 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
 					   get_rel_name(relid));
 
-	object.classId = TriggerRelationId;
-	object.objectId = HeapTupleGetOid(tup);
-	object.objectSubId = 0;
-
-	systable_endscan(tgscan);
-	heap_close(tgrel, AccessShareLock);
-
 	/*
 	 * Do the deletion
 	 */
@@ -1093,6 +1057,59 @@ RemoveTriggerById(Oid trigOid)
 }
 
 /*
+ * get_trigger_oid - Look up a trigger by name to find its OID.
+ *
+ * If missing_ok is false, throw an error if trigger not found.  If
+ * true, just return InvalidOid.
+ */
+Oid
+get_trigger_oid(Oid relid, const char *trigname, bool missing_ok)
+{
+	Relation	tgrel;
+	ScanKeyData skey[2];
+	SysScanDesc tgscan;
+	HeapTuple	tup;
+	Oid			oid;
+
+	/*
+	 * Find the trigger, verify permissions, set up object address
+	 */
+	tgrel = heap_open(TriggerRelationId, AccessShareLock);
+
+	ScanKeyInit(&skey[0],
+				Anum_pg_trigger_tgrelid,
+				BTEqualStrategyNumber, F_OIDEQ,
+				ObjectIdGetDatum(relid));
+	ScanKeyInit(&skey[1],
+				Anum_pg_trigger_tgname,
+				BTEqualStrategyNumber, F_NAMEEQ,
+				CStringGetDatum(trigname));
+
+	tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
+								SnapshotNow, 2, skey);
+
+	tup = systable_getnext(tgscan);
+
+	if (!HeapTupleIsValid(tup))
+	{
+		if (!missing_ok)
+			ereport(ERROR,
+					(errcode(ERRCODE_UNDEFINED_OBJECT),
+					 errmsg("trigger \"%s\" for table \"%s\" does not exist",
+							trigname, get_rel_name(relid))));
+		oid = InvalidOid;
+	}
+	else
+	{
+		oid = HeapTupleGetOid(tup);
+	}
+
+	systable_endscan(tgscan);
+	heap_close(tgrel, AccessShareLock);
+	return oid;
+}
+
+/*
  *		renametrig		- changes the name of a trigger on a relation
  *
  *		trigger name is changed in trigger catalog.
diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c
index ba3de63..e49a492 100644
--- a/src/backend/commands/tsearchcmds.c
+++ b/src/backend/commands/tsearchcmds.c
@@ -295,7 +295,7 @@ RemoveTSParsers(DropStmt *drop)
 		Oid			prsOid;
 		ObjectAddress object;
 
-		prsOid = TSParserGetPrsid(names, true);
+		prsOid = get_ts_parser_oid(names, true);
 
 		if (!OidIsValid(prsOid))
 		{
@@ -368,7 +368,7 @@ RenameTSParser(List *oldname, const char *newname)
 
 	rel = heap_open(TSParserRelationId, RowExclusiveLock);
 
-	prsId = TSParserGetPrsid(oldname, false);
+	prsId = get_ts_parser_oid(oldname, false);
 
 	tup = SearchSysCacheCopy1(TSPARSEROID, ObjectIdGetDatum(prsId));
 
@@ -517,7 +517,7 @@ DefineTSDictionary(List *names, List *parameters)
 
 		if (pg_strcasecmp(defel->defname, "template") == 0)
 		{
-			templId = TSTemplateGetTmplid(defGetQualifiedName(defel), false);
+			templId = get_ts_template_oid(defGetQualifiedName(defel), false);
 		}
 		else
 		{
@@ -582,7 +582,7 @@ RenameTSDictionary(List *oldname, const char *newname)
 
 	rel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
 
-	dictId = TSDictionaryGetDictid(oldname, false);
+	dictId = get_ts_dict_oid(oldname, false);
 
 	tup = SearchSysCacheCopy1(TSDICTOID, ObjectIdGetDatum(dictId));
 
@@ -643,7 +643,7 @@ RemoveTSDictionaries(DropStmt *drop)
 		HeapTuple	tup;
 		Oid			namespaceId;
 
-		dictOid = TSDictionaryGetDictid(names, true);
+		dictOid = get_ts_dict_oid(names, true);
 
 		if (!OidIsValid(dictOid))
 		{
@@ -731,7 +731,7 @@ AlterTSDictionary(AlterTSDictionaryStmt *stmt)
 	bool		repl_null[Natts_pg_ts_dict];
 	bool		repl_repl[Natts_pg_ts_dict];
 
-	dictId = TSDictionaryGetDictid(stmt->dictname, false);
+	dictId = get_ts_dict_oid(stmt->dictname, false);
 
 	rel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
 
@@ -841,7 +841,7 @@ AlterTSDictionaryOwner(List *name, Oid newOwnerId)
 
 	rel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
 
-	dictId = TSDictionaryGetDictid(name, false);
+	dictId = get_ts_dict_oid(name, false);
 
 	tup = SearchSysCacheCopy1(TSDICTOID, ObjectIdGetDatum(dictId));
 
@@ -1073,7 +1073,7 @@ RenameTSTemplate(List *oldname, const char *newname)
 
 	rel = heap_open(TSTemplateRelationId, RowExclusiveLock);
 
-	tmplId = TSTemplateGetTmplid(oldname, false);
+	tmplId = get_ts_template_oid(oldname, false);
 
 	tup = SearchSysCacheCopy1(TSTEMPLATEOID, ObjectIdGetDatum(tmplId));
 
@@ -1126,7 +1126,7 @@ RemoveTSTemplates(DropStmt *drop)
 		Oid			tmplOid;
 		ObjectAddress object;
 
-		tmplOid = TSTemplateGetTmplid(names, true);
+		tmplOid = get_ts_template_oid(names, true);
 
 		if (!OidIsValid(tmplOid))
 		{
@@ -1194,7 +1194,7 @@ GetTSConfigTuple(List *names)
 	HeapTuple	tup;
 	Oid			cfgId;
 
-	cfgId = TSConfigGetCfgid(names, true);
+	cfgId = get_ts_config_oid(names, true);
 	if (!OidIsValid(cfgId))
 		return NULL;
 
@@ -1329,9 +1329,9 @@ DefineTSConfiguration(List *names, List *parameters)
 		DefElem    *defel = (DefElem *) lfirst(pl);
 
 		if (pg_strcasecmp(defel->defname, "parser") == 0)
-			prsOid = TSParserGetPrsid(defGetQualifiedName(defel), false);
+			prsOid = get_ts_parser_oid(defGetQualifiedName(defel), false);
 		else if (pg_strcasecmp(defel->defname, "copy") == 0)
-			sourceOid = TSConfigGetCfgid(defGetQualifiedName(defel), false);
+			sourceOid = get_ts_config_oid(defGetQualifiedName(defel), false);
 		else
 			ereport(ERROR,
 					(errcode(ERRCODE_SYNTAX_ERROR),
@@ -1461,7 +1461,7 @@ RenameTSConfiguration(List *oldname, const char *newname)
 
 	rel = heap_open(TSConfigRelationId, RowExclusiveLock);
 
-	cfgId = TSConfigGetCfgid(oldname, false);
+	cfgId = get_ts_config_oid(oldname, false);
 
 	tup = SearchSysCacheCopy1(TSCONFIGOID, ObjectIdGetDatum(cfgId));
 
@@ -1626,7 +1626,7 @@ AlterTSConfigurationOwner(List *name, Oid newOwnerId)
 
 	rel = heap_open(TSConfigRelationId, RowExclusiveLock);
 
-	cfgId = TSConfigGetCfgid(name, false);
+	cfgId = get_ts_config_oid(name, false);
 
 	tup = SearchSysCacheCopy1(TSCONFIGOID, ObjectIdGetDatum(cfgId));
 
@@ -1828,7 +1828,7 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
 	{
 		List	   *names = (List *) lfirst(c);
 
-		dictIds[i] = TSDictionaryGetDictid(names, false);
+		dictIds[i] = get_ts_dict_oid(names, false);
 		i++;
 	}
 
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index 90d5c76..8745201 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -712,8 +712,8 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
 
 			/* Copy comment on constraint */
 			if ((inhRelation->options & CREATE_TABLE_LIKE_COMMENTS) &&
-				(comment = GetComment(GetConstraintByName(RelationGetRelid(relation),
-														  n->conname),
+				(comment = GetComment(get_constraint_oid(RelationGetRelid(relation),
+														  n->conname, false),
 									  ConstraintRelationId,
 									  0)) != NULL)
 			{
diff --git a/src/backend/rewrite/rewriteSupport.c b/src/backend/rewrite/rewriteSupport.c
index 27d21e3..786a7c6 100644
--- a/src/backend/rewrite/rewriteSupport.c
+++ b/src/backend/rewrite/rewriteSupport.c
@@ -17,9 +17,14 @@
 #include "access/heapam.h"
 #include "catalog/indexing.h"
 #include "catalog/pg_class.h"
+#include "catalog/pg_rewrite.h"
 #include "rewrite/rewriteSupport.h"
+#include "utils/fmgroids.h"
 #include "utils/inval.h"
+#include "utils/lsyscache.h"
+#include "utils/rel.h"
 #include "utils/syscache.h"
+#include "utils/tqual.h"
 
 
 /*
@@ -86,3 +91,82 @@ SetRelationRuleStatus(Oid relationId, bool relHasRules,
 	heap_freetuple(tuple);
 	heap_close(relationRelation, RowExclusiveLock);
 }
+
+/*
+ * Find rule oid.
+ *
+ * If missing_ok is false, throw an error if rule name not found.  If
+ * true, just return InvalidOid.
+ */
+Oid
+get_rewrite_oid(Oid relid, const char *rulename, bool missing_ok)
+{
+	HeapTuple	tuple;
+	Oid			ruleoid;
+
+	/* Find the rule's pg_rewrite tuple, get its OID */
+	tuple = SearchSysCache2(RULERELNAME,
+							ObjectIdGetDatum(relid),
+							PointerGetDatum(rulename));
+	if (!HeapTupleIsValid(tuple))
+	{
+		if (missing_ok)
+			return InvalidOid;
+		ereport(ERROR,
+				(errcode(ERRCODE_UNDEFINED_OBJECT),
+				 errmsg("rule \"%s\" for relation \"%s\" does not exist",
+						rulename, get_rel_name(relid))));
+	}
+	Assert(relid == ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class);
+	ruleoid = HeapTupleGetOid(tuple);
+	ReleaseSysCache(tuple);
+	return ruleoid;
+}
+
+/*
+ * Find rule oid, given only a rule name but no rel OID.
+ *
+ * If there's more than one, it's an error.  If there aren't any, that's an
+ * error, too.  In general, this should be avoided - it is provided to support
+ * syntax that is compatible with pre-7.3 versions of PG, where rule names
+ * were unique across the entire database.
+ */
+Oid
+get_rewrite_oid_without_relid(const char *rulename, Oid *reloid)
+{
+	Relation	RewriteRelation;
+	HeapScanDesc scanDesc;
+	ScanKeyData scanKeyData;
+	HeapTuple	htup;
+	Oid			ruleoid;
+
+	/* Search pg_rewrite for such a rule */
+	ScanKeyInit(&scanKeyData,
+				Anum_pg_rewrite_rulename,
+				BTEqualStrategyNumber, F_NAMEEQ,
+				CStringGetDatum(rulename));
+
+	RewriteRelation = heap_open(RewriteRelationId, AccessShareLock);
+	scanDesc = heap_beginscan(RewriteRelation, SnapshotNow, 1, &scanKeyData);
+
+	htup = heap_getnext(scanDesc, ForwardScanDirection);
+	if (!HeapTupleIsValid(htup))
+		ereport(ERROR,
+				(errcode(ERRCODE_UNDEFINED_OBJECT),
+				 errmsg("rule \"%s\" does not exist", rulename)));
+
+	ruleoid = HeapTupleGetOid(htup);
+	if (reloid != NULL)
+		*reloid = ((Form_pg_rewrite) GETSTRUCT(htup))->ev_class;
+
+	if (HeapTupleIsValid(htup = heap_getnext(scanDesc, ForwardScanDirection)))
+		ereport(ERROR,
+				(errcode(ERRCODE_DUPLICATE_OBJECT),
+				 errmsg("there are multiple rules named \"%s\"", rulename),
+				 errhint("Specify a relation name as well as a rule name.")));
+
+	heap_endscan(scanDesc);
+	heap_close(RewriteRelation, AccessShareLock);
+
+	return ruleoid;
+}
diff --git a/src/backend/tsearch/dict_thesaurus.c b/src/backend/tsearch/dict_thesaurus.c
index ee3c118..c793f3b 100644
--- a/src/backend/tsearch/dict_thesaurus.c
+++ b/src/backend/tsearch/dict_thesaurus.c
@@ -642,7 +642,7 @@ thesaurus_init(PG_FUNCTION_ARGS)
 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 				 errmsg("missing Dictionary parameter")));
 
-	d->subdictOid = TSDictionaryGetDictid(stringToQualifiedNameList(subdictname), false);
+	d->subdictOid = get_ts_dict_oid(stringToQualifiedNameList(subdictname), false);
 	d->subdict = lookup_ts_dictionary_cache(d->subdictOid);
 
 	compileTheLexeme(d);
diff --git a/src/backend/tsearch/wparser.c b/src/backend/tsearch/wparser.c
index 0fed35c..25ab898 100644
--- a/src/backend/tsearch/wparser.c
+++ b/src/backend/tsearch/wparser.c
@@ -134,7 +134,7 @@ ts_token_type_byname(PG_FUNCTION_ARGS)
 		Oid			prsId;
 
 		funcctx = SRF_FIRSTCALL_INIT();
-		prsId = TSParserGetPrsid(textToQualifiedNameList(prsname), false);
+		prsId = get_ts_parser_oid(textToQualifiedNameList(prsname), false);
 		tt_setup_firstcall(funcctx, prsId);
 	}
 
@@ -282,7 +282,7 @@ ts_parse_byname(PG_FUNCTION_ARGS)
 		Oid			prsId;
 
 		funcctx = SRF_FIRSTCALL_INIT();
-		prsId = TSParserGetPrsid(textToQualifiedNameList(prsname), false);
+		prsId = get_ts_parser_oid(textToQualifiedNameList(prsname), false);
 		prs_setup_firstcall(funcctx, prsId, txt);
 	}
 
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index 2450cc7..10cfcdb 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -1096,7 +1096,7 @@ regconfigin(PG_FUNCTION_ARGS)
 	 */
 	names = stringToQualifiedNameList(cfg_name_or_oid);
 
-	result = TSConfigGetCfgid(names, false);
+	result = get_ts_config_oid(names, false);
 
 	PG_RETURN_OID(result);
 }
@@ -1206,7 +1206,7 @@ regdictionaryin(PG_FUNCTION_ARGS)
 	 */
 	names = stringToQualifiedNameList(dict_name_or_oid);
 
-	result = TSDictionaryGetDictid(names, false);
+	result = get_ts_dict_oid(names, false);
 
 	PG_RETURN_OID(result);
 }
diff --git a/src/backend/utils/adt/tsvector_op.c b/src/backend/utils/adt/tsvector_op.c
index 78f08f4..a664044 100644
--- a/src/backend/utils/adt/tsvector_op.c
+++ b/src/backend/utils/adt/tsvector_op.c
@@ -1326,7 +1326,7 @@ tsvector_update_trigger(PG_FUNCTION_ARGS, bool config_column)
 					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 					 errmsg("text search configuration name \"%s\" must be schema-qualified",
 							trigger->tgargs[1])));
-		cfgId = TSConfigGetCfgid(names, false);
+		cfgId = get_ts_config_oid(names, false);
 	}
 
 	/* initialize parse state */
diff --git a/src/backend/utils/cache/ts_cache.c b/src/backend/utils/cache/ts_cache.c
index 77d8e2f..ac048dd 100644
--- a/src/backend/utils/cache/ts_cache.c
+++ b/src/backend/utils/cache/ts_cache.c
@@ -581,7 +581,7 @@ getTSCurrentConfig(bool emitError)
 
 	/* Look up the config */
 	TSCurrentConfigCache =
-		TSConfigGetCfgid(stringToQualifiedNameList(TSCurrentConfig),
+		get_ts_config_oid(stringToQualifiedNameList(TSCurrentConfig),
 						 !emitError);
 
 	return TSCurrentConfigCache;
@@ -601,7 +601,7 @@ assignTSCurrentConfig(const char *newval, bool doit, GucSource source)
 		Form_pg_ts_config cfg;
 		char	   *buf;
 
-		cfgId = TSConfigGetCfgid(stringToQualifiedNameList(newval), true);
+		cfgId = get_ts_config_oid(stringToQualifiedNameList(newval), true);
 
 		if (!OidIsValid(cfgId))
 			return NULL;
diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h
index 0fd61a9..3358eb5 100644
--- a/src/include/catalog/namespace.h
+++ b/src/include/catalog/namespace.h
@@ -74,16 +74,16 @@ extern bool OpfamilyIsVisible(Oid opfid);
 extern Oid	ConversionGetConid(const char *conname);
 extern bool ConversionIsVisible(Oid conid);
 
-extern Oid	TSParserGetPrsid(List *names, bool failOK);
+extern Oid	get_ts_parser_oid(List *names, bool missing_ok);
 extern bool TSParserIsVisible(Oid prsId);
 
-extern Oid	TSDictionaryGetDictid(List *names, bool failOK);
+extern Oid	get_ts_dict_oid(List *names, bool missing_ok);
 extern bool TSDictionaryIsVisible(Oid dictId);
 
-extern Oid	TSTemplateGetTmplid(List *names, bool failOK);
+extern Oid	get_ts_template_oid(List *names, bool missing_ok);
 extern bool TSTemplateIsVisible(Oid tmplId);
 
-extern Oid	TSConfigGetCfgid(List *names, bool failOK);
+extern Oid	get_ts_config_oid(List *names, bool missing_ok);
 extern bool TSConfigIsVisible(Oid cfgid);
 
 extern void DeconstructQualifiedName(List *names,
@@ -112,7 +112,7 @@ extern OverrideSearchPath *GetOverrideSearchPath(MemoryContext context);
 extern void PushOverrideSearchPath(OverrideSearchPath *newpath);
 extern void PopOverrideSearchPath(void);
 
-extern Oid	FindConversionByName(List *conname);
+extern Oid	get_conversion_oid(List *conname, bool missing_ok);
 extern Oid	FindDefaultConversionProc(int4 for_encoding, int4 to_encoding);
 
 /* initialization & transaction cleanup code */
diff --git a/src/include/catalog/pg_constraint.h b/src/include/catalog/pg_constraint.h
index c3dfcb0..83ca05f 100644
--- a/src/include/catalog/pg_constraint.h
+++ b/src/include/catalog/pg_constraint.h
@@ -237,6 +237,6 @@ extern char *ChooseConstraintName(const char *name1, const char *name2,
 
 extern void AlterConstraintNamespaces(Oid ownerId, Oid oldNspId,
 						  Oid newNspId, bool isType);
-extern Oid	GetConstraintByName(Oid relid, const char *conname);
+extern Oid	get_constraint_oid(Oid relid, const char *conname, bool missing_ok);
 
 #endif   /* PG_CONSTRAINT_H */
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index 76aff43..2ee79cc 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -67,6 +67,7 @@ extern void DropCastById(Oid castOid);
 extern void AlterFunctionNamespace(List *name, List *argtypes, bool isagg,
 					   const char *newschema);
 extern void ExecuteDoStmt(DoStmt *stmt);
+extern Oid get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok);
 
 /* commands/operatorcmds.c */
 extern void DefineOperator(List *names, List *parameters);
@@ -75,6 +76,8 @@ extern void RemoveOperatorById(Oid operOid);
 extern void AlterOperatorOwner(List *name, TypeName *typeName1,
 				   TypeName *typename2, Oid newOwnerId);
 extern void AlterOperatorOwner_oid(Oid operOid, Oid newOwnerId);
+extern Oid get_opclass_oid(Oid amID, List *opclassname, bool missing_ok);
+extern Oid get_opfamily_oid(Oid amID, List *opfamilyname, bool missing_ok);
 
 /* commands/aggregatecmds.c */
 extern void DefineAggregate(List *name, List *args, bool oldstyle,
diff --git a/src/include/commands/trigger.h b/src/include/commands/trigger.h
index 98bc0c6..267a08e 100644
--- a/src/include/commands/trigger.h
+++ b/src/include/commands/trigger.h
@@ -111,6 +111,7 @@ extern Oid CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
 extern void DropTrigger(Oid relid, const char *trigname,
 			DropBehavior behavior, bool missing_ok);
 extern void RemoveTriggerById(Oid trigOid);
+extern Oid get_trigger_oid(Oid relid, const char *name, bool missing_ok);
 
 extern void renametrig(Oid relid, const char *oldname, const char *newname);
 
diff --git a/src/include/rewrite/rewriteSupport.h b/src/include/rewrite/rewriteSupport.h
index 7784d98..7ad5287 100644
--- a/src/include/rewrite/rewriteSupport.h
+++ b/src/include/rewrite/rewriteSupport.h
@@ -22,4 +22,7 @@ extern bool IsDefinedRewriteRule(Oid owningRel, const char *ruleName);
 extern void SetRelationRuleStatus(Oid relationId, bool relHasRules,
 					  bool relIsBecomingView);
 
+extern Oid get_rewrite_oid(Oid relid, const char *rulename, bool missing_ok);
+extern Oid get_rewrite_oid_without_relid(const char *rulename, Oid *relid);
+
 #endif   /* REWRITESUPPORT_H */
#6KaiGai Kohei
kaigai@ak.jp.nec.com
In reply to: Robert Haas (#5)
Re: get_whatever_oid, part 2

(2010/07/09 22:36), Robert Haas wrote:

2010/7/8 KaiGai Kohei<kaigai@ak.jp.nec.com>:

At the part 1 patch, the object class was entirely matched with
name of the system catalog.
E.g, get_namespace_oid(), get_langeage_oid().
^^^^^^^^^ ^^^^^^^^
| |
+--> pg_namespace +--> pg_language

But some of APIs in the part 2 have different object class name
from their corresponding system catalog.

How about the following renamings?
- get_tsparser_oid() -> get_ts_parser_oid()
- get_tsdictionary_oid() -> get_ts_dict_oid()
- get_tstemplate_oid() -> get_ts_template_oid()
- get_tsconfiguration_oid() -> get_ts_config_oid()
- get_rule_oid() -> get_rewrite_oid()
- get_rule_oid_without_relid() -> get_rewrite_oid_without_relid()

I like that idea. Done, attached.

I checked it, but here is nothing to comment any more.
So, I marked it as "ready for committer".

Thanks,
--
KaiGai Kohei <kaigai@ak.jp.nec.com>