diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml index 4fb42842c6f..1515e649153 100644 --- a/doc/src/sgml/xfunc.sgml +++ b/doc/src/sgml/xfunc.sgml @@ -3154,9 +3154,10 @@ CREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer, is zero based. get_call_result_type can also be used as an alternative to get_fn_expr_rettype. There is also get_fn_expr_variadic, which can be used to - find out whether the call contained an explicit VARIADIC - keyword. This is primarily useful for VARIADIC "any" - functions, as described below. + find out whether variadic arguments have been merged into an array. + This is primarily useful for VARIADIC "any" functions, + since such merging will always have occurred for variadic functions + taking ordinary array types. diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index edb165fcc9f..de7cf4fc058 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -374,6 +374,11 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, newa->location = exprLocation((Node *) vargs); fargs = lappend(fargs, newa); + + /* We could not have had VARIADIC marking before ... */ + Assert(!func_variadic); + /* ... but now, it's a VARIADIC call */ + func_variadic = true; } /* build the appropriate output structure */ diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 71798efc436..eca03cb82de 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -8604,7 +8604,7 @@ generate_relation_name(Oid relid, List *namespaces) * * If we're dealing with a potentially variadic function (in practice, this * means a FuncExpr and not some other way of calling the function), then - * was_variadic must specify whether VARIADIC appeared in the original call, + * was_variadic should specify whether variadic arguments have been merged, * and *use_variadic_p will be set to indicate whether to print VARIADIC in * the output. For non-FuncExpr cases, was_variadic should be FALSE and * use_variadic_p can be NULL. @@ -8639,14 +8639,16 @@ generate_function_name(Oid funcid, int nargs, List *argnames, Oid *argtypes, * since it affects the lookup rules in func_get_detail(). * * Currently, we always print VARIADIC if the function is variadic and - * takes a variadic type other than ANY. (In principle, if VARIADIC - * wasn't originally specified and the array actual argument is - * deconstructable, we could print the array elements separately and not - * print VARIADIC, thus more nearly reproducing the original input. For - * the moment that seems like too much complication for the benefit.) - * However, if the function takes VARIADIC ANY, then the parser didn't - * fold the arguments together into an array, so we must print VARIADIC if - * and only if it was used originally. + * takes a variadic type other than ANY. However, if the function takes + * VARIADIC ANY, then the parser didn't fold the arguments together into + * an array, so we must print VARIADIC if and only if it was used + * originally. + * + * Note: with the current definition of funcvariadic, we could just set + * use_variadic = was_variadic, which indeed is the solution adopted in + * 9.4. However, in rules/views stored before 9.3.5, funcvariadic will + * reflect the previous definition (was VARIADIC written in the call?). + * So in 9.3 we cannot trust it unless the function is VARIADIC ANY. */ if (use_variadic_p) { diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c index 675213064b8..778f75aefcd 100644 --- a/src/backend/utils/fmgr/fmgr.c +++ b/src/backend/utils/fmgr/fmgr.c @@ -2452,6 +2452,8 @@ get_call_expr_arg_stable(Node *expr, int argnum) * Get the VARIADIC flag from the function invocation * * Returns false (the default assumption) if information is not available + * + * Note this is generally only of interest to VARIADIC ANY functions */ bool get_fn_expr_variadic(FmgrInfo *flinfo) diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index 75b716a9671..c17b74e4b12 100644 --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -346,7 +346,8 @@ typedef struct FuncExpr Oid funcid; /* PG_PROC OID of the function */ Oid funcresulttype; /* PG_TYPE OID of result value */ bool funcretset; /* true if function returns set */ - bool funcvariadic; /* true if VARIADIC was used in call */ + bool funcvariadic; /* true if variadic arguments have been + * combined into an array last argument */ CoercionForm funcformat; /* how to display this function call */ Oid funccollid; /* OID of collation of result */ Oid inputcollid; /* OID of collation that function should use */