diff --git a/src/common/backend/catalog/gs_package.cpp b/src/common/backend/catalog/gs_package.cpp old mode 100644 new mode 100755 index 553066b9f82427b34ac1f411cd31fdc343b83c75..7186bd80c75c94497c90361479c6eecfb4253c0d --- a/src/common/backend/catalog/gs_package.cpp +++ b/src/common/backend/catalog/gs_package.cpp @@ -176,7 +176,7 @@ bool IsExistPackageName(const char* pkgname) return false; } -Oid PackageNameListGetOid(List* pkgnameList, bool missing_ok) +Oid PackageNameListGetOid(List* pkgnameList, bool missing_ok, bool isPkgBody) { Oid pkgOid = InvalidOid; char* schemaname = NULL; @@ -196,6 +196,28 @@ Oid PackageNameListGetOid(List* pkgnameList, bool missing_ok) } else { pkgOid = PackageNameGetOid(pkgname); } + if (isPkgBody && OidIsValid(pkgOid)) { + HeapTuple tuple = SearchSysCache1(PACKAGEOID, ObjectIdGetDatum(pkgOid)); + if (!HeapTupleIsValid(tuple)) { + ereport(ERROR, + (errmodule(MOD_PLSQL), errcode(ERRCODE_CACHE_LOOKUP_FAILED), + errmsg("cache lookup failed for package %u", pkgOid), + errdetail("cache lookup failed"), + errcause("System error"), + erraction("rebuild package"))); + } + bool isNull = false; + (void)SysCacheGetAttr(PACKAGEOID, tuple, Anum_gs_package_pkgbodydeclsrc, &isNull); + if (isNull && !missing_ok) { + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_PACKAGE), + errmsg("package body %s does not exist", NameListToString(pkgnameList)))); + } else if (isNull && missing_ok) { + ReleaseSysCache(tuple); + return InvalidOid; + } + ReleaseSysCache(tuple); + } if (!OidIsValid(pkgOid) && !missing_ok) { ereport(ERROR, (errcode(ERRCODE_UNDEFINED_PACKAGE), diff --git a/src/common/backend/catalog/objectaddress.cpp b/src/common/backend/catalog/objectaddress.cpp index d5200fb6c0024890fda720263c8993edc3c594f7..dc4bc41ada071fe293a4d82d51ff81ce51ca79f2 100644 --- a/src/common/backend/catalog/objectaddress.cpp +++ b/src/common/backend/catalog/objectaddress.cpp @@ -835,7 +835,7 @@ ObjectAddress get_object_address( break; case OBJECT_PACKAGE_BODY: address.classId = PackageRelationId; - address.objectId = PackageNameListGetOid(objname, missing_ok); + address.objectId = PackageNameListGetOid(objname, missing_ok, true); address.objectSubId = (int32)address.objectId; /* same as objectId for package body */ break; case OBJECT_OPERATOR: diff --git a/src/gausskernel/optimizer/commands/functioncmds.cpp b/src/gausskernel/optimizer/commands/functioncmds.cpp index 088e1711c339597be282dfd5e042b9ae9adab2ed..2e87617a7eb182ae3017f94c42a93c5f4ce78090 100644 --- a/src/gausskernel/optimizer/commands/functioncmds.cpp +++ b/src/gausskernel/optimizer/commands/functioncmds.cpp @@ -1673,6 +1673,7 @@ void RemovePackageById(Oid pkgOid, bool isBody) HeapTuple newtup = heap_modify_tuple(pkgtup, RelationGetDescr(relation), values, nulls, replaces); DropErrorByOid(PLPGSQL_PACKAGE_BODY, pkgOid); simple_heap_update(relation, &newtup->t_self, newtup); + CatalogUpdateIndexes(relation, newtup); } ReleaseSysCache(pkgtup); diff --git a/src/gausskernel/optimizer/commands/packagecmds.cpp b/src/gausskernel/optimizer/commands/packagecmds.cpp index e5825ffbde741f2c67be0aa03f2c8ff8c0b1a8a1..b2d6c63ec2195e1c77bb5a4ca90042ad64b709d6 100644 --- a/src/gausskernel/optimizer/commands/packagecmds.cpp +++ b/src/gausskernel/optimizer/commands/packagecmds.cpp @@ -237,7 +237,7 @@ ObjectAddress AlterPackageOwner(List* name, Oid newOwnerId) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("package not supported in distributed database"))); #endif - Oid pkgOid = PackageNameListGetOid(name, false); + Oid pkgOid = PackageNameListGetOid(name, false, false); Relation rel; HeapTuple tup; ObjectAddress address; diff --git a/src/include/catalog/gs_package.h b/src/include/catalog/gs_package.h index 2441a1a3e7dffbea8fbaca96f80474897a0933b1..94b94c6bc205eb766a69a2637c6c5493c034fb40 100644 --- a/src/include/catalog/gs_package.h +++ b/src/include/catalog/gs_package.h @@ -48,7 +48,7 @@ extern Oid SysynonymPkgNameGetOid(const char* pkgname, Oid namespaceId); extern Oid saveCallFromPkgOid(Oid pkgOid); extern void restoreCallFromPkgOid(Oid pkgOid); extern NameData* GetPackageName(Oid packageOid); -extern Oid PackageNameListGetOid(List* pkgnameList, bool missing_ok=false); +extern Oid PackageNameListGetOid(List* pkgnameList, bool missing_ok=false, bool isPkgBody = false); extern Oid GetPackageNamespace(Oid packageOid); extern bool IsExistPackageName(const char* pkgname); extern void BuildSessionPackageRuntimeForAutoSession(uint64 sessionId, uint64 parentSessionId, diff --git a/src/test/regress/expected/plpgsql_override_out.out b/src/test/regress/expected/plpgsql_override_out.out index 2b2bcf4ec9722331627afe6fbd8d2aef714c3bc8..0a71ab4be0f6cad1a6d571eb753d97c6f4b097f0 100644 --- a/src/test/regress/expected/plpgsql_override_out.out +++ b/src/test/regress/expected/plpgsql_override_out.out @@ -1005,6 +1005,13 @@ end; ERROR: Named argument "b" can not be a const CONTEXT: compilation of PL/pgSQL function "inline_code_block" near line 4 set plsql_compile_check_options=''; +drop package body if exists pck1; +drop package body pck1; +ERROR: package body pck1 does not exist +drop package body pck1; +ERROR: package body pck1 does not exist +drop package body if exists pck1; +NOTICE: package pck1() does not exist, skipping drop package if exists pck1; NOTICE: drop cascades to 2 other objects --?.* diff --git a/src/test/regress/sql/plpgsql_override_out.sql b/src/test/regress/sql/plpgsql_override_out.sql index 0073d6c986770fad8169a5cdac52808003929d86..096ce1f16221057e092f058d3378b2a1c5d41273 100644 --- a/src/test/regress/sql/plpgsql_override_out.sql +++ b/src/test/regress/sql/plpgsql_override_out.sql @@ -697,5 +697,9 @@ end; / set plsql_compile_check_options=''; +drop package body if exists pck1; +drop package body pck1; +drop package body pck1; +drop package body if exists pck1; drop package if exists pck1; drop schema if exists plpgsql_override_out cascade;