diff options
Diffstat (limited to 'src/mango/src/mango_idx.erl')
-rw-r--r-- | src/mango/src/mango_idx.erl | 55 |
1 files changed, 31 insertions, 24 deletions
diff --git a/src/mango/src/mango_idx.erl b/src/mango/src/mango_idx.erl index c5f870d5b..4dd2e180d 100644 --- a/src/mango/src/mango_idx.erl +++ b/src/mango/src/mango_idx.erl @@ -20,7 +20,6 @@ -export([ list/1, recover/1, - for_sort/2, new/2, validate_new/2, @@ -36,7 +35,7 @@ def/1, opts/1, columns/1, - is_usable/2, + is_usable/3, start_key/2, end_key/2, cursor_mod/1, @@ -57,9 +56,8 @@ list(Db) -> {ok, Indexes} = ddoc_cache:open(db_to_name(Db), ?MODULE), Indexes. -get_usable_indexes(Db, Selector0, Opts) -> - Selector = mango_selector:normalize(Selector0), +get_usable_indexes(Db, Selector, Opts) -> ExistingIndexes = mango_idx:list(Db), if ExistingIndexes /= [] -> ok; true -> ?MANGO_ERROR({no_usable_index, no_indexes_defined}) @@ -70,13 +68,17 @@ get_usable_indexes(Db, Selector0, Opts) -> ?MANGO_ERROR({no_usable_index, no_index_matching_name}) end, - SortIndexes = mango_idx:for_sort(FilteredIndexes, Opts), - if SortIndexes /= [] -> ok; true -> - ?MANGO_ERROR({no_usable_index, missing_sort_index}) - end, + SortFields = get_sort_fields(Opts), + UsableFilter = fun(I) -> is_usable(I, Selector, SortFields) end, + UsableIndexes0 = lists:filter(UsableFilter, FilteredIndexes), + + case maybe_filter_by_sort_fields(UsableIndexes0, SortFields) of + {ok, SortIndexes} -> + SortIndexes; + {error, no_usable_index} -> + ?MANGO_ERROR({no_usable_index, missing_sort_index}) + end. - UsableFilter = fun(I) -> mango_idx:is_usable(I, Selector) end, - lists:filter(UsableFilter, SortIndexes). recover(Db) -> {ok, DDocs0} = mango_util:open_ddocs(Db), @@ -93,33 +95,38 @@ recover(Db) -> end, DDocs)}. -for_sort(Indexes, Opts) -> - % If a sort was specified we have to find an index that - % can satisfy the request. +get_sort_fields(Opts) -> case lists:keyfind(sort, 1, Opts) of - {sort, {SProps}} when is_list(SProps) -> - for_sort_int(Indexes, {SProps}); + {sort, Sort} -> + mango_sort:fields(Sort); _ -> - Indexes + [] end. -for_sort_int(Indexes, Sort) -> - Fields = mango_sort:fields(Sort), +maybe_filter_by_sort_fields(Indexes, []) -> + {ok, Indexes}; + +maybe_filter_by_sort_fields(Indexes, SortFields) -> FilterFun = fun(Idx) -> Cols = mango_idx:columns(Idx), case {mango_idx:type(Idx), Cols} of {_, all_fields} -> true; {<<"text">>, _} -> - sets:is_subset(sets:from_list(Fields), sets:from_list(Cols)); + sets:is_subset(sets:from_list(SortFields), sets:from_list(Cols)); {<<"json">>, _} -> - lists:prefix(Fields, Cols); + lists:prefix(SortFields, Cols); {<<"special">>, _} -> - lists:prefix(Fields, Cols) + lists:prefix(SortFields, Cols) end end, - lists:filter(FilterFun, Indexes). + case lists:filter(FilterFun, Indexes) of + [] -> + {error, no_usable_index}; + FilteredIndexes -> + {ok, FilteredIndexes} + end. new(Db, Opts) -> @@ -250,9 +257,9 @@ columns(#idx{}=Idx) -> Mod:columns(Idx). -is_usable(#idx{}=Idx, Selector) -> +is_usable(#idx{}=Idx, Selector, SortFields) -> Mod = idx_mod(Idx), - Mod:is_usable(Idx, Selector). + Mod:is_usable(Idx, Selector, SortFields). start_key(#idx{}=Idx, Ranges) -> |