From 61619b3142c1de8f60f91964ff2656054d4f11a6 Mon Sep 17 00:00:00 2001 From: Antonin Kral Date: Thu, 10 May 2012 06:57:54 +0200 Subject: Imported Upstream version 2.0.5 --- db/ops/update.cpp | 28 ++++++++++++++++++++++------ db/ops/update.h | 3 +++ 2 files changed, 25 insertions(+), 6 deletions(-) (limited to 'db/ops') 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 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; } diff --git a/db/ops/update.h b/db/ops/update.h index de5805a..73e4437 100644 --- a/db/ops/update.h +++ b/db/ops/update.h @@ -623,6 +623,9 @@ namespace mongo { } + /** @return true iff the elements aren't eoo(), are distinct, and share a field name. */ + static bool duplicateFieldName( const BSONElement &a, const BSONElement &b ); + public: bool canApplyInPlace() const { -- cgit v1.2.3