summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEliot Horowitz <eliot@10gen.com>2012-09-18 20:26:54 -0400
committerDan Pasette <dan@10gen.com>2012-09-18 20:30:33 -0400
commit242597ae464698f8fc243ec869654cdc756dabb9 (patch)
treebf54ec813409a45ecee03122154a9f61b2edc8ab
parent7c3283a3031e72da3c1f48a00e17f37b7d78f9e3 (diff)
downloadmongo-242597ae464698f8fc243ec869654cdc756dabb9.tar.gz
SERVER-6993 - fix findAndModify positional operator regression with undotted query fields
-rw-r--r--jstests/find_and_modify_server6993.js9
-rw-r--r--src/mongo/db/commands/find_and_modify.cpp26
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;
}