summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjiangph <jiangph@cn.ibm.com>2018-11-02 17:12:10 +0800
committerjiangph <jiangph@cn.ibm.com>2018-11-06 17:15:14 +0800
commit8ad49a22b198b84b062268340acc3fd84fb9bcc7 (patch)
tree13513dc73eae010271e1ef721fe8fdea4eebd526
parentf350d5f5de8413ffaa6c5fac6bfb19f090fbd8ec (diff)
downloadcouchdb-8ad49a22b198b84b062268340acc3fd84fb9bcc7.tar.gz
Support out-of-sync in mango when doc is deleted
- under situation where the document is deleted while the mrview index for this document is not updated, the returned value from mrview is {doc,null}. There is no such consideration in Mango to cause case_clause error. This fix is to consider out-of-sync between documents in database and their index and not to cause 500 when the _find endpoint is called.
-rw-r--r--src/mango/src/mango_cursor_view.erl8
-rw-r--r--src/mango/test/01-index-crud-test.py35
-rw-r--r--src/mango/test/mango.py6
3 files changed, 48 insertions, 1 deletions
diff --git a/src/mango/src/mango_cursor_view.erl b/src/mango/src/mango_cursor_view.erl
index 174381e4a..b3a7f4080 100644
--- a/src/mango/src/mango_cursor_view.erl
+++ b/src/mango/src/mango_cursor_view.erl
@@ -229,6 +229,9 @@ view_cb({row, Row}, #mrargs{extra = Options} = Acc) ->
doc = couch_util:get_value(doc, Row)
},
case ViewRow#view_row.doc of
+ null ->
+ put(mango_docs_examined, get(mango_docs_examined) + 1),
+ maybe_send_mango_ping();
undefined ->
ViewRow2 = ViewRow#view_row{
value = couch_util:get_value(value, Row)
@@ -427,7 +430,10 @@ doc_member(Cursor, RowProps) ->
match_doc(Selector, Doc, ExecutionStats1);
Else ->
Else
- end
+ end;
+ null ->
+ ExecutionStats1 = mango_execution_stats:incr_docs_examined(ExecutionStats),
+ {no_match, null, {execution_stats, ExecutionStats1}}
end.
diff --git a/src/mango/test/01-index-crud-test.py b/src/mango/test/01-index-crud-test.py
index cf5b91865..f57db39af 100644
--- a/src/mango/test/01-index-crud-test.py
+++ b/src/mango/test/01-index-crud-test.py
@@ -13,8 +13,24 @@
import random
import mango
+import copy
import unittest
+DOCS = [
+ {
+ "_id": "1",
+ "name": "Jimi",
+ "age": 10,
+ "cars": 1
+ },
+ {
+ "_id": "2",
+ "name": "kate",
+ "age": 8,
+ "cars": 0
+ }
+]
+
class IndexCrudTests(mango.DbPerClass):
def setUp(self):
self.db.recreate()
@@ -271,6 +287,25 @@ class IndexCrudTests(mango.DbPerClass):
except Exception as e:
self.assertEqual(e.response.status_code, 500)
+ def test_out_of_sync(self):
+ self.db.save_docs(copy.deepcopy(DOCS))
+ self.db.create_index(["age"], name="age")
+
+ selector = {
+ "age": {
+ "$gt": 0
+ },
+ }
+ docs = self.db.find(selector,
+ use_index="_design/a017b603a47036005de93034ff689bbbb6a873c4")
+ self.assertEqual(len(docs), 2)
+
+ self.db.delete_doc("1")
+
+ docs1 = self.db.find(selector, update="False",
+ use_index="_design/a017b603a47036005de93034ff689bbbb6a873c4")
+ self.assertEqual(len(docs1), 1)
+
@unittest.skipUnless(mango.has_text_service(), "requires text service")
class IndexCrudTextTests(mango.DbPerClass):
diff --git a/src/mango/test/mango.py b/src/mango/test/mango.py
index bc12bbc68..59486c861 100644
--- a/src/mango/test/mango.py
+++ b/src/mango/test/mango.py
@@ -113,6 +113,12 @@ class Database(object):
r.raise_for_status()
return r.json()
+ def delete_doc(self, docid):
+ r = self.sess.get(self.path(docid))
+ r.raise_for_status()
+ original_rev = r.json()['_rev']
+ self.sess.delete(self.path(docid), params={"rev": original_rev})
+
def ddoc_info(self, ddocid):
r = self.sess.get(self.path([ddocid, "_info"]))
r.raise_for_status()