@@ -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 { \
@@ -1247,8 +1248,7 @@ static void
12471248makePackHTAB (Package * package ,bool is_trans )
12481249{
12491250HASHCTL ctl ;
1250- char key [NAMEDATALEN ],
1251- hash_name [BUFSIZ ];
1251+ char hash_name [BUFSIZ ];
12521252
12531253if (is_trans )
12541254package -> hctxTransact = AllocSetContextCreate (ModuleContext ,
@@ -1260,7 +1260,7 @@ makePackHTAB(Package *package, bool is_trans)
12601260ALLOCSET_DEFAULT_SIZES );
12611261
12621262snprintf (hash_name ,BUFSIZ ,"%s variables hash for package \"%s\"" ,
1263- is_trans ?"Transactional" :"Regular" ,key );
1263+ is_trans ?"Transactional" :"Regular" ,package -> transObject . name );
12641264ctl .keysize = NAMEDATALEN ;
12651265ctl .entrysize = sizeof (Variable );
12661266ctl .hcxt = (is_trans ?package -> hctxTransact :package -> hctxRegular );
@@ -1677,6 +1677,9 @@ rollbackSavepoint(TransObject *object, TransObjectType type)
16771677/* Restore regular vars HTAB */
16781678makePackHTAB ((Package * )object , false);
16791679}
1680+ else
1681+ /* Pass current state to parent level */
1682+ releaseSavepoint (object ,TRANS_PACKAGE );
16801683}
16811684else
16821685{
@@ -1696,39 +1699,57 @@ static void
16961699releaseSavepoint (TransObject * object ,TransObjectType type )
16971700{
16981701dlist_head * states ;
1699-
17001702Assert (GetActualState (object )-> level == GetCurrentTransactionNestLevel ());
1701- states = & object -> states ;
17021703
1703- /* Object existed in parent transaction */
1704- 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 ))
17051708{
1706- TransState * stateToDelete ;
1707- dlist_node * nodeToDelete ;
1709+ ChangedObject * co_new ;
1710+ ChangesStackNode * csn ;
17081711
1709- /* Remove previous state */
1710- nodeToDelete = dlist_next_node (states ,dlist_head_node (states ));
1711- stateToDelete = dlist_container (TransState ,node ,nodeToDelete );
1712- removeState (object ,type ,stateToDelete );
1713- }
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 );
17141721
1715- /*
1716- * Object has no more previous states and can be completely removed if
1717- * necessary
1718- */
1719- if (!GetActualState (object )-> is_valid &&
1720- !dlist_has_next (states ,dlist_head_node (states )))
1721- {
1722- removeObject (object ,type );
17231722}
1724- /* Change subxact level due to release */
17251723else
17261724{
1727- TransState * state ;
1725+ states = & object -> states ;
17281726
1729- state = GetActualState (object );
1730- 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+ }
17311749}
1750+
1751+ /* Change subxact level due to release */
1752+ GetActualState (object )-> level -- ;
17321753}
17331754
17341755/*
@@ -1961,31 +1982,7 @@ processChanges(Action action)
19611982GetActualState (variable )-> is_valid = false;
19621983}
19631984
1964- /* Did this object change at parent level? */
1965- if (dlist_is_empty (changesStack )||
1966- isObjectChangedInUpperTrans (object ))
1967- {
1968- /* We just have to drop previous state */
1969- releaseSavepoint (object ,i ?TRANS_VARIABLE :TRANS_PACKAGE );
1970- }
1971- else
1972- {
1973- /* Mark object as changed at parent level */
1974- ChangedObject * co_new ;
1975- ChangesStackNode * csn ;
1976-
1977- /*
1978- * Impossible to push in upper list existing node
1979- * because it was created in another context
1980- */
1981- csn = dlist_head_element (ChangesStackNode ,node ,changesStack );
1982- co_new = makeChangedObject (object ,csn -> ctx );
1983- dlist_push_head (i ?csn -> changedVarsList :
1984- csn -> changedPacksList ,& co_new -> node );
1985-
1986- /* Change subxact level due to release */
1987- GetActualState (object )-> level -- ;
1988- }
1985+ releaseSavepoint (object ,i ?TRANS_VARIABLE :TRANS_PACKAGE );
19891986break ;
19901987}
19911988}