Skip to content

Commit 89c120c

Browse files
committedJan 30, 2019
Merge branch 'master' into stable
2 parents 649bf07 + 4f3d9ec commit 89c120c

File tree

3 files changed

+73
-34
lines changed

3 files changed

+73
-34
lines changed
 

‎expected/pg_variables_trans.out

+21
Original file line numberDiff line numberDiff line change
@@ -1859,6 +1859,27 @@ SELECT pgv_insert('vars4', 'r1', row('str1', 'str1'));
18591859
ERROR: could not identify a hash function for type unknown
18601860
SELECT pgv_select('vars4', 'r1', 0);
18611861
ERROR: unrecognized variable "r1"
1862+
-- If variable created and removed in same transaction level,
1863+
-- it should be totally removed and should not be present
1864+
-- in changes list and cache.
1865+
BEGIN;
1866+
SELECT pgv_set('vars', 'any1', 'some value'::text, true);
1867+
pgv_set
1868+
---------
1869+
1870+
(1 row)
1871+
1872+
SAVEPOINT comm;
1873+
SELECT pgv_remove('vars', 'any1');
1874+
pgv_remove
1875+
------------
1876+
1877+
(1 row)
1878+
1879+
RELEASE comm;
1880+
SELECT pgv_get('vars', 'any1',NULL::text);
1881+
ERROR: unrecognized variable "any1"
1882+
COMMIT;
18621883
SELECT pgv_free();
18631884
pgv_free
18641885
----------

‎pg_variables.c

+41-34
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ static bool isObjectChangedInUpperTrans(TransObject *object);
7373

7474
static void addToChangesStack(TransObject *object, TransObjectType type);
7575
static void pushChangesStack(void);
76-
static void removeFromChangedVars(Package *package);
76+
static void removeFromChangesStack(TransObject *object, TransObjectType type);
7777

7878
/* Constructors */
7979
static void makePackHTAB(Package *package, bool is_trans);
@@ -1658,16 +1658,16 @@ removeObject(TransObject *object, TransObjectType type)
16581658
bool found;
16591659
HTAB *hash;
16601660

1661+
/*
1662+
* Delete an object from the change history of the overlying
1663+
* transaction level (head of 'changesStack' at this point).
1664+
*/
1665+
if (!dlist_is_empty(changesStack))
1666+
removeFromChangesStack(object, type);
16611667
if (type == TRANS_PACKAGE)
16621668
{
16631669
Package *package = (Package *) object;
16641670

1665-
/*
1666-
* Delete a variable from the change history of the overlying
1667-
* transaction level (head of 'changesStack' at this point)
1668-
*/
1669-
if (!dlist_is_empty(changesStack))
1670-
removeFromChangedVars(package);
16711671
/* Regular variables had already removed */
16721672
MemoryContextDelete(package->hctxTransact);
16731673
hash = packagesHash;
@@ -1691,24 +1691,24 @@ removeObject(TransObject *object, TransObjectType type)
16911691
* Create a new state of object
16921692
*/
16931693
static void
1694-
createSavepoint(TransObject *transObj, TransObjectType type)
1694+
createSavepoint(TransObject *object, TransObjectType type)
16951695
{
16961696
TransState *newState,
16971697
*prevState;
16981698

1699-
prevState = GetActualState(transObj);
1699+
prevState = GetActualState(object);
17001700
if (type == TRANS_PACKAGE)
17011701
newState = (TransState *) MemoryContextAllocZero(ModuleContext,
17021702
sizeof(PackState));
17031703
else
17041704
{
1705-
Variable *var = (Variable *) transObj;
1705+
Variable *var = (Variable *) object;
17061706

17071707
newState = (TransState *) MemoryContextAllocZero(var->package->hctxTransact,
17081708
sizeof(VarState));
17091709
copyValue((VarState *) prevState, (VarState *) newState, var);
17101710
}
1711-
dlist_push_head(&transObj->states, &newState->node);
1711+
dlist_push_head(&object->states, &newState->node);
17121712
newState->is_valid = prevState->is_valid;
17131713
}
17141714

@@ -1809,14 +1809,14 @@ releaseSavepoint(TransObject *object, TransObjectType type)
18091809
* Check if object was changed in current transaction level
18101810
*/
18111811
static bool
1812-
isObjectChangedInCurrentTrans(TransObject *transObj)
1812+
isObjectChangedInCurrentTrans(TransObject *object)
18131813
{
18141814
TransState *state;
18151815

18161816
if (!changesStack)
18171817
return false;
18181818

1819-
state = GetActualState(transObj);
1819+
state = GetActualState(object);
18201820
return state->level == GetCurrentTransactionNestLevel();
18211821
}
18221822

@@ -1916,56 +1916,63 @@ makeChangedObject(TransObject *object, MemoryContext ctx)
19161916
* in current transaction level
19171917
*/
19181918
static void
1919-
addToChangesStack(TransObject *transObj, TransObjectType type)
1919+
addToChangesStack(TransObject *object, TransObjectType type)
19201920
{
19211921
prepareChangesStack();
19221922

1923-
if (!isObjectChangedInCurrentTrans(transObj))
1923+
if (!isObjectChangedInCurrentTrans(object))
19241924
{
19251925
ChangesStackNode *csn;
19261926
ChangedObject *co;
19271927

19281928
csn = get_actual_changes_list();
1929-
co = makeChangedObject(transObj, csn->ctx);
1929+
co = makeChangedObject(object, csn->ctx);
19301930
dlist_push_head(type == TRANS_PACKAGE ? csn->changedPacksList :
19311931
csn->changedVarsList, &co->node);
19321932

19331933
/* Give this object current subxact level */
1934-
GetActualState(transObj)->level = GetCurrentTransactionNestLevel();
1934+
GetActualState(object)->level = GetCurrentTransactionNestLevel();
19351935
}
19361936
}
19371937

19381938
/*
19391939
* Remove from the changes list a deleted package
19401940
*/
19411941
static void
1942-
removeFromChangedVars(Package *package)
1942+
removeFromChangesStack(TransObject *object, TransObjectType type)
19431943
{
19441944
dlist_mutable_iter var_miter,
1945-
pack_miter;
1946-
dlist_head *changedVarsList,
1947-
*changedPacksList;
1945+
pack_miter;
1946+
dlist_head *changesList;
1947+
ChangesStackNode *csn = get_actual_changes_list();
19481948

1949-
/* First remove corresponding variables from changedVarsList */
1950-
changedVarsList = get_actual_changes_list()->changedVarsList;
1951-
dlist_foreach_modify(var_miter, changedVarsList)
1949+
/*
1950+
* If we remove package, we should remove corresponding variables
1951+
* from changedVarsList first.
1952+
*/
1953+
if (type == TRANS_PACKAGE)
19521954
{
1953-
ChangedObject *co_cur = dlist_container(ChangedObject, node,
1954-
var_miter.cur);
1955-
Variable *var = (Variable *) co_cur->object;
1955+
changesList = csn->changedVarsList;
1956+
dlist_foreach_modify(var_miter, changesList)
1957+
{
1958+
ChangedObject *co_cur = dlist_container(ChangedObject, node,
1959+
var_miter.cur);
1960+
Variable *var = (Variable *) co_cur->object;
19561961

1957-
if (var->package == package)
1958-
dlist_delete(&co_cur->node);
1962+
if (var->package == (Package *)object)
1963+
dlist_delete(&co_cur->node);
1964+
}
19591965
}
1960-
/* Now remove package itself from changedPacksList */
1961-
changedPacksList = get_actual_changes_list()->changedPacksList;
1962-
dlist_foreach_modify(pack_miter, changedPacksList)
1966+
/* Now remove object itself from changes list */
1967+
changesList = (type == TRANS_PACKAGE ? csn->changedPacksList :
1968+
csn->changedVarsList);
1969+
dlist_foreach_modify(pack_miter, changesList)
19631970
{
19641971
ChangedObject *co_cur = dlist_container(ChangedObject, node,
19651972
pack_miter.cur);
1966-
Package *pack = (Package *) co_cur->object;
1973+
TransObject *obj = co_cur->object;
19671974

1968-
if (pack == package)
1975+
if (obj == object)
19691976
{
19701977
dlist_delete(&co_cur->node);
19711978
break;

‎sql/pg_variables_trans.sql

+11
Original file line numberDiff line numberDiff line change
@@ -471,4 +471,15 @@ SELECT pgv_insert('package', 'errs',row(1), true);
471471
SELECT pgv_insert('vars4', 'r1', row('str1', 'str1'));
472472
SELECT pgv_select('vars4', 'r1', 0);
473473

474+
-- If variable created and removed in same transaction level,
475+
-- it should be totally removed and should not be present
476+
-- in changes list and cache.
477+
BEGIN;
478+
SELECT pgv_set('vars', 'any1', 'some value'::text, true);
479+
SAVEPOINT comm;
480+
SELECT pgv_remove('vars', 'any1');
481+
RELEASE comm;
482+
SELECT pgv_get('vars', 'any1',NULL::text);
483+
COMMIT;
484+
474485
SELECT pgv_free();

0 commit comments

Comments
 (0)
Please sign in to comment.