summaryrefslogtreecommitdiff
path: root/db
diff options
context:
space:
mode:
Diffstat (limited to 'db')
-rw-r--r--db/jsobj.cpp2
-rw-r--r--db/jsobj.h1
-rw-r--r--db/matcher.cpp14
-rw-r--r--db/matcher.h13
-rw-r--r--db/queryutil.cpp81
5 files changed, 70 insertions, 41 deletions
diff --git a/db/jsobj.cpp b/db/jsobj.cpp
index bf44e9370cc..b872239310e 100644
--- a/db/jsobj.cpp
+++ b/db/jsobj.cpp
@@ -411,6 +411,8 @@ namespace mongo {
if ( fn[1] == 'n' && fn[3] == 0 )
return BSONObj::NE;
}
+ else if ( fn[1] == 'm' && fn[2] == 'o' && fn[3] == 'd' && fn[4] == 0 )
+ return BSONObj::opMOD;
else if ( fn[1] == 'i' && fn[2] == 'n' && fn[3] == 0 )
return BSONObj::opIN;
else if ( fn[1] == 'n' && fn[2] == 'i' && fn[3] == 'n' && fn[4] == 0 )
diff --git a/db/jsobj.h b/db/jsobj.h
index 9fd2a1b88ec..711c539a2a7 100644
--- a/db/jsobj.h
+++ b/db/jsobj.h
@@ -901,6 +901,7 @@ namespace mongo {
opALL = 0x0B,
NIN = 0x0C,
opEXISTS = 0x0D,
+ opMOD = 0x0E
};
};
ostream& operator<<( ostream &s, const BSONObj &o );
diff --git a/db/matcher.cpp b/db/matcher.cpp
index bc6792c7e67..fac352a1d60 100644
--- a/db/matcher.cpp
+++ b/db/matcher.cpp
@@ -246,6 +246,11 @@ namespace mongo {
basics.push_back( BasicMatcher( e , BSONObj::opIN , fe.embeddedObject() ) );
ok = true;
}
+ else if ( fn[1] == 'm' && fn[2] == 'o' && fn[3] == 'd' && fn[4] == 0 && fe.type() == Array ) {
+ // $mod
+ basics.push_back( BasicMatcher( e , BSONObj::opMOD ) );
+ ok = true;
+ }
else if ( fn[1] == 'n' && fn[2] == 'i' && fn[3] == 'n' && fn[4] == 0 && fe.type() == Array ) {
// $nin
basics.push_back( BasicMatcher( e , BSONObj::NIN , fe.embeddedObject() ) );
@@ -315,7 +320,14 @@ namespace mongo {
}
return count == r.number();
}
-
+
+ if ( op == BSONObj::opMOD ){
+ if ( ! l.isNumber() )
+ return false;
+
+ return l.numberLong() % bm.mod == bm.modm;
+ }
+
/* check LT, GTE, ... */
if ( !( l.isNumber() && r.isNumber() ) && ( l.type() != r.type() ) )
return false;
diff --git a/db/matcher.h b/db/matcher.h
index c814fe3c2cb..03b5b335845 100644
--- a/db/matcher.h
+++ b/db/matcher.h
@@ -57,9 +57,17 @@ namespace mongo {
}
BasicMatcher( BSONElement _e , int _op ) : toMatch( _e ) , compareOp( _op ){
+ if ( _op == BSONObj::opMOD ){
+ BSONObj o = _e.embeddedObject().firstElement().embeddedObject();
+ mod = o["0"].numberInt();
+ modm = o["1"].numberInt();
+
+ uassert( "mod can't be 0" , mod );
+ uassert( "mod eq can't be 0" , modm );
+ }
}
-
+
BasicMatcher( BSONElement _e , int _op , const BSONObj& array ) : toMatch( _e ) , compareOp( _op ){
myset.reset( new set<BSONElement,element_lt>() );
@@ -74,6 +82,9 @@ namespace mongo {
BSONElement toMatch;
int compareOp;
shared_ptr< set<BSONElement,element_lt> > myset;
+
+ int mod;
+ int modm;
};
// SQL where clause equivalent
diff --git a/db/queryutil.cpp b/db/queryutil.cpp
index 4a99736ddac..a4d44f9e965 100644
--- a/db/queryutil.cpp
+++ b/db/queryutil.cpp
@@ -23,7 +23,7 @@
#include "queryoptimizer.h"
namespace mongo {
-
+
FieldRange::FieldRange( const BSONElement &e, bool optimize ) {
lower() = minKey.firstElement();
lowerInclusive() = true;
@@ -41,49 +41,52 @@ namespace mongo {
return;
}
switch( e.getGtLtOp() ) {
- case BSONObj::Equality:
- lower() = e;
- upper() = e;
- break;
- case BSONObj::LT:
- upperInclusive() = false;
- case BSONObj::LTE:
- upper() = e;
- break;
- case BSONObj::GT:
- lowerInclusive() = false;
- case BSONObj::GTE:
- lower() = e;
- break;
+ case BSONObj::Equality:
+ lower() = e;
+ upper() = e;
+ break;
+ case BSONObj::LT:
+ upperInclusive() = false;
+ case BSONObj::LTE:
+ upper() = e;
+ break;
+ case BSONObj::GT:
+ lowerInclusive() = false;
+ case BSONObj::GTE:
+ lower() = e;
+ break;
case BSONObj::opALL: {
massert( "$all requires array", e.type() == Array );
- BSONObjIterator i( e.embeddedObject() );
- if ( i.moreWithEOO() ) {
- BSONElement f = i.next();
- if ( !f.eoo() )
- lower() = upper() = f;
- }
- break;
+ BSONObjIterator i( e.embeddedObject() );
+ if ( i.moreWithEOO() ) {
+ BSONElement f = i.next();
+ if ( !f.eoo() )
+ lower() = upper() = f;
+ }
+ break;
}
+ case BSONObj::opMOD: {
+ break;
+ }
case BSONObj::opIN: {
- massert( "$in requires array", e.type() == Array );
- BSONElement max = minKey.firstElement();
- BSONElement min = maxKey.firstElement();
- BSONObjIterator i( e.embeddedObject() );
- while( i.moreWithEOO() ) {
- BSONElement f = i.next();
- if ( f.eoo() )
- break;
- if ( max.woCompare( f, false ) < 0 )
- max = f;
- if ( min.woCompare( f, false ) > 0 )
- min = f;
- }
- lower() = min;
- upper() = max;
+ massert( "$in requires array", e.type() == Array );
+ BSONElement max = minKey.firstElement();
+ BSONElement min = maxKey.firstElement();
+ BSONObjIterator i( e.embeddedObject() );
+ while( i.moreWithEOO() ) {
+ BSONElement f = i.next();
+ if ( f.eoo() )
+ break;
+ if ( max.woCompare( f, false ) < 0 )
+ max = f;
+ if ( min.woCompare( f, false ) > 0 )
+ min = f;
}
- default:
- break;
+ lower() = min;
+ upper() = max;
+ }
+ default:
+ break;
}
if ( optimize ){