summaryrefslogtreecommitdiff
path: root/src/mango/test/05-index-selection-test.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/mango/test/05-index-selection-test.py')
-rw-r--r--src/mango/test/05-index-selection-test.py336
1 files changed, 0 insertions, 336 deletions
diff --git a/src/mango/test/05-index-selection-test.py b/src/mango/test/05-index-selection-test.py
deleted file mode 100644
index cb4d32986..000000000
--- a/src/mango/test/05-index-selection-test.py
+++ /dev/null
@@ -1,336 +0,0 @@
-# Licensed under the Apache License, Version 2.0 (the "License"); you may not
-# use this file except in compliance with the License. You may obtain a copy of
-# the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations under
-# the License.
-
-import mango
-import user_docs
-import unittest
-
-
-class IndexSelectionTests:
- def test_basic(self):
- resp = self.db.find({"age": 123}, explain=True)
- self.assertEqual(resp["index"]["type"], "json")
-
- def test_with_and(self):
- resp = self.db.find(
- {
- "name.first": "Stephanie",
- "name.last": "This doesn't have to match anything.",
- },
- explain=True,
- )
- self.assertEqual(resp["index"]["type"], "json")
-
- def test_with_nested_and(self):
- resp = self.db.find(
- {"name.first": {"$gt": "a", "$lt": "z"}, "name.last": "Foo"}, explain=True
- )
- self.assertEqual(resp["index"]["type"], "json")
-
- def test_with_or(self):
- ddocid = "_design/company_and_manager"
-
- resp = self.db.find(
- {
- "company": {"$gt": "a", "$lt": "z"},
- "$or": [{"manager": "Foo"}, {"manager": "Bar"}],
- },
- explain=True,
- )
- self.assertEqual(resp["index"]["ddoc"], ddocid)
-
- def test_use_most_columns(self):
- ddocid = "_design/age"
- resp = self.db.find(
- {
- "name.first": "Stephanie",
- "name.last": "Something or other",
- "age": {"$gt": 1},
- },
- explain=True,
- )
- self.assertNotEqual(resp["index"]["ddoc"], ddocid)
-
- resp = self.db.find(
- {
- "name.first": "Stephanie",
- "name.last": "Something or other",
- "age": {"$gt": 1},
- },
- use_index=ddocid,
- explain=True,
- )
- self.assertEqual(resp["index"]["ddoc"], ddocid)
-
- def test_no_valid_sort_index(self):
- try:
- self.db.find({"_id": {"$gt": None}}, sort=["name"], return_raw=True)
- except Exception as e:
- self.assertEqual(e.response.status_code, 400)
- else:
- raise AssertionError("bad find")
-
- def test_invalid_use_index(self):
- # ddoc id for the age index
- ddocid = "_design/age"
- r = self.db.find({}, use_index=ddocid, return_raw=True)
- self.assertEqual(
- r["warning"].split("\n")[0].lower(),
- "{0} was not used because it does not contain a valid index for this query.".format(
- ddocid
- ),
- )
-
- def test_uses_index_when_no_range_or_equals(self):
- # index on ["manager"] should be valid because
- # selector requires "manager" to exist. The
- # selector doesn't narrow the keyrange so it's
- # a full index scan
- selector = {"manager": {"$exists": True}}
- docs = self.db.find(selector)
- self.assertEqual(len(docs), 14)
-
- resp_explain = self.db.find(selector, explain=True)
- self.assertEqual(resp_explain["index"]["type"], "json")
-
- def test_reject_use_index_invalid_fields(self):
- ddocid = "_design/company_and_manager"
- selector = {"company": "Pharmex"}
- r = self.db.find(selector, use_index=ddocid, return_raw=True)
- self.assertEqual(
- r["warning"].split("\n")[0].lower(),
- "{0} was not used because it does not contain a valid index for this query.".format(
- ddocid
- ),
- )
-
- # should still return a correct result
- for d in r["docs"]:
- self.assertEqual(d["company"], "Pharmex")
-
- def test_reject_use_index_ddoc_and_name_invalid_fields(self):
- ddocid = "_design/company_and_manager"
- name = "company_and_manager"
- selector = {"company": "Pharmex"}
-
- resp = self.db.find(selector, use_index=[ddocid, name], return_raw=True)
- self.assertEqual(
- resp["warning"].split("\n")[0].lower(),
- "{0}, {1} was not used because it is not a valid index for this query.".format(
- ddocid, name
- ),
- )
-
- # should still return a correct result
- for d in resp["docs"]:
- self.assertEqual(d["company"], "Pharmex")
-
- def test_reject_use_index_sort_order(self):
- # index on ["company","manager"] which should not be valid
- # and there is no valid fallback (i.e. an index on ["company"])
- ddocid = "_design/company_and_manager"
- selector = {"company": {"$gt": None}}
- try:
- self.db.find(selector, use_index=ddocid, sort=[{"company": "desc"}])
- except Exception as e:
- self.assertEqual(e.response.status_code, 400)
- else:
- raise AssertionError("did not reject bad use_index")
-
- def test_use_index_fallback_if_valid_sort(self):
- ddocid_valid = "_design/fallbackfoo"
- ddocid_invalid = "_design/fallbackfoobar"
- self.db.create_index(fields=["foo"], ddoc=ddocid_invalid)
- self.db.create_index(fields=["foo", "bar"], ddoc=ddocid_valid)
- selector = {"foo": {"$gt": None}}
-
- resp_explain = self.db.find(
- selector, sort=["foo", "bar"], use_index=ddocid_invalid, explain=True
- )
- self.assertEqual(resp_explain["index"]["ddoc"], ddocid_valid)
-
- resp = self.db.find(
- selector, sort=["foo", "bar"], use_index=ddocid_invalid, return_raw=True
- )
- self.assertEqual(
- resp["warning"].split("\n")[0].lower(),
- "{0} was not used because it does not contain a valid index for this query.".format(
- ddocid_invalid
- ),
- )
- self.assertEqual(len(resp["docs"]), 0)
-
- def test_prefer_use_index_over_optimal_index(self):
- # index on ["company"] even though index on ["company", "manager"] is better
- ddocid_preferred = "_design/testsuboptimal"
- self.db.create_index(fields=["baz"], ddoc=ddocid_preferred)
- self.db.create_index(fields=["baz", "bar"])
- selector = {"baz": {"$gt": None}, "bar": {"$gt": None}}
- resp = self.db.find(selector, use_index=ddocid_preferred, return_raw=True)
- self.assertTrue("warning" not in resp)
-
- resp_explain = self.db.find(selector, use_index=ddocid_preferred, explain=True)
- self.assertEqual(resp_explain["index"]["ddoc"], ddocid_preferred)
-
- # This doc will not be saved given the new ddoc validation code
- # in couch_mrview
- def test_manual_bad_view_idx01(self):
- design_doc = {
- "_id": "_design/bad_view_index",
- "language": "query",
- "views": {
- "queryidx1": {
- "map": {"fields": {"age": "asc"}},
- "reduce": "_count",
- "options": {"def": {"fields": [{"age": "asc"}]}, "w": 2},
- }
- },
- "views": {
- "views001": {
- "map": "function(employee){if(employee.training)"
- + "{emit(employee.number, employee.training);}}"
- }
- },
- }
- with self.assertRaises(KeyError):
- self.db.save_doc(design_doc)
-
- def test_explain_sort_reverse(self):
- selector = {"manager": {"$gt": None}}
- resp_explain = self.db.find(
- selector, fields=["manager"], sort=[{"manager": "desc"}], explain=True
- )
- self.assertEqual(resp_explain["index"]["type"], "json")
-
-
-class JSONIndexSelectionTests(mango.UserDocsTests, IndexSelectionTests):
- @classmethod
- def setUpClass(klass):
- super(JSONIndexSelectionTests, klass).setUpClass()
-
- def test_uses_all_docs_when_fields_do_not_match_selector(self):
- # index exists on ["company", "manager"] but not ["company"]
- # so we should fall back to all docs (so we include docs
- # with no "manager" field)
- selector = {"company": "Pharmex"}
- docs = self.db.find(selector)
- self.assertEqual(len(docs), 1)
- self.assertEqual(docs[0]["company"], "Pharmex")
- self.assertNotIn("manager", docs[0])
-
- resp_explain = self.db.find(selector, explain=True)
-
- self.assertEqual(resp_explain["index"]["type"], "special")
-
- def test_uses_all_docs_when_selector_doesnt_require_fields_to_exist(self):
- # as in test above, use a selector that doesn't overlap with the index
- # due to an explicit exists clause
- selector = {"company": "Pharmex", "manager": {"$exists": False}}
- docs = self.db.find(selector)
- self.assertEqual(len(docs), 1)
- self.assertEqual(docs[0]["company"], "Pharmex")
- self.assertNotIn("manager", docs[0])
-
- resp_explain = self.db.find(selector, explain=True)
- self.assertEqual(resp_explain["index"]["type"], "special")
-
-
-@unittest.skipUnless(mango.has_text_service(), "requires text service")
-class TextIndexSelectionTests(mango.UserDocsTests):
- @classmethod
- def setUpClass(klass):
- super(TextIndexSelectionTests, klass).setUpClass()
- if mango.has_text_service():
- user_docs.add_text_indexes(klass.db, {})
-
- def test_with_text(self):
- resp = self.db.find(
- {
- "$text": "Stephanie",
- "name.first": "Stephanie",
- "name.last": "This doesn't have to match anything.",
- },
- explain=True,
- )
- self.assertEqual(resp["index"]["type"], "text")
-
- def test_no_view_index(self):
- resp = self.db.find({"name.first": "Ohai!"}, explain=True)
- self.assertEqual(resp["index"]["type"], "text")
-
- def test_with_or(self):
- resp = self.db.find(
- {
- "$or": [
- {"name.first": "Stephanie"},
- {"name.last": "This doesn't have to match anything."},
- ]
- },
- explain=True,
- )
- self.assertEqual(resp["index"]["type"], "text")
-
- def test_manual_bad_text_idx(self):
- design_doc = {
- "_id": "_design/bad_text_index",
- "language": "query",
- "indexes": {
- "text_index": {
- "default_analyzer": "keyword",
- "default_field": {},
- "selector": {},
- "fields": "all_fields",
- "analyzer": {
- "name": "perfield",
- "default": "keyword",
- "fields": {"$default": "standard"},
- },
- }
- },
- "indexes": {
- "st_index": {
- "analyzer": "standard",
- "index": 'function(doc){\n index("st_index", doc.geometry);\n}',
- }
- },
- }
- self.db.save_doc(design_doc)
- docs = self.db.find({"age": 48})
- self.assertEqual(len(docs), 1)
- self.assertEqual(docs[0]["name"]["first"], "Stephanie")
- self.assertEqual(docs[0]["age"], 48)
-
-
-@unittest.skipUnless(mango.has_text_service(), "requires text service")
-class MultiTextIndexSelectionTests(mango.UserDocsTests):
- @classmethod
- def setUpClass(klass):
- super(MultiTextIndexSelectionTests, klass).setUpClass()
- if mango.has_text_service():
- klass.db.create_text_index(ddoc="foo", analyzer="keyword")
- klass.db.create_text_index(ddoc="bar", analyzer="email")
-
- def test_fallback_to_json_with_multi_text(self):
- resp = self.db.find(
- {"name.first": "A first name", "name.last": "A last name"}, explain=True
- )
- self.assertEqual(resp["index"]["type"], "json")
-
- def test_multi_text_index_is_error(self):
- try:
- self.db.find({"$text": "a query"}, explain=True)
- except Exception as e:
- self.assertEqual(e.response.status_code, 400)
-
- def test_use_index_works(self):
- resp = self.db.find({"$text": "a query"}, use_index="foo", explain=True)
- self.assertEqual(resp["index"]["ddoc"], "_design/foo")