summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline/expression_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/pipeline/expression_test.cpp')
-rw-r--r--src/mongo/db/pipeline/expression_test.cpp112
1 files changed, 70 insertions, 42 deletions
diff --git a/src/mongo/db/pipeline/expression_test.cpp b/src/mongo/db/pipeline/expression_test.cpp
index 6dd4c4b9974..e579eece98c 100644
--- a/src/mongo/db/pipeline/expression_test.cpp
+++ b/src/mongo/db/pipeline/expression_test.cpp
@@ -40,6 +40,7 @@
#include "mongo/db/jsobj.h"
#include "mongo/db/json.h"
#include "mongo/db/pipeline/accumulator.h"
+#include "mongo/db/pipeline/accumulator_multi.h"
#include "mongo/db/pipeline/expression.h"
#include "mongo/db/pipeline/expression_context_for_test.h"
#include "mongo/db/query/collation/collator_interface_mock.h"
@@ -154,6 +155,22 @@ void assertExpectedArray(const BSONObj& spec, const BSONArray& expected) {
ASSERT_VALUE_EQ(result, Value(expected));
};
+/**
+ * Given 'parseFn', parses and evaluates 'spec' and verifies that the result is equal to
+ * 'expected'. Useful when the parser for an expression is unavailable in certain contexts (for
+ * instance, when evaluating an expression that's guarded by a feature flag that's off by default).
+ */
+void parseAndVerifyResults(
+ const std::function<boost::intrusive_ptr<Expression>(
+ ExpressionContext* const, BSONElement, const VariablesParseState&)>& parseFn,
+ const BSONElement& elem,
+ Value expected) {
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
+ auto expr = parseFn(&expCtx, elem, vps);
+ ASSERT_VALUE_EQ(expr->evaluate({}, &expCtx.variables), expected);
+}
+
/* ------------------------- ExpressionArrayToObject -------------------------- */
TEST(ExpressionArrayToObjectTest, KVFormatSimple) {
@@ -731,31 +748,38 @@ TEST(ExpressionFromAccumulators, Avg) {
}
TEST(ExpressionFromAccumulators, FirstNLastN) {
- RAIIServerParameterControllerForTest controller("featureFlagExactTopNAccumulator", true);
+ using Sense = AccumulatorFirstLastN::Sense;
// $firstN
- assertExpectedArray(fromjson("{$firstN: {n: 3, output: [19, 7, 28, 3, 5]}}"),
- BSONArray(fromjson("[19, 7, 28]")));
- assertExpectedArray(fromjson("{$firstN: {n: 6, output: [19, 7, 28, 3, 5]}}"),
- BSONArray(fromjson("[19, 7, 28, 3, 5]")));
- assertExpectedArray(fromjson("{$firstN: {n: 3, output: [1,2,3,4,5,6]}}"),
- BSONArray(fromjson("[1,2,3]")));
- assertExpectedArray(fromjson("{$firstN: {n: 3, output: [1,2,null,null]}}"),
- BSONArray(fromjson("[1,2,null]")));
- assertExpectedArray(fromjson("{$firstN: {n: 3, output: [1.1, 2.713, 3, 3.4]}}"),
- BSONArray(fromjson("[1.1, 2.713, 3]")));
+ auto firstNFn = [&](const BSONObj& spec, const BSONArray& expected) {
+ parseAndVerifyResults(AccumulatorFirstLastN::parseExpression<Sense::kFirst>,
+ spec.firstElement(),
+ Value(expected));
+ };
+ firstNFn(fromjson("{$firstN: {n: 3, output: [19, 7, 28, 3, 5]}}"),
+ BSONArray(fromjson("[19, 7, 28]")));
+ firstNFn(fromjson("{$firstN: {n: 6, output: [19, 7, 28, 3, 5]}}"),
+ BSONArray(fromjson("[19, 7, 28, 3, 5]")));
+ firstNFn(fromjson("{$firstN: {n: 3, output: [1,2,3,4,5,6]}}"), BSONArray(fromjson("[1,2,3]")));
+ firstNFn(fromjson("{$firstN: {n: 3, output: [1,2,null,null]}}"),
+ BSONArray(fromjson("[1,2,null]")));
+ firstNFn(fromjson("{$firstN: {n: 3, output: [1.1, 2.713, 3, 3.4]}}"),
+ BSONArray(fromjson("[1.1, 2.713, 3]")));
// $lastN
- assertExpectedArray(fromjson("{$lastN: {n: 3, output: [19, 7, 28, 3, 5]}}"),
- BSONArray(fromjson("[28,3,5]")));
- assertExpectedArray(fromjson("{$lastN: {n: 6, output: [19, 7, 28, 3, 5]}}"),
- BSONArray(fromjson("[19, 7, 28, 3, 5]")));
- assertExpectedArray(fromjson("{$lastN: {n: 3, output: [3,2,1,4,5,6]}}"),
- BSONArray(fromjson("[4,5,6]")));
- assertExpectedArray(fromjson("{$lastN: {n: 3, output: [1,2,null,3]}}"),
- BSONArray(fromjson("[2,null,3]")));
- assertExpectedArray(fromjson("{$lastN: {n: 3, output: [3, 2.713, 1.1, 2.7]}}"),
- BSONArray(fromjson("[2.713, 1.1, 2.7]")));
+ auto lastNFn = [&](const BSONObj& spec, const BSONArray& expected) {
+ parseAndVerifyResults(AccumulatorFirstLastN::parseExpression<Sense::kLast>,
+ spec.firstElement(),
+ Value(expected));
+ };
+ lastNFn(fromjson("{$lastN: {n: 3, output: [19, 7, 28, 3, 5]}}"),
+ BSONArray(fromjson("[28,3,5]")));
+ lastNFn(fromjson("{$lastN: {n: 6, output: [19, 7, 28, 3, 5]}}"),
+ BSONArray(fromjson("[19, 7, 28, 3, 5]")));
+ lastNFn(fromjson("{$lastN: {n: 3, output: [3,2,1,4,5,6]}}"), BSONArray(fromjson("[4,5,6]")));
+ lastNFn(fromjson("{$lastN: {n: 3, output: [1,2,null,3]}}"), BSONArray(fromjson("[2,null,3]")));
+ lastNFn(fromjson("{$lastN: {n: 3, output: [3, 2.713, 1.1, 2.7]}}"),
+ BSONArray(fromjson("[2.713, 1.1, 2.7]")));
}
TEST(ExpressionFromAccumulators, Max) {
@@ -782,31 +806,35 @@ TEST(ExpressionFromAccumulators, Min) {
}
TEST(ExpressionFromAccumulators, MinNMaxN) {
- RAIIServerParameterControllerForTest controller("featureFlagExactTopNAccumulator", true);
+ using Sense = AccumulatorMinMax::Sense;
+ auto maxNFn = [&](const BSONObj& spec, const BSONArray& expected) {
+ parseAndVerifyResults(
+ AccumulatorMinMaxN::parseExpression<Sense::kMax>, spec.firstElement(), Value(expected));
+ };
// $maxN
- assertExpectedArray(fromjson("{$maxN: {n: 3, output: [19, 7, 28, 3, 5]}}"),
- BSONArray(fromjson("[28, 19, 7]")));
- assertExpectedArray(fromjson("{$maxN: {n: 6, output: [19, 7, 28, 3, 5]}}"),
- BSONArray(fromjson("[28, 19, 7, 5, 3]")));
- assertExpectedArray(fromjson("{$maxN: {n: 3, output: [1,2,3]}}"),
- BSONArray(fromjson("[3,2,1]")));
- assertExpectedArray(fromjson("{$maxN: {n: 3, output: [1,2,null]}}"),
- BSONArray(fromjson("[2,1]")));
- assertExpectedArray(fromjson("{$maxN: {n: 3, output: [1.1, 2.713, 3]}}"),
- BSONArray(fromjson("[3, 2.713, 1.1]")));
+ maxNFn(fromjson("{$maxN: {n: 3, output: [19, 7, 28, 3, 5]}}"),
+ BSONArray(fromjson("[28, 19, 7]")));
+ maxNFn(fromjson("{$maxN: {n: 6, output: [19, 7, 28, 3, 5]}}"),
+ BSONArray(fromjson("[28, 19, 7, 5, 3]")));
+ maxNFn(fromjson("{$maxN: {n: 3, output: [1,2,3]}}"), BSONArray(fromjson("[3,2,1]")));
+ maxNFn(fromjson("{$maxN: {n: 3, output: [1,2,null]}}"), BSONArray(fromjson("[2,1]")));
+ maxNFn(fromjson("{$maxN: {n: 3, output: [1.1, 2.713, 3]}}"),
+ BSONArray(fromjson("[3, 2.713, 1.1]")));
+
+ auto minNFn = [&](const BSONObj& spec, const BSONArray& expected) {
+ parseAndVerifyResults(
+ AccumulatorMinMaxN::parseExpression<Sense::kMin>, spec.firstElement(), Value(expected));
+ };
// $minN
- assertExpectedArray(fromjson("{$minN: {n: 3, output: [19, 7, 28, 3, 5]}}"),
- BSONArray(fromjson("[3,5,7]")));
- assertExpectedArray(fromjson("{$minN: {n: 6, output: [19, 7, 28, 3, 5]}}"),
- BSONArray(fromjson("[3,5,7,19,28]")));
- assertExpectedArray(fromjson("{$minN: {n: 3, output: [3,2,1]}}"),
- BSONArray(fromjson("[1,2,3]")));
- assertExpectedArray(fromjson("{$minN: {n: 3, output: [1,2,null]}}"),
- BSONArray(fromjson("[1,2]")));
- assertExpectedArray(fromjson("{$minN: {n: 3, output: [3, 2.713, 1.1]}}"),
- BSONArray(fromjson("[1.1, 2.713, 3]")));
+ minNFn(fromjson("{$minN: {n: 3, output: [19, 7, 28, 3, 5]}}"), BSONArray(fromjson("[3,5,7]")));
+ minNFn(fromjson("{$minN: {n: 6, output: [19, 7, 28, 3, 5]}}"),
+ BSONArray(fromjson("[3,5,7,19, 28]")));
+ minNFn(fromjson("{$minN: {n: 3, output: [3,2,1]}}"), BSONArray(fromjson("[1,2,3]")));
+ minNFn(fromjson("{$minN: {n: 3, output: [1,2,null]}}"), BSONArray(fromjson("[1,2]")));
+ minNFn(fromjson("{$minN: {n: 3, output: [3, 2.713, 1.1]}}"),
+ BSONArray(fromjson("[1.1, 2.713, 3]")));
}
TEST(ExpressionFromAccumulators, Sum) {