!4371 修复函数体存在类型依赖,调用函数时自动重编译失效的问题
Merge pull request !4371 from lukeman/master
This commit is contained in:
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
Reference in New Issue
Block a user