diff options
Diffstat (limited to 'src/backend/parser/parse_func.c')
-rw-r--r-- | src/backend/parser/parse_func.c | 74 |
1 files changed, 54 insertions, 20 deletions
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index 393fa6c41ac..76dcd29185c 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.197 2007/06/06 23:00:37 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.198 2007/11/11 19:22:49 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -33,6 +33,7 @@ #include "utils/syscache.h" +static Oid FuncNameAsType(List *funcname); static Node *ParseComplexProjection(ParseState *pstate, char *funcname, Node *first_arg, int location); static void unknown_attribute(ParseState *pstate, Node *relref, char *attname, @@ -752,12 +753,9 @@ func_get_detail(List *funcname, */ if (nargs == 1 && fargs != NIL) { - Oid targetType; + Oid targetType = FuncNameAsType(funcname); - targetType = LookupTypeName(NULL, - makeTypeNameFromNameList(funcname)); - if (OidIsValid(targetType) && - !ISCOMPLEX(targetType)) + if (OidIsValid(targetType)) { Oid sourceType = argtypes[0]; Node *arg1 = linitial(fargs); @@ -986,6 +984,33 @@ make_fn_arguments(ParseState *pstate, } /* + * FuncNameAsType - + * convenience routine to see if a function name matches a type name + * + * Returns the OID of the matching type, or InvalidOid if none. We ignore + * shell types and complex types. + */ +static Oid +FuncNameAsType(List *funcname) +{ + Oid result; + Type typtup; + + typtup = LookupTypeName(NULL, makeTypeNameFromNameList(funcname), NULL); + if (typtup == NULL) + return InvalidOid; + + if (((Form_pg_type) GETSTRUCT(typtup))->typisdefined && + !OidIsValid(typeTypeRelid(typtup))) + result = typeTypeId(typtup); + else + result = InvalidOid; + + ReleaseSysCache(typtup); + return result; +} + +/* * ParseComplexProjection - * handles function calls with a single argument that is of complex type. * If the function call is actually a column projection, return a suitably @@ -1181,6 +1206,27 @@ 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. @@ -1205,14 +1251,7 @@ LookupFuncNameTypeNames(List *funcname, List *argtypes, bool noError) { TypeName *t = (TypeName *) lfirst(args_item); - argoids[i] = LookupTypeName(NULL, t); - - if (!OidIsValid(argoids[i])) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("type \"%s\" does not exist", - TypeNameToString(t)))); - + argoids[i] = LookupTypeNameOid(t); args_item = lnext(args_item); } @@ -1250,12 +1289,7 @@ LookupAggNameTypeNames(List *aggname, List *argtypes, bool noError) { TypeName *t = (TypeName *) lfirst(lc); - argoids[i] = LookupTypeName(NULL, t); - if (!OidIsValid(argoids[i])) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("type \"%s\" does not exist", - TypeNameToString(t)))); + argoids[i] = LookupTypeNameOid(t); i++; } |