diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2003-04-08 23:20:04 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2003-04-08 23:20:04 +0000 |
commit | 730840c9b649a48604083270d48792915ca89233 (patch) | |
tree | cf3ccc25e61cdfc07061ebec63393d77b3a2f643 /src/backend/parser/parse_func.c | |
parent | 6fb5115850be766c42177cebf672c68c7d8e3ddd (diff) | |
download | postgresql-730840c9b649a48604083270d48792915ca89233.tar.gz postgresql-730840c9b649a48604083270d48792915ca89233.zip |
First phase of work on array improvements. ARRAY[x,y,z] constructor
expressions, ARRAY(sub-SELECT) expressions, some array functions.
Polymorphic functions using ANYARRAY/ANYELEMENT argument and return
types. Some regression tests in place, documentation is lacking.
Joe Conway, with some kibitzing from Tom Lane.
Diffstat (limited to 'src/backend/parser/parse_func.c')
-rw-r--r-- | src/backend/parser/parse_func.c | 68 |
1 files changed, 39 insertions, 29 deletions
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index 3dd5c66f440..59690f4aefb 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.144 2003/02/09 06:56:28 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.145 2003/04/08 23:20:02 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -37,10 +37,6 @@ 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(int nargs, - List *fargs, - Oid *input_typeids, - Oid *function_typeids); static int match_argtypes(int nargs, Oid *input_typeids, FuncCandidateList function_typeids, @@ -81,8 +77,8 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, Node *first_arg = NULL; int nargs = length(fargs); int argn; - Oid oid_array[FUNC_MAX_ARGS]; - Oid *true_oid_array; + Oid actual_arg_types[FUNC_MAX_ARGS]; + Oid *declared_arg_types; Node *retval; bool retset; FuncDetailCode fdresult; @@ -145,7 +141,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, * function. Extract arg type info and transform RangeVar arguments * into varnodes of the appropriate form. */ - MemSet(oid_array, 0, FUNC_MAX_ARGS * sizeof(Oid)); + MemSet(actual_arg_types, 0, FUNC_MAX_ARGS * sizeof(Oid)); argn = 0; foreach(i, fargs) @@ -238,7 +234,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, else toid = exprType(arg); - oid_array[argn++] = toid; + actual_arg_types[argn++] = toid; } /* @@ -248,16 +244,16 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, * function's return value. it also returns the true argument types * to the function. */ - fdresult = func_get_detail(funcname, fargs, nargs, oid_array, + fdresult = func_get_detail(funcname, fargs, nargs, actual_arg_types, &funcid, &rettype, &retset, - &true_oid_array); + &declared_arg_types); if (fdresult == FUNCDETAIL_COERCION) { /* * We can do it as a trivial coercion. coerce_type can handle * these cases, so why duplicate code... */ - return coerce_type(lfirst(fargs), oid_array[0], rettype, + return coerce_type(lfirst(fargs), actual_arg_types[0], rettype, COERCION_EXPLICIT, COERCE_EXPLICIT_CALL); } else if (fdresult == FUNCDETAIL_NORMAL) @@ -303,14 +299,24 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, /* * Else generate a detailed complaint for a function */ - func_error(NULL, funcname, nargs, oid_array, + func_error(NULL, funcname, nargs, actual_arg_types, "Unable to identify a function that satisfies the " "given argument types" "\n\tYou may need to add explicit typecasts"); } + /* + * enforce consistency with ANYARRAY and ANYELEMENT argument and + * return types, possibly adjusting return type or declared_arg_types + * (which will be used as the cast destination by make_fn_arguments) + */ + rettype = enforce_generic_type_consistency(actual_arg_types, + declared_arg_types, + nargs, + rettype); + /* perform the necessary typecasting of arguments */ - make_arguments(nargs, fargs, oid_array, true_oid_array); + make_fn_arguments(fargs, actual_arg_types, declared_arg_types); /* build the appropriate output structure */ if (fdresult == FUNCDETAIL_NORMAL) @@ -1130,32 +1136,36 @@ typeInheritsFrom(Oid subclassTypeId, Oid superclassTypeId) } -/* make_arguments() - * Given the number and types of arguments to a function, and the - * actual arguments and argument types, do the necessary typecasting. +/* + * make_fn_arguments() + * + * Given the actual argument expressions for a function, and the desired + * input types for the function, add any necessary typecasting to the + * expression tree. Caller should already have verified that casting is + * allowed. + * + * Caution: given argument list is modified in-place. */ -static void -make_arguments(int nargs, - List *fargs, - Oid *input_typeids, - Oid *function_typeids) +void +make_fn_arguments(List *fargs, + Oid *actual_arg_types, + Oid *declared_arg_types) { List *current_fargs; - int i; + int i = 0; - for (i = 0, current_fargs = fargs; - i < nargs; - i++, current_fargs = lnext(current_fargs)) + foreach(current_fargs, fargs) { /* types don't match? then force coercion using a function call... */ - if (input_typeids[i] != function_typeids[i]) + if (actual_arg_types[i] != declared_arg_types[i]) { lfirst(current_fargs) = coerce_type(lfirst(current_fargs), - input_typeids[i], - function_typeids[i], + actual_arg_types[i], + declared_arg_types[i], COERCION_IMPLICIT, COERCE_IMPLICIT_CAST); } + i++; } } |