diff --git a/src/common/backend/parser/gram.y b/src/common/backend/parser/gram.y index 6da38e9ce705f54df177610f60907e1f680539bd..a281a2142a357d904491e6b5121a90d7e1a20e98 100644 --- a/src/common/backend/parser/gram.y +++ b/src/common/backend/parser/gram.y @@ -30555,6 +30555,20 @@ check_outarg_info(const bool *have_assigend, const char *argmodes,const int proa } } +static bool HasVariadic(int nargs, const char* argmodes) +{ + if (!argmodes) { + return false; + } + + for (int i = nargs - 1; i >= 0; --i) { + if (argmodes[i] == FUNC_PARAM_VARIADIC) { + return true; + } + } + return false; +} + // Added CALL for procedure and function static Node * makeCallFuncStmt(List* funcname,List* parameters, bool is_call) @@ -30629,15 +30643,16 @@ makeCallFuncStmt(List* funcname,List* parameters, bool is_call) return NULL; } + /* get the all args informations, only "in" parameters if p_argmodes is null */ + narg = get_func_arg_info(proctup, &p_argtypes, &p_argnames, &p_argmodes); + bool hasVariadic = HasVariadic(narg, p_argmodes); + #ifndef ENABLE_MULTIPLE_NODES - if (!has_overload_func && !enable_out_param_override()) + if (!hasVariadic && !has_overload_func && !enable_out_param_override()) #else - if (!has_overload_func) + if (!hasVariadic && !has_overload_func) #endif { - /* get the all args informations, only "in" parameters if p_argmodes is null */ - narg = get_func_arg_info(proctup,&p_argtypes,&p_argnames,&p_argmodes); - /* get the all "in" parameters, except "out" or "table_colums" parameters */ ntable_colums = get_table_modes(narg, p_argmodes); narg -= ntable_colums; diff --git a/src/test/regress/expected/hw_procedure_define.out b/src/test/regress/expected/hw_procedure_define.out index ed4bb7060f50c6168d3e4867a965328aeab7cb2d..c8233b894507d8a9af7eeed9c1688a696f257133 100644 --- a/src/test/regress/expected/hw_procedure_define.out +++ b/src/test/regress/expected/hw_procedure_define.out @@ -913,5 +913,43 @@ ERROR: invalid input syntax for integer: "abc" CONTEXT: PL/pgSQL function test_bt_b() line 3 at assignment referenced column: test_bt_b drop procedure test_bt_b; +-- test variadic +CREATE procedure pro(variadic my_args text[]) + AS +DECLARE + result_text text; +BEGIN + result_text := ''; + FOR i IN 1..array_length(my_args, 1) LOOP + result_text := result_text || my_args[i] || ' '; + raise notice '%',result_text; + END LOOP; +END; +/ +call pro('Hello', 'World', 'from', 'OpenGauss'); +NOTICE: Hello +NOTICE: Hello World +NOTICE: Hello World from +NOTICE: Hello World from OpenGauss + pro +----- + +(1 row) + +select pro('Hello', 'World', 'from', 'OpenGauss'); +NOTICE: Hello +CONTEXT: referenced column: pro +NOTICE: Hello World +CONTEXT: referenced column: pro +NOTICE: Hello World from +CONTEXT: referenced column: pro +NOTICE: Hello World from OpenGauss +CONTEXT: referenced column: pro + pro +----- + +(1 row) + +drop procedure pro; \c regression; drop database IF EXISTS pl_test_pkg_define; diff --git a/src/test/regress/sql/hw_procedure_define.sql b/src/test/regress/sql/hw_procedure_define.sql index 5491e5d9ebfc880556e90923d9ac387cfad035e4..6b096fccc059d58078be7bde044ba559b0be23a5 100644 --- a/src/test/regress/sql/hw_procedure_define.sql +++ b/src/test/regress/sql/hw_procedure_define.sql @@ -687,5 +687,24 @@ select prosrc from pg_proc where proname='test_bt_b'; select test_bt_b(); drop procedure test_bt_b; +-- test variadic +CREATE procedure pro(variadic my_args text[]) + AS +DECLARE + result_text text; +BEGIN + result_text := ''; + FOR i IN 1..array_length(my_args, 1) LOOP + result_text := result_text || my_args[i] || ' '; + raise notice '%',result_text; + END LOOP; +END; +/ + +call pro('Hello', 'World', 'from', 'OpenGauss'); +select pro('Hello', 'World', 'from', 'OpenGauss'); + +drop procedure pro; + \c regression; drop database IF EXISTS pl_test_pkg_define;