Permalink
Browse files

SERVER-6993 - fix findAndModify positional operator regression with u…

…ndotted query fields
  • Loading branch information...
1 parent b62e772 commit 4cfe47b8c3c529df5cca132a007ad7d2d5b3ba29 @erh erh committed Sep 19, 2012
Showing with 34 additions and 1 deletion.
  1. +9 −0 jstests/find_and_modify_server6993.js
  2. +25 −1 src/mongo/db/commands/find_and_modify.cpp
View
9 jstests/find_and_modify_server6993.js
@@ -0,0 +1,9 @@
+
+c = db.find_and_modify_server6993;
+c.drop();
+
+c.insert( { a:[ 1, 2 ] } );
+
+c.findAndModify( { query:{ a:1 }, update:{ $set:{ 'a.$':5 } } } );
+
+assert.eq( 5, c.findOne().a[ 0 ] );
View
26 src/mongo/db/commands/find_and_modify.cpp
@@ -123,6 +123,30 @@ namespace mongo {
// we're going to re-write the query to be more efficient
// we have to be a little careful because of positional operators
// maybe we can pass this all through eventually, but right now isn't an easy way
+
+ bool hasPositionalUpdate = false;
+ {
+ // if the update has a positional piece ($)
+ // then we need to pull all query parts in
+ // so here we check for $
+ // a little hacky
+ BSONObjIterator i( update );
+ while ( i.more() ) {
+ const BSONElement& elem = i.next();
+
+ if ( elem.fieldName()[0] != '$' || elem.type() != Object )
+ continue;
+
+ BSONObjIterator j( elem.Obj() );
+ while ( j.more() ) {
+ if ( str::contains( j.next().fieldName(), ".$" ) ) {
+ hasPositionalUpdate = true;
+ break;
+ }
+ }
+ }
+ }
+
BSONObjBuilder b( queryOriginal.objsize() + 10 );
b.append( doc["_id"] );
@@ -137,7 +161,7 @@ namespace mongo {
continue;
}
- if ( ! str::contains( elem.fieldName() , '.' ) ) {
+ if ( ! hasPositionalUpdate ) {
// if there is a dotted field, accept we may need more query parts
continue;
}

0 comments on commit 4cfe47b

Please sign in to comment.