-
Type: Bug
-
Resolution: Done
-
Priority: Major - P3
-
None
-
Affects Version/s: None
-
Component/s: Aggregation Framework
-
Labels:
-
Query
-
ALL
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 }