Hello,

Our implementation of variadic parameters are not complete. The
support of "any" type is incomplete. Modificator VARIADIC for funccall
parameters needs transformation from ArrayExpr to standard parameters
list.

==current behave==
postgres=# select variadic_demo2(10,'Petr',20,20,30);
NOTICE:  arg(0) = 10
NOTICE:  arg(1) = Petr
NOTICE:  arg(2) = 20
NOTICE:  arg(3) = 20
NOTICE:  arg(4) = 30
 variadic_demo2
----------------

(1 row)

Time: 3,245 ms
postgres=# select variadic_demo2(10,'Petr',20, variadic array[10,20]);
NOTICE:  arg(0) = 10
NOTICE:  arg(1) = Petr
NOTICE:  arg(2) = 20
NOTICE:  arg(3) = {10,20}
 variadic_demo2
----------------

(1 row)

==fixed behave==

Time: 1,287 ms
postgres=# select variadic_demo2(10,'Petr',20,20,30);
NOTICE:  arg(0) = 10
NOTICE:  arg(1) = Petr
NOTICE:  arg(2) = 20
NOTICE:  arg(3) = 20
NOTICE:  arg(4) = 30
 variadic_demo2
----------------

(1 row)

Time: 0,994 ms
postgres=# select variadic_demo2(10,'Petr',20, variadic array[10,20]);
NOTICE:  arg(0) = 10
NOTICE:  arg(1) = Petr
NOTICE:  arg(2) = 20
NOTICE:  arg(3) = 10
NOTICE:  arg(4) = 20
 variadic_demo2
----------------

(1 row)

regards
Pavel Stehule
*** ./src/backend/parser/parse_func.c.orig	2009-03-30 13:16:13.000000000 +0200
--- ./src/backend/parser/parse_func.c	2009-03-30 14:15:13.000000000 +0200
***************
*** 284,294 ****
  	/* perform the necessary typecasting of arguments */
  	make_fn_arguments(pstate, fargs, actual_arg_types, declared_arg_types);
  
  	/*
  	 * If it's a variadic function call, transform the last nvargs arguments
  	 * into an array --- unless it's an "any" variadic.
  	 */
! 	if (nvargs > 0 && declared_arg_types[nargs - 1] != ANYOID)
  	{
  		ArrayExpr *newa = makeNode(ArrayExpr);
  		int 	non_var_args = nargs - nvargs;
--- 284,316 ----
  	/* perform the necessary typecasting of arguments */
  	make_fn_arguments(pstate, fargs, actual_arg_types, declared_arg_types);
  
+ 	/* 
+ 	 * When function call is variadic and arg type is ANY, then transform 
+ 	 * array to standard list of arguments.
+ 	 */
+ 	if (func_variadic && declared_arg_types[nargs - 1] == ANYOID)
+ 	{
+ 		ArrayExpr *aexpr = (ArrayExpr *) llast(fargs);
+ 		if (!IsA(aexpr, ArrayExpr))
+ 			ereport(ERROR,
+ 					(errcode(ERRCODE_DATATYPE_MISMATCH),
+ 					 errmsg("variadic parameter should be any array type"),
+ 					 parser_errposition(pstate, exprLocation((Node *) aexpr))));
+ 		
+ 		if (aexpr->multidims)
+ 			ereport(ERROR,
+ 					(errcode(ERRCODE_DATATYPE_MISMATCH),
+ 					 errmsg("multidimensional variadic arguments are not supported yet"),
+ 					 parser_errposition(pstate, exprLocation((Node *) aexpr))));
+ 		
+ 		fargs = list_truncate(fargs, nargs - 1);
+ 		fargs = list_concat(fargs, aexpr->elements);
+ 	}
  	/*
  	 * If it's a variadic function call, transform the last nvargs arguments
  	 * into an array --- unless it's an "any" variadic.
  	 */
! 	else if (nvargs > 0 && declared_arg_types[nargs - 1] != ANYOID)
  	{
  		ArrayExpr *newa = makeNode(ArrayExpr);
  		int 	non_var_args = nargs - nvargs;

Attachment: varidic_test.tgz
Description: GNU Zip compressed data

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to