-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mango: generate a warning instead of an error when an user-specified index cannot be used #962
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -66,12 +66,8 @@ def test_no_valid_sort_index(self): | |
def test_invalid_use_index(self): | ||
# ddoc id for the age index | ||
ddocid = "_design/ad3d537c03cd7c6a43cf8dff66ef70ea54c2b40f" | ||
try: | ||
self.db.find({}, use_index=ddocid) | ||
except Exception as e: | ||
self.assertEqual(e.response.status_code, 400) | ||
else: | ||
raise AssertionError("bad find") | ||
r = self.db.find({}, use_index=ddocid, return_raw=True) | ||
self.assertEqual(r["warning"], '{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 | ||
|
@@ -87,19 +83,18 @@ def test_uses_index_when_no_range_or_equals(self): | |
resp_explain = self.db.find(selector, explain=True) | ||
self.assertEqual(resp_explain["index"]["type"], "json") | ||
|
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. whitespace |
||
def test_reject_use_index_invalid_fields(self): | ||
# index on ["company","manager"] which should not be valid | ||
ddocid = "_design/a0c425a60cf3c3c09e3c537c9ef20059dcef9198" | ||
selector = { | ||
"company": "Pharmex" | ||
} | ||
try: | ||
self.db.find(selector, use_index=ddocid) | ||
except Exception as e: | ||
self.assertEqual(e.response.status_code, 400) | ||
else: | ||
raise AssertionError("did not reject bad use_index") | ||
r = self.db.find(selector, use_index=ddocid, return_raw=True) | ||
self.assertEqual(r["warning"], '{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): | ||
# index on ["company","manager"] which should not be valid | ||
|
@@ -108,41 +103,58 @@ def test_reject_use_index_ddoc_and_name_invalid_fields(self): | |
selector = { | ||
"company": "Pharmex" | ||
} | ||
try: | ||
self.db.find(selector, use_index=[ddocid,name]) | ||
except Exception as e: | ||
self.assertEqual(e.response.status_code, 400) | ||
else: | ||
raise AssertionError("did not reject bad use_index") | ||
|
||
resp = self.db.find(selector, use_index=[ddocid,name], return_raw=True) | ||
self.assertEqual(resp["warning"], "{0}, {1} was not used because it is not a valid index for this query.".format(ddocid, name)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in the test case above, you're checking that a value is returned
We should be consistent? |
||
|
||
# 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/a0c425a60cf3c3c09e3c537c9ef20059dcef9198" | ||
selector = { | ||
"company": {"$gt": None}, | ||
"manager": {"$gt": None} | ||
"company": {"$gt": None} | ||
} | ||
try: | ||
self.db.find(selector, use_index=ddocid, sort=[{"manager":"desc"}]) | ||
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_reject_use_index_ddoc_and_name_sort_order(self): | ||
# index on ["company","manager"] which should not be valid | ||
ddocid = "_design/a0c425a60cf3c3c09e3c537c9ef20059dcef9198" | ||
name = "a0c425a60cf3c3c09e3c537c9ef20059dcef9198" | ||
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 = { | ||
"company": {"$gt": None}, | ||
"manager": {"$gt": None} | ||
"foo": {"$gt": None} | ||
} | ||
try: | ||
self.db.find(selector, use_index=[ddocid,name], sort=[{"manager":"desc"}]) | ||
except Exception as e: | ||
self.assertEqual(e.response.status_code, 400) | ||
else: | ||
raise AssertionError("did not reject bad use_index") | ||
|
||
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"], '{0} was not used because it does not contain a valid index for this query.'.format(ddocid_invalid)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above, we should get a value back here right? It's going to fall back on the ddoc_valid and return a result, so just confirm a result? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. agree that we should check the result in the cases above. In this test, however, I don't expect any matches (and can assert that). |
||
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 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are we sorting the indexes here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is to remove duplicates - an index might belong to GlobalIndexes and be specified by the user explicitly.