diff options
| author | Tom Lane <tgl@sss.pgh.pa.us> | 2002-08-22 00:01:51 +0000 |
|---|---|---|
| committer | Tom Lane <tgl@sss.pgh.pa.us> | 2002-08-22 00:01:51 +0000 |
| commit | b663f3443ba096a06970214c3e83e79f6e570b84 (patch) | |
| tree | 049e26c1b02535c12bee6e60ba89cf1d42a41a72 /src/backend/parser | |
| parent | 606c9b9d4fafe9300d039c044edc9727c0ed43c9 (diff) | |
| download | postgresql-b663f3443ba096a06970214c3e83e79f6e570b84.tar.gz | |
Add a bunch of pseudo-types to replace the behavior formerly associated
with OPAQUE, as per recent pghackers discussion. I still want to do some
more work on the 'cstring' pseudo-type, but I'm going to commit the bulk
of the changes now before the tree starts shifting under me ...
Diffstat (limited to 'src/backend/parser')
| -rw-r--r-- | src/backend/parser/parse_coerce.c | 61 | ||||
| -rw-r--r-- | src/backend/parser/parse_func.c | 29 |
2 files changed, 51 insertions, 39 deletions
diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c index b472505588..1016c782d2 100644 --- a/src/backend/parser/parse_coerce.c +++ b/src/backend/parser/parse_coerce.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.79 2002/07/20 05:29:01 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.80 2002/08/22 00:01:42 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -47,7 +47,6 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId, Node *result; if (targetTypeId == inputTypeId || - targetTypeId == InvalidOid || node == NULL) { /* no conversion needed, but constraints may need to be applied */ @@ -97,6 +96,12 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId, if (targetTypeId != baseTypeId) result = (Node *) TypeConstraints(result, targetTypeId); } + else if (targetTypeId == ANYOID || + targetTypeId == ANYARRAYOID) + { + /* assume can_coerce_type verified that implicit coercion is okay */ + result = node; + } else if (IsBinaryCompatible(inputTypeId, targetTypeId)) { /* @@ -213,18 +218,10 @@ can_coerce_type(int nargs, Oid *input_typeids, Oid *func_typeids, if (inputTypeId == targetTypeId) continue; - /* - * one of the known-good transparent conversions? then drop - * through... - */ - if (IsBinaryCompatible(inputTypeId, targetTypeId)) - continue; - - /* don't know what to do for the output type? then quit... */ - if (targetTypeId == InvalidOid) + /* don't choke on references to no-longer-existing types */ + if (!typeidIsValid(inputTypeId)) return false; - /* don't know what to do for the input type? then quit... */ - if (inputTypeId == InvalidOid) + if (!typeidIsValid(targetTypeId)) return false; /* @@ -238,18 +235,44 @@ can_coerce_type(int nargs, Oid *input_typeids, Oid *func_typeids, continue; } + /* accept if target is ANY */ + if (targetTypeId == ANYOID) + continue; + + /* if target is ANYARRAY and source is a varlena array type, accept */ + if (targetTypeId == ANYARRAYOID) + { + Oid typOutput; + Oid typElem; + bool typIsVarlena; + + if (getTypeOutputInfo(inputTypeId, &typOutput, &typElem, + &typIsVarlena)) + { + if (OidIsValid(typElem) && typIsVarlena) + continue; + } + /* + * Otherwise reject; this assumes there are no explicit coercions + * to ANYARRAY. If we don't reject then parse_coerce would have + * to repeat the above test. + */ + return false; + } + + /* + * one of the known-good transparent conversions? then drop + * through... + */ + if (IsBinaryCompatible(inputTypeId, targetTypeId)) + continue; + /* * If input is a class type that inherits from target, no problem */ if (typeInheritsFrom(inputTypeId, targetTypeId)) continue; - /* don't choke on references to no-longer-existing types */ - if (!typeidIsValid(inputTypeId)) - return false; - if (!typeidIsValid(targetTypeId)) - return false; - /* * Else, try for run-time conversion using functions: look for a * single-argument function named with the target type name and diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index edd0e81095..87e432b7cf 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.134 2002/08/08 01:44:30 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.135 2002/08/22 00:01:42 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1264,10 +1264,7 @@ func_error(const char *caller, List *funcname, { if (i) appendStringInfo(&argbuf, ", "); - if (OidIsValid(argtypes[i])) - appendStringInfo(&argbuf, format_type_be(argtypes[i])); - else - appendStringInfo(&argbuf, "opaque"); + appendStringInfo(&argbuf, format_type_be(argtypes[i])); } if (caller == NULL) @@ -1289,7 +1286,7 @@ func_error(const char *caller, List *funcname, * Convenience routine to check that a function exists and is an * aggregate. * - * Note: basetype is InvalidOid if we are looking for an aggregate on + * Note: basetype is ANYOID if we are looking for an aggregate on * all types. */ Oid @@ -1303,7 +1300,7 @@ find_aggregate_func(const char *caller, List *aggname, Oid basetype) if (!OidIsValid(oid)) { - if (basetype == InvalidOid) + if (basetype == ANYOID) elog(ERROR, "%s: aggregate %s(*) does not exist", caller, NameListToString(aggname)); else @@ -1322,7 +1319,7 @@ find_aggregate_func(const char *caller, List *aggname, Oid basetype) if (!pform->proisagg) { - if (basetype == InvalidOid) + if (basetype == ANYOID) elog(ERROR, "%s: function %s(*) is not an aggregate", caller, NameListToString(aggname)); else @@ -1366,12 +1363,9 @@ LookupFuncName(List *funcname, int nargs, const Oid *argtypes) * Like LookupFuncName, but the argument types are specified by a * list of TypeName nodes. Also, if we fail to find the function * and caller is not NULL, then an error is reported via func_error. - * - * "opaque" is accepted as a typename only if opaqueOK is true. */ Oid -LookupFuncNameTypeNames(List *funcname, List *argtypes, bool opaqueOK, - const char *caller) +LookupFuncNameTypeNames(List *funcname, List *argtypes, const char *caller) { Oid funcoid; Oid argoids[FUNC_MAX_ARGS]; @@ -1389,15 +1383,10 @@ LookupFuncNameTypeNames(List *funcname, List *argtypes, bool opaqueOK, TypeName *t = (TypeName *) lfirst(argtypes); argoids[i] = LookupTypeName(t); - if (!OidIsValid(argoids[i])) - { - char *typnam = TypeNameToString(t); - if (opaqueOK && strcmp(typnam, "opaque") == 0) - argoids[i] = InvalidOid; - else - elog(ERROR, "Type \"%s\" does not exist", typnam); - } + if (!OidIsValid(argoids[i])) + elog(ERROR, "Type \"%s\" does not exist", + TypeNameToString(t)); argtypes = lnext(argtypes); } |
