diff options
author | Eliot Horowitz <eliot@10gen.com> | 2010-03-22 13:37:56 -0400 |
---|---|---|
committer | Eliot Horowitz <eliot@10gen.com> | 2010-03-22 13:37:56 -0400 |
commit | 4aea2b8ca54ac62f57fdb38897c56bf590ee315b (patch) | |
tree | bdbe3bdb65afc5c2567ace7243170530d80bc93b | |
parent | fd7616631bbbd8317449b5e093890b326d026492 (diff) | |
download | mongo-4aea2b8ca54ac62f57fdb38897c56bf590ee315b.tar.gz |
fix a.0.x for regex SERVER-799
-rw-r--r-- | db/jsobj.cpp | 73 | ||||
-rw-r--r-- | jstests/regex_embed1.js | 25 |
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" ); + + + |