@@ -77,7 +77,8 @@ static void removeFromChangedVars(Package *package);
77
77
78
78
/* Constructors */
79
79
static void makePackHTAB (Package * package ,bool is_trans );
80
-
80
+ static inline ChangedObject *
81
+ makeChangedObject (TransObject * object ,MemoryContext ctx );
81
82
82
83
#define CHECK_ARGS_FOR_NULL () \
83
84
do { \
@@ -1247,8 +1248,7 @@ static void
1247
1248
makePackHTAB (Package * package ,bool is_trans )
1248
1249
{
1249
1250
HASHCTL ctl ;
1250
- char key [NAMEDATALEN ],
1251
- hash_name [BUFSIZ ];
1251
+ char hash_name [BUFSIZ ];
1252
1252
1253
1253
if (is_trans )
1254
1254
package -> hctxTransact = AllocSetContextCreate (ModuleContext ,
@@ -1260,7 +1260,7 @@ makePackHTAB(Package *package, bool is_trans)
1260
1260
ALLOCSET_DEFAULT_SIZES );
1261
1261
1262
1262
snprintf (hash_name ,BUFSIZ ,"%s variables hash for package \"%s\"" ,
1263
- is_trans ?"Transactional" :"Regular" ,key );
1263
+ is_trans ?"Transactional" :"Regular" ,package -> transObject . name );
1264
1264
ctl .keysize = NAMEDATALEN ;
1265
1265
ctl .entrysize = sizeof (Variable );
1266
1266
ctl .hcxt = (is_trans ?package -> hctxTransact :package -> hctxRegular );
@@ -1677,6 +1677,9 @@ rollbackSavepoint(TransObject *object, TransObjectType type)
1677
1677
/* Restore regular vars HTAB */
1678
1678
makePackHTAB ((Package * )object , false);
1679
1679
}
1680
+ else
1681
+ /* Pass current state to parent level */
1682
+ releaseSavepoint (object ,TRANS_PACKAGE );
1680
1683
}
1681
1684
else
1682
1685
{
@@ -1696,39 +1699,57 @@ static void
1696
1699
releaseSavepoint (TransObject * object ,TransObjectType type )
1697
1700
{
1698
1701
dlist_head * states ;
1699
-
1700
1702
Assert (GetActualState (object )-> level == GetCurrentTransactionNestLevel ());
1701
- states = & object -> states ;
1702
1703
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 ))
1705
1708
{
1706
- TransState * stateToDelete ;
1707
- dlist_node * nodeToDelete ;
1709
+ ChangedObject * co_new ;
1710
+ ChangesStackNode * csn ;
1708
1711
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 );
1714
1721
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 );
1723
1722
}
1724
- /* Change subxact level due to release */
1725
1723
else
1726
1724
{
1727
- TransState * state ;
1725
+ states = & object -> states ;
1728
1726
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
+ }
1731
1749
}
1750
+
1751
+ /* Change subxact level due to release */
1752
+ GetActualState (object )-> level -- ;
1732
1753
}
1733
1754
1734
1755
/*
@@ -1961,31 +1982,7 @@ processChanges(Action action)
1961
1982
GetActualState (variable )-> is_valid = false;
1962
1983
}
1963
1984
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 );
1989
1986
break ;
1990
1987
}
1991
1988
}