diff options
Diffstat (limited to 'db')
-rw-r--r-- | db/jsobj.cpp | 2 | ||||
-rw-r--r-- | db/jsobj.h | 1 | ||||
-rw-r--r-- | db/matcher.cpp | 14 | ||||
-rw-r--r-- | db/matcher.h | 13 | ||||
-rw-r--r-- | db/queryutil.cpp | 81 |
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 ){ |