From 0f4ede314e823e00cd273f07b97c3e4baaebe1b5 Mon Sep 17 00:00:00 2001 From: lukeman Date: Thu, 7 Sep 2023 20:48:01 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81gs=5Fdependencies=E3=80=81?= =?UTF-8?q?=E5=BF=BD=E7=95=A5=E4=BE=9D=E8=B5=96=E5=88=9B=E5=BB=BApackage?= =?UTF-8?q?=E3=80=81=E5=A4=B1=E6=95=88=E9=87=8D=E7=BC=96=E8=AF=91=E8=AF=AD?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/backend/catalog/CMakeLists.txt | 2 +- src/common/backend/catalog/Makefile | 4 +- src/common/backend/catalog/builtin_funcs.ini | 16 + src/common/backend/catalog/dependency.cpp | 5 +- src/common/backend/catalog/gs_package.cpp | 130 +- src/common/backend/catalog/heap.cpp | 124 +- src/common/backend/catalog/namespace.cpp | 10 +- src/common/backend/catalog/objectaddress.cpp | 50 +- src/common/backend/catalog/pg_depend.cpp | 68 +- src/common/backend/catalog/pg_enum.cpp | 58 + src/common/backend/catalog/pg_object.cpp | 88 +- src/common/backend/catalog/pg_proc.cpp | 185 +- src/common/backend/catalog/pg_type.cpp | 188 +- src/common/backend/nodes/makefuncs.cpp | 3 +- src/common/backend/nodes/nodes.cpp | 5 + src/common/backend/nodes/outfuncs.cpp | 45 + src/common/backend/nodes/readfuncs.cpp | 32 +- src/common/backend/parser/gram.y | 156 +- src/common/backend/parser/parse_type.cpp | 318 +- src/common/backend/parser/scan.l | 1 + src/common/backend/utils/CMakeLists.txt | 2 + src/common/backend/utils/Makefile | 2 +- src/common/backend/utils/adt/regproc.cpp | 34 + src/common/backend/utils/adt/ruleutils.cpp | 10 +- src/common/backend/utils/adt/varlena.cpp | 20 + src/common/backend/utils/cache/lsyscache.cpp | 33 +- .../backend/utils/gsplsql/CMakeLists.txt | 19 + src/common/backend/utils/gsplsql/Makefile | 24 + .../backend/utils/gsplsql/gsdependencies.cpp | 1480 ++++++++ .../utils/gsplsql/gsobject_dependencies.cpp | 1529 ++++++++ src/common/backend/utils/init/globals.cpp | 3 +- src/common/backend/utils/misc/guc/guc_sql.cpp | 3 +- .../backend/utils/misc/guc/guc_storage.cpp | 3 +- .../backend/utils/misc/sec_rls_utils.cpp | 30 + .../interfaces/libpq/frontend_parser/gram.y | 6 +- src/common/pl/plpgsql/src/gram.y | 179 +- src/common/pl/plpgsql/src/pl_comp.cpp | 293 +- src/common/pl/plpgsql/src/pl_debugger.cpp | 23 +- src/common/pl/plpgsql/src/pl_exec.cpp | 123 +- src/common/pl/plpgsql/src/pl_funcs.cpp | 6 +- src/common/pl/plpgsql/src/pl_handler.cpp | 226 +- src/common/pl/plpgsql/src/pl_package.cpp | 176 +- src/gausskernel/CMakeLists.txt | 1 + src/gausskernel/bootstrap/bootstrap.cpp | 1 - .../optimizer/commands/event_trigger.cpp | 1 + .../optimizer/commands/functioncmds.cpp | 512 ++- .../optimizer/commands/packagecmds.cpp | 94 + .../optimizer/commands/tablecmds.cpp | 64 +- .../optimizer/commands/typecmds.cpp | 55 + src/gausskernel/process/tcop/utility.cpp | 80 + .../process/threadpool/knl_session.cpp | 110 + .../storage/access/heap/heapam.cpp | 4 +- src/include/access/heapam.h | 2 +- src/include/catalog/dependency.h | 17 +- src/include/catalog/gs_dependencies.h | 52 + src/include/catalog/gs_dependencies_fn.h | 147 + src/include/catalog/gs_dependencies_obj.h | 52 + src/include/catalog/gs_package.h | 5 +- src/include/catalog/gs_package_fn.h | 2 +- src/include/catalog/heap.h | 4 +- src/include/catalog/indexing.h | 12 + src/include/catalog/objectaddress.h | 1 + src/include/catalog/pg_enum.h | 2 +- src/include/catalog/pg_object.h | 12 +- src/include/catalog/pg_proc.h | 4 + src/include/catalog/pg_proc.h_for_llt | 9 +- src/include/catalog/pg_proc_fn.h | 6 +- src/include/catalog/pg_type.h | 6 + src/include/catalog/pg_type_fn.h | 15 +- .../rollback-post_catalog_maindb_92_916.sql | 19 + .../rollback-post_catalog_otherdb_92_916.sql | 19 + .../upgrade-post_catalog_maindb_92_916.sql | 79 + .../upgrade-post_catalog_otherdb_92_916.sql | 79 + src/include/commands/defrem.h | 3 + src/include/knl/knl_session.h | 54 + src/include/miscadmin.h | 5 +- src/include/nodes/makefuncs.h | 2 +- src/include/nodes/nodes.h | 4 + src/include/nodes/parsenodes.h | 15 + src/include/nodes/parsenodes_common.h | 12 + src/include/nodes/primnodes.h | 2 + src/include/parser/kwlist.h | 2 + src/include/parser/parse_type.h | 24 +- src/include/parser/scanner.h | 1 + src/include/storage/lmgr.h | 1 + src/include/tcop/tcopprot.h | 2 + src/include/utils/builtins.h | 6 + src/include/utils/lsyscache.h | 2 + src/include/utils/pl_package.h | 2 +- src/include/utils/plpgsql.h | 111 +- src/include/utils/sec_rls_utils.h | 1 + src/test/regress/expected/b_compatibility.out | 10 +- src/test/regress/expected/function.out | 2 +- .../expected/pldeveloper_gs_source.out | 2 +- .../plpgsql_depend/plpgsql_depend_reftype.out | 988 +++++ .../plpgsql_depend/plpgsql_depend_type.out | 3240 +++++++++++++++++ .../plpgsql_depend/plpgsql_pkg_dependency.out | 64 + .../plpgsql_pkg_variable_dependency.out | 3051 ++++++++++++++++ .../plpgsql_depend/plpgsql_recompile.out | 219 ++ .../regress/expected/plpgsql_package_type.out | 6 +- .../regress/expected/plsql_show_all_error.out | 2 +- .../expected/single_node_type_sanity.out | 42 +- src/test/regress/parallel_schedule0 | 2 + src/test/regress/parallel_schedule0B | 5 +- .../plpgsql_depend/plpgsql_depend_reftype.sql | 474 +++ .../plpgsql_depend/plpgsql_depend_type.sql | 1419 ++++++++ .../plpgsql_depend/plpgsql_pkg_dependency.sql | 40 + .../plpgsql_pkg_variable_dependency.sql | 1541 ++++++++ .../sql/plpgsql_depend/plpgsql_recompile.sql | 110 + .../regress/sql/single_node_type_sanity.sql | 2 +- 110 files changed, 18161 insertions(+), 485 deletions(-) create mode 100644 src/common/backend/utils/gsplsql/CMakeLists.txt create mode 100644 src/common/backend/utils/gsplsql/Makefile create mode 100644 src/common/backend/utils/gsplsql/gsdependencies.cpp create mode 100644 src/common/backend/utils/gsplsql/gsobject_dependencies.cpp create mode 100644 src/include/catalog/gs_dependencies.h create mode 100644 src/include/catalog/gs_dependencies_fn.h create mode 100644 src/include/catalog/gs_dependencies_obj.h create mode 100644 src/include/catalog/upgrade_sql/rollback_catalog_maindb/rollback-post_catalog_maindb_92_916.sql create mode 100644 src/include/catalog/upgrade_sql/rollback_catalog_otherdb/rollback-post_catalog_otherdb_92_916.sql create mode 100644 src/include/catalog/upgrade_sql/upgrade_catalog_maindb/upgrade-post_catalog_maindb_92_916.sql create mode 100644 src/include/catalog/upgrade_sql/upgrade_catalog_otherdb/upgrade-post_catalog_otherdb_92_916.sql create mode 100644 src/test/regress/expected/plpgsql_depend/plpgsql_depend_reftype.out create mode 100644 src/test/regress/expected/plpgsql_depend/plpgsql_depend_type.out create mode 100644 src/test/regress/expected/plpgsql_depend/plpgsql_pkg_dependency.out create mode 100644 src/test/regress/expected/plpgsql_depend/plpgsql_pkg_variable_dependency.out create mode 100644 src/test/regress/expected/plpgsql_depend/plpgsql_recompile.out create mode 100644 src/test/regress/sql/plpgsql_depend/plpgsql_depend_reftype.sql create mode 100644 src/test/regress/sql/plpgsql_depend/plpgsql_depend_type.sql create mode 100644 src/test/regress/sql/plpgsql_depend/plpgsql_pkg_dependency.sql create mode 100644 src/test/regress/sql/plpgsql_depend/plpgsql_pkg_variable_dependency.sql create mode 100644 src/test/regress/sql/plpgsql_depend/plpgsql_recompile.sql diff --git a/src/common/backend/catalog/CMakeLists.txt b/src/common/backend/catalog/CMakeLists.txt index 052d10407..35defa2c6 100755 --- a/src/common/backend/catalog/CMakeLists.txt +++ b/src/common/backend/catalog/CMakeLists.txt @@ -14,7 +14,7 @@ set(POSTGRES_BKI_SRCS_S @gs_client_global_keys_args.h @pg_job.h @gs_asp.h @pg_job_proc.h @pg_extension_data_source.h @pg_statistic_ext.h @pg_object.h @pg_synonym.h @toasting.h @indexing.h @gs_obsscaninfo.h @pg_directory.h @pg_hashbucket.h @gs_global_chain.h @gs_global_config.h @pg_streaming_stream.h @pg_streaming_cont_query.h @pg_streaming_reaper_status.h @gs_matview.h @gs_matview_dependency.h @pgxc_slice.h -@gs_opt_model.h @pg_recyclebin.h @pg_snapshot.h @gs_model.h @gs_package.h @gs_job_argument.h @gs_job_attribute.h @pg_uid.h @gs_db_privilege.h +@gs_opt_model.h @pg_recyclebin.h @pg_snapshot.h @gs_model.h @gs_dependencies.h @gs_dependencies_obj.h @gs_package.h @gs_job_argument.h @gs_job_attribute.h @pg_uid.h @gs_db_privilege.h @pg_replication_origin.h @pg_publication.h @pg_publication_rel.h @pg_subscription.h @gs_sql_patch.h @pg_subscription_rel.h" ) diff --git a/src/common/backend/catalog/Makefile b/src/common/backend/catalog/Makefile index c38bf4a48..6b7de7b10 100644 --- a/src/common/backend/catalog/Makefile +++ b/src/common/backend/catalog/Makefile @@ -38,7 +38,7 @@ all: $(BKIFILES) schemapg.h # indexing.h had better be last, and toasting.h just before it. POSTGRES_BKI_SRCS = $(addprefix $(top_srcdir)/src/include/catalog/,\ - gs_package.h pg_proc.h pg_type.h pg_attribute.h pg_class.h pg_partition.h\ + pg_proc.h pg_type.h pg_attribute.h pg_class.h pg_partition.h\ pg_attrdef.h pg_constraint.h pg_inherits.h pg_index.h pg_operator.data \ pg_opfamily.h pg_opclass.h pg_am.h pg_amop.data pg_amproc.h \ pg_language.h pg_largeobject_metadata.h pg_largeobject.h pg_aggregate.h \ @@ -59,7 +59,7 @@ POSTGRES_BKI_SRCS = $(addprefix $(top_srcdir)/src/include/catalog/,\ pg_job.h gs_asp.h pg_job_proc.h pg_extension_data_source.h pg_statistic_ext.h pg_object.h pg_synonym.h \ toasting.h indexing.h gs_obsscaninfo.h pg_directory.h pg_hashbucket.h gs_global_chain.h gs_global_config.h\ pg_streaming_stream.h pg_streaming_cont_query.h pg_streaming_reaper_status.h gs_matview.h\ - gs_matview_dependency.h pgxc_slice.h gs_opt_model.h gs_model.h\ + gs_matview_dependency.h pgxc_slice.h gs_opt_model.h gs_dependencies.h gs_dependencies_obj.h gs_package.h gs_model.h\ pg_recyclebin.h pg_snapshot.h gs_job_argument.h gs_job_attribute.h pg_uid.h gs_db_privilege.h\ pg_replication_origin.h pg_publication.h pg_publication_rel.h pg_subscription.h gs_sql_patch.h\ pg_subscription_rel.h \ diff --git a/src/common/backend/catalog/builtin_funcs.ini b/src/common/backend/catalog/builtin_funcs.ini index 43e5d2149..88498b5bd 100755 --- a/src/common/backend/catalog/builtin_funcs.ini +++ b/src/common/backend/catalog/builtin_funcs.ini @@ -12452,6 +12452,22 @@ AddFuncGroup( "ubtvacuumcleanup", 1, AddBuiltinFunc(_0(4762), _1("ubtvacuumcleanup"), _2(2), _3(true), _4(false), _5(ubtvacuumcleanup), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(2, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ubtvacuumcleanup"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), + AddFuncGroup( + "undefinedin", 1, + AddBuiltinFunc(_0(UNDEFINEDINPUT), _1("undefinedin"), _2(1), _3(true), _4(false), _5(undefinedin), _6(4408), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 2275), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("undefinedin"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "undefinedout", 1, + AddBuiltinFunc(_0(UNDEFINEDOUTPUT), _1("undefinedout"), _2(1), _3(true), _4(false), _5(undefinedout), _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 705), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("undefinedout"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "undefinedrecv", 1, + AddBuiltinFunc(_0(UNDEFINEDRECV), _1("undefinedrecv"), _2(1), _3(true), _4(false), _5(undefinedrecv), _6(4408), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("undefinedrecv"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "undefinedsend", 1, + AddBuiltinFunc(_0(UNDEFINEDSEND), _1("undefinedsend"), _2(1), _3(true), _4(false), _5(undefinedsend), _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 705), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("undefinedsend"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), AddFuncGroup( "unique_key_recheck", 1, AddBuiltinFunc(_0(1250), _1("unique_key_recheck"), _2(0), _3(true), _4(false), _5(unique_key_recheck), _6(2279), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(0), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("unique_key_recheck"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("deferred UNIQUE constraint check"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) diff --git a/src/common/backend/catalog/dependency.cpp b/src/common/backend/catalog/dependency.cpp index bd62afbd7..8a375de9f 100644 --- a/src/common/backend/catalog/dependency.cpp +++ b/src/common/backend/catalog/dependency.cpp @@ -118,7 +118,8 @@ #include "utils/snapmgr.h" #include "datasource/datasource.h" #include "postmaster/rbcleaner.h" - +#include "catalog/gs_dependencies_fn.h" +#include "catalog/gs_dependencies_obj.h" /* * This constant table maps ObjectClasses to the corresponding catalog OIDs. * See also getObjectClass(). @@ -126,6 +127,7 @@ static const Oid object_classes[MAX_OCLASS] = { RelationRelationId, /* OCLASS_CLASS */ ProcedureRelationId, /* OCLASS_PROC */ + DependenciesObjRelationId, /* OCLASS_GS_DEPENDENCIES */ TypeRelationId, /* OCLASS_TYPE */ CastRelationId, /* OCLASS_CAST */ CollationRelationId, /* OCLASS_COLLATION */ @@ -873,7 +875,6 @@ void findDependentObjects(const ObjectAddress* object, int flags, ObjectAddressS subflags = 0; /* keep compiler quiet */ break; } - findDependentObjects(&otherObject, subflags, &mystack, targetObjects, pendingObjects, depRel); } diff --git a/src/common/backend/catalog/gs_package.cpp b/src/common/backend/catalog/gs_package.cpp index c6ff29542..f256603a1 100755 --- a/src/common/backend/catalog/gs_package.cpp +++ b/src/common/backend/catalog/gs_package.cpp @@ -56,7 +56,7 @@ #include "utils/plpgsql.h" #include "utils/pl_global_package_runtime_cache.h" #include "utils/pl_package.h" - +#include "catalog/gs_dependencies_fn.h" #include "tcop/pquery.h" #include "executor/executor.h" #include "executor/tstoreReceiver.h" @@ -70,6 +70,8 @@ static void CopyParentSessionPkgs(SessionPackageRuntime* sessionPkgs, List* pkgL static void RestorePkgValuesByPkgState(PLpgSQL_package* targetPkg, PackageRuntimeState* pkgState, bool isInit = false); static void RestoreAutonmSessionPkgs(SessionPackageRuntime* sessionPkgs); static void ReleaseUnusedPortalContext(List* portalContexts, bool releaseAll = false); +static bool gspkg_is_same_pkg_spec(HeapTuple tup, const char* pkg_spec_src); + #define MAXSTRLEN ((1 << 11) - 1) static Acl* PackageAclDefault(Oid ownerId) @@ -230,14 +232,14 @@ Oid PackageNameListGetOid(List* pkgnameList, bool missing_ok, bool isPkgBody) return pkgOid; } -NameData* GetPackageName(Oid packageOid) +char* GetPackageName(Oid packageOid) { bool isNull = false; HeapTuple pkgTuple = SearchSysCache1(PACKAGEOID, ObjectIdGetDatum(packageOid)); - NameData* pkgName = NULL; + char* pkgName = NULL; if (HeapTupleIsValid(pkgTuple)) { Datum pkgName_datum = SysCacheGetAttr(PACKAGEOID, pkgTuple, Anum_gs_package_pkgname, &isNull); - pkgName = DatumGetName(pkgName_datum); + pkgName = pstrdup(NameStr(*(DatumGetName(pkgName_datum)))); ReleaseSysCache(pkgTuple); } else { pkgName = NULL; @@ -299,8 +301,23 @@ PLpgSQL_package* PackageInstantiation(Oid packageOid) return pkg; } +void plpgsql_clear_created_pkg(Oid pkg_oid) +{ + if (u_sess->SPI_cxt._connected > -1 && + u_sess->plsql_cxt.plpgsql_pkg_HashTable != NULL) { + PLpgSQL_pkg_hashkey hashkey; + hashkey.pkgOid = pkg_oid; + plpgsql_hashtable_delete_and_check_invalid_item(PACKAGEOID, pkg_oid); + PLpgSQL_package* pkg = plpgsql_pkg_HashTableLookup(&hashkey); + if (pkg) { + delete_package(pkg); + } + } +} + Oid PackageSpecCreate(Oid pkgNamespace, const char* pkgName, const Oid ownerId, const char* pkgSpecSrc, bool replace, bool pkgSecDef) { + u_sess->plsql_cxt.compile_has_warning_info = false; Relation pkgDesc; Oid pkgOid = InvalidOid; bool nulls[Natts_gs_package]; @@ -310,6 +327,7 @@ Oid PackageSpecCreate(Oid pkgNamespace, const char* pkgName, const Oid ownerId, TupleDesc tupDesc; ObjectAddress myself; ObjectAddress referenced; + bool is_same = false; int i; bool isReplaced = false; bool isUpgrade = false; @@ -379,6 +397,9 @@ Oid PackageSpecCreate(Oid pkgNamespace, const char* pkgName, const Oid ownerId, errcause("System error"), erraction("Drop and rebuild package."))); } + if (enable_plpgsql_gsdependency_guc()) { + is_same = gspkg_is_same_pkg_spec(oldpkgtup, pkgSpecSrc); + } if (!pg_package_ownercheck(HeapTupleGetOid(oldpkgtup), ownerId)) { ReleaseSysCache(oldpkgtup); aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PACKAGE, pkgName); @@ -402,18 +423,18 @@ Oid PackageSpecCreate(Oid pkgNamespace, const char* pkgName, const Oid ownerId, Assert(OidIsValid(pkgOid)); CatalogUpdateIndexes(pkgDesc, tup); - - if (isReplaced) { + if (isReplaced && !(is_same && GetPgObjectValid(pkgOid, OBJECT_TYPE_PKGSPEC))) { (void)deleteDependencyRecordsFor(PackageRelationId, pkgOid, true); - DeleteTypesDenpendOnPackage(PackageRelationId, pkgOid); /* the 'shared dependencies' also change when update. */ - deleteSharedDependencyRecordsFor(PackageRelationId, pkgOid, 0); + deleteSharedDependencyRecordsFor(PackageRelationId, pkgOid, 0); DeleteFunctionByPackageOid(pkgOid); - } + DeleteTypesDenpendOnPackage(PackageRelationId, pkgOid); + } heap_freetuple_ext(tup); heap_close(pkgDesc, RowExclusiveLock); + CacheInvalidateFunction(InvalidOid, pkgOid); /* Record dependencies */ ObjectAddressSet(myself, PackageRelationId, pkgOid); isUpgrade = u_sess->attr.attr_common.IsInplaceUpgrade && myself.objectId < FirstBootstrapObjectId && !isReplaced; @@ -434,9 +455,6 @@ Oid PackageSpecCreate(Oid pkgNamespace, const char* pkgName, const Oid ownerId, /* Post creation hook for new schema */ InvokeObjectAccessHook(OAT_POST_CREATE, PackageRelationId, pkgOid, 0, NULL); - /* Advance command counter so new tuple can be seen by validator */ - CommandCounterIncrement(); - /* Recode the procedure create time. */ if (OidIsValid(pkgOid)) { if (!isReplaced) { @@ -444,20 +462,31 @@ Oid PackageSpecCreate(Oid pkgNamespace, const char* pkgName, const Oid ownerId, CreatePgObject(pkgOid, OBJECT_TYPE_PKGSPEC, ownerId, objectOpt); } else { UpdatePgObjectMtime(pkgOid, OBJECT_TYPE_PROC); + if (enable_plpgsql_gsdependency_guc()) { + CommandCounterIncrement(); + SetPgObjectValid(pkgOid, OBJECT_TYPE_PKGSPEC, true); + } } } + SetCurrCompilePgObjStatus(true); + /* Advance command counter so new tuple can be seen by validator */ + CommandCounterIncrement(); + /* dependency between packages are only needed for package spec */ if (!isUpgrade) { u_sess->plsql_cxt.pkg_dependencies = NIL; u_sess->plsql_cxt.need_pkg_dependencies = true; } + PG_TRY(); { + list_free_ext(u_sess->plsql_cxt.func_compiled_list); plpgsql_package_validator(pkgOid, true, true); } PG_CATCH(); { + list_free_ext(u_sess->plsql_cxt.func_compiled_list); u_sess->plsql_cxt.need_pkg_dependencies = false; if (u_sess->plsql_cxt.pkg_dependencies != NIL) { list_free(u_sess->plsql_cxt.pkg_dependencies); @@ -469,12 +498,12 @@ Oid PackageSpecCreate(Oid pkgNamespace, const char* pkgName, const Oid ownerId, u_sess->plsql_cxt.need_pkg_dependencies = false; /* record dependency discovered during validation */ - if (!isUpgrade && u_sess->plsql_cxt.pkg_dependencies != NIL) { + if (!isUpgrade && u_sess->plsql_cxt.pkg_dependencies != NIL && !enable_plpgsql_gsdependency_guc()) { recordDependencyOnPackage(PackageRelationId, pkgOid, u_sess->plsql_cxt.pkg_dependencies); list_free(u_sess->plsql_cxt.pkg_dependencies); u_sess->plsql_cxt.pkg_dependencies = NIL; } - + plpgsql_clear_created_pkg(oldPkgOid); return pkgOid; } @@ -488,6 +517,7 @@ Oid PackageBodyCreate(Oid pkgNamespace, const char* pkgName, const Oid ownerId, TupleDesc tupDesc; int i = 0; bool isReplaced = false; + bool is_same = false; #ifndef ENABLE_MULTIPLE_NODES if (u_sess->attr.attr_common.plsql_show_all_error == true) { if (pkgBodySrc == NULL) { @@ -495,6 +525,7 @@ Oid PackageBodyCreate(Oid pkgNamespace, const char* pkgName, const Oid ownerId, } } #endif + u_sess->plsql_cxt.compile_has_warning_info = false; Assert(PointerIsValid(pkgBodySrc)); HeapTuple tup = NULL; HeapTuple oldpkgtup = NULL; @@ -539,6 +570,7 @@ Oid PackageBodyCreate(Oid pkgNamespace, const char* pkgName, const Oid ownerId, pkgDesc = heap_open(PackageRelationId, RowExclusiveLock); tupDesc = RelationGetDescr(pkgDesc); + bool pkgBodyDeclSrcIsNull = false; if (OidIsValid(oldPkgOid)) { oldpkgtup = SearchSysCache1(PACKAGEOID, ObjectIdGetDatum(oldPkgOid)); if (!HeapTupleIsValid(oldpkgtup)) { @@ -549,13 +581,23 @@ Oid PackageBodyCreate(Oid pkgNamespace, const char* pkgName, const Oid ownerId, errcause("System error"), erraction("Drop and rebuild package"))); } - bool isNull = false; - SysCacheGetAttr(PACKAGEOID, oldpkgtup, Anum_gs_package_pkgbodydeclsrc, &isNull); - if (!isNull && !replace) { - ereport(ERROR, (errcode(ERRCODE_DUPLICATE_PACKAGE), errmsg("package body already exists"))); - } else if (!isNull) { - DeleteFunctionByPackageOid(oldPkgOid); - DeleteTypesDenpendOnPackage(PackageRelationId, oldPkgOid, false); + + Datum pkgBodyDeclSrcDatum =SysCacheGetAttr(PACKAGEOID, oldpkgtup, Anum_gs_package_pkgbodydeclsrc, &pkgBodyDeclSrcIsNull); + if (enable_plpgsql_gsdependency_guc()) { + if (!pkgBodyDeclSrcIsNull) { + char* pkgBodyDeclSrcStr = TextDatumGetCString(pkgBodyDeclSrcDatum); + is_same = (0 == strcmp(pkgBodyDeclSrcStr, pkgBodySrc)); + } + } + if (!pkgBodyDeclSrcIsNull) { + if (!replace) { + ereport(ERROR, (errcode(ERRCODE_DUPLICATE_PACKAGE), errmsg("package body already exists"))); + } else { + DeleteFunctionByPackageOid(oldPkgOid); + if (!(is_same && GetPgObjectValid(oldPkgOid, OBJECT_TYPE_PKGBODY))) { + DeleteTypesDenpendOnPackage(PackageRelationId, oldPkgOid, false); + } + } } tup = heap_modify_tuple(oldpkgtup, tupDesc, values, nulls, replaces); simple_heap_update(pkgDesc, &tup->t_self, tup); @@ -577,24 +619,31 @@ Oid PackageBodyCreate(Oid pkgNamespace, const char* pkgName, const Oid ownerId, heap_close(pkgDesc, RowExclusiveLock); + CacheInvalidateFunction(InvalidOid, oldPkgOid); /* Post creation hook for new schema */ InvokeObjectAccessHook(OAT_POST_CREATE, PackageRelationId, oldPkgOid, 0, NULL); - /* Advance command counter so new tuple can be seen by validator */ - CommandCounterIncrement(); - /* Recode the procedure create time. */ if (OidIsValid(oldPkgOid)) { - if (!isReplaced) { + if (pkgBodyDeclSrcIsNull) { PgObjectOption objectOpt = {true, true, false, false}; - CreatePgObject(oldPkgOid, OBJECT_TYPE_PKGSPEC, ownerId, objectOpt); + CreatePgObject(oldPkgOid, OBJECT_TYPE_PKGBODY, ownerId, objectOpt); } else { UpdatePgObjectMtime(oldPkgOid, OBJECT_TYPE_PROC); + if (enable_plpgsql_gsdependency_guc()) { + CommandCounterIncrement(); + SetPgObjectValid(oldPkgOid, OBJECT_TYPE_PKGSPEC, true); + SetPgObjectValid(oldPkgOid, OBJECT_TYPE_PKGBODY, true); + } } } - + /* Advance command counter so new tuple can be seen by validator */ + CommandCounterIncrement(); + SetCurrCompilePgObjStatus(true); + list_free_ext(u_sess->plsql_cxt.func_compiled_list); + u_sess->plsql_cxt.real_func_num = 0; plpgsql_package_validator(oldPkgOid, false, true); - + plpgsql_clear_created_pkg(oldPkgOid); return oldPkgOid; } @@ -1821,8 +1870,13 @@ bool isSameArgList(CreateFunctionStmt* stmt1, CreateFunctionStmt* stmt2) Type typtup1; Type typtup2; errno_t rc; - typtup1 = LookupTypeName(NULL, t1, NULL); - typtup2 = LookupTypeName(NULL, t2, NULL); + if (enable_plpgsql_undefined()) { + typtup1 = LookupTypeNameSupportUndef(NULL, t1, NULL); + typtup2 = LookupTypeNameSupportUndef(NULL, t2, NULL); + } else { + typtup1 = LookupTypeName(NULL, t1, NULL); + typtup2 = LookupTypeName(NULL, t2, NULL); + } bool isTableOf1 = false; bool isTableOf2 = false; Oid baseOid1 = InvalidOid; @@ -1910,4 +1964,20 @@ bool isSameArgList(CreateFunctionStmt* stmt1, CreateFunctionStmt* stmt2) return true; } +static bool gspkg_is_same_pkg_spec(HeapTuple tup, const char* pkg_spec_src) +{ + bool is_null; + Datum old_pkg_spec_src_datum = SysCacheGetAttr(PACKAGEOID, tup, Anum_gs_package_pkgspecsrc, &is_null); + if (is_null) { + return pkg_spec_src == NULL; + } + char* old_pkg_spec_src = TextDatumGetCString(old_pkg_spec_src_datum); + if (strcmp(pkg_spec_src, old_pkg_spec_src) == 0) { + pfree_ext(old_pkg_spec_src); + return true; + } + pfree_ext(old_pkg_spec_src); + return false; +} + #endif diff --git a/src/common/backend/catalog/heap.cpp b/src/common/backend/catalog/heap.cpp index 9f58d2337..688138536 100644 --- a/src/common/backend/catalog/heap.cpp +++ b/src/common/backend/catalog/heap.cpp @@ -116,6 +116,8 @@ #include "foreign/fdwapi.h" #include "instruments/generate_report.h" #include "catalog/gs_encrypted_columns.h" +#include "catalog/gs_dependencies_fn.h" +#include "utils/plpgsql.h" #ifdef PGXC #include "catalog/pgxc_class.h" @@ -998,6 +1000,34 @@ void InsertPgAttributeTuple(Relation pg_attribute_rel, Form_pg_attribute new_att heap_freetuple(tup); } +static bool make_gs_depend_param_body(GsDependParamBody* gs_depend_param_body, const char* typ_name, + const char relkind, const Oid namespace_oid) +{ + bool need_build_depend = false; + int cw = CompileWhich(); + need_build_depend = (relkind == RELKIND_RELATION || relkind == RELKIND_COMPOSITE_TYPE) && + (cw == PLPGSQL_COMPILE_PACKAGE_PROC || cw == PLPGSQL_COMPILE_PACKAGE || cw == PLPGSQL_COMPILE_PROC); + if (!need_build_depend) { + return false; + } + gs_depend_param_body->dependNamespaceOid = namespace_oid; + if (NULL != u_sess->plsql_cxt.curr_compile_context && + NULL != u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package) { + PLpgSQL_package* pkg = u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package; + gs_depend_param_body->dependPkgOid = pkg->pkg_oid; + gs_depend_param_body->dependPkgName = pkg->pkg_signature; + } + char* real_typ_name = ParseTypeName((char*)typ_name, gs_depend_param_body->dependPkgOid); + if (real_typ_name == NULL) { + gs_depend_param_body->dependName = pstrdup(typ_name); + } else { + gs_depend_param_body->dependName = real_typ_name; + } + gs_depend_param_body->refPosType = GSDEPEND_REFOBJ_POS_IN_TYPE; + gs_depend_param_body->type = GSDEPEND_OBJECT_TYPE_TYPE; + return true; +} + /* -------------------------------- * AddNewAttributeTuples * @@ -1005,7 +1035,8 @@ void InsertPgAttributeTuple(Relation pg_attribute_rel, Form_pg_attribute new_att * tuples to pg_attribute. * -------------------------------- */ -static void AddNewAttributeTuples(Oid new_rel_oid, TupleDesc tupdesc, char relkind, bool oidislocal, int oidinhcount, bool hasbucket, bool hasuids) +static void AddNewAttributeTuples(Oid new_rel_oid, TupleDesc tupdesc, char relkind, + bool oidislocal, int oidinhcount, bool hasbucket, bool hasuids, List* depend_extend, const char* typ_name, Oid namespace_oid) { Form_pg_attribute attr; int i; @@ -1020,7 +1051,13 @@ static void AddNewAttributeTuples(Oid new_rel_oid, TupleDesc tupdesc, char relki rel = heap_open(AttributeRelationId, RowExclusiveLock); indstate = CatalogOpenIndexes(rel); - + GsDependParamBody gs_depend_param_body; + gsplsql_init_gs_depend_param_body(&gs_depend_param_body); + bool need_build_depend = false; + if (enable_plpgsql_gsdependency()) { + need_build_depend = make_gs_depend_param_body(&gs_depend_param_body, typ_name, relkind, namespace_oid); + } + ListCell* depend_extend_cell = list_head(depend_extend); /* * First we add the user attributes. This is also a convenient place to * add dependencies on their datatypes and collations. @@ -1048,7 +1085,17 @@ static void AddNewAttributeTuples(Oid new_rel_oid, TupleDesc tupdesc, char relki referenced.classId = TypeRelationId; referenced.objectId = attr->atttypid; referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + + if (need_build_depend) { + if (NULL != depend_extend_cell) { + gs_depend_param_body.dependExtend = (TypeDependExtend*)lfirst(depend_extend_cell); + } else { + gs_depend_param_body.dependExtend = NULL; + } + recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL, &gs_depend_param_body); + } else { + recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + } /* The default collation is pinned, so don't bother recording it */ if (OidIsValid(attr->attcollation) && attr->attcollation != DEFAULT_COLLATION_OID) { @@ -1058,6 +1105,12 @@ static void AddNewAttributeTuples(Oid new_rel_oid, TupleDesc tupdesc, char relki recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } } + if (need_build_depend && NULL != depend_extend_cell) { + depend_extend_cell = lnext(depend_extend_cell); + } + } + if (need_build_depend) { + pfree_ext(gs_depend_param_body.dependName); } /* @@ -2600,7 +2653,7 @@ Oid heap_create_with_catalog(const char *relname, Oid relnamespace, Oid reltable int oidinhcount, OnCommitAction oncommit, Datum reloptions, bool use_user_acl, bool allow_system_table_mods, PartitionState *partTableState, int8 row_compress, HashBucketInfo *bucketinfo, bool record_dependce, List *ceLst, StorageType storage_type, - LOCKMODE partLockMode, ObjectAddress *typaddress) + LOCKMODE partLockMode, ObjectAddress *typaddress, List* depend_extend) { Relation pg_class_desc; Relation new_rel_desc; @@ -3002,7 +3055,7 @@ Oid heap_create_with_catalog(const char *relname, Oid relnamespace, Oid reltable * now add tuples to pg_attribute for the attributes in our new relation. */ AddNewAttributeTuples( - relid, new_rel_desc->rd_att, relkind, oidislocal, oidinhcount, relhasbucket, relhasuids); + relid, new_rel_desc->rd_att, relkind, oidislocal, oidinhcount, relhasbucket, relhasuids, depend_extend, relname, relnamespace); if (ceLst != NULL) { AddNewGsSecEncryptedColumnsTuples(relid, ceLst); } @@ -8208,3 +8261,64 @@ void AddOrDropUidsAttr(Oid relOid, bool oldRelHasUids, bool newRelHasUids) } } +static void heap_serialize_rel_attribute(Relation att_rel, Oid rel_oid, + int att_idx, StringInfoData* concat_name, bool* depend_undefined) +{ + ScanKeyData skey[2]; + SysScanDesc scan; + HeapTuple tuple; + bool is_null = false; + int key_num = 0; + ScanKeyInit(&skey[key_num++], Anum_pg_attribute_attrelid, BTEqualStrategyNumber, + F_OIDEQ, ObjectIdGetDatum(rel_oid)); + ScanKeyInit(&skey[key_num++], Anum_pg_attribute_attnum, BTEqualStrategyNumber, + F_INT4EQ, Int32GetDatum(att_idx)); + scan = systable_beginscan(att_rel, AttributeRelidNumIndexId, true, SnapshotSelf, key_num, skey); + tuple = systable_getnext(scan); + if (!HeapTupleIsValid(tuple)) { + systable_endscan(scan); + return; + } + Datum id_dropped_datum = heap_getattr(tuple, Anum_pg_attribute_attisdropped, + RelationGetDescr(att_rel), &is_null); + if (is_null || DatumGetBool(id_dropped_datum)) { + systable_endscan(scan); + return; + } + Datum att_name_datum = heap_getattr(tuple, Anum_pg_attribute_attname, + RelationGetDescr(att_rel), &is_null); + if (!is_null) { + appendStringInfoString(concat_name, DatumGetName(att_name_datum)->data); + } + Datum typ_oid_datum = heap_getattr(tuple, Anum_pg_attribute_atttypid, + RelationGetDescr(att_rel), &is_null); + appendStringInfoString(concat_name, ":"); + Oid typ_oid = DatumGetObjectId(typ_oid_datum); + if (!is_null && OidIsValid(typ_oid) && typ_oid != UNDEFINEDOID) { + (void)MakeTypeNamesStrForTypeOid(DatumGetObjectId(typ_oid_datum), depend_undefined, concat_name); + } else if (NULL != depend_undefined) { + *depend_undefined = true; + } + appendStringInfoString(concat_name, ","); + systable_endscan(scan); +} + +char* heap_serialize_row_attr(Oid rel_oid, bool* depend_undefined) +{ + Relation rel; + StringInfoData concat_name; + char rel_kind = get_rel_relkind(rel_oid); + if (rel_kind != RELKIND_COMPOSITE_TYPE && rel_kind != RELKIND_RELATION) { + return NULL; + } + int att_num = get_relnatts(rel_oid); + rel = heap_open(AttributeRelationId, AccessShareLock); + initStringInfo(&concat_name); + for (int i = 1; i <= att_num; i++) { + heap_serialize_rel_attribute(rel, rel_oid, i, &concat_name, depend_undefined); + } + heap_close(rel, AccessShareLock); + char* ret = pstrdup(concat_name.data); + FreeStringInfo(&concat_name); + return ret; +} diff --git a/src/common/backend/catalog/namespace.cpp b/src/common/backend/catalog/namespace.cpp index c03f43c11..74448e204 100644 --- a/src/common/backend/catalog/namespace.cpp +++ b/src/common/backend/catalog/namespace.cpp @@ -3354,6 +3354,9 @@ Oid LookupExplicitNamespace(const char* nspname, bool missing_ok) if (!(u_sess->analyze_cxt.is_under_analyze || (IS_PGXC_DATANODE && IsConnFromCoord())) || u_sess->exec_cxt.is_exec_trigger_func) { + if (!OidIsValid(namespaceId) && enable_plpgsql_undefined_not_check_nspoid()) { + return namespaceId; + } aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE); if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_NAMESPACE, nspname); @@ -3543,7 +3546,12 @@ Oid get_namespace_oid(const char* nspname, bool missing_ok) Oid oid = InvalidOid; oid = GetSysCacheOid1(NAMESPACENAME, CStringGetDatum(nspname)); - if (!OidIsValid(oid) && !missing_ok) { + if (!OidIsValid(oid) && !missing_ok) { + if (enable_plpgsql_undefined_not_check_nspoid()) { + ereport(LOG, (errmodule(MOD_PLSQL), + (ERRCODE_UNDEFINED_SCHEMA), errmsg("%s does not exist. Ignore it.", nspname))); + return oid; + } char message[MAXSTRLEN]; errno_t rc = sprintf_s(message, MAXSTRLEN, "schema \"%s\" does not exist", nspname); if (strlen(nspname) > MAXSTRLEN) { diff --git a/src/common/backend/catalog/objectaddress.cpp b/src/common/backend/catalog/objectaddress.cpp index dc4bc41ad..d23aeba89 100644 --- a/src/common/backend/catalog/objectaddress.cpp +++ b/src/common/backend/catalog/objectaddress.cpp @@ -89,6 +89,7 @@ #include "utils/syscache.h" #include "access/heapam.h" #include "datasource/datasource.h" +#include "catalog/pg_depend.h" /* * ObjectProperty @@ -3742,4 +3743,51 @@ get_object_address_usermapping(List *objname, List *objargs, bool missing_ok) return address; } - +Oid get_object_package(const ObjectAddress* address) +{ + const ObjectPropertyType* property = NULL; + property = get_object_property_data(address->classId); + if (property->attnum_namespace == InvalidAttrNumber) { + return InvalidOid; + } + Relation dependRel; + const int nKeys = 3; + ScanKeyData key[nKeys]; + SysScanDesc scan = NULL; + HeapTuple tuple = NULL; + bool isNull = true; + Oid pkgOid = InvalidOid; + int keyNum = 0; + dependRel = heap_open(DependRelationId, AccessShareLock); + ScanKeyInit(&key[keyNum++], Anum_pg_depend_classid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(address->classId)); + ScanKeyInit(&key[keyNum++], Anum_pg_depend_objid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(address->objectId)); + ScanKeyInit(&key[keyNum++], Anum_pg_depend_objsubid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(address->objectSubId)); + scan = systable_beginscan(dependRel, DependDependerIndexId, true, NULL, nKeys, key); + ObjectAddress procObjAddr; + procObjAddr.classId = InvalidOid; + while (HeapTupleIsValid(tuple = systable_getnext(scan))) { + Datum objOidDatum = heap_getattr(tuple, Anum_pg_depend_refobjid, + RelationGetDescr(dependRel), &isNull); + Assert(!isNull); + Datum classOidDatum = heap_getattr(tuple, Anum_pg_depend_refclassid, + RelationGetDescr(dependRel), &isNull); + Assert(!isNull); + if (classOidDatum == ProcedureRelationId) { + procObjAddr.classId = ProcedureRelationId; + procObjAddr.objectId = DatumGetObjectId(objOidDatum); + procObjAddr.objectSubId = 0; + break; + } + if (classOidDatum != PackageRelationId) { + continue; + } + pkgOid = DatumGetObjectId(objOidDatum); + break; + } + systable_endscan(scan); + heap_close(dependRel, AccessShareLock); + if (OidIsValid(procObjAddr.classId)) { + pkgOid = get_object_package(&procObjAddr); + } + return pkgOid; +} diff --git a/src/common/backend/catalog/pg_depend.cpp b/src/common/backend/catalog/pg_depend.cpp index 3e1935be5..1de567c49 100644 --- a/src/common/backend/catalog/pg_depend.cpp +++ b/src/common/backend/catalog/pg_depend.cpp @@ -35,6 +35,11 @@ #include "utils/rel.h" #include "utils/rel_gs.h" #include "utils/snapmgr.h" +#include "catalog/pg_proc.h" +#include "catalog/pg_rewrite.h" +#include "catalog/gs_dependencies_fn.h" +#include "catalog/gs_dependencies_obj.h" +#include "catalog/pg_object.h" static bool isObjectPinned(const ObjectAddress* object, Relation rel); @@ -45,9 +50,10 @@ static bool isObjectPinned(const ObjectAddress* object, Relation rel); * * This simply creates an entry in pg_depend, without any other processing. */ -void recordDependencyOn(const ObjectAddress* depender, const ObjectAddress* referenced, DependencyType behavior) +void recordDependencyOn(const ObjectAddress* depender, const ObjectAddress* referenced, DependencyType behavior, + GsDependParamBody* gsdependParamBody) { - recordMultipleDependencies(depender, referenced, 1, behavior); + recordMultipleDependencies(depender, referenced, 1, behavior, gsdependParamBody); } /* @@ -55,7 +61,8 @@ void recordDependencyOn(const ObjectAddress* depender, const ObjectAddress* refe * object. This has a little less overhead than recording each separately. */ void recordMultipleDependencies( - const ObjectAddress* depender, const ObjectAddress* referenced, int nreferenced, DependencyType behavior) + const ObjectAddress* depender, const ObjectAddress* referenced, int nreferenced, DependencyType behavior, + GsDependParamBody* gsdependParamBody) { Relation dependDesc; CatalogIndexState indstate; @@ -90,7 +97,20 @@ void recordMultipleDependencies( * need to record dependencies on it. This saves lots of space in * pg_depend, so it's worth the time taken to check. */ - if (!isObjectPinned(referenced, dependDesc)) { + bool isPinned = isObjectPinned(referenced, dependDesc); + if (enable_plpgsql_gsdependency() && DEPENDENCY_NORMAL == behavior && + gsplsql_need_build_gs_dependency(gsdependParamBody, referenced, isPinned)) { + bool ret = gsplsql_build_gs_type_dependency(gsdependParamBody, referenced); + if (ret) { + gsdependParamBody->hasDependency = true; + } + } + if (isPinned) { + continue; + } + if (!enable_plpgsql_gsdependency() || NULL == gsdependParamBody || + (GSDEPEND_REFOBJ_POS_IN_TYPE == gsdependParamBody->refPosType + && GSDEPEND_OBJECT_TYPE_TYPE == gsdependParamBody->type)) { /* * Record the Dependency. Note we don't bother to check for * duplicate dependencies; there's no harm in them. @@ -450,6 +470,17 @@ long changeDependencyFor(Oid classId, Oid objectId, Oid refClassId, Oid oldRefOb return count; } +bool IsPinnedObject(Oid classOid, Oid objOid) { + ObjectAddress objAddr; + objAddr.classId = classOid; + objAddr.objectId = objOid; + objAddr.objectSubId = 0; + Relation dependDesc = heap_open(DependRelationId, AccessShareLock); + bool isPinned = isObjectPinned(&objAddr, dependDesc); + heap_close(dependDesc, AccessShareLock); + return isPinned; +} + /* * Adjust all dependency records to come from a different object of the same type * @@ -1003,3 +1034,32 @@ bool IsPackageDependType(Oid typOid, Oid pkgOid, bool isRefCur) return isFind; } + +void DeletePgDependObject(const ObjectAddress* object, const ObjectAddress* ref_object) +{ + int keyNum = 0; + ScanKeyData key[2]; + ScanKeyInit(&key[keyNum++], Anum_pg_depend_classid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->classId)); + ScanKeyInit(&key[keyNum++], Anum_pg_depend_objid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); + Relation relation = heap_open(DependRelationId, RowExclusiveLock); + SysScanDesc scan = systable_beginscan(relation, DependDependerIndexId, true, NULL, keyNum, key); + bool is_null = false; + HeapTuple tuple; + while (HeapTupleIsValid(tuple = systable_getnext(scan))) { + + Datum refclassid_datum = heap_getattr(tuple, Anum_pg_depend_refclassid, + RelationGetDescr(relation), &is_null); + Datum refobjid_datum = heap_getattr(tuple, Anum_pg_depend_refobjid, + RelationGetDescr(relation), &is_null); + if (ref_object->classId == DatumGetObjectId(refclassid_datum) && + ref_object->objectId == DatumGetObjectId(refobjid_datum)) { + simple_heap_delete(relation, &tuple->t_self); + systable_endscan(scan); + heap_close(relation, RowExclusiveLock); + CommandCounterIncrement(); + return; + } + } + systable_endscan(scan); + heap_close(relation, RowExclusiveLock); +} \ No newline at end of file diff --git a/src/common/backend/catalog/pg_enum.cpp b/src/common/backend/catalog/pg_enum.cpp index cd5e034f6..a03f399b1 100644 --- a/src/common/backend/catalog/pg_enum.cpp +++ b/src/common/backend/catalog/pg_enum.cpp @@ -21,12 +21,14 @@ #include "catalog/indexing.h" #include "catalog/pg_enum.h" #include "catalog/pg_type.h" +#include "catalog/gs_dependencies_fn.h" #include "storage/lmgr.h" #include "miscadmin.h" #include "utils/builtins.h" #include "utils/fmgroids.h" #include "utils/syscache.h" #include "utils/snapmgr.h" +#include "utils/lsyscache.h" static void RenumberEnumType(Relation pg_enum, HeapTuple* existing, int nelems); static int sort_order_cmp(const void* p1, const void* p2); @@ -136,6 +138,13 @@ void EnumValuesCreate(Oid enumTypeOid, List* vals, Oid collation) */ void EnumValuesDelete(Oid enumTypeOid) { + GsDependObjDesc refObj; + if (enable_plpgsql_gsdependency_guc()) { + refObj.name = NULL; + if (!OidIsValid(enumTypeOid)) { + gsplsql_get_depend_obj_by_typ_id(&refObj, enumTypeOid, InvalidOid); + } + } Relation pg_enum = NULL; ScanKeyData key[1]; SysScanDesc scan = NULL; @@ -154,6 +163,13 @@ void EnumValuesDelete(Oid enumTypeOid) systable_endscan(scan); heap_close(pg_enum, RowExclusiveLock); + if (enable_plpgsql_gsdependency_guc() && NULL != refObj.name) { + CommandCounterIncrement(); + (void)gsplsql_remove_ref_dependency(&refObj); + pfree_ext(refObj.schemaName); + pfree_ext(refObj.packageName); + pfree_ext(refObj.name); + } } /* @@ -413,6 +429,10 @@ restart: heap_freetuple_ext(enum_tup); heap_close(pg_enum, RowExclusiveLock); + if (enable_plpgsql_gsdependency_guc()) { + CommandCounterIncrement(); + (void)gsplsql_build_ref_type_dependency(enumTypeOid); + } } /* @@ -434,6 +454,12 @@ void RenameEnumLabel(Oid enumTypeOid, const char* oldVal, const char* newVal) checkEnumLableValue(newVal); checkEnumLableValue(oldVal); + if (enable_plpgsql_gsdependency_guc() && gsplsql_is_object_depend(enumTypeOid, GSDEPEND_OBJECT_TYPE_TYPE)) { + ereport(ERROR, + (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST), + errmsg("The rename operator on %s is not allowed, " + "because it is dependent on another object.", get_typename(enumTypeOid)))); + } /* * Acquire a lock on the enum type, which we won't release until commit. * This ensures that two backends aren't concurrently modifying the same @@ -571,3 +597,35 @@ static int sort_order_cmp(const void* p1, const void* p2) else return 0; } + +char* SerializeEnumAttr(Oid enumTypeOid) +{ + if (!type_is_enum(enumTypeOid)) { + return NULL; + } + CatCList* list = SearchSysCacheList1(ENUMTYPOIDNAME, ObjectIdGetDatum(enumTypeOid)); + if (list == NULL) { + return NULL; + } + if (0 == list->n_members) { + ReleaseSysCacheList(list); + return NULL; + } + HeapTuple* enumList = (HeapTuple*)palloc(list->n_members * sizeof(HeapTuple)); + for (int i = 0; i < list->n_members; i++) { + enumList[i] = t_thrd.lsc_cxt.FetchTupleFromCatCList(list, i); + } + qsort(enumList, list->n_members, sizeof(HeapTuple), sort_order_cmp); + StringInfoData concatName; + initStringInfo(&concatName); + for (int i = 0; i < list->n_members; i++) { + Form_pg_enum en = (Form_pg_enum)GETSTRUCT(enumList[i]); + appendStringInfoString(&concatName, NameStr(en->enumlabel)); + appendStringInfoString(&concatName, ","); + } + pfree_ext(enumList); + ReleaseSysCacheList(list); + char* ret = pstrdup(concatName.data); + FreeStringInfo(&concatName); + return ret; +} diff --git a/src/common/backend/catalog/pg_object.cpp b/src/common/backend/catalog/pg_object.cpp index b3cb14a81..27ded1291 100644 --- a/src/common/backend/catalog/pg_object.cpp +++ b/src/common/backend/catalog/pg_object.cpp @@ -38,6 +38,7 @@ #include "miscadmin.h" #include "catalog/index.h" #include "utils/knl_relcache.h" +#include "utils/pl_package.h" /* * @Description: Insert a new record to pg_object. @@ -50,7 +51,7 @@ * @in changecsn - the commit sequence number when the old version expires. * @returns - void */ -void CreatePgObject(Oid objectOid, PgObjectType objectType, Oid creator, const PgObjectOption objectOpt) +void CreatePgObject(Oid objectOid, PgObjectType objectType, Oid creator, const PgObjectOption objectOpt, bool isValid) { Datum values[Natts_pg_object]; bool nulls[Natts_pg_object]; @@ -95,7 +96,7 @@ void CreatePgObject(Oid objectOid, PgObjectType objectType, Oid creator, const P } else { nulls[Anum_pg_object_mtime - 1] = true; } - + values[Anum_pg_object_valid - 1] = BoolGetDatum(isValid); if (objectOpt.hasCreatecsn && (t_thrd.proc->workingVersionNum >= INPLACE_UPDATE_VERSION_NUM)) { values[Anum_pg_object_createcsn - 1] = UInt64GetDatum(csn); } else { @@ -503,3 +504,86 @@ void recordCommentObjectTime(ObjectAddress addr, Relation rel, ObjectType objTyp break; } } + +bool GetPgObjectValid(Oid oid, PgObjectType objectType) +{ + HeapTuple tuple = SearchSysCache2(PGOBJECTID, ObjectIdGetDatum(oid), CharGetDatum(objectType)); + if (!HeapTupleIsValid(tuple)) { + return false; + } + bool isNull; + Datum validDatum = SysCacheGetAttr(PGOBJECTID, tuple, Anum_pg_object_valid, &isNull); + if (isNull) { + ReleaseSysCache(tuple); + return false; + } + ReleaseSysCache(tuple); + return DatumGetBool(validDatum); +} + +bool SetPgObjectValid(Oid oid, PgObjectType objectType, bool valid) +{ + Relation relation = heap_open(PgObjectRelationId, RowExclusiveLock); + HeapTuple tuple = SearchSysCache2(PGOBJECTID, ObjectIdGetDatum(oid), CharGetDatum(objectType)); + if (!HeapTupleIsValid(tuple)) { + heap_close(relation, RowExclusiveLock); + return false; + } + bool isNull; + Datum oldValidDatum = SysCacheGetAttr(PGOBJECTID, tuple, Anum_pg_object_valid, &isNull); + if (isNull) { + ReleaseSysCache(tuple); + heap_close(relation, RowExclusiveLock); + return false; + } + bool oldValid = DatumGetBool(oldValidDatum); + if (oldValid == valid) { + ReleaseSysCache(tuple); + heap_close(relation, RowExclusiveLock); + return oldValid; + } + Datum values[Natts_pg_object]; + bool nulls[Natts_pg_object] = {false}; + bool replaces[Natts_pg_object] = {false}; + values[Anum_pg_object_valid -1] = BoolGetDatum(valid); + replaces[Anum_pg_object_valid -1] = true; + HeapTuple new_tuple = heap_modify_tuple(tuple, RelationGetDescr(relation), values, nulls, replaces); + (void)simple_heap_update(relation, &new_tuple->t_self, new_tuple, true);//debug tuple->t_self + CatalogUpdateIndexes(relation, new_tuple); + heap_freetuple(new_tuple); + ReleaseSysCache(tuple); + heap_close(relation, RowExclusiveLock); + CommandCounterIncrement(); + return oldValid; +} + +bool GetCurrCompilePgObjStatus() +{ + return u_sess->plsql_cxt.currCompilingObjStatus; +} + +void SetCurrCompilePgObjStatus(bool status) +{ + u_sess->plsql_cxt.currCompilingObjStatus = status; +} + +void UpdateCurrCompilePgObjStatus(bool status) +{ + u_sess->plsql_cxt.currCompilingObjStatus = status && u_sess->plsql_cxt.currCompilingObjStatus; +} + +void InvalidateCurrCompilePgObj() +{ + if (u_sess->plsql_cxt.functionStyleType == FUNCTION_STYLE_TYPE_REFRESH_HEAD) { + return; + } + switch (CompileWhich()) { + case PLPGSQL_COMPILE_PACKAGE: + case PLPGSQL_COMPILE_PACKAGE_PROC: + case PLPGSQL_COMPILE_PROC: + u_sess->plsql_cxt.currCompilingObjStatus = false; + break; + default: + break; + } +} diff --git a/src/common/backend/catalog/pg_proc.cpp b/src/common/backend/catalog/pg_proc.cpp index 14356df94..0fe66c701 100644 --- a/src/common/backend/catalog/pg_proc.cpp +++ b/src/common/backend/catalog/pg_proc.cpp @@ -75,6 +75,8 @@ #include "commands/tablecmds.h" #include "storage/lmgr.h" #include "libpq/md5.h" +#include "catalog/gs_dependencies_fn.h" +#include "catalog/gs_dependencies.h" #ifdef ENABLE_MOT #include "storage/mot/jit_exec.h" @@ -1030,6 +1032,24 @@ static bool user_define_func_check(Oid languageId, const char* probin, char** ab return user_define_fun; } +static void plpgsql_clear_created_func(Oid funcoid) +{ + if (u_sess->SPI_cxt._connected > -1 && + u_sess->plsql_cxt.plpgsql_HashTable != NULL) { + HASH_SEQ_STATUS hash_seq; + hash_seq_init(&hash_seq, u_sess->plsql_cxt.plpgsql_HashTable); + plpgsql_hashent* hash_ent = NULL; + while ((hash_ent = (plpgsql_hashent*)hash_seq_search(&hash_seq)) != NULL) { + PLpgSQL_function* func = hash_ent->function; + if (hash_ent->key.funcOid == funcoid && !OidIsValid(func->pkg_oid)) { + delete_function(func, false); + hash_seq_term(&hash_seq); + break; + } + } + } +} + /* ---------------------------------------------------------------- * ProcedureCreate * @@ -1043,7 +1063,8 @@ ObjectAddress ProcedureCreate(const char* procedureName, Oid procNamespace, Oid bool isAgg, bool isWindowFunc, bool security_definer, bool isLeakProof, bool isStrict, char volatility, oidvector* parameterTypes, Datum allParameterTypes, Datum parameterModes, Datum parameterNames, List* parameterDefaults, Datum proconfig, float4 procost, float4 prorows, int2vector* prodefaultargpos, bool fenced, - bool shippable, bool package, bool proIsProcedure, const char *proargsrc, bool isPrivate) + bool shippable, bool package, bool proIsProcedure, const char *proargsrc, bool isPrivate, + TypeDependExtend* paramTypDependExt, TypeDependExtend* retTypDependExt, CreateFunctionStmt* stmt) { Oid retval; int parameterCount; @@ -1079,10 +1100,10 @@ ObjectAddress ProcedureCreate(const char* procedureName, Oid procNamespace, Oid char* libPath = NULL; char* final_file_name = NULL; List* name = NULL; - + List* dependenciesRefObjOids = NULL; /* sanity checks */ Assert(PointerIsValid(prosrc)); - + u_sess->plsql_cxt.compile_has_warning_info = false; /* * Check function name to ensure that it doesn't conflict with existing synonym. */ @@ -1453,7 +1474,7 @@ ObjectAddress ProcedureCreate(const char* procedureName, Oid procNamespace, Oid tupDesc = RelationGetDescr(rel); /* A db do not overload a function by arguments.*/ - NameData* pkgname = NULL; + char* pkgname = NULL; char* schemaName = get_namespace_name(procNamespace); if (OidIsValid(propackageid)) { pkgname = GetPackageName(propackageid); @@ -1461,13 +1482,13 @@ ObjectAddress ProcedureCreate(const char* procedureName, Oid procNamespace, Oid if (pkgname == NULL) { name = list_make2(makeString(schemaName), makeString(pstrdup(procedureName))); } else { - name = list_make3(makeString(schemaName), makeString(pstrdup(pkgname->data)), makeString(pstrdup(procedureName))); + name = list_make3(makeString(schemaName), makeString(pstrdup(pkgname)), makeString(pstrdup(procedureName))); } #ifndef ENABLE_MULTIPLE_NODES if (pkgname == NULL) { LockProcName(schemaName, NULL, procedureName); } else { - LockProcName(schemaName, pkgname->data, procedureName); + LockProcName(schemaName, pkgname, procedureName); } #endif if (isOraStyle && !package) { @@ -1583,6 +1604,18 @@ ObjectAddress ProcedureCreate(const char* procedureName, Oid procNamespace, Oid */ replaces[Anum_pg_proc_proowner - 1] = false; replaces[Anum_pg_proc_proacl - 1] = false; + retval = HeapTupleGetOid(oldtup); + if (enable_plpgsql_gsdependency_guc()) { + GsDependObjDesc objDesc = gsplsql_construct_func_head_obj(retval, procNamespace, propackageid); + objDesc.type = GSDEPEND_OBJECT_TYPE_PROCHEAD; + gsplsql_remove_dependencies_object(&objDesc); + //delete dependencies + objDesc.refPosType = GSDEPEND_REFOBJ_POS_IN_PROCALL; + Relation relation = heap_open(DependenciesRelationId, RowExclusiveLock); + dependenciesRefObjOids = gsplsql_delete_objs(relation, &objDesc); + CommandCounterIncrement(); + heap_close(relation, RowExclusiveLock); + } /* Okay, do it... */ tup = heap_modify_tuple(oldtup, tupDesc, values, nulls, replaces); @@ -1621,13 +1654,16 @@ ObjectAddress ProcedureCreate(const char* procedureName, Oid procNamespace, Oid (void)simple_heap_insert(rel, tup); is_update = false; + retval = HeapTupleGetOid(tup); } /* Need to update indexes for either the insert or update case */ CatalogUpdateIndexes(rel, tup); - - retval = HeapTupleGetOid(tup); - + GsDependObjDesc funcHeadObjDesc; + if (enable_plpgsql_gsdependency_guc()) { + CommandCounterIncrement(); + funcHeadObjDesc = gsplsql_construct_func_head_obj(retval, procNamespace, propackageid); + } /* * Create dependencies for the new function. If we are updating an * existing function, first delete any existing pg_depend entries. @@ -1657,12 +1693,16 @@ ObjectAddress ProcedureCreate(const char* procedureName, Oid procNamespace, Oid retval, JitExec::JIT_PURGE_SCOPE_SP, JitExec::JIT_PURGE_REPLACE, procedureName); } #endif + } else { + CacheInvalidateFunction(retval, InvalidOid); } myself.classId = ProcedureRelationId; myself.objectId = retval; myself.objectSubId = 0; + bool hasDependency = false; + bool hasUndefined = false; if (u_sess->attr.attr_common.IsInplaceUpgrade && myself.objectId < FirstBootstrapObjectId && !is_update) recordPinnedDependency(&myself); else { @@ -1678,18 +1718,60 @@ ObjectAddress ProcedureCreate(const char* procedureName, Oid procNamespace, Oid referenced.objectSubId = 0; recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + GsDependParamBody gsDependParamBody; + gsplsql_init_gs_depend_param_body(&gsDependParamBody); + if (enable_plpgsql_gsdependency()) { + gsDependParamBody.dependNamespaceOid = procNamespace; + if (NULL != u_sess->plsql_cxt.curr_compile_context && + NULL != u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package) { + Assert(propackageid == + u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package->pkg_oid); + gsDependParamBody.dependPkgOid = propackageid; + gsDependParamBody.dependPkgName = pkgname; + } + gsDependParamBody.refPosType = GSDEPEND_REFOBJ_POS_IN_PROCHEAD; + gsDependParamBody.type = GSDEPEND_OBJECT_TYPE_TYPE; + gsDependParamBody.dependName = funcHeadObjDesc.name; + } + /* dependency on return type */ referenced.classId = TypeRelationId; referenced.objectId = returnType; referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + if (enable_plpgsql_gsdependency() && NULL != retTypDependExt) { + gsDependParamBody.dependExtend = retTypDependExt; + recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL, &gsDependParamBody); + if (gsDependParamBody.hasDependency) { + hasDependency = true; + } + if (gsDependParamBody.dependExtend->dependUndefined) { + hasUndefined = true; + } + } else { + recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + } /* dependency on parameter types */ for (i = 0; i < allParamCount; i++) { referenced.classId = TypeRelationId; referenced.objectId = allParams[i]; referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + /* + * in plsql_dependency GUC, we don't build the dependency between procedure and type + * when the type is dropped or rebuild we don't want the procedure to be dropped. + */ + if (enable_plpgsql_gsdependency() && NULL != paramTypDependExt) { + gsDependParamBody.dependExtend = paramTypDependExt + i; + recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL, &gsDependParamBody); + if (gsDependParamBody.hasDependency) { + hasDependency = true; + } + if (gsDependParamBody.dependExtend->dependUndefined) { + hasUndefined = true; + } + } else { + recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + } } /* dependency on packages */ @@ -1723,6 +1805,34 @@ ObjectAddress ProcedureCreate(const char* procedureName, Oid procNamespace, Oid recordDependencyOnCurrentExtension(&myself, is_update); } + if (enable_plpgsql_gsdependency_guc()) { + CommandCounterIncrement(); + gsplsql_delete_unrefer_depend_obj_in_list(dependenciesRefObjOids, false); + list_free(dependenciesRefObjOids); + if (hasDependency && stmt != NULL) { + funcHeadObjDesc.type = GSDEPEND_OBJECT_TYPE_PROCHEAD; + DependenciesProchead procHead; + procHead.type = T_DependenciesProchead; + procHead.proName = pstrdup(procedureName); + procHead.proArgSrc = stmt->inputHeaderSrc; + procHead.funcHeadSrc = stmt->funcHeadSrc; + if (stmt->funcHeadSrc == NULL) { + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("The header info of procedure %s is null.", procHead.proName))); + } + procHead.undefined = hasUndefined; + gsplsql_update_object_ast(&funcHeadObjDesc, (DependenciesDatum*)(&procHead)); + pfree_ext(procHead.proName); + } + //schema func + if (!OidIsValid(propackageid)) { + funcHeadObjDesc.name = (char*)procedureName; + funcHeadObjDesc.type = GSDEPEND_OBJECT_TYPE_FUNCTION; + gsplsql_build_ref_dependency(&funcHeadObjDesc, nullptr); + } + } + heap_freetuple_ext(tup); /* Post creation hook for new function */ @@ -1732,13 +1842,27 @@ ObjectAddress ProcedureCreate(const char* procedureName, Oid procNamespace, Oid if (OidIsValid(retval)) { if (!is_update) { PgObjectOption objectOpt = {true, true, false, false}; - CreatePgObject(retval, OBJECT_TYPE_PROC, proowner, objectOpt); + CreatePgObject(retval, OBJECT_TYPE_PROC, proowner, objectOpt, !hasUndefined); } else { UpdatePgObjectMtime(retval, OBJECT_TYPE_PROC); + CommandCounterIncrement(); + if (enable_plpgsql_gsdependency_guc()) { + SetPgObjectValid(retval, OBJECT_TYPE_PROC, true); + } } } heap_close(rel, RowExclusiveLock); + CacheInvalidateFunction(retval, InvalidOid); + if (u_sess->SPI_cxt._connected == -1 && !u_sess->plsql_cxt.isCreatePkg && + !u_sess->plsql_cxt.isCreatePkgFunction) { + plpgsql_hashtable_clear_invalid_obj(); + } + if (!OidIsValid(propackageid)) { + SetCurrCompilePgObjStatus(!hasUndefined); + } else { + UpdateCurrCompilePgObjStatus(!hasUndefined); + } /* * To user-defined C_function, need rename library filename to special name, @@ -1761,14 +1885,12 @@ ObjectAddress ProcedureCreate(const char* procedureName, Oid procNamespace, Oid copyLibraryToSpecialName(absolutePath, final_file_name, libPath, function_type); } + /* Advance command counter so new tuple can be seen by validator */ + CommandCounterIncrement(); /* Verify function body */ if (OidIsValid(languageValidator)) { ArrayType* set_items = NULL; int save_nestlevel; - - /* Advance command counter so new tuple can be seen by validator */ - CommandCounterIncrement(); - /* Set per-function configuration parameters */ set_items = (ArrayType*)DatumGetPointer(proconfig); if (set_items != NULL) { /* Need a new GUC nesting level */ @@ -1782,11 +1904,40 @@ ObjectAddress ProcedureCreate(const char* procedureName, Oid procNamespace, Oid if (set_items != NULL) AtEOXact_GUC(true, save_nestlevel); } + int rc = CompileWhich(); + if ((rc == PLPGSQL_COMPILE_PACKAGE_PROC || rc == PLPGSQL_COMPILE_PACKAGE) && enable_plpgsql_gsdependency_guc()) { + MemoryContext oldCxt = MemoryContextSwitchTo(SESS_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_OPTIMIZER)); + u_sess->plsql_cxt.func_compiled_list = list_append_unique_oid(u_sess->plsql_cxt.func_compiled_list, retval); + MemoryContextSwitchTo(oldCxt); + PLpgSQL_package* pkg = u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package; + if (pkg->is_bodycompiled) { + u_sess->plsql_cxt.real_func_num++; + } + } if (user_defined_c_fun) { libraryLock.unLock(); } - + if (enable_plpgsql_gsdependency_guc() && !OidIsValid(propackageid)) { + if (u_sess->plsql_cxt.has_error) { + SetPgObjectValid(retval, OBJECT_TYPE_PROC, false); + } else { + SetPgObjectValid(retval, OBJECT_TYPE_PROC, GetCurrCompilePgObjStatus()); + } + if (!GetCurrCompilePgObjStatus()) { + ereport(WARNING, (errmodule(MOD_PLSQL), + errmsg("%s created with compilation erors.", + proIsProcedure ? "Procedure" : "Function"))); + } + } + if (enable_plpgsql_gsdependency_guc() && u_sess->plsql_cxt.has_error) { + SetPgObjectValid(retval, OBJECT_TYPE_PROC, false); + } + if (propackageid == InvalidOid) { + plpgsql_clear_created_func(ObjectIdGetDatum(retval)); + } pfree_ext(final_file_name); + pfree_ext(pkgname); + list_free_ext(name); return myself; } diff --git a/src/common/backend/catalog/pg_type.cpp b/src/common/backend/catalog/pg_type.cpp index 5dc1f2962..ef332aae6 100644 --- a/src/common/backend/catalog/pg_type.cpp +++ b/src/common/backend/catalog/pg_type.cpp @@ -37,6 +37,10 @@ #include "utils/rel.h" #include "utils/rel_gs.h" #include "utils/syscache.h" +#include "catalog/gs_package.h" +#include "parser/parse_type.h" +#include "catalog/gs_dependencies_fn.h" +#include "utils/pl_package.h" /* ---------------------------------------------------------------- * TypeShellMake @@ -196,7 +200,7 @@ ObjectAddress TypeCreate(Oid newTypeOid, const char* typname, Oid typeNamespace, const char* defaultTypeValue, /* human readable rep */ char* defaultTypeBin, /* cooked rep */ bool passedByValue, char alignment, char storage, int32 typeMod, int32 typNDims, /* Array dimensions for baseType */ - bool typeNotNull, Oid typeCollation) + bool typeNotNull, Oid typeCollation, TypeDependExtend* dependExtend) { Relation pg_type_desc; Oid typeObjectId; @@ -296,6 +300,7 @@ ObjectAddress TypeCreate(Oid newTypeOid, const char* typname, Oid typeNamespace, /* So far, we support explicitly assigned pseudo type during inplace upgrade. */ Assert(u_sess->cmd_cxt.TypeCreateType == TYPTYPE_PSEUDO || u_sess->cmd_cxt.TypeCreateType == TYPTYPE_BASE || + u_sess->cmd_cxt.TypeCreateType == TYPTYPE_UNDEFINE || u_sess->cmd_cxt.TypeCreateType == TYPTYPE_SET); typeType = u_sess->cmd_cxt.TypeCreateType; @@ -420,6 +425,11 @@ ObjectAddress TypeCreate(Oid newTypeOid, const char* typname, Oid typeNamespace, /* Update indexes */ CatalogUpdateIndexes(pg_type_desc, tup); + if (enable_plpgsql_gsdependency() && NULL != dependExtend) { + dependExtend->typType = typeType; + dependExtend->typCategory = typeCategory; + } + /* * Create dependencies. We can/must skip this in bootstrap mode. * During inplace upgrade, we insert pinned dependency for the newly added type. @@ -452,7 +462,9 @@ ObjectAddress TypeCreate(Oid newTypeOid, const char* typname, Oid typeNamespace, baseType, typeCollation, (Node*)(defaultTypeBin ? stringToNode(defaultTypeBin) : NULL), - rebuildDeps); + rebuildDeps, + typname, + dependExtend); } /* Post creation hook for new type */ @@ -462,7 +474,14 @@ ObjectAddress TypeCreate(Oid newTypeOid, const char* typname, Oid typeNamespace, * finish up */ heap_close(pg_type_desc, RowExclusiveLock); - + CommandCounterIncrement(); + if (enable_plpgsql_gsdependency_guc() && !isImplicitArray && + ((TYPTYPE_BASE == typeType && TYPCATEGORY_ARRAY == typeCategory) || + TYPTYPE_TABLEOF == typeType || typeType == TYPTYPE_ENUM)) { + if (CompileWhich() == PLPGSQL_COMPILE_NULL) { + (void)gsplsql_build_ref_type_dependency(typeObjectId); + } + } return address; } @@ -481,7 +500,7 @@ void GenerateTypeDependencies(Oid typeNamespace, Oid typeObjectId, Oid relationO char relationKind, /* ditto */ Oid owner, Oid inputProcedure, Oid outputProcedure, Oid receiveProcedure, Oid sendProcedure, Oid typmodinProcedure, Oid typmodoutProcedure, Oid analyzeProcedure, Oid elementType, bool isImplicitArray, Oid baseType, - Oid typeCollation, Node* defaultExpr, bool rebuild) + Oid typeCollation, Node* defaultExpr, bool rebuild, const char* typname, TypeDependExtend* dependExtend) { ObjectAddress myself, referenced; @@ -593,7 +612,35 @@ void GenerateTypeDependencies(Oid typeNamespace, Oid typeObjectId, Oid relationO referenced.classId = TypeRelationId; referenced.objectId = elementType; referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, isImplicitArray ? DEPENDENCY_INTERNAL : DEPENDENCY_NORMAL); + int cw = CompileWhich(); + if (enable_plpgsql_gsdependency() && NULL != dependExtend && cw != PLPGSQL_COMPILE_NULL && + ((TYPTYPE_BASE == dependExtend->typType && TYPCATEGORY_ARRAY == dependExtend->typCategory) || + TYPTYPE_TABLEOF == dependExtend->typType)) { + GsDependParamBody gsDependParamBody; + gsplsql_init_gs_depend_param_body(&gsDependParamBody); + gsDependParamBody.dependNamespaceOid = typeNamespace; + if (NULL != u_sess->plsql_cxt.curr_compile_context && + NULL != u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package) { + gsDependParamBody.dependPkgOid = + u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package->pkg_oid; + gsDependParamBody.dependPkgName = + u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package->pkg_signature; + } + char* realTypName = ParseTypeName((char*)typname, gsDependParamBody.dependPkgOid); + if (realTypName == NULL) { + gsDependParamBody.dependName = (char*)typname; + } else { + gsDependParamBody.dependName = realTypName; + } + gsDependParamBody.refPosType = GSDEPEND_REFOBJ_POS_IN_TYPE; + gsDependParamBody.type = GSDEPEND_OBJECT_TYPE_TYPE; + gsDependParamBody.dependExtend = dependExtend; + recordDependencyOn(&myself, &referenced, isImplicitArray ? DEPENDENCY_INTERNAL : DEPENDENCY_NORMAL, + &gsDependParamBody); + pfree_ext(realTypName); + } else { + recordDependencyOn(&myself, &referenced, isImplicitArray ? DEPENDENCY_INTERNAL : DEPENDENCY_NORMAL); + } } /* Normal dependency from a domain to its base type. */ @@ -775,3 +822,134 @@ bool moveArrayTypeName(Oid typeOid, const char* typname, Oid typeNamespace) return true; } + +Oid TypeNameGetOid(const char* schemaName, const char* packageName, const char* typeName) +{ + Oid pkgOid = InvalidOid; + Oid typOid = InvalidOid; + Oid namespaceOid = InvalidOid; + if (schemaName != NULL) { + namespaceOid = LookupNamespaceNoError(schemaName); + } + if (packageName != NULL) { + pkgOid = PackageNameGetOid(packageName, namespaceOid); + if (!OidIsValid(pkgOid)) { + return InvalidOid; + } + } + char* castTypeName = CastPackageTypeName(typeName, pkgOid, pkgOid != InvalidOid, true); + typOid = TypenameGetTypidExtended(castTypeName, false); + pfree_ext(castTypeName); + return typOid; +} + +char* MakeTypeNamesStrForTypeOid(Oid typOid, bool* dependUndefined, StringInfo concatName) +{ + char* ret = NULL; + char* name = NULL; + char* pkgName = NULL; + char* schemaName = NULL; + if (NULL != concatName) { + MakeTypeNamesStrForTypeOid(concatName, typOid, &schemaName, &pkgName, &name); + } else { + StringInfoData curConcatName; + initStringInfo(&curConcatName); + MakeTypeNamesStrForTypeOid(&curConcatName, typOid, &schemaName, &pkgName, &name); + ret = pstrdup(curConcatName.data); + FreeStringInfo(&curConcatName); + } + if (NULL != dependUndefined) { + if (UNDEFINEDOID == typOid) { // UNDEFINEDOID + *dependUndefined = true; + } else if (gsplsql_check_type_depend_undefined(schemaName, pkgName, name)) { + *dependUndefined = true; + } + } + pfree_ext(schemaName); + pfree_ext(pkgName); + pfree_ext(name); + return ret; +} + +void MakeTypeNamesStrForTypeOid(StringInfo concatName, Oid typOid, + char** schemaName, char** pkgName, char** name) +{ + char* curTypeName = NULL; + char* curPkgName = NULL; + char* curSchemaName = NULL; + + curSchemaName = get_typenamespace(typOid); + appendStringInfoString(concatName, curSchemaName == NULL ? "" : curSchemaName); + if (NULL != schemaName) { + *schemaName = curSchemaName; + } else { + pfree_ext(curSchemaName); + } + + Oid pkgOid = GetTypePackageOid(typOid); + if (OidIsValid(pkgOid)) { + appendStringInfoString(concatName, "."); + curPkgName = GetPackageName(pkgOid); + appendStringInfoString(concatName, curPkgName == NULL ? "" : curPkgName); + if (NULL != pkgName) { + *pkgName = curPkgName; + } else { + pfree_ext(curPkgName); + } + } + appendStringInfoString(concatName, "."); + curTypeName = get_typename(typOid); + if (NULL != curTypeName && OidIsValid(pkgOid)) { + char* realName = ParseTypeName(curTypeName, pkgOid); + if (NULL != realName) { + pfree_ext(curTypeName); + curTypeName = realName; + } + } + appendStringInfoString(concatName, curTypeName == NULL ? "" : curTypeName); + if (NULL != name) { + *name = curTypeName; + } else { + pfree_ext(curTypeName); + } +} + +Oid GetTypePackageOid(Oid typoid) +{ + ObjectAddress objectAddress; + objectAddress.classId = TypeRelationId; + objectAddress.objectId = typoid; + objectAddress.objectSubId = 0; + Oid pkgOid = get_object_package(&objectAddress);// debug todo + if (InvalidOid == pkgOid && type_is_array(typoid)) { + objectAddress.objectId = get_element_type(typoid); + pkgOid = get_object_package(&objectAddress); + } + return pkgOid; +} + +void InstanceTypeNameDependExtend(TypeDependExtend** dependExtend) +{ + if (NULL != dependExtend && NULL == (*dependExtend)) { + (*dependExtend) = (TypeDependExtend*)palloc(sizeof(TypeDependExtend)); + (*dependExtend)->typeOid = InvalidOid; + (*dependExtend)->undefDependObjOid = InvalidOid; + (*dependExtend)->dependUndefined = false; + (*dependExtend)->schemaName = NULL; + (*dependExtend)->packageName = NULL; + (*dependExtend)->objectName = NULL; + (*dependExtend)->typType = TYPTYPE_INVALID; + (*dependExtend)->typCategory = TYPCATEGORY_INVALID; + } +} + +void ReleaseTypeNameDependExtend(TypeDependExtend** dependExtend) +{ + if (NULL != dependExtend && NULL != (*dependExtend)) { + pfree_ext((*dependExtend)->schemaName); + pfree_ext((*dependExtend)->packageName); + pfree_ext((*dependExtend)->objectName); + pfree_ext(*dependExtend); + *dependExtend = NULL; + } +} diff --git a/src/common/backend/nodes/makefuncs.cpp b/src/common/backend/nodes/makefuncs.cpp index 9e9167f0c..ccd789e06 100644 --- a/src/common/backend/nodes/makefuncs.cpp +++ b/src/common/backend/nodes/makefuncs.cpp @@ -498,13 +498,14 @@ TypeName* makeTypeNameFromNameList(List* names) * makeTypeNameFromOid - * build a TypeName node to represent a type already known by OID/typmod. */ -TypeName* makeTypeNameFromOid(Oid typeOid, int32 typmod) +TypeName* makeTypeNameFromOid(Oid typeOid, int32 typmod, TypeDependExtend* dependExtend) { TypeName* n = makeNode(TypeName); n->typeOid = typeOid; n->typemod = typmod; n->location = -1; + n->dependExtend = dependExtend; n->charset = PG_INVALID_ENCODING; return n; } diff --git a/src/common/backend/nodes/nodes.cpp b/src/common/backend/nodes/nodes.cpp index 0603bfd82..4d1d8b7f1 100755 --- a/src/common/backend/nodes/nodes.cpp +++ b/src/common/backend/nodes/nodes.cpp @@ -341,6 +341,11 @@ static const TagStr g_tagStrArr[] = {{T_Invalid, "Invalid"}, {T_CreatePackageBodyStmt, "CreatePackageBodyStmt"}, {T_AddTableIntoCBIState, "AddTableIntoCBIState"}, {T_AlterFunctionStmt, "AlterFunctionStmt"}, + {T_CompileStmt, "CompileStmt"}, + {T_DependenciesUndefined, "DependenciesUndefined"}, + {T_DependenciesVariable, "DependenciesVariable"}, + {T_DependenciesType, "DependenciesType"}, + {T_DependenciesProchead, "DependenciesProchead"}, {T_DoStmt, "DoStmt"}, {T_RenameStmt, "RenameStmt"}, {T_RuleStmt, "RuleStmt"}, diff --git a/src/common/backend/nodes/outfuncs.cpp b/src/common/backend/nodes/outfuncs.cpp index 568599c6a..b37dfa1c2 100755 --- a/src/common/backend/nodes/outfuncs.cpp +++ b/src/common/backend/nodes/outfuncs.cpp @@ -3589,6 +3589,39 @@ static void _outIndexOptInfo(StringInfo str, IndexOptInfo* node) } } +static void _outDependenciesProchead(StringInfo str, DependenciesProchead* node) +{ + WRITE_NODE_TYPE("DependenciesProchead"); + WRITE_BOOL_FIELD(undefined); + WRITE_STRING_FIELD(proName); + WRITE_STRING_FIELD(proArgSrc); + WRITE_STRING_FIELD(funcHeadSrc); +} + +static void _outDependenciesType(StringInfo str, DependenciesType* node) +{ + WRITE_NODE_TYPE("DependenciesType"); + WRITE_CHAR_FIELD(typType); + WRITE_CHAR_FIELD(typCategory); + WRITE_STRING_FIELD(attrInfo); + WRITE_BOOL_FIELD(isRel); + WRITE_STRING_FIELD(elemTypName); + WRITE_STRING_FIELD(idxByTypName); +} + +static void _outDependenciesVariable(StringInfo str, DependenciesVariable* node) +{ + WRITE_NODE_TYPE("DependenciesVariable"); + WRITE_STRING_FIELD(typName); + WRITE_INT_FIELD(typMod); + WRITE_STRING_FIELD(extraInfo); +} + +static void _outDependenciesUndefined(StringInfo str, DependenciesUndefined* node) +{ + WRITE_NODE_TYPE("DependenciesUndefined"); +} + static void _outEquivalenceClass(StringInfo str, EquivalenceClass* node) { /* @@ -6585,6 +6618,18 @@ static void _outNode(StringInfo str, const void* obj) case T_IndexOptInfo: _outIndexOptInfo(str, (IndexOptInfo*)obj); break; + case T_DependenciesProchead: + _outDependenciesProchead(str, (DependenciesProchead*)obj); + break; + case T_DependenciesUndefined: + _outDependenciesUndefined(str, (DependenciesUndefined*)obj); + break; + case T_DependenciesType: + _outDependenciesType(str, (DependenciesType*)obj); + break; + case T_DependenciesVariable: + _outDependenciesVariable(str, (DependenciesVariable*)obj); + break; case T_EquivalenceClass: _outEquivalenceClass(str, (EquivalenceClass*)obj); break; diff --git a/src/common/backend/nodes/readfuncs.cpp b/src/common/backend/nodes/readfuncs.cpp index f3842a92f..c4c93aa19 100755 --- a/src/common/backend/nodes/readfuncs.cpp +++ b/src/common/backend/nodes/readfuncs.cpp @@ -6289,6 +6289,32 @@ static UserVar* _readUserVar() READ_DONE(); } +static DependenciesProchead* _readDependenciesProchead() +{ + READ_LOCALS(DependenciesProchead); + + READ_BOOL_FIELD(undefined); + READ_STRING_FIELD(proName); + READ_STRING_FIELD(proArgSrc); + READ_STRING_FIELD(funcHeadSrc); + + READ_DONE(); +} + +static DependenciesType* _readDependenciesType() +{ + READ_LOCALS(DependenciesType); + + READ_CHAR_FIELD(typType); + READ_CHAR_FIELD(typCategory); + READ_STRING_FIELD(attrInfo); + READ_BOOL_FIELD(isRel); + READ_STRING_FIELD(elemTypName); + READ_STRING_FIELD(idxByTypName); + + READ_DONE(); +} + /* * parseNodeString * @@ -6780,7 +6806,11 @@ Node* parseNodeString(void) return_value = _readCharsetcollateOptions(); } else if (MATCH("CHARSET", 7)) { return_value = _readCharsetClause(); - } else { + } else if (MATCH("DependenciesProchead", 20)) { + return_value = _readDependenciesProchead(); + } else if (MATCH("DependenciesType", 16)) { + return_value = _readDependenciesType(); + } else { ereport(ERROR, (errcode(ERRCODE_UNRECOGNIZED_NODE_TYPE), errmsg("parseNodeString(): badly formatted node string \"%s\"...", token))); diff --git a/src/common/backend/parser/gram.y b/src/common/backend/parser/gram.y index 3774cc94f..9f9d232e6 100644 --- a/src/common/backend/parser/gram.y +++ b/src/common/backend/parser/gram.y @@ -59,6 +59,7 @@ #include "catalog/pg_proc.h" #include "catalog/gs_package.h" #include "catalog/pg_trigger.h" +#include "catalog/pg_type_fn.h" #include "commands/defrem.h" #include "commands/trigger.h" #ifdef ENABLE_MULTIPLE_NODES @@ -248,6 +249,7 @@ static void ParseUpdateMultiSet(List *set_target_list, SelectStmt *stmt, core_yy static char *GetTargetFuncArgTypeName(char *typeString, TypeName* t); static char *FormatFuncArgType(core_yyscan_t yyscanner, char *argsString, List* parameters); static char *ParseFunctionArgSrc(core_yyscan_t yyscanner); +static char *ParseFuncHeadSrc(core_yyscan_t yyscanner, bool isFunction = true); static void parameter_check_execute_direct(const char* query); static Node *make_node_from_scanbuf(int start_pos, int end_pos, core_yyscan_t yyscanner); static int64 SequenceStrGetInt64(const char *str); @@ -370,7 +372,7 @@ static void setDelimiterName(core_yyscan_t yyscanner, char*input, VariableSetStm DropForeignServerStmt DropUserMappingStmt ExplainStmt ExecDirectStmt FetchStmt GetDiagStmt GrantStmt GrantRoleStmt GrantDbStmt IndexStmt InsertStmt ListenStmt LoadStmt LockStmt NotifyStmt ExplainableStmt PreparableStmt - CreateFunctionStmt CreateEventStmt CreateProcedureStmt CreatePackageStmt CreatePackageBodyStmt AlterFunctionStmt AlterProcedureStmt ReindexStmt RemoveAggrStmt + CreateFunctionStmt CreateEventStmt CreateProcedureStmt CreatePackageStmt CreatePackageBodyStmt AlterFunctionStmt CompileStmt AlterProcedureStmt ReindexStmt RemoveAggrStmt RemoveFuncStmt RemoveOperStmt RemovePackageStmt RenameStmt RevokeStmt RevokeRoleStmt RevokeDbStmt RuleActionStmt RuleActionStmtOrEmpty RuleStmt SecLabelStmt SelectStmt TimeCapsuleStmt TransactionStmt TruncateStmt CallFuncStmt @@ -434,7 +436,7 @@ static void setDelimiterName(core_yyscan_t yyscanner, char*input, VariableSetStm start_opt preserve_opt rename_opt status_opt comments_opt action_opt end_opt definer_name_opt -%type opt_lock lock_type cast_context opt_wait +%type opt_lock lock_type cast_context opt_wait compile_pkg_opt %type vacuum_option_list vacuum_option_elem opt_verify_options %type opt_check opt_force opt_or_replace opt_grant_grant_option opt_grant_admin_option @@ -864,7 +866,7 @@ static void setDelimiterName(core_yyscan_t yyscanner, char*input, VariableSetStm CACHE CALL CALLED CANCELABLE CASCADE CASCADED CASE CAST CATALOG_P CATALOG_NAME CHAIN CHANGE CHAR_P CHARACTER CHARACTERISTICS CHARACTERSET CHARSET CHECK CHECKPOINT CLASS CLASS_ORIGIN CLEAN CLIENT CLIENT_MASTER_KEY CLIENT_MASTER_KEYS CLOB CLOSE CLUSTER COALESCE COLLATE COLLATION COLUMN COLUMN_ENCRYPTION_KEY COLUMN_ENCRYPTION_KEYS COLUMN_NAME COLUMNS COMMENT COMMENTS COMMIT - COMMITTED COMPACT COMPATIBLE_ILLEGAL_CHARS COMPLETE COMPLETION COMPRESS CONCURRENTLY CONDITION CONFIGURATION CONNECTION CONSISTENT CONSTANT CONSTRAINT CONSTRAINT_CATALOG CONSTRAINT_NAME CONSTRAINT_SCHEMA CONSTRAINTS + COMMITTED COMPACT COMPATIBLE_ILLEGAL_CHARS COMPILE COMPLETE COMPLETION COMPRESS CONCURRENTLY CONDITION CONFIGURATION CONNECTION CONSISTENT CONSTANT CONSTRAINT CONSTRAINT_CATALOG CONSTRAINT_NAME CONSTRAINT_SCHEMA CONSTRAINTS CONTENT_P CONTINUE_P CONTVIEW CONVERSION_P CONVERT_P CONNECT COORDINATOR COORDINATORS COPY COST CREATE CROSS CSN CSV CUBE CURRENT_P CURRENT_CATALOG CURRENT_DATE CURRENT_ROLE CURRENT_SCHEMA @@ -931,7 +933,7 @@ static void setDelimiterName(core_yyscan_t yyscanner, char*input, VariableSetStm SAMPLE SAVEPOINT SCHEDULE SCHEMA SCHEMA_NAME SCROLL SEARCH SECOND_P SECURITY SELECT SEPARATOR_P SEQUENCE SEQUENCES SERIALIZABLE SERVER SESSION SESSION_USER SET SETS SETOF SHARE SHIPPABLE SHOW SHUTDOWN SIBLINGS - SIMILAR SIMPLE SIZE SKIP SLAVE SLICE SMALLDATETIME SMALLDATETIME_FORMAT_P SMALLINT SNAPSHOT SOME SOURCE_P SPACE SPILL SPLIT STABLE STACKED_P STANDALONE_P START STARTS STARTWITH + SIMILAR SIMPLE SIZE SKIP SLAVE SLICE SMALLDATETIME SMALLDATETIME_FORMAT_P SMALLINT SNAPSHOT SOME SOURCE_P SPACE SPECIFICATION SPILL SPLIT STABLE STACKED_P STANDALONE_P START STARTS STARTWITH STATEMENT STATEMENT_ID STATISTICS STDIN STDOUT STORAGE STORE_P STORED STRATIFY STREAM STRICT_P STRIP_P SUBCLASS_ORIGIN SUBPARTITION SUBPARTITIONS SUBSCRIPTION SUBSTRING SYMMETRIC SYNONYM SYSDATE SYSID SYSTEM_P SYS_REFCURSOR STARTING SQL_P @@ -1199,6 +1201,7 @@ stmt : | ClosePortalStmt | ClusterStmt | CommentStmt + | CompileStmt | ConstraintsSetStmt | CopyStmt | CreateAsStmt @@ -15001,6 +15004,7 @@ CreateFunctionStmt: CREATE opt_or_replace definer_user FUNCTION func_name_opt_arg proc_args RETURNS func_return createfunc_opt_list opt_definition { + set_function_style_pg(); CreateFunctionStmt *n = makeNode(CreateFunctionStmt); n->isOraStyle = false; n->isPrivate = false; @@ -15020,6 +15024,7 @@ CreateFunctionStmt: | CREATE opt_or_replace definer_user FUNCTION func_name_opt_arg proc_args RETURNS TABLE '(' table_func_column_list ')' createfunc_opt_list opt_definition { + set_function_style_pg(); CreateFunctionStmt *n = makeNode(CreateFunctionStmt); n->isOraStyle = false; n->isPrivate = false; @@ -15040,6 +15045,7 @@ CreateFunctionStmt: | CREATE opt_or_replace definer_user FUNCTION func_name_opt_arg proc_args createfunc_opt_list opt_definition { + set_function_style_pg(); CreateFunctionStmt *n = makeNode(CreateFunctionStmt); n->isOraStyle = false; n->isPrivate = false; @@ -15062,6 +15068,10 @@ CreateFunctionStmt: u_sess->parser_cxt.eaten_begin = false; pg_yyget_extra(yyscanner)->core_yy_extra.include_ora_comment = true; u_sess->parser_cxt.isCreateFuncOrProc = true; + if (set_is_create_plsql_type()) { + set_create_plsql_type_start(); + set_function_style_a(); + } } subprogram_body { int rc = 0; @@ -15081,6 +15091,9 @@ CreateFunctionStmt: n->funcname = $5; n->parameters = $6; n->inputHeaderSrc = FormatFuncArgType(yyscanner, funSource->headerSrc, n->parameters); + if (enable_plpgsql_gsdependency_guc()) { + n->funcHeadSrc = ParseFuncHeadSrc(yyscanner); + } n->returnType = $8; n->options = $9; n->options = lappend(n->options, makeDefElem("as", @@ -15937,6 +15950,10 @@ CreateProcedureStmt: u_sess->parser_cxt.eaten_begin = false; pg_yyget_extra(yyscanner)->core_yy_extra.include_ora_comment = true; u_sess->parser_cxt.isCreateFuncOrProc = true; + if (set_is_create_plsql_type()) { + set_create_plsql_type_start(); + set_function_style_a(); + } } subprogram_body { int rc = 0; @@ -15959,6 +15976,9 @@ CreateProcedureStmt: n->funcname = $5; n->parameters = $6; n->inputHeaderSrc = FormatFuncArgType(yyscanner, funSource->headerSrc, n->parameters); + if (enable_plpgsql_gsdependency_guc()) { + n->funcHeadSrc = ParseFuncHeadSrc(yyscanner, false); + } n->returnType = NULL; n->isProcedure = true; if (0 == count) @@ -15980,9 +16000,11 @@ CreateProcedureStmt: ; CreatePackageStmt: - CREATE opt_or_replace PACKAGE pkg_name invoker_rights as_is {pg_yyget_extra(yyscanner)->core_yy_extra.include_ora_comment = true;} + CREATE opt_or_replace PACKAGE pkg_name invoker_rights as_is {pg_yyget_extra(yyscanner)->core_yy_extra.include_ora_comment = true;set_function_style_a();} { - u_sess->plsql_cxt.package_as_line = GetLineNumber(t_thrd.postgres_cxt.debug_query_string, @6); + set_create_plsql_type_start(); + u_sess->plsql_cxt.need_create_depend = true; + u_sess->plsql_cxt.package_as_line = GetLineNumber(t_thrd.postgres_cxt.debug_query_string, @6); CreatePackageStmt *n = makeNode(CreatePackageStmt); char *pkgNameBegin = NULL; char *pkgNameEnd = NULL; @@ -16060,6 +16082,7 @@ CreatePackageStmt: } else { parser_yyerror("package spec is not ended correctly"); } + u_sess->plsql_cxt.isCreatePkg = false; } tok = YYLEX; } @@ -16397,8 +16420,10 @@ pkg_body_subprogram: { } ; CreatePackageBodyStmt: - CREATE opt_or_replace PACKAGE BODY_P pkg_name as_is {pg_yyget_extra(yyscanner)->core_yy_extra.include_ora_comment = true;} pkg_body_subprogram + CREATE opt_or_replace PACKAGE BODY_P pkg_name as_is {pg_yyget_extra(yyscanner)->core_yy_extra.include_ora_comment = true;set_function_style_a();} pkg_body_subprogram { + set_create_plsql_type_start(); + u_sess->plsql_cxt.need_create_depend = true; char *pkgNameBegin = NULL; char *pkgNameEnd = NULL; char *pkgName = NULL; @@ -16590,7 +16615,11 @@ param_name: type_function_name ; func_return: - func_type + func_type { + if (enable_plpgsql_gsdependency_guc()) { + pg_yyget_extra(yyscanner)->core_yy_extra.return_pos_end = yylloc; + } + } { /* We can catch over-specified results here if we want to, * but for now better to silently swallow typmod, etc. @@ -16598,7 +16627,11 @@ func_return: */ $$ = $1; } - | func_type DETERMINISTIC + | func_type { + if (enable_plpgsql_gsdependency_guc()) { + pg_yyget_extra(yyscanner)->core_yy_extra.return_pos_end = yylloc; + } + } DETERMINISTIC { $$ = $1; } @@ -17099,6 +17132,69 @@ opt_restrict: | /* EMPTY */ ; +compile_pkg_opt: + BODY_P {$$ = COMPILE_PKG_BODY;} + | PACKAGE {$$ = COMPILE_PACKAGE;} + | SPECIFICATION {$$ = COMPILE_PKG_SPECIFICATION;} + | /* EMPTY */ {$$ = COMPILE_PACKAGE;} + ; +CompileStmt: + ALTER PROCEDURE function_with_argtypes COMPILE + { + u_sess->plsql_cxt.during_compile = true; + CompileStmt *n = makeNode(CompileStmt); + if (enable_plpgsql_gsdependency_guc()) { + n->objName = ((FuncWithArgs*)$3)->funcname; + n->funcArgs = ((FuncWithArgs*)$3)->funcargs; + n->compileItem = COMPILE_PROCEDURE; + } + $$ = (Node*)n; + } + | ALTER PROCEDURE func_name_opt_arg COMPILE + { + u_sess->plsql_cxt.during_compile = true; + CompileStmt *n = makeNode(CompileStmt); + if (enable_plpgsql_gsdependency_guc()) { + n->objName = $3; + n->funcArgs = NULL; + n->compileItem = COMPILE_PROCEDURE; + } + $$ = (Node*)n; + } + | ALTER FUNCTION function_with_argtypes COMPILE + { + u_sess->plsql_cxt.during_compile = true; + CompileStmt *n = makeNode(CompileStmt); + if (enable_plpgsql_gsdependency_guc()) { + n->objName = ((FuncWithArgs*)$3)->funcname; + n->funcArgs = ((FuncWithArgs*)$3)->funcargs; + n->compileItem = COMPILE_FUNCTION; + } + $$ = (Node*)n; + } + | ALTER FUNCTION func_name_opt_arg COMPILE + { + u_sess->plsql_cxt.during_compile = true; + CompileStmt *n = makeNode(CompileStmt); + if (enable_plpgsql_gsdependency_guc()) { + n->objName = $3; + n->funcArgs = NULL; + n->compileItem = COMPILE_FUNCTION; + } + $$ = (Node*)n; + } + | ALTER PACKAGE pkg_name COMPILE compile_pkg_opt + { + u_sess->plsql_cxt.during_compile = true; + CompileStmt *n = makeNode(CompileStmt); + if (enable_plpgsql_gsdependency_guc()) { + n->objName = $3; + n->funcArgs = NULL; + n->compileItem = (CompileEntry)$5; + } + $$ = (Node*)n; + } + ; /***************************************************************************** * @@ -28944,6 +29040,7 @@ unreserved_keyword: | COMMITTED | COMPATIBLE_ILLEGAL_CHARS | COMPLETE + | COMPILE | COMPLETION | COMPRESS | CONDITION @@ -29285,6 +29382,7 @@ unreserved_keyword: | SNAPSHOT | SOURCE_P | SPACE + | SPECIFICATION | SPILL | SPLIT | SQL_P @@ -31360,7 +31458,12 @@ static char *GetTargetFuncArgTypeName(char *typeString, TypeName* t) { Type typtup; Oid toid; - typtup = LookupTypeName(NULL, t, NULL, false); + TypeDependExtend* dependExtend = NULL; + if (enable_plpgsql_gsdependency()) { + InstanceTypeNameDependExtend(&dependExtend); + } + typtup = LookupTypeName(NULL, t, NULL, false, dependExtend); + pfree_ext(dependExtend); if (typtup) { toid = typeTypeId(typtup); @@ -31424,9 +31527,10 @@ static char *FormatFuncArgType(core_yyscan_t yyscanner, char *argsString, List* pfree(argsString); proc_header_len = proc_header_len; - yyextra->core_yy_extra.func_param_begin = 0; - yyextra->core_yy_extra.func_param_end = 0; - + if (!enable_plpgsql_gsdependency_guc()) { + yyextra->core_yy_extra.func_param_begin = 0; + yyextra->core_yy_extra.func_param_end = 0; + } return buf.data; } @@ -31459,6 +31563,32 @@ static char *ParseFunctionArgSrc(core_yyscan_t yyscanner) return proc_header_str; } +static char *ParseFuncHeadSrc(core_yyscan_t yyscanner, bool is_function) +{ + base_yy_extra_type *yyextra = pg_yyget_extra(yyscanner); + int proc_header_src_end = 0; + char *proc_header_info = NULL; + if (is_function) { + proc_header_src_end = yyextra->core_yy_extra.return_pos_end - 1; + } else { + proc_header_src_end = yyextra->core_yy_extra.func_param_end + 1; + } + if (proc_header_src_end == 1) { + return proc_header_info; + } + yyextra->core_yy_extra.return_pos_end = 0; + yyextra->core_yy_extra.func_param_begin = 0; + yyextra->core_yy_extra.func_param_end = 0; + if (proc_header_src_end > 0) { + proc_header_info = (char*)palloc0(proc_header_src_end + 1); + errno_t rc = EOK; + rc = strncpy_s(proc_header_info, (proc_header_src_end + 1), yyextra->core_yy_extra.scanbuf, proc_header_src_end); + securec_check(rc, "\0", "\0"); + proc_header_info[proc_header_src_end] = '\0'; + } + return proc_header_info; +} + static void parameter_check_execute_direct(const char* query) { #ifndef ENABLE_MULTIPLE_NODES diff --git a/src/common/backend/parser/parse_type.cpp b/src/common/backend/parser/parse_type.cpp index cd9673a34..f0d1c02ba 100644 --- a/src/common/backend/parser/parse_type.cpp +++ b/src/common/backend/parser/parse_type.cpp @@ -39,6 +39,9 @@ #include "utils/pl_package.h" #include "catalog/gs_collation.h" #include "parser/parse_utilcmd.h" +#include "catalog/pg_object.h" +#include "catalog/gs_dependencies_fn.h" +#include "catalog/pg_type_fn.h" static int32 typenameTypeMod(ParseState* pstate, const TypeName* typname, Type typ); @@ -71,13 +74,35 @@ Oid LookupPctTypeInPackage(RangeVar* rel, Oid pkgOid, const char* field) } } +Type LookupTypeNameSupportUndef(ParseState *pstate, const TypeName *typeName, int32 *typmod_p, bool print_notice) +{ + Type typtup = NULL; + CreatePlsqlType oldCreatePlsqlType = u_sess->plsql_cxt.createPlsqlType; + PG_TRY(); + { + set_create_plsql_type_not_check_nsp_oid(); + TypeDependExtend* dependExt = NULL; + InstanceTypeNameDependExtend(&dependExt); + typtup = LookupTypeName(pstate, typeName, typmod_p, print_notice, dependExt); + pfree_ext(dependExt); + } + PG_CATCH(); + { + set_create_plsql_type(oldCreatePlsqlType); + PG_RE_THROW(); + } + PG_END_TRY(); + set_create_plsql_type(oldCreatePlsqlType); + return typtup; +} + /* * LookupTypeName * Wrapper for typical case. */ -Type LookupTypeName(ParseState *pstate, const TypeName *typeName, int32 *typmod_p, bool print_notice) +Type LookupTypeName(ParseState *pstate, const TypeName *typeName, int32 *typmod_p, bool print_notice, TypeDependExtend* dependExtend) { - return LookupTypeNameExtended(pstate, typeName, typmod_p, true, print_notice); + return LookupTypeNameExtended(pstate, typeName, typmod_p, true, print_notice, dependExtend); } /* @@ -108,14 +133,16 @@ Type LookupTypeName(ParseState *pstate, const TypeName *typeName, int32 *typmod_ * pstate is only used for error location info, and may be NULL. */ Type LookupTypeNameExtended(ParseState* pstate, const TypeName* typname, int32* typmod_p, bool temp_ok, - bool print_notice) + bool print_notice, TypeDependExtend* dependExtend) { Oid typoid = InvalidOid; - HeapTuple tup; + HeapTuple tup = NULL; int32 typmod = -1; Oid pkgOid = InvalidOid; bool notPkgType = false; - + char* schemaname = NULL; + char* typeName = NULL; + char* pkgName = NULL; if (typname->names == NIL) { /* We have the OID already if it's an internally generated TypeName */ typoid = typname->typeOid; @@ -128,10 +155,12 @@ Type LookupTypeNameExtended(ParseState* pstate, const TypeName* typname, int32* char* pkgName = NULL; char* schemaName = NULL; /* deconstruct the name list */ + int typTupStatus = InvalidTypeTup; switch (list_length(typname->names)) { case 1: tup = getPLpgsqlVarTypeTup(strVal(linitial(typname->names))); - if (HeapTupleIsValid(tup)) { + typTupStatus = GetTypeTupStatus(tup); + if (typTupStatus == NormalTypeTup) { return tup; } ereport(ERROR, @@ -141,16 +170,18 @@ Type LookupTypeNameExtended(ParseState* pstate, const TypeName* typname, int32* parser_errposition(pstate, typname->location))); break; case 2: - tup = FindPkgVariableType(pstate, typname, typmod_p); - if (HeapTupleIsValid(tup)) { + tup = FindPkgVariableType(pstate, typname, typmod_p, dependExtend); + typTupStatus = GetTypeTupStatus(tup); + if (typTupStatus == NormalTypeTup) { return (Type)tup; } rel->relname = strVal(linitial(typname->names)); field = strVal(lsecond(typname->names)); break; case 3: - tup = FindPkgVariableType(pstate, typname, typmod_p); - if (HeapTupleIsValid(tup)) { + tup = FindPkgVariableType(pstate, typname, typmod_p, dependExtend); + typTupStatus = GetTypeTupStatus(tup); + if (typTupStatus == NormalTypeTup) { return (Type)tup; } pkgName = strVal(linitial(typname->names)); @@ -164,8 +195,9 @@ Type LookupTypeNameExtended(ParseState* pstate, const TypeName* typname, int32* field = strVal(lthird(typname->names)); break; case 4: - tup = FindPkgVariableType(pstate, typname, typmod_p); - if (HeapTupleIsValid(tup)) { + tup = FindPkgVariableType(pstate, typname, typmod_p, dependExtend); + typTupStatus = GetTypeTupStatus(tup); + if (typTupStatus == NormalTypeTup) { return (Type)tup; } pkgName = strVal(lsecond(typname->names)); @@ -203,14 +235,38 @@ Type LookupTypeNameExtended(ParseState* pstate, const TypeName* typname, int32* u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package->pkg_oid, field); } if (!OidIsValid(relid)) { - relid = RangeVarGetRelidExtended(rel, NoLock, false, false, false, true, NULL, NULL, NULL, NULL); + if (enable_plpgsql_undefined()) { + relid = RangeVarGetRelidExtended(rel, NoLock, true, false, false, true, NULL, NULL, NULL, NULL); + if (!OidIsValid(relid) && HeapTupleIsValid(tup)) { + if (NULL != dependExtend) { + dependExtend->dependUndefined = true; + } + if (GetCurrCompilePgObjStatus() && + u_sess->plsql_cxt.functionStyleType != FUNCTION_STYLE_TYPE_REFRESH_HEAD) { + ereport(WARNING, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("TYPE %s does not exist in type.", rel->relname))); + } + InvalidateCurrCompilePgObj(); + return tup; + } + } else { + relid = RangeVarGetRelidExtended(rel, NoLock, false, false, false, true, NULL, NULL, NULL, NULL); + } } attnum = get_attnum(relid, field); if (attnum == InvalidAttrNumber) { - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_COLUMN), - errmsg("column \"%s\" of relation \"%s\" does not exist", field, rel->relname), - parser_errposition(pstate, typname->location))); + if (enable_plpgsql_undefined()) { + if (NULL != dependExtend) { + dependExtend->dependUndefined = true; + } + return SearchSysCache1(TYPEOID, ObjectIdGetDatum(UNDEFINEDOID)); + } else { + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("column \"%s\" of relation \"%s\" does not exist", field, rel->relname), + parser_errposition(pstate, typname->location))); + } } typoid = get_atttype(relid, attnum); @@ -220,6 +276,16 @@ Type LookupTypeNameExtended(ParseState* pstate, const TypeName* typname, int32* typmod = get_atttypmod(relid, attnum); } + if (enable_plpgsql_undefined() && UndefineTypeTup == typTupStatus && NULL != dependExtend) { + gsplsql_delete_unrefer_depend_obj_oid(dependExtend->undefDependObjOid, false); + dependExtend->undefDependObjOid = InvalidOid; + ReleaseSysCache(tup); + tup = NULL; + } + if (enable_plpgsql_gsdependency() && NULL != dependExtend) { + dependExtend->typeOid = get_rel_type_id(relid); + } + /* If an array reference, return the array type instead */ if (typname->arrayBounds != NIL) { typoid = get_array_type(typoid); @@ -235,10 +301,6 @@ Type LookupTypeNameExtended(ParseState* pstate, const TypeName* typname, int32* } } else { /* Normal reference to a type name */ - char* schemaname = NULL; - char* typeName = NULL; - char* pkgName = NULL; - /* Handle %ROWTYPE reference to type of an existing table. */ if (typname->pct_rowtype) { RangeVar* relvar = NULL; @@ -266,14 +328,25 @@ Type LookupTypeNameExtended(ParseState* pstate, const TypeName* typname, int32* } Oid class_oid = RangeVarGetRelidExtended(relvar, NoLock, true, false, false, true, NULL, NULL); if (!OidIsValid(class_oid)) { - pfree_ext(relvar); /* if case: cursor%rowtype */ tup = getCursorTypeTup(strVal(linitial(typname->names))); if (HeapTupleIsValid(tup)) { return (Type)tup; } - - ereport(ERROR, + if (enable_plpgsql_undefined() && NULL != dependExtend) { + Oid undefRefObjOid = gsplsql_try_build_exist_schema_undef_table(relvar); + if (OidIsValid(undefRefObjOid)) { + dependExtend->undefDependObjOid = undefRefObjOid; + dependExtend->dependUndefined = true; + InvalidateCurrCompilePgObj(); + tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(UNDEFINEDOID)); + if (typmod_p != NULL) { + *typmod_p = -1; + } + } + } + pfree_ext(relvar); + ereport(NULL != tup ? WARNING : ERROR, (errmodule(MOD_PARSER), errcode(ERRCODE_UNDEFINED_TABLE), errmsg("relation does not exist when parse word."), @@ -281,6 +354,7 @@ Type LookupTypeNameExtended(ParseState* pstate, const TypeName* typname, int32* NameListToString(typname->names)), errcause("incorrectly referencing relation"), erraction("check the relation name for %%ROWTYPE"))); + return (Type)tup; } char relkind = get_rel_relkind(class_oid); /* onyl table is allowed for %ROWTYPE. */ @@ -328,13 +402,23 @@ Type LookupTypeNameExtended(ParseState* pstate, const TypeName* typname, int32* /* find type in current packgae first */ typoid = LookupTypeInPackage(typname->names, typeName); } - if (isPkgType) { - typoid = LookupTypeInPackage(typname->names, typeName, pkgOid); - } - if (!OidIsValid(typoid)) { - /* Unqualified type name, so search the search path */ - typoid = TypenameGetTypidExtended(typeName, temp_ok); - notPkgType = true; /* should also track type dependency, fix when refactoring */ + if (enable_plpgsql_gsdependency_guc()) { + if (isPkgType) { + typoid = LookupTypeInPackage(typname->names, typeName, pkgOid); + } else if (!OidIsValid(typoid)) { + /* Unqualified type name, so search the search path */ + typoid = TypenameGetTypidExtended(typeName, temp_ok); + notPkgType = true; /* should also track type dependency, fix when refactoring */ + } + } else { + if (isPkgType) { + typoid = LookupTypeInPackage(typname->names, typeName, pkgOid); + } + if (!OidIsValid(typoid)) { + /* Unqualified type name, so search the search path */ + typoid = TypenameGetTypidExtended(typeName, temp_ok); + notPkgType = true; /* should also track type dependency, fix when refactoring */ + } } } @@ -355,29 +439,58 @@ Type LookupTypeNameExtended(ParseState* pstate, const TypeName* typname, int32* if (typmod_p != NULL) { *typmod_p = -1; } - return NULL; - } + if (enable_plpgsql_undefined() && NULL != dependExtend) { + if (NULL != schemaname && NULL == pkgName && !OidIsValid(get_namespace_oid(schemaname, true))) { + pkgName = schemaname; + schemaname = NULL; + } + GsDependObjDesc objDesc; + objDesc.schemaName = schemaname; + char* activeSchemaName = NULL; + if (schemaname == NULL) { + activeSchemaName = get_namespace_name(get_compiled_object_nspoid()); + objDesc.schemaName = activeSchemaName; + } + objDesc.packageName = pkgName; + objDesc.name = typeName; + objDesc.type = GSDEPEND_OBJECT_TYPE_TYPE; + if (u_sess->plsql_cxt.functionStyleType != FUNCTION_STYLE_TYPE_REFRESH_HEAD) { + dependExtend->undefDependObjOid = gsplsql_flush_undef_ref_depend_obj(&objDesc); + } else { + dependExtend->undefDependObjOid = InvalidOid; + } + dependExtend->dependUndefined = true; + pfree_ext(activeSchemaName); + if (GetCurrCompilePgObjStatus() && + u_sess->plsql_cxt.functionStyleType != FUNCTION_STYLE_TYPE_REFRESH_HEAD) { + ereport(WARNING, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("Type %s does not exist.", typeName))); + } + InvalidateCurrCompilePgObj(); + tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(UNDEFINEDOID)); + } + } else { + /* Don't support the type in blacklist. */ + bool is_unsupported_type = !u_sess->attr.attr_common.IsInplaceUpgrade && IsTypeInBlacklist(typoid); + if (is_unsupported_type) { + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("type %s is not yet supported.", format_type_be(typoid)))); + } - /* Don't support the type in blacklist. */ - bool is_unsupported_type = !u_sess->attr.attr_common.IsInplaceUpgrade && IsTypeInBlacklist(typoid); - if (is_unsupported_type) { - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("type %s is not yet supported.", format_type_be(typoid)))); - } + tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typoid)); - tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typoid)); - - /* should not happen */ - if (!HeapTupleIsValid(tup)) { - ereport(ERROR, (errcode(ERRCODE_CACHE_LOOKUP_FAILED), errmsg("cache lookup failed for type %u", typoid))); + /* should not happen */ + if (!HeapTupleIsValid(tup)) { + ereport(ERROR, (errcode(ERRCODE_CACHE_LOOKUP_FAILED), errmsg("cache lookup failed for type %u", typoid))); + } + if (!typname->pct_type) { + typmod = typenameTypeMod(pstate, typname, (Type)tup); + } + if (typmod_p != NULL) { + *typmod_p = typmod; + } } - if (!typname->pct_type) { - typmod = typenameTypeMod(pstate, typname, (Type)tup); - } - if (typmod_p != NULL) { - *typmod_p = typmod; - } - return (Type)tup; } @@ -388,11 +501,11 @@ Type LookupTypeNameExtended(ParseState* pstate, const TypeName* typname, int32* * a suitable error message if the type cannot be found or is not defined. * Callers of this can therefore assume the result is a fully valid type. */ -Type typenameType(ParseState* pstate, const TypeName* typname, int32* typmod_p) +Type typenameType(ParseState* pstate, const TypeName* typname, int32* typmod_p, TypeDependExtend* dependExtend) { Type tup; - tup = LookupTypeName(pstate, typname, typmod_p); + tup = LookupTypeName(pstate, typname, typmod_p, true, dependExtend); /* * If the type is relation, then we check @@ -447,11 +560,11 @@ Oid typenameTypeId(ParseState* pstate, const TypeName* typname) * This is equivalent to typenameType, but we only hand back the type OID * and typmod, not the syscache entry. */ -void typenameTypeIdAndMod(ParseState* pstate, const TypeName* typname, Oid* typeid_p, int32* typmod_p) +void typenameTypeIdAndMod(ParseState* pstate, const TypeName* typname, Oid* typeid_p, int32* typmod_p, TypeDependExtend* dependExtend) { Type tup; - tup = typenameType(pstate, typname, typmod_p); + tup = typenameType(pstate, typname, typmod_p, dependExtend); *typeid_p = HeapTupleGetOid(tup); ReleaseSysCache(tup); } @@ -906,7 +1019,7 @@ static void pts_error_callback(void* arg) * such as "int4" or "integer" or "character varying(32)", parse * the string and convert it to a type OID and type modifier. */ -void parseTypeString(const char* str, Oid* typeid_p, int32* typmod_p) +void parseTypeString(const char* str, Oid* typeid_p, int32* typmod_p, TypeDependExtend* dependExtend) { StringInfoData buf; buf.data = NULL; @@ -970,7 +1083,7 @@ void parseTypeString(const char* str, Oid* typeid_p, int32* typmod_p) goto fail; } - typenameTypeIdAndMod(NULL, typname, typeid_p, typmod_p); + typenameTypeIdAndMod(NULL, typname, typeid_p, typmod_p, dependExtend); pfree_ext(buf.data); @@ -979,7 +1092,13 @@ void parseTypeString(const char* str, Oid* typeid_p, int32* typmod_p) fail: pfree_ext(buf.data); InsertErrorMessage("invalid type name", u_sess->plsql_cxt.plpgsql_yylloc); - ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("invalid type name \"%s\"", str))); + if (enable_plpgsql_undefined()) { + InvalidateCurrCompilePgObj(); + *typeid_p = UNDEFINEDOID; + ereport(WARNING, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("invalid type name \"%s\"", str))); + } else { + ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("invalid type name \"%s\"", str))); + } } /* @@ -1448,8 +1567,31 @@ char* CastPackageTypeName(const char* typName, Oid objOid, bool isPackage, bool return castTypName.data; } +char* ParseTypeName(const char* typName, Oid pkgOid) +{ + if (!OidIsValid(pkgOid)) { + return NULL; + } + char* oldStr = NULL; + const int oldStrLen =12; + oldStr = (char*)palloc0(oldStrLen * sizeof(char)); + pg_ltoa(pkgOid, oldStr); + int len = strlen(oldStr); + char* pos = strstr((char*)typName, oldStr); + pfree_ext(oldStr); + if (NULL == pos) { + return NULL; + } + pos +=len; + if (*pos != '.') { + return NULL; + } + return pstrdup(++pos); +} + /* find if %type ref a package variable type */ -HeapTuple FindPkgVariableType(ParseState* pstate, const TypeName* typname, int32* typmod_p) +HeapTuple FindPkgVariableType(ParseState* pstate, const TypeName* typname, int32* typmod_p, + TypeDependExtend* depend_extend) { HeapTuple tup = NULL; @@ -1457,8 +1599,7 @@ HeapTuple FindPkgVariableType(ParseState* pstate, const TypeName* typname, int32 return tup; #else int32 typmod = -1; - - if (u_sess->plsql_cxt.curr_compile_context == NULL) { + if (!enable_plpgsql_gsdependency_guc() && u_sess->plsql_cxt.curr_compile_context == NULL) { return tup; } @@ -1469,15 +1610,14 @@ HeapTuple FindPkgVariableType(ParseState* pstate, const TypeName* typname, int32 } /* find package.var%TYPE second */ - if (list_length(typname->names) <= 1 || list_length(typname->names) >= 4) { + if (list_length(typname->names) <= 1) { + return tup; + } + if (list_length(typname->names) >= (enable_plpgsql_gsdependency_guc() ? 5 :4)) { return tup; } PLpgSQL_datum* datum = GetPackageDatum(typname->names); if (datum != NULL && datum->dtype == PLPGSQL_DTYPE_VAR) { - if (OidIsValid(((PLpgSQL_var*)datum)->datatype->tableOfIndexType)) { - ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("not support ref table of variable as procedure argument type"))); - } Oid typOid = ((PLpgSQL_var*)datum)->datatype->typoid; tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typOid)); /* should not happen */ @@ -1489,6 +1629,19 @@ HeapTuple FindPkgVariableType(ParseState* pstate, const TypeName* typname, int32 if (typmod_p != NULL) { *typmod_p = typmod; } + if (enable_plpgsql_gsdependency() && NULL != depend_extend) { + DeconstructQualifiedName(typname->names, &depend_extend->schemaName, + &depend_extend->objectName, &depend_extend->packageName); + } + } else if (enable_plpgsql_undefined() && NULL != depend_extend) { + Oid undefRefObjOid = gsplsql_try_build_exist_pkg_undef_var(typname->names); + if (OidIsValid(undefRefObjOid)) { + depend_extend->undefDependObjOid = undefRefObjOid; + tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(UNDEFINEDOID)); + if (typmod_p != NULL) { + *typmod_p = -1; + } + } } return tup; #endif @@ -1535,13 +1688,18 @@ Oid LookupTypeInPackage(List* typeNames, const char* typeName, Oid pkgOid, Oid n /* pkgOid is invalid, try to find the type in current compile package */ if (!OidIsValid(pkgOid)) { - /* if not compiling packgae, just return invalid oid */ - if (u_sess->plsql_cxt.curr_compile_context == NULL || - u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package == NULL) { - return typOid; + if (enable_plpgsql_gsdependency_guc() && + u_sess->plsql_cxt.functionStyleType == FUNCTION_STYLE_TYPE_REFRESH_HEAD && + OidIsValid(u_sess->plsql_cxt.currRefreshPkgOid)) { + pkgOid = u_sess->plsql_cxt.currRefreshPkgOid; + } else { + /* if not compiling packgae, just return invalid oid */ + if (u_sess->plsql_cxt.curr_compile_context == NULL || + u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package == NULL) { + return typOid; + } + pkgOid = u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package->pkg_oid; } - - pkgOid = u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package->pkg_oid; /* find public package type first */ castTypeName = CastPackageTypeName(typeName, pkgOid, true, true); typOid = TypenameGetTypidExtended(castTypeName, false); @@ -1574,7 +1732,13 @@ Oid LookupTypeInPackage(List* typeNames, const char* typeName, Oid pkgOid, Oid n pfree_ext(castTypeName); if (OidIsValid(typOid)) { - check_record_nest_tableof_index_type(NULL, typeNames); + bool pkgValid = true; + if (enable_plpgsql_gsdependency_guc()) { + pkgValid = GetPgObjectValid(pkgOid, OBJECT_TYPE_PKGSPEC); + } + if (pkgValid) { + // check_record_nest_tableof_index_type(NULL, typeNames); + } return typOid; } @@ -1639,3 +1803,11 @@ void check_type_supports_multi_charset(Oid typid, bool allow_array) errmsg("multi character set for datatype '%s' is not supported", get_typename(typid)))); } } + +TypeTupStatus GetTypeTupStatus(Type typ) +{ + if (HeapTupleIsValid(typ)) { + return (UNDEFINEDOID == HeapTupleGetOid(typ) ? UndefineTypeTup : NormalTypeTup); + } + return InvalidTypeTup; +} \ No newline at end of file diff --git a/src/common/backend/parser/scan.l b/src/common/backend/parser/scan.l index a61f6e4aa..888959016 100755 --- a/src/common/backend/parser/scan.l +++ b/src/common/backend/parser/scan.l @@ -1368,6 +1368,7 @@ scanner_init(const char *str, yyext->include_ora_comment = false; yyext->func_param_begin = 0; yyext->func_param_end = 0; + yyext->return_pos_end = 0; /* * Make a scan buffer with special termination needed by flex. diff --git a/src/common/backend/utils/CMakeLists.txt b/src/common/backend/utils/CMakeLists.txt index 8e5cfe5a8..b744e3d4c 100755 --- a/src/common/backend/utils/CMakeLists.txt +++ b/src/common/backend/utils/CMakeLists.txt @@ -70,6 +70,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/mb ${CMAKE_CURRENT_SOURCE_DIR}/misc ${CMAKE_CURRENT_SOURCE_DIR}/sort + ${CMAKE_CURRENT_SOURCE_DIR}/gsplsql ) add_subdirectory(adt) @@ -84,6 +85,7 @@ add_subdirectory(time) add_subdirectory(mb) add_subdirectory(misc) add_subdirectory(sort) +add_subdirectory(gsplsql) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/errcodes.h DESTINATION include/postgresql/server/utils) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/fmgroids.h DESTINATION include/postgresql/server/utils) diff --git a/src/common/backend/utils/Makefile b/src/common/backend/utils/Makefile index ba303b2ba..8788ea9f6 100644 --- a/src/common/backend/utils/Makefile +++ b/src/common/backend/utils/Makefile @@ -16,7 +16,7 @@ ifneq "$(MAKECMDGOALS)" "clean" endif endif OBJS = fmgrtab.o -SUBDIRS = adt cache error fmgr hash init mb misc mmgr resowner sort time +SUBDIRS = adt cache error fmgr hash init mb misc mmgr resowner sort time gsplsql # location of Catalog.pm catalogdir = $(top_srcdir)/src/common/backend/catalog diff --git a/src/common/backend/utils/adt/regproc.cpp b/src/common/backend/utils/adt/regproc.cpp index 5b00a3cc4..a5d33d180 100644 --- a/src/common/backend/utils/adt/regproc.cpp +++ b/src/common/backend/utils/adt/regproc.cpp @@ -41,6 +41,7 @@ #include "utils/syscache.h" #include "utils/snapmgr.h" #include "catalog/pg_proc_fn.h" +#include "catalog/pg_type_fn.h" static void parseNameAndArgTypes(const char* string, bool allowNone, List** names, int* nargs, Oid* argtypes); @@ -340,6 +341,39 @@ format_procedure_parts(Oid procedure_oid, List **objnames, List **objargs) } +char * format_procedure_no_visible(Oid procedure_oid) +{ + char* result = NULL; + HeapTuple proctup; + proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(procedure_oid)); + if (HeapTupleIsValid(proctup)) { + Form_pg_proc procform = (Form_pg_proc)GETSTRUCT(proctup); + char* proname = NameStr(procform->proname); + StringInfoData buf; + initStringInfo(&buf); + appendStringInfo(&buf, "%s(", proname); + bool isNull = false; + Datum argTypeDtum = ProcedureGetAllArgTypes(proctup, &isNull); + oidvector* proargs = (oidvector*)PG_DETOAST_DATUM(argTypeDtum); + int nargs = proargs->dim1; + int i; + for (i = 0; i < nargs; i++) { + if (i > 0) + appendStringInfoChar(&buf, ','); + MakeTypeNamesStrForTypeOid(&buf, proargs->values[i]); + } + appendStringInfoChar(&buf, ')'); + result = buf.data; + ReleaseSysCache(proctup); + } else { + /* If OID doesn't match any pg_proc entry, return it numerically */ + result = (char*)palloc(NAMEDATALEN); + errno_t rc = snprintf_s(result, NAMEDATALEN, NAMEDATALEN - 1, "%u", procedure_oid); + securec_check_ss(rc, "\0", "\0"); + } + return result; +} + /* * Routine to produce regprocedure names; see format_procedure above. * diff --git a/src/common/backend/utils/adt/ruleutils.cpp b/src/common/backend/utils/adt/ruleutils.cpp index 8030a9eac..241a6c6ff 100644 --- a/src/common/backend/utils/adt/ruleutils.cpp +++ b/src/common/backend/utils/adt/ruleutils.cpp @@ -4564,7 +4564,7 @@ char* pg_get_functiondef_worker(Oid funcid, int* headerlines) int oldlen; char* p = NULL; bool isOraFunc = false; - NameData* pkgname = NULL; + char* pkgname = NULL; initStringInfo(&buf); /* Look up the function */ @@ -4610,7 +4610,7 @@ char* pg_get_functiondef_worker(Oid funcid, int* headerlines) if (proIsProcedure) { if (pkgname != NULL) { appendStringInfo(&buf, "CREATE OR REPLACE PROCEDURE %s(", - quote_qualified_identifier(nsp, pkgname->data, name)); + quote_qualified_identifier(nsp, pkgname, name)); } else if (u_sess->attr.attr_sql.sql_compatibility == B_FORMAT) { appendStringInfo(&buf, "CREATE DEFINER = %s PROCEDURE %s(", GetUserNameFromId(proc->proowner), quote_qualified_identifier(nsp, name)); @@ -4622,7 +4622,7 @@ char* pg_get_functiondef_worker(Oid funcid, int* headerlines) } else { if (pkgname != NULL) { appendStringInfo(&buf, "CREATE OR REPLACE FUNCTION %s(", - quote_qualified_identifier(nsp, pkgname->data, name)); + quote_qualified_identifier(nsp, pkgname, name)); } else if (u_sess->attr.attr_sql.sql_compatibility == B_FORMAT) { appendStringInfo(&buf, "CREATE DEFINER = %s FUNCTION %s(", GetUserNameFromId(proc->proowner), quote_qualified_identifier(nsp, name)); @@ -12230,7 +12230,7 @@ static char* generate_function_name( int p_nvargs; Oid* p_true_typeids = NULL; Oid p_vatype; - NameData* pkgname = NULL; + char* pkgname = NULL; Datum pkgOiddatum; Oid pkgOid = InvalidOid; bool isnull = true; @@ -12286,7 +12286,7 @@ static char* generate_function_name( else nspname = get_namespace_name(procform->pronamespace); if (OidIsValid(pkgOid)) { - result = quote_qualified_identifier(nspname, pkgname->data, proname); + result = quote_qualified_identifier(nspname, pkgname, proname); } else { result = quote_qualified_identifier(nspname, proname); } diff --git a/src/common/backend/utils/adt/varlena.cpp b/src/common/backend/utils/adt/varlena.cpp index 129277cce..973574c3e 100644 --- a/src/common/backend/utils/adt/varlena.cpp +++ b/src/common/backend/utils/adt/varlena.cpp @@ -806,6 +806,26 @@ Datum unknownsend(PG_FUNCTION_ARGS) PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); } +Datum undefinedin(PG_FUNCTION_ARGS) +{ + return unknownin(fcinfo); +} + +Datum undefinedout(PG_FUNCTION_ARGS) +{ + return unknownout(fcinfo); +} + +Datum undefinedrecv(PG_FUNCTION_ARGS) +{ + return unknownrecv(fcinfo); +} + +Datum undefinedsend(PG_FUNCTION_ARGS) +{ + return unknownsend(fcinfo); +} + static Datum text_length_huge(Datum str) { if (pg_database_encoding_max_length() == 1) { diff --git a/src/common/backend/utils/cache/lsyscache.cpp b/src/common/backend/utils/cache/lsyscache.cpp index 77ee10f32..3d8f691f7 100644 --- a/src/common/backend/utils/cache/lsyscache.cpp +++ b/src/common/backend/utils/cache/lsyscache.cpp @@ -4233,6 +4233,24 @@ bool type_is_range(Oid typid) return (get_typtype(typid) == TYPTYPE_RANGE); } +/* + * type_is_relation + * + * Convenience function to determine whether a type OID represents + * a ordinaty table type. + */ +bool type_is_relation(Oid typid) +{ + if (get_typtype(typid) != TYPTYPE_COMPOSITE) { + return false; + } + Oid relid = get_typ_typrelid(typid); + if (!OidIsValid(relid)) { + return false; + } + return get_rel_relkind(relid) == RELKIND_RELATION; +} + /* * get_type_category_preferred * @@ -5325,7 +5343,7 @@ Oid get_func_oid(const char* funcname, Oid funcnamespace, Expr* expr) char* proname = NULL; Datum pkgOiddatum; bool isnull = true; - NameData* pkgname = NULL; + char* pkgname = NULL; Oid pkgOid = InvalidOid; procform = (Form_pg_proc)GETSTRUCT(proctupl); proname = NameStr(procform->proname); @@ -6434,3 +6452,16 @@ void spq_free_attstatsslot(AttStatsSlot *sslot) pfree(sslot->numbers_arr); } #endif + +Oid get_array_internal_depend_type_oid(Oid arrTypOid) +{ + Oid elemOid = get_element_type(arrTypOid); + if (elemOid == InvalidOid) { + return InvalidOid; + } + Oid arrOid = get_array_type(elemOid); + if (arrOid == arrTypOid) { + return elemOid; + } + return InvalidOid; +} diff --git a/src/common/backend/utils/gsplsql/CMakeLists.txt b/src/common/backend/utils/gsplsql/CMakeLists.txt new file mode 100644 index 000000000..95faff68b --- /dev/null +++ b/src/common/backend/utils/gsplsql/CMakeLists.txt @@ -0,0 +1,19 @@ +#This is the main CMAKE for build all components. +AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} TGT_gsplsql_SRC) + +set(TGT_gsplsql_INC + ${PROJECT_OPENGS_DIR}/contrib/log_fdw + ${PROJECT_TRUNK_DIR}/distribute/bin/gds + ${PROJECT_SRC_DIR}/include/libcomm + ${PROJECT_SRC_DIR}/include + ${PROJECT_SRC_DIR}/lib/gstrace + ${LZ4_INCLUDE_PATH} + ${LIBCGROUP_INCLUDE_PATH} + ${EVENT_INCLUDE_PATH} + ${ZLIB_INCLUDE_PATH} + ) + +set(gsplsql_DEF_OPTIONS ${MACRO_OPTIONS}) +set(gsplsql_COMPILE_OPTIONS ${OPTIMIZE_OPTIONS} ${OS_OPTIONS} ${PROTECT_OPTIONS} ${WARNING_OPTIONS} ${BIN_SECURE_OPTIONS} ${CHECK_OPTIONS}) +set(gsplsql_LINK_OPTIONS ${BIN_LINK_OPTIONS}) +add_static_objtarget(common_backend_utils_gsplsql TGT_gsplsql_SRC TGT_gsplsql_INC "${gsplsql_DEF_OPTIONS}" "${gsplsql_COMPILE_OPTIONS}" "${gsplsql_LINK_OPTIONS}") diff --git a/src/common/backend/utils/gsplsql/Makefile b/src/common/backend/utils/gsplsql/Makefile new file mode 100644 index 000000000..27da6e777 --- /dev/null +++ b/src/common/backend/utils/gsplsql/Makefile @@ -0,0 +1,24 @@ +#------------------------------------------------------------------------- +# +# Makefile-- +# Makefile for utils/hash +# +# IDENTIFICATION +# src/common/backend/utils/gsplsql/Makefile +# +#------------------------------------------------------------------------- + +subdir = src/common/backend/utils/gsplsql +top_builddir = ../../../../.. +include $(top_builddir)/src/Makefile.global + +ifneq "$(MAKECMDGOALS)" "clean" + ifneq "$(MAKECMDGOALS)" "distclean" + ifneq "$(shell which g++ |grep hutaf_llt |wc -l)" "1" + -include $(DEPEND) + endif + endif +endif +OBJS = gsdependencies.o gsobject_dependencies.o + +include $(top_srcdir)/src/gausskernel/common.mk diff --git a/src/common/backend/utils/gsplsql/gsdependencies.cpp b/src/common/backend/utils/gsplsql/gsdependencies.cpp new file mode 100644 index 000000000..bf7320193 --- /dev/null +++ b/src/common/backend/utils/gsplsql/gsdependencies.cpp @@ -0,0 +1,1480 @@ +/* +* Copyright (c) 2021 Huawei Technologies Co.,Ltd. +* +* openGauss is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +* --------------------------------------------------------------------------------------- +* +* gsdependencies.cpp +* +* +* IDENTIFICATION +* src/common/backend/utils/gsplsql/gsdependencies.cpp +* +* --------------------------------------------------------------------------------------- + */ + +#include "postgres.h" +#include "utils/plpgsql.h" +#include "utils/builtins.h" +#include "catalog/gs_dependencies_fn.h" +#include "utils/lsyscache.h" +#include "catalog/gs_dependencies.h" +#include "utils/pl_package.h" +#include "utils/fmgroids.h" +#include "catalog/indexing.h" +#include "storage/lmgr.h" +#include "catalog/pg_proc.h" +#include "catalog/pg_object.h" +#include "commands/dbcommands.h" +#include "catalog/pg_enum.h" +#include "catalog/heap.h" +#include "catalog/pg_type_fn.h" +#include "catalog/gs_package.h" +#include "catalog/gs_dependencies_obj.h" +#include "catalog/pg_proc_fn.h" +#include "parser/parse_type.h" +#include "utils/lsyscache.h" + +static void complete_process_variables(PLpgSQL_package* pkg, bool isCreate, bool isRecompile); +static bool datumIsVariable(PLpgSQL_datum* datum); +static void do_complete_process_variables(PLpgSQL_package* pkg, bool isCreate, bool isRecompile, PLpgSQL_datum* datum); +static Oid gsplsql_parse_exist_pkg_and_build_obj_desc(GsDependObjDesc* obj, List* var_name, ListCell** attr_list); +static inline void gsplsql_free_var_mem_for_gs_dependencies(GsDependObjDesc* obj); +static inline bool gsplsql_is_proc_head_depend_type(const GsDependObjDesc* obj_desc, const GsDependObjDesc* ref_obj_desc); +static void gsplsql_insert_gs_dependency(Relation relation, NameData* schema_name_data, + NameData* pkg_name_data, StringInfo object_name, + int ref_obj_pos, Oid ref_obj_oid); +static DependenciesType *gsplsql_make_dependencies_type(Oid typOid); +static inline void gsplsql_delete_type(const char *schemaName, const char *pkgName, char *typName); +static bool gsplsql_invalidate_obj(GsDependObjDesc* obj, Datum refobjpos_datum, + bool is_ref_remove, Oid curr_compile_oid); +static List* GetPkgFuncOids(Oid schemaOid, Oid pkgOid); +static bool gsplsql_get_depend_body_desc(GsDependParamBody* gs_depend_param_body); + +static DependenciesDatum *gsplsql_make_var_depend_datum(const PLpgSQL_datum *datum, Oid *namespace_oid, bool *depend_undefined); +static DependenciesDatum *gsplsql_make_row_var_depend_datum(const PLpgSQL_datum *datum, Oid *namespace_oid, bool *depend_undefined); +static DependenciesDatum *gsplsql_make_record_var_depend_datum(const PLpgSQL_datum *datum, Oid *namespace_oid, bool *depend_undefined); + +static bool gsplsql_invalidate_pkg(const char *schemaName, const char *pkgName, bool isSpec, Oid currCompileOid); +static bool gsplsql_invalidate_func(Oid func_oid, Oid curr_compile_oid); +static bool gsplsql_check_var_attrs(PLpgSQL_datum *datum, ListCell *attr_list); + +static inline Oid gsplsql_parse_pkg_var_and_attrs4(GsDependObjDesc* obj, List* var_name, ListCell** attr_list); +static inline Oid gsplsql_parse_pkg_var_and_attrs3(GsDependObjDesc* obj, ListCell* var_name, ListCell** attr_list); +static inline Oid gsplsql_parse_pkg_var_obj2(GsDependObjDesc* obj, ListCell* var_name); + +void gsplsql_init_gs_depend_obj_desc(GsDependObjDesc* object) +{ + object->schemaName = NULL; + object->packageName = NULL; + object->name = NULL; + object->type = GSDEPEND_OBJECT_TYPE_INVALID; + object->refPosType = GSDEPEND_REFOBJ_POS_INVALID; +} + +bool gsplsql_need_build_gs_dependency(GsDependParamBody* gsdependParamBody, const ObjectAddress* referenced, bool is_pinned) +{ + if (NULL == gsdependParamBody) { + return false; + } + if (UNDEFINEDOID == referenced->objectId) { + return true; + } + if (is_pinned) { + if (NULL != gsdependParamBody->dependExtend) { + if (NULL != gsdependParamBody->dependExtend->objectName) { + return true; + } else if (OidIsValid(gsdependParamBody->dependExtend->typeOid)) { + return !IsPinnedObject(TypeRelationId, gsdependParamBody->dependExtend->typeOid); + } else { + return false; + } + } + } + return true; +} + +bool gsplsql_remove_gs_dependency(const GsDependObjDesc* obj_desc) +{ + Relation rel = heap_open(DependenciesRelationId, RowExclusiveLock); + List* list = gsplsql_delete_objs(rel, obj_desc); + gsplsql_delete_unrefer_depend_obj_in_list(list, true); + list_free(list); + heap_close(rel, RowExclusiveLock); + return true; +} + +bool gsplsql_build_gs_type_in_body_dependency(PLpgSQL_type* type) +{ + GsDependParamBody gs_depend_param_body; + gsplsql_init_gs_depend_param_body(&gs_depend_param_body); + bool ret = gsplsql_get_depend_body_desc(&gs_depend_param_body); + if (!ret) { + return false; + } + gs_depend_param_body.dependExtend = type->dependExtend; + gs_depend_param_body.type = GSDEPEND_OBJECT_TYPE_TYPE; + ObjectAddress ref; + ref.classId = TypeRelationId; + ref.objectId =type->typoid; + ref.objectSubId = 0; + bool needBuild = gsplsql_need_build_gs_dependency(&gs_depend_param_body, &ref, + IsPinnedObject(ref.classId, ref.objectId)); + if (!needBuild) { + return false; + } + return gsplsql_build_gs_type_dependency(&gs_depend_param_body, &ref); +} + +static bool gsplsql_get_depend_body_desc(GsDependParamBody* gs_depend_param_body) +{ + int cw = CompileWhich(); + if (cw == PLPGSQL_COMPILE_PACKAGE || cw == PLPGSQL_COMPILE_PACKAGE_PROC) { + PLpgSQL_package* pkg = u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package; + gs_depend_param_body->dependNamespaceOid = pkg->namespaceOid; + gs_depend_param_body->dependPkgOid = pkg->pkg_oid; + gs_depend_param_body->dependPkgName = pkg->pkg_signature; + gs_depend_param_body->dependName = pkg->pkg_signature; + gs_depend_param_body->refPosType = pkg->is_spec_compiling ? + GSDEPEND_REFOBJ_POS_IN_PKGSPEC : GSDEPEND_REFOBJ_POS_IN_PKGBODY; + return true; + } else if (cw == PLPGSQL_COMPILE_PROC) { + PLpgSQL_function* func = u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile; + gs_depend_param_body->dependNamespaceOid = func->namespaceOid; + gs_depend_param_body->dependName = format_procedure_no_visible(func->fn_oid); + gs_depend_param_body->refPosType = GSDEPEND_REFOBJ_POS_IN_PROCBODY; + return true; + } + return false; +} + +static char* gsplsql_get_obj_name_by_obj_addr(const ObjectAddress* depender, Oid pkgOid) +{ + switch (depender->classId) { + case ProcedureRelationId: { + return pstrdup(format_procedure_no_visible(depender->objectId)); + } break; + case TypeRelationId: { + char* name = get_typename(depender->objectId); + if (name != NULL && OidIsValid(pkgOid)) { + char* real_name = ParseTypeName(name, pkgOid); + if (NULL != real_name) { + pfree_ext(name); + name = real_name; + } + } + return name; + } break; + case RelationRelationId: { + char* name = get_rel_name(depender->objectId); + if (name != NULL && OidIsValid(pkgOid)) { + char* real_name = ParseTypeName(name, pkgOid); + if (NULL != real_name) { + pfree_ext(name); + name = real_name; + } + } + return name; + } break; + default: + break; + } + + return NULL; +} + +static bool gsplsql_make_ref_type_depend_obj_desc(const ObjectAddress* referenced, GsDependParamBody* gsdependParamBody, + GsDependObjDesc* ref_obj_desc, TypeDependExtend* depend_extend, ObjectAddress* ref_assemble) +{ + bool dep_is_null = depend_extend == NULL; + ref_obj_desc->name = (dep_is_null ? NULL :depend_extend->objectName); + if (NULL == ref_obj_desc->name) { + ref_obj_desc->packageName = NULL; + Oid ref_typ_oid = dep_is_null ? InvalidOid : depend_extend->typeOid; + if (ref_typ_oid == InvalidOid) { + ref_typ_oid = referenced->objectId; + if (referenced->classId == RelationRelationId) { + ref_typ_oid = get_rel_type_id(ref_typ_oid); + } + } else { + ref_assemble->classId = TypeRelationId; + ref_assemble->objectId = ref_typ_oid; + } + if (ref_assemble->objectId == UNDEFINEDOID) { + return false; + } + Oid elem_oid_for_arr = get_array_internal_depend_type_oid(ref_assemble->objectId); + if (OidIsValid(elem_oid_for_arr)) { + ref_assemble->objectId = elem_oid_for_arr; + } + Oid ref_pkg_oid = GetTypePackageOid(ref_typ_oid); + if (gsdependParamBody->dependPkgOid != InvalidOid && + gsdependParamBody->dependPkgOid == ref_pkg_oid) { + return gsdependParamBody->refPosType == GSDEPEND_REFOBJ_POS_IN_PROCHEAD; + } + if (OidIsValid(ref_pkg_oid)) { + char* pkg_name = GetPackageName(ref_pkg_oid); + if (pkg_name != NULL) { + ref_obj_desc->packageName = pstrdup(pkg_name); + pfree_ext(pkg_name); + } + } + AssertEreport(TypeRelationId == ref_assemble->classId, MOD_PLSQL, + "ref_assemble->classId must be type."); + ref_obj_desc->schemaName = get_typenamespace(ref_assemble->objectId); + ref_obj_desc->name = gsplsql_get_obj_name_by_obj_addr(ref_assemble, ref_pkg_oid); + ref_obj_desc->type = gsdependParamBody->type; + } else { + ref_obj_desc->schemaName = pstrdup(depend_extend->schemaName); + ref_obj_desc->packageName = pstrdup(depend_extend->packageName); + ref_obj_desc->type = GSDEPEND_OBJECT_TYPE_VARIABLE; + } + return true; +} + +static void gsplsql_adjust_ref_pos_type(GsDependObjDesc* obj_desc) +{ + switch (CompileWhich()) { + case PLPGSQL_COMPILE_PACKAGE_PROC: { + PLpgSQL_package* pkg = + u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package; + if (!pkg->is_spec_compiling) { + obj_desc->refPosType = GSDEPEND_REFOBJ_POS_IN_PKGBODY; + obj_desc->name = pkg->pkg_signature; + } + } break; + case PLPGSQL_COMPILE_PROC: { + PLpgSQL_function* func = u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile; + *obj_desc = gsplsql_construct_func_head_obj(func->fn_oid, + func->namespaceOid, func->pkg_oid); + obj_desc->refPosType = GSDEPEND_REFOBJ_POS_IN_PROCBODY; + obj_desc->name = func->fn_signature; + } break; + default: + break; + } +} + +static bool gsplsql_build_gs_type_dependency(GsDependObjDesc* obj_desc, GsDependObjDesc* ref_obj_desc, + const Oid typOid, bool* depend_undefined) +{ + DependenciesDatum* depend_datum = NULL; + if (NULL != ref_obj_desc->packageName) { + List* typNameList = NIL; + if (NULL != ref_obj_desc->name) { + typNameList = lcons(makeString(ref_obj_desc->name), typNameList); + } + if (NULL != ref_obj_desc->packageName) { + typNameList = lcons(makeString(ref_obj_desc->packageName), typNameList); + } + Oid namespace_oid = InvalidOid; + if (NULL != ref_obj_desc->schemaName) { + typNameList = lcons(makeString(ref_obj_desc->schemaName), typNameList); + namespace_oid = get_namespace_oid(ref_obj_desc->schemaName, true); + } + Oid pkg_oid = PackageNameGetOid(ref_obj_desc->packageName, namespace_oid); + if (ref_obj_desc->type == GSDEPEND_OBJECT_TYPE_VARIABLE) { + PLpgSQL_datum* datum = NULL; + if (OidIsValid(pkg_oid)) { + datum = GetPackageDatum(typNameList); + } + depend_datum = gsplsql_make_depend_datum_from_plsql_datum(datum, + &ref_obj_desc->schemaName, depend_undefined); + } else { + if (!GetPgObjectValid(pkg_oid, OBJECT_TYPE_PKGSPEC)) { + if (GetCurrCompilePgObjStatus()) { + ereport(WARNING, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("Package %u is invalid.", pkg_oid))); + } + InvalidateCurrCompilePgObj(); + } + Oid type_oid = LookupTypeInPackage(typNameList, ref_obj_desc->name, + pkg_oid, namespace_oid); + depend_datum = gsplsql_make_depend_datum_by_type_oid(type_oid, depend_undefined); + } + list_free_ext(typNameList); + } else { + depend_datum = gsplsql_make_depend_datum_by_type_oid(typOid, depend_undefined); + } + return gsplsql_build_gs_dependency(obj_desc, ref_obj_desc, depend_datum); +} + +static bool gsplsql_match_obj_desc(const GsDependObjDesc* lhs, const GsDependObjDesc* rhs, bool match_name) +{ + if (NULL != lhs->schemaName || NULL != rhs->schemaName) { + if (NULL != lhs->schemaName && NULL != rhs->schemaName && + 0 != strcmp(lhs->schemaName, rhs->schemaName)) { + return false; + } else { + return false; + } + } + if (NULL != lhs->packageName || NULL != rhs->packageName) { + if (NULL != lhs->packageName && NULL != rhs->packageName && + 0 != strcmp(lhs->packageName, rhs->packageName)) { + return false; + } else { + return false; + } + } + if (match_name) { + if (NULL != lhs->name || NULL != rhs->name) { + if (NULL != lhs->name && NULL != rhs->name) { + return 0 == strcmp(lhs->packageName, rhs->packageName); + } else { + return false; + } + } + } + return true; +} + +bool gsplsql_undefine_in_same_pkg(GsDependObjDesc* obj_desc, Oid undefObjOid) +{ + if (NULL == obj_desc || NULL == obj_desc->packageName) { + return false; + } + GsDependObjDesc ref_obj_desc; + bool ret = gsplsql_search_depend_obj_by_oid(undefObjOid, &ref_obj_desc); + if (!ret) { + ereport(WARNING, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("dependencies object %u does not exist.", undefObjOid))); + return false; + } + ret = gsplsql_match_obj_desc(obj_desc, &ref_obj_desc, false) && (NULL != ref_obj_desc.packageName); + free_gs_depend_obj_desc(&ref_obj_desc); + if (ret) { + gsplsql_delete_unrefer_depend_obj_oid(undefObjOid, false); + return true; + } + return false; +} + +bool gsplsql_build_gs_type_dependency(GsDependParamBody* gsdependParamBody, const ObjectAddress* referenced) +{ + Oid namespace_oid = gsdependParamBody->dependNamespaceOid; + GsDependObjDesc obj_desc; + GsDependObjDesc ref_obj_desc = {NULL, NULL, NULL, GSDEPEND_OBJECT_TYPE_INVALID, 0}; + obj_desc.schemaName = get_namespace_name(namespace_oid); + obj_desc.packageName = gsdependParamBody->dependPkgName; + obj_desc.refPosType = gsdependParamBody->refPosType; + obj_desc.name = gsdependParamBody->dependName; + if (GSDEPEND_REFOBJ_POS_IN_TYPE == obj_desc.refPosType) { + gsplsql_adjust_ref_pos_type(&obj_desc); + } + TypeDependExtend* depend_extend = gsdependParamBody->dependExtend; + if (referenced->objectId == UNDEFINEDOID) { + if (GetCurrCompilePgObjStatus()) { + ereport(WARNING, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("Type %s depends on an undefined type.", obj_desc.name))); + } + InvalidateCurrCompilePgObj(); + if (NULL == depend_extend) { + return false; + } + depend_extend->dependUndefined = true; + if (OidIsValid(depend_extend->undefDependObjOid)) { + bool ret = gsplsql_undefine_in_same_pkg(&obj_desc, depend_extend->undefDependObjOid); + if (ret) { + return false; + } + } + /* + * pkg.v1%type + */ + if (OidIsValid(depend_extend->undefDependObjOid)) { + if (gsplsql_search_depend_obj_by_oid(depend_extend->undefDependObjOid, &ref_obj_desc)) { + free_gs_depend_obj_desc(&ref_obj_desc); + } + return gsplsql_build_gs_dependency(&obj_desc, depend_extend->undefDependObjOid); + } + } + ObjectAddress ref_assemble = *referenced; + bool ret = gsplsql_make_ref_type_depend_obj_desc(referenced, gsdependParamBody, &ref_obj_desc, depend_extend, &ref_assemble); + if (!ret) { + return false; + } + if (GSDEPEND_OBJECT_TYPE_TYPE == gsdependParamBody->type) { + bool dep_undefined = false; + ret = gsplsql_build_gs_type_dependency(&obj_desc, &ref_obj_desc, ref_assemble.objectId, &dep_undefined); + if (NULL != depend_extend && dep_undefined) { + depend_extend->dependUndefined = dep_undefined; + } + } + pfree_ext(ref_obj_desc.schemaName); + return ret; +} + +Oid gsplsql_try_build_exist_schema_undef_table(RangeVar* rel_var) +{ + if (NULL != rel_var->schemaname && + !OidIsValid(get_namespace_oid(rel_var->schemaname, true))) { + return InvalidOid; + } + GsDependObjDesc obj_desc; + char* active_schema_name = NULL; + if (NULL != rel_var->schemaname) { + obj_desc.schemaName = rel_var->schemaname; + } else { + active_schema_name = get_namespace_name(get_compiled_object_nspoid()); + obj_desc.schemaName = active_schema_name; + } + obj_desc.packageName = NULL; + obj_desc.name = rel_var->relname; + obj_desc.type = GSDEPEND_OBJECT_TYPE_TYPE; + return gsplsql_flush_undef_ref_depend_obj(&obj_desc); +} + +Oid gsplsql_try_build_exist_pkg_undef_var(List* dtnames) +{ + ListCell* attr_list = NULL; + GsDependObjDesc obj_desc; + gsplsql_init_gs_depend_obj_desc(&obj_desc); + if (!OidIsValid(gsplsql_parse_exist_pkg_and_build_obj_desc(&obj_desc, dtnames, &attr_list))) { + pfree_ext(obj_desc.schemaName); + pfree_ext(obj_desc.packageName); + pfree_ext(obj_desc.name); + return InvalidOid; + } + return gsplsql_flush_undef_ref_depend_obj(&obj_desc); +} + +Oid gsplsql_flush_undef_ref_depend_obj(const GsDependObjDesc* object) +{ + DependenciesUndefined* nodeUndefined = makeNode(DependenciesUndefined); + Oid objOid = gsplsql_update_object_ast(object, (const DependenciesDatum*)nodeUndefined); + pfree_ext(nodeUndefined); + return objOid; +} + +bool gsplsql_exist_dependency(GsDependObjDesc* obj_desc) +{ + NameData schema_name_data; + NameData pkg_name_data; + StringInfoData object_name_data; + gsplsql_construct_non_empty_obj(obj_desc, &schema_name_data, &pkg_name_data, &object_name_data); + int keyNum = 0; + ScanKeyData key[3]; + ScanKeyInit(&key[keyNum++], Anum_gs_dependencies_schemaname, BTEqualStrategyNumber, + F_NAMEEQ, NameGetDatum(&schema_name_data)); + ScanKeyInit(&key[keyNum++], Anum_gs_dependencies_packagename, BTEqualStrategyNumber, + F_NAMEEQ, NameGetDatum(&pkg_name_data)); + ScanKeyInit(&key[keyNum++], Anum_gs_dependencies_refobjpos, BTEqualStrategyNumber, + F_INT4EQ, Int32GetDatum(obj_desc->refPosType)); + bool is_null = false; + HeapTuple tuple; + Relation dep_rel = heap_open(DependenciesRelationId, AccessShareLock); + SysScanDesc scan = systable_beginscan(dep_rel, DependenciesNameIndexId, true, SnapshotSelf, keyNum, key); + while (HeapTupleIsValid(tuple = systable_getnext(scan))) { + Datum obj_datum_tmp = heap_getattr(tuple, Anum_gs_dependencies_objectname, + RelationGetDescr(dep_rel), &is_null); + char* obj_name_tmp = TextDatumGetCString(obj_datum_tmp); + if (object_name_data.data != NULL && strcmp(object_name_data.data, obj_name_tmp) == 0) { + pfree_ext(obj_name_tmp); + systable_endscan(scan); + heap_close(dep_rel, AccessShareLock); + FreeStringInfo(&object_name_data); + return true; + } + pfree_ext(obj_name_tmp); + } + systable_endscan(scan); + heap_close(dep_rel, AccessShareLock); + FreeStringInfo(&object_name_data); + return false; +} + +void gsplsql_construct_non_empty_obj(const GsDependObjDesc* object, Name schema_name_data, + Name pkg_name_data, StringInfo object_name) +{ + if (object->schemaName == NULL || strlen(object->schemaName) == 0) { + (void)namestrcpy(schema_name_data, "null"); + } else { + (void)namestrcpy(schema_name_data, object->schemaName); + } + if (object->packageName == NULL || strlen(object->packageName) == 0) { + (void)namestrcpy(pkg_name_data, "null"); + } else { + (void)namestrcpy(pkg_name_data, object->packageName); + } + initStringInfo(object_name); + if (object->name == NULL || strlen(object->name) == 0) { + if (object->packageName != NULL && strlen(object->packageName) != 0) { + appendStringInfoString(object_name, object->packageName); + } else { + appendStringInfoString(object_name, "null"); + } + } else { + appendStringInfoString(object_name, object->name); + } +} + +GsDependObjDesc gsplsql_construct_func_head_obj(Oid procOid, Oid procNamespace, Oid proPackageId) +{ + GsDependObjDesc obj_desc; + gsplsql_init_gs_depend_obj_desc(&obj_desc); + obj_desc.schemaName = get_namespace_name(procNamespace); + if (OidIsValid(proPackageId)) { + obj_desc.packageName = GetPackageName(proPackageId); + } else { + obj_desc.packageName = pstrdup("null"); + } + MemoryContext save_context = CurrentMemoryContext; + PG_TRY(); + { + obj_desc.name = format_procedure_no_visible(procOid); + } + PG_CATCH(); + { + ErrorData* edata = &t_thrd.log_cxt.errordata[t_thrd.log_cxt.errordata_stack_depth]; + if (edata->sqlerrcode == ERRCODE_CACHE_LOOKUP_FAILED) { + (void)MemoryContextSwitchTo(save_context); + obj_desc.name = get_func_name(procOid); + ereport(WARNING, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("The oid of the input parameter type of function %s does not exist.", obj_desc.name))); + FlushErrorState(); + } else { + PG_RE_THROW(); + } + } + PG_END_TRY(); + return obj_desc; +} + +bool gsplsql_set_pkg_func_status(Oid schema_oid, Oid pkg_oid, bool status) +{ + bool result = false; + List* list = GetPkgFuncOids(schema_oid, pkg_oid); + ListCell* cell = NULL; + foreach(cell, list) { + Oid func_oid = lfirst_oid(cell); + result = SetPgObjectValid(func_oid, OBJECT_TYPE_PROC, status) || result; + } + list_free(list); + return result; +} + +void gsplsql_build_gs_variable_dependency(List* var_name) +{ + ListCell* attr_list = NULL; + GsDependObjDesc ref_obj_desc; + GsDependObjDesc obj_desc; + gsplsql_init_gs_depend_obj_desc(&ref_obj_desc); + gsplsql_init_gs_depend_obj_desc(&obj_desc); + if (!OidIsValid(gsplsql_parse_exist_pkg_and_build_obj_desc(&ref_obj_desc, var_name, &attr_list))) { + gsplsql_free_var_mem_for_gs_dependencies(&ref_obj_desc); + return; + } + int rc = CompileWhich(); + if (rc == PLPGSQL_COMPILE_PACKAGE || rc == PLPGSQL_COMPILE_PACKAGE_PROC) { + PLpgSQL_package* pkg = u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package; + obj_desc.schemaName = get_namespace_name(pkg->namespaceOid); + obj_desc.packageName = pkg->pkg_signature; + obj_desc.name = pkg->pkg_signature; + if (pkg->is_spec_compiling) { + obj_desc.refPosType = GSDEPEND_REFOBJ_POS_IN_PKGSPEC; + } else { + obj_desc.refPosType = GSDEPEND_REFOBJ_POS_IN_PKGBODY; + } + } else if (rc == PLPGSQL_COMPILE_PROC) { + PLpgSQL_function* func = u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile; + obj_desc = gsplsql_construct_func_head_obj(func->fn_oid, func->namespaceOid, func->pkg_oid); + obj_desc.refPosType = GSDEPEND_REFOBJ_POS_IN_PROCBODY; + } else { + gsplsql_free_var_mem_for_gs_dependencies(&ref_obj_desc); + return; + } + List* new_var_name = list_make3(makeString(ref_obj_desc.schemaName), makeString(ref_obj_desc.packageName), + makeString(ref_obj_desc.name)); + PLpgSQL_datum* datum = GetPackageDatum(new_var_name); + list_free_ext(new_var_name); + if (datum == NULL) { + if (!enable_plpgsql_undefined()) { + ereport(ERROR, (errmodule(MOD_PLSQL), errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("%s.%s.%s must be declared.", + ref_obj_desc.schemaName, ref_obj_desc.packageName, + ref_obj_desc.name))); + } else { + ereport(WARNING, (errmodule(MOD_PLSQL), errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("%s.%s.%s must be declared.", + ref_obj_desc.schemaName, ref_obj_desc.packageName, + ref_obj_desc.name))); + } + ref_obj_desc.type = GSDEPEND_OBJECT_TYPE_UNDEFIND; + } else { + if (!datumIsVariable(datum)) { + return; + } + if (!gsplsql_check_var_attrs(datum, attr_list)) { + if (!enable_plpgsql_undefined()) { + ereport(ERROR, (errmodule(MOD_PLSQL), errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("%s.%s.%s datum does not have %s attribute.", + ref_obj_desc.schemaName, ref_obj_desc.packageName, + ref_obj_desc.name, strVal(lfirst(attr_list))))); + } else { + if (GetCurrCompilePgObjStatus()) { + ereport(WARNING, (errmodule(MOD_PLSQL), errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("%s.%s.%s datum does not have %s attribute.", + ref_obj_desc.schemaName, ref_obj_desc.packageName, + ref_obj_desc.name, strVal(lfirst(attr_list))))); + } + InvalidateCurrCompilePgObj(); + } + } + } + bool type_depend_undefined = false; + gsplsql_build_gs_dependency(&obj_desc, &ref_obj_desc, + gsplsql_make_depend_datum_from_plsql_datum(datum, NULL, &type_depend_undefined)); + if (type_depend_undefined) { + if (GetCurrCompilePgObjStatus()) { + ereport(WARNING, (errcode(ERRCODE_UNDEFINED_OBJECT), + errdetail("dependencies %s attribute must be declared.", ref_obj_desc.name))); + } + InvalidateCurrCompilePgObj(); + } + pfree_ext(obj_desc.schemaName); + gsplsql_free_var_mem_for_gs_dependencies(&ref_obj_desc); +} + +bool gsplsql_build_gs_dependency(const GsDependObjDesc* obj_desc, const GsDependObjDesc* ref_obj_desc, + const DependenciesDatum* ref_obj_ast) +{ + if (!gsplsql_is_proc_head_depend_type(obj_desc, ref_obj_desc)) { + if (NULL != obj_desc->schemaName && NULL != ref_obj_desc->schemaName && + 0 == strcmp(obj_desc->schemaName, ref_obj_desc->schemaName)) { + if (NULL != obj_desc->packageName && NULL != ref_obj_desc->packageName && + 0 == strcmp(obj_desc->packageName, ref_obj_desc->packageName)) { + return false; + } + } + } + Oid ref_obj_oid = gsplsql_update_object_ast(ref_obj_desc, ref_obj_ast); + return gsplsql_build_gs_dependency(obj_desc, ref_obj_oid); +} + +void gsplsql_init_gs_depend_param_body(GsDependParamBody* param_body) +{ + if (NULL == param_body) { + return; + } + param_body->dependNamespaceOid = InvalidOid; + param_body->dependPkgOid = InvalidOid; + param_body->dependPkgName = NULL; + param_body->dependName = NULL; + param_body->dependExtend = NULL; + param_body->type = GSDEPEND_OBJECT_TYPE_INVALID; + param_body->refPosType = GSDEPEND_REFOBJ_POS_INVALID; + param_body->hasDependency = false; +} + +bool gsplsql_build_gs_dependency(const GsDependObjDesc* obj_desc, const Oid ref_obj_oid) +{ + if (InvalidOid == ref_obj_oid) { + return false; + } + ScanKeyData key; + HeapTuple tuple = NULL; + int rc = CompileWhich(); + if (rc == PLPGSQL_COMPILE_PACKAGE || rc == PLPGSQL_COMPILE_PACKAGE_PROC) { + PLpgSQL_package* pkg = u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package; + pkg->preRefObjectOidList = list_delete_oid(pkg->preRefObjectOidList, ref_obj_oid); + } + bool find = false; + bool is_null = false; + NameData schema_name_data; + NameData pkg_name_data; + StringInfoData object_name_data; + gsplsql_construct_non_empty_obj(obj_desc, &schema_name_data, &pkg_name_data, &object_name_data); + Relation relation = heap_open(DependenciesRelationId, RowExclusiveLock); + ScanKeyInit(&key, Anum_gs_dependencies_refobjoid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(ref_obj_oid)); + SysScanDesc scan = systable_beginscan(relation, DependenciesRefOidIndexId, true, SnapshotSelf, 1, &key); + while (HeapTupleIsValid(tuple = systable_getnext(scan))) { + Datum schema_name_datum = heap_getattr(tuple, Anum_gs_dependencies_schemaname, + RelationGetDescr(relation),&is_null); + AssertEreport(!is_null, MOD_PLSQL, "schemaName must not be null"); + Datum pkg_name_datum = heap_getattr(tuple, Anum_gs_dependencies_packagename, + RelationGetDescr(relation),&is_null); + AssertEreport(!is_null, MOD_PLSQL, "pkgName must not be null"); + Datum name_datum = heap_getattr(tuple, Anum_gs_dependencies_objectname, + RelationGetDescr(relation),&is_null); + AssertEreport(!is_null, MOD_PLSQL, "name must not be null"); + char* obj_name = TextDatumGetCString(name_datum); + if (0 != strcmp(schema_name_data.data, NameStr(*DatumGetName(schema_name_datum))) || + 0 != strcmp(pkg_name_data.data, NameStr(*DatumGetName(pkg_name_datum))) || + 0 != strcmp(object_name_data.data, obj_name)) { + pfree_ext(obj_name); + continue; + } + pfree_ext(obj_name); + Datum ref_obj_pos_datum = heap_getattr(tuple, Anum_gs_dependencies_refobjpos, + RelationGetDescr(relation),&is_null); + AssertEreport(!is_null, MOD_PLSQL, "refobjpos must not be null"); + if (obj_desc->refPosType == DatumGetInt32(ref_obj_pos_datum)) { + find = true; + break; + } + } + if (!find) { + gsplsql_insert_gs_dependency(relation, &schema_name_data, &pkg_name_data, &object_name_data, + obj_desc->refPosType, ref_obj_oid); + } + systable_endscan(scan); + heap_close(relation, RowExclusiveLock); + FreeStringInfo(&object_name_data); + return true; +} + +void gsplsql_invalidate_objs(Oid oid, bool is_ref_remove, Oid curr_compile_oid) +{ + Relation relation; + List* list = NIL; + List* list_tmp = NIL; + relation = heap_open(DependenciesRelationId, AccessShareLock); + list_tmp = gsplsql_search_gs_depend_rel_by_oid(relation, oid); + if (list_tmp == NULL) { + heap_close(relation, AccessShareLock); + return; + } + list = list_concat(list, list_tmp); + ListCell* cell = NULL; + foreach (cell, list) { + bool is_null = false; + GsDependObjDesc obj_desc; + gsplsql_init_gs_depend_obj_desc(&obj_desc); + HeapTuple tuple = (HeapTuple)lfirst(cell); + Datum schema_name_datum = heap_getattr(tuple, Anum_gs_dependencies_schemaname, + RelationGetDescr(relation), &is_null); + if (!is_null) { + obj_desc.schemaName = NameStr(*(DatumGetName(schema_name_datum))); + } + Datum package_name_datum = heap_getattr(tuple, Anum_gs_dependencies_packagename, + RelationGetDescr(relation), &is_null); + if (!is_null) { + obj_desc.packageName = NameStr(*(DatumGetName(package_name_datum))); + } + Datum obj_name_datum = heap_getattr(tuple, Anum_gs_dependencies_objectname, + RelationGetDescr(relation), &is_null); + if (!is_null) { + obj_desc.name = TextDatumGetCString(obj_name_datum); + } + Datum refobjpos_datum = heap_getattr(tuple, Anum_gs_dependencies_refobjpos, + RelationGetDescr(relation), &is_null); + if (!gsplsql_invalidate_obj(&obj_desc, refobjpos_datum, is_ref_remove, curr_compile_oid)) { + continue; + } + pfree_ext(obj_desc.name); + heap_freetuple(tuple); + } + list_free(list); + heap_close(relation, AccessShareLock); +} + +List *gsplsql_search_gs_depend_rel_by_oid(Relation relation, Oid ref_obj_oid) +{ + if (!OidIsValid(ref_obj_oid)) { + return NULL; + } + ScanKeyData key; + List* list = NIL; + HeapTuple tuple = NULL; + ScanKeyInit(&key, Anum_gs_dependencies_refobjoid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(ref_obj_oid)); + SysScanDesc scan = systable_beginscan(relation, DependenciesRefOidIndexId, true, SnapshotSelf, 1, &key); + while (HeapTupleIsValid(tuple = systable_getnext(scan))) { + list = lappend(list, heap_copytuple(tuple)); + } + systable_endscan(scan); + return list; +} + +DependenciesDatum* gsplsql_make_depend_datum_from_plsql_datum(const PLpgSQL_datum *datum, char** schema_name, + bool* depend_undefined) +{ + if (datum == NULL) { + *depend_undefined = true; + if (GetCurrCompilePgObjStatus()) { + ereport(WARNING, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("The dependent variable is undefined."))); + } + InvalidateCurrCompilePgObj(); + return (DependenciesDatum*)makeNode(DependenciesUndefined); + } + Oid namespaceOid = InvalidOid; + DependenciesDatum* ret = NULL; + switch (datum->dtype) { + case PLPGSQL_DTYPE_VAR: { + ret = gsplsql_make_var_depend_datum(datum, &namespaceOid, depend_undefined); + } break; + case PLPGSQL_DTYPE_RECORD: + case PLPGSQL_DTYPE_ROW: { + ret = gsplsql_make_row_var_depend_datum(datum, &namespaceOid, depend_undefined); + } break; + case PLPGSQL_DTYPE_REC: { + ret = gsplsql_make_record_var_depend_datum(datum, &namespaceOid, depend_undefined); + } break; + default: + return NULL; + } + return ret; +} + +bool gsplsql_check_type_depend_undefined(const char* schemaName, const char* pkg_name, const char* typname, bool isDeleteType) +{ + const GsDependObjDesc obj_desc = { + (char*)schemaName, (char*)pkg_name, (char*)typname, + GSDEPEND_OBJECT_TYPE_INVALID, GSDEPEND_REFOBJ_POS_IN_TYPE + }; + NameData schema_name_data; + NameData pkg_name_data; + StringInfoData object_name_data; + gsplsql_construct_non_empty_obj(&obj_desc, &schema_name_data, &pkg_name_data, &object_name_data); + int keyNum = 0; + ScanKeyData key[3]; + ScanKeyInit(&key[keyNum++], Anum_gs_dependencies_schemaname, BTEqualStrategyNumber, F_NAMEEQ, NameGetDatum(&schema_name_data)); + ScanKeyInit(&key[keyNum++], Anum_gs_dependencies_packagename, BTEqualStrategyNumber, F_NAMEEQ, NameGetDatum(&pkg_name_data)); + ScanKeyInit(&key[keyNum++], Anum_gs_dependencies_refobjpos, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(obj_desc.refPosType)); + DependenciesUndefined* undefinedNode = makeNode(DependenciesUndefined); + char* undefinedAst = nodeToString(undefinedNode); + pfree_ext(undefinedNode); + bool is_null = false; + bool hasUndefine = false; + HeapTuple tuple; + Relation dep_rel = heap_open(DependenciesRelationId, AccessShareLock); + Relation obj_rel = heap_open(DependenciesObjRelationId, AccessShareLock); + SysScanDesc scan = systable_beginscan(dep_rel, DependenciesNameIndexId, true, SnapshotSelf, keyNum, key); + while (HeapTupleIsValid(tuple = systable_getnext(scan))) { + Datum obj_datum_tmp = heap_getattr(tuple, Anum_gs_dependencies_objectname, + RelationGetDescr(dep_rel), &is_null); + char* obj_name_tmp = TextDatumGetCString(obj_datum_tmp); + Datum ref_obj_oid_datum = heap_getattr(tuple, Anum_gs_dependencies_refobjoid, + RelationGetDescr(dep_rel), &is_null); + if (isDeleteType) { + hasUndefine = gsplsql_check_type_depend_ast_equal(obj_rel, DatumGetObjectId(ref_obj_oid_datum), undefinedAst); + if (hasUndefine) { + gsplsql_delete_type(schemaName, pkg_name, obj_name_tmp); + } + } else if (object_name_data.data != NULL && strcmp(object_name_data.data, obj_name_tmp) == 0){ + hasUndefine = gsplsql_check_type_depend_ast_equal(obj_rel, DatumGetObjectId(ref_obj_oid_datum), undefinedAst); + if (hasUndefine) { + pfree_ext(obj_name_tmp); + break; + } + } + pfree_ext(obj_name_tmp); + } + systable_endscan(scan); + heap_close(dep_rel, AccessShareLock); + heap_close(obj_rel, AccessShareLock); + FreeStringInfo(&object_name_data); + pfree_ext(undefinedAst); + return hasUndefine; +} + +DependenciesDatum* gsplsql_make_depend_datum_by_type_oid(const Oid typOid, bool* depend_undefined) +{ + if (!get_typisdefined(typOid)) { + if (GetCurrCompilePgObjStatus()) { + ereport(WARNING, (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("Type %u does not exist.", typOid))); + } + InvalidateCurrCompilePgObj(); + *depend_undefined = true; + return (DependenciesDatum*)makeNode(DependenciesUndefined); + } + bool hasUndefined = false; + DependenciesType* typNode = gsplsql_make_dependencies_type(typOid); + if (typNode->typType == TYPTYPE_ENUM) { + typNode->attrInfo = SerializeEnumAttr(typOid); + } else if (typNode->typType == TYPTYPE_COMPOSITE) { + typNode->attrInfo = heap_serialize_row_attr(get_typ_typrelid(typOid), &hasUndefined); + if (hasUndefined) { + *depend_undefined = hasUndefined; + return (DependenciesDatum*)makeNode(DependenciesUndefined); + } + typNode->isRel = type_is_relation(typOid); + } else { + PLpgSQL_type* typ = NULL; + if (NULL == u_sess->plsql_cxt.curr_compile_context || + NULL == u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile) { + typ = plpgsql_build_datatype(typOid, -1, 0); + } else { + typ = plpgsql_build_datatype(typOid, -1, + u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile->fn_input_collation); + } + if (typNode->typType == TYPTYPE_TABLEOF) { + typNode->elemTypName = MakeTypeNamesStrForTypeOid(get_element_type(typ->typoid), &hasUndefined); + if (OidIsValid(typ->tableOfIndexType)) { + typNode->idxByTypName = MakeTypeNamesStrForTypeOid(typ->tableOfIndexType, &hasUndefined); + } + } else if (typNode->typType == TYPTYPE_BASE) { + if (typNode->typCategory == TYPCATEGORY_ARRAY) { + typNode->elemTypName = MakeTypeNamesStrForTypeOid(get_element_type(typ->typoid), &hasUndefined); + } + } + pfree_ext(typ); + if (hasUndefined) { + *depend_undefined = hasUndefined; + pfree_ext(typNode->elemTypName); + pfree_ext(typNode->idxByTypName); + pfree_ext(typNode); + return (DependenciesDatum*)makeNode(DependenciesUndefined); + } + } + return (DependenciesDatum*)typNode; +} + +static List* GetPkgFuncOids(Oid schemaOid, Oid pkgOid) +{ + HeapTuple tuple; + int keyNum = 0; + ScanKeyData key[2]; + ScanKeyInit(&key[keyNum++], Anum_pg_proc_pronamespace, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(schemaOid)); + ScanKeyInit(&key[keyNum++], Anum_pg_proc_packageid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(pkgOid)); + List* list = NIL; + Relation relation = heap_open(ProcedureRelationId, AccessShareLock); + SysScanDesc scan = systable_beginscan(relation, ProcedureNameAllArgsNspIndexId, true, NULL, keyNum, key); + while (HeapTupleIsValid(tuple = systable_getnext(scan))) { + list = lappend_oid(list, HeapTupleGetOid(tuple)); + } + systable_endscan(scan); + heap_close(relation, AccessShareLock); + return list; +} + +List* gsplsql_delete_objs(Relation relation, const GsDependObjDesc* obj_desc) +{ + NameData schema_name_data; + NameData pkg_name_data; + StringInfoData object_name_data; + gsplsql_construct_non_empty_obj(obj_desc, &schema_name_data, &pkg_name_data, &object_name_data); + if (obj_desc->refPosType == GSDEPEND_REFOBJ_POS_IN_PKGALL_OBJ) { + FreeStringInfo(&object_name_data); + } + int keyNum = 0; + ScanKeyData key[2]; + ScanKeyInit(&key[keyNum++], Anum_gs_dependencies_schemaname, BTEqualStrategyNumber, F_NAMEEQ, NameGetDatum(&schema_name_data)); + ScanKeyInit(&key[keyNum++], Anum_gs_dependencies_packagename, BTEqualStrategyNumber, F_NAMEEQ, NameGetDatum(&pkg_name_data)); + List* list = NIL; + HeapTuple tuple; + bool is_null; + SysScanDesc scan = systable_beginscan(relation, DependenciesNameIndexId, true, SnapshotSelf, keyNum, key); + while (HeapTupleIsValid(tuple = systable_getnext(scan))) { + Datum ref_pos_type_datum = heap_getattr(tuple, Anum_gs_dependencies_refobjpos, + RelationGetDescr(relation), &is_null); + if (!((DatumGetInt32(ref_pos_type_datum) & obj_desc->refPosType))) { + continue; + } + Datum obj_datum_tmp = heap_getattr(tuple, Anum_gs_dependencies_objectname, + RelationGetDescr(relation), &is_null); + char* obj_name_tmp = TextDatumGetCString(obj_datum_tmp); + if (object_name_data.data != NULL && 0 != strcmp(object_name_data.data, obj_name_tmp)) { + pfree_ext(obj_name_tmp); + continue; + } + pfree_ext(obj_name_tmp); + Datum ref_obj_oid_datum = heap_getattr(tuple, Anum_gs_dependencies_refobjoid, + RelationGetDescr(relation), &is_null); + if (!list_member_oid(list, DatumGetObjectId(ref_obj_oid_datum))) { + list = lappend_oid(list, DatumGetObjectId(ref_obj_oid_datum)); + } + simple_heap_delete(relation, &tuple->t_self, 0, true); + } + systable_endscan(scan); + FreeStringInfo(&object_name_data); + CommandCounterIncrement(); + return list; +} + +void gsplsql_make_desc_from_gs_dependencies_tuple(HeapTuple gs_depend_tuple, TupleDesc tup_desc, + GsDependObjDesc *obj_desc) +{ + bool is_null = false; + Datum schema_name_datum = heap_getattr(gs_depend_tuple, Anum_gs_dependencies_schemaname, tup_desc, &is_null); + AssertEreport(!is_null, MOD_PLSQL, "schema name must not be null."); + obj_desc->schemaName = NameStr(*(DatumGetName(schema_name_datum))); + Datum package_name_datum = heap_getattr(gs_depend_tuple, Anum_gs_dependencies_packagename, tup_desc, &is_null); + if (!is_null) { + obj_desc->packageName = NameStr(*(DatumGetName(package_name_datum))); + } + Datum obj_name_datum = heap_getattr(gs_depend_tuple, Anum_gs_dependencies_objectname, tup_desc, &is_null); + AssertEreport(!is_null, MOD_PLSQL, "object name must not be null."); + obj_desc->name = TextDatumGetCString(obj_name_datum); + Datum refobjpos_datum = heap_getattr(gs_depend_tuple, Anum_gs_dependencies_refobjpos, tup_desc, &is_null); + AssertEreport(!is_null, MOD_PLSQL, "refobjpos must not be null."); + obj_desc->refPosType = DatumGetInt32(refobjpos_datum); +} + +void gsplsql_prepare_gs_depend_for_pkg_compile(PLpgSQL_package* pkg, bool isCreate) +{ + if (pkg == NULL) { + return; + } + AssertEreport(!pkg->preRefObjectOidList, MOD_PLSQL, "preRefObjectOidList must not be null."); + AssertEreport(!pkg->preSelfObjectList, MOD_PLSQL, "preSelfObjectList must not be null."); + char* schema_name =get_namespace_name(pkg->namespaceOid); + (void)gsplsql_check_type_depend_undefined(schema_name, pkg->pkg_signature, NULL, true); + Relation relation = heap_open(DependenciesRelationId, RowExclusiveLock); + GsDependObjDesc obj_desc = { + schema_name, + pkg->pkg_signature, + NULL, + GSDEPEND_OBJECT_TYPE_INVALID, + isCreate ? GSDEPEND_REFOBJ_POS_IN_PKGALL_OBJ : GSDEPEND_REFOBJ_POS_IN_PKGRECOMPILE_OBJ + }; + pkg->preRefObjectOidList = gsplsql_delete_objs(relation, &obj_desc); + heap_close(relation, RowExclusiveLock); + pkg->preSelfObjectList = gsplsql_get_depend_obj_list_by_specified_pkg(schema_name, pkg->pkg_signature, + isCreate ? GSDEPEND_OBJECT_TYPE_PKG : GSDEPEND_OBJECT_TYPE_PKG_RECOMPILE); + pfree_ext(schema_name); +} + +void gsplsql_complete_gs_depend_for_pkg_compile(PLpgSQL_package* pkg, bool isCreate, bool isRecompile) +{ + if (pkg == NULL) { + return; + } + complete_process_variables(pkg, isCreate, isRecompile); + ListCell* lc = NULL; + List* tmp_pre_self_obj_list = list_copy(pkg->preSelfObjectList); + List* tmp_pre_ref_obj_oid_list = list_copy(pkg->preRefObjectOidList); + list_free_ext(pkg->preSelfObjectList); + list_free_ext(pkg->preRefObjectOidList); + Oid pkg_oid = pkg->pkg_oid; + foreach (lc, tmp_pre_self_obj_list) { + Oid ref_obj_oid = lfirst_oid(lc); + gsplsql_remove_depend_obj_by_specified_oid(ref_obj_oid, pkg_oid, list_member_oid(tmp_pre_ref_obj_oid_list, ref_obj_oid)); + } + gsplsql_delete_unrefer_depend_obj_in_list(tmp_pre_ref_obj_oid_list, false); + list_free_ext(tmp_pre_self_obj_list); + list_free_ext(tmp_pre_ref_obj_oid_list); +} + +bool gsplsql_parse_type_and_name_from_gsplsql_datum(const PLpgSQL_datum* datum, char** datum_name, + GsDependObjectType* datum_type) +{ + switch (datum->dtype) { + case PLPGSQL_DTYPE_VAR: { + PLpgSQL_var* var = (PLpgSQL_var*)datum; + *datum_name = var->refname; + *datum_type = GSDEPEND_OBJECT_TYPE_VARIABLE; + return var->addNamespace; + } break; + case PLPGSQL_DTYPE_RECORD: + case PLPGSQL_DTYPE_ROW: { + PLpgSQL_row* row = (PLpgSQL_row*)datum; + *datum_name = row->refname; + *datum_type = GSDEPEND_OBJECT_TYPE_VARIABLE; + return row->addNamespace; + } break; + case PLPGSQL_DTYPE_REC: { + PLpgSQL_rec* rec = (PLpgSQL_rec*)datum; + *datum_name = rec->refname; + *datum_type = GSDEPEND_OBJECT_TYPE_VARIABLE; + return rec->addNamespace; + } break; + default: + return false; + } + return true; +} + +Oid gsplsql_parse_pkg_var_obj4(GsDependObjDesc* obj, List* var_name) +{ + ListCell* attr_list = NULL; + Oid oid = gsplsql_parse_pkg_var_and_attrs4(obj, var_name, &attr_list); + return oid; +} + +/* + * static function + */ +static inline void gsplsql_delete_type(const char *schemaName, const char *pkgName, char *typName) +{ + ObjectAddress address; + Oid typeOid = TypeNameGetOid(schemaName, pkgName, typName); + address.classId = TypeRelationId; + address.objectId = typeOid; + address.objectSubId = 0; + HeapTuple tuple = SearchSysCache1((int)TYPEOID, ObjectIdGetDatum(typeOid)); + if (HeapTupleIsValid(tuple)) { + performDeletion(&address, DROP_CASCADE, PERFORM_DELETION_INTERNAL); + ReleaseSysCache(tuple); + } +} + +static inline bool gsplsql_invalidate_func(Oid func_oid, Oid curr_compile_oid) +{ + if (!OidIsValid(func_oid) || func_oid == curr_compile_oid) { + return false; + } + return SetPgObjectValid(func_oid, OBJECT_TYPE_PROC, false); +} + +static bool gsplsql_invalidate_pkg(const char *schemaName, const char *pkgName, bool isSpec, Oid currCompileOid) +{ + Oid schemaOid = get_namespace_oid(schemaName, true); + Oid pkgOid = InvalidOid; + if (pkgName != NULL) { + pkgOid = PackageNameGetOid(pkgName, schemaOid); + } + if (!OidIsValid(pkgOid) || pkgOid == currCompileOid) { + return false; + } + bool result = false; + if (isSpec) { + result = SetPgObjectValid(pkgOid, OBJECT_TYPE_PKGSPEC, false) || result; + } + result = SetPgObjectValid(pkgOid, OBJECT_TYPE_PKGBODY, false) || result; + result = gsplsql_set_pkg_func_status(schemaOid, pkgOid, false) || result; + return result; +} + +static bool gsplsql_invalidate_obj(GsDependObjDesc* obj, Datum refobjpos_datum, + bool is_ref_remove, Oid curr_compile_oid) +{ + if (obj->schemaName == NULL || obj->name == NULL) { + return false; + } + int ref_pos = DatumGetInt32(refobjpos_datum); + switch (ref_pos) { + case GSDEPEND_REFOBJ_POS_IN_TYPE: + if (obj->packageName != NULL && strcmp(obj->packageName, "null") != 0) { + return gsplsql_invalidate_pkg(obj->schemaName, obj->packageName, true, curr_compile_oid); + } + break; + case GSDEPEND_REFOBJ_POS_IN_PKGSPEC: + return gsplsql_invalidate_pkg(obj->schemaName, obj->packageName, true, curr_compile_oid); + case GSDEPEND_REFOBJ_POS_IN_PKGBODY: + return gsplsql_invalidate_pkg(obj->schemaName, obj->packageName, false, curr_compile_oid); + case GSDEPEND_REFOBJ_POS_IN_PROCHEAD: + case GSDEPEND_REFOBJ_POS_IN_PROCBODY: { + Oid func_oid = gsplsql_get_proc_oid(obj->schemaName, obj->packageName, obj->name); + HeapTuple tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(func_oid)); + if (!HeapTupleIsValid(tuple)) { + return false; + } + bool is_null = false; + Datum proisprivate_datum = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_proisprivate, &is_null); + if (is_null) { + proisprivate_datum = BoolGetDatum(false); + } + ReleaseSysCache(tuple); + if (obj->packageName == NULL || strcmp(obj->packageName, "null") == 0) { + return gsplsql_invalidate_func(func_oid, curr_compile_oid); + } else if (DatumGetBool(proisprivate_datum)) { + return gsplsql_invalidate_pkg(obj->schemaName, obj->packageName, false, curr_compile_oid); //pkg body + } else { + return gsplsql_invalidate_pkg(obj->schemaName, obj->packageName, true, curr_compile_oid); + } + } + default: + return false; + } + return false; +} + +static bool gsplsql_check_var_attrs(PLpgSQL_datum *datum, ListCell *attr_list) +{ + if (attr_list == NULL) { + return true; + } + char* first_attr_str = strVal(lfirst(attr_list)); + if (first_attr_str == NULL) { + return true; + } + switch (datum->dtype) { + case PLPGSQL_DTYPE_VAR: { + return false; + } break; + case PLPGSQL_DTYPE_RECORD: { + PLpgSQL_row* row = (PLpgSQL_row*)datum; + for (int i = 0; i < row->nfields; i++) { + if (row->fieldnames[i] != NULL && strcmp(first_attr_str, row->fieldnames[i]) == 0) { + return true; + } + } + return false; + } break; + case PLPGSQL_DTYPE_ROW: { + PLpgSQL_row* row = (PLpgSQL_row*)datum; + if (row->rowtupdesc == NULL) { + return false; + } + for (int i = 0; i < row->rowtupdesc->natts; i++) { + if (strcmp(first_attr_str, row->rowtupdesc->attrs[i].attname.data) == 0) { + return true; + } + } + return false; + } break; + case PLPGSQL_DTYPE_REC: { + PLpgSQL_rec* rec = (PLpgSQL_rec*)datum; + if (rec->tupdesc == NULL) { + return false; + } + for (int i = 0; i < rec->tupdesc->natts; i++) { + if (strcmp(first_attr_str, rec->tupdesc->attrs[i].attname.data) == 0) { + return true; + } + } + return false; + } break; + default: + return true; + } +} + +static void gsplsql_insert_gs_dependency(Relation relation, NameData* schema_name_data, + NameData* pkg_name_data, StringInfo object_name, + int ref_obj_pos, Oid ref_obj_oid) +{ + Datum values[Natts_gs_dependencies]; + bool nulls[Natts_gs_dependencies] = {false}; + values[Anum_gs_dependencies_schemaname - 1] = NameGetDatum(schema_name_data); + values[Anum_gs_dependencies_packagename - 1] = NameGetDatum(pkg_name_data); + values[Anum_gs_dependencies_objectname - 1] = CStringGetTextDatum(object_name->data); + values[Anum_gs_dependencies_refobjpos - 1] = NameGetDatum(ref_obj_pos); + values[Anum_gs_dependencies_refobjoid - 1] = NameGetDatum(ref_obj_oid); + HeapTuple tup = heap_form_tuple(RelationGetDescr(relation), values, nulls); + (void)simple_heap_insert(relation, tup); + CatalogUpdateIndexes(relation, tup); + heap_freetuple(tup); +} + +static inline void gsplsql_free_var_mem_for_gs_dependencies(GsDependObjDesc* obj) +{ + pfree_ext(obj->schemaName); + pfree_ext(obj->packageName); + pfree_ext(obj->name); +} + +static inline bool gsplsql_is_proc_head_depend_type(const GsDependObjDesc* obj_desc, const GsDependObjDesc* ref_obj_desc) +{ + return obj_desc->refPosType == GSDEPEND_REFOBJ_POS_IN_PROCHEAD && ref_obj_desc->type == GSDEPEND_OBJECT_TYPE_TYPE; +} + +static inline Oid gsplsql_parse_pkg_var_obj2(GsDependObjDesc* obj, ListCell* var_name) +{ + Oid schema_oid = get_compiled_object_nspoid(); + obj->schemaName = get_namespace_name(schema_oid); + obj->packageName = pstrdup(strVal(lfirst(var_name))); + obj->name= pstrdup(strVal(lfirst(lnext(var_name)))); + return schema_oid; +} + +static inline Oid gsplsql_parse_pkg_var_and_attrs3(GsDependObjDesc* obj, ListCell* var_name, ListCell** attr_list) +{ + Oid schema_oid = InvalidOid; + char* first_str = strVal(lfirst(var_name)); + schema_oid = get_namespace_oid(first_str, true); + if (!OidIsValid(schema_oid)) { + *attr_list = lnext(lnext(var_name)); + return gsplsql_parse_pkg_var_obj2(obj, var_name); + } + obj->schemaName = pstrdup(strVal(lfirst(var_name))); + obj->packageName = pstrdup(strVal(lfirst(lnext(var_name)))); + obj->name= pstrdup(strVal(lfirst(lnext(lnext(var_name))))); + schema_oid = get_namespace_oid(obj->schemaName, true); + return schema_oid; +} + +static inline Oid gsplsql_parse_pkg_var_and_attrs4(GsDependObjDesc* obj, List* var_name, ListCell** attr_list) +{ + Oid schema_oid = InvalidOid; + char* first_str = strVal(linitial(var_name)); + schema_oid = get_namespace_oid(first_str, true); + if (OidIsValid(schema_oid)) { //schema.pkg.row.col + *attr_list = list_nth_cell(var_name, 3); // 3->attr start location + return gsplsql_parse_pkg_var_and_attrs3(obj, list_head(var_name), attr_list); + } else if (IsExistPackageName(first_str)) { //pkg.var.attr.attr + *attr_list = list_nth_cell(var_name, 2); // 2->attr start location + return gsplsql_parse_pkg_var_obj2(obj, list_head(var_name)); + } else { + //check catalog name and then ignore it + char* dbname = get_database_name(u_sess->proc_cxt.MyDatabaseId); + if (dbname == NULL || strcmp(first_str, dbname) != 0) { + ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("Cross-database references are not implemented: \"%s\".", NameListToString(var_name)))); + } + char* second_str = strVal(lsecond(var_name)); + schema_oid = get_namespace_oid(second_str, true); + if (OidIsValid(schema_oid)) { // db.schema.pkg.var + obj->schemaName = pstrdup(strVal(lsecond(var_name))); + obj->packageName = pstrdup(strVal(lthird(var_name))); + obj->name= pstrdup(strVal(lfourth(var_name))); + return schema_oid; + } + } + return schema_oid; +} + +static void do_complete_process_variables(PLpgSQL_package* pkg, bool isCreate, bool isRecompile, PLpgSQL_datum* datum) +{ + if (isCreate || isRecompile) { + (void)gsplsql_build_ref_dependency(pkg->namespaceOid, datum, pkg->pkg_signature, + NULL != pkg->preSelfObjectList ? &pkg->preSelfObjectList : NULL, pkg->pkg_oid); + } else { + GsDependObjDesc ref_obj_desc; + gsplsql_init_gs_depend_obj_desc(&ref_obj_desc); + bool succeed = gsplsql_parse_type_and_name_from_gsplsql_datum(datum, &ref_obj_desc.name, &ref_obj_desc.type); + if (!succeed) { + return; + } + ref_obj_desc.schemaName = get_namespace_name(pkg->namespaceOid); + ref_obj_desc.packageName = (char*)pkg->pkg_signature; + ref_obj_desc.type = GSDEPEND_OBJECT_TYPE_TYPE; + HeapTuple tuple = gsplsql_search_object(&ref_obj_desc, true); + if (!HeapTupleIsValid(tuple)) { + return; + } + Oid refObjOid = HeapTupleGetOid(tuple); + heap_freetuple(tuple); + pkg->preSelfObjectList = list_delete_oid(pkg->preSelfObjectList, refObjOid); + } +} + +static void complete_process_variables(PLpgSQL_package* pkg, bool isCreate, bool isRecompile) +{ + for (int i = 0; i < pkg->ndatums; i++) { + PLpgSQL_datum* datum = pkg->datums[i]; + if (datumIsVariable(datum)) { + do_complete_process_variables(pkg, isCreate, isRecompile, datum); + } + } +} + +static Oid gsplsql_parse_exist_pkg_and_build_obj_desc(GsDependObjDesc* obj, List* var_name, ListCell** attr_list) +{ + Oid schema_oid = InvalidOid; + int length = list_length(var_name); + if (length == 2) { // pkg.var + schema_oid = gsplsql_parse_pkg_var_obj2(obj, list_head(var_name)); + } else if (length == 3) { //schema.pkg.var + schema_oid = gsplsql_parse_pkg_var_and_attrs3(obj, list_head(var_name), attr_list); + } else if (length == 4) { // a.b.c.d + schema_oid = gsplsql_parse_pkg_var_and_attrs4(obj, var_name, attr_list); + } else { + ereport(WARNING, (errmodule(MOD_PLSQL), errcode(ERRCODE_NONEXISTANT_VARIABLE), + errmsg("Unrecognized package variable."))); + return InvalidOid; + } + obj->type = GSDEPEND_OBJECT_TYPE_VARIABLE; + if (!OidIsValid(schema_oid)) { + return InvalidOid; + } + Oid pkg_oid = PackageNameGetOid(obj->packageName, schema_oid); + if (NULL != u_sess->plsql_cxt.curr_compile_context && + NULL != u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package) { + if (pkg_oid == u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package->pkg_oid) { + return InvalidOid; + } + } + return pkg_oid; +} + +static bool datumIsVariable(PLpgSQL_datum* datum) +{ + switch (datum->dtype) { + case PLPGSQL_DTYPE_VAR: + case PLPGSQL_DTYPE_ROW: + case PLPGSQL_DTYPE_REC: + case PLPGSQL_DTYPE_RECORD: + return true; + default: + break; + } + return false; +} + +static DependenciesType *gsplsql_make_dependencies_type(Oid typOid) +{ + DependenciesType* typNode = makeNode(DependenciesType); + typNode->typType = get_typtype(typOid); + typNode->typCategory = get_typecategory(typOid); + typNode->isRel = false; + typNode->attrInfo = NULL; + typNode->elemTypName = NULL; + typNode->idxByTypName = NULL; + return typNode; +} + +static DependenciesDatum *gsplsql_make_record_var_depend_datum(const PLpgSQL_datum *datum, Oid *namespace_oid, bool *depend_undefined) +{ + DependenciesVariable* var_node = makeNode(DependenciesVariable); + PLpgSQL_rec* rec = (PLpgSQL_rec*)datum; + Oid typOid = InvalidOid; + if (rec->tupdesc == NULL) { + return NULL; + } + var_node->typName = MakeTypeNamesStrForTypeOid(typOid, depend_undefined); + if (*depend_undefined) { + pfree_ext(var_node->typName); + return (DependenciesDatum*)makeNode(DependenciesUndefined); + } + var_node->typMod = rec->tupdesc->tdtypmod; + var_node->extraInfo = NULL; + if (NULL != rec->pkg) { + *namespace_oid = rec->pkg->namespaceOid; + } + return (DependenciesDatum*)var_node; +} +static DependenciesDatum *gsplsql_make_row_var_depend_datum(const PLpgSQL_datum *datum, Oid *namespace_oid, bool *depend_undefined) +{ + DependenciesVariable* var_node = makeNode(DependenciesVariable); + PLpgSQL_row* row = (PLpgSQL_row*)datum; + Oid typOid = InvalidOid; + if (row->rowtupdesc == NULL) { + return NULL; + } + if (datum->dtype == PLPGSQL_DTYPE_ROW) { + typOid = row->rowtupdesc->tdtypeid; + } else { + typOid = row->recordVarTypOid; + } + if (!OidIsValid(typOid)) { + return NULL; + } + var_node->typName = MakeTypeNamesStrForTypeOid(typOid, depend_undefined); + if (*depend_undefined) { + pfree_ext(var_node->typName); + return (DependenciesDatum*)makeNode(DependenciesUndefined); + } + var_node->typMod = row->rowtupdesc->tdtypmod; + var_node->extraInfo = NULL; + if (NULL != row->pkg) { + *namespace_oid = row->pkg->namespaceOid; + } + return (DependenciesDatum*)var_node; +} +static DependenciesDatum *gsplsql_make_var_depend_datum(const PLpgSQL_datum *datum, Oid *namespace_oid, bool *depend_undefined) +{ + DependenciesVariable* var_node = makeNode(DependenciesVariable); + PLpgSQL_var* var = (PLpgSQL_var*)datum; + if (var->datatype == NULL) { + return NULL; + } + var_node->typName = MakeTypeNamesStrForTypeOid(var->datatype->typoid, depend_undefined); + if (*depend_undefined) { + pfree_ext(var_node->typName); + return (DependenciesDatum*)makeNode(DependenciesUndefined); + } + var_node->typMod = var->datatype->atttypmod; + if (var->cursor_explicit_expr != NULL && var->cursor_explicit_expr->query != NULL) { + var_node->extraInfo = pstrdup(var->cursor_explicit_expr->query); + } + if (NULL != var->pkg) { + *namespace_oid = var->pkg->namespaceOid; + } + return (DependenciesDatum*)var_node; +} diff --git a/src/common/backend/utils/gsplsql/gsobject_dependencies.cpp b/src/common/backend/utils/gsplsql/gsobject_dependencies.cpp new file mode 100644 index 000000000..ee5c23a4e --- /dev/null +++ b/src/common/backend/utils/gsplsql/gsobject_dependencies.cpp @@ -0,0 +1,1529 @@ +/* +* Copyright (c) 2021 Huawei Technologies Co.,Ltd. +* +* openGauss is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +* --------------------------------------------------------------------------------------- +* +* gsobject_gsdependencies.cpp +* +* +* IDENTIFICATION +* src/common/backend/utils/gsplsql/gsobject_gsdependencies.cpp +* +* --------------------------------------------------------------------------------------- + */ +/* +* Copyright (c) 2021 Huawei Technologies Co.,Ltd. +* +* openGauss is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +* --------------------------------------------------------------------------------------- +* +* gsobject_gsdependencies.cpp +* +* +* IDENTIFICATION +* src/common/backend/utils/gsplsql/gsobject_gsdependencies.cpp +* +* --------------------------------------------------------------------------------------- + */ + +#include "utils/plpgsql.h" +#include "catalog/gs_dependencies_fn.h" +#include "utils/lsyscache.h" +#include "utils/pl_package.h" +#include "catalog/gs_package.h" +#include "catalog/pg_synonym.h" +#include "catalog/pg_proc.h" +#include "utils/fmgroids.h" +#include "catalog/gs_dependencies.h" +#include "catalog/gs_dependencies_obj.h" +#include "catalog/indexing.h" +#include "utils/builtins.h" +#include "catalog/pg_proc_fn.h" +#include "catalog/pg_object.h" +#include "access/sysattr.h" +#include "catalog/pg_type_fn.h" +#include "libpq/md5.h" +#include "catalog/dependency.h" +#include "utils/lsyscache.h" +#include "parser/parse_type.h" + +static void gsplsql_update_ref_dep_obj_base_on_ast(const GsDependObjDesc *ref_obj_desc, HeapTuple obj_tuple, + char *ref_obj_ast_str, bool ast_changed); +static Oid gsplsql_get_curr_compile_oid(); +static void gsplsql_do_ref_obj_affect_oper(const GsDependObjDesc *ref_obj_desc, Relation gs_depend_rel, List *list, + bool pre_undefined, bool ast_changed); +static void gsplsql_cascade_delete_type_by_type_name(GsDependObjDesc *obj_desc); +static void gsplsql_refresh_proc_header(Oid ref_obj_oid); +static void gsplsql_delete_dependencies_object_by_oid(Oid oid); +static bool gsplsql_update_proc_header(CreateFunctionStmt *stmt, Oid funcid); +static void gsplsql_rename_func_name(const char *nsp_name, const char *pkg_name, const char *old_func_name, + const char *new_func_name); +static void gsplsql_obj_func_name(const char *nsp_name, const char *pkg_name, const char *old_func_name, + const char *new_func_name); + +static bool is_proc_info_changed(Oid funcid, oidvector *new_parameter_types, ArrayType *new_all_parameter_types, + char *new_parameter_defaults, Oid new_prorettype, bool new_returnsset); +static inline void gsplsql_delete_ref_obj_from_pkg(Oid ref_obj_oid); + +bool gsplsql_is_undefined_func(Oid func_oid) +{ + GsDependObjDesc obj; + Form_pg_proc procForm = NULL; + gsplsql_init_gs_depend_obj_desc(&obj); + HeapTuple tup = SearchSysCache1(PROCOID, ObjectIdGetDatum(func_oid)); + if (!HeapTupleIsValid(tup)) { + return true; + } + procForm = (Form_pg_proc)GETSTRUCT(tup); + bool is_null; + Datum proPackageIdDatum = SysCacheGetAttr(PROCOID, tup, Anum_pg_proc_packageid, &is_null); + Oid proPackageId = DatumGetObjectId(proPackageIdDatum); + obj = gsplsql_construct_func_head_obj(func_oid, procForm->pronamespace, proPackageId); + obj.type = GSDEPEND_OBJECT_TYPE_PROCHEAD; + ReleaseSysCache(tup); + HeapTuple obj_tuple = gsplsql_search_object(&obj, false); + if (!HeapTupleIsValid(obj_tuple)) { + return false; + } + Datum ast_datum = gsplsql_get_depend_object_attr(obj_tuple, Anum_gs_dependencies_obj_objnode, &is_null); + if (is_null) { + return false; + } + char* ast_str = TextDatumGetCString(ast_datum); + DependenciesProchead* ast_node = (DependenciesProchead*)stringToNode(ast_str); + if (ast_node == NULL) { + pfree_ext(ast_str); + return true; + } + pfree_ext(ast_str); + heap_freetuple(obj_tuple); + pfree_ext(obj.name); + pfree_ext(obj.schemaName); + return ast_node->undefined; +} + +void gsplsql_delete_unrefer_depend_obj_oid(Oid ref_obj_oid, bool skip_in_use) +{ + if (!OidIsValid(ref_obj_oid) || + (skip_in_use && list_member_oid(u_sess->plsql_cxt.usindDependObjOids, ref_obj_oid))) { + return; + } + Relation rel; + ScanKeyData key; + rel = heap_open(DependenciesRelationId, AccessShareLock); + ScanKeyInit(&key, Anum_gs_dependencies_refobjoid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(ref_obj_oid)); + SysScanDesc scan = systable_beginscan(rel, DependenciesRefOidIndexId, true, SnapshotSelf, 1, &key); + HeapTuple tuple = systable_getnext(scan); + if (!HeapTupleIsValid(tuple)) { + gsplsql_delete_dependencies_object_by_oid(ref_obj_oid); + } + systable_endscan(scan); + heap_close(rel, AccessShareLock); +} + +bool gsplsql_search_depend_obj_by_oid(Oid oid, GsDependObjDesc* obj_desc) +{ + bool is_null = false; + HeapTuple tuple = NULL; + Relation relation; + const int keyNum = 1; + ScanKeyData key[keyNum]; + SysScanDesc scan = NULL; + ScanKeyInit(&key[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(oid)); + relation = heap_open(DependenciesObjRelationId, AccessShareLock); + scan = systable_beginscan(relation, DependenciesObjOidIndexId, true, SnapshotSelf, keyNum, key); + tuple = systable_getnext(scan); + if (HeapTupleIsValid(tuple)) { + Datum schemaNameDatum = heap_getattr(tuple, Anum_gs_dependencies_obj_schemaname, + RelationGetDescr(relation), &is_null); + Datum pkgNameDatum = heap_getattr(tuple, Anum_gs_dependencies_obj_packagename, + RelationGetDescr(relation), &is_null); + Datum nameDatum = heap_getattr(tuple, Anum_gs_dependencies_obj_name, + RelationGetDescr(relation), &is_null); + obj_desc->schemaName = pstrdup(DatumGetName(schemaNameDatum)->data); + obj_desc->packageName = DatumGetName(pkgNameDatum)->data; + if (0 == strcmp(obj_desc->packageName, "null")) { + obj_desc->packageName = NULL; + } else { + obj_desc->packageName = pstrdup(obj_desc->packageName); + } + char* nameStr= TextDatumGetCString(nameDatum); + obj_desc->name = pstrdup(nameStr); + pfree_ext(nameStr); + systable_endscan(scan); + heap_close(relation, AccessShareLock); + return true; + } + systable_endscan(scan); + heap_close(relation, AccessShareLock); + return false; +} + +HeapTuple gsplsql_search_object_by_name(const char* schema_name, const char* package_name, + const char* object_name, GsDependObjectType type) +{ + GsDependObjDesc object; + object.schemaName = (char*)schema_name; + object.packageName = (char*)package_name; + object.name = (char*)object_name; + object.type = type; + object.refPosType = GSDEPEND_REFOBJ_POS_INVALID; + return gsplsql_search_object(&object, false); +} + +HeapTuple gsplsql_search_object(const GsDependObjDesc* obj_desc, bool supp_undef_type) +{ + NameData schema_name_data; + NameData pkg_name_data; + StringInfoData object_name_data; + gsplsql_construct_non_empty_obj(obj_desc, &schema_name_data, &pkg_name_data, &object_name_data); + int keyNum = 0; + ScanKeyData key[3]; + ScanKeyInit(&key[keyNum++], Anum_gs_dependencies_obj_schemaname, BTEqualStrategyNumber, F_NAMEEQ, NameGetDatum(&schema_name_data)); + ScanKeyInit(&key[keyNum++], Anum_gs_dependencies_obj_packagename, BTEqualStrategyNumber, F_NAMEEQ, NameGetDatum(&pkg_name_data)); + ScanKeyInit(&key[keyNum++], Anum_gs_dependencies_obj_type, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(obj_desc->type)); + Relation relation = heap_open(DependenciesObjRelationId, AccessShareLock); + SysScanDesc scan = systable_beginscan(relation, DependenciesObjNameIndexId, true, SnapshotSelf, keyNum, key); + HeapTuple tuple; + HeapTuple retTuple = NULL; + /* compare the first partition'delta with main table */ + while (HeapTupleIsValid(tuple = systable_getnext(scan))) { + bool is_null; + Datum datum = heap_getattr(tuple, Anum_gs_dependencies_obj_name, + RelationGetDescr(relation), &is_null); + if (is_null) { + continue; + } + char* obj_name = TextDatumGetCString(datum); + if (0 == strcmp(object_name_data.data, obj_name)) { + retTuple = heap_copytuple(tuple); + pfree_ext(obj_name); + break; + } + pfree_ext(obj_name); + } + systable_endscan(scan); + heap_close(relation, AccessShareLock); + FreeStringInfo(&object_name_data); + if (!HeapTupleIsValid(retTuple) && supp_undef_type) { + retTuple = gsplsql_search_object_by_name(obj_desc->schemaName, obj_desc->packageName, + obj_desc->name, GSDEPEND_OBJECT_TYPE_UNDEFIND); + } + return retTuple; +} + +Datum gsplsql_get_depend_object_attr(HeapTuple tup, int attr_number, bool *is_null) +{ + Relation relation = heap_open(DependenciesObjRelationId, AccessShareLock); + Datum datum = heap_getattr(tup, attr_number, RelationGetDescr(relation), is_null); + heap_close(relation, AccessShareLock); + return datum; +} + +List* gsplsql_prepare_recompile_func(Oid func_oid, Oid schema_oid, Oid pkg_oid, bool is_recompile) +{ + if (!is_recompile || OidIsValid(pkg_oid)) { + return NULL; + } + if (!enable_plpgsql_gsdependency()) { + return NULL; + } + GsDependObjDesc obj_desc = gsplsql_construct_func_head_obj(func_oid, schema_oid, pkg_oid); + obj_desc.type = GSDEPEND_OBJECT_TYPE_FUNCTION; + obj_desc.refPosType = GSDEPEND_REFOBJ_POS_IN_PROCBODY; + Relation rel = heap_open(DependenciesRelationId, RowExclusiveLock); + List* list = gsplsql_delete_objs(rel, &obj_desc); + heap_close(rel, RowExclusiveLock); + return list; +} + +void gsplsql_complete_recompile_func(List* list) +{ + if (list == NULL) { + return; + } + if (!enable_plpgsql_gsdependency()) { + return; + } + gsplsql_delete_unrefer_depend_obj_in_list(list, false); + list_free(list); +} + +Oid gsplsql_get_pkg_oid_by_func_oid(Oid func_oid) +{ + HeapTuple tuple = SearchSysCache((int)PROCOID, ObjectIdGetDatum(func_oid), 0, 0, 0); + if (!HeapTupleIsValid(tuple)) { + return InvalidOid; + } + bool is_null; + Datum packageOidDatum = SysCacheGetAttr((int)PROCOID, tuple, Anum_pg_proc_packageid, &is_null); + Oid pkg_oid = DatumGetObjectId(packageOidDatum); + ReleaseSysCache(tuple); + return pkg_oid; +} + +Oid gsplsql_get_proc_oid(const char* schemaName, const char* packageName, const char* name) +{ + Oid expected_nsp_oid = GetSysCacheOid1(NAMESPACENAME, CStringGetDatum(schemaName)); + Oid expected_pkg_oid = InvalidOid; + if (packageName != NULL) { + expected_pkg_oid = GetSysCacheOid2(PKGNAMENSP, CStringGetDatum(packageName), ObjectIdGetDatum(expected_nsp_oid)); + } + HeapTuple proc_tup = NULL; + bool is_null = false; + Form_pg_proc proc_form = NULL; + const char* leftBracketPos = strchr(name, '('); + if (leftBracketPos == NULL) { + return InvalidOid; + } + StringInfoData procNameStr; + initStringInfo(&procNameStr); + appendBinaryStringInfo(&procNameStr, name, leftBracketPos - name); + CatCList* catlist; + catlist = SearchSysCacheList1(PROCNAMEARGSNSP, CStringGetDatum(procNameStr.data)); + for (int i = 0; i < catlist->n_members; i++) { + proc_tup = t_thrd.lsc_cxt.FetchTupleFromCatCList(catlist, i); + if (HeapTupleIsValid(proc_tup)) { + proc_form = (Form_pg_proc)GETSTRUCT(proc_tup); + if (proc_form->pronamespace != expected_nsp_oid) { + continue; + } + Datum proPackageIdDatum = SysCacheGetAttr(PROCOID, proc_tup, Anum_pg_proc_packageid, &is_null); + Oid proPackageId = DatumGetObjectId(proPackageIdDatum); + if (proPackageId != expected_pkg_oid) { + continue; + } + Oid proc_oid = HeapTupleGetOid(proc_tup); + char* dbFuncHeadName = format_procedure_no_visible(proc_oid); + if (strcmp(name, dbFuncHeadName) == 0) { + ReleaseSysCacheList(catlist); + return proc_oid; + } + } + } + ReleaseSysCacheList(catlist); + FreeStringInfo(&procNameStr); + ereport(ERROR, (errmodule(MOD_PLSQL), errmsg("function %s does not exist", name))); + return InvalidOid; +} + +Oid gsplsql_get_proc_oid(const char* schemaName, const char* packageName, const char* name, const char* proc_arg_src) +{ + Oid expected_nsp_oid = GetSysCacheOid1(NAMESPACENAME, CStringGetDatum(schemaName)); + Oid expected_pkg_oid = InvalidOid; + if (packageName != NULL) { + expected_pkg_oid = GetSysCacheOid2(PKGNAMENSP, CStringGetDatum(packageName), ObjectIdGetDatum(expected_nsp_oid)); + } + HeapTuple proc_tup = NULL; + bool is_null = false; + Form_pg_proc proc_form = NULL; + CatCList* catlist; + catlist = SearchSysCacheList1(PROCNAMEARGSNSP, CStringGetDatum(name)); + for (int i = 0; i < catlist->n_members; i++) { + proc_tup = t_thrd.lsc_cxt.FetchTupleFromCatCList(catlist, i); + if (HeapTupleIsValid(proc_tup)) { + proc_form = (Form_pg_proc)GETSTRUCT(proc_tup); + if (proc_form->pronamespace != expected_nsp_oid) { + continue; + } + Datum proPackageIdDatum = SysCacheGetAttr(PROCOID, proc_tup, Anum_pg_proc_packageid, &is_null); + Oid proPackageId = DatumGetObjectId(proPackageIdDatum); + if (proPackageId != expected_pkg_oid) { + continue; + } + Oid proc_oid = HeapTupleGetOid(proc_tup); + Datum proArgSrcdatum = SysCacheGetAttr(PROCOID, proc_tup, Anum_pg_proc_proargsrc, &is_null); + if (is_null && proc_arg_src == NULL) { + ReleaseSysCacheList(catlist); + return proc_oid; + } + if (is_null || proc_arg_src == NULL) { + continue; + } + char* pro_arg_src_in_db = TextDatumGetCString(proArgSrcdatum); + if (strcmp(proc_arg_src, pro_arg_src_in_db) == 0) { + pfree_ext(pro_arg_src_in_db); + ReleaseSysCacheList(catlist); + return proc_oid; + } + pfree_ext(pro_arg_src_in_db); + } + } + ReleaseSysCacheList(catlist); + ereport(ERROR, (errmodule(MOD_PLSQL), errmsg("function %s does not exist", name))); + return InvalidOid; +} + +char* gsplsql_do_refresh_proc_header(const GsDependObjDesc* obj_desc, bool* is_undefined) +{ + Oid funcid = InvalidOid; + char* schema_name = obj_desc->schemaName; + bool is_null = false; + char* package_name = obj_desc->packageName; + HeapTuple obj_tuple = gsplsql_search_object(obj_desc, false); + if (!HeapTupleIsValid(obj_tuple)) { + return NULL; + } + Datum ast_datum = gsplsql_get_depend_object_attr(obj_tuple, Anum_gs_dependencies_obj_objnode, &is_null); + char* ast_str = TextDatumGetCString(ast_datum); + DependenciesProchead* ast_node = (DependenciesProchead*)stringToNode(ast_str); + pfree_ext(ast_str); + char* func_name = ast_node->proName; + if (package_name == NULL || strcmp(package_name, "null") == 0) { + funcid = gsplsql_get_proc_oid(schema_name, NULL, func_name, ast_node->proArgSrc); + } else { + funcid = gsplsql_get_proc_oid(schema_name, package_name, func_name, ast_node->proArgSrc); + } + if (!OidIsValid(funcid)) { + heap_freetuple(obj_tuple); + return NULL; + } + StringInfoData proc_src; + initStringInfo(&proc_src); + if (ast_node->funcHeadSrc != NULL) { + appendStringInfoString(&proc_src, ast_node->funcHeadSrc); + } else { + ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("The header information of procedure %s is null.", func_name))); + } + appendStringInfoString(&proc_src, "\n"); + appendStringInfoString(&proc_src, "is begin null; end;"); + volatile bool has_undefined = false; + CreatePlsqlType oldCreatePlsqlType = u_sess->plsql_cxt.createPlsqlType; + FunctionStyleType oldFunctionStyleType = u_sess->plsql_cxt.functionStyleType; + bool oldNeedCreateDepend = u_sess->plsql_cxt.need_create_depend; + Oid oldCurrRefreshPkgOid = u_sess->plsql_cxt.currRefreshPkgOid; + Oid oldCurrObjectNspoid = u_sess->plsql_cxt.curr_object_nspoid; + PG_TRY(); + { + u_sess->plsql_cxt.createPlsqlType = CREATE_PLSQL_TYPE_START; + set_create_plsql_type_not_check_nsp_oid(); + u_sess->plsql_cxt.functionStyleType = FUNCTION_STYLE_TYPE_REFRESH_HEAD; + u_sess->plsql_cxt.need_create_depend = true; + u_sess->plsql_cxt.currRefreshPkgOid = gsplsql_get_pkg_oid_by_func_oid(funcid); + HeapTuple procTup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid)); + if (!HeapTupleIsValid(procTup)) { + ereport(ERROR, (errcode(ERRCODE_CACHE_LOOKUP_FAILED), + errmsg("cache lookup failed for function %u", funcid))); + } + Form_pg_proc procForm = (Form_pg_proc)GETSTRUCT(procTup); + u_sess->plsql_cxt.curr_object_nspoid = procForm->pronamespace; + ReleaseSysCache(procTup); + OverrideSearchPath* overrideSearchPath = GetOverrideSearchPath(CurrentMemoryContext); + overrideSearchPath->schemas = lcons_oid(u_sess->plsql_cxt.curr_object_nspoid, overrideSearchPath->schemas); + PushOverrideSearchPath(overrideSearchPath); + list_free(overrideSearchPath->schemas); + pfree_ext(overrideSearchPath); + List* stmtList = raw_parser(proc_src.data, NULL); + CreateFunctionStmt* stmt = (CreateFunctionStmt*)linitial(stmtList); + u_sess->plsql_cxt.createPlsqlType = CREATE_PLSQL_TYPE_START; + set_create_plsql_type_not_check_nsp_oid(); + has_undefined = gsplsql_update_proc_header(stmt, funcid); + if (enable_plpgsql_gsdependency_guc()) { + u_sess->plsql_cxt.createPlsqlType = oldCreatePlsqlType; + } + u_sess->plsql_cxt.functionStyleType = oldFunctionStyleType; + u_sess->plsql_cxt.need_create_depend = oldNeedCreateDepend; + u_sess->plsql_cxt.currRefreshPkgOid = oldCurrRefreshPkgOid; + u_sess->plsql_cxt.curr_object_nspoid = oldCurrObjectNspoid; + PopOverrideSearchPath(); + } + PG_CATCH(); + { + u_sess->plsql_cxt.currRefreshPkgOid = oldCurrRefreshPkgOid; + if (enable_plpgsql_gsdependency_guc()) { + u_sess->plsql_cxt.createPlsqlType = oldCreatePlsqlType; + } + u_sess->plsql_cxt.functionStyleType = oldFunctionStyleType; + u_sess->plsql_cxt.need_create_depend = oldNeedCreateDepend; + u_sess->plsql_cxt.curr_object_nspoid = oldCurrObjectNspoid; + PopOverrideSearchPath(); + PG_RE_THROW(); + } + PG_END_TRY(); + // updates the AST status, which is used for automatic recompillation + // the data queried last time cannot be used. There is a bug in nested compilation + HeapTuple objTupleNew = gsplsql_search_object(obj_desc, false); + if (!HeapTupleIsValid(objTupleNew)) { + return NULL; + } + Datum astDatumNew = gsplsql_get_depend_object_attr(objTupleNew, Anum_gs_dependencies_obj_objnode, &is_null); + char* astStrNew = TextDatumGetCString(astDatumNew); + DependenciesProchead* astNodeNew = (DependenciesProchead*)stringToNode(astStrNew); + pfree_ext(astStrNew); + bool undefined_in_db = astNodeNew->undefined; + if (is_undefined != NULL) { + *is_undefined = has_undefined; + } + if (has_undefined != undefined_in_db) { + ast_node->undefined = has_undefined; + if (ast_node->funcHeadSrc == NULL) { + ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("The header info of procedure %s is null.", func_name))); + } + Datum values[Natts_gs_dependencies_obj]; + bool nulls[Natts_gs_dependencies_obj] = {false}; + bool replaces[Natts_gs_dependencies_obj] = {false}; + values[Anum_gs_dependencies_obj_objnode -1] = CStringGetTextDatum(nodeToString(ast_node)); + replaces[Anum_gs_dependencies_obj_objnode -1] = true; + Relation relation = heap_open(DependenciesObjRelationId, RowExclusiveLock); + HeapTuple newTuple = heap_modify_tuple(objTupleNew, RelationGetDescr(relation), values, nulls, replaces); + (void)simple_heap_update(relation, &objTupleNew->t_self, newTuple); + CatalogUpdateIndexes(relation, newTuple); + heap_freetuple(newTuple); + heap_close(relation, RowExclusiveLock); + CommandCounterIncrement(); + } + heap_freetuple(objTupleNew); + char* new_func_head_name = format_procedure_no_visible(funcid); + //The function header info may change. The obj name is updated accordingly. + gsplsql_rename_func_name(schema_name, package_name, obj_desc->name, new_func_head_name); + gsplsql_obj_func_name(schema_name, package_name, obj_desc->name, new_func_head_name); + return new_func_head_name; +} + +void gsplsql_delete_unrefer_depend_obj_in_list(List* ref_obj_oid_list, bool skip_in_use) +{ + ListCell* lc = NULL; + foreach(lc, ref_obj_oid_list) { + Oid ref_obj_oid = lfirst_oid(lc); + gsplsql_delete_unrefer_depend_obj_oid(ref_obj_oid, skip_in_use); + } +} + +Oid gsplsql_insert_dependencies_object(const GsDependObjDesc *object, char *obj_ast_str) +{ + Datum values[Natts_gs_dependencies_obj]; + bool nulls[Natts_gs_dependencies_obj] = {false}; + NameData schemaNameData; + NameData packageNameData; + StringInfoData objectNameData; + HeapTuple tup; + Oid tupOid; + Relation rel; + TupleDesc tupDesc = NULL; + gsplsql_construct_non_empty_obj(object, &schemaNameData, &packageNameData, &objectNameData); + values[Anum_gs_dependencies_obj_schemaname - 1] = NameGetDatum(&schemaNameData); + values[Anum_gs_dependencies_obj_packagename - 1] = NameGetDatum(&packageNameData); + values[Anum_gs_dependencies_obj_name - 1] = CStringGetTextDatum(objectNameData.data); + values[Anum_gs_dependencies_obj_type - 1] = Int32GetDatum(object->type); + values[Anum_gs_dependencies_obj_objnode - 1] = CStringGetTextDatum(obj_ast_str); + rel = heap_open(DependenciesObjRelationId, RowExclusiveLock); + tupDesc = RelationGetDescr(rel); + tup = heap_form_tuple(tupDesc, values, nulls); + (void)simple_heap_insert(rel, tup); + CatalogUpdateIndexes(rel, tup); + tupOid = HeapTupleGetOid(tup); + heap_close(rel, RowExclusiveLock); + FreeStringInfo(&objectNameData); + return tupOid; +} + +void gsplsql_remove_dependencies_object(const GsDependObjDesc* obj_desc) +{ + HeapTuple tuple = NULL; + Relation relation = NULL; + SysScanDesc scan = NULL; + bool is_null = false; + NameData schema_name_data; + NameData pkg_name_data; + StringInfoData object_name_data; + gsplsql_construct_non_empty_obj(obj_desc, &schema_name_data, &pkg_name_data, &object_name_data); + int keyNum = 0; + ScanKeyData key[3]; + ScanKeyInit(&key[keyNum++], Anum_gs_dependencies_obj_schemaname, BTEqualStrategyNumber, F_NAMEEQ, NameGetDatum(&schema_name_data)); + ScanKeyInit(&key[keyNum++], Anum_gs_dependencies_obj_packagename, BTEqualStrategyNumber, F_NAMEEQ, NameGetDatum(&pkg_name_data)); + ScanKeyInit(&key[keyNum++], Anum_gs_dependencies_obj_type, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(obj_desc->type)); + relation = heap_open(DependenciesObjRelationId, RowExclusiveLock); + scan = systable_beginscan(relation, DependenciesObjNameIndexId, true, SnapshotSelf, keyNum, key); + while (HeapTupleIsValid(tuple = systable_getnext(scan))) { + Datum datum = heap_getattr(tuple, Anum_gs_dependencies_obj_name, + RelationGetDescr(relation), &is_null); + if (is_null) { + continue; + } + char* obj_name = TextDatumGetCString(datum); + if (0 == strcmp(object_name_data.data, obj_name)) { + pfree_ext(obj_name); + break; + } + pfree_ext(obj_name); + } + if (HeapTupleIsValid(tuple)) { + simple_heap_delete(relation, &tuple->t_self, 0, true); + CommandCounterIncrement(); + } + systable_endscan(scan); + heap_close(relation, RowExclusiveLock); + FreeStringInfo(&object_name_data); +} + +bool gsplsql_is_object_depend(Oid oid, GsDependObjectType type) +{ + if (!OidIsValid(oid)) { + return false; + } + GsDependObjDesc obj; + obj.schemaName = NULL; + bool result = false; + switch (type) + { + case GSDEPEND_OBJECT_TYPE_TYPE: + gsplsql_get_depend_obj_by_typ_id(&obj, oid, InvalidOid); + obj.refPosType = GSDEPEND_REFOBJ_POS_IN_TYPE; + break; + default: + return result; + } + if (NULL == obj.schemaName) { + return false; + } + HeapTuple obj_tup = gsplsql_search_object(&obj, false); + if (HeapTupleIsValid(obj_tup)) { + heap_freetuple(obj_tup); + result = true; + } + if (!result) { + result = gsplsql_exist_dependency(&obj); + } + pfree_ext(obj.schemaName); + pfree_ext(obj.packageName); + pfree_ext(obj.name); + return result; +} + +List* gsplsql_get_depend_obj_list_by_specified_pkg(const char* schema_name, const char* package_name, + GsDependObjectType type) +{ + int keyNum = 0; + ScanKeyData key[2]; + ScanKeyInit(&key[keyNum++], Anum_gs_dependencies_obj_schemaname, BTEqualStrategyNumber, F_NAMEEQ, + NULL != schema_name ? NameGetDatum(schema_name) : NameGetDatum("null")); + ScanKeyInit(&key[keyNum++], Anum_gs_dependencies_obj_packagename, BTEqualStrategyNumber, F_NAMEEQ, + NULL != package_name ? NameGetDatum(package_name) : NameGetDatum("null")); + Relation relation = heap_open(DependenciesObjRelationId, AccessShareLock); + SysScanDesc scan = systable_beginscan(relation, DependenciesObjNameIndexId, true, SnapshotSelf, keyNum, key); + HeapTuple tuple; + Datum obj_oid_datum; + bool is_null = true; + List* list = NIL; + while (HeapTupleIsValid(tuple = systable_getnext(scan))) { + + Datum obj_type_datum = heap_getattr(tuple, Anum_gs_dependencies_obj_type, + RelationGetDescr(relation), &is_null); + if (DatumGetInt32(obj_type_datum) == GSDEPEND_OBJECT_TYPE_PROCHEAD) { + continue; + } + obj_oid_datum = heap_getattr(tuple, ObjectIdAttributeNumber, + RelationGetDescr(relation), &is_null); + + if (type == GSDEPEND_OBJECT_TYPE_PKG || type == GSDEPEND_OBJECT_TYPE_PKG_RECOMPILE) { + if (DatumGetInt32(obj_type_datum) != GSDEPEND_OBJECT_TYPE_FUNCTION) { + list = lappend_oid(list, DatumGetObjectId(obj_oid_datum)); + } + } else { + if (DatumGetInt32(obj_type_datum) == type) { + list = lappend_oid(list, DatumGetObjectId(obj_oid_datum)); + } + } + } + systable_endscan(scan); + heap_close(relation, AccessShareLock); + return list; +} + +bool gsplsql_remove_ref_dependency(const GsDependObjDesc* ref_obj_desc) +{ + Oid oid = InvalidOid; + if (ref_obj_desc->type == GSDEPEND_OBJECT_TYPE_PKG || + ref_obj_desc->type == GSDEPEND_OBJECT_TYPE_PKG_BODY) { + List* list = gsplsql_get_depend_obj_list_by_specified_pkg(ref_obj_desc->schemaName, + ref_obj_desc->packageName, ref_obj_desc->type); + ListCell* cell = NULL; + foreach(cell, list) { + Oid ref_obj_oid = lfirst_oid(cell); + gsplsql_remove_depend_obj_by_specified_oid(ref_obj_oid, gsplsql_get_curr_compile_oid()); + } + list_free(list); + return true; + } + HeapTuple obj_tuple = gsplsql_search_object(ref_obj_desc, false); + if (!HeapTupleIsValid(obj_tuple)) { + return false; + } + oid = HeapTupleGetOid(obj_tuple); + heap_freetuple(obj_tuple); + gsplsql_remove_depend_obj_by_specified_oid(oid, gsplsql_get_curr_compile_oid()); + return true; +} + +void gsplsql_remove_depend_obj_by_specified_oid(Oid ref_obj_oid, Oid curr_compile_oid, bool is_same_pkg) +{ + const int keyNum = 1; + ScanKeyData key[keyNum]; + ScanKeyInit(&key[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(ref_obj_oid)); + Relation relation = heap_open(DependenciesObjRelationId, RowExclusiveLock); + SysScanDesc scan = systable_beginscan(relation, DependenciesObjOidIndexId, true, SnapshotSelf, keyNum, key); + HeapTuple tuple = systable_getnext(scan); + if (!HeapTupleIsValid(tuple)) { + systable_endscan(scan); + heap_close(relation, RowExclusiveLock); + } + Datum values[Natts_gs_dependencies_obj]; + bool nulls[Natts_gs_dependencies_obj] = {false}; + bool replaces[Natts_gs_dependencies_obj] = {false}; + DependenciesUndefined* undefinedNode = makeNode(DependenciesUndefined); + char* ast_str = nodeToString(undefinedNode); + pfree_ext(undefinedNode); + values[Anum_gs_dependencies_obj_objnode -1] = CStringGetTextDatum(ast_str); + replaces[Anum_gs_dependencies_obj_objnode -1] = true; + HeapTuple new_tuple = heap_modify_tuple(tuple, RelationGetDescr(relation), values, nulls, replaces); + (void)simple_heap_update(relation, &new_tuple->t_self, new_tuple, true); + CatalogUpdateIndexes(relation, new_tuple); + heap_freetuple(new_tuple); + systable_endscan(scan); + heap_close(relation, RowExclusiveLock); + pfree_ext(ast_str); + CommandCounterIncrement(); + gsplsql_refresh_proc_header(ref_obj_oid); + if (!is_same_pkg) { + gsplsql_invalidate_objs(ref_obj_oid, true, + OidIsValid(curr_compile_oid) ? curr_compile_oid : gsplsql_get_curr_compile_oid()); + } +} + +void gsplsql_get_depend_obj_by_typ_id(GsDependObjDesc* ref_obj, Oid typ_oid, + Oid pkg_oid, bool drop_typ) +{ + gsplsql_init_gs_depend_obj_desc(ref_obj); + if (!OidIsValid(typ_oid)) { + return; + } + Oid rel_oid = get_typ_typrelid(typ_oid); + if (OidIsValid(rel_oid)) { + char rel_kind = get_rel_relkind(rel_oid); + switch (rel_kind) + { + case RELKIND_RELATION: + case RELKIND_FOREIGN_TABLE: + case RELKIND_COMPOSITE_TYPE: + case RELPERSISTENCE_PERMANENT: + case RELPERSISTENCE_UNLOGGED: + case RELPERSISTENCE_GLOBAL_TEMP: + break; + default: + if (!drop_typ || rel_kind != '\0') { + return; + } + } + } + ref_obj->schemaName = get_typenamespace(typ_oid); + ref_obj->name = get_typename(typ_oid); + Oid cur_pkg_oid = GetTypePackageOid(typ_oid); + if (!OidIsValid(cur_pkg_oid)) { + cur_pkg_oid = pkg_oid; + } + if (OidIsValid(cur_pkg_oid)) { + ref_obj->packageName = GetPackageName(cur_pkg_oid); + char* real_name = ParseTypeName(ref_obj->name, cur_pkg_oid); + pfree_ext(ref_obj->name); + ref_obj->name = real_name; + } else { + ref_obj->packageName = pstrdup("null"); + } + ref_obj->refPosType = GSDEPEND_REFOBJ_POS_INVALID; + ref_obj->type = GSDEPEND_OBJECT_TYPE_TYPE; +} + +bool gsplsql_build_ref_type_dependency(Oid typ_oid) +{ + if (!enable_plpgsql_gsdependency_guc()) { + return false; + } + Oid curr_pkg_oid = InvalidOid; + int cw = CompileWhich(); + if (cw == PLPGSQL_COMPILE_PACKAGE_PROC || cw == PLPGSQL_COMPILE_PACKAGE) { + curr_pkg_oid = u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package->pkg_oid; + } + GsDependObjDesc ref_obj; + gsplsql_get_depend_obj_by_typ_id(&ref_obj, typ_oid, curr_pkg_oid); + if (ref_obj.type == GSDEPEND_OBJECT_TYPE_INVALID) { + return false; + } + bool has_undefined = false; + DependenciesDatum* datum = gsplsql_make_depend_datum_by_type_oid(typ_oid, &has_undefined); + bool ret = gsplsql_build_ref_dependency(&ref_obj, datum); + pfree_ext(datum); + free_gs_depend_obj_desc(&ref_obj); + return ret; +} + +bool gsplsql_build_ref_dependency(Oid nsp_oid, const PLpgSQL_datum* ref_datum, const char* pkg_name, + List** ref_obj_oids, Oid curr_compile_oid) +{ + if (ref_datum == NULL) { + return false; + } + GsDependObjDesc ref_obj_desc = {"", "", ""}; + bool succeed = gsplsql_parse_type_and_name_from_gsplsql_datum(ref_datum, &ref_obj_desc.name, &ref_obj_desc.type); + if (!succeed) { + return false; + } + ref_obj_desc.schemaName = get_namespace_name(nsp_oid); + if (pkg_name != NULL) { + ref_obj_desc.packageName = (char*)pkg_name; + } + bool depend_undefined = false; + DependenciesDatum* ref_obj_ast = gsplsql_make_depend_datum_from_plsql_datum(ref_datum, NULL, &depend_undefined); + bool ret = gsplsql_build_ref_dependency(&ref_obj_desc, ref_obj_ast, ref_obj_oids, curr_compile_oid); + pfree_ext(ref_obj_desc.schemaName); + if (depend_undefined) { + if (GetCurrCompilePgObjStatus()) { + ereport(WARNING, (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("Object %s depends on an undefined type.", ref_obj_desc.name))); + } + InvalidateCurrCompilePgObj(); + } + return ret; +} + +bool gsplsql_build_ref_dependency(const GsDependObjDesc* ref_obj_desc, const DependenciesDatum* ref_obj_ast, + List** ref_obj_oids, Oid curr_compile_oid) +{ + HeapTuple obj_tuple = gsplsql_search_object(ref_obj_desc, true); + if (!HeapTupleIsValid(obj_tuple)) { + return false; + } + Oid ref_obj_oid = HeapTupleGetOid(obj_tuple); + if (ref_obj_oids != NULL) { + *ref_obj_oids = list_delete_oid(*ref_obj_oids, ref_obj_oid); + } + gsplsql_delete_ref_obj_from_pkg(ref_obj_oid); + Relation gs_depend_rel; + List* list = NIL; + gs_depend_rel = heap_open(DependenciesRelationId, AccessShareLock); + list = gsplsql_search_gs_depend_rel_by_oid(gs_depend_rel, ref_obj_oid); + if (list == NULL) { + heap_close(gs_depend_rel, AccessShareLock); + return false; + } + bool pre_undefined = false; + bool ast_changed = false; + char* ref_obj_ast_str = NULL; + if (ref_obj_ast != NULL) { + ref_obj_ast_str = nodeToString(ref_obj_ast); + bool is_null; + Datum ast_datum = gsplsql_get_depend_object_attr(obj_tuple, Anum_gs_dependencies_obj_objnode, &is_null); + if (is_null) { + ast_changed = true; + } else { + char* pre_ast_str = TextDatumGetCString(ast_datum); + DependenciesUndefined* undefined_ast = makeNode(DependenciesUndefined); + char* undefined_ast_str = nodeToString(undefined_ast); + pre_undefined = (0 == strcmp(undefined_ast_str, pre_ast_str)); + if (strcmp(ref_obj_ast_str, pre_ast_str) != 0) { + ast_changed = true; + } + if (pre_undefined && strcmp(ref_obj_ast_str, undefined_ast_str) == 0) { + ast_changed = true; + } + pfree_ext(pre_ast_str); + pfree_ext(undefined_ast); + pfree_ext(undefined_ast_str); + } + } else { + ast_changed = true; + } + gsplsql_update_ref_dep_obj_base_on_ast(ref_obj_desc, obj_tuple, ref_obj_ast_str, ast_changed); + heap_freetuple(obj_tuple); + pfree_ext(ref_obj_ast_str); + gsplsql_do_ref_obj_affect_oper(ref_obj_desc, gs_depend_rel, list, pre_undefined, ast_changed); + heap_close(gs_depend_rel, AccessShareLock); + if (ast_changed) { + gsplsql_invalidate_objs(ref_obj_oid, false, + OidIsValid(curr_compile_oid) ? curr_compile_oid : gsplsql_get_curr_compile_oid()); + } + return true; +} + +Oid gsplsql_update_object_ast(const GsDependObjDesc* object, const DependenciesDatum* ref_obj_ast) +{ + Datum values[Natts_gs_dependencies_obj]; + bool nulls[Natts_gs_dependencies_obj] = {false}; + bool replaces[Natts_gs_dependencies_obj] = {false}; + bool is_null = false; + Oid oid; + HeapTuple newTuple = NULL; + char* ref_obj_ast_str = nodeToString(ref_obj_ast); + HeapTuple tup = gsplsql_search_object(object, NULL == ref_obj_ast || T_DependenciesUndefined == ref_obj_ast->type); + if (!HeapTupleIsValid(tup)) { + oid = gsplsql_insert_dependencies_object(object, ref_obj_ast_str); + pfree_ext(ref_obj_ast_str); + return oid; + } + oid = HeapTupleGetOid(tup); + Datum ast_datum = gsplsql_get_depend_object_attr(tup, Anum_gs_dependencies_obj_objnode, &is_null); + char* ast_str = TextDatumGetCString(ast_datum); + if (strcmp(ast_str, ref_obj_ast_str) == 0) { + pfree_ext(ref_obj_ast_str); + pfree_ext(ast_str); + heap_freetuple(tup); + return oid; + } + replaces[Anum_gs_dependencies_obj_objnode -1] = true; + values[Anum_gs_dependencies_obj_objnode -1] = CStringGetTextDatum(ref_obj_ast_str); + Relation relation = heap_open(DependenciesObjRelationId, RowExclusiveLock); + newTuple = heap_modify_tuple(tup, RelationGetDescr(relation), values, nulls, replaces); + simple_heap_update(relation, &tup->t_self, newTuple, true); + CatalogUpdateIndexes(relation, newTuple); + heap_freetuple(tup); + heap_freetuple(newTuple); + heap_close(relation, RowExclusiveLock); + CommandCounterIncrement(); + return oid; +} + +void free_gs_depend_obj_desc(GsDependObjDesc* obj_desc) +{ + if (obj_desc != NULL) { + pfree_ext(obj_desc->schemaName); + pfree_ext(obj_desc->packageName); + pfree_ext(obj_desc->name); + } +} + +Oid gsplsql_flush_undef_ref_type_dependency(Oid type_oid) +{ + if (!enable_plpgsql_gsdependency_guc()) { + return false; + } + Oid cur_pkg_oid = InvalidOid; + int cw = CompileWhich(); + if (cw == PLPGSQL_COMPILE_PACKAGE || cw == PLPGSQL_COMPILE_PACKAGE_PROC) { + cur_pkg_oid = u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package->pkg_oid; + } + GsDependObjDesc ref_obj_desc; + gsplsql_get_depend_obj_by_typ_id(&ref_obj_desc, type_oid, cur_pkg_oid); + if (ref_obj_desc.type == GSDEPEND_OBJECT_TYPE_INVALID) { + free_gs_depend_obj_desc(&ref_obj_desc); + return false; + } + HeapTuple obj_tuple = gsplsql_search_object(&ref_obj_desc, true); + if (!HeapTupleIsValid(obj_tuple)) { + free_gs_depend_obj_desc(&ref_obj_desc); + return false; + } + Oid ref_obj_oid = HeapTupleGetOid(obj_tuple); + heap_freetuple(obj_tuple); + gsplsql_delete_ref_obj_from_pkg(ref_obj_oid); + free_gs_depend_obj_desc(&ref_obj_desc); + return false; +} + +Oid get_compiled_object_nspoid() +{ + int rc = CompileWhich(); + Oid nspOid = InvalidOid; + if (rc == PLPGSQL_COMPILE_PACKAGE || rc == PLPGSQL_COMPILE_PACKAGE_PROC) { + nspOid = u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package->namespaceOid; + } else if (rc == PLPGSQL_COMPILE_PROC) { + nspOid = u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile->namespaceOid; + } else if (OidIsValid(u_sess->plsql_cxt.curr_object_nspoid)) { + nspOid = u_sess->plsql_cxt.curr_object_nspoid; + } else { + nspOid = GetOidBySchemaName(); + } + return nspOid; +} + +bool gsplsql_check_type_depend_ast_equal(Relation obj_rel, Oid obj_oid, const char* equal_ast) +{ + ScanKeyData key; + ScanKeyInit(&key, ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(obj_oid)); + SysScanDesc scan = systable_beginscan(obj_rel, DependenciesObjOidIndexId, true, SnapshotSelf, 1, &key); + HeapTuple tuple = systable_getnext(scan); + if (!HeapTupleIsValid(tuple)) { + systable_endscan(scan); + ereport(WARNING, (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("dependencies object %u does not exist.", obj_oid))); + return false; + } + bool is_null = false; + Datum ast_datum = heap_getattr(tuple, Anum_gs_dependencies_obj_objnode, + RelationGetDescr(obj_rel), &is_null); + if (is_null) { + systable_endscan(scan); + return false; + } + char* pre_ast_str = TextDatumGetCString(ast_datum); + bool ret = strcmp(equal_ast, pre_ast_str) == 0; + pfree_ext(pre_ast_str); + systable_endscan(scan); + return ret; +} + +/* + * static func + */ +static void gsplsql_cascade_delete_type_by_type_name(GsDependObjDesc *obj_desc) +{ + ObjectAddress address; + Oid typeOid = InvalidOid; + if (obj_desc->refPosType == GSDEPEND_REFOBJ_POS_IN_TYPE) { + typeOid = TypeNameGetOid(obj_desc->schemaName, obj_desc->packageName, obj_desc->name); + if (!OidIsValid(typeOid)) { + return; + } + address.classId = TypeRelationId; + address.objectId = typeOid; + address.objectSubId = 0; + performDeletion(&address, DROP_CASCADE, PERFORM_DELETION_INTERNAL); + } +} + +static inline void gsplsql_delete_ref_obj_from_pkg(Oid ref_obj_oid) +{ + int rc = CompileWhich(); + if (rc == PLPGSQL_COMPILE_PACKAGE || rc == PLPGSQL_COMPILE_PACKAGE_PROC) { + PLpgSQL_package* pkg = u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package; + pkg->preSelfObjectList = list_delete_oid(pkg->preSelfObjectList, ref_obj_oid); + } +} + +static Oid gsplsql_get_curr_compile_oid() +{ + Oid oid = InvalidOid; + int rc = CompileWhich(); + switch (rc) { + case PLPGSQL_COMPILE_PACKAGE: + case PLPGSQL_COMPILE_PACKAGE_PROC: { + PLpgSQL_package *pkg = u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package; + oid = pkg->pkg_oid; + } break; + case PLPGSQL_COMPILE_PROC: { + PLpgSQL_function *func = u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile; + oid = func->fn_oid; + } break; + default: + break; + } + return oid; +} + +/* + * update proc header and the values of some fields in pg_proc + * this methods copies part of the code of ProcedureCreate and CreateFunction + */ +static bool gsplsql_update_proc_header(CreateFunctionStmt *stmt, Oid funcid) +{ + Oid language_oid = InvalidOid; + int all_param_count; + char* alquery_string = stmt->queryStr; + oidvector* parameter_types = NULL; + TypeDependExtend* param_type_depend_ext = NULL; + TypeDependExtend* ret_type_depend_ext = NULL; + ArrayType* all_parameter_types = NULL; + ArrayType* parameter_modes = NULL; + ArrayType* parameter_names = NULL; + Datum values[Natts_pg_proc]; + bool nulls[Natts_pg_proc] = {false}; + bool replaces[Natts_pg_proc] = {false}; + List* parameter_defaults = NIL; + Oid required_result_type; + List* defargpos = NIL; + int parameter_count; +#ifdef ENABLE_MULTI_NODES + bool fenced = true; +#else + bool fenced = false; +#endif + Oid prorettype = InvalidOid; + bool returnsSet = false; + List* parameters = stmt->parameters; + bool has_undefined = false; + + examine_parameter_list(parameters, language_oid, alquery_string, ¶meter_types, ¶m_type_depend_ext, + &all_parameter_types, ¶meter_modes, ¶meter_names, ¶meter_defaults, + &required_result_type, &defargpos, fenced, &has_undefined); + pfree_ext(param_type_depend_ext); + if (stmt->returnType) { + InstanceTypeNameDependExtend(&ret_type_depend_ext); + /* explicit RETURNS clause */ + compute_return_type(stmt->returnType, language_oid, &prorettype, &returnsSet, fenced, stmt->startLineNumber, + ret_type_depend_ext, true); + if (ret_type_depend_ext->dependUndefined) { + has_undefined = true; + } + pfree_ext(ret_type_depend_ext); + } else if (OidIsValid(required_result_type)) { + /* default RETURNS clause from OUT parameters */ + prorettype = required_result_type; + returnsSet = false; + } else { + ereport( + ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), errmsg("function result type must be specified"))); + /* Alternative possibility: default to RETURNS VOID */ + prorettype = VOIDOID; + returnsSet = false; + } + if (has_undefined) { + ereport( + LOG, (errmsg("the function header has an unknown dependency. function oid is %u", funcid))); + } + char* parameter_defaults_str = NULL; + if (parameter_defaults != NIL) { + parameter_defaults_str = nodeToString(parameter_defaults); + } + parameter_count = parameter_types->dim1; + if (parameter_count < 0 || parameter_count > FUNC_MAX_ARGS) { + ereport(ERROR, + (errcode(ERRCODE_TOO_MANY_ARGUMENTS), + errmsg_plural("functions cannot have more than %d argument", + "functions cannot have more than %d arguments", + FUNC_MAX_ARGS, + FUNC_MAX_ARGS))); + } + if (all_parameter_types != PointerGetDatum(NULL)) { + ArrayType* all_param_array = (ArrayType*)DatumGetPointer(all_parameter_types); + all_param_count = ARR_DIMS(all_param_array)[0]; + if (ARR_NDIM(all_param_array) != 1 || all_param_count <= 0 || ARR_HASNULL(all_param_array) || + ARR_ELEMTYPE(all_param_array) != OIDOID) { + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("all_parameter_types is not a 1-D Oid array"))); + } + } else { + all_param_count = parameter_count; + } + + if (parameter_count < 0 || parameter_count > FUNC_MAX_ARGS) { + ereport(ERROR, + (errcode(ERRCODE_TOO_MANY_ARGUMENTS), + errmsg_plural("functions cannot have more than %d argument", + "functions cannot have more than %d arguments", + FUNC_MAX_ARGS, + FUNC_MAX_ARGS))); + } + if (parameter_count > FUNC_MAX_ARGS) { + char hex[MD5_HASH_LEN + 1]; + if (!pg_md5_hash((void*)parameter_types->values, parameter_types->dim1 * sizeof(Oid), hex)) { + ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of memory"))); + } + /* Build a dummy oidvector using the hash value and use it as proargtypes field value. */ + oidvector* dummy = buildoidvector((Oid*)hex, MD5_HASH_LEN / sizeof(Oid)); + values[Anum_pg_proc_proargtypes - 1] = PointerGetDatum(dummy); + values[Anum_pg_proc_proargtypesext - 1] = PointerGetDatum(parameter_types); + } else { + values[Anum_pg_proc_proargtypes - 1] = PointerGetDatum(parameter_types); + nulls[Anum_pg_proc_proargtypesext - 1] = true; + } + CacheInvalidateFunction(funcid, InvalidOid); + if (!is_proc_info_changed(funcid, parameter_types, all_parameter_types, parameter_defaults_str, + prorettype, returnsSet)) { + ereport(LOG, (errcode(ERRCODE_PLPGSQL_ERROR), + errmsg("The header of function %u does not need to be modified.", funcid))); + pfree_ext(parameter_defaults_str); + return has_undefined; + } + + replaces[Anum_pg_proc_allargtypes - 1] = true; + replaces[Anum_pg_proc_allargtypesext - 1] = true; + replaces[Anum_pg_proc_proargtypes - 1] = true; + replaces[Anum_pg_proc_proallargtypes - 1] = true; + replaces[Anum_pg_proc_proargtypesext - 1] = true; + if (all_parameter_types != PointerGetDatum(NULL)) { + values[Anum_pg_proc_proallargtypes - 1] = PointerGetDatum(all_parameter_types); + } else { + nulls[Anum_pg_proc_proallargtypes - 1] = true; + } + if (all_parameter_types != PointerGetDatum(NULL)) { + if (all_param_count <= FUNC_MAX_ARGS_INROW) { + nulls[Anum_pg_proc_allargtypesext - 1] = true; + values[Anum_pg_proc_allargtypes - 1] = PointerGetDatum(all_parameter_types); + } else { + oidvector* dummy = MakeMd5HashOids((oidvector*)all_parameter_types); + values[Anum_pg_proc_allargtypes - 1] = PointerGetDatum(dummy); + values[Anum_pg_proc_allargtypesext - 1] = PointerGetDatum(all_parameter_types); + } + } else if (parameter_types != PointerGetDatum(NULL)){ + values[Anum_pg_proc_allargtypes - 1] = values[Anum_pg_proc_proargtypes - 1]; + values[Anum_pg_proc_allargtypesext - 1] = values[Anum_pg_proc_proargtypesext - 1]; + nulls[Anum_pg_proc_allargtypesext - 1] = nulls[Anum_pg_proc_proargtypesext - 1]; + } else { + nulls[Anum_pg_proc_allargtypes - 1] = true; + nulls[Anum_pg_proc_allargtypesext - 1] = true; + } + replaces[Anum_pg_proc_proargdefaults - 1] = true; + if (parameter_defaults != NIL) { + values[Anum_pg_proc_proargdefaults - 1] = CStringGetTextDatum(parameter_defaults_str); + } else { + nulls[Anum_pg_proc_proargdefaults - 1] = true; + } + pfree_ext(parameter_defaults_str); + replaces[Anum_pg_proc_prorettype - 1] = true; + replaces[Anum_pg_proc_proretset - 1] = true; + values[Anum_pg_proc_prorettype - 1] = ObjectIdGetDatum(prorettype); + values[Anum_pg_proc_proretset - 1] = BoolGetDatum(returnsSet); + + Relation rel = heap_open(ProcedureRelationId, RowExclusiveLock); + HeapTuple tup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid)); + if (HeapTupleIsValid(tup)) { + HeapTuple newTuple = heap_modify_tuple(tup, RelationGetDescr(rel), values, nulls, replaces); + simple_heap_update(rel, &newTuple->t_self, newTuple); + CatalogUpdateIndexes(rel, newTuple); + heap_freetuple(newTuple); + ReleaseSysCache(tup); + CommandCounterIncrement(); + } + heap_close(rel, RowExclusiveLock); + return has_undefined; +} + +static bool is_proc_info_changed(Oid funcid, oidvector *new_parameter_types, ArrayType *new_all_parameter_types, + char *new_parameter_defaults, Oid new_prorettype, bool new_returnsset) +{ + HeapTuple proc_tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid)); + bool is_null = false; + if (!HeapTupleIsValid((proc_tuple))) { + return false; + } + + Form_pg_proc proc_form = (Form_pg_proc)GETSTRUCT(proc_tuple); + oidvector* proargtypes = NULL; + if (proc_form->pronargs <= FUNC_MAX_ARGS_INROW) { + proargtypes = &proc_form->proargtypes; + } else { + Datum proargtypesDatum = SysCacheGetAttr(PROCOID, proc_tuple, Anum_pg_proc_proargtypesext, &is_null); + if (is_null) { + proargtypes = (oidvector*)PG_DETOAST_DATUM(proargtypesDatum); + } + } + //check proargtypes + if ((new_parameter_types != NULL && proargtypes == NULL) || + (new_parameter_types == NULL && proargtypes != NULL)) { + ReleaseSysCache(proc_tuple); + return true; + } else if (new_parameter_types != NULL && proargtypes != NULL && + !DatumGetBool(DirectFunctionCall2(oidvectoreq, + PointerGetDatum(new_parameter_types), + PointerGetDatum(proargtypes)))){ + ReleaseSysCache(proc_tuple); + return true; + } + + Datum pro_all_arg_types = SysCacheGetAttr(PROCOID, proc_tuple, Anum_pg_proc_proallargtypes, &is_null); + if (pro_all_arg_types != PointerGetDatum(NULL)) { + if (new_all_parameter_types == NULL) { + ReleaseSysCache(proc_tuple); + return true; + } else { + // get new_allpara_type + int new_allpara_count = ARR_DIMS(new_all_parameter_types)[0]; + size_t size_tmp = new_allpara_count * sizeof(Oid); + Oid *new_p_argtypes = (Oid *)palloc(size_tmp); + errno_t rc = memcpy_s(new_p_argtypes, size_tmp, ARR_DATA_PTR(new_all_parameter_types), size_tmp); + securec_check(rc, "\0", "\0"); + oidvector *new_allpara_type = buildoidvector(new_p_argtypes, new_allpara_count); + // get allpara_type + ArrayType *arr = DatumGetArrayTypeP(pro_all_arg_types); + int allpara_count = ARR_DIMS(arr)[0]; + if (ARR_NDIM(arr) != 1 || allpara_count < 0 || ARR_HASNULL(arr) || ARR_ELEMTYPE(arr) != OIDOID) { + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("pro_all_arg_types is not a 1-D Oid array"))); + } + size_tmp = allpara_count * sizeof(Oid); + Oid *p_argtypes = (Oid *)palloc(size_tmp); + rc = memcpy_s(p_argtypes, size_tmp, ARR_DATA_PTR(new_all_parameter_types), size_tmp); + securec_check(rc, "\0", "\0"); + oidvector *allpara_type = buildoidvector(p_argtypes, allpara_count); + if (!DatumGetBool(DirectFunctionCall2(oidvectoreq, PointerGetDatum(allpara_type), + PointerGetDatum(new_allpara_type)))) { + ReleaseSysCache(proc_tuple); + return true; + } + pfree_ext(allpara_type); + pfree_ext(p_argtypes); + pfree_ext(new_allpara_type); + pfree_ext(new_p_argtypes); + } + } else { + if (new_all_parameter_types != NULL) { + ReleaseSysCache(proc_tuple); + return true; + } + } + + Datum proargdefaultsDatum = SysCacheGetAttr(PROCOID, proc_tuple, Anum_pg_proc_proargdefaults, &is_null); + if (!is_null) { + if (new_parameter_defaults == NULL) { + ReleaseSysCache(proc_tuple); + return true; + } else { + char* proargdefaults = TextDatumGetCString(proargdefaultsDatum); + if (strcmp(new_parameter_defaults, proargdefaults) != 0) { + ReleaseSysCache(proc_tuple); + return true; + } + pfree_ext(proargdefaults); + } + } else { + if (new_parameter_defaults != NULL) { + ReleaseSysCache(proc_tuple); + return true; + } + } + + Datum retTypeDatum = SysCacheGetAttr(PROCOID, proc_tuple, Anum_pg_proc_prorettype, &is_null); + if (!is_null) { + Oid rettype = DatumGetObjectId(retTypeDatum); + if (new_prorettype != rettype) { + ReleaseSysCache(proc_tuple); + return true; + } + } else { + ReleaseSysCache(proc_tuple); + return true; + } + + Datum retSetDatum = SysCacheGetAttr(PROCOID, proc_tuple, Anum_pg_proc_proretset, &is_null); + if (!is_null) { + bool retset = DatumGetBool(retSetDatum); + if (new_returnsset != retset) { + ReleaseSysCache(proc_tuple); + return true; + } + } else { + ReleaseSysCache(proc_tuple); + return true; + } + + ReleaseSysCache(proc_tuple); + return false; +} + +static void gsplsql_refresh_proc_header(Oid ref_obj_oid) +{ + Relation gs_depend_rel; + List* list = NIL; + gs_depend_rel = heap_open(DependenciesRelationId, AccessShareLock); + list = gsplsql_search_gs_depend_rel_by_oid(gs_depend_rel, ObjectIdGetDatum(ref_obj_oid)); + if (list == NIL) { + heap_close(gs_depend_rel, AccessShareLock); + return; + } + ListCell* cell = NULL; + foreach(cell, list) { + HeapTuple tuple = (HeapTuple)lfirst(cell); + GsDependObjDesc obj_desc; + gsplsql_make_desc_from_gs_dependencies_tuple(tuple, RelationGetDescr(gs_depend_rel), &obj_desc); + if (obj_desc.refPosType == GSDEPEND_REFOBJ_POS_IN_PROCHEAD) { + obj_desc.type = GSDEPEND_OBJECT_TYPE_PROCHEAD; + (void)gsplsql_do_refresh_proc_header(&obj_desc); + } + pfree_ext(obj_desc.name); + heap_freetuple(tuple); + } + heap_close(gs_depend_rel, AccessShareLock); +} + +static void gsplsql_do_ref_obj_affect_oper(const GsDependObjDesc *ref_obj_desc, Relation gs_depend_rel, List *list, + bool pre_undefined, bool ast_changed) +{ + ListCell* lc = NULL; + foreach (lc, list) { + HeapTuple tuple = (HeapTuple)lfirst(lc); + GsDependObjDesc obj_desc; + gsplsql_make_desc_from_gs_dependencies_tuple(tuple, RelationGetDescr(gs_depend_rel), &obj_desc); + if (obj_desc.refPosType == GSDEPEND_REFOBJ_POS_IN_PROCHEAD && + (ref_obj_desc->type != GSDEPEND_OBJECT_TYPE_VARIABLE || ast_changed)) { + obj_desc.type = GSDEPEND_OBJECT_TYPE_PROCHEAD; + char* new_func_head_name = gsplsql_do_refresh_proc_header(&obj_desc); + if (new_func_head_name != NULL) { + obj_desc.name = new_func_head_name; + } + } + if (ast_changed) { + if (pre_undefined && ref_obj_desc->type == GSDEPEND_OBJECT_TYPE_TYPE && + (obj_desc.refPosType & (GSDEPEND_REFOBJ_POS_IN_TYPE | GSDEPEND_REFOBJ_POS_IN_PROCBODY))) { + gsplsql_cascade_delete_type_by_type_name(&obj_desc); + } + } + pfree_ext(obj_desc.name); + heap_freetuple(tuple); + } +} + +static inline bool gsplsql_is_need_update_ref_dep_obj(char* ref_obj_ast_str, bool ast_changed, int32 obj_type) +{ + return (NULL != ref_obj_ast_str && ast_changed) || obj_type == GSDEPEND_OBJECT_TYPE_UNDEFIND; +} + +static void gsplsql_update_ref_dep_obj_base_on_ast(const GsDependObjDesc *ref_obj_desc, HeapTuple obj_tuple, + char *ref_obj_ast_str, bool ast_changed) +{ + bool is_null; + Datum type_datum = gsplsql_get_depend_object_attr(obj_tuple, Anum_gs_dependencies_obj_type, &is_null); + AssertEreport(!is_null, MOD_PLSQL, "Object Type must not be null."); + if (!gsplsql_is_need_update_ref_dep_obj(ref_obj_ast_str, ast_changed, DatumGetInt32(type_datum))) { + return; + } + HeapTuple new_obj_tuple; + Relation gs_dep_obj_rel; + Datum values[Natts_gs_dependencies_obj]; + bool nulls[Natts_gs_dependencies_obj] = {false}; + bool replaces[Natts_gs_dependencies_obj] = {false}; + if (DatumGetInt32(type_datum) == GSDEPEND_OBJECT_TYPE_UNDEFIND) { + values[Anum_gs_dependencies_obj_type -1] = DatumGetInt32(ref_obj_desc->type); + replaces[Anum_gs_dependencies_obj_type -1] = true; + } + if (NULL != ref_obj_ast_str && ast_changed) { + values[Anum_gs_dependencies_obj_objnode -1] = CStringGetTextDatum(ref_obj_ast_str); + replaces[Anum_gs_dependencies_obj_objnode -1] = true; + } + + gs_dep_obj_rel = heap_open(DependenciesObjRelationId, RowExclusiveLock); + new_obj_tuple = heap_modify_tuple(obj_tuple, RelationGetDescr(gs_dep_obj_rel), values, nulls, replaces); + (void)simple_heap_update(gs_dep_obj_rel, &obj_tuple->t_self, new_obj_tuple, true); + CatalogUpdateIndexes(gs_dep_obj_rel, new_obj_tuple); + heap_freetuple(new_obj_tuple); + heap_close(gs_dep_obj_rel, RowExclusiveLock); + CommandCounterIncrement(); +} + +static void gsplsql_rename_func_name(const char *nsp_name, const char *pkg_name, const char *old_func_name, + const char *new_func_name) +{ + HeapTuple tuple = NULL; + HeapTuple new_tuple = NULL; + int keyNum = 0; + ScanKeyData key[3]; + SysScanDesc scan = NULL; + Datum values[Natts_gs_dependencies]; + bool nulls[Natts_gs_dependencies] = {false}; + bool replaces[Natts_gs_dependencies] = {false}; + Assert(nsp_name != NULL && pkg_name != NULL && old_func_name != NULL && new_func_name != NULL); + values[Anum_gs_dependencies_objectname -1] = CStringGetTextDatum(new_func_name); + replaces[Anum_gs_dependencies_objectname -1] = true; + ScanKeyInit(&key[keyNum++], Anum_gs_dependencies_schemaname, BTEqualStrategyNumber, F_NAMEEQ, + NameGetDatum(nsp_name)); + ScanKeyInit(&key[keyNum++], Anum_gs_dependencies_packagename, BTEqualStrategyNumber, F_NAMEEQ, + NameGetDatum(pkg_name)); + ScanKeyInit(&key[keyNum++], Anum_gs_dependencies_objectname, BTEqualStrategyNumber, F_TEXTEQ, + CStringGetTextDatum(old_func_name)); + Relation relation = heap_open(DependenciesRelationId, RowExclusiveLock); + scan = systable_beginscan(relation, InvalidOid, false, SnapshotSelf, keyNum, key); + while (HeapTupleIsValid(tuple = systable_getnext(scan))) { + new_tuple = heap_modify_tuple(tuple, RelationGetDescr(relation), values, nulls, replaces); + simple_heap_update(relation, &new_tuple->t_self, new_tuple, true); + CatalogUpdateIndexes(relation, new_tuple); + heap_freetuple(new_tuple); + } + systable_endscan(scan); + heap_close(relation, RowExclusiveLock); + CommandCounterIncrement(); +} + +static void gsplsql_obj_func_name(const char *nsp_name, const char *pkg_name, const char *old_func_name, + const char *new_func_name) +{ + HeapTuple tuple = NULL; + HeapTuple new_tuple = NULL; + int keyNum = 0; + ScanKeyData key[3]; + SysScanDesc scan = NULL; + Datum values[Natts_gs_dependencies_obj]; + bool nulls[Natts_gs_dependencies_obj] = {false}; + bool replaces[Natts_gs_dependencies_obj] = {false}; + Assert(nsp_name != NULL && pkg_name != NULL && old_func_name != NULL && new_func_name != NULL); + values[Anum_gs_dependencies_obj_name -1] = CStringGetTextDatum(new_func_name); + replaces[Anum_gs_dependencies_obj_name -1] = true; + ScanKeyInit(&key[keyNum++], Anum_gs_dependencies_schemaname, BTEqualStrategyNumber, F_NAMEEQ, + NameGetDatum(nsp_name)); + ScanKeyInit(&key[keyNum++], Anum_gs_dependencies_packagename, BTEqualStrategyNumber, F_NAMEEQ, + NameGetDatum(pkg_name)); + ScanKeyInit(&key[keyNum++], Anum_gs_dependencies_obj_name, BTEqualStrategyNumber, F_TEXTEQ, + CStringGetTextDatum(old_func_name)); + Relation relation = heap_open(DependenciesObjRelationId, RowExclusiveLock); + scan = systable_beginscan(relation, InvalidOid, false, SnapshotSelf, keyNum, key); + while (HeapTupleIsValid(tuple = systable_getnext(scan))) { + new_tuple = heap_modify_tuple(tuple, RelationGetDescr(relation), values, nulls, replaces); + simple_heap_update(relation, &new_tuple->t_self, new_tuple, true); + CatalogUpdateIndexes(relation, new_tuple); + heap_freetuple(new_tuple); + } + systable_endscan(scan); + heap_close(relation, RowExclusiveLock); + CommandCounterIncrement(); +} + +static void gsplsql_delete_dependencies_object_by_oid(Oid oid) +{ + Relation dep_rel = heap_open(DependenciesObjRelationId, RowExclusiveLock); + ScanKeyData key; + ScanKeyInit(&key, ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(oid)); + SysScanDesc scan = systable_beginscan(dep_rel, DependenciesObjOidIndexId, true, SnapshotSelf, 1, &key); + HeapTuple tuple = systable_getnext(scan); + if (!HeapTupleIsValid(tuple)) { + systable_endscan(scan); + heap_close(dep_rel, RowExclusiveLock); + ereport(LOG, (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("dependencies object %u does not exist.", oid))); + return; + } + simple_heap_delete(dep_rel, &tuple->t_self, 0, true); + systable_endscan(scan); + heap_close(dep_rel, RowExclusiveLock); + CommandCounterIncrement(); +} + +void gsplsql_remove_type_gs_dependency(const GsDependObjDesc* obj_desc) +{ + Relation relation = heap_open(DependenciesRelationId, RowExclusiveLock); + List* list = gsplsql_delete_objs(relation, obj_desc); + if (obj_desc->packageName != NULL) { + Oid nsp_oid = get_namespace_oid(obj_desc->schemaName, true); + Oid pkg_oid = PackageNameGetOid(obj_desc->packageName, nsp_oid); + ObjectAddress object; + object.classId = PackageRelationId; + object.objectId = pkg_oid; + ObjectAddress ref_object; + ListCell* cell = NULL; + foreach(cell, list) { + Oid ref_obj_oid = lfirst_oid(cell); + GsDependObjDesc ref_obj_desc; + bool has_object = gsplsql_search_depend_obj_by_oid(ref_obj_oid, &ref_obj_desc); + if (has_object) { + if (ref_obj_desc.packageName != NULL) { + Oid ref_nsp_oid = get_namespace_oid(ref_obj_desc.schemaName, true); + Oid ref_pkg_oid = PackageNameGetOid(ref_obj_desc.packageName, ref_nsp_oid); + ref_object.classId = PackageRelationId; + ref_object.objectId = ref_pkg_oid; + DeletePgDependObject(&object, &ref_object); + } + free_gs_depend_obj_desc(&ref_obj_desc); + } + } + } + gsplsql_delete_unrefer_depend_obj_in_list(list, true); + list_free(list); + heap_close(relation, RowExclusiveLock); +} \ No newline at end of file diff --git a/src/common/backend/utils/init/globals.cpp b/src/common/backend/utils/init/globals.cpp index 94c3cd33c..bb39a1f02 100644 --- a/src/common/backend/utils/init/globals.cpp +++ b/src/common/backend/utils/init/globals.cpp @@ -75,12 +75,13 @@ bool will_shutdown = false; * NEXT | 92899 | ? | ? * ********************************************/ -const uint32 GRAND_VERSION_NUM = 92915; +const uint32 GRAND_VERSION_NUM = 92916; /******************************************** * 2.VERSION NUM FOR EACH FEATURE * Please write indescending order. ********************************************/ +const uint32 SUPPORT_GS_DEPENDENCY_VERSION_NUM = 92916; const uint32 SPQ_VERSION_NUM = 92915; const uint32 PARTITION_ACCESS_EXCLUSIVE_LOCK_UPGRADE_VERSION = 92913; const uint32 PAGE_DIST_VERSION_NUM = 92912; diff --git a/src/common/backend/utils/misc/guc/guc_sql.cpp b/src/common/backend/utils/misc/guc/guc_sql.cpp index edc4298c7..fad34bfdb 100755 --- a/src/common/backend/utils/misc/guc/guc_sql.cpp +++ b/src/common/backend/utils/misc/guc/guc_sql.cpp @@ -384,7 +384,8 @@ static const struct behavior_compat_entry behavior_compat_options[OPT_MAX] = { {"truncate_numeric_tail_zero", OPT_TRUNC_NUMERIC_TAIL_ZERO}, {"allow_orderby_undistinct_column", OPT_ALLOW_ORDERBY_UNDISTINCT_COLUMN}, {"select_into_return_null", OPT_SELECT_INTO_RETURN_NULL}, - {"accept_empty_str", OPT_ACCEPT_EMPTY_STR} + {"accept_empty_str", OPT_ACCEPT_EMPTY_STR}, + {"plpgsql_dependency", OPT_PLPGSQL_DEPENDENCY} }; // increase SQL_IGNORE_STRATEGY_NUM if we need more strategy diff --git a/src/common/backend/utils/misc/guc/guc_storage.cpp b/src/common/backend/utils/misc/guc/guc_storage.cpp index d7201f1a7..2563c82e4 100755 --- a/src/common/backend/utils/misc/guc/guc_storage.cpp +++ b/src/common/backend/utils/misc/guc/guc_storage.cpp @@ -6003,7 +6003,8 @@ static bool check_and_assign_type_oids(List* elemlist) if ((typeoid = atooid(static_cast(list_nth(elemlist, 1)))) >= FirstBootstrapObjectId || (arraytypeid = atooid(static_cast(list_nth(elemlist, 2)))) >= FirstBootstrapObjectId || - ((typtype = *static_cast(list_nth(elemlist, 3))) != TYPTYPE_BASE && typtype != TYPTYPE_PSEUDO && typtype != TYPTYPE_SET)) + ((typtype = *static_cast(list_nth(elemlist, 3))) != TYPTYPE_BASE + && typtype != TYPTYPE_PSEUDO && typtype != TYPTYPE_SET && typtype != TYPTYPE_UNDEFINE)) return false; u_sess->upg_cxt.Inplace_upgrade_next_pg_type_oid = typeoid; diff --git a/src/common/backend/utils/misc/sec_rls_utils.cpp b/src/common/backend/utils/misc/sec_rls_utils.cpp index b8d48c91c..593c18cb6 100644 --- a/src/common/backend/utils/misc/sec_rls_utils.cpp +++ b/src/common/backend/utils/misc/sec_rls_utils.cpp @@ -31,6 +31,11 @@ #include "utils/rel.h" #include "utils/sec_rls_utils.h" #include "utils/syscache.h" +#include "catalog/pg_depend.h" +#include "utils/fmgroids.h" +#include "catalog/pg_rlspolicy.h" +#include "catalog/pg_proc.h" +#include "catalog/indexing.h" /* * CheckBypassRlsPolicies @@ -220,3 +225,28 @@ void SupportRlsForRel(const Relation relation) /* relase sys cache tuple */ ReleaseSysCache(tuple); } + +bool IsRlsFunction(Oid funcid) +{ + if (!OidIsValid(funcid)) { + return false; + } + ScanKeyData key[2]; + HeapTuple tup = NULL; + Form_pg_depend deprec; + Relation relation = heap_open(DependRelationId, AccessShareLock); + ScanKeyInit(&key[0], Anum_pg_depend_refclassid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(ProcedureRelationId)); + ScanKeyInit(&key[1], Anum_pg_depend_refobjid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(funcid)); + SysScanDesc scan = systable_beginscan(relation, DependReferenceIndexId, true, NULL, 2, key); + while (HeapTupleIsValid(tup = systable_getnext(scan))) { + deprec = (Form_pg_depend)GETSTRUCT(tup); + if (deprec->classid == RlsPolicyRelationId) { + systable_endscan(scan); + heap_close(relation, AccessShareLock); + return true; + } + } + systable_endscan(scan); + heap_close(relation, AccessShareLock); + return false; +} \ No newline at end of file diff --git a/src/common/interfaces/libpq/frontend_parser/gram.y b/src/common/interfaces/libpq/frontend_parser/gram.y index b366d2eb2..fd4955325 100755 --- a/src/common/interfaces/libpq/frontend_parser/gram.y +++ b/src/common/interfaces/libpq/frontend_parser/gram.y @@ -518,7 +518,7 @@ extern THR_LOCAL bool stmt_contains_operator_plus; CACHE CALL CALLED CANCELABLE CASCADE CASCADED CASE CAST CATALOG_P CATALOG_NAME CHAIN CHANGE CHAR_P CHARACTER CHARACTERISTICS CHARACTERSET CHECK CHECKPOINT CHARSET CLASS CLASS_ORIGIN CLEAN CLIENT CLIENT_MASTER_KEY CLIENT_MASTER_KEYS CLOB CLOSE CLUSTER COALESCE COLLATE COLLATION COLUMN COLUMN_ENCRYPTION_KEY COLUMN_ENCRYPTION_KEYS COLUMN_NAME COLUMNS COMMENT COMMENTS COMMIT CONVERT_P - CONNECT COMMITTED COMPACT COMPATIBLE_ILLEGAL_CHARS COMPLETE COMPLETION COMPRESS CONDITION CONCURRENTLY CONFIGURATION CONNECTBY CONNECTION CONSISTENT CONSTANT CONSTRAINT + CONNECT COMMITTED COMPACT COMPATIBLE_ILLEGAL_CHARS COMPILE COMPLETE COMPLETION COMPRESS CONDITION CONCURRENTLY CONFIGURATION CONNECTBY CONNECTION CONSISTENT CONSTANT CONSTRAINT CONSTRAINT_CATALOG CONSTRAINT_NAME CONSTRAINT_SCHEMA CONSTRAINTS CONTENT_P CONTINUE_P CONTVIEW CONVERSION_P COORDINATOR COORDINATORS COPY COST CREATE CROSS CSN CSV CUBE CURRENT_P CURRENT_CATALOG CURRENT_DATE CURRENT_ROLE CURRENT_SCHEMA @@ -584,7 +584,7 @@ extern THR_LOCAL bool stmt_contains_operator_plus; SAMPLE SAVEPOINT SCHEDULE SCHEMA SCHEMA_NAME SCROLL SEARCH SECOND_P SECURITY SELECT SEPARATOR_P SEQUENCE SEQUENCES SERIALIZABLE SERVER SESSION SESSION_USER SET SETS SETOF SHARE SHIPPABLE SHOW SHUTDOWN SIBLINGS - SIMILAR SIMPLE SIZE SKIP SLAVE SLICE SMALLDATETIME SMALLDATETIME_FORMAT_P SMALLINT SNAPSHOT SOME SOURCE_P SPACE SPILL SPLIT STABLE STACKED_P STANDALONE_P START STARTS STARTWITH + SIMILAR SIMPLE SIZE SKIP SLAVE SLICE SMALLDATETIME SMALLDATETIME_FORMAT_P SMALLINT SNAPSHOT SOME SOURCE_P SPACE SPECIFICATION SPILL SPLIT STABLE STACKED_P STANDALONE_P START STARTS STARTWITH STATEMENT STATEMENT_ID STATISTICS STDIN STDOUT STORAGE STORE_P STORED STRATIFY STREAM STRICT_P STRIP_P SUBCLASS_ORIGIN SUBPARTITION SUBPARTITIONS SUBSCRIPTION SUBSTRING SWLEVEL SWNOCYCLE SWROWNUM SYMMETRIC SYNONYM SYSDATE SYSID SYSTEM_P SYS_REFCURSOR STARTING SQL_P @@ -11663,6 +11663,7 @@ unreserved_keyword: | COMMITTED | COMPATIBLE_ILLEGAL_CHARS | COMPLETE + | COMPILE | COMPLETION | COMPRESS | CONDITION @@ -11967,6 +11968,7 @@ unreserved_keyword: | SNAPSHOT | SOURCE_P | SPACE + | SPECIFICATION | SPILL | SQL_P | STABLE diff --git a/src/common/pl/plpgsql/src/gram.y b/src/common/pl/plpgsql/src/gram.y index 2a798b661..0ad2f767c 100755 --- a/src/common/pl/plpgsql/src/gram.y +++ b/src/common/pl/plpgsql/src/gram.y @@ -18,6 +18,7 @@ #include "access/xact.h" #include "catalog/dependency.h" #include "catalog/gs_package.h" +#include "catalog/gs_dependencies_fn.h" #include "catalog/namespace.h" #include "catalog/pg_proc.h" #include "catalog/pg_synonym.h" @@ -240,7 +241,7 @@ static Oid get_table_type(PLpgSQL_datum* datum); static Node* make_columnDef_from_attr(PLpgSQL_rec_attr* attr); static TypeName* make_typename_from_datatype(PLpgSQL_type* datatype); static Oid plpgsql_build_package_record_type(const char* typname, List* list, bool add2namespace); -static void plpgsql_build_package_array_type(const char* typname, Oid elemtypoid, char arraytype); +static void plpgsql_build_package_array_type(const char* typname, Oid elemtypoid, char arraytype, TypeDependExtend* dependExtend = NULL); static void plpgsql_build_package_refcursor_type(const char* typname); int plpgsql_yylex_single(void); static void get_datum_tok_type(PLpgSQL_datum* target, int* tok_flag); @@ -1299,6 +1300,9 @@ decl_statement : decl_varname_list decl_const decl_datatype decl_collate decl_no parser_errposition(@5))); } } + if (enable_plpgsql_gsdependency()) { + gsplsql_build_gs_type_in_body_dependency($3); + } } pfree_ext(varname->name); } @@ -1442,7 +1446,7 @@ decl_statement : decl_varname_list decl_const decl_datatype decl_collate decl_no plpgsql_build_varrayType($2->name, $2->lineno, $9, true); if (IS_PACKAGE) { - plpgsql_build_package_array_type($2->name, $9->typoid, TYPCATEGORY_ARRAY); + plpgsql_build_package_array_type($2->name, $9->typoid, TYPCATEGORY_ARRAY, $9->dependExtend); } pfree_ext($2->name); pfree($2); @@ -1596,7 +1600,7 @@ decl_statement : decl_varname_list decl_const decl_datatype decl_collate decl_no } plpgsql_build_tableType($2->name, $2->lineno, $6, true); if (IS_PACKAGE) { - plpgsql_build_package_array_type($2->name, $6->typoid, TYPCATEGORY_TABLEOF); + plpgsql_build_package_array_type($2->name, $6->typoid, TYPCATEGORY_TABLEOF, $6->dependExtend); } pfree_ext($2->name); pfree($2); @@ -1767,9 +1771,9 @@ decl_statement : decl_varname_list decl_const decl_datatype decl_collate decl_no if (IS_PACKAGE) { if ($10->typoid == VARCHAROID) { - plpgsql_build_package_array_type($2->name, $6->typoid, TYPCATEGORY_TABLEOF_VARCHAR); + plpgsql_build_package_array_type($2->name, $6->typoid, TYPCATEGORY_TABLEOF_VARCHAR, $6->dependExtend); } else { - plpgsql_build_package_array_type($2->name, $6->typoid, TYPCATEGORY_TABLEOF_INTEGER); + plpgsql_build_package_array_type($2->name, $6->typoid, TYPCATEGORY_TABLEOF_INTEGER, $6->dependExtend); } } pfree_ext($2->name); @@ -1914,6 +1918,11 @@ decl_statement : decl_varname_list decl_const decl_datatype decl_collate decl_no } if (IS_PACKAGE) { newp->typoid = plpgsql_build_package_record_type($2->name, $6, true); + } else if (enable_plpgsql_gsdependency()) { + ListCell* cell = NULL; + foreach(cell, $6) { + gsplsql_build_gs_type_in_body_dependency(((PLpgSQL_rec_attr*)lfirst(cell))->type); + } } pfree_ext($2->name); pfree($2); @@ -5968,6 +5977,9 @@ cursor_variable : T_DATUM $1.ident), parser_errposition(@1))); } + if (enable_plpgsql_gsdependency()) { + gsplsql_build_gs_variable_dependency($1.idents); + } $$ = $1.dno; } | T_WORD @@ -8279,6 +8291,12 @@ static bool construct_cword(StringInfo ds, ArrayParseContext *context, int *tok, } else { yyerror("syntax error"); } + if (enable_plpgsql_gsdependency()) { + FuncCandidateList clist = FuncnameGetCandidates(idents, -1, NIL, false, false, true); + if (clist == NULL) { + gsplsql_build_gs_variable_dependency(idents); + } + } if (u_sess->attr.attr_sql.sql_compatibility != A_FORMAT) { int dno = -1; char *name = NameListToString(idents); @@ -8300,7 +8318,21 @@ static bool construct_cword(StringInfo ds, ArrayParseContext *context, int *tok, int curloc = yylloc; *tok = yylex(); plpgsql_push_back_token(*tok); - return construct_object_type(ds, context, makeTypeNameFromNameList(idents), tok, parenlevel, curloc, loc); + bool result; + CreatePlsqlType oldCreatePlsqlType = u_sess->plsql_cxt.createPlsqlType; + PG_TRY(); + { + set_create_plsql_type_not_check_nsp_oid(); + result = construct_object_type(ds, context, makeTypeNameFromNameList(idents), tok, parenlevel, curloc, loc); + set_create_plsql_type(oldCreatePlsqlType); + } + PG_CATCH(); + { + set_create_plsql_type(oldCreatePlsqlType); + PG_RE_THROW(); + } + PG_END_TRY(); + return result; } /* Convenience routine to read an expression with one possible terminator */ @@ -8879,6 +8911,9 @@ read_sql_construct6(int until, idents = yylval.wdatum.idents; int var_dno = yylval.wdatum.dno; + if (enable_plpgsql_gsdependency()) { + gsplsql_build_gs_variable_dependency(idents); + } if (type_flag == PLPGSQL_TOK_TABLE_VAR) { /* * table var name may be schema.pkg.table_var @@ -9591,16 +9626,20 @@ read_datatype(int tok) if (tok_is_keyword(tok, &yylval, K_TYPE, "type")) { + TypeDependExtend* typeDependExtend = NULL; + if (enable_plpgsql_gsdependency()) { + InstanceTypeNameDependExtend(&typeDependExtend); + } /* find val.col%TYPE first */ HeapTuple tup = NULL; int collectionType = PLPGSQL_COLLECTION_NONE; Oid tableOfIndexType = InvalidOid; int32 typMod = -1; - tup = FindRowVarColType(dtnames, &collectionType, &tableOfIndexType, &typMod); + tup = FindRowVarColType(dtnames, &collectionType, &tableOfIndexType, &typMod, typeDependExtend); if (tup != NULL) { Oid typOid = typeTypeId(tup); ReleaseSysCache(tup); - PLpgSQL_type* type = plpgsql_build_datatype(typOid, typMod, InvalidOid); + PLpgSQL_type* type = plpgsql_build_datatype(typOid, typMod, InvalidOid, typeDependExtend); if (OidIsValid(tableOfIndexType)) { type->collectionType = collectionType; type->tableOfIndexType = tableOfIndexType; @@ -9610,22 +9649,47 @@ read_datatype(int tok) /* find pkg.var%TYPE second */ PLpgSQL_datum* datum = GetPackageDatum(dtnames); - if (datum != NULL && datum->dtype == PLPGSQL_DTYPE_VAR) { - PLpgSQL_var* var = (PLpgSQL_var*)datum; - Oid typOid = var->datatype->typoid; - int32 typmod = var->datatype->atttypmod; - Oid collation = var->datatype->collation; - int collectionType = var->datatype->collectionType; - Oid tableOfIndexType = var->datatype->tableOfIndexType; - - PLpgSQL_type* type = plpgsql_build_datatype(typOid, typmod, collation); - type->collectionType = collectionType; - type->tableOfIndexType = tableOfIndexType; - return type; + if (datum != NULL) { + if (datum->dtype == PLPGSQL_DTYPE_VAR) { + PLpgSQL_var* var = (PLpgSQL_var*)datum; + Oid typOid = var->datatype->typoid; + int32 typmod = var->datatype->atttypmod; + Oid collation = var->datatype->collation; + int collectionType = var->datatype->collectionType; + Oid tableOfIndexType = var->datatype->tableOfIndexType; + if (var->pkg != NULL && enable_plpgsql_gsdependency()) { + typeDependExtend->objectName = pstrdup(var->refname); + typeDependExtend->packageName = pstrdup(var->pkg->pkg_signature); + typeDependExtend->schemaName = get_namespace_name(var->pkg->namespaceOid); + } + PLpgSQL_type* type = plpgsql_build_datatype(typOid, typmod, collation, typeDependExtend); + type->collectionType = collectionType; + type->tableOfIndexType = tableOfIndexType; + return type; + } else if (datum->dtype == PLPGSQL_DTYPE_ROW){ + PLpgSQL_row* row = (PLpgSQL_row*)datum; + if (row->rowtupdesc && row->rowtupdesc->tdtypeid != RECORDOID && + OidIsValid(row->rowtupdesc->tdtypeid)) { + if (row->pkg != NULL && enable_plpgsql_gsdependency()) { + typeDependExtend->objectName = pstrdup(row->refname); + typeDependExtend->packageName = pstrdup(row->pkg->pkg_signature); + typeDependExtend->schemaName = get_namespace_name(row->pkg->namespaceOid); + } + return plpgsql_build_datatype(row->rowtupdesc->tdtypeid, -1, InvalidOid, typeDependExtend); + } + } } - result = plpgsql_parse_cwordtype(dtnames); + result = plpgsql_parse_cwordtype(dtnames, typeDependExtend); if (result) return result; + if (enable_plpgsql_undefined()) { + Oid tryUndefObjOid = gsplsql_try_build_exist_pkg_undef_var(dtnames); + if (OidIsValid(tryUndefObjOid)) { + typeDependExtend->undefDependObjOid = tryUndefObjOid; + typeDependExtend->dependUndefined = true; + return plpgsql_build_datatype(UNDEFINEDOID, -1, InvalidOid, typeDependExtend); + } + } } else if (tok_is_keyword(tok, &yylval, K_ROWTYPE, "rowtype")) @@ -12031,7 +12095,25 @@ parse_datatype(const char *string, int location) u_sess->plsql_cxt.plpgsql_yylloc = plpgsql_yylloc; /* Let the main parser try to parse it under standard SQL rules */ - parseTypeString(string, &type_id, &typmod); + TypeDependExtend* typeDependExtend = NULL; + if (enable_plpgsql_gsdependency()) { + InstanceTypeNameDependExtend(&typeDependExtend); + CreatePlsqlType oldCreatePlsqlType = u_sess->plsql_cxt.createPlsqlType; + PG_TRY(); + { + set_create_plsql_type_not_check_nsp_oid(); + parseTypeString(string, &type_id, &typmod, typeDependExtend); + set_create_plsql_type(oldCreatePlsqlType); + } + PG_CATCH(); + { + set_create_plsql_type(oldCreatePlsqlType); + PG_RE_THROW(); + } + PG_END_TRY(); + } else { + parseTypeString(string, &type_id, &typmod, typeDependExtend); + } (void)MemoryContextSwitchTo(oldCxt); @@ -12041,11 +12123,11 @@ parse_datatype(const char *string, int location) /* Okay, build a PLpgSQL_type data structure for it */ if (u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile == NULL) { - return plpgsql_build_datatype(type_id, typmod, 0); + return plpgsql_build_datatype(type_id, typmod, 0, typeDependExtend); } return plpgsql_build_datatype(type_id, typmod, - u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile->fn_input_collation); + u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile->fn_input_collation, typeDependExtend); } /* Build a arrary_type by elem_type. */ @@ -12420,6 +12502,9 @@ static PLpgSQL_type* build_type_from_record_var(int dno, int location) /* already build one, just use it */ if(IsPackageDependType(oldtypeoid, pkgoid)) { newtypeoid = oldtypeoid; + if (CompileWhich() == PLPGSQL_COMPILE_PACKAGE) { + (void)gsplsql_flush_undef_ref_type_dependency(newtypeoid); + } } else { ereport(errstate, (errmodule(MOD_PLSQL), @@ -12459,6 +12544,9 @@ static PLpgSQL_type* build_type_from_record_var(int dno, int location) /* build dependency on created composite type. */ buildDependencyForCompositeType(newtypeoid); + if (CompileWhich() == PLPGSQL_COMPILE_PACKAGE) { + (void)gsplsql_flush_undef_ref_type_dependency(newtypeoid); + } } /* build datatype of the created composite type. */ @@ -12496,6 +12584,7 @@ static Oid plpgsql_build_package_record_type(const char* typname, List* list, bo Oid oldtypeoid = InvalidOid; Oid newtypeoid = InvalidOid; char* schamaName = NULL; + Oid pkgOid = u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package->pkg_oid; Oid pkgNamespaceOid = u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package->namespaceOid; if (OidIsValid(pkgNamespaceOid)) { schamaName = get_namespace_name(pkgNamespaceOid); @@ -12503,7 +12592,7 @@ static Oid plpgsql_build_package_record_type(const char* typname, List* list, bo pkgNamespaceOid = getCurrentNamespace(); } char* casttypename = CastPackageTypeName(typname, - u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package->pkg_oid, true, + pkgOid, true, u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package->is_spec_compiling); if (strlen(casttypename) >= NAMEDATALEN ) { ereport(errstate, @@ -12518,10 +12607,14 @@ static Oid plpgsql_build_package_record_type(const char* typname, List* list, bo } oldtypeoid = GetSysCacheOid2(TYPENAMENSP, PointerGetDatum(casttypename), ObjectIdGetDatum(pkgNamespaceOid)); - if (OidIsValid(oldtypeoid)) { + bool oldTypeOidIsValid = OidIsValid(oldtypeoid); + if (oldTypeOidIsValid) { /* already build on, just use it */ - if(IsPackageDependType(oldtypeoid, u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package->pkg_oid)) { + if(IsPackageDependType(oldtypeoid, pkgOid)) { newtypeoid = oldtypeoid; + if (CompileWhich() == PLPGSQL_COMPILE_PACKAGE) { + (void)gsplsql_flush_undef_ref_type_dependency(newtypeoid); + } } else { ereport(errstate, (errmodule(MOD_PLSQL), @@ -12568,6 +12661,9 @@ static Oid plpgsql_build_package_record_type(const char* typname, List* list, bo CommandCounterIncrement(); pfree_ext(r); list_free_deep(codeflist); + if (CompileWhich() == PLPGSQL_COMPILE_PACKAGE) { + gsplsql_build_ref_type_dependency(newtypeoid); + } } PLpgSQL_type *newtype = NULL; @@ -12583,7 +12679,7 @@ static Oid plpgsql_build_package_record_type(const char* typname, List* list, bo return newtypeoid; } -static void plpgsql_build_package_array_type(const char* typname,Oid elemtypoid, char arraytype) +static void plpgsql_build_package_array_type(const char* typname,Oid elemtypoid, char arraytype, TypeDependExtend* dependExtend) { char typtyp; ObjectAddress myself, referenced; @@ -12604,8 +12700,25 @@ static void plpgsql_build_package_array_type(const char* typname,Oid elemtypoid pkgNamespaceOid = getCurrentNamespace(); } + Oid pkgOid = u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package->pkg_oid; Oid oldtypeoid = GetSysCacheOid2(TYPENAMENSP, PointerGetDatum(casttypename), ObjectIdGetDatum(pkgNamespaceOid)); + bool oldtypeoidIsValid = OidIsValid(oldtypeoid); + if (enable_plpgsql_gsdependency() && u_sess->plsql_cxt.need_create_depend) { + char* schemaName = get_namespace_name(pkgNamespaceOid); + char* packageName = GetPackageName(pkgOid); + bool dependUndef = gsplsql_check_type_depend_undefined(schemaName, packageName, typname); + pfree_ext(schemaName); + pfree_ext(packageName); + if (dependUndef) { + ObjectAddress address; + address.classId = TypeRelationId; + address.objectId = oldtypeoid; + address.objectSubId = 0; + performDeletion(&address, DROP_CASCADE, PERFORM_DELETION_INTERNAL); + oldtypeoidIsValid = false; + } + } if (OidIsValid(oldtypeoid)) { /* alread build one, just return */ if(IsPackageDependType(oldtypeoid, u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package->pkg_oid)) { @@ -12624,7 +12737,9 @@ static void plpgsql_build_package_array_type(const char* typname,Oid elemtypoid if (arraytype == TYPCATEGORY_TABLEOF || arraytype == TYPCATEGORY_TABLEOF_VARCHAR || arraytype == TYPCATEGORY_TABLEOF_INTEGER) { - elemtypoid = get_array_type(elemtypoid); + if (UNDEFINEDOID != elemtypoid) { + elemtypoid = get_array_type(elemtypoid); + } typtyp = TYPTYPE_TABLEOF; } else { typtyp = TYPTYPE_BASE; @@ -12665,7 +12780,8 @@ static void plpgsql_build_package_array_type(const char* typname,Oid elemtypoid -1, /* typmod */ 0, /* array dimensions for typBaseType */ false, /* Type NOT NULL */ - get_typcollation(elemtypoid)); + get_typcollation(elemtypoid), + dependExtend); CommandCounterIncrement(); @@ -12678,6 +12794,7 @@ static void plpgsql_build_package_array_type(const char* typname,Oid elemtypoid pfree_ext(casttypename); } + static void plpgsql_build_package_refcursor_type(const char* typname) { CreateSynonymStmt stmt; @@ -12789,7 +12906,7 @@ static Node* make_columnDef_from_attr(PLpgSQL_rec_attr* attr) static TypeName* make_typename_from_datatype(PLpgSQL_type* datatype) { - return makeTypeNameFromOid(datatype->typoid, datatype->atttypmod); + return makeTypeNameFromOid(datatype->typoid, datatype->atttypmod, datatype->dependExtend); } /* diff --git a/src/common/pl/plpgsql/src/pl_comp.cpp b/src/common/pl/plpgsql/src/pl_comp.cpp index 8255d637a..eb72dc22e 100644 --- a/src/common/pl/plpgsql/src/pl_comp.cpp +++ b/src/common/pl/plpgsql/src/pl_comp.cpp @@ -48,7 +48,9 @@ #include "miscadmin.h" #include "tcop/tcopprot.h" #include "commands/event_trigger.h" - +#include "catalog/gs_dependencies_fn.h" +#include "catalog/pg_object.h" +#include "catalog/pg_type_fn.h" /* functions reference other modules */ extern THR_LOCAL List* baseSearchPath; @@ -124,13 +126,14 @@ static bool plpgsql_check_search_path(PLpgSQL_function* func, HeapTuple proc_tup return check_search_path_interface(func->fn_searchpath->schemas, proc_tup); } -PLpgSQL_function* plpgsql_compile(FunctionCallInfo fcinfo, bool for_validator) +PLpgSQL_function* plpgsql_compile(FunctionCallInfo fcinfo, bool for_validator, bool isRecompile) { Oid func_oid = fcinfo->flinfo->fn_oid; PLpgSQL_func_hashkey hashkey; bool function_valid = false; bool hashkey_valid = false; bool isnull = false; + bool func_valid = true; /* * Lookup the pg_proc tuple by Oid; we'll need it in any case */ @@ -149,7 +152,25 @@ PLpgSQL_function* plpgsql_compile(FunctionCallInfo fcinfo, bool for_validator) Datum pkgoiddatum = SysCacheGetAttr(PROCOID, proc_tup, Anum_pg_proc_packageid, &isnull); Oid packageOid = DatumGetObjectId(pkgoiddatum); Oid old_value = saveCallFromPkgOid(packageOid); - + if (enable_plpgsql_gsdependency_guc()) { + if (func == NULL) { + /* Compute hashkey using function signature and actual arg types */ + compute_function_hashkey(proc_tup, fcinfo, proc_struct, &hashkey, for_validator); + hashkey_valid = true; + /* And do the lookup */ + func = plpgsql_HashTableLookup(&hashkey); + } + /** + * only check for func need recompile or not, + */ + if (func_oid >= FirstNormalObjectId) { + func_valid = GetPgObjectValid(func_oid, OBJECT_TYPE_PROC); + } + if (!func_valid) { + fcinfo->flinfo->fn_extra = NULL; + } + } + recheck: if (func == NULL) { /* Compute hashkey using function signature and actual arg types */ @@ -160,10 +181,16 @@ recheck: func = plpgsql_HashTableLookup(&hashkey); } + if (!func_valid && func != NULL && !u_sess->plsql_cxt.need_create_depend && + !isRecompile && u_sess->SPI_cxt._connected >= 0 && !u_sess->plsql_cxt.during_compile) { + func->is_need_recompile = true; + } + if (func != NULL) { /* We have a compiled function, but is it still valid? */ if (func->fn_xmin == HeapTupleGetRawXmin(proc_tup) && - ItemPointerEquals(&func->fn_tid, &proc_tup->t_self) && plpgsql_check_search_path(func, proc_tup)) { + ItemPointerEquals(&func->fn_tid, &proc_tup->t_self) && plpgsql_check_search_path(func, proc_tup) && + !isRecompile && !func->is_need_recompile) { function_valid = true; } else { /* @@ -230,9 +257,14 @@ recheck: */ PLpgSQL_compile_context* save_compile_context = u_sess->plsql_cxt.curr_compile_context; int save_compile_status = getCompileStatus(); + bool save_curr_status = GetCurrCompilePgObjStatus(); PG_TRY(); { + List* ref_obj_list = gsplsql_prepare_recompile_func(func_oid, proc_struct->pronamespace, packageOid, isRecompile); + SetCurrCompilePgObjStatus(true); func = do_compile(fcinfo, proc_tup, func, &hashkey, for_validator); + UpdateCurrCompilePgObjStatus(save_curr_status); + gsplsql_complete_recompile_func(ref_obj_list); (void)CompileStatusSwtichTo(save_compile_status); } PG_CATCH(); @@ -245,6 +277,7 @@ recheck: InsertError(func_oid); } #endif + SetCurrCompilePgObjStatus(save_compile_status); popToOldCompileContext(save_compile_context); (void)CompileStatusSwtichTo(save_compile_status); PG_RE_THROW(); @@ -590,6 +623,7 @@ static PLpgSQL_function* do_compile(FunctionCallInfo fcinfo, HeapTuple proc_tup, int* in_arg_varnos = NULL; PLpgSQL_variable** out_arg_variables; Oid pkgoid = InvalidOid; + Oid namespaceOid = InvalidOid; Oid* saved_pseudo_current_userId = NULL; char* signature = NULL; @@ -631,6 +665,8 @@ static PLpgSQL_function* do_compile(FunctionCallInfo fcinfo, HeapTuple proc_tup, /* Null prokind items are created when there is no procedure */ isFunc = true; } + Datum pronamespaceDatum = SysCacheGetAttr(PROCOID, proc_tup, Anum_pg_proc_pronamespace, &isnull); + namespaceOid = DatumGetObjectId(pronamespaceDatum); /* * Setup error traceback support for ereport() */ @@ -715,6 +751,7 @@ static PLpgSQL_function* do_compile(FunctionCallInfo fcinfo, HeapTuple proc_tup, curr_compile->compile_tmp_cxt = MemoryContextSwitchTo(curr_compile->compile_cxt); func->fn_signature = pstrdup(signature); func->is_private = BoolGetDatum(proisprivatedatum); + func->namespaceOid = namespaceOid; /* * if function belong to a package, it will use package search path. */ @@ -1196,8 +1233,63 @@ static PLpgSQL_function* do_compile(FunctionCallInfo fcinfo, HeapTuple proc_tup, * Now parse the function's text */ bool saved_flag = u_sess->plsql_cxt.have_error; - u_sess->plsql_cxt.have_error = false; - parse_rc = plpgsql_yyparse(); + ResourceOwnerData* oldowner = NULL; + int64 stackId = 0; + MemoryContext oldcxt; + volatile bool has_error = false; + if (enable_plpgsql_gsdependency_guc() && u_sess->plsql_cxt.isCreateFunction && !IsInitdb) { + oldowner = t_thrd.utils_cxt.CurrentResourceOwner; + oldcxt = CurrentMemoryContext; + SPI_savepoint_create("createFunction"); + stackId = u_sess->plsql_cxt.nextStackEntryId; + MemoryContextSwitchTo(oldcxt); + bool save_isPerform = u_sess->parser_cxt.isPerform; + PG_TRY(); + { + u_sess->parser_cxt.isPerform = false; + parse_rc = plpgsql_yyparse(); + u_sess->parser_cxt.isPerform = save_isPerform; + SPI_savepoint_release("createFunction"); + stp_cleanup_subxact_resource(stackId); + MemoryContextSwitchTo(oldcxt); + t_thrd.utils_cxt.CurrentResourceOwner = oldowner; + } + PG_CATCH(); + { + u_sess->parser_cxt.isPerform = save_isPerform; + SPI_savepoint_rollbackAndRelease("createFunction", InvalidTransactionId); + stp_cleanup_subxact_resource(stackId); + t_thrd.utils_cxt.CurrentResourceOwner = oldowner; + MemoryContextSwitchTo(oldcxt); + has_error = true; + ErrorData* edata = &t_thrd.log_cxt.errordata[t_thrd.log_cxt.errordata_stack_depth]; + ereport(WARNING, + (errmodule(MOD_PLSQL), + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("%s", edata->message), + errdetail("N/A"), + errcause("compile package or procedure error."), + erraction("check package or procedure error and redefine"))); + if (edata->sqlerrcode == ERRCODE_OUT_OF_LOGICAL_MEMORY) { + PG_RE_THROW(); + } + FlushErrorState(); + } + PG_END_TRY(); + }else { + bool save_isPerform = u_sess->parser_cxt.isPerform; + u_sess->parser_cxt.isPerform = false; + parse_rc = plpgsql_yyparse(); + u_sess->parser_cxt.isPerform = save_isPerform; + } + if (enable_plpgsql_gsdependency_guc() && has_error) { + plpgsql_scanner_finish(); + pfree_ext(proc_source); + PopOverrideSearchPath(); + u_sess->plsql_cxt.curr_compile_context = popCompileContext(); + clearCompileContext(curr_compile); + return NULL; + } #ifndef ENABLE_MULTIPLE_NODES if (u_sess->plsql_cxt.have_error && u_sess->attr.attr_common.plsql_show_all_error) { u_sess->plsql_cxt.have_error = false; @@ -1323,6 +1415,31 @@ static PLpgSQL_function* do_compile(FunctionCallInfo fcinfo, HeapTuple proc_tup, if (curr_compile->plpgsql_DumpExecTree) { plpgsql_dumptree(func); } + + if (enable_plpgsql_gsdependency_guc()) { + bool curr_compile_status = GetCurrCompilePgObjStatus(); + if (curr_compile_status) { + bool is_undefined = gsplsql_is_undefined_func(func->fn_oid); + func->isValid = !is_undefined; + + if (!func->isValid && u_sess->plsql_cxt.createPlsqlType == CREATE_PLSQL_TYPE_RECOMPILE) { + GsDependObjDesc obj = gsplsql_construct_func_head_obj(func->fn_oid, func->namespaceOid, func->pkg_oid); + obj.type = GSDEPEND_OBJECT_TYPE_PROCHEAD; + gsplsql_do_refresh_proc_header(&obj, &is_undefined); + } + + if (is_undefined && !u_sess->plsql_cxt.compile_has_warning_info) { + u_sess->plsql_cxt.compile_has_warning_info = true; + ereport(WARNING, (errmodule(MOD_PLSQL), errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("The header information of function %s is not defined.", NameStr(proc_struct->proname)))); + } + UpdateCurrCompilePgObjStatus(!is_undefined); + } else { + func->isValid = GetCurrCompilePgObjStatus(); + } + } else { + func->isValid = true; + } /* * add it to the hash table except specified function. */ @@ -2075,7 +2192,7 @@ void getTableofTypeFromVar(PLpgSQL_var* var, int* collectionType, Oid* tableofIn } } -HeapTuple FindRowVarColType(List* nameList, int* collectionType, Oid* tableofIndexType, int32* typMod) +HeapTuple FindRowVarColType(List* nameList, int* collectionType, Oid* tableofIndexType, int32* typMod, TypeDependExtend* dependExtend) { if (u_sess->plsql_cxt.curr_compile_context == NULL) { return NULL; @@ -2083,28 +2200,31 @@ HeapTuple FindRowVarColType(List* nameList, int* collectionType, Oid* tableofInd PLpgSQL_datum* datum = NULL; char* field = NULL; - + char* schemaName = NULL; + char* packageName = NULL; + char* objectName = NULL; /* find row var and field first */ switch (list_length(nameList)) { case 2: { + objectName = strVal(linitial(nameList)); datum = plpgsql_lookup_datum(false, strVal(linitial(nameList)), NULL, NULL, NULL); field = strVal(lsecond(nameList)); break; } case 3: { - char* word1 = strVal(linitial(nameList)); - char* word2 = strVal(lsecond(nameList)); - List *names2 = list_make2(makeString(word1), makeString(word2)); + packageName = strVal(linitial(nameList)); + objectName = strVal(lsecond(nameList)); + List *names2 = list_make2(makeString(packageName), makeString(objectName)); datum = GetPackageDatum(names2); list_free_ext(names2); field = strVal(lthird(nameList)); break; } case 4: { - char* word1 = strVal(linitial(nameList)); - char* word2 = strVal(lsecond(nameList)); - char* word3 = strVal(lthird(nameList)); - List *names3 = list_make3(makeString(word1), makeString(word2), makeString(word3)); + schemaName = strVal(linitial(nameList)); + packageName = strVal(lsecond(nameList)); + objectName = strVal(lthird(nameList)); + List *names3 = list_make3(makeString(schemaName), makeString(packageName), makeString(objectName)); datum = GetPackageDatum(names3); list_free_ext(names3); field = strVal(lfourth(nameList)); @@ -2154,6 +2274,12 @@ HeapTuple FindRowVarColType(List* nameList, int* collectionType, Oid* tableofInd return NULL; } + if (enable_plpgsql_gsdependency() && NULL != dependExtend) { + dependExtend->schemaName = schemaName; + dependExtend->packageName = packageName; + dependExtend->objectName = objectName; + } + HeapTuple tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typOid)); /* should not happen */ if (!HeapTupleIsValid(tup)) { @@ -3035,11 +3161,26 @@ PLpgSQL_type* plpgsql_parse_wordtype(char* ident) return NULL; } +static PLpgSQL_type* gsplsql_make_type_for_pkg_var_ref_type(GsDependObjDesc* obj, PLpgSQL_datum* datum, + TypeDependExtend* dependExtend) +{ + InstanceTypeNameDependExtend(&dependExtend); + dependExtend->schemaName = pstrdup(obj->schemaName); + dependExtend->packageName = pstrdup(obj->packageName); + dependExtend->objectName = pstrdup(obj->name); + PLpgSQL_var* var = (PLpgSQL_var*)datum; + PLpgSQL_type* type = plpgsql_build_datatype(var->datatype->typoid, var->datatype->atttypmod, + var->datatype->collation, dependExtend); + type->collectionType = var->datatype->collectionType; + type->tableOfIndexType = var->datatype->tableOfIndexType; + return type; +} + /* ---------- * plpgsql_parse_cwordtype Same lookup for compositeword%TYPE * ---------- */ -PLpgSQL_type* plpgsql_parse_cwordtype(List* idents) +PLpgSQL_type* plpgsql_parse_cwordtype(List* idents, TypeDependExtend* dependExtend) { PLpgSQL_type* dtype = NULL; PLpgSQL_nsitem* nse = NULL; @@ -3119,6 +3260,21 @@ PLpgSQL_type* plpgsql_parse_cwordtype(List* idents) goto done; } fldname = strVal(lthird(idents)); + } else if (enable_plpgsql_gsdependency_guc()) { + GsDependObjDesc objDesc; + Oid schemaOId = gsplsql_parse_pkg_var_obj4(&objDesc, idents); + if (!OidIsValid(schemaOId) || !OidIsValid(PackageNameGetOid(objDesc.packageName, schemaOId))) { + goto done; + } + List* new_var_name = list_make3(makeString(objDesc.schemaName), makeString(objDesc.packageName), + makeString(objDesc.name)); + PLpgSQL_datum* datum = GetPackageDatum(new_var_name); + list_free_ext(new_var_name); + if (datum != NULL && datum->dtype == PLPGSQL_DTYPE_VAR) { + MemoryContextSwitchTo(old_cxt); + return gsplsql_make_type_for_pkg_var_ref_type(&objDesc, datum, dependExtend); + } + goto done; } else { goto done; } @@ -3160,6 +3316,13 @@ PLpgSQL_type* plpgsql_parse_cwordtype(List* idents) */ MemoryContextSwitchTo(old_cxt); dtype = build_datatype(type_tup, attr_struct->atttypmod, attr_struct->attcollation); + if (enable_plpgsql_gsdependency() && NULL != dtype) { + Oid typ_oid = get_rel_type_id(class_oid); + AssertEreport(InvalidOid != typ_oid, MOD_PLSQL, "all relation must have type"); + dtype->dependExtend = dependExtend; + InstanceTypeNameDependExtend(&dtype->dependExtend); + dtype->dependExtend->typeOid = typ_oid; + } MemoryContextSwitchTo(u_sess->plsql_cxt.curr_compile_context->compile_tmp_cxt); done: @@ -3191,20 +3354,45 @@ PLpgSQL_type* plpgsql_parse_wordrowtype(char* ident) * but no need to collect more errdetails. */ (void)RelnameGetRelidExtended(ident, &class_oid); - + Oid typ_oid = InvalidOid; + TypeDependExtend* dependExtend = NULL; if (!OidIsValid(class_oid)) { char message[MAXSTRLEN]; errno_t rc = 0; rc = sprintf_s(message, MAXSTRLEN, "relation \"%s\" does not exist when parse word.", ident); securec_check_ss(rc, "", ""); InsertErrorMessage(message, u_sess->plsql_cxt.plpgsql_yylloc, true); - ereport(ERROR, - (errmodule(MOD_PLSQL), - errcode(ERRCODE_UNDEFINED_TABLE), - errmsg("relation \"%s\" does not exist when parse word.", ident))); + if (enable_plpgsql_undefined()) { + RangeVar rangvar; + rangvar.schemaname = NULL; + rangvar.relname = ident; + Oid undefRefObjOid = gsplsql_try_build_exist_schema_undef_table(&rangvar); + if (OidIsValid(undefRefObjOid)) { + InstanceTypeNameDependExtend(&dependExtend); + dependExtend->undefDependObjOid = undefRefObjOid; + dependExtend->dependUndefined = true; + typ_oid = UNDEFINEDOID; + ereport(WARNING, + (errmodule(MOD_PLSQL), + errcode(ERRCODE_UNDEFINED_TABLE), + errmsg("relation \"%s\" does not exist when parse word.", ident))); + } else { + ereport(ERROR, + (errmodule(MOD_PLSQL), + errcode(ERRCODE_UNDEFINED_TABLE), + errmsg("relation \"%s\" does not exist when parse word.", ident))); + } + } else { + ereport(ERROR, + (errmodule(MOD_PLSQL), + errcode(ERRCODE_UNDEFINED_TABLE), + errmsg("relation \"%s\" does not exist when parse word.", ident))); + } + } else { + typ_oid = get_rel_type_id(class_oid); } /* Build and return the row type struct */ - return plpgsql_build_datatype(get_rel_type_id(class_oid), -1, InvalidOid); + return plpgsql_build_datatype(typ_oid, -1, InvalidOid, dependExtend); } /* ---------- @@ -3218,23 +3406,64 @@ PLpgSQL_type* plpgsql_parse_cwordrowtype(List* idents) RangeVar* relvar = NULL; MemoryContext old_cxt = NULL; - if (list_length(idents) != 2) { + if (!enable_plpgsql_gsdependency_guc() && list_length(idents) != 2) { return NULL; } + switch (list_length(idents)) + { + case 1: + relvar = makeRangeVar(NULL, strVal(linitial(idents)), -1); + break; + case 2: + relvar = makeRangeVar(strVal(linitial(idents)), strVal(lsecond(idents)), -1); + break; + case 3: + relvar = makeRangeVar(strVal(lsecond(idents)), strVal(lthird(idents)), -1); + relvar->catalogname = strVal(linitial(idents)); + break; + default: + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("improper %%ROWTYPE reference"))); + break; + } /* Avoid memory leaks in long-term function context */ old_cxt = MemoryContextSwitchTo(u_sess->plsql_cxt.curr_compile_context->compile_tmp_cxt); /* Look up relation name. Can't lock it - we might not have privileges. */ - relvar = makeRangeVar(strVal(linitial(idents)), strVal(lsecond(idents)), -1); - + Oid typ_oid = InvalidOid; + TypeDependExtend* dependExtend = NULL; /* Here relvar is allowed to be a synonym object. */ - class_oid = RangeVarGetRelidExtended(relvar, NoLock, false, false, false, true, NULL, NULL); + if (!enable_plpgsql_undefined()) { + class_oid = RangeVarGetRelidExtended(relvar, NoLock, false, false, false, true, NULL, NULL); + pfree_ext(relvar); + typ_oid = get_rel_type_id(class_oid); + } else { + class_oid = RangeVarGetRelidExtended(relvar, NoLock, true, false, false, true, NULL, NULL); + typ_oid = get_rel_type_id(class_oid); + if (!OidIsValid(typ_oid) && enable_plpgsql_undefined()) { + Oid undefRefObjOid = gsplsql_try_build_exist_schema_undef_table(relvar); + pfree_ext(relvar); + if (OidIsValid(undefRefObjOid)) { + InstanceTypeNameDependExtend(&dependExtend); + dependExtend->undefDependObjOid = undefRefObjOid; + dependExtend->dependUndefined = true; + typ_oid = UNDEFINEDOID; + } + } + if (!OidIsValid(typ_oid) || UNDEFINEDOID == typ_oid) { + ereport((typ_oid == UNDEFINEDOID ? WARNING : ERROR), + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("relation does not exist when parse word."))); + } + } + MemoryContextSwitchTo(old_cxt); /* Build and return the row type struct */ - return plpgsql_build_datatype(get_rel_type_id(class_oid), -1, InvalidOid); + return plpgsql_build_datatype(typ_oid, -1, InvalidOid, dependExtend); } /* cursor generate a composite type, find its col type */ @@ -3970,7 +4199,7 @@ PLpgSQL_row* build_row_from_rec_type(const char* rowname, int lineno, PLpgSQL_re * If collation is not InvalidOid then it overrides the type's default * collation. But collation is ignored if the datatype is non-collatable. */ -PLpgSQL_type* plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation) +PLpgSQL_type* plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation, TypeDependExtend* type_depend_extend) { HeapTuple type_tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typeOid)); if (!HeapTupleIsValid(type_tup)) { @@ -4003,7 +4232,11 @@ PLpgSQL_type* plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation) typ = build_datatype(type_tup, typmod, collation); } ReleaseSysCache(type_tup); - + if (enable_plpgsql_gsdependency() && NULL != typ) { + InstanceTypeNameDependExtend(&type_depend_extend); + typ->dependExtend = type_depend_extend; + typ->dependExtend->typeOid = typeOid; + } return typ; } @@ -4045,6 +4278,7 @@ PLpgSQL_type* build_datatype(HeapTuple type_tup, int32 typmod, Oid collation) case TYPTYPE_DOMAIN: case TYPTYPE_ENUM: case TYPTYPE_RANGE: + case TYPTYPE_UNDEFINE: typ->ttype = PLPGSQL_TTYPE_SCALAR; break; case TYPTYPE_COMPOSITE: @@ -4075,6 +4309,7 @@ PLpgSQL_type* build_datatype(HeapTuple type_tup, int32 typmod, Oid collation) typ->typrelid = type_struct->typrelid; typ->typioparam = getTypeIOParam(type_tup); typ->collation = type_struct->typcollation; + typ->dependExtend = NULL; if (OidIsValid(collation) && OidIsValid(typ->collation)) { typ->collation = collation; } diff --git a/src/common/pl/plpgsql/src/pl_debugger.cpp b/src/common/pl/plpgsql/src/pl_debugger.cpp index c9da25752..24a5e3df3 100644 --- a/src/common/pl/plpgsql/src/pl_debugger.cpp +++ b/src/common/pl/plpgsql/src/pl_debugger.cpp @@ -391,8 +391,7 @@ void server_send_end_msg(DebugInfo* debug) char* pkgname = NULL; Assert(funcname != NULL); if (pkgoid != InvalidOid) { - NameData* pkgName = GetPackageName(pkgoid); - pkgname = NameStr(*pkgName); + pkgname = GetPackageName(pkgoid); } char* pkgfuncname = quote_qualified_identifier(pkgname, funcname); appendStringInfo(&str, "%u:%s:%d:%s", funcoid, pkgfuncname, 0, "[EXECUTION FINISHED]"); @@ -489,8 +488,8 @@ PLDebug_variable* get_debug_variable_var(PLpgSQL_var* node, const char* target) var->value = OidOutputFunctionCall(form->typoutput, node->value); } if (node->ispkg && node->pkg != NULL) { - NameData* pkgName = GetPackageName(node->pkg->pkg_oid); - var->pkgname = AssignStr(NameStr(*pkgName)); + char* pkgName = GetPackageName(node->pkg->pkg_oid); + var->pkgname = AssignStr(pkgName); } else { var->pkgname = pstrdup(""); } @@ -551,8 +550,8 @@ PLDebug_variable* get_debug_variable_row(PLpgSQL_row* node, PLpgSQL_execstate* e pfree(buf); } if (node->ispkg && node->pkg != NULL) { - NameData* pkgName = GetPackageName(node->pkg->pkg_oid); - var->pkgname = AssignStr(NameStr(*pkgName)); + char* pkgName = GetPackageName(node->pkg->pkg_oid); + var->pkgname = AssignStr(pkgName); } else { var->pkgname = pstrdup(""); } @@ -585,8 +584,8 @@ PLDebug_variable* get_debug_variable_rec(PLpgSQL_rec* node, const char* target) pfree(buf); } if (node->ispkg && node->pkg != NULL) { - NameData* pkgName = GetPackageName(node->pkg->pkg_oid); - var->pkgname = AssignStr(NameStr(*pkgName)); + char* pkgName = GetPackageName(node->pkg->pkg_oid); + var->pkgname = AssignStr(pkgName); } else { var->pkgname = pstrdup(""); } @@ -899,8 +898,7 @@ static bool get_cur_info(StringInfo str, PLpgSQL_execstate* estate, DebugInfo* d char* pkgname = NULL; if (pkgoid != InvalidOid) { - NameData* pkgName = GetPackageName(pkgoid); - pkgname = NameStr(*pkgName); + pkgname = GetPackageName(pkgoid); } char* pkgfuncname = quote_qualified_identifier(pkgname, funcname); @@ -1211,8 +1209,7 @@ PLDebug_frame* get_frame(DebugInfo* debug) funcname = pstrdup("anonymous block"); } if (pkgoid != InvalidOid) { - NameData* pkgName = GetPackageName(pkgoid); - pkgname = NameStr(*pkgName); + pkgname = GetPackageName(pkgoid); } frame->frameno = debug->debugStackIdx; frame->funcname = quote_qualified_identifier(pkgname, funcname); @@ -1888,4 +1885,4 @@ static void debug_server_info_code(DebugInfo* debug) } pfree(buf); -} \ No newline at end of file +} diff --git a/src/common/pl/plpgsql/src/pl_exec.cpp b/src/common/pl/plpgsql/src/pl_exec.cpp index f502c577c..8a99f9a9d 100644 --- a/src/common/pl/plpgsql/src/pl_exec.cpp +++ b/src/common/pl/plpgsql/src/pl_exec.cpp @@ -311,7 +311,7 @@ void record_plsql_action(char* stmt, PLpgSQL_function* func) initStringInfo(&plsql_string); initStringInfo(&funcname); if (OidIsValid(func->pkg_oid)) { - char* pkgname = NameStr(*GetPackageName(func->pkg_oid)); + char* pkgname = GetPackageName(func->pkg_oid); appendStringInfo(&funcname, "%s.%s", pkgname, func->fn_signature); } else { appendStringInfo(&funcname, "%s", func->fn_signature); @@ -707,9 +707,9 @@ static char* AssembleAutomnousStatement(PLpgSQL_function* func, FunctionCallInfo Oid proPackageId = DatumGetObjectId(datum); if (proPackageId != InvalidOid) { - NameData* pkgName = GetPackageName(proPackageId); + char* pkgName = GetPackageName(proPackageId); if (pkgName != NULL) { - appendStringInfo(&buf, "%s", quote_qualified_identifier(NameStr(*pkgName), NULL)); + appendStringInfo(&buf, "%s", quote_qualified_identifier(pkgName, NULL)); } else { ReleaseSysCache(procTup); ereport(ERROR, (errmodule(MOD_PLSQL), errcode(ERRCODE_CACHE_LOOKUP_FAILED), @@ -2569,6 +2569,29 @@ static int check_line_validity_in_foreach_a(PLpgSQL_stmt_foreach_a* stmt, int li return check_line_validity(stmt->body, linenum, prevValidLine); } +static bool check_rowtype_has_been_changed(TupleDesc row_tupdesc, TupleDesc type_tupdesc) +{ + if (row_tupdesc->natts != type_tupdesc->natts) { + return true; + } + for (int i = 0; i < row_tupdesc->natts; i++) { + Form_pg_attribute row_attr = &row_tupdesc->attrs[i]; + Form_pg_attribute type_attr = &type_tupdesc->attrs[i]; + if (row_attr->attnum != type_attr->attnum || row_attr->atttypid != type_attr->atttypid || + row_attr->attisdropped != type_attr->attisdropped) { + return true; + } + } + return false; +} + +static inline void gsplsql_report_row_var_check_err(Oid typ_oid) +{ + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), errmodule(MOD_PLSQL), + errmsg("type %s has been changed, please switch the session", format_type_be(typ_oid)))); +} + /* ---------- * check_line_validity_in_for_query * ---------- @@ -2626,8 +2649,20 @@ PLpgSQL_datum* copy_plpgsql_datum(PLpgSQL_datum* datum) result = (PLpgSQL_datum*)newm; } break; + case PLPGSQL_DTYPE_ROW: { + PLpgSQL_row* row = (PLpgSQL_row*)datum; + if (row->rowtupdesc && row->rowtupdesc->tdtypeid != RECORDOID) { + TupleDesc tup_desc = lookup_rowtype_tupdesc(row->rowtupdesc->tdtypeid, row->rowtupdesc->tdtypmod); + if (check_rowtype_has_been_changed(row->rowtupdesc, tup_desc)) { + Oid type_oid = tup_desc->tdtypeid; + ReleaseTupleDesc(tup_desc); + gsplsql_report_row_var_check_err(type_oid); + } + ReleaseTupleDesc(tup_desc); + } + result = datum; + } break; case PLPGSQL_DTYPE_EXPR: - case PLPGSQL_DTYPE_ROW: case PLPGSQL_DTYPE_RECORD: case PLPGSQL_DTYPE_RECFIELD: case PLPGSQL_DTYPE_ARRAYELEM: @@ -14339,6 +14374,62 @@ static bool plpgsql_check_invalid_by_dependency(List* invalItems, int cacheid, u return false; } +void plpgsql_hashtable_clear_invalid_pkg() +{ + if (!u_sess->plsql_cxt.has_invalid_pkg) { + return; + } + if (unlikely(u_sess->plsql_cxt.plpgsql_pkg_HashTable == NULL)) { + u_sess->plsql_cxt.has_invalid_pkg = false; + return; + } + HASH_SEQ_STATUS hash_pkgseq; + hash_seq_init(&hash_pkgseq, u_sess->plsql_cxt.plpgsql_pkg_HashTable); + plpgsql_pkg_HashEnt* pkghentry = NULL; + while ((pkghentry = (plpgsql_pkg_HashEnt*)hash_seq_search(&hash_pkgseq)) != NULL) { + PLpgSQL_package* pkg = pkghentry->package; + if (pkg->pkg_xmin == InvalidTransactionId) { + delete_package(pkg); + } + } + u_sess->plsql_cxt.has_invalid_pkg = false; +} + +void plpgsql_hashtable_clear_invalid_func() +{ + if (!u_sess->plsql_cxt.has_invalid_func) { + return; + } + if (unlikely(u_sess->plsql_cxt.plpgsql_HashTable == NULL)) { + u_sess->plsql_cxt.has_invalid_func = false; + return; + } + HASH_SEQ_STATUS hash_seq; + hash_seq_init(&hash_seq, u_sess->plsql_cxt.plpgsql_HashTable); + plpgsql_HashEnt* hentry = NULL; + while ((hentry = (plpgsql_HashEnt*)hash_seq_search(&hash_seq)) != NULL) { + PLpgSQL_function* func = hentry->function; + if (func->fn_xmin == InvalidTransactionId) { + func->use_count = 0; + delete_function(func, false); + } + } + u_sess->plsql_cxt.has_invalid_func = false; +} + +void plpgsql_hashtable_clear_invalid_obj(bool need_clear) +{ + if (u_sess->SPI_cxt._connected > 0 || u_sess->plsql_cxt.is_package_instantiation) { + return; + } + if (u_sess->plsql_cxt.during_compile && !need_clear) { + return; + } + AcceptInvalidationMessages(); + plpgsql_hashtable_clear_invalid_pkg(); + plpgsql_hashtable_clear_invalid_func(); +} + /* * Check dependency for function and package's hash table, * and delete the invalid package or functio from session. @@ -14348,6 +14439,7 @@ static bool plpgsql_check_invalid_by_dependency(List* invalItems, int cacheid, u void plpgsql_hashtable_delete_and_check_invalid_item(int classId, Oid objId) { if (classId == PROCOID) { + u_sess->plsql_cxt.has_invalid_func = true; if (likely(u_sess->plsql_cxt.plpgsql_HashTable != NULL)) { HASH_SEQ_STATUS hash_seq; hash_seq_init(&hash_seq, u_sess->plsql_cxt.plpgsql_HashTable); @@ -15390,4 +15482,27 @@ static bool plsql_convert_expr_value_charset(PLpgSQL_execstate* estate, Datum *v return plsql_convert_value_charset_internal(estate, val, isnull, val_type, val_collation, target_collation); } +void plpgsql_free_override_stack(int depth) +{ + int searchpath_len = list_length(u_sess->catalog_cxt.overrideStack); + while (searchpath_len > depth) { + Assert(u_sess->catalog_cxt.overrideStack != NULL); + OverrideStackEntry *entry = (OverrideStackEntry *)linitial(u_sess->catalog_cxt.overrideStack); + u_sess->catalog_cxt.overrideStack = list_delete_first(u_sess->catalog_cxt.overrideStack); + list_free_ext(entry->searchPath); + pfree_ext(entry); + searchpath_len--; + if (u_sess->catalog_cxt.overrideStack) { + OverrideStackEntry *entry = (OverrideStackEntry *)linitial(u_sess->catalog_cxt.overrideStack); + u_sess->catalog_cxt.activeSearchPath = entry->searchPath; + u_sess->catalog_cxt.activeCreationNamespace = entry->creationNamespace; + u_sess->catalog_cxt.activeTempCreationPending = false; + } else { + u_sess->catalog_cxt.activeSearchPath = u_sess->catalog_cxt.baseSearchPath; + u_sess->catalog_cxt.activeCreationNamespace = u_sess->catalog_cxt.baseCreationNamespace; + u_sess->catalog_cxt.activeTempCreationPending = u_sess->catalog_cxt.baseTempCreationPending; + } + } +} + #endif diff --git a/src/common/pl/plpgsql/src/pl_funcs.cpp b/src/common/pl/plpgsql/src/pl_funcs.cpp index 2914bf24d..b448db319 100644 --- a/src/common/pl/plpgsql/src/pl_funcs.cpp +++ b/src/common/pl/plpgsql/src/pl_funcs.cpp @@ -224,7 +224,7 @@ static char* GetPackageSchemaName() return packageSchemaName; } -static char* GetPackageSchemaName(Oid packageOid) +char* GetPackageSchemaName(Oid packageOid) { Oid packageSchemaOid = GetPackageNamespace(packageOid); char* packageSchemaName = get_namespace_name(packageSchemaOid); @@ -270,8 +270,8 @@ PLpgSQL_nsitem* plpgsql_ns_lookup( char* currCompilePackageSchemaName = NULL; rc = CompileWhich(); if (OidIsValid(u_sess->plsql_cxt.running_pkg_oid)) { - NameData* CompilePackageName = GetPackageName(u_sess->plsql_cxt.running_pkg_oid); - currCompilePackageName = CompilePackageName->data; + char* CompilePackageName = GetPackageName(u_sess->plsql_cxt.running_pkg_oid); + currCompilePackageName = CompilePackageName; currCompilePackageSchemaName = GetPackageSchemaName(u_sess->plsql_cxt.running_pkg_oid); } else if (rc == PLPGSQL_COMPILE_PACKAGE_PROC || rc == PLPGSQL_COMPILE_PACKAGE) { currCompilePackageName = u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package->pkg_signature; diff --git a/src/common/pl/plpgsql/src/pl_handler.cpp b/src/common/pl/plpgsql/src/pl_handler.cpp index 1e0cf297c..b11c61e1a 100755 --- a/src/common/pl/plpgsql/src/pl_handler.cpp +++ b/src/common/pl/plpgsql/src/pl_handler.cpp @@ -43,6 +43,8 @@ #include "executor/spi_priv.h" #include "distributelayer/streamMain.h" #include "commands/event_trigger.h" +#include "catalog/pg_object.h" +#include "catalog/gs_dependencies_fn.h" #ifdef STREAMPLAN #include "optimizer/streamplan.h" @@ -56,6 +58,8 @@ PG_MODULE_MAGIC; #endif #define MAXSTRLEN ((1 << 11) - 1) +static void init_do_stmt(PLpgSQL_package *pkg, bool isCreate, ListCell *cell, int oldCompileStatus, + PLpgSQL_compile_context *curr_compile, List *temp_tableof_index, MemoryContext oldcxt); static void auditExecPLpgSQLFunction(PLpgSQL_function* func, AuditResult result) { char details[PGAUDIT_MAXLENGTH]; @@ -769,6 +773,8 @@ Datum plpgsql_call_handler(PG_FUNCTION_ARGS) #endif int connect = SPI_connectid(); Oid firstLevelPkgOid = InvalidOid; + bool save_need_create_depend = u_sess->plsql_cxt.need_create_depend; + bool save_curr_status = GetCurrCompilePgObjStatus(); PG_TRY(); { PGSTAT_START_PLSQL_TIME_RECORD(); @@ -779,7 +785,33 @@ Datum plpgsql_call_handler(PG_FUNCTION_ARGS) bool saved_current_stp_with_exception = plpgsql_get_current_value_stp_with_exception(); /* Find or compile the function */ if (func == NULL) { + u_sess->plsql_cxt.compile_has_warning_info = false; + SetCurrCompilePgObjStatus(true); + if (enable_plpgsql_gsdependency_guc()) { + if (gsplsql_is_undefined_func(func_oid)) { + ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FUNCTION), + (errmsg("\"%s\" header is undefined, you can try to recreate", get_func_name(func_oid))))); + } + if (GetPgObjectValid(func_oid, OBJECT_TYPE_PROC)) { + u_sess->plsql_cxt.need_create_depend = false; + } else { + u_sess->plsql_cxt.need_create_depend = true; + } + } func = plpgsql_compile(fcinfo, false); + if (func == NULL) { + ereport(ERROR, (errcode(ERRCODE_NO_FUNCTION_PROVIDED), errmodule(MOD_PLSQL), + errmsg("compile function error."), + errdetail("It may be because the compilation encountered an error and the exception was caught."), + errcause("compile procedure error."), + erraction("compile function result is null, it has error"))); + } + if (enable_plpgsql_gsdependency_guc()) { + if (!OidIsValid(func->pkg_oid)) { + SetPgObjectValid(func_oid, OBJECT_TYPE_PROC, true); + } + } + u_sess->plsql_cxt.need_create_depend = save_need_create_depend; } if (func->fn_readonly) { stp_disable_xact_and_set_err_msg(&savedisAllowCommitRollback, STP_XACT_IMMUTABLE); @@ -971,6 +1003,8 @@ Datum plpgsql_call_handler(PG_FUNCTION_ARGS) } PG_CATCH(); { + u_sess->plsql_cxt.need_create_depend = save_need_create_depend; + SetCurrCompilePgObjStatus(save_curr_status); /* clean stp save pointer if the outermost function is end. */ if (u_sess->SPI_cxt._connected == 0) { t_thrd.utils_cxt.STPSavedResourceOwner = NULL; @@ -992,7 +1026,7 @@ Datum plpgsql_call_handler(PG_FUNCTION_ARGS) /* destory all the SPI connect created in this PL function. */ SPI_disconnect(connect); - + u_sess->plsql_cxt.need_create_depend = save_need_create_depend; /* re-throw the original error messages */ ReThrowError(edata); } @@ -1022,6 +1056,7 @@ Datum plpgsql_call_handler(PG_FUNCTION_ARGS) u_sess->opt_cxt.is_stream_support = outer_is_stream_support; } #endif + UpdateCurrCompilePgObjStatus(save_curr_status); if (has_switch) { SetUserIdAndSecContext(old_user, save_sec_context); u_sess->exec_cxt.cast_owner = InvalidOid; @@ -1332,6 +1367,7 @@ Datum plpgsql_validator(PG_FUNCTION_ARGS) } ReleaseSysCache(tuple); + bool save_curr_status = GetCurrCompilePgObjStatus(); /* Postpone body checks if !u_sess->attr.attr_sql.check_function_bodies */ if (u_sess->attr.attr_sql.check_function_bodies) { FunctionCallInfoData fake_fcinfo; @@ -1369,12 +1405,14 @@ Datum plpgsql_validator(PG_FUNCTION_ARGS) /* Test-compile the function */ PG_TRY(); { + SetCurrCompilePgObjStatus(true); u_sess->parser_cxt.isCreateFuncOrProc = true; func = plpgsql_compile(&fake_fcinfo, true); u_sess->parser_cxt.isCreateFuncOrProc = false; } PG_CATCH(); { + SetCurrCompilePgObjStatus(save_curr_status); #ifndef ENABLE_MULTIPLE_NODES u_sess->parser_cxt.isPerform = false; bool insertError = (u_sess->attr.attr_common.plsql_show_all_error || @@ -1433,6 +1471,7 @@ Datum plpgsql_validator(PG_FUNCTION_ARGS) pl_validate_function_sql(func, replace); u_sess->ClientAuthInProgress = saved_client_auth; } + UpdateCurrCompilePgObjStatus(save_curr_status); } #ifndef ENABLE_MULTIPLE_NODES if (!IsInitdb && u_sess->plsql_cxt.isCreateFunction) { @@ -1572,7 +1611,7 @@ void FunctionInPackageCompile(PLpgSQL_package* pkg) * ---------- */ #ifndef ENABLE_MULTIPLE_NODES -void PackageInit(PLpgSQL_package* pkg, bool isCreate) +void PackageInit(PLpgSQL_package* pkg, bool isCreate, bool isSpec, bool isNeedCompileFunc) { if (likely(pkg != NULL)) { if (likely(pkg->isInit)) { @@ -1585,23 +1624,23 @@ void PackageInit(PLpgSQL_package* pkg, bool isCreate) PushOverrideSearchPath(pkg->pkg_searchpath); ListCell* cell = NULL; int oldCompileStatus = getCompileStatus(); - if (isCreate) { - CompileStatusSwtichTo(COMPILIE_PKG); - } + CompileStatusSwtichTo(COMPILIE_PKG); PLpgSQL_compile_context* curr_compile = createCompileContext("PL/pgSQL package context"); SPI_NESTCOMPILE_LOG(curr_compile->compile_cxt); MemoryContext temp = NULL; - if (u_sess->plsql_cxt.curr_compile_context != NULL) { + if (u_sess->plsql_cxt.curr_compile_context != NULL && + u_sess->plsql_cxt.curr_compile_context->compile_tmp_cxt != NULL) { temp = MemoryContextSwitchTo(u_sess->plsql_cxt.curr_compile_context->compile_tmp_cxt); } u_sess->plsql_cxt.curr_compile_context = curr_compile; pushCompileContext(); curr_compile->plpgsql_curr_compile_package = pkg; checkCompileMemoryContext(pkg->pkg_cxt); + MemoryContext oldcxt = MemoryContextSwitchTo(pkg->pkg_cxt); if (isCreate) { int exception_num = 0; - curr_compile->compile_tmp_cxt = MemoryContextSwitchTo(pkg->pkg_cxt); + curr_compile->compile_tmp_cxt = oldcxt; processPackageProcList(pkg); foreach(cell, pkg->proc_list) { @@ -1616,9 +1655,11 @@ void PackageInit(PLpgSQL_package* pkg, bool isCreate) } PG_CATCH(); { + set_create_plsql_type_end(); if (u_sess->plsql_cxt.create_func_error) { u_sess->plsql_cxt.create_func_error = false; exception_num += 1; + FlushErrorState(); } else { PG_RE_THROW(); } @@ -1638,16 +1679,15 @@ void PackageInit(PLpgSQL_package* pkg, bool isCreate) errcause("compile procedure error."), erraction("check procedure error and redefine procedure"))); } - (void*)MemoryContextSwitchTo(curr_compile->compile_tmp_cxt); } else { - if (pkg->is_bodycompiled) { + if (pkg->is_bodycompiled && !isSpec && isNeedCompileFunc) { (void)CompileStatusSwtichTo(COMPILIE_PKG_FUNC); - curr_compile->compile_tmp_cxt = MemoryContextSwitchTo(pkg->pkg_cxt); + curr_compile->compile_tmp_cxt = oldcxt; FunctionInPackageCompile(pkg); - (void*)MemoryContextSwitchTo(curr_compile->compile_tmp_cxt); (void)CompileStatusSwtichTo(oldCompileStatus); } } + (void*)MemoryContextSwitchTo(oldcxt); if (u_sess->attr.attr_common.plsql_show_all_error) { PopOverrideSearchPath(); ereport(DEBUG3, (errmodule(MOD_NEST_COMPILE), errcode(ERRCODE_LOG), @@ -1669,71 +1709,43 @@ void PackageInit(PLpgSQL_package* pkg, bool isCreate) int save_compile_list_length = list_length(u_sess->plsql_cxt.compile_context_list); int save_compile_status = u_sess->plsql_cxt.compile_status; List* temp_tableof_index = NULL; + bool save_is_package_instantiation = u_sess->plsql_cxt.is_package_instantiation; + bool needExecDoStmt = true; + if (enable_plpgsql_undefined()) { + needExecDoStmt = GetCurrCompilePgObjStatus(); + } + ResourceOwnerData* oldowner = NULL; + int64 stackId = 0; + if (isCreate && enable_plpgsql_gsdependency_guc() && !IsInitdb) { + oldowner = t_thrd.utils_cxt.CurrentResourceOwner; + SPI_savepoint_create("PackageInit"); + stackId = u_sess->plsql_cxt.nextStackEntryId; + } + bool save_isPerform = u_sess->parser_cxt.isPerform; PG_TRY(); { u_sess->plsql_cxt.is_package_instantiation = true; - foreach(cell, pkg->proc_list) { - if (IsA(lfirst(cell), DoStmt)) { - curr_compile->compile_tmp_cxt = MemoryContextSwitchTo(pkg->pkg_cxt); - DoStmt* doStmt = (DoStmt*)lfirst(cell); - if (!isCreate) { - if (!doStmt->isExecuted) { - (void)CompileStatusSwtichTo(COMPILIE_PKG_ANON_BLOCK); - temp_tableof_index = u_sess->plsql_cxt.func_tableof_index; - u_sess->plsql_cxt.func_tableof_index = NULL; - if (u_sess->SPI_cxt._connected > -1 && - u_sess->SPI_cxt._connected != u_sess->SPI_cxt._curid) { - SPI_STACK_LOG("begin", NULL, NULL); - _SPI_begin_call(false); - ExecuteDoStmt(doStmt, true); - SPI_STACK_LOG("end", NULL, NULL); - _SPI_end_call(false); - } else { - ExecuteDoStmt(doStmt, true); - } - if (!doStmt->isSpec) { - pkg->isInit = true; - - } - free_func_tableof_index(); - u_sess->plsql_cxt.func_tableof_index = temp_tableof_index; - (void)CompileStatusSwtichTo(oldCompileStatus); - doStmt->isExecuted = true; - } - } else { - if (doStmt->isSpec && !doStmt->isExecuted) { - (void)CompileStatusSwtichTo(COMPILIE_PKG_ANON_BLOCK); - temp_tableof_index = u_sess->plsql_cxt.func_tableof_index; - u_sess->plsql_cxt.func_tableof_index = NULL; - if (u_sess->SPI_cxt._connected > -1 && - u_sess->SPI_cxt._connected != u_sess->SPI_cxt._curid) { - SPI_STACK_LOG("begin", NULL, NULL); - _SPI_begin_call(false); - ExecuteDoStmt(doStmt, true); - SPI_STACK_LOG("end", NULL, NULL); - _SPI_end_call(false); - } else if (!doStmt->isExecuted) { - ExecuteDoStmt(doStmt, true); - } - free_func_tableof_index(); - u_sess->plsql_cxt.func_tableof_index = temp_tableof_index; - (void)CompileStatusSwtichTo(oldCompileStatus); - doStmt->isExecuted = true; - } - } - (void*)MemoryContextSwitchTo(curr_compile->compile_tmp_cxt); - } + if (needExecDoStmt) { + init_do_stmt(pkg, isCreate, cell, oldCompileStatus, curr_compile, temp_tableof_index, oldcxt); + } + if (isCreate && enable_plpgsql_gsdependency_guc() && !IsInitdb) { + SPI_savepoint_release("PackageInit"); + stp_cleanup_subxact_resource(stackId); + MemoryContextSwitchTo(oldcxt); + t_thrd.utils_cxt.CurrentResourceOwner = oldowner; } stp_reset_xact_state_and_err_msg(oldStatus, needResetErrMsg); - u_sess->plsql_cxt.is_package_instantiation = false; + u_sess->plsql_cxt.is_package_instantiation = save_is_package_instantiation; ereport(DEBUG3, (errmodule(MOD_NEST_COMPILE), errcode(ERRCODE_LOG), errmsg("%s finish compile, level: %d", __func__, list_length(u_sess->plsql_cxt.compile_context_list)))); u_sess->plsql_cxt.curr_compile_context = popCompileContext(); CompileStatusSwtichTo(oldCompileStatus); clearCompileContext(curr_compile); + PopOverrideSearchPath(); } PG_CATCH(); { + u_sess->parser_cxt.isPerform = save_isPerform; stp_reset_xact_state_and_err_msg(oldStatus, needResetErrMsg); u_sess->plsql_cxt.is_package_instantiation = false; free_temp_func_tableof_index(temp_tableof_index); @@ -1744,10 +1756,35 @@ void PackageInit(PLpgSQL_package* pkg, bool isCreate) u_sess->plsql_cxt.curr_compile_context = save_compile_context; u_sess->plsql_cxt.compile_status = save_compile_status; clearCompileContextList(save_compile_list_length); - PG_RE_THROW(); + u_sess->plsql_cxt.curr_compile_context = popCompileContext(); + /*avoid memeory leak*/ + clearCompileContext(curr_compile); + if (isCreate && enable_plpgsql_gsdependency_guc() && !IsInitdb) { + SPI_savepoint_rollbackAndRelease("PackageInit", InvalidTransactionId); + stp_cleanup_subxact_resource(stackId); + if (likely(u_sess->SPI_cxt._curid >= 0)) { + if (likely(u_sess->SPI_cxt._current == &(u_sess->SPI_cxt._stack[u_sess->SPI_cxt._curid]))) { + _SPI_end_call(true); + } + } + SPI_finish(); + t_thrd.utils_cxt.CurrentResourceOwner = oldowner; + MemoryContextSwitchTo(oldcxt); + ErrorData* edata = &t_thrd.log_cxt.errordata[t_thrd.log_cxt.errordata_stack_depth]; + ereport(WARNING, + (errmodule(MOD_PLSQL), + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("%s", edata->message), + errdetail("N/A"), + errcause("compile package or procedure error."), + erraction("check package or procedure error and redefine"))); + FlushErrorState(); + } else { + PG_RE_THROW(); + } } PG_END_TRY(); - PopOverrideSearchPath(); + MemoryContextSwitchTo(oldcxt); restoreCallFromPkgOid(old_value); } #endif @@ -1867,3 +1904,62 @@ void DecreasePackageUseCount(PLpgSQL_function* func) } } +static void init_do_stmt(PLpgSQL_package *pkg, bool isCreate, ListCell *cell, int oldCompileStatus, + PLpgSQL_compile_context *curr_compile, List *temp_tableof_index, MemoryContext oldcxt) +{ + foreach(cell, pkg->proc_list) { + if (IsA(lfirst(cell), DoStmt)) { + curr_compile->compile_tmp_cxt = MemoryContextSwitchTo(pkg->pkg_cxt); + DoStmt* doStmt = (DoStmt*)lfirst(cell); + if (!isCreate) { + if (!doStmt->isExecuted) { + (void)CompileStatusSwtichTo(COMPILIE_PKG_ANON_BLOCK); + temp_tableof_index = u_sess->plsql_cxt.func_tableof_index; + u_sess->plsql_cxt.func_tableof_index = NULL; + if (u_sess->SPI_cxt._connected > -1 && + u_sess->SPI_cxt._connected != u_sess->SPI_cxt._curid) { + SPI_STACK_LOG("begin", NULL, NULL); + _SPI_begin_call(false); + ExecuteDoStmt(doStmt, true); + SPI_STACK_LOG("end", NULL, NULL); + _SPI_end_call(false); + } else { + ExecuteDoStmt(doStmt, true); + } + if (!doStmt->isSpec) { + pkg->isInit = true; + + } + free_func_tableof_index(); + u_sess->plsql_cxt.func_tableof_index = temp_tableof_index; + (void)CompileStatusSwtichTo(oldCompileStatus); + doStmt->isExecuted = true; + } + } else { + if (isCreate && enable_plpgsql_gsdependency_guc() && !IsInitdb) { + MemoryContextSwitchTo(oldcxt); + } + if (doStmt->isSpec && !doStmt->isExecuted) { + (void)CompileStatusSwtichTo(COMPILIE_PKG_ANON_BLOCK); + temp_tableof_index = u_sess->plsql_cxt.func_tableof_index; + u_sess->plsql_cxt.func_tableof_index = NULL; + if (u_sess->SPI_cxt._connected > -1 && + u_sess->SPI_cxt._connected != u_sess->SPI_cxt._curid) { + SPI_STACK_LOG("begin", NULL, NULL); + _SPI_begin_call(false); + ExecuteDoStmt(doStmt, true); + SPI_STACK_LOG("end", NULL, NULL); + _SPI_end_call(false); + } else if (!doStmt->isExecuted) { + ExecuteDoStmt(doStmt, true); + } + free_func_tableof_index(); + u_sess->plsql_cxt.func_tableof_index = temp_tableof_index; + (void)CompileStatusSwtichTo(oldCompileStatus); + doStmt->isExecuted = true; + } + } + (void*)MemoryContextSwitchTo(curr_compile->compile_tmp_cxt); + } + } +} diff --git a/src/common/pl/plpgsql/src/pl_package.cpp b/src/common/pl/plpgsql/src/pl_package.cpp index e3b25c5c2..c4d6cd016 100644 --- a/src/common/pl/plpgsql/src/pl_package.cpp +++ b/src/common/pl/plpgsql/src/pl_package.cpp @@ -41,8 +41,8 @@ #include "miscadmin.h" #include "parser/scanner.h" #include "parser/parser.h" - - +#include "catalog/pg_object.h" +#include "catalog/gs_dependencies_fn.h" static void plpgsql_pkg_append_dlcell(plpgsql_pkg_HashEnt* entity); @@ -54,7 +54,10 @@ extern void plpgsql_compile_error_callback(void* arg); static Node* plpgsql_bind_variable_column_ref(ParseState* pstate, ColumnRef* cref); static Node* plpgsql_describe_ref(ParseState* pstate, ColumnRef* cref); - +static void gsplsql_pkg_set_status(PLpgSQL_package* pkg, bool isSpec, bool isCreate, bool isValid, bool isRecompile, + bool pkg_spec_valid, bool pkg_body_valid); +static void gsplsql_pkg_set_status_in_mem(PLpgSQL_package* pkg, bool is_spec, bool is_valid); +static inline bool gsplsql_pkg_get_valid(PLpgSQL_package* pkg, bool is_spec); /* * plpgsql_parser_setup_bind set up parser hooks for dynamic parameters * only support DBE_SQL. @@ -750,7 +753,8 @@ extern PLpgSQL_package* plpgsql_pkg_HashTableLookup(PLpgSQL_pkg_hashkey* pkg_key } } -static PLpgSQL_package* do_pkg_compile(Oid pkgOid, HeapTuple pkg_tup, PLpgSQL_package* pkg, PLpgSQL_pkg_hashkey* hashkey, bool isSpec) +static PLpgSQL_package* do_pkg_compile(Oid pkgOid, HeapTuple pkg_tup, PLpgSQL_package* pkg, + PLpgSQL_pkg_hashkey* hashkey, bool isSpec, bool isCreate) { Form_gs_package pkg_struct = (Form_gs_package)GETSTRUCT(pkg_tup); Datum pkgsrcdatum; @@ -819,6 +823,7 @@ static PLpgSQL_package* do_pkg_compile(Oid pkgOid, HeapTuple pkg_tup, PLpgSQL_pa */ PLpgSQL_compile_context* curr_compile = createCompileContext(context_name); SPI_NESTCOMPILE_LOG(curr_compile->compile_cxt); + bool pkg_is_null = false; if (pkg == NULL) { pkg = (PLpgSQL_package*)MemoryContextAllocZero( SESS_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_OPTIMIZER), sizeof(PLpgSQL_package)); @@ -830,6 +835,7 @@ static PLpgSQL_package* do_pkg_compile(Oid pkgOid, HeapTuple pkg_tup, PLpgSQL_pa pkg->proc_list = NULL; pkg->invalItems = NIL; pkg->use_count = 0; + pkg_is_null = true; } saved_pseudo_current_userId = u_sess->misc_cxt.Pseudo_CurrentUserId; u_sess->misc_cxt.Pseudo_CurrentUserId = &pkg->pkg_owner; @@ -866,6 +872,9 @@ static PLpgSQL_package* do_pkg_compile(Oid pkgOid, HeapTuple pkg_tup, PLpgSQL_pa * most signature will not be so long originally, so we should do a strdup. */ curr_compile->compile_tmp_cxt = MemoryContextSwitchTo(pkg->pkg_cxt); + if (enable_plpgsql_gsdependency() && isSpec && pkg_is_null) { + gsplsql_prepare_gs_depend_for_pkg_compile(pkg, isCreate); + } pkg->pkg_signature = pstrdup(signature); pkg->pkg_searchpath = (OverrideSearchPath*)palloc0(sizeof(OverrideSearchPath)); pkg->pkg_searchpath->addCatalog = true; @@ -1084,7 +1093,7 @@ List* GetPackageListName(const char* pkgName, const Oid nspOid) /* * compile and init package by package oid */ -PLpgSQL_package* plpgsql_pkg_compile(Oid pkgOid, bool for_validator, bool isSpec, bool isCreate) +PLpgSQL_package* plpgsql_pkg_compile(Oid pkgOid, bool for_validator, bool isSpec, bool isCreate, bool isRecompile) { #ifdef ENABLE_MULTIPLE_NODES ereport(ERROR, (errcode(ERRCODE_INVALID_PACKAGE_DEFINITION), @@ -1095,6 +1104,8 @@ PLpgSQL_package* plpgsql_pkg_compile(Oid pkgOid, bool for_validator, bool isSpec PLpgSQL_package* pkg = NULL; PLpgSQL_pkg_hashkey hashkey; bool pkg_valid = false; + bool pkg_spec_valid = true; + bool pkg_body_valid = true; /* * Lookup the gs_package tuple by Oid; we'll need it in any case */ @@ -1111,12 +1122,33 @@ PLpgSQL_package* plpgsql_pkg_compile(Oid pkgOid, bool for_validator, bool isSpec } pkg_struct = (Form_gs_package)GETSTRUCT(pkg_tup); hashkey.pkgOid = pkgOid; + if (enable_plpgsql_gsdependency_guc()) { + if (isCreate) { + u_sess->plsql_cxt.need_create_depend = true; + } else { + /** + * only check for pkg need recompile or not, + * flag u_sess->plsql_cxt.need_create_depend would be set under ddl + */ + if (isSpec) { + pkg_spec_valid = GetPgObjectValid(pkgOid, OBJECT_TYPE_PKGSPEC); + } else { + pkg_body_valid = GetPgObjectValid(pkgOid, OBJECT_TYPE_PKGBODY); + } + } + } pkg = plpgsql_pkg_HashTableLookup(&hashkey); - + if ((!pkg_body_valid || !pkg_spec_valid) && pkg != NULL && + !u_sess->plsql_cxt.need_create_depend && u_sess->SPI_cxt._connected >= 0 && + !isRecompile && !u_sess->plsql_cxt.during_compile) { + pkg->is_need_recompile = true; + } + bool pkg_status = true; if (pkg != NULL) { Assert(pkg->pkg_oid == pkgOid); - if (pkg->pkg_xmin == HeapTupleGetRawXmin(pkg_tup) && - ItemPointerEquals(&pkg->pkg_tid, &pkg_tup->t_self)) { + pkg_status = pkg->pkg_xmin == HeapTupleGetRawXmin(pkg_tup) && + ItemPointerEquals(&pkg->pkg_tid, &pkg_tup->t_self) && !isRecompile && !pkg->is_need_recompile; + if (pkg_status) { pkg_valid = true; } else { /* need reuse pkg slot in hash table later, we need clear all refcount for this pkg and delete it here */ @@ -1126,24 +1158,33 @@ PLpgSQL_package* plpgsql_pkg_compile(Oid pkgOid, bool for_validator, bool isSpec } PLpgSQL_compile_context* save_compile_context = u_sess->plsql_cxt.curr_compile_context; Oid old_value = saveCallFromPkgOid(pkgOid); + int oidCompileStatus = getCompileStatus(); + bool save_need_create_depend = u_sess->plsql_cxt.need_create_depend; + bool save_curr_status = GetCurrCompilePgObjStatus(); + bool save_is_pkg_compile = u_sess->plsql_cxt.is_pkg_compile; PG_TRY(); { + SetCurrCompilePgObjStatus(true); if (!pkg_valid) { pkg = NULL; - pkg = do_pkg_compile(pkgOid, pkg_tup, pkg, &hashkey, true); + pkg = do_pkg_compile(pkgOid, pkg_tup, pkg, &hashkey, true, isCreate); + gsplsql_pkg_set_status_in_mem(pkg, true, GetCurrCompilePgObjStatus()); #ifndef ENABLE_MULTIPLE_NODES - PackageInit(pkg, isCreate); + PackageInit(pkg, isCreate, isSpec); #endif if (!isSpec && pkg != NULL) { - pkg = do_pkg_compile(pkgOid, pkg_tup, pkg, &hashkey, false); + gsplsql_pkg_set_status(pkg, true, false, GetCurrCompilePgObjStatus(), false, + pkg_spec_valid, pkg_body_valid); + pkg = do_pkg_compile(pkgOid, pkg_tup, pkg, &hashkey, false, isCreate); if (pkg == NULL) { ereport(ERROR, (errmodule(MOD_PLSQL), errcode(ERRCODE_CACHE_LOOKUP_FAILED), errmsg("package %u not found", pkgOid))); } + gsplsql_pkg_set_status_in_mem(pkg, false, GetCurrCompilePgObjStatus()); ReleaseSysCache(pkg_tup); pkg_tup = NULL; #ifndef ENABLE_MULTIPLE_NODES - PackageInit(pkg, isCreate); + PackageInit(pkg, isCreate, isSpec); #endif } else if(!isSpec && pkg == NULL) { ereport(ERROR, (errmodule(MOD_PLSQL), errcode(ERRCODE_CACHE_LOOKUP_FAILED), @@ -1151,38 +1192,60 @@ PLpgSQL_package* plpgsql_pkg_compile(Oid pkgOid, bool for_validator, bool isSpec } } else { if (!pkg->is_bodycompiled && !isSpec) { - pkg = do_pkg_compile(pkgOid, pkg_tup, pkg, &hashkey, false); + pkg = do_pkg_compile(pkgOid, pkg_tup, pkg, &hashkey, false, isCreate); + gsplsql_pkg_set_status_in_mem(pkg, false, GetCurrCompilePgObjStatus()); + } else { + if (pkg != NULL) { + bool temp_pkg_valid = gsplsql_pkg_get_valid(pkg, isSpec); + UpdateCurrCompilePgObjStatus(temp_pkg_valid); + if (!temp_pkg_valid) { + ereport(LOG, (errmodule(MOD_PLSQL), errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("In nested compilation, package %s is invalid.", pkg->pkg_signature))); + } + } } - /* package must be compiled befor init */ #ifndef ENABLE_MULTIPLE_NODES if (pkg != NULL) { - PackageInit(pkg, isCreate); + PackageInit(pkg, isCreate, isSpec); } else { ereport(ERROR, (errmodule(MOD_PLSQL), errcode(ERRCODE_CACHE_LOOKUP_FAILED), errmsg("package spec %u not found", pkgOid))); } #endif } + u_sess->plsql_cxt.need_create_depend = save_need_create_depend; + u_sess->plsql_cxt.is_pkg_compile = save_is_pkg_compile; } PG_CATCH(); { + SetCurrCompilePgObjStatus(save_curr_status); + u_sess->plsql_cxt.need_create_depend = save_need_create_depend; + u_sess->plsql_cxt.is_pkg_compile = save_is_pkg_compile; #ifndef ENABLE_MULTIPLE_NODES bool insertError = u_sess->attr.attr_common.plsql_show_all_error || !u_sess->attr.attr_sql.check_function_bodies; if (insertError) { InsertError(pkgOid); } -#endif popToOldCompileContext(save_compile_context); + CompileStatusSwtichTo(oidCompileStatus); +#endif PG_RE_THROW(); } PG_END_TRY(); + if (enable_plpgsql_gsdependency_guc() && !pkg_valid) { + gsplsql_complete_gs_depend_for_pkg_compile(pkg, isCreate, isRecompile); + } if (HeapTupleIsValid(pkg_tup)) { ReleaseSysCache(pkg_tup); pkg_tup = NULL; } restoreCallFromPkgOid(old_value); + gsplsql_pkg_set_status(pkg, isSpec, isCreate, GetCurrCompilePgObjStatus(), isRecompile, + pkg_spec_valid, pkg_body_valid); + UpdateCurrCompilePgObjStatus(save_curr_status); + pkg->is_need_recompile = false; /* * Finally return the compiled function */ @@ -1660,3 +1723,84 @@ void InsertErrorMessage(const char* message, int yyloc, bool isQueryString, int } addErrorList(message, lines); } + +static inline bool gsplsql_pkg_get_valid(PLpgSQL_package* pkg, bool is_spec) +{ + if (is_spec) { + return (pkg->status & PACKAGE_SPEC_VALID) == PACKAGE_SPEC_VALID; + } + return (pkg->status & PACKAGE_BODY_VALID) == PACKAGE_BODY_VALID;; +} + +static void gsplsql_pkg_set_status_in_mem(PLpgSQL_package* pkg, bool is_spec, bool is_valid) +{ + if (pkg == NULL) { + return; + } + if (is_spec) { + if (is_valid) { + pkg->status |= PACKAGE_SPEC_VALID; + } else { + pkg->status &= PACKAGE_SPEC_INVALID; + } + } else { + if (is_valid) { + pkg->status |= PACKAGE_BODY_VALID; + } else { + pkg->status &= PACKAGE_BODY_INVALID; + } + } +} + +static void gsplsql_pkg_set_status(PLpgSQL_package* pkg, bool isSpec, bool isCreate, bool isValid, bool isRecompile, + bool pkg_spec_valid, bool pkg_body_valid) +{ + gsplsql_pkg_set_status_in_mem(pkg, isSpec, GetCurrCompilePgObjStatus()); + if (!enable_plpgsql_gsdependency_guc() || pkg == NULL) { + return; + } + if (isSpec) { + if (pkg_spec_valid != isValid) { + SetPgObjectValid(pkg->pkg_oid, OBJECT_TYPE_PKGSPEC, isValid); + if (!isValid) { + SetPgObjectValid(pkg->pkg_oid, OBJECT_TYPE_PKGBODY, isValid); + } + HeapTuple tup = SearchSysCache1(PACKAGEOID, ObjectIdGetDatum(pkg->pkg_oid)); + if (!HeapTupleIsValid(tup)) { + ereport(ERROR, (errmodule(MOD_PLSQL), errcode(ERRCODE_CACHE_LOOKUP_FAILED), + errmsg("cache lookup failed for package %u, while compile package", pkg->pkg_oid), + errdetail("cache lookup failed"), + errcause("System error"), + erraction("Drop or rebuild the package"))); + } + bool is_null; + (void)SysCacheGetAttr(PACKAGEOID, tup, Anum_gs_package_pkgbodydeclsrc, &is_null); + if (is_null || !isValid) { + gsplsql_set_pkg_func_status(pkg->namespaceOid, pkg->pkg_oid, isValid); + } + ReleaseSysCache(tup); + } + } else { + if (pkg_body_valid != isValid) { + bool spec_status = gsplsql_pkg_get_valid(pkg, true); + if (!spec_status && isValid) { + spec_status = isValid; + } + SetPgObjectValid(pkg->pkg_oid, OBJECT_TYPE_PKGSPEC, spec_status); + SetPgObjectValid(pkg->pkg_oid, OBJECT_TYPE_PKGBODY, isValid); + gsplsql_set_pkg_func_status(pkg->namespaceOid, pkg->pkg_oid, isValid); + } + } + if (isValid) { + return; + } + if (isCreate) { + ereport(WARNING, (errmodule(MOD_PLSQL), + errmsg("Package %screated with compilation erors.", isSpec ? "" : "Body "))); + } else if (isRecompile) { + ereport(WARNING, (errmodule(MOD_PLSQL), + errmsg("Package %s %srecompile with compilation erors.", + pkg->pkg_signature, isSpec ? "" : "Body "))); + } + return; +} diff --git a/src/gausskernel/CMakeLists.txt b/src/gausskernel/CMakeLists.txt index c17872f3f..d66a3457c 100755 --- a/src/gausskernel/CMakeLists.txt +++ b/src/gausskernel/CMakeLists.txt @@ -52,6 +52,7 @@ set(gaussdb_objects $ $ $ + $ $ $ $ diff --git a/src/gausskernel/bootstrap/bootstrap.cpp b/src/gausskernel/bootstrap/bootstrap.cpp index 8f82f369c..a1719d5d9 100755 --- a/src/gausskernel/bootstrap/bootstrap.cpp +++ b/src/gausskernel/bootstrap/bootstrap.cpp @@ -628,7 +628,6 @@ static void fix_attr_notnull(const char* name, int attnum) void DefineAttr(const char* name, char* type, int attnum) { Oid typeoid; - if (t_thrd.bootstrap_cxt.boot_reldesc != NULL) { ereport(WARNING, (errmsg("no open relations allowed with CREATE command"))); closerel(NULL); diff --git a/src/gausskernel/optimizer/commands/event_trigger.cpp b/src/gausskernel/optimizer/commands/event_trigger.cpp index d53078aa8..e72d74c2b 100644 --- a/src/gausskernel/optimizer/commands/event_trigger.cpp +++ b/src/gausskernel/optimizer/commands/event_trigger.cpp @@ -120,6 +120,7 @@ static const event_trigger_support_data event_trigger_support[] = { {"VIEW", true}, {"PACKAGE", true}, {"PACKAGE BODY", true}, + {"PACKAGE SPECIFICATION", true}, {"ROW LEVEL SECURITY POLICY", true}, {"SYNONYM", true}, { NULL, false } diff --git a/src/gausskernel/optimizer/commands/functioncmds.cpp b/src/gausskernel/optimizer/commands/functioncmds.cpp index 2e87617a7..1068ee163 100644 --- a/src/gausskernel/optimizer/commands/functioncmds.cpp +++ b/src/gausskernel/optimizer/commands/functioncmds.cpp @@ -89,6 +89,8 @@ #include "tcop/utility.h" #include "tsearch/ts_type.h" #include "commands/comment.h" +#include "catalog/gs_dependencies_fn.h" +#include "utils/sec_rls_utils.h" #ifdef ENABLE_MOT #include "storage/mot/jit_exec.h" @@ -135,11 +137,12 @@ static void CreateFunctionComment(Oid funcOid, List* options, bool lock = false) * validator, so as not to produce a NOTICE and then an ERROR for the same * condition.) */ -static void compute_return_type( - TypeName* returnType, Oid languageOid, Oid* prorettype_p, bool* returnsSet_p, bool fenced, int startLineNumber) +void compute_return_type( + TypeName* returnType, Oid languageOid, Oid* prorettype_p, bool* returnsSet_p, bool fenced, int startLineNumber, + TypeDependExtend* type_depend_extend, bool is_refresh_head) { - Oid rettype; - Type typtup; + Oid rettype = InvalidOid; + Type typtup = NULL; AclResult aclresult; Oid typowner = InvalidOid; ObjectAddress address; @@ -150,7 +153,11 @@ static void compute_return_type( */ bool isalter = false; - typtup = LookupTypeName(NULL, returnType, NULL); + if (enable_plpgsql_gsdependency()) { + typtup = LookupTypeName(NULL, returnType, NULL, true, type_depend_extend); + } else { + typtup = LookupTypeName(NULL, returnType, NULL); + } /* * If the type is relation, then we check @@ -161,8 +168,8 @@ static void compute_return_type( (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("return type '%s' must be in installation group", TypeNameToString(returnType)))); } - - if (typtup) { + TypeTupStatus typStatus = GetTypeTupStatus(typtup); + if (NormalTypeTup == typStatus) { if (!((Form_pg_type)GETSTRUCT(typtup))->typisdefined) { if (languageOid == SQLlanguageId) ereport(ERROR, @@ -217,43 +224,53 @@ static void compute_return_type( (languageOid != INTERNALlanguageId && languageOid != ClanguageId)) { const char* message = "type does not exist"; InsertErrorMessage(message, startLineNumber); - ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("type \"%s\" does not exist", typnam))); - } - - /* Reject if there's typmod decoration, too */ - if (returnType->typmods != NIL) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("type modifier cannot be specified for shell type \"%s\"", typnam))); - - /* Otherwise, go ahead and make a shell type */ - ereport(NOTICE, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("type \"%s\" is not yet defined", typnam), - errdetail("Creating a shell type definition."))); - namespaceId = QualifiedNameGetCreationNamespace(returnType->names, &typname); - - if (u_sess->attr.attr_sql.enforce_a_behavior) { - typowner = GetUserIdFromNspId(namespaceId); - - if (!OidIsValid(typowner)) - typowner = GetUserId(); - else if (typowner != GetUserId()) - isalter = true; + if (UndefineTypeTup == typStatus) { + if (!is_refresh_head) { + ereport(WARNING, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("type \"%s\" does not exist", typnam))); + } + rettype = typeTypeId(typtup); + ReleaseSysCache(typtup); + } else { + if (!is_refresh_head) { + ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("type \"%s\" does not exist", typnam))); + } + } } else { - typowner = GetUserId(); - } - aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE); - if (aclresult != ACLCHECK_OK) - aclcheck_error(aclresult, ACL_KIND_NAMESPACE, get_namespace_name(namespaceId)); - if (isalter) { - aclresult = pg_namespace_aclcheck(namespaceId, typowner, ACL_CREATE); + /* Reject if there's typmod decoration, too */ + if (returnType->typmods != NIL) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("type modifier cannot be specified for shell type \"%s\"", typnam))); + + /* Otherwise, go ahead and make a shell type */ + ereport(NOTICE, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("type \"%s\" is not yet defined", typnam), + errdetail("Creating a shell type definition."))); + namespaceId = QualifiedNameGetCreationNamespace(returnType->names, &typname); + + if (u_sess->attr.attr_sql.enforce_a_behavior) { + typowner = GetUserIdFromNspId(namespaceId); + + if (!OidIsValid(typowner)) + typowner = GetUserId(); + else if (typowner != GetUserId()) + isalter = true; + } else { + typowner = GetUserId(); + } + aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE); if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_NAMESPACE, get_namespace_name(namespaceId)); + if (isalter) { + aclresult = pg_namespace_aclcheck(namespaceId, typowner, ACL_CREATE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_NAMESPACE, get_namespace_name(namespaceId)); + } + address = TypeShellMake(typname, namespaceId, typowner); + rettype = address.objectId; + Assert(OidIsValid(rettype)); } - address = TypeShellMake(typname, namespaceId, typowner); - rettype = address.objectId; - Assert(OidIsValid(rettype)); } aclresult = pg_type_aclcheck(rettype, GetUserId(), ACL_USAGE); @@ -277,9 +294,10 @@ static void compute_return_type( * requiredResultType is set to InvalidOid if there are no OUT parameters, * else it is set to the OID of the implied result type. */ -static void examine_parameter_list(List* parameters, Oid languageOid, const char* queryString, - oidvector** parameterTypes, ArrayType** allParameterTypes, ArrayType** parameterModes, ArrayType** parameterNames, - List** parameterDefaults, Oid* requiredResultType, List** defargpos, bool fenced) +void examine_parameter_list(List* parameters, Oid languageOid, const char* queryString, + oidvector** parameterTypes, TypeDependExtend** type_depend_extend, ArrayType** allParameterTypes, + ArrayType** parameterModes, ArrayType** parameterNames, + List** parameterDefaults, Oid* requiredResultType, List** defargpos, bool fenced, bool* has_undefined) { int parameterCount = list_length(parameters); Oid* inTypes = NULL; @@ -307,6 +325,9 @@ static void examine_parameter_list(List* parameters, Oid languageOid, const char allTypes = (Datum*)palloc(parameterCount * sizeof(Datum)); paramModes = (Datum*)palloc(parameterCount * sizeof(Datum)); paramNames = (Datum*)palloc0(parameterCount * sizeof(Datum)); + if (enable_plpgsql_gsdependency()) { + *type_depend_extend = (TypeDependExtend*)palloc0((parameterCount) * sizeof(TypeDependExtend)); + } } *parameterDefaults = NIL; @@ -326,8 +347,16 @@ static void examine_parameter_list(List* parameters, Oid languageOid, const char AclResult aclresult; char* objname = NULL; objname = strVal(linitial(t->names)); - typtup = LookupTypeName(NULL, t, NULL); - if (!HeapTupleIsValid(typtup)) { + if (enable_plpgsql_gsdependency()) { + typtup = LookupTypeName(NULL, t, NULL, true, (*type_depend_extend) + i); + if (NULL != has_undefined && !*has_undefined && (*type_depend_extend)[i].dependUndefined) { + *has_undefined = true; + } + } else { + typtup = LookupTypeName(NULL, t, NULL); + } + int typ_tup_status = GetTypeTupStatus(typtup); + if (NormalTypeTup != typ_tup_status) { toid = findPackageParameter(objname); } /* @@ -339,6 +368,15 @@ static void examine_parameter_list(List* parameters, Oid languageOid, const char (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("argument type '%s' must be in installation group", TypeNameToString(t)))); } + + if (enable_plpgsql_gsdependency() && UndefineTypeTup == typ_tup_status) { + if (OidIsValid(toid)) { + gsplsql_delete_unrefer_depend_obj_oid((*type_depend_extend)[i].undefDependObjOid, false); + (*type_depend_extend)[i].undefDependObjOid = InvalidOid; + ReleaseSysCache(typtup); + typtup = NULL; + } + } if (typtup) { if (!((Form_pg_type)GETSTRUCT(typtup))->typisdefined) { @@ -972,6 +1010,8 @@ ObjectAddress CreateFunction(CreateFunctionStmt* stmt, const char* queryString, Oid namespaceId = InvalidOid; AclResult aclresult; oidvector* parameterTypes = NULL; + TypeDependExtend* param_type_depend_ext = NULL; + TypeDependExtend* ret_type_depend_ext = NULL; ArrayType* allParameterTypes = NULL; ArrayType* parameterModes = NULL; ArrayType* parameterNames = NULL; @@ -1160,25 +1200,49 @@ ObjectAddress CreateFunction(CreateFunctionStmt* stmt, const char* queryString, * Convert remaining parameters of CREATE to form wanted by * ProcedureCreate. */ - examine_parameter_list(stmt->parameters, languageOid, queryString, ¶meterTypes, &allParameterTypes, - ¶meterModes, ¶meterNames, ¶meterDefaults, &requiredResultType, &defargpos, fenced); - - prodefaultargpos = GetDefaultArgPos(defargpos); - - if (stmt->returnType) { - /* explicit RETURNS clause */ - compute_return_type(stmt->returnType, languageOid, &prorettype, &returnsSet, fenced, stmt->startLineNumber); - } else if (OidIsValid(requiredResultType)) { - /* default RETURNS clause from OUT parameters */ - prorettype = requiredResultType; - returnsSet = false; + if (stmt->isOraStyle) { + set_function_style_a(); } else { - ereport( - ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), errmsg("function result type must be specified"))); - /* Alternative possibility: default to RETURNS VOID */ - prorettype = VOIDOID; - returnsSet = false; + set_function_style_pg(); } + CreatePlsqlType oldCreatePlsqlType = u_sess->plsql_cxt.createPlsqlType; + Oid old_curr_object_nspoid = u_sess->plsql_cxt.curr_object_nspoid; + PG_TRY(); + { + set_create_plsql_type_not_check_nsp_oid(); + u_sess->plsql_cxt.curr_object_nspoid = namespaceId; + examine_parameter_list(stmt->parameters, languageOid, queryString, ¶meterTypes, ¶m_type_depend_ext, &allParameterTypes, + ¶meterModes, ¶meterNames, ¶meterDefaults, &requiredResultType, &defargpos, fenced); + + prodefaultargpos = GetDefaultArgPos(defargpos); + + if (stmt->returnType) { + /* explicit RETURNS clause */ + InstanceTypeNameDependExtend(&ret_type_depend_ext); + compute_return_type(stmt->returnType, languageOid, &prorettype, &returnsSet, fenced, stmt->startLineNumber, + ret_type_depend_ext, false); + } else if (OidIsValid(requiredResultType)) { + /* default RETURNS clause from OUT parameters */ + InstanceTypeNameDependExtend(&ret_type_depend_ext); + prorettype = requiredResultType; + returnsSet = false; + } else { + ereport( + ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), errmsg("function result type must be specified"))); + /* Alternative possibility: default to RETURNS VOID */ + prorettype = VOIDOID; + returnsSet = false; + } + set_create_plsql_type(oldCreatePlsqlType); + u_sess->plsql_cxt.curr_object_nspoid = old_curr_object_nspoid; + } + PG_CATCH(); + { + set_create_plsql_type(oldCreatePlsqlType); + u_sess->plsql_cxt.curr_object_nspoid = old_curr_object_nspoid; + PG_RE_THROW(); + } + PG_END_TRY(); if (returnsSet) { Oid typerelid = typeidTypeRelid(prorettype); @@ -1257,15 +1321,20 @@ ObjectAddress CreateFunction(CreateFunctionStmt* stmt, const char* queryString, package, proIsProcedure, stmt->inputHeaderSrc, - stmt->isPrivate); + stmt->isPrivate, + param_type_depend_ext, + ret_type_depend_ext, + stmt); CreateFunctionComment(address.objectId, functionOptions); - + pfree_ext(param_type_depend_ext); + pfree_ext(ret_type_depend_ext); u_sess->plsql_cxt.procedure_start_line = 0; u_sess->plsql_cxt.procedure_first_line = 0; u_sess->plsql_cxt.isCreateFunction = false; if (u_sess->plsql_cxt.debug_query_string != NULL && !OidIsValid(pkg_oid)) { pfree_ext(u_sess->plsql_cxt.debug_query_string); + u_sess->plsql_cxt.has_error = false; } return address; } @@ -1548,9 +1617,8 @@ void RemoveFunctionById(Oid funcOid) Form_pg_proc procedureStruct = (Form_pg_proc)GETSTRUCT(tup); isagg = procedureStruct->proisagg; - -#ifdef ENABLE_MOT char* funcName = pstrdup(NameStr(procedureStruct->proname)); +#ifdef ENABLE_MOT bool isNull = false; Datum prokindDatum = SysCacheGetAttr(PROCOID, tup, Anum_pg_proc_prokind, &isNull); bool proIsProcedure = isNull ? false : PROC_IS_PRO(CharGetDatum(prokindDatum)); @@ -1562,12 +1630,24 @@ void RemoveFunctionById(Oid funcOid) PrepareCFunctionLibrary(tup); } +#ifndef ENABLE_MULTIPLE_NODES + GsDependObjDesc func_head_obj; + if (t_thrd.proc->workingVersionNum >= SUPPORT_GS_DEPENDENCY_VERSION_NUM) { + Oid pro_namespace = procedureStruct->pronamespace; + bool is_null; + Datum pro_package_id_datum = SysCacheGetAttr(PROCOID, tup, Anum_pg_proc_packageid, &is_null); + Oid proc_packageid = DatumGetObjectId(pro_package_id_datum); + func_head_obj = gsplsql_construct_func_head_obj(funcOid, pro_namespace, proc_packageid); + } +#endif + simple_heap_delete(relation, &tup->t_self); ReleaseSysCache(tup); heap_close(relation, RowExclusiveLock); + CacheInvalidateFunction(funcOid, InvalidOid); /* * If there's a pg_aggregate tuple, delete that too. */ @@ -1600,6 +1680,21 @@ void RemoveFunctionById(Oid funcOid) } pfree_ext(funcName); #endif +#ifndef ENABLE_MULTIPLE_NODES + if (t_thrd.proc->workingVersionNum >= SUPPORT_GS_DEPENDENCY_VERSION_NUM) { + CommandCounterIncrement(); + func_head_obj.type = GSDEPEND_OBJECT_TYPE_PROCHEAD; + gsplsql_remove_dependencies_object(&func_head_obj); + func_head_obj.refPosType = GSDEPEND_REFOBJ_POS_IN_PROCALL; + gsplsql_remove_gs_dependency(&func_head_obj); + if (enable_plpgsql_gsdependency_guc()) { + func_head_obj.name = funcName; + func_head_obj.type = GSDEPEND_OBJECT_TYPE_FUNCTION; + gsplsql_remove_ref_dependency(&func_head_obj); + } + free_gs_depend_obj_desc(&func_head_obj); + } +#endif } /* * Guts of function deletion. @@ -1643,6 +1738,25 @@ void RemovePackageById(Oid pkgOid, bool isBody) HeapTuple pkgtup = SearchSysCache1(PACKAGEOID, ObjectIdGetDatum(pkgOid)); if (!HeapTupleIsValid(pkgtup)) /* should not happen */ ereport(ERROR, (errcode(ERRCODE_CACHE_LOOKUP_FAILED), errmsg("cache lookup failed for package %u", pkgOid))); +#ifndef ENABLE_MULTIPLE_NODES + GsDependObjDesc pkg; + if (t_thrd.proc->workingVersionNum >= SUPPORT_GS_DEPENDENCY_VERSION_NUM) { + bool is_null; + Datum schema_name_datum = SysCacheGetAttr(PACKAGEOID, pkgtup, Anum_gs_package_pkgnamespace, &is_null); + pkg.schemaName = get_namespace_name(DatumGetObjectId(schema_name_datum)); + Datum pkg_name_datum = SysCacheGetAttr(PACKAGEOID, pkgtup, Anum_gs_package_pkgname, &is_null); + pkg.packageName = pstrdup(NameStr(*DatumGetName(pkg_name_datum))); + pkg.name = NULL; + pkg.type = GSDEPEND_OBJECT_TYPE_INVALID; + if (isBody) { + pkg.type = GSDEPEND_OBJECT_TYPE_PKG_BODY; + pkg.refPosType = GSDEPEND_REFOBJ_POS_IN_PKGBODY; + } else { + pkg.type = GSDEPEND_OBJECT_TYPE_PKG; + pkg.refPosType = GSDEPEND_REFOBJ_POS_IN_PKGALL_OBJ; + } + } +#endif if (!isBody) { /* if replace package specification,delete all function in this package first. @@ -1679,16 +1793,60 @@ void RemovePackageById(Oid pkgOid, bool isBody) heap_close(relation, RowExclusiveLock); + CacheInvalidateFunction(InvalidOid, pkgOid); /* * If there's a pg_aggregate tuple, delete that too. */ /* Recode time of delete package. */ if (pkgOid != InvalidOid) { - DeletePgObject(pkgOid, OBJECT_TYPE_PKGSPEC); + if (isBody) { + DeletePgObject(pkgOid, OBJECT_TYPE_PKGSPEC); + } else { + DeletePgObject(pkgOid, OBJECT_TYPE_PKGSPEC); + DeletePgObject(pkgOid, OBJECT_TYPE_PKGBODY); + } +#ifndef ENABLE_MULTIPLE_NODES + if (t_thrd.proc->workingVersionNum >= SUPPORT_GS_DEPENDENCY_VERSION_NUM) { + CommandCounterIncrement(); + gsplsql_remove_gs_dependency(&pkg); + if (enable_plpgsql_gsdependency_guc()) { + gsplsql_remove_ref_dependency(&pkg); + } + pfree_ext(pkg.packageName); + pfree_ext(pkg.schemaName); + } +#endif } } +void DeleteFunctionByFuncTuple(HeapTuple proctup) +{ + Oid funcOid = InvalidOid; + if (HeapTupleIsValid(proctup)) { + funcOid = HeapTupleGetOid(proctup); + if (!OidIsValid(funcOid)) { + ereport(ERROR, + (errcode(ERRCODE_CACHE_LOOKUP_FAILED), + errmodule(MOD_PLSQL), + errmsg("cache lookup failed for relid %u", funcOid))); + } + } else { + ereport(ERROR, + (errcode(ERRCODE_CACHE_LOOKUP_FAILED), + errmodule(MOD_PLSQL), + errmsg("cache lookup failed for relid %u", funcOid))); + } + (void)deleteDependencyRecordsFor(ProcedureRelationId, funcOid, true); + DeleteTypesDenpendOnPackage(ProcedureRelationId, funcOid); + /* the 'shared dependencies' also change when update. */ + deleteSharedDependencyRecordsFor(ProcedureRelationId, funcOid, 0); + + /* send invalid message for for relation holding replaced function as trigger */ + InvalidRelcacheForTriggerFunction(funcOid, ((Form_pg_proc)GETSTRUCT(proctup))->prorettype); + RemoveFunctionById(funcOid); +} + void DeleteFunctionByPackageOid(Oid package_oid) { if (!OidIsValid(package_oid)) { @@ -1702,29 +1860,7 @@ void DeleteFunctionByPackageOid(Oid package_oid) SysScanDesc scan = systable_beginscan(pg_proc_rel, InvalidOid, false, NULL, 1, &entry); while ((oldtup = systable_getnext(scan)) != NULL) { HeapTuple proctup = heap_copytuple(oldtup); - Oid funcOid = InvalidOid; - if (HeapTupleIsValid(proctup)) { - funcOid = HeapTupleGetOid(proctup); - if (!OidIsValid(funcOid)) { - ereport(ERROR, - (errcode(ERRCODE_CACHE_LOOKUP_FAILED), - errmodule(MOD_PLSQL), - errmsg("cache lookup failed for relid %u", funcOid))); - } - } else { - ereport(ERROR, - (errcode(ERRCODE_CACHE_LOOKUP_FAILED), - errmodule(MOD_PLSQL), - errmsg("cache lookup failed for relid %u", funcOid))); - } - (void)deleteDependencyRecordsFor(ProcedureRelationId, funcOid, true); - DeleteTypesDenpendOnPackage(ProcedureRelationId, funcOid); - /* the 'shared dependencies' also change when update. */ - deleteSharedDependencyRecordsFor(ProcedureRelationId, funcOid, 0); - - /* send invalid message for for relation holding replaced function as trigger */ - InvalidRelcacheForTriggerFunction(funcOid, ((Form_pg_proc)GETSTRUCT(proctup))->prorettype); - RemoveFunctionById(funcOid); + DeleteFunctionByFuncTuple(proctup); heap_freetuple(proctup); } systable_endscan(scan); @@ -2103,6 +2239,202 @@ bool IsFunctionTemp(AlterFunctionStmt* stmt) return false; } +static inline void SetFuncValid(Oid func_oid, bool is_procedure) +{ + SetPgObjectValid(func_oid, OBJECT_TYPE_PROC, GetCurrCompilePgObjStatus()); + if (!GetCurrCompilePgObjStatus()) { + ereport(WARNING, (errmodule(MOD_PLSQL), + errmsg("%s %s recompile with compilation errors.", + is_procedure ? "Procedure" : "Functions", + get_func_name(func_oid)))); + } +} + +static inline bool CheckBeforeRecompile(Oid func_oid) +{ + if (OidIsValid(gsplsql_get_pkg_oid_by_func_oid(func_oid))) { + ereport(WARNING, (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is a function in package", get_func_name(func_oid)), + errhint("Replace the ALTER FUNCTION with ALTER PACKAGE."))); + return false; + } + if (gsplsql_is_undefined_func(func_oid)) { + ereport(WARNING, (errcode(ERRCODE_UNDEFINED_FUNCTION), + errmsg("\"%s\" header is undefined, you can try to recreate.", get_func_name(func_oid)))); + return false; + } + return true; +} + +static void CheckIsTriggerAndAssign(Oid func_oid, FunctionCallInfo fcinfo, TriggerData* trigdata) +{ + + HeapTuple tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(func_oid)); + if (!HeapTupleIsValid(tuple)) { + ereport(ERROR, (errcode(ERRCODE_CACHE_LOOKUP_FAILED), + errdetail("cache lookup failed for function %u", func_oid))); + } + Form_pg_proc proc = (Form_pg_proc)GETSTRUCT(tuple); + char functyptype = get_typtype(proc->prorettype); + if (functyptype == TYPTYPE_PSEUDO) { + if (proc->prorettype == TRIGGEROID || (proc->prorettype == OPAQUEOID && proc->pronargs == 0)) { + error_t rc = memset_s(&trigdata, sizeof(TriggerData), 0, sizeof(TriggerData)); + securec_check(rc, "", ""); + trigdata->type = T_TriggerData; + fcinfo->context = (Node*)trigdata; + } + } + ReleaseSysCache(tuple); +} + +void RecompileSingleFunction(Oid func_oid, bool is_procedure) +{ + FunctionCallInfoData fake_fcinfo; + FmgrInfo flinfo; + if (!CheckBeforeRecompile(func_oid)) { + return; + } + error_t rc = memset_s(&fake_fcinfo, sizeof(fake_fcinfo), 0, sizeof(fake_fcinfo)); + securec_check(rc, "", ""); + rc = memset_s(&flinfo, sizeof(flinfo), 0, sizeof(flinfo)); + securec_check(rc, "", ""); + + fake_fcinfo.flinfo = &flinfo; + fake_fcinfo.arg = (Datum*)palloc0(sizeof(Datum)); + fake_fcinfo.arg[0] = ObjectIdGetDatum(func_oid); + flinfo.fn_oid = func_oid; + flinfo.fn_mcxt = CurrentMemoryContext; + + _PG_init(); + PLpgSQL_compile_context* save_compile_context = u_sess->plsql_cxt.curr_compile_context; + int save_compile_list_length = list_length(u_sess->plsql_cxt.compile_context_list); + int save_compile_status = getCompileStatus(); + bool save_need_create_depend = u_sess->plsql_cxt.need_create_depend; + u_sess->plsql_cxt.isCreateFunction = false; + u_sess->plsql_cxt.compile_has_warning_info = false; + int save_searchpath_stack = list_length(u_sess->catalog_cxt.overrideStack); + + PG_TRY(); + { + u_sess->plsql_cxt.createPlsqlType = CREATE_PLSQL_TYPE_RECOMPILE; + if (GetPgObjectValid(func_oid, OBJECT_TYPE_PROC)) { + u_sess->plsql_cxt.need_create_depend = false; + } else { + u_sess->plsql_cxt.need_create_depend = true; + } + SetCurrCompilePgObjStatus(true); + TriggerData trigdata; + CheckIsTriggerAndAssign(func_oid, &fake_fcinfo, &trigdata); + PLpgSQL_function* func = plpgsql_compile(&fake_fcinfo, true, true); + u_sess->plsql_cxt.need_create_depend = save_need_create_depend; + if(func != NULL) { + SetFuncValid(func->fn_oid, is_procedure); + } + SetCurrCompilePgObjStatus(true); + if (enable_plpgsql_gsdependency_guc()) { + u_sess->plsql_cxt.createPlsqlType = CREATE_PLSQL_TYPE_END; + } + } + PG_CATCH(); + { + if (enable_plpgsql_gsdependency_guc()) { + u_sess->plsql_cxt.createPlsqlType = CREATE_PLSQL_TYPE_END; + } + SetCurrCompilePgObjStatus(true); + u_sess->plsql_cxt.curr_compile_context = save_compile_context; + u_sess->plsql_cxt.compile_status = save_compile_status; + u_sess->plsql_cxt.need_create_depend = save_need_create_depend; + + clearCompileContextList(save_compile_list_length); + plpgsql_free_override_stack(save_searchpath_stack); + PG_RE_THROW(); + } + PG_END_TRY(); +} + +static bool IsNeedRecompile(Oid oid) +{ + bool is_null; + HeapTuple tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(oid)); + if (!HeapTupleIsValid(tuple)) { + return false; + } + Datum pro_lang_datum = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prolang, &is_null); + char* lang = get_language_name(DatumGetObjectId(pro_lang_datum)); + ReleaseSysCache(tuple); + return (!IsSystemObjOid(oid) && !IsMaskingFunctionOid(oid) && !IsRlsFunction(oid) && + strcasecmp(lang, "plpgsql") == 0); +} + +static inline void ReportRecompileFuncWarning(CompileStmt* stmt) +{ + ereport(WARNING, + (errcode(ERRCODE_UNDEFINED_FUNCTION), + errmsg("%s %s does not exist, if it is a stored %s, use ALTER %s.", + stmt->compileItem == COMPILE_FUNCTION ? "Functions" : "Procedure", + NameListToString(stmt->objName), + stmt->compileItem == COMPILE_FUNCTION ? "procedure" : "functions", + stmt->compileItem == COMPILE_FUNCTION ? "PROCEDURE" : "FUNCTION"))); +} + +static void RecompileFunctionWithArgs(CompileStmt* stmt) +{ + Oid func_oid = LookupFuncNameTypeNames(stmt->objName, stmt->funcArgs, false); + if (!OidIsValid(func_oid)) { + ReportRecompileFuncWarning(stmt); + return; + } + if (PROC_IS_FUNC(get_func_prokind(func_oid)) && stmt->compileItem == COMPILE_PROCEDURE) { + ReportRecompileFuncWarning(stmt); + } + if (PROC_IS_PRO(get_func_prokind(func_oid)) && stmt->compileItem == COMPILE_FUNCTION) { + ReportRecompileFuncWarning(stmt); + } + if (!IsNeedRecompile(func_oid)) { + RecompileSingleFunction(func_oid, stmt->compileItem == COMPILE_PROCEDURE); + return; + } + return; +} + +void RecompileFunction(CompileStmt* stmt) +{ + if (stmt->funcArgs != NULL) { + RecompileFunctionWithArgs(stmt); + return; + } + int num = 0; + FuncCandidateList clist = NULL; + StringInfoData err_string; + initStringInfo(&err_string); + clist = FuncnameGetCandidates(stmt->objName, -1, NULL, false, false, false, false, + stmt->compileItem == COMPILE_FUNCTION ? 'f' : 'p'); + if (clist == NULL) { + ReportRecompileFuncWarning(stmt); + return; + } + for (; clist; clist = clist->next) { + if (IsNeedRecompile(clist->oid) && !OidIsValid(gsplsql_get_pkg_oid_by_func_oid(clist->oid))) { + RecompileSingleFunction(clist->oid, stmt->compileItem == COMPILE_PROCEDURE); + num++; + appendStringInfoString(&err_string, format_procedure(clist->oid)); + if (clist->next != NULL) { + appendStringInfoString(&err_string, ","); + } else { + appendStringInfoString(&err_string, "."); + } + } + } + if (num > 1) { + ereport(NOTICE, + (errcode(ERRCODE_AMBIGUOUS_FUNCTION), + errmsg("Compile %d %s: %s", num, + stmt->compileItem == COMPILE_FUNCTION ? "functions" : "procedure", + err_string.data))); + } + FreeStringInfo(&err_string); +} + /* * Implements the ALTER FUNCTION utility command (except for the * RENAME and OWNER clauses, which are handled as part of the generic diff --git a/src/gausskernel/optimizer/commands/packagecmds.cpp b/src/gausskernel/optimizer/commands/packagecmds.cpp index b2d6c63ec..7835ddbe7 100644 --- a/src/gausskernel/optimizer/commands/packagecmds.cpp +++ b/src/gausskernel/optimizer/commands/packagecmds.cpp @@ -228,6 +228,100 @@ void CreatePackageBodyCommand(CreatePackageBodyStmt* stmt, const char* queryStri } } +static inline void clear_plsql_ctx_line_info() +{ + u_sess->plsql_cxt.procedure_first_line = 0; + u_sess->plsql_cxt.procedure_start_line = 0; + u_sess->plsql_cxt.package_first_line = 0; + u_sess->plsql_cxt.package_as_line = 0; +} + +static void RecompileSinglePackage(Oid package_oid, bool is_spec) +{ + Oid* save_pseudo_current_user_id = u_sess->misc_cxt.Pseudo_CurrentUserId; + _PG_init(); + PLpgSQL_compile_context* save_compile_context = u_sess->plsql_cxt.curr_compile_context; + int save_compile_list_length = list_length(u_sess->plsql_cxt.compile_context_list); + int save_compile_status = getCompileStatus(); + bool save_need_create_depend = u_sess->plsql_cxt.need_create_depend; + u_sess->plsql_cxt.isCreateFunction = false; + u_sess->plsql_cxt.compile_has_warning_info = false; + int save_searchpath_stack = list_length(u_sess->catalog_cxt.overrideStack); + PG_TRY(); + { + u_sess->plsql_cxt.createPlsqlType = CREATE_PLSQL_TYPE_RECOMPILE; + if (GetPgObjectValid(package_oid, is_spec ? OBJECT_TYPE_PKGSPEC : OBJECT_TYPE_PKGBODY)) { + u_sess->plsql_cxt.need_create_depend = false; + } else { + u_sess->plsql_cxt.need_create_depend = true; + } + SetCurrCompilePgObjStatus(true); + (void)plpgsql_pkg_compile(package_oid, true, is_spec, false, true); + u_sess->misc_cxt.Pseudo_CurrentUserId = save_pseudo_current_user_id; + u_sess->plsql_cxt.need_create_depend = save_need_create_depend; + if (enable_plpgsql_gsdependency_guc()) { + u_sess->plsql_cxt.createPlsqlType = CREATE_PLSQL_TYPE_END; + } + SetCurrCompilePgObjStatus(true); + } + PG_CATCH(); + { + if (enable_plpgsql_gsdependency_guc()) { + u_sess->plsql_cxt.createPlsqlType = CREATE_PLSQL_TYPE_END; + } + SetCurrCompilePgObjStatus(true); + u_sess->plsql_cxt.curr_compile_context = save_compile_context; + u_sess->plsql_cxt.compile_status = save_compile_status; + u_sess->plsql_cxt.need_create_depend = save_need_create_depend; + clearCompileContextList(save_compile_list_length); + u_sess->plsql_cxt.running_pkg_oid = InvalidOid; + clear_plsql_ctx_line_info(); + u_sess->plsql_cxt.in_package_function_compile = false; + u_sess->misc_cxt.Pseudo_CurrentUserId = save_pseudo_current_user_id; + plpgsql_free_override_stack(save_searchpath_stack); + PG_RE_THROW(); + } + PG_END_TRY(); +} + +static inline void RecompilePackageByOid(Oid pkg_oid) +{ + bool is_null; + HeapTuple pkg_tup = SearchSysCache1(PACKAGEOID, ObjectIdGetDatum(pkg_oid)); + if (!HeapTupleIsValid(pkg_tup)) { + ereport(ERROR, (errcode(ERRCODE_CACHE_LOOKUP_FAILED), + errdetail("cache lookup failed for package %u, while recompile package.", pkg_oid))); + return; + } + SysCacheGetAttr(PACKAGEOID, pkg_tup, Anum_gs_package_pkgbodydeclsrc, &is_null); + if (is_null) { + ReleaseSysCache(pkg_tup); + RecompileSinglePackage(pkg_oid, true); + return; + } + ReleaseSysCache(pkg_tup); + RecompileSinglePackage(pkg_oid, false); +} + +void RecompilePackage(CompileStmt* stmt) +{ + Oid pkg_oid = PackageNameListGetOid(stmt->objName, false, false); + if (IsSystemObjOid(pkg_oid)) { + return; + } + switch (stmt->compileItem) { + case COMPILE_PKG_SPECIFICATION: + RecompileSinglePackage(pkg_oid, true); + break; + case COMPILE_PKG_BODY: + RecompileSinglePackage(pkg_oid, false); + break; + default: + RecompilePackageByOid(pkg_oid); + break; + } +} + /* * Change package owner by name */ diff --git a/src/gausskernel/optimizer/commands/tablecmds.cpp b/src/gausskernel/optimizer/commands/tablecmds.cpp index a2f6d820b..6201ecd2b 100755 --- a/src/gausskernel/optimizer/commands/tablecmds.cpp +++ b/src/gausskernel/optimizer/commands/tablecmds.cpp @@ -176,6 +176,7 @@ #include "pgstat.h" #include "postmaster/rbcleaner.h" #include "catalog/gs_collation.h" +#include "catalog/gs_dependencies_fn.h" #ifdef ENABLE_MULTIPLE_NODES #include "tsdb/utils/ts_relcache.h" #include "tsdb/common/ts_tablecmds.h" @@ -2065,6 +2066,7 @@ ObjectAddress DefineRelation(CreateStmt* stmt, char relkind, Oid ownerId, Object bool relhasuids = false; Oid nspdefcoll = InvalidOid; Oid rel_coll_oid = InvalidOid; + List* depend_extend = NIL; /* * isalter is true, change the owner of the objects as the owner of the @@ -2601,6 +2603,14 @@ ObjectAddress DefineRelation(CreateStmt* stmt, char relkind, Oid ownerId, Object } else ofTypeId = InvalidOid; + if (enable_plpgsql_gsdependency()) { + ListCell* cell = NULL; + foreach(cell, schema) { + ColumnDef* col_def = (ColumnDef*)lfirst(cell); + depend_extend = lappend(depend_extend, col_def->typname->dependExtend); + } + } + /* * Look up inheritance ancestors and generate relation schema, including * inherited attributes. @@ -2920,7 +2930,8 @@ ObjectAddress DefineRelation(CreateStmt* stmt, char relkind, Oid ownerId, Object ceLst, storage_type, AccessShareLock, - typaddress); + typaddress, + depend_extend); if (bucketinfo != NULL) { pfree_ext(bucketinfo->bucketcol); pfree_ext(bucketinfo->bucketlist); @@ -3064,7 +3075,11 @@ ObjectAddress DefineRelation(CreateStmt* stmt, char relkind, Oid ownerId, Object relation_close(rel, NoLock); list_free_ext(rawDefaults); list_free_ext(ceLst); - + if (enable_plpgsql_gsdependency_guc() && relkind != RELKIND_TOASTVALUE) { + if (CompileWhich() == PLPGSQL_COMPILE_NULL) { + (void)gsplsql_build_ref_type_dependency(get_rel_type_id(relationId)); + } + } return address; } @@ -5979,7 +5994,33 @@ ObjectAddress renameatt(RenameStmt* stmt) } TrForbidAccessRbObject(RelationRelationId, relid, stmt->relation->relname); - + if (enable_plpgsql_gsdependency_guc()) { + Oid type_oid = get_rel_type_id(relid); + if (OidIsValid(type_oid)) { + GsDependObjDesc obj; + gsplsql_get_depend_obj_by_typ_id(&obj, type_oid, InvalidOid); + HeapTuple obj_tup = gsplsql_search_object(&obj, false); + if (HeapTupleIsValid(obj_tup)) { + heap_freetuple(obj_tup); + pfree_ext(obj.schemaName); + pfree_ext(obj.packageName); + pfree_ext(obj.name); + ereport(ERROR, + (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST), + errmsg("cannot rename attribute of the type because it is dependent on another object."))); + } + obj.refPosType = GSDEPEND_REFOBJ_POS_IN_TYPE; + bool exist_dep = gsplsql_exist_dependency(&obj); + pfree_ext(obj.schemaName); + pfree_ext(obj.packageName); + pfree_ext(obj.name); + if (exist_dep) { + ereport(ERROR, + (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST), + errmsg("cannot rename attribute of the type because it is dependent on another object."))); + } + } + } // Check relations's internal mask Relation rel = relation_open(relid, AccessShareLock); if ((((uint32)RelationGetInternalMask(rel)) & INTERNAL_MASK_DALTER)) @@ -6560,7 +6601,19 @@ ObjectAddress RenameRelation(RenameStmt* stmt) errdetail("%s table doesn't support this ALTER yet.", ISMLOG(relname) ? "mlog" : "matviewmap")))); } ReleaseSysCache(tuple); - + if (enable_plpgsql_gsdependency_guc()) { + bool exist_dep = false; + char rel_kind = get_rel_relkind(relid); + if (RELKIND_RELATION == rel_kind) { + exist_dep = gsplsql_is_object_depend(get_rel_type_id(relid), GSDEPEND_OBJECT_TYPE_TYPE); + } + if (exist_dep) { + ereport(ERROR, + (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST), + errmsg("The rename operator on %s is not allowed, " + "because it is dependent on another object.", stmt->relation->relname))); + } + } TrForbidAccessRbObject(RelationRelationId, relid, stmt->relation->relname); /* If table has history table, we need rename corresponding history table */ if (is_ledger_usertable(relid)) { @@ -7731,6 +7784,9 @@ void AlterTable(Oid relid, LOCKMODE lockmode, AlterTableStmt* stmt) if (stmt->cmds != NIL) { /* process 'ALTER TABLE' cmd */ ATController(stmt, rel, stmt->cmds, interpretInhOption(stmt->relation->inhOpt), lockmode); + if (enable_plpgsql_gsdependency_guc()) { + (void)gsplsql_build_ref_type_dependency(get_rel_type_id(relid)); + } } else { /* if do not call ATController, close the relation in here, but keep lock until commit */ relation_close(rel, NoLock); diff --git a/src/gausskernel/optimizer/commands/typecmds.cpp b/src/gausskernel/optimizer/commands/typecmds.cpp index c562d2a11..8efb57063 100644 --- a/src/gausskernel/optimizer/commands/typecmds.cpp +++ b/src/gausskernel/optimizer/commands/typecmds.cpp @@ -83,6 +83,8 @@ #include "utils/rel_gs.h" #include "utils/syscache.h" #include "utils/snapmgr.h" +#include "catalog/gs_dependencies_fn.h" +#include "catalog/pg_object.h" /* result structure for get_rels_with_domain() */ typedef struct { @@ -644,6 +646,20 @@ ObjectAddress DefineType(List* names, List* parameters) */ void RemoveTypeById(Oid typeOid) { +#ifndef ENABLE_MULTIPLE_NODES + GsDependObjDesc ref_obj; + if (t_thrd.proc->workingVersionNum >= SUPPORT_GS_DEPENDENCY_VERSION_NUM) { + gsplsql_init_gs_depend_obj_desc(&ref_obj); + char relkind = get_rel_relkind(typeOid); + if (relkind == RELKIND_COMPOSITE_TYPE || relkind == '\0') { + ref_obj.name = NULL; + Oid elem_oid = get_array_internal_depend_type_oid(typeOid); + if (!OidIsValid(elem_oid)) { + gsplsql_get_depend_obj_by_typ_id(&ref_obj, typeOid, InvalidOid, true); + } + } + } +#endif Relation relation; HeapTuple tup; @@ -682,6 +698,37 @@ void RemoveTypeById(Oid typeOid) ReleaseSysCache(tup); heap_close(relation, RowExclusiveLock); +#ifndef ENABLE_MULTIPLE_NODES + if (t_thrd.proc->workingVersionNum >= SUPPORT_GS_DEPENDENCY_VERSION_NUM && NULL != ref_obj.name) { + CommandCounterIncrement(); + ref_obj.refPosType = GSDEPEND_REFOBJ_POS_IN_TYPE; + gsplsql_remove_type_gs_dependency(&ref_obj); + if (enable_plpgsql_gsdependency_guc()) { + ref_obj.type = GSDEPEND_OBJECT_TYPE_TYPE; + (void)gsplsql_remove_ref_dependency(&ref_obj); + Oid pkg_oid = GetTypePackageOid(typeOid); + if (OidIsValid(pkg_oid)) { + bool invalid_pkg = true; + if (NULL != u_sess->plsql_cxt.curr_compile_context && + NULL != u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package) { + invalid_pkg = pkg_oid == + u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package->pkg_oid; + } + if (invalid_pkg) { + bool is_spec = ref_obj.name[0] != '$'; + SetPgObjectValid(pkg_oid, is_spec ? OBJECT_TYPE_PKGSPEC : OBJECT_TYPE_PKGBODY, false); + if (is_spec) { + SetPgObjectValid(pkg_oid, OBJECT_TYPE_PKGBODY, false); + } + gsplsql_set_pkg_func_status(GetPackageNamespace(pkg_oid), pkg_oid, false); + } + } + } + pfree_ext(ref_obj.schemaName); + pfree_ext(ref_obj.packageName); + pfree_ext(ref_obj.name); + } +#endif } /* @@ -3283,6 +3330,14 @@ ObjectAddress RenameType(RenameStmt* stmt) } #endif + if (enable_plpgsql_gsdependency_guc() && + gsplsql_is_object_depend(typeOid, GSDEPEND_OBJECT_TYPE_TYPE)) { + ereport(ERROR, + (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST), + errmsg("The rename operator of %s is not allowed, because it is referenced by the other object.", + TypeNameToString(typname)))); + } + /* * If type is composite we need to rename associated pg_class entry too. * RenameRelationInternal will call RenameTypeInternal automatically. diff --git a/src/gausskernel/process/tcop/utility.cpp b/src/gausskernel/process/tcop/utility.cpp index d13f0c8e5..298f572ee 100755 --- a/src/gausskernel/process/tcop/utility.cpp +++ b/src/gausskernel/process/tcop/utility.cpp @@ -470,6 +470,7 @@ static void check_xact_readonly(Node* parse_tree) case T_AlterDatabaseSetStmt: case T_AlterDomainStmt: case T_AlterFunctionStmt: + case T_CompileStmt: case T_AlterRoleSetStmt: case T_AlterObjectSchemaStmt: case T_AlterOwnerStmt: @@ -3388,13 +3389,21 @@ void standard_ProcessUtility(processutility_context* processutility_cxt, #endif PG_TRY(); { + set_create_plsql_type_start(); + u_sess->plsql_cxt.isCreatePkg = true; CreatePackageCommand((CreatePackageStmt*)parse_tree, query_string); + set_create_plsql_type_end(); + set_function_style_none(); + u_sess->plsql_cxt.isCreatePkg = false; } PG_CATCH(); { if (u_sess->plsql_cxt.debug_query_string) { pfree_ext(u_sess->plsql_cxt.debug_query_string); } + set_create_plsql_type_end(); + set_function_style_none(); + u_sess->plsql_cxt.isCreatePkg = false; PG_RE_THROW(); } PG_END_TRY(); @@ -3408,13 +3417,21 @@ void standard_ProcessUtility(processutility_context* processutility_cxt, #endif PG_TRY(); { + set_create_plsql_type_start(); + u_sess->plsql_cxt.isCreatePkg = true; CreatePackageBodyCommand((CreatePackageBodyStmt*)parse_tree, query_string); + set_create_plsql_type_end(); + set_function_style_none(); + u_sess->plsql_cxt.isCreatePkg = false; } PG_CATCH(); { if (u_sess->plsql_cxt.debug_query_string) { pfree_ext(u_sess->plsql_cxt.debug_query_string); } + set_create_plsql_type_end(); + set_function_style_none(); + u_sess->plsql_cxt.isCreatePkg = false; PG_RE_THROW(); } PG_END_TRY(); @@ -5725,10 +5742,15 @@ ProcessUtilitySlow(Node *parse_tree, { PG_TRY(); { + set_create_plsql_type_start(); address = CreateFunction((CreateFunctionStmt*)parse_tree, query_string, InvalidOid); + set_create_plsql_type_end(); + set_function_style_none(); } PG_CATCH(); { + set_create_plsql_type_end(); + set_function_style_none(); #ifndef ENABLE_MULTIPLE_NODES CreateFunctionStmt* stmt = (CreateFunctionStmt*)parse_tree; char* schemaname = NULL; @@ -5833,6 +5855,29 @@ ProcessUtilitySlow(Node *parse_tree, #endif } break; + case T_CompileStmt: + { + if (u_sess->SPI_cxt._connected == -1) { + plpgsql_hashtable_clear_invalid_obj(true); + } + u_sess->plsql_cxt.during_compile = true; + u_sess->plsql_cxt.isCreateFunction = true; + if (!enable_plpgsql_gsdependency_guc()) { + u_sess->plsql_cxt.during_compile = false; + ereport(ERROR, (errmsg("This operation is not supported."))); + break; + } + u_sess->plsql_cxt.is_alter_compile_stmt = true; + CompileStmt* tmpStmt = (CompileStmt*)parse_tree; + if (tmpStmt->compileItem == COMPILE_FUNCTION || tmpStmt->compileItem == COMPILE_PROCEDURE) { + RecompileFunction(tmpStmt); + } else { + RecompilePackage(tmpStmt); + } + u_sess->plsql_cxt.during_compile = false; + u_sess->plsql_cxt.is_alter_compile_stmt = false; + } break; + case T_IndexStmt: /* CREATE INDEX */ { IndexStmt* stmt = (IndexStmt*)parse_tree; @@ -8458,6 +8503,29 @@ static const char* AlterObjectTypeCommandTag(ObjectType obj_type) return tag; } +static const char* CompileTag(CompileEntry compileItem) +{ + const char* tag = NULL; + switch (compileItem) { + case COMPILE_PROCEDURE: + tag = "ALTER PROCEDURE"; + break; + case COMPILE_FUNCTION: + tag = "ALTER FUNCTION"; + break; + case COMPILE_PACKAGE: + tag = "ALTER PACKAGE"; + break; + case COMPILE_PKG_SPECIFICATION: + tag = "ALTER PACKAGE SPECIFICATION"; + break; + case COMPILE_PKG_BODY: + tag = "ALTER PACKAGE BODY"; + break; + } + return tag; +} + /* * CreateCommandTag * utility to get a string representation of the command operation, @@ -8902,6 +8970,17 @@ const char* CreateCommandTag(Node* parse_tree) tag = "ALTER FUNCTION"; break; + case T_CompileStmt: { + u_sess->plsql_cxt.during_compile = true; + if (!enable_plpgsql_gsdependency_guc()) { + u_sess->plsql_cxt.during_compile = false; + ereport(ERROR, (errmsg("This operation is not supported."))); + break; + } + CompileStmt* stmt = (CompileStmt*)parse_tree; + tag = CompileTag(stmt->compileItem); + } break; + case T_GrantStmt: { GrantStmt* stmt = (GrantStmt*)parse_tree; @@ -10059,6 +10138,7 @@ LogStmtLevel GetCommandLogLevel(Node* parse_tree) break; case T_AlterFunctionStmt: + case T_CompileStmt: case T_CreateEventStmt: case T_AlterEventStmt: case T_DropEventStmt: diff --git a/src/gausskernel/process/threadpool/knl_session.cpp b/src/gausskernel/process/threadpool/knl_session.cpp index 6369903b2..eb17d2271 100755 --- a/src/gausskernel/process/threadpool/knl_session.cpp +++ b/src/gausskernel/process/threadpool/knl_session.cpp @@ -871,6 +871,13 @@ static void knl_u_plpgsql_init(knl_u_plpgsql_context* plsql_cxt) plsql_cxt->pragma_autonomous = false; plsql_cxt->is_insert_gs_source = false; plsql_cxt->CursorRecordTypeList = NIL; + plsql_cxt->need_create_depend = true; + plsql_cxt->createPlsqlType = CREATE_PLSQL_TYPE_END; + plsql_cxt->functionStyleType = FUNCTION_STYLE_TYPE_NONE; + plsql_cxt->is_pkg_compile = false; + plsql_cxt->isCreatePkg = false; + plsql_cxt->isCreatePkgFunction = false; + plsql_cxt->currCompilingObjStatus = true; } static void knl_u_stat_init(knl_u_stat_context* stat_cxt) @@ -1738,3 +1745,106 @@ bool enable_out_param_override() return u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && PROC_OUTPARAM_OVERRIDE; } + +bool enable_plpgsql_undefined_not_check_nspoid() +{ + return enable_plpgsql_gsdependency() && + (u_sess->plsql_cxt.createPlsqlType == CREATE_PLSQL_TYPE_NOT_CHECK_NSPOID); +} + +bool enable_plpgsql_gsdependency_guc() +{ +#ifdef ENABLE_MULTIPLE_NODES + return false; +#endif + if (unlikely(IsInitdb || t_thrd.proc->workingVersionNum < SUPPORT_GS_DEPENDENCY_VERSION_NUM)) { + return false; + } + int save_compile_status = u_sess->plsql_cxt.compile_status; + if (save_compile_status != COMPILIE_ANON_BLOCK && PLPGSQL_DEPENDENCY && + u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && + (!u_sess->is_autonomous_session || u_sess->plsql_cxt.during_compile)) { + return true; + } + return false; +} + +bool enable_plpgsql_gsdependency() +{ + if (u_sess->plsql_cxt.is_pkg_compile) { + return enable_plpgsql_gsdependency_guc() && u_sess->plsql_cxt.need_create_depend; + } + if (u_sess->plsql_cxt.functionStyleType == FUNCTION_STYLE_TYPE_A) { + return enable_plpgsql_gsdependency_guc(); + } else if (u_sess->plsql_cxt.functionStyleType == FUNCTION_STYLE_TYPE_PG) { + return false; + } else { + return enable_plpgsql_gsdependency_guc() && u_sess->plsql_cxt.need_create_depend; + } +} + +bool enable_plpgsql_undefined() +{ + return enable_plpgsql_gsdependency() && + (u_sess->plsql_cxt.createPlsqlType == CREATE_PLSQL_TYPE_START || + u_sess->plsql_cxt.createPlsqlType == CREATE_PLSQL_TYPE_RECORD_DEPENDENCE || + u_sess->plsql_cxt.createPlsqlType == CREATE_PLSQL_TYPE_RECOMPILE || + u_sess->plsql_cxt.createPlsqlType == CREATE_PLSQL_TYPE_NOT_CHECK_NSPOID); +} + +void set_create_plsql_type_not_check_nsp_oid() +{ + if (enable_plpgsql_undefined()) { + u_sess->plsql_cxt.createPlsqlType = CREATE_PLSQL_TYPE_NOT_CHECK_NSPOID; + } +} + +void set_create_plsql_type_start() +{ + if (enable_plpgsql_gsdependency_guc()) { + u_sess->plsql_cxt.createPlsqlType = CREATE_PLSQL_TYPE_START; + } +} + +void set_create_plsql_type_end() +{ + if (enable_plpgsql_gsdependency_guc()) { + u_sess->plsql_cxt.createPlsqlType = CREATE_PLSQL_TYPE_END; + } +} + +void set_create_plsql_type(CreatePlsqlType type) +{ + if (enable_plpgsql_gsdependency_guc()) { + u_sess->plsql_cxt.createPlsqlType = type; + } +} + +void set_function_style_none() +{ + u_sess->plsql_cxt.functionStyleType = FUNCTION_STYLE_TYPE_NONE; +} + +void set_function_style_a() +{ + u_sess->plsql_cxt.functionStyleType = FUNCTION_STYLE_TYPE_A; +} + +void set_function_style_pg() +{ + u_sess->plsql_cxt.functionStyleType = FUNCTION_STYLE_TYPE_PG; +} + +bool set_is_create_plsql_type() +{ + if (enable_plpgsql_gsdependency_guc()) { + if (u_sess->plsql_cxt.isCreatePkgFunction == true && + u_sess->plsql_cxt.isCreatePkgFunction == false) { + return false; + } + if (u_sess->plsql_cxt.functionStyleType == FUNCTION_STYLE_TYPE_REFRESH_HEAD) { + return false; + } + } + return true; +} \ No newline at end of file diff --git a/src/gausskernel/storage/access/heap/heapam.cpp b/src/gausskernel/storage/access/heap/heapam.cpp index f497b78c7..e950e2e47 100755 --- a/src/gausskernel/storage/access/heap/heapam.cpp +++ b/src/gausskernel/storage/access/heap/heapam.cpp @@ -6082,7 +6082,7 @@ static void HeapSatisfiesHOTUpdate(Relation relation, Bitmapset* hot_attrs, Bitm * on the relation associated with the tuple). Any failure is reported * via ereport(). */ -void simple_heap_update(Relation relation, ItemPointer otid, HeapTuple tup) +void simple_heap_update(Relation relation, ItemPointer otid, HeapTuple tup, bool allow_update_self) { TM_Result result; TM_FailureData tmfd; @@ -6113,7 +6113,7 @@ void simple_heap_update(Relation relation, ItemPointer otid, HeapTuple tup) true /* wait for commit */, &tmfd, &lockmode, - false); + allow_update_self); switch (result) { case TM_SelfModified: /* Tuple was already updated in current command? */ diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index dea6a8444..fb64b089a 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -357,7 +357,7 @@ extern TransactionId MultiXactIdGetUpdateXid(TransactionId xmax, uint16 t_infoma extern Oid simple_heap_insert(Relation relation, HeapTuple tup); extern void simple_heap_delete(Relation relation, ItemPointer tid, int options = 0, bool allow_update_self = false); -extern void simple_heap_update(Relation relation, ItemPointer otid, HeapTuple tup); +extern void simple_heap_update(Relation relation, ItemPointer otid, HeapTuple tup, bool allow_update_self = false); extern MultiXactStatus GetMXactStatusForLock(LockTupleMode mode, bool isUpdate); extern void heap_markpos(TableScanDesc scan); diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h index f2081aa3b..2d641cc2f 100644 --- a/src/include/catalog/dependency.h +++ b/src/include/catalog/dependency.h @@ -20,7 +20,8 @@ #include "catalog/objectaddress.h" #include "catalog/pg_directory.h" - +struct GsDependParamBody; +struct GsDependObjDesc; /* * Precise semantics of a dependency relationship are specified by the * DependencyType code (which is stored in a "char" field in pg_depend, @@ -163,6 +164,7 @@ typedef struct { typedef enum ObjectClass { OCLASS_CLASS, /* pg_class */ OCLASS_PROC, /* pg_proc */ + OCLASS_DEPENDENCIES_OBJ, /* gs_dependencies_obj */ OCLASS_TYPE, /* pg_type */ OCLASS_CAST, /* pg_cast */ OCLASS_COLLATION, /* pg_collation */ @@ -280,12 +282,20 @@ extern void free_object_addresses(ObjectAddresses *addrs); /* in pg_depend.c */ extern void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, - DependencyType behavior); + DependencyType behavior, GsDependParamBody* gsdependParamBody = NULL); extern void recordMultipleDependencies(const ObjectAddress *depender, const ObjectAddress *referenced, int nreferenced, - DependencyType behavior); + DependencyType behavior, GsDependParamBody* gsdependParamBody = NULL); + +extern bool IsPinnedObject(Oid classOid, Oid objOid); + +extern void doRecordParamDefaultDependencies(bool* hasDependency, bool* hasUndefined, GsDependObjDesc* funcObjDesc, + const ObjectAddress* depender, const ObjectAddress* ref, int nref); + +extern void recordParamDefaultDependencies(bool* hasDependency, bool* hasUndefined, GsDependObjDesc* gsDependObjDesc, + const ObjectAddress* depender, Node* expr, List* rtable); extern void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace); @@ -331,6 +341,7 @@ extern Oid get_index_constraint(Oid indexId); /* use for reindex concurrently */ extern List *get_index_ref_constraints(Oid indexId); +extern void DeletePgDependObject(const ObjectAddress* object, const ObjectAddress* ref_object); /* in pg_shdepend.c */ extern void recordSharedDependencyOn(ObjectAddress *depender, ObjectAddress *referenced, diff --git a/src/include/catalog/gs_dependencies.h b/src/include/catalog/gs_dependencies.h new file mode 100644 index 000000000..1598a2675 --- /dev/null +++ b/src/include/catalog/gs_dependencies.h @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2021 Huawei Technologies Co.,Ltd. +* +* openGauss is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +* --------------------------------------------------------------------------------------- +* +* gs_dependencies.h +* Definition about package dependencies. +* +* +* IDENTIFICATION +* src/include/catalog/gs_dependencies.h +* +* --------------------------------------------------------------------------------------- +*/ +#ifndef GS_DEPENDENCIES_H +#define GS_DEPENDENCIES_H + +#include "catalog/genbki.h" + +#define DependenciesRelationId 7111 +#define DependenciesRelationId_Rowtype_Id 7112 + +CATALOG(gs_dependencies,7111) BKI_SCHEMA_MACRO BKI_WITHOUT_OIDS +{ + NameData schemaname; + NameData packagename; + int4 refobjpos; + Oid refobjoid; +#ifdef CATALOG_VARLEN + text objectname; +#endif +} FormData_gs_dependencies; + +typedef FormData_gs_dependencies *Form_gs_dependencies; + +#define Natts_gs_dependencies 5 +#define Anum_gs_dependencies_schemaname 1 +#define Anum_gs_dependencies_packagename 2 +#define Anum_gs_dependencies_refobjpos 3 +#define Anum_gs_dependencies_refobjoid 4 +#define Anum_gs_dependencies_objectname 5 +#endif \ No newline at end of file diff --git a/src/include/catalog/gs_dependencies_fn.h b/src/include/catalog/gs_dependencies_fn.h new file mode 100644 index 000000000..a765b7f37 --- /dev/null +++ b/src/include/catalog/gs_dependencies_fn.h @@ -0,0 +1,147 @@ +/* +* Copyright (c) 2021 Huawei Technologies Co.,Ltd. +* +* openGauss is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +* --------------------------------------------------------------------------------------- +* +* gs_dependencies_fn.h +* Definition about catalog of dependencies function object. +* +* +* IDENTIFICATION +* src/include/catalog/gs_dependencies_fn.h +* +* --------------------------------------------------------------------------------------- +*/ + +#ifndef GS_DEPENDENCIES_FN_H +#define GS_DEPENDENCIES_FN_H +#include "utils/plpgsql.h" +#include "nodes/pg_list.h" + +struct ObjectAddress; + +typedef struct GsDependObjDesc { + char* schemaName; + char* packageName; + char* name; + GsDependObjectType type; + int refPosType; +} GsDependObjDesc; + +typedef struct GsDependParamBody { + Oid dependNamespaceOid; + Oid dependPkgOid; + char* dependPkgName; + char* dependName; + TypeDependExtend* dependExtend; + GsDependObjectType type; + int refPosType; + bool hasDependency; +} GsDependParamBody; + +typedef struct PkgVarInfo { + char* nsp_name; + char* pkg_name; + char* var_name; + Param* param; +} PkgVarInfo; + +/* + * business interface + */ +extern bool gsplsql_is_undefined_func(Oid func_oid); +extern void gsplsql_build_gs_variable_dependency(List* var_name); +extern DependenciesDatum* gsplsql_make_depend_datum_by_type_oid(const Oid typOid, bool* depend_undefined); +extern void free_gs_depend_obj_desc(GsDependObjDesc* obj_desc); +extern Oid gsplsql_get_pkg_oid_by_func_oid(Oid func_oid); +extern Oid get_compiled_object_nspoid(); +extern bool gsplsql_build_gs_type_dependency(GsDependParamBody* gsdependParamBody, const ObjectAddress* referenced); +extern bool gsplsql_undefine_in_same_pkg(GsDependObjDesc* obj_desc, Oid undefObjOid); +extern Oid gsplsql_try_build_exist_pkg_undef_var(List* dtnames); +extern Oid gsplsql_try_build_exist_schema_undef_table(RangeVar* rel_var); +extern Oid gsplsql_flush_undef_ref_depend_obj(const GsDependObjDesc* object); +extern Oid gsplsql_flush_undef_ref_type_dependency(Oid type_oid); +extern bool gsplsql_need_build_gs_dependency(GsDependParamBody* gsdependParamBody, const ObjectAddress* referenced, bool is_pinned); +extern void gsplsql_init_gs_depend_param_body(GsDependParamBody* param_body); +extern void gsplsql_get_depend_obj_by_typ_id(GsDependObjDesc* ref_obj, Oid typ_oid, + Oid pkg_oid, bool drop_typ = false); +extern bool gsplsql_exist_dependency(GsDependObjDesc* obj_desc); +extern bool gsplsql_is_object_depend(Oid oid, GsDependObjectType type); +extern bool gsplsql_build_gs_type_in_body_dependency(PLpgSQL_type* type); +/* + * basic interface + */ +extern DependenciesDatum* gsplsql_make_depend_datum_from_plsql_datum(const PLpgSQL_datum *datum, char** schema_name, + bool* depend_undefined); +extern bool gsplsql_check_type_depend_undefined(const char* schemaName, const char* pkg_name, + const char* typname, bool isDeleteType = false); +extern TupleDesc build_gs_depend_expr(PLpgSQL_expr* expr, PLpgSQL_function* func, bool need_tupdesc = false); +extern bool gsplsql_build_gs_dependency(const GsDependObjDesc* obj_desc, const GsDependObjDesc* ref_obj_desc, + const DependenciesDatum* ref_obj_ast); +extern bool gsplsql_build_gs_dependency(const GsDependObjDesc* obj_desc, const Oid ref_obj_oid); +extern Oid gsplsql_update_object_ast(const GsDependObjDesc* object, const DependenciesDatum* ref_obj_ast); +extern bool gsplsql_build_ref_dependency(Oid nsp_oid, const PLpgSQL_datum* ref_datum, const char* pkg_name = NULL, + List** ref_obj_oids = NULL, Oid curr_compile_oid = InvalidOid); +extern bool gsplsql_build_ref_dependency(const GsDependObjDesc* ref_obj_desc, const DependenciesDatum* ref_obj_ast, + List** ref_obj_oids = NULL, Oid curr_compile_oid = InvalidOid); +extern Oid gsplsql_insert_dependencies_object(const GsDependObjDesc *object, char *obj_ast_str); +extern bool gsplsql_set_pkg_func_status(Oid schema_oid, Oid pkg_oid, bool status); +extern void gsplsql_remove_dependencies_object(const GsDependObjDesc* ref_obj_desc); +extern bool gsplsql_remove_gs_dependency(const GsDependObjDesc* ref_obj_desc); +extern bool gsplsql_remove_ref_dependency(const GsDependObjDesc* ref_obj_desc); +extern bool gsplsql_build_ref_type_dependency(Oid typ_oid); +extern List* gsplsql_prepare_recompile_func(Oid func_oid, Oid schema_oid, Oid pkg_oid, bool is_recompile); +extern void gsplsql_complete_recompile_func(List* list); +extern Oid gsplsql_parse_pkg_var_obj4(GsDependObjDesc* obj, List* var_name); +/* + * internal interface + */ +extern void gsplsql_remove_depend_obj_by_specified_oid(Oid ref_obj_oid, Oid curr_compile_oid = InvalidOid, bool is_same_pkg = false); +extern GsDependObjDesc gsplsql_construct_func_head_obj(Oid procOid, Oid procNamespace, Oid proPackageId); +extern char* gsplsql_do_refresh_proc_header(const GsDependObjDesc* obj, bool* is_undefined = NULL); +extern List* gsplsql_delete_objs(Relation relation, const GsDependObjDesc* obj_desc); +extern List* gsplsql_get_depend_obj_list_by_specified_pkg(const char* schema_name, const char* package_name, + GsDependObjectType type); +extern void gsplsql_make_desc_from_gs_dependencies_tuple(HeapTuple gs_depend_tuple, TupleDesc tup_desc, + GsDependObjDesc *obj_desc); +extern void gsplsql_remove_depend_obj_by_specified_oid(Oid ref_obj_oid, Oid curr_compile_oid, bool is_same_pkg); +extern void gsplsql_delete_unrefer_depend_obj_in_list(List* ref_obj_oid_list, bool skip_in_use); +extern List *gsplsql_search_gs_depend_rel_by_oid(Relation relation, Oid ref_obj_oid); +extern void gsplsql_invalidate_objs(Oid oid, bool is_ref_remove, Oid curr_compile_oid); +extern void gsplsql_build_gs_var_dependency(Param* param); +extern void gsplsql_build_gs_synonym_dependency(Oid refSynOid); +extern void gsplsql_build_gs_table_dependency(Oid relid); +extern Oid gsplsql_get_proc_oid(const char* schemaName, const char* packageName, const char* name); +extern Oid gsplsql_get_proc_oid(const char* schemaName, const char* packageName, const char* name, + const char* proc_arg_src); +extern Datum gsplsql_get_depend_object_attr(HeapTuple tup, int attr_number, bool *is_null); +extern void gsplsql_construct_non_empty_obj(const GsDependObjDesc* object, Name schema_name_data, + Name pkg_name_data, StringInfo object_name_data); +extern void gsplsql_build_gs_func_dependency(Oid func_oid); +extern void gsplsql_build_gs_func_dependency(List* func_name_list, FuncCandidateList func_candidate_list); +extern GsDependObjDesc gsplsql_parse_func_name_to_obj_desc(List *funcNameList, Oid namespaceOid); +extern void gsplsql_complete_gs_depend_for_pkg_compile(PLpgSQL_package* pkg, bool isCreate, bool isRecompile); +extern void gsplsql_prepare_gs_depend_for_pkg_compile(PLpgSQL_package* pkg, bool isCreate); +extern void gsplsql_init_gs_depend_obj_desc(GsDependObjDesc* object); +extern HeapTuple gsplsql_search_object(const GsDependObjDesc* object, bool supp_undef_type); +extern bool gsplsql_parse_type_and_name_from_gsplsql_datum(const PLpgSQL_datum* datum, char** datum_name, + GsDependObjectType* datum_type); +extern HeapTuple gsplsql_search_object_by_name(const char* schema_name, const char* package_name, + const char* object_name, GsDependObjectType type); +extern GsDependObjDesc get_func_gs_depend_obj_desc(Oid func_oid); +extern void gsplsql_delete_unrefer_depend_obj_oid(Oid ref_obj_oid, bool skip_in_use); +extern bool gsplsql_check_type_depend_ast_equal(Relation obj_rel, Oid obj_oid, const char* equal_ast); +extern bool gsplsql_search_depend_obj_by_oid(Oid oid, GsDependObjDesc* obj_desc); +extern void gsplsql_remove_type_gs_dependency(const GsDependObjDesc* obj_desc); + +#endif /* GS_DEPENDENCIES_FN_H */ diff --git a/src/include/catalog/gs_dependencies_obj.h b/src/include/catalog/gs_dependencies_obj.h new file mode 100644 index 000000000..4426d425a --- /dev/null +++ b/src/include/catalog/gs_dependencies_obj.h @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2021 Huawei Technologies Co.,Ltd. +* +* openGauss is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +* --------------------------------------------------------------------------------------- +* +* gs_dependencies_fn.h +* Definition about dependencies object. +* +* +* IDENTIFICATION +* src/include/catalog/gs_dependencies_obj.h +* +* --------------------------------------------------------------------------------------- +*/ +#ifndef GS_DEPENDENCIES_OBJ_H +#define GS_DEPENDENCIES_OBJ_H + +#include "catalog/genbki.h" + +#define DependenciesObjRelationId 7169 +#define DependenciesObjRelationId_Rowtype_Id 7170 + +CATALOG(gs_dependencies_obj,7169) BKI_SCHEMA_MACRO +{ + NameData schemaname; + NameData packagename; + int4 type; +#ifdef CATALOG_VARLEN + text name; + pg_node_tree objnode; +#endif +} FormData_gs_dependencies_obj; + +typedef FormData_gs_dependencies_obj *Form_gs_dependencies_obj; + +#define Natts_gs_dependencies_obj 5 +#define Anum_gs_dependencies_obj_schemaname 1 +#define Anum_gs_dependencies_obj_packagename 2 +#define Anum_gs_dependencies_obj_type 3 +#define Anum_gs_dependencies_obj_name 4 +#define Anum_gs_dependencies_obj_objnode 5 +#endif \ No newline at end of file diff --git a/src/include/catalog/gs_package.h b/src/include/catalog/gs_package.h index 94b94c6bc..3b481d52f 100644 --- a/src/include/catalog/gs_package.h +++ b/src/include/catalog/gs_package.h @@ -43,11 +43,12 @@ #define PackageRelation_Rowtype_Id 9745 extern Oid PackageNameGetOid(const char* pkgname, Oid namespaceId = InvalidOid); extern PLpgSQL_package* PackageInstantiation(Oid packageOid); -extern void PackageInit(PLpgSQL_package* pkg, bool isCreate=false); +extern void PackageInit(PLpgSQL_package* pkg, bool isCreate=false, bool isSpec = false, + bool isNeedCompileFunc = true); extern Oid SysynonymPkgNameGetOid(const char* pkgname, Oid namespaceId); extern Oid saveCallFromPkgOid(Oid pkgOid); extern void restoreCallFromPkgOid(Oid pkgOid); -extern NameData* GetPackageName(Oid packageOid); +extern char* GetPackageName(Oid packageOid); extern Oid PackageNameListGetOid(List* pkgnameList, bool missing_ok=false, bool isPkgBody = false); extern Oid GetPackageNamespace(Oid packageOid); extern bool IsExistPackageName(const char* pkgname); diff --git a/src/include/catalog/gs_package_fn.h b/src/include/catalog/gs_package_fn.h index 59fb47172..bc0aa8ebd 100644 --- a/src/include/catalog/gs_package_fn.h +++ b/src/include/catalog/gs_package_fn.h @@ -34,7 +34,7 @@ extern Oid PackageBodyCreate(Oid pkgNamespace, const char* pkgName, const Oid ow extern bool IsFunctionInPackage(List* wholename); extern PLpgSQL_package* PackageInstantiation(Oid packageOid); extern void PackageInit(PLpgSQL_package* pkg, bool isCreate); -extern NameData* GetPackageName(Oid packageOid); +extern char* GetPackageName(Oid packageOid); extern Oid PackageNameListGetOid(List* pkgnameList, bool missing_ok); extern Oid PackageNameGetOid(const char* pkgname, Oid namespaceId); extern bool IsExistPackageName(const char* pkgname); diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h index f2bd42173..55f4c9c65 100644 --- a/src/include/catalog/heap.h +++ b/src/include/catalog/heap.h @@ -135,7 +135,8 @@ extern Oid heap_create_with_catalog(const char *relname, List* ceLst = NULL, StorageType storage_type = HEAP_DISK, LOCKMODE partLockMode = AccessExclusiveLock, - ObjectAddress *typaddress= NULL); + ObjectAddress *typaddress= NULL, + List* depend_extend = NIL); extern void heap_create_init_fork(Relation rel); @@ -261,4 +262,5 @@ extern int GetIndexKeyAttsByTuple(Relation relation, HeapTuple indexTuple); extern bool GetIndexVisibleStateByTuple(HeapTuple indexTuple); extern void AddOrDropUidsAttr(Oid relOid, bool oldRelHasUids, bool newRelHasUids); +extern char* heap_serialize_row_attr(Oid rel_oid, bool* depend_undefined); #endif /* HEAP_H */ diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h index ec233c0a8..679453fb0 100644 --- a/src/include/catalog/indexing.h +++ b/src/include/catalog/indexing.h @@ -254,6 +254,18 @@ DECLARE_UNIQUE_INDEX(gs_package_oid_index, 9993, on gs_package using btree(oid o DECLARE_UNIQUE_INDEX(gs_package_name_index, 9736, on gs_package using btree(pkgname name_ops, pkgnamespace oid_ops)); #define PackageNameIndexId 9736 +DECLARE_INDEX(gs_dependencies_name_index, 8004, on gs_dependencies using btree(schemaname name_ops, packagename name_ops, refobjpos int4_ops)); +#define DependenciesNameIndexId 8004 + +DECLARE_INDEX(gs_dependencies_refoid_index, 8006, on gs_dependencies using btree(refobjoid oid_ops)); +#define DependenciesRefOidIndexId 8006 + +DECLARE_UNIQUE_INDEX(gs_dependencies_obj_oid_index, 8007, on gs_dependencies_obj using btree(oid oid_ops)); +#define DependenciesObjOidIndexId 8007 + +DECLARE_INDEX(gs_dependencies_obj_name_index, 8008, on gs_dependencies_obj using btree(schemaname name_ops, packagename name_ops, type int4_ops)); +#define DependenciesObjNameIndexId 8008 + /* This following index is not used for a cache and is not unique */ DECLARE_INDEX(pg_shdepend_depender_index, 1232, on pg_shdepend using btree(dbid oid_ops, classid oid_ops, objid oid_ops, objsubid int4_ops)); #define SharedDependDependerIndexId 1232 diff --git a/src/include/catalog/objectaddress.h b/src/include/catalog/objectaddress.h index e023a16e8..6d79b2d26 100644 --- a/src/include/catalog/objectaddress.h +++ b/src/include/catalog/objectaddress.h @@ -95,5 +95,6 @@ extern int read_objtype_from_string(const char *objtype); extern char *getObjectIdentityParts(const ObjectAddress *address, List **objname, List **objargs); extern ArrayType *strlist_to_textarray(List *list); +extern Oid get_object_package(const ObjectAddress* address); #endif /* PARSE_OBJECT_H */ diff --git a/src/include/catalog/pg_enum.h b/src/include/catalog/pg_enum.h index d692ff0b6..48954e588 100644 --- a/src/include/catalog/pg_enum.h +++ b/src/include/catalog/pg_enum.h @@ -69,6 +69,6 @@ extern void AddEnumLabel(Oid enumTypeOid, const char *newVal, const char *neighbor, bool newValIsAfter, bool skipIfExists); extern void RenameEnumLabel(Oid enumTypeOid, const char *oldVal, const char *newVal); - +extern char* SerializeEnumAttr(Oid enumTypeOid); #endif /* PG_ENUM_H */ diff --git a/src/include/catalog/pg_object.h b/src/include/catalog/pg_object.h index 18b929529..69500464c 100644 --- a/src/include/catalog/pg_object.h +++ b/src/include/catalog/pg_object.h @@ -60,6 +60,7 @@ CATALOG(pg_object,9025) BKI_WITHOUT_OIDS BKI_SCHEMA_MACRO timestamptz mtime; /* When modify the object. */ int8 createcsn; /* When create relation */ int8 changecsn; /* When modify the table structure or store properties */ + bool valid; /* Is valid? */ } FormData_pg_object; #ifdef new_timestamptz @@ -78,7 +79,7 @@ typedef FormData_pg_object* Form_pg_object; * compiler constants for pg_object *------------------------------------------------------------------------- */ -#define Natts_pg_object 7 +#define Natts_pg_object 8 #define Anum_pg_object_oid 1 #define Anum_pg_object_type 2 #define Anum_pg_object_creator 3 @@ -86,6 +87,7 @@ typedef FormData_pg_object* Form_pg_object; #define Anum_pg_object_mtime 5 #define Anum_pg_object_createcsn 6 #define Anum_pg_object_changecsn 7 +#define Anum_pg_object_valid 8 #define PgObjectType char @@ -103,7 +105,13 @@ typedef FormData_pg_object* Form_pg_object; #define OBJECT_TYPE_PKGSPEC 'S' #define OBJECT_TYPE_PKGBODY 'B' -extern void CreatePgObject(Oid objectOid, PgObjectType objectType, Oid creator, const PgObjectOption objectOpt); +extern bool GetPgObjectValid(Oid oid, PgObjectType objectType); +extern bool SetPgObjectValid(Oid oid, PgObjectType objectType, bool valid); +extern bool GetCurrCompilePgObjStatus(); +extern void SetCurrCompilePgObjStatus(bool status); +extern void UpdateCurrCompilePgObjStatus(bool status); +extern void InvalidateCurrCompilePgObj(); +extern void CreatePgObject(Oid objectOid, PgObjectType objectType, Oid creator, const PgObjectOption objectOpt, bool isValid = true); extern void DeletePgObject(Oid objectOid, PgObjectType objectType); extern void GetObjectCSN(Oid objectOid, Relation userRel, PgObjectType objectType, ObjectCSN * const csnInfo); void UpdatePgObjectMtime(Oid objectOid, PgObjectType objectType); diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 344940d82..11c80cf16 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -432,6 +432,10 @@ typedef FormData_pg_proc *Form_pg_proc; #define GROUPCONCATFUNCOID 4097 #define CURSORTOXMLOID 2925 #define CURSORTOXMLSCHEMAOID 2928 +#define UNDEFINEDINPUT 5704 +#define UNDEFINEDOUTPUT 5707 +#define UNDEFINEDSEND 5709 +#define UNDEFINEDRECV 5710 /* * Symbolic values for prokind column diff --git a/src/include/catalog/pg_proc.h_for_llt b/src/include/catalog/pg_proc.h_for_llt index 449ca7e38..5a60c6c51 100755 --- a/src/include/catalog/pg_proc.h_for_llt +++ b/src/include/catalog/pg_proc.h_for_llt @@ -5784,7 +5784,14 @@ DATA(insert OID = 4208 ( get_db_source_datasize PGNSP PGUID 12 1 0 0 0 f f f f t DESCR("total source datasize for the current database"); DATA(insert OID = 4209 ( pg_clean_region_info PGNSP PGUID 12 1 0 0 0 f f f f t f s 0 0 1043 "" _null_ _null_ _null_ _null_ pg_clean_region_info _null_ _null_ _null_ "" f)); DESCR("clean region map information cache for the current database"); - +DATA(insert OID = 5704 ( undefinedin PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 4408 "2275" _null_ _null_ _null_ _null_ undefinedin _null_ _null_ _null_ "" f)); +DESCR("I/O"); +DATA(insert OID = 5707 ( undefinedout PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2275 "4408" _null_ _null_ _null_ _null_ undefinedout _null_ _null_ _null_ "" f)); +DESCR("I/O"); +DATA(insert OID = 5710 ( undefinedrecv PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 4408 "2281" _null_ _null_ _null_ _null_ undefinedrecv _null_ _null_ _null_ "" f)); +DESCR("I/O"); +DATA(insert OID = 5709 ( undefinedsend PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 17 "4408" _null_ _null_ _null_ _null_ undefinedsend _null_ _null_ _null_ "" f)); +DESCR("I/O"); /* * Symbolic values for provolatile column: these indicate whether the result * of a function is dependent *only* on the values of its explicit arguments, diff --git a/src/include/catalog/pg_proc_fn.h b/src/include/catalog/pg_proc_fn.h index b53c1b62a..18929c337 100644 --- a/src/include/catalog/pg_proc_fn.h +++ b/src/include/catalog/pg_proc_fn.h @@ -49,7 +49,11 @@ extern ObjectAddress ProcedureCreate(const char *procedureName, bool package, bool proIsProcedure, const char *proargsrc, - bool isPrivate = false); + bool isPrivate = false, + TypeDependExtend* paramTypDependExt = NULL, + TypeDependExtend* retTypDependExt = NULL, + CreateFunctionStmt* stmt = NULL + ); extern bool function_parse_error_transpose(const char *prosrc); diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h index c14a37c6b..4eb0a3e03 100644 --- a/src/include/catalog/pg_type.h +++ b/src/include/catalog/pg_type.h @@ -817,9 +817,14 @@ DATA(insert OID = 5729 ( pg_ddl_command PGNSP PGUID SIZEOF_POINTER t p P f #define PGDDLCOMMANDOID 5729 DATA(insert OID = 3272 ( anyset PGNSP PGUID -1 f s H t t \054 0 0 0 anyset_in anyset_out - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); #define ANYSETOID 3272 + +DATA(insert OID = 4408 ( undefined PGNSP PGUID -2 f u W f t \054 0 0 0 undefinedin undefinedout undefinedrecv undefinedsend - - - c p f 0 -1 0 0 _null_ _null_ _null_ )); +DESCR("undefined objects as PLSQL compilation time"); +#define UNDEFINEDOID 4408 /* * macros */ +#define TYPTYPE_INVALID '\0' /* not an allowed type */ #define TYPTYPE_BASE 'b' /* base type (ordinary scalar type) */ #define TYPTYPE_COMPOSITE 'c' /* composite (e.g., table's rowtype) */ #define TYPTYPE_DOMAIN 'd' /* domain over another type */ @@ -828,6 +833,7 @@ DATA(insert OID = 3272 ( anyset PGNSP PGUID -1 f s H t t \054 0 0 0 anyset_in #define TYPTYPE_RANGE 'r' /* range type */ #define TYPTYPE_TABLEOF 'o' /* table of type */ #define TYPTYPE_SET 's' /* set type */ +#define TYPTYPE_UNDEFINE 'u' /* undefine type */ #define TYPCATEGORY_INVALID '\0' /* not an allowed category */ #define TYPCATEGORY_ARRAY 'A' diff --git a/src/include/catalog/pg_type_fn.h b/src/include/catalog/pg_type_fn.h index 9f24a28ad..421d5eadb 100644 --- a/src/include/catalog/pg_type_fn.h +++ b/src/include/catalog/pg_type_fn.h @@ -52,7 +52,8 @@ extern ObjectAddress TypeCreate(Oid newTypeOid, int32 typeMod, int32 typNDims, bool typeNotNull, - Oid typeCollation); + Oid typeCollation, + TypeDependExtend* dependExtend = NULL); extern void GenerateTypeDependencies(Oid typeNamespace, Oid typeObjectId, @@ -71,7 +72,9 @@ extern void GenerateTypeDependencies(Oid typeNamespace, Oid baseType, Oid typeCollation, Node *defaultExpr, - bool rebuild); + bool rebuild, + const char* typname = NULL, + TypeDependExtend* dependExtend = NULL); extern void RenameTypeInternal(Oid typeOid, const char *newTypeName, @@ -82,6 +85,12 @@ extern char *makeArrayTypeName(const char *typname, Oid typeNamespace); extern bool moveArrayTypeName(Oid typeOid, const char *typname, Oid typeNamespace); - +extern void InstanceTypeNameDependExtend(TypeDependExtend** dependExtend); +extern void ReleaseTypeNameDependExtend(TypeDependExtend** dependExtend); +extern char* MakeTypeNamesStrForTypeOid(Oid typOid, bool* dependUndefined = NULL, StringInfo concatName = NULL); +extern void MakeTypeNamesStrForTypeOid(StringInfo concatName, Oid typOid, + char** schemaName = NULL, char** pkgName = NULL, char** name = NULL); +extern Oid GetTypePackageOid(Oid typoid); +extern Oid TypeNameGetOid(const char* schemaName, const char* packageName, const char* typeName); #endif /* PG_TYPE_FN_H */ diff --git a/src/include/catalog/upgrade_sql/rollback_catalog_maindb/rollback-post_catalog_maindb_92_916.sql b/src/include/catalog/upgrade_sql/rollback_catalog_maindb/rollback-post_catalog_maindb_92_916.sql new file mode 100644 index 000000000..95716d9be --- /dev/null +++ b/src/include/catalog/upgrade_sql/rollback_catalog_maindb/rollback-post_catalog_maindb_92_916.sql @@ -0,0 +1,19 @@ +DROP INDEX IF EXISTS pg_catalog.gs_dependencies_name_index; +DROP INDEX IF EXISTS pg_catalog.gs_dependencies_refoid_index; +DROP INDEX IF EXISTS pg_catalog.gs_dependencies_obj_oid_index; +DROP INDEX IF EXISTS pg_catalog.gs_dependencies_obj_name_index; +DROP TABLE IF EXISTS pg_catalog.gs_dependencies; +DROP TABLE IF EXISTS pg_catalog.gs_dependencies_obj; + +DECLARE + cnt int; +BEGIN + select count(*) into cnt from pg_type where oid = 4408; + if cnt = 1 then + DROP FUNCTION IF EXISTS pg_catalog.undefinedin(cstring) CASCADE; + DROP FUNCTION IF EXISTS pg_catalog.undefinedout(undefined) CASCADE; + DROP FUNCTION IF EXISTS pg_catalog.undefinedrecv(internal) CASCADE; + DROP FUNCTION IF EXISTS pg_catalog.undefinedsend(undefined) CASCADE; + end if; +END; +DROP TYPE IF EXISTS pg_catalog.undefined CASCADE; \ No newline at end of file diff --git a/src/include/catalog/upgrade_sql/rollback_catalog_otherdb/rollback-post_catalog_otherdb_92_916.sql b/src/include/catalog/upgrade_sql/rollback_catalog_otherdb/rollback-post_catalog_otherdb_92_916.sql new file mode 100644 index 000000000..95716d9be --- /dev/null +++ b/src/include/catalog/upgrade_sql/rollback_catalog_otherdb/rollback-post_catalog_otherdb_92_916.sql @@ -0,0 +1,19 @@ +DROP INDEX IF EXISTS pg_catalog.gs_dependencies_name_index; +DROP INDEX IF EXISTS pg_catalog.gs_dependencies_refoid_index; +DROP INDEX IF EXISTS pg_catalog.gs_dependencies_obj_oid_index; +DROP INDEX IF EXISTS pg_catalog.gs_dependencies_obj_name_index; +DROP TABLE IF EXISTS pg_catalog.gs_dependencies; +DROP TABLE IF EXISTS pg_catalog.gs_dependencies_obj; + +DECLARE + cnt int; +BEGIN + select count(*) into cnt from pg_type where oid = 4408; + if cnt = 1 then + DROP FUNCTION IF EXISTS pg_catalog.undefinedin(cstring) CASCADE; + DROP FUNCTION IF EXISTS pg_catalog.undefinedout(undefined) CASCADE; + DROP FUNCTION IF EXISTS pg_catalog.undefinedrecv(internal) CASCADE; + DROP FUNCTION IF EXISTS pg_catalog.undefinedsend(undefined) CASCADE; + end if; +END; +DROP TYPE IF EXISTS pg_catalog.undefined CASCADE; \ No newline at end of file diff --git a/src/include/catalog/upgrade_sql/upgrade_catalog_maindb/upgrade-post_catalog_maindb_92_916.sql b/src/include/catalog/upgrade_sql/upgrade_catalog_maindb/upgrade-post_catalog_maindb_92_916.sql new file mode 100644 index 000000000..c1b980a8d --- /dev/null +++ b/src/include/catalog/upgrade_sql/upgrade_catalog_maindb/upgrade-post_catalog_maindb_92_916.sql @@ -0,0 +1,79 @@ +declare + dependencies_exist int:=0; + dependencies_obj_exist int:=0; +begin + select count(*) into dependencies_exist from pg_catalog.pg_class where oid = 7111; + if dependencies_exist = 0 then + SET LOCAL inplace_upgrade_next_system_object_oids = IUO_CATALOG, false, true, 7111, 7112, 0, 0; + DROP INDEX IF EXISTS pg_catalog.gs_dependencies_name_index; + DROP INDEX IF EXISTS pg_catalog.gs_dependencies_refoid_index; + DROP TYPE IF EXISTS pg_catalog.gs_dependencies; + CREATE TABLE IF NOT EXISTS pg_catalog.gs_dependencies( + schemaname name NOCOMPRESS NOT NULL, + packagename name NOCOMPRESS NOT NULL, + refobjpos int NOT NULL, + refobjoid oid NOT NULL, + objectname text + ); + SET LOCAL inplace_upgrade_next_system_object_oids = IUO_CATALOG, false, true, 0, 0, 0, 8004; + CREATE INDEX pg_catalog.gs_dependencies_name_index ON pg_catalog.gs_dependencies USING BTREE(schemaname name_ops, packagename name_ops, refobjpos int4_ops); + SET LOCAL inplace_upgrade_next_system_object_oids = IUO_CATALOG, false, true, 0, 0, 0, 8006; + CREATE INDEX pg_catalog.gs_dependencies_refoid_index ON pg_catalog.gs_dependencies USING BTREE(refobjoid oid_ops); + GRANT SELECT ON TABLE pg_catalog.gs_dependencies TO PUBLIC; + end if; + select count(*) into dependencies_obj_exist from pg_catalog.pg_class where oid = 7169; + if dependencies_obj_exist = 0 then + DROP INDEX IF EXISTS pg_catalog.gs_dependencies_obj_oid_index; + DROP INDEX IF EXISTS pg_catalog.gs_dependencies_obj_name_index; + SET LOCAL inplace_upgrade_next_system_object_oids = IUO_CATALOG, false, true, 7169, 7170, 0, 0; + DROP TYPE IF EXISTS pg_catalog.gs_dependencies_obj; + CREATE TABLE IF NOT EXISTS pg_catalog.gs_dependencies_obj( + schemaname name NOCOMPRESS NOT NULL, + packagename name NOCOMPRESS NOT NULL, + type int, + name text, + objnode pg_node_tree + ) WITH OIDS; + SET LOCAL inplace_upgrade_next_system_object_oids = IUO_CATALOG, false, true, 0, 0, 0, 8007; + CREATE UNIQUE INDEX pg_catalog.gs_dependencies_obj_oid_index ON pg_catalog.gs_dependencies_obj USING BTREE(oid oid_ops); + SET LOCAL inplace_upgrade_next_system_object_oids = IUO_CATALOG, false, true, 0, 0, 0, 8008; + CREATE INDEX pg_catalog.gs_dependencies_obj_name_index ON pg_catalog.gs_dependencies_obj USING BTREE(schemaname name_ops, packagename name_ops, type int4_ops); + GRANT SELECT ON TABLE pg_catalog.gs_dependencies_obj TO PUBLIC; + end if; +end; +/ + +DROP TYPE IF EXISTS pg_catalog.undefined; +SET LOCAL inplace_upgrade_next_system_object_oids = IUO_TYPE, 4408, 0, u; +CREATE TYPE pg_catalog.undefined; + +DROP FUNCTION IF EXISTS pg_catalog.undefinedin(cstring) CASCADE; +SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 5704; +CREATE FUNCTION pg_catalog.undefinedin(cstring) RETURNS undefined LANGUAGE INTERNAL IMMUTABLE STRICT as 'undefinedin'; + +DROP FUNCTION IF EXISTS pg_catalog.undefinedout(undefined) CASCADE; +SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 5707; +CREATE FUNCTION pg_catalog.undefinedout(undefined) RETURNS cstring LANGUAGE INTERNAL IMMUTABLE STRICT as 'undefinedout'; + +DROP FUNCTION IF EXISTS pg_catalog.undefinedrecv(internal) CASCADE; +SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 5710; +CREATE FUNCTION pg_catalog.undefinedrecv(internal) RETURNS undefined LANGUAGE INTERNAL IMMUTABLE STRICT as 'undefinedrecv'; + +DROP FUNCTION IF EXISTS pg_catalog.undefinedsend(undefined) CASCADE; +SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 5709; +CREATE FUNCTION pg_catalog.undefinedsend(undefined) RETURNS bytea LANGUAGE INTERNAL IMMUTABLE STRICT as 'undefinedsend'; +SET LOCAL inplace_upgrade_next_system_object_oids = IUO_CATALOG, false, true, 0, 0, 0, 0; + +CREATE TYPE pg_catalog.undefined( + INPUT=undefinedin, + OUTPUT=undefinedout, + RECEIVE=undefinedrecv, + SEND=undefinedsend, + PASSEDBYVALUE=false, + INTERNALLENGTH=-2, + CATEGORY='W', + PREFERRED=false, + ALIGNMENT=char, + STORAGE=plain +); +COMMENT ON TYPE pg_catalog.undefined IS 'undefined objects at PLSQL compilation time'; diff --git a/src/include/catalog/upgrade_sql/upgrade_catalog_otherdb/upgrade-post_catalog_otherdb_92_916.sql b/src/include/catalog/upgrade_sql/upgrade_catalog_otherdb/upgrade-post_catalog_otherdb_92_916.sql new file mode 100644 index 000000000..c1b980a8d --- /dev/null +++ b/src/include/catalog/upgrade_sql/upgrade_catalog_otherdb/upgrade-post_catalog_otherdb_92_916.sql @@ -0,0 +1,79 @@ +declare + dependencies_exist int:=0; + dependencies_obj_exist int:=0; +begin + select count(*) into dependencies_exist from pg_catalog.pg_class where oid = 7111; + if dependencies_exist = 0 then + SET LOCAL inplace_upgrade_next_system_object_oids = IUO_CATALOG, false, true, 7111, 7112, 0, 0; + DROP INDEX IF EXISTS pg_catalog.gs_dependencies_name_index; + DROP INDEX IF EXISTS pg_catalog.gs_dependencies_refoid_index; + DROP TYPE IF EXISTS pg_catalog.gs_dependencies; + CREATE TABLE IF NOT EXISTS pg_catalog.gs_dependencies( + schemaname name NOCOMPRESS NOT NULL, + packagename name NOCOMPRESS NOT NULL, + refobjpos int NOT NULL, + refobjoid oid NOT NULL, + objectname text + ); + SET LOCAL inplace_upgrade_next_system_object_oids = IUO_CATALOG, false, true, 0, 0, 0, 8004; + CREATE INDEX pg_catalog.gs_dependencies_name_index ON pg_catalog.gs_dependencies USING BTREE(schemaname name_ops, packagename name_ops, refobjpos int4_ops); + SET LOCAL inplace_upgrade_next_system_object_oids = IUO_CATALOG, false, true, 0, 0, 0, 8006; + CREATE INDEX pg_catalog.gs_dependencies_refoid_index ON pg_catalog.gs_dependencies USING BTREE(refobjoid oid_ops); + GRANT SELECT ON TABLE pg_catalog.gs_dependencies TO PUBLIC; + end if; + select count(*) into dependencies_obj_exist from pg_catalog.pg_class where oid = 7169; + if dependencies_obj_exist = 0 then + DROP INDEX IF EXISTS pg_catalog.gs_dependencies_obj_oid_index; + DROP INDEX IF EXISTS pg_catalog.gs_dependencies_obj_name_index; + SET LOCAL inplace_upgrade_next_system_object_oids = IUO_CATALOG, false, true, 7169, 7170, 0, 0; + DROP TYPE IF EXISTS pg_catalog.gs_dependencies_obj; + CREATE TABLE IF NOT EXISTS pg_catalog.gs_dependencies_obj( + schemaname name NOCOMPRESS NOT NULL, + packagename name NOCOMPRESS NOT NULL, + type int, + name text, + objnode pg_node_tree + ) WITH OIDS; + SET LOCAL inplace_upgrade_next_system_object_oids = IUO_CATALOG, false, true, 0, 0, 0, 8007; + CREATE UNIQUE INDEX pg_catalog.gs_dependencies_obj_oid_index ON pg_catalog.gs_dependencies_obj USING BTREE(oid oid_ops); + SET LOCAL inplace_upgrade_next_system_object_oids = IUO_CATALOG, false, true, 0, 0, 0, 8008; + CREATE INDEX pg_catalog.gs_dependencies_obj_name_index ON pg_catalog.gs_dependencies_obj USING BTREE(schemaname name_ops, packagename name_ops, type int4_ops); + GRANT SELECT ON TABLE pg_catalog.gs_dependencies_obj TO PUBLIC; + end if; +end; +/ + +DROP TYPE IF EXISTS pg_catalog.undefined; +SET LOCAL inplace_upgrade_next_system_object_oids = IUO_TYPE, 4408, 0, u; +CREATE TYPE pg_catalog.undefined; + +DROP FUNCTION IF EXISTS pg_catalog.undefinedin(cstring) CASCADE; +SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 5704; +CREATE FUNCTION pg_catalog.undefinedin(cstring) RETURNS undefined LANGUAGE INTERNAL IMMUTABLE STRICT as 'undefinedin'; + +DROP FUNCTION IF EXISTS pg_catalog.undefinedout(undefined) CASCADE; +SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 5707; +CREATE FUNCTION pg_catalog.undefinedout(undefined) RETURNS cstring LANGUAGE INTERNAL IMMUTABLE STRICT as 'undefinedout'; + +DROP FUNCTION IF EXISTS pg_catalog.undefinedrecv(internal) CASCADE; +SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 5710; +CREATE FUNCTION pg_catalog.undefinedrecv(internal) RETURNS undefined LANGUAGE INTERNAL IMMUTABLE STRICT as 'undefinedrecv'; + +DROP FUNCTION IF EXISTS pg_catalog.undefinedsend(undefined) CASCADE; +SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 5709; +CREATE FUNCTION pg_catalog.undefinedsend(undefined) RETURNS bytea LANGUAGE INTERNAL IMMUTABLE STRICT as 'undefinedsend'; +SET LOCAL inplace_upgrade_next_system_object_oids = IUO_CATALOG, false, true, 0, 0, 0, 0; + +CREATE TYPE pg_catalog.undefined( + INPUT=undefinedin, + OUTPUT=undefinedout, + RECEIVE=undefinedrecv, + SEND=undefinedsend, + PASSEDBYVALUE=false, + INTERNALLENGTH=-2, + CATEGORY='W', + PREFERRED=false, + ALIGNMENT=char, + STORAGE=plain +); +COMMENT ON TYPE pg_catalog.undefined IS 'undefined objects at PLSQL compilation time'; diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h index da016d790..0ab2eca12 100644 --- a/src/include/commands/defrem.h +++ b/src/include/commands/defrem.h @@ -58,6 +58,7 @@ extern void RemoveFunctionById(Oid funcOid); extern void remove_encrypted_proc_by_id(Oid funcOid); extern void RemovePackageById(Oid pkgOid, bool isBody = false); extern void DeleteFunctionByPackageOid(Oid package_oid); +extern void DeleteFunctionByFuncTuple(HeapTuple func_tup); extern void SetFunctionReturnType(Oid funcOid, Oid newRetType); extern void SetFunctionArgType(Oid funcOid, int argIndex, Oid newArgType); extern ObjectAddress AlterFunctionOwner(List* name, List* argtypes, Oid newOwnerId); @@ -76,6 +77,7 @@ extern void IsThereOpClassInNamespace(const char *opcname, Oid opcmethod, Oid opcnamespace); extern void IsThereOpFamilyInNamespace(const char *opfname, Oid opfmethod, Oid opfnamespace); +extern void RecompileFunction(CompileStmt* stmt); /* commands/operatorcmds.c */ extern void CreatePackageCommand(CreatePackageStmt* parsetree, const char* queryString); @@ -89,6 +91,7 @@ extern ObjectAddress AlterOperatorOwner(List* name, TypeName* typeName1, TypeNam extern void AlterOperatorOwner_oid(Oid operOid, Oid newOwnerId); extern ObjectAddress AlterOperatorNamespace(List* names, List* argtypes, const char* newschema); extern Oid AlterOperatorNamespace_oid(Oid operOid, Oid newNspOid); +extern void RecompilePackage(CompileStmt* stmt); /* commands/aggregatecmds.c */ extern ObjectAddress DefineAggregate(List* name, List* args, bool oldstyle, List* parameters); diff --git a/src/include/knl/knl_session.h b/src/include/knl/knl_session.h index 09e586d42..6cf1f1604 100644 --- a/src/include/knl/knl_session.h +++ b/src/include/knl/knl_session.h @@ -1564,6 +1564,21 @@ typedef struct PLpgSQL_compile_context { MemoryContext compile_cxt; } PLpgSQL_compile_context; +typedef enum CreatePlsqlType { + CREATE_PLSQL_TYPE_START = 0, + CREATE_PLSQL_TYPE_NOT_CHECK_NSPOID = 1, + CREATE_PLSQL_TYPE_RECORD_DEPENDENCE = 2, + CREATE_PLSQL_TYPE_RECOMPILE = 3, + CREATE_PLSQL_TYPE_END = 4 +} CreatePlsqlType; + +typedef enum FunctionStyleType { + FUNCTION_STYLE_TYPE_NONE = 0, + FUNCTION_STYLE_TYPE_PG = 1, + FUNCTION_STYLE_TYPE_A = 2, + FUNCTION_STYLE_TYPE_REFRESH_HEAD = 3 +} FunctionStyleType; + typedef struct knl_u_plpgsql_context { bool inited; @@ -1674,6 +1689,33 @@ typedef struct knl_u_plpgsql_context { char* debug_query_string; bool is_insert_gs_source; /* is doing insert gs_source? */ List* CursorRecordTypeList; /*Save the type recorded during the cursor definition*/ + + // gs depend + bool compile_has_warning_info; + bool expr_can_have_out_func; + bool currCompilingObjStatus; + bool need_create_depend; + bool during_compile; + bool is_pkg_compile; + bool isCreatePkg; + bool isCreatePkgFunction; + bool has_invalid_pkg; + bool has_invalid_func; + bool has_error; + bool is_exec_autonomous; + bool in_package_function_compile; + bool is_alter_compile_stmt; + CreatePlsqlType createPlsqlType; + FunctionStyleType functionStyleType; + List* pkg_var_info; + List* func_compiled_list; + List* needRebuildViews; + List* usindDependObjOids; + Oid curr_object_nspoid; + Oid currRefreshPkgOid; + MemoryContext depend_mem_cxt; /* temp context for build_gs_depend*/ + int compile_check_node_level; + int real_func_num; } knl_u_plpgsql_context; //this is used to define functions in package @@ -3037,6 +3079,18 @@ extern void free_session_context(knl_session_context* session); extern void use_fake_session(); extern bool stp_set_commit_rollback_err_msg(stp_xact_err_type type); extern bool enable_out_param_override(); +extern bool enable_plpgsql_gsdependency_guc(); +extern bool enable_plpgsql_gsdependency(); +extern bool enable_plpgsql_undefined(); +extern bool enable_plpgsql_undefined_not_check_nspoid(); +extern void set_create_plsql_type_not_check_nsp_oid(); +extern void set_create_plsql_type_start(); +extern void set_create_plsql_type_end(); +extern void set_create_plsql_type(CreatePlsqlType type); +extern void set_function_style_none(); +extern void set_function_style_a(); +extern void set_function_style_pg(); +extern bool set_is_create_plsql_type(); extern THR_LOCAL knl_session_context* u_sess; diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index 538af8477..5de080590 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -37,6 +37,7 @@ /***************************************************************************** * Backend version and inplace upgrade staffs *****************************************************************************/ +extern const uint32 SUPPORT_GS_DEPENDENCY_VERSION_NUM; extern const uint32 TXNSTATUS_CACHE_DFX_VERSION_NUM; extern const uint32 PARAM_MARK_VERSION_NUM; extern const uint32 TIMESCALE_DB_VERSION_NUM; @@ -199,7 +200,8 @@ extern bool contain_backend_version(uint32 version_number); #define OPT_ALLOW_ORDERBY_UNDISTINCT_COLUMN 33554432 #define OPT_SELECT_INTO_RETURN_NULL 67108864 #define OPT_ACCEPT_EMPTY_STR 134217728 -#define OPT_MAX 28 +#define OPT_PLPGSQL_DEPENDENCY 268435456 +#define OPT_MAX 29 #define PLPSQL_OPT_FOR_LOOP 1 #define PLPSQL_OPT_OUTPARAM 2 @@ -241,6 +243,7 @@ extern bool contain_backend_version(uint32 version_number); #define PLSQL_COMPILE_OUTPARAM (u_sess->utils_cxt.plsql_compile_behavior_compat_flags & PLPSQL_OPT_OUTPARAM) #define SELECT_INTO_RETURN_NULL (u_sess->utils_cxt.behavior_compat_flags & OPT_SELECT_INTO_RETURN_NULL) +#define PLPGSQL_DEPENDENCY (u_sess->utils_cxt.behavior_compat_flags & OPT_PLPGSQL_DEPENDENCY) /* define database compatibility Attribute */ typedef struct { diff --git a/src/include/nodes/makefuncs.h b/src/include/nodes/makefuncs.h index b68060aae..57fcc0883 100644 --- a/src/include/nodes/makefuncs.h +++ b/src/include/nodes/makefuncs.h @@ -59,7 +59,7 @@ extern Alias* makeAlias(const char* aliasname, List* colnames); extern RelabelType* makeRelabelType(Expr* arg, Oid rtype, int32 rtypmod, Oid rcollid, CoercionForm rformat); -extern TypeName* makeTypeNameFromOid(Oid typeOid, int32 typmod); +extern TypeName* makeTypeNameFromOid(Oid typeOid, int32 typmod, TypeDependExtend* dependExtend = NULL); extern FuncExpr* makeFuncExpr( Oid funcid, Oid rettype, List* args, Oid funccollid, Oid inputcollid, CoercionForm fformat); diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index 7cb091f06..d0e4ac754 100755 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -469,6 +469,10 @@ typedef enum NodeTag { T_DropEventStmt, T_ShowEventStmt, T_CompileStmt, + T_DependenciesProchead, + T_DependenciesUndefined, + T_DependenciesType, + T_DependenciesVariable, T_DoStmt, T_RenameStmt, T_RuleStmt, diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index ba77f9015..e2a8e1faa 100755 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -1384,6 +1384,21 @@ typedef struct AlterFunctionStmt { List* actions; /* list of DefElem */ } AlterFunctionStmt; +enum CompileEntry { + COMPILE_PROCEDURE, + COMPILE_FUNCTION, + COMPILE_PACKAGE, + COMPILE_PKG_SPECIFICATION, + COMPILE_PKG_BODY +}; + +typedef struct CompileStmt { + NodeTag type; + List* objName; + List* funcArgs; + CompileEntry compileItem; +} CompileStmt; + typedef struct InlineCodeBlock { NodeTag type; char* source_text; /* source text of anonymous code block */ diff --git a/src/include/nodes/parsenodes_common.h b/src/include/nodes/parsenodes_common.h index d860b8ba8..f189d838e 100644 --- a/src/include/nodes/parsenodes_common.h +++ b/src/include/nodes/parsenodes_common.h @@ -155,6 +155,16 @@ typedef struct DropRoleStmt { DropBehavior behavior; /* CASCADE or RESTRICT */ } DropRoleStmt; +typedef struct TypeDependExtend { + Oid typeOid; /* real depend type OID */ + Oid undefDependObjOid; /* undefined oid in gs_dependencies_obj when the column's type is undefined */ + bool dependUndefined; + char* schemaName; + char* packageName; + char* objectName; + char typType; + char typCategory; +} TypeDependExtend; /* * TypeName - specifies a type in definitions * @@ -181,6 +191,7 @@ typedef struct TypeName { int end_location; /* %TYPE and date specified, token end location */ bool pct_rowtype; /* %ROWTYPE specified? */ int charset; + TypeDependExtend* dependExtend = NULL; } TypeName; typedef enum FunctionParameterMode { @@ -2244,6 +2255,7 @@ typedef struct CreateFunctionStmt { List* withClause; /* a list of DefElem */ bool isProcedure; /* true if it is a procedure */ char* inputHeaderSrc; + char* funcHeadSrc; bool isPrivate; /* in package, it's true is a private procedure*/ bool isFunctionDeclare; /* in package,it's true is a function delcare*/ bool isExecuted; diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index e4160768e..b97fd480b 100644 --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -257,6 +257,8 @@ typedef struct Param { Oid recordVarTypOid; /* package record var's composite type oid */ List* tableOfIndexTypeList; /* type Oid list of table of, max size 6 */ bool is_bind_param; + char* name; + bool is_pkg_var; } Param; /* diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h index d7c94bfbf..1c6869408 100644 --- a/src/include/parser/kwlist.h +++ b/src/include/parser/kwlist.h @@ -130,6 +130,7 @@ PG_KEYWORD("commit", COMMIT, UNRESERVED_KEYWORD) PG_KEYWORD("committed", COMMITTED, UNRESERVED_KEYWORD) PG_KEYWORD("compact", COMPACT, TYPE_FUNC_NAME_KEYWORD) PG_KEYWORD("compatible_illegal_chars", COMPATIBLE_ILLEGAL_CHARS, UNRESERVED_KEYWORD) +PG_KEYWORD("compile", COMPILE, UNRESERVED_KEYWORD) PG_KEYWORD("complete", COMPLETE, UNRESERVED_KEYWORD) PG_KEYWORD("completion", COMPLETION, UNRESERVED_KEYWORD) PG_KEYWORD("compress", COMPRESS, UNRESERVED_KEYWORD) @@ -589,6 +590,7 @@ PG_KEYWORD("snapshot", SNAPSHOT, UNRESERVED_KEYWORD) PG_KEYWORD("some", SOME, RESERVED_KEYWORD) PG_KEYWORD("source", SOURCE_P, UNRESERVED_KEYWORD) PG_KEYWORD("space", SPACE, UNRESERVED_KEYWORD) +PG_KEYWORD("specification", SPECIFICATION, UNRESERVED_KEYWORD) PG_KEYWORD("spill", SPILL, UNRESERVED_KEYWORD) PG_KEYWORD("split", SPLIT, UNRESERVED_KEYWORD) PG_KEYWORD("sql", SQL_P, UNRESERVED_KEYWORD) diff --git a/src/include/parser/parse_type.h b/src/include/parser/parse_type.h index 848981993..83a21cea6 100644 --- a/src/include/parser/parse_type.h +++ b/src/include/parser/parse_type.h @@ -19,14 +19,18 @@ typedef HeapTuple Type; -extern Type LookupTypeName(ParseState* pstate, const TypeName* typname, int32* typmod_p, bool print_notice = true); +extern Type LookupTypeNameSupportUndef(ParseState *pstate, const TypeName *typeName, + int32 *typmod_p, bool print_notice = true); +extern Type LookupTypeName(ParseState* pstate, const TypeName* typname, int32* typmod_p, bool print_notice = true, + TypeDependExtend* dependExtend = NULL); extern Type LookupTypeNameExtended(ParseState* pstate, const TypeName* typname, int32* typmod_p, bool temp_ok, - bool print_notice = true); + bool print_notice = true, TypeDependExtend* dependExtend = NULL); extern Oid LookupPctTypeInPackage(RangeVar* rel, Oid pkgOid, const char* field); extern Oid LookupTypeInPackage(List* typeNames, const char* typeName, Oid pkgOid = InvalidOid, Oid namespaceId = InvalidOid); -extern Type typenameType(ParseState* pstate, const TypeName* typname, int32* typmod_p); +extern Type typenameType(ParseState* pstate, const TypeName* typname, int32* typmod_p, TypeDependExtend* dependExtend = NULL); extern Oid typenameTypeId(ParseState* pstate, const TypeName* typname); -extern void typenameTypeIdAndMod(ParseState* pstate, const TypeName* typname, Oid* typeid_p, int32* typmod_p); +extern void typenameTypeIdAndMod(ParseState* pstate, const TypeName* typname, Oid* typeid_p, int32* typmod_p, + TypeDependExtend* dependExtend = NULL); extern char* TypeNameToString(const TypeName* typname); extern char* TypeNameListToString(List* typenames); @@ -55,11 +59,19 @@ extern bool IsTypeSupportedByORCRelation(_in_ Oid typeOid); extern bool IsTypeSupportedByTsStore(_in_ int kvtype, _in_ Oid typeOid); extern bool IsTypeSupportedByUStore (_in_ Oid typeOid, _in_ int32 typeMod); extern TypeName *typeStringToTypeName(const char *str); -extern void parseTypeString(const char* str, Oid* typeid_p, int32* typmod_p); +extern void parseTypeString(const char* str, Oid* typeid_p, int32* typmod_p, TypeDependExtend* depenExtend = NULL); extern bool IsTypeTableInInstallationGroup(const Type type_tup); -extern HeapTuple FindPkgVariableType(ParseState* pstate, const TypeName* typname, int32* typmod_p); +extern HeapTuple FindPkgVariableType(ParseState* pstate, const TypeName* typname, int32* typmod_p, + TypeDependExtend* depend_extend = NULL); extern char* CastPackageTypeName(const char* typName, Oid pkgOid, bool isPackage, bool isPublic = true); extern bool IsBinaryType(Oid typid); #define ISCOMPLEX(typeid) (typeidTypeRelid(typeid) != InvalidOid) extern void check_type_supports_multi_charset(Oid typid, bool allow_array); +extern char* ParseTypeName(const char* typName, Oid pkgOid); +typedef enum TypeTupStatus { + NormalTypeTup = 0, + UndefineTypeTup = 1, + InvalidTypeTup = 2 +} TypeTupStatus; +extern TypeTupStatus GetTypeTupStatus(Type typ); #endif /* PARSE_TYPE_H */ diff --git a/src/include/parser/scanner.h b/src/include/parser/scanner.h index 1ab1f419c..8640517e6 100644 --- a/src/include/parser/scanner.h +++ b/src/include/parser/scanner.h @@ -117,6 +117,7 @@ typedef struct core_yy_extra_type { bool include_ora_comment; /* dont igore comment when ture */ int func_param_begin; /* function and procedure param string start pos,exclude left parenthesis */ int func_param_end; /* function and procedure param string end pos,exclude right parenthesis */ + int return_pos_end; bool isPlpgsqlKeyWord; const PlpgsqlKeywordValue* plKeywordValue; bool is_delimiter_name; diff --git a/src/include/storage/lmgr.h b/src/include/storage/lmgr.h index 9de4afff5..929ed2bd5 100644 --- a/src/include/storage/lmgr.h +++ b/src/include/storage/lmgr.h @@ -115,4 +115,5 @@ extern void DescribeLockTag(StringInfo buf, const LOCKTAG* tag); extern bool ConditionalLockCStoreFreeSpace(Relation relation); extern void UnlockCStoreFreeSpace(Relation relation); extern const char* GetLockNameFromTagType(uint16 locktag_type); + #endif /* LMGR_H */ diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h index 447f73055..2941f8ef3 100644 --- a/src/include/tcop/tcopprot.h +++ b/src/include/tcop/tcopprot.h @@ -41,6 +41,8 @@ extern List* pg_parse_query(const char* query_string, List** query_string_locati extern List* pg_analyze_and_rewrite(Node* parsetree, const char* query_string, Oid* paramTypes, int numParams); extern List* pg_analyze_and_rewrite_params( Node* parsetree, const char* query_string, ParserSetupHook parserSetup, void* parserSetupArg); +extern Query* pg_analyze_and_get_query(Node* parsetree, const char* query_string, + ParserSetupHook parserSetup, void* parserSetupArg); extern PlannedStmt* pg_plan_query( Query* querytree, int cursorOptions, ParamListInfo boundParams, bool underExplain = false); extern List* pg_plan_queries(List* querytrees, int cursorOptions, ParamListInfo boundParams); diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index 54629770e..c8d715890 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -856,6 +856,7 @@ extern char* format_operator(Oid operator_oid); extern char *format_procedure_qualified(Oid procedure_oid); extern char *format_operator_qualified(Oid operator_oid); extern void format_procedure_parts(Oid procedure_oid, List **objnames, List **objargs); +extern char * format_procedure_no_visible(Oid procedure_oid); /* rowtypes.c */ extern Datum record_in(PG_FUNCTION_ARGS); @@ -1101,6 +1102,11 @@ extern Datum unknownout(PG_FUNCTION_ARGS); extern Datum unknownrecv(PG_FUNCTION_ARGS); extern Datum unknownsend(PG_FUNCTION_ARGS); +extern Datum undefinedin(PG_FUNCTION_ARGS); +extern Datum undefinedout(PG_FUNCTION_ARGS); +extern Datum undefinedrecv(PG_FUNCTION_ARGS); +extern Datum undefinedsend(PG_FUNCTION_ARGS); + extern Datum pg_column_size(PG_FUNCTION_ARGS); extern Datum datalength(PG_FUNCTION_ARGS); diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h index 8015eab2f..a4818edf3 100644 --- a/src/include/utils/lsyscache.h +++ b/src/include/utils/lsyscache.h @@ -120,6 +120,7 @@ extern bool type_is_rowtype(Oid typid); extern bool type_is_enum(Oid typid); extern bool type_is_range(Oid typid); extern bool type_is_set(Oid typid); +extern bool type_is_relation(Oid typid); extern void get_type_category_preferred(Oid typid, char* typcategory, bool* typispreferred); extern Oid get_typ_typrelid(Oid typid); extern Oid get_element_type(Oid typid); @@ -222,6 +223,7 @@ extern Oid get_valid_relname_relid(const char* relnamespace, const char* relname extern bool get_func_iswindow(Oid funcid); extern char get_func_prokind(Oid funcid); extern char get_typecategory(Oid typid); +extern Oid get_array_internal_depend_type_oid(Oid arrTypOid); #ifdef USE_SPQ /* comparison types */ diff --git a/src/include/utils/pl_package.h b/src/include/utils/pl_package.h index aef7ce828..b82fb4cd8 100644 --- a/src/include/utils/pl_package.h +++ b/src/include/utils/pl_package.h @@ -72,5 +72,5 @@ extern List* GetPackageListName(const char* pkgName, const Oid nspOid); extern HeapTuple getPLpgsqlVarTypeTup(char* word); extern HeapTuple FindRowVarColType(List* nameList, int* collectionType = NULL, Oid* tableofIndexType = NULL, - int32* typMod = NULL); + int32* typMod = NULL, TypeDependExtend* dependExtend = NULL); #endif diff --git a/src/include/utils/plpgsql.h b/src/include/utils/plpgsql.h index 3ac659cd7..5060daeae 100644 --- a/src/include/utils/plpgsql.h +++ b/src/include/utils/plpgsql.h @@ -289,6 +289,35 @@ typedef enum { PLPGSQL_CURSOR_NAME } PLpgSQL_con_info_item_value; +/* + * GsDependency object type + */ +typedef enum { + GSDEPEND_OBJECT_TYPE_INVALID = 0, + GSDEPEND_OBJECT_TYPE_UNDEFIND, + GSDEPEND_OBJECT_TYPE_VARIABLE, + GSDEPEND_OBJECT_TYPE_TYPE, + GSDEPEND_OBJECT_TYPE_FUNCTION, + GSDEPEND_OBJECT_TYPE_PROCHEAD, + GSDEPEND_OBJECT_TYPE_PKG, + GSDEPEND_OBJECT_TYPE_PKG_BODY, + GSDEPEND_OBJECT_TYPE_PKG_RECOMPILE +} GsDependObjectType; + +/* +* GsDependency reference object position type +*/ +#define GSDEPEND_REFOBJ_POS_INVALID 0 +#define GSDEPEND_REFOBJ_POS_IN_TYPE 1 +#define GSDEPEND_REFOBJ_POS_IN_PKGSPEC 2 +#define GSDEPEND_REFOBJ_POS_IN_PROCHEAD 4 +#define GSDEPEND_REFOBJ_POS_IN_PROCBODY 8 +#define GSDEPEND_REFOBJ_POS_IN_PKGBODY 16 +#define GSDEPEND_REFOBJ_POS_IN_PKGRECOMPILE_OBJ (GSDEPEND_REFOBJ_POS_IN_PKGSPEC | \ + GSDEPEND_REFOBJ_POS_IN_PKGBODY | GSDEPEND_REFOBJ_POS_IN_PROCBODY) +#define GSDEPEND_REFOBJ_POS_IN_PKGALL_OBJ (GSDEPEND_REFOBJ_POS_IN_PKGRECOMPILE_OBJ) +#define GSDEPEND_REFOBJ_POS_IN_PROCALL (GSDEPEND_REFOBJ_POS_IN_PROCHEAD | GSDEPEND_REFOBJ_POS_IN_PROCBODY) + /********************************************************************** * Node and structure definitions **********************************************************************/ @@ -302,6 +331,46 @@ typedef struct PLpgSQL_datum { /* Generic datum array item */ bool ispkg; } PLpgSQL_datum; +/* + * DependenciesDatum is the common supertype for DependenciesUndefined, DependenciesVariable, + * DependenciesType, DependenciesProchead + */ +typedef struct DependenciesDatum { /* Generic datum array item */ + NodeTag type; +} DependenciesDatum; + +/* + * PLpgSQL dependencies undefined/type/variable/function/procedure + */ +typedef struct DependenciesUndefined { /* Generic datum array item */ + NodeTag type; +} DependenciesUndefined; + +typedef struct DependenciesVariable { + NodeTag type; + char* typName; + int32 typMod; + char* extraInfo; +} DependenciesVariable; + +typedef struct DependenciesType{ + NodeTag type; + char typType; + char typCategory; + char* attrInfo; + bool isRel; + char* elemTypName; + char* idxByTypName; +} DependenciesType; + +typedef struct DependenciesProchead{ + NodeTag type; + bool undefined; + char* proName; + char* proArgSrc; + char* funcHeadSrc; +} DependenciesProchead; + typedef enum PLpgSQL_trigtype { PLPGSQL_DML_TRIGGER, @@ -403,6 +472,8 @@ typedef struct { /* openGauss data type */ * then convert to tuple descriptior. */ Oid cursorCompositeOid = InvalidOid; + Oid tableofOid; + TypeDependExtend* dependExtend; } PLpgSQL_type; typedef struct { @@ -1161,6 +1232,10 @@ typedef struct PLpgSQL_function { /* Complete compiled function */ bool is_autonomous; bool is_plpgsql_func_with_outparam; bool is_insert_gs_source; + /* gs depend */ + bool isValid; + bool is_need_recompile; + Oid namespaceOid; } PLpgSQL_function; class AutonomousSession; @@ -1362,6 +1437,13 @@ typedef struct plpgsql_pkg_hashent { } plpgsql_pkg_HashEnt; +#define PACKAGE_INVALID 0x0 +#define PACKAGE_SPEC_VALID 0x1 +#define PACKAGE_SPEC_INVALID 0xFE +#define PACKAGE_BODY_VALID 0x2 +#define PACKAGE_BODY_INVALID 0xFD +#define PACKAGE_VALID 0x3 + typedef struct PLpgSQL_package { /* Complete compiled package */ char* pkg_signature; Oid pkg_oid; @@ -1407,6 +1489,15 @@ typedef struct PLpgSQL_package { /* Complete compiled package */ knl_u_plpgsql_pkg_context* u_pkg; Oid namespaceOid; bool isInit; + + /** + * gs_dependencies_fn.h + */ + NodeTag type; + List* preRefObjectOidList; + List* preSelfObjectList; + unsigned char status; + bool is_need_recompile; } PLpgSQL_package; @@ -1664,7 +1755,7 @@ typedef struct plpgsql_hashent { DListCell* cell; /* Dlist cell for delete function compile results. */ } plpgsql_HashEnt; -extern PLpgSQL_function* plpgsql_compile(FunctionCallInfo fcinfo, bool forValidator); +extern PLpgSQL_function* plpgsql_compile(FunctionCallInfo fcinfo, bool forValidator, bool isRecompile = false); extern void delete_function(PLpgSQL_function* func, bool fromPackage = false); extern PLpgSQL_function* plpgsql_compile_nohashkey(FunctionCallInfo fcinfo); /* parse trigger func */ extern PLpgSQL_function* plpgsql_compile_inline(char* proc_source); @@ -1679,10 +1770,10 @@ extern bool plpgsql_parse_tripword(char* word1, char* word2, char* word3, PLwdat extern bool plpgsql_parse_quadword(char* word1, char* word2, char* word3, char* word4, PLwdatum* wdatum, PLcword* cword, int* tok_flag); extern PLpgSQL_type* plpgsql_parse_wordtype(char* ident); -extern PLpgSQL_type* plpgsql_parse_cwordtype(List* idents); +extern PLpgSQL_type* plpgsql_parse_cwordtype(List* idents, TypeDependExtend* dependExtend = NULL); extern PLpgSQL_type* plpgsql_parse_wordrowtype(char* ident); extern PLpgSQL_type* plpgsql_parse_cwordrowtype(List* idents); -extern PLpgSQL_type* plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation); +extern PLpgSQL_type* plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation, TypeDependExtend* type_depend_extend = NULL); extern PLpgSQL_type* build_datatype(HeapTuple type_tup, int32 typmod, Oid collation); extern PLpgSQL_type* plpgsql_build_nested_datatype(); extern const char *plpgsql_code_int2cstring(int sqlcode); @@ -1707,12 +1798,13 @@ extern bool plpgsql_check_colocate(Query* query, RangeTblEntry* rte, void* plpgs extern void plpgsql_HashTableDeleteAll(); extern void plpgsql_hashtable_delete_and_check_invalid_item(int classId, Oid objId); extern void delete_package_and_check_invalid_item(Oid pkgOid); +extern void plpgsql_hashtable_clear_invalid_obj(bool need_clear = false); extern void plpgsql_HashTableDelete(PLpgSQL_function* func); extern bool plpgsql_get_current_value_stp_with_exception(); extern void plpgsql_restore_current_value_stp_with_exception(bool saved_current_stp_with_exception); extern void plpgsql_set_current_value_stp_with_exception(); extern void delete_pkg_in_HashTable(Oid pkgOid); -extern PLpgSQL_package* plpgsql_pkg_compile(Oid pkgOid, bool for_validator, bool isSpec, bool isCreate=false); +extern PLpgSQL_package* plpgsql_pkg_compile(Oid pkgOid, bool for_validator, bool isSpec, bool isCreate=false, bool isRecompile = false); extern PLpgSQL_datum* plpgsql_pkg_adddatum(const List* wholeName, char** objname, char** pkgname); extern int plpgsql_pkg_adddatum2ns(const List* name); extern bool plpgsql_check_insert_colocate( @@ -1823,7 +1915,7 @@ extern PLpgSQL_nsitem* plpgsql_ns_lookup( extern PLpgSQL_nsitem* plpgsql_ns_lookup_label(PLpgSQL_nsitem* ns_cur, const char* name); extern void free_func_tableof_index(); extern void free_temp_func_tableof_index(List* temp_tableof_index); - +extern char* GetPackageSchemaName(Oid packageOid); /* ---------- * Other functions in pl_funcs.c @@ -2008,4 +2100,13 @@ extern void stp_reserve_subxact_resowner(ResourceOwner resowner); extern void stp_cleanup_subxact_resowner(int64 minStackId); extern void stp_cleanup_subxact_resource(int64 stackId); extern void InsertGsSource(Oid objId, Oid nspid, const char* name, const char* type, bool status); +extern void examine_parameter_list(List* parameters, Oid languageOid, const char* queryString, + oidvector** parameterTypes, TypeDependExtend** type_depend_extend, ArrayType** allParameterTypes, + ArrayType** parameterModes, ArrayType** parameterNames, + List** parameterDefaults, Oid* requiredResultType, List** defargpos, bool fenced, bool* has_undefined = NULL); +extern void compute_return_type( + TypeName* returnType, Oid languageOid, Oid* prorettype_p, bool* returnsSet_p, bool fenced, int startLineNumber, + TypeDependExtend* type_depend_extend, bool is_refresh_head); +void plpgsql_free_override_stack(int depth); + #endif /* PLPGSQL_H */ diff --git a/src/include/utils/sec_rls_utils.h b/src/include/utils/sec_rls_utils.h index 7db8daff2..4c947d494 100644 --- a/src/include/utils/sec_rls_utils.h +++ b/src/include/utils/sec_rls_utils.h @@ -115,5 +115,6 @@ extern EnableRlsFeature CheckEnableRlsPolicies(const Relation relation, Oid role extern SelectStmt* MakeRlsSelectStmtForCopyTo(const Relation relation, const CopyStmt* stmt); extern void LicenseSupportRls(); extern void SupportRlsForRel(const Relation relation); +extern bool IsRlsFunction(Oid funcid); #endif /* UTILS_SEC_RLS_UTILS_H */ diff --git a/src/test/regress/expected/b_compatibility.out b/src/test/regress/expected/b_compatibility.out index e4ec8c110..1f14115da 100644 --- a/src/test/regress/expected/b_compatibility.out +++ b/src/test/regress/expected/b_compatibility.out @@ -1386,12 +1386,20 @@ CONTEXT: compilation of PL/pgSQL function "proc_label1" near line 1 NOTICE: identifier "label11111111111111111111111111111111111111111111111111111111112" will be truncated to "label1111111111111111111111111111111111111111111111111111111111" CONTEXT: compilation of PL/pgSQL function "proc_label1" near line 3 call proc_label(5); +NOTICE: identifier "label11111111111111111111111111111111111111111111111111111111112" will be truncated to "label1111111111111111111111111111111111111111111111111111111111" +CONTEXT: compilation of PL/pgSQL function "proc_label" near line 1 +NOTICE: identifier "label11111111111111111111111111111111111111111111111111111111112" will be truncated to "label1111111111111111111111111111111111111111111111111111111111" +CONTEXT: compilation of PL/pgSQL function "proc_label" near line 3 proc_label ------------ (1 row) call proc_label1(5); +NOTICE: identifier "label11111111111111111111111111111111111111111111111111111111112" will be truncated to "label1111111111111111111111111111111111111111111111111111111111" +CONTEXT: compilation of PL/pgSQL function "proc_label1" near line 1 +NOTICE: identifier "label11111111111111111111111111111111111111111111111111111111112" will be truncated to "label1111111111111111111111111111111111111111111111111111111111" +CONTEXT: compilation of PL/pgSQL function "proc_label1" near line 3 proc_label1 ------------- @@ -2867,4 +2875,4 @@ drop user use_b_1144425 cascade; drop database b_cmpt_db; drop database db_a1144425; DROP USER test_c; -DROP USER test_d; +DROP USER test_d; \ No newline at end of file diff --git a/src/test/regress/expected/function.out b/src/test/regress/expected/function.out index 681493dcb..bdbd7339a 100644 --- a/src/test/regress/expected/function.out +++ b/src/test/regress/expected/function.out @@ -1484,7 +1484,7 @@ call sche1.pro(); ERROR: relation "test" already exists in schema "sche1" DETAIL: creating new table with existing name in the same schema CONTEXT: SQL statement "create table test as select * from sche_t1" -PL/pgSQL function sche1.subpro() line 2 at SQL statement +PL/pgSQL function subpro() line 2 at SQL statement SQL statement "CALL subpro()" PL/pgSQL function sche1.pro() line 3 at PERFORM drop schema sche1 cascade; diff --git a/src/test/regress/expected/pldeveloper_gs_source.out b/src/test/regress/expected/pldeveloper_gs_source.out index 617c97c19..bbc87e421 100644 --- a/src/test/regress/expected/pldeveloper_gs_source.out +++ b/src/test/regress/expected/pldeveloper_gs_source.out @@ -1262,4 +1262,4 @@ drop cascades to function test2(integer) drop cascades to function skipinsertgssource() drop cascades to function test1() drop role jackson_src; -drop role gs_developper; +drop role gs_developper; \ No newline at end of file diff --git a/src/test/regress/expected/plpgsql_depend/plpgsql_depend_reftype.out b/src/test/regress/expected/plpgsql_depend/plpgsql_depend_reftype.out new file mode 100644 index 000000000..f3e31f3db --- /dev/null +++ b/src/test/regress/expected/plpgsql_depend/plpgsql_depend_reftype.out @@ -0,0 +1,988 @@ +drop schema if exists plpgsql_depend_reftype cascade; +NOTICE: schema "plpgsql_depend_reftype" does not exist, skipping +create schema plpgsql_depend_reftype; +set current_schema = plpgsql_depend_reftype; +set behavior_compat_options = 'plpgsql_dependency'; +-- prepare data table +create or replace function create_data_table returns int as $$ +begin +drop table if exists stu; +create table stu (sno int, name varchar, sex varchar, cno int); +insert into stu values(1,'zhang','M',1); +insert into stu values(1,'zhang','M',1); +insert into stu values(2,'wangwei','M',2); +insert into stu values(3,'liu','F',3); +return 1; +end; +$$ +LANGUAGE plpgsql; +-- drop data table +create or replace function drop_data_table returns int as $$ +begin +drop table if exists stu; +return 1; +end; +$$ +LANGUAGE plpgsql; +-- drop data table cascade +create or replace function drop_data_table_cascade returns int as $$ +begin +drop table if exists stu cascade; +return 1; +end; +$$ +LANGUAGE plpgsql; +-- test 1 ref type +select create_data_table(); +NOTICE: table "stu" does not exist, skipping +CONTEXT: SQL statement "drop table if exists stu" +PL/pgSQL function create_data_table() line 3 at SQL statement +referenced column: create_data_table + create_data_table +------------------- + 1 +(1 row) + +--- define schema define table --- +--cur_db.def_schema.def_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c regression.plpgsql_depend_reftype.stu%RowType); + procedure proc1(); +end pkg; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------------------+-------------+------+------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_reftype | null | 3 | stu | {DependenciesType :typType c :typCategory C :attrInfo sno:pg_catalog.int4,name:pg_catalog.varchar,sex:pg_catalog.varchar,cno:pg_catalog.int4, :isRel true :elemTypName <> :idxByTypName <>} +(1 row) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------------------+-------------+------------+----------- + plpgsql_depend_reftype | pkg | r1 | 1 +(1 row) + +--other_db.def_schema.def_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c undefdb.plpgsql_depend_reftype.stu%RowType); + procedure proc1(); +end pkg; +/ +ERROR: cross-database references are not implemented: "undefdb.plpgsql_depend_reftype.stu" +CONTEXT: compilation of PL/pgSQL package near line 1 +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------------------+-------------+------+------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_reftype | null | 3 | stu | {DependenciesType :typType c :typCategory C :attrInfo sno:pg_catalog.int4,name:pg_catalog.varchar,sex:pg_catalog.varchar,cno:pg_catalog.int4, :isRel true :elemTypName <> :idxByTypName <>} +(1 row) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------------------+-------------+------------+----------- + plpgsql_depend_reftype | pkg | r1 | 1 +(1 row) + +--cur_db.def_schema.def_rowtype_in_prochead +create or replace procedure proc12(v_1 regression.plpgsql_depend_reftype.stu%RowType) +as +begin + NULL; +end; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------------------+-------------+------+------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_reftype | null | 5 | proc12(plpgsql_depend_reftype.stu) | {DependenciesProchead :undefined false :proName proc12 :proArgSrc v_1\ regression.plpgsql_depend_reftype.stu%RowType :funcHeadSrc create\ or\ replace\ procedure\ proc12\(v_1\ regression.plpgsql_depend_reftype.stu%RowType\)} + plpgsql_depend_reftype | null | 3 | stu | {DependenciesType :typType c :typCategory C :attrInfo sno:pg_catalog.int4,name:pg_catalog.varchar,sex:pg_catalog.varchar,cno:pg_catalog.int4, :isRel true :elemTypName <> :idxByTypName <>} +(2 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------------------+-------------+------------------------------------+----------- + plpgsql_depend_reftype | null | proc12(plpgsql_depend_reftype.stu) | 4 + plpgsql_depend_reftype | pkg | r1 | 1 +(2 rows) + +--other_db.def_schema.def_rowtype_in_prochead +create or replace procedure proc12(v_1 undefdb.plpgsql_depend_reftype.stu%RowType) +as +begin + NULL; +end; +/ +ERROR: cross-database references are not implemented: "undefdb.plpgsql_depend_reftype.stu" +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------------------+-------------+------+------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_reftype | null | 5 | proc12(plpgsql_depend_reftype.stu) | {DependenciesProchead :undefined false :proName proc12 :proArgSrc v_1\ regression.plpgsql_depend_reftype.stu%RowType :funcHeadSrc create\ or\ replace\ procedure\ proc12\(v_1\ regression.plpgsql_depend_reftype.stu%RowType\)} + plpgsql_depend_reftype | null | 3 | stu | {DependenciesType :typType c :typCategory C :attrInfo sno:pg_catalog.int4,name:pg_catalog.varchar,sex:pg_catalog.varchar,cno:pg_catalog.int4, :isRel true :elemTypName <> :idxByTypName <>} +(2 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------------------+-------------+------------------------------------+----------- + plpgsql_depend_reftype | null | proc12(plpgsql_depend_reftype.stu) | 4 + plpgsql_depend_reftype | pkg | r1 | 1 +(2 rows) + +--- define schema undefine table --- +--cur_db.def_schema.undef_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c regression.plpgsql_depend_reftype.undefstu%RowType); + procedure proc1(); +end pkg; +/ +WARNING: relation does not exist when parse word. +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Type r1 depends on an undefined type. +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Package created with compilation erors. +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------------------+-------------+------+------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_reftype | null | 5 | proc12(plpgsql_depend_reftype.stu) | {DependenciesProchead :undefined false :proName proc12 :proArgSrc v_1\ regression.plpgsql_depend_reftype.stu%RowType :funcHeadSrc create\ or\ replace\ procedure\ proc12\(v_1\ regression.plpgsql_depend_reftype.stu%RowType\)} + plpgsql_depend_reftype | null | 3 | stu | {DependenciesType :typType c :typCategory C :attrInfo sno:pg_catalog.int4,name:pg_catalog.varchar,sex:pg_catalog.varchar,cno:pg_catalog.int4, :isRel true :elemTypName <> :idxByTypName <>} + plpgsql_depend_reftype | null | 3 | undefstu | {DependenciesUndefined} +(3 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------------------+-------------+------------------------------------+----------- + plpgsql_depend_reftype | null | proc12(plpgsql_depend_reftype.stu) | 4 + plpgsql_depend_reftype | pkg | r1 | 1 +(2 rows) + +--other_db.def_schema.undef_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c undefdb.plpgsql_depend_reftype.undefstu%RowType); + procedure proc1(); +end pkg; +/ +ERROR: cross-database references are not implemented: "undefdb.plpgsql_depend_reftype.undefstu" +CONTEXT: compilation of PL/pgSQL package near line 1 +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------------------+-------------+------+------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_reftype | null | 5 | proc12(plpgsql_depend_reftype.stu) | {DependenciesProchead :undefined false :proName proc12 :proArgSrc v_1\ regression.plpgsql_depend_reftype.stu%RowType :funcHeadSrc create\ or\ replace\ procedure\ proc12\(v_1\ regression.plpgsql_depend_reftype.stu%RowType\)} + plpgsql_depend_reftype | null | 3 | stu | {DependenciesType :typType c :typCategory C :attrInfo sno:pg_catalog.int4,name:pg_catalog.varchar,sex:pg_catalog.varchar,cno:pg_catalog.int4, :isRel true :elemTypName <> :idxByTypName <>} + plpgsql_depend_reftype | null | 3 | undefstu | {DependenciesUndefined} +(3 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------------------+-------------+------------------------------------+----------- + plpgsql_depend_reftype | null | proc12(plpgsql_depend_reftype.stu) | 4 + plpgsql_depend_reftype | pkg | r1 | 1 +(2 rows) + +--cur_db.def_schema.undef_rowtype_in_prochead +create or replace procedure proc12(v_1 regression.plpgsql_depend_reftype.undefstu%RowType) +as +begin + NULL; +end; +/ +WARNING: relation does not exist when parse word. +DETAIL: relation "regression.plpgsql_depend_reftype.undefstu" referenced by %ROWTYPE does not exist. +WARNING: Type proc12(pg_catalog.undefined) depends on an undefined type. +WARNING: The header information of function proc12 is not defined. +CONTEXT: compilation of PL/pgSQL function "proc12" near line 1 +WARNING: Procedure created with compilation erors. +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------------------+-------------+------+------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + plpgsql_depend_reftype | null | 5 | proc12(pg_catalog.undefined) | {DependenciesProchead :undefined true :proName proc12 :proArgSrc v_1\ regression.plpgsql_depend_reftype.undefstu%RowType :funcHeadSrc create\ or\ replace\ procedure\ proc12\(v_1\ regression.plpgsql_depend_reftype.undefstu%RowType\)} + plpgsql_depend_reftype | null | 3 | undefstu | {DependenciesUndefined} +(2 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------------------+-------------+------------------------------+----------- + plpgsql_depend_reftype | null | proc12(pg_catalog.undefined) | 4 + plpgsql_depend_reftype | pkg | r1 | 1 +(2 rows) + +--other_db.def_schema.undef_rowtype_in_prochead +create or replace procedure proc12(v_1 undefdb.plpgsql_depend_reftype.undefstu%RowType) +as +begin + NULL; +end; +/ +ERROR: cross-database references are not implemented: "undefdb.plpgsql_depend_reftype.undefstu" +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------------------+-------------+------+------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + plpgsql_depend_reftype | null | 5 | proc12(pg_catalog.undefined) | {DependenciesProchead :undefined true :proName proc12 :proArgSrc v_1\ regression.plpgsql_depend_reftype.undefstu%RowType :funcHeadSrc create\ or\ replace\ procedure\ proc12\(v_1\ regression.plpgsql_depend_reftype.undefstu%RowType\)} + plpgsql_depend_reftype | null | 3 | undefstu | {DependenciesUndefined} +(2 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------------------+-------------+------------------------------+----------- + plpgsql_depend_reftype | null | proc12(pg_catalog.undefined) | 4 + plpgsql_depend_reftype | pkg | r1 | 1 +(2 rows) + +--- undefine schema --- +--cur_db.undef_schema.undef_rowtype_in_prochead +create or replace procedure proc12(v_1 regression.undefplpgsql_depend_reftype.undefstu%RowType) +as +begin + NULL; +end; +/ +ERROR: relation does not exist when parse word. +DETAIL: relation "regression.undefplpgsql_depend_reftype.undefstu" referenced by %ROWTYPE does not exist. +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------------------+-------------+------+------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + plpgsql_depend_reftype | null | 5 | proc12(pg_catalog.undefined) | {DependenciesProchead :undefined true :proName proc12 :proArgSrc v_1\ regression.plpgsql_depend_reftype.undefstu%RowType :funcHeadSrc create\ or\ replace\ procedure\ proc12\(v_1\ regression.plpgsql_depend_reftype.undefstu%RowType\)} + plpgsql_depend_reftype | null | 3 | undefstu | {DependenciesUndefined} +(2 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------------------+-------------+------------------------------+----------- + plpgsql_depend_reftype | null | proc12(pg_catalog.undefined) | 4 + plpgsql_depend_reftype | pkg | r1 | 1 +(2 rows) + +--- define schema define table --- +--def_schema.def_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c plpgsql_depend_reftype.stu%RowType); + procedure proc1(); +end pkg; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------------------+-------------+------+------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + plpgsql_depend_reftype | null | 5 | proc12(pg_catalog.undefined) | {DependenciesProchead :undefined true :proName proc12 :proArgSrc v_1\ regression.plpgsql_depend_reftype.undefstu%RowType :funcHeadSrc create\ or\ replace\ procedure\ proc12\(v_1\ regression.plpgsql_depend_reftype.undefstu%RowType\)} + plpgsql_depend_reftype | null | 3 | stu | {DependenciesType :typType c :typCategory C :attrInfo sno:pg_catalog.int4,name:pg_catalog.varchar,sex:pg_catalog.varchar,cno:pg_catalog.int4, :isRel true :elemTypName <> :idxByTypName <>} + plpgsql_depend_reftype | null | 3 | undefstu | {DependenciesUndefined} +(3 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------------------+-------------+------------------------------+----------- + plpgsql_depend_reftype | null | proc12(pg_catalog.undefined) | 4 + plpgsql_depend_reftype | pkg | r1 | 1 +(2 rows) + +--def_schema.def_rowtype_in_prochead +create or replace procedure proc12(v_1 plpgsql_depend_reftype.stu%RowType) +as +begin + NULL; +end; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------------------+-------------+------+------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_reftype | null | 5 | proc12(plpgsql_depend_reftype.stu) | {DependenciesProchead :undefined false :proName proc12 :proArgSrc v_1\ plpgsql_depend_reftype.stu%RowType :funcHeadSrc create\ or\ replace\ procedure\ proc12\(v_1\ plpgsql_depend_reftype.stu%RowType\)} + plpgsql_depend_reftype | null | 3 | stu | {DependenciesType :typType c :typCategory C :attrInfo sno:pg_catalog.int4,name:pg_catalog.varchar,sex:pg_catalog.varchar,cno:pg_catalog.int4, :isRel true :elemTypName <> :idxByTypName <>} +(2 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------------------+-------------+------------------------------------+----------- + plpgsql_depend_reftype | null | proc12(plpgsql_depend_reftype.stu) | 4 + plpgsql_depend_reftype | pkg | r1 | 1 +(2 rows) + +--def_schema.undef_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c plpgsql_depend_reftype.undefstu%RowType); + procedure proc1(); +end pkg; +/ +WARNING: relation does not exist when parse word. +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Type r1 depends on an undefined type. +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Package created with compilation erors. +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------------------+-------------+------+------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_reftype | null | 5 | proc12(plpgsql_depend_reftype.stu) | {DependenciesProchead :undefined false :proName proc12 :proArgSrc v_1\ plpgsql_depend_reftype.stu%RowType :funcHeadSrc create\ or\ replace\ procedure\ proc12\(v_1\ plpgsql_depend_reftype.stu%RowType\)} + plpgsql_depend_reftype | null | 3 | stu | {DependenciesType :typType c :typCategory C :attrInfo sno:pg_catalog.int4,name:pg_catalog.varchar,sex:pg_catalog.varchar,cno:pg_catalog.int4, :isRel true :elemTypName <> :idxByTypName <>} + plpgsql_depend_reftype | null | 3 | undefstu | {DependenciesUndefined} +(3 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------------------+-------------+------------------------------------+----------- + plpgsql_depend_reftype | null | proc12(plpgsql_depend_reftype.stu) | 4 + plpgsql_depend_reftype | pkg | r1 | 1 +(2 rows) + +--def_schema.undef_rowtype_in_prochead +create or replace procedure proc12(v_1 plpgsql_depend_reftype.undefstu%RowType) +as +begin + NULL; +end; +/ +WARNING: relation does not exist when parse word. +DETAIL: relation "plpgsql_depend_reftype.undefstu" referenced by %ROWTYPE does not exist. +WARNING: The header information of function proc12 is not defined. +CONTEXT: compilation of PL/pgSQL function "proc12" near line 1 +WARNING: Procedure created with compilation erors. +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------------------+-------------+------+------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_reftype | null | 5 | proc12(pg_catalog.undefined) | {DependenciesProchead :undefined true :proName proc12 :proArgSrc v_1\ plpgsql_depend_reftype.undefstu%RowType :funcHeadSrc create\ or\ replace\ procedure\ proc12\(v_1\ plpgsql_depend_reftype.undefstu%RowType\)} + plpgsql_depend_reftype | null | 3 | undefstu | {DependenciesUndefined} +(2 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------------------+-------------+------------------------------+----------- + plpgsql_depend_reftype | null | proc12(pg_catalog.undefined) | 4 + plpgsql_depend_reftype | pkg | r1 | 1 +(2 rows) + +--- define table --- +--def_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c stu%RowType); + procedure proc1(); +end pkg; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------------------+-------------+------+------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_reftype | null | 5 | proc12(pg_catalog.undefined) | {DependenciesProchead :undefined true :proName proc12 :proArgSrc v_1\ plpgsql_depend_reftype.undefstu%RowType :funcHeadSrc create\ or\ replace\ procedure\ proc12\(v_1\ plpgsql_depend_reftype.undefstu%RowType\)} + plpgsql_depend_reftype | null | 3 | stu | {DependenciesType :typType c :typCategory C :attrInfo sno:pg_catalog.int4,name:pg_catalog.varchar,sex:pg_catalog.varchar,cno:pg_catalog.int4, :isRel true :elemTypName <> :idxByTypName <>} + plpgsql_depend_reftype | null | 3 | undefstu | {DependenciesUndefined} +(3 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------------------+-------------+------------------------------+----------- + plpgsql_depend_reftype | null | proc12(pg_catalog.undefined) | 4 + plpgsql_depend_reftype | pkg | r1 | 1 +(2 rows) + +--def_rowtype_in_prochead +create or replace procedure proc12(v_1 stu%RowType) +as +begin + NULL; +end; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------------------+-------------+------+------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_reftype | null | 5 | proc12(plpgsql_depend_reftype.stu) | {DependenciesProchead :undefined false :proName proc12 :proArgSrc v_1\ stu%RowType :funcHeadSrc create\ or\ replace\ procedure\ proc12\(v_1\ stu%RowType\)} + plpgsql_depend_reftype | null | 3 | stu | {DependenciesType :typType c :typCategory C :attrInfo sno:pg_catalog.int4,name:pg_catalog.varchar,sex:pg_catalog.varchar,cno:pg_catalog.int4, :isRel true :elemTypName <> :idxByTypName <>} +(2 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------------------+-------------+------------------------------------+----------- + plpgsql_depend_reftype | null | proc12(plpgsql_depend_reftype.stu) | 4 + plpgsql_depend_reftype | pkg | r1 | 1 +(2 rows) + +--undef_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c undefstu%RowType); + procedure proc1(); +end pkg; +/ +WARNING: relation "undefstu" does not exist when parse word. +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Type r1 depends on an undefined type. +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Package created with compilation erors. +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------------------+-------------+------+------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_reftype | null | 5 | proc12(plpgsql_depend_reftype.stu) | {DependenciesProchead :undefined false :proName proc12 :proArgSrc v_1\ stu%RowType :funcHeadSrc create\ or\ replace\ procedure\ proc12\(v_1\ stu%RowType\)} + plpgsql_depend_reftype | null | 3 | stu | {DependenciesType :typType c :typCategory C :attrInfo sno:pg_catalog.int4,name:pg_catalog.varchar,sex:pg_catalog.varchar,cno:pg_catalog.int4, :isRel true :elemTypName <> :idxByTypName <>} + plpgsql_depend_reftype | null | 3 | undefstu | {DependenciesUndefined} +(3 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------------------+-------------+------------------------------------+----------- + plpgsql_depend_reftype | null | proc12(plpgsql_depend_reftype.stu) | 4 + plpgsql_depend_reftype | pkg | r1 | 1 +(2 rows) + +--undef_rowtype_in_prochead +create or replace procedure proc12(v_1 undefstu%RowType) +as +begin + NULL; +end; +/ +WARNING: relation does not exist when parse word. +DETAIL: relation "undefstu" referenced by %ROWTYPE does not exist. +WARNING: The header information of function proc12 is not defined. +CONTEXT: compilation of PL/pgSQL function "proc12" near line 1 +WARNING: Procedure created with compilation erors. +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------------------+-------------+------+------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_reftype | null | 5 | proc12(pg_catalog.undefined) | {DependenciesProchead :undefined true :proName proc12 :proArgSrc v_1\ undefstu%RowType :funcHeadSrc create\ or\ replace\ procedure\ proc12\(v_1\ undefstu%RowType\)} + plpgsql_depend_reftype | null | 3 | undefstu | {DependenciesUndefined} +(2 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------------------+-------------+------------------------------+----------- + plpgsql_depend_reftype | null | proc12(pg_catalog.undefined) | 4 + plpgsql_depend_reftype | pkg | r1 | 1 +(2 rows) + +--def_type_in_body +create or replace package pkg +is + type r1 is record(a int, c regression.plpgsql_depend_reftype.stu.sno%Type); + procedure proc1(); +end pkg; +/ +WARNING: invalid type name "regression.plpgsql_depend_reftype.stu.sno%Type" +LINE 1: PACKAGE DECLARE type r1 is record(a int, c regression.plp... + ^ +QUERY: PACKAGE DECLARE type r1 is record(a int, c regression.plpgsql_depend_reftype.stu.sno%Type); + procedure proc1(); +end +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Package created with compilation erors. +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------------------+-------------+------+------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_reftype | null | 5 | proc12(pg_catalog.undefined) | {DependenciesProchead :undefined true :proName proc12 :proArgSrc v_1\ undefstu%RowType :funcHeadSrc create\ or\ replace\ procedure\ proc12\(v_1\ undefstu%RowType\)} + plpgsql_depend_reftype | null | 3 | undefstu | {DependenciesUndefined} +(2 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------------------+-------------+------------------------------+----------- + plpgsql_depend_reftype | null | proc12(pg_catalog.undefined) | 4 +(1 row) + +--def_type_in_prohead +create or replace procedure proc12(v_1 regression.plpgsql_depend_reftype.stu.sno%Type) +as +begin + NULL; +end; +/ +NOTICE: type reference regression.plpgsql_depend_reftype.stu.sno%TYPE converted to integer +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------------------+-------------+------+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_reftype | null | 5 | proc12(pg_catalog.int4) | {DependenciesProchead :undefined false :proName proc12 :proArgSrc v_1\ integer :funcHeadSrc create\ or\ replace\ procedure\ proc12\(v_1\ regression.plpgsql_depend_reftype.stu.sno%Type\)} + plpgsql_depend_reftype | null | 3 | stu | {DependenciesType :typType c :typCategory C :attrInfo sno:pg_catalog.int4,name:pg_catalog.varchar,sex:pg_catalog.varchar,cno:pg_catalog.int4, :isRel true :elemTypName <> :idxByTypName <>} +(2 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------------------+-------------+-------------------------+----------- + plpgsql_depend_reftype | null | proc12(pg_catalog.int4) | 4 +(1 row) + +--undef_type_in_body +create or replace package pkg +is + type r1 is record(a int, c regression.plpgsql_depend_reftype.stu.undefsno%Type); + procedure proc1(); +end pkg; +/ +WARNING: invalid type name "regression.plpgsql_depend_reftype.stu.undefsno%Type" +LINE 1: PACKAGE DECLARE type r1 is record(a int, c regression.plp... + ^ +QUERY: PACKAGE DECLARE type r1 is record(a int, c regression.plpgsql_depend_reftype.stu.undefsno%Type); + procedure proc1(); +end +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Package created with compilation erors. +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------------------+-------------+------+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_reftype | null | 5 | proc12(pg_catalog.int4) | {DependenciesProchead :undefined false :proName proc12 :proArgSrc v_1\ integer :funcHeadSrc create\ or\ replace\ procedure\ proc12\(v_1\ regression.plpgsql_depend_reftype.stu.sno%Type\)} + plpgsql_depend_reftype | null | 3 | stu | {DependenciesType :typType c :typCategory C :attrInfo sno:pg_catalog.int4,name:pg_catalog.varchar,sex:pg_catalog.varchar,cno:pg_catalog.int4, :isRel true :elemTypName <> :idxByTypName <>} +(2 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------------------+-------------+-------------------------+----------- + plpgsql_depend_reftype | null | proc12(pg_catalog.int4) | 4 +(1 row) + +--undef_type_in_prohead +create or replace procedure proc12(v_1 regression.plpgsql_depend_reftype.stu.undefsno%Type) +as +begin + NULL; +end; +/ +WARNING: Procedure created with compilation erors. +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +select drop_data_table_cascade(); + drop_data_table_cascade +------------------------- + 1 +(1 row) + +drop schema if exists plpgsql_depend_reftype cascade; +NOTICE: drop cascades to 6 other objects +DETAIL: drop cascades to function create_data_table() +drop cascades to function drop_data_table() +drop cascades to function drop_data_table_cascade() +--?.* +drop cascades to function plpgsql_depend_reftype.proc1() +drop cascades to function proc12(undefined) +reset behavior_compat_options; +create schema plpgsql_depend_reftype; +set current_schema = plpgsql_depend_reftype; +set behavior_compat_options = 'plpgsql_dependency'; +--test 2 ref pkg var type +create or replace package refpkg as +type r1 is record(a int, b int); +procedure proc1(); +end refpkg; +/ +--- define table --- +--cur_db.def_schema.def_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c regression.plpgsql_depend_reftype.refpkg.r1.a%Type); + procedure proc1(); +end pkg; +/ +WARNING: invalid type name "regression.plpgsql_depend_reftype.refpkg.r1.a%Type" +LINE 1: PACKAGE DECLARE type r1 is record(a int, c regression.plp... + ^ +QUERY: PACKAGE DECLARE type r1 is record(a int, c regression.plpgsql_depend_reftype.refpkg.r1.a%Type); + procedure proc1(); +end +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Package created with compilation erors. +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +--other_db.def_schema.def_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c undefdb.plpgsql_depend_reftype.refpkg.r1.a%Type); + procedure proc1(); +end pkg; +/ +WARNING: invalid type name "undefdb.plpgsql_depend_reftype.refpkg.r1.a%Type" +LINE 1: PACKAGE DECLARE type r1 is record(a int, c undefdb.plpgsq... + ^ +QUERY: PACKAGE DECLARE type r1 is record(a int, c undefdb.plpgsql_depend_reftype.refpkg.r1.a%Type); + procedure proc1(); +end +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Package created with compilation erors. +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +--cur_db.def_schema.def_rowtype_in_prochead +create or replace procedure proc12(v_1 regression.plpgsql_depend_reftype.refpkg.r1.a%Type) +as +begin + NULL; +end; +/ +ERROR: improper %TYPE reference (too many dotted names): regression.plpgsql_depend_reftype.refpkg.r1.a +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +--other_db.def_schema.def_rowtype_in_prochead +create or replace procedure proc12(v_1 undefdb.plpgsql_depend_reftype.refpkg.r1.a%Type) +as +begin + NULL; +end; +/ +ERROR: improper %TYPE reference (too many dotted names): undefdb.plpgsql_depend_reftype.refpkg.r1.a +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +--- define schema define pkgrec --- +--cur_db.def_schema.undef_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c regression.plpgsql_depend_reftype.refpkg.undefr1.a%Type); + procedure proc1(); +end pkg; +/ +WARNING: invalid type name "regression.plpgsql_depend_reftype.refpkg.undefr1.a%Type" +LINE 1: PACKAGE DECLARE type r1 is record(a int, c regression.plp... + ^ +QUERY: PACKAGE DECLARE type r1 is record(a int, c regression.plpgsql_depend_reftype.refpkg.undefr1.a%Type); + procedure proc1(); +end +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Package created with compilation erors. +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +--other_db.def_schema.undef_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c undefdb.plpgsql_depend_reftype.refpkg.undefr1.a%Type); + procedure proc1(); +end pkg; +/ +WARNING: invalid type name "undefdb.plpgsql_depend_reftype.refpkg.undefr1.a%Type" +LINE 1: PACKAGE DECLARE type r1 is record(a int, c undefdb.plpgsq... + ^ +QUERY: PACKAGE DECLARE type r1 is record(a int, c undefdb.plpgsql_depend_reftype.refpkg.undefr1.a%Type); + procedure proc1(); +end +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Package created with compilation erors. +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +--cur_db.def_schema.undef_rowtype_in_prochead +create or replace procedure proc12(v_1 regression.plpgsql_depend_reftype.refpkg.undefr1.a%Type) +as +begin + NULL; +end; +/ +ERROR: improper %TYPE reference (too many dotted names): regression.plpgsql_depend_reftype.refpkg.undefr1.a +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +--other_db.def_schema.undef_rowtype_in_prochead +create or replace procedure proc12(v_1 undefdb.plpgsql_depend_reftype.refpkg.undefr1.a%Type) +as +begin + NULL; +end; +/ +ERROR: improper %TYPE reference (too many dotted names): undefdb.plpgsql_depend_reftype.refpkg.undefr1.a +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +--- define schema undefine pkg--- +--cur_db.def_schema.undef_rowtype_in_prochead +create or replace procedure proc12(v_1 regression.plpgsql_depend_reftype.undefpkg.undefr1.a%Type) +as +begin + NULL; +end; +/ +ERROR: improper %TYPE reference (too many dotted names): regression.plpgsql_depend_reftype.undefpkg.undefr1.a +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +--- undefine schema --- +--cur_db.undef_schema.undef_rowtype_in_prochead +create or replace procedure proc12(v_1 regression.undefplpgsql_depend_reftype.refpkg.undefr1.a%Type) +as +begin + NULL; +end; +/ +ERROR: improper %TYPE reference (too many dotted names): regression.undefplpgsql_depend_reftype.refpkg.undefr1.a +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +--- define schema define pkg rec--- +--def_schema.def_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c plpgsql_depend_reftype.refpkg.r1.a%Type); + procedure proc1; +end pkg; +/ +ERROR: cross-database references are not implemented: plpgsql_depend_reftype.refpkg.r1.a +CONTEXT: compilation of PL/pgSQL package near line 1 +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +--def_schema.def_rowtype_in_prochead rsy +create or replace procedure proc12(v_1 plpgsql_depend_reftype.refpkg.r1.a%Type) +as +begin + NULL; +end; +/ +ERROR: cross-database references are not implemented: plpgsql_depend_reftype.refpkg.r1.a +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +--- define schema define pkg rec --- +--def_schema.undef_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c plpgsql_depend_reftype.refpkg.undefr1.a%Type); + procedure proc1(); +end pkg; +/ +ERROR: cross-database references are not implemented: plpgsql_depend_reftype.refpkg.undefr1.a +CONTEXT: compilation of PL/pgSQL package near line 1 +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +--def_schema.undef_rowtype_in_prochead +create or replace procedure proc12(v_1 plpgsql_depend_reftype.refpkg.undefr1.a%Type) +as +begin + NULL; +end; +/ +ERROR: cross-database references are not implemented: plpgsql_depend_reftype.refpkg.undefr1.a +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +--- undefine schema --- rsy +create or replace procedure proc12(v_1 undefplpgsql_depend_reftype.refpkg.undefr1.a%Type) +as +begin + NULL; +end; +/ +ERROR: cross-database references are not implemented: undefplpgsql_depend_reftype.refpkg.undefr1.a +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +--- define pkg rec --- +--def_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c refpkg.r1.a%Type); + procedure proc1; +end pkg; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------------------+-------------+------+------+------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_reftype | refpkg | 3 | r1 | {DependenciesType :typType c :typCategory C :attrInfo a:pg_catalog.int4,b:pg_catalog.int4, :isRel false :elemTypName <> :idxByTypName <>} +(1 row) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------------------+-------------+------------+----------- + plpgsql_depend_reftype | pkg | r1 | 1 +(1 row) + +--def_rowtype_in_prochead +create or replace procedure proc12(v_1 refpkg.r1.a%Type) +as +begin + NULL; +end; +/ +NOTICE: type reference refpkg.r1.a%TYPE converted to integer +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------------------+-------------+------+-------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_reftype | null | 5 | proc12(pg_catalog.int4) | {DependenciesProchead :undefined false :proName proc12 :proArgSrc v_1\ integer :funcHeadSrc create\ or\ replace\ procedure\ proc12\(v_1\ refpkg.r1.a%Type\)} + plpgsql_depend_reftype | refpkg | 3 | r1 | {DependenciesType :typType c :typCategory C :attrInfo a:pg_catalog.int4,b:pg_catalog.int4, :isRel false :elemTypName <> :idxByTypName <>} +(2 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------------------+-------------+-------------------------+----------- + plpgsql_depend_reftype | null | proc12(pg_catalog.int4) | 4 + plpgsql_depend_reftype | pkg | r1 | 1 +(2 rows) + +--- define pkg rec --- +--undef_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c refpkg.undefr1%Type); + procedure proc1(); +end pkg; +/ +WARNING: Type r1 depends on an undefined type. +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Package created with compilation erors. +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------------------+-------------+------+-------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_reftype | null | 5 | proc12(pg_catalog.int4) | {DependenciesProchead :undefined false :proName proc12 :proArgSrc v_1\ integer :funcHeadSrc create\ or\ replace\ procedure\ proc12\(v_1\ refpkg.r1.a%Type\)} + plpgsql_depend_reftype | refpkg | 3 | r1 | {DependenciesType :typType c :typCategory C :attrInfo a:pg_catalog.int4,b:pg_catalog.int4, :isRel false :elemTypName <> :idxByTypName <>} + plpgsql_depend_reftype | refpkg | 2 | undefr1 | {DependenciesUndefined} +(3 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------------------+-------------+-------------------------+----------- + plpgsql_depend_reftype | null | proc12(pg_catalog.int4) | 4 + plpgsql_depend_reftype | pkg | r1 | 1 +(2 rows) + +--undef_rowtype_in_prochead +create or replace procedure proc12(v_1 refpkg.undefr1%Type) +as +begin + NULL; +end; +/ +WARNING: The header information of function proc12 is not defined. +CONTEXT: compilation of PL/pgSQL function "proc12" near line 1 +WARNING: Procedure created with compilation erors. +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------------------+-------------+------+------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------ + plpgsql_depend_reftype | null | 5 | proc12(pg_catalog.undefined) | {DependenciesProchead :undefined true :proName proc12 :proArgSrc v_1\ undefined :funcHeadSrc create\ or\ replace\ procedure\ proc12\(v_1\ refpkg.undefr1%Type\)} + plpgsql_depend_reftype | refpkg | 2 | undefr1 | {DependenciesUndefined} +(2 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------------------+-------------+------------------------------+----------- + plpgsql_depend_reftype | null | proc12(pg_catalog.undefined) | 4 + plpgsql_depend_reftype | pkg | r1 | 1 +(2 rows) + +drop package refpkg; +NOTICE: drop cascades to function plpgsql_depend_reftype.proc1() +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------------------+-------------+------+------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------ + plpgsql_depend_reftype | null | 5 | proc12(pg_catalog.undefined) | {DependenciesProchead :undefined true :proName proc12 :proArgSrc v_1\ undefined :funcHeadSrc create\ or\ replace\ procedure\ proc12\(v_1\ refpkg.undefr1%Type\)} + plpgsql_depend_reftype | refpkg | 2 | undefr1 | {DependenciesUndefined} +(2 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------------------+-------------+------------------------------+----------- + plpgsql_depend_reftype | null | proc12(pg_catalog.undefined) | 4 + plpgsql_depend_reftype | pkg | r1 | 1 +(2 rows) + +-- clean +drop schema plpgsql_depend_reftype cascade; +NOTICE: drop cascades to 3 other objects +--?.* +drop cascades to function plpgsql_depend_reftype.proc1() +drop cascades to function proc12(undefined) +reset behavior_compat_options; diff --git a/src/test/regress/expected/plpgsql_depend/plpgsql_depend_type.out b/src/test/regress/expected/plpgsql_depend/plpgsql_depend_type.out new file mode 100644 index 000000000..da5d26149 --- /dev/null +++ b/src/test/regress/expected/plpgsql_depend/plpgsql_depend_type.out @@ -0,0 +1,3240 @@ +drop schema if exists plpgsql_depend_type cascade; +NOTICE: schema "plpgsql_depend_type" does not exist, skipping +create schema plpgsql_depend_type; +set current_schema = plpgsql_depend_type; +set behavior_compat_options = 'plpgsql_dependency'; +-- prepare data table +create or replace function create_data_table returns int as $$ +begin +drop table if exists stu; +create table stu (sno int, name varchar, sex varchar, cno int); +insert into stu values(1,'zhang','M',1); +insert into stu values(1,'zhang','M',1); +insert into stu values(2,'wangwei','M',2); +insert into stu values(3,'liu','F',3); +return 1; +end; +$$ +LANGUAGE plpgsql; +-- drop data table +create or replace function drop_data_table returns int as $$ +begin +drop table if exists stu; +return 1; +end; +$$ +LANGUAGE plpgsql; +-- drop data table cascade +create or replace function drop_data_table_cascade returns int as $$ +begin +drop table if exists stu cascade; +return 1; +end; +$$ +LANGUAGE plpgsql; +-- test 0 pkg_record_undefine_schema_type +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + type r1 is record(a int, b sr); + procedure proc1; +end pkg; +/ +WARNING: Type sr does not exist. +LINE 1: PACKAGE DECLARE type r1 is record(a int, b sr); + ^ +QUERY: PACKAGE DECLARE type r1 is record(a int, b sr); + procedure proc1; +end +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Package created with compilation erors. +-- valid is false +select valid from pg_object where object_type='S' and object_oid in ( + select Oid from gs_package where pkgname='pkg' and pkgnamespace = ( + select Oid from pg_namespace where nspname = 'plpgsql_depend_type') + ); + valid +------- + f +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast +from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where ( + a.schemaname='plpgsql_depend_type' and a.packagename='pkg' +) or ( + b.schemaname='plpgsql_depend_type' and b.packagename='pkg' +) order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+----+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | pkg | r1 | 1 | plpgsql_depend_type | null | sr | 3 | {DependenciesUndefined} +(1 row) + +-- remove dependency, no rows +drop package pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast +from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where ( + a.schemaname='plpgsql_depend_type' and a.packagename='pkg' +) or ( + b.schemaname='plpgsql_depend_type' and b.packagename='pkg' +) order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 1 pkg_record_non_complete_define_schema_type +drop package if exists pkg2; +NOTICE: package pkg2() does not exist, skipping +create or replace package pkg2 +is + type r2 is record(a int, b sr); + procedure proc1; +end pkg2; +/ +WARNING: Type sr does not exist. +LINE 1: PACKAGE DECLARE type r2 is record(a int, b sr); + ^ +QUERY: PACKAGE DECLARE type r2 is record(a int, b sr); + procedure proc1; +end +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Package created with compilation erors. +create or replace package pkg +is + type r1 is record(a int, b pkg2.r2); + procedure proc1; +end pkg; +/ +--?.* +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Package created with compilation erors. +-- valid is false +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+----+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | pkg | r1 | 1 | plpgsql_depend_type | pkg2 | r2 | 3 | {DependenciesUndefined} +(1 row) + +-- remove ref dependency, undefined +drop package pkg2; +NOTICE: drop cascades to 2 other objects +--?.* +drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+----+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | pkg | r1 | 1 | plpgsql_depend_type | pkg2 | r2 | 3 | {DependenciesUndefined} +(1 row) + +-- remove dependency, no rows +drop package pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + + -- test 2 pkg_record_define_schema_type +drop type if exists sr cascade; +NOTICE: type "sr" does not exist, skipping +create type sr as (a int, b int); +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + type r1 is record(a int, b sr); + procedure proc1; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+----+--------+---------------------+-------+-------+-------+------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | pkg | r1 | 1 | plpgsql_depend_type | null | sr | 3 | {DependenciesType :typType c :typCategory C :attrInfo a:pg_catalog.int4,b:pg_catalog.int4, :isRel false :elemTypName <> :idxByTypName <>} +(1 row) + +-- remove ref dependency, undefined +drop type sr cascade; +--?.* +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+----+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | pkg | r1 | 1 | plpgsql_depend_type | null | sr | 3 | {DependenciesUndefined} +(1 row) + +-- remove dependency, no rows +drop package pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 3 pkg_tbl_undefine_schema_type +drop type if exists undefsr cascade; +NOTICE: type "undefsr" does not exist, skipping +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + type tf1 is table of undefsr index by binary_integer; + procedure proc1; +end pkg; +/ +WARNING: Type undefsr does not exist. +LINE 1: PACKAGE DECLARE type tf1 is table of undefsr index by bin... + ^ +QUERY: PACKAGE DECLARE type tf1 is table of undefsr index by binary_integer; + procedure proc1; +end +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Package created with compilation erors. +-- valid is false +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+-----+--------+---------------------+-------+---------+-------+------------------------- + plpgsql_depend_type | pkg | tf1 | 1 | plpgsql_depend_type | null | undefsr | 3 | {DependenciesUndefined} +(1 row) + +-- define ref dependency +create type undefsr as (a int, b int); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +drop type undefsr cascade; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- remove dependency, no rows +drop package pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 4 pkg_tbl_define_schema_type +drop type if exists sr cascade; +NOTICE: type "sr" does not exist, skipping +create type sr as (a int, b int); +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + type tf1 is table of sr index by binary_integer; + procedure proc1; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+-----+--------+---------------------+-------+-------+-------+------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | pkg | tf1 | 1 | plpgsql_depend_type | null | sr | 3 | {DependenciesType :typType c :typCategory C :attrInfo a:pg_catalog.int4,b:pg_catalog.int4, :isRel false :elemTypName <> :idxByTypName <>} +(1 row) + +-- remove dependency +drop type sr cascade; +NOTICE: drop cascades to type _sr[] +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- remove dependency +drop package pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 5 pkg_varray_undefine_schema_type +drop type if exists undefsr cascade; +NOTICE: type "undefsr" does not exist, skipping +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + type varr1 is varray(1024) of undefsr; + procedure proc1; +end pkg; +/ +WARNING: Type undefsr does not exist. +LINE 1: PACKAGE DECLARE type varr1 is varray(1024) of undefsr; + ^ +QUERY: PACKAGE DECLARE type varr1 is varray(1024) of undefsr; + procedure proc1; +end +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Package created with compilation erors. +-- valid is false +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+-------+--------+---------------------+-------+---------+-------+------------------------- + plpgsql_depend_type | pkg | varr1 | 1 | plpgsql_depend_type | null | undefsr | 3 | {DependenciesUndefined} +(1 row) + +-- define ref dependency +create type undefsr as (a int, b int); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +drop type undefsr cascade; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- remove dependency, no rows +drop package pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 6 pkg_varray_define_schema_type +drop type if exists sr cascade; +NOTICE: type "sr" does not exist, skipping +create type sr as (a int, b int); +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + type t_arr_sr is varray(999) of sr; + procedure proc1; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+----------+--------+---------------------+-------+-------+-------+------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | pkg | t_arr_sr | 1 | plpgsql_depend_type | null | sr | 3 | {DependenciesType :typType c :typCategory C :attrInfo a:pg_catalog.int4,b:pg_catalog.int4, :isRel false :elemTypName <> :idxByTypName <>} +(1 row) + +-- define ref dependency +drop type sr cascade; +NOTICE: drop cascades to type sr[] +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- remove dependency, no rows +drop package pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 7 pkg_tbl_undefine_pkg_type +drop package if exists pkg2; +NOTICE: package pkg2() does not exist, skipping +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + type tf1 is table of pkg2.r1 index by binary_integer; + procedure proc1; +end pkg; +/ +WARNING: Type r1 does not exist. +LINE 1: PACKAGE DECLARE type tf1 is table of pkg2.r1 index by bin... + ^ +QUERY: PACKAGE DECLARE type tf1 is table of pkg2.r1 index by binary_integer; + procedure proc1; +end +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Package created with compilation erors. +-- valid is false +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+-----+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | pkg | tf1 | 1 | plpgsql_depend_type | pkg2 | r1 | 3 | {DependenciesUndefined} +(1 row) + +-- remove dependency +drop package pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 8 pkg_tbl_define_pkg_type +drop package if exists pkg2; +NOTICE: package pkg2() does not exist, skipping +create or replace package pkg2 +is + type r1 is record(a int, b int); + procedure proc1; +end pkg2; +/ +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + type tf1 is table of pkg2.r1 index by binary_integer; + procedure proc1; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+-----+--------+---------------------+-------+-------+-------+------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | pkg | tf1 | 1 | plpgsql_depend_type | pkg2 | r1 | 3 | {DependenciesType :typType c :typCategory C :attrInfo a:pg_catalog.int4,b:pg_catalog.int4, :isRel false :elemTypName <> :idxByTypName <>} +(1 row) + +-- define ref dependency +drop package pkg2; +NOTICE: drop cascades to 2 other objects +--?.* +drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- remove dependency, no rows +drop package pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 9 pkg_varray_undefine_pkg_type +drop package if exists pkg2; +NOTICE: package pkg2() does not exist, skipping +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + type t_arr_sr is varray(999) of pkg2.r1; + procedure proc1; +end pkg; +/ +WARNING: Type r1 does not exist. +LINE 1: PACKAGE DECLARE type t_arr_sr is varray(999) of pkg2.r1; + ^ +QUERY: PACKAGE DECLARE type t_arr_sr is varray(999) of pkg2.r1; + procedure proc1; +end +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Package created with compilation erors. +-- valid is false +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+----------+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | pkg | t_arr_sr | 1 | plpgsql_depend_type | pkg2 | r1 | 3 | {DependenciesUndefined} +(1 row) + +-- remove dependency +drop package pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 10 pkg_varray_define_pkg_type +drop package if exists pkg2; +NOTICE: package pkg2() does not exist, skipping +create or replace package pkg2 +is + type r1 is record(a int, b int); + procedure proc1; +end pkg2; +/ +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + type tf1 is varray(999) of pkg2.r1; + procedure proc1; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+-----+--------+---------------------+-------+-------+-------+------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | pkg | tf1 | 1 | plpgsql_depend_type | pkg2 | r1 | 3 | {DependenciesType :typType c :typCategory C :attrInfo a:pg_catalog.int4,b:pg_catalog.int4, :isRel false :elemTypName <> :idxByTypName <>} +(1 row) + +-- define ref dependency +drop package pkg2; +NOTICE: drop cascades to 2 other objects +--?.* +drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- remove dependency, no rows +drop package pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 11 pkg_record_undefine_table_rowtype +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + type r1 is record(a int, c undefStu%RowType); + procedure proc1; +end pkg; +/ +WARNING: relation "undefstu" does not exist when parse word. +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Type r1 depends on an undefined type. +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Package created with compilation erors. +-- valid is false +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+----+--------+---------------------+-------+----------+-------+------------------------- + plpgsql_depend_type | pkg | r1 | 1 | plpgsql_depend_type | null | undefstu | 3 | {DependenciesUndefined} +(1 row) + +-- remove dependency +drop package pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 12 pkg_record_define_table_rowtype +select create_data_table(); +NOTICE: table "stu" does not exist, skipping +CONTEXT: SQL statement "drop table if exists stu" +PL/pgSQL function create_data_table() line 3 at SQL statement +referenced column: create_data_table + create_data_table +------------------- + 1 +(1 row) + +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + type r1 is record(a int, c stu%RowType); + procedure proc1; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+----+--------+---------------------+-------+-------+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | pkg | r1 | 1 | plpgsql_depend_type | null | stu | 3 | {DependenciesType :typType c :typCategory C :attrInfo sno:pg_catalog.int4,name:pg_catalog.varchar,sex:pg_catalog.varchar,cno:pg_catalog.int4, :isRel true :elemTypName <> :idxByTypName <>} +(1 row) + +alter table stu add column z int; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+----+--------+---------------------+-------+-------+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | pkg | r1 | 1 | plpgsql_depend_type | null | stu | 3 | {DependenciesType :typType c :typCategory C :attrInfo sno:pg_catalog.int4,name:pg_catalog.varchar,sex:pg_catalog.varchar,cno:pg_catalog.int4,z:pg_catalog.int4, :isRel true :elemTypName <> :idxByTypName <>} +(1 row) + +alter package pkg compile; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+----+--------+---------------------+-------+-------+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | pkg | r1 | 1 | plpgsql_depend_type | null | stu | 3 | {DependenciesType :typType c :typCategory C :attrInfo sno:pg_catalog.int4,name:pg_catalog.varchar,sex:pg_catalog.varchar,cno:pg_catalog.int4,z:pg_catalog.int4, :isRel true :elemTypName <> :idxByTypName <>} +(1 row) + +alter table stu drop column z; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+----+--------+---------------------+-------+-------+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | pkg | r1 | 1 | plpgsql_depend_type | null | stu | 3 | {DependenciesType :typType c :typCategory C :attrInfo sno:pg_catalog.int4,name:pg_catalog.varchar,sex:pg_catalog.varchar,cno:pg_catalog.int4, :isRel true :elemTypName <> :idxByTypName <>} +(1 row) + +alter package pkg compile; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+----+--------+---------------------+-------+-------+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | pkg | r1 | 1 | plpgsql_depend_type | null | stu | 3 | {DependenciesType :typType c :typCategory C :attrInfo sno:pg_catalog.int4,name:pg_catalog.varchar,sex:pg_catalog.varchar,cno:pg_catalog.int4, :isRel true :elemTypName <> :idxByTypName <>} +(1 row) + +alter table stu rename to newstu; +ERROR: The rename operator on stu is not allowed, because it is dependent on another object. +-- remove dependency, no drop +select drop_data_table(); +ERROR: cannot drop table stu because other objects depend on it +--?.* +HINT: Use DROP ... CASCADE to drop the dependent objects too. +CONTEXT: SQL statement "drop table if exists stu" +PL/pgSQL function drop_data_table() line 3 at SQL statement +referenced column: drop_data_table +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+----+--------+---------------------+-------+-------+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | pkg | r1 | 1 | plpgsql_depend_type | null | stu | 3 | {DependenciesType :typType c :typCategory C :attrInfo sno:pg_catalog.int4,name:pg_catalog.varchar,sex:pg_catalog.varchar,cno:pg_catalog.int4, :isRel true :elemTypName <> :idxByTypName <>} +(1 row) + +-- remove dependency, undefined +select drop_data_table_cascade(); +--?.* +CONTEXT: SQL statement "drop table if exists stu cascade" +PL/pgSQL function drop_data_table_cascade() line 3 at SQL statement +referenced column: drop_data_table_cascade + drop_data_table_cascade +------------------------- + 1 +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+----+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | pkg | r1 | 1 | plpgsql_depend_type | null | stu | 3 | {DependenciesUndefined} +(1 row) + +-- remove dependency, no rows +drop package pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 13 pkg_record_undefine_table_undefine_col_type +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + type r1 is record(a int, c undefStu.undefname%Type); + procedure proc1; +end pkg; +/ +WARNING: invalid type name "undefStu.undefname%Type" +LINE 1: PACKAGE DECLARE type r1 is record(a int, c undefStu.undef... + ^ +QUERY: PACKAGE DECLARE type r1 is record(a int, c undefStu.undefname%Type); + procedure proc1; +end +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Package created with compilation erors. +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- remove dependency, no rows +drop package pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 14 pkg_record_define_table_undefine_col_type +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + type r1 is record(a int, c stu.undefname%Type); + procedure proc1; +end pkg; +/ +WARNING: invalid type name "stu.undefname%Type" +LINE 1: PACKAGE DECLARE type r1 is record(a int, c stu.undefname%... + ^ +QUERY: PACKAGE DECLARE type r1 is record(a int, c stu.undefname%Type); + procedure proc1; +end +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Package created with compilation erors. +-- valid is false +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- remove dependency, no rows +drop package pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 15 pkg_record_define_table_col_type +select create_data_table(); +NOTICE: table "stu" does not exist, skipping +CONTEXT: SQL statement "drop table if exists stu" +PL/pgSQL function create_data_table() line 3 at SQL statement +referenced column: create_data_table + create_data_table +------------------- + 1 +(1 row) + +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + type r1 is record(a int, c stu.name%Type); + procedure proc1; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+----+--------+---------------------+-------+-------+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | pkg | r1 | 1 | plpgsql_depend_type | null | stu | 3 | {DependenciesType :typType c :typCategory C :attrInfo sno:pg_catalog.int4,name:pg_catalog.varchar,sex:pg_catalog.varchar,cno:pg_catalog.int4, :isRel true :elemTypName <> :idxByTypName <>} +(1 row) + +-- remove dependency, undefined +select drop_data_table(); + drop_data_table +----------------- + 1 +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+----+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | pkg | r1 | 1 | plpgsql_depend_type | null | stu | 3 | {DependenciesUndefined} +(1 row) + +-- remove dependency, no rows +drop package pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 16 pkg_record_define_pkg_v1_type +drop package if exists pkg2; +NOTICE: package pkg2() does not exist, skipping +create or replace package pkg2 +is + v1 int; + procedure proc1; +end pkg2; +/ +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + type r1 is record(a int, c pkg2.v1%Type); + procedure proc1; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+----+--------+---------------------+-------+-------+-------+-------------------------------------------------------------------------- + plpgsql_depend_type | pkg | r1 | 1 | plpgsql_depend_type | pkg2 | v1 | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +-- define ref dependency, undefined +drop package pkg2; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+----+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | pkg | r1 | 1 | plpgsql_depend_type | pkg2 | v1 | 2 | {DependenciesUndefined} +(1 row) + +-- remove dependency, no rows +drop package pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 16 pkg_record_define_pkg_r1_rowtype +drop package if exists pkg2; +NOTICE: package pkg2() does not exist, skipping +create or replace package pkg2 +is + type r2 is record(a int, b int); + procedure proc1; +end pkg2; +/ +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + type r1 is record(a int, c pkg2.r2%RowType); + procedure proc1; +end pkg; +/ +ERROR: schema "pkg2" does not exist +CONTEXT: compilation of PL/pgSQL package near line 1 +-- compile error +-- valid is none +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- define ref dependency +drop package pkg2; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- remove dependency, no rows +drop package pkg; +ERROR: package pkg does not exist +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 17 pkg_record_define_schema_pkg_r1_rowtype +drop package if exists pkg2; +NOTICE: package pkg2() does not exist, skipping +create or replace package pkg2 +is + type r2 is record(a int, b int); + procedure proc1; +end pkg2; +/ +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + type r1 is record(a int, c plpgsql_depend_type.pkg2.r2%RowType); + procedure proc1; +end pkg; +/ +ERROR: cross-database references are not implemented: "plpgsql_depend_type.pkg2.r2" +CONTEXT: compilation of PL/pgSQL package near line 1 +-- compile error +-- valid is none +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- define ref dependency +drop package pkg2; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- remove dependency, no rows +drop package pkg; +ERROR: package pkg does not exist +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 18 pkg_body_record_define_schema +drop type if exists sr cascade; +NOTICE: type "sr" does not exist, skipping +create type sr as (a int, b int); +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + function proc1() return int; +end pkg; +/ +create or replace package body pkg +is + type r1 is record(a int, b sr); + function proc1() return int as + begin + return 1; + end; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+----+--------+---------------------+-------+-------+-------+------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | pkg | r1 | 1 | plpgsql_depend_type | null | sr | 3 | {DependenciesType :typType c :typCategory C :attrInfo a:pg_catalog.int4,b:pg_catalog.int4, :isRel false :elemTypName <> :idxByTypName <>} +(1 row) + +-- define ref dependency +drop type sr cascade; +--?.* +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+----+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | pkg | r1 | 1 | plpgsql_depend_type | null | sr | 3 | {DependenciesUndefined} +(1 row) + +-- remove dependency, no rows +drop package pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 19 pkg_body_tableof_define_schema +drop type if exists sr cascade; +NOTICE: type "sr" does not exist, skipping +create type sr as (a int, b int); +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + function proc1() return int; +end pkg; +/ +create or replace package body pkg +is + type tf1 is table of sr index by binary_integer; + function proc1() return int as + begin + return 1; + end; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+-----+--------+---------------------+-------+-------+-------+------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | pkg | tf1 | 1 | plpgsql_depend_type | null | sr | 3 | {DependenciesType :typType c :typCategory C :attrInfo a:pg_catalog.int4,b:pg_catalog.int4, :isRel false :elemTypName <> :idxByTypName <>} +(1 row) + +-- define ref dependency +drop type sr cascade; +NOTICE: drop cascades to type _sr[] +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- remove dependency, no rows +drop package pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 20 pkg_body_varray_define_schema +drop type if exists sr cascade; +NOTICE: type "sr" does not exist, skipping +create type sr as (a int, b int); +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + function proc1() return int; +end pkg; +/ +create or replace package body pkg +is + type t_arr_sr is varray(999) of sr; + function proc1() return int as + begin + return 1; + end; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+----------+--------+---------------------+-------+-------+-------+------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | pkg | t_arr_sr | 1 | plpgsql_depend_type | null | sr | 3 | {DependenciesType :typType c :typCategory C :attrInfo a:pg_catalog.int4,b:pg_catalog.int4, :isRel false :elemTypName <> :idxByTypName <>} +(1 row) + +-- define ref dependency +drop type sr cascade; +NOTICE: drop cascades to type sr[] +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- remove dependency, no rows +drop package pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 21 pkg_body_record_undefine_schema_type +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + function proc1() return int; +end pkg; +/ +create or replace package body pkg +is + type t_arr_sr is varray(999) of undefsr; + function proc1() return int as + begin + return 1; + end; +end pkg; +/ +WARNING: Type undefsr does not exist. +LINE 1: PACKAGE DECLARE type t_arr_sr is varray(999) of undefsr; + ^ +QUERY: PACKAGE DECLARE type t_arr_sr is varray(999) of undefsr; + function proc1() return int as + begin + return 1; + end; +end +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Package Body created with compilation erors. +-- valid is false +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+----------+--------+---------------------+-------+---------+-------+------------------------- + plpgsql_depend_type | pkg | t_arr_sr | 1 | plpgsql_depend_type | null | undefsr | 3 | {DependenciesUndefined} +(1 row) + +-- remove dependency, no rows +drop package pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 22 pkg_spec_var_used_undefine_pkg_type +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + v_1 pkg2.r1; + procedure proc1; +end pkg; +/ +WARNING: Type r1 does not exist. +LINE 1: PACKAGE DECLARE v_1 pkg2.r1; + ^ +QUERY: PACKAGE DECLARE v_1 pkg2.r1; + procedure proc1; +end +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Package created with compilation erors. +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+-----+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | pkg | pkg | 2 | plpgsql_depend_type | pkg2 | r1 | 3 | {DependenciesUndefined} +(1 row) + +-- define ref dependency +drop package pkg2; +ERROR: package pkg2 does not exist +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+-----+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | pkg | pkg | 2 | plpgsql_depend_type | pkg2 | r1 | 3 | {DependenciesUndefined} +(1 row) + +-- remove dependency, no rows +drop package pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 23 pkg_spec_var_used_define_schema_type +drop type if exists sr cascade; +NOTICE: type "sr" does not exist, skipping +create type sr as (a int, b int); +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + v_1 sr; + procedure proc1; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+-----+--------+---------------------+-------+-------+-------+------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | pkg | pkg | 2 | plpgsql_depend_type | null | sr | 3 | {DependenciesType :typType c :typCategory C :attrInfo a:pg_catalog.int4,b:pg_catalog.int4, :isRel false :elemTypName <> :idxByTypName <>} +(1 row) + +-- define ref dependency +drop type sr cascade; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+-----+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | pkg | pkg | 2 | plpgsql_depend_type | null | sr | 3 | {DependenciesUndefined} +(1 row) + +-- remove dependency, no rows +drop package pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 24 pkg_body_var_used_define_schema_type +drop type if exists sr cascade; +NOTICE: type "sr" does not exist, skipping +create type sr as(a int, b int); +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + procedure proc1; +end pkg; +/ +create or replace package body pkg +is + v_1 sr; + procedure proc1() as begin null; end; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+-----+--------+---------------------+-------+-------+-------+------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | pkg | pkg | 16 | plpgsql_depend_type | null | sr | 3 | {DependenciesType :typType c :typCategory C :attrInfo a:pg_catalog.int4,b:pg_catalog.int4, :isRel false :elemTypName <> :idxByTypName <>} +(1 row) + +-- define ref dependency +drop type sr cascade; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+-----+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | pkg | pkg | 16 | plpgsql_depend_type | null | sr | 3 | {DependenciesUndefined} +(1 row) + +-- remove dependency, no rows +drop package pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 25 pkg_proc_body_var_used_define_schema_type +drop type if exists sr cascade; +NOTICE: type "sr" does not exist, skipping +create type sr as(a int, b int); +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + procedure proc1; +end pkg; +/ +create or replace package body pkg +is + procedure proc1() as + declare + v_1 sr; + begin null; end; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+-----+--------+---------------------+-------+-------+-------+------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | pkg | pkg | 16 | plpgsql_depend_type | null | sr | 3 | {DependenciesType :typType c :typCategory C :attrInfo a:pg_catalog.int4,b:pg_catalog.int4, :isRel false :elemTypName <> :idxByTypName <>} +(1 row) + +-- define ref dependency, undefined +drop type sr cascade; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+-----+-----+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | pkg | pkg | 16 | plpgsql_depend_type | null | sr | 3 | {DependenciesUndefined} +(1 row) + +-- remove dependency, no rows +drop package pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 26 proc_body_var_used_define_schema_type +drop type if exists sr cascade; +NOTICE: type "sr" does not exist, skipping +create type sr as(a int, b int); +drop procedure if exists proc1; +NOTICE: function proc1() does not exist, skipping +create or replace procedure proc1() as +declare + v_1 sr; +begin + null; +end; +/ +-- valid is true +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+---------+--------+---------------------+-------+-------+-------+------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | proc1() | 8 | plpgsql_depend_type | null | sr | 3 | {DependenciesType :typType c :typCategory C :attrInfo a:pg_catalog.int4,b:pg_catalog.int4, :isRel false :elemTypName <> :idxByTypName <>} +(1 row) + +-- define ref dependency +drop type sr cascade; +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+---------+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | null | proc1() | 8 | plpgsql_depend_type | null | sr | 3 | {DependenciesUndefined} +(1 row) + +-- remove dependency, no rows +drop procedure proc1; +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + + -- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- test 27 proc_body_var_used_define_pkg_tablof +drop type if exists sr cascade; +NOTICE: type "sr" does not exist, skipping +create type sr as(a int, b int); +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + type tf1 is table of sr index by binary_integer; +end pkg; +/ +drop procedure if exists proc1; +NOTICE: function proc1() does not exist, skipping +create or replace procedure proc1() as +declare + v_tf1 pkg.tf1; +begin + null; +end; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+---------+--------+---------------------+-------+-------+-------+------------------------------------------------------------------------------------------------------------------------------------------ + plpgsql_depend_type | null | proc1() | 8 | plpgsql_depend_type | pkg | tf1 | 3 | {DependenciesType :typType o :typCategory F :attrInfo <> :isRel false :elemTypName plpgsql_depend_type.sr :idxByTypName pg_catalog.int4} +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+---------+--------+---------------------+-------+-------+-------+------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | proc1() | 8 | plpgsql_depend_type | pkg | tf1 | 3 | {DependenciesType :typType o :typCategory F :attrInfo <> :isRel false :elemTypName plpgsql_depend_type.sr :idxByTypName pg_catalog.int4} + plpgsql_depend_type | pkg | tf1 | 1 | plpgsql_depend_type | null | sr | 3 | {DependenciesType :typType c :typCategory C :attrInfo a:pg_catalog.int4,b:pg_catalog.int4, :isRel false :elemTypName <> :idxByTypName <>} +(2 rows) + +-- drop ref dependency +drop type sr cascade; +NOTICE: drop cascades to type _sr[] +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+---------+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | null | proc1() | 8 | plpgsql_depend_type | pkg | tf1 | 3 | {DependenciesUndefined} +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+---------+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | null | proc1() | 8 | plpgsql_depend_type | pkg | tf1 | 3 | {DependenciesUndefined} +(1 row) + +-- remove dependency +drop package pkg; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+---------+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | null | proc1() | 8 | plpgsql_depend_type | pkg | tf1 | 3 | {DependenciesUndefined} +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+---------+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | null | proc1() | 8 | plpgsql_depend_type | pkg | tf1 | 3 | {DependenciesUndefined} +(1 row) + +-- remove dependency, no rows +drop procedure proc1; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 28 proc_body_var_used_define_pkg_varray +drop type if exists sr cascade; +NOTICE: type "sr" does not exist, skipping +create type sr as(a int, b int); +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + type arr1 is varray(888) of sr; + type tf1 is table of sr index by binary_integer; +end pkg; +/ +drop procedure if exists proc1; +NOTICE: function proc1() does not exist, skipping +create or replace procedure proc1() as +declare + v_arr1 pkg.arr1; + v_tf1 pkg.tf1; +begin + null; +end; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+---------+--------+---------------------+-------+-------+-------+------------------------------------------------------------------------------------------------------------------------------------------ + plpgsql_depend_type | null | proc1() | 8 | plpgsql_depend_type | pkg | arr1 | 3 | {DependenciesType :typType b :typCategory A :attrInfo <> :isRel false :elemTypName plpgsql_depend_type.sr :idxByTypName <>} + plpgsql_depend_type | null | proc1() | 8 | plpgsql_depend_type | pkg | tf1 | 3 | {DependenciesType :typType o :typCategory F :attrInfo <> :isRel false :elemTypName plpgsql_depend_type.sr :idxByTypName pg_catalog.int4} +(2 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+---------+--------+---------------------+-------+-------+-------+------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | pkg | arr1 | 1 | plpgsql_depend_type | null | sr | 3 | {DependenciesType :typType c :typCategory C :attrInfo a:pg_catalog.int4,b:pg_catalog.int4, :isRel false :elemTypName <> :idxByTypName <>} + plpgsql_depend_type | null | proc1() | 8 | plpgsql_depend_type | pkg | arr1 | 3 | {DependenciesType :typType b :typCategory A :attrInfo <> :isRel false :elemTypName plpgsql_depend_type.sr :idxByTypName <>} + plpgsql_depend_type | null | proc1() | 8 | plpgsql_depend_type | pkg | tf1 | 3 | {DependenciesType :typType o :typCategory F :attrInfo <> :isRel false :elemTypName plpgsql_depend_type.sr :idxByTypName pg_catalog.int4} + plpgsql_depend_type | pkg | tf1 | 1 | plpgsql_depend_type | null | sr | 3 | {DependenciesType :typType c :typCategory C :attrInfo a:pg_catalog.int4,b:pg_catalog.int4, :isRel false :elemTypName <> :idxByTypName <>} +(4 rows) + +-- drop ref dependency +drop type sr cascade; +NOTICE: drop cascades to 2 other objects +DETAIL: drop cascades to type _sr[] +drop cascades to type sr[] +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+---------+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | null | proc1() | 8 | plpgsql_depend_type | pkg | arr1 | 3 | {DependenciesUndefined} + plpgsql_depend_type | null | proc1() | 8 | plpgsql_depend_type | pkg | tf1 | 3 | {DependenciesUndefined} +(2 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+---------+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | null | proc1() | 8 | plpgsql_depend_type | pkg | arr1 | 3 | {DependenciesUndefined} + plpgsql_depend_type | null | proc1() | 8 | plpgsql_depend_type | pkg | tf1 | 3 | {DependenciesUndefined} +(2 rows) + +-- remove ref dependency +drop package pkg; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+---------+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | null | proc1() | 8 | plpgsql_depend_type | pkg | arr1 | 3 | {DependenciesUndefined} + plpgsql_depend_type | null | proc1() | 8 | plpgsql_depend_type | pkg | tf1 | 3 | {DependenciesUndefined} +(2 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+---------+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | null | proc1() | 8 | plpgsql_depend_type | pkg | arr1 | 3 | {DependenciesUndefined} + plpgsql_depend_type | null | proc1() | 8 | plpgsql_depend_type | pkg | tf1 | 3 | {DependenciesUndefined} +(2 rows) + +-- remove dependency, no rows +drop procedure proc1; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 29 proc_param_type_used_define_schema_type +drop type if exists sr cascade; +NOTICE: type "sr" does not exist, skipping +create type sr as(a int, b int); +drop procedure if exists proc1; +NOTICE: function proc1() does not exist, skipping +create or replace procedure proc1(v_1 sr) as +begin + null; +end; +/ +-- valid is true +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.sr)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.sr)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+-------------------------------+--------+---------------------+-------+-------------------------------+-------+------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | proc1(plpgsql_depend_type.sr) | 4 | plpgsql_depend_type | null | sr | 3 | {DependenciesType :typType c :typCategory C :attrInfo a:pg_catalog.int4,b:pg_catalog.int4, :isRel false :elemTypName <> :idxByTypName <>} + | | | | plpgsql_depend_type | null | proc1(plpgsql_depend_type.sr) | 5 | {DependenciesProchead :undefined false :proName proc1 :proArgSrc v_1\ sr :funcHeadSrc create\ or\ replace\ procedure\ proc1\(v_1\ sr\)} +(2 rows) + +-- define ref dependency +drop type sr cascade; +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + proname | valid | proargtypes | proargsrc +---------+-------+-------------+----------- + proc1 | f | 4408 | v_1 sr +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(pg_catalog.undefined)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(pg_catalog.undefined)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+-----------------------------+--------+---------------------+-------+-----------------------------+-------+---------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | proc1(pg_catalog.undefined) | 4 | plpgsql_depend_type | null | sr | 3 | {DependenciesUndefined} + | | | | plpgsql_depend_type | null | proc1(pg_catalog.undefined) | 5 | {DependenciesProchead :undefined true :proName proc1 :proArgSrc v_1\ sr :funcHeadSrc create\ or\ replace\ procedure\ proc1\(v_1\ sr\)} +(2 rows) + + -- create ref dependency +create type sr as (a int, b int); +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + proname | valid | proargtypes | proargsrc +---------+-------+-------------+----------- +--?.* +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.sr)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.sr)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+-------------------------------+--------+---------------------+-------+-------------------------------+-------+------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | proc1(plpgsql_depend_type.sr) | 4 | plpgsql_depend_type | null | sr | 3 | {DependenciesType :typType c :typCategory C :attrInfo a:pg_catalog.int4,b:pg_catalog.int4, :isRel false :elemTypName <> :idxByTypName <>} + | | | | plpgsql_depend_type | null | proc1(plpgsql_depend_type.sr) | 5 | {DependenciesProchead :undefined false :proName proc1 :proArgSrc v_1\ sr :funcHeadSrc create\ or\ replace\ procedure\ proc1\(v_1\ sr\)} +(2 rows) + +-- remove dependency, no rows +drop procedure proc1; +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.sr)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.sr)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + + -- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 30 proc_return_type_used_define_schema_type +drop type if exists sr cascade; +create type sr as(a int, b int); +drop function if exists proc1; +NOTICE: function proc1() does not exist, skipping +create or replace function proc1() return sr as +begin + null; +end; +/ +-- valid is true +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+---------+--------+---------------------+-------+---------+-------+------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | proc1() | 4 | plpgsql_depend_type | null | sr | 3 | {DependenciesType :typType c :typCategory C :attrInfo a:pg_catalog.int4,b:pg_catalog.int4, :isRel false :elemTypName <> :idxByTypName <>} + | | | | plpgsql_depend_type | null | proc1() | 5 | {DependenciesProchead :undefined false :proName proc1 :proArgSrc <> :funcHeadSrc create\ or\ replace\ function\ proc1\(\)\ return\ sr} +(2 rows) + +-- remove ref dependency +drop type sr cascade; +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + proname | valid | proargtypes | proargsrc +---------+-------+-------------+----------- + proc1 | f | | +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+---------+--------+---------------------+-------+---------+-------+--------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | proc1() | 4 | plpgsql_depend_type | null | sr | 3 | {DependenciesUndefined} + | | | | plpgsql_depend_type | null | proc1() | 5 | {DependenciesProchead :undefined true :proName proc1 :proArgSrc <> :funcHeadSrc create\ or\ replace\ function\ proc1\(\)\ return\ sr} +(2 rows) + + -- create ref dependency +create type sr as (a int, b int); +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + proname | valid | proargtypes | proargsrc +---------+-------+-------------+----------- + proc1 | f | | +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+---------+--------+---------------------+-------+---------+-------+------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | proc1() | 4 | plpgsql_depend_type | null | sr | 3 | {DependenciesType :typType c :typCategory C :attrInfo a:pg_catalog.int4,b:pg_catalog.int4, :isRel false :elemTypName <> :idxByTypName <>} + | | | | plpgsql_depend_type | null | proc1() | 5 | {DependenciesProchead :undefined false :proName proc1 :proArgSrc <> :funcHeadSrc create\ or\ replace\ function\ proc1\(\)\ return\ sr} +(2 rows) + +-- remove dependency, no rows +drop function proc1; +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + + -- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 31 proc_param_type_used_undefine_schema_type +drop type if exists sr cascade; +drop procedure if exists proc1; +NOTICE: function proc1() does not exist, skipping +create or replace procedure proc1(v_1 sr) as +begin + null; +end; +/ +WARNING: Type sr does not exist. +WARNING: Type proc1(pg_catalog.undefined) depends on an undefined type. +WARNING: The header information of function proc1 is not defined. +CONTEXT: compilation of PL/pgSQL function "proc1" near line 1 +WARNING: Procedure created with compilation erors. +-- valid is false +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(pg_catalog.undefined)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(pg_catalog.undefined)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+-----------------------------+--------+---------------------+-------+-----------------------------+-------+---------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | proc1(pg_catalog.undefined) | 4 | plpgsql_depend_type | null | sr | 3 | {DependenciesUndefined} + | | | | plpgsql_depend_type | null | proc1(pg_catalog.undefined) | 5 | {DependenciesProchead :undefined true :proName proc1 :proArgSrc v_1\ sr :funcHeadSrc create\ or\ replace\ procedure\ proc1\(v_1\ sr\)} +(2 rows) + +-- create ref dependency +create type sr as (a int, b int); +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on +po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = +(select Oid from pg_namespace where nspname='plpgsql_depend_type'); + proname | valid | proargtypes | proargsrc +---------+-------+-------------+----------- +--?.* +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.sr)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.sr)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+-------------------------------+--------+---------------------+-------+-------------------------------+-------+------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | proc1(plpgsql_depend_type.sr) | 4 | plpgsql_depend_type | null | sr | 3 | {DependenciesType :typType c :typCategory C :attrInfo a:pg_catalog.int4,b:pg_catalog.int4, :isRel false :elemTypName <> :idxByTypName <>} + | | | | plpgsql_depend_type | null | proc1(plpgsql_depend_type.sr) | 5 | {DependenciesProchead :undefined false :proName proc1 :proArgSrc v_1\ sr :funcHeadSrc create\ or\ replace\ procedure\ proc1\(v_1\ sr\)} +(2 rows) + +-- define ref dependency +alter procedure proc1 compile; +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + proname | valid | proargtypes | proargsrc +---------+-------+-------------+----------- +--?.* +(1 row) + +drop type sr cascade; +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + proname | valid | proargtypes | proargsrc +---------+-------+-------------+----------- + proc1 | f | 4408 | v_1 sr +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(pg_catalog.undefined)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(pg_catalog.undefined)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+-----------------------------+--------+---------------------+-------+-----------------------------+-------+---------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | proc1(pg_catalog.undefined) | 4 | plpgsql_depend_type | null | sr | 3 | {DependenciesUndefined} + | | | | plpgsql_depend_type | null | proc1(pg_catalog.undefined) | 5 | {DependenciesProchead :undefined true :proName proc1 :proArgSrc v_1\ sr :funcHeadSrc create\ or\ replace\ procedure\ proc1\(v_1\ sr\)} +(2 rows) + +-- remove dependency, no rows +drop procedure proc1; +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.sr)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.sr)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + + -- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos + from gs_dependencies where schemaname='plpgsql_depend_type' + order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 32 proc_return_type_used_undefine_schema_type +drop type if exists sr cascade; +NOTICE: type "sr" does not exist, skipping +drop function if exists proc1; +NOTICE: function proc1() does not exist, skipping +create or replace function proc1() return sr as +begin + null; +end; +/ +WARNING: Type sr does not exist. +WARNING: type "sr" does not exist +WARNING: Type proc1() depends on an undefined type. +WARNING: The header information of function proc1 is not defined. +CONTEXT: compilation of PL/pgSQL function "proc1" near line 1 +WARNING: Function created with compilation erors. +-- valid is false +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+---------+--------+---------------------+-------+---------+-------+--------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | proc1() | 4 | plpgsql_depend_type | null | sr | 3 | {DependenciesUndefined} + | | | | plpgsql_depend_type | null | proc1() | 5 | {DependenciesProchead :undefined true :proName proc1 :proArgSrc <> :funcHeadSrc create\ or\ replace\ function\ proc1\(\)\ return\ sr} +(2 rows) + +-- create ref dependency +create type sr as (a int, b int); +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + proname | valid | proargtypes | proargsrc +---------+-------+-------------+----------- + proc1 | f | | +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+---------+--------+---------------------+-------+---------+-------+------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | proc1() | 4 | plpgsql_depend_type | null | sr | 3 | {DependenciesType :typType c :typCategory C :attrInfo a:pg_catalog.int4,b:pg_catalog.int4, :isRel false :elemTypName <> :idxByTypName <>} + | | | | plpgsql_depend_type | null | proc1() | 5 | {DependenciesProchead :undefined false :proName proc1 :proArgSrc <> :funcHeadSrc create\ or\ replace\ function\ proc1\(\)\ return\ sr} +(2 rows) + +-- remove dependency +drop type sr cascade; +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + proname | valid | proargtypes | proargsrc +---------+-------+-------------+----------- + proc1 | f | | +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+---------+--------+---------------------+-------+---------+-------+--------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | proc1() | 4 | plpgsql_depend_type | null | sr | 3 | {DependenciesUndefined} + | | | | plpgsql_depend_type | null | proc1() | 5 | {DependenciesProchead :undefined true :proName proc1 :proArgSrc <> :funcHeadSrc create\ or\ replace\ function\ proc1\(\)\ return\ sr} +(2 rows) + +-- remove dependency, no rows +drop procedure proc1; +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + + -- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +--test 33 proc_param_type_used_define_pkg_type +drop type if exists sr cascade; +NOTICE: type "sr" does not exist, skipping +create type sr as (a int, b int); +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is + type arr1 is varray(888) of sr; + type tf1 is table of sr index by binary_integer; + procedure proc1; +end pkg; +/ +drop procedure if exists proc1; +NOTICE: function proc1() does not exist, skipping +create or replace procedure proc1(v_1 pkg.arr1) as +begin + null; +end; +/ +-- valid is true +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + t +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.pkg.arr1)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.pkg.arr1)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+-------------------------------------+--------+---------------------+-------+-------------------------------------+-------+----------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | proc1(plpgsql_depend_type.pkg.arr1) | 4 | plpgsql_depend_type | pkg | arr1 | 3 | {DependenciesType :typType b :typCategory A :attrInfo <> :isRel false :elemTypName plpgsql_depend_type.sr :idxByTypName <>} + | | | | plpgsql_depend_type | null | proc1(plpgsql_depend_type.pkg.arr1) | 5 | {DependenciesProchead :undefined false :proName proc1 :proArgSrc v_1\ pkg.arr1 :funcHeadSrc create\ or\ replace\ procedure\ proc1\(v_1\ pkg.arr1\)} +(2 rows) + + -- remove ref dependency +create or replace package pkg +is + type tf1 is table of sr index by binary_integer; + procedure proc1; +end pkg; +/ +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + proname | valid | proargtypes | proargsrc +---------+-------+-------------+-------------- + proc1 | f | 4408 | v_1 pkg.arr1 +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(pg_catalog.undefined)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(pg_catalog.undefined)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+-----------------------------+--------+---------------------+-------+-----------------------------+-------+---------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | proc1(pg_catalog.undefined) | 4 | plpgsql_depend_type | pkg | arr1 | 3 | {DependenciesUndefined} + | | | | plpgsql_depend_type | null | proc1(pg_catalog.undefined) | 5 | {DependenciesProchead :undefined true :proName proc1 :proArgSrc v_1\ pkg.arr1 :funcHeadSrc create\ or\ replace\ procedure\ proc1\(v_1\ pkg.arr1\)} +(2 rows) + + -- create ref dependency +create or replace package pkg +is + type arr1 is varray(888) of sr; + procedure proc1; +end pkg; +/ +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + proname | valid | proargtypes | proargsrc +---------+-------+-------------+-------------- +--?.* +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.pkg.arr1)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.pkg.arr1)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+-------------------------------------+--------+---------------------+-------+-------------------------------------+-------+----------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | proc1(plpgsql_depend_type.pkg.arr1) | 4 | plpgsql_depend_type | pkg | arr1 | 3 | {DependenciesUndefined} + | | | | plpgsql_depend_type | null | proc1(plpgsql_depend_type.pkg.arr1) | 5 | {DependenciesProchead :undefined false :proName proc1 :proArgSrc v_1\ pkg.arr1 :funcHeadSrc create\ or\ replace\ procedure\ proc1\(v_1\ pkg.arr1\)} +(2 rows) + +-- remove dependency, no rows +drop procedure proc1; +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.pkg.arr1)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.pkg.arr1)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + + -- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +---------------------+-------------+------+------+------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | 3 | sr | {DependenciesType :typType c :typCategory C :attrInfo a:pg_catalog.int4,b:pg_catalog.int4, :isRel false :elemTypName <> :idxByTypName <>} +(1 row) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +---------------------+-------------+------------+----------- + plpgsql_depend_type | pkg | arr1 | 1 +(1 row) + +-- test 34 proc_param_type_used_define_pkg_type +drop type if exists sr cascade; +NOTICE: drop cascades to type sr[] +create type sr as (a int, b int); +drop package if exists pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +create or replace package pkg +is + type arr1 is varray(888) of sr; + type tf1 is table of sr index by binary_integer; + procedure proc1; +end pkg; +/ +drop procedure if exists proc1; +NOTICE: function proc1() does not exist, skipping +create or replace function proc1() return pkg.tf1 as +begin + null; +end; +/ +ERROR: table of index type is not supported as function return type. +DETAIL: N/A +-- valid is true +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + + -- remove ref dependency +create or replace package pkg +is + type arr1 is varray(888) of sr; + procedure proc1; +end pkg; +/ +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + proname | valid | proargtypes | proargsrc +---------+-------+-------------+----------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + + -- create ref dependency +create or replace package pkg +is + type tf1 is table of sr index by binary_integer; + procedure proc1; +end pkg; +/ +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + proname | valid | proargtypes | proargsrc +---------+-------+-------------+----------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +-- remove dependency, no rows +drop procedure proc1; +ERROR: function proc1 does not exist +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + + -- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +---------------------+-------------+------+------+------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | 3 | sr | {DependenciesType :typType c :typCategory C :attrInfo a:pg_catalog.int4,b:pg_catalog.int4, :isRel false :elemTypName <> :idxByTypName <>} +(1 row) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +---------------------+-------------+------------+----------- + plpgsql_depend_type | pkg | tf1 | 1 +(1 row) + +--test 35 proc_param_type_used_undefine_pkg_type +drop type if exists sr cascade; +NOTICE: drop cascades to type _sr[] +drop package if exists pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +drop procedure if exists proc1; +NOTICE: function proc1() does not exist, skipping +create or replace procedure proc1(v_1 pkg.arr1) as +begin + null; +end; +/ +WARNING: Type arr1 does not exist. +WARNING: Type proc1(pg_catalog.undefined) depends on an undefined type. +WARNING: The header information of function proc1 is not defined. +CONTEXT: compilation of PL/pgSQL function "proc1" near line 1 +WARNING: Procedure created with compilation erors. +-- valid is true +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(pg_catalog.undefined)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(pg_catalog.undefined)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+-----------------------------+--------+---------------------+-------+-----------------------------+-------+---------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | proc1(pg_catalog.undefined) | 4 | plpgsql_depend_type | pkg | arr1 | 3 | {DependenciesUndefined} + | | | | plpgsql_depend_type | null | proc1(pg_catalog.undefined) | 5 | {DependenciesProchead :undefined true :proName proc1 :proArgSrc v_1\ pkg.arr1 :funcHeadSrc create\ or\ replace\ procedure\ proc1\(v_1\ pkg.arr1\)} +(2 rows) + + -- remove ref dependency +create or replace package pkg +is + type tf1 is table of sr index by binary_integer; + procedure proc1; +end pkg; +/ +WARNING: Type sr does not exist. +LINE 1: PACKAGE DECLARE type tf1 is table of sr index by binary_i... + ^ +QUERY: PACKAGE DECLARE type tf1 is table of sr index by binary_integer; + procedure proc1; +end +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Package created with compilation erors. +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + proname | valid | proargtypes | proargsrc +---------+-------+-------------+-------------- + proc1 | f | 4408 | v_1 pkg.arr1 +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(pg_catalog.undefined)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(pg_catalog.undefined)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+-----------------------------+--------+---------------------+-------+-----------------------------+-------+---------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | proc1(pg_catalog.undefined) | 4 | plpgsql_depend_type | pkg | arr1 | 3 | {DependenciesUndefined} + | | | | plpgsql_depend_type | null | proc1(pg_catalog.undefined) | 5 | {DependenciesProchead :undefined true :proName proc1 :proArgSrc v_1\ pkg.arr1 :funcHeadSrc create\ or\ replace\ procedure\ proc1\(v_1\ pkg.arr1\)} +(2 rows) + +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+-----------------------------+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | null | proc1(pg_catalog.undefined) | 4 | plpgsql_depend_type | pkg | arr1 | 3 | {DependenciesUndefined} + plpgsql_depend_type | pkg | tf1 | 1 | plpgsql_depend_type | null | sr | 3 | {DependenciesUndefined} +(2 rows) + + -- create ref dependency +create or replace package pkg +is + type arr1 is varray(888) of sr; + procedure proc1; +end pkg; +/ +WARNING: Type sr does not exist. +LINE 1: PACKAGE DECLARE type arr1 is varray(888) of sr; + ^ +QUERY: PACKAGE DECLARE type arr1 is varray(888) of sr; + procedure proc1; +end +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Package created with compilation erors. +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + proname | valid | proargtypes | proargsrc +---------+-------+-------------+-------------- +--?.* +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.pkg.arr1)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.pkg.arr1)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+-------------------------------------+--------+---------------------+-------+-------------------------------------+-------+----------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | proc1(plpgsql_depend_type.pkg.arr1) | 4 | plpgsql_depend_type | pkg | arr1 | 3 | {DependenciesUndefined} + | | | | plpgsql_depend_type | null | proc1(plpgsql_depend_type.pkg.arr1) | 5 | {DependenciesProchead :undefined false :proName proc1 :proArgSrc v_1\ pkg.arr1 :funcHeadSrc create\ or\ replace\ procedure\ proc1\(v_1\ pkg.arr1\)} +(2 rows) + +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+-------------------------------------+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | pkg | arr1 | 1 | plpgsql_depend_type | null | sr | 3 | {DependenciesUndefined} + plpgsql_depend_type | null | proc1(plpgsql_depend_type.pkg.arr1) | 4 | plpgsql_depend_type | pkg | arr1 | 3 | {DependenciesUndefined} +(2 rows) + +create type sr as (a int, b int); +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + proname | valid | proargtypes | proargsrc +---------+-------+-------------+-------------- + proc1 | f | 4408 | v_1 pkg.arr1 +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.pkg.arr1)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.pkg.arr1)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+-----------------------------+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | null | proc1(pg_catalog.undefined) | 4 | plpgsql_depend_type | pkg | arr1 | 3 | {DependenciesUndefined} +(1 row) + +alter package pkg compile; +drop type sr; +ERROR: cannot drop type sr because other objects depend on it +DETAIL: type sr[] depends on type sr +HINT: Use DROP ... CASCADE to drop the dependent objects too. +drop type sr cascade; +NOTICE: drop cascades to type sr[] +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + proname | valid | proargtypes | proargsrc +---------+-------+-------------+-------------- + proc1 | f | 4408 | v_1 pkg.arr1 +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.pkg.arr1)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.pkg.arr1)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- + f +(1 row) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+-----------------------------+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | null | proc1(pg_catalog.undefined) | 4 | plpgsql_depend_type | pkg | arr1 | 3 | {DependenciesUndefined} +(1 row) + +drop package pkg; +NOTICE: drop cascades to function plpgsql_depend_type.proc1() +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.pkg.arr1)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.pkg.arr1)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+-----------------------------+--------+---------------------+-------+-------+-------+------------------------- + plpgsql_depend_type | null | proc1(pg_catalog.undefined) | 4 | plpgsql_depend_type | pkg | arr1 | 3 | {DependenciesUndefined} +(1 row) + +-- remove dependency, no rows +drop procedure proc1; +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); + valid +------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.pkg.arr1)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.pkg.arr1)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +--test 36 schema_table_nest_record +create type ssr is ( + id integer, + name varchar, + addr text +); +create type stab is table of ssr; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'stab') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +create or replace procedure proc1(a stab) as begin null; end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'stab') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.stab)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.stab)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+---------------------------------+--------+---------------------+-------+---------------------------------+-------+----------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | proc1(plpgsql_depend_type.stab) | 4 | plpgsql_depend_type | null | stab | 3 | {DependenciesType :typType o :typCategory O :attrInfo <> :isRel false :elemTypName plpgsql_depend_type.ssr :idxByTypName <>} + | | | | plpgsql_depend_type | null | proc1(plpgsql_depend_type.stab) | 5 | {DependenciesProchead :undefined false :proName proc1 :proArgSrc a\ stab :funcHeadSrc create\ or\ replace\ procedure\ proc1\(a\ stab\)} +(2 rows) + +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + proname | valid | proargtypes | proargsrc +---------+-------+-------------+----------- +--?.* +(1 row) + +create or replace procedure proc1(a ssr) as begin null; end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'stab') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.ssr)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.ssr)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+--------------------------------+--------+---------------------+-------+--------------------------------+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | proc1(plpgsql_depend_type.ssr) | 4 | plpgsql_depend_type | null | ssr | 3 | {DependenciesType :typType c :typCategory C :attrInfo id:pg_catalog.int4,name:pg_catalog.varchar,addr:pg_catalog.text, :isRel false :elemTypName <> :idxByTypName <>} + | | | | plpgsql_depend_type | null | proc1(plpgsql_depend_type.ssr) | 5 | {DependenciesProchead :undefined false :proName proc1 :proArgSrc a\ ssr :funcHeadSrc create\ or\ replace\ procedure\ proc1\(a\ ssr\)} +(2 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.stab)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.stab)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + proname | valid | proargtypes | proargsrc +---------+-------+-------------+----------- +--?.* +(1 row) + +drop type ssr; +ERROR: cannot drop type ssr because other objects depend on it +DETAIL: type _ssr[] depends on type ssr[] +HINT: Use DROP ... CASCADE to drop the dependent objects too. +drop type ssr cascade; +NOTICE: drop cascades to type _ssr[] +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'stab') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.ssr)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.ssr)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.stab)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.stab)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(pg_catalog.undefined)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(pg_catalog.undefined)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+-----------------------------+--------+---------------------+-------+-----------------------------+-------+-------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | proc1(pg_catalog.undefined) | 4 | plpgsql_depend_type | null | ssr | 3 | {DependenciesUndefined} + | | | | plpgsql_depend_type | null | proc1(pg_catalog.undefined) | 5 | {DependenciesProchead :undefined true :proName proc1 :proArgSrc a\ ssr :funcHeadSrc create\ or\ replace\ procedure\ proc1\(a\ ssr\)} +(2 rows) + +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + proname | valid | proargtypes | proargsrc +---------+-------+-------------+----------- + proc1 | f | 4408 | a ssr +(1 row) + +create type ssr is ( + id integer, + name varchar, + addr text +); +create type stab is table of ssr; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'stab') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.ssr)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.ssr)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+--------------------------------+--------+---------------------+-------+--------------------------------+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | proc1(plpgsql_depend_type.ssr) | 4 | plpgsql_depend_type | null | ssr | 3 | {DependenciesType :typType c :typCategory C :attrInfo id:pg_catalog.int4,name:pg_catalog.varchar,addr:pg_catalog.text, :isRel false :elemTypName <> :idxByTypName <>} + | | | | plpgsql_depend_type | null | proc1(plpgsql_depend_type.ssr) | 5 | {DependenciesProchead :undefined false :proName proc1 :proArgSrc a\ ssr :funcHeadSrc create\ or\ replace\ procedure\ proc1\(a\ ssr\)} +(2 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.stab)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.stab)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + proname | valid | proargtypes | proargsrc +---------+-------+-------------+----------- +--?.* +(1 row) + +drop procedure proc1; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'stab') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.ssr)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.ssr)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.stab)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.stab)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + proname | valid | proargtypes | proargsrc +---------+-------+-------------+----------- +(0 rows) + +drop type ssr; +ERROR: cannot drop type ssr because other objects depend on it +DETAIL: type _ssr[] depends on type ssr[] +HINT: Use DROP ... CASCADE to drop the dependent objects too. +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- is clean +drop type stab; +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; + schemaname | packagename | type | name | objnode +------------+-------------+------+------+--------- +(0 rows) + +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + schemaname | packagename | objectname | refobjpos +------------+-------------+------------+----------- +(0 rows) + +-- test 37 +create type t2 as enum ('create', 'modify', 'closed'); +alter type t2 rename value 'create' to 'newcreate'; +create or replace procedure proc1(vb t2) as +declare +v_1 t2; +begin +null; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.t2)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.t2)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+-------------------------------+--------+---------------------+-------+-------------------------------+-------+--------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | proc1(plpgsql_depend_type.t2) | 4 | plpgsql_depend_type | null | t2 | 3 | {DependenciesType :typType e :typCategory E :attrInfo newcreate,modify,closed, :isRel false :elemTypName <> :idxByTypName <>} + plpgsql_depend_type | null | proc1(plpgsql_depend_type.t2) | 8 | plpgsql_depend_type | null | t2 | 3 | {DependenciesType :typType e :typCategory E :attrInfo newcreate,modify,closed, :isRel false :elemTypName <> :idxByTypName <>} + | | | | plpgsql_depend_type | null | proc1(plpgsql_depend_type.t2) | 5 | {DependenciesProchead :undefined false :proName proc1 :proArgSrc vb\ t2 :funcHeadSrc create\ or\ replace\ procedure\ proc1\(vb\ t2\)} +(3 rows) + +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + proname | valid | proargtypes | proargsrc +---------+-------+-------------+----------- +--?.* +(1 row) + +alter type t2 add value 'modif3' before 'closed'; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.t2)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.t2)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +---------------------+------+-------------------------------+--------+---------------------+-------+-------------------------------+-------+--------------------------------------------------------------------------------------------------------------------------------------- + plpgsql_depend_type | null | proc1(plpgsql_depend_type.t2) | 4 | plpgsql_depend_type | null | t2 | 3 | {DependenciesType :typType e :typCategory E :attrInfo newcreate,modify,modif3,closed, :isRel false :elemTypName <> :idxByTypName <>} + plpgsql_depend_type | null | proc1(plpgsql_depend_type.t2) | 8 | plpgsql_depend_type | null | t2 | 3 | {DependenciesType :typType e :typCategory E :attrInfo newcreate,modify,modif3,closed, :isRel false :elemTypName <> :idxByTypName <>} + | | | | plpgsql_depend_type | null | proc1(plpgsql_depend_type.t2) | 5 | {DependenciesProchead :undefined false :proName proc1 :proArgSrc vb\ t2 :funcHeadSrc create\ or\ replace\ procedure\ proc1\(vb\ t2\)} +(3 rows) + +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + proname | valid | proargtypes | proargsrc +---------+-------+-------------+----------- +--?.* +(1 row) + +alter type t2 rename to t3; +ERROR: The rename operator of t2 is not allowed, because it is referenced by the other object. +drop type t2; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.t2)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.t2)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +----+----+----+--------+-------+-------+-------+-------+-------- +(0 rows) + +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + proname | valid | proargtypes | proargsrc +---------+-------+-------------+----------- + proc1 | f | 4408 | vb t2 +(1 row) + +-- clean +drop schema plpgsql_depend_type cascade; +NOTICE: drop cascades to 5 other objects +DETAIL: drop cascades to function create_data_table() +drop cascades to function drop_data_table() +drop cascades to function drop_data_table_cascade() +drop cascades to type ssr +drop cascades to function proc1(undefined) +reset behavior_compat_options; \ No newline at end of file diff --git a/src/test/regress/expected/plpgsql_depend/plpgsql_pkg_dependency.out b/src/test/regress/expected/plpgsql_depend/plpgsql_pkg_dependency.out new file mode 100644 index 000000000..3659dbac4 --- /dev/null +++ b/src/test/regress/expected/plpgsql_depend/plpgsql_pkg_dependency.out @@ -0,0 +1,64 @@ +drop schema if exists plpgsql_pkg_dependency cascade; +NOTICE: schema "plpgsql_pkg_dependency" does not exist, skipping +create schema plpgsql_pkg_dependency; +set current_schema = plpgsql_pkg_dependency; +set behavior_compat_options = 'plpgsql_dependency'; +create or replace package test_package_depend2_pkg is +type t is record (col1 int, col2 text); +procedure p1(param test_package_depend3_pkg.t); +end test_package_depend2_pkg; +/ +WARNING: Type t does not exist. +WARNING: The header information of function p1 is not defined. +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Package created with compilation erors. +create or replace package body test_package_depend2_pkg is +procedure p1(param test_package_depend3_pkg.t) is + begin + RAISE INFO 'call param: %', param; + end; +end test_package_depend2_pkg; +/ +WARNING: Type t does not exist. +WARNING: The header information of function p1 is not defined. +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: The header information of function p1 is not defined. +CONTEXT: compilation of PL/pgSQL package near line 1 +WARNING: Package Body created with compilation erors. +create or replace package test_package_depend3_pkg is +type t is record (col1 int, col2 text, col3 varchar); +procedure p1(param test_package_depend2_pkg.t); +end test_package_depend3_pkg; +/ +--?WARNING: Package ?.* is invalid. +WARNING: Package created with compilation erors. +create or replace package body test_package_depend3_pkg is +procedure p1(param test_package_depend2_pkg.t) is + begin + RAISE INFO 'call param: %', param; + end; +end test_package_depend3_pkg; +/ +--?WARNING: Package ?.* is invalid. +WARNING: Package Body created with compilation erors. +call test_package_depend2_pkg.p1((1,'a','2023')); +INFO: call param: (1,a,2023) + p1 +---- + +(1 row) + +call test_package_depend3_pkg.p1((1,'a')); +INFO: call param: (1,a) + p1 +---- + +(1 row) + +drop package if exists test_package_depend2_pkg; +--?.* +drop package if exists test_package_depend3_pkg; +NOTICE: drop cascades to function plpgsql_pkg_dependency.p1(undefined) +-- clean +drop schema plpgsql_pkg_dependency cascade; +reset behavior_compat_options; diff --git a/src/test/regress/expected/plpgsql_depend/plpgsql_pkg_variable_dependency.out b/src/test/regress/expected/plpgsql_depend/plpgsql_pkg_variable_dependency.out new file mode 100644 index 000000000..2a508c177 --- /dev/null +++ b/src/test/regress/expected/plpgsql_depend/plpgsql_pkg_variable_dependency.out @@ -0,0 +1,3051 @@ +drop schema if exists pkg_var_test cascade; +NOTICE: schema "pkg_var_test" does not exist, skipping +create schema pkg_var_test; +set current_schema = pkg_var_test; +set behavior_compat_options = 'plpgsql_dependency'; +-- 1.test function depends on package var in assignment statement +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace function test_func return int +is + func_var int; +begin + func_var := test_pkg.ref_var; + return 1; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + ref_var int; + -- unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + -- ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +WARNING: pkg_var_test.test_pkg.ref_var must be declared. +CONTEXT: compilation of PL/pgSQL function "test_func" near line 1 +WARNING: The dependent variable is undefined. +CONTEXT: compilation of PL/pgSQL function "test_func" near line 1 +WARNING: Functions test_func recompile with compilation errors. +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 1 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +drop function test_func; +-- 1.1 modifying the package var type +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace function test_func return int +is + func_var int; +begin + func_var := test_pkg.ref_var; + return 1; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + ref_var int; + unref_var varchar(16); +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + ref_var varchar(16); + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+----------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.varchar :typMod 20 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+----------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.varchar :typMod 20 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +drop function test_func; +-- 2.test function depends on package var in return statement +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace function test_func return int +is + func_var int; +begin + func_var := 1; + return test_pkg.ref_var; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + ref_var int; + -- unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + -- ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +WARNING: pkg_var_test.test_pkg.ref_var must be declared. +CONTEXT: compilation of PL/pgSQL function "test_func" near line 4 +WARNING: The dependent variable is undefined. +CONTEXT: compilation of PL/pgSQL function "test_func" near line 4 +WARNING: Functions test_func recompile with compilation errors. +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 1 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +drop function test_func; +-- 2.1 modifying the package var type +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace function test_func return int +is + func_var int; +begin + func_var := 1; + return test_pkg.ref_var; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + ref_var int; + unref_var varchar(16); +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + ref_var varchar(16); + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+----------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.varchar :typMod 20 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+----------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.varchar :typMod 20 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +drop function test_func; +-- 3.test function depends on package var in if statement +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace function test_func return int +is + func_var int; +begin + if test_pkg.ref_var = 1 then + func_var := 1; + end if; + return 1; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + ref_var int; + -- unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + -- ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +WARNING: pkg_var_test.test_pkg.ref_var must be declared. +CONTEXT: compilation of PL/pgSQL function "test_func" near line 1 +WARNING: The dependent variable is undefined. +CONTEXT: compilation of PL/pgSQL function "test_func" near line 1 +WARNING: Functions test_func recompile with compilation errors. +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 1 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +drop function test_func; +-- 3.1 modifying the package var type +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace function test_func return int +is + func_var int; +begin + if test_pkg.ref_var = 1 then + func_var := 1; + end if; + return 1; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + ref_var int; + unref_var varchar(16); +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + ref_var varchar(16); + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+----------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.varchar :typMod 20 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+----------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.varchar :typMod 20 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +drop function test_func; +-- 4.test function depends on package var in while statement +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace function test_func return int +is + func_var int; +begin + while test_pkg.ref_var < 1 loop + func_var := 1; + end loop; + return 1; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + ref_var int; + -- unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + -- ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +WARNING: pkg_var_test.test_pkg.ref_var must be declared. +CONTEXT: compilation of PL/pgSQL function "test_func" near line 1 +WARNING: The dependent variable is undefined. +CONTEXT: compilation of PL/pgSQL function "test_func" near line 1 +WARNING: Functions test_func recompile with compilation errors. +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 1 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +drop function test_func; +-- 4.1 modifying the package var type +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace function test_func return int +is + func_var int; +begin + while test_pkg.ref_var < 1 loop + func_var := 1; + end loop; + return 1; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + ref_var int; + unref_var varchar(16); +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + ref_var varchar(16); + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+----------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.varchar :typMod 20 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+----------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.varchar :typMod 20 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +drop function test_func; +-- 5.test function depends on package var in case statement +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace function test_func return int +is + func_var int; +begin + case test_pkg.ref_var + when 1 then + func_var := 1; + end case; + return 1; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + ref_var int; + -- unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + -- ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +WARNING: pkg_var_test.test_pkg.ref_var must be declared. +CONTEXT: compilation of PL/pgSQL function "test_func" near line 1 +WARNING: The dependent variable is undefined. +CONTEXT: compilation of PL/pgSQL function "test_func" near line 1 +WARNING: Functions test_func recompile with compilation errors. +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 1 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +drop function test_func; +-- 5.1 modifying the package var type +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace function test_func return int +is + func_var int; +begin + case test_pkg.ref_var + when 1 then + func_var := 1; + end case; + return 1; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + ref_var int; + unref_var varchar(16); +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + ref_var varchar(16); + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+----------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.varchar :typMod 20 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+----------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.varchar :typMod 20 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +drop function test_func; +-- 6.test procedure depends on package var in assignment statement +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace procedure test_proc +is + proc_var int; +begin + proc_var := test_pkg.ref_var; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +create or replace package test_pkg as + ref_var int; + -- unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +create or replace package test_pkg as + -- ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +alter procedure test_proc compile; +WARNING: pkg_var_test.test_pkg.ref_var must be declared. +CONTEXT: compilation of PL/pgSQL function "test_proc" near line 1 +WARNING: The dependent variable is undefined. +CONTEXT: compilation of PL/pgSQL function "test_proc" near line 1 +WARNING: Procedure test_proc recompile with compilation errors. +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 1 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +drop procedure test_proc; +-- 6.1 modifying the package var type +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace procedure test_proc +is + proc_var int; +begin + proc_var := test_pkg.ref_var; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +create or replace package test_pkg as + ref_var int; + unref_var varchar(16); +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +create or replace package test_pkg as + ref_var varchar(16); + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+----------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.varchar :typMod 20 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+----------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.varchar :typMod 20 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +drop procedure test_proc; +-- 7.test procedure depends on package var in if statement +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace procedure test_proc +is + proc_var int; +begin + if test_pkg.ref_var = 1 then + proc_var := 1; + end if; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +create or replace package test_pkg as + ref_var int; + -- unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +create or replace package test_pkg as + -- ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +alter procedure test_proc compile; +WARNING: pkg_var_test.test_pkg.ref_var must be declared. +CONTEXT: compilation of PL/pgSQL function "test_proc" near line 1 +WARNING: The dependent variable is undefined. +CONTEXT: compilation of PL/pgSQL function "test_proc" near line 1 +WARNING: Procedure test_proc recompile with compilation errors. +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 1 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +drop procedure test_proc; +-- 7.1 modifying the package var type +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace procedure test_proc +is + proc_var int; +begin + if test_pkg.ref_var = 1 then + proc_var := 1; + end if; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +create or replace package test_pkg as + ref_var int; + unref_var varchar(16); +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +create or replace package test_pkg as + ref_var varchar(16); + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+----------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.varchar :typMod 20 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+----------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.varchar :typMod 20 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +drop procedure test_proc; +-- 8.test procedure depends on package var in while statement +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace procedure test_proc +is + proc_var int; +begin + while test_pkg.ref_var < 1 loop + proc_var := 1; + end loop; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +create or replace package test_pkg as + ref_var int; + -- unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +create or replace package test_pkg as + -- ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +alter procedure test_proc compile; +WARNING: pkg_var_test.test_pkg.ref_var must be declared. +CONTEXT: compilation of PL/pgSQL function "test_proc" near line 1 +WARNING: The dependent variable is undefined. +CONTEXT: compilation of PL/pgSQL function "test_proc" near line 1 +WARNING: Procedure test_proc recompile with compilation errors. +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 1 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +drop procedure test_proc; +-- 8.1 modifying the package var type +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace procedure test_proc +is + proc_var int; +begin + while test_pkg.ref_var < 1 loop + proc_var := 1; + end loop; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +create or replace package test_pkg as + ref_var int; + unref_var varchar(16); +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +create or replace package test_pkg as + ref_var varchar(16); + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+----------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.varchar :typMod 20 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+----------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.varchar :typMod 20 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +drop procedure test_proc; +-- 9.test procedure depends on package var in case statement +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace procedure test_proc +is + proc_var int; +begin + case test_pkg.ref_var + when 1 then + proc_var := 1; + end case; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +create or replace package test_pkg as + ref_var int; + -- unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +create or replace package test_pkg as + -- ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +alter procedure test_proc compile; +WARNING: pkg_var_test.test_pkg.ref_var must be declared. +CONTEXT: compilation of PL/pgSQL function "test_proc" near line 1 +WARNING: The dependent variable is undefined. +CONTEXT: compilation of PL/pgSQL function "test_proc" near line 1 +WARNING: Procedure test_proc recompile with compilation errors. +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 1 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +drop procedure test_proc; +-- 9.1 modifying the package var type +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace procedure test_proc +is + proc_var int; +begin + case test_pkg.ref_var + when 1 then + proc_var := 1; + end case; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +create or replace package test_pkg as + ref_var int; + unref_var varchar(16); +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +create or replace package test_pkg as + ref_var varchar(16); + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+----------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.varchar :typMod 20 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+----------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.varchar :typMod 20 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.int4 :typMod -1 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | t +(1 row) + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_proc() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_proc | f +(1 row) + +drop procedure test_proc; +-- 10.test the cursor var of the dependent package in the open statement +create table test_table (ref_col int, unref_col int); +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +create or replace function test_func return int +is +begin + open test_pkg.ref_var; + return 1; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.refcursor :typMod -1 :extraInfo select\ ref_col\ from\ test_table} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + -- cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.refcursor :typMod -1 :extraInfo select\ ref_col\ from\ test_table} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + -- cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +ERROR: "test_pkg.ref_var" is not a known variable +LINE 2: open test_pkg.ref_var; + ^ +QUERY: DECLARE begin + open test_pkg.ref_var; + return 1; +end +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.refcursor :typMod -1 :extraInfo select\ ref_col\ from\ test_table} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.refcursor :typMod -1 :extraInfo select\ ref_col\ from\ test_table} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +drop function test_func; +-- 10.1 modifying the package var type +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +create or replace function test_func return int +is +begin + open test_pkg.ref_var; + return 1; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.refcursor :typMod -1 :extraInfo select\ ref_col\ from\ test_table} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + unref_var varchar(32); +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.refcursor :typMod -1 :extraInfo select\ ref_col\ from\ test_table} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + ref_var varchar(32); + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+----------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.varchar :typMod 36 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +ERROR: variable "ref_var" must be of type cursor or refcursor +LINE 2: open test_pkg.ref_var; + ^ +QUERY: DECLARE begin + open test_pkg.ref_var; + return 1; +end +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+----------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.varchar :typMod 36 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.refcursor :typMod -1 :extraInfo select\ ref_col\ from\ test_table} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.refcursor :typMod -1 :extraInfo select\ ref_col\ from\ test_table} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +drop function test_func; +drop table test_table; +-- 11.test the cursor var of the dependent package in the fetch statement +create table test_table (ref_col int, unref_col int); +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +create or replace function test_func return int +is + func_var int; +begin + fetch test_pkg.ref_var into func_var; + return func_var; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.refcursor :typMod -1 :extraInfo select\ ref_col\ from\ test_table} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + -- cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.refcursor :typMod -1 :extraInfo select\ ref_col\ from\ test_table} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + -- cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +WARNING: pkg_var_test.test_pkg.ref_var must be declared. +CONTEXT: compilation of PL/pgSQL function "test_func" near line 1 +WARNING: The dependent variable is undefined. +CONTEXT: compilation of PL/pgSQL function "test_func" near line 1 +ERROR: missing "FROM or IN" at end of SQL expression +LINE 3: fetch test_pkg.ref_var into func_var; + ^ +QUERY: DECLARE func_var int; +begin + fetch test_pkg.ref_var into func_var; + return func_var; +end +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.refcursor :typMod -1 :extraInfo select\ ref_col\ from\ test_table} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.refcursor :typMod -1 :extraInfo select\ ref_col\ from\ test_table} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +drop function test_func; +-- 11.1 modifying the package var type +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +create or replace function test_func return int +is + func_var int; +begin + fetch test_pkg.ref_var into func_var; + return func_var; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.refcursor :typMod -1 :extraInfo select\ ref_col\ from\ test_table} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + unref_var varchar(32); +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.refcursor :typMod -1 :extraInfo select\ ref_col\ from\ test_table} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + ref_var varchar(32); + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+----------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.varchar :typMod 36 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +ERROR: variable "ref_var" must be of type cursor or refcursor +LINE 3: fetch test_pkg.ref_var into func_var; + ^ +QUERY: DECLARE func_var int; +begin + fetch test_pkg.ref_var into func_var; + return func_var; +end +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+----------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.varchar :typMod 36 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.refcursor :typMod -1 :extraInfo select\ ref_col\ from\ test_table} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.refcursor :typMod -1 :extraInfo select\ ref_col\ from\ test_table} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +drop function test_func; +drop table test_table; +-- 12.test the cursor var of the dependent package in the close statement +create table test_table (ref_col int, unref_col int); +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +create or replace function test_func return int +is +begin + close test_pkg.ref_var; + return 1; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.refcursor :typMod -1 :extraInfo select\ ref_col\ from\ test_table} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + -- cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.refcursor :typMod -1 :extraInfo select\ ref_col\ from\ test_table} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + -- cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +ERROR: "test_pkg.ref_var" is not a known variable +LINE 2: close test_pkg.ref_var; + ^ +QUERY: DECLARE begin + close test_pkg.ref_var; + return 1; +end +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.refcursor :typMod -1 :extraInfo select\ ref_col\ from\ test_table} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.refcursor :typMod -1 :extraInfo select\ ref_col\ from\ test_table} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +drop function test_func; +-- 12.1 modifying the package var type +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +create or replace function test_func return int +is +begin + close test_pkg.ref_var; + return 1; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.refcursor :typMod -1 :extraInfo select\ ref_col\ from\ test_table} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + unref_var varchar(32); +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.refcursor :typMod -1 :extraInfo select\ ref_col\ from\ test_table} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +create or replace package test_pkg as + ref_var varchar(32); + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+----------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.varchar :typMod 36 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +ERROR: variable "ref_var" must be of type cursor or refcursor +LINE 2: close test_pkg.ref_var; + ^ +QUERY: DECLARE begin + close test_pkg.ref_var; + return 1; +end +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+----------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.varchar :typMod 36 :extraInfo <>} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.refcursor :typMod -1 :extraInfo select\ ref_col\ from\ test_table} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+-------------------------------------------------------------------------------------------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesVariable :typName pg_catalog.refcursor :typMod -1 :extraInfo select\ ref_col\ from\ test_table} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | t +(1 row) + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + sn | pn | on | refpos | refsn | refpn | refon | refot | refast +--------------+------+-------------+--------+--------------+----------+---------+-------+------------------------- + pkg_var_test | null | test_func() | 8 | pkg_var_test | test_pkg | ref_var | 2 | {DependenciesUndefined} +(1 row) + +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + nspname | proname | valid +--------------+-----------+------- + pkg_var_test | test_func | f +(1 row) + +drop function test_func; +drop table test_table; +-- clean +drop schema pkg_var_test cascade; +reset behavior_compat_options; diff --git a/src/test/regress/expected/plpgsql_depend/plpgsql_recompile.out b/src/test/regress/expected/plpgsql_depend/plpgsql_recompile.out new file mode 100644 index 000000000..048e9bae1 --- /dev/null +++ b/src/test/regress/expected/plpgsql_depend/plpgsql_recompile.out @@ -0,0 +1,219 @@ +drop schema if exists plpgsql_recompile cascade; +NOTICE: schema "plpgsql_recompile" does not exist, skipping +create schema plpgsql_recompile; +set current_schema = plpgsql_recompile; +set behavior_compat_options = 'plpgsql_dependency'; +---test 1 +create type s_type as ( + id integer, + name varchar, + addr text +); +create or replace procedure type_alter(a s_type) +is +begin + RAISE INFO 'call a: %', a; +end; +/ +select valid from pg_object where object_type='P' and object_oid +in (select Oid from pg_proc where propackageid = 0 and proname='type_alter' and pronamespace = +(select Oid from pg_namespace where nspname = 'plpgsql_recompile')); + valid +------- + t +(1 row) + +call type_alter((1,'zhang','shanghai')); +INFO: call a: (1,zhang,shanghai) + type_alter +------------ + +(1 row) + +alter function type_alter compile; +WARNING: Functions type_alter does not exist, if it is a stored procedure, use ALTER PROCEDURE. +alter procedure type_alter(s_type) compile; +alter type s_type ADD attribute a int; +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='type_alter' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_recompile')); + valid +------- + f +(1 row) + +call type_alter((1,'zhang','shanghai',100)); +INFO: call a: (1,zhang,shanghai,100) + type_alter +------------ + +(1 row) + +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='type_alter' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_recompile')); + valid +------- + t +(1 row) + +alter type s_type DROP attribute a; +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='type_alter' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_recompile')); + valid +------- + f +(1 row) + +call type_alter((1,'zhang','shanghai')); +INFO: call a: (1,zhang,shanghai) + type_alter +------------ + +(1 row) + +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='type_alter' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_recompile')); + valid +------- + t +(1 row) + +alter type s_type ALTER attribute id type float; +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='type_alter' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_recompile')); + valid +------- + f +(1 row) + +alter procedure type_alter compile; +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='type_alter' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_recompile')); + valid +------- + t +(1 row) + +call type_alter((1.0,'zhang','shanghai')); +INFO: call a: (1,zhang,shanghai) + type_alter +------------ + +(1 row) + +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='type_alter' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_recompile')); + valid +------- + t +(1 row) + +-- report error +alter type s_type RENAME to s_type_rename; +ERROR: The rename operator of s_type is not allowed, because it is referenced by the other object. +ALTER type s_type RENAME ATTRIBUTE name TO new_name; +ERROR: cannot rename attribute of the type because it is dependent on another object. +call type_alter((1,'zhang','shanghai')); +INFO: call a: (1,zhang,shanghai) + type_alter +------------ + +(1 row) + +-- test 2 +drop table if exists stu; +NOTICE: table "stu" does not exist, skipping +create table stu(sno int, name varchar, sex varchar, cno int); +create type r1 as (a int, c stu%RowType); +drop package if exists pkg; +NOTICE: package pkg() does not exist, skipping +create or replace package pkg +is +procedure proc1(p_in r1); +end pkg; +/ +create or replace package body pkg +is +declare +v1 r1; +v2 stu%RowType; +procedure proc1(p_in r1) as +begin +RAISE INFO 'call p_in: %', p_in; +end; +end pkg; +/ +call pkg.proc1((1,(1,'zhang','M',1))); +INFO: call p_in: (1,"(1,zhang,M,1)") + proc1 +------- + +(1 row) + +alter package pkg compile; +alter package pkg compile specification; +alter package pkg compile body; +alter package pkg compile package; +alter table stu ADD column b int; +alter package pkg compile; +call pkg.proc1((1,(1,'zhang','M',1,2))); +INFO: call p_in: (1,"(1,zhang,M,1,2)") + proc1 +------- + +(1 row) + +alter table stu DROP column b; +alter package pkg compile; +call pkg.proc1((1,(1,'zhang','M',1))); +INFO: call p_in: (1,"(1,zhang,M,1)") + proc1 +------- + +(1 row) + +alter table stu RENAME to stu_re; +ERROR: The rename operator on stu is not allowed, because it is dependent on another object. +alter package pkg compile; +call pkg.proc1((1,(1,'zhang','M',1))); +INFO: call p_in: (1,"(1,zhang,M,1)") + proc1 +------- + +(1 row) + +alter type r1 ALTER attribute a type float; +alter package pkg compile; +call pkg.proc1((1.0,(1,'zhang','M',1))); +INFO: call p_in: (1,"(1,zhang,M,1)") + proc1 +------- + +(1 row) + +--compile error +create or replace package body pkg +is +declare +v1 r1%RowType; +procedure proc1(p_in r1) as +begin +select into v1 values (1,ROW(1,'zhang','M',1)); +RAISE INFO 'call p_in: %', p_in; +end; +end pkg; +/ +WARNING: syntax error at or near "(" when compile function proc1(r1) +DETAIL: N/A +CONTEXT: compilation of PL/pgSQL package near line 1 +alter package pkg compile; +ERROR: syntax error at or near "(" when compile function proc1(r1) +LINE 2: select into v1 values (1,ROW(1,'zhang','M',1)); + ^ +DETAIL: syntax error +QUERY: DECLARE begin +select into v1 values (1,ROW(1,'zhang','M',1)); +RAISE INFO 'call p_in: %', p_in; +end +-- select oid,* from pg_type where typname='stu'; +drop schema plpgsql_recompile cascade; +NOTICE: drop cascades to 6 other objects +DETAIL: drop cascades to type s_type +drop cascades to function type_alter(s_type) +drop cascades to table stu +drop cascades to type r1 +--?.* +drop cascades to function plpgsql_recompile.proc1(r1) +reset behavior_compat_options; diff --git a/src/test/regress/expected/plpgsql_package_type.out b/src/test/regress/expected/plpgsql_package_type.out index 33aaa1e21..949d6d91c 100644 --- a/src/test/regress/expected/plpgsql_package_type.out +++ b/src/test/regress/expected/plpgsql_package_type.out @@ -1403,8 +1403,6 @@ va t1; procedure p1(vb pck2.va%type); end pck2; / -ERROR: not support ref table of variable as procedure argument type -CONTEXT: compilation of PL/pgSQL package near line 3 create or replace package pck2 as type t1 is table of int index by varchar2; va t1; @@ -1478,6 +1476,8 @@ ERROR: package plpgsql_packagetype1.p_test1 does not exist -- clean up -- drop schema if exists plpgsql_packagetype2 cascade; drop schema if exists plpgsql_packagetype1 cascade; -NOTICE: drop cascades to 2 other objects +NOTICE: drop cascades to 4 other objects +--?.* +drop cascades to function plpgsql_packagetype1.p1(integer[]) --?.* drop cascades to function plpgsql_packagetype1.p1() diff --git a/src/test/regress/expected/plsql_show_all_error.out b/src/test/regress/expected/plsql_show_all_error.out index dab1436cf..732581215 100644 --- a/src/test/regress/expected/plsql_show_all_error.out +++ b/src/test/regress/expected/plsql_show_all_error.out @@ -1868,4 +1868,4 @@ select name, status, src from DBE_PLDEVELOPER.gs_source; delete from DBE_PLDEVELOPER.gs_source; drop package pac_1139606; -NOTICE: drop cascades to function public.pro_1139606() +NOTICE: drop cascades to function public.pro_1139606() \ No newline at end of file diff --git a/src/test/regress/expected/single_node_type_sanity.out b/src/test/regress/expected/single_node_type_sanity.out index 56f0c3ef7..2cc6b331e 100644 --- a/src/test/regress/expected/single_node_type_sanity.out +++ b/src/test/regress/expected/single_node_type_sanity.out @@ -21,9 +21,10 @@ WHERE (p1.typnamespace = 0 OR NOT p1.typisdefined OR (p1.typalign not in ('c', 's', 'i', 'd')) OR (p1.typstorage not in ('p', 'x', 'e', 'm'))) AND p1.typname not in ('desc_tab', 'date_table', 'number_table', 'varchar2_table'); - oid | typname ------+--------- -(0 rows) + oid | typname +------+----------- + 4408 | undefined +(1 row) -- Look for "pass by value" types that can't be passed by value. SELECT p1.oid, p1.typname @@ -66,15 +67,16 @@ WHERE p1.typtype not in ('c','d','p') AND p1.typname NOT LIKE E'\\_%' AND NOT EXISTS (SELECT 1 FROM pg_type as p2 WHERE p2.typname = ('_' || p1.typname)::name AND - p2.typelem = p1.oid and p1.typarray = p2.oid) AND p1.typname not in ('desc_tab', 'date_table', 'number_table', 'varchar2_table'); + p2.typelem = p1.oid and p1.typarray = p2.oid) AND p1.typname not in ('desc_tab', 'date_table', 'number_table', 'varchar2_table') order by p1.oid; oid | typname ------+------------------ 32 | oidvector_extend + 194 | pg_node_tree 210 | smgr 705 | unknown 3272 | anyset - 194 | pg_node_tree -(5 rows) + 4408 | undefined +(6 rows) -- Make sure typarray points to a varlena array type of our own base SELECT p1.oid, p1.typname as basetype, p2.typname as arraytype, @@ -166,14 +168,15 @@ SELECT DISTINCT typtype, typinput FROM pg_type AS p1 WHERE p1.typtype not in ('b', 'p', 'o') ORDER BY 1; - typtype | typinput ----------+----------- + typtype | typinput +---------+------------- c | record_in d | domain_in e | enum_in r | range_in s | anyset_in -(5 rows) + u | undefinedin +(6 rows) -- Check for bogus typoutput routines -- As of 8.0, this check finds refcursor, which is borrowing @@ -207,13 +210,14 @@ SELECT DISTINCT typtype, typoutput FROM pg_type AS p1 WHERE p1.typtype not in ('b', 'd', 'p', 'o') ORDER BY 1; - typtype | typoutput ----------+------------ + typtype | typoutput +---------+-------------- c | record_out e | enum_out r | range_out s | anyset_out -(4 rows) + u | undefinedout +(5 rows) -- Domains should have same typoutput as their base types SELECT p1.oid, p1.typname, p2.oid, p2.typname @@ -283,13 +287,14 @@ SELECT DISTINCT typtype, typreceive FROM pg_type AS p1 WHERE p1.typtype not in ('b', 'p', 'o', 's') ORDER BY 1; - typtype | typreceive ----------+------------- + typtype | typreceive +---------+--------------- c | record_recv d | domain_recv e | enum_recv r | range_recv -(4 rows) + u | undefinedrecv +(5 rows) -- Check for bogus typsend routines -- As of 7.4, this check finds refcursor, which is borrowing @@ -324,12 +329,13 @@ SELECT DISTINCT typtype, typsend FROM pg_type AS p1 WHERE p1.typtype not in ('b', 'd', 'p', 'o', 's') ORDER BY 1; - typtype | typsend ----------+------------- + typtype | typsend +---------+--------------- c | record_send e | enum_send r | range_send -(3 rows) + u | undefinedsend +(4 rows) -- Domains should have same typsend as their base types SELECT p1.oid, p1.typname, p2.oid, p2.typname diff --git a/src/test/regress/parallel_schedule0 b/src/test/regress/parallel_schedule0 index b7cb0e674..1043f8e65 100644 --- a/src/test/regress/parallel_schedule0 +++ b/src/test/regress/parallel_schedule0 @@ -767,6 +767,8 @@ test: plpgsql_insert_record plpgsql_condition_name test: hw_package_variable package_typmod_test test: autonomous_cursor test: plpgsql_reset_session +#test: plpgsql_depend +test: plpgsql_depend/plpgsql_depend_type plpgsql_depend/plpgsql_pkg_dependency plpgsql_depend/plpgsql_recompile plpgsql_depend/plpgsql_pkg_variable_dependency plpgsql_depend/plpgsql_depend_reftype #test: plancache limit rangefuncs prepare test: returning largeobject test: hw_explain_pretty1 hw_explain_pretty2 hw_explain_pretty3 diff --git a/src/test/regress/parallel_schedule0B b/src/test/regress/parallel_schedule0B index 6925c8d4b..ca26dd1ef 100644 --- a/src/test/regress/parallel_schedule0B +++ b/src/test/regress/parallel_schedule0B @@ -283,6 +283,8 @@ test: plpgsql_insert_record plpgsql_condition_name test: hw_package_variable package_typmod_test test: autonomous_cursor test: plpgsql_reset_session +#test: plpgsql_depend +test: plpgsql_depend/plpgsql_depend_type plpgsql_depend/plpgsql_pkg_dependency plpgsql_depend/plpgsql_recompile plpgsql_depend/plpgsql_pkg_variable_dependency plpgsql_depend/plpgsql_depend_reftype #test: plancache limit rangefuncs prepare test: returning largeobject test: hw_explain_pretty1 hw_explain_pretty2 hw_explain_pretty3 @@ -442,4 +444,5 @@ test: udf_crem create_c_function # procedure, Function Test #test: create_procedure test: create_function -test: pg_compatibility \ No newline at end of file +test: pg_compatibility + diff --git a/src/test/regress/sql/plpgsql_depend/plpgsql_depend_reftype.sql b/src/test/regress/sql/plpgsql_depend/plpgsql_depend_reftype.sql new file mode 100644 index 000000000..2f3c393b3 --- /dev/null +++ b/src/test/regress/sql/plpgsql_depend/plpgsql_depend_reftype.sql @@ -0,0 +1,474 @@ + +drop schema if exists plpgsql_depend_reftype cascade; +create schema plpgsql_depend_reftype; +set current_schema = plpgsql_depend_reftype; +set behavior_compat_options = 'plpgsql_dependency'; + +-- prepare data table +create or replace function create_data_table returns int as $$ +begin +drop table if exists stu; +create table stu (sno int, name varchar, sex varchar, cno int); +insert into stu values(1,'zhang','M',1); +insert into stu values(1,'zhang','M',1); +insert into stu values(2,'wangwei','M',2); +insert into stu values(3,'liu','F',3); +return 1; +end; +$$ +LANGUAGE plpgsql; +-- drop data table +create or replace function drop_data_table returns int as $$ +begin +drop table if exists stu; +return 1; +end; +$$ +LANGUAGE plpgsql; +-- drop data table cascade +create or replace function drop_data_table_cascade returns int as $$ +begin +drop table if exists stu cascade; +return 1; +end; +$$ +LANGUAGE plpgsql; + +-- test 1 ref type +select create_data_table(); + +--- define schema define table --- +--cur_db.def_schema.def_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c regression.plpgsql_depend_reftype.stu%RowType); + procedure proc1(); +end pkg; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--other_db.def_schema.def_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c undefdb.plpgsql_depend_reftype.stu%RowType); + procedure proc1(); +end pkg; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--cur_db.def_schema.def_rowtype_in_prochead +create or replace procedure proc12(v_1 regression.plpgsql_depend_reftype.stu%RowType) +as +begin + NULL; +end; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--other_db.def_schema.def_rowtype_in_prochead +create or replace procedure proc12(v_1 undefdb.plpgsql_depend_reftype.stu%RowType) +as +begin + NULL; +end; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--- define schema undefine table --- +--cur_db.def_schema.undef_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c regression.plpgsql_depend_reftype.undefstu%RowType); + procedure proc1(); +end pkg; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--other_db.def_schema.undef_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c undefdb.plpgsql_depend_reftype.undefstu%RowType); + procedure proc1(); +end pkg; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--cur_db.def_schema.undef_rowtype_in_prochead +create or replace procedure proc12(v_1 regression.plpgsql_depend_reftype.undefstu%RowType) +as +begin + NULL; +end; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--other_db.def_schema.undef_rowtype_in_prochead +create or replace procedure proc12(v_1 undefdb.plpgsql_depend_reftype.undefstu%RowType) +as +begin + NULL; +end; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--- undefine schema --- +--cur_db.undef_schema.undef_rowtype_in_prochead +create or replace procedure proc12(v_1 regression.undefplpgsql_depend_reftype.undefstu%RowType) +as +begin + NULL; +end; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + + +--- define schema define table --- +--def_schema.def_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c plpgsql_depend_reftype.stu%RowType); + procedure proc1(); +end pkg; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--def_schema.def_rowtype_in_prochead +create or replace procedure proc12(v_1 plpgsql_depend_reftype.stu%RowType) +as +begin + NULL; +end; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--def_schema.undef_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c plpgsql_depend_reftype.undefstu%RowType); + procedure proc1(); +end pkg; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--def_schema.undef_rowtype_in_prochead +create or replace procedure proc12(v_1 plpgsql_depend_reftype.undefstu%RowType) +as +begin + NULL; +end; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--- define table --- +--def_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c stu%RowType); + procedure proc1(); +end pkg; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--def_rowtype_in_prochead +create or replace procedure proc12(v_1 stu%RowType) +as +begin + NULL; +end; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--undef_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c undefstu%RowType); + procedure proc1(); +end pkg; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--undef_rowtype_in_prochead +create or replace procedure proc12(v_1 undefstu%RowType) +as +begin + NULL; +end; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--def_type_in_body +create or replace package pkg +is + type r1 is record(a int, c regression.plpgsql_depend_reftype.stu.sno%Type); + procedure proc1(); +end pkg; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; +--def_type_in_prohead +create or replace procedure proc12(v_1 regression.plpgsql_depend_reftype.stu.sno%Type) +as +begin + NULL; +end; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--undef_type_in_body +create or replace package pkg +is + type r1 is record(a int, c regression.plpgsql_depend_reftype.stu.undefsno%Type); + procedure proc1(); +end pkg; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; +--undef_type_in_prohead +create or replace procedure proc12(v_1 regression.plpgsql_depend_reftype.stu.undefsno%Type) +as +begin + NULL; +end; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +select drop_data_table_cascade(); + +drop schema if exists plpgsql_depend_reftype cascade; +reset behavior_compat_options; +create schema plpgsql_depend_reftype; +set current_schema = plpgsql_depend_reftype; +set behavior_compat_options = 'plpgsql_dependency'; +--test 2 ref pkg var type +create or replace package refpkg as +type r1 is record(a int, b int); +procedure proc1(); +end refpkg; +/ +--- define table --- +--cur_db.def_schema.def_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c regression.plpgsql_depend_reftype.refpkg.r1.a%Type); + procedure proc1(); +end pkg; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--other_db.def_schema.def_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c undefdb.plpgsql_depend_reftype.refpkg.r1.a%Type); + procedure proc1(); +end pkg; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--cur_db.def_schema.def_rowtype_in_prochead +create or replace procedure proc12(v_1 regression.plpgsql_depend_reftype.refpkg.r1.a%Type) +as +begin + NULL; +end; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--other_db.def_schema.def_rowtype_in_prochead +create or replace procedure proc12(v_1 undefdb.plpgsql_depend_reftype.refpkg.r1.a%Type) +as +begin + NULL; +end; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + + +--- define schema define pkgrec --- +--cur_db.def_schema.undef_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c regression.plpgsql_depend_reftype.refpkg.undefr1.a%Type); + procedure proc1(); +end pkg; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--other_db.def_schema.undef_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c undefdb.plpgsql_depend_reftype.refpkg.undefr1.a%Type); + procedure proc1(); +end pkg; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--cur_db.def_schema.undef_rowtype_in_prochead +create or replace procedure proc12(v_1 regression.plpgsql_depend_reftype.refpkg.undefr1.a%Type) +as +begin + NULL; +end; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--other_db.def_schema.undef_rowtype_in_prochead +create or replace procedure proc12(v_1 undefdb.plpgsql_depend_reftype.refpkg.undefr1.a%Type) +as +begin + NULL; +end; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--- define schema undefine pkg--- +--cur_db.def_schema.undef_rowtype_in_prochead +create or replace procedure proc12(v_1 regression.plpgsql_depend_reftype.undefpkg.undefr1.a%Type) +as +begin + NULL; +end; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--- undefine schema --- +--cur_db.undef_schema.undef_rowtype_in_prochead +create or replace procedure proc12(v_1 regression.undefplpgsql_depend_reftype.refpkg.undefr1.a%Type) +as +begin + NULL; +end; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--- define schema define pkg rec--- +--def_schema.def_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c plpgsql_depend_reftype.refpkg.r1.a%Type); + procedure proc1; +end pkg; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--def_schema.def_rowtype_in_prochead rsy +create or replace procedure proc12(v_1 plpgsql_depend_reftype.refpkg.r1.a%Type) +as +begin + NULL; +end; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--- define schema define pkg rec --- +--def_schema.undef_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c plpgsql_depend_reftype.refpkg.undefr1.a%Type); + procedure proc1(); +end pkg; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--def_schema.undef_rowtype_in_prochead +create or replace procedure proc12(v_1 plpgsql_depend_reftype.refpkg.undefr1.a%Type) +as +begin + NULL; +end; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--- undefine schema --- rsy +create or replace procedure proc12(v_1 undefplpgsql_depend_reftype.refpkg.undefr1.a%Type) +as +begin + NULL; +end; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + + +--- define pkg rec --- +--def_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c refpkg.r1.a%Type); + procedure proc1; +end pkg; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--def_rowtype_in_prochead +create or replace procedure proc12(v_1 refpkg.r1.a%Type) +as +begin + NULL; +end; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--- define pkg rec --- +--undef_rowtype_in_body +create or replace package pkg +is + type r1 is record(a int, c refpkg.undefr1%Type); + procedure proc1(); +end pkg; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +--undef_rowtype_in_prochead +create or replace procedure proc12(v_1 refpkg.undefr1%Type) +as +begin + NULL; +end; +/ +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + +drop package refpkg; +select * from gs_dependencies_obj where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_reftype' order by schemaname, packagename, objectname, refobjpos; + + +-- clean +drop schema plpgsql_depend_reftype cascade; +reset behavior_compat_options; \ No newline at end of file diff --git a/src/test/regress/sql/plpgsql_depend/plpgsql_depend_type.sql b/src/test/regress/sql/plpgsql_depend/plpgsql_depend_type.sql new file mode 100644 index 000000000..dc7f6c4aa --- /dev/null +++ b/src/test/regress/sql/plpgsql_depend/plpgsql_depend_type.sql @@ -0,0 +1,1419 @@ +drop schema if exists plpgsql_depend_type cascade; +create schema plpgsql_depend_type; +set current_schema = plpgsql_depend_type; +set behavior_compat_options = 'plpgsql_dependency'; + +-- prepare data table +create or replace function create_data_table returns int as $$ +begin +drop table if exists stu; +create table stu (sno int, name varchar, sex varchar, cno int); +insert into stu values(1,'zhang','M',1); +insert into stu values(1,'zhang','M',1); +insert into stu values(2,'wangwei','M',2); +insert into stu values(3,'liu','F',3); +return 1; +end; +$$ +LANGUAGE plpgsql; +-- drop data table +create or replace function drop_data_table returns int as $$ +begin +drop table if exists stu; +return 1; +end; +$$ +LANGUAGE plpgsql; +-- drop data table cascade +create or replace function drop_data_table_cascade returns int as $$ +begin +drop table if exists stu cascade; +return 1; +end; +$$ +LANGUAGE plpgsql; +-- test 0 pkg_record_undefine_schema_type +drop package if exists pkg; +create or replace package pkg +is + type r1 is record(a int, b sr); + procedure proc1; +end pkg; +/ +-- valid is false +select valid from pg_object where object_type='S' and object_oid in ( + select Oid from gs_package where pkgname='pkg' and pkgnamespace = ( + select Oid from pg_namespace where nspname = 'plpgsql_depend_type') + ); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast +from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where ( + a.schemaname='plpgsql_depend_type' and a.packagename='pkg' +) or ( + b.schemaname='plpgsql_depend_type' and b.packagename='pkg' +) order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop package pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast +from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where ( + a.schemaname='plpgsql_depend_type' and a.packagename='pkg' +) or ( + b.schemaname='plpgsql_depend_type' and b.packagename='pkg' +) order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 1 pkg_record_non_complete_define_schema_type +drop package if exists pkg2; +create or replace package pkg2 +is + type r2 is record(a int, b sr); + procedure proc1; +end pkg2; +/ +create or replace package pkg +is + type r1 is record(a int, b pkg2.r2); + procedure proc1; +end pkg; +/ +-- valid is false +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove ref dependency, undefined +drop package pkg2; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop package pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + + -- test 2 pkg_record_define_schema_type +drop type if exists sr cascade; +create type sr as (a int, b int); +drop package if exists pkg; +create or replace package pkg +is + type r1 is record(a int, b sr); + procedure proc1; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove ref dependency, undefined +drop type sr cascade; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop package pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 3 pkg_tbl_undefine_schema_type +drop type if exists undefsr cascade; +drop package if exists pkg; +create or replace package pkg +is + type tf1 is table of undefsr index by binary_integer; + procedure proc1; +end pkg; +/ +-- valid is false +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- define ref dependency +create type undefsr as (a int, b int); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +drop type undefsr cascade; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop package pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 4 pkg_tbl_define_schema_type +drop type if exists sr cascade; +create type sr as (a int, b int); +drop package if exists pkg; +create or replace package pkg +is + type tf1 is table of sr index by binary_integer; + procedure proc1; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency +drop type sr cascade; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency +drop package pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 5 pkg_varray_undefine_schema_type +drop type if exists undefsr cascade; +drop package if exists pkg; +create or replace package pkg +is + type varr1 is varray(1024) of undefsr; + procedure proc1; +end pkg; +/ +-- valid is false +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- define ref dependency +create type undefsr as (a int, b int); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +drop type undefsr cascade; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop package pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 6 pkg_varray_define_schema_type +drop type if exists sr cascade; +create type sr as (a int, b int); +drop package if exists pkg; +create or replace package pkg +is + type t_arr_sr is varray(999) of sr; + procedure proc1; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- define ref dependency +drop type sr cascade; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop package pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 7 pkg_tbl_undefine_pkg_type +drop package if exists pkg2; +drop package if exists pkg; +create or replace package pkg +is + type tf1 is table of pkg2.r1 index by binary_integer; + procedure proc1; +end pkg; +/ +-- valid is false +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency +drop package pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 8 pkg_tbl_define_pkg_type +drop package if exists pkg2; +create or replace package pkg2 +is + type r1 is record(a int, b int); + procedure proc1; +end pkg2; +/ +drop package if exists pkg; +create or replace package pkg +is + type tf1 is table of pkg2.r1 index by binary_integer; + procedure proc1; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- define ref dependency +drop package pkg2; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop package pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 9 pkg_varray_undefine_pkg_type +drop package if exists pkg2; +drop package if exists pkg; +create or replace package pkg +is + type t_arr_sr is varray(999) of pkg2.r1; + procedure proc1; +end pkg; +/ +-- valid is false +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency +drop package pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 10 pkg_varray_define_pkg_type +drop package if exists pkg2; +create or replace package pkg2 +is + type r1 is record(a int, b int); + procedure proc1; +end pkg2; +/ +drop package if exists pkg; +create or replace package pkg +is + type tf1 is varray(999) of pkg2.r1; + procedure proc1; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- define ref dependency +drop package pkg2; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop package pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 11 pkg_record_undefine_table_rowtype +drop package if exists pkg; +create or replace package pkg +is + type r1 is record(a int, c undefStu%RowType); + procedure proc1; +end pkg; +/ +-- valid is false +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency +drop package pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 12 pkg_record_define_table_rowtype +select create_data_table(); +drop package if exists pkg; +create or replace package pkg +is + type r1 is record(a int, c stu%RowType); + procedure proc1; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + +alter table stu add column z int; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + +alter package pkg compile; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + +alter table stu drop column z; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + +alter package pkg compile; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + +alter table stu rename to newstu; + +-- remove dependency, no drop +select drop_data_table(); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, undefined +select drop_data_table_cascade(); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop package pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 13 pkg_record_undefine_table_undefine_col_type +drop package if exists pkg; +create or replace package pkg +is + type r1 is record(a int, c undefStu.undefname%Type); + procedure proc1; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop package pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 14 pkg_record_define_table_undefine_col_type +drop package if exists pkg; +create or replace package pkg +is + type r1 is record(a int, c stu.undefname%Type); + procedure proc1; +end pkg; +/ +-- valid is false +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop package pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 15 pkg_record_define_table_col_type +select create_data_table(); +drop package if exists pkg; +create or replace package pkg +is + type r1 is record(a int, c stu.name%Type); + procedure proc1; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, undefined +select drop_data_table(); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop package pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 16 pkg_record_define_pkg_v1_type +drop package if exists pkg2; +create or replace package pkg2 +is + v1 int; + procedure proc1; +end pkg2; +/ +drop package if exists pkg; +create or replace package pkg +is + type r1 is record(a int, c pkg2.v1%Type); + procedure proc1; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- define ref dependency, undefined +drop package pkg2; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop package pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 16 pkg_record_define_pkg_r1_rowtype +drop package if exists pkg2; +create or replace package pkg2 +is + type r2 is record(a int, b int); + procedure proc1; +end pkg2; +/ +drop package if exists pkg; +create or replace package pkg +is + type r1 is record(a int, c pkg2.r2%RowType); + procedure proc1; +end pkg; +/ +-- compile error +-- valid is none +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- define ref dependency +drop package pkg2; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop package pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 17 pkg_record_define_schema_pkg_r1_rowtype +drop package if exists pkg2; +create or replace package pkg2 +is + type r2 is record(a int, b int); + procedure proc1; +end pkg2; +/ +drop package if exists pkg; +create or replace package pkg +is + type r1 is record(a int, c plpgsql_depend_type.pkg2.r2%RowType); + procedure proc1; +end pkg; +/ +-- compile error +-- valid is none +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- define ref dependency +drop package pkg2; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop package pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 18 pkg_body_record_define_schema +drop type if exists sr cascade; +create type sr as (a int, b int); +drop package if exists pkg; +create or replace package pkg +is + function proc1() return int; +end pkg; +/ +create or replace package body pkg +is + type r1 is record(a int, b sr); + function proc1() return int as + begin + return 1; + end; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- define ref dependency +drop type sr cascade; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop package pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 19 pkg_body_tableof_define_schema +drop type if exists sr cascade; +create type sr as (a int, b int); +drop package if exists pkg; +create or replace package pkg +is + function proc1() return int; +end pkg; +/ +create or replace package body pkg +is + type tf1 is table of sr index by binary_integer; + function proc1() return int as + begin + return 1; + end; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- define ref dependency +drop type sr cascade; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop package pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 20 pkg_body_varray_define_schema +drop type if exists sr cascade; +create type sr as (a int, b int); +drop package if exists pkg; +create or replace package pkg +is + function proc1() return int; +end pkg; +/ +create or replace package body pkg +is + type t_arr_sr is varray(999) of sr; + function proc1() return int as + begin + return 1; + end; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- define ref dependency +drop type sr cascade; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop package pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 21 pkg_body_record_undefine_schema_type +drop package if exists pkg; +create or replace package pkg +is + function proc1() return int; +end pkg; +/ +create or replace package body pkg +is + type t_arr_sr is varray(999) of undefsr; + function proc1() return int as + begin + return 1; + end; +end pkg; +/ +-- valid is false +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop package pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 22 pkg_spec_var_used_undefine_pkg_type +drop package if exists pkg; +create or replace package pkg +is + v_1 pkg2.r1; + procedure proc1; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- define ref dependency +drop package pkg2; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop package pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 23 pkg_spec_var_used_define_schema_type +drop type if exists sr cascade; +create type sr as (a int, b int); +drop package if exists pkg; +create or replace package pkg +is + v_1 sr; + procedure proc1; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- define ref dependency +drop type sr cascade; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop package pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 24 pkg_body_var_used_define_schema_type +drop type if exists sr cascade; +create type sr as(a int, b int); +drop package if exists pkg; +create or replace package pkg +is + procedure proc1; +end pkg; +/ +create or replace package body pkg +is + v_1 sr; + procedure proc1() as begin null; end; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- define ref dependency +drop type sr cascade; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop package pkg; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 25 pkg_proc_body_var_used_define_schema_type +drop type if exists sr cascade; +create type sr as(a int, b int); +drop package if exists pkg; +create or replace package pkg +is + procedure proc1; +end pkg; +/ +create or replace package body pkg +is + procedure proc1() as + declare + v_1 sr; + begin null; end; +end pkg; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- define ref dependency, undefined +drop type sr cascade; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop package pkg; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 26 proc_body_var_used_define_schema_type +drop type if exists sr cascade; +create type sr as(a int, b int); +drop procedure if exists proc1; +create or replace procedure proc1() as +declare + v_1 sr; +begin + null; +end; +/ +-- valid is true +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- define ref dependency +drop type sr cascade; +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop procedure proc1; +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + -- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + +-- test 27 proc_body_var_used_define_pkg_tablof +drop type if exists sr cascade; +create type sr as(a int, b int); +drop package if exists pkg; +create or replace package pkg +is + type tf1 is table of sr index by binary_integer; +end pkg; +/ +drop procedure if exists proc1; +create or replace procedure proc1() as +declare + v_tf1 pkg.tf1; +begin + null; +end; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- drop ref dependency +drop type sr cascade; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency +drop package pkg; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop procedure proc1; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 28 proc_body_var_used_define_pkg_varray +drop type if exists sr cascade; +create type sr as(a int, b int); +drop package if exists pkg; +create or replace package pkg +is + type arr1 is varray(888) of sr; + type tf1 is table of sr index by binary_integer; +end pkg; +/ +drop procedure if exists proc1; +create or replace procedure proc1() as +declare + v_arr1 pkg.arr1; + v_tf1 pkg.tf1; +begin + null; +end; +/ +-- valid is true +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- drop ref dependency +drop type sr cascade; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove ref dependency +drop package pkg; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop procedure proc1; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select valid from pg_object where object_type='B' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 29 proc_param_type_used_define_schema_type +drop type if exists sr cascade; +create type sr as(a int, b int); +drop procedure if exists proc1; +create or replace procedure proc1(v_1 sr) as +begin + null; +end; +/ +-- valid is true +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.sr)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.sr)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- define ref dependency +drop type sr cascade; +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(pg_catalog.undefined)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(pg_catalog.undefined)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + -- create ref dependency +create type sr as (a int, b int); +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.sr)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.sr)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop procedure proc1; +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.sr)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.sr)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + -- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 30 proc_return_type_used_define_schema_type +drop type if exists sr cascade; +create type sr as(a int, b int); +drop function if exists proc1; +create or replace function proc1() return sr as +begin + null; +end; +/ +-- valid is true +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove ref dependency +drop type sr cascade; +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + -- create ref dependency +create type sr as (a int, b int); +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop function proc1; +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + -- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 31 proc_param_type_used_undefine_schema_type +drop type if exists sr cascade; +drop procedure if exists proc1; +create or replace procedure proc1(v_1 sr) as +begin + null; +end; +/ +-- valid is false +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(pg_catalog.undefined)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(pg_catalog.undefined)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- create ref dependency +create type sr as (a int, b int); +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on +po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = +(select Oid from pg_namespace where nspname='plpgsql_depend_type'); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.sr)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.sr)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- define ref dependency +alter procedure proc1 compile; +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); +drop type sr cascade; +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(pg_catalog.undefined)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(pg_catalog.undefined)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop procedure proc1; +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.sr)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.sr)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + -- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos + from gs_dependencies where schemaname='plpgsql_depend_type' + order by schemaname, packagename, objectname, refobjpos; +-- test 32 proc_return_type_used_undefine_schema_type +drop type if exists sr cascade; +drop function if exists proc1; +create or replace function proc1() return sr as +begin + null; +end; +/ +-- valid is false +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- create ref dependency +create type sr as (a int, b int); +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency +drop type sr cascade; +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop procedure proc1; +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + -- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + +--test 33 proc_param_type_used_define_pkg_type +drop type if exists sr cascade; +create type sr as (a int, b int); +drop package if exists pkg; +create or replace package pkg +is + type arr1 is varray(888) of sr; + type tf1 is table of sr index by binary_integer; + procedure proc1; +end pkg; +/ +drop procedure if exists proc1; +create or replace procedure proc1(v_1 pkg.arr1) as +begin + null; +end; +/ +-- valid is true +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.pkg.arr1)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.pkg.arr1)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + -- remove ref dependency +create or replace package pkg +is + type tf1 is table of sr index by binary_integer; + procedure proc1; +end pkg; +/ +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(pg_catalog.undefined)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(pg_catalog.undefined)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + -- create ref dependency +create or replace package pkg +is + type arr1 is varray(888) of sr; + procedure proc1; +end pkg; +/ +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.pkg.arr1)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.pkg.arr1)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop procedure proc1; +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.pkg.arr1)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.pkg.arr1)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + -- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 34 proc_param_type_used_define_pkg_type +drop type if exists sr cascade; +create type sr as (a int, b int); +drop package if exists pkg; +create or replace package pkg +is + type arr1 is varray(888) of sr; + type tf1 is table of sr index by binary_integer; + procedure proc1; +end pkg; +/ +drop procedure if exists proc1; +create or replace function proc1() return pkg.tf1 as +begin + null; +end; +/ +-- valid is true +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + -- remove ref dependency +create or replace package pkg +is + type arr1 is varray(888) of sr; + procedure proc1; +end pkg; +/ +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + -- create ref dependency +create or replace package pkg +is + type tf1 is table of sr index by binary_integer; + procedure proc1; +end pkg; +/ +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +-- remove dependency, no rows +drop procedure proc1; +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1()') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1()') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + -- is clean +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +--test 35 proc_param_type_used_undefine_pkg_type +drop type if exists sr cascade; +drop package if exists pkg; +drop procedure if exists proc1; +create or replace procedure proc1(v_1 pkg.arr1) as +begin + null; +end; +/ +-- valid is true +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(pg_catalog.undefined)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(pg_catalog.undefined)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + -- remove ref dependency +create or replace package pkg +is + type tf1 is table of sr index by binary_integer; + procedure proc1; +end pkg; +/ + +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(pg_catalog.undefined)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(pg_catalog.undefined)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + + -- create ref dependency +create or replace package pkg +is + type arr1 is varray(888) of sr; + procedure proc1; +end pkg; +/ + +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.pkg.arr1)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.pkg.arr1)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + +create type sr as (a int, b int); +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.pkg.arr1)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.pkg.arr1)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + +alter package pkg compile; +drop type sr; +drop type sr cascade; +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.pkg.arr1)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.pkg.arr1)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select valid from pg_object where object_type='S' and object_oid in (select Oid from gs_package where pkgname='pkg' and pkgnamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + +drop package pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.pkg.arr1)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.pkg.arr1)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + +-- remove dependency, no rows +drop procedure proc1; +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='proc1' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_depend_type')); +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.pkg.arr1)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.pkg.arr1)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.packagename='pkg') or (b.schemaname='plpgsql_depend_type' and b.packagename='pkg') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + +--test 36 schema_table_nest_record +create type ssr is ( + id integer, + name varchar, + addr text +); +create type stab is table of ssr; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'stab') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; + +create or replace procedure proc1(a stab) as begin null; end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'stab') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid + where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.stab)') + or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.stab)') + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + +create or replace procedure proc1(a ssr) as begin null; end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'stab') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.ssr)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.ssr)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.stab)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.stab)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + +drop type ssr; +drop type ssr cascade; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'stab') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.ssr)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.ssr)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.stab)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.stab)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(pg_catalog.undefined)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(pg_catalog.undefined)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + +create type ssr is ( + id integer, + name varchar, + addr text +); +create type stab is table of ssr; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'stab') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.ssr)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.ssr)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.stab)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.stab)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + +drop procedure proc1; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'stab') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.ssr)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.ssr)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.stab)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.stab)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + +drop type ssr; +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- is clean +drop type stab; +select * from gs_dependencies_obj where schemaname='plpgsql_depend_type' order by schemaname, packagename, name, type; +select schemaname, packagename, objectname, refobjpos from gs_dependencies where schemaname='plpgsql_depend_type' order by schemaname, packagename, objectname, refobjpos; + +-- test 37 +create type t2 as enum ('create', 'modify', 'closed'); + +alter type t2 rename value 'create' to 'newcreate'; + +create or replace procedure proc1(vb t2) as +declare +v_1 t2; +begin +null; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.t2)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.t2)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + +alter type t2 add value 'modif3' before 'closed'; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.t2)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.t2)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + +alter type t2 rename to t3; +drop type t2; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a right join gs_dependencies_obj as b on b.oid = a.refobjoid where (a.schemaname='plpgsql_depend_type' and a.objectname = 'proc1(plpgsql_depend_type.t2)') or (b.schemaname='plpgsql_depend_type' and b.name = 'proc1(plpgsql_depend_type.t2)') order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select pr.proname, po.valid, pr.proargtypes, pr.proargsrc from pg_proc as pr inner join pg_object as po on po.object_type='P' and po.object_oid = pr.Oid where pr.propackageid=0 and pr.proname='proc1' and pr.pronamespace = (select Oid from pg_namespace where nspname='plpgsql_depend_type'); + + +-- clean +drop schema plpgsql_depend_type cascade; +reset behavior_compat_options; \ No newline at end of file diff --git a/src/test/regress/sql/plpgsql_depend/plpgsql_pkg_dependency.sql b/src/test/regress/sql/plpgsql_depend/plpgsql_pkg_dependency.sql new file mode 100644 index 000000000..605af9f4a --- /dev/null +++ b/src/test/regress/sql/plpgsql_depend/plpgsql_pkg_dependency.sql @@ -0,0 +1,40 @@ +drop schema if exists plpgsql_pkg_dependency cascade; +create schema plpgsql_pkg_dependency; +set current_schema = plpgsql_pkg_dependency; +set behavior_compat_options = 'plpgsql_dependency'; + +create or replace package test_package_depend2_pkg is +type t is record (col1 int, col2 text); +procedure p1(param test_package_depend3_pkg.t); +end test_package_depend2_pkg; +/ +create or replace package body test_package_depend2_pkg is +procedure p1(param test_package_depend3_pkg.t) is + begin + RAISE INFO 'call param: %', param; + end; +end test_package_depend2_pkg; +/ + +create or replace package test_package_depend3_pkg is +type t is record (col1 int, col2 text, col3 varchar); +procedure p1(param test_package_depend2_pkg.t); +end test_package_depend3_pkg; +/ +create or replace package body test_package_depend3_pkg is +procedure p1(param test_package_depend2_pkg.t) is + begin + RAISE INFO 'call param: %', param; + end; +end test_package_depend3_pkg; +/ + +call test_package_depend2_pkg.p1((1,'a','2023')); +call test_package_depend3_pkg.p1((1,'a')); + +drop package if exists test_package_depend2_pkg; +drop package if exists test_package_depend3_pkg; + +-- clean +drop schema plpgsql_pkg_dependency cascade; +reset behavior_compat_options; \ No newline at end of file diff --git a/src/test/regress/sql/plpgsql_depend/plpgsql_pkg_variable_dependency.sql b/src/test/regress/sql/plpgsql_depend/plpgsql_pkg_variable_dependency.sql new file mode 100644 index 000000000..6c26023d9 --- /dev/null +++ b/src/test/regress/sql/plpgsql_depend/plpgsql_pkg_variable_dependency.sql @@ -0,0 +1,1541 @@ +drop schema if exists pkg_var_test cascade; +create schema pkg_var_test; +set current_schema = pkg_var_test; +set behavior_compat_options = 'plpgsql_dependency'; + +-- 1.test function depends on package var in assignment statement +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace function test_func return int +is + func_var int; +begin + func_var := test_pkg.ref_var; + return 1; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +create or replace package test_pkg as + ref_var int; + -- unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +create or replace package test_pkg as + -- ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +drop function test_func; + +-- 1.1 modifying the package var type +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace function test_func return int +is + func_var int; +begin + func_var := test_pkg.ref_var; + return 1; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +create or replace package test_pkg as + ref_var int; + unref_var varchar(16); +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +create or replace package test_pkg as + ref_var varchar(16); + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +drop function test_func; + +-- 2.test function depends on package var in return statement +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace function test_func return int +is + func_var int; +begin + func_var := 1; + return test_pkg.ref_var; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +create or replace package test_pkg as + ref_var int; + -- unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +create or replace package test_pkg as + -- ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +drop function test_func; + +-- 2.1 modifying the package var type +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace function test_func return int +is + func_var int; +begin + func_var := 1; + return test_pkg.ref_var; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +create or replace package test_pkg as + ref_var int; + unref_var varchar(16); +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +create or replace package test_pkg as + ref_var varchar(16); + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +drop function test_func; + + +-- 3.test function depends on package var in if statement +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace function test_func return int +is + func_var int; +begin + if test_pkg.ref_var = 1 then + func_var := 1; + end if; + return 1; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +create or replace package test_pkg as + ref_var int; + -- unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +create or replace package test_pkg as + -- ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +drop function test_func; + +-- 3.1 modifying the package var type +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace function test_func return int +is + func_var int; +begin + if test_pkg.ref_var = 1 then + func_var := 1; + end if; + return 1; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +create or replace package test_pkg as + ref_var int; + unref_var varchar(16); +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +create or replace package test_pkg as + ref_var varchar(16); + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +drop function test_func; + + +-- 4.test function depends on package var in while statement +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace function test_func return int +is + func_var int; +begin + while test_pkg.ref_var < 1 loop + func_var := 1; + end loop; + return 1; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +create or replace package test_pkg as + ref_var int; + -- unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +create or replace package test_pkg as + -- ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +drop function test_func; + +-- 4.1 modifying the package var type +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace function test_func return int +is + func_var int; +begin + while test_pkg.ref_var < 1 loop + func_var := 1; + end loop; + return 1; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +create or replace package test_pkg as + ref_var int; + unref_var varchar(16); +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +create or replace package test_pkg as + ref_var varchar(16); + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +drop function test_func; + +-- 5.test function depends on package var in case statement +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace function test_func return int +is + func_var int; +begin + case test_pkg.ref_var + when 1 then + func_var := 1; + end case; + return 1; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +create or replace package test_pkg as + ref_var int; + -- unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +create or replace package test_pkg as + -- ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +drop function test_func; + +-- 5.1 modifying the package var type +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace function test_func return int +is + func_var int; +begin + case test_pkg.ref_var + when 1 then + func_var := 1; + end case; + return 1; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +create or replace package test_pkg as + ref_var int; + unref_var varchar(16); +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +create or replace package test_pkg as + ref_var varchar(16); + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +drop function test_func; + +-- 6.test procedure depends on package var in assignment statement +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace procedure test_proc +is + proc_var int; +begin + proc_var := test_pkg.ref_var; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + + +create or replace package test_pkg as + ref_var int; + -- unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +create or replace package test_pkg as + -- ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +drop procedure test_proc; + +-- 6.1 modifying the package var type +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace procedure test_proc +is + proc_var int; +begin + proc_var := test_pkg.ref_var; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + + +create or replace package test_pkg as + ref_var int; + unref_var varchar(16); +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +create or replace package test_pkg as + ref_var varchar(16); + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +drop procedure test_proc; + + +-- 7.test procedure depends on package var in if statement +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace procedure test_proc +is + proc_var int; +begin + if test_pkg.ref_var = 1 then + proc_var := 1; + end if; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + + +create or replace package test_pkg as + ref_var int; + -- unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +create or replace package test_pkg as + -- ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +drop procedure test_proc; + +-- 7.1 modifying the package var type +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace procedure test_proc +is + proc_var int; +begin + if test_pkg.ref_var = 1 then + proc_var := 1; + end if; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + + +create or replace package test_pkg as + ref_var int; + unref_var varchar(16); +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +create or replace package test_pkg as + ref_var varchar(16); + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +drop procedure test_proc; + +-- 8.test procedure depends on package var in while statement +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace procedure test_proc +is + proc_var int; +begin + while test_pkg.ref_var < 1 loop + proc_var := 1; + end loop; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + + +create or replace package test_pkg as + ref_var int; + -- unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +create or replace package test_pkg as + -- ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +drop procedure test_proc; + +-- 8.1 modifying the package var type +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace procedure test_proc +is + proc_var int; +begin + while test_pkg.ref_var < 1 loop + proc_var := 1; + end loop; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + + +create or replace package test_pkg as + ref_var int; + unref_var varchar(16); +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +create or replace package test_pkg as + ref_var varchar(16); + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +drop procedure test_proc; + + +-- 9.test procedure depends on package var in case statement +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace procedure test_proc +is + proc_var int; +begin + case test_pkg.ref_var + when 1 then + proc_var := 1; + end case; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + + +create or replace package test_pkg as + ref_var int; + -- unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +create or replace package test_pkg as + -- ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +drop procedure test_proc; + +-- 9.1 modifying the package var type +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +create or replace procedure test_proc +is + proc_var int; +begin + case test_pkg.ref_var + when 1 then + proc_var := 1; + end case; +end; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + + +create or replace package test_pkg as + ref_var int; + unref_var varchar(16); +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +create or replace package test_pkg as + ref_var varchar(16); + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +create or replace package test_pkg as + ref_var int; + unref_var int; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +alter procedure test_proc compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_proc%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_proc'; + +drop procedure test_proc; + +-- 10.test the cursor var of the dependent package in the open statement +create table test_table (ref_col int, unref_col int); + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ + +create or replace function test_func return int +is +begin + open test_pkg.ref_var; + return 1; +end; +/ + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + -- cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +create or replace package test_pkg as + -- cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +drop function test_func; + + +-- 10.1 modifying the package var type + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ + +create or replace function test_func return int +is +begin + open test_pkg.ref_var; + return 1; +end; +/ + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + unref_var varchar(32); +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +create or replace package test_pkg as + ref_var varchar(32); + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +drop function test_func; +drop table test_table; + +-- 11.test the cursor var of the dependent package in the fetch statement +create table test_table (ref_col int, unref_col int); + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ + +create or replace function test_func return int +is + func_var int; +begin + fetch test_pkg.ref_var into func_var; + return func_var; +end; +/ + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + -- cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +create or replace package test_pkg as + -- cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +drop function test_func; + +-- 11.1 modifying the package var type + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ + +create or replace function test_func return int +is + func_var int; +begin + fetch test_pkg.ref_var into func_var; + return func_var; +end; +/ + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + unref_var varchar(32); +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +create or replace package test_pkg as + ref_var varchar(32); + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +drop function test_func; +drop table test_table; + +-- 12.test the cursor var of the dependent package in the close statement +create table test_table (ref_col int, unref_col int); + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ + +create or replace function test_func return int +is +begin + close test_pkg.ref_var; + return 1; +end; +/ + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + -- cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +create or replace package test_pkg as + -- cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +drop function test_func; + + +-- 12.1 modifying the package var type + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ + +create or replace function test_func return int +is +begin + close test_pkg.ref_var; + return 1; +end; +/ + +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, + b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast + from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid + order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace + where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and + pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + unref_var varchar(32); +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +create or replace package test_pkg as + ref_var varchar(32); + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +create or replace package test_pkg as + cursor ref_var is select ref_col from test_table; + cursor unref_var is select unref_col from test_table; +end test_pkg; +/ +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +alter function test_func compile; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + + +drop package test_pkg; +select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos as refpos, b.schemaname as refsn, b.packagename as refpn, b.name as refon, b.type as refot, b.objnode as refast from gs_dependencies as a, gs_dependencies_obj as b where a.schemaname = 'pkg_var_test' and a.objectname like 'test_func%' and a.refobjoid = b.oid order by a.schemaname, a.objectname, a.refobjpos, b.type, b.name; +select nspname, proname, valid from pg_proc,pg_object,pg_namespace where pg_proc.oid=pg_object.object_oid and pg_namespace.oid=pg_proc.pronamespace and pg_namespace.nspname='pkg_var_test' and pg_proc.proname='test_func'; + +drop function test_func; +drop table test_table; +-- clean +drop schema pkg_var_test cascade; +reset behavior_compat_options; \ No newline at end of file diff --git a/src/test/regress/sql/plpgsql_depend/plpgsql_recompile.sql b/src/test/regress/sql/plpgsql_depend/plpgsql_recompile.sql new file mode 100644 index 000000000..6689ad27b --- /dev/null +++ b/src/test/regress/sql/plpgsql_depend/plpgsql_recompile.sql @@ -0,0 +1,110 @@ +drop schema if exists plpgsql_recompile cascade; +create schema plpgsql_recompile; +set current_schema = plpgsql_recompile; +set behavior_compat_options = 'plpgsql_dependency'; +---test 1 +create type s_type as ( + id integer, + name varchar, + addr text +); + +create or replace procedure type_alter(a s_type) +is +begin + RAISE INFO 'call a: %', a; +end; +/ +select valid from pg_object where object_type='P' and object_oid +in (select Oid from pg_proc where propackageid = 0 and proname='type_alter' and pronamespace = +(select Oid from pg_namespace where nspname = 'plpgsql_recompile')); +call type_alter((1,'zhang','shanghai')); + +alter function type_alter compile; +alter procedure type_alter(s_type) compile; + +alter type s_type ADD attribute a int; +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='type_alter' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_recompile')); +call type_alter((1,'zhang','shanghai',100)); +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='type_alter' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_recompile')); + +alter type s_type DROP attribute a; +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='type_alter' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_recompile')); +call type_alter((1,'zhang','shanghai')); +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='type_alter' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_recompile')); + +alter type s_type ALTER attribute id type float; +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='type_alter' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_recompile')); +alter procedure type_alter compile; +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='type_alter' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_recompile')); +call type_alter((1.0,'zhang','shanghai')); +select valid from pg_object where object_type='P' and object_oid in (select Oid from pg_proc where propackageid = 0 and proname='type_alter' and pronamespace = (select Oid from pg_namespace where nspname = 'plpgsql_recompile')); + +-- report error +alter type s_type RENAME to s_type_rename; +ALTER type s_type RENAME ATTRIBUTE name TO new_name; +call type_alter((1,'zhang','shanghai')); + +-- test 2 +drop table if exists stu; +create table stu(sno int, name varchar, sex varchar, cno int); +create type r1 as (a int, c stu%RowType); + +drop package if exists pkg; +create or replace package pkg +is +procedure proc1(p_in r1); +end pkg; +/ +create or replace package body pkg +is +declare +v1 r1; +v2 stu%RowType; +procedure proc1(p_in r1) as +begin +RAISE INFO 'call p_in: %', p_in; +end; +end pkg; +/ + +call pkg.proc1((1,(1,'zhang','M',1))); +alter package pkg compile; +alter package pkg compile specification; +alter package pkg compile body; +alter package pkg compile package; + +alter table stu ADD column b int; +alter package pkg compile; +call pkg.proc1((1,(1,'zhang','M',1,2))); + + +alter table stu DROP column b; +alter package pkg compile; +call pkg.proc1((1,(1,'zhang','M',1))); + +alter table stu RENAME to stu_re; +alter package pkg compile; +call pkg.proc1((1,(1,'zhang','M',1))); + +alter type r1 ALTER attribute a type float; +alter package pkg compile; +call pkg.proc1((1.0,(1,'zhang','M',1))); + +--compile error +create or replace package body pkg +is +declare +v1 r1%RowType; +procedure proc1(p_in r1) as +begin +select into v1 values (1,ROW(1,'zhang','M',1)); +RAISE INFO 'call p_in: %', p_in; +end; +end pkg; +/ +alter package pkg compile; + +-- select oid,* from pg_type where typname='stu'; +drop schema plpgsql_recompile cascade; +reset behavior_compat_options; diff --git a/src/test/regress/sql/single_node_type_sanity.sql b/src/test/regress/sql/single_node_type_sanity.sql index 5d1bcba05..bad1e6bb3 100644 --- a/src/test/regress/sql/single_node_type_sanity.sql +++ b/src/test/regress/sql/single_node_type_sanity.sql @@ -61,7 +61,7 @@ WHERE p1.typtype not in ('c','d','p') AND p1.typname NOT LIKE E'\\_%' AND NOT EXISTS (SELECT 1 FROM pg_type as p2 WHERE p2.typname = ('_' || p1.typname)::name AND - p2.typelem = p1.oid and p1.typarray = p2.oid) AND p1.typname not in ('desc_tab', 'date_table', 'number_table', 'varchar2_table'); + p2.typelem = p1.oid and p1.typarray = p2.oid) AND p1.typname not in ('desc_tab', 'date_table', 'number_table', 'varchar2_table') order by p1.oid; -- Make sure typarray points to a varlena array type of our own base SELECT p1.oid, p1.typname as basetype, p2.typname as arraytype,