@@ -64,7 +64,7 @@ static void resetVariablesCache(void);
6464
6565/* Functions to work with transactional objects */
6666static void createSavepoint (TransObject * object , TransObjectType type );
67- static void releaseSavepoint (TransObject * object , TransObjectType type );
67+ static void releaseSavepoint (TransObject * object , TransObjectType type , bool sub );
6868static void rollbackSavepoint (TransObject * object , TransObjectType type );
6969
7070static void copyValue (VarState * src , VarState * dest , Variable * destVar );
@@ -2408,11 +2408,14 @@ rollbackSavepoint(TransObject *object, TransObjectType type)
24082408 * Remove previous state of object
24092409 */
24102410static void
2411- releaseSavepoint (TransObject * object , TransObjectType type )
2411+ releaseSavepoint (TransObject * object , TransObjectType type , bool sub )
24122412{
24132413 dlist_head * states = & object -> states ;
24142414
24152415 Assert (GetActualState (object )-> levels .level == GetCurrentTransactionNestLevel ());
2416+ #ifdef PGPRO_EE
2417+ Assert (GetActualState (object )-> levels .atxlevel == getNestLevelATX ());
2418+ #endif
24162419
24172420 /*
24182421 * If the object is not valid and does not exist at a higher level (or if
@@ -2438,6 +2441,15 @@ releaseSavepoint(TransObject *object, TransObjectType type)
24382441
24392442 nodeToDelete = dlist_next_node (states , dlist_head_node (states ));
24402443 stateToDelete = dlist_container (TransState , node , nodeToDelete );
2444+ #ifdef PGPRO_EE
2445+ /*
2446+ * We can not delete package state inside autonomous transaction
2447+ * because the state can be used in pgvRestoreContext().
2448+ * Exception: the state was created within this autonomous transaction.
2449+ */
2450+ Assert (type != TRANS_PACKAGE || getNestLevelATX () == 0 ||
2451+ stateToDelete -> levels .atxlevel == getNestLevelATX ());
2452+ #endif
24412453 removeState (object , type , stateToDelete );
24422454 }
24432455
@@ -2450,6 +2462,12 @@ releaseSavepoint(TransObject *object, TransObjectType type)
24502462
24512463 /* Change subxact level due to release */
24522464 GetActualState (object )-> levels .level -- ;
2465+
2466+ #ifdef PGPRO_EE
2467+ /* Change ATX level due to finish autonomous transaction */
2468+ if (!sub && getNestLevelATX () > 0 )
2469+ GetActualState (object )-> levels .atxlevel = 0 ;
2470+ #endif
24532471}
24542472
24552473static void
@@ -2647,7 +2665,7 @@ typedef enum Action
26472665 * Apply savepoint actions on list of variables or packages.
26482666 */
26492667static void
2650- applyAction (Action action , TransObjectType type , dlist_head * list )
2668+ applyAction (Action action , TransObjectType type , dlist_head * list , bool sub )
26512669{
26522670 dlist_iter iter ;
26532671
@@ -2677,7 +2695,7 @@ applyAction(Action action, TransObjectType type, dlist_head *list)
26772695 GetActualState (variable )-> is_valid = false;
26782696 }
26792697
2680- releaseSavepoint (object , type );
2698+ releaseSavepoint (object , type , sub );
26812699 break ;
26822700 }
26832701 }
@@ -2688,7 +2706,7 @@ applyAction(Action action, TransObjectType type, dlist_head *list)
26882706 * apply corresponding action on them
26892707 */
26902708static void
2691- processChanges (Action action )
2709+ processChanges (Action action , bool sub )
26922710{
26932711 ChangesStackNode * bottom_list ;
26942712
@@ -2697,8 +2715,8 @@ processChanges(Action action)
26972715 bottom_list = dlist_container (ChangesStackNode , node ,
26982716 dlist_pop_head_node (changesStack ));
26992717
2700- applyAction (action , TRANS_VARIABLE , bottom_list -> changedVarsList );
2701- applyAction (action , TRANS_PACKAGE , bottom_list -> changedPacksList );
2718+ applyAction (action , TRANS_VARIABLE , bottom_list -> changedVarsList , sub );
2719+ applyAction (action , TRANS_PACKAGE , bottom_list -> changedPacksList , sub );
27022720
27032721 /* Remove changes list of current level */
27042722 MemoryContextDelete (bottom_list -> ctx );
@@ -2866,10 +2884,10 @@ pgvRestoreContext()
28662884 /* Remove all package states, generated in ATX transaction */
28672885 while ((state = GetActualState (object )) != context -> state )
28682886 {
2887+ removeState (object , TRANS_PACKAGE , state );
28692888 if (dlist_is_empty (& object -> states ))
28702889 elog (ERROR , "pg_variables extension can not find "
28712890 "transaction state for package" );
2872- removeState (object , TRANS_PACKAGE , state );
28732891 }
28742892
28752893 /*
@@ -2935,10 +2953,10 @@ pgvSubTransCallback(SubXactEvent event, SubTransactionId mySubid,
29352953 compatibility_check ();
29362954 break ;
29372955 case SUBXACT_EVENT_COMMIT_SUB :
2938- processChanges (RELEASE_SAVEPOINT );
2956+ processChanges (RELEASE_SAVEPOINT , true );
29392957 break ;
29402958 case SUBXACT_EVENT_ABORT_SUB :
2941- processChanges (ROLLBACK_TO_SAVEPOINT );
2959+ processChanges (ROLLBACK_TO_SAVEPOINT , true );
29422960 break ;
29432961 case SUBXACT_EVENT_PRE_COMMIT_SUB :
29442962 break ;
@@ -2965,16 +2983,16 @@ pgvTransCallback(XactEvent event, void *arg)
29652983 {
29662984 case XACT_EVENT_PRE_COMMIT :
29672985 compatibility_check ();
2968- processChanges (RELEASE_SAVEPOINT );
2986+ processChanges (RELEASE_SAVEPOINT , false );
29692987 break ;
29702988 case XACT_EVENT_ABORT :
2971- processChanges (ROLLBACK_TO_SAVEPOINT );
2989+ processChanges (ROLLBACK_TO_SAVEPOINT , false );
29722990 break ;
29732991 case XACT_EVENT_PARALLEL_PRE_COMMIT :
2974- processChanges (RELEASE_SAVEPOINT );
2992+ processChanges (RELEASE_SAVEPOINT , false );
29752993 break ;
29762994 case XACT_EVENT_PARALLEL_ABORT :
2977- processChanges (ROLLBACK_TO_SAVEPOINT );
2995+ processChanges (ROLLBACK_TO_SAVEPOINT , false );
29782996 break ;
29792997 default :
29802998 break ;
0 commit comments