!2497 【海量】创建存储过程时,包1内包含同名存储过程,创建同义词,调用失败
Merge pull request !2497 from liuyongzhen/fix_bug
This commit is contained in:
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
Reference in New Issue
Block a user