Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

fix EmbeddedBuilder where field names are same length but different S…

…ERVER-367
  • Loading branch information...
commit 55ada812dd87b7bfde54499b9755919e930b9add 1 parent 117a9b6
@erh erh authored
Showing with 42 additions and 13 deletions.
  1. +31 −13 db/query.cpp
  2. +11 −0 jstests/set3.js
View
44 db/query.cpp
@@ -174,14 +174,17 @@ namespace mongo {
class EmbeddedBuilder {
public:
EmbeddedBuilder( BSONObjBuilder *b ) {
- builders_.push_back( make_pair( "", b ) );
+ _builders.push_back( make_pair( "", b ) );
}
// It is assumed that the calls to prepareContext will be made with the 'name'
// parameter in lex ascending order.
void prepareContext( string &name ) {
- int i = 1, n = builders_.size();
- while( i < n && name.substr( 0, builders_[ i ].first.length() ) == builders_[ i ].first ) {
- name = name.substr( builders_[ i ].first.length() + 1 );
+ int i = 1, n = _builders.size();
+ while( i < n &&
+ name.substr( 0, _builders[ i ].first.length() ) == _builders[ i ].first &&
+ ( name[ _builders[i].first.length() ] == '.' || name[ _builders[i].first.length() ] == 0 )
+ ){
+ name = name.substr( _builders[ i ].first.length() + 1 );
++i;
}
for( int j = n - 1; j >= i; --j ) {
@@ -205,9 +208,10 @@ namespace mongo {
return back()->subarrayStart( name.c_str() );
}
void done() {
- while( !builderStorage_.empty() )
+ while( ! _builderStorage.empty() )
popBuilder();
}
+
static string splitDot( string & str ) {
size_t pos = str.find( '.' );
if ( pos == string::npos )
@@ -216,20 +220,24 @@ namespace mongo {
str = str.substr( pos + 1 );
return ret;
}
+
private:
void addBuilder( const string &name ) {
shared_ptr< BSONObjBuilder > newBuilder( new BSONObjBuilder( back()->subobjStart( name.c_str() ) ) );
- builders_.push_back( make_pair( name, newBuilder.get() ) );
- builderStorage_.push_back( newBuilder );
+ _builders.push_back( make_pair( name, newBuilder.get() ) );
+ _builderStorage.push_back( newBuilder );
}
void popBuilder() {
back()->done();
- builders_.pop_back();
- builderStorage_.pop_back();
+ _builders.pop_back();
+ _builderStorage.pop_back();
}
- BSONObjBuilder *back() { return builders_.back().second; }
- vector< pair< string, BSONObjBuilder * > > builders_;
- vector< shared_ptr< BSONObjBuilder > > builderStorage_;
+
+ BSONObjBuilder *back() { return _builders.back().second; }
+
+ vector< pair< string, BSONObjBuilder * > > _builders;
+ vector< shared_ptr< BSONObjBuilder > > _builderStorage;
+
};
/* Used for modifiers such as $inc, $set, ... */
@@ -521,7 +529,17 @@ namespace mongo {
vector< Mod >::iterator m = mods_.begin();
map< string, BSONElement >::iterator p = existing.begin();
while( m != mods_.end() || p != existing.end() ) {
- int cmp = compare( m, p, existing.end() );
+
+ if ( m == mods_.end() ){
+ // no more mods, just regular elements
+ assert( p != existing.end() );
+ if ( mayAddEmbedded( existing, p->first ) )
+ b2.appendAs( p->second, p->first );
+ p++;
+ continue;
+ }
+
+ FieldCompareResult cmp = compare( m, p, existing.end() );
if ( cmp <= 0 )
uassert( "Modifier spec implies existence of an encapsulating object with a name that already represents a non-object,"
" or is referenced in another $set clause",
View
11 jstests/set3.js
@@ -0,0 +1,11 @@
+
+t = db.set3;
+t.drop();
+
+t.insert( { "test1" : { "test2" : { "abcdefghijklmnopqrstu" : {"id":1} } } } );
+t.update( {}, {"$set":{"test1.test2.abcdefghijklmnopqrstuvwxyz":{"id":2}}})
+
+x = t.findOne();
+assert.eq( 1 , x.test1.test2.abcdefghijklmnopqrstu.id , "A" );
+assert.eq( 2 , x.test1.test2.abcdefghijklmnopqrstuvwxyz.id , "B" );
+
Please sign in to comment.
Something went wrong with that request. Please try again.