!5977 修复在开启proc_outparam_override后,无法在package内重载入参不一致且带出参的函数的问题

Merge pull request !5977 from wangfeihuo/master
This commit is contained in:
opengauss_bot
2024-08-12 06:25:38 +00:00
committed by Gitee
9 changed files with 642 additions and 97 deletions

View File

@ -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) {

View File

@ -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;

View File

@ -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()

View File

@ -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

View File

@ -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)

View File

@ -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)
--?.*

View File

@ -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;

View File

@ -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

View File

@ -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;