forked from huawei/openGauss-server
autonomous package value support anonymous block
Offering: openGaussDev More detail: autonomous package value support anonymous block Match-id-f3ca9de6f1d4d47382dad1566a600a1aa0e8d0ba
This commit is contained in:
parent
06c8f2afcf
commit
0319403518
|
@ -1105,8 +1105,29 @@ static List* BuildFuncInfoList(PLpgSQL_execstate* estate)
|
|||
void BuildSessionPackageRuntimeForAutoSession(uint64 sessionId, uint64 parentSessionId,
|
||||
PLpgSQL_execstate* estate, PLpgSQL_function* func)
|
||||
{
|
||||
SessionPackageRuntime* parentSessionPkgs = NULL;
|
||||
MemoryContext pkgRuntimeCtx = AllocSetContextCreate(CurrentMemoryContext,
|
||||
"SessionPackageRuntime",
|
||||
ALLOCSET_SMALL_MINSIZE,
|
||||
ALLOCSET_SMALL_INITSIZE,
|
||||
ALLOCSET_DEFAULT_MAXSIZE);
|
||||
MemoryContext oldCtx = MemoryContextSwitchTo(pkgRuntimeCtx);
|
||||
SessionPackageRuntime* resultSessionPkgs = (SessionPackageRuntime*)palloc0(sizeof(SessionPackageRuntime));
|
||||
resultSessionPkgs->context = pkgRuntimeCtx;
|
||||
|
||||
/* doing insert gs_source, no need to restore package value */
|
||||
if (func->is_insert_gs_source) {
|
||||
resultSessionPkgs->is_insert_gs_source = true;
|
||||
g_instance.global_session_pkg->Add(sessionId, resultSessionPkgs);
|
||||
MemoryContextSwitchTo(oldCtx);
|
||||
MemoryContextDelete(resultSessionPkgs->context);
|
||||
return;
|
||||
}
|
||||
|
||||
if (u_sess->plsql_cxt.plpgsqlpkg_dlist_objects != NULL) {
|
||||
CopyCurrentSessionPkgs(resultSessionPkgs, u_sess->plsql_cxt.plpgsqlpkg_dlist_objects);
|
||||
}
|
||||
|
||||
SessionPackageRuntime* parentSessionPkgs = NULL;
|
||||
/* get parent session pkgs, build current session pkgs need include them */
|
||||
if (parentSessionId != 0) {
|
||||
if (!u_sess->plsql_cxt.not_found_parent_session_pkgs) {
|
||||
|
@ -1120,17 +1141,6 @@ void BuildSessionPackageRuntimeForAutoSession(uint64 sessionId, uint64 parentSes
|
|||
}
|
||||
}
|
||||
}
|
||||
MemoryContext pkgRuntimeCtx = AllocSetContextCreate(CurrentMemoryContext,
|
||||
"SessionPackageRuntime",
|
||||
ALLOCSET_SMALL_MINSIZE,
|
||||
ALLOCSET_SMALL_INITSIZE,
|
||||
ALLOCSET_DEFAULT_MAXSIZE);
|
||||
MemoryContext oldCtx = MemoryContextSwitchTo(pkgRuntimeCtx);
|
||||
SessionPackageRuntime* resultSessionPkgs = (SessionPackageRuntime*)palloc0(sizeof(SessionPackageRuntime));
|
||||
resultSessionPkgs->context = pkgRuntimeCtx;
|
||||
if (u_sess->plsql_cxt.plpgsqlpkg_dlist_objects != NULL) {
|
||||
CopyCurrentSessionPkgs(resultSessionPkgs, u_sess->plsql_cxt.plpgsqlpkg_dlist_objects);
|
||||
}
|
||||
|
||||
if (parentSessionPkgs) {
|
||||
List* parentPkgList = parentSessionPkgs->runtimes;
|
||||
|
@ -1387,6 +1397,9 @@ void initAutoSessionPkgsValue(uint64 sessionId)
|
|||
if (sessionPkgs->runtimes == NULL) {
|
||||
return;
|
||||
}
|
||||
if (sessionPkgs->is_insert_gs_source) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach(cell, sessionPkgs->runtimes) {
|
||||
pkgState = (PackageRuntimeState*)lfirst(cell);
|
||||
|
@ -1510,11 +1523,7 @@ void initAutonomousPkgValue(PLpgSQL_package* targetPkg, uint64 sessionId)
|
|||
|
||||
List *processAutonmSessionPkgs(PLpgSQL_function* func, PLpgSQL_execstate* estate, bool isAutonm)
|
||||
{
|
||||
List *autonmsList = NULL;
|
||||
/* ignore inline_code_block function */
|
||||
if (!OidIsValid(func->fn_oid)) {
|
||||
return NULL;
|
||||
}
|
||||
List *autonmsList = NIL;
|
||||
|
||||
uint64 currentSessionId = IS_THREAD_POOL_WORKER ? u_sess->session_id : t_thrd.proc_cxt.MyProcPid;
|
||||
|
||||
|
@ -1525,6 +1534,13 @@ List *processAutonmSessionPkgs(PLpgSQL_function* func, PLpgSQL_execstate* estate
|
|||
* sessionpkgs from g_instance.global_session_pkg
|
||||
*/
|
||||
uint64 automnSessionId = u_sess->SPI_cxt.autonomous_session->current_attach_sessionid;
|
||||
if (func->is_insert_gs_source) {
|
||||
/* doing insert gs_source, need do noting */
|
||||
g_instance.global_session_pkg->Remove(automnSessionId);
|
||||
g_instance.global_session_pkg->Remove(currentSessionId);
|
||||
return NIL;
|
||||
}
|
||||
|
||||
SessionPackageRuntime* sessionpkgs = g_instance.global_session_pkg->Fetch(automnSessionId);
|
||||
RestoreAutonmSessionPkgs(sessionpkgs);
|
||||
if (sessionpkgs != NULL) {
|
||||
|
@ -1546,7 +1562,11 @@ List *processAutonmSessionPkgs(PLpgSQL_function* func, PLpgSQL_execstate* estate
|
|||
* and restore package values by it.
|
||||
*/
|
||||
if (u_sess->is_autonomous_session == true && u_sess->SPI_cxt._connected == 0) {
|
||||
BuildSessionPackageRuntimeForParentSession(currentSessionId, estate);
|
||||
/* doing insert gs_source, need do noting */
|
||||
if (u_sess->plsql_cxt.auto_parent_session_pkgs == NULL
|
||||
|| !u_sess->plsql_cxt.auto_parent_session_pkgs->is_insert_gs_source) {
|
||||
BuildSessionPackageRuntimeForParentSession(currentSessionId, estate);
|
||||
}
|
||||
/* autonomous session will be reused by next autonomous procedure, need clean it */
|
||||
if (u_sess->plsql_cxt.auto_parent_session_pkgs != NULL) {
|
||||
MemoryContextDelete(u_sess->plsql_cxt.auto_parent_session_pkgs->context);
|
||||
|
@ -1560,11 +1580,6 @@ List *processAutonmSessionPkgs(PLpgSQL_function* func, PLpgSQL_execstate* estate
|
|||
|
||||
void processAutonmSessionPkgsInException(PLpgSQL_function* func)
|
||||
{
|
||||
/* ignore inline_code_block function */
|
||||
if (!OidIsValid(func->fn_oid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint64 currentSessionId = IS_THREAD_POOL_WORKER ? u_sess->session_id : t_thrd.proc_cxt.MyProcPid;
|
||||
|
||||
if (IsAutonomousTransaction(func->action->isAutonomous)) {
|
||||
|
@ -1578,6 +1593,13 @@ void processAutonmSessionPkgsInException(PLpgSQL_function* func)
|
|||
return;
|
||||
}
|
||||
uint64 automnSessionId = u_sess->SPI_cxt.autonomous_session->current_attach_sessionid;
|
||||
if (func->is_insert_gs_source) {
|
||||
/* doing insert gs_source, need do noting */
|
||||
g_instance.global_session_pkg->Remove(automnSessionId);
|
||||
g_instance.global_session_pkg->Remove(currentSessionId);
|
||||
return;
|
||||
}
|
||||
|
||||
SessionPackageRuntime* sessionpkgs = g_instance.global_session_pkg->Fetch(automnSessionId);
|
||||
RestoreAutonmSessionPkgs(sessionpkgs);
|
||||
if (sessionpkgs != NULL) {
|
||||
|
@ -1596,7 +1618,11 @@ void processAutonmSessionPkgsInException(PLpgSQL_function* func)
|
|||
* and restore package values by it.
|
||||
*/
|
||||
if (u_sess->is_autonomous_session == true && u_sess->SPI_cxt._connected == 0) {
|
||||
BuildSessionPackageRuntimeForParentSession(currentSessionId, NULL);
|
||||
/* doing insert gs_source, need do noting */
|
||||
if (u_sess->plsql_cxt.auto_parent_session_pkgs == NULL
|
||||
|| !u_sess->plsql_cxt.auto_parent_session_pkgs->is_insert_gs_source) {
|
||||
BuildSessionPackageRuntimeForParentSession(currentSessionId, NULL);
|
||||
}
|
||||
/* autonomous session will be reused by next autonomous procedure, need clean it */
|
||||
if (u_sess->plsql_cxt.auto_parent_session_pkgs != NULL) {
|
||||
MemoryContextDelete(u_sess->plsql_cxt.auto_parent_session_pkgs->context);
|
||||
|
|
|
@ -752,6 +752,7 @@ static PLpgSQL_function* do_compile(FunctionCallInfo fcinfo, HeapTuple proc_tup,
|
|||
func->resolve_option = GetResolveOption();
|
||||
func->invalItems = NIL;
|
||||
func->is_autonomous = false;
|
||||
func->is_insert_gs_source = false;
|
||||
|
||||
func->pkg_oid = pkgoid;
|
||||
func->fn_searchpath->addCatalog = true;
|
||||
|
@ -1420,6 +1421,7 @@ PLpgSQL_function* plpgsql_compile_inline(char* proc_source)
|
|||
func->fn_retbyval = true;
|
||||
func->fn_rettyplen = sizeof(int32);
|
||||
func->is_autonomous = false;
|
||||
func->is_insert_gs_source = false;
|
||||
getTypeInputInfo(VOIDOID, &typinput, &func->fn_rettypioparam);
|
||||
fmgr_info(typinput, &(func->fn_retinput));
|
||||
|
||||
|
|
|
@ -838,9 +838,7 @@ Datum plpgsql_exec_autonm_function(PLpgSQL_function* func,
|
|||
#ifndef ENABLE_MULTIPLE_NODES
|
||||
uint64 sessionId = IS_THREAD_POOL_WORKER ? u_sess->session_id : t_thrd.proc_cxt.MyProcPid;
|
||||
/* add session package values to global for autonm session, to restore package values */
|
||||
if (OidIsValid(func->fn_oid)) {
|
||||
BuildSessionPackageRuntimeForAutoSession(sessionId, u_sess->autonomous_parent_sessionid, &estate, func);
|
||||
}
|
||||
BuildSessionPackageRuntimeForAutoSession(sessionId, u_sess->autonomous_parent_sessionid, &estate, func);
|
||||
#endif
|
||||
|
||||
/* Statement concatenation. If the block is an anonymous block, the entire anonymous block is returned. */
|
||||
|
@ -1011,8 +1009,7 @@ Datum plpgsql_exec_function(PLpgSQL_function* func, FunctionCallInfo fcinfo, boo
|
|||
|
||||
#ifndef ENABLE_MULTIPLE_NODES
|
||||
check_debug(func, &estate);
|
||||
bool isExecAutoFunc = OidIsValid(func->fn_oid) &&
|
||||
u_sess->is_autonomous_session == true && u_sess->SPI_cxt._connected == 0;
|
||||
bool isExecAutoFunc = u_sess->is_autonomous_session == true && u_sess->SPI_cxt._connected == 0;
|
||||
/* when exec autonomous transaction procedure, need update package values by parent session */
|
||||
if (isExecAutoFunc) {
|
||||
initAutoSessionPkgsValue(u_sess->autonomous_parent_sessionid);
|
||||
|
|
|
@ -186,6 +186,7 @@ static SessionPackageRuntime* CopySessionPackageRuntime(SessionPackageRuntime *r
|
|||
sessPkgRuntime->portalContext = CopyPortalContexts(runtime->portalContext);
|
||||
sessPkgRuntime->portalData = CopyPortalDatas(runtime);
|
||||
sessPkgRuntime->funcValInfo = CopyFuncInfoDatas(runtime);
|
||||
sessPkgRuntime->is_insert_gs_source = runtime->is_insert_gs_source;
|
||||
MemoryContextSwitchTo(oldCtx);
|
||||
return sessPkgRuntime;
|
||||
}
|
||||
|
|
|
@ -219,7 +219,9 @@ static void InsertGsSource(Oid objId, Oid nspid, const char* name, const char* t
|
|||
{
|
||||
(void)CompileStatusSwtichTo(NONE_STATUS);
|
||||
u_sess->plsql_cxt.curr_compile_context = NULL;
|
||||
u_sess->plsql_cxt.is_insert_gs_source = true;
|
||||
ExecuteDoStmt(stmt, true);
|
||||
u_sess->plsql_cxt.is_insert_gs_source = false;
|
||||
}
|
||||
PG_CATCH();
|
||||
{
|
||||
|
@ -228,6 +230,7 @@ static void InsertGsSource(Oid objId, Oid nspid, const char* name, const char* t
|
|||
}
|
||||
(void)CompileStatusSwtichTo(save_compile_status);
|
||||
u_sess->plsql_cxt.curr_compile_context = save_compile_context;
|
||||
u_sess->plsql_cxt.is_insert_gs_source = false;
|
||||
clearCompileContextList(save_compile_list_length);
|
||||
PG_RE_THROW();
|
||||
}
|
||||
|
@ -1075,6 +1078,7 @@ Datum plpgsql_inline_handler(PG_FUNCTION_ARGS)
|
|||
PG_END_TRY();
|
||||
PGSTAT_END_PLSQL_TIME_RECORD(PL_COMPILATION_TIME);
|
||||
|
||||
func->is_insert_gs_source = u_sess->plsql_cxt.is_insert_gs_source;
|
||||
/* Mark packages the function use, so them can't be deleted from under us */
|
||||
AddPackageUseCount(func);
|
||||
/* Mark the function as busy, just pro forma */
|
||||
|
@ -1093,7 +1097,6 @@ Datum plpgsql_inline_handler(PG_FUNCTION_ARGS)
|
|||
fake_fcinfo.flinfo = &flinfo;
|
||||
flinfo.fn_oid = InvalidOid;
|
||||
flinfo.fn_mcxt = CurrentMemoryContext;
|
||||
|
||||
PGSTAT_START_PLSQL_TIME_RECORD();
|
||||
/* save flag for nest plpgsql compile */
|
||||
save_compile_context = u_sess->plsql_cxt.curr_compile_context;
|
||||
|
|
|
@ -842,6 +842,7 @@ static void knl_u_plpgsql_init(knl_u_plpgsql_context* plsql_cxt)
|
|||
plsql_cxt->cur_exception_cxt = NULL;
|
||||
plsql_cxt->pragma_autonomous = false;
|
||||
plsql_cxt->ActiveLobToastOid = InvalidOid;
|
||||
plsql_cxt->is_insert_gs_source = false;
|
||||
}
|
||||
|
||||
static void knl_u_stat_init(knl_u_stat_context* stat_cxt)
|
||||
|
|
|
@ -1583,10 +1583,12 @@ typedef struct knl_u_plpgsql_context {
|
|||
uint64 parent_session_id;
|
||||
ThreadId parent_thread_id;
|
||||
MemoryContext parent_context; /* parent_context from parent session */
|
||||
|
||||
Oid ActiveLobToastOid;
|
||||
struct ExceptionContext* cur_exception_cxt;
|
||||
bool pragma_autonomous; /* save autonomous flag */
|
||||
char* debug_query_string;
|
||||
bool is_insert_gs_source; /* is doing insert gs_source? */
|
||||
} knl_u_plpgsql_context;
|
||||
|
||||
//this is used to define functions in package
|
||||
|
|
|
@ -42,6 +42,7 @@ typedef struct SessionPackageRuntime
|
|||
List* portalContext;
|
||||
List* portalData;
|
||||
List* funcValInfo;
|
||||
bool is_insert_gs_source;
|
||||
} SessionPackageRuntime;
|
||||
|
||||
typedef struct GPRCValue
|
||||
|
|
|
@ -1053,6 +1053,7 @@ typedef struct PLpgSQL_function { /* Complete compiled function */
|
|||
|
||||
bool is_autonomous;
|
||||
bool is_plpgsql_func_with_outparam;
|
||||
bool is_insert_gs_source;
|
||||
} PLpgSQL_function;
|
||||
|
||||
class AutonomousSession;
|
||||
|
|
|
@ -2007,3 +2007,82 @@ CONTEXT: referenced column: p1
|
|||
|
||||
drop package pck1;
|
||||
NOTICE: drop cascades to function public.p1(integer,integer)
|
||||
-- anoymous block with autonomous
|
||||
create or replace package pck1 as
|
||||
type r1 is record(a int, b int);
|
||||
va int;
|
||||
vb r1;
|
||||
vc varchar2(20);
|
||||
end pck1;
|
||||
/
|
||||
declare
|
||||
begin
|
||||
pck1.va := 1;
|
||||
pck1.vb := (2,3);
|
||||
pck1.vc := 'before auto';
|
||||
end;
|
||||
/
|
||||
-- (a) autonomous anoymous block
|
||||
declare
|
||||
PRAGMA AUTONOMOUS_TRANSACTION;
|
||||
begin
|
||||
raise info 'pck1.va: %',pck1.va;
|
||||
raise info 'pck1.vb: %',pck1.vb;
|
||||
raise info 'pck1.vc: %',pck1.vc;
|
||||
pck1.va := 11;
|
||||
pck1.vb := (22,33);
|
||||
pck1.vc := 'after auto';
|
||||
end;
|
||||
/
|
||||
INFO: pck1.va: 1
|
||||
|
||||
INFO: pck1.vb: (2,3)
|
||||
|
||||
INFO: pck1.vc: before auto
|
||||
|
||||
declare
|
||||
begin
|
||||
raise info 'pck1.va: %',pck1.va;
|
||||
raise info 'pck1.vb: %',pck1.vb;
|
||||
raise info 'pck1.vc: %',pck1.vc;
|
||||
pck1.va := 111;
|
||||
pck1.vb := (222,333);
|
||||
pck1.vc := 'before after auto';
|
||||
end;
|
||||
/
|
||||
INFO: pck1.va: 11
|
||||
INFO: pck1.vb: (22,33)
|
||||
INFO: pck1.vc: after auto
|
||||
-- (b) autonomous anoymous block with error
|
||||
declare
|
||||
PRAGMA AUTONOMOUS_TRANSACTION;
|
||||
begin
|
||||
raise info 'pck1.va: %',pck1.va;
|
||||
raise info 'pck1.vb: %',pck1.vb;
|
||||
raise info 'pck1.vc: %',pck1.vc;
|
||||
pck1.va := 1111;
|
||||
pck1.vb := (2222,3333);
|
||||
pck1.vc := 'after after auto';
|
||||
pck1.va := 3/0;
|
||||
end;
|
||||
/
|
||||
INFO: pck1.va: 111
|
||||
|
||||
INFO: pck1.vb: (222,333)
|
||||
|
||||
INFO: pck1.vc: before after auto
|
||||
|
||||
ERROR: ERROR: division by zero
|
||||
CONTEXT: SQL statement "SELECT 3/0"
|
||||
PL/pgSQL function inline_code_block line 10 at assignment
|
||||
|
||||
declare
|
||||
begin
|
||||
raise info 'pck1.va: %',pck1.va;
|
||||
raise info 'pck1.vb: %',pck1.vb;
|
||||
raise info 'pck1.vc: %',pck1.vc;
|
||||
end;
|
||||
/
|
||||
INFO: pck1.va: 1111
|
||||
INFO: pck1.vb: (2222,3333)
|
||||
INFO: pck1.vc: after after auto
|
||||
|
|
|
@ -1478,3 +1478,66 @@ call pck1.p1(10,20);
|
|||
call pck1.p1(10,20);
|
||||
|
||||
drop package pck1;
|
||||
|
||||
-- anoymous block with autonomous
|
||||
create or replace package pck1 as
|
||||
type r1 is record(a int, b int);
|
||||
va int;
|
||||
vb r1;
|
||||
vc varchar2(20);
|
||||
end pck1;
|
||||
/
|
||||
|
||||
declare
|
||||
begin
|
||||
pck1.va := 1;
|
||||
pck1.vb := (2,3);
|
||||
pck1.vc := 'before auto';
|
||||
end;
|
||||
/
|
||||
|
||||
-- (a) autonomous anoymous block
|
||||
declare
|
||||
PRAGMA AUTONOMOUS_TRANSACTION;
|
||||
begin
|
||||
raise info 'pck1.va: %',pck1.va;
|
||||
raise info 'pck1.vb: %',pck1.vb;
|
||||
raise info 'pck1.vc: %',pck1.vc;
|
||||
pck1.va := 11;
|
||||
pck1.vb := (22,33);
|
||||
pck1.vc := 'after auto';
|
||||
end;
|
||||
/
|
||||
|
||||
declare
|
||||
begin
|
||||
raise info 'pck1.va: %',pck1.va;
|
||||
raise info 'pck1.vb: %',pck1.vb;
|
||||
raise info 'pck1.vc: %',pck1.vc;
|
||||
pck1.va := 111;
|
||||
pck1.vb := (222,333);
|
||||
pck1.vc := 'before after auto';
|
||||
end;
|
||||
/
|
||||
|
||||
-- (b) autonomous anoymous block with error
|
||||
declare
|
||||
PRAGMA AUTONOMOUS_TRANSACTION;
|
||||
begin
|
||||
raise info 'pck1.va: %',pck1.va;
|
||||
raise info 'pck1.vb: %',pck1.vb;
|
||||
raise info 'pck1.vc: %',pck1.vc;
|
||||
pck1.va := 1111;
|
||||
pck1.vb := (2222,3333);
|
||||
pck1.vc := 'after after auto';
|
||||
pck1.va := 3/0;
|
||||
end;
|
||||
/
|
||||
|
||||
declare
|
||||
begin
|
||||
raise info 'pck1.va: %',pck1.va;
|
||||
raise info 'pck1.vb: %',pck1.vb;
|
||||
raise info 'pck1.vc: %',pck1.vc;
|
||||
end;
|
||||
/
|
Loading…
Reference in New Issue