Permalink
Browse files

SERVER-6909 fix case where update can modify document such that query…

… doesn't work anymore
  • Loading branch information...
1 parent 853db71 commit 414a7dc114f34a341c8b4907a4e24760b449e724 @erh erh committed with monkey101 Sep 18, 2012
Showing with 36 additions and 5 deletions.
  1. +21 −0 jstests/find_and_modify_server6909.js
  2. +15 −5 src/mongo/db/commands/find_and_modify.cpp
@@ -0,0 +1,21 @@
+c = db.find_and_modify_server6906;
+
+
+c.drop();
+
+c.insert( { _id : 5 , a:{ b:1 } } );
+ret = c.findAndModify( { query:{ 'a.b':1 },
+ update:{ $set:{ 'a.b':2 } }, // Ensure the query on 'a.b' no longer matches.
+ new:true } );
+assert.eq( 5, ret._id );
+assert.eq( 2, ret.a.b );
+
+
+c.drop();
+
+c.insert( { _id : null , a:{ b:1 } } );
+ret = c.findAndModify( { query:{ 'a.b':1 },
+ update:{ $set:{ 'a.b':2 } }, // Ensure the query on 'a.b' no longer matches.
+ new:true } );
+assert.eq( 2, ret.a.b );
+
@@ -78,7 +78,7 @@ namespace mongo {
return runNoDirectClient( ns ,
query , fields , update ,
upsert , returnNew , remove ,
- result );
+ result , errmsg );
}
catch ( PageFaultException& e ) {
e.touch();
@@ -108,7 +108,7 @@ namespace mongo {
bool runNoDirectClient( const string& ns ,
const BSONObj& queryOriginal , const BSONObj& fields , const BSONObj& update ,
bool upsert , bool returnNew , bool remove ,
- BSONObjBuilder& result ) {
+ BSONObjBuilder& result , string& errmsg ) {
Lock::DBWrite lk( ns );
@@ -177,11 +177,21 @@ namespace mongo {
UpdateResult res = updateObjects( ns.c_str() , update , queryModified , upsert , false , true , cc().curop()->debug() );
if ( returnNew ) {
- if ( ! res.existing && res.upserted.isSet() ) {
+ if ( res.upserted.isSet() ) {
queryModified = BSON( "_id" << res.upserted );
}
- log() << "queryModified: " << queryModified << endl;
- verify( Helpers::findOne( ns.c_str() , queryModified , doc ) );
+ else if ( queryModified["_id"].type() ) {
+ // we do this so that if the update changes the fields, it still matches
+ queryModified = queryModified["_id"].wrap();
+ }
+ if ( ! Helpers::findOne( ns.c_str() , queryModified , doc ) ) {
+ errmsg = str::stream() << "can't find object after modification "
+ << " ns: " << ns
+ << " queryModified: " << queryModified
+ << " queryOriginal: " << queryOriginal;
+ log() << errmsg << endl;
+ return false;
+ }
_appendHelper( result , doc , true , fields );
}

0 comments on commit 414a7dc

Please sign in to comment.