From 23a7b56ebe4115b447b224c6bc050d7f12d90c27 Mon Sep 17 00:00:00 2001 From: liuyongzhen Date: Mon, 28 Nov 2022 16:54:23 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E6=B5=B7=E9=87=8F=E3=80=91=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E5=AD=98=E5=82=A8=E8=BF=87=E7=A8=8B=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E5=8C=851=E5=86=85=E5=8C=85=E5=90=AB=E5=90=8C=E5=90=8D?= =?UTF-8?q?=E5=AD=98=E5=82=A8=E8=BF=87=E7=A8=8B=EF=BC=8C=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E5=90=8C=E4=B9=89=E8=AF=8D=EF=BC=8C=E8=B0=83=E7=94=A8=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/backend/catalog/namespace.cpp | 62 +++++++++++++------ .../regress/expected/hw_package_function.out | 54 ++++++++++++++++ src/test/regress/sql/hw_package_function.sql | 52 ++++++++++++++++ 3 files changed, 150 insertions(+), 18 deletions(-) diff --git a/src/common/backend/catalog/namespace.cpp b/src/common/backend/catalog/namespace.cpp index 651353c7e..5777412e5 100644 --- a/src/common/backend/catalog/namespace.cpp +++ b/src/common/backend/catalog/namespace.cpp @@ -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); diff --git a/src/test/regress/expected/hw_package_function.out b/src/test/regress/expected/hw_package_function.out index 6b5b87615..8b1d07d85 100644 --- a/src/test/regress/expected/hw_package_function.out +++ b/src/test/regress/expected/hw_package_function.out @@ -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; diff --git a/src/test/regress/sql/hw_package_function.sql b/src/test/regress/sql/hw_package_function.sql index 5740ca1be..ea1f5395b 100644 --- a/src/test/regress/sql/hw_package_function.sql +++ b/src/test/regress/sql/hw_package_function.sql @@ -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; +