summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJacob Evans <jacob.evans@mongodb.com>2019-10-15 02:21:45 +0000
committerevergreen <evergreen@mongodb.com>2019-10-15 02:21:45 +0000
commitfd3a1af42439bce510688051e0c820de13c7166f (patch)
treeb4cd127268ba2184bede1db8915f0dc650c958fd /src
parentd819272026fd1c21b9fb18ae692648cfa590aa68 (diff)
downloadmongo-fd3a1af42439bce510688051e0c820de13c7166f.tar.gz
SERVER-43796 Fix unittests and compile
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/pipeline/accumulator_js_test.cpp77
-rw-r--r--src/mongo/db/pipeline/accumulator_test.cpp71
-rw-r--r--src/mongo/db/pipeline/document_source_group_test.cpp47
3 files changed, 93 insertions, 102 deletions
diff --git a/src/mongo/db/pipeline/accumulator_js_test.cpp b/src/mongo/db/pipeline/accumulator_js_test.cpp
index 7637388ca4b..8efb460cf27 100644
--- a/src/mongo/db/pipeline/accumulator_js_test.cpp
+++ b/src/mongo/db/pipeline/accumulator_js_test.cpp
@@ -75,25 +75,22 @@ void MapReduceFixture::tearDown() {
namespace InternalJsReduce {
-static void assertProcessFailsWithCode(std::string accumulatorName,
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
+template <typename AccName>
+static void assertProcessFailsWithCode(const boost::intrusive_ptr<ExpressionContext>& expCtx,
Value processArgument,
int code) {
- auto factory = AccumulationStatement::getFactory(accumulatorName);
- boost::intrusive_ptr<Accumulator> accum(factory(expCtx));
+ auto accum = AccName::create(expCtx);
ASSERT_THROWS_CODE(accum->process(processArgument, false), AssertionException, code);
}
-static void assertExpectedResults(std::string accumulatorName,
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
+template <typename AccName>
+static void assertExpectedResults(const boost::intrusive_ptr<ExpressionContext>& expCtx,
std::string eval,
std::vector<Value> data,
Value expectedResult) {
- auto factory = AccumulationStatement::getFactory(accumulatorName);
-
// Asserts that result equals expected result when not sharded.
{
- boost::intrusive_ptr<Accumulator> accum(factory(expCtx));
+ auto accum = AccName::create(expCtx);
for (auto&& val : data) {
auto input = Value(DOC("eval" << eval << "data" << val));
accum->process(input, false);
@@ -105,8 +102,8 @@ static void assertExpectedResults(std::string accumulatorName,
// Asserts that result equals expected result when all input is on one shard.
{
- boost::intrusive_ptr<Accumulator> accum(factory(expCtx));
- boost::intrusive_ptr<Accumulator> shard(factory(expCtx));
+ auto accum = AccName::create(expCtx);
+ auto shard = AccName::create(expCtx);
for (auto&& val : data) {
auto input = Value(DOC("eval" << eval << "data" << val));
shard->process(input, false);
@@ -119,10 +116,10 @@ static void assertExpectedResults(std::string accumulatorName,
// Asserts that result equals expected result when each input is on a separate shard.
{
- boost::intrusive_ptr<Accumulator> accum(factory(expCtx));
+ auto accum = AccName::create(expCtx);
for (auto&& val : data) {
auto input = Value(DOC("eval" << eval << "data" << val));
- boost::intrusive_ptr<Accumulator> shard(factory(expCtx));
+ auto shard = AccName::create(expCtx);
shard->process(input, false);
accum->process(shard->getValue(true), true);
}
@@ -134,23 +131,22 @@ static void assertExpectedResults(std::string accumulatorName,
TEST_F(MapReduceFixture, InternalJsReduceProducesExpectedResults) {
// Null value.
- assertExpectedResults("$_internalJsReduce",
- getExpCtx(),
- "function(key, value) { return null; };",
- {Value(DOC("k" << 1 << "v" << Value(BSONNULL)))},
- Value(BSONNULL));
+ assertExpectedResults<AccumulatorInternalJsReduce>(
+ getExpCtx(),
+ "function(key, value) { return null; };",
+ {Value(DOC("k" << 1 << "v" << Value(BSONNULL)))},
+ Value(BSONNULL));
// Multiple inputs.
- assertExpectedResults("$_internalJsReduce",
- getExpCtx(),
- "function(key, values) { return Array.sum(values); };",
- {Value(DOC("k" << std::string("foo") << "v" << Value(2))),
- Value(DOC("k" << std::string("foo") << "v" << Value(5)))},
- Value(7.0));
+ assertExpectedResults<AccumulatorInternalJsReduce>(
+ getExpCtx(),
+ "function(key, values) { return Array.sum(values); };",
+ {Value(DOC("k" << std::string("foo") << "v" << Value(2))),
+ Value(DOC("k" << std::string("foo") << "v" << Value(5)))},
+ Value(7.0));
// Multiple inputs, numeric key.
- assertExpectedResults(
- "$_internalJsReduce",
+ assertExpectedResults<AccumulatorInternalJsReduce>(
getExpCtx(),
"function(key, values) { return Array.sum(values); };",
{Value(DOC("k" << 1 << "v" << Value(2))), Value(DOC("k" << 1 << "v" << Value(5)))},
@@ -158,9 +154,7 @@ TEST_F(MapReduceFixture, InternalJsReduceProducesExpectedResults) {
}
TEST_F(MapReduceFixture, InternalJsReduceIdempotentOnlyWhenJSFunctionIsIdempotent) {
-
- auto factory = AccumulationStatement::getFactory("$_internalJsReduce");
- boost::intrusive_ptr<Accumulator> accum(factory(getExpCtx()));
+ auto accum = AccumulatorInternalJsReduce::create(getExpCtx());
// A non-idempotent Javascript function will produce non-idempotent results. In this case a
// single document reduce causes a change in value.
@@ -177,11 +171,9 @@ TEST_F(MapReduceFixture, InternalJsReduceIdempotentOnlyWhenJSFunctionIsIdempoten
}
TEST_F(MapReduceFixture, InternalJsReduceFailsWhenEvalContainsInvalidJavascript) {
- auto factory = AccumulationStatement::getFactory("$_internalJsReduce");
-
// Multiple source documents.
{
- boost::intrusive_ptr<Accumulator> accum(factory(getExpCtx()));
+ auto accum = AccumulatorInternalJsReduce::create(getExpCtx());
auto input = Value(DOC("eval" << std::string("INVALID_JAVASCRIPT") << "data"
<< Value(DOC("k" << Value(1) << "v" << Value(2)))));
@@ -193,7 +185,7 @@ TEST_F(MapReduceFixture, InternalJsReduceFailsWhenEvalContainsInvalidJavascript)
// Single source document.
{
- boost::intrusive_ptr<Accumulator> accum(factory(getExpCtx()));
+ auto accum = AccumulatorInternalJsReduce::create(getExpCtx());
auto input = Value(DOC("eval" << std::string("INVALID_JAVASCRIPT") << "data"
<< Value(DOC("k" << Value(1) << "v" << Value(2)))));
@@ -206,24 +198,24 @@ TEST_F(MapReduceFixture, InternalJsReduceFailsWhenEvalContainsInvalidJavascript)
TEST_F(MapReduceFixture, InternalJsReduceFailsIfArgumentNotDocument) {
auto argument = Value(2);
- assertProcessFailsWithCode("$_internalJsReduce", getExpCtx(), argument, 31242);
+ assertProcessFailsWithCode<AccumulatorInternalJsReduce>(getExpCtx(), argument, 31242);
}
TEST_F(MapReduceFixture, InternalJsReduceFailsIfEvalAndDataArgumentsNotProvided) {
// Data argument missing.
auto argument =
Value(DOC("eval" << std::string("function(key, values) { return Array.sum(values); };")));
- assertProcessFailsWithCode("$_internalJsReduce", getExpCtx(), argument, 31243);
+ assertProcessFailsWithCode<AccumulatorInternalJsReduce>(getExpCtx(), argument, 31243);
// Eval argument missing.
argument = Value(DOC("data" << Value(DOC("k" << Value(1) << "v" << Value(2)))));
- assertProcessFailsWithCode("$_internalJsReduce", getExpCtx(), argument, 31243);
+ assertProcessFailsWithCode<AccumulatorInternalJsReduce>(getExpCtx(), argument, 31243);
}
TEST_F(MapReduceFixture, InternalJsReduceFailsIfEvalArgumentNotOfTypeStringOrCode) {
auto argument = Value(
DOC("eval" << 1 << "data" << Value(DOC("k" << std::string("foo") << "v" << Value(2)))));
- assertProcessFailsWithCode("$_internalJsReduce", getExpCtx(), argument, 31244);
+ assertProcessFailsWithCode<AccumulatorInternalJsReduce>(getExpCtx(), argument, 31244);
// MapReduce does not accept JavaScript function of BSON type CodeWScope.
BSONObjBuilder objBuilder;
@@ -231,14 +223,15 @@ TEST_F(MapReduceFixture, InternalJsReduceFailsIfEvalArgumentNotOfTypeStringOrCod
"eval", "function(key, values) { return Array.sum(values); };", BSONObj());
objBuilder.append("data", BSON("k" << std::string("foo") << "v" << Value(2)));
- assertProcessFailsWithCode("$_internalJsReduce", getExpCtx(), Value(objBuilder.obj()), 31244);
+ assertProcessFailsWithCode<AccumulatorInternalJsReduce>(
+ getExpCtx(), Value(objBuilder.obj()), 31244);
}
TEST_F(MapReduceFixture, InternalJsReduceFailsIfDataArgumentNotDocument) {
auto argument =
Value(DOC("eval" << std::string("function(key, values) { return Array.sum(values); };")
<< "data" << Value(2)));
- assertProcessFailsWithCode("$_internalJsReduce", getExpCtx(), argument, 31245);
+ assertProcessFailsWithCode<AccumulatorInternalJsReduce>(getExpCtx(), argument, 31245);
}
TEST_F(MapReduceFixture, InternalJsReduceFailsIfDataArgumentDoesNotContainExpectedFields) {
@@ -246,19 +239,19 @@ TEST_F(MapReduceFixture, InternalJsReduceFailsIfDataArgumentDoesNotContainExpect
auto argument = Value(
DOC("eval" << std::string("function(key, values) { return Array.sum(values); };") << "data"
<< Value(DOC("foo" << std::string("keyVal") << "v" << Value(2)))));
- assertProcessFailsWithCode("$_internalJsReduce", getExpCtx(), argument, 31251);
+ assertProcessFailsWithCode<AccumulatorInternalJsReduce>(getExpCtx(), argument, 31251);
// No "v" field.
argument = Value(
DOC("eval" << std::string("function(key, values) { return Array.sum(values); };") << "data"
<< Value(DOC("k" << std::string("keyVal") << "bar" << Value(2)))));
- assertProcessFailsWithCode("$_internalJsReduce", getExpCtx(), argument, 31251);
+ assertProcessFailsWithCode<AccumulatorInternalJsReduce>(getExpCtx(), argument, 31251);
// Both "k" and "v" fields missing.
argument =
Value(DOC("eval" << std::string("function(key, values) { return Array.sum(values); };")
<< "data" << Value(Document())));
- assertProcessFailsWithCode("$_internalJsReduce", getExpCtx(), argument, 31251);
+ assertProcessFailsWithCode<AccumulatorInternalJsReduce>(getExpCtx(), argument, 31251);
}
} // namespace InternalJsReduce
diff --git a/src/mongo/db/pipeline/accumulator_test.cpp b/src/mongo/db/pipeline/accumulator_test.cpp
index ec4b88eae37..14f9f74eda8 100644
--- a/src/mongo/db/pipeline/accumulator_test.cpp
+++ b/src/mongo/db/pipeline/accumulator_test.cpp
@@ -46,20 +46,19 @@ using std::numeric_limits;
using std::string;
/**
- * Takes the name of an Accumulator as its first argument and a list of pairs of arguments and
+ * Takes the name of an Accumulator as its template argument and a list of pairs of arguments and
* expected results as its second argument, and asserts that for the given Accumulator the arguments
* evaluate to the expected results.
*/
+template <typename AccName>
static void assertExpectedResults(
- std::string accumulatorName,
const intrusive_ptr<ExpressionContext>& expCtx,
std::initializer_list<std::pair<std::vector<Value>, Value>> operations) {
- auto factory = AccumulationStatement::getFactory(accumulatorName);
for (auto&& op : operations) {
try {
// Asserts that result equals expected result when not sharded.
{
- boost::intrusive_ptr<Accumulator> accum(factory(expCtx));
+ auto accum = AccName::create(expCtx);
for (auto&& val : op.first) {
accum->process(val, false);
}
@@ -70,8 +69,8 @@ static void assertExpectedResults(
// Asserts that result equals expected result when all input is on one shard.
{
- boost::intrusive_ptr<Accumulator> accum(factory(expCtx));
- boost::intrusive_ptr<Accumulator> shard(factory(expCtx));
+ auto accum = AccName::create(expCtx);
+ auto shard = AccName::create(expCtx);
for (auto&& val : op.first) {
shard->process(val, false);
}
@@ -83,9 +82,9 @@ static void assertExpectedResults(
// Asserts that result equals expected result when each input is on a separate shard.
{
- boost::intrusive_ptr<Accumulator> accum(factory(expCtx));
+ auto accum = AccName::create(expCtx);
for (auto&& val : op.first) {
- boost::intrusive_ptr<Accumulator> shard(factory(expCtx));
+ auto shard = AccName::create(expCtx);
shard->process(val, false);
accum->process(shard->getValue(true), true);
}
@@ -102,8 +101,7 @@ static void assertExpectedResults(
TEST(Accumulators, Avg) {
intrusive_ptr<ExpressionContext> expCtx(new ExpressionContextForTest());
- assertExpectedResults(
- "$avg",
+ assertExpectedResults<AccumulatorAvg>(
expCtx,
{
// No documents evaluated.
@@ -158,8 +156,7 @@ TEST(Accumulators, Avg) {
TEST(Accumulators, First) {
intrusive_ptr<ExpressionContext> expCtx(new ExpressionContextForTest());
- assertExpectedResults(
- "$first",
+ assertExpectedResults<AccumulatorFirst>(
expCtx,
{// No documents evaluated.
{{}, Value()},
@@ -177,8 +174,7 @@ TEST(Accumulators, First) {
TEST(Accumulators, Last) {
intrusive_ptr<ExpressionContext> expCtx(new ExpressionContextForTest());
- assertExpectedResults(
- "$last",
+ assertExpectedResults<AccumulatorLast>(
expCtx,
{// No documents evaluated.
{{}, Value()},
@@ -196,8 +192,7 @@ TEST(Accumulators, Last) {
TEST(Accumulators, Min) {
intrusive_ptr<ExpressionContext> expCtx(new ExpressionContextForTest());
- assertExpectedResults(
- "$min",
+ assertExpectedResults<AccumulatorMin>(
expCtx,
{// No documents evaluated.
{{}, Value(BSONNULL)},
@@ -217,13 +212,13 @@ TEST(Accumulators, MinRespectsCollation) {
intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
expCtx->setCollator(&collator);
- assertExpectedResults("$min", expCtx, {{{Value("abc"_sd), Value("cba"_sd)}, Value("cba"_sd)}});
+ assertExpectedResults<AccumulatorMin>(expCtx,
+ {{{Value("abc"_sd), Value("cba"_sd)}, Value("cba"_sd)}});
}
TEST(Accumulators, Max) {
intrusive_ptr<ExpressionContext> expCtx(new ExpressionContextForTest());
- assertExpectedResults(
- "$max",
+ assertExpectedResults<AccumulatorMax>(
expCtx,
{// No documents evaluated.
{{}, Value(BSONNULL)},
@@ -243,13 +238,13 @@ TEST(Accumulators, MaxRespectsCollation) {
intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
expCtx->setCollator(&collator);
- assertExpectedResults("$max", expCtx, {{{Value("abc"_sd), Value("cba"_sd)}, Value("abc"_sd)}});
+ assertExpectedResults<AccumulatorMax>(expCtx,
+ {{{Value("abc"_sd), Value("cba"_sd)}, Value("abc"_sd)}});
}
TEST(Accumulators, Sum) {
intrusive_ptr<ExpressionContext> expCtx(new ExpressionContextForTest());
- assertExpectedResults(
- "$sum",
+ assertExpectedResults<AccumulatorSum>(
expCtx,
{// No documents evaluated.
{{}, Value(0)},
@@ -340,48 +335,42 @@ TEST(Accumulators, AddToSetRespectsCollation) {
intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
expCtx->setCollator(&collator);
- assertExpectedResults("$addToSet",
- expCtx,
- {{{Value("a"_sd), Value("b"_sd), Value("c"_sd)},
- Value(std::vector<Value>{Value("a"_sd)})}});
+ assertExpectedResults<AccumulatorAddToSet>(expCtx,
+ {{{Value("a"_sd), Value("b"_sd), Value("c"_sd)},
+ Value(std::vector<Value>{Value("a"_sd)})}});
}
/* ------------------------- AccumulatorMergeObjects -------------------------- */
-namespace AccumulatorMergeObjects {
-
TEST(AccumulatorMergeObjects, MergingZeroObjectsShouldReturnEmptyDocument) {
intrusive_ptr<ExpressionContext> expCtx(new ExpressionContextForTest());
- assertExpectedResults("$mergeObjects", expCtx, {{{}, {Value(Document({}))}}});
+ assertExpectedResults<AccumulatorMergeObjects>(expCtx, {{{}, {Value(Document({}))}}});
}
TEST(AccumulatorMergeObjects, MergingWithSingleObjectShouldLeaveUnchanged) {
intrusive_ptr<ExpressionContext> expCtx(new ExpressionContextForTest());
- assertExpectedResults("$mergeObjects", expCtx, {{{}, {Value(Document({}))}}});
+ assertExpectedResults<AccumulatorMergeObjects>(expCtx, {{{}, {Value(Document({}))}}});
auto doc = Value(Document({{"a", 1}, {"b", 1}}));
- assertExpectedResults("$mergeObjects", expCtx, {{{doc}, doc}});
+ assertExpectedResults<AccumulatorMergeObjects>(expCtx, {{{doc}, doc}});
}
TEST(AccumulatorMergeObjects, MergingDisjointObjectsShouldIncludeAllFields) {
intrusive_ptr<ExpressionContext> expCtx(new ExpressionContextForTest());
auto first = Value(Document({{"a", 1}, {"b", 1}}));
auto second = Value(Document({{"c", 1}}));
- assertExpectedResults("$mergeObjects",
- expCtx,
- {{{first, second}, Value(Document({{"a", 1}, {"b", 1}, {"c", 1}}))}});
+ assertExpectedResults<AccumulatorMergeObjects>(
+ expCtx, {{{first, second}, Value(Document({{"a", 1}, {"b", 1}, {"c", 1}}))}});
}
TEST(AccumulatorMergeObjects, MergingIntersectingObjectsShouldOverrideInOrderReceived) {
intrusive_ptr<ExpressionContext> expCtx(new ExpressionContextForTest());
auto first = Value(Document({{"a", "oldValue"_sd}, {"b", 0}, {"c", 1}}));
auto second = Value(Document({{"a", "newValue"_sd}}));
- assertExpectedResults(
- "$mergeObjects",
- expCtx,
- {{{first, second}, Value(Document({{"a", "newValue"_sd}, {"b", 0}, {"c", 1}}))}});
+ assertExpectedResults<AccumulatorMergeObjects>(
+ expCtx, {{{first, second}, Value(Document({{"a", "newValue"_sd}, {"b", 0}, {"c", 1}}))}});
}
TEST(AccumulatorMergeObjects, MergingIntersectingEmbeddedObjectsShouldOverrideInOrderReceived) {
@@ -391,7 +380,7 @@ TEST(AccumulatorMergeObjects, MergingIntersectingEmbeddedObjectsShouldOverrideIn
auto first = Value(Document({{"d", 1}, {"subDoc", firstSubDoc}}));
auto second = Value(Document({{"subDoc", secondSubDoc}}));
auto expected = Value(Document({{"d", 1}, {"subDoc", secondSubDoc}}));
- assertExpectedResults("$mergeObjects", expCtx, {{{first, second}, expected}});
+ assertExpectedResults<AccumulatorMergeObjects>(expCtx, {{{first, second}, expected}});
}
TEST(AccumulatorMergeObjects, MergingWithEmptyDocumentShouldIgnore) {
@@ -399,9 +388,7 @@ TEST(AccumulatorMergeObjects, MergingWithEmptyDocumentShouldIgnore) {
auto first = Value(Document({{"a", 0}, {"b", 1}, {"c", 1}}));
auto second = Value(Document({}));
auto expected = Value(Document({{"a", 0}, {"b", 1}, {"c", 1}}));
- assertExpectedResults("$mergeObjects", expCtx, {{{first, second}, expected}});
+ assertExpectedResults<AccumulatorMergeObjects>(expCtx, {{{first, second}, expected}});
}
-} // namespace AccumulatorMergeObjects
-
} // namespace AccumulatorTests
diff --git a/src/mongo/db/pipeline/document_source_group_test.cpp b/src/mongo/db/pipeline/document_source_group_test.cpp
index e2fdfe4f107..a2ed4358248 100644
--- a/src/mongo/db/pipeline/document_source_group_test.cpp
+++ b/src/mongo/db/pipeline/document_source_group_test.cpp
@@ -73,9 +73,11 @@ TEST_F(DocumentSourceGroupTest, ShouldBeAbleToPauseLoading) {
auto expCtx = getExpCtx();
expCtx->inMongos = true; // Disallow external sort.
// This is the only way to do this in a debug build.
- AccumulationStatement countStatement{"count",
- ExpressionConstant::create(expCtx, Value(1)),
- AccumulationStatement::getFactory("$sum")};
+ auto&& parser = AccumulationStatement::getParser("$sum");
+ auto accumulatorArg = BSON("" << 1);
+ auto [expression, factory] =
+ parser(expCtx, accumulatorArg.firstElement(), expCtx->variablesParseState);
+ AccumulationStatement countStatement{"count", expression, factory};
auto group = DocumentSourceGroup::create(
expCtx, ExpressionConstant::create(expCtx, Value(BSONNULL)), {countStatement});
auto mock =
@@ -108,11 +110,14 @@ TEST_F(DocumentSourceGroupTest, ShouldBeAbleToPauseLoadingWhileSpilled) {
expCtx->allowDiskUse = true;
const size_t maxMemoryUsageBytes = 1000;
- VariablesParseState vps = expCtx->variablesParseState;
- AccumulationStatement pushStatement{"spaceHog",
- ExpressionFieldPath::parse(expCtx, "$largeStr", vps),
- AccumulationStatement::getFactory("$push")};
- auto groupByExpression = ExpressionFieldPath::parse(expCtx, "$_id", vps);
+ auto&& parser = AccumulationStatement::getParser("$push");
+ auto accumulatorArg = BSON(""
+ << "$largeStr");
+ auto [expression, factory] =
+ parser(expCtx, accumulatorArg.firstElement(), expCtx->variablesParseState);
+ AccumulationStatement pushStatement{"spaceHog", expression, factory};
+ auto groupByExpression =
+ ExpressionFieldPath::parse(expCtx, "$_id", expCtx->variablesParseState);
auto group = DocumentSourceGroup::create(
expCtx, groupByExpression, {pushStatement}, maxMemoryUsageBytes);
@@ -148,11 +153,14 @@ TEST_F(DocumentSourceGroupTest, ShouldErrorIfNotAllowedToSpillToDiskAndResultSet
expCtx->inMongos = true; // Disallow external sort.
// This is the only way to do this in a debug build.
- VariablesParseState vps = expCtx->variablesParseState;
- AccumulationStatement pushStatement{"spaceHog",
- ExpressionFieldPath::parse(expCtx, "$largeStr", vps),
- AccumulationStatement::getFactory("$push")};
- auto groupByExpression = ExpressionFieldPath::parse(expCtx, "$_id", vps);
+ auto&& parser = AccumulationStatement::getParser("$push");
+ auto accumulatorArg = BSON(""
+ << "$largeStr");
+ auto [expression, factory] =
+ parser(expCtx, accumulatorArg.firstElement(), expCtx->variablesParseState);
+ AccumulationStatement pushStatement{"spaceHog", expression, factory};
+ auto groupByExpression =
+ ExpressionFieldPath::parse(expCtx, "$_id", expCtx->variablesParseState);
auto group = DocumentSourceGroup::create(
expCtx, groupByExpression, {pushStatement}, maxMemoryUsageBytes);
@@ -170,11 +178,14 @@ TEST_F(DocumentSourceGroupTest, ShouldCorrectlyTrackMemoryUsageBetweenPauses) {
expCtx->inMongos = true; // Disallow external sort.
// This is the only way to do this in a debug build.
- VariablesParseState vps = expCtx->variablesParseState;
- AccumulationStatement pushStatement{"spaceHog",
- ExpressionFieldPath::parse(expCtx, "$largeStr", vps),
- AccumulationStatement::getFactory("$push")};
- auto groupByExpression = ExpressionFieldPath::parse(expCtx, "$_id", vps);
+ auto&& parser = AccumulationStatement::getParser("$push");
+ auto accumulatorArg = BSON(""
+ << "$largeStr");
+ auto [expression, factory] =
+ parser(expCtx, accumulatorArg.firstElement(), expCtx->variablesParseState);
+ AccumulationStatement pushStatement{"spaceHog", expression, factory};
+ auto groupByExpression =
+ ExpressionFieldPath::parse(expCtx, "$_id", expCtx->variablesParseState);
auto group = DocumentSourceGroup::create(
expCtx, groupByExpression, {pushStatement}, maxMemoryUsageBytes);