Skip to content

Commit b53645f

Browse files
CherkashinSergeyza-arthur
authored andcommitted
Optimize objects removal in subtransaction commit
1 parent 1a7be6a commit b53645f

File tree

2 files changed

+28
-98
lines changed

2 files changed

+28
-98
lines changed

expected/pg_variables_trans.out

+1-1
Original file line numberDiff line numberDiff line change
@@ -1879,7 +1879,7 @@ SELECT pgv_remove('vars', 'any1');
18791879

18801880
RELEASE comm;
18811881
SELECT pgv_get('vars', 'any1',NULL::text);
1882-
ERROR: unrecognized package "vars"
1882+
ERROR: unrecognized variable "any1"
18831883
COMMIT;
18841884
-- Test for PGPRO-2440
18851885
SELECT pgv_insert('vars3', 'r3', row(1 :: integer, NULL::varchar), true);

pg_variables.c

+27-97
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ static bool isObjectChangedInUpperTrans(TransObject *object);
7272

7373
static void addToChangesStack(TransObject *object, TransObjectType type);
7474
static void pushChangesStack(void);
75-
static void removeFromChangesStack(TransObject *object, TransObjectType type);
7675

7776
/* Constructors */
7877
static void makePackHTAB(Package *package, bool is_trans);
@@ -1309,7 +1308,6 @@ makePackHTAB(Package *package, bool is_trans)
13091308
HTAB **htab;
13101309
MemoryContext *context;
13111310

1312-
// maybe we should use macro pack_hctx?
13131311
htab = is_trans ? &package->varHashTransact : &package->varHashRegular;
13141312
context = is_trans ? &package->hctxTransact : &package->hctxRegular;
13151313

@@ -1403,7 +1401,6 @@ createPackage(text *name, bool is_trans)
14031401
{
14041402
PackState *packState;
14051403

1406-
//memset(package, 0, sizeof(Package));
14071404
package->varHashRegular = NULL;
14081405
package->varHashTransact = NULL;
14091406
package->hctxRegular = NULL;
@@ -1419,7 +1416,6 @@ createPackage(text *name, bool is_trans)
14191416
if (!pack_htab(package, is_trans))
14201417
makePackHTAB(package, is_trans);
14211418
/* Add to changes list */
1422-
//addToChangesStack(&package->transObject, TRANS_PACKAGE);
14231419
if (!isObjectChangedInCurrentTrans(&package->transObject))
14241420
{
14251421
createSavepoint(&package->transObject, TRANS_PACKAGE);
@@ -1671,12 +1667,6 @@ removeObject(TransObject *object, TransObjectType type)
16711667
HTAB *hash;
16721668
Package *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);
16801670
if (type == TRANS_PACKAGE)
16811671
{
16821672
package = (Package *) object;
@@ -1789,17 +1779,38 @@ rollbackSavepoint(TransObject *object, TransObjectType type)
17891779
static void
17901780
releaseSavepoint(TransObject *object, TransObjectType type)
17911781
{
1792-
dlist_head *states;
1782+
dlist_head *states = &object->states;
17931783
Assert(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
{
18001812
ChangedObject *co_new;
18011813
ChangesStackNode *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)
18091820
dlist_push_head(type == TRANS_PACKAGE ? csn->changedPacksList :
18101821
csn->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 */
18501825
GetActualState(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.

0 commit comments

Comments
 (0)