diff options
Diffstat (limited to 'src/mongo/db/pipeline/expression_test.cpp')
-rw-r--r-- | src/mongo/db/pipeline/expression_test.cpp | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/src/mongo/db/pipeline/expression_test.cpp b/src/mongo/db/pipeline/expression_test.cpp index e18d7d2f5cf..fe1ccb49ec0 100644 --- a/src/mongo/db/pipeline/expression_test.cpp +++ b/src/mongo/db/pipeline/expression_test.cpp @@ -5797,4 +5797,37 @@ public: SuiteInstance<All> myall; +TEST(ExpressionSubtractTest, OverflowLong) { + const auto maxLong = std::numeric_limits<long long int>::max(); + const auto minLong = std::numeric_limits<long long int>::min(); + intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); + + // The following subtractions should not fit into a long long data type. + BSONObj obj = BSON("$subtract" << BSON_ARRAY(maxLong << minLong)); + auto expression = Expression::parseExpression(expCtx, obj, expCtx->variablesParseState); + Value result = expression->evaluate({}, &expCtx->variables); + ASSERT_EQ(result.getType(), BSONType::NumberDouble); + ASSERT_EQ(result.getDouble(), static_cast<double>(maxLong) - minLong); + + obj = BSON("$subtract" << BSON_ARRAY(minLong << maxLong)); + expression = Expression::parseExpression(expCtx, obj, expCtx->variablesParseState); + result = expression->evaluate({}, &expCtx->variables); + ASSERT_EQ(result.getType(), BSONType::NumberDouble); + ASSERT_EQ(result.getDouble(), static_cast<double>(minLong) - maxLong); + + // minLong = -1 - maxLong. The below subtraction should fit into long long data type. + obj = BSON("$subtract" << BSON_ARRAY(-1 << maxLong)); + expression = Expression::parseExpression(expCtx, obj, expCtx->variablesParseState); + result = expression->evaluate({}, &expCtx->variables); + ASSERT_EQ(result.getType(), BSONType::NumberLong); + ASSERT_EQ(result.getLong(), -1LL - maxLong); + + // The minLong's negation does not fit into long long, hence it should be converted to double + // data type. + obj = BSON("$subtract" << BSON_ARRAY(0 << minLong)); + expression = Expression::parseExpression(expCtx, obj, expCtx->variablesParseState); + result = expression->evaluate({}, &expCtx->variables); + ASSERT_EQ(result.getType(), BSONType::NumberDouble); + ASSERT_EQ(result.getDouble(), static_cast<double>(minLong) * -1); +} } // namespace ExpressionTests |