@@ -72,7 +72,6 @@ static bool isObjectChangedInUpperTrans(TransObject *object);
7272
7373static void addToChangesStack (TransObject * object ,TransObjectType type );
7474static void pushChangesStack (void );
75- static void removeFromChangesStack (TransObject * object ,TransObjectType type );
7675
7776/* Constructors */
7877static void makePackHTAB (Package * package ,bool is_trans );
@@ -1309,7 +1308,6 @@ makePackHTAB(Package *package, bool is_trans)
13091308HTAB * * htab ;
13101309MemoryContext * context ;
13111310
1312- // maybe we should use macro pack_hctx?
13131311htab = is_trans ?& package -> varHashTransact :& package -> varHashRegular ;
13141312context = is_trans ?& package -> hctxTransact :& package -> hctxRegular ;
13151313
@@ -1403,7 +1401,6 @@ createPackage(text *name, bool is_trans)
14031401{
14041402PackState * packState ;
14051403
1406- //memset(package, 0, sizeof(Package));
14071404package -> varHashRegular = NULL ;
14081405package -> varHashTransact = NULL ;
14091406package -> hctxRegular = NULL ;
@@ -1419,7 +1416,6 @@ createPackage(text *name, bool is_trans)
14191416if (!pack_htab (package ,is_trans ))
14201417makePackHTAB (package ,is_trans );
14211418/* Add to changes list */
1422- //addToChangesStack(&package->transObject, TRANS_PACKAGE);
14231419if (!isObjectChangedInCurrentTrans (& package -> transObject ))
14241420{
14251421createSavepoint (& package -> transObject ,TRANS_PACKAGE );
@@ -1671,12 +1667,6 @@ removeObject(TransObject *object, TransObjectType type)
16711667HTAB * hash ;
16721668Package * package = NULL ;
16731669
1674- /*
1675- * Delete an object from the change history of the overlying
1676- * transaction level (head of 'changesStack' at this point).
1677- */
1678- if (changesStack && !dlist_is_empty (changesStack ))
1679- removeFromChangesStack (object ,type );
16801670if (type == TRANS_PACKAGE )
16811671{
16821672package = (Package * )object ;
@@ -1789,17 +1779,38 @@ rollbackSavepoint(TransObject *object, TransObjectType type)
17891779static void
17901780releaseSavepoint (TransObject * object ,TransObjectType type )
17911781{
1792- dlist_head * states ;
1782+ dlist_head * states = & object -> states ;
17931783Assert (GetActualState (object )-> level == GetCurrentTransactionNestLevel ());
17941784
1795- /* Mark object as changed in parent transaction... */
1796- if (!dlist_is_empty (changesStack )/* ...if there is an upper level... */
1797- /* ...and object is not yet in list of that level changes. */
1798- && !isObjectChangedInUpperTrans (object ))
1785+ /*
1786+ * If the object is not valid and does not exist at a higher level
1787+ * (or if we complete the transaction) - remove object.
1788+ */
1789+ if (!GetActualState (object )-> is_valid &&
1790+ (!dlist_has_next (states ,dlist_head_node (states ))||
1791+ dlist_is_empty (changesStack ))
1792+ )
1793+ {
1794+ removeObject (object ,type );
1795+ return ;
1796+ }
1797+
1798+ /* If object has been changed in upper level -
1799+ * replace state of that level with the current one. */
1800+ if (isObjectChangedInUpperTrans (object ))
1801+ {
1802+ TransState * stateToDelete ;
1803+ dlist_node * nodeToDelete ;
1804+ nodeToDelete = dlist_next_node (states ,dlist_head_node (states ));
1805+ stateToDelete = dlist_container (TransState ,node ,nodeToDelete );
1806+ removeState (object ,type ,stateToDelete );
1807+ }
1808+ /* If the object does not yet have a record in previous level changesStack,
1809+ * create it. */
1810+ else if (!dlist_is_empty (changesStack ))
17991811{
18001812ChangedObject * co_new ;
18011813ChangesStackNode * csn ;
1802-
18031814/*
18041815 * Impossible to push in upper list existing node
18051816 * because it was created in another context
@@ -1809,43 +1820,7 @@ releaseSavepoint(TransObject *object, TransObjectType type)
18091820dlist_push_head (type == TRANS_PACKAGE ?csn -> changedPacksList :
18101821csn -> changedVarsList ,
18111822& co_new -> node );
1812-
18131823}
1814- else
1815- {
1816- states = & object -> states ;
1817-
1818- /* If object existed in parent transaction... */
1819- if (dlist_has_next (states ,dlist_head_node (states )))
1820- {
1821- TransState * stateToDelete ;
1822- dlist_node * nodeToDelete ;
1823-
1824- /* ...remove its previous state */
1825- nodeToDelete = dlist_next_node (states ,dlist_head_node (states ));
1826- stateToDelete = dlist_container (TransState ,node ,nodeToDelete );
1827- removeState (object ,type ,stateToDelete );
1828- }
1829-
1830- /*
1831- * Object has no more previous states and can be completely removed if
1832- * necessary
1833- */
1834- if (!GetActualState (object )-> is_valid &&
1835- !dlist_has_next (states ,dlist_head_node (states )))
1836- {
1837- removeObject (object ,type );
1838- /* Remove package if it became empty */
1839- if (type == TRANS_VARIABLE )
1840- {
1841- Package * pack = ((Variable * )object )-> package ;
1842- if (isPackageEmpty (pack ))
1843- (GetActualState (& pack -> transObject ))-> is_valid = false;
1844- }
1845- return ;
1846- }
1847- }
1848-
18491824/* Change subxact level due to release */
18501825GetActualState (object )-> level -- ;
18511826}
@@ -1980,51 +1955,6 @@ addToChangesStack(TransObject *object, TransObjectType type)
19801955}
19811956}
19821957
1983- /*
1984- * Remove from the changes list a deleted package
1985- */
1986- static void
1987- removeFromChangesStack (TransObject * object ,TransObjectType type )
1988- {
1989- dlist_mutable_iter var_miter ,
1990- pack_miter ;
1991- dlist_head * changesList ;
1992- ChangesStackNode * csn = get_actual_changes_list ();
1993-
1994- /*
1995- * If we remove package, we should remove corresponding variables
1996- * from changedVarsList first.
1997- */
1998- if (type == TRANS_PACKAGE )
1999- {
2000- changesList = csn -> changedVarsList ;
2001- dlist_foreach_modify (var_miter ,changesList )
2002- {
2003- ChangedObject * co_cur = dlist_container (ChangedObject ,node ,
2004- var_miter .cur );
2005- Variable * var = (Variable * )co_cur -> object ;
2006-
2007- if (var -> package == (Package * )object )
2008- dlist_delete (& co_cur -> node );
2009- }
2010- }
2011- /* Now remove object itself from changes list */
2012- changesList = (type == TRANS_PACKAGE ?csn -> changedPacksList :
2013- csn -> changedVarsList );
2014- dlist_foreach_modify (pack_miter ,changesList )
2015- {
2016- ChangedObject * co_cur = dlist_container (ChangedObject ,node ,
2017- pack_miter .cur );
2018- TransObject * obj = co_cur -> object ;
2019-
2020- if (obj == object )
2021- {
2022- dlist_delete (& co_cur -> node );
2023- break ;
2024- }
2025- }
2026- }
2027-
20281958/*
20291959 * Possible actions on variables.
20301960 * Savepoints are created in setters so we don't need a CREATE_SAVEPOINT action.