summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarren Smith <garren.smith@gmail.com>2018-06-18 14:50:27 +0200
committerGarren Smith <garren.smith@gmail.com>2018-06-18 14:52:05 +0200
commitde8c6e1d65665bd68c78ef31f80e82c1f046a9b9 (patch)
treed8aaebb525964c53c92d22f332f6d05538e14c3d
parent65d4d9563fc4945f10fd258e9617ade4a1ed707a (diff)
downloadcouchdb-de8c6e1d65665bd68c78ef31f80e82c1f046a9b9.tar.gz
Move sort filtering into is_usable
-rw-r--r--src/mango/src/mango_cursor.erl18
-rw-r--r--src/mango/src/mango_idx.erl27
-rw-r--r--src/mango/src/mango_idx_special.erl15
-rw-r--r--src/mango/src/mango_idx_text.erl13
-rw-r--r--src/mango/src/mango_idx_view.erl15
-rw-r--r--src/mango/test/18-json-sort.py14
-rw-r--r--src/mango/test/mango.py1
7 files changed, 47 insertions, 56 deletions
diff --git a/src/mango/src/mango_cursor.erl b/src/mango/src/mango_cursor.erl
index 5108d36b2..5d2ea717d 100644
--- a/src/mango/src/mango_cursor.erl
+++ b/src/mango/src/mango_cursor.erl
@@ -48,18 +48,12 @@
create(Db, Selector0, Opts) ->
Selector = mango_selector:normalize(Selector0),
UsableIndexes = mango_idx:get_usable_indexes(Db, Selector, Opts),
- case length(UsableIndexes) of
- 0 ->
- AllDocs = mango_idx:special(Db),
- create_cursor(Db, AllDocs, Selector, Opts);
- _ ->
- case mango_cursor:maybe_filter_indexes_by_ddoc(UsableIndexes, Opts) of
- [] ->
- % use_index doesn't match a valid index - fall back to a valid one
- create_cursor(Db, UsableIndexes, Selector, Opts);
- UserSpecifiedIndex ->
- create_cursor(Db, UserSpecifiedIndex, Selector, Opts)
- end
+ case mango_cursor:maybe_filter_indexes_by_ddoc(UsableIndexes, Opts) of
+ [] ->
+ % use_index doesn't match a valid index - fall back to a valid one
+ create_cursor(Db, UsableIndexes, Selector, Opts);
+ UserSpecifiedIndex ->
+ create_cursor(Db, UserSpecifiedIndex, Selector, Opts)
end.
diff --git a/src/mango/src/mango_idx.erl b/src/mango/src/mango_idx.erl
index 7c37585c7..211edacf4 100644
--- a/src/mango/src/mango_idx.erl
+++ b/src/mango/src/mango_idx.erl
@@ -66,13 +66,12 @@ get_usable_indexes(Db, Selector, Opts) ->
SortFields = get_sort_fields(Opts),
UsableFilter = fun(I) -> is_usable(I, Selector, SortFields) end,
- UsableIndexes1 = lists:filter(UsableFilter, UsableIndexes0),
- case maybe_filter_by_sort_fields(UsableIndexes1, Selector, SortFields) of
- {ok, SortIndexes} ->
- SortIndexes;
- {error, no_usable_index} ->
- ?MANGO_ERROR({no_usable_index, missing_sort_index})
+ case lists:filter(UsableFilter, UsableIndexes0) of
+ [] ->
+ ?MANGO_ERROR({no_usable_index, missing_sort_index});
+ UsableIndexes1 ->
+ UsableIndexes1
end.
@@ -100,22 +99,6 @@ get_sort_fields(Opts) ->
end.
-maybe_filter_by_sort_fields(Indexes, _Selector, []) ->
- {ok, Indexes};
-
-maybe_filter_by_sort_fields(Indexes, Selector, SortFields) ->
- FilterFun = fun(Idx) ->
- Mod = idx_mod(Idx),
- Mod:maybe_filter_by_sort_fields(Idx, SortFields, Selector)
- end,
- case lists:filter(FilterFun, Indexes) of
- [] ->
- {error, no_usable_index};
- FilteredIndexes ->
- {ok, FilteredIndexes}
- end.
-
-
new(Db, Opts) ->
Def = get_idx_def(Opts),
Type = get_idx_type(Opts),
diff --git a/src/mango/src/mango_idx_special.erl b/src/mango/src/mango_idx_special.erl
index a2869ad8e..aa1ec2f41 100644
--- a/src/mango/src/mango_idx_special.erl
+++ b/src/mango/src/mango_idx_special.erl
@@ -65,9 +65,11 @@ columns(#idx{def=all_docs}) ->
[<<"_id">>].
-is_usable(#idx{def=all_docs}, Selector, _) ->
+is_usable(#idx{def=all_docs}, _Selector, []) ->
+ true;
+is_usable(#idx{def=all_docs} = Idx, Selector, SortFields) ->
Fields = mango_idx_view:indexable_fields(Selector),
- lists:member(<<"_id">>, Fields).
+ lists:member(<<"_id">>, Fields) and maybe_filter_by_sort_fields(Idx, SortFields, Selector).
start_key([{'$gt', Key, _, _}]) ->
@@ -100,6 +102,13 @@ end_key([{'$eq', Key, '$eq', Key}]) ->
Key.
+% maybe_filter_by_sort_fields(Idx, SortFields, Selector) ->
+% Cols = columns(Idx),
+% io:format("HERE BOOM ~p ~n ~p ~n", [Idx, Cols]),
+% lists:prefix(SortFields, Cols).
+
+maybe_filter_by_sort_fields(_Idx, [], _Selector) ->
+ true;
maybe_filter_by_sort_fields(Idx, SortFields, _Selector) ->
- Cols = mango_idx:columns(Idx),
+ Cols = columns(Idx),
lists:prefix(SortFields, Cols).
diff --git a/src/mango/src/mango_idx_text.erl b/src/mango/src/mango_idx_text.erl
index 6e4f0350b..29b4441a1 100644
--- a/src/mango/src/mango_idx_text.erl
+++ b/src/mango/src/mango_idx_text.erl
@@ -23,8 +23,7 @@
to_json/1,
columns/1,
is_usable/3,
- get_default_field_options/1,
- maybe_filter_by_sort_fields/3
+ get_default_field_options/1
]).
@@ -377,16 +376,6 @@ forbid_index_all() ->
config:get("mango", "index_all_disabled", "false").
-maybe_filter_by_sort_fields(Idx, SortFields, _Selector) ->
- Cols = mango_idx:columns(Idx),
- case Cols of
- all_fields ->
- true;
- _ ->
- sets:is_subset(sets:from_list(SortFields), sets:from_list(Cols))
- end.
-
-
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
diff --git a/src/mango/src/mango_idx_view.erl b/src/mango/src/mango_idx_view.erl
index fe4549e34..db3c5eb15 100644
--- a/src/mango/src/mango_idx_view.erl
+++ b/src/mango/src/mango_idx_view.erl
@@ -24,7 +24,6 @@
columns/1,
start_key/1,
end_key/1,
- maybe_filter_by_sort_fields/3,
indexable_fields/1,
field_ranges/1,
@@ -132,7 +131,8 @@ is_usable(Idx, Selector, SortFields) ->
[<<"_id">>, <<"_rev">>]),
mango_selector:has_required_fields(Selector, RequiredFields2)
- andalso not is_text_search(Selector).
+ andalso not is_text_search(Selector)
+ andalso can_use_sort(RequiredFields, SortFields, Selector).
is_text_search({[]}) ->
@@ -514,11 +514,12 @@ range_pos(Low, Arg, High) ->
end.
-maybe_filter_by_sort_fields(Idx, SortFields, Selector) ->
- Cols = mango_idx:columns(Idx),
+can_use_sort(_Cols, [], _Selector) ->
+ true;
+can_use_sort(Cols, SortFields, Selector) ->
case lists:subtract(SortFields, Cols) of
[] ->
- NormalizedSortFields = normalize_sort_fields(Cols, SortFields, Selector),
+ NormalizedSortFields = add_constant_sort_fields(Cols, SortFields, Selector),
lists:prefix(NormalizedSortFields, Cols);
_ ->
false
@@ -526,7 +527,7 @@ maybe_filter_by_sort_fields(Idx, SortFields, Selector) ->
% This is an user experience improvement. If a selector has a sort field set
-% then an index is only valid if the prefix of the sort fields match the
+% then an index is only valid if the sort fields match the
% prefix of the index fields.
% e.g Index = [A, B, C] with Sort = [A, B] is a valid sort
@@ -541,7 +542,7 @@ maybe_filter_by_sort_fields(Idx, SortFields, Selector) ->
% The sort will work as expected and this will increase the possibility
% of the index being choosen. It also helps a user where they might not have
% put correct initial fields in the sort.
-normalize_sort_fields(Cols, SortFields, Selector) ->
+add_constant_sort_fields(Cols, SortFields, Selector) ->
lists:foldr(fun (Col, Sort) ->
case lists:member(Col, SortFields) of
true ->
diff --git a/src/mango/test/18-json-sort.py b/src/mango/test/18-json-sort.py
index 58ace485c..6c5db4880 100644
--- a/src/mango/test/18-json-sort.py
+++ b/src/mango/test/18-json-sort.py
@@ -154,6 +154,20 @@ class JSONIndexSortOptimisations(mango.DbPerClass):
resp = e.response.json()
self.assertEqual(resp["error"], "no_usable_index")
+ def test_empty_sort(self):
+ self.db.create_index(["cars", "age", "name"], name="cars-age-name")
+ selector = {
+ "name": {
+ "$gt": "Eddie",
+ },
+ "age": 10,
+ "cars": {
+ "$gt": "1"
+ }
+ }
+ explain = self.db.find(selector, explain=True)
+ self.assertEqual(explain["index"]["name"], "cars-age-name")
+
def test_in_between(self):
self.db.create_index(["cars", "age", "name"], name="cars-age-name")
selector = {
diff --git a/src/mango/test/mango.py b/src/mango/test/mango.py
index 9b6b998cd..13873211a 100644
--- a/src/mango/test/mango.py
+++ b/src/mango/test/mango.py
@@ -240,6 +240,7 @@ class Database(object):
else:
path = self.path("_find")
r = self.sess.post(path, data=body)
+ print r.json()
r.raise_for_status()
if explain or return_raw:
return r.json()