summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--db/matcher.cpp27
-rw-r--r--db/matcher.h1
-rw-r--r--mongo.xcodeproj/project.pbxproj2
3 files changed, 30 insertions, 0 deletions
diff --git a/db/matcher.cpp b/db/matcher.cpp
index baaeee52bfc..a6717c51dcd 100644
--- a/db/matcher.cpp
+++ b/db/matcher.cpp
@@ -299,6 +299,18 @@ namespace mongo {
BSONObjIterator i(jsobj);
while ( i.more() ) {
BSONElement e = i.next();
+
+ const char *ef = e.fieldName();
+ if ( ef[1] == 'o' && ef[2] == 'r' && ef[3] == 0 ) {
+ uassert( 13086, "$or must be a nonempty array", e.type() == Array && e.embeddedObject().nFields() > 0 );
+ BSONObjIterator j( e.embeddedObject() );
+ while( j.more() ) {
+ BSONElement f = j.next();
+ uassert( 13087, "$or match element must be an object", f.type() == Object );
+ _orMatchers.push_back( shared_ptr< Matcher >( new Matcher( f.embeddedObject(), constrainIndexKey ) ) );
+ }
+ break;
+ }
if ( ( e.type() == CodeWScope || e.type() == Code || e.type() == String ) && strcmp(e.fieldName(), "$where")==0 ) {
// $where: function()...
@@ -704,6 +716,21 @@ namespace mongo {
/* assuming there is usually only one thing to match. if more this
could be slow sometimes. */
+ // for now $or must be the only top level field if present
+ if ( _orMatchers.size() > 0 ) {
+ for( vector< shared_ptr< Matcher > >::const_iterator i = _orMatchers.begin();
+ i != _orMatchers.end(); ++i ) {
+ if( details ) {
+ // just to be safe - may not be strictly necessary.
+ details->reset();
+ }
+ if ( (*i)->matches( jsobj, details ) ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
// check normal non-regex cases:
for ( unsigned i = 0; i < basics.size(); i++ ) {
ElementMatcher& bm = basics[i];
diff --git a/db/matcher.h b/db/matcher.h
index 6e2cad7233e..7eac2e97da7 100644
--- a/db/matcher.h
+++ b/db/matcher.h
@@ -181,6 +181,7 @@ namespace mongo {
// so we delete the mem when we're done:
vector< shared_ptr< BSONObjBuilder > > _builders;
+ vector< shared_ptr< Matcher > > _orMatchers;
friend class CoveredIndexMatcher;
};
diff --git a/mongo.xcodeproj/project.pbxproj b/mongo.xcodeproj/project.pbxproj
index f0042da60be..05913868189 100644
--- a/mongo.xcodeproj/project.pbxproj
+++ b/mongo.xcodeproj/project.pbxproj
@@ -538,6 +538,7 @@
93E5B88F10D7FF890044F9E4 /* v8_wrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = v8_wrapper.h; sourceTree = "<group>"; };
93E727090F4B5B5B004F9B5D /* shardkey.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = shardkey.cpp; sourceTree = "<group>"; };
93E7270A0F4B5B5B004F9B5D /* shardkey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shardkey.h; sourceTree = "<group>"; };
+ 93E8A4381173E6480025F7F8 /* or1.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = or1.js; sourceTree = "<group>"; };
93F0957010E165E50053380C /* basic.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = basic.js; sourceTree = "<group>"; };
93F095CC10E16FF70053380C /* shellfork.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = shellfork.js; sourceTree = "<group>"; };
C6859E8B029090EE04C91782 /* mongo.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = mongo.1; sourceTree = "<group>"; };
@@ -779,6 +780,7 @@
934BEB9A10DFFA9600178102 /* jstests */ = {
isa = PBXGroup;
children = (
+ 93E8A4381173E6480025F7F8 /* or1.js */,
930750A8114EFB9900272A70 /* update_addToSet.js */,
930750A9114EFB9900272A70 /* update_arraymatch1.js */,
930750AA114EFB9900272A70 /* update_arraymatch2.js */,