@@ -77,7 +77,8 @@ static void removeFromChangedVars(Package *package);
7777
7878/* Constructors */
7979static void makePackHTAB (Package * package , bool is_trans );
80-
80+ static inline ChangedObject *
81+ makeChangedObject (TransObject * object , MemoryContext ctx );
8182
8283#define CHECK_ARGS_FOR_NULL () \
8384do { \
@@ -1676,6 +1677,9 @@ rollbackSavepoint(TransObject *object, TransObjectType type)
16761677 /* Restore regular vars HTAB */
16771678 makePackHTAB ((Package * ) object , false);
16781679 }
1680+ else
1681+ /* Pass current state to parent level */
1682+ releaseSavepoint (object , TRANS_PACKAGE );
16791683 }
16801684 else
16811685 {
@@ -1695,39 +1699,57 @@ static void
16951699releaseSavepoint (TransObject * object , TransObjectType type )
16961700{
16971701 dlist_head * states ;
1698-
16991702 Assert (GetActualState (object )-> level == GetCurrentTransactionNestLevel ());
1700- states = & object -> states ;
17011703
1702- /* Object existed in parent transaction */
1703- if (dlist_has_next (states , dlist_head_node (states )))
1704+ /* Mark object as changed in parent transaction... */
1705+ if (!dlist_is_empty (changesStack ) /* ...if there is an upper level... */
1706+ /* ...and object is not yet in list of that level changes. */
1707+ && !isObjectChangedInUpperTrans (object ))
17041708 {
1705- TransState * stateToDelete ;
1706- dlist_node * nodeToDelete ;
1709+ ChangedObject * co_new ;
1710+ ChangesStackNode * csn ;
17071711
1708- /* Remove previous state */
1709- nodeToDelete = dlist_next_node (states , dlist_head_node (states ));
1710- stateToDelete = dlist_container (TransState , node , nodeToDelete );
1711- removeState (object , type , stateToDelete );
1712- }
1712+ /*
1713+ * Impossible to push in upper list existing node
1714+ * because it was created in another context
1715+ */
1716+ csn = dlist_head_element (ChangesStackNode , node , changesStack );
1717+ co_new = makeChangedObject (object , csn -> ctx );
1718+ dlist_push_head (type == TRANS_PACKAGE ? csn -> changedPacksList :
1719+ csn -> changedVarsList ,
1720+ & co_new -> node );
17131721
1714- /*
1715- * Object has no more previous states and can be completely removed if
1716- * necessary
1717- */
1718- if (!GetActualState (object )-> is_valid &&
1719- !dlist_has_next (states , dlist_head_node (states )))
1720- {
1721- removeObject (object , type );
17221722 }
1723- /* Change subxact level due to release */
17241723 else
17251724 {
1726- TransState * state ;
1725+ states = & object -> states ;
17271726
1728- state = GetActualState (object );
1729- state -> level -- ;
1727+ /* If object existed in parent transaction... */
1728+ if (dlist_has_next (states , dlist_head_node (states )))
1729+ {
1730+ TransState * stateToDelete ;
1731+ dlist_node * nodeToDelete ;
1732+
1733+ /* ...remove its previous state */
1734+ nodeToDelete = dlist_next_node (states , dlist_head_node (states ));
1735+ stateToDelete = dlist_container (TransState , node , nodeToDelete );
1736+ removeState (object , type , stateToDelete );
1737+ }
1738+
1739+ /*
1740+ * Object has no more previous states and can be completely removed if
1741+ * necessary
1742+ */
1743+ if (!GetActualState (object )-> is_valid &&
1744+ !dlist_has_next (states , dlist_head_node (states )))
1745+ {
1746+ removeObject (object , type );
1747+ return ;
1748+ }
17301749 }
1750+
1751+ /* Change subxact level due to release */
1752+ GetActualState (object )-> level -- ;
17311753}
17321754
17331755/*
@@ -1960,31 +1982,7 @@ processChanges(Action action)
19601982 GetActualState (variable )-> is_valid = false;
19611983 }
19621984
1963- /* Did this object change at parent level? */
1964- if (dlist_is_empty (changesStack ) ||
1965- isObjectChangedInUpperTrans (object ))
1966- {
1967- /* We just have to drop previous state */
1968- releaseSavepoint (object , i ? TRANS_VARIABLE : TRANS_PACKAGE );
1969- }
1970- else
1971- {
1972- /* Mark object as changed at parent level */
1973- ChangedObject * co_new ;
1974- ChangesStackNode * csn ;
1975-
1976- /*
1977- * Impossible to push in upper list existing node
1978- * because it was created in another context
1979- */
1980- csn = dlist_head_element (ChangesStackNode , node , changesStack );
1981- co_new = makeChangedObject (object , csn -> ctx );
1982- dlist_push_head (i ? csn -> changedVarsList :
1983- csn -> changedPacksList , & co_new -> node );
1984-
1985- /* Change subxact level due to release */
1986- GetActualState (object )-> level -- ;
1987- }
1985+ releaseSavepoint (object , i ? TRANS_VARIABLE : TRANS_PACKAGE );
19881986 break ;
19891987 }
19901988 }
0 commit comments