diff options
author | Antonin Kral <a.kral@bobek.cz> | 2012-05-10 06:57:57 +0200 |
---|---|---|
committer | Antonin Kral <a.kral@bobek.cz> | 2012-05-10 06:57:57 +0200 |
commit | 8813daaab256108f7aa6300875e8562d031f2c2f (patch) | |
tree | 06daade9022f76b2775d23f4613817365a2ded99 /db/ops/update.cpp | |
parent | d72a59184a3d51b17b30ed20fe656421bd4d2248 (diff) | |
parent | 61619b3142c1de8f60f91964ff2656054d4f11a6 (diff) | |
download | mongodb-8813daaab256108f7aa6300875e8562d031f2c2f.tar.gz |
Merge tag 'upstream/2.0.5'
Upstream version 2.0.5
Diffstat (limited to 'db/ops/update.cpp')
-rw-r--r-- | db/ops/update.cpp | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/db/ops/update.cpp b/db/ops/update.cpp index 6a7aad4..4fb8750 100644 --- a/db/ops/update.cpp +++ b/db/ops/update.cpp @@ -642,6 +642,14 @@ namespace mongo { } + bool ModSetState::duplicateFieldName( const BSONElement &a, const BSONElement &b ) { + return + !a.eoo() && + !b.eoo() && + ( a.rawdata() != b.rawdata() ) && + ( a.fieldName() == string( b.fieldName() ) ); + } + template< class Builder > void ModSetState::createNewFromMods( const string& root , Builder& b , const BSONObj &obj ) { DEBUGUPDATE( "\t\t createNewFromMods root: " << root ); @@ -654,8 +662,18 @@ namespace mongo { ModStateHolder::iterator mend = _mods.lower_bound( buf.str() ); set<string> onedownseen; - + BSONElement prevE; while ( e.type() && m != mend ) { + + if ( duplicateFieldName( prevE, e ) ) { + // Just copy through an element with a duplicate field name. + b.append( e ); + prevE = e; + e = es.next(); + continue; + } + prevE = e; + string field = root + e.fieldName(); FieldCompareResult cmp = compareDottedFieldNames( m->second.m->fieldName , field ); @@ -684,11 +702,9 @@ namespace mongo { m++; } else { - // this is a very weird case - // have seen it in production, but can't reproduce - // this assert prevents an inf. loop - // but likely isn't the correct solution - assert(0); + massert( 16062 , "ModSet::createNewFromMods - " + "SERVER-4777 unhandled duplicate field" , 0 ); + } continue; } |