Skip to content

Commit e398691

Browse files
committed
SERVER-6909 fix case where update can modify document such that query doesn't work anymore
1 parent aaf69ad commit e398691

File tree

2 files changed

+36
-5
lines changed

2 files changed

+36
-5
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
c = db.find_and_modify_server6906;
2+
3+
4+
c.drop();
5+
6+
c.insert( { _id : 5 , a:{ b:1 } } );
7+
ret = c.findAndModify( { query:{ 'a.b':1 },
8+
update:{ $set:{ 'a.b':2 } }, // Ensure the query on 'a.b' no longer matches.
9+
new:true } );
10+
assert.eq( 5, ret._id );
11+
assert.eq( 2, ret.a.b );
12+
13+
14+
c.drop();
15+
16+
c.insert( { _id : null , a:{ b:1 } } );
17+
ret = c.findAndModify( { query:{ 'a.b':1 },
18+
update:{ $set:{ 'a.b':2 } }, // Ensure the query on 'a.b' no longer matches.
19+
new:true } );
20+
assert.eq( 2, ret.a.b );
21+

src/mongo/db/commands/find_and_modify.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ namespace mongo {
7878
return runNoDirectClient( ns ,
7979
query , fields , update ,
8080
upsert , returnNew , remove ,
81-
result );
81+
result , errmsg );
8282
}
8383
catch ( PageFaultException& e ) {
8484
e.touch();
@@ -108,7 +108,7 @@ namespace mongo {
108108
bool runNoDirectClient( const string& ns ,
109109
const BSONObj& queryOriginal , const BSONObj& fields , const BSONObj& update ,
110110
bool upsert , bool returnNew , bool remove ,
111-
BSONObjBuilder& result ) {
111+
BSONObjBuilder& result , string& errmsg ) {
112112

113113

114114
Lock::DBWrite lk( ns );
@@ -177,11 +177,21 @@ namespace mongo {
177177
UpdateResult res = updateObjects( ns.c_str() , update , queryModified , upsert , false , true , cc().curop()->debug() );
178178

179179
if ( returnNew ) {
180-
if ( ! res.existing && res.upserted.isSet() ) {
180+
if ( res.upserted.isSet() ) {
181181
queryModified = BSON( "_id" << res.upserted );
182182
}
183-
log() << "queryModified: " << queryModified << endl;
184-
verify( Helpers::findOne( ns.c_str() , queryModified , doc ) );
183+
else if ( queryModified["_id"].type() ) {
184+
// we do this so that if the update changes the fields, it still matches
185+
queryModified = queryModified["_id"].wrap();
186+
}
187+
if ( ! Helpers::findOne( ns.c_str() , queryModified , doc ) ) {
188+
errmsg = str::stream() << "can't find object after modification "
189+
<< " ns: " << ns
190+
<< " queryModified: " << queryModified
191+
<< " queryOriginal: " << queryOriginal;
192+
log() << errmsg << endl;
193+
return false;
194+
}
185195
_appendHelper( result , doc , true , fields );
186196
}
187197

0 commit comments

Comments
 (0)