diff options
author | Eliot Horowitz <eliot@10gen.com> | 2012-09-18 20:26:54 -0400 |
---|---|---|
committer | Dan Pasette <dan@10gen.com> | 2012-09-18 20:30:33 -0400 |
commit | 242597ae464698f8fc243ec869654cdc756dabb9 (patch) | |
tree | bf54ec813409a45ecee03122154a9f61b2edc8ab | |
parent | 7c3283a3031e72da3c1f48a00e17f37b7d78f9e3 (diff) | |
download | mongo-242597ae464698f8fc243ec869654cdc756dabb9.tar.gz |
SERVER-6993 - fix findAndModify positional operator regression with undotted query fields
-rw-r--r-- | jstests/find_and_modify_server6993.js | 9 | ||||
-rw-r--r-- | src/mongo/db/commands/find_and_modify.cpp | 26 |
2 files changed, 34 insertions, 1 deletions
diff --git a/jstests/find_and_modify_server6993.js b/jstests/find_and_modify_server6993.js new file mode 100644 index 00000000000..b8a31915372 --- /dev/null +++ b/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 ] ); diff --git a/src/mongo/db/commands/find_and_modify.cpp b/src/mongo/db/commands/find_and_modify.cpp index 900090a159c..0ad78239de2 100644 --- a/src/mongo/db/commands/find_and_modify.cpp +++ b/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; } |