mirror of
https://github.com/postgres/postgres.git
synced 2025-07-07 00:36:50 +03:00
Move checking an explicit VARIADIC "any" argument into the parser.
This is more efficient and simpler . It does mean that an untyped NULL can no longer be used in such cases, which should be mentioned in Release Notes, but doesn't seem a terrible loss. The workaround is to cast the NULL to some array type. Pavel Stehule, reviewed by Jeevan Chalke.
This commit is contained in:
@ -79,6 +79,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
|
||||
Node *retval;
|
||||
bool retset;
|
||||
int nvargs;
|
||||
Oid vatype;
|
||||
FuncDetailCode fdresult;
|
||||
|
||||
/*
|
||||
@ -214,7 +215,8 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
|
||||
fdresult = func_get_detail(funcname, fargs, argnames, nargs,
|
||||
actual_arg_types,
|
||||
!func_variadic, true,
|
||||
&funcid, &rettype, &retset, &nvargs,
|
||||
&funcid, &rettype, &retset,
|
||||
&nvargs, &vatype,
|
||||
&declared_arg_types, &argdefaults);
|
||||
if (fdresult == FUNCDETAIL_COERCION)
|
||||
{
|
||||
@ -382,6 +384,22 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
|
||||
fargs = lappend(fargs, newa);
|
||||
}
|
||||
|
||||
/*
|
||||
* When function is called an explicit VARIADIC labeled parameter,
|
||||
* and the declared_arg_type is "any", then sanity check the actual
|
||||
* parameter type now - it must be an array.
|
||||
*/
|
||||
if (nargs > 0 && vatype == ANYOID && func_variadic)
|
||||
{
|
||||
Oid va_arr_typid = actual_arg_types[nargs - 1];
|
||||
|
||||
if (!OidIsValid(get_element_type(va_arr_typid)))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DATATYPE_MISMATCH),
|
||||
errmsg("VARIADIC argument must be an array"),
|
||||
parser_errposition(pstate, exprLocation((Node *) llast(fargs)))));
|
||||
}
|
||||
|
||||
/* build the appropriate output structure */
|
||||
if (fdresult == FUNCDETAIL_NORMAL)
|
||||
{
|
||||
@ -1033,6 +1051,7 @@ func_get_detail(List *funcname,
|
||||
Oid *rettype, /* return value */
|
||||
bool *retset, /* return value */
|
||||
int *nvargs, /* return value */
|
||||
Oid *vatype, /* return value */
|
||||
Oid **true_typeids, /* return value */
|
||||
List **argdefaults) /* optional return value */
|
||||
{
|
||||
@ -1251,6 +1270,7 @@ func_get_detail(List *funcname,
|
||||
pform = (Form_pg_proc) GETSTRUCT(ftup);
|
||||
*rettype = pform->prorettype;
|
||||
*retset = pform->proretset;
|
||||
*vatype = pform->provariadic;
|
||||
/* fetch default args if caller wants 'em */
|
||||
if (argdefaults && best_candidate->ndargs > 0)
|
||||
{
|
||||
|
Reference in New Issue
Block a user