diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2002-09-18 21:35:25 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2002-09-18 21:35:25 +0000 |
commit | b26dfb95222fddd25322bdddf3a5a58d3392d8b1 (patch) | |
tree | 757cf0bafab985d38a5c84d3afebe5edd34c4f27 /src/backend/parser/parse_func.c | |
parent | cc70ba2e4daa78ba99619770e19beb06de3dfd1c (diff) |
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
Diffstat (limited to 'src/backend/parser/parse_func.c')
-rw-r--r-- | src/backend/parser/parse_func.c | 39 |
1 files changed, 17 insertions, 22 deletions
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index 648ddfbaf0c..9a54a900aea 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.136 2002/09/04 20:31:23 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.137 2002/09/18 21:35:22 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -32,15 +32,12 @@ #include "utils/syscache.h" -static Node *ParseComplexProjection(ParseState *pstate, - char *funcname, - Node *first_arg); +static Node *ParseComplexProjection(char *funcname, Node *first_arg); static Oid **argtype_inherit(int nargs, Oid *argtypes); static int find_inheritors(Oid relid, Oid **supervec); static Oid **gen_cross_product(InhPaths *arginh, int nargs); -static void make_arguments(ParseState *pstate, - int nargs, +static void make_arguments(int nargs, List *fargs, Oid *input_typeids, Oid *function_typeids); @@ -137,7 +134,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, * ParseComplexProjection can't handle the projection, we have * to keep going. */ - retval = ParseComplexProjection(pstate, cname, first_arg); + retval = ParseComplexProjection(cname, first_arg); if (retval) return retval; } @@ -243,8 +240,8 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, * We can do it as a trivial coercion. coerce_type can handle * these cases, so why duplicate code... */ - return coerce_type(pstate, lfirst(fargs), - oid_array[0], rettype, -1, true); + return coerce_type(lfirst(fargs), oid_array[0], rettype, + COERCION_EXPLICIT, COERCE_EXPLICIT_CALL); } else if (fdresult == FUNCDETAIL_NORMAL) { @@ -296,7 +293,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, } /* perform the necessary typecasting of arguments */ - make_arguments(pstate, nargs, fargs, oid_array, true_oid_array); + make_arguments(nargs, fargs, oid_array, true_oid_array); /* build the appropriate output structure */ if (fdresult == FUNCDETAIL_NORMAL) @@ -307,6 +304,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, funcnode->funcid = funcid; funcnode->funcresulttype = rettype; funcnode->funcretset = retset; + funcnode->funcformat = COERCE_EXPLICIT_CALL; funcnode->func_fcache = NULL; expr->typeOid = rettype; @@ -367,7 +365,7 @@ match_argtypes(int nargs, { next_candidate = current_candidate->next; if (can_coerce_type(nargs, input_typeids, current_candidate->args, - false)) + COERCION_IMPLICIT)) { current_candidate->next = *candidates; *candidates = current_candidate; @@ -470,7 +468,7 @@ func_select_candidate(int nargs, { if (input_typeids[i] != UNKNOWNOID) { - if (IsBinaryCompatible(current_typeids[i], input_typeids[i])) + if (IsBinaryCoercible(input_typeids[i], current_typeids[i])) nmatch++; } } @@ -776,7 +774,7 @@ func_get_detail(List *funcname, Node *arg1 = lfirst(fargs); if ((sourceType == UNKNOWNOID && IsA(arg1, Const)) || - IsBinaryCompatible(sourceType, targetType)) + IsBinaryCoercible(sourceType, targetType)) { /* Yup, it's a type coercion */ *funcid = InvalidOid; @@ -1120,8 +1118,7 @@ typeInheritsFrom(Oid subclassTypeId, Oid superclassTypeId) * actual arguments and argument types, do the necessary typecasting. */ static void -make_arguments(ParseState *pstate, - int nargs, +make_arguments(int nargs, List *fargs, Oid *input_typeids, Oid *function_typeids) @@ -1136,11 +1133,11 @@ make_arguments(ParseState *pstate, /* types don't match? then force coercion using a function call... */ if (input_typeids[i] != function_typeids[i]) { - lfirst(current_fargs) = coerce_type(pstate, - lfirst(current_fargs), + lfirst(current_fargs) = coerce_type(lfirst(current_fargs), input_typeids[i], - function_typeids[i], -1, - false); + function_typeids[i], + COERCION_IMPLICIT, + COERCE_IMPLICIT_CAST); } } } @@ -1179,9 +1176,7 @@ setup_field_select(Node *input, char *attname, Oid relid) * NB: argument is expected to be transformed already, ie, not a RangeVar. */ static Node * -ParseComplexProjection(ParseState *pstate, - char *funcname, - Node *first_arg) +ParseComplexProjection(char *funcname, Node *first_arg) { Oid argtype = exprType(first_arg); Oid argrelid; |