diff --git a/src/common/backend/catalog/pg_object.cpp b/src/common/backend/catalog/pg_object.cpp index 27ded1291..da20cc88a 100644 --- a/src/common/backend/catalog/pg_object.cpp +++ b/src/common/backend/catalog/pg_object.cpp @@ -548,7 +548,7 @@ bool SetPgObjectValid(Oid oid, PgObjectType objectType, bool valid) 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 + (void)simple_heap_update(relation, &new_tuple->t_self, new_tuple, true); CatalogUpdateIndexes(relation, new_tuple); heap_freetuple(new_tuple); ReleaseSysCache(tuple); diff --git a/src/common/backend/parser/gram.y b/src/common/backend/parser/gram.y index f429075c7..64efe39c8 100644 --- a/src/common/backend/parser/gram.y +++ b/src/common/backend/parser/gram.y @@ -16615,12 +16615,11 @@ param_name: type_function_name ; func_return: - func_type { - if (enable_plpgsql_gsdependency_guc()) { - pg_yyget_extra(yyscanner)->core_yy_extra.return_pos_end = yylloc; - } - } + 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. * - thomas 2000-03-22 diff --git a/src/common/backend/utils/gsplsql/gsdependencies.cpp b/src/common/backend/utils/gsplsql/gsdependencies.cpp index bf7320193..f4f8c53b7 100644 --- a/src/common/backend/utils/gsplsql/gsdependencies.cpp +++ b/src/common/backend/utils/gsplsql/gsdependencies.cpp @@ -562,6 +562,9 @@ bool gsplsql_set_pkg_func_status(Oid schema_oid, Oid pkg_oid, bool status) foreach(cell, list) { Oid func_oid = lfirst_oid(cell); result = SetPgObjectValid(func_oid, OBJECT_TYPE_PROC, status) || result; + if (!status) { + CacheInvalidateFunction(func_oid, pkg_oid); + } } list_free(list); return result; @@ -1118,7 +1121,9 @@ 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); + bool result = SetPgObjectValid(func_oid, OBJECT_TYPE_PROC, false); + CacheInvalidateFunction(func_oid, InvalidOid); + return result; } static bool gsplsql_invalidate_pkg(const char *schemaName, const char *pkgName, bool isSpec, Oid currCompileOid) diff --git a/src/common/pl/plpgsql/src/gram.y b/src/common/pl/plpgsql/src/gram.y index 8d38e0977..4c5b598bf 100755 --- a/src/common/pl/plpgsql/src/gram.y +++ b/src/common/pl/plpgsql/src/gram.y @@ -1447,6 +1447,8 @@ 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, $9->dependExtend); + } else if (enable_plpgsql_gsdependency()) { + gsplsql_build_gs_type_in_body_dependency($9); } pfree_ext($2->name); pfree($2); @@ -1482,6 +1484,12 @@ decl_statement : decl_varname_list decl_const decl_datatype decl_collate decl_no plpgsql_build_varrayType($2->name, $2->lineno, newp, true); if (IS_PACKAGE) { plpgsql_build_package_array_type($2->name, newp->typoid, TYPCATEGORY_ARRAY); + } else if (enable_plpgsql_gsdependency()) { + PLpgSQL_rec_type* rec_var = (PLpgSQL_rec_type*)u_sess->plsql_cxt.curr_compile_context->plpgsql_Datums[$9]; + int i; + for (i = 0; i < rec_var->attrnum; i++) { + gsplsql_build_gs_type_in_body_dependency(rec_var->types[i]); + } } pfree_ext($2->name); pfree($2); @@ -1601,6 +1609,8 @@ 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, $6->dependExtend); + } else if (enable_plpgsql_gsdependency()) { + gsplsql_build_gs_type_in_body_dependency($6); } pfree_ext($2->name); pfree($2); @@ -1663,6 +1673,12 @@ decl_statement : decl_varname_list decl_const decl_datatype decl_collate decl_no plpgsql_build_tableType($2->name, $2->lineno, newp, true); if (IS_PACKAGE) { plpgsql_build_package_array_type($2->name, newp->typoid, TYPCATEGORY_TABLEOF); + } else if (enable_plpgsql_gsdependency()) { + PLpgSQL_rec_type* rec_var = (PLpgSQL_rec_type*)u_sess->plsql_cxt.curr_compile_context->plpgsql_Datums[$6]; + int i; + for (i = 0; i < rec_var->attrnum; i++) { + gsplsql_build_gs_type_in_body_dependency(rec_var->types[i]); + } } pfree_ext($2->name); pfree($2); @@ -1775,6 +1791,8 @@ decl_statement : decl_varname_list decl_const decl_datatype decl_collate decl_no } else { plpgsql_build_package_array_type($2->name, $6->typoid, TYPCATEGORY_TABLEOF_INTEGER, $6->dependExtend); } + } else if (enable_plpgsql_gsdependency()) { + gsplsql_build_gs_type_in_body_dependency($6); } pfree_ext($2->name); pfree($2); @@ -1858,6 +1876,12 @@ decl_statement : decl_varname_list decl_const decl_datatype decl_collate decl_no } else { plpgsql_build_package_array_type($2->name, newp->typoid, TYPCATEGORY_TABLEOF_INTEGER); } + } else if (enable_plpgsql_gsdependency()) { + int i; + PLpgSQL_rec_type* rec_var = (PLpgSQL_rec_type*)u_sess->plsql_cxt.curr_compile_context->plpgsql_Datums[$6]; + for (i = 0; i < rec_var->attrnum; i++) { + gsplsql_build_gs_type_in_body_dependency(rec_var->types[i]); + } } pfree_ext($2->name); pfree($2); @@ -12704,24 +12728,12 @@ static void plpgsql_build_package_array_type(const char* typname,Oid elemtypoid 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)) { + if(IsPackageDependType(oldtypeoid, pkgOid)) { + if (CompileWhich() == PLPGSQL_COMPILE_PACKAGE) { + (void)gsplsql_flush_undef_ref_type_dependency(oldtypeoid); + } return; } else { ereport(errstate, @@ -12791,6 +12803,9 @@ static void plpgsql_build_package_array_type(const char* typname,Oid elemtypoid myself.objectSubId = 0; recordDependencyOn(&referenced, &myself, DEPENDENCY_AUTO); CommandCounterIncrement(); + if (CompileWhich() == PLPGSQL_COMPILE_PACKAGE && typtyp != TYPTYPE_TABLEOF) { + (void)gsplsql_build_ref_type_dependency(referenced.objectId); + } pfree_ext(casttypename); } diff --git a/src/common/pl/plpgsql/src/pl_comp.cpp b/src/common/pl/plpgsql/src/pl_comp.cpp index eb72dc22e..69ed5ffe4 100644 --- a/src/common/pl/plpgsql/src/pl_comp.cpp +++ b/src/common/pl/plpgsql/src/pl_comp.cpp @@ -1276,7 +1276,7 @@ static PLpgSQL_function* do_compile(FunctionCallInfo fcinfo, HeapTuple proc_tup, FlushErrorState(); } PG_END_TRY(); - }else { + } else { bool save_isPerform = u_sess->parser_cxt.isPerform; u_sess->parser_cxt.isPerform = false; parse_rc = plpgsql_yyparse(); diff --git a/src/common/pl/plpgsql/src/pl_handler.cpp b/src/common/pl/plpgsql/src/pl_handler.cpp index b11c61e1a..50f82f78c 100755 --- a/src/common/pl/plpgsql/src/pl_handler.cpp +++ b/src/common/pl/plpgsql/src/pl_handler.cpp @@ -725,6 +725,20 @@ Datum plpgsql_call_handler(PG_FUNCTION_ARGS) has_switch = true; } + bool save_need_create_depend = u_sess->plsql_cxt.need_create_depend; + u_sess->plsql_cxt.need_create_depend = false; + + _PG_init(); + /* + * Connect to SPI manager + */ + SPI_STACK_LOG("connect", NULL, NULL); + rc = SPI_connect_ext(DestSPI, NULL, NULL, nonatomic ? SPI_OPT_NONATOMIC : 0, func_oid); + if (rc != SPI_OK_CONNECT) { + ereport(ERROR, (errmodule(MOD_PLSQL), errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("SPI_connect failed: %s when execute PLSQL function.", SPI_result_code_string(rc)))); + } + Oid package_oid = get_package_id(func_oid); if (OidIsValid(package_oid)) { if (u_sess->plsql_cxt.curr_compile_context == NULL || @@ -742,19 +756,7 @@ Datum plpgsql_call_handler(PG_FUNCTION_ARGS) } } } - int fun_arg = fcinfo->nargs; - - _PG_init(); - /* - * Connect to SPI manager - */ - SPI_STACK_LOG("connect", NULL, NULL); - rc = SPI_connect_ext(DestSPI, NULL, NULL, nonatomic ? SPI_OPT_NONATOMIC : 0, func_oid); - if (rc != SPI_OK_CONNECT) { - ereport(ERROR, (errmodule(MOD_PLSQL), errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("SPI_connect failed: %s when execute PLSQL function.", SPI_result_code_string(rc)))); - } #ifdef ENABLE_MULTIPLE_NODES bool outer_is_stream = false; bool outer_is_stream_support = false; @@ -773,7 +775,6 @@ 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(); { @@ -787,31 +788,15 @@ Datum plpgsql_call_handler(PG_FUNCTION_ARGS) 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); + if (enable_plpgsql_gsdependency_guc() && func != NULL) { + SetPgObjectValid(func_oid, OBJECT_TYPE_PROC, GetCurrCompilePgObjStatus()); + if (!GetCurrCompilePgObjStatus()) { + ereport(WARNING, (errmodule(MOD_PLSQL), + errmsg("Function %s recompile with compilation errors, please use ALTER COMPILE to recompile.", + get_func_name(func_oid)))); } } - 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); @@ -1026,11 +1011,11 @@ 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); } PG_END_TRY(); + u_sess->plsql_cxt.need_create_depend = save_need_create_depend; /* clean stp save pointer if the outermost function is end. */ if (u_sess->SPI_cxt._connected == 0) { t_thrd.utils_cxt.STPSavedResourceOwner = NULL; diff --git a/src/gausskernel/optimizer/commands/functioncmds.cpp b/src/gausskernel/optimizer/commands/functioncmds.cpp index 1068ee163..2976f911c 100644 --- a/src/gausskernel/optimizer/commands/functioncmds.cpp +++ b/src/gausskernel/optimizer/commands/functioncmds.cpp @@ -2390,7 +2390,7 @@ static void RecompileFunctionWithArgs(CompileStmt* stmt) if (PROC_IS_PRO(get_func_prokind(func_oid)) && stmt->compileItem == COMPILE_FUNCTION) { ReportRecompileFuncWarning(stmt); } - if (!IsNeedRecompile(func_oid)) { + if (IsNeedRecompile(func_oid)) { RecompileSingleFunction(func_oid, stmt->compileItem == COMPILE_PROCEDURE); return; } diff --git a/src/gausskernel/optimizer/commands/packagecmds.cpp b/src/gausskernel/optimizer/commands/packagecmds.cpp index 7835ddbe7..9e5d16faa 100644 --- a/src/gausskernel/optimizer/commands/packagecmds.cpp +++ b/src/gausskernel/optimizer/commands/packagecmds.cpp @@ -273,6 +273,7 @@ static void RecompileSinglePackage(Oid package_oid, bool is_spec) 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; + u_sess->plsql_cxt.during_compile = false; clearCompileContextList(save_compile_list_length); u_sess->plsql_cxt.running_pkg_oid = InvalidOid; clear_plsql_ctx_line_info(); diff --git a/src/include/catalog/gs_dependencies_fn.h b/src/include/catalog/gs_dependencies_fn.h index a765b7f37..4d1fe09c5 100644 --- a/src/include/catalog/gs_dependencies_fn.h +++ b/src/include/catalog/gs_dependencies_fn.h @@ -143,5 +143,4 @@ extern void gsplsql_delete_unrefer_depend_obj_oid(Oid ref_obj_oid, bool skip_in_ 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/test/regress/expected/plpgsql_depend/plpgsql_depend_type.out b/src/test/regress/expected/plpgsql_depend/plpgsql_depend_type.out index da5d26149..480d58b51 100644 --- a/src/test/regress/expected/plpgsql_depend/plpgsql_depend_type.out +++ b/src/test/regress/expected/plpgsql_depend/plpgsql_depend_type.out @@ -2651,7 +2651,7 @@ select a.schemaname as sn, a.packagename as pn, a.objectname as on, a.refobjpos 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) | 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) diff --git a/src/test/regress/expected/plpgsql_depend/plpgsql_recompile.out b/src/test/regress/expected/plpgsql_depend/plpgsql_recompile.out index 96747c1f7..ebcbd7ccf 100644 --- a/src/test/regress/expected/plpgsql_depend/plpgsql_recompile.out +++ b/src/test/regress/expected/plpgsql_depend/plpgsql_recompile.out @@ -268,13 +268,133 @@ 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'; +-- test 3 +create procedure test_subtype_proc is +xx s_type; +begin +xx := (1,'aaa','bbb'); +raise notice '%',xx; +end; +/ +call test_subtype_proc(); +NOTICE: (1,aaa,bbb) + test_subtype_proc +------------------- + +(1 row) + +alter type s_type ADD attribute a int; +--修改后,预期调用成功 +call test_subtype_proc(); +NOTICE: (1,aaa,bbb,) + test_subtype_proc +------------------- + +(1 row) + +--手动触发编译, 调用成功 +alter procedure test_subtype_proc compile; +call test_subtype_proc(); +NOTICE: (1,aaa,bbb,) + test_subtype_proc +------------------- + +(1 row) + +-- test 4 +create or replace package pkg +is +procedure proc1(); +end pkg; +/ +create or replace package body pkg +is +xxx s_type; +procedure proc1() as +yyy s_type; +begin +xxx:= (1,'aaa','aaaaa'); +yyy:= (2,'bbb','bbbbb'); +RAISE INFO 'call xxx: %, yyy: %', xxx, yyy; +end; +end pkg; +/ +call pkg.proc1(); +INFO: call xxx: (1,aaa,aaaaa,), yyy: (2,bbb,bbbbb,) + proc1 +------- + +(1 row) + +alter type s_type ADD attribute b int; +--修改后,预期调用成功 +call pkg.proc1(); +INFO: call xxx: (1,aaa,aaaaa,,), yyy: (2,bbb,bbbbb,,) + proc1 +------- + +(1 row) + +--手动触发编译, 调用成功 +alter package pkg compile; +call pkg.proc1(); +INFO: call xxx: (1,aaa,aaaaa,,), yyy: (2,bbb,bbbbb,,) + proc1 +------- + +(1 row) + +-- test 5 +create or replace package pkg +is +procedure proc1(p_in s_type); +end pkg; +/ +create or replace package body pkg +is +xxx s_type; +procedure proc1(p_in s_type) as +yyy s_type; +begin +xxx:= (1,'aaa','aaaaa'); +yyy:= (2,'bbb','bbbbb'); +RAISE INFO 'call xxx: %, yyy: %, p_in: %', xxx, yyy, p_in; +end; +end pkg; +/ +call pkg.proc1((1,'zhang','M',1,2)); +INFO: call xxx: (1,aaa,aaaaa,,), yyy: (2,bbb,bbbbb,,), p_in: (1,zhang,M,1,2) + proc1 +------- + +(1 row) + +alter type s_type ADD attribute c int; +--修改后,预期调用成功 +call pkg.proc1((1,'zhang','M',1,2,3)); +INFO: call xxx: (1,aaa,aaaaa,,,), yyy: (2,bbb,bbbbb,,,), p_in: (1,zhang,M,1,2,3) + proc1 +------- + +(1 row) + +--手动触发编译, 调用成功 +alter package pkg compile; +call pkg.proc1((1,'zhang','M',1,2,3)); +INFO: call xxx: (1,aaa,aaaaa,,,), yyy: (2,bbb,bbbbb,,,), p_in: (1,zhang,M,1,2,3) + proc1 +------- + +(1 row) + +-- clean drop schema plpgsql_recompile cascade; -NOTICE: drop cascades to 6 other objects +NOTICE: drop cascades to 7 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 test_subtype_proc() --?.* -drop cascades to function plpgsql_recompile.proc1(r1) +drop cascades to function plpgsql_recompile.proc1(s_type) reset behavior_compat_options; diff --git a/src/test/regress/sql/plpgsql_depend/plpgsql_recompile.sql b/src/test/regress/sql/plpgsql_depend/plpgsql_recompile.sql index b6ccd5415..2654f6564 100644 --- a/src/test/regress/sql/plpgsql_depend/plpgsql_recompile.sql +++ b/src/test/regress/sql/plpgsql_depend/plpgsql_recompile.sql @@ -132,6 +132,77 @@ end pkg; / alter package pkg compile; --- select oid,* from pg_type where typname='stu'; +-- test 3 +create procedure test_subtype_proc is +xx s_type; +begin +xx := (1,'aaa','bbb'); +raise notice '%',xx; +end; +/ + +call test_subtype_proc(); +alter type s_type ADD attribute a int; +--修改后,预期调用成功 +call test_subtype_proc(); +--手动触发编译, 调用成功 +alter procedure test_subtype_proc compile; +call test_subtype_proc(); + +-- test 4 +create or replace package pkg +is +procedure proc1(); +end pkg; +/ +create or replace package body pkg +is +xxx s_type; +procedure proc1() as +yyy s_type; +begin +xxx:= (1,'aaa','aaaaa'); +yyy:= (2,'bbb','bbbbb'); +RAISE INFO 'call xxx: %, yyy: %', xxx, yyy; +end; +end pkg; +/ + +call pkg.proc1(); +alter type s_type ADD attribute b int; +--修改后,预期调用成功 +call pkg.proc1(); +--手动触发编译, 调用成功 +alter package pkg compile; +call pkg.proc1(); + +-- test 5 +create or replace package pkg +is +procedure proc1(p_in s_type); +end pkg; +/ +create or replace package body pkg +is +xxx s_type; +procedure proc1(p_in s_type) as +yyy s_type; +begin +xxx:= (1,'aaa','aaaaa'); +yyy:= (2,'bbb','bbbbb'); +RAISE INFO 'call xxx: %, yyy: %, p_in: %', xxx, yyy, p_in; +end; +end pkg; +/ + +call pkg.proc1((1,'zhang','M',1,2)); +alter type s_type ADD attribute c int; +--修改后,预期调用成功 +call pkg.proc1((1,'zhang','M',1,2,3)); +--手动触发编译, 调用成功 +alter package pkg compile; +call pkg.proc1((1,'zhang','M',1,2,3)); + +-- clean drop schema plpgsql_recompile cascade; reset behavior_compat_options;