On select, mnesia_rocksdb would only calculate a key prefix for the
first select clause in a multi-clause select pattern. This could give erroneous results if the first pattern was more specific (on the key) than following patterns. This change calculates a prefix for all clauses and keeps the shortest common prefix.
This commit is contained in:
parent
ff823c4ee1
commit
0345e3558b
@ -1403,7 +1403,7 @@ do_select(Ref, Tab, _Type, MS, AccKeys, Limit) when is_boolean(AccKeys) ->
|
|||||||
limit = Limit},
|
limit = Limit},
|
||||||
with_iterator(Ref, fun(I) -> i_do_select(I, Sel, AccKeys, []) end).
|
with_iterator(Ref, fun(I) -> i_do_select(I, Sel, AccKeys, []) end).
|
||||||
|
|
||||||
i_do_select(I, #sel{keypat = {Pfx, _KP},
|
i_do_select(I, #sel{keypat = Pfx,
|
||||||
compiled_ms = MS,
|
compiled_ms = MS,
|
||||||
limit = Limit} = Sel, AccKeys, Acc) ->
|
limit = Limit} = Sel, AccKeys, Acc) ->
|
||||||
StartKey =
|
StartKey =
|
||||||
@ -1534,27 +1534,26 @@ iterator_next(I, K) ->
|
|||||||
Other
|
Other
|
||||||
end.
|
end.
|
||||||
|
|
||||||
keypat([{HeadPat,Gs,_}|_], KeyPos) when is_tuple(HeadPat) ->
|
keypat([H|T], KeyPos) ->
|
||||||
KP = element(KeyPos, HeadPat),
|
keypat(T, KeyPos, keypat_pfx(H, KeyPos)).
|
||||||
KeyVars = extract_vars(KP),
|
|
||||||
Guards = relevant_guards(Gs, KeyVars),
|
|
||||||
Pfx = sext:prefix(KP),
|
|
||||||
{Pfx, [{KP, Guards, [true]}]};
|
|
||||||
keypat(_, _) ->
|
|
||||||
{<<>>, [{'_',[],[true]}]}.
|
|
||||||
|
|
||||||
relevant_guards(Gs, Vars) ->
|
keypat(_, _, <<>>) -> <<>>;
|
||||||
case Vars -- ['_'] of
|
keypat([H|T], KeyPos, Pfx0) ->
|
||||||
[] ->
|
Pfx = keypat_pfx(H, KeyPos),
|
||||||
[];
|
keypat(T, KeyPos, common_prefix(Pfx, Pfx0));
|
||||||
Vars1 ->
|
keypat([], _, Pfx) ->
|
||||||
Fun =
|
Pfx.
|
||||||
fun(G) ->
|
|
||||||
Vg = extract_vars(G),
|
common_prefix(<<H, T/binary>>, <<H, T1/binary>>) ->
|
||||||
intersection(Vg, Vars1) =/= [] andalso (Vg--Vars1) == []
|
<<H, (common_prefix(T, T1))/binary>>;
|
||||||
end,
|
common_prefix(_, _) ->
|
||||||
lists:filter(Fun, Gs)
|
<<>>.
|
||||||
end.
|
|
||||||
|
keypat_pfx({HeadPat,_Gs,_}, KeyPos) when is_tuple(HeadPat) ->
|
||||||
|
KP = element(KeyPos, HeadPat),
|
||||||
|
sext:prefix(KP);
|
||||||
|
keypat_pfx(_, _) ->
|
||||||
|
<<>>.
|
||||||
|
|
||||||
%% ----------------------------------------------------------------------------
|
%% ----------------------------------------------------------------------------
|
||||||
%% COMMON PRIVATE
|
%% COMMON PRIVATE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user