diff options
Diffstat (limited to 'src/backend/parser')
-rw-r--r-- | src/backend/parser/parse_func.c | 32 | ||||
-rw-r--r-- | src/backend/parser/parse_oper.c | 4 | ||||
-rw-r--r-- | src/backend/parser/parse_type.c | 88 |
3 files changed, 76 insertions, 48 deletions
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index 32179aacb55..63be2a44f16 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -1259,7 +1259,8 @@ func_get_detail(List *funcname, /* Get list of possible candidates from namespace search */ raw_candidates = FuncnameGetCandidates(funcname, nargs, fargnames, - expand_variadic, expand_defaults); + expand_variadic, expand_defaults, + false); /* * Quickly check if there is an exact match to the input datatypes (there @@ -1714,7 +1715,7 @@ FuncNameAsType(List *funcname) Oid result; Type typtup; - typtup = LookupTypeName(NULL, makeTypeNameFromNameList(funcname), NULL); + typtup = LookupTypeName(NULL, makeTypeNameFromNameList(funcname), NULL, false); if (typtup == NULL) return InvalidOid; @@ -1873,7 +1874,7 @@ LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError) { FuncCandidateList clist; - clist = FuncnameGetCandidates(funcname, nargs, NIL, false, false); + clist = FuncnameGetCandidates(funcname, nargs, NIL, false, false, noError); while (clist) { @@ -1893,27 +1894,6 @@ LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError) } /* - * LookupTypeNameOid - * Convenience routine to look up a type, silently accepting shell types - */ -static Oid -LookupTypeNameOid(const TypeName *typename) -{ - Oid result; - Type typtup; - - typtup = LookupTypeName(NULL, typename, NULL); - if (typtup == NULL) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("type \"%s\" does not exist", - TypeNameToString(typename)))); - result = typeTypeId(typtup); - ReleaseSysCache(typtup); - return result; -} - -/* * LookupFuncNameTypeNames * Like LookupFuncName, but the argument types are specified by a * list of TypeName nodes. @@ -1940,7 +1920,7 @@ LookupFuncNameTypeNames(List *funcname, List *argtypes, bool noError) { TypeName *t = (TypeName *) lfirst(args_item); - argoids[i] = LookupTypeNameOid(t); + argoids[i] = LookupTypeNameOid(NULL, t, noError); args_item = lnext(args_item); } @@ -1980,7 +1960,7 @@ LookupAggNameTypeNames(List *aggname, List *argtypes, bool noError) { TypeName *t = (TypeName *) lfirst(lc); - argoids[i] = LookupTypeNameOid(t); + argoids[i] = LookupTypeNameOid(NULL, t, noError); i++; } diff --git a/src/backend/parser/parse_oper.c b/src/backend/parser/parse_oper.c index 387f7fd0b36..99dbd30d758 100644 --- a/src/backend/parser/parse_oper.c +++ b/src/backend/parser/parse_oper.c @@ -148,12 +148,12 @@ LookupOperNameTypeNames(ParseState *pstate, List *opername, if (oprleft == NULL) leftoid = InvalidOid; else - leftoid = typenameTypeId(pstate, oprleft); + leftoid = LookupTypeNameOid(pstate, oprleft, noError); if (oprright == NULL) rightoid = InvalidOid; else - rightoid = typenameTypeId(pstate, oprright); + rightoid = LookupTypeNameOid(pstate, oprright, noError); return LookupOperName(pstate, opername, leftoid, rightoid, noError, location); diff --git a/src/backend/parser/parse_type.c b/src/backend/parser/parse_type.c index 635aa1d3631..b329dfb1684 100644 --- a/src/backend/parser/parse_type.c +++ b/src/backend/parser/parse_type.c @@ -56,7 +56,7 @@ static int32 typenameTypeMod(ParseState *pstate, const TypeName *typeName, */ Type LookupTypeName(ParseState *pstate, const TypeName *typeName, - int32 *typmod_p) + int32 *typmod_p, bool missing_ok) { Oid typoid; HeapTuple tup; @@ -116,24 +116,32 @@ LookupTypeName(ParseState *pstate, const TypeName *typeName, * concurrent DDL. But taking a lock would carry a performance * penalty and would also require a permissions check. */ - relid = RangeVarGetRelid(rel, NoLock, false); + relid = RangeVarGetRelid(rel, NoLock, missing_ok); attnum = get_attnum(relid, field); if (attnum == InvalidAttrNumber) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_COLUMN), - errmsg("column \"%s\" of relation \"%s\" does not exist", - field, rel->relname), - parser_errposition(pstate, typeName->location))); - typoid = get_atttype(relid, attnum); + { + if (missing_ok) + typoid = InvalidOid; + else + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("column \"%s\" of relation \"%s\" does not exist", + field, rel->relname), + parser_errposition(pstate, typeName->location))); + } + else + { + typoid = get_atttype(relid, attnum); - /* this construct should never have an array indicator */ - Assert(typeName->arrayBounds == NIL); + /* this construct should never have an array indicator */ + Assert(typeName->arrayBounds == NIL); - /* emit nuisance notice (intentionally not errposition'd) */ - ereport(NOTICE, - (errmsg("type reference %s converted to %s", - TypeNameToString(typeName), - format_type_be(typoid)))); + /* emit nuisance notice (intentionally not errposition'd) */ + ereport(NOTICE, + (errmsg("type reference %s converted to %s", + TypeNameToString(typeName), + format_type_be(typoid)))); + } } else { @@ -149,10 +157,13 @@ LookupTypeName(ParseState *pstate, const TypeName *typeName, /* Look in specific schema only */ Oid namespaceId; - namespaceId = LookupExplicitNamespace(schemaname, false); - typoid = GetSysCacheOid2(TYPENAMENSP, - PointerGetDatum(typname), - ObjectIdGetDatum(namespaceId)); + namespaceId = LookupExplicitNamespace(schemaname, missing_ok); + if (OidIsValid(namespaceId)) + typoid = GetSysCacheOid2(TYPENAMENSP, + PointerGetDatum(typname), + ObjectIdGetDatum(namespaceId)); + else + typoid = InvalidOid; } else { @@ -185,6 +196,43 @@ LookupTypeName(ParseState *pstate, const TypeName *typeName, } /* + * LookupTypeNameOid + * Given a TypeName object, lookup the pg_type syscache entry of the type. + * Returns InvalidOid if no such type can be found. If the type is found, + * return its Oid. + * + * NB: direct callers of this function need to be aware that the type OID + * returned may correspond to a shell type. Most code should go through + * typenameTypeId instead. + * + * pstate is only used for error location info, and may be NULL. + */ +Oid +LookupTypeNameOid(ParseState *pstate, const TypeName *typeName, bool missing_ok) +{ + Oid typoid; + Type tup; + + tup = LookupTypeName(pstate, typeName, NULL, missing_ok); + if (tup == NULL) + { + if (!missing_ok) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("type \"%s\" does not exist", + TypeNameToString(typeName)), + parser_errposition(pstate, typeName->location))); + + return InvalidOid; + } + + typoid = HeapTupleGetOid(tup); + ReleaseSysCache(tup); + + return typoid; +} + +/* * typenameType - given a TypeName, return a Type structure and typmod * * This is equivalent to LookupTypeName, except that this will report @@ -196,7 +244,7 @@ typenameType(ParseState *pstate, const TypeName *typeName, int32 *typmod_p) { Type tup; - tup = LookupTypeName(pstate, typeName, typmod_p); + tup = LookupTypeName(pstate, typeName, typmod_p, false); if (tup == NULL) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), |