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

Commit6753a2c

Browse files
authored
Merge pull request#9 from CherkashinSergey/add_xact_support
Add xact support optimization
2 parentsf807d8f +bf7c420 commit6753a2c

File tree

3 files changed

+85
-32
lines changed

3 files changed

+85
-32
lines changed

‎README.md‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,15 @@ SELECT pgv_get('pack','var_int', NULL::int);
335335
ERROR: unrecognized variable"var_int"
336336
COMMIT;
337337
```
338+
Also you cannot undo removing variable by`ROLLBACK`:
339+
```sql
340+
SELECT pgv_set('pack','var_int',122, true);
341+
BEGIN;
342+
SELECT pgv_free();
343+
ROLLBACK;
344+
SELECT pgv_get('pack','var_int',NULL::int);
345+
ERROR: unrecognized package"pack"
346+
```
338347
If you created transactional variable once, you should use flag`is_transactional`
339348
every time when you want to change variable value by functions`pgv_set()`,
340349
`pgv_insert()` and deprecated setters (i.e.`pgv_set_int()`). If you try to

‎pg_variables.c‎

Lines changed: 72 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ static HashVariableEntry *createVariableInternal(HashPackageEntry *package,
7676
text*name,Oidtypid,
7777
boolis_transactional);
7878
staticvoidcreateSavepoint(HashPackageEntry*package,HashVariableEntry*variable);
79-
staticboolisVarChangedInTrans(HashVariableEntry*variable);
79+
staticboolisVarChangedInCurrentTrans(HashVariableEntry*variable);
80+
staticboolisVarChangedInUpperTrans(HashVariableEntry*variable);
8081
staticvoidaddToChangedVars(HashPackageEntry*package,HashVariableEntry*variable);
8182

8283
#defineCHECK_ARGS_FOR_NULL() \
@@ -100,12 +101,11 @@ static HashPackageEntry *LastPackage = NULL;
100101
staticHashVariableEntry*LastVariable=NULL;
101102

102103
/*
103-
*List of variables, changed intop leveltransaction. Used to limit
104+
*Stack oflists ofvariables, changed ineachtransaction level. Used to limit
104105
* number of proceeded variables on start of transaction.
105106
*/
106-
staticdlist_head*changedVars=NULL;
107-
staticMemoryContextchangedVarsContext=NULL;
108107
staticdlist_head*changedVarsStack=NULL;
108+
staticMemoryContextchangedVarsContext=NULL;
109109
#defineget_actual_changed_vars_list() \
110110
((dlist_head_element(ChangedVarsStackNode, node, changedVarsStack))-> \
111111
changedVarsList)
@@ -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 (!isVarChangedInTrans(variable)&&variable->is_transactional)
624+
if (!isVarChangedInCurrentTrans(variable)&&variable->is_transactional)
625625
{
626626
createSavepoint(package,variable);
627627
addToChangedVars(package,variable);
@@ -707,7 +707,7 @@ variable_update(PG_FUNCTION_ARGS)
707707
else
708708
variable=LastVariable;
709709

710-
if (variable->is_transactional&& !isVarChangedInTrans(variable))
710+
if (variable->is_transactional&& !isVarChangedInCurrentTrans(variable))
711711
{
712712
createSavepoint(package,variable);
713713
addToChangedVars(package,variable);
@@ -785,7 +785,7 @@ variable_delete(PG_FUNCTION_ARGS)
785785
else
786786
variable=LastVariable;
787787

788-
if (variable->is_transactional&& !isVarChangedInTrans(variable))
788+
if (variable->is_transactional&& !isVarChangedInCurrentTrans(variable))
789789
{
790790
createSavepoint(package,variable);
791791
addToChangedVars(package,variable);
@@ -1220,7 +1220,7 @@ remove_packages(PG_FUNCTION_ARGS)
12201220

12211221
packagesHash=NULL;
12221222
ModuleContext=NULL;
1223-
changedVars=NULL;
1223+
changedVarsStack=NULL;
12241224

12251225
PG_RETURN_VOID();
12261226
}
@@ -1663,7 +1663,7 @@ createVariableInternal(HashPackageEntry *package, text *name, Oid typid,
16631663
* For each transaction level there should be own savepoint.
16641664
* New value should be stored in a last state.
16651665
*/
1666-
if (variable->is_transactional&& !isVarChangedInTrans(variable))
1666+
if (variable->is_transactional&& !isVarChangedInCurrentTrans(variable))
16671667
{
16681668
createSavepoint(package,variable);
16691669
}
@@ -1769,6 +1769,11 @@ releaseSavepoint(HashVariableEntry *variable)
17691769
dlist_delete(nodeToDelete);
17701770
pfree(historyEntryToDelete);
17711771
}
1772+
/*
1773+
* If variable was changed in subtransaction, so it is considered it
1774+
* was changed in parent transaction.
1775+
*/
1776+
(get_actual_value(variable)->level)--;
17721777
}
17731778

17741779
/*
@@ -1792,22 +1797,32 @@ rollbackSavepoint(HashPackageEntry *package, HashVariableEntry *variable)
17921797
* Check if variable was changed in current transaction level
17931798
*/
17941799
staticbool
1795-
isVarChangedInTrans(HashVariableEntry*variable)
1800+
isVarChangedInCurrentTrans(HashVariableEntry*variable)
17961801
{
1797-
dlist_iteriter;
1798-
dlist_head*changedVars;
1802+
ValueHistoryEntry*var_state;
17991803

18001804
if (!changedVarsStack)
18011805
return false;
18021806

1803-
changedVars=get_actual_changed_vars_list();
1804-
dlist_foreach(iter,changedVars)
1805-
{
1806-
ChangedVarsNode*cvn;
1807+
var_state=get_actual_value(variable);
1808+
return (var_state->level==GetCurrentTransactionNestLevel());
1809+
}
18071810

1808-
cvn=dlist_container(ChangedVarsNode,node,iter.cur);
1809-
if (cvn->variable==variable)
1810-
return true;
1811+
/*
1812+
* Check if variable was changed in parent transaction level
1813+
*/
1814+
staticbool
1815+
isVarChangedInUpperTrans(HashVariableEntry*variable)
1816+
{
1817+
ValueHistoryEntry*var_state,
1818+
*var_prev_state;
1819+
1820+
var_state=get_actual_value(variable);
1821+
1822+
if(dlist_has_next(&variable->data,&var_state->node))
1823+
{
1824+
var_prev_state=get_history_entry(var_state->node.next);
1825+
return (var_prev_state->level== (GetCurrentTransactionNestLevel()-1));
18111826
}
18121827
return false;
18131828
}
@@ -1890,12 +1905,12 @@ popChangedVarsStack()
18901905
{
18911906
if (changedVarsStack)
18921907
{
1893-
ChangedVarsStackNode*cvse;
1908+
ChangedVarsStackNode*cvsn;
18941909

18951910
Assert(!dlist_is_empty(changedVarsStack));
1896-
cvse=dlist_container(ChangedVarsStackNode,node,
1911+
cvsn=dlist_container(ChangedVarsStackNode,node,
18971912
dlist_pop_head_node(changedVarsStack));
1898-
MemoryContextDelete(cvse->ctx);
1913+
MemoryContextDelete(cvsn->ctx);
18991914
if (dlist_is_empty(changedVarsStack))
19001915
{
19011916
MemoryContextDelete(changedVarsContext);
@@ -1905,6 +1920,20 @@ popChangedVarsStack()
19051920
}
19061921
}
19071922

1923+
/*
1924+
* Initialize an instance of ChangedVarsNode datatype
1925+
*/
1926+
staticinlineChangedVarsNode*
1927+
initChangedVarsNode(MemoryContextctx,HashPackageEntry*package,HashVariableEntry*variable)
1928+
{
1929+
ChangedVarsNode*cvn;
1930+
1931+
cvn=MemoryContextAllocZero(ctx,sizeof(ChangedVarsNode));
1932+
cvn->package=package;
1933+
cvn->variable=variable;
1934+
returncvn;
1935+
}
1936+
19081937
/*
19091938
* Add a variable to list of changed vars in current transaction level
19101939
*/
@@ -1925,20 +1954,19 @@ addToChangedVars(HashPackageEntry *package, HashVariableEntry *variable)
19251954

19261955
Assert(changedVarsStack&&changedVarsContext);
19271956

1928-
if (!isVarChangedInTrans(variable))
1957+
if (!isVarChangedInCurrentTrans(variable))
19291958
{
19301959
ChangedVarsNode*cvn;
19311960

19321961
cvsn=dlist_head_element(ChangedVarsStackNode,node,changedVarsStack);
1933-
cvn=MemoryContextAllocZero(cvsn->ctx,sizeof(ChangedVarsNode));
1934-
cvn->package=package;
1935-
cvn->variable=variable;
1962+
cvn=initChangedVarsNode(cvsn->ctx,package,variable);
19361963
dlist_push_head(cvsn->changedVarsList,&cvn->node);
1964+
get_actual_value(cvn->variable)->level=GetCurrentTransactionNestLevel();
19371965
}
19381966
}
19391967

19401968
/*
1941-
* If variable waschenged in some subtransaction, it is considered that it was
1969+
* If variable waschanged in some subtransaction, it is considered that it was
19421970
* changed in parent transaction. So it is important to add this variable to
19431971
* list of changes of parent transaction. But if var was already changed in
19441972
* upper level, it has savepoint there, so we need to release it.
@@ -1957,13 +1985,25 @@ levelUpOrRelease()
19571985
Assert(!dlist_is_empty(changedVarsStack));
19581986
dlist_foreach(iter,bottom_list->changedVarsList)
19591987
{
1960-
ChangedVarsNode*cvn;
1988+
ChangedVarsNode*cvn_old;
19611989

1962-
cvn=dlist_container(ChangedVarsNode,node,iter.cur);
1963-
if (isVarChangedInTrans(cvn->variable))
1964-
releaseSavepoint(cvn->variable);
1990+
cvn_old=dlist_container(ChangedVarsNode,node,iter.cur);
1991+
if (isVarChangedInUpperTrans(cvn_old->variable))
1992+
releaseSavepoint(cvn_old->variable);
19651993
else
1966-
addToChangedVars(cvn->package,cvn->variable);
1994+
{
1995+
ChangedVarsNode*cvn_new;
1996+
ChangedVarsStackNode*cvsn;
1997+
1998+
/*
1999+
* Impossible to push in upper list existing node because
2000+
* it was created in another context
2001+
*/
2002+
cvsn=dlist_head_element(ChangedVarsStackNode,node,changedVarsStack);
2003+
cvn_new=initChangedVarsNode(cvsn->ctx,cvn_old->package,cvn_old->variable);
2004+
dlist_push_head(cvsn->changedVarsList,&cvn_new->node);
2005+
(get_actual_value(cvn_new->variable)->level)--;
2006+
}
19672007
}
19682008
MemoryContextDelete(bottom_list->ctx);
19692009
}

‎pg_variables.h‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ typedef struct ValueHistoryEntry{
6868
ScalarVarscalar;
6969
RecordVarrecord;
7070
}value;
71+
/* Transaction nest level of current entry */
72+
intlevel;
7173
}ValueHistoryEntry;
7274

7375
typedefdlist_headValueHistory;
@@ -139,6 +141,8 @@ extern void insert_savepoint(HashVariableEntry *variable,
139141
(&((dlist_head_element(ValueHistoryEntry, node, &variable->data))->value.scalar))
140142
#defineget_actual_value_record(variable) \
141143
(&((dlist_head_element(ValueHistoryEntry, node, &variable->data))->value.record))
144+
#defineget_actual_value(variable) \
145+
(dlist_head_element(ValueHistoryEntry, node, &variable->data))
142146
#defineget_history_entry(node_ptr) \
143147
dlist_container(ValueHistoryEntry, node, node_ptr)
144148

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp