@@ -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{
12491250 HASHCTL ctl ;
1250- char key [NAMEDATALEN ],
1251- hash_name [BUFSIZ ];
1251+ char hash_name [BUFSIZ ];
12521252
12531253 if (is_trans )
12541254 package -> hctxTransact = AllocSetContextCreate (ModuleContext ,
@@ -1260,7 +1260,7 @@ makePackHTAB(Package *package, bool is_trans)
12601260 ALLOCSET_DEFAULT_SIZES );
12611261
12621262 snprintf (hash_name , BUFSIZ , "%s variables hash for package \"%s\"" ,
1263- is_trans ? "Transactional" : "Regular" , key );
1263+ is_trans ? "Transactional" : "Regular" , package -> transObject . name );
12641264 ctl .keysize = NAMEDATALEN ;
12651265 ctl .entrysize = sizeof (Variable );
12661266 ctl .hcxt = (is_trans ? package -> hctxTransact : package -> hctxRegular );
@@ -1677,6 +1677,9 @@ rollbackSavepoint(TransObject *object, TransObjectType type)
16771677 /* Restore regular vars HTAB */
16781678 makePackHTAB ((Package * ) object , false);
16791679 }
1680+ else
1681+ /* Pass current state to parent level */
1682+ releaseSavepoint (object , TRANS_PACKAGE );
16801683 }
16811684 else
16821685 {
@@ -1696,39 +1699,57 @@ static void
16961699releaseSavepoint (TransObject * object , TransObjectType type )
16971700{
16981701 dlist_head * states ;
1699-
17001702 Assert (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 */
17251723 else
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)
19611982 GetActualState (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 );
19891986 break ;
19901987 }
19911988 }
0 commit comments