You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by to...@apache.org on 2015/09/10 02:34:07 UTC

[05/26] couchdb-mango git commit: Handle extra <<>> when elemMatch normalizes selector

Handle extra <<>> when elemMatch normalizes selector

When $elemMatch is applied to non-objects such as:
{"results":{"$elemMatch": {"$gte": 80, "$lt": 85}}},
our normalizer modifies the selector to include <<>>. This
causes issues for our path_str and match functions. This
fix addresses those issues by removing the <<>> from the selector
and also not adding a period when a Part is <<>>.

BugzId: 44817


Project: http://git-wip-us.apache.org/repos/asf/couchdb-mango/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-mango/commit/10fcac2b
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-mango/tree/10fcac2b
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-mango/diff/10fcac2b

Branch: refs/heads/master
Commit: 10fcac2be08f22395935bd938d5dccf5e8d71ac9
Parents: ca5ff7b
Author: Tony Sun <to...@cloudant.com>
Authored: Tue Aug 25 11:26:50 2015 -0700
Committer: Tony Sun <to...@cloudant.com>
Committed: Tue Aug 25 13:23:53 2015 -0700

----------------------------------------------------------------------
 src/mango_selector.erl      | 15 +++++++++++++++
 src/mango_selector_text.erl |  8 +++++++-
 test/06-basic-text-test.py  | 18 ++++++++++++++++++
 test/friend_docs.py         |  4 +++-
 4 files changed, 43 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-mango/blob/10fcac2b/src/mango_selector.erl
----------------------------------------------------------------------
diff --git a/src/mango_selector.erl b/src/mango_selector.erl
index c008a4c..21c55ae 100644
--- a/src/mango_selector.erl
+++ b/src/mango_selector.erl
@@ -411,6 +411,21 @@ match({[{<<"$all">>, Args}]}, Values, _Cmp) when is_list(Values) ->
 match({[{<<"$all">>, _Args}]}, _Values, _Cmp) ->
     false;
 
+%% This is for $elemMatch and possibly $in because of our normalizer.
+%% A selector such as {"field_name": {"$elemMatch": {"$gte": 80, "$lt": 85}}}
+%% gets normalized to:
+%% {[{<<"field_name">>,
+%%     {[{<<"$elemMatch">>,
+%%         {[{<<"$and">>, [
+%%             {[{<<>>,{[{<<"$gte">>,80}]}}]},
+%%             {[{<<>>,{[{<<"$lt">>,85}]}}]}
+%%         ]}]}
+%%     }]}
+%% }]}.
+%% So we filter out the <<>>.
+match({[{<<>>, Arg}]}, Values, Cmp) ->
+    match(Arg, Values, Cmp);
+
 % Matches when any element in values matches the
 % sub-selector Arg.
 match({[{<<"$elemMatch">>, Arg}]}, Values, Cmp) when is_list(Values) ->

http://git-wip-us.apache.org/repos/asf/couchdb-mango/blob/10fcac2b/src/mango_selector_text.erl
----------------------------------------------------------------------
diff --git a/src/mango_selector_text.erl b/src/mango_selector_text.erl
index 74a4012..24d4ad1 100644
--- a/src/mango_selector_text.erl
+++ b/src/mango_selector_text.erl
@@ -274,7 +274,13 @@ path_str([Part], Acc) ->
     % during recursion of convert.
     [Part | Acc];
 path_str([Part | Rest], Acc) ->
-    path_str(Rest, [<<".">>, Part | Acc]).
+    case Part of
+        % do not append a period if Part is blank
+        <<>> ->
+            path_str(Rest, [Acc]);
+        _ ->
+            path_str(Rest, [<<".">>, Part | Acc])
+    end.
 
 
 type_str(Value) when is_number(Value) ->

http://git-wip-us.apache.org/repos/asf/couchdb-mango/blob/10fcac2b/test/06-basic-text-test.py
----------------------------------------------------------------------
diff --git a/test/06-basic-text-test.py b/test/06-basic-text-test.py
index baf912b..670fad5 100644
--- a/test/06-basic-text-test.py
+++ b/test/06-basic-text-test.py
@@ -404,6 +404,24 @@ class ElemMatchTests(mango.FriendDocsTextTests):
     def setUpClass(klass):
         raise unittest.SkipTest('text index is not supported yet')
 
+    def test_elem_match_non_object(self):
+        q = {"bestfriends":{
+                "$elemMatch":
+                    {"$eq":"Wolverine", "$eq":"Cyclops"}
+            }
+        }
+        docs = self.db.find(q)
+        print len(docs)
+        assert len(docs) == 1
+        assert docs[0]["bestfriends"] == ["Wolverine", "Cyclops"]
+
+        q = {"results": {"$elemMatch": {"$gte": 80, "$lt": 85}}}
+
+        docs = self.db.find(q)
+        print len(docs)
+        assert len(docs) == 1
+        assert docs[0]["results"] == [82, 85, 88]
+
     def test_elem_match(self):
         q = {"friends": {
                 "$elemMatch":

http://git-wip-us.apache.org/repos/asf/couchdb-mango/blob/10fcac2b/test/friend_docs.py
----------------------------------------------------------------------
diff --git a/test/friend_docs.py b/test/friend_docs.py
index 8bba58d..ec2c082 100644
--- a/test/friend_docs.py
+++ b/test/friend_docs.py
@@ -461,7 +461,8 @@ DOCS =  [
                 },
                 "type": "personal"
             }
-        ]
+        ],
+        "bestfriends" : ["Wolverine", "Cyclops"]
     },
     {
         "_id": "54a431719faa420a5b4fbeb0",
@@ -530,6 +531,7 @@ DOCS =  [
                 "type": "work"
             }
         ]
+        "results": [ 82, 85, 88 ]
     },
     {
         "_id": "54a4317132f2c81561833259",