From 0c6e1cd808d6ce6e6a4c8accb25b91db072abc06 Mon Sep 17 00:00:00 2001 From: TotaJ Date: Mon, 26 Jul 2021 19:37:16 +0800 Subject: [PATCH] Don't need out parameter for procedure. --- src/common/pl/plpgsql/src/gram.y | 17 ++- src/test/regress/expected/function.out | 118 ++++++++++++++++++ .../regress/expected/hw_func_return_out.out | 8 -- src/test/regress/sql/function.sql | 62 +++++++++ 4 files changed, 196 insertions(+), 9 deletions(-) diff --git a/src/common/pl/plpgsql/src/gram.y b/src/common/pl/plpgsql/src/gram.y index 0515648dc..daee91243 100755 --- a/src/common/pl/plpgsql/src/gram.y +++ b/src/common/pl/plpgsql/src/gram.y @@ -3285,6 +3285,7 @@ make_callfunc_stmt(const char *sqlstart, int location, bool is_assign) int nparams = 0; int nfields = 0; int narg = 0; + int inArgNum = 0; int i= 0; int tok = 0; Oid *p_argtypes = NULL; @@ -3372,6 +3373,20 @@ make_callfunc_stmt(const char *sqlstart, int location, bool is_assign) } /* 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); + if (p_argmodes) + { + for (i = 0; i < narg; i++) + { + if (p_argmodes[i] == 'i' || p_argmodes[i] == 'b') + { + inArgNum++; + } + } + } + else + { + inArgNum = narg; + } procStruct = (Form_pg_proc) GETSTRUCT(proctup); ndefaultargs = procStruct->pronargdefaults; ReleaseSysCache(proctup); @@ -3701,7 +3716,7 @@ make_callfunc_stmt(const char *sqlstart, int location, bool is_assign) } } - if (!multi_func && narg - i > ndefaultargs) + if (!multi_func && inArgNum - i > ndefaultargs) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FUNCTION), errmsg("function %s has no enough parameters", sqlstart))); diff --git a/src/test/regress/expected/function.out b/src/test/regress/expected/function.out index 81d173c3c..cc0e08712 100644 --- a/src/test/regress/expected/function.out +++ b/src/test/regress/expected/function.out @@ -1491,3 +1491,121 @@ drop cascades to function sche1.subpro() drop cascades to function sche1.pro() -- clear option reset search_path; +CREATE OR REPLACE FUNCTION func_increment_sql_1(i int, out result_1 bigint, out result_2 bigint) +returns SETOF RECORD +as $$ +begin + result_1 = i + 1; + result_2 = i * 10; + raise notice '%', result_1; + raise notice '%', result_2; +return next; +end; +$$language plpgsql; +SELECT func_increment_sql_1(1); +NOTICE: 2 +CONTEXT: referenced column: func_increment_sql_1 +NOTICE: 10 +CONTEXT: referenced column: func_increment_sql_1 + func_increment_sql_1 +---------------------- + (2,10) +(1 row) + +CREATE OR REPLACE FUNCTION func_increment_sql_2(i int, inout result_1 bigint, out result_2 bigint) +returns SETOF RECORD +as $$ +begin + raise notice '%', result_1; + result_1 = i + 1; + result_2 = i * 10; + raise notice '%', result_1; + raise notice '%', result_2; +return next; +end; +$$language plpgsql; +--error +SELECT func_increment_sql_2(1); +ERROR: function func_increment_sql_2(integer) does not exist +LINE 1: SELECT func_increment_sql_2(1); + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. +CONTEXT: referenced column: func_increment_sql_2 +--success +SELECT func_increment_sql_2(1,2); +NOTICE: 2 +CONTEXT: referenced column: func_increment_sql_2 +NOTICE: 2 +CONTEXT: referenced column: func_increment_sql_2 +NOTICE: 10 +CONTEXT: referenced column: func_increment_sql_2 + func_increment_sql_2 +---------------------- + (2,10) +(1 row) + +CREATE OR REPLACE FUNCTION fun_test_1(i int) +RETURNS void +as $$ +begin + PERFORM func_increment_sql_1(i); +end; +$$language plpgsql; +select fun_test_1(1); +NOTICE: 2 +CONTEXT: referenced column: func_increment_sql_1 +SQL statement "SELECT func_increment_sql_1(i)" +PL/pgSQL function fun_test_1(integer) line 3 at PERFORM +referenced column: fun_test_1 +NOTICE: 10 +CONTEXT: referenced column: func_increment_sql_1 +SQL statement "SELECT func_increment_sql_1(i)" +PL/pgSQL function fun_test_1(integer) line 3 at PERFORM +referenced column: fun_test_1 + fun_test_1 +------------ + +(1 row) + +--error +CREATE OR REPLACE FUNCTION fun_test_2(i int) +RETURNS void +as $$ +begin + PERFORM func_increment_sql_2(i); +end; +$$language plpgsql; +ERROR: function func_increment_sql_2 has no enough parameters +CONTEXT: compilation of PL/pgSQL function "fun_test_2" near line 1 +CREATE OR REPLACE FUNCTION fun_test_2(i int) +RETURNS void +as $$ +begin + PERFORM func_increment_sql_2(i,i+1); +end; +$$language plpgsql; +select fun_test_2(1); +NOTICE: 2 +CONTEXT: referenced column: func_increment_sql_2 +SQL statement "SELECT func_increment_sql_2(i,i+1)" +PL/pgSQL function fun_test_2(integer) line 3 at PERFORM +referenced column: fun_test_2 +NOTICE: 2 +CONTEXT: referenced column: func_increment_sql_2 +SQL statement "SELECT func_increment_sql_2(i,i+1)" +PL/pgSQL function fun_test_2(integer) line 3 at PERFORM +referenced column: fun_test_2 +NOTICE: 10 +CONTEXT: referenced column: func_increment_sql_2 +SQL statement "SELECT func_increment_sql_2(i,i+1)" +PL/pgSQL function fun_test_2(integer) line 3 at PERFORM +referenced column: fun_test_2 + fun_test_2 +------------ + +(1 row) + +DROP FUNCTION func_increment_sql_1; +DROP FUNCTION func_increment_sql_2; +DROP FUNCTION fun_test_1; +DROP FUNCTION fun_test_2; diff --git a/src/test/regress/expected/hw_func_return_out.out b/src/test/regress/expected/hw_func_return_out.out index 348eccec1..06f9122d1 100644 --- a/src/test/regress/expected/hw_func_return_out.out +++ b/src/test/regress/expected/hw_func_return_out.out @@ -29,8 +29,6 @@ begin c := test_return(a); end; / -ERROR: function test_return has no enough parameters -CONTEXT: compilation of PL/pgSQL function "inline_code_block" near line 3 declare a int := 1; b int; @@ -276,8 +274,6 @@ AS RETURN result; END; / -ERROR: function test_return has no enough parameters -CONTEXT: compilation of PL/pgSQL function "test_return18" near line 1 CREATE OR REPLACE FUNCTION test_return19( i integer,j out integer) RETURN record AS @@ -630,8 +626,6 @@ begin c := test_return(a); end; / -ERROR: function test_return has no enough parameters -CONTEXT: compilation of PL/pgSQL function "inline_code_block" near line 3 declare a int := 1; b int; @@ -877,8 +871,6 @@ AS RETURN result; END; / -ERROR: function test_return has no enough parameters -CONTEXT: compilation of PL/pgSQL function "test_return18" near line 1 CREATE OR REPLACE FUNCTION test_return19( i integer,j out integer) RETURN record AS diff --git a/src/test/regress/sql/function.sql b/src/test/regress/sql/function.sql index 906e65d57..9dfd2dfa2 100644 --- a/src/test/regress/sql/function.sql +++ b/src/test/regress/sql/function.sql @@ -864,3 +864,65 @@ drop schema sche1 cascade; -- clear option reset search_path; + +CREATE OR REPLACE FUNCTION func_increment_sql_1(i int, out result_1 bigint, out result_2 bigint) +returns SETOF RECORD +as $$ +begin + result_1 = i + 1; + result_2 = i * 10; + raise notice '%', result_1; + raise notice '%', result_2; +return next; +end; +$$language plpgsql; +SELECT func_increment_sql_1(1); + +CREATE OR REPLACE FUNCTION func_increment_sql_2(i int, inout result_1 bigint, out result_2 bigint) +returns SETOF RECORD +as $$ +begin + raise notice '%', result_1; + result_1 = i + 1; + result_2 = i * 10; + raise notice '%', result_1; + raise notice '%', result_2; +return next; +end; +$$language plpgsql; +--error +SELECT func_increment_sql_2(1); +--success +SELECT func_increment_sql_2(1,2); + +CREATE OR REPLACE FUNCTION fun_test_1(i int) +RETURNS void +as $$ +begin + PERFORM func_increment_sql_1(i); +end; +$$language plpgsql; +select fun_test_1(1); + +--error +CREATE OR REPLACE FUNCTION fun_test_2(i int) +RETURNS void +as $$ +begin + PERFORM func_increment_sql_2(i); +end; +$$language plpgsql; + +CREATE OR REPLACE FUNCTION fun_test_2(i int) +RETURNS void +as $$ +begin + PERFORM func_increment_sql_2(i,i+1); +end; +$$language plpgsql; +select fun_test_2(1); + +DROP FUNCTION func_increment_sql_1; +DROP FUNCTION func_increment_sql_2; +DROP FUNCTION fun_test_1; +DROP FUNCTION fun_test_2;