summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEliot Horowitz <eliot@10gen.com>2010-03-22 13:37:56 -0400
committerEliot Horowitz <eliot@10gen.com>2010-03-22 13:37:56 -0400
commit4aea2b8ca54ac62f57fdb38897c56bf590ee315b (patch)
treebdbe3bdb65afc5c2567ace7243170530d80bc93b
parentfd7616631bbbd8317449b5e093890b326d026492 (diff)
downloadmongo-4aea2b8ca54ac62f57fdb38897c56bf590ee315b.tar.gz
fix a.0.x for regex SERVER-799
-rw-r--r--db/jsobj.cpp73
-rw-r--r--jstests/regex_embed1.js25
2 files changed, 73 insertions, 25 deletions
diff --git a/db/jsobj.cpp b/db/jsobj.cpp
index 938492cacc5..9f9a6840303 100644
--- a/db/jsobj.cpp
+++ b/db/jsobj.cpp
@@ -845,36 +845,59 @@ namespace mongo {
}
void BSONObj::getFieldsDotted(const char *name, BSONElementSet &ret ) const {
- BSONElement e = getField( name );
- if ( e.eoo() ) {
- const char *p = strchr(name, '.');
- if ( p ) {
- string left(name, p-name);
- BSONElement e = getField( left );
- if ( e.type() == Array ) {
- BSONObjIterator i( e.embeddedObject() );
- while( i.moreWithEOO() ) {
- BSONElement f = i.next();
- if ( f.eoo() )
- break;
+ BSONObjIterator i(*this);
+ while ( i.more() ){
+ BSONElement e = i.next();
+ FieldCompareResult cmp = compareDottedFieldNames( name , e.fieldName() );
+ switch ( cmp ){
+
+ case LEFT_BEFORE:
+ case RIGHT_BEFORE:
+ break;
+
+ case RIGHT_SUBFIELD:
+ assert(0);
+ break;
+
+ case LEFT_SUBFIELD: {
+ const char * next = name + strlen( e.fieldName() ) + 1;
+ bool allDigits = false;
+ if ( isdigit( *next ) ){
+ const char * temp = next + 1;
+ while ( isdigit( *temp ) )
+ temp++;
+ allDigits = *temp == '.';
+ }
+
+ if ( e.type() == Object || allDigits ){
+ e.embeddedObject().getFieldsDotted( next , ret );
+ }
+ else if ( e.type() == Array ){
+ BSONObjIterator j( e.embeddedObject() );
+ while ( j.more() ){
+ BSONElement f = j.next();
if ( f.type() == Object )
- f.embeddedObject().getFieldsDotted(p+1, ret);
+ f.embeddedObject().getFieldsDotted( next , ret );
}
- } else if ( e.type() == Object ) {
- e.embeddedObject().getFieldsDotted(p+1, ret);
}
+ else {
+ // intentially left blank, this means no match
+ }
+ return;
}
- } else {
- if ( e.type() == Array ) {
- BSONObjIterator i( e.embeddedObject() );
- while( i.moreWithEOO() ) {
- BSONElement f = i.next();
- if ( f.eoo() )
- break;
- ret.insert( f );
+
+ case SAME: {
+ if ( e.type() == Array ){
+ BSONObjIterator j( e.embeddedObject() );
+ while ( j.more() )
+ ret.insert( j.next() );
}
- } else {
- ret.insert( e );
+ else {
+ ret.insert( e );
+ }
+ return;
+ }
+
}
}
}
diff --git a/jstests/regex_embed1.js b/jstests/regex_embed1.js
new file mode 100644
index 00000000000..61b1b9a14f6
--- /dev/null
+++ b/jstests/regex_embed1.js
@@ -0,0 +1,25 @@
+
+t = db.regex_embed1
+
+t.drop()
+
+t.insert( { _id : 1 , a : [ { x : "abc" } , { x : "def" } ] } )
+t.insert( { _id : 2 , a : [ { x : "ab" } , { x : "de" } ] } )
+t.insert( { _id : 3 , a : [ { x : "ab" } , { x : "de" } , { x : "abc" } ] } )
+
+function test( m ){
+ assert.eq( 3 , t.find().itcount() , m + "1" );
+ assert.eq( 2 , t.find( { "a.x" : "abc" } ).itcount() , m + "2" );
+ assert.eq( 2 , t.find( { "a.x" : /.*abc.*/ } ).itcount() , m + "3" );
+
+ assert.eq( 1 , t.find( { "a.0.x" : "abc" } ).itcount() , m + "4" );
+ assert.eq( 1 , t.find( { "a.0.x" : /abc/ } ).itcount() , m + "5" );
+}
+
+test( "A" );
+
+t.ensureIndex( { "a.x" : 1 } )
+test( "B" );
+
+
+