diff options
Diffstat (limited to 'jstests/aggregation/bugs/server18427.js')
-rw-r--r-- | jstests/aggregation/bugs/server18427.js | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/jstests/aggregation/bugs/server18427.js b/jstests/aggregation/bugs/server18427.js index 35fcef8a4ac..25c34a83bb1 100644 --- a/jstests/aggregation/bugs/server18427.js +++ b/jstests/aggregation/bugs/server18427.js @@ -9,6 +9,9 @@ load('jstests/aggregation/extras/utils.js'); coll.drop(); assert.writeOK(coll.insert({_id: 0})); + var decimalE = NumberDecimal("2.718281828459045235360287471352662"); + var decimal1overE = NumberDecimal("0.3678794411714423215955237701614609"); + // Helper for testing that op returns expResult. function testOp(op, expResult) { var pipeline = [{$project: {_id: 0, result: op}}]; @@ -18,9 +21,15 @@ load('jstests/aggregation/extras/utils.js'); // $log, $log10, $ln. // Valid input: numeric/null/NaN, base positive and not equal to 1, arg positive. + // - NumberDouble testOp({$log: [10, 10]}, 1); testOp({$log10: [10]}, 1); testOp({$ln: [Math.E]}, 1); + // - NumberDecimal + testOp({$log: [NumberDecimal("10"), NumberDecimal("10")]}, NumberDecimal("1")); + testOp({$log10: [NumberDecimal("10")]}, NumberDecimal("1")); + // The below answer is actually correct: the input is an approximation of E + testOp({$ln: [decimalE]}, NumberDecimal("0.9999999999999999999999999999999998")); // All types converted to doubles. testOp({$log: [NumberLong("10"), NumberLong("10")]}, 1); testOp({$log10: [NumberLong("10")]}, 1); @@ -30,11 +39,15 @@ load('jstests/aggregation/extras/utils.js'); // Null inputs result in null. testOp({$log: [null, 10]}, null); testOp({$log: [10, null]}, null); + testOp({$log: [null, NumberDecimal(10)]}, null); + testOp({$log: [NumberDecimal(10), null]}, null); testOp({$log10: [null]}, null); testOp({$ln: [null]}, null); // NaN inputs result in NaN. testOp({$log: [NaN, 10]}, NaN); testOp({$log: [10, NaN]}, NaN); + testOp({$log: [NaN, NumberDecimal(10)]}, NaN); + testOp({$log: [NumberDecimal(10), NaN]}, NaN); testOp({$log10: [NaN]}, NaN); testOp({$ln: [NaN]}, NaN); @@ -50,13 +63,24 @@ load('jstests/aggregation/extras/utils.js'); assertErrorCode(coll, [{$project: {log: {$log: [5, 0]}}}], 28759); assertErrorCode(coll, [{$project: {log10: {$log10: [0]}}}], 28761); assertErrorCode(coll, [{$project: {ln: {$ln: [0]}}}], 28766); + assertErrorCode(coll, [{$project: {log: {$log: [NumberDecimal(0), NumberDecimal(5)]}}}], 28758); + assertErrorCode(coll, [{$project: {log: {$log: [NumberDecimal(5), NumberDecimal(0)]}}}], 28759); + assertErrorCode(coll, [{$project: {log10: {$log10: [NumberDecimal(0)]}}}], 28761); + assertErrorCode(coll, [{$project: {ln: {$ln: [NumberDecimal(0)]}}}], 28766); // Args/bases cannot be negative. assertErrorCode(coll, [{$project: {log: {$log: [-1, 5]}}}], 28758); assertErrorCode(coll, [{$project: {log: {$log: [5, -1]}}}], 28759); assertErrorCode(coll, [{$project: {log10: {$log10: [-1]}}}], 28761); assertErrorCode(coll, [{$project: {ln: {$ln: [-1]}}}], 28766); + assertErrorCode( + coll, [{$project: {log: {$log: [NumberDecimal(-1), NumberDecimal(5)]}}}], 28758); + assertErrorCode( + coll, [{$project: {log: {$log: [NumberDecimal(5), NumberDecimal(-1)]}}}], 28759); + assertErrorCode(coll, [{$project: {log10: {$log10: [NumberDecimal(-1)]}}}], 28761); + assertErrorCode(coll, [{$project: {ln: {$ln: [NumberDecimal(-1)]}}}], 28766); // Base can't equal 1. assertErrorCode(coll, [{$project: {log: {$log: [5, 1]}}}], 28759); + assertErrorCode(coll, [{$project: {log: {$log: [NumberDecimal(5), NumberDecimal(1)]}}}], 28759); // $pow, $exp. @@ -68,6 +92,18 @@ load('jstests/aggregation/extras/utils.js'); testOp({$pow: [-2, 2]}, 4); testOp({$pow: [NumberInt("2"), 2]}, 4); testOp({$pow: [-2, NumberInt("2")]}, 4); + // $pow -- if either input is a NumberDecimal, return a NumberDecimal + testOp({$pow: [NumberDecimal("10.0"), -2]}, + NumberDecimal("0.01000000000000000000000000000000000")); + testOp({$pow: [0.5, NumberDecimal("-1")]}, + NumberDecimal("2.000000000000000000000000000000000")); + testOp({$pow: [-2, NumberDecimal("2")]}, NumberDecimal("4.000000000000000000000000000000000")); + testOp({$pow: [NumberInt("2"), NumberDecimal("2")]}, + NumberDecimal("4.000000000000000000000000000000000")); + testOp({$pow: [NumberDecimal("-2.0"), NumberInt("2")]}, + NumberDecimal("4.000000000000000000000000000000000")); + testOp({$pow: [NumberDecimal("10.0"), 2]}, + NumberDecimal("100.0000000000000000000000000000000")); // If exponent is negative and base not -1, 0, or 1, return a double. testOp({$pow: [NumberLong("2"), NumberLong("-1")]}, 1 / 2); @@ -78,6 +114,9 @@ load('jstests/aggregation/extras/utils.js'); // If result would overflow a long, return a double. testOp({$pow: [NumberInt("2"), NumberLong("63")]}, 9223372036854776000); + // Exact decimal result + testOp({$pow: [NumberInt("5"), NumberDecimal("-112")]}, + NumberDecimal("5192296858534827628530496329220096E-112")); // Result would be incorrect if double were returned. testOp({$pow: [NumberInt("3"), NumberInt("35")]}, NumberLong("50031545098999707")); @@ -91,16 +130,23 @@ load('jstests/aggregation/extras/utils.js'); // Else return an int if it fits. testOp({$pow: [NumberInt("4"), NumberInt("2")]}, 16); - // $exp always returns doubles, since e is a double. + // $exp always returns doubles for non-zero non-decimal inputs, since e is a double. testOp({$exp: [NumberInt("-1")]}, 1 / Math.E); testOp({$exp: [NumberLong("1")]}, Math.E); + // $exp returns decimal results for decimal inputs + testOp({$exp: [NumberDecimal("-1")]}, decimal1overE); + testOp({$exp: [NumberDecimal("1")]}, decimalE); // Null input results in null. testOp({$pow: [null, 2]}, null); testOp({$pow: [1 / 2, null]}, null); + testOp({$pow: [null, NumberDecimal(2)]}, null); + testOp({$pow: [NumberDecimal("0.5"), null]}, null); testOp({$exp: [null]}, null); // NaN input results in NaN. testOp({$pow: [NaN, 2]}, NaN); testOp({$pow: [1 / 2, NaN]}, NaN); + testOp({$pow: [NaN, NumberDecimal(2)]}, NumberDecimal("NaN")); + testOp({$pow: [NumberDecimal("0.5"), NaN]}, NumberDecimal("NaN")); testOp({$exp: [NaN]}, NaN); // Invalid inputs - non-numeric/non-null types, or 0 to a negative exponent. @@ -108,4 +154,6 @@ load('jstests/aggregation/extras/utils.js'); assertErrorCode(coll, [{$project: {pow: {$pow: ["string", 5]}}}], 28762); assertErrorCode(coll, [{$project: {pow: {$pow: [5, "string"]}}}], 28763); assertErrorCode(coll, [{$project: {exp: {$exp: ["string"]}}}], 28765); + assertErrorCode(coll, [{$project: {pow: {$pow: [NumberDecimal(0), NumberLong("-1")]}}}], 28764); + assertErrorCode(coll, [{$project: {pow: {$pow: ["string", NumberDecimal(5)]}}}], 28762); }()); |