|
Observed behavior: If one of the arguments to $mod is a double, the left argument is cast to an int (not a long long) before the modulus is calculated. This can result in a loss of information in the left operand before the modulus is calculated.
Expected behavior: Casting to an int does not occur in this case because it can alter the $mod result due to data loss.
c = db.c;
|
c.drop();
|
|
c.save( {} );
|
|
// The correct mod is calculated.
|
assert.eq( 1, c.aggregate( { $project:{ z:{ $mod:[ NumberLong('4294967296'), NumberLong( 3 ) ] } } } ).re\
|
sult[ 0 ].z );
|
|
// An incorrect mod is calculated due to a lossy integer conversion in ExpressionMod::evaluate.
|
assert.eq( 1, c.aggregate( { $project:{ z:{ $mod:[ NumberLong('4294967296'), 3.0 ] } } } ).result[ 0 ].z \
|
);
|
|