Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit745ea14

Browse files
CherkashinSergeyza-arthur
authored andcommitted
Fix package removal in rollback
1 parent89ac2ee commit745ea14

File tree

3 files changed

+109
-18
lines changed

3 files changed

+109
-18
lines changed

‎expected/pg_variables_trans.out‎

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1962,6 +1962,49 @@ SELECT package FROM pgv_stats() ORDER BY package;
19621962
---------
19631963
(0 rows)
19641964

1965+
-- Package should exist after rollback if it contains regular variable
1966+
BEGIN;
1967+
SELECT pgv_set('vars', 'any1', 'some value'::text);
1968+
pgv_set
1969+
---------
1970+
1971+
(1 row)
1972+
1973+
ROLLBACK;
1974+
SELECT package FROM pgv_stats() ORDER BY package;
1975+
package
1976+
---------
1977+
vars
1978+
(1 row)
1979+
1980+
-- Package should not exist if it becomes empty in rolled back transaction
1981+
BEGIN;
1982+
SAVEPOINT comm2;
1983+
SELECT pgv_remove('vars');
1984+
pgv_remove
1985+
------------
1986+
1987+
(1 row)
1988+
1989+
ROLLBACK TO comm2;
1990+
SELECT pgv_exists('vars');
1991+
pgv_exists
1992+
------------
1993+
f
1994+
(1 row)
1995+
1996+
SELECT package FROM pgv_stats() ORDER BY package;
1997+
package
1998+
---------
1999+
vars
2000+
(1 row)
2001+
2002+
COMMIT;
2003+
SELECT package FROM pgv_stats() ORDER BY package;
2004+
package
2005+
---------
2006+
(0 rows)
2007+
19652008
SELECT pgv_free();
19662009
pgv_free
19672010
----------

‎pg_variables.c‎

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -961,13 +961,11 @@ removePackageInternal(Package *package)
961961
GetPackState(package)->trans_var_num=0;
962962
}
963963

964+
/* Check if package has any valid variables */
964965
staticbool
965966
isPackageEmpty(Package*package)
966967
{
967-
intvar_num=0;
968-
969-
if (package->varHashTransact)
970-
var_num+=hash_get_num_entries(package->varHashTransact);
968+
intvar_num=GetPackState(package)->trans_var_num;
971969

972970
if (package->varHashRegular)
973971
var_num+=hash_get_num_entries(package->varHashRegular);
@@ -1357,7 +1355,7 @@ initObjectHistory(TransObject *object, TransObjectType type)
13571355
VarState*varState= (VarState*)state;
13581356
ScalarVar*scalar=&(varState->value.scalar);
13591357

1360-
get_typlenbyval(variable->typid,&scalar->typlen,
1358+
get_typlenbyval(variable->typid,&scalar->typlen,
13611359
&scalar->typbyval);
13621360
varState->value.scalar.is_null= true;
13631361
}
@@ -1613,7 +1611,7 @@ createVariableInternal(Package *package, text *name, Oid typid, bool is_record,
16131611
(!found|| !GetActualState(variable)->is_valid))
16141612
GetPackState(package)->trans_var_num++;
16151613
GetActualState(variable)->is_valid= true;
1616-
1614+
16171615
/* If it is necessary, put variable to changedVars */
16181616
if (is_transactional)
16191617
addToChangesStack(transObject,TRANS_VARIABLE);
@@ -1779,16 +1777,49 @@ rollbackSavepoint(TransObject *object, TransObjectType type)
17791777
state=GetActualState(object);
17801778
removeState(object,type,state);
17811779

1782-
if (dlist_is_empty(&object->states))
1780+
if (type==TRANS_PACKAGE)
17831781
{
1784-
if (type==TRANS_PACKAGE&&numOfRegVars((Package*)object)>0)
1782+
/* If there is no more states... */
1783+
if (dlist_is_empty(&object->states))
1784+
{
1785+
/* ...but object is a package and has some regular variables... */
1786+
if (numOfRegVars((Package*)object)>0)
1787+
{
1788+
/* ...create a new state to make package valid. */
1789+
initObjectHistory(object,type);
1790+
GetActualState(object)->level=GetCurrentTransactionNestLevel()-1;
1791+
if (!dlist_is_empty(changesStack))
1792+
addToChangesStackUpperLevel(object,type);
1793+
}
1794+
else
1795+
/* ...or remove an object if it is no longer needed. */
1796+
removeObject(object,type);
1797+
}
1798+
/*
1799+
* But if a package has more states, but hasn't valid variables,
1800+
* mark it as not valid or remove at top level transaction.
1801+
*/
1802+
elseif (isPackageEmpty((Package*)object))
17851803
{
1786-
initObjectHistory(object,type);
1787-
GetActualState(object)->level=GetCurrentTransactionNestLevel()-1;
1788-
if (!dlist_is_empty(changesStack))
1804+
if (dlist_is_empty(changesStack))
1805+
{
1806+
removeObject(object,type);
1807+
return;
1808+
}
1809+
elseif (!isObjectChangedInUpperTrans(object)&&
1810+
!dlist_is_empty(changesStack))
1811+
{
1812+
createSavepoint(object,type);
17891813
addToChangesStackUpperLevel(object,type);
1814+
GetActualState(object)->level=GetCurrentTransactionNestLevel()-1;
1815+
}
1816+
GetActualState(object)->is_valid= false;
17901817
}
1791-
else
1818+
}
1819+
else
1820+
{
1821+
if (dlist_is_empty(&object->states))
1822+
/* Remove a variable if it is no longer needed. */
17921823
removeObject(object,type);
17931824
}
17941825
}
@@ -1840,9 +1871,9 @@ addToChangesStackUpperLevel(TransObject *object, TransObjectType type)
18401871
ChangedObject*co_new;
18411872
ChangesStackNode*csn;
18421873
/*
1843-
* Impossible to push in upper list existing node
1844-
* because it was created in another context
1845-
*/
1874+
* Impossible to push in upper list existing node
1875+
* because it was created in another context
1876+
*/
18461877
csn=dlist_head_element(ChangesStackNode,node,changesStack);
18471878
co_new=makeChangedObject(object,csn->ctx);
18481879
dlist_push_head(type==TRANS_PACKAGE ?csn->changedPacksList :
@@ -1875,13 +1906,14 @@ isObjectChangedInUpperTrans(TransObject *object)
18751906
*prev_state;
18761907

18771908
cur_state=GetActualState(object);
1878-
if (dlist_has_next(&object->states,&cur_state->node))
1909+
if (dlist_has_next(&object->states,&cur_state->node)&&
1910+
cur_state->level==GetCurrentTransactionNestLevel())
18791911
{
18801912
prev_state=dlist_container(TransState,node,cur_state->node.next);
18811913
returnprev_state->level==GetCurrentTransactionNestLevel()-1;
18821914
}
1883-
1884-
returnfalse;
1915+
else
1916+
returncur_state->level==GetCurrentTransactionNestLevel()-1;
18851917
}
18861918

18871919
/*

‎sql/pg_variables_trans.sql‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,4 +509,20 @@ ROLLBACK TO sp_to_rollback;
509509
COMMIT;
510510
SELECT packageFROM pgv_stats()ORDER BY package;
511511

512+
-- Package should exist after rollback if it contains regular variable
513+
BEGIN;
514+
SELECT pgv_set('vars','any1','some value'::text);
515+
ROLLBACK;
516+
SELECT packageFROM pgv_stats()ORDER BY package;
517+
518+
-- Package should not exist if it becomes empty in rolled back transaction
519+
BEGIN;
520+
SAVEPOINT comm2;
521+
SELECT pgv_remove('vars');
522+
ROLLBACK TO comm2;
523+
SELECT pgv_exists('vars');
524+
SELECT packageFROM pgv_stats()ORDER BY package;
525+
COMMIT;
526+
SELECT packageFROM pgv_stats()ORDER BY package;
527+
512528
SELECT pgv_free();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp