From d6b86524fdcab147f10200091a9c0b0485d645af Mon Sep 17 00:00:00 2001 From: dragan Date: Thu, 8 Aug 2024 09:12:30 +0200 Subject: [PATCH 1/2] Fix wrong index preparation in mrdb:index_read_/3 In the case when index is of type {_}, index is returned as is instead of putting it into a tuple {Ix, ordered}. An example Given the following index plugin implementation: -module(key6). -record(cgh, {key, val}). -export([k6/3 , add_index/0 , create_table/0 , tst_bad_type/0 ]). k6(_, _, #cgh{key = {Name, K8, _Cid, _Vn}}) -> [list_to_binary([atom_to_binary(Name), list_to_binary(lists:sublist(K8, 6))])]. add_index() -> mnesia_schema:add_index_plugin({k6}, key6, k6). create_table() -> mnesia:create_table(cgh, [{attributes, record_info(fields, cgh)}, {type, ordered_set}, {index, [{k6}]}, {rocksdb_copies, [node()]}, {local_content, true}]). tst_bad_type() -> E1 = #cgh{key = {n1, "u1vgrjkh",{ecgi,238,6,213020,50},3}, val = ok}, mnesia:dirty_write(E1), Index1 = list_to_binary([atom_to_binary(n1), list_to_binary(lists:sublist("u1vgrjkh", 6))]), mrdb:index_read(cgh, Index1, {k6}). -- testing -- Eshell V14.2.2 (press Ctrl+G to abort, type help(). for help) (rock@bang)2> mnesia:create_schema([node()]). ok (rock@bang)3> mnesia:start(). ok (rock@bang)4> mnesia_rocksdb:register(). {ok,rocksdb_copies} (rock@bang)5> l(key6). {module,key6} (rock@bang)6> key6:add_index(). {atomic,ok} (rock@bang)7> key6:create_table(). {atomic,ok} (rock@bang)8> key6:tst_bad_type(). ** exception exit: {aborted,{bad_type,{cgh,index,{k6}}}} in function mnesia:abort/1 (mnesia.erl, line 362) in call from mrdb:ensure_ref/1 (~/projects/erlang/github/mnesia_rocksdb/src/mrdb.erl, line 609) in call from mrdb:index_read_/3 (~/projects/erlang/github/mnesia_rocksdb/src/mrdb.erl, line 945) -- after patch -- (rock@bang)9> c(mrdb). Recompiling ~/projects/erlang/github/mnesia_rocksdb/src/mrdb.erl {ok,mrdb} (rock@bang)10> key6:tst_bad_type(). [{cgh,{n1,"u1vgrjkh",{ecgi,238,6,213020,50},3},ok}] (rock@bang)11> --- src/mrdb.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mrdb.erl b/src/mrdb.erl index dd2e06c..fb9d431 100644 --- a/src/mrdb.erl +++ b/src/mrdb.erl @@ -938,7 +938,7 @@ index_read_(#{name := Main, semantics := Sem} = Ref, Val, Ix) -> _ when is_atom(Ix) -> {attr_pos(Ix, Ref), ordered}; {_} -> - Ix; + {Ix, ordered}; _ when is_integer(Ix) -> {Ix, ordered} end, From 996ae8271784a3c2898f83d78cabd71bbe5a1583 Mon Sep 17 00:00:00 2001 From: Ulf Wiger Date: Thu, 8 Aug 2024 16:06:20 +0200 Subject: [PATCH 2/2] Improve tests (fail without Havelka's fix) --- test/mnesia_rocksdb_indexes_SUITE.erl | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/test/mnesia_rocksdb_indexes_SUITE.erl b/test/mnesia_rocksdb_indexes_SUITE.erl index 00ca1a3..b2197a4 100644 --- a/test/mnesia_rocksdb_indexes_SUITE.erl +++ b/test/mnesia_rocksdb_indexes_SUITE.erl @@ -41,10 +41,12 @@ , fail_1_disc_only/1 , plugin_ram_copies1/1 , plugin_ram_copies2/1 + , plugin_ram_copies3/1 , plugin_disc_copies/1 , fail_plugin_disc_only/1 , plugin_disc_copies_bag/1 , plugin_rdb_ordered/1 + , plugin_rdb_none/1 , index_iterator/1 ]). @@ -74,10 +76,12 @@ run(Config) -> {pfx},mnesia_rocksdb, ix_prefixes), test_index_plugin(cfg([pr1, ram_copies, ordered], Config)), test_index_plugin(cfg([pr2, ram_copies, bag], Config)), + test_index_plugin(cfg([pr3, ram_copies, none], Config)), test_index_plugin(cfg([pd1, disc_copies, ordered], Config)), fail(test_index_plugin, [cfg([pd2, disc_only_copies, ordered], Config)]), test_index_plugin(cfg([pd2, disc_copies, bag], Config)), test_index_plugin(cfg([pl2, rdb, ordered], Config)), + test_index_plugin(cfg([pl3, rdb, none], Config)), index_plugin_mgmt(Config), ok. @@ -106,10 +110,12 @@ groups() -> , {plugin, [sequence], [ plugin_ram_copies1 , plugin_ram_copies2 + , plugin_ram_copies3 , plugin_disc_copies , fail_plugin_disc_only , plugin_disc_copies_bag , plugin_rdb_ordered + , plugin_rdb_none ]} ]. @@ -179,11 +185,14 @@ fail_1_disc_only( _Cfg) -> fail(test, [1, disc_only_copies, do1]). plugin_ram_copies1(Cfg) -> test_index_plugin(cfg([pr1, ram_copies, ordered], Cfg)). plugin_ram_copies2(Cfg) -> test_index_plugin(cfg([pr2, ram_copies, bag], Cfg)). +plugin_ram_copies3(Cfg) -> test_index_plugin(cfg([pr3, ram_copies, none], Cfg)). plugin_disc_copies(Cfg) -> test_index_plugin(cfg([pd1, disc_copies, ordered], Cfg)). fail_plugin_disc_only(Cfg) -> fail(test_index_plugin, [cfg([pd2, disc_only_copies, ordered], Cfg)]). plugin_disc_copies_bag(Cfg) -> test_index_plugin(cfg([pd2, disc_copies, bag], Cfg)). plugin_rdb_ordered(Cfg) -> test_index_plugin(cfg([pl2, rdb, ordered], Cfg)). +plugin_rdb_none(Cfg) -> test_index_plugin(cfg([pl3, rdb, none], Cfg)). + test(N, Type, T) -> {atomic, ok} = mnesia:create_table(T, [{Type,[node()]}, {attributes,[k,a,b,c]}, @@ -206,7 +215,7 @@ add_del_indexes() -> test_index_plugin(Config) -> #{tab := Tab, type := Type, ixtype := IxType} = cfg(Config), {atomic, ok} = mnesia:create_table(Tab, [{Type, [node()]}, - {index, [{{pfx}, IxType}]}]), + {index, [ixtype(IxType)]}]), mnesia:dirty_write({Tab, "foobar", "sentence"}), mnesia:dirty_write({Tab, "yellow", "sensor"}), mnesia:dirty_write({Tab, "truth", "white"}), @@ -218,13 +227,27 @@ test_index_plugin(Config) -> Res2 = lists:sort(mnesia:dirty_index_read(Tab,<<"whi">>, {pfx})), [{Tab,"foobar","sentence"}] = mnesia:dirty_index_read( Tab, <<"foo">>, {pfx}); - IxType == ordered -> + IxType == ordered; IxType == none -> Res1 = lists:sort(mnesia:dirty_index_read(Tab,<<"sen">>, {pfx})), Res2 = lists:sort(mnesia:dirty_index_read(Tab,<<"whi">>, {pfx})), [{Tab,"foobar","sentence"}] = mnesia:dirty_index_read( Tab, <<"foo">>, {pfx}) + end, + if Type == rdb -> + Res1 = lists:sort(mrdb:index_read(Tab,<<"sen">>, {pfx})), + Res2 = lists:sort(mrdb:index_read(Tab,<<"whi">>, {pfx})), + [{Tab,"foobar","sentence"}] = mrdb:index_read( + Tab, <<"foo">>, {pfx}); + true -> + ok end. +ixtype(T) when T==bag; + T==ordered -> + {{pfx}, T}; +ixtype(none) -> + {pfx}. + create_bag_index(_Config) -> {aborted, {combine_error, _, _}} = mnesia:create_table(bi, [{rdb, [node()]}, {index, [{val, bag}]}]),