From 0886fc6a5c75b294544263ea979b9cf6195407d9 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Tue, 8 Apr 2014 10:27:56 -0400 Subject: Add new to_reg* functions for error-free OID lookups. These functions won't throw an error if the object doesn't exist, or if (for functions and operators) there's more than one matching object. Yugo Nagata and Nozomi Anzai, reviewed by Amit Khandekar, Marti Raudsepp, Amit Kapila, and me. --- src/backend/utils/adt/regproc.c | 108 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 104 insertions(+), 4 deletions(-) (limited to 'src/backend/utils/adt/regproc.c') diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c index 5d73562a4fc..ed2bdbfb097 100644 --- a/src/backend/utils/adt/regproc.c +++ b/src/backend/utils/adt/regproc.c @@ -152,6 +152,31 @@ regprocin(PG_FUNCTION_ARGS) PG_RETURN_OID(result); } +/* + * to_regproc - converts "proname" to proc OID + * + * If the name is not found, we return NULL. + */ +Datum +to_regproc(PG_FUNCTION_ARGS) +{ + char *pro_name = PG_GETARG_CSTRING(0); + List *names; + FuncCandidateList clist; + + /* + * Parse the name into components and see if it matches any pg_proc entries + * in the current search path. + */ + names = stringToQualifiedNameList(pro_name); + clist = FuncnameGetCandidates(names, -1, NIL, false, false, true); + + if (clist == NULL || clist->next != NULL) + PG_RETURN_NULL(); + + PG_RETURN_OID(clist->oid); +} + /* * regprocout - converts proc OID to "pro_name" */ @@ -502,7 +527,7 @@ regoperin(PG_FUNCTION_ARGS) * pg_operator entries in the current search path. */ names = stringToQualifiedNameList(opr_name_or_oid); - clist = OpernameGetCandidates(names, '\0'); + clist = OpernameGetCandidates(names, '\0', false); if (clist == NULL) ereport(ERROR, @@ -519,6 +544,31 @@ regoperin(PG_FUNCTION_ARGS) PG_RETURN_OID(result); } +/* + * to_regoper - converts "oprname" to operator OID + * + * If the name is not found, we return NULL. + */ +Datum +to_regoper(PG_FUNCTION_ARGS) +{ + char *opr_name = PG_GETARG_CSTRING(0); + List *names; + FuncCandidateList clist; + + /* + * Parse the name into components and see if it matches any pg_operator + * entries in the current search path. + */ + names = stringToQualifiedNameList(opr_name); + clist = OpernameGetCandidates(names, '\0', true); + + if (clist == NULL || clist->next != NULL) + PG_RETURN_NULL(); + + PG_RETURN_OID(clist->oid); +} + /* * regoperout - converts operator OID to "opr_name" */ @@ -558,7 +608,7 @@ regoperout(PG_FUNCTION_ARGS) * qualify it. */ clist = OpernameGetCandidates(list_make1(makeString(oprname)), - '\0'); + '\0', false); if (clist != NULL && clist->next == NULL && clist->oid == oprid) result = pstrdup(oprname); @@ -872,6 +922,33 @@ regclassin(PG_FUNCTION_ARGS) PG_RETURN_OID(result); } +/* + * to_regclass - converts "classname" to class OID + * + * If the name is not found, we return NULL. + */ +Datum +to_regclass(PG_FUNCTION_ARGS) +{ + char *class_name = PG_GETARG_CSTRING(0); + Oid result; + List *names; + + /* + * Parse the name into components and see if it matches any pg_class entries + * in the current search path. + */ + names = stringToQualifiedNameList(class_name); + + /* We might not even have permissions on this relation; don't lock it. */ + result = RangeVarGetRelid(makeRangeVarFromNameList(names), NoLock, true); + + if (OidIsValid(result)) + PG_RETURN_OID(result); + else + PG_RETURN_NULL(); +} + /* * regclassout - converts class OID to "class_name" */ @@ -1028,11 +1105,34 @@ regtypein(PG_FUNCTION_ARGS) * Normal case: invoke the full parser to deal with special cases such as * array syntax. */ - parseTypeString(typ_name_or_oid, &result, &typmod); + parseTypeString(typ_name_or_oid, &result, &typmod, false); PG_RETURN_OID(result); } +/* + * to_regtype - converts "typename" to type OID + * + * If the name is not found, we return NULL. + */ +Datum +to_regtype(PG_FUNCTION_ARGS) +{ + char *typ_name = PG_GETARG_CSTRING(0); + Oid result; + int32 typmod; + + /* + * Invoke the full parser to deal with special cases such as array syntax. + */ + parseTypeString(typ_name, &result, &typmod, true); + + if (OidIsValid(result)) + PG_RETURN_OID(result); + else + PG_RETURN_NULL(); +} + /* * regtypeout - converts type OID to "typ_name" */ @@ -1523,7 +1623,7 @@ parseNameAndArgTypes(const char *string, bool allowNone, List **names, else { /* Use full parser to resolve the type name */ - parseTypeString(typename, &typeid, &typmod); + parseTypeString(typename, &typeid, &typmod, false); } if (*nargs >= FUNC_MAX_ARGS) ereport(ERROR, -- cgit v1.2.3