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

Commit22a4cc1

Browse files
The removal of a variable can be undone on rollback
1 parentbf7c420 commit22a4cc1

File tree

5 files changed

+126
-26
lines changed

5 files changed

+126
-26
lines changed

‎expected/pg_variables_trans.out

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1392,7 +1392,7 @@ SELECT pgv_free();
13921392

13931393
(1 row)
13941394

1395-
--Additional tests
1395+
--Additional tests
13961396
SELECT pgv_insert('vars3', 'r1', tab, true) FROM tab;
13971397
pgv_insert
13981398
------------
@@ -1598,3 +1598,58 @@ BEGIN;
15981598
SELECT pgv_set('vars', 'any1', 'wrong type'::varchar, true);
15991599
ERROR: variable "any1" requires "text" value
16001600
COMMIT;
1601+
-- THE REMOVAL OF THE VARIABLE MUST BE CANCELED ON ROLLBACK
1602+
SELECT pgv_set('vars', 'any1', 'variable exists'::text, true);
1603+
pgv_set
1604+
---------
1605+
1606+
(1 row)
1607+
1608+
BEGIN;
1609+
SELECT pgv_remove('vars', 'any1');
1610+
pgv_remove
1611+
------------
1612+
1613+
(1 row)
1614+
1615+
SELECT pgv_exists('vars', 'any1');
1616+
pgv_exists
1617+
------------
1618+
f
1619+
(1 row)
1620+
1621+
ROLLBACK;
1622+
SELECT pgv_exists('vars', 'any1');
1623+
pgv_exists
1624+
------------
1625+
t
1626+
(1 row)
1627+
1628+
SELECT pgv_get('vars', 'any1',NULL::text);
1629+
pgv_get
1630+
-----------------
1631+
variable exists
1632+
(1 row)
1633+
1634+
BEGIN;
1635+
SELECT pgv_remove('vars', 'any1');
1636+
pgv_remove
1637+
------------
1638+
1639+
(1 row)
1640+
1641+
SELECT pgv_exists('vars', 'any1');
1642+
pgv_exists
1643+
------------
1644+
f
1645+
(1 row)
1646+
1647+
COMMIT;
1648+
SELECT pgv_exists('vars', 'any1');
1649+
pgv_exists
1650+
------------
1651+
f
1652+
(1 row)
1653+
1654+
SELECT pgv_get('vars', 'any1',NULL::text);
1655+
ERROR: unrecognized variable "any1"

‎pg_variables.c

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,7 @@ variable_insert(PG_FUNCTION_ARGS)
621621
errmsg("variable \"%s\" already created as %sTRANSACTIONAL",
622622
key,LastVariable->is_transactional ?"" :"NOT ")));
623623
}
624-
if (!isVarChangedInCurrentTrans(variable)&&variable->is_transactional)
624+
if (variable->is_transactional&&!isVarChangedInCurrentTrans(variable))
625625
{
626626
createSavepoint(package,variable);
627627
addToChangedVars(package,variable);
@@ -1030,7 +1030,6 @@ variable_select_by_values(PG_FUNCTION_ARGS)
10301030
staticvoid
10311031
cleanVariableCurrentState(HashVariableEntry*variable)
10321032
{
1033-
ValueHistory*history;
10341033
ValueHistoryEntry*historyEntryToDelete;
10351034

10361035
if (variable->typid==RECORDOID)
@@ -1043,8 +1042,7 @@ cleanVariableCurrentState(HashVariableEntry *variable)
10431042
pfree(DatumGetPointer(scalar->value));
10441043
}
10451044

1046-
history=&variable->data;
1047-
historyEntryToDelete=get_history_entry(dlist_pop_head_node(history));
1045+
historyEntryToDelete=get_history_entry(dlist_pop_head_node(&variable->data));
10481046
pfree(historyEntryToDelete);
10491047
}
10501048

@@ -1069,7 +1067,8 @@ variable_exists(PG_FUNCTION_ARGS)
10691067
{
10701068
text*package_name;
10711069
text*var_name;
1072-
HashPackageEntry*package;
1070+
HashPackageEntry*package;
1071+
HashVariableEntry*variable;
10731072
charkey[NAMEDATALEN];
10741073
boolfound;
10751074

@@ -1089,12 +1088,13 @@ variable_exists(PG_FUNCTION_ARGS)
10891088

10901089
getKeyFromName(var_name,key);
10911090

1092-
hash_search(package->variablesHash,key,HASH_FIND,&found);
1091+
variable= (HashVariableEntry*)hash_search(package->variablesHash,
1092+
key,HASH_FIND,&found);
10931093

10941094
PG_FREE_IF_COPY(package_name,0);
10951095
PG_FREE_IF_COPY(var_name,1);
10961096

1097-
PG_RETURN_BOOL(found);
1097+
PG_RETURN_BOOL(found?get_actual_value(variable)->is_valid:found);
10981098
}
10991099

11001100
/*
@@ -1141,16 +1141,29 @@ remove_variable(PG_FUNCTION_ARGS)
11411141
getKeyFromName(var_name,key);
11421142

11431143
variable= (HashVariableEntry*)hash_search(package->variablesHash,
1144-
key,HASH_REMOVE,&found);
1144+
key,HASH_FIND,&found);
11451145
if (!found)
11461146
ereport(ERROR,
11471147
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1148-
errmsg("unrecognized variable \"%s\"",key)));
1149-
1150-
/* Remove variable from cache */
1151-
LastVariable=NULL;
1152-
1153-
cleanVariableAllStates(variable);
1148+
errmsg("unrecognized variable \"%s\"",key)));
1149+
else
1150+
{
1151+
if (variable->is_transactional)
1152+
{
1153+
createSavepoint(package,variable);
1154+
addToChangedVars(package,variable);
1155+
get_actual_value(variable)->is_valid= false;
1156+
}
1157+
else
1158+
{
1159+
/* Remove variable from package */
1160+
hash_search(package->variablesHash,key,HASH_REMOVE,&found);
1161+
/* Free allocated memory */
1162+
cleanVariableAllStates(variable);
1163+
}
1164+
/* Remove variable from cache */
1165+
LastVariable=NULL;
1166+
}
11541167

11551168
PG_FREE_IF_COPY(package_name,0);
11561169
PG_FREE_IF_COPY(var_name,1);
@@ -1606,6 +1619,10 @@ getVariableInternal(HTAB *variables, text *name, Oid typid, bool strict)
16061619
errmsg("variable \"%s\" requires \"%s\" value",
16071620
key,var_type)));
16081621
}
1622+
if (!get_actual_value(variable)->is_valid&&strict)
1623+
ereport(ERROR,
1624+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1625+
errmsg("unrecognized variable \"%s\"",key)));
16091626
}
16101627
else
16111628
{
@@ -1684,12 +1701,13 @@ createVariableInternal(HashPackageEntry *package, text *name, Oid typid,
16841701
dlist_push_head(&variable->data,&historyEntry->node);
16851702
if (typid!=RECORDOID)
16861703
{
1687-
ScalarVar*scalar=get_actual_value_scalar(variable);
1704+
ScalarVar*scalar=&(historyEntry->value.scalar);
16881705

16891706
get_typlenbyval(variable->typid,&scalar->typlen,
16901707
&scalar->typbyval);
1691-
scalar->is_null= true;
1708+
historyEntry->value.scalar.is_null= true;
16921709
}
1710+
historyEntry->is_valid= true;
16931711
}
16941712
}
16951713
/* If it is necessary, put variable to changedVars */
@@ -1734,7 +1752,7 @@ createSavepoint(HashPackageEntry *package, HashVariableEntry *variable)
17341752
}
17351753
else
17361754
scalar->value=0;
1737-
1755+
history_entry_new->is_valid=history_entry_prev->is_valid;
17381756
dlist_push_head(history,&history_entry_new->node);
17391757
MemoryContextSwitchTo(oldcxt);
17401758
}
@@ -1744,9 +1762,10 @@ createSavepoint(HashPackageEntry *package, HashVariableEntry *variable)
17441762
* Remove previous state of variable
17451763
*/
17461764
staticvoid
1747-
releaseSavepoint(HashVariableEntry*variable)
1765+
releaseSavepoint(HashPackageEntry*package,HashVariableEntry*variable)
17481766
{
1749-
ValueHistory*history;
1767+
ValueHistory*history;
1768+
ValueHistoryEntry*historyEntry;
17501769

17511770
history=&variable->data;
17521771
if (dlist_has_next(history,dlist_head_node(history)))
@@ -1773,7 +1792,15 @@ releaseSavepoint(HashVariableEntry *variable)
17731792
* If variable was changed in subtransaction, so it is considered it
17741793
* was changed in parent transaction.
17751794
*/
1776-
(get_actual_value(variable)->level)--;
1795+
historyEntry=get_actual_value(variable);
1796+
historyEntry->level--;
1797+
if (!historyEntry->is_valid&&
1798+
!dlist_has_next(history,dlist_head_node(history)))
1799+
{
1800+
boolfound;
1801+
1802+
hash_search(package->variablesHash,variable->name,HASH_REMOVE,&found);
1803+
}
17771804
}
17781805

17791806
/*
@@ -1805,7 +1832,7 @@ isVarChangedInCurrentTrans(HashVariableEntry *variable)
18051832
return false;
18061833

18071834
var_state=get_actual_value(variable);
1808-
return(var_state->level==GetCurrentTransactionNestLevel());
1835+
returnvar_state->level==GetCurrentTransactionNestLevel();
18091836
}
18101837

18111838
/*
@@ -1822,7 +1849,7 @@ isVarChangedInUpperTrans(HashVariableEntry *variable)
18221849
if(dlist_has_next(&variable->data,&var_state->node))
18231850
{
18241851
var_prev_state=get_history_entry(var_state->node.next);
1825-
return(var_prev_state->level== (GetCurrentTransactionNestLevel()-1));
1852+
returnvar_prev_state->level== (GetCurrentTransactionNestLevel()-1);
18261853
}
18271854
return false;
18281855
}
@@ -1989,7 +2016,7 @@ levelUpOrRelease()
19892016

19902017
cvn_old=dlist_container(ChangedVarsNode,node,iter.cur);
19912018
if (isVarChangedInUpperTrans(cvn_old->variable))
1992-
releaseSavepoint(cvn_old->variable);
2019+
releaseSavepoint(cvn_old->package,cvn_old->variable);
19932020
else
19942021
{
19952022
ChangedVarsNode*cvn_new;
@@ -2038,7 +2065,7 @@ applyActionOnChangedVars(Action action)
20382065
switch(action)
20392066
{
20402067
caseRELEASE_SAVEPOINT:
2041-
releaseSavepoint(cvn->variable);
2068+
releaseSavepoint(cvn->package,cvn->variable);
20422069
break;
20432070
caseROLLBACK_TO_SAVEPOINT:
20442071
rollbackSavepoint(cvn->package,cvn->variable);

‎pg_variables.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ typedef struct ValueHistoryEntry{
7070
}value;
7171
/* Transaction nest level of current entry */
7272
intlevel;
73+
boolis_valid;
7374
}ValueHistoryEntry;
7475

7576
typedefdlist_headValueHistory;

‎pg_variables_record.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ insert_savepoint(HashVariableEntry *variable, MemoryContext packageContext)
367367
record_prev=get_actual_value_record(variable);
368368
oldcxt=MemoryContextSwitchTo(packageContext);
369369
history_entry_new=palloc0(sizeof(ValueHistoryEntry));
370+
history_entry_new->is_valid= true;
370371
record_new=&(history_entry_new->value.record);
371372
dlist_push_head(&variable->data,&history_entry_new->node);
372373
init_attributes(variable,record_prev->tupdesc,packageContext);

‎sql/pg_variables_trans.sql

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ SELECT pgv_get('vars2', 'any1',NULL::text);
339339

340340
SELECT pgv_free();
341341

342-
--Additional tests
342+
--Additional tests
343343
SELECT pgv_insert('vars3','r1', tab, true)FROM tab;
344344
BEGIN;
345345
SELECT pgv_insert('vars3','r1', row(5 ::integer,'before savepoint sp1' ::varchar),true);
@@ -393,3 +393,19 @@ SELECT pgv_get('vars', 'any1',NULL::text);
393393
BEGIN;
394394
SELECT pgv_set('vars','any1','wrong type'::varchar, true);
395395
COMMIT;
396+
397+
-- THE REMOVAL OF THE VARIABLE MUST BE CANCELED ON ROLLBACK
398+
SELECT pgv_set('vars','any1','variable exists'::text, true);
399+
BEGIN;
400+
SELECT pgv_remove('vars','any1');
401+
SELECT pgv_exists('vars','any1');
402+
ROLLBACK;
403+
SELECT pgv_exists('vars','any1');
404+
SELECT pgv_get('vars','any1',NULL::text);
405+
406+
BEGIN;
407+
SELECT pgv_remove('vars','any1');
408+
SELECT pgv_exists('vars','any1');
409+
COMMIT;
410+
SELECT pgv_exists('vars','any1');
411+
SELECT pgv_get('vars','any1',NULL::text);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp