summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlberto Lerner <alerner@10gen.com>2012-10-16 21:40:02 -0400
committerAlberto Lerner <alerner@10gen.com>2012-10-16 21:46:07 -0400
commit43294fd78b4374530c219771f076aa8f2118ea23 (patch)
tree6e56a5e3ce37d4389da1e5d28d06be6d52f39bde
parentc26d366ca17b120f3bf3c538a44815d2a7acbf61 (diff)
downloadmongo-43294fd78b4374530c219771f076aa8f2118ea23.tar.gz
SERVER-7371 Fix same corner case as the last one, but now when applied to secondary.
-rw-r--r--src/mongo/db/ops/update_internal.cpp13
-rw-r--r--src/mongo/dbtests/repltests.cpp18
2 files changed, 30 insertions, 1 deletions
diff --git a/src/mongo/db/ops/update_internal.cpp b/src/mongo/db/ops/update_internal.cpp
index a56ab070ff5..c7448a04525 100644
--- a/src/mongo/db/ops/update_internal.cpp
+++ b/src/mongo/db/ops/update_internal.cpp
@@ -812,9 +812,20 @@ namespace mongo {
<< " not: " << e.type() );
}
else {
- // skip both as we're not applying this mod
+ // Since we're not applying the mod, we keep what was there before
+ builder.append( e );
+
+ // Skip both as we're not applying this mod. Note that we'll advance
+ // the iterator on the mod side for all the mods that are under the
+ // root we are now.
e = es.next();
m++;
+ while ( m != mend &&
+ ( compareDottedFieldNames( m->second->m->fieldName,
+ field,
+ lexNumCmp ) == LEFT_SUBFIELD ) ) {
+ m++;
+ }
continue;
}
}
diff --git a/src/mongo/dbtests/repltests.cpp b/src/mongo/dbtests/repltests.cpp
index aa4721bbdf4..754556ae540 100644
--- a/src/mongo/dbtests/repltests.cpp
+++ b/src/mongo/dbtests/repltests.cpp
@@ -1142,6 +1142,23 @@ namespace ReplTests {
}
};
+ class ReplayArrayFieldNotAppended : public Base {
+ public:
+ void doIt() const {
+ client()->update( ns(), BSONObj(), fromjson( "{$push:{'a.0.b':2}}" ) );
+ client()->update( ns(), BSONObj(), fromjson( "{$set:{'a.0':1}}") );
+ }
+ using ReplTests::Base::check;
+ void check() const {
+ ASSERT_EQUALS( 1, count() );
+ check( fromjson( "{_id:0,a:[1,{b:[1]}]}" ), one(fromjson("{'_id':0}") ) );
+ }
+ void reset() const {
+ deleteAll( ns() );
+ insert( fromjson( "{'_id':0,a:[{b:[0]},{b:[1]}]}" ) );
+ }
+ };
+
} // namespace Idempotence
class DeleteOpIsIdBased : public Base {
@@ -1369,6 +1386,7 @@ namespace ReplTests {
add< Idempotence::AddToSetEmptyMissing >();
add< Idempotence::AddToSetWithDollarSigns >();
add< Idempotence::ReplaySetPreexistingNoOpPull >();
+ add< Idempotence::ReplayArrayFieldNotAppended >();
add< DeleteOpIsIdBased >();
add< DatabaseIgnorerBasic >();
add< DatabaseIgnorerUpdate >();