0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00

fix $inc with doubles

This commit is contained in:
Eliot Horowitz 2010-01-26 11:54:45 -05:00
parent c86eda25ac
commit 47b67b74b4
3 changed files with 39 additions and 10 deletions

View File

@ -266,7 +266,13 @@ namespace mongo {
switch( m.op ) {
case Mod::INC:
uassert( 10140 , "Cannot apply $inc modifier to non-number", e.isNumber() || e.eoo() );
mss->amIInPlacePossible( e.isNumber() );
if ( mss->amIInPlacePossible( e.isNumber() ) ){
// check more typing info here
if ( m.elt.type() != e.type() ){
// if i'm incrememnting with a double, then the storage has to be a double
mss->amIInPlacePossible( m.elt.type() != NumberDouble );
}
}
break;
case Mod::SET:
mss->amIInPlacePossible( m.elt.type() == e.type() &&

View File

@ -26,7 +26,10 @@ namespace mongo {
class ModState;
class ModSetState;
/* Used for modifiers such as $inc, $set, $push, ... */
/* Used for modifiers such as $inc, $set, $push, ...
* stores the info about a single operation
* once created should never be modified
*/
struct Mod {
// See opFromStr below
// 0 1 2 3 4 5 6 7 8 9 10
@ -58,22 +61,25 @@ namespace mongo {
}
/**
* increments in
* @param in incrememnts the actual value inside in
*/
void incrementMe( BSONElement& in ) const {
BSONElementManipulator manip( in );
BSONType a = in.type();
BSONType b = elt.type();
if ( a == NumberDouble || b == NumberDouble ){
switch ( in.type() ){
case NumberDouble:
manip.setNumber( elt.numberDouble() + in.numberDouble() );
}
else if ( a == NumberLong || b == NumberLong ){
break;
case NumberLong:
manip.setLong( elt.numberLong() + in.numberLong() );
}
else {
break;
case NumberInt:
manip.setInt( elt.numberInt() + in.numberInt() );
break;
default:
assert(0);
}
}
void appendIncremented( BSONObjBuilder& bb , const BSONElement& in, ModState& ms ) const;

View File

@ -662,6 +662,22 @@ namespace UpdateTests {
};
class inc2 : public SingleTest {
virtual BSONObj initial(){
return BSON( "_id" << 1 << "x" << 1 );
}
virtual BSONObj mod(){
return BSON( "$inc" << BSON( "x" << 2.5 ) );
}
virtual BSONObj after(){
return BSON( "_id" << 1 << "x" << 3.5 );
}
virtual const char * ns(){
return "unittests.inc2";
}
};
class bit1 : public Base {
const char * ns(){
return "unittests.bit1";
@ -758,6 +774,7 @@ namespace UpdateTests {
add< ModSetTests::push1 >();
add< basic::inc1 >();
add< basic::inc2 >();
add< basic::bit1 >();
add< basic::unset >();
add< basic::setswitchint >();