summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEliot Horowitz <eliot@10gen.com>2009-08-20 17:02:25 -0400
committerEliot Horowitz <eliot@10gen.com>2009-08-20 17:02:25 -0400
commit280d239455d8df6b29d4afb096a77bf57839378b (patch)
tree916c71fdf20a96917b1398900c30406981c940d7
parent7e0ffc751713b0b9358b975cbbc6ec12d41bf04b (diff)
parent792c9ea3f714c74b2fef567b0bc5a57579db0642 (diff)
downloadmongo-280d239455d8df6b29d4afb096a77bf57839378b.tar.gz
Merge branch 'master' of git@github.com:mongodb/mongo
-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
-rw-r--r--jstests/fm2.js9
-rw-r--r--jstests/mod1.js16
-rw-r--r--shell/dbshell.cpp4
8 files changed, 98 insertions, 42 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 ){
diff --git a/jstests/fm2.js b/jstests/fm2.js
new file mode 100644
index 00000000000..bee89300db3
--- /dev/null
+++ b/jstests/fm2.js
@@ -0,0 +1,9 @@
+
+t = db.fm2
+t.drop();
+
+t.insert( { "one" : { "two" : {"three":"four"} } } );
+
+x = t.find({},{"one.two":1})[0]
+assert.eq( 1 , x.one.keySet().length , "ks l 1" );
+
diff --git a/jstests/mod1.js b/jstests/mod1.js
new file mode 100644
index 00000000000..c77b5091e89
--- /dev/null
+++ b/jstests/mod1.js
@@ -0,0 +1,16 @@
+
+t = db.mod1;
+t.drop();
+
+t.save( { a : 1 } );
+t.save( { a : 2 } );
+t.save( { a : 11 } );
+
+assert.eq( 2 , t.find( "this.a % 10 == 1" ).itcount() , "A" );
+assert.eq( 2 , t.find( { a : { $mod : [ 10 , 1 ] } } ).itcount() , "B" );
+
+t.ensureIndex( { a : 1 } );
+
+assert.eq( 2 , t.find( "this.a % 10 == 1" ).itcount() , "C" );
+assert.eq( 2 , t.find( { a : { $mod : [ 10 , 1 ] } } ).itcount() , "D" );
+
diff --git a/shell/dbshell.cpp b/shell/dbshell.cpp
index f6208518d52..1f09709c278 100644
--- a/shell/dbshell.cpp
+++ b/shell/dbshell.cpp
@@ -301,7 +301,7 @@ int _main(int argc, char* argv[]) {
if ( line )
while ( line[0] == ' ' )
line++;
-
+
if ( ! line || ( strlen(line) == 4 && strstr( line , "exit" ) ) ){
cout << "bye" << endl;
break;
@@ -311,6 +311,8 @@ int _main(int argc, char* argv[]) {
if ( code == "exit" ){
break;
}
+ if ( code.size() == 0 )
+ continue;
bool wascmd = false;
{