Handle unsatisfiable [empty] ranges
Queries sometimes contain unsatisfiable ranges (i.e x < 0 and x > 0).
This is indicated by the [empty] value. In this case, we should not
perform a search and simply return 0 documents.
Fixes COUCHDB-2614
diff --git a/src/mango_cursor_view.erl b/src/mango_cursor_view.erl
index ddf1e1a..cb35968 100644
--- a/src/mango_cursor_view.erl
+++ b/src/mango_cursor_view.erl
@@ -54,10 +54,15 @@
index = Idx,
ranges = Ranges
} = Cursor,
- [{range, {[
- {start_key, mango_idx:start_key(Idx, Ranges)},
- {end_key, mango_idx:end_key(Idx, Ranges)}
- ]}}].
+ case Ranges of
+ [empty] ->
+ [{range, empty}];
+ _ ->
+ [{range, {[
+ {start_key, mango_idx:start_key(Idx, Ranges)},
+ {end_key, mango_idx:end_key(Idx, Ranges)}
+ ]}}]
+ end.
execute(#cursor{db = Db, index = Idx} = Cursor0, UserFun, UserAcc) ->
@@ -65,25 +70,31 @@
user_fun = UserFun,
user_acc = UserAcc
},
- BaseArgs = #mrargs{
- view_type = map,
- reduce = false,
- start_key = mango_idx:start_key(Idx, Cursor#cursor.ranges),
- end_key = mango_idx:end_key(Idx, Cursor#cursor.ranges),
- include_docs = true
- },
- Args = apply_opts(Cursor#cursor.opts, BaseArgs),
- CB = fun ?MODULE:handle_message/2,
- {ok, LastCursor} = case mango_idx:def(Idx) of
- all_docs ->
- fabric:all_docs(Db, CB, Cursor, Args);
+ case Cursor#cursor.ranges of
+ [empty] ->
+ % empty indicates unsatisfiable ranges, so don't perform search
+ {ok, UserAcc};
_ ->
- % Normal view
- DDoc = ddocid(Idx),
- Name = mango_idx:name(Idx),
- fabric:query_view(Db, DDoc, Name, CB, Cursor, Args)
- end,
- {ok, LastCursor#cursor.user_acc}.
+ BaseArgs = #mrargs{
+ view_type = map,
+ reduce = false,
+ start_key = mango_idx:start_key(Idx, Cursor#cursor.ranges),
+ end_key = mango_idx:end_key(Idx, Cursor#cursor.ranges),
+ include_docs = true
+ },
+ Args = apply_opts(Cursor#cursor.opts, BaseArgs),
+ CB = fun ?MODULE:handle_message/2,
+ {ok, LastCursor} = case mango_idx:def(Idx) of
+ all_docs ->
+ fabric:all_docs(Db, CB, Cursor, Args);
+ _ ->
+ % Normal view
+ DDoc = ddocid(Idx),
+ Name = mango_idx:name(Idx),
+ fabric:query_view(Db, DDoc, Name, CB, Cursor, Args)
+ end,
+ {ok, LastCursor#cursor.user_acc}
+ end.
% Any of these indexes may be a composite index. For each
diff --git a/test/02-basic-find-test.py b/test/02-basic-find-test.py
index 8113b21..37459a2 100644
--- a/test/02-basic-find-test.py
+++ b/test/02-basic-find-test.py
@@ -258,3 +258,12 @@
})
assert len(docs) == 1
assert docs[0]["user_id"] == "eo"
+
+ def test_unsatisfiable_range(self):
+ docs = self.db.find({
+ "$and":[
+ {"age":{"$gt": 0}},
+ {"age":{"$lt": 0}}
+ ]
+ })
+ assert len(docs) == 0