--- mongo-git/db/update.h 2011-02-06 13:30:47.000000000 -0200 +++ mongo/db/update.h 2011-02-06 13:38:13.000000000 -0200 @@ -32,8 +32,8 @@ */ struct Mod { // See opFromStr below - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 - enum Op { INC, SET, PUSH, PUSH_ALL, PULL, PULL_ALL , POP, UNSET, BITAND, BITOR , BIT , ADDTOSET, RENAME_FROM, RENAME_TO } op; + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 + enum Op { INC, SET, PUSH, PUSH_ALL, PULL, PULL_ALL , POP, UNSET, BITAND, BITOR , BIT , ADDTOSET, RENAME_FROM, RENAME_TO, MULTIPLY } op; static const char* modNames[]; static unsigned modNamesNum; @@ -108,6 +108,8 @@ template< class Builder > void appendIncremented( Builder& bb , const BSONElement& in, ModState& ms ) const; + template< class Builder > + void appendMultiplied( Builder& bb , const BSONElement& in, ModState& ms ) const; bool operator<( const Mod &other ) const { return strcmp( fieldName, other.fieldName ) < 0; @@ -339,6 +341,10 @@ } break; } + case 'm': { + if ( fn[2] == 'u' && fn[3] == 'l' && fn[4] == 't' && fn[5] == 'i' && fn[6] == 'p' && fn[7] == 'l' && fn[8] == 'y') + return Mod::MULTIPLY; + } default: break; } uassert( 10161 , "Invalid modifier specified " + string( fn ), false ); --- mongo-git/db/update.cpp 2011-02-06 13:30:47.000000000 -0200 +++ mongo/db/update.cpp 2011-02-06 13:34:08.000000000 -0200 @@ -84,6 +84,27 @@ } template< class Builder > + void Mod::appendMultiplied( Builder& bb , const BSONElement& in, ModState& ms ) const { + BSONType a = in.type(); + BSONType b = elt.type(); + + if ( a == NumberDouble || b == NumberDouble ){ + ms.incType = NumberDouble; + ms.incdouble = elt.numberDouble() * in.numberDouble(); + } + else if ( a == NumberLong || b == NumberLong ){ + ms.incType = NumberLong; + ms.inclong = elt.numberLong() * in.numberLong(); + } + else { + ms.incType = NumberInt; + ms.incint = elt.numberInt() * in.numberInt(); + } + + ms.appendIncValue( bb , false ); + } + + template< class Builder > void appendUnset( Builder &b ) { } @@ -331,6 +352,11 @@ break; } + case MULTIPLY: { + appendMultiplied( b , in , ms ); + break; + } + default: stringstream ss; ss << "Mod::apply can't handle type: " << op;