@@ -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 */
16771678makePackHTAB ((Package * )object , false);
16781679}
1680+ else
1681+ /* Pass current state to parent level */
1682+ releaseSavepoint (object ,TRANS_PACKAGE );
16791683}
16801684else
16811685{
@@ -1695,39 +1699,57 @@ static void
16951699releaseSavepoint (TransObject * object ,TransObjectType type )
16961700{
16971701dlist_head * states ;
1698-
16991702Assert (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 */
17241723else
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)
19601982GetActualState (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 );
19881986break ;
19891987}
19901988}