diff --git a/src/common/backend/catalog/namespace.cpp b/src/common/backend/catalog/namespace.cpp index 9565b927a..5283da063 100644 --- a/src/common/backend/catalog/namespace.cpp +++ b/src/common/backend/catalog/namespace.cpp @@ -1656,6 +1656,10 @@ FuncCandidateList FuncnameGetCandidates(List* names, int nargs, List* argnames, if (pkg_oid != package_oid) { continue; } + Datum pro_is_private_datum = SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_proisprivate, &isNull); + if (!isNull && !u_sess->is_autonomous_session && DatumGetBool(pro_is_private_datum)) { + continue; + } namespaceId = GetPackageNamespace(pkg_oid); } else if (caller_pkg_oid == package_oid) { if (pkgname != NULL) { diff --git a/src/common/backend/catalog/pg_proc.cpp b/src/common/backend/catalog/pg_proc.cpp index 946275a75..d30119793 100644 --- a/src/common/backend/catalog/pg_proc.cpp +++ b/src/common/backend/catalog/pg_proc.cpp @@ -1521,49 +1521,6 @@ ObjectAddress ProcedureCreate(const char* procedureName, Oid procNamespace, Oid ObjectIdGetDatum(procNamespace)); #endif } -#ifndef ENABLE_MULTIPLE_NODES - if (enable_out_param_override() && !u_sess->attr.attr_common.IsInplaceUpgrade && !IsInitdb && !proIsProcedure && - IsPlpgsqlLanguageOid(languageObjectId)) { - bool findOutParamFunc = false; - CatCList *catlist = NULL; - if (t_thrd.proc->workingVersionNum < 92470) { - catlist = SearchSysCacheList1(PROCNAMEARGSNSP, CStringGetDatum(procedureName)); - } else { - catlist = SearchSysCacheList1(PROCALLARGS, CStringGetDatum(procedureName)); - } - for (int i = 0; i < catlist->n_members; ++i) { - HeapTuple proctup = t_thrd.lsc_cxt.FetchTupleFromCatCList(catlist, i); - Form_pg_proc procform = (Form_pg_proc)GETSTRUCT(proctup); - bool isNull = false; - Datum packageOidDatum = SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_packageid, &isNull); - Oid packageOid = InvalidOid; - if (!isNull) { - packageOid = DatumGetObjectId(packageOidDatum); - } - if (packageOid == propackageid && procform->pronamespace == procNamespace) { - isNull = false; - (void)SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_proallargtypes, &isNull); - if (!isNull) { - findOutParamFunc = true; - break; - } - } - } - - ReleaseSysCacheList(catlist); - if (existOutParam) { - if (!HeapTupleIsValid(oldtup) && findOutParamFunc) { - ereport(ERROR, - (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - (errmsg("\"%s\" functions with plpgsql language and out params are not supported Overloaded.", - procedureName), - errdetail("N/A."), - errcause("functions with plpgsql language and out params are not supported Overloaded."), - erraction("Drop function before create function.")))); - } - } - } -#endif if (HeapTupleIsValid(oldtup)) { /* There is one; okay to replace it? */ bool isNull = false; diff --git a/src/common/backend/parser/parse_func.cpp b/src/common/backend/parser/parse_func.cpp index dbb514d09..e9eed9439 100644 --- a/src/common/backend/parser/parse_func.cpp +++ b/src/common/backend/parser/parse_func.cpp @@ -1493,42 +1493,31 @@ FuncCandidateList sort_candidate_func_list(FuncCandidateList oldCandidates) candidates[index++] = cur; cur = cur->next; } - - FuncCandidateList sortedCandidates = NULL; - FuncCandidateList lastCandidate = NULL; - for (int i = 0; i < size; i++) { - if (candidates[i] == NULL) { - continue; - } - int smallestIndex = i; - for (int j = 0; j < size; j++) { - FuncCandidateList cur2 = candidates[j]; - if (cur2 != NULL && candidates[smallestIndex]->allArgNum > cur2->allArgNum) { - smallestIndex = j; + + int i, j; + FuncCandidateList temp; + for (i = 0; i < index - 1; i++) { + for (j = 0; j < index - (i + 1); j++) { + if (candidates[j]->allArgNum > candidates[j + 1]->allArgNum) { + temp = candidates[j]; + candidates[j] = candidates[j + 1]; + candidates[j + 1] = temp; } } + } - FuncCandidateList smallest = candidates[smallestIndex]; - if (lastCandidate == NULL) { - lastCandidate = smallest; - sortedCandidates = smallest; - } else { - lastCandidate->next = smallest; - lastCandidate = lastCandidate->next; - smallest->next = NULL; - } - candidates[smallestIndex] = NULL; - } - - for (int i = 0; i < size; i++) { - if (candidates[i] != NULL) { - lastCandidate->next = candidates[i]; - lastCandidate = lastCandidate->next; + FuncCandidateList sorted_candidates = candidates[0]; + FuncCandidateList next_candidates = sorted_candidates; + for (i = 0; i < index; i++) { + candidates[i]->next = NULL; + if (i != 0) { + next_candidates->next = candidates[i]; + next_candidates = next_candidates->next; } } - lastCandidate->next = NULL; + pfree(candidates); - return sortedCandidates; + return sorted_candidates; } /* func_get_detail() diff --git a/src/common/pl/plpgsql/src/gram.y b/src/common/pl/plpgsql/src/gram.y index 9e2c0a79f..9a72b649c 100755 --- a/src/common/pl/plpgsql/src/gram.y +++ b/src/common/pl/plpgsql/src/gram.y @@ -228,6 +228,7 @@ static void checkFuncName(List* funcname); static void IsInPublicNamespace(char* varname); static void CheckDuplicateCondition (char* name); static void SetErrorState(); +static bool oid_is_function(Oid funcid, bool* isSystemObj); static void AddNamespaceIfNeed(int dno, char* ident); static void AddNamespaceIfPkgVar(const char* ident, IdentifierLookup save_IdentifierLookup); bool plpgsql_is_token_keyword(int tok); @@ -7230,7 +7231,8 @@ make_callfunc_stmt(const char *sqlstart, int location, bool is_assign, bool eate return NULL; } - if (clist->next) + bool isSystemObj = false; + if (clist->next || (clist->next && enable_out_param_override() && oid_is_function(clist->oid, &isSystemObj))) { multi_func = true; char* schemaname = NULL; @@ -7311,7 +7313,7 @@ make_callfunc_stmt(const char *sqlstart, int location, bool is_assign, bool eate is_assign = false; } /* has any "out" parameters, user execsql stmt */ - if (is_assign) + if (is_assign && !(clist->next && enable_out_param_override() && oid_is_function(clist->oid, &isSystemObj))) { appendStringInfoString(&func_inparas, "SELECT "); } @@ -7633,6 +7635,12 @@ make_callfunc_stmt(const char *sqlstart, int location, bool is_assign, bool eate appendStringInfoString(&func_inparas, "=>"); (void)yylex(); yylex_outparam(fieldnames, varnos, nfields, &row, &rec, &tok, &varno, true, true); + if (varno != -1 && enable_out_param_override() && oid_is_function(clist->oid, &isSystemObj)) { + int dtype = u_sess->plsql_cxt.curr_compile_context->plpgsql_Datums[varno]->dtype; + if (dtype == PLPGSQL_DTYPE_ROW) { + out_param_dno = yylval.wdatum.dno; + } + } plpgsql_push_back_token(tok); expr = read_sql_construct(',', ')', 0, ",|)", "", true, false, false, NULL, &tok); appendStringInfoString(&func_inparas, expr->query); @@ -7645,6 +7653,12 @@ make_callfunc_stmt(const char *sqlstart, int location, bool is_assign, bool eate else { yylex_outparam(fieldnames, varnos, nfields, &row, &rec, &tok, &varno, true, true); + if (varno != -1 && enable_out_param_override() && oid_is_function(clist->oid, &isSystemObj)) { + int dtype = u_sess->plsql_cxt.curr_compile_context->plpgsql_Datums[varno]->dtype; + if (dtype == PLPGSQL_DTYPE_ROW) { + out_param_dno = yylval.wdatum.dno; + } + } plpgsql_push_back_token(tok); yylex_inparam(&func_inparas, &nparams, &tok, &tableof_func_dno, &tableof_var_dno); namedarg[nfields] = false; @@ -7766,8 +7780,10 @@ make_callfunc_stmt(const char *sqlstart, int location, bool is_assign, bool eate narg = procStruct->pronargs; ReleaseSysCache(proctup); - for (int k = 0; k < all_arg; k++) { - check_tableofindex_args(varnos[k], p_argtypes[k]); + if (!(enable_out_param_override() && oid_is_function(clist->oid, &isSystemObj))) { + for (int k = 0; k < all_arg; k++) { + check_tableofindex_args(varnos[k], p_argtypes[k]); + } } /* if there is no "out" parameters ,use perform stmt,others use exesql */ @@ -8166,14 +8182,15 @@ is_function(const char *name, bool is_assign, bool no_parenthesis, List* funcNam } return false; } - else if (clist->next) + bool isSystemObj = false; + if (clist->next && !(enable_out_param_override() && oid_is_function(clist->oid, & isSystemObj))) { if (is_assign) return false; else return true; } - else + while(clist) { proctup = SearchSysCache(PROCOID, ObjectIdGetDatum(clist->oid), @@ -8211,14 +8228,18 @@ is_function(const char *name, bool is_assign, bool no_parenthesis, List* funcNam } } } + ReleaseSysCache(proctup); + if (have_inoutargs && is_function_with_plpgsql_language_and_outparam(clist->oid)) + return true; + + if (!have_outargs && is_assign && + !(clist->next && enable_out_param_override() && oid_is_function(clist->oid, &isSystemObj))) + return false; + + clist = clist->next; } - if (have_inoutargs && is_function_with_plpgsql_language_and_outparam(clist->oid)) - return true; - if (!have_outargs && is_assign) - return false; - return true;/* passed all test */ } return false; @@ -8250,6 +8271,36 @@ static void checkFuncName(List* funcname) (void)MemoryContextSwitchTo(colCxt); } +static bool oid_is_function(Oid funcid, bool* isSystemObj) +{ + HeapTuple proctup = NULL; + if (OidIsValid(funcid)) { + proctup = SearchSysCache(PROCOID, ObjectIdGetDatum(funcid), 0, 0, 0); + if (HeapTupleIsValid(proctup)) { + bool isNull; + Datum protypeDatum = SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_prokind, &isNull); + char protype; + if (!isNull) { + protype = DatumGetChar(protypeDatum); + } else { + protype = PROKIND_FUNCTION; + } + Datum pronamespaceDatum = SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_pronamespace, &isNull); + Oid pronamespace = DatumGetObjectId(pronamespaceDatum); + Assert(OidIsValid(pronamespace)); + ReleaseSysCache(proctup); + if (IsPackageSchemaOid(pronamespace) || IsSystemNamespace(pronamespace)) { + *isSystemObj = true; + return false; + } + if (PROC_IS_FUNC(protype)) { + return true; + } + } + } + return false; +} + /* * @brief is_datatype * check if a given type is a datatype diff --git a/src/test/regress/expected/hw_package.out b/src/test/regress/expected/hw_package.out index 4f8fdf738..10568d3df 100644 --- a/src/test/regress/expected/hw_package.out +++ b/src/test/regress/expected/hw_package.out @@ -467,8 +467,13 @@ function autonomous_f_150_2_private(pnum1 int) return int end; end autonomous_pkg_150_2; / +ERROR: function "autonomous_pkg_150_1.autonomous_f_150_1_private" doesn't exist +CONTEXT: compilation of PL/pgSQL package near line 2 select autonomous_pkg_150_2.autonomous_f_150_2_private(1); -ERROR: not support call package private function or procedure +ERROR: function autonomous_pkg_150_2.autonomous_f_150_2_private(integer) does not exist +LINE 1: select autonomous_pkg_150_2.autonomous_f_150_2_private(1); + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. CONTEXT: referenced column: autonomous_f_150_2_private drop table if exists au_pkg; create table au_pkg(id int,name varchar); @@ -1667,9 +1672,7 @@ drop table if exists test.emp_t; drop schema if exists test cascade; drop table if exists au_pkg; drop package autonomous_pkg_150_2; -NOTICE: drop cascades to 2 other objects -DETAIL: drop cascades to function public.autonomous_f_150_2(integer) -drop cascades to function public.autonomous_f_150_2_private(integer) +NOTICE: drop cascades to function public.autonomous_f_150_2(integer) drop package autonomous_pkg_150_1; NOTICE: drop cascades to 2 other objects DETAIL: drop cascades to function public.autonomous_f_150_1(integer) diff --git a/src/test/regress/expected/out_param_func.out b/src/test/regress/expected/out_param_func.out index e1ad69eff..edf5c9e89 100644 --- a/src/test/regress/expected/out_param_func.out +++ b/src/test/regress/expected/out_param_func.out @@ -1042,8 +1042,6 @@ DECLARE return c; END; $$ LANGUAGE 'plpgsql' NOT FENCED; -ERROR: "func8_1" functions with plpgsql language and out params are not supported Overloaded. -DETAIL: N/A. --8.2 同一schema、package下,不允许存在同名的plpgsql语言的out出参函数,但可以replace CREATE or replace FUNCTION func8_2(in a integer, out b integer) RETURNS int @@ -1068,8 +1066,6 @@ DECLARE return c; END; $$ LANGUAGE 'plpgsql' NOT FENCED; -ERROR: "func8_2" functions with plpgsql language and out params are not supported Overloaded. -DETAIL: N/A. CREATE or replace FUNCTION func8_2(in a integer, out b integer) RETURNS int AS $$ @@ -1089,8 +1085,6 @@ function func8_2(in a int, out b int, out d integer) return int; end pck8_2; / -ERROR: "func8_2" functions with plpgsql language and out params are not supported Overloaded. -DETAIL: N/A. --8.3 同一schema、package下,允许存在同名的psql语言的不带out出参函数 CREATE or replace FUNCTION func8_3(in a integer) RETURNS int @@ -1222,7 +1216,7 @@ drop function v_func1; --clean reset behavior_compat_options; drop schema out_param_schema cascade; -NOTICE: drop cascades to 24 other objects +NOTICE: drop cascades to 29 other objects DETAIL: drop cascades to function func1(integer) drop cascades to function func1_1(integer,integer) drop cascades to function func2(integer) @@ -1239,7 +1233,12 @@ drop cascades to function out_param_schema.func7_1(integer) drop cascades to function out_param_schema.func7_2(integer) drop cascades to function out_param_schema.func8_1(integer) drop cascades to function out_param_schema.func8_1(integer) -drop cascades to function func8_2(integer) +--?.* +--?.* +--?.* +--?.* +--?.* +--?.* drop cascades to function func8_3(integer) drop cascades to function func8_3(integer,integer) --?.* diff --git a/src/test/regress/expected/out_param_func_overload.out b/src/test/regress/expected/out_param_func_overload.out new file mode 100644 index 000000000..8c76cecb5 --- /dev/null +++ b/src/test/regress/expected/out_param_func_overload.out @@ -0,0 +1,298 @@ +create schema out_param_func_overload; +set current_schema= out_param_func_overload; +set behavior_compat_options='proc_outparam_override'; +-- 0 +create or replace package pkg_type +as +function func(i1 in int, o1 out number, o2 out varchar2) return number; +function func(i1 in int, i2 in int, o1 out number, o2 out varchar2) return number; +end pkg_type; +/ +create or replace package body pkg_type +is + function func(i1 in int, o1 out number, o2 out varchar2) + return number + is + BEGIN + raise notice 'func(i1 in int, o1 out number, o2 out varchar2)'; + o1 := 12.34; + o2 := 'test1'; + return 12.34; + end; + function func(i1 in int, i2 in int, o1 out number, o2 out varchar2) + return number + is + begin + raise notice 'func(i1 in int, i2 in int, o1 out number, o2 out varchar2)'; + o1 := 43.21; + o2 := 'test2'; + return 43.21; + end; +end pkg_type; +/ +DECLARE +ii1 int := -1; +ii2 int := -1; +oo1 number := -1; +oo2 varchar2 := ''; +rr1 number := -1; +begin + rr1 := pkg_type.func(ii1, ii2, oo1, oo2); + raise notice 'pkg_type ii1:%', ii1; + raise notice 'pkg_type ii2:%', ii2; + raise notice 'pkg_type oo1:%', oo1; + raise notice 'pkg_type oo2:%', oo2; + raise notice 'pkg_type rr1:%', rr1; +END; +/ +NOTICE: func(i1 in int, i2 in int, o1 out number, o2 out varchar2) +CONTEXT: SQL statement "CALL pkg_type.func(ii1,ii2,oo1,oo2)" +PL/pgSQL function inline_code_block line 7 at assignment +NOTICE: pkg_type ii1:-1 +NOTICE: pkg_type ii2:-1 +NOTICE: pkg_type oo1:43.21 +NOTICE: pkg_type oo2:test2 +NOTICE: pkg_type rr1:43.21 +DECLARE +ii1 int := -1; +ii2 int := -1; +oo1 number := -1; +oo2 varchar2 := ''; +rr1 number := -1; +begin + rr1 := pkg_type.func(ii1, oo1, oo2); + raise notice 'pkg_type ii1:%', ii1; + raise notice 'pkg_type ii2:%', ii2; + raise notice 'pkg_type oo1:%', oo1; + raise notice 'pkg_type oo2:%', oo2; + raise notice 'pkg_type rr1:%', rr1; +END; +/ +NOTICE: func(i1 in int, o1 out number, o2 out varchar2) +CONTEXT: SQL statement "CALL pkg_type.func(ii1,oo1,oo2)" +PL/pgSQL function inline_code_block line 7 at assignment +NOTICE: pkg_type ii1:-1 +NOTICE: pkg_type ii2:-1 +NOTICE: pkg_type oo1:12.34 +NOTICE: pkg_type oo2:test1 +NOTICE: pkg_type rr1:12.34 +drop package pkg_type; +NOTICE: drop cascades to 2 other objects +DETAIL: drop cascades to function out_param_func_overload.func(integer) +drop cascades to function out_param_func_overload.func(integer,integer) +-- 1 private +create or replace package pkg_type as +function func(a varchar2) return varchar2; +end pkg_type; +/ +create or replace package body pkg_type as +function func(a varchar2) return varchar2 +as +b varchar2(5) :='var'; +BEGIN +return b; +end; +function func(a integer) return integer +as +b integer := 2; +BEGIN +return b; +end; +end pkg_type; +/ +select pkg_type.func(1); + func +------ + var +(1 row) + +drop package pkg_type; +NOTICE: drop cascades to 2 other objects +DETAIL: drop cascades to function out_param_func_overload.func(character varying) +drop cascades to function out_param_func_overload.func(integer) +-- test overload +create or replace package pkg_type is + function func(a int) return int; + function func(a int, b out int) return int; +end pkg_type; +/ +create or replace package body pkg_type +is + function func(a int) + return int + is + BEGIN + raise notice 'func(a int)'; + return 1; + end; + function func(a int, b out int) + return int + is + begin + b := 1; + raise notice 'func(a int, b out int)'; + return 2; + end; +end pkg_type; +/ +DECLARE +a int := -1; +b int := -1; +c int := -1; +begin + c := pkg_type.func(a); + raise notice 'pkg_type a:%', a; + raise notice 'pkg_type b:%', b; + raise notice 'pkg_type c:%', c; +END; +/ +NOTICE: func(a int) +CONTEXT: SQL statement "CALL pkg_type.func(a)" +PL/pgSQL function inline_code_block line 5 at assignment +NOTICE: pkg_type a:-1 +NOTICE: pkg_type b:-1 +NOTICE: pkg_type c:1 +DECLARE +a int := -1; +b int := -1; +c int := -1; +begin + c := pkg_type.func(a, b); + raise notice 'pkg_type a:%', a; + raise notice 'pkg_type b:%', b; + raise notice 'pkg_type c:%', c; +END; +/ +NOTICE: func(a int, b out int) +CONTEXT: SQL statement "CALL pkg_type.func(a,b)" +PL/pgSQL function inline_code_block line 5 at assignment +NOTICE: pkg_type a:-1 +NOTICE: pkg_type b:1 +NOTICE: pkg_type c:2 +drop package pkg_type; +NOTICE: drop cascades to 2 other objects +DETAIL: drop cascades to function out_param_func_overload.func(integer) +drop cascades to function out_param_func_overload.func(integer) +-- test overload with out +create or replace package pkg_type is + function func(a out int) return int; + function func(a int, b out int) return int; +end pkg_type; +/ +create or replace package body pkg_type +is + function func(a out int) + return int + is + BEGIN + raise notice 'func(a out int)'; + a := 1; + return 2; + end; + function func(a int, b out int) + return int + is + begin + raise notice 'func(a int, b out int)'; + b := 1; + return 3; + end; +end pkg_type; +/ +DECLARE +a int := -1; +b int := -1; +c int := -1; +begin + c := pkg_type.func(a, b); + raise notice 'pkg_type a:%', a; + raise notice 'pkg_type b:%', b; + raise notice 'pkg_type c:%', c; +END; +/ +NOTICE: func(a int, b out int) +CONTEXT: SQL statement "CALL pkg_type.func(a,b)" +PL/pgSQL function inline_code_block line 5 at assignment +NOTICE: pkg_type a:-1 +NOTICE: pkg_type b:1 +NOTICE: pkg_type c:3 +DECLARE +a int := -1; +b int := -1; +c int := -1; +begin + c := pkg_type.func(a); + raise notice 'pkg_type a:%', a; + raise notice 'pkg_type b:%', b; + raise notice 'pkg_type c:%', c; +END; +/ +NOTICE: func(a out int) +CONTEXT: SQL statement "CALL pkg_type.func(a)" +PL/pgSQL function inline_code_block line 5 at assignment +NOTICE: pkg_type a:1 +NOTICE: pkg_type b:-1 +NOTICE: pkg_type c:2 +drop package pkg_type; +NOTICE: drop cascades to 2 other objects +DETAIL: drop cascades to function out_param_func_overload.func() +drop cascades to function out_param_func_overload.func(integer) +create or replace package pkg_type is + function func(a int, b out int) return int; + function func2(a int, b out int) return int; +end pkg_type; +/ +create or replace package body pkg_type +is + function func(a int, b out int) + return int + is + BEGIN + b := 1; + raise notice 'func(a int, b out int)'; + return 1; + end; + function func2(a int, b out int) + return int + is + begin + b := 2; + raise notice 'func2(a int, b out int): b:%', b; + func(a, b); + raise notice 'func2(a int, b out int): b:%', b; + return 2; + end; +end pkg_type; +/ +DECLARE +a int := -1; +b int := -1; +c int := -1; +begin + c := pkg_type.func2(a, b); + raise notice 'pkg_type a:%', a; + raise notice 'pkg_type b:%', b; + raise notice 'pkg_type c:%', c; +END; +/ +NOTICE: func2(a int, b out int): b:2 +CONTEXT: SQL statement "CALL pkg_type.func2(a,b)" +PL/pgSQL function inline_code_block line 5 at assignment +NOTICE: func(a int, b out int) +CONTEXT: SQL statement "CALL func(a,b)" +PL/pgSQL function func2(integer) line 4 at SQL statement +SQL statement "CALL pkg_type.func2(a,b)" +PL/pgSQL function inline_code_block line 5 at assignment +NOTICE: func2(a int, b out int): b:1 +CONTEXT: SQL statement "CALL pkg_type.func2(a,b)" +PL/pgSQL function inline_code_block line 5 at assignment +NOTICE: pkg_type a:-1 +NOTICE: pkg_type b:1 +NOTICE: pkg_type c:2 +drop package pkg_type; +NOTICE: drop cascades to 2 other objects +DETAIL: drop cascades to function out_param_func_overload.func(integer) +drop cascades to function out_param_func_overload.func2(integer) +--clean +reset behavior_compat_options; +drop schema out_param_func_overload cascade; diff --git a/src/test/regress/parallel_schedule0A b/src/test/regress/parallel_schedule0A index 819c7cb6e..3c9ed4c48 100644 --- a/src/test/regress/parallel_schedule0A +++ b/src/test/regress/parallel_schedule0A @@ -64,7 +64,7 @@ test: select_into_user_defined_variables test: select_into_file test: gs_dump_package trigger_dump -test: out_param_func +test: out_param_func out_param_func_overload #test: sqlcode_cursor test: gs_dump_tableconstraint diff --git a/src/test/regress/sql/out_param_func_overload.sql b/src/test/regress/sql/out_param_func_overload.sql new file mode 100644 index 000000000..06e448031 --- /dev/null +++ b/src/test/regress/sql/out_param_func_overload.sql @@ -0,0 +1,244 @@ +create schema out_param_func_overload; +set current_schema= out_param_func_overload; +set behavior_compat_options='proc_outparam_override'; + + +-- 0 +create or replace package pkg_type +as +function func(i1 in int, o1 out number, o2 out varchar2) return number; +function func(i1 in int, i2 in int, o1 out number, o2 out varchar2) return number; +end pkg_type; +/ + +create or replace package body pkg_type +is + function func(i1 in int, o1 out number, o2 out varchar2) + return number + is + BEGIN + raise notice 'func(i1 in int, o1 out number, o2 out varchar2)'; + o1 := 12.34; + o2 := 'test1'; + return 12.34; + end; + function func(i1 in int, i2 in int, o1 out number, o2 out varchar2) + return number + is + begin + raise notice 'func(i1 in int, i2 in int, o1 out number, o2 out varchar2)'; + o1 := 43.21; + o2 := 'test2'; + return 43.21; + end; +end pkg_type; +/ + +DECLARE +ii1 int := -1; +ii2 int := -1; +oo1 number := -1; +oo2 varchar2 := ''; +rr1 number := -1; +begin + rr1 := pkg_type.func(ii1, ii2, oo1, oo2); + raise notice 'pkg_type ii1:%', ii1; + raise notice 'pkg_type ii2:%', ii2; + raise notice 'pkg_type oo1:%', oo1; + raise notice 'pkg_type oo2:%', oo2; + raise notice 'pkg_type rr1:%', rr1; +END; +/ + +DECLARE +ii1 int := -1; +ii2 int := -1; +oo1 number := -1; +oo2 varchar2 := ''; +rr1 number := -1; +begin + rr1 := pkg_type.func(ii1, oo1, oo2); + raise notice 'pkg_type ii1:%', ii1; + raise notice 'pkg_type ii2:%', ii2; + raise notice 'pkg_type oo1:%', oo1; + raise notice 'pkg_type oo2:%', oo2; + raise notice 'pkg_type rr1:%', rr1; +END; +/ +drop package pkg_type; + +-- 1 private +create or replace package pkg_type as +function func(a varchar2) return varchar2; +end pkg_type; +/ +create or replace package body pkg_type as +function func(a varchar2) return varchar2 +as +b varchar2(5) :='var'; +BEGIN +return b; +end; +function func(a integer) return integer +as +b integer := 2; +BEGIN +return b; +end; +end pkg_type; +/ +select pkg_type.func(1); +drop package pkg_type; + +-- test overload +create or replace package pkg_type is + function func(a int) return int; + function func(a int, b out int) return int; +end pkg_type; +/ +create or replace package body pkg_type +is + function func(a int) + return int + is + BEGIN + raise notice 'func(a int)'; + return 1; + end; + function func(a int, b out int) + return int + is + begin + b := 1; + raise notice 'func(a int, b out int)'; + return 2; + end; +end pkg_type; +/ + +DECLARE +a int := -1; +b int := -1; +c int := -1; +begin + c := pkg_type.func(a); + raise notice 'pkg_type a:%', a; + raise notice 'pkg_type b:%', b; + raise notice 'pkg_type c:%', c; +END; +/ + +DECLARE +a int := -1; +b int := -1; +c int := -1; +begin + c := pkg_type.func(a, b); + raise notice 'pkg_type a:%', a; + raise notice 'pkg_type b:%', b; + raise notice 'pkg_type c:%', c; +END; +/ +drop package pkg_type; + + +-- test overload with out +create or replace package pkg_type is + function func(a out int) return int; + function func(a int, b out int) return int; +end pkg_type; +/ + +create or replace package body pkg_type +is + function func(a out int) + return int + is + BEGIN + raise notice 'func(a out int)'; + a := 1; + return 2; + end; + function func(a int, b out int) + return int + is + begin + raise notice 'func(a int, b out int)'; + b := 1; + return 3; + end; +end pkg_type; +/ + +DECLARE +a int := -1; +b int := -1; +c int := -1; +begin + c := pkg_type.func(a, b); + raise notice 'pkg_type a:%', a; + raise notice 'pkg_type b:%', b; + raise notice 'pkg_type c:%', c; +END; +/ + +DECLARE +a int := -1; +b int := -1; +c int := -1; +begin + c := pkg_type.func(a); + raise notice 'pkg_type a:%', a; + raise notice 'pkg_type b:%', b; + raise notice 'pkg_type c:%', c; +END; +/ +drop package pkg_type; + + +create or replace package pkg_type is + function func(a int, b out int) return int; + function func2(a int, b out int) return int; +end pkg_type; +/ +create or replace package body pkg_type +is + function func(a int, b out int) + return int + is + BEGIN + b := 1; + raise notice 'func(a int, b out int)'; + return 1; + end; + function func2(a int, b out int) + return int + is + begin + b := 2; + raise notice 'func2(a int, b out int): b:%', b; + func(a, b); + raise notice 'func2(a int, b out int): b:%', b; + return 2; + end; +end pkg_type; +/ + +DECLARE +a int := -1; +b int := -1; +c int := -1; +begin + c := pkg_type.func2(a, b); + raise notice 'pkg_type a:%', a; + raise notice 'pkg_type b:%', b; + raise notice 'pkg_type c:%', c; +END; +/ + +drop package pkg_type; + +--clean +reset behavior_compat_options; + +drop schema out_param_func_overload cascade;