Details
-
Bug
-
Resolution: Done
-
Major - P3
-
None
-
None
-
Query
-
ALL
Description
Observed behavior: The results of some additions may depend on whether the values come from a constant or a non constant expression.
Expected behavior: The result of an addition depends on values only.
Test:
c = db.c;
|
c.drop();
|
|
|
c.save( { a:0.0 } );
|
|
|
large = NumberLong('9223372036854775807'); |
|
|
// 1. Two large longs overflow.
|
printjson( c.aggregate( { $project:{ sum:{ $add:[ large, large ] } } } ) );
|
// 2. Two large longs are cast to doubles if they are summed with a double, and do not overflow.
|
printjson( c.aggregate( { $project:{ sum:{ $add:[ large, large, 0.0 ] } } } ) );
|
// 3. The constant folding implementation sums the first two operands, which overflow, then sums the overflow result with the value of '$a'.
|
printjson( c.aggregate( { $project:{ sum:{ $add:[ large, large, '$a' ] } } } ) ); |
Results:
// 1
|
{
|
"result" : [ |
{
|
"_id" : ObjectId("50121f8b8e4c36714e472e38"), |
"sum" : NumberLong(-2) |
}
|
],
|
"ok" : 1 |
}
|
// 2
|
{
|
"result" : [ |
{
|
"_id" : ObjectId("50121f8b8e4c36714e472e38"), |
"sum" : 18446744073709552000 |
}
|
],
|
"ok" : 1 |
}
|
// 3
|
{
|
"result" : [ |
{
|
"_id" : ObjectId("50121f8b8e4c36714e472e38"), |
"sum" : -2 |
}
|
],
|
"ok" : 1 |
}
|