!2497 【海量】创建存储过程时,包1内包含同名存储过程,创建同义词,调用失败

Merge pull request !2497 from liuyongzhen/fix_bug
This commit is contained in:
opengauss-bot
2022-12-01 08:49:20 +00:00
committed by Gitee
3 changed files with 150 additions and 18 deletions

View File

@ -3159,6 +3159,7 @@ bool IsPackageFunction(List* funcname)
Oid namespaceId = InvalidOid;
char *pkgname = NULL;
bool isFirstFunction = true;
bool isSynonymPkg = false;
/* deconstruct the name list */
DeconstructQualifiedName(funcname, &schemaname, &func_name, &pkgname);
@ -3171,6 +3172,30 @@ bool IsPackageFunction(List* funcname)
recomputeNamespacePath();
}
if (NULL != pkgname) {
if (OidIsValid(namespaceId)) {
if (OidIsValid(SysynonymPkgNameGetOid(pkgname, namespaceId))) {
isSynonymPkg = true;
}
} else {
List* tempActiveSearchPath = NIL;
ListCell* l = NULL;
recomputeNamespacePath();
tempActiveSearchPath = list_copy(u_sess->catalog_cxt.activeSearchPath);
foreach (l, tempActiveSearchPath) {
Oid namespaceId = lfirst_oid(l);
if (OidIsValid(SysynonymPkgNameGetOid(pkgname, namespaceId))) {
isSynonymPkg = true;
list_free_ext(tempActiveSearchPath);
break;
}
}
list_free_ext(tempActiveSearchPath);
}
}
#ifndef ENABLE_MULTIPLE_NODES
if (t_thrd.proc->workingVersionNum < 92470) {
catlist = SearchSysCacheList1(PROCNAMEARGSNSP, CStringGetDatum(func_name));
@ -3191,27 +3216,28 @@ bool IsPackageFunction(List* funcname)
} else {
packageid = InvalidOid;
}
if (OidIsValid(namespaceId)) {
/* Consider only procs in specified namespace */
if (procform->pronamespace != namespaceId)
continue;
} else {
/*
* Consider only procs that are in the search path and are not in
* the temp namespace.
*/
ListCell* nsp = NULL;
if (!isSynonymPkg) {
if (OidIsValid(namespaceId)) {
/* Consider only procs in specified namespace */
if (procform->pronamespace != namespaceId)
continue;
} else {
/*
* Consider only procs that are in the search path and are not in
* the temp namespace.
*/
ListCell* nsp = NULL;
foreach (nsp, u_sess->catalog_cxt.activeSearchPath) {
if (procform->pronamespace == lfirst_oid(nsp) &&
procform->pronamespace != u_sess->catalog_cxt.myTempNamespace)
break;
foreach (nsp, u_sess->catalog_cxt.activeSearchPath) {
if (procform->pronamespace == lfirst_oid(nsp) &&
procform->pronamespace != u_sess->catalog_cxt.myTempNamespace)
break;
}
if (nsp == NULL)
continue; /* proc is not in search path */
}
if (nsp == NULL)
continue; /* proc is not in search path */
}
/* package function and not package function can not overload */
proctup = t_thrd.lsc_cxt.FetchTupleFromCatCList(catlist, i);
Datum ispackage = SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_package, &isNull);

View File

@ -846,3 +846,57 @@ DETAIL: drop cascades to function public.p1(_int4[],_int4[],integer)
drop cascades to function public.p1(_int4[],integer)
drop cascades to function public.p4()
set behavior_compat_options='';
--fix package synonym
DROP DATABASE IF EXISTS db;
NOTICE: database "db" does not exist, skipping
CREATE DATABASE db DBCOMPATIBILITY 'A';
\c db
CREATE USER pkg_user1 PASSWORD 'Abc@123456';
grant all on database db to pkg_user1;
CREATE USER pkg_user2 PASSWORD 'Abc@123456';
grant all on database db to pkg_user2;
create or replace synonym pkg_user2.syn1 for pkg_user1.pkg1;
SET ROLE pkg_user1 PASSWORD 'Abc@123456';
create or replace package pkg1 IS
cons1 constant text := 'lili';
PROCEDURE p1(p int);
PROCEDURE p1(p text);
end pkg1;
/
create or replace package body pkg1 IS
PROCEDURE p1(p int) IS
BEGIN
raise info 'the number is %.',p;
end;
PROCEDURE p1(p text) IS
BEGIN
raise info 'the text is %.',p;
end;
end pkg1;
/
grant all privileges on package pkg1 to pkg_user2;
SET ROLE pkg_user2 PASSWORD 'Abc@123456';
create or replace package pkg2 IS
PROCEDURE f1(p int);
end pkg2;
/
create or replace package body pkg2 is
PROCEDURE f1(p int) IS
BEGIN
syn1.p1(p);
end;
end pkg2;
/
call pkg2.f1(5);
INFO: the number is 5.
CONTEXT: SQL statement "CALL syn1.p1(p)"
PL/pgSQL function f1(integer) line 3 at PERFORM
f1
----
(1 row)
\c regression
drop database db;
drop user pkg_user1;
drop user pkg_user2;

View File

@ -687,5 +687,57 @@ procedure p4();
pv1 ty1;
end pkg112;
/
drop package if exists pkg112;
set behavior_compat_options='';
--fix package synonym
DROP DATABASE IF EXISTS db;
CREATE DATABASE db DBCOMPATIBILITY 'A';
\c db
CREATE USER pkg_user1 PASSWORD 'Abc@123456';
grant all on database db to pkg_user1;
CREATE USER pkg_user2 PASSWORD 'Abc@123456';
grant all on database db to pkg_user2;
create or replace synonym pkg_user2.syn1 for pkg_user1.pkg1;
SET ROLE pkg_user1 PASSWORD 'Abc@123456';
create or replace package pkg1 IS
cons1 constant text := 'lili';
PROCEDURE p1(p int);
PROCEDURE p1(p text);
end pkg1;
/
create or replace package body pkg1 IS
PROCEDURE p1(p int) IS
BEGIN
raise info 'the number is %.',p;
end;
PROCEDURE p1(p text) IS
BEGIN
raise info 'the text is %.',p;
end;
end pkg1;
/
grant all privileges on package pkg1 to pkg_user2;
SET ROLE pkg_user2 PASSWORD 'Abc@123456';
create or replace package pkg2 IS
PROCEDURE f1(p int);
end pkg2;
/
create or replace package body pkg2 is
PROCEDURE f1(p int) IS
BEGIN
syn1.p1(p);
end;
end pkg2;
/
call pkg2.f1(5);
\c regression
drop database db;
drop user pkg_user1;
drop user pkg_user2;