@ -79,6 +79,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
Node * retval ;
Node * retval ;
bool retset ;
bool retset ;
int nvargs ;
int nvargs ;
Oid vatype ;
FuncDetailCode fdresult ;
FuncDetailCode fdresult ;
/*
/*
@ -214,7 +215,8 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
fdresult = func_get_detail ( funcname , fargs , argnames , nargs ,
fdresult = func_get_detail ( funcname , fargs , argnames , nargs ,
actual_arg_types ,
actual_arg_types ,
! func_variadic , true ,
! func_variadic , true ,
& funcid , & rettype , & retset , & nvargs ,
& funcid , & rettype , & retset ,
& nvargs , & vatype ,
& declared_arg_types , & argdefaults ) ;
& declared_arg_types , & argdefaults ) ;
if ( fdresult = = FUNCDETAIL_COERCION )
if ( fdresult = = FUNCDETAIL_COERCION )
{
{
@ -382,6 +384,22 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
fargs = lappend ( fargs , newa ) ;
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 */
/* build the appropriate output structure */
if ( fdresult = = FUNCDETAIL_NORMAL )
if ( fdresult = = FUNCDETAIL_NORMAL )
{
{
@ -1033,6 +1051,7 @@ func_get_detail(List *funcname,
Oid * rettype , /* return value */
Oid * rettype , /* return value */
bool * retset , /* return value */
bool * retset , /* return value */
int * nvargs , /* return value */
int * nvargs , /* return value */
Oid * vatype , /* return value */
Oid * * true_typeids , /* return value */
Oid * * true_typeids , /* return value */
List * * argdefaults ) /* optional return value */
List * * argdefaults ) /* optional return value */
{
{
@ -1251,6 +1270,7 @@ func_get_detail(List *funcname,
pform = ( Form_pg_proc ) GETSTRUCT ( ftup ) ;
pform = ( Form_pg_proc ) GETSTRUCT ( ftup ) ;
* rettype = pform - > prorettype ;
* rettype = pform - > prorettype ;
* retset = pform - > proretset ;
* retset = pform - > proretset ;
* vatype = pform - > provariadic ;
/* fetch default args if caller wants 'em */
/* fetch default args if caller wants 'em */
if ( argdefaults & & best_candidate - > ndargs > 0 )
if ( argdefaults & & best_candidate - > ndargs > 0 )
{
{