summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony Sun <tony.sun427@gmail.com>2017-10-03 17:40:24 -0700
committerTony Sun <tony.sun427@gmail.com>2017-11-14 09:43:29 -0800
commit165fe03352c93e0a4f895ba1c9ecf07683c91887 (patch)
tree260792652f41148fdfddf1100b0ea8783a41f48b
parent563b9049ab0cc989ece4a26f931933db926027f0 (diff)
downloadcouchdb-fix-explicit-exists-operator.tar.gz
fix exists false when field is explicitly definedfix-explicit-exists-operator
When users explicitly defined a text index's fields, and used $exists with false, we tag false when constructing the query. This led to a function clause for indexable_fields since we did not account for it. This fix patches that up, but note that we don't care about the false value itself since we only care about fields.
-rw-r--r--src/mango/src/mango_idx_text.erl3
-rw-r--r--src/mango/test/07-text-custom-field-list-test.py50
2 files changed, 53 insertions, 0 deletions
diff --git a/src/mango/src/mango_idx_text.erl b/src/mango/src/mango_idx_text.erl
index 1d5ae9bad..369e2cd08 100644
--- a/src/mango/src/mango_idx_text.erl
+++ b/src/mango/src/mango_idx_text.erl
@@ -329,6 +329,9 @@ indexable_fields(Fields, {op_or, Args}) when is_list(Args) ->
indexable_fields(Fields, {op_not, {ExistsQuery, Arg}}) when is_tuple(Arg) ->
Fields0 = indexable_fields(Fields, ExistsQuery),
indexable_fields(Fields0, Arg);
+% forces "$exists" : false to use _all_docs
+indexable_fields(Fields, {op_not, {ExistsQuery, false}}) ->
+ [];
indexable_fields(Fields, {op_insert, Arg}) when is_binary(Arg) ->
Fields;
diff --git a/src/mango/test/07-text-custom-field-list-test.py b/src/mango/test/07-text-custom-field-list-test.py
index a43e33003..9bfe07598 100644
--- a/src/mango/test/07-text-custom-field-list-test.py
+++ b/src/mango/test/07-text-custom-field-list-test.py
@@ -12,6 +12,7 @@
import mango
import unittest
+import user_docs
@unittest.skipUnless(mango.has_text_service(), "requires text service")
@@ -160,3 +161,52 @@ class CustomFieldsTest(mango.UserDocsTextTests):
})
assert len(docs) == 1
assert docs[0]["user_id"] == 10
+
+@unittest.skipUnless(mango.has_text_service(), "requires text service")
+class CustomFieldsExistsTest(mango.UserDocsTextTests):
+
+ FIELDS = [
+ {"name": "exists_field", "type": "string"},
+ {"name": "exists_array.[]", "type": "string"},
+ {"name": "exists_object.should", "type": "string"},
+ {"name": "twitter", "type": "string"}
+ ]
+
+ def test_exists_field(self):
+ docs = self.db.find({"exists_field": {"$exists": True}})
+ self.assertEqual(len(docs), 2)
+ for d in docs:
+ self.assertIn(d["user_id"], (7, 8))
+
+ docs = self.db.find({"exists_field": {"$exists": False}})
+ self.assertEqual(len(docs), len(user_docs.DOCS) - 2)
+ for d in docs:
+ self.assertNotIn(d["user_id"], (7, 8))
+
+ def test_exists_array(self):
+ docs = self.db.find({"exists_array": {"$exists": True}})
+ self.assertEqual(len(docs), 2)
+ for d in docs:
+ self.assertIn(d["user_id"], (9, 10))
+
+ docs = self.db.find({"exists_array": {"$exists": False}})
+ self.assertEqual(len(docs), len(user_docs.DOCS) - 2)
+ for d in docs:
+ self.assertNotIn(d["user_id"], (9, 10))
+
+ def test_exists_object_member(self):
+ docs = self.db.find({"exists_object.should": {"$exists": True}})
+ self.assertEqual(len(docs), 1)
+ self.assertEqual(docs[0]["user_id"], 11)
+
+ docs = self.db.find({"exists_object.should": {"$exists": False}})
+ self.assertEqual(len(docs), len(user_docs.DOCS) - 1)
+ for d in docs:
+ self.assertNotEqual(d["user_id"], 11)
+
+ def test_exists_false_same_as_views(self):
+ docs = self.db.find({
+ "twitter": {"$exists": False}
+ })
+ for d in docs:
+ self.assertNotIn(d["user_id"], (0, 1, 4, 13))