Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:23
erlang
0643-mnesia-Do-not-unconditionally-delete-index...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0643-mnesia-Do-not-unconditionally-delete-index-keys.patch of Package erlang
From 0835f0bf7a0f897eac6fc0e971ce54538feca175 Mon Sep 17 00:00:00 2001 From: Dan Gudmundsson <dgud@erlang.org> Date: Wed, 18 Aug 2021 13:32:08 +0200 Subject: [PATCH] mnesia: Do not unconditionally delete index keys delete_object(NonExistingRecord) deleted index keys even if the record didn't exist, in set tables, and nothing was deleted from the real table. Solve this by doing the same checks as was done for bag tables. Fixes GH-5040 --- lib/mnesia/src/mnesia_index.erl | 23 +++++-------- lib/mnesia/test/mnesia_trans_access_test.erl | 34 ++++++++++++++++++-- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/lib/mnesia/src/mnesia_index.erl b/lib/mnesia/src/mnesia_index.erl index 2ca6c55870..964c50aa52 100644 --- a/lib/mnesia/src/mnesia_index.erl +++ b/lib/mnesia/src/mnesia_index.erl @@ -139,22 +139,15 @@ del_object_index(#index{pos_list = PosL, setorbag = SorB}, Storage, Tab, K, Obj) del_object_index2(PosL, SorB, Storage, Tab, K, Obj). del_object_index2([], _, _Storage, _Tab, _K, _Obj) -> ok; -del_object_index2([{{Pos, Type}, Ixt} | Tail], SoB, Storage, Tab, K, Obj) -> +del_object_index2([{{Pos, Type}, Ixt} | Tail], SoB, Storage, Tab, Key, Obj) -> ValsF = index_vals_f(Storage, Tab, Pos), - case SoB of - bag -> - del_object_bag(Type, ValsF, Tab, K, Obj, Ixt); - _ -> %% If set remove the tuple in index table - del_ixes(Type, Ixt, ValsF, Obj, K) - end, - del_object_index2(Tail, SoB, Storage, Tab, K, Obj). - -del_object_bag(Type, ValsF, Tab, Key, Obj, Ixt) -> - IxKeys = ValsF(Obj), Found = [{X, ValsF(X)} || X <- mnesia_lib:db_get(Tab, Key)], - del_object_bag_(IxKeys, Found, Type, Tab, Key, Obj, Ixt). + IxKeys = ValsF(Obj), + del_object_index3(IxKeys, Found, Type, Tab, Key, Obj, Ixt), + del_object_index2(Tail, SoB, Storage, Tab, Key, Obj). + -del_object_bag_([IxK|IxKs], Found, Type, Tab, Key, Obj, Ixt) -> +del_object_index3([IxK|IxKs], Found, Type, Tab, Key, Obj, Ixt) -> case [X || {X, Ixes} <- Found, lists:member(IxK, Ixes)] of [Old] when Old =:= Obj -> case Type of @@ -166,8 +159,8 @@ del_object_bag_([IxK|IxKs], Found, Type, Tab, Key, Obj, Ixt) -> _ -> ok end, - del_object_bag_(IxKs, Found, Type, Tab, Key, Obj, Ixt); -del_object_bag_([], _, _, _, _, _, _) -> + del_object_index3(IxKs, Found, Type, Tab, Key, Obj, Ixt); +del_object_index3([], _, _, _, _, _, _) -> ok. clear_index(Index, Tab, K, Obj) -> diff --git a/lib/mnesia/test/mnesia_trans_access_test.erl b/lib/mnesia/test/mnesia_trans_access_test.erl index 723a85fd2c..dec396252b 100644 --- a/lib/mnesia/test/mnesia_trans_access_test.erl +++ b/lib/mnesia/test/mnesia_trans_access_test.erl @@ -31,7 +31,7 @@ basic_nested/1, mix_of_nested_activities/1, nested_trans_both_ok/1, nested_trans_child_dies/1, nested_trans_parent_dies/1, nested_trans_both_dies/1, - index_match_object/1, index_read/1,index_write/1, + index_match_object/1, index_read/1,index_write/1, index_delete_object/1, index_update_set/1, index_update_bag/1, add_table_index_ram/1, add_table_index_disc/1, add_table_index_disc_only/1, create_live_table_index_ram/1, @@ -77,7 +77,7 @@ groups() -> nested_trans_parent_dies, nested_trans_both_dies]}, {index_tabs, [], [index_match_object, index_read, {group, index_update}, - index_write]}, + index_write, index_delete_object]}, {index_update, [], [index_update_set, index_update_bag]}, {index_lifecycle, [], @@ -1078,6 +1078,36 @@ index_write(Config)when is_list(Config) -> ?verify_mnesia(Nodes, []). +index_delete_object(suite) -> []; +index_delete_object(doc) -> ["See issue: GH-5040"]; +index_delete_object(Config) when is_list(Config) -> + Nodes = ?acquire_nodes(1, Config), + {atomic, ok} = mnesia:create_table(ram_set,[{index, [ix]}, {attributes, [key, ix, val]}, + {ram_copies, Nodes}]), + {atomic, ok} = mnesia:create_table(do_set, [{index, [ix]}, {attributes, [key, ix, val]}, + {disc_only_copies, Nodes}]), + {atomic, ok} = mnesia:create_table(ram_bag,[{index, [ix]}, {attributes, [key, ix, val]}, + {ram_copies, Nodes}]), + {atomic, ok} = mnesia:create_table(do_bag, [{index, [ix]}, {attributes, [key, ix, val]}, + {disc_only_copies, Nodes}]), + Test = fun(Tab) -> + io:format("Testing: ~p~n",[Tab]), + Rec = {Tab, 2, 4, data}, + Rec2 = {Tab, 3, 5, data}, + ok = mnesia:dirty_write(Rec), + ok = mnesia:dirty_write(Rec2), + [Rec] = mnesia:dirty_index_read(Tab, 4, ix), + ?match(ok, mnesia:dirty_delete_object({Tab, 2, 4, does_not_exist})), + [Rec] = mnesia:dirty_read(Tab, 2), + [Rec] = mnesia:dirty_index_read(Tab, 4, ix), + ?match(ok, mnesia:dirty_delete_object(Rec)), + [] = mnesia:dirty_read(Tab, 2), + [] = mnesia:dirty_index_read(Tab, 4, ix), + [Rec2] = mnesia:dirty_read(Tab, 3), + [Rec2] = mnesia:dirty_index_read(Tab, 5, ix) + end, + [Test(Tab) || Tab <- [ram_set,do_set,ram_bag,do_bag]], + ?verify_mnesia(Nodes, []). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Add and drop indecies -- 2.31.1
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor