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 553066b9f..7186bd80c --- 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 06883547e..7f7e2b029 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 088e1711c..2e87617a7 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 e5825ffbd..b2d6c63ec 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 2441a1a3e..94b94c6bc 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 2b2bcf4ec..0a71ab4be 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 0073d6c98..096ce1f16 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;