summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron <aaron@10gen.com>2009-05-22 10:46:33 -0400
committerAaron <aaron@10gen.com>2009-05-22 10:46:33 -0400
commitd8e129c8ab3844903cd19ae565ab32faf0aadd59 (patch)
tree676d7d70b53a0a1957f1fc0a03bd955e4b54be5b
parent80502a3fdb0ea4127b1b04a468bbe23dbb1484aa (diff)
downloadmongo-d8e129c8ab3844903cd19ae565ab32faf0aadd59.tar.gz
BUG SERVER-67 correctly handle insertion of new null element with $set
-rw-r--r--db/jsobjmanipulator.h1
-rw-r--r--db/query.cpp32
-rw-r--r--dbtests/updatetests.cpp10
3 files changed, 29 insertions, 14 deletions
diff --git a/db/jsobjmanipulator.h b/db/jsobjmanipulator.h
index 9412e9aec33..0a7e0314c17 100644
--- a/db/jsobjmanipulator.h
+++ b/db/jsobjmanipulator.h
@@ -29,6 +29,7 @@ class BSONElementManipulator {
public:
BSONElementManipulator( const BSONElement &element ) :
element_( element ) {
+ assert( !element_.eoo() );
}
/** Replace a Timestamp type with a Date type initialized to
OpTime::now().asDate()
diff --git a/db/query.cpp b/db/query.cpp
index 1547bd64c8d..3677b477585 100644
--- a/db/query.cpp
+++ b/db/query.cpp
@@ -355,21 +355,25 @@ namespace mongo {
for ( vector<Mod>::const_iterator i = mods_.begin(); i != mods_.end(); ++i ) {
const Mod& m = *i;
BSONElement e = obj.getFieldDotted(m.fieldName);
- switch( m.op ) {
- case Mod::INC:
- uassert( "Cannot apply $inc modifier to non-number", e.isNumber() || e.eoo() );
- if ( !e.isNumber() )
- inPlacePossible = false;
- break;
- case Mod::SET:
- if ( !( e.isNumber() && m.elt.isNumber() ) &&
- m.elt.valuesize() != e.valuesize() )
+ if ( e.eoo() ) {
+ inPlacePossible = false;
+ } else {
+ switch( m.op ) {
+ case Mod::INC:
+ uassert( "Cannot apply $inc modifier to non-number", e.isNumber() || e.eoo() );
+ if ( !e.isNumber() )
+ inPlacePossible = false;
+ break;
+ case Mod::SET:
+ if ( !( e.isNumber() && m.elt.isNumber() ) &&
+ m.elt.valuesize() != e.valuesize() )
+ inPlacePossible = false;
+ break;
+ case Mod::PUSH:
+ uassert( "Cannot apply $push modifier to non-array", e.type() == Array || e.eoo() );
inPlacePossible = false;
- break;
- case Mod::PUSH:
- uassert( "Cannot apply $push modifier to non-array", e.type() == Array || e.eoo() );
- inPlacePossible = false;
- break;
+ break;
+ }
}
}
if ( !inPlacePossible ) {
diff --git a/dbtests/updatetests.cpp b/dbtests/updatetests.cpp
index 6c50b3b39d4..10beba793c0 100644
--- a/dbtests/updatetests.cpp
+++ b/dbtests/updatetests.cpp
@@ -456,6 +456,15 @@ namespace UpdateTests {
}
};
+ class UpdateMissingToNull : public SetBase {
+ public:
+ void run() {
+ client().insert( ns(), BSON( "a" << 5 ) );
+ client().update( ns(), BSON( "a" << 5 ), fromjson( "{$set:{b:null}}" ) );
+ ASSERT_EQUALS( jstNULL, client().findOne( ns(), QUERY( "a" << 5 ) ).getField( "b" ).type() );
+ }
+ };
+
class All : public Suite {
public:
All() {
@@ -503,6 +512,7 @@ namespace UpdateTests {
add< ModParentOfIndex >();
add< PreserveIdWithIndex >();
add< CheckNoMods >();
+ add< UpdateMissingToNull >();
}
};