summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Evans <jacob.evans@10gen.com>2020-05-12 15:55:02 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-05-16 01:30:05 +0000
commita7f769dd597e33e988832c43c99912c1d3139c9b (patch)
tree9366f0dfc75db2c9c92e2b101de17542ae573e89
parent6b38c78843e7eb58dc344d88903727762d7d486d (diff)
downloadmongo-a7f769dd597e33e988832c43c99912c1d3139c9b.tar.gz
SERVER-47713 Change Expression code to remove intrusive ExpressionContext
-rw-r--r--src/mongo/db/commands/mr_common.cpp21
-rw-r--r--src/mongo/db/commands/run_aggregate.cpp4
-rw-r--r--src/mongo/db/exec/add_fields_projection_executor.cpp6
-rw-r--r--src/mongo/db/exec/find_projection_executor_test.cpp78
-rw-r--r--src/mongo/db/exec/projection_executor_builder.cpp19
-rw-r--r--src/mongo/db/exec/projection_executor_test.cpp14
-rw-r--r--src/mongo/db/matcher/expression_expr.cpp6
-rw-r--r--src/mongo/db/matcher/extensions_callback_real.cpp8
-rw-r--r--src/mongo/db/matcher/rewrite_expr_test.cpp6
-rw-r--r--src/mongo/db/pipeline/accumulation_statement.cpp6
-rw-r--r--src/mongo/db/pipeline/accumulation_statement.h16
-rw-r--r--src/mongo/db/pipeline/accumulator.h67
-rw-r--r--src/mongo/db/pipeline/accumulator_add_to_set.cpp5
-rw-r--r--src/mongo/db/pipeline/accumulator_avg.cpp5
-rw-r--r--src/mongo/db/pipeline/accumulator_first.cpp5
-rw-r--r--src/mongo/db/pipeline/accumulator_js_reduce.cpp16
-rw-r--r--src/mongo/db/pipeline/accumulator_js_reduce.h29
-rw-r--r--src/mongo/db/pipeline/accumulator_js_test.cpp16
-rw-r--r--src/mongo/db/pipeline/accumulator_last.cpp6
-rw-r--r--src/mongo/db/pipeline/accumulator_merge_objects.cpp6
-rw-r--r--src/mongo/db/pipeline/accumulator_min_max.cpp9
-rw-r--r--src/mongo/db/pipeline/accumulator_push.cpp5
-rw-r--r--src/mongo/db/pipeline/accumulator_std_dev.cpp9
-rw-r--r--src/mongo/db/pipeline/accumulator_sum.cpp6
-rw-r--r--src/mongo/db/pipeline/accumulator_test.cpp78
-rw-r--r--src/mongo/db/pipeline/aggregation_context_fixture.h8
-rw-r--r--src/mongo/db/pipeline/document_source_bucket.cpp11
-rw-r--r--src/mongo/db/pipeline/document_source_bucket_auto.cpp14
-rw-r--r--src/mongo/db/pipeline/document_source_bucket_auto_test.cpp10
-rw-r--r--src/mongo/db/pipeline/document_source_graph_lookup.cpp2
-rw-r--r--src/mongo/db/pipeline/document_source_graph_lookup_test.cpp26
-rw-r--r--src/mongo/db/pipeline/document_source_group.cpp18
-rw-r--r--src/mongo/db/pipeline/document_source_group_test.cpp26
-rw-r--r--src/mongo/db/pipeline/document_source_lookup.cpp2
-rw-r--r--src/mongo/db/pipeline/document_source_merge.cpp2
-rw-r--r--src/mongo/db/pipeline/document_source_redact.cpp2
-rw-r--r--src/mongo/db/pipeline/document_source_replace_root.cpp4
-rw-r--r--src/mongo/db/pipeline/expression.cpp567
-rw-r--r--src/mongo/db/pipeline/expression.h445
-rw-r--r--src/mongo/db/pipeline/expression_and_test.cpp19
-rw-r--r--src/mongo/db/pipeline/expression_compare_test.cpp30
-rw-r--r--src/mongo/db/pipeline/expression_context.cpp30
-rw-r--r--src/mongo/db/pipeline/expression_context.h2
-rw-r--r--src/mongo/db/pipeline/expression_convert_test.cpp446
-rw-r--r--src/mongo/db/pipeline/expression_date_test.cpp292
-rw-r--r--src/mongo/db/pipeline/expression_field_path_test.cpp182
-rw-r--r--src/mongo/db/pipeline/expression_find_internal.h6
-rw-r--r--src/mongo/db/pipeline/expression_find_internal_test.cpp43
-rw-r--r--src/mongo/db/pipeline/expression_function.cpp9
-rw-r--r--src/mongo/db/pipeline/expression_function.h13
-rw-r--r--src/mongo/db/pipeline/expression_internal_remove_field_tombstones.h7
-rw-r--r--src/mongo/db/pipeline/expression_internal_remove_field_tombstones_test.cpp6
-rw-r--r--src/mongo/db/pipeline/expression_javascript_test.cpp45
-rw-r--r--src/mongo/db/pipeline/expression_js_emit.cpp16
-rw-r--r--src/mongo/db/pipeline/expression_js_emit.h11
-rw-r--r--src/mongo/db/pipeline/expression_nary_test.cpp119
-rw-r--r--src/mongo/db/pipeline/expression_object_test.cpp227
-rw-r--r--src/mongo/db/pipeline/expression_or_test.cpp19
-rw-r--r--src/mongo/db/pipeline/expression_replace_test.cpp6
-rw-r--r--src/mongo/db/pipeline/expression_test.cpp495
-rw-r--r--src/mongo/db/pipeline/expression_trigonometric.cpp54
-rw-r--r--src/mongo/db/pipeline/expression_trigonometric.h4
-rw-r--r--src/mongo/db/pipeline/expression_trigonometric_test.cpp16
-rw-r--r--src/mongo/db/pipeline/expression_trim_test.cpp118
-rw-r--r--src/mongo/db/pipeline/expression_walker_test.cpp2
-rw-r--r--src/mongo/db/pipeline/make_js_function.cpp3
-rw-r--r--src/mongo/db/pipeline/make_js_function.h3
-rw-r--r--src/mongo/db/pipeline/sharded_union_test.cpp27
-rw-r--r--src/mongo/db/pipeline/variables.cpp2
-rw-r--r--src/mongo/db/pipeline/variables.h2
-rw-r--r--src/mongo/db/query/canonical_query.h5
-rw-r--r--src/mongo/db/query/get_executor.cpp31
-rw-r--r--src/mongo/db/query/projection_parser.cpp4
-rw-r--r--src/mongo/db/query/sort_pattern.cpp4
-rw-r--r--src/mongo/db/query/stage_builder.cpp6
-rw-r--r--src/mongo/dbtests/query_plan_executor.cpp2
76 files changed, 1880 insertions, 2009 deletions
diff --git a/src/mongo/db/commands/mr_common.cpp b/src/mongo/db/commands/mr_common.cpp
index 00ba75a57c2..d3b8e792bb4 100644
--- a/src/mongo/db/commands/mr_common.cpp
+++ b/src/mongo/db/commands/mr_common.cpp
@@ -106,7 +106,9 @@ auto translateSort(boost::intrusive_ptr<ExpressionContext> expCtx, const BSONObj
auto translateMap(boost::intrusive_ptr<ExpressionContext> expCtx, std::string code) {
auto emitExpression = ExpressionInternalJsEmit::create(
- expCtx, ExpressionFieldPath::parse(expCtx, "$$ROOT", expCtx->variablesParseState), code);
+ expCtx.get(),
+ ExpressionFieldPath::parse(expCtx.get(), "$$ROOT", expCtx->variablesParseState),
+ code);
auto node = std::make_unique<projection_executor::InclusionNode>(
ProjectionPolicies{ProjectionPolicies::DefaultIdPolicy::kExcludeId});
node->addExpressionForPath(FieldPath{"emits"s}, std::move(emitExpression));
@@ -120,17 +122,17 @@ auto translateMap(boost::intrusive_ptr<ExpressionContext> expCtx, std::string co
}
auto translateReduce(boost::intrusive_ptr<ExpressionContext> expCtx, std::string code) {
- auto initializer = ExpressionArray::create(expCtx, {});
- auto argument = ExpressionFieldPath::parse(expCtx, "$emits", expCtx->variablesParseState);
+ auto initializer = ExpressionArray::create(expCtx.get(), {});
+ auto argument = ExpressionFieldPath::parse(expCtx.get(), "$emits", expCtx->variablesParseState);
auto reduceFactory = [expCtx, funcSource = std::move(code)]() {
- return AccumulatorInternalJsReduce::create(expCtx, funcSource);
+ return AccumulatorInternalJsReduce::create(expCtx.get(), funcSource);
};
AccumulationStatement jsReduce("value",
AccumulationExpression(std::move(initializer),
std::move(argument),
std::move(reduceFactory)));
auto groupKeyExpression =
- ExpressionFieldPath::parse(expCtx, "$emits.k", expCtx->variablesParseState);
+ ExpressionFieldPath::parse(expCtx.get(), "$emits.k", expCtx->variablesParseState);
return DocumentSourceGroup::create(expCtx,
std::move(groupKeyExpression),
make_vector<AccumulationStatement>(std::move(jsReduce)),
@@ -141,12 +143,13 @@ auto translateFinalize(boost::intrusive_ptr<ExpressionContext> expCtx,
MapReduceJavascriptCodeOrNull codeObj) {
return codeObj.getCode().map([&](auto&& code) {
auto jsExpression = ExpressionFunction::create(
- expCtx,
+ expCtx.get(),
ExpressionArray::create(
- expCtx,
+ expCtx.get(),
make_vector<boost::intrusive_ptr<Expression>>(
- ExpressionFieldPath::parse(expCtx, "$_id", expCtx->variablesParseState),
- ExpressionFieldPath::parse(expCtx, "$value", expCtx->variablesParseState))),
+ ExpressionFieldPath::parse(expCtx.get(), "$_id", expCtx->variablesParseState),
+ ExpressionFieldPath::parse(
+ expCtx.get(), "$value", expCtx->variablesParseState))),
code,
ExpressionFunction::kJavaScript);
auto node = std::make_unique<projection_executor::InclusionNode>(
diff --git a/src/mongo/db/commands/run_aggregate.cpp b/src/mongo/db/commands/run_aggregate.cpp
index 6293a8cac31..c8805eee8c3 100644
--- a/src/mongo/db/commands/run_aggregate.cpp
+++ b/src/mongo/db/commands/run_aggregate.cpp
@@ -216,8 +216,8 @@ bool handleCursorCommand(OperationContext* opCtx,
// If adding this object will cause us to exceed the message size limit, then we stash it
// for later.
- auto* expCtx = exec->getExpCtx().get();
- BSONObj next = expCtx->needsMerge ? nextDoc.toBsonWithMetaData() : nextDoc.toBson();
+ BSONObj next =
+ exec->getExpCtx()->needsMerge ? nextDoc.toBsonWithMetaData() : nextDoc.toBson();
if (!FindCommon::haveSpaceForNext(next, objCount, responseBuilder.bytesUsed())) {
exec->enqueue(nextDoc);
stashedResult = true;
diff --git a/src/mongo/db/exec/add_fields_projection_executor.cpp b/src/mongo/db/exec/add_fields_projection_executor.cpp
index ec3acc136bc..a91f42c1408 100644
--- a/src/mongo/db/exec/add_fields_projection_executor.cpp
+++ b/src/mongo/db/exec/add_fields_projection_executor.cpp
@@ -247,7 +247,7 @@ void AddFieldsProjectionExecutor::parse(const BSONObj& spec) {
// This is a literal or regular value.
_root->addExpressionForPath(
FieldPath(elem.fieldName()),
- Expression::parseOperand(_expCtx, elem, _expCtx->variablesParseState));
+ Expression::parseOperand(_expCtx.get(), elem, _expCtx->variablesParseState));
}
}
}
@@ -270,7 +270,7 @@ bool AddFieldsProjectionExecutor::parseObjectAsExpression(
// This is an expression like {$add: [...]}. We already verified that it has only one field.
invariant(objSpec.nFields() == 1);
_root->addExpressionForPath(
- pathToObject, Expression::parseExpression(_expCtx, objSpec, variablesParseState));
+ pathToObject, Expression::parseExpression(_expCtx.get(), objSpec, variablesParseState));
return true;
}
return false;
@@ -300,7 +300,7 @@ void AddFieldsProjectionExecutor::parseSubObject(const BSONObj& subObj,
// This is a literal or regular value.
node->addExpressionForPath(
FieldPath(elem.fieldName()),
- Expression::parseOperand(_expCtx, elem, variablesParseState));
+ Expression::parseOperand(_expCtx.get(), elem, variablesParseState));
}
}
}
diff --git a/src/mongo/db/exec/find_projection_executor_test.cpp b/src/mongo/db/exec/find_projection_executor_test.cpp
index c0baf7a01fd..0940ef96be5 100644
--- a/src/mongo/db/exec/find_projection_executor_test.cpp
+++ b/src/mongo/db/exec/find_projection_executor_test.cpp
@@ -56,16 +56,17 @@ protected:
const BSONObj& matchSpec,
const std::string& path,
const Document& input) {
- auto executor = createProjectionExecutor(getExpCtx(), projSpec, {});
+ auto executor = createProjectionExecutor(getExpCtxRaw(), projSpec, {});
auto matchExpr = CopyableMatchExpression{matchSpec,
- getExpCtx(),
+ getExpCtxRaw(),
std::make_unique<ExtensionsCallbackNoop>(),
MatchExpressionParser::kBanAllSpecialFeatures};
auto expr = make_intrusive<ExpressionInternalFindPositional>(
- getExpCtx(),
- ExpressionFieldPath::parse(getExpCtx(), "$$ROOT", getExpCtx()->variablesParseState),
- ExpressionFieldPath::parse(
- getExpCtx(), "$$" + kProjectionPostImageVarName, getExpCtx()->variablesParseState),
+ getExpCtxRaw(),
+ ExpressionFieldPath::parse(getExpCtxRaw(), "$$ROOT", getExpCtx()->variablesParseState),
+ ExpressionFieldPath::parse(getExpCtxRaw(),
+ "$$" + kProjectionPostImageVarName,
+ getExpCtx()->variablesParseState),
path,
std::move(matchExpr));
executor->setRootReplacementExpression(expr);
@@ -80,11 +81,12 @@ protected:
boost::optional<int> skip,
int limit,
const Document& input) {
- auto executor = createProjectionExecutor(getExpCtx(), projSpec, {});
+ auto executor = createProjectionExecutor(getExpCtxRaw(), projSpec, {});
auto expr = make_intrusive<ExpressionInternalFindSlice>(
- getExpCtx(),
- ExpressionFieldPath::parse(
- getExpCtx(), "$$" + kProjectionPostImageVarName, getExpCtx()->variablesParseState),
+ getExpCtxRaw(),
+ ExpressionFieldPath::parse(getExpCtxRaw(),
+ "$$" + kProjectionPostImageVarName,
+ getExpCtx()->variablesParseState),
path,
skip,
limit);
@@ -116,17 +118,17 @@ TEST_F(PositionalProjectionExecutionTest, AppliesProjectionToPreImage) {
}
TEST_F(PositionalProjectionExecutionTest, ShouldAddInclusionFieldsAndWholeDocumentToDependencies) {
- auto executor = createProjectionExecutor(getExpCtx(), fromjson("{bar: 1, _id: 0}"), {});
+ auto executor = createProjectionExecutor(getExpCtxRaw(), fromjson("{bar: 1, _id: 0}"), {});
auto matchSpec = fromjson("{bar: 1, 'foo.bar': {$gte: 5}}");
auto matchExpr = CopyableMatchExpression{matchSpec,
- getExpCtx(),
+ getExpCtxRaw(),
std::make_unique<ExtensionsCallbackNoop>(),
MatchExpressionParser::kBanAllSpecialFeatures};
auto expr = make_intrusive<ExpressionInternalFindPositional>(
- getExpCtx(),
- ExpressionFieldPath::parse(getExpCtx(), "$$ROOT", getExpCtx()->variablesParseState),
+ getExpCtxRaw(),
+ ExpressionFieldPath::parse(getExpCtxRaw(), "$$ROOT", getExpCtx()->variablesParseState),
ExpressionFieldPath::parse(
- getExpCtx(), "$$" + kProjectionPostImageVarName, getExpCtx()->variablesParseState),
+ getExpCtxRaw(), "$$" + kProjectionPostImageVarName, getExpCtx()->variablesParseState),
"foo.bar",
std::move(matchExpr));
executor->setRootReplacementExpression(expr);
@@ -141,17 +143,17 @@ TEST_F(PositionalProjectionExecutionTest, ShouldAddInclusionFieldsAndWholeDocume
}
TEST_F(PositionalProjectionExecutionTest, ShouldConsiderAllPathsAsModified) {
- auto executor = createProjectionExecutor(getExpCtx(), fromjson("{bar: 1, _id: 0}"), {});
+ auto executor = createProjectionExecutor(getExpCtxRaw(), fromjson("{bar: 1, _id: 0}"), {});
auto matchSpec = fromjson("{bar: 1, 'foo.bar': {$gte: 5}}");
auto matchExpr = CopyableMatchExpression{matchSpec,
- getExpCtx(),
+ getExpCtxRaw(),
std::make_unique<ExtensionsCallbackNoop>(),
MatchExpressionParser::kBanAllSpecialFeatures};
auto expr = make_intrusive<ExpressionInternalFindPositional>(
- getExpCtx(),
- ExpressionFieldPath::parse(getExpCtx(), "$$ROOT", getExpCtx()->variablesParseState),
+ getExpCtxRaw(),
+ ExpressionFieldPath::parse(getExpCtxRaw(), "$$ROOT", getExpCtx()->variablesParseState),
ExpressionFieldPath::parse(
- getExpCtx(), "$$" + kProjectionPostImageVarName, getExpCtx()->variablesParseState),
+ getExpCtxRaw(), "$$" + kProjectionPostImageVarName, getExpCtx()->variablesParseState),
"foo.bar",
std::move(matchExpr));
executor->setRootReplacementExpression(expr);
@@ -184,21 +186,21 @@ TEST_F(SliceProjectionExecutionTest, AppliesProjectionToPostImage) {
}
TEST_F(SliceProjectionExecutionTest, CanApplySliceAndPositionalProjectionsTogether) {
- auto executor = createProjectionExecutor(getExpCtx(), fromjson("{foo: 1, bar: 1}"), {});
+ auto executor = createProjectionExecutor(getExpCtxRaw(), fromjson("{foo: 1, bar: 1}"), {});
auto matchSpec = fromjson("{foo: {$gte: 3}}");
auto matchExpr = CopyableMatchExpression{matchSpec,
- getExpCtx(),
+ getExpCtxRaw(),
std::make_unique<ExtensionsCallbackNoop>(),
MatchExpressionParser::kBanAllSpecialFeatures};
auto positionalExpr = make_intrusive<ExpressionInternalFindPositional>(
- getExpCtx(),
- ExpressionFieldPath::parse(getExpCtx(), "$$ROOT", getExpCtx()->variablesParseState),
+ getExpCtxRaw(),
+ ExpressionFieldPath::parse(getExpCtxRaw(), "$$ROOT", getExpCtx()->variablesParseState),
ExpressionFieldPath::parse(
- getExpCtx(), "$$" + kProjectionPostImageVarName, getExpCtx()->variablesParseState),
+ getExpCtxRaw(), "$$" + kProjectionPostImageVarName, getExpCtx()->variablesParseState),
"foo",
std::move(matchExpr));
auto sliceExpr =
- make_intrusive<ExpressionInternalFindSlice>(getExpCtx(), positionalExpr, "bar", 1, 1);
+ make_intrusive<ExpressionInternalFindSlice>(getExpCtxRaw(), positionalExpr, "bar", 1, 1);
executor->setRootReplacementExpression(sliceExpr);
ASSERT_DOCUMENT_EQ(
@@ -215,11 +217,11 @@ TEST_F(SliceProjectionExecutionTest, CanApplySliceWithExclusionProjection) {
TEST_F(SliceProjectionExecutionTest,
ShouldAddFieldsAndWholeDocumentToDependenciesWithInclusionProjection) {
- auto executor = createProjectionExecutor(getExpCtx(), fromjson("{bar: 1, _id: 0}"), {});
+ auto executor = createProjectionExecutor(getExpCtxRaw(), fromjson("{bar: 1, _id: 0}"), {});
auto expr = make_intrusive<ExpressionInternalFindSlice>(
- getExpCtx(),
+ getExpCtxRaw(),
ExpressionFieldPath::parse(
- getExpCtx(), "$$" + kProjectionPostImageVarName, getExpCtx()->variablesParseState),
+ getExpCtxRaw(), "$$" + kProjectionPostImageVarName, getExpCtx()->variablesParseState),
"foo.bar",
1,
1);
@@ -234,11 +236,11 @@ TEST_F(SliceProjectionExecutionTest,
}
TEST_F(SliceProjectionExecutionTest, ShouldConsiderAllPathsAsModifiedWithInclusionProjection) {
- auto executor = createProjectionExecutor(getExpCtx(), fromjson("{bar: 1}"), {});
+ auto executor = createProjectionExecutor(getExpCtxRaw(), fromjson("{bar: 1}"), {});
auto expr = make_intrusive<ExpressionInternalFindSlice>(
- getExpCtx(),
+ getExpCtxRaw(),
ExpressionFieldPath::parse(
- getExpCtx(), "$$" + kProjectionPostImageVarName, getExpCtx()->variablesParseState),
+ getExpCtxRaw(), "$$" + kProjectionPostImageVarName, getExpCtx()->variablesParseState),
"foo.bar",
1,
1);
@@ -249,11 +251,11 @@ TEST_F(SliceProjectionExecutionTest, ShouldConsiderAllPathsAsModifiedWithInclusi
}
TEST_F(SliceProjectionExecutionTest, ShouldConsiderAllPathsAsModifiedWithExclusionProjection) {
- auto executor = createProjectionExecutor(getExpCtx(), fromjson("{bar: 0}"), {});
+ auto executor = createProjectionExecutor(getExpCtxRaw(), fromjson("{bar: 0}"), {});
auto expr = make_intrusive<ExpressionInternalFindSlice>(
- getExpCtx(),
+ getExpCtxRaw(),
ExpressionFieldPath::parse(
- getExpCtx(), "$$" + kProjectionPostImageVarName, getExpCtx()->variablesParseState),
+ getExpCtxRaw(), "$$" + kProjectionPostImageVarName, getExpCtx()->variablesParseState),
"foo.bar",
1,
1);
@@ -264,11 +266,11 @@ TEST_F(SliceProjectionExecutionTest, ShouldConsiderAllPathsAsModifiedWithExclusi
}
TEST_F(SliceProjectionExecutionTest, ShouldAddWholeDocumentToDependenciesWithExclusionProjection) {
- auto executor = createProjectionExecutor(getExpCtx(), fromjson("{bar: 0}"), {});
+ auto executor = createProjectionExecutor(getExpCtxRaw(), fromjson("{bar: 0}"), {});
auto expr = make_intrusive<ExpressionInternalFindSlice>(
- getExpCtx(),
+ getExpCtxRaw(),
ExpressionFieldPath::parse(
- getExpCtx(), "$$" + kProjectionPostImageVarName, getExpCtx()->variablesParseState),
+ getExpCtxRaw(), "$$" + kProjectionPostImageVarName, getExpCtx()->variablesParseState),
"foo.bar",
1,
1);
diff --git a/src/mongo/db/exec/projection_executor_builder.cpp b/src/mongo/db/exec/projection_executor_builder.cpp
index d8ff0f6dfb6..cd0e3cb49b4 100644
--- a/src/mongo/db/exec/projection_executor_builder.cpp
+++ b/src/mongo/db/exec/projection_executor_builder.cpp
@@ -76,15 +76,17 @@ using ProjectionExecutorVisitorContext =
template <typename Executor>
auto makeProjectionPreImageExpression(const ProjectionExecutorVisitorData<Executor>& data) {
- return ExpressionFieldPath::parse(data.expCtx, "$$ROOT", data.expCtx->variablesParseState);
+ return ExpressionFieldPath::parse(
+ data.expCtx.get(), "$$ROOT", data.expCtx->variablesParseState);
}
template <typename Executor>
auto makeProjectionPostImageExpression(const ProjectionExecutorVisitorData<Executor>& data) {
return data.rootReplacementExpression
? data.rootReplacementExpression
- : ExpressionFieldPath::parse(
- data.expCtx, "$$" + kProjectionPostImageVarName, data.expCtx->variablesParseState);
+ : ExpressionFieldPath::parse(data.expCtx.get(),
+ "$$" + kProjectionPostImageVarName,
+ data.expCtx->variablesParseState);
}
/**
@@ -106,7 +108,7 @@ auto createFindPositionalExpression(const projection_ast::ProjectionPositionalAS
exact_pointer_cast<projection_ast::MatchExpressionASTNode*>(children[0].get());
invariant(matchExprNode);
- return make_intrusive<ExpressionInternalFindPositional>(data.expCtx,
+ return make_intrusive<ExpressionInternalFindPositional>(data.expCtx.get(),
makeProjectionPreImageExpression(data),
makeProjectionPostImageExpression(data),
path,
@@ -125,8 +127,11 @@ auto createFindSliceExpression(const projection_ast::ProjectionSliceASTNode* nod
const FieldPath& path) {
invariant(node);
- return make_intrusive<ExpressionInternalFindSlice>(
- data.expCtx, makeProjectionPostImageExpression(data), path, node->skip(), node->limit());
+ return make_intrusive<ExpressionInternalFindSlice>(data.expCtx.get(),
+ makeProjectionPostImageExpression(data),
+ path,
+ node->skip(),
+ node->limit());
}
/**
@@ -146,7 +151,7 @@ auto createFindElemMatchExpression(const projection_ast::ProjectionElemMatchASTN
exact_pointer_cast<projection_ast::MatchExpressionASTNode*>(children[0].get());
invariant(matchExprNode);
- return make_intrusive<ExpressionInternalFindElemMatch>(data.expCtx,
+ return make_intrusive<ExpressionInternalFindElemMatch>(data.expCtx.get(),
makeProjectionPreImageExpression(data),
path,
matchExprNode->matchExpression());
diff --git a/src/mongo/db/exec/projection_executor_test.cpp b/src/mongo/db/exec/projection_executor_test.cpp
index 3c6fea2808e..0ae80010b3e 100644
--- a/src/mongo/db/exec/projection_executor_test.cpp
+++ b/src/mongo/db/exec/projection_executor_test.cpp
@@ -569,9 +569,9 @@ TEST(ProjectionExecutorType, ShouldCoerceNumericsToBools) {
}
TEST(ProjectionExecutorType, GetExpressionForPathGetsTopLevelExpression) {
- const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto projectObj = BSON("$add" << BSON_ARRAY(BSON("$const" << 1) << BSON("$const" << 3)));
- auto expr = Expression::parseObject(expCtx, projectObj, expCtx->variablesParseState);
+ auto expr = Expression::parseObject(&expCtx, projectObj, expCtx.variablesParseState);
ProjectionPolicies defaultPolicies;
auto node = InclusionNode(defaultPolicies);
node.addExpressionForPath(FieldPath("key"), expr);
@@ -580,11 +580,11 @@ TEST(ProjectionExecutorType, GetExpressionForPathGetsTopLevelExpression) {
}
TEST(ProjectionExecutorType, GetExpressionForPathGetsCorrectTopLevelExpression) {
- const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto correctObj = BSON("$add" << BSON_ARRAY(BSON("$const" << 1) << BSON("$const" << 3)));
auto incorrectObj = BSON("$add" << BSON_ARRAY(BSON("$const" << 2) << BSON("$const" << 4)));
- auto correctExpr = Expression::parseObject(expCtx, correctObj, expCtx->variablesParseState);
- auto incorrectExpr = Expression::parseObject(expCtx, incorrectObj, expCtx->variablesParseState);
+ auto correctExpr = Expression::parseObject(&expCtx, correctObj, expCtx.variablesParseState);
+ auto incorrectExpr = Expression::parseObject(&expCtx, incorrectObj, expCtx.variablesParseState);
ProjectionPolicies defaultPolicies;
auto node = InclusionNode(defaultPolicies);
node.addExpressionForPath(FieldPath("key"), correctExpr);
@@ -594,9 +594,9 @@ TEST(ProjectionExecutorType, GetExpressionForPathGetsCorrectTopLevelExpression)
}
TEST(ProjectionExecutorType, GetExpressionForPathGetsNonTopLevelExpression) {
- const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto projectObj = BSON("$add" << BSON_ARRAY(BSON("$const" << 1) << BSON("$const" << 3)));
- auto expr = Expression::parseObject(expCtx, projectObj, expCtx->variablesParseState);
+ auto expr = Expression::parseObject(&expCtx, projectObj, expCtx.variablesParseState);
ProjectionPolicies defaultPolicies;
auto node = InclusionNode(defaultPolicies);
node.addExpressionForPath(FieldPath("key.second"), expr);
diff --git a/src/mongo/db/matcher/expression_expr.cpp b/src/mongo/db/matcher/expression_expr.cpp
index 01f3affa84c..e649e22450a 100644
--- a/src/mongo/db/matcher/expression_expr.cpp
+++ b/src/mongo/db/matcher/expression_expr.cpp
@@ -43,7 +43,7 @@ ExprMatchExpression::ExprMatchExpression(boost::intrusive_ptr<Expression> expr,
ExprMatchExpression::ExprMatchExpression(BSONElement elem,
const boost::intrusive_ptr<ExpressionContext>& expCtx)
- : ExprMatchExpression(Expression::parseOperand(expCtx, elem, expCtx->variablesParseState),
+ : ExprMatchExpression(Expression::parseOperand(expCtx.get(), elem, expCtx->variablesParseState),
expCtx) {}
bool ExprMatchExpression::matches(const MatchableDocument* doc, MatchDetails* details) const {
@@ -108,8 +108,8 @@ std::unique_ptr<MatchExpression> ExprMatchExpression::shallowClone() const {
// TODO SERVER-31003: Replace Expression clone via serialization with Expression::clone().
BSONObjBuilder bob;
bob << "" << _expression->serialize(false);
- boost::intrusive_ptr<Expression> clonedExpr =
- Expression::parseOperand(_expCtx, bob.obj().firstElement(), _expCtx->variablesParseState);
+ boost::intrusive_ptr<Expression> clonedExpr = Expression::parseOperand(
+ _expCtx.get(), bob.obj().firstElement(), _expCtx->variablesParseState);
auto clone = std::make_unique<ExprMatchExpression>(std::move(clonedExpr), _expCtx);
if (_rewriteResult) {
diff --git a/src/mongo/db/matcher/extensions_callback_real.cpp b/src/mongo/db/matcher/extensions_callback_real.cpp
index 34d2dfc4a26..07fb7b38935 100644
--- a/src/mongo/db/matcher/extensions_callback_real.cpp
+++ b/src/mongo/db/matcher/extensions_callback_real.cpp
@@ -73,11 +73,11 @@ StatusWithMatchExpression ExtensionsCallbackReal::parseWhere(
// Desugar $where to $expr. The $where function is invoked through a $function expression by
// passing the document as $$CURRENT.
auto fnExpression = ExpressionFunction::createForWhere(
- expCtx,
+ expCtx.get(),
ExpressionArray::create(
- expCtx,
- make_vector<boost::intrusive_ptr<Expression>>(
- ExpressionFieldPath::parse(expCtx, "$$CURRENT", expCtx->variablesParseState))),
+ expCtx.get(),
+ make_vector<boost::intrusive_ptr<Expression>>(ExpressionFieldPath::parse(
+ expCtx.get(), "$$CURRENT", expCtx->variablesParseState))),
code,
ExpressionFunction::kJavaScript);
diff --git a/src/mongo/db/matcher/rewrite_expr_test.cpp b/src/mongo/db/matcher/rewrite_expr_test.cpp
index 6cad57f9c62..9fa64b3c70b 100644
--- a/src/mongo/db/matcher/rewrite_expr_test.cpp
+++ b/src/mongo/db/matcher/rewrite_expr_test.cpp
@@ -46,12 +46,12 @@ namespace {
* - No MatchExpression (when full or superset rewrite is not possible)
*/
void testExprRewrite(BSONObj expr, BSONObj expectedMatch) {
- boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto expression =
- Expression::parseOperand(expCtx, expr.firstElement(), expCtx->variablesParseState);
+ Expression::parseOperand(&expCtx, expr.firstElement(), expCtx.variablesParseState);
- auto result = RewriteExpr::rewrite(expression, expCtx->getCollator());
+ auto result = RewriteExpr::rewrite(expression, expCtx.getCollator());
// Confirm expected match.
if (!expectedMatch.isEmpty()) {
diff --git a/src/mongo/db/pipeline/accumulation_statement.cpp b/src/mongo/db/pipeline/accumulation_statement.cpp
index a5950af7c96..31c97af9168 100644
--- a/src/mongo/db/pipeline/accumulation_statement.cpp
+++ b/src/mongo/db/pipeline/accumulation_statement.cpp
@@ -29,6 +29,7 @@
#include "mongo/platform/basic.h"
+#include <boost/intrusive_ptr.hpp>
#include <string>
#include "mongo/db/pipeline/accumulation_statement.h"
@@ -42,7 +43,6 @@
namespace mongo {
-using boost::intrusive_ptr;
using std::string;
namespace {
@@ -88,9 +88,7 @@ boost::intrusive_ptr<AccumulatorState> AccumulationStatement::makeAccumulator()
}
AccumulationStatement AccumulationStatement::parseAccumulationStatement(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- const BSONElement& elem,
- const VariablesParseState& vps) {
+ ExpressionContext* const expCtx, const BSONElement& elem, const VariablesParseState& vps) {
auto fieldName = elem.fieldNameStringData();
uassert(40234,
str::stream() << "The field '" << fieldName << "' must be an accumulator object",
diff --git a/src/mongo/db/pipeline/accumulation_statement.h b/src/mongo/db/pipeline/accumulation_statement.h
index e49930b1c61..83f0ad5561c 100644
--- a/src/mongo/db/pipeline/accumulation_statement.h
+++ b/src/mongo/db/pipeline/accumulation_statement.h
@@ -29,8 +29,6 @@
#pragma once
-#include <boost/intrusive_ptr.hpp>
-
#include "mongo/bson/bsonelement.h"
#include "mongo/db/pipeline/accumulator.h"
#include "mongo/db/pipeline/expression.h"
@@ -129,8 +127,9 @@ struct AccumulationExpression {
* the expression to be evaluated by the accumulator and an AccumulatorState::Factory.
*/
template <class AccName>
-AccumulationExpression genericParseSingleExpressionAccumulator(
- boost::intrusive_ptr<ExpressionContext> expCtx, BSONElement elem, VariablesParseState vps) {
+AccumulationExpression genericParseSingleExpressionAccumulator(ExpressionContext* const expCtx,
+ BSONElement elem,
+ VariablesParseState vps) {
auto initializer = ExpressionConstant::create(expCtx, Value(BSONNULL));
auto argument = Expression::parseOperand(expCtx, elem, vps);
return {initializer, argument, [expCtx]() { return AccName::create(expCtx); }};
@@ -144,7 +143,7 @@ AccumulationExpression genericParseSingleExpressionAccumulator(
class AccumulationStatement {
public:
using Parser = std::function<AccumulationExpression(
- boost::intrusive_ptr<ExpressionContext>, BSONElement, VariablesParseState)>;
+ ExpressionContext* const, BSONElement, VariablesParseState)>;
AccumulationStatement(std::string fieldName, AccumulationExpression expr)
: fieldName(std::move(fieldName)), expr(std::move(expr)) {}
@@ -155,10 +154,9 @@ public:
*
* Throws an AssertionException if parsing fails.
*/
- static AccumulationStatement parseAccumulationStatement(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- const BSONElement& elem,
- const VariablesParseState& vps);
+ static AccumulationStatement parseAccumulationStatement(ExpressionContext* const expCtx,
+ const BSONElement& elem,
+ const VariablesParseState& vps);
/**
* Registers an AccumulatorState with a parsing function, so that when an accumulator with the
diff --git a/src/mongo/db/pipeline/accumulator.h b/src/mongo/db/pipeline/accumulator.h
index e59ccb543da..2e70fbf6ad4 100644
--- a/src/mongo/db/pipeline/accumulator.h
+++ b/src/mongo/db/pipeline/accumulator.h
@@ -67,7 +67,7 @@ class AccumulatorState : public RefCountable {
public:
using Factory = std::function<boost::intrusive_ptr<AccumulatorState>()>;
- AccumulatorState(const boost::intrusive_ptr<ExpressionContext>& expCtx) : _expCtx(expCtx) {}
+ AccumulatorState(ExpressionContext* const expCtx) : _expCtx(expCtx) {}
/** Marks the beginning of a new group. The input is the result of evaluating
* AccumulatorExpression::initializer, which can read from the group key.
@@ -137,7 +137,7 @@ protected:
/// Update subclass's internal state based on input
virtual void processInternal(const Value& input, bool merging) = 0;
- const boost::intrusive_ptr<ExpressionContext>& getExpressionContext() const {
+ auto getExpressionContext() const {
return _expCtx;
}
@@ -145,7 +145,7 @@ protected:
int _memUsageBytes = 0;
private:
- boost::intrusive_ptr<ExpressionContext> _expCtx;
+ ExpressionContext* _expCtx;
};
class AccumulatorAddToSet final : public AccumulatorState {
@@ -154,7 +154,7 @@ public:
* Creates a new $addToSet accumulator. If no memory limit is given, defaults to the value of
* the server parameter 'internalQueryMaxAddToSetBytes'.
*/
- AccumulatorAddToSet(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ AccumulatorAddToSet(ExpressionContext* const expCtx,
boost::optional<int> maxMemoryUsageBytes = boost::none);
void processInternal(const Value& input, bool merging) final;
@@ -162,8 +162,7 @@ public:
const char* getOpName() const final;
void reset() final;
- static boost::intrusive_ptr<AccumulatorState> create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx);
+ static boost::intrusive_ptr<AccumulatorState> create(ExpressionContext* const expCtx);
bool isAssociative() const final {
return true;
@@ -180,15 +179,14 @@ private:
class AccumulatorFirst final : public AccumulatorState {
public:
- explicit AccumulatorFirst(const boost::intrusive_ptr<ExpressionContext>& expCtx);
+ explicit AccumulatorFirst(ExpressionContext* const expCtx);
void processInternal(const Value& input, bool merging) final;
Value getValue(bool toBeMerged) final;
const char* getOpName() const final;
void reset() final;
- static boost::intrusive_ptr<AccumulatorState> create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx);
+ static boost::intrusive_ptr<AccumulatorState> create(ExpressionContext* const expCtx);
AccumulatorDocumentsNeeded documentsNeeded() const final {
return AccumulatorDocumentsNeeded::kFirstDocument;
@@ -201,15 +199,14 @@ private:
class AccumulatorLast final : public AccumulatorState {
public:
- explicit AccumulatorLast(const boost::intrusive_ptr<ExpressionContext>& expCtx);
+ explicit AccumulatorLast(ExpressionContext* const expCtx);
void processInternal(const Value& input, bool merging) final;
Value getValue(bool toBeMerged) final;
const char* getOpName() const final;
void reset() final;
- static boost::intrusive_ptr<AccumulatorState> create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx);
+ static boost::intrusive_ptr<AccumulatorState> create(ExpressionContext* const expCtx);
AccumulatorDocumentsNeeded documentsNeeded() const final {
return AccumulatorDocumentsNeeded::kLastDocument;
@@ -221,15 +218,14 @@ private:
class AccumulatorSum final : public AccumulatorState {
public:
- explicit AccumulatorSum(const boost::intrusive_ptr<ExpressionContext>& expCtx);
+ explicit AccumulatorSum(ExpressionContext* const expCtx);
void processInternal(const Value& input, bool merging) final;
Value getValue(bool toBeMerged) final;
const char* getOpName() const final;
void reset() final;
- static boost::intrusive_ptr<AccumulatorState> create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx);
+ static boost::intrusive_ptr<AccumulatorState> create(ExpressionContext* const expCtx);
bool isAssociative() const final {
return true;
@@ -252,7 +248,7 @@ public:
MAX = -1, // Used to "scale" comparison.
};
- AccumulatorMinMax(const boost::intrusive_ptr<ExpressionContext>& expCtx, Sense sense);
+ AccumulatorMinMax(ExpressionContext* const expCtx, Sense sense);
void processInternal(const Value& input, bool merging) final;
Value getValue(bool toBeMerged) final;
@@ -274,18 +270,14 @@ private:
class AccumulatorMax final : public AccumulatorMinMax {
public:
- explicit AccumulatorMax(const boost::intrusive_ptr<ExpressionContext>& expCtx)
- : AccumulatorMinMax(expCtx, MAX) {}
- static boost::intrusive_ptr<AccumulatorState> create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx);
+ explicit AccumulatorMax(ExpressionContext* const expCtx) : AccumulatorMinMax(expCtx, MAX) {}
+ static boost::intrusive_ptr<AccumulatorState> create(ExpressionContext* const expCtx);
};
class AccumulatorMin final : public AccumulatorMinMax {
public:
- explicit AccumulatorMin(const boost::intrusive_ptr<ExpressionContext>& expCtx)
- : AccumulatorMinMax(expCtx, MIN) {}
- static boost::intrusive_ptr<AccumulatorState> create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx);
+ explicit AccumulatorMin(ExpressionContext* const expCtx) : AccumulatorMinMax(expCtx, MIN) {}
+ static boost::intrusive_ptr<AccumulatorState> create(ExpressionContext* const expCtx);
};
class AccumulatorPush final : public AccumulatorState {
@@ -294,7 +286,7 @@ public:
* Creates a new $push accumulator. If no memory limit is given, defaults to the value of the
* server parameter 'internalQueryMaxPushBytes'.
*/
- AccumulatorPush(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ AccumulatorPush(ExpressionContext* const expCtx,
boost::optional<int> maxMemoryUsageBytes = boost::none);
void processInternal(const Value& input, bool merging) final;
@@ -302,8 +294,7 @@ public:
const char* getOpName() const final;
void reset() final;
- static boost::intrusive_ptr<AccumulatorState> create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx);
+ static boost::intrusive_ptr<AccumulatorState> create(ExpressionContext* const expCtx);
private:
std::vector<Value> _array;
@@ -312,15 +303,14 @@ private:
class AccumulatorAvg final : public AccumulatorState {
public:
- explicit AccumulatorAvg(const boost::intrusive_ptr<ExpressionContext>& expCtx);
+ explicit AccumulatorAvg(ExpressionContext* const expCtx);
void processInternal(const Value& input, bool merging) final;
Value getValue(bool toBeMerged) final;
const char* getOpName() const final;
void reset() final;
- static boost::intrusive_ptr<AccumulatorState> create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx);
+ static boost::intrusive_ptr<AccumulatorState> create(ExpressionContext* const expCtx);
private:
/**
@@ -337,7 +327,7 @@ private:
class AccumulatorStdDev : public AccumulatorState {
public:
- AccumulatorStdDev(const boost::intrusive_ptr<ExpressionContext>& expCtx, bool isSamp);
+ AccumulatorStdDev(ExpressionContext* const expCtx, bool isSamp);
void processInternal(const Value& input, bool merging) final;
Value getValue(bool toBeMerged) final;
@@ -353,31 +343,28 @@ private:
class AccumulatorStdDevPop final : public AccumulatorStdDev {
public:
- explicit AccumulatorStdDevPop(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit AccumulatorStdDevPop(ExpressionContext* const expCtx)
: AccumulatorStdDev(expCtx, false) {}
- static boost::intrusive_ptr<AccumulatorState> create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx);
+ static boost::intrusive_ptr<AccumulatorState> create(ExpressionContext* const expCtx);
};
class AccumulatorStdDevSamp final : public AccumulatorStdDev {
public:
- explicit AccumulatorStdDevSamp(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit AccumulatorStdDevSamp(ExpressionContext* const expCtx)
: AccumulatorStdDev(expCtx, true) {}
- static boost::intrusive_ptr<AccumulatorState> create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx);
+ static boost::intrusive_ptr<AccumulatorState> create(ExpressionContext* const expCtx);
};
class AccumulatorMergeObjects : public AccumulatorState {
public:
- AccumulatorMergeObjects(const boost::intrusive_ptr<ExpressionContext>& expCtx);
+ AccumulatorMergeObjects(ExpressionContext* const expCtx);
void processInternal(const Value& input, bool merging) final;
Value getValue(bool toBeMerged) final;
const char* getOpName() const final;
void reset() final;
- static boost::intrusive_ptr<AccumulatorState> create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx);
+ static boost::intrusive_ptr<AccumulatorState> create(ExpressionContext* const expCtx);
private:
MutableDocument _output;
diff --git a/src/mongo/db/pipeline/accumulator_add_to_set.cpp b/src/mongo/db/pipeline/accumulator_add_to_set.cpp
index 7af05eda870..d33e09b7f2d 100644
--- a/src/mongo/db/pipeline/accumulator_add_to_set.cpp
+++ b/src/mongo/db/pipeline/accumulator_add_to_set.cpp
@@ -79,7 +79,7 @@ Value AccumulatorAddToSet::getValue(bool toBeMerged) {
return Value(vector<Value>(_set.begin(), _set.end()));
}
-AccumulatorAddToSet::AccumulatorAddToSet(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+AccumulatorAddToSet::AccumulatorAddToSet(ExpressionContext* const expCtx,
boost::optional<int> maxMemoryUsageBytes)
: AccumulatorState(expCtx),
_set(expCtx->getValueComparator().makeUnorderedValueSet()),
@@ -92,8 +92,7 @@ void AccumulatorAddToSet::reset() {
_memUsageBytes = sizeof(*this);
}
-intrusive_ptr<AccumulatorState> AccumulatorAddToSet::create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx) {
+intrusive_ptr<AccumulatorState> AccumulatorAddToSet::create(ExpressionContext* const expCtx) {
return new AccumulatorAddToSet(expCtx, boost::none);
}
diff --git a/src/mongo/db/pipeline/accumulator_avg.cpp b/src/mongo/db/pipeline/accumulator_avg.cpp
index 1e7f55f5ab3..143ac643222 100644
--- a/src/mongo/db/pipeline/accumulator_avg.cpp
+++ b/src/mongo/db/pipeline/accumulator_avg.cpp
@@ -93,8 +93,7 @@ void AccumulatorAvg::processInternal(const Value& input, bool merging) {
_count++;
}
-intrusive_ptr<AccumulatorState> AccumulatorAvg::create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx) {
+intrusive_ptr<AccumulatorState> AccumulatorAvg::create(ExpressionContext* const expCtx) {
return new AccumulatorAvg(expCtx);
}
@@ -122,7 +121,7 @@ Value AccumulatorAvg::getValue(bool toBeMerged) {
return Value(_nonDecimalTotal.getDouble() / static_cast<double>(_count));
}
-AccumulatorAvg::AccumulatorAvg(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+AccumulatorAvg::AccumulatorAvg(ExpressionContext* const expCtx)
: AccumulatorState(expCtx), _isDecimal(false), _count(0) {
// This is a fixed size AccumulatorState so we never need to update this
_memUsageBytes = sizeof(*this);
diff --git a/src/mongo/db/pipeline/accumulator_first.cpp b/src/mongo/db/pipeline/accumulator_first.cpp
index b48b9e2330e..cfb22aef242 100644
--- a/src/mongo/db/pipeline/accumulator_first.cpp
+++ b/src/mongo/db/pipeline/accumulator_first.cpp
@@ -58,7 +58,7 @@ Value AccumulatorFirst::getValue(bool toBeMerged) {
return _first;
}
-AccumulatorFirst::AccumulatorFirst(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+AccumulatorFirst::AccumulatorFirst(ExpressionContext* const expCtx)
: AccumulatorState(expCtx), _haveFirst(false) {
_memUsageBytes = sizeof(*this);
}
@@ -70,8 +70,7 @@ void AccumulatorFirst::reset() {
}
-intrusive_ptr<AccumulatorState> AccumulatorFirst::create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx) {
+intrusive_ptr<AccumulatorState> AccumulatorFirst::create(ExpressionContext* const expCtx) {
return new AccumulatorFirst(expCtx);
}
} // namespace mongo
diff --git a/src/mongo/db/pipeline/accumulator_js_reduce.cpp b/src/mongo/db/pipeline/accumulator_js_reduce.cpp
index ce09c01c8a4..af34132130f 100644
--- a/src/mongo/db/pipeline/accumulator_js_reduce.cpp
+++ b/src/mongo/db/pipeline/accumulator_js_reduce.cpp
@@ -38,7 +38,7 @@ namespace mongo {
REGISTER_ACCUMULATOR(_internalJsReduce, AccumulatorInternalJsReduce::parseInternalJsReduce);
AccumulationExpression AccumulatorInternalJsReduce::parseInternalJsReduce(
- boost::intrusive_ptr<ExpressionContext> expCtx, BSONElement elem, VariablesParseState vps) {
+ ExpressionContext* const expCtx, BSONElement elem, VariablesParseState vps) {
uassert(31326,
str::stream() << kAccumulatorName << " requires a document argument, but found "
<< elem.type(),
@@ -173,7 +173,7 @@ Value AccumulatorInternalJsReduce::getValue(bool toBeMerged) {
}
boost::intrusive_ptr<AccumulatorState> AccumulatorInternalJsReduce::create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx, StringData funcSource) {
+ ExpressionContext* const expCtx, StringData funcSource) {
return make_intrusive<AccumulatorInternalJsReduce>(expCtx, funcSource);
}
@@ -194,7 +194,7 @@ Document AccumulatorInternalJsReduce::serialize(boost::intrusive_ptr<Expression>
REGISTER_ACCUMULATOR(accumulator, AccumulatorJs::parse);
boost::intrusive_ptr<AccumulatorState> AccumulatorJs::create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionContext* const expCtx,
std::string init,
std::string accumulate,
std::string merge,
@@ -206,7 +206,7 @@ boost::intrusive_ptr<AccumulatorState> AccumulatorJs::create(
namespace {
// Parses a constant expression of type String or Code.
std::string parseFunction(StringData fieldName,
- boost::intrusive_ptr<ExpressionContext> expCtx,
+ ExpressionContext* const expCtx,
BSONElement elem,
VariablesParseState vps) {
boost::intrusive_ptr<Expression> expr = Expression::parseOperand(expCtx, elem, vps);
@@ -240,7 +240,7 @@ Document AccumulatorJs::serialize(boost::intrusive_ptr<Expression> initializer,
return DOC(getOpName() << args.freeze());
}
-AccumulationExpression AccumulatorJs::parse(boost::intrusive_ptr<ExpressionContext> expCtx,
+AccumulationExpression AccumulatorJs::parse(ExpressionContext* const expCtx,
BSONElement elem,
VariablesParseState vps) {
/*
@@ -336,7 +336,7 @@ Value AccumulatorJs::getValue(bool toBeMerged) {
// Get the final value given the current accumulator state.
if (_finalize) {
- auto& expCtx = getExpressionContext();
+ auto expCtx = getExpressionContext();
auto jsExec = expCtx->getJsExecWithScope();
auto func = makeJsFunc(expCtx, *_finalize);
@@ -361,7 +361,7 @@ void AccumulatorJs::startNewGroup(Value const& input) {
// constructor, and we clear it at the end of each group (in .reset()).
invariant(!_state);
- auto& expCtx = getExpressionContext();
+ auto expCtx = getExpressionContext();
auto jsExec = expCtx->getJsExecWithScope();
auto func = makeJsFunc(expCtx, _init);
@@ -420,7 +420,7 @@ void AccumulatorJs::reducePendingCalls() {
// ($accumulator is not registered as an expression the way $sum and $avg and others are).
invariant(!_pendingCalls.empty());
- auto& expCtx = getExpressionContext();
+ auto expCtx = getExpressionContext();
auto jsExec = expCtx->getJsExecWithScope();
// Expose user functions.
diff --git a/src/mongo/db/pipeline/accumulator_js_reduce.h b/src/mongo/db/pipeline/accumulator_js_reduce.h
index 5843f893a18..fe87b2b359a 100644
--- a/src/mongo/db/pipeline/accumulator_js_reduce.h
+++ b/src/mongo/db/pipeline/accumulator_js_reduce.h
@@ -42,14 +42,14 @@ class AccumulatorInternalJsReduce final : public AccumulatorState {
public:
static constexpr auto kAccumulatorName = "$_internalJsReduce"_sd;
- static boost::intrusive_ptr<AccumulatorState> create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx, StringData funcSource);
+ static boost::intrusive_ptr<AccumulatorState> create(ExpressionContext* const expCtx,
+ StringData funcSource);
- static AccumulationExpression parseInternalJsReduce(
- boost::intrusive_ptr<ExpressionContext> expCtx, BSONElement elem, VariablesParseState vps);
+ static AccumulationExpression parseInternalJsReduce(ExpressionContext* const expCtx,
+ BSONElement elem,
+ VariablesParseState vps);
- AccumulatorInternalJsReduce(const boost::intrusive_ptr<ExpressionContext>& expCtx,
- StringData funcSource)
+ AccumulatorInternalJsReduce(ExpressionContext* const expCtx, StringData funcSource)
: AccumulatorState(expCtx), _funcSource(funcSource) {
_memUsageBytes = sizeof(*this);
}
@@ -85,14 +85,13 @@ public:
// An AccumulatorState instance only owns its "static" arguments: those that don't need to be
// evaluated per input document.
- static boost::intrusive_ptr<AccumulatorState> create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- std::string init,
- std::string accumulate,
- std::string merge,
- boost::optional<std::string> finalize);
-
- static AccumulationExpression parse(boost::intrusive_ptr<ExpressionContext> expCtx,
+ static boost::intrusive_ptr<AccumulatorState> create(ExpressionContext* const expCtx,
+ std::string init,
+ std::string accumulate,
+ std::string merge,
+ boost::optional<std::string> finalize);
+
+ static AccumulationExpression parse(ExpressionContext* const expCtx,
BSONElement elem,
VariablesParseState vps);
@@ -106,7 +105,7 @@ public:
void startNewGroup(Value const& input) final;
private:
- AccumulatorJs(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ AccumulatorJs(ExpressionContext* const expCtx,
std::string init,
std::string accumulate,
std::string merge,
diff --git a/src/mongo/db/pipeline/accumulator_js_test.cpp b/src/mongo/db/pipeline/accumulator_js_test.cpp
index f2c471b5536..6ce4adae7c9 100644
--- a/src/mongo/db/pipeline/accumulator_js_test.cpp
+++ b/src/mongo/db/pipeline/accumulator_js_test.cpp
@@ -45,19 +45,19 @@ namespace {
class MapReduceFixture : public ServiceContextMongoDTest {
protected:
- MapReduceFixture() : _expCtx((new ExpressionContextForTest())) {
- _expCtx->mongoProcessInterface = std::make_shared<StandaloneProcessInterface>(nullptr);
+ MapReduceFixture() {
+ _expCtx.mongoProcessInterface = std::make_shared<StandaloneProcessInterface>(nullptr);
}
- boost::intrusive_ptr<ExpressionContextForTest>& getExpCtx() {
- return _expCtx;
+ auto getExpCtx() {
+ return &_expCtx;
}
private:
void setUp() override;
void tearDown() override;
- boost::intrusive_ptr<ExpressionContextForTest> _expCtx;
+ ExpressionContextForTest _expCtx;
};
@@ -75,7 +75,7 @@ void MapReduceFixture::tearDown() {
namespace InternalJsReduce {
template <typename AccName>
-static void assertProcessFailsWithCode(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+static void assertProcessFailsWithCode(ExpressionContext* const expCtx,
const std::string& eval,
Value processArgument,
int code) {
@@ -83,7 +83,7 @@ static void assertProcessFailsWithCode(const boost::intrusive_ptr<ExpressionCont
ASSERT_THROWS_CODE(accum->process(processArgument, false), AssertionException, code);
}
-static void assertParsingFailsWithCode(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+static void assertParsingFailsWithCode(ExpressionContext* const expCtx,
BSONElement elem,
int code) {
ASSERT_THROWS_CODE(AccumulatorInternalJsReduce::parseInternalJsReduce(
@@ -93,7 +93,7 @@ static void assertParsingFailsWithCode(const boost::intrusive_ptr<ExpressionCont
}
template <typename AccName>
-static void assertExpectedResults(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+static void assertExpectedResults(ExpressionContext* const expCtx,
const std::string& eval,
std::vector<Value> data,
Value expectedResult) {
diff --git a/src/mongo/db/pipeline/accumulator_last.cpp b/src/mongo/db/pipeline/accumulator_last.cpp
index 14362e42cab..a1dade1aefb 100644
--- a/src/mongo/db/pipeline/accumulator_last.cpp
+++ b/src/mongo/db/pipeline/accumulator_last.cpp
@@ -54,8 +54,7 @@ Value AccumulatorLast::getValue(bool toBeMerged) {
return _last;
}
-AccumulatorLast::AccumulatorLast(const boost::intrusive_ptr<ExpressionContext>& expCtx)
- : AccumulatorState(expCtx) {
+AccumulatorLast::AccumulatorLast(ExpressionContext* const expCtx) : AccumulatorState(expCtx) {
_memUsageBytes = sizeof(*this);
}
@@ -64,8 +63,7 @@ void AccumulatorLast::reset() {
_last = Value();
}
-intrusive_ptr<AccumulatorState> AccumulatorLast::create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx) {
+intrusive_ptr<AccumulatorState> AccumulatorLast::create(ExpressionContext* const expCtx) {
return new AccumulatorLast(expCtx);
}
} // namespace mongo
diff --git a/src/mongo/db/pipeline/accumulator_merge_objects.cpp b/src/mongo/db/pipeline/accumulator_merge_objects.cpp
index 6b23ae528a1..5eb03eed74b 100644
--- a/src/mongo/db/pipeline/accumulator_merge_objects.cpp
+++ b/src/mongo/db/pipeline/accumulator_merge_objects.cpp
@@ -49,13 +49,11 @@ const char* AccumulatorMergeObjects::getOpName() const {
return "$mergeObjects";
}
-intrusive_ptr<AccumulatorState> AccumulatorMergeObjects::create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx) {
+intrusive_ptr<AccumulatorState> AccumulatorMergeObjects::create(ExpressionContext* const expCtx) {
return new AccumulatorMergeObjects(expCtx);
}
-AccumulatorMergeObjects::AccumulatorMergeObjects(
- const boost::intrusive_ptr<ExpressionContext>& expCtx)
+AccumulatorMergeObjects::AccumulatorMergeObjects(ExpressionContext* const expCtx)
: AccumulatorState(expCtx) {
_memUsageBytes = sizeof(*this);
}
diff --git a/src/mongo/db/pipeline/accumulator_min_max.cpp b/src/mongo/db/pipeline/accumulator_min_max.cpp
index 265a84b7075..f6dc80f8766 100644
--- a/src/mongo/db/pipeline/accumulator_min_max.cpp
+++ b/src/mongo/db/pipeline/accumulator_min_max.cpp
@@ -69,8 +69,7 @@ Value AccumulatorMinMax::getValue(bool toBeMerged) {
return _val;
}
-AccumulatorMinMax::AccumulatorMinMax(const boost::intrusive_ptr<ExpressionContext>& expCtx,
- Sense sense)
+AccumulatorMinMax::AccumulatorMinMax(ExpressionContext* const expCtx, Sense sense)
: AccumulatorState(expCtx), _sense(sense) {
_memUsageBytes = sizeof(*this);
}
@@ -80,13 +79,11 @@ void AccumulatorMinMax::reset() {
_memUsageBytes = sizeof(*this);
}
-intrusive_ptr<AccumulatorState> AccumulatorMin::create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx) {
+intrusive_ptr<AccumulatorState> AccumulatorMin::create(ExpressionContext* const expCtx) {
return new AccumulatorMin(expCtx);
}
-intrusive_ptr<AccumulatorState> AccumulatorMax::create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx) {
+intrusive_ptr<AccumulatorState> AccumulatorMax::create(ExpressionContext* const expCtx) {
return new AccumulatorMax(expCtx);
}
} // namespace mongo
diff --git a/src/mongo/db/pipeline/accumulator_push.cpp b/src/mongo/db/pipeline/accumulator_push.cpp
index 3a004dd9731..98744314735 100644
--- a/src/mongo/db/pipeline/accumulator_push.cpp
+++ b/src/mongo/db/pipeline/accumulator_push.cpp
@@ -81,7 +81,7 @@ Value AccumulatorPush::getValue(bool toBeMerged) {
return Value(_array);
}
-AccumulatorPush::AccumulatorPush(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+AccumulatorPush::AccumulatorPush(ExpressionContext* const expCtx,
boost::optional<int> maxMemoryUsageBytes)
: AccumulatorState(expCtx),
_maxMemUsageBytes(maxMemoryUsageBytes.value_or(internalQueryMaxPushBytes.load())) {
@@ -93,8 +93,7 @@ void AccumulatorPush::reset() {
_memUsageBytes = sizeof(*this);
}
-intrusive_ptr<AccumulatorState> AccumulatorPush::create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx) {
+intrusive_ptr<AccumulatorState> AccumulatorPush::create(ExpressionContext* const expCtx) {
return new AccumulatorPush(expCtx, boost::none);
}
} // namespace mongo
diff --git a/src/mongo/db/pipeline/accumulator_std_dev.cpp b/src/mongo/db/pipeline/accumulator_std_dev.cpp
index cdd31b2c897..84588fef6f3 100644
--- a/src/mongo/db/pipeline/accumulator_std_dev.cpp
+++ b/src/mongo/db/pipeline/accumulator_std_dev.cpp
@@ -96,18 +96,15 @@ Value AccumulatorStdDev::getValue(bool toBeMerged) {
}
}
-intrusive_ptr<AccumulatorState> AccumulatorStdDevSamp::create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx) {
+intrusive_ptr<AccumulatorState> AccumulatorStdDevSamp::create(ExpressionContext* const expCtx) {
return new AccumulatorStdDevSamp(expCtx);
}
-intrusive_ptr<AccumulatorState> AccumulatorStdDevPop::create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx) {
+intrusive_ptr<AccumulatorState> AccumulatorStdDevPop::create(ExpressionContext* const expCtx) {
return new AccumulatorStdDevPop(expCtx);
}
-AccumulatorStdDev::AccumulatorStdDev(const boost::intrusive_ptr<ExpressionContext>& expCtx,
- bool isSamp)
+AccumulatorStdDev::AccumulatorStdDev(ExpressionContext* const expCtx, bool isSamp)
: AccumulatorState(expCtx), _isSamp(isSamp), _count(0), _mean(0), _m2(0) {
// This is a fixed size AccumulatorState so we never need to update this
_memUsageBytes = sizeof(*this);
diff --git a/src/mongo/db/pipeline/accumulator_sum.cpp b/src/mongo/db/pipeline/accumulator_sum.cpp
index 182f592ce3f..59f08945ef1 100644
--- a/src/mongo/db/pipeline/accumulator_sum.cpp
+++ b/src/mongo/db/pipeline/accumulator_sum.cpp
@@ -85,8 +85,7 @@ void AccumulatorSum::processInternal(const Value& input, bool merging) {
}
}
-intrusive_ptr<AccumulatorState> AccumulatorSum::create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx) {
+intrusive_ptr<AccumulatorState> AccumulatorSum::create(ExpressionContext* const expCtx) {
return new AccumulatorSum(expCtx);
}
@@ -127,8 +126,7 @@ Value AccumulatorSum::getValue(bool toBeMerged) {
}
}
-AccumulatorSum::AccumulatorSum(const boost::intrusive_ptr<ExpressionContext>& expCtx)
- : AccumulatorState(expCtx) {
+AccumulatorSum::AccumulatorSum(ExpressionContext* const expCtx) : AccumulatorState(expCtx) {
// This is a fixed size AccumulatorState so we never need to update this.
_memUsageBytes = sizeof(*this);
}
diff --git a/src/mongo/db/pipeline/accumulator_test.cpp b/src/mongo/db/pipeline/accumulator_test.cpp
index d3da839801f..dbae124306d 100644
--- a/src/mongo/db/pipeline/accumulator_test.cpp
+++ b/src/mongo/db/pipeline/accumulator_test.cpp
@@ -55,7 +55,7 @@ using std::string;
*/
template <typename AccName>
static void assertExpectedResults(
- const intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionContext* const expCtx,
std::initializer_list<std::pair<std::vector<Value>, Value>> operations) {
for (auto&& op : operations) {
try {
@@ -103,9 +103,9 @@ static void assertExpectedResults(
}
TEST(Accumulators, Avg) {
- intrusive_ptr<ExpressionContext> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
assertExpectedResults<AccumulatorAvg>(
- expCtx,
+ &expCtx,
{
// No documents evaluated.
{{}, Value(BSONNULL)},
@@ -158,9 +158,9 @@ TEST(Accumulators, Avg) {
}
TEST(Accumulators, First) {
- intrusive_ptr<ExpressionContext> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
assertExpectedResults<AccumulatorFirst>(
- expCtx,
+ &expCtx,
{// No documents evaluated.
{{}, Value()},
@@ -176,9 +176,9 @@ TEST(Accumulators, First) {
}
TEST(Accumulators, Last) {
- intrusive_ptr<ExpressionContext> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
assertExpectedResults<AccumulatorLast>(
- expCtx,
+ &expCtx,
{// No documents evaluated.
{{}, Value()},
@@ -194,9 +194,9 @@ TEST(Accumulators, Last) {
}
TEST(Accumulators, Min) {
- intrusive_ptr<ExpressionContext> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
assertExpectedResults<AccumulatorMin>(
- expCtx,
+ &expCtx,
{// No documents evaluated.
{{}, Value(BSONNULL)},
@@ -212,18 +212,18 @@ TEST(Accumulators, Min) {
}
TEST(Accumulators, MinRespectsCollation) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto collator =
std::make_unique<CollatorInterfaceMock>(CollatorInterfaceMock::MockType::kReverseString);
- expCtx->setCollator(std::move(collator));
- assertExpectedResults<AccumulatorMin>(expCtx,
+ expCtx.setCollator(std::move(collator));
+ assertExpectedResults<AccumulatorMin>(&expCtx,
{{{Value("abc"_sd), Value("cba"_sd)}, Value("cba"_sd)}});
}
TEST(Accumulators, Max) {
- intrusive_ptr<ExpressionContext> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
assertExpectedResults<AccumulatorMax>(
- expCtx,
+ &expCtx,
{// No documents evaluated.
{{}, Value(BSONNULL)},
@@ -239,18 +239,18 @@ TEST(Accumulators, Max) {
}
TEST(Accumulators, MaxRespectsCollation) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto collator =
std::make_unique<CollatorInterfaceMock>(CollatorInterfaceMock::MockType::kReverseString);
- expCtx->setCollator(std::move(collator));
- assertExpectedResults<AccumulatorMax>(expCtx,
+ expCtx.setCollator(std::move(collator));
+ assertExpectedResults<AccumulatorMax>(&expCtx,
{{{Value("abc"_sd), Value("cba"_sd)}, Value("abc"_sd)}});
}
TEST(Accumulators, Sum) {
- intrusive_ptr<ExpressionContext> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
assertExpectedResults<AccumulatorSum>(
- expCtx,
+ &expCtx,
{// No documents evaluated.
{{}, Value(0)},
@@ -337,19 +337,19 @@ TEST(Accumulators, Sum) {
}
TEST(Accumulators, AddToSetRespectsCollation) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto collator =
std::make_unique<CollatorInterfaceMock>(CollatorInterfaceMock::MockType::kAlwaysEqual);
- expCtx->setCollator(std::move(collator));
- assertExpectedResults<AccumulatorAddToSet>(expCtx,
+ expCtx.setCollator(std::move(collator));
+ assertExpectedResults<AccumulatorAddToSet>(&expCtx,
{{{Value("a"_sd), Value("b"_sd), Value("c"_sd)},
Value(std::vector<Value>{Value("a"_sd)})}});
}
TEST(Accumulators, AddToSetRespectsMaxMemoryConstraint) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
const int maxMemoryBytes = 20ull;
- auto addToSet = AccumulatorAddToSet(expCtx, maxMemoryBytes);
+ auto addToSet = AccumulatorAddToSet(&expCtx, maxMemoryBytes);
ASSERT_THROWS_CODE(
addToSet.process(
Value("This is a large string. Certainly we must be over 20 bytes by now"_sd), false),
@@ -358,9 +358,9 @@ TEST(Accumulators, AddToSetRespectsMaxMemoryConstraint) {
}
TEST(Accumulators, PushRespectsMaxMemoryConstraint) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
const int maxMemoryBytes = 20ull;
- auto addToSet = AccumulatorPush(expCtx, maxMemoryBytes);
+ auto addToSet = AccumulatorPush(&expCtx, maxMemoryBytes);
ASSERT_THROWS_CODE(
addToSet.process(
Value("This is a large string. Certainly we must be over 20 bytes by now"_sd), false),
@@ -371,52 +371,52 @@ TEST(Accumulators, PushRespectsMaxMemoryConstraint) {
/* ------------------------- AccumulatorMergeObjects -------------------------- */
TEST(AccumulatorMergeObjects, MergingZeroObjectsShouldReturnEmptyDocument) {
- intrusive_ptr<ExpressionContext> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
- assertExpectedResults<AccumulatorMergeObjects>(expCtx, {{{}, {Value(Document({}))}}});
+ assertExpectedResults<AccumulatorMergeObjects>(&expCtx, {{{}, {Value(Document({}))}}});
}
TEST(AccumulatorMergeObjects, MergingWithSingleObjectShouldLeaveUnchanged) {
- intrusive_ptr<ExpressionContext> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
- assertExpectedResults<AccumulatorMergeObjects>(expCtx, {{{}, {Value(Document({}))}}});
+ assertExpectedResults<AccumulatorMergeObjects>(&expCtx, {{{}, {Value(Document({}))}}});
auto doc = Value(Document({{"a", 1}, {"b", 1}}));
- assertExpectedResults<AccumulatorMergeObjects>(expCtx, {{{doc}, doc}});
+ assertExpectedResults<AccumulatorMergeObjects>(&expCtx, {{{doc}, doc}});
}
TEST(AccumulatorMergeObjects, MergingDisjointObjectsShouldIncludeAllFields) {
- intrusive_ptr<ExpressionContext> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto first = Value(Document({{"a", 1}, {"b", 1}}));
auto second = Value(Document({{"c", 1}}));
assertExpectedResults<AccumulatorMergeObjects>(
- expCtx, {{{first, second}, Value(Document({{"a", 1}, {"b", 1}, {"c", 1}}))}});
+ &expCtx, {{{first, second}, Value(Document({{"a", 1}, {"b", 1}, {"c", 1}}))}});
}
TEST(AccumulatorMergeObjects, MergingIntersectingObjectsShouldOverrideInOrderReceived) {
- intrusive_ptr<ExpressionContext> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto first = Value(Document({{"a", "oldValue"_sd}, {"b", 0}, {"c", 1}}));
auto second = Value(Document({{"a", "newValue"_sd}}));
assertExpectedResults<AccumulatorMergeObjects>(
- expCtx, {{{first, second}, Value(Document({{"a", "newValue"_sd}, {"b", 0}, {"c", 1}}))}});
+ &expCtx, {{{first, second}, Value(Document({{"a", "newValue"_sd}, {"b", 0}, {"c", 1}}))}});
}
TEST(AccumulatorMergeObjects, MergingIntersectingEmbeddedObjectsShouldOverrideInOrderReceived) {
- intrusive_ptr<ExpressionContext> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto firstSubDoc = Document({{"a", 1}, {"b", 2}, {"c", 3}});
auto secondSubDoc = Document({{"a", 2}, {"b", 1}});
auto first = Value(Document({{"d", 1}, {"subDoc", firstSubDoc}}));
auto second = Value(Document({{"subDoc", secondSubDoc}}));
auto expected = Value(Document({{"d", 1}, {"subDoc", secondSubDoc}}));
- assertExpectedResults<AccumulatorMergeObjects>(expCtx, {{{first, second}, expected}});
+ assertExpectedResults<AccumulatorMergeObjects>(&expCtx, {{{first, second}, expected}});
}
TEST(AccumulatorMergeObjects, MergingWithEmptyDocumentShouldIgnore) {
- intrusive_ptr<ExpressionContext> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
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<AccumulatorMergeObjects>(expCtx, {{{first, second}, expected}});
+ assertExpectedResults<AccumulatorMergeObjects>(&expCtx, {{{first, second}, expected}});
}
} // namespace AccumulatorTests
diff --git a/src/mongo/db/pipeline/aggregation_context_fixture.h b/src/mongo/db/pipeline/aggregation_context_fixture.h
index cd7d2887e99..287caae977c 100644
--- a/src/mongo/db/pipeline/aggregation_context_fixture.h
+++ b/src/mongo/db/pipeline/aggregation_context_fixture.h
@@ -53,11 +53,15 @@ public:
_expCtx->tempDir = tempDir.path();
}
- boost::intrusive_ptr<ExpressionContextForTest> getExpCtx() {
+ auto getExpCtx() {
return _expCtx;
}
- OperationContext* getOpCtx() {
+ auto getExpCtxRaw() {
+ return _expCtx.get();
+ }
+
+ auto getOpCtx() {
return _opCtx.get();
}
diff --git a/src/mongo/db/pipeline/document_source_bucket.cpp b/src/mongo/db/pipeline/document_source_bucket.cpp
index 3245d21b742..73386201792 100644
--- a/src/mongo/db/pipeline/document_source_bucket.cpp
+++ b/src/mongo/db/pipeline/document_source_bucket.cpp
@@ -45,10 +45,9 @@ REGISTER_MULTI_STAGE_ALIAS(bucket,
DocumentSourceBucket::createFromBson);
namespace {
-intrusive_ptr<ExpressionConstant> getExpressionConstant(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expressionElem,
- const VariablesParseState& vps) {
+intrusive_ptr<ExpressionConstant> getExpressionConstant(ExpressionContext* const expCtx,
+ BSONElement expressionElem,
+ const VariablesParseState& vps) {
auto expr = Expression::parseOperand(expCtx, expressionElem, vps)->optimize();
return dynamic_cast<ExpressionConstant*>(expr.get());
}
@@ -95,7 +94,7 @@ list<intrusive_ptr<DocumentSource>> DocumentSourceBucket::createFromBson(
argument.type() == BSONType::Array);
for (auto&& boundaryElem : argument.embeddedObject()) {
- auto exprConst = getExpressionConstant(pExpCtx, boundaryElem, vps);
+ auto exprConst = getExpressionConstant(pExpCtx.get(), boundaryElem, vps);
uassert(40191,
str::stream() << "The $bucket 'boundaries' field must be an array of "
"constant values, but found value: "
@@ -134,7 +133,7 @@ list<intrusive_ptr<DocumentSource>> DocumentSourceBucket::createFromBson(
} else if ("default" == argName) {
// If there is a default, make sure that it parses to a constant expression then add
// default to switch.
- auto exprConst = getExpressionConstant(pExpCtx, argument, vps);
+ auto exprConst = getExpressionConstant(pExpCtx.get(), argument, vps);
uassert(40195,
str::stream()
<< "The $bucket 'default' field must be a constant expression, but found: "
diff --git a/src/mongo/db/pipeline/document_source_bucket_auto.cpp b/src/mongo/db/pipeline/document_source_bucket_auto.cpp
index c6decbca69c..29199b451c9 100644
--- a/src/mongo/db/pipeline/document_source_bucket_auto.cpp
+++ b/src/mongo/db/pipeline/document_source_bucket_auto.cpp
@@ -53,10 +53,10 @@ boost::intrusive_ptr<Expression> parseGroupByExpression(
const VariablesParseState& vps) {
if (groupByField.type() == BSONType::Object &&
groupByField.embeddedObject().firstElementFieldName()[0] == '$') {
- return Expression::parseObject(expCtx, groupByField.embeddedObject(), vps);
+ return Expression::parseObject(expCtx.get(), groupByField.embeddedObject(), vps);
} else if (groupByField.type() == BSONType::String &&
groupByField.valueStringData()[0] == '$') {
- return ExpressionFieldPath::parse(expCtx, groupByField.str(), vps);
+ return ExpressionFieldPath::parse(expCtx.get(), groupByField.str(), vps);
} else {
uasserted(
40239,
@@ -431,9 +431,9 @@ intrusive_ptr<DocumentSourceBucketAuto> DocumentSourceBucketAuto::create(
if (accumulationStatements.empty()) {
accumulationStatements.emplace_back(
"count",
- AccumulationExpression(ExpressionConstant::create(pExpCtx, Value(BSONNULL)),
- ExpressionConstant::create(pExpCtx, Value(1)),
- [pExpCtx] { return AccumulatorSum::create(pExpCtx); }));
+ AccumulationExpression(ExpressionConstant::create(pExpCtx.get(), Value(BSONNULL)),
+ ExpressionConstant::create(pExpCtx.get(), Value(1)),
+ [pExpCtx] { return AccumulatorSum::create(pExpCtx.get()); }));
}
return new DocumentSourceBucketAuto(pExpCtx,
groupByExpression,
@@ -512,8 +512,8 @@ intrusive_ptr<DocumentSource> DocumentSourceBucketAuto::createFromBson(
argument.type() == BSONType::Object);
for (auto&& outputField : argument.embeddedObject()) {
- auto stmt =
- AccumulationStatement::parseAccumulationStatement(pExpCtx, outputField, vps);
+ auto stmt = AccumulationStatement::parseAccumulationStatement(
+ pExpCtx.get(), outputField, vps);
stmt.expr.initializer = stmt.expr.initializer->optimize();
uassert(4544714,
"Can't refer to the group key in $bucketAuto",
diff --git a/src/mongo/db/pipeline/document_source_bucket_auto_test.cpp b/src/mongo/db/pipeline/document_source_bucket_auto_test.cpp
index 970f8ecdfd7..09db9c459b4 100644
--- a/src/mongo/db/pipeline/document_source_bucket_auto_test.cpp
+++ b/src/mongo/db/pipeline/document_source_bucket_auto_test.cpp
@@ -357,7 +357,7 @@ TEST_F(BucketAutoTests, ShouldBeAbleToCorrectlySpillToDisk) {
const size_t maxMemoryUsageBytes = 1000;
VariablesParseState vps = expCtx->variablesParseState;
- auto groupByExpression = ExpressionFieldPath::parse(expCtx, "$a", vps);
+ auto groupByExpression = ExpressionFieldPath::parse(expCtx.get(), "$a", vps);
const int numBuckets = 2;
auto bucketAutoStage = DocumentSourceBucketAuto::create(
@@ -394,7 +394,7 @@ TEST_F(BucketAutoTests, ShouldBeAbleToPauseLoadingWhileSpilled) {
const size_t maxMemoryUsageBytes = 1000;
VariablesParseState vps = expCtx->variablesParseState;
- auto groupByExpression = ExpressionFieldPath::parse(expCtx, "$a", vps);
+ auto groupByExpression = ExpressionFieldPath::parse(expCtx.get(), "$a", vps);
const int numBuckets = 2;
auto bucketAutoStage = DocumentSourceBucketAuto::create(
@@ -551,7 +551,7 @@ TEST_F(BucketAutoTests, FailsWithInvalidNumberOfBuckets) {
const int numBuckets = 0;
ASSERT_THROWS_CODE(
DocumentSourceBucketAuto::create(
- getExpCtx(), ExpressionConstant::create(getExpCtx(), Value(0)), numBuckets),
+ getExpCtx(), ExpressionConstant::create(getExpCtxRaw(), Value(0)), numBuckets),
AssertionException,
40243);
}
@@ -636,7 +636,7 @@ void assertCannotSpillToDisk(const boost::intrusive_ptr<ExpressionContext>& expC
const size_t maxMemoryUsageBytes = 1000;
VariablesParseState vps = expCtx->variablesParseState;
- auto groupByExpression = ExpressionFieldPath::parse(expCtx, "$a", vps);
+ auto groupByExpression = ExpressionFieldPath::parse(expCtx.get(), "$a", vps);
const int numBuckets = 2;
auto bucketAutoStage = DocumentSourceBucketAuto::create(
@@ -675,7 +675,7 @@ TEST_F(BucketAutoTests, ShouldCorrectlyTrackMemoryUsageBetweenPauses) {
const size_t maxMemoryUsageBytes = 1000;
VariablesParseState vps = expCtx->variablesParseState;
- auto groupByExpression = ExpressionFieldPath::parse(expCtx, "$a", vps);
+ auto groupByExpression = ExpressionFieldPath::parse(expCtx.get(), "$a", vps);
const int numBuckets = 2;
auto bucketAutoStage = DocumentSourceBucketAuto::create(
diff --git a/src/mongo/db/pipeline/document_source_graph_lookup.cpp b/src/mongo/db/pipeline/document_source_graph_lookup.cpp
index 98b795217fc..a84d1773a1f 100644
--- a/src/mongo/db/pipeline/document_source_graph_lookup.cpp
+++ b/src/mongo/db/pipeline/document_source_graph_lookup.cpp
@@ -525,7 +525,7 @@ intrusive_ptr<DocumentSource> DocumentSourceGraphLookUp::createFromBson(
const auto argName = argument.fieldNameStringData();
if (argName == "startWith") {
- startWith = Expression::parseOperand(expCtx, argument, vps);
+ startWith = Expression::parseOperand(expCtx.get(), argument, vps);
continue;
} else if (argName == "maxDepth") {
uassert(40100,
diff --git a/src/mongo/db/pipeline/document_source_graph_lookup_test.cpp b/src/mongo/db/pipeline/document_source_graph_lookup_test.cpp
index 6453c4e2eb6..5d4fe741a6c 100644
--- a/src/mongo/db/pipeline/document_source_graph_lookup_test.cpp
+++ b/src/mongo/db/pipeline/document_source_graph_lookup_test.cpp
@@ -93,7 +93,7 @@ TEST_F(DocumentSourceGraphLookUpTest,
"results",
"from",
"to",
- ExpressionFieldPath::create(expCtx, "_id"),
+ ExpressionFieldPath::create(expCtx.get(), "_id"),
boost::none,
boost::none,
boost::none,
@@ -122,7 +122,7 @@ TEST_F(DocumentSourceGraphLookUpTest,
"results",
"from",
"to",
- ExpressionFieldPath::create(expCtx, "_id"),
+ ExpressionFieldPath::create(expCtx.get(), "_id"),
boost::none,
boost::none,
boost::none,
@@ -152,7 +152,7 @@ TEST_F(DocumentSourceGraphLookUpTest,
"results",
"from",
"to",
- ExpressionFieldPath::create(expCtx, "_id"),
+ ExpressionFieldPath::create(expCtx.get(), "_id"),
boost::none,
boost::none,
boost::none,
@@ -195,7 +195,7 @@ TEST_F(DocumentSourceGraphLookUpTest,
"results",
"from",
"to",
- ExpressionFieldPath::create(expCtx, "_id"),
+ ExpressionFieldPath::create(expCtx.get(), "_id"),
boost::none,
boost::none,
boost::none,
@@ -259,7 +259,7 @@ TEST_F(DocumentSourceGraphLookUpTest, ShouldPropagatePauses) {
"results",
"from",
"to",
- ExpressionFieldPath::create(expCtx, "startPoint"),
+ ExpressionFieldPath::create(expCtx.get(), "startPoint"),
boost::none,
boost::none,
boost::none,
@@ -335,7 +335,7 @@ TEST_F(DocumentSourceGraphLookUpTest, ShouldPropagatePausesWhileUnwinding) {
"results",
"from",
"to",
- ExpressionFieldPath::create(expCtx, "startPoint"),
+ ExpressionFieldPath::create(expCtx.get(), "startPoint"),
boost::none,
boost::none,
boost::none,
@@ -394,7 +394,7 @@ TEST_F(DocumentSourceGraphLookUpTest, GraphLookupShouldReportAsFieldIsModified)
"results",
"from",
"to",
- ExpressionFieldPath::create(expCtx, "startPoint"),
+ ExpressionFieldPath::create(expCtx.get(), "startPoint"),
boost::none,
boost::none,
boost::none,
@@ -421,7 +421,7 @@ TEST_F(DocumentSourceGraphLookUpTest, GraphLookupShouldReportFieldsModifiedByAbs
"results",
"from",
"to",
- ExpressionFieldPath::create(expCtx, "startPoint"),
+ ExpressionFieldPath::create(expCtx.get(), "startPoint"),
boost::none,
boost::none,
boost::none,
@@ -453,10 +453,10 @@ TEST_F(DocumentSourceGraphLookUpTest, GraphLookupWithComparisonExpressionForStar
"results",
"from",
"to",
- ExpressionCompare::create(expCtx,
+ ExpressionCompare::create(expCtx.get(),
ExpressionCompare::GT,
- ExpressionFieldPath::create(expCtx, "a"),
- ExpressionFieldPath::create(expCtx, "b")),
+ ExpressionFieldPath::create(expCtx.get(), "a"),
+ ExpressionFieldPath::create(expCtx.get(), "b")),
boost::none,
boost::none,
boost::none,
@@ -516,7 +516,7 @@ TEST_F(DocumentSourceGraphLookUpTest, ShouldExpandArraysAtEndOfConnectFromField)
"results",
"to",
"_id",
- ExpressionFieldPath::create(expCtx, "startVal"),
+ ExpressionFieldPath::create(expCtx.get(), "startVal"),
boost::none,
boost::none,
boost::none,
@@ -589,7 +589,7 @@ TEST_F(DocumentSourceGraphLookUpTest, ShouldNotExpandArraysWithinArraysAtEndOfCo
"results",
"connectedTo",
"coordinate",
- ExpressionFieldPath::create(expCtx, "startVal"),
+ ExpressionFieldPath::create(expCtx.get(), "startVal"),
boost::none,
boost::none,
boost::none,
diff --git a/src/mongo/db/pipeline/document_source_group.cpp b/src/mongo/db/pipeline/document_source_group.cpp
index 230162d2f51..582ac6c8c41 100644
--- a/src/mongo/db/pipeline/document_source_group.cpp
+++ b/src/mongo/db/pipeline/document_source_group.cpp
@@ -372,23 +372,23 @@ intrusive_ptr<Expression> parseIdExpression(const intrusive_ptr<ExpressionContex
if (groupField.type() == Object) {
// {_id: {}} is treated as grouping on a constant, not an expression
if (groupField.Obj().isEmpty()) {
- return ExpressionConstant::create(expCtx, Value(groupField));
+ return ExpressionConstant::create(expCtx.get(), Value(groupField));
}
const BSONObj idKeyObj = groupField.Obj();
if (idKeyObj.firstElementFieldName()[0] == '$') {
// grouping on a $op expression
- return Expression::parseObject(expCtx, idKeyObj, vps);
+ return Expression::parseObject(expCtx.get(), idKeyObj, vps);
} else {
for (auto&& field : idKeyObj) {
uassert(17390,
"$group does not support inclusion-style expressions",
!field.isNumber() && field.type() != Bool);
}
- return ExpressionObject::parse(expCtx, idKeyObj, vps);
+ return ExpressionObject::parse(expCtx.get(), idKeyObj, vps);
}
} else {
- return Expression::parseOperand(expCtx, groupField, vps);
+ return Expression::parseOperand(expCtx.get(), groupField, vps);
}
}
@@ -437,7 +437,7 @@ intrusive_ptr<DocumentSource> DocumentSourceGroup::createFromBson(
} else {
// Any other field will be treated as an accumulator specification.
pGroup->addAccumulator(
- AccumulationStatement::parseAccumulationStatement(pExpCtx, groupField, vps));
+ AccumulationStatement::parseAccumulationStatement(pExpCtx.get(), groupField, vps));
}
}
@@ -707,7 +707,7 @@ boost::optional<DocumentSource::DistributedPlanLogic> DocumentSourceGroup::distr
VariablesParseState vps = pExpCtx->variablesParseState;
/* the merger will use the same grouping key */
- mergingGroup->setIdExpression(ExpressionFieldPath::parse(pExpCtx, "$$ROOT._id", vps));
+ mergingGroup->setIdExpression(ExpressionFieldPath::parse(pExpCtx.get(), "$$ROOT._id", vps));
for (auto&& accumulatedField : _accumulatedFields) {
// The merger's output field names will be the same, as will the accumulator factories.
@@ -715,8 +715,8 @@ boost::optional<DocumentSource::DistributedPlanLogic> DocumentSourceGroup::distr
// original accumulator may be collecting an expression based on a field expression or
// constant. Here, we accumulate the output of the same name from the prior group.
auto copiedAccumulatedField = accumulatedField;
- copiedAccumulatedField.expr.argument =
- ExpressionFieldPath::parse(pExpCtx, "$$ROOT." + copiedAccumulatedField.fieldName, vps);
+ copiedAccumulatedField.expr.argument = ExpressionFieldPath::parse(
+ pExpCtx.get(), "$$ROOT." + copiedAccumulatedField.fieldName, vps);
mergingGroup->addAccumulator(copiedAccumulatedField);
}
@@ -794,7 +794,7 @@ DocumentSourceGroup::rewriteGroupAsTransformOnFirstDocument() const {
}
std::vector<std::pair<std::string, boost::intrusive_ptr<Expression>>> fields;
- fields.push_back(std::make_pair("_id", ExpressionFieldPath::create(pExpCtx, groupId)));
+ fields.push_back(std::make_pair("_id", ExpressionFieldPath::create(pExpCtx.get(), groupId)));
for (auto&& accumulator : _accumulatedFields) {
fields.push_back(std::make_pair(accumulator.fieldName, accumulator.expr.argument));
diff --git a/src/mongo/db/pipeline/document_source_group_test.cpp b/src/mongo/db/pipeline/document_source_group_test.cpp
index 584052ad8f6..568f31e08ff 100644
--- a/src/mongo/db/pipeline/document_source_group_test.cpp
+++ b/src/mongo/db/pipeline/document_source_group_test.cpp
@@ -75,10 +75,10 @@ TEST_F(DocumentSourceGroupTest, ShouldBeAbleToPauseLoading) {
// This is the only way to do this in a debug build.
auto&& parser = AccumulationStatement::getParser("$sum", boost::none);
auto accumulatorArg = BSON("" << 1);
- auto accExpr = parser(expCtx, accumulatorArg.firstElement(), expCtx->variablesParseState);
+ auto accExpr = parser(expCtx.get(), accumulatorArg.firstElement(), expCtx->variablesParseState);
AccumulationStatement countStatement{"count", accExpr};
auto group = DocumentSourceGroup::create(
- expCtx, ExpressionConstant::create(expCtx, Value(BSONNULL)), {countStatement});
+ expCtx, ExpressionConstant::create(expCtx.get(), Value(BSONNULL)), {countStatement});
auto mock =
DocumentSourceMock::createForTest({DocumentSource::GetNextResult::makePauseExecution(),
Document(),
@@ -113,10 +113,10 @@ TEST_F(DocumentSourceGroupTest, ShouldBeAbleToPauseLoadingWhileSpilled) {
auto&& parser = AccumulationStatement::getParser("$push", boost::none);
auto accumulatorArg = BSON(""
<< "$largeStr");
- auto accExpr = parser(expCtx, accumulatorArg.firstElement(), expCtx->variablesParseState);
+ auto accExpr = parser(expCtx.get(), accumulatorArg.firstElement(), expCtx->variablesParseState);
AccumulationStatement pushStatement{"spaceHog", accExpr};
auto groupByExpression =
- ExpressionFieldPath::parse(expCtx, "$_id", expCtx->variablesParseState);
+ ExpressionFieldPath::parse(expCtx.get(), "$_id", expCtx->variablesParseState);
auto group = DocumentSourceGroup::create(
expCtx, groupByExpression, {pushStatement}, maxMemoryUsageBytes);
@@ -156,10 +156,10 @@ TEST_F(DocumentSourceGroupTest, ShouldErrorIfNotAllowedToSpillToDiskAndResultSet
auto&& parser = AccumulationStatement::getParser("$push", boost::none);
auto accumulatorArg = BSON(""
<< "$largeStr");
- auto accExpr = parser(expCtx, accumulatorArg.firstElement(), expCtx->variablesParseState);
+ auto accExpr = parser(expCtx.get(), accumulatorArg.firstElement(), expCtx->variablesParseState);
AccumulationStatement pushStatement{"spaceHog", accExpr};
auto groupByExpression =
- ExpressionFieldPath::parse(expCtx, "$_id", expCtx->variablesParseState);
+ ExpressionFieldPath::parse(expCtx.get(), "$_id", expCtx->variablesParseState);
auto group = DocumentSourceGroup::create(
expCtx, groupByExpression, {pushStatement}, maxMemoryUsageBytes);
@@ -182,10 +182,10 @@ TEST_F(DocumentSourceGroupTest, ShouldCorrectlyTrackMemoryUsageBetweenPauses) {
auto&& parser = AccumulationStatement::getParser("$push", boost::none);
auto accumulatorArg = BSON(""
<< "$largeStr");
- auto accExpr = parser(expCtx, accumulatorArg.firstElement(), expCtx->variablesParseState);
+ auto accExpr = parser(expCtx.get(), accumulatorArg.firstElement(), expCtx->variablesParseState);
AccumulationStatement pushStatement{"spaceHog", accExpr};
auto groupByExpression =
- ExpressionFieldPath::parse(expCtx, "$_id", expCtx->variablesParseState);
+ ExpressionFieldPath::parse(expCtx.get(), "$_id", expCtx->variablesParseState);
auto group = DocumentSourceGroup::create(
expCtx, groupByExpression, {pushStatement}, maxMemoryUsageBytes);
@@ -209,7 +209,7 @@ TEST_F(DocumentSourceGroupTest, ShouldCorrectlyTrackMemoryUsageBetweenPauses) {
TEST_F(DocumentSourceGroupTest, ShouldReportSingleFieldGroupKeyAsARename) {
auto expCtx = getExpCtx();
VariablesParseState vps = expCtx->variablesParseState;
- auto groupByExpression = ExpressionFieldPath::parse(expCtx, "$x", vps);
+ auto groupByExpression = ExpressionFieldPath::parse(expCtx.get(), "$x", vps);
auto group = DocumentSourceGroup::create(expCtx, groupByExpression, {});
auto modifiedPathsRet = group->getModifiedPaths();
ASSERT(modifiedPathsRet.type == DocumentSource::GetModPathsReturn::Type::kAllExcept);
@@ -221,9 +221,9 @@ TEST_F(DocumentSourceGroupTest, ShouldReportSingleFieldGroupKeyAsARename) {
TEST_F(DocumentSourceGroupTest, ShouldReportMultipleFieldGroupKeysAsARename) {
auto expCtx = getExpCtx();
VariablesParseState vps = expCtx->variablesParseState;
- auto x = ExpressionFieldPath::parse(expCtx, "$x", vps);
- auto y = ExpressionFieldPath::parse(expCtx, "$y", vps);
- auto groupByExpression = ExpressionObject::create(expCtx, {{"x", x}, {"y", y}});
+ auto x = ExpressionFieldPath::parse(expCtx.get(), "$x", vps);
+ auto y = ExpressionFieldPath::parse(expCtx.get(), "$y", vps);
+ auto groupByExpression = ExpressionObject::create(expCtx.get(), {{"x", x}, {"y", y}});
auto group = DocumentSourceGroup::create(expCtx, groupByExpression, {});
auto modifiedPathsRet = group->getModifiedPaths();
ASSERT(modifiedPathsRet.type == DocumentSource::GetModPathsReturn::Type::kAllExcept);
@@ -236,7 +236,7 @@ TEST_F(DocumentSourceGroupTest, ShouldReportMultipleFieldGroupKeysAsARename) {
TEST_F(DocumentSourceGroupTest, ShouldNotReportDottedGroupKeyAsARename) {
auto expCtx = getExpCtx();
VariablesParseState vps = expCtx->variablesParseState;
- auto xDotY = ExpressionFieldPath::parse(expCtx, "$x.y", vps);
+ auto xDotY = ExpressionFieldPath::parse(expCtx.get(), "$x.y", vps);
auto group = DocumentSourceGroup::create(expCtx, xDotY, {});
auto modifiedPathsRet = group->getModifiedPaths();
ASSERT(modifiedPathsRet.type == DocumentSource::GetModPathsReturn::Type::kAllExcept);
diff --git a/src/mongo/db/pipeline/document_source_lookup.cpp b/src/mongo/db/pipeline/document_source_lookup.cpp
index 56b0cec6597..af45df02f2f 100644
--- a/src/mongo/db/pipeline/document_source_lookup.cpp
+++ b/src/mongo/db/pipeline/document_source_lookup.cpp
@@ -101,7 +101,7 @@ DocumentSourceLookUp::DocumentSourceLookUp(NamespaceString fromNs,
_letVariables.emplace_back(
varName.toString(),
- Expression::parseOperand(expCtx, varElem, expCtx->variablesParseState),
+ Expression::parseOperand(expCtx.get(), varElem, expCtx->variablesParseState),
_variablesParseState.defineVariable(varName));
}
diff --git a/src/mongo/db/pipeline/document_source_merge.cpp b/src/mongo/db/pipeline/document_source_merge.cpp
index 456d0615662..256f23f01a2 100644
--- a/src/mongo/db/pipeline/document_source_merge.cpp
+++ b/src/mongo/db/pipeline/document_source_merge.cpp
@@ -374,7 +374,7 @@ DocumentSourceMerge::DocumentSourceMerge(NamespaceString outputNs,
_letVariables->emplace(
varName.toString(),
- Expression::parseOperand(expCtx, varElem, expCtx->variablesParseState));
+ Expression::parseOperand(expCtx.get(), varElem, expCtx->variablesParseState));
}
}
}
diff --git a/src/mongo/db/pipeline/document_source_redact.cpp b/src/mongo/db/pipeline/document_source_redact.cpp
index fbb221594b6..efe6316c69b 100644
--- a/src/mongo/db/pipeline/document_source_redact.cpp
+++ b/src/mongo/db/pipeline/document_source_redact.cpp
@@ -179,7 +179,7 @@ intrusive_ptr<DocumentSource> DocumentSourceRedact::createFromBson(
Variables::Id decendId = vps.defineVariable("DESCEND");
Variables::Id pruneId = vps.defineVariable("PRUNE");
Variables::Id keepId = vps.defineVariable("KEEP");
- intrusive_ptr<Expression> expression = Expression::parseOperand(expCtx, elem, vps);
+ intrusive_ptr<Expression> expression = Expression::parseOperand(expCtx.get(), elem, vps);
intrusive_ptr<DocumentSourceRedact> source = new DocumentSourceRedact(expCtx, expression);
// TODO figure out how much of this belongs in constructor and how much here.
diff --git a/src/mongo/db/pipeline/document_source_replace_root.cpp b/src/mongo/db/pipeline/document_source_replace_root.cpp
index eda91efb23c..2d3e1de27af 100644
--- a/src/mongo/db/pipeline/document_source_replace_root.cpp
+++ b/src/mongo/db/pipeline/document_source_replace_root.cpp
@@ -86,7 +86,7 @@ intrusive_ptr<DocumentSource> DocumentSourceReplaceRoot::createFromBson(
const auto stageName = elem.fieldNameStringData();
auto newRootExpression = [&]() {
if (stageName == kAliasNameReplaceWith) {
- return Expression::parseOperand(expCtx, elem, expCtx->variablesParseState);
+ return Expression::parseOperand(expCtx.get(), elem, expCtx->variablesParseState);
}
invariant(
@@ -106,7 +106,7 @@ intrusive_ptr<DocumentSource> DocumentSourceReplaceRoot::createFromBson(
// to adapt the two.
BSONObj parsingBson = BSON("newRoot" << spec.getNewRoot());
return Expression::parseOperand(
- expCtx, parsingBson.firstElement(), expCtx->variablesParseState);
+ expCtx.get(), parsingBson.firstElement(), expCtx->variablesParseState);
}();
// Whether this was specified as $replaceWith or $replaceRoot, always use the name $replaceRoot
diff --git a/src/mongo/db/pipeline/expression.cpp b/src/mongo/db/pipeline/expression.cpp
index 55d3b0cbf3f..1ef7406c421 100644
--- a/src/mongo/db/pipeline/expression.cpp
+++ b/src/mongo/db/pipeline/expression.cpp
@@ -88,10 +88,9 @@ string Expression::removeFieldPrefix(const string& prefixedField) {
return string(pPrefixedField + 1);
}
-intrusive_ptr<Expression> Expression::parseObject(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONObj obj,
- const VariablesParseState& vps) {
+intrusive_ptr<Expression> Expression::parseObject(ExpressionContext* const expCtx,
+ BSONObj obj,
+ const VariablesParseState& vps) {
if (obj.isEmpty()) {
return ExpressionObject::create(expCtx, {});
}
@@ -124,10 +123,9 @@ void Expression::registerExpression(
parserMap[key] = {parser, requiredMinVersion};
}
-intrusive_ptr<Expression> Expression::parseExpression(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONObj obj,
- const VariablesParseState& vps) {
+intrusive_ptr<Expression> Expression::parseExpression(ExpressionContext* const expCtx,
+ BSONObj obj,
+ const VariablesParseState& vps) {
uassert(15983,
str::stream() << "An object representing an expression must have exactly one "
"field: "
@@ -157,10 +155,9 @@ intrusive_ptr<Expression> Expression::parseExpression(
return entry.parser(expCtx, obj.firstElement(), vps);
}
-Expression::ExpressionVector ExpressionNary::parseArguments(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement exprElement,
- const VariablesParseState& vps) {
+Expression::ExpressionVector ExpressionNary::parseArguments(ExpressionContext* const expCtx,
+ BSONElement exprElement,
+ const VariablesParseState& vps) {
ExpressionVector out;
if (exprElement.type() == Array) {
BSONForEach(elem, exprElement.Obj()) {
@@ -173,10 +170,9 @@ Expression::ExpressionVector ExpressionNary::parseArguments(
return out;
}
-intrusive_ptr<Expression> Expression::parseOperand(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement exprElement,
- const VariablesParseState& vps) {
+intrusive_ptr<Expression> Expression::parseOperand(ExpressionContext* const expCtx,
+ BSONElement exprElement,
+ const VariablesParseState& vps) {
BSONType type = exprElement.type();
if (type == String && exprElement.valuestr()[0] == '$') {
@@ -755,11 +751,11 @@ const char* ExpressionCeil::getOpName() const {
/* -------------------- ExpressionCoerceToBool ------------------------- */
intrusive_ptr<ExpressionCoerceToBool> ExpressionCoerceToBool::create(
- const intrusive_ptr<ExpressionContext>& expCtx, intrusive_ptr<Expression> pExpression) {
+ ExpressionContext* const expCtx, intrusive_ptr<Expression> pExpression) {
return new ExpressionCoerceToBool(expCtx, std::move(pExpression));
}
-ExpressionCoerceToBool::ExpressionCoerceToBool(const intrusive_ptr<ExpressionContext>& expCtx,
+ExpressionCoerceToBool::ExpressionCoerceToBool(ExpressionContext* const expCtx,
intrusive_ptr<Expression> pExpression)
: Expression(expCtx, {std::move(pExpression)}), pExpression(_children[0]) {}
@@ -802,7 +798,7 @@ namespace {
struct BoundOp {
ExpressionCompare::CmpOp op;
- auto operator()(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ auto operator()(ExpressionContext* const expCtx,
BSONElement bsonExpr,
const VariablesParseState& vps) const {
return ExpressionCompare::parse(expCtx, std::move(bsonExpr), vps, op);
@@ -818,11 +814,10 @@ REGISTER_EXPRESSION(lt, BoundOp{ExpressionCompare::LT});
REGISTER_EXPRESSION(lte, BoundOp{ExpressionCompare::LTE});
REGISTER_EXPRESSION(ne, BoundOp{ExpressionCompare::NE});
-intrusive_ptr<Expression> ExpressionCompare::parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement bsonExpr,
- const VariablesParseState& vps,
- CmpOp op) {
+intrusive_ptr<Expression> ExpressionCompare::parse(ExpressionContext* const expCtx,
+ BSONElement bsonExpr,
+ const VariablesParseState& vps,
+ CmpOp op) {
intrusive_ptr<ExpressionCompare> expr = new ExpressionCompare(expCtx, op);
ExpressionVector args = parseArguments(expCtx, bsonExpr, vps);
expr->validateArguments(args);
@@ -831,7 +826,7 @@ intrusive_ptr<Expression> ExpressionCompare::parse(
}
boost::intrusive_ptr<ExpressionCompare> ExpressionCompare::create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionContext* const expCtx,
CmpOp cmpOp,
const boost::intrusive_ptr<Expression>& exprLeft,
const boost::intrusive_ptr<Expression>& exprRight) {
@@ -949,10 +944,9 @@ Value ExpressionCond::evaluate(const Document& root, Variables* variables) const
return _children[idx]->evaluate(root, variables);
}
-intrusive_ptr<Expression> ExpressionCond::parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps) {
+intrusive_ptr<Expression> ExpressionCond::parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps) {
if (expr.type() != Object) {
return Base::parse(expCtx, expr, vps);
}
@@ -989,22 +983,20 @@ const char* ExpressionCond::getOpName() const {
/* ---------------------- ExpressionConstant --------------------------- */
-intrusive_ptr<Expression> ExpressionConstant::parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement exprElement,
- const VariablesParseState& vps) {
+intrusive_ptr<Expression> ExpressionConstant::parse(ExpressionContext* const expCtx,
+ BSONElement exprElement,
+ const VariablesParseState& vps) {
return new ExpressionConstant(expCtx, Value(exprElement));
}
-intrusive_ptr<ExpressionConstant> ExpressionConstant::create(
- const intrusive_ptr<ExpressionContext>& expCtx, const Value& value) {
+intrusive_ptr<ExpressionConstant> ExpressionConstant::create(ExpressionContext* const expCtx,
+ const Value& value) {
intrusive_ptr<ExpressionConstant> pEC(new ExpressionConstant(expCtx, value));
return pEC;
}
-ExpressionConstant::ExpressionConstant(const boost::intrusive_ptr<ExpressionContext>& expCtx,
- const Value& value)
+ExpressionConstant::ExpressionConstant(ExpressionContext* const expCtx, const Value& value)
: Expression(expCtx), _value(value) {}
@@ -1065,10 +1057,9 @@ boost::optional<TimeZone> makeTimeZone(const TimeZoneDatabase* tzdb,
REGISTER_EXPRESSION(dateFromParts, ExpressionDateFromParts::parse);
-intrusive_ptr<Expression> ExpressionDateFromParts::parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps) {
+intrusive_ptr<Expression> ExpressionDateFromParts::parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps) {
uassert(40519,
"$dateFromParts only supports an object as its argument",
@@ -1146,19 +1137,18 @@ intrusive_ptr<Expression> ExpressionDateFromParts::parse(
timeZoneElem ? parseOperand(expCtx, timeZoneElem, vps) : nullptr);
}
-ExpressionDateFromParts::ExpressionDateFromParts(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- intrusive_ptr<Expression> year,
- intrusive_ptr<Expression> month,
- intrusive_ptr<Expression> day,
- intrusive_ptr<Expression> hour,
- intrusive_ptr<Expression> minute,
- intrusive_ptr<Expression> second,
- intrusive_ptr<Expression> millisecond,
- intrusive_ptr<Expression> isoWeekYear,
- intrusive_ptr<Expression> isoWeek,
- intrusive_ptr<Expression> isoDayOfWeek,
- intrusive_ptr<Expression> timeZone)
+ExpressionDateFromParts::ExpressionDateFromParts(ExpressionContext* const expCtx,
+ intrusive_ptr<Expression> year,
+ intrusive_ptr<Expression> month,
+ intrusive_ptr<Expression> day,
+ intrusive_ptr<Expression> hour,
+ intrusive_ptr<Expression> minute,
+ intrusive_ptr<Expression> second,
+ intrusive_ptr<Expression> millisecond,
+ intrusive_ptr<Expression> isoWeekYear,
+ intrusive_ptr<Expression> isoWeek,
+ intrusive_ptr<Expression> isoDayOfWeek,
+ intrusive_ptr<Expression> timeZone)
: Expression(expCtx,
{std::move(year),
std::move(month),
@@ -1405,10 +1395,9 @@ void ExpressionDateFromParts::_doAddDependencies(DepsTracker* deps) const {
/* ---------------------- ExpressionDateFromString --------------------- */
REGISTER_EXPRESSION(dateFromString, ExpressionDateFromString::parse);
-intrusive_ptr<Expression> ExpressionDateFromString::parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps) {
+intrusive_ptr<Expression> ExpressionDateFromString::parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps) {
uassert(40540,
str::stream() << "$dateFromString only supports an object as an argument, found: "
@@ -1449,13 +1438,12 @@ intrusive_ptr<Expression> ExpressionDateFromString::parse(
onErrorElem ? parseOperand(expCtx, onErrorElem, vps) : nullptr);
}
-ExpressionDateFromString::ExpressionDateFromString(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- intrusive_ptr<Expression> dateString,
- intrusive_ptr<Expression> timeZone,
- intrusive_ptr<Expression> format,
- intrusive_ptr<Expression> onNull,
- intrusive_ptr<Expression> onError)
+ExpressionDateFromString::ExpressionDateFromString(ExpressionContext* const expCtx,
+ intrusive_ptr<Expression> dateString,
+ intrusive_ptr<Expression> timeZone,
+ intrusive_ptr<Expression> format,
+ intrusive_ptr<Expression> onNull,
+ intrusive_ptr<Expression> onError)
: Expression(expCtx,
{std::move(dateString),
std::move(timeZone),
@@ -1588,10 +1576,9 @@ void ExpressionDateFromString::_doAddDependencies(DepsTracker* deps) const {
/* ---------------------- ExpressionDateToParts ----------------------- */
REGISTER_EXPRESSION(dateToParts, ExpressionDateToParts::parse);
-intrusive_ptr<Expression> ExpressionDateToParts::parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps) {
+intrusive_ptr<Expression> ExpressionDateToParts::parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps) {
uassert(40524,
"$dateToParts only supports an object as its argument",
@@ -1627,7 +1614,7 @@ intrusive_ptr<Expression> ExpressionDateToParts::parse(
isoDateElem ? parseOperand(expCtx, isoDateElem, vps) : nullptr);
}
-ExpressionDateToParts::ExpressionDateToParts(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ExpressionDateToParts::ExpressionDateToParts(ExpressionContext* const expCtx,
intrusive_ptr<Expression> date,
intrusive_ptr<Expression> timeZone,
intrusive_ptr<Expression> iso8601)
@@ -1737,10 +1724,9 @@ void ExpressionDateToParts::_doAddDependencies(DepsTracker* deps) const {
/* ---------------------- ExpressionDateToString ----------------------- */
REGISTER_EXPRESSION(dateToString, ExpressionDateToString::parse);
-intrusive_ptr<Expression> ExpressionDateToString::parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps) {
+intrusive_ptr<Expression> ExpressionDateToString::parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps) {
verify(expr.fieldNameStringData() == "$dateToString");
uassert(18629,
@@ -1776,12 +1762,11 @@ intrusive_ptr<Expression> ExpressionDateToString::parse(
onNullElem ? parseOperand(expCtx, onNullElem, vps) : nullptr);
}
-ExpressionDateToString::ExpressionDateToString(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- intrusive_ptr<Expression> date,
- intrusive_ptr<Expression> format,
- intrusive_ptr<Expression> timeZone,
- intrusive_ptr<Expression> onNull)
+ExpressionDateToString::ExpressionDateToString(ExpressionContext* const expCtx,
+ intrusive_ptr<Expression> date,
+ intrusive_ptr<Expression> format,
+ intrusive_ptr<Expression> timeZone,
+ intrusive_ptr<Expression> onNull)
: Expression(expCtx,
{std::move(format), std::move(date), std::move(timeZone), std::move(onNull)}),
_format(_children[0]),
@@ -1932,13 +1917,13 @@ const char* ExpressionExp::getOpName() const {
/* ---------------------- ExpressionObject --------------------------- */
-ExpressionObject::ExpressionObject(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ExpressionObject::ExpressionObject(ExpressionContext* const expCtx,
std::vector<boost::intrusive_ptr<Expression>> _children,
vector<pair<string, intrusive_ptr<Expression>&>>&& expressions)
: Expression(expCtx, std::move(_children)), _expressions(std::move(expressions)) {}
boost::intrusive_ptr<ExpressionObject> ExpressionObject::create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionContext* const expCtx,
std::vector<std::pair<std::string, boost::intrusive_ptr<Expression>>>&&
expressionsWithChildrenInPlace) {
std::vector<boost::intrusive_ptr<Expression>> children;
@@ -1956,10 +1941,9 @@ boost::intrusive_ptr<ExpressionObject> ExpressionObject::create(
return new ExpressionObject(expCtx, std::move(children), std::move(expressions));
}
-intrusive_ptr<ExpressionObject> ExpressionObject::parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONObj obj,
- const VariablesParseState& vps) {
+intrusive_ptr<ExpressionObject> ExpressionObject::parse(ExpressionContext* const expCtx,
+ BSONObj obj,
+ const VariablesParseState& vps) {
// Make sure we don't have any duplicate field names.
stdx::unordered_set<string> specifiedFields;
@@ -2046,16 +2030,15 @@ Expression::ComputedPaths ExpressionObject::getComputedPaths(const std::string&
/* --------------------- ExpressionFieldPath --------------------------- */
// this is the old deprecated version only used by tests not using variables
-intrusive_ptr<ExpressionFieldPath> ExpressionFieldPath::create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx, const string& fieldPath) {
+intrusive_ptr<ExpressionFieldPath> ExpressionFieldPath::create(ExpressionContext* const expCtx,
+ const string& fieldPath) {
return new ExpressionFieldPath(expCtx, "CURRENT." + fieldPath, Variables::kRootId);
}
// this is the new version that supports every syntax
-intrusive_ptr<ExpressionFieldPath> ExpressionFieldPath::parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- const string& raw,
- const VariablesParseState& vps) {
+intrusive_ptr<ExpressionFieldPath> ExpressionFieldPath::parse(ExpressionContext* const expCtx,
+ const string& raw,
+ const VariablesParseState& vps) {
uassert(16873,
str::stream() << "FieldPath '" << raw << "' doesn't start with $",
raw.c_str()[0] == '$'); // c_str()[0] is always a valid reference.
@@ -2078,7 +2061,7 @@ intrusive_ptr<ExpressionFieldPath> ExpressionFieldPath::parse(
}
}
-ExpressionFieldPath::ExpressionFieldPath(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ExpressionFieldPath::ExpressionFieldPath(ExpressionContext* const expCtx,
const string& theFieldPath,
Variables::Id variable)
: Expression(expCtx), _fieldPath(theFieldPath), _variable(variable) {}
@@ -2215,10 +2198,9 @@ Expression::ComputedPaths ExpressionFieldPath::getComputedPaths(const std::strin
/* ------------------------- ExpressionFilter ----------------------------- */
REGISTER_EXPRESSION(filter, ExpressionFilter::parse);
-intrusive_ptr<Expression> ExpressionFilter::parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vpsIn) {
+intrusive_ptr<Expression> ExpressionFilter::parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vpsIn) {
verify(expr.fieldNameStringData() == "$filter");
uassert(28646, "$filter only supports an object as its argument", expr.type() == Object);
@@ -2262,7 +2244,7 @@ intrusive_ptr<Expression> ExpressionFilter::parse(
expCtx, std::move(varName), varId, std::move(input), std::move(cond));
}
-ExpressionFilter::ExpressionFilter(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ExpressionFilter::ExpressionFilter(ExpressionContext* const expCtx,
string varName,
Variables::Id varId,
intrusive_ptr<Expression> input,
@@ -2342,10 +2324,9 @@ const char* ExpressionFloor::getOpName() const {
/* ------------------------- ExpressionLet ----------------------------- */
REGISTER_EXPRESSION(let, ExpressionLet::parse);
-intrusive_ptr<Expression> ExpressionLet::parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vpsIn) {
+intrusive_ptr<Expression> ExpressionLet::parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vpsIn) {
verify(expr.fieldNameStringData() == "$let");
uassert(16874, "$let only supports an object as its argument", expr.type() == Object);
@@ -2395,7 +2376,7 @@ intrusive_ptr<Expression> ExpressionLet::parse(
return new ExpressionLet(expCtx, std::move(vars), std::move(children));
}
-ExpressionLet::ExpressionLet(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ExpressionLet::ExpressionLet(ExpressionContext* const expCtx,
VariableMap&& vars,
std::vector<boost::intrusive_ptr<Expression>> children)
: Expression(expCtx, std::move(children)),
@@ -2451,10 +2432,9 @@ void ExpressionLet::_doAddDependencies(DepsTracker* deps) const {
/* ------------------------- ExpressionMap ----------------------------- */
REGISTER_EXPRESSION(map, ExpressionMap::parse);
-intrusive_ptr<Expression> ExpressionMap::parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vpsIn) {
+intrusive_ptr<Expression> ExpressionMap::parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vpsIn) {
verify(expr.fieldNameStringData() == "$map");
uassert(16878, "$map only supports an object as its argument", expr.type() == Object);
@@ -2500,7 +2480,7 @@ intrusive_ptr<Expression> ExpressionMap::parse(
return new ExpressionMap(expCtx, varName, varId, input, in);
}
-ExpressionMap::ExpressionMap(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ExpressionMap::ExpressionMap(ExpressionContext* const expCtx,
const string& varName,
Variables::Id varId,
intrusive_ptr<Expression> input,
@@ -2629,10 +2609,9 @@ const stdx::unordered_map<DocumentMetadataFields::MetaType, StringData> kMetaTyp
} // namespace
-intrusive_ptr<Expression> ExpressionMeta::parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vpsIn) {
+intrusive_ptr<Expression> ExpressionMeta::parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vpsIn) {
uassert(17307, "$meta only supports string arguments", expr.type() == String);
const auto iter = kMetaNameToMetaType.find(expr.valueStringData());
@@ -2643,8 +2622,7 @@ intrusive_ptr<Expression> ExpressionMeta::parse(
}
}
-ExpressionMeta::ExpressionMeta(const boost::intrusive_ptr<ExpressionContext>& expCtx,
- MetaType metaType)
+ExpressionMeta::ExpressionMeta(ExpressionContext* const expCtx, MetaType metaType)
: Expression(expCtx), _metaType(metaType) {}
Value ExpressionMeta::serialize(bool explain) const {
@@ -2937,7 +2915,7 @@ ExpressionIndexOfArray::Arguments ExpressionIndexOfArray::evaluateAndValidateArg
*/
class ExpressionIndexOfArray::Optimized : public ExpressionIndexOfArray {
public:
- Optimized(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ Optimized(ExpressionContext* const expCtx,
const ValueUnorderedMap<vector<int>>& indexMap,
const ExpressionVector& operands)
: ExpressionIndexOfArray(expCtx), _indexMap(std::move(indexMap)) {
@@ -3544,8 +3522,9 @@ bool representableAsLong(long long base, long long exp) {
/* ----------------------- ExpressionPow ---------------------------- */
-intrusive_ptr<Expression> ExpressionPow::create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx, Value base, Value exp) {
+intrusive_ptr<Expression> ExpressionPow::create(ExpressionContext* const expCtx,
+ Value base,
+ Value exp) {
intrusive_ptr<ExpressionPow> expr(new ExpressionPow(expCtx));
expr->_children.push_back(
ExpressionConstant::create(expr->getExpressionContext(), std::move(base)));
@@ -3735,10 +3714,9 @@ const char* ExpressionRange::getOpName() const {
/* ------------------------ ExpressionReduce ------------------------------ */
REGISTER_EXPRESSION(reduce, ExpressionReduce::parse);
-intrusive_ptr<Expression> ExpressionReduce::parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps) {
+intrusive_ptr<Expression> ExpressionReduce::parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps) {
uassert(40075,
str::stream() << "$reduce requires an object as an argument, found: "
<< typeName(expr.type()),
@@ -3837,7 +3815,7 @@ Value ExpressionReplaceBase::serialize(bool explain) const {
namespace {
std::tuple<intrusive_ptr<Expression>, intrusive_ptr<Expression>, intrusive_ptr<Expression>>
parseExpressionReplaceBase(const char* opName,
- const intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionContext* const expCtx,
BSONElement expr,
const VariablesParseState& vps) {
@@ -3913,10 +3891,9 @@ intrusive_ptr<Expression> ExpressionReplaceBase::optimize() {
REGISTER_EXPRESSION(replaceOne, ExpressionReplaceOne::parse);
-intrusive_ptr<Expression> ExpressionReplaceOne::parse(
- const intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps) {
+intrusive_ptr<Expression> ExpressionReplaceOne::parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps) {
auto [input, find, replacement] = parseExpressionReplaceBase(opName, expCtx, expr, vps);
return make_intrusive<ExpressionReplaceOne>(
expCtx, std::move(input), std::move(find), std::move(replacement));
@@ -3945,10 +3922,9 @@ Value ExpressionReplaceOne::_doEval(StringData input,
REGISTER_EXPRESSION(replaceAll, ExpressionReplaceAll::parse);
-intrusive_ptr<Expression> ExpressionReplaceAll::parse(
- const intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps) {
+intrusive_ptr<Expression> ExpressionReplaceAll::parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps) {
auto [input, find, replacement] = parseExpressionReplaceBase(opName, expCtx, expr, vps);
return make_intrusive<ExpressionReplaceAll>(
expCtx, std::move(input), std::move(find), std::move(replacement));
@@ -4189,7 +4165,7 @@ Value ExpressionSetIsSubset::evaluate(const Document& root, Variables* variables
*/
class ExpressionSetIsSubset::Optimized : public ExpressionSetIsSubset {
public:
- Optimized(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ Optimized(ExpressionContext* const expCtx,
const ValueSet& cachedRhsSet,
const ExpressionVector& operands)
: ExpressionSetIsSubset(expCtx), _cachedRhsSet(cachedRhsSet) {
@@ -4760,10 +4736,9 @@ Value ExpressionSwitch::evaluate(const Document& root, Variables* variables) con
return _default->evaluate(root, variables);
}
-boost::intrusive_ptr<Expression> ExpressionSwitch::parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps) {
+boost::intrusive_ptr<Expression> ExpressionSwitch::parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps) {
uassert(40060,
str::stream() << "$switch requires an object as an argument, found: "
<< typeName(expr.type()),
@@ -4912,10 +4887,9 @@ REGISTER_EXPRESSION(trim, ExpressionTrim::parse);
REGISTER_EXPRESSION(ltrim, ExpressionTrim::parse);
REGISTER_EXPRESSION(rtrim, ExpressionTrim::parse);
-intrusive_ptr<Expression> ExpressionTrim::parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps) {
+intrusive_ptr<Expression> ExpressionTrim::parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps) {
const auto name = expr.fieldNameStringData();
TrimType trimType = TrimType::kBoth;
if (name == "$ltrim"_sd) {
@@ -5231,7 +5205,7 @@ Value ExpressionTrunc::evaluate(const Document& root, Variables* variables) cons
root, _children, getOpName(), Decimal128::kRoundTowardZero, &std::trunc, variables);
}
-intrusive_ptr<Expression> ExpressionTrunc::parse(const intrusive_ptr<ExpressionContext>& expCtx,
+intrusive_ptr<Expression> ExpressionTrunc::parse(ExpressionContext* const expCtx,
BSONElement elem,
const VariablesParseState& vps) {
return ExpressionRangedArity<ExpressionTrunc, 1, 2>::parse(expCtx, elem, vps);
@@ -5270,10 +5244,9 @@ const char* ExpressionIsNumber::getOpName() const {
/* -------------------------- ExpressionZip ------------------------------ */
REGISTER_EXPRESSION(zip, ExpressionZip::parse);
-intrusive_ptr<Expression> ExpressionZip::parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps) {
+intrusive_ptr<Expression> ExpressionZip::parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps) {
uassert(34460,
str::stream() << "$zip only supports an object as an argument, found "
<< typeName(expr.type()),
@@ -5458,8 +5431,7 @@ namespace {
*/
class ConversionTable {
public:
- using ConversionFunc =
- std::function<Value(const boost::intrusive_ptr<ExpressionContext>&, Value)>;
+ using ConversionFunc = std::function<Value(ExpressionContext* const, Value)>;
ConversionTable() {
//
@@ -5467,17 +5439,17 @@ public:
//
table[BSONType::NumberDouble][BSONType::NumberDouble] = &performIdentityConversion;
table[BSONType::NumberDouble][BSONType::String] = &performFormatDouble;
- table[BSONType::NumberDouble][BSONType::Bool] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return Value(inputValue.coerceToBool());
- };
+ table[BSONType::NumberDouble][BSONType::Bool] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ return Value(inputValue.coerceToBool());
+ };
table[BSONType::NumberDouble][BSONType::Date] = &performCastNumberToDate;
table[BSONType::NumberDouble][BSONType::NumberInt] = &performCastDoubleToInt;
table[BSONType::NumberDouble][BSONType::NumberLong] = &performCastDoubleToLong;
- table[BSONType::NumberDouble][BSONType::NumberDecimal] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return Value(inputValue.coerceToDecimal());
- };
+ table[BSONType::NumberDouble][BSONType::NumberDecimal] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ return Value(inputValue.coerceToDecimal());
+ };
//
// Conversions from String
@@ -5486,11 +5458,11 @@ public:
table[BSONType::String][BSONType::String] = &performIdentityConversion;
table[BSONType::String][BSONType::jstOID] = &parseStringToOID;
table[BSONType::String][BSONType::Bool] = &performConvertToTrue;
- table[BSONType::String][BSONType::Date] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return Value(expCtx->timeZoneDatabase->fromString(
- inputValue.getStringData(), mongo::TimeZoneDatabase::utcZone()));
- };
+ table[BSONType::String][BSONType::Date] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ return Value(expCtx->timeZoneDatabase->fromString(inputValue.getStringData(),
+ mongo::TimeZoneDatabase::utcZone()));
+ };
table[BSONType::String][BSONType::NumberInt] = &parseStringToNumber<int, 10>;
table[BSONType::String][BSONType::NumberLong] = &parseStringToNumber<long long, 10>;
table[BSONType::String][BSONType::NumberDecimal] = &parseStringToNumber<Decimal128, 0>;
@@ -5498,139 +5470,139 @@ public:
//
// Conversions from jstOID
//
- table[BSONType::jstOID][BSONType::String] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return Value(inputValue.getOid().toString());
- };
+ table[BSONType::jstOID][BSONType::String] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ return Value(inputValue.getOid().toString());
+ };
table[BSONType::jstOID][BSONType::jstOID] = &performIdentityConversion;
table[BSONType::jstOID][BSONType::Bool] = &performConvertToTrue;
- table[BSONType::jstOID][BSONType::Date] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return Value(inputValue.getOid().asDateT());
- };
+ table[BSONType::jstOID][BSONType::Date] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ return Value(inputValue.getOid().asDateT());
+ };
//
// Conversions from Bool
//
- table[BSONType::Bool][BSONType::NumberDouble] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return inputValue.getBool() ? Value(1.0) : Value(0.0);
- };
- table[BSONType::Bool][BSONType::String] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return inputValue.getBool() ? Value("true"_sd) : Value("false"_sd);
- };
+ table[BSONType::Bool][BSONType::NumberDouble] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ return inputValue.getBool() ? Value(1.0) : Value(0.0);
+ };
+ table[BSONType::Bool][BSONType::String] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ return inputValue.getBool() ? Value("true"_sd) : Value("false"_sd);
+ };
table[BSONType::Bool][BSONType::Bool] = &performIdentityConversion;
- table[BSONType::Bool][BSONType::NumberInt] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return inputValue.getBool() ? Value(int{1}) : Value(int{0});
- };
- table[BSONType::Bool][BSONType::NumberLong] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return inputValue.getBool() ? Value(1LL) : Value(0LL);
- };
- table[BSONType::Bool][BSONType::NumberDecimal] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return inputValue.getBool() ? Value(Decimal128(1)) : Value(Decimal128(0));
- };
+ table[BSONType::Bool][BSONType::NumberInt] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ return inputValue.getBool() ? Value(int{1}) : Value(int{0});
+ };
+ table[BSONType::Bool][BSONType::NumberLong] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ return inputValue.getBool() ? Value(1LL) : Value(0LL);
+ };
+ table[BSONType::Bool][BSONType::NumberDecimal] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ return inputValue.getBool() ? Value(Decimal128(1)) : Value(Decimal128(0));
+ };
//
// Conversions from Date
//
- table[BSONType::Date][BSONType::NumberDouble] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return Value(static_cast<double>(inputValue.getDate().toMillisSinceEpoch()));
- };
- table[BSONType::Date][BSONType::String] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- auto dateString = TimeZoneDatabase::utcZone().formatDate(Value::kISOFormatString,
- inputValue.getDate());
- return Value(dateString);
- };
- table[BSONType::Date][BSONType::Bool] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return Value(inputValue.coerceToBool());
- };
+ table[BSONType::Date][BSONType::NumberDouble] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ return Value(static_cast<double>(inputValue.getDate().toMillisSinceEpoch()));
+ };
+ table[BSONType::Date][BSONType::String] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ auto dateString = TimeZoneDatabase::utcZone().formatDate(Value::kISOFormatString,
+ inputValue.getDate());
+ return Value(dateString);
+ };
+ table[BSONType::Date][BSONType::Bool] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ return Value(inputValue.coerceToBool());
+ };
table[BSONType::Date][BSONType::Date] = &performIdentityConversion;
- table[BSONType::Date][BSONType::NumberLong] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return Value(inputValue.getDate().toMillisSinceEpoch());
- };
- table[BSONType::Date][BSONType::NumberDecimal] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return Value(
- Decimal128(static_cast<int64_t>(inputValue.getDate().toMillisSinceEpoch())));
- };
+ table[BSONType::Date][BSONType::NumberLong] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ return Value(inputValue.getDate().toMillisSinceEpoch());
+ };
+ table[BSONType::Date][BSONType::NumberDecimal] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ return Value(
+ Decimal128(static_cast<int64_t>(inputValue.getDate().toMillisSinceEpoch())));
+ };
//
// Conversions from NumberInt
//
- table[BSONType::NumberInt][BSONType::NumberDouble] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return Value(inputValue.coerceToDouble());
- };
- table[BSONType::NumberInt][BSONType::String] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return Value(static_cast<std::string>(str::stream() << inputValue.getInt()));
- };
- table[BSONType::NumberInt][BSONType::Bool] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return Value(inputValue.coerceToBool());
- };
+ table[BSONType::NumberInt][BSONType::NumberDouble] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ return Value(inputValue.coerceToDouble());
+ };
+ table[BSONType::NumberInt][BSONType::String] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ return Value(static_cast<std::string>(str::stream() << inputValue.getInt()));
+ };
+ table[BSONType::NumberInt][BSONType::Bool] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ return Value(inputValue.coerceToBool());
+ };
table[BSONType::NumberInt][BSONType::NumberInt] = &performIdentityConversion;
- table[BSONType::NumberInt][BSONType::NumberLong] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return Value(static_cast<long long>(inputValue.getInt()));
- };
- table[BSONType::NumberInt][BSONType::NumberDecimal] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return Value(inputValue.coerceToDecimal());
- };
+ table[BSONType::NumberInt][BSONType::NumberLong] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ return Value(static_cast<long long>(inputValue.getInt()));
+ };
+ table[BSONType::NumberInt][BSONType::NumberDecimal] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ return Value(inputValue.coerceToDecimal());
+ };
//
// Conversions from NumberLong
//
- table[BSONType::NumberLong][BSONType::NumberDouble] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return Value(inputValue.coerceToDouble());
- };
- table[BSONType::NumberLong][BSONType::String] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return Value(static_cast<std::string>(str::stream() << inputValue.getLong()));
- };
- table[BSONType::NumberLong][BSONType::Bool] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return Value(inputValue.coerceToBool());
- };
+ table[BSONType::NumberLong][BSONType::NumberDouble] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ return Value(inputValue.coerceToDouble());
+ };
+ table[BSONType::NumberLong][BSONType::String] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ return Value(static_cast<std::string>(str::stream() << inputValue.getLong()));
+ };
+ table[BSONType::NumberLong][BSONType::Bool] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ return Value(inputValue.coerceToBool());
+ };
table[BSONType::NumberLong][BSONType::Date] = &performCastNumberToDate;
table[BSONType::NumberLong][BSONType::NumberInt] = &performCastLongToInt;
table[BSONType::NumberLong][BSONType::NumberLong] = &performIdentityConversion;
- table[BSONType::NumberLong][BSONType::NumberDecimal] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return Value(inputValue.coerceToDecimal());
- };
+ table[BSONType::NumberLong][BSONType::NumberDecimal] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ return Value(inputValue.coerceToDecimal());
+ };
//
// Conversions from NumberDecimal
//
table[BSONType::NumberDecimal][BSONType::NumberDouble] = &performCastDecimalToDouble;
- table[BSONType::NumberDecimal][BSONType::String] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return Value(inputValue.getDecimal().toString());
- };
- table[BSONType::NumberDecimal][BSONType::Bool] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return Value(inputValue.coerceToBool());
- };
+ table[BSONType::NumberDecimal][BSONType::String] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ return Value(inputValue.getDecimal().toString());
+ };
+ table[BSONType::NumberDecimal][BSONType::Bool] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ return Value(inputValue.coerceToBool());
+ };
table[BSONType::NumberDecimal][BSONType::Date] = &performCastNumberToDate;
- table[BSONType::NumberDecimal][BSONType::NumberInt] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return performCastDecimalToInt(BSONType::NumberInt, inputValue);
- };
- table[BSONType::NumberDecimal][BSONType::NumberLong] =
- [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return performCastDecimalToInt(BSONType::NumberLong, inputValue);
- };
+ table[BSONType::NumberDecimal][BSONType::NumberInt] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ return performCastDecimalToInt(BSONType::NumberInt, inputValue);
+ };
+ table[BSONType::NumberDecimal][BSONType::NumberLong] = [](ExpressionContext* const expCtx,
+ Value inputValue) {
+ return performCastDecimalToInt(BSONType::NumberLong, inputValue);
+ };
table[BSONType::NumberDecimal][BSONType::NumberDecimal] = &performIdentityConversion;
//
@@ -5686,8 +5658,7 @@ private:
std::isfinite(inputDouble));
}
- static Value performCastDoubleToInt(const boost::intrusive_ptr<ExpressionContext>& expCtx,
- Value inputValue) {
+ static Value performCastDoubleToInt(ExpressionContext* const expCtx, Value inputValue) {
double inputDouble = inputValue.getDouble();
validateDoubleValueIsFinite(inputDouble);
@@ -5701,8 +5672,7 @@ private:
return Value(static_cast<int>(inputDouble));
}
- static Value performCastDoubleToLong(const boost::intrusive_ptr<ExpressionContext>& expCtx,
- Value inputValue) {
+ static Value performCastDoubleToLong(ExpressionContext* const expCtx, Value inputValue) {
double inputDouble = inputValue.getDouble();
validateDoubleValueIsFinite(inputDouble);
@@ -5757,8 +5727,7 @@ private:
return result;
}
- static Value performCastDecimalToDouble(const boost::intrusive_ptr<ExpressionContext>& expCtx,
- Value inputValue) {
+ static Value performCastDecimalToDouble(ExpressionContext* const expCtx, Value inputValue) {
Decimal128 inputDecimal = inputValue.getDecimal();
std::uint32_t signalingFlags = Decimal128::SignalingFlag::kNoFlag;
@@ -5775,8 +5744,7 @@ private:
return Value(result);
}
- static Value performCastLongToInt(const boost::intrusive_ptr<ExpressionContext>& expCtx,
- Value inputValue) {
+ static Value performCastLongToInt(ExpressionContext* const expCtx, Value inputValue) {
long long longValue = inputValue.getLong();
uassert(ErrorCodes::ConversionFailure,
@@ -5788,8 +5756,7 @@ private:
return Value(static_cast<int>(longValue));
}
- static Value performCastNumberToDate(const boost::intrusive_ptr<ExpressionContext>& expCtx,
- Value inputValue) {
+ static Value performCastNumberToDate(ExpressionContext* const expCtx, Value inputValue) {
long long millisSinceEpoch;
switch (inputValue.getType()) {
@@ -5810,8 +5777,7 @@ private:
return Value(Date_t::fromMillisSinceEpoch(millisSinceEpoch));
}
- static Value performFormatDouble(const boost::intrusive_ptr<ExpressionContext>& expCtx,
- Value inputValue) {
+ static Value performFormatDouble(ExpressionContext* const expCtx, Value inputValue) {
double doubleValue = inputValue.getDouble();
if (std::isinf(doubleValue)) {
@@ -5826,8 +5792,7 @@ private:
}
template <class targetType, int base>
- static Value parseStringToNumber(const boost::intrusive_ptr<ExpressionContext>& expCtx,
- Value inputValue) {
+ static Value parseStringToNumber(ExpressionContext* const expCtx, Value inputValue) {
auto stringValue = inputValue.getStringData();
targetType result;
@@ -5848,8 +5813,7 @@ private:
return Value(result);
}
- static Value parseStringToOID(const boost::intrusive_ptr<ExpressionContext>& expCtx,
- Value inputValue) {
+ static Value parseStringToOID(ExpressionContext* const expCtx, Value inputValue) {
try {
return Value(OID::createFromString(inputValue.getStringData()));
} catch (const DBException& ex) {
@@ -5861,19 +5825,17 @@ private:
}
}
- static Value performConvertToTrue(const boost::intrusive_ptr<ExpressionContext>& expCtx,
- Value inputValue) {
+ static Value performConvertToTrue(ExpressionContext* const expCtx, Value inputValue) {
return Value(true);
}
- static Value performIdentityConversion(const boost::intrusive_ptr<ExpressionContext>& expCtx,
- Value inputValue) {
+ static Value performIdentityConversion(ExpressionContext* const expCtx, Value inputValue) {
return inputValue;
}
};
Expression::Parser makeConversionAlias(const StringData shortcutName, BSONType toType) {
- return [=](const intrusive_ptr<ExpressionContext>& expCtx,
+ return [=](ExpressionContext* const expCtx,
BSONElement elem,
const VariablesParseState& vps) -> intrusive_ptr<Expression> {
// Use parseArguments to allow for a singleton array, or the unwrapped version.
@@ -5902,10 +5864,9 @@ REGISTER_EXPRESSION(toLong, makeConversionAlias("$toLong"_sd, BSONType::NumberLo
REGISTER_EXPRESSION(toDecimal, makeConversionAlias("$toDecimal"_sd, BSONType::NumberDecimal));
REGISTER_EXPRESSION(toBool, makeConversionAlias("$toBool"_sd, BSONType::Bool));
-boost::intrusive_ptr<Expression> ExpressionConvert::create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- boost::intrusive_ptr<Expression> input,
- BSONType toType) {
+boost::intrusive_ptr<Expression> ExpressionConvert::create(ExpressionContext* const expCtx,
+ boost::intrusive_ptr<Expression> input,
+ BSONType toType) {
return new ExpressionConvert(
expCtx,
std::move(input),
@@ -5914,7 +5875,7 @@ boost::intrusive_ptr<Expression> ExpressionConvert::create(
nullptr);
}
-ExpressionConvert::ExpressionConvert(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ExpressionConvert::ExpressionConvert(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> input,
boost::intrusive_ptr<Expression> to,
boost::intrusive_ptr<Expression> onError,
@@ -5925,10 +5886,9 @@ ExpressionConvert::ExpressionConvert(const boost::intrusive_ptr<ExpressionContex
_onError(_children[2]),
_onNull(_children[3]) {}
-intrusive_ptr<Expression> ExpressionConvert::parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps) {
+intrusive_ptr<Expression> ExpressionConvert::parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps) {
uassert(ErrorCodes::FailedToParse,
str::stream() << "$convert expects an object of named arguments but found: "
<< typeName(expr.type()),
@@ -6072,7 +6032,7 @@ Value ExpressionConvert::performConversion(BSONType targetType, Value inputValue
namespace {
-auto CommonRegexParse(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+auto CommonRegexParse(ExpressionContext* const expCtx,
BSONElement expr,
const VariablesParseState& vpsIn,
StringData opName) {
@@ -6366,10 +6326,9 @@ void ExpressionRegex::_doAddDependencies(DepsTracker* deps) const {
/* -------------------------- ExpressionRegexFind ------------------------------ */
REGISTER_EXPRESSION(regexFind, ExpressionRegexFind::parse);
-boost::intrusive_ptr<Expression> ExpressionRegexFind::parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vpsIn) {
+boost::intrusive_ptr<Expression> ExpressionRegexFind::parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vpsIn) {
auto opName = "$regexFind"_sd;
auto [input, regex, options] = CommonRegexParse(expCtx, expr, vpsIn, opName);
return new ExpressionRegexFind(
@@ -6387,10 +6346,9 @@ Value ExpressionRegexFind::evaluate(const Document& root, Variables* variables)
/* -------------------------- ExpressionRegexFindAll ------------------------------ */
REGISTER_EXPRESSION(regexFindAll, ExpressionRegexFindAll::parse);
-boost::intrusive_ptr<Expression> ExpressionRegexFindAll::parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vpsIn) {
+boost::intrusive_ptr<Expression> ExpressionRegexFindAll::parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vpsIn) {
auto opName = "$regexFindAll"_sd;
auto [input, regex, options] = CommonRegexParse(expCtx, expr, vpsIn, opName);
return new ExpressionRegexFindAll(
@@ -6448,10 +6406,9 @@ Value ExpressionRegexFindAll::evaluate(const Document& root, Variables* variable
/* -------------------------- ExpressionRegexMatch ------------------------------ */
REGISTER_EXPRESSION(regexMatch, ExpressionRegexMatch::parse);
-boost::intrusive_ptr<Expression> ExpressionRegexMatch::parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vpsIn) {
+boost::intrusive_ptr<Expression> ExpressionRegexMatch::parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vpsIn) {
auto opName = "$regexMatch"_sd;
auto [input, regex, options] = CommonRegexParse(expCtx, expr, vpsIn, opName);
return new ExpressionRegexMatch(
diff --git a/src/mongo/db/pipeline/expression.h b/src/mongo/db/pipeline/expression.h
index 4f772ca2363..b68ac1ab9fa 100644
--- a/src/mongo/db/pipeline/expression.h
+++ b/src/mongo/db/pipeline/expression.h
@@ -92,7 +92,7 @@ class DocumentSource;
class Expression : public RefCountable {
public:
using Parser = std::function<boost::intrusive_ptr<Expression>(
- const boost::intrusive_ptr<ExpressionContext>&, BSONElement, const VariablesParseState&)>;
+ ExpressionContext* const, BSONElement, const VariablesParseState&)>;
/**
* Represents new paths computed by an expression. Computed paths are partitioned into renames
@@ -195,10 +195,9 @@ public:
* Calls parseExpression() on any sub-document (including possibly the entire document) which
* consists of a single field name starting with a '$'.
*/
- static boost::intrusive_ptr<Expression> parseObject(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONObj obj,
- const VariablesParseState& vps);
+ static boost::intrusive_ptr<Expression> parseObject(ExpressionContext* const expCtx,
+ BSONObj obj,
+ const VariablesParseState& vps);
/**
* Parses a BSONObj which has already been determined to be a functional expression.
@@ -206,10 +205,9 @@ public:
* Throws an error if 'obj' does not contain exactly one field, or if that field's name does not
* match a registered expression name.
*/
- static boost::intrusive_ptr<Expression> parseExpression(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONObj obj,
- const VariablesParseState& vps);
+ static boost::intrusive_ptr<Expression> parseExpression(ExpressionContext* const expCtx,
+ BSONObj obj,
+ const VariablesParseState& vps);
/**
* Parses a BSONElement which is an argument to an Expression.
@@ -218,10 +216,9 @@ public:
* parseObject(), ExpressionFieldPath::parse(), ExpressionArray::parse(), or
* ExpressionConstant::parse() as necessary.
*/
- static boost::intrusive_ptr<Expression> parseOperand(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement exprElement,
- const VariablesParseState& vps);
+ static boost::intrusive_ptr<Expression> parseOperand(ExpressionContext* const expCtx,
+ BSONElement exprElement,
+ const VariablesParseState& vps);
/**
* Return whether 'name' refers to an expression in the language.
@@ -256,16 +253,16 @@ public:
return _children;
}
- const boost::intrusive_ptr<ExpressionContext>& getExpressionContext() const {
+ auto getExpressionContext() const {
return _expCtx;
}
protected:
using ExpressionVector = std::vector<boost::intrusive_ptr<Expression>>;
- Expression(const boost::intrusive_ptr<ExpressionContext>& expCtx) : Expression(expCtx, {}) {}
+ Expression(ExpressionContext* const expCtx) : Expression(expCtx, {}) {}
- Expression(const boost::intrusive_ptr<ExpressionContext>& expCtx, ExpressionVector&& children)
+ Expression(ExpressionContext* const expCtx, ExpressionVector&& children)
: _children(std::move(children)), _expCtx(expCtx) {
auto varIds = _expCtx->variablesParseState.getDefinedVariableIDs();
if (!varIds.empty()) {
@@ -288,7 +285,7 @@ protected:
private:
boost::optional<Variables::Id> _boundaryVariableId;
- boost::intrusive_ptr<ExpressionContext> _expCtx;
+ ExpressionContext* const _expCtx;
};
/**
@@ -318,7 +315,7 @@ public:
virtual void validateArguments(const ExpressionVector& args) const {}
- static ExpressionVector parseArguments(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ static ExpressionVector parseArguments(ExpressionContext* const expCtx,
BSONElement bsonExpr,
const VariablesParseState& vps);
@@ -327,8 +324,7 @@ public:
}
protected:
- explicit ExpressionNary(const boost::intrusive_ptr<ExpressionContext>& expCtx)
- : Expression(expCtx) {}
+ explicit ExpressionNary(ExpressionContext* const expCtx) : Expression(expCtx) {}
void _doAddDependencies(DepsTracker* deps) const override;
};
@@ -337,10 +333,9 @@ protected:
template <typename SubClass>
class ExpressionNaryBase : public ExpressionNary {
public:
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement bsonExpr,
- const VariablesParseState& vps) {
+ static boost::intrusive_ptr<Expression> parse(ExpressionContext* const expCtx,
+ BSONElement bsonExpr,
+ const VariablesParseState& vps) {
auto expr = make_intrusive<SubClass>(expCtx);
ExpressionVector args = parseArguments(expCtx, bsonExpr, vps);
expr->validateArguments(args);
@@ -349,15 +344,14 @@ public:
}
protected:
- explicit ExpressionNaryBase(const boost::intrusive_ptr<ExpressionContext>& expCtx)
- : ExpressionNary(expCtx) {}
+ explicit ExpressionNaryBase(ExpressionContext* const expCtx) : ExpressionNary(expCtx) {}
};
/// Inherit from this class if your expression takes a variable number of arguments.
template <typename SubClass>
class ExpressionVariadic : public ExpressionNaryBase<SubClass> {
public:
- explicit ExpressionVariadic(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionVariadic(ExpressionContext* const expCtx)
: ExpressionNaryBase<SubClass>(expCtx) {}
};
@@ -368,7 +362,7 @@ public:
template <typename SubClass, int MinArgs, int MaxArgs>
class ExpressionRangedArity : public ExpressionNaryBase<SubClass> {
public:
- explicit ExpressionRangedArity(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionRangedArity(ExpressionContext* const expCtx)
: ExpressionNaryBase<SubClass>(expCtx) {}
void validateArguments(const Expression::ExpressionVector& args) const override {
@@ -384,7 +378,7 @@ public:
template <typename SubClass, int NArgs>
class ExpressionFixedArity : public ExpressionNaryBase<SubClass> {
public:
- explicit ExpressionFixedArity(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionFixedArity(ExpressionContext* const expCtx)
: ExpressionNaryBase<SubClass>(expCtx) {}
void validateArguments(const Expression::ExpressionVector& args) const override {
@@ -403,7 +397,7 @@ template <typename AccumulatorState>
class ExpressionFromAccumulator
: public ExpressionVariadic<ExpressionFromAccumulator<AccumulatorState>> {
public:
- explicit ExpressionFromAccumulator(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionFromAccumulator(ExpressionContext* const expCtx)
: ExpressionVariadic<ExpressionFromAccumulator<AccumulatorState>>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final {
@@ -457,7 +451,7 @@ public:
template <typename SubClass>
class ExpressionSingleNumericArg : public ExpressionFixedArity<SubClass, 1> {
public:
- explicit ExpressionSingleNumericArg(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionSingleNumericArg(ExpressionContext* const expCtx)
: ExpressionFixedArity<SubClass, 1>(expCtx) {}
virtual ~ExpressionSingleNumericArg() = default;
@@ -484,7 +478,7 @@ public:
template <typename SubClass>
class ExpressionTwoNumericArgs : public ExpressionFixedArity<SubClass, 2> {
public:
- explicit ExpressionTwoNumericArgs(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionTwoNumericArgs(ExpressionContext* const expCtx)
: ExpressionFixedArity<SubClass, 2>(expCtx) {}
virtual ~ExpressionTwoNumericArgs() = default;
@@ -535,13 +529,12 @@ public:
/**
* Creates a new ExpressionConstant with value 'value'.
*/
- static boost::intrusive_ptr<ExpressionConstant> create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx, const Value& value);
+ static boost::intrusive_ptr<ExpressionConstant> create(ExpressionContext* const expCtx,
+ const Value& value);
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement bsonExpr,
- const VariablesParseState& vps);
+ static boost::intrusive_ptr<Expression> parse(ExpressionContext* const expCtx,
+ BSONElement bsonExpr,
+ const VariablesParseState& vps);
/**
* Returns true if 'expression' is nullptr or if 'expression' is an instance of an
@@ -581,7 +574,7 @@ protected:
void _doAddDependencies(DepsTracker* deps) const override;
private:
- ExpressionConstant(const boost::intrusive_ptr<ExpressionContext>& expCtx, const Value& value);
+ ExpressionConstant(ExpressionContext* const expCtx, const Value& value);
Value _value;
};
@@ -647,10 +640,9 @@ public:
return this;
}
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement operatorElem,
- const VariablesParseState& variablesParseState) {
+ static boost::intrusive_ptr<Expression> parse(ExpressionContext* const expCtx,
+ BSONElement operatorElem,
+ const VariablesParseState& variablesParseState) {
if (operatorElem.type() == BSONType::Object) {
if (operatorElem.embeddedObject().firstElementFieldName()[0] == '$') {
// Assume this is an expression specification representing the date argument
@@ -703,7 +695,7 @@ public:
}
protected:
- explicit DateExpressionAcceptingTimeZone(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ explicit DateExpressionAcceptingTimeZone(ExpressionContext* const expCtx,
const StringData opName,
boost::intrusive_ptr<Expression> date,
boost::intrusive_ptr<Expression> timeZone)
@@ -738,7 +730,7 @@ private:
class ExpressionAbs final : public ExpressionSingleNumericArg<ExpressionAbs> {
public:
- explicit ExpressionAbs(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionAbs(ExpressionContext* const expCtx)
: ExpressionSingleNumericArg<ExpressionAbs>(expCtx) {}
Value evaluateNumericArg(const Value& numericArg) const final;
@@ -751,7 +743,7 @@ public:
class ExpressionAdd final : public ExpressionVariadic<ExpressionAdd> {
public:
- explicit ExpressionAdd(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionAdd(ExpressionContext* const expCtx)
: ExpressionVariadic<ExpressionAdd>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -773,7 +765,7 @@ public:
class ExpressionAllElementsTrue final : public ExpressionFixedArity<ExpressionAllElementsTrue, 1> {
public:
- explicit ExpressionAllElementsTrue(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionAllElementsTrue(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionAllElementsTrue, 1>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -787,7 +779,7 @@ public:
class ExpressionAnd final : public ExpressionVariadic<ExpressionAnd> {
public:
- explicit ExpressionAnd(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionAnd(ExpressionContext* const expCtx)
: ExpressionVariadic<ExpressionAnd>(expCtx) {}
boost::intrusive_ptr<Expression> optimize() final;
@@ -810,7 +802,7 @@ public:
class ExpressionAnyElementTrue final : public ExpressionFixedArity<ExpressionAnyElementTrue, 1> {
public:
- explicit ExpressionAnyElementTrue(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionAnyElementTrue(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionAnyElementTrue, 1>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -824,10 +816,10 @@ public:
class ExpressionArray final : public ExpressionVariadic<ExpressionArray> {
public:
- explicit ExpressionArray(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionArray(ExpressionContext* const expCtx)
: ExpressionVariadic<ExpressionArray>(expCtx) {}
- ExpressionArray(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionArray(ExpressionContext* const expCtx,
std::vector<boost::intrusive_ptr<Expression>>&& children)
: ExpressionVariadic<ExpressionArray>(expCtx) {
_children = std::move(children);
@@ -837,8 +829,7 @@ public:
Value serialize(bool explain) const final;
static boost::intrusive_ptr<ExpressionArray> create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- std::vector<boost::intrusive_ptr<Expression>>&& children) {
+ ExpressionContext* const expCtx, std::vector<boost::intrusive_ptr<Expression>>&& children) {
return make_intrusive<ExpressionArray>(expCtx, std::move(children));
}
@@ -853,7 +844,7 @@ public:
class ExpressionArrayElemAt final : public ExpressionFixedArity<ExpressionArrayElemAt, 2> {
public:
- explicit ExpressionArrayElemAt(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionArrayElemAt(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionArrayElemAt, 2>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -866,7 +857,7 @@ public:
class ExpressionFirst final : public ExpressionFixedArity<ExpressionFirst, 1> {
public:
- explicit ExpressionFirst(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionFirst(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionFirst, 1>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -879,7 +870,7 @@ public:
class ExpressionLast final : public ExpressionFixedArity<ExpressionLast, 1> {
public:
- explicit ExpressionLast(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionLast(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionLast, 1>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -892,7 +883,7 @@ public:
class ExpressionObjectToArray final : public ExpressionFixedArity<ExpressionObjectToArray, 1> {
public:
- explicit ExpressionObjectToArray(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionObjectToArray(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionObjectToArray, 1>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -905,7 +896,7 @@ public:
class ExpressionArrayToObject final : public ExpressionFixedArity<ExpressionArrayToObject, 1> {
public:
- explicit ExpressionArrayToObject(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionArrayToObject(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionArrayToObject, 1>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -918,7 +909,7 @@ public:
class ExpressionBsonSize final : public ExpressionFixedArity<ExpressionBsonSize, 1> {
public:
- explicit ExpressionBsonSize(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionBsonSize(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionBsonSize, 1>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -933,7 +924,7 @@ public:
class ExpressionCeil final : public ExpressionSingleNumericArg<ExpressionCeil> {
public:
- explicit ExpressionCeil(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionCeil(ExpressionContext* const expCtx)
: ExpressionSingleNumericArg<ExpressionCeil>(expCtx) {}
Value evaluateNumericArg(const Value& numericArg) const final;
@@ -952,8 +943,7 @@ public:
Value serialize(bool explain) const final;
static boost::intrusive_ptr<ExpressionCoerceToBool> create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- boost::intrusive_ptr<Expression> pExpression);
+ ExpressionContext* const expCtx, boost::intrusive_ptr<Expression> pExpression);
void acceptVisitor(ExpressionVisitor* visitor) final {
return visitor->visit(this);
@@ -963,7 +953,7 @@ protected:
void _doAddDependencies(DepsTracker* deps) const final;
private:
- ExpressionCoerceToBool(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionCoerceToBool(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> pExpression);
boost::intrusive_ptr<Expression>& pExpression;
@@ -986,7 +976,7 @@ public:
CMP = 6, // return -1, 0, 1 for a < b, a == b, a > b
};
- ExpressionCompare(const boost::intrusive_ptr<ExpressionContext>& expCtx, CmpOp cmpOp)
+ ExpressionCompare(ExpressionContext* const expCtx, CmpOp cmpOp)
: ExpressionFixedArity<ExpressionCompare, 2>(expCtx), cmpOp(cmpOp) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -996,14 +986,13 @@ public:
return cmpOp;
}
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement bsonExpr,
- const VariablesParseState& vps,
- CmpOp cmpOp);
+ static boost::intrusive_ptr<Expression> parse(ExpressionContext* const expCtx,
+ BSONElement bsonExpr,
+ const VariablesParseState& vps,
+ CmpOp cmpOp);
static boost::intrusive_ptr<ExpressionCompare> create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionContext* const expCtx,
CmpOp cmpOp,
const boost::intrusive_ptr<Expression>& exprLeft,
const boost::intrusive_ptr<Expression>& exprRight);
@@ -1019,7 +1008,7 @@ private:
class ExpressionConcat final : public ExpressionVariadic<ExpressionConcat> {
public:
- explicit ExpressionConcat(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionConcat(ExpressionContext* const expCtx)
: ExpressionVariadic<ExpressionConcat>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -1037,7 +1026,7 @@ public:
class ExpressionConcatArrays final : public ExpressionVariadic<ExpressionConcatArrays> {
public:
- explicit ExpressionConcatArrays(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionConcatArrays(ExpressionContext* const expCtx)
: ExpressionVariadic<ExpressionConcatArrays>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -1055,15 +1044,14 @@ public:
class ExpressionCond final : public ExpressionFixedArity<ExpressionCond, 3> {
public:
- explicit ExpressionCond(const boost::intrusive_ptr<ExpressionContext>& expCtx) : Base(expCtx) {}
+ explicit ExpressionCond(ExpressionContext* const expCtx) : Base(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
const char* getOpName() const final;
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps);
+ static boost::intrusive_ptr<Expression> parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps);
void acceptVisitor(ExpressionVisitor* visitor) final {
return visitor->visit(this);
@@ -1079,10 +1067,9 @@ public:
Value serialize(bool explain) const final;
Value evaluate(const Document& root, Variables* variables) const final;
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps);
+ static boost::intrusive_ptr<Expression> parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps);
void acceptVisitor(ExpressionVisitor* visitor) final {
return visitor->visit(this);
@@ -1092,7 +1079,7 @@ protected:
void _doAddDependencies(DepsTracker* deps) const final;
private:
- ExpressionDateFromString(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionDateFromString(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> dateString,
boost::intrusive_ptr<Expression> timeZone,
boost::intrusive_ptr<Expression> format,
@@ -1112,10 +1099,9 @@ public:
Value serialize(bool explain) const final;
Value evaluate(const Document& root, Variables* variables) const final;
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps);
+ static boost::intrusive_ptr<Expression> parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps);
void acceptVisitor(ExpressionVisitor* visitor) final {
return visitor->visit(this);
@@ -1125,7 +1111,7 @@ protected:
void _doAddDependencies(DepsTracker* deps) const final;
private:
- ExpressionDateFromParts(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionDateFromParts(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> year,
boost::intrusive_ptr<Expression> month,
boost::intrusive_ptr<Expression> day,
@@ -1194,10 +1180,9 @@ public:
Value serialize(bool explain) const final;
Value evaluate(const Document& root, Variables* variables) const final;
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps);
+ static boost::intrusive_ptr<Expression> parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps);
void acceptVisitor(ExpressionVisitor* visitor) final {
return visitor->visit(this);
@@ -1210,7 +1195,7 @@ private:
/**
* The iso8601 argument controls whether to output ISO8601 elements or natural calendar.
*/
- ExpressionDateToParts(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionDateToParts(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> date,
boost::intrusive_ptr<Expression> timeZone,
boost::intrusive_ptr<Expression> iso8601);
@@ -1228,10 +1213,9 @@ public:
Value serialize(bool explain) const final;
Value evaluate(const Document& root, Variables* variables) const final;
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps);
+ static boost::intrusive_ptr<Expression> parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps);
void acceptVisitor(ExpressionVisitor* visitor) final {
return visitor->visit(this);
@@ -1241,7 +1225,7 @@ protected:
void _doAddDependencies(DepsTracker* deps) const final;
private:
- ExpressionDateToString(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionDateToString(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> format,
boost::intrusive_ptr<Expression> date,
boost::intrusive_ptr<Expression> timeZone,
@@ -1255,7 +1239,7 @@ private:
class ExpressionDayOfMonth final : public DateExpressionAcceptingTimeZone<ExpressionDayOfMonth> {
public:
- explicit ExpressionDayOfMonth(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ explicit ExpressionDayOfMonth(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> date,
boost::intrusive_ptr<Expression> timeZone = nullptr)
: DateExpressionAcceptingTimeZone<ExpressionDayOfMonth>(
@@ -1273,7 +1257,7 @@ public:
class ExpressionDayOfWeek final : public DateExpressionAcceptingTimeZone<ExpressionDayOfWeek> {
public:
- explicit ExpressionDayOfWeek(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ explicit ExpressionDayOfWeek(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> date,
boost::intrusive_ptr<Expression> timeZone = nullptr)
: DateExpressionAcceptingTimeZone<ExpressionDayOfWeek>(
@@ -1291,7 +1275,7 @@ public:
class ExpressionDayOfYear final : public DateExpressionAcceptingTimeZone<ExpressionDayOfYear> {
public:
- explicit ExpressionDayOfYear(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ explicit ExpressionDayOfYear(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> date,
boost::intrusive_ptr<Expression> timeZone = nullptr)
: DateExpressionAcceptingTimeZone<ExpressionDayOfYear>(
@@ -1309,7 +1293,7 @@ public:
class ExpressionDivide final : public ExpressionFixedArity<ExpressionDivide, 2> {
public:
- explicit ExpressionDivide(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionDivide(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionDivide, 2>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -1323,7 +1307,7 @@ public:
class ExpressionExp final : public ExpressionSingleNumericArg<ExpressionExp> {
public:
- explicit ExpressionExp(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionExp(ExpressionContext* const expCtx)
: ExpressionSingleNumericArg<ExpressionExp>(expCtx) {}
Value evaluateNumericArg(const Value& numericArg) const final;
@@ -1358,14 +1342,13 @@ public:
indicator
@returns the newly created field path expression
*/
- static boost::intrusive_ptr<ExpressionFieldPath> create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx, const std::string& fieldPath);
+ static boost::intrusive_ptr<ExpressionFieldPath> create(ExpressionContext* const expCtx,
+ const std::string& fieldPath);
/// Like create(), but works with the raw std::string from the user with the "$" prefixes.
- static boost::intrusive_ptr<ExpressionFieldPath> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- const std::string& raw,
- const VariablesParseState& vps);
+ static boost::intrusive_ptr<ExpressionFieldPath> parse(ExpressionContext* const expCtx,
+ const std::string& raw,
+ const VariablesParseState& vps);
/**
* Returns true if this expression logically represents the path 'dottedPath'. For example, if
@@ -1392,7 +1375,7 @@ protected:
void _doAddDependencies(DepsTracker* deps) const final;
private:
- ExpressionFieldPath(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionFieldPath(ExpressionContext* const expCtx,
const std::string& fieldPath,
Variables::Id variable);
@@ -1425,10 +1408,9 @@ public:
Value serialize(bool explain) const final;
Value evaluate(const Document& root, Variables* variables) const final;
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps);
+ static boost::intrusive_ptr<Expression> parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps);
void acceptVisitor(ExpressionVisitor* visitor) final {
return visitor->visit(this);
@@ -1438,7 +1420,7 @@ protected:
void _doAddDependencies(DepsTracker* deps) const final;
private:
- ExpressionFilter(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionFilter(ExpressionContext* const expCtx,
std::string varName,
Variables::Id varId,
boost::intrusive_ptr<Expression> input,
@@ -1457,7 +1439,7 @@ private:
class ExpressionFloor final : public ExpressionSingleNumericArg<ExpressionFloor> {
public:
- explicit ExpressionFloor(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionFloor(ExpressionContext* const expCtx)
: ExpressionSingleNumericArg<ExpressionFloor>(expCtx) {}
Value evaluateNumericArg(const Value& numericArg) const final;
@@ -1471,7 +1453,7 @@ public:
class ExpressionHour final : public DateExpressionAcceptingTimeZone<ExpressionHour> {
public:
- explicit ExpressionHour(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ explicit ExpressionHour(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> date,
boost::intrusive_ptr<Expression> timeZone = nullptr)
: DateExpressionAcceptingTimeZone<ExpressionHour>(
@@ -1489,7 +1471,7 @@ public:
class ExpressionIfNull final : public ExpressionFixedArity<ExpressionIfNull, 2> {
public:
- explicit ExpressionIfNull(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionIfNull(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionIfNull, 2>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -1503,7 +1485,7 @@ public:
class ExpressionIn final : public ExpressionFixedArity<ExpressionIn, 2> {
public:
- explicit ExpressionIn(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionIn(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionIn, 2>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -1517,7 +1499,7 @@ public:
class ExpressionIndexOfArray : public ExpressionRangedArity<ExpressionIndexOfArray, 2, 4> {
public:
- explicit ExpressionIndexOfArray(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionIndexOfArray(ExpressionContext* const expCtx)
: ExpressionRangedArity<ExpressionIndexOfArray, 2, 4>(expCtx) {}
@@ -1558,7 +1540,7 @@ private:
class ExpressionIndexOfBytes final : public ExpressionRangedArity<ExpressionIndexOfBytes, 2, 4> {
public:
- explicit ExpressionIndexOfBytes(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionIndexOfBytes(ExpressionContext* const expCtx)
: ExpressionRangedArity<ExpressionIndexOfBytes, 2, 4>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -1575,7 +1557,7 @@ public:
*/
class ExpressionIndexOfCP final : public ExpressionRangedArity<ExpressionIndexOfCP, 2, 4> {
public:
- explicit ExpressionIndexOfCP(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionIndexOfCP(ExpressionContext* const expCtx)
: ExpressionRangedArity<ExpressionIndexOfCP, 2, 4>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -1593,10 +1575,9 @@ public:
Value serialize(bool explain) const final;
Value evaluate(const Document& root, Variables* variables) const final;
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps);
+ static boost::intrusive_ptr<Expression> parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps);
struct NameAndExpression {
std::string name;
@@ -1617,7 +1598,7 @@ protected:
void _doAddDependencies(DepsTracker* deps) const final;
private:
- ExpressionLet(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionLet(ExpressionContext* const expCtx,
VariableMap&& vars,
std::vector<boost::intrusive_ptr<Expression>> children);
@@ -1627,7 +1608,7 @@ private:
class ExpressionLn final : public ExpressionSingleNumericArg<ExpressionLn> {
public:
- explicit ExpressionLn(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionLn(ExpressionContext* const expCtx)
: ExpressionSingleNumericArg<ExpressionLn>(expCtx) {}
Value evaluateNumericArg(const Value& numericArg) const final;
@@ -1640,7 +1621,7 @@ public:
class ExpressionLog final : public ExpressionFixedArity<ExpressionLog, 2> {
public:
- explicit ExpressionLog(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionLog(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionLog, 2>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -1653,7 +1634,7 @@ public:
class ExpressionLog10 final : public ExpressionSingleNumericArg<ExpressionLog10> {
public:
- explicit ExpressionLog10(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionLog10(ExpressionContext* const expCtx)
: ExpressionSingleNumericArg<ExpressionLog10>(expCtx) {}
Value evaluateNumericArg(const Value& numericArg) const final;
@@ -1670,10 +1651,9 @@ public:
Value serialize(bool explain) const final;
Value evaluate(const Document& root, Variables* variables) const final;
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps);
+ static boost::intrusive_ptr<Expression> parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps);
ComputedPaths getComputedPaths(const std::string& exprFieldPath,
Variables::Id renamingVar) const final;
@@ -1687,7 +1667,7 @@ protected:
private:
ExpressionMap(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionContext* const expCtx,
const std::string& varName, // name of variable to set
Variables::Id varId, // id of variable to set
boost::intrusive_ptr<Expression> input, // yields array to iterate
@@ -1704,10 +1684,9 @@ public:
Value serialize(bool explain) const final;
Value evaluate(const Document& root, Variables* variables) const final;
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps);
+ static boost::intrusive_ptr<Expression> parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps);
void acceptVisitor(ExpressionVisitor* visitor) final {
return visitor->visit(this);
@@ -1721,15 +1700,14 @@ protected:
void _doAddDependencies(DepsTracker* deps) const final;
private:
- ExpressionMeta(const boost::intrusive_ptr<ExpressionContext>& expCtx,
- DocumentMetadataFields::MetaType metaType);
+ ExpressionMeta(ExpressionContext* const expCtx, DocumentMetadataFields::MetaType metaType);
DocumentMetadataFields::MetaType _metaType;
};
class ExpressionMillisecond final : public DateExpressionAcceptingTimeZone<ExpressionMillisecond> {
public:
- explicit ExpressionMillisecond(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ explicit ExpressionMillisecond(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> date,
boost::intrusive_ptr<Expression> timeZone = nullptr)
: DateExpressionAcceptingTimeZone<ExpressionMillisecond>(
@@ -1747,7 +1725,7 @@ public:
class ExpressionMinute final : public DateExpressionAcceptingTimeZone<ExpressionMinute> {
public:
- explicit ExpressionMinute(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ explicit ExpressionMinute(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> date,
boost::intrusive_ptr<Expression> timeZone = nullptr)
: DateExpressionAcceptingTimeZone<ExpressionMinute>(
@@ -1765,7 +1743,7 @@ public:
class ExpressionMod final : public ExpressionFixedArity<ExpressionMod, 2> {
public:
- explicit ExpressionMod(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionMod(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionMod, 2>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -1779,7 +1757,7 @@ public:
class ExpressionMultiply final : public ExpressionVariadic<ExpressionMultiply> {
public:
- explicit ExpressionMultiply(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionMultiply(ExpressionContext* const expCtx)
: ExpressionVariadic<ExpressionMultiply>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -1801,7 +1779,7 @@ public:
class ExpressionMonth final : public DateExpressionAcceptingTimeZone<ExpressionMonth> {
public:
- explicit ExpressionMonth(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ explicit ExpressionMonth(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> date,
boost::intrusive_ptr<Expression> timeZone = nullptr)
: DateExpressionAcceptingTimeZone<ExpressionMonth>(
@@ -1819,7 +1797,7 @@ public:
class ExpressionNot final : public ExpressionFixedArity<ExpressionNot, 1> {
public:
- explicit ExpressionNot(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionNot(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionNot, 1>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -1846,17 +1824,16 @@ public:
Value serialize(bool explain) const final;
static boost::intrusive_ptr<ExpressionObject> create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionContext* const expCtx,
std::vector<std::pair<std::string, boost::intrusive_ptr<Expression>>>&&
expressionsWithChildrenInPlace);
/**
* Parses and constructs an ExpressionObject from 'obj'.
*/
- static boost::intrusive_ptr<ExpressionObject> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONObj obj,
- const VariablesParseState& vps);
+ static boost::intrusive_ptr<ExpressionObject> parse(ExpressionContext* const expCtx,
+ BSONObj obj,
+ const VariablesParseState& vps);
/**
* This ExpressionObject must outlive the returned vector.
@@ -1877,7 +1854,7 @@ protected:
private:
ExpressionObject(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionContext* const expCtx,
std::vector<boost::intrusive_ptr<Expression>> children,
std::vector<std::pair<std::string, boost::intrusive_ptr<Expression>&>>&& expressions);
@@ -1889,7 +1866,7 @@ private:
class ExpressionOr final : public ExpressionVariadic<ExpressionOr> {
public:
- explicit ExpressionOr(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionOr(ExpressionContext* const expCtx)
: ExpressionVariadic<ExpressionOr>(expCtx) {}
boost::intrusive_ptr<Expression> optimize() final;
@@ -1911,11 +1888,12 @@ public:
class ExpressionPow final : public ExpressionFixedArity<ExpressionPow, 2> {
public:
- explicit ExpressionPow(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionPow(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionPow, 2>(expCtx) {}
- static boost::intrusive_ptr<Expression> create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx, Value base, Value exp);
+ static boost::intrusive_ptr<Expression> create(ExpressionContext* const expCtx,
+ Value base,
+ Value exp);
void acceptVisitor(ExpressionVisitor* visitor) final {
return visitor->visit(this);
@@ -1929,7 +1907,7 @@ private:
class ExpressionRange final : public ExpressionRangedArity<ExpressionRange, 2, 3> {
public:
- explicit ExpressionRange(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionRange(ExpressionContext* const expCtx)
: ExpressionRangedArity<ExpressionRange, 2, 3>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -1943,7 +1921,7 @@ public:
class ExpressionReduce final : public Expression {
public:
- ExpressionReduce(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionReduce(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> input,
boost::intrusive_ptr<Expression> initial,
boost::intrusive_ptr<Expression> in,
@@ -1958,10 +1936,9 @@ public:
Value evaluate(const Document& root, Variables* variables) const final;
boost::intrusive_ptr<Expression> optimize() final;
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps);
+ static boost::intrusive_ptr<Expression> parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps);
Value serialize(bool explain) const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -1983,7 +1960,7 @@ private:
class ExpressionReplaceBase : public Expression {
public:
- ExpressionReplaceBase(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionReplaceBase(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> input,
boost::intrusive_ptr<Expression> find,
boost::intrusive_ptr<Expression> replacement)
@@ -2014,10 +1991,9 @@ class ExpressionReplaceOne final : public ExpressionReplaceBase {
public:
using ExpressionReplaceBase::ExpressionReplaceBase;
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps);
+ static boost::intrusive_ptr<Expression> parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps);
static constexpr const char* const opName = "$replaceOne";
const char* getOpName() const final {
@@ -2036,10 +2012,9 @@ class ExpressionReplaceAll final : public ExpressionReplaceBase {
public:
using ExpressionReplaceBase::ExpressionReplaceBase;
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps);
+ static boost::intrusive_ptr<Expression> parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps);
static constexpr const char* const opName = "$replaceAll";
const char* getOpName() const final {
@@ -2056,7 +2031,7 @@ protected:
class ExpressionSecond final : public DateExpressionAcceptingTimeZone<ExpressionSecond> {
public:
- ExpressionSecond(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionSecond(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> date,
boost::intrusive_ptr<Expression> timeZone = nullptr)
: DateExpressionAcceptingTimeZone<ExpressionSecond>(
@@ -2074,7 +2049,7 @@ public:
class ExpressionSetDifference final : public ExpressionFixedArity<ExpressionSetDifference, 2> {
public:
- explicit ExpressionSetDifference(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionSetDifference(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionSetDifference, 2>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -2088,7 +2063,7 @@ public:
class ExpressionSetEquals final : public ExpressionVariadic<ExpressionSetEquals> {
public:
- explicit ExpressionSetEquals(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionSetEquals(ExpressionContext* const expCtx)
: ExpressionVariadic<ExpressionSetEquals>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -2103,7 +2078,7 @@ public:
class ExpressionSetIntersection final : public ExpressionVariadic<ExpressionSetIntersection> {
public:
- explicit ExpressionSetIntersection(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionSetIntersection(ExpressionContext* const expCtx)
: ExpressionVariadic<ExpressionSetIntersection>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -2126,7 +2101,7 @@ public:
// Not final, inherited from for optimizations.
class ExpressionSetIsSubset : public ExpressionFixedArity<ExpressionSetIsSubset, 2> {
public:
- explicit ExpressionSetIsSubset(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionSetIsSubset(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionSetIsSubset, 2>(expCtx) {}
boost::intrusive_ptr<Expression> optimize() override;
@@ -2144,7 +2119,7 @@ private:
class ExpressionSetUnion final : public ExpressionVariadic<ExpressionSetUnion> {
public:
- explicit ExpressionSetUnion(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionSetUnion(ExpressionContext* const expCtx)
: ExpressionVariadic<ExpressionSetUnion>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -2166,7 +2141,7 @@ public:
class ExpressionSize final : public ExpressionFixedArity<ExpressionSize, 1> {
public:
- explicit ExpressionSize(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionSize(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionSize, 1>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -2180,7 +2155,7 @@ public:
class ExpressionReverseArray final : public ExpressionFixedArity<ExpressionReverseArray, 1> {
public:
- explicit ExpressionReverseArray(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionReverseArray(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionReverseArray, 1>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -2194,7 +2169,7 @@ public:
class ExpressionSlice final : public ExpressionRangedArity<ExpressionSlice, 2, 3> {
public:
- explicit ExpressionSlice(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionSlice(ExpressionContext* const expCtx)
: ExpressionRangedArity<ExpressionSlice, 2, 3>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -2208,7 +2183,7 @@ public:
class ExpressionIsArray final : public ExpressionFixedArity<ExpressionIsArray, 1> {
public:
- explicit ExpressionIsArray(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionIsArray(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionIsArray, 1>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -2221,7 +2196,7 @@ public:
class ExpressionRound final : public ExpressionRangedArity<ExpressionRound, 1, 2> {
public:
- explicit ExpressionRound(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionRound(ExpressionContext* const expCtx)
: ExpressionRangedArity<ExpressionRound, 1, 2>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -2234,7 +2209,7 @@ public:
class ExpressionSplit final : public ExpressionFixedArity<ExpressionSplit, 2> {
public:
- explicit ExpressionSplit(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionSplit(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionSplit, 2>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -2248,7 +2223,7 @@ public:
class ExpressionSqrt final : public ExpressionSingleNumericArg<ExpressionSqrt> {
public:
- explicit ExpressionSqrt(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionSqrt(ExpressionContext* const expCtx)
: ExpressionSingleNumericArg<ExpressionSqrt>(expCtx) {}
Value evaluateNumericArg(const Value& numericArg) const final;
@@ -2262,7 +2237,7 @@ public:
class ExpressionStrcasecmp final : public ExpressionFixedArity<ExpressionStrcasecmp, 2> {
public:
- explicit ExpressionStrcasecmp(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionStrcasecmp(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionStrcasecmp, 2>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -2276,7 +2251,7 @@ public:
class ExpressionSubstrBytes final : public ExpressionFixedArity<ExpressionSubstrBytes, 3> {
public:
- explicit ExpressionSubstrBytes(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionSubstrBytes(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionSubstrBytes, 3>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -2290,7 +2265,7 @@ public:
class ExpressionSubstrCP final : public ExpressionFixedArity<ExpressionSubstrCP, 3> {
public:
- explicit ExpressionSubstrCP(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionSubstrCP(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionSubstrCP, 3>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -2304,7 +2279,7 @@ public:
class ExpressionStrLenBytes final : public ExpressionFixedArity<ExpressionStrLenBytes, 1> {
public:
- explicit ExpressionStrLenBytes(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionStrLenBytes(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionStrLenBytes, 1>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -2318,7 +2293,7 @@ public:
class ExpressionBinarySize final : public ExpressionFixedArity<ExpressionBinarySize, 1> {
public:
- ExpressionBinarySize(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ ExpressionBinarySize(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionBinarySize, 1>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -2332,7 +2307,7 @@ public:
class ExpressionStrLenCP final : public ExpressionFixedArity<ExpressionStrLenCP, 1> {
public:
- explicit ExpressionStrLenCP(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionStrLenCP(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionStrLenCP, 1>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -2346,7 +2321,7 @@ public:
class ExpressionSubtract final : public ExpressionFixedArity<ExpressionSubtract, 2> {
public:
- explicit ExpressionSubtract(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionSubtract(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionSubtract, 2>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -2363,7 +2338,7 @@ public:
using ExpressionPair =
std::pair<boost::intrusive_ptr<Expression>&, boost::intrusive_ptr<Expression>&>;
- ExpressionSwitch(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionSwitch(ExpressionContext* const expCtx,
std::vector<boost::intrusive_ptr<Expression>> children,
std::vector<ExpressionPair> branches)
: Expression(expCtx, std::move(children)),
@@ -2372,10 +2347,9 @@ public:
Value evaluate(const Document& root, Variables* variables) const final;
boost::intrusive_ptr<Expression> optimize() final;
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vpsIn);
+ static boost::intrusive_ptr<Expression> parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vpsIn);
Value serialize(bool explain) const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -2393,7 +2367,7 @@ private:
class ExpressionToLower final : public ExpressionFixedArity<ExpressionToLower, 1> {
public:
- explicit ExpressionToLower(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionToLower(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionToLower, 1>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -2407,7 +2381,7 @@ public:
class ExpressionToUpper final : public ExpressionFixedArity<ExpressionToUpper, 1> {
public:
- explicit ExpressionToUpper(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionToUpper(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionToUpper, 1>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -2431,7 +2405,7 @@ private:
};
public:
- ExpressionTrim(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionTrim(ExpressionContext* const expCtx,
TrimType trimType,
StringData name,
boost::intrusive_ptr<Expression> input,
@@ -2444,10 +2418,9 @@ public:
Value evaluate(const Document& root, Variables* variables) const final;
boost::intrusive_ptr<Expression> optimize() final;
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vpsIn);
+ static boost::intrusive_ptr<Expression> parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vpsIn);
Value serialize(bool explain) const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -2493,13 +2466,12 @@ private:
class ExpressionTrunc final : public ExpressionRangedArity<ExpressionTrunc, 1, 2> {
public:
- explicit ExpressionTrunc(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionTrunc(ExpressionContext* const expCtx)
: ExpressionRangedArity<ExpressionTrunc, 1, 2>(expCtx) {}
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement elem,
- const VariablesParseState& vps);
+ static boost::intrusive_ptr<Expression> parse(ExpressionContext* const expCtx,
+ BSONElement elem,
+ const VariablesParseState& vps);
Value evaluate(const Document& root, Variables* variables) const final;
const char* getOpName() const final;
@@ -2511,7 +2483,7 @@ public:
class ExpressionType final : public ExpressionFixedArity<ExpressionType, 1> {
public:
- explicit ExpressionType(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionType(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionType, 1>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -2524,7 +2496,7 @@ public:
class ExpressionIsNumber final : public ExpressionFixedArity<ExpressionIsNumber, 1> {
public:
- explicit ExpressionIsNumber(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionIsNumber(ExpressionContext* const expCtx)
: ExpressionFixedArity<ExpressionIsNumber, 1>(expCtx) {}
Value evaluate(const Document& root, Variables* variables) const final;
@@ -2537,7 +2509,7 @@ public:
class ExpressionWeek final : public DateExpressionAcceptingTimeZone<ExpressionWeek> {
public:
- ExpressionWeek(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionWeek(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> date,
boost::intrusive_ptr<Expression> timeZone = nullptr)
: DateExpressionAcceptingTimeZone<ExpressionWeek>(
@@ -2555,7 +2527,7 @@ public:
class ExpressionIsoWeekYear final : public DateExpressionAcceptingTimeZone<ExpressionIsoWeekYear> {
public:
- explicit ExpressionIsoWeekYear(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ explicit ExpressionIsoWeekYear(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> date,
boost::intrusive_ptr<Expression> timeZone = nullptr)
: DateExpressionAcceptingTimeZone<ExpressionIsoWeekYear>(
@@ -2574,7 +2546,7 @@ public:
class ExpressionIsoDayOfWeek final
: public DateExpressionAcceptingTimeZone<ExpressionIsoDayOfWeek> {
public:
- ExpressionIsoDayOfWeek(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionIsoDayOfWeek(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> date,
boost::intrusive_ptr<Expression> timeZone = nullptr)
: DateExpressionAcceptingTimeZone<ExpressionIsoDayOfWeek>(
@@ -2592,7 +2564,7 @@ public:
class ExpressionIsoWeek final : public DateExpressionAcceptingTimeZone<ExpressionIsoWeek> {
public:
- ExpressionIsoWeek(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionIsoWeek(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> date,
boost::intrusive_ptr<Expression> timeZone = nullptr)
: DateExpressionAcceptingTimeZone<ExpressionIsoWeek>(
@@ -2610,7 +2582,7 @@ public:
class ExpressionYear final : public DateExpressionAcceptingTimeZone<ExpressionYear> {
public:
- ExpressionYear(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionYear(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> date,
boost::intrusive_ptr<Expression> timeZone = nullptr)
: DateExpressionAcceptingTimeZone<ExpressionYear>(
@@ -2628,7 +2600,7 @@ public:
class ExpressionZip final : public Expression {
public:
- ExpressionZip(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionZip(ExpressionContext* const expCtx,
bool useLongestLength,
std::vector<boost::intrusive_ptr<Expression>> children,
std::vector<std::reference_wrapper<boost::intrusive_ptr<Expression>>> inputs,
@@ -2640,10 +2612,9 @@ public:
Value evaluate(const Document& root, Variables* variables) const final;
boost::intrusive_ptr<Expression> optimize() final;
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vpsIn);
+ static boost::intrusive_ptr<Expression> parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vpsIn);
Value serialize(bool explain) const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -2665,14 +2636,13 @@ public:
* Creates a $convert expression converting from 'input' to the type given by 'toType'. Leaves
* 'onNull' and 'onError' unspecified.
*/
- static boost::intrusive_ptr<Expression> create(const boost::intrusive_ptr<ExpressionContext>&,
+ static boost::intrusive_ptr<Expression> create(ExpressionContext* const,
boost::intrusive_ptr<Expression> input,
BSONType toType);
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vpsIn);
+ static boost::intrusive_ptr<Expression> parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vpsIn);
Value evaluate(const Document& root, Variables* variables) const final;
boost::intrusive_ptr<Expression> optimize() final;
@@ -2686,7 +2656,7 @@ protected:
void _doAddDependencies(DepsTracker* deps) const final;
private:
- ExpressionConvert(const boost::intrusive_ptr<ExpressionContext>&,
+ ExpressionConvert(ExpressionContext* const,
boost::intrusive_ptr<Expression> input,
boost::intrusive_ptr<Expression> to,
boost::intrusive_ptr<Expression> onError,
@@ -2778,7 +2748,7 @@ public:
return _opName;
}
- ExpressionRegex(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionRegex(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> input,
boost::intrusive_ptr<Expression> regex,
boost::intrusive_ptr<Expression> options,
@@ -2822,10 +2792,9 @@ private:
class ExpressionRegexFind final : public ExpressionRegex {
public:
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vpsIn);
+ static boost::intrusive_ptr<Expression> parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vpsIn);
Value evaluate(const Document& root, Variables* variables) const final;
@@ -2838,10 +2807,9 @@ public:
class ExpressionRegexFindAll final : public ExpressionRegex {
public:
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vpsIn);
+ static boost::intrusive_ptr<Expression> parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vpsIn);
Value evaluate(const Document& root, Variables* variables) const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -2853,10 +2821,9 @@ public:
class ExpressionRegexMatch final : public ExpressionRegex {
public:
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vpsIn);
+ static boost::intrusive_ptr<Expression> parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vpsIn);
Value evaluate(const Document& root, Variables* variables) const final;
diff --git a/src/mongo/db/pipeline/expression_and_test.cpp b/src/mongo/db/pipeline/expression_and_test.cpp
index dc5b799b000..cbfa37a77d1 100644
--- a/src/mongo/db/pipeline/expression_and_test.cpp
+++ b/src/mongo/db/pipeline/expression_and_test.cpp
@@ -102,19 +102,18 @@ class ExpectedResultBase {
public:
virtual ~ExpectedResultBase() {}
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
BSONObj specObject = BSON("" << spec());
BSONElement specElement = specObject.firstElement();
- VariablesParseState vps = expCtx->variablesParseState;
- intrusive_ptr<Expression> expression = Expression::parseOperand(expCtx, specElement, vps);
+ VariablesParseState vps = expCtx.variablesParseState;
+ intrusive_ptr<Expression> expression = Expression::parseOperand(&expCtx, specElement, vps);
ASSERT_BSONOBJ_EQ(constify(spec()), expressionToBson(expression));
ASSERT_BSONOBJ_EQ(
BSON("" << expectedResult()),
- toBson(expression->evaluate(fromBson(BSON("a" << 1)), &expCtx->variables)));
+ toBson(expression->evaluate(fromBson(BSON("a" << 1)), &expCtx.variables)));
intrusive_ptr<Expression> optimized = expression->optimize();
- ASSERT_BSONOBJ_EQ(
- BSON("" << expectedResult()),
- toBson(optimized->evaluate(fromBson(BSON("a" << 1)), &expCtx->variables)));
+ ASSERT_BSONOBJ_EQ(BSON("" << expectedResult()),
+ toBson(optimized->evaluate(fromBson(BSON("a" << 1)), &expCtx.variables)));
}
protected:
@@ -126,11 +125,11 @@ class OptimizeBase {
public:
virtual ~OptimizeBase() {}
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
BSONObj specObject = BSON("" << spec());
BSONElement specElement = specObject.firstElement();
- VariablesParseState vps = expCtx->variablesParseState;
- intrusive_ptr<Expression> expression = Expression::parseOperand(expCtx, specElement, vps);
+ VariablesParseState vps = expCtx.variablesParseState;
+ intrusive_ptr<Expression> expression = Expression::parseOperand(&expCtx, specElement, vps);
ASSERT_BSONOBJ_EQ(constify(spec()), expressionToBson(expression));
intrusive_ptr<Expression> optimized = expression->optimize();
ASSERT_BSONOBJ_EQ(expectedOptimized(), expressionToBson(optimized));
diff --git a/src/mongo/db/pipeline/expression_compare_test.cpp b/src/mongo/db/pipeline/expression_compare_test.cpp
index 8ed9b2aa3d8..11836d77267 100644
--- a/src/mongo/db/pipeline/expression_compare_test.cpp
+++ b/src/mongo/db/pipeline/expression_compare_test.cpp
@@ -91,9 +91,9 @@ public:
void run() {
BSONObj specObject = BSON("" << spec());
BSONElement specElement = specObject.firstElement();
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
- intrusive_ptr<Expression> expression = Expression::parseOperand(expCtx, specElement, vps);
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
+ intrusive_ptr<Expression> expression = Expression::parseOperand(&expCtx, specElement, vps);
intrusive_ptr<Expression> optimized = expression->optimize();
ASSERT_BSONOBJ_EQ(constify(expectedOptimized()), expressionToBson(optimized));
}
@@ -122,16 +122,16 @@ public:
OptimizeBase::run();
BSONObj specObject = BSON("" << spec());
BSONElement specElement = specObject.firstElement();
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
- intrusive_ptr<Expression> expression = Expression::parseOperand(expCtx, specElement, vps);
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
+ intrusive_ptr<Expression> expression = Expression::parseOperand(&expCtx, specElement, vps);
// Check expression spec round trip.
ASSERT_BSONOBJ_EQ(constify(spec()), expressionToBson(expression));
// Check evaluation result.
- ASSERT_BSONOBJ_EQ(expectedResult(), toBson(expression->evaluate({}, &expCtx->variables)));
+ ASSERT_BSONOBJ_EQ(expectedResult(), toBson(expression->evaluate({}, &expCtx.variables)));
// Check that the result is the same after optimizing.
intrusive_ptr<Expression> optimized = expression->optimize();
- ASSERT_BSONOBJ_EQ(expectedResult(), toBson(optimized->evaluate({}, &expCtx->variables)));
+ ASSERT_BSONOBJ_EQ(expectedResult(), toBson(optimized->evaluate({}, &expCtx.variables)));
}
protected:
@@ -160,11 +160,11 @@ class ParseError {
public:
virtual ~ParseError() {}
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
BSONObj specObject = BSON("" << spec());
BSONElement specElement = specObject.firstElement();
- VariablesParseState vps = expCtx->variablesParseState;
- ASSERT_THROWS(Expression::parseOperand(expCtx, specElement, vps), AssertionException);
+ VariablesParseState vps = expCtx.variablesParseState;
+ ASSERT_THROWS(Expression::parseOperand(&expCtx, specElement, vps), AssertionException);
}
protected:
@@ -365,10 +365,10 @@ public:
void run() {
BSONObj specObject = BSON("" << BSON("$ne" << BSON_ARRAY("a" << 1)));
BSONElement specElement = specObject.firstElement();
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
- intrusive_ptr<Expression> expression = Expression::parseOperand(expCtx, specElement, vps);
- ASSERT_VALUE_EQ(expression->evaluate({}, &expCtx->variables), Value(true));
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
+ intrusive_ptr<Expression> expression = Expression::parseOperand(&expCtx, specElement, vps);
+ ASSERT_VALUE_EQ(expression->evaluate({}, &expCtx.variables), Value(true));
}
};
diff --git a/src/mongo/db/pipeline/expression_context.cpp b/src/mongo/db/pipeline/expression_context.cpp
index a077071dca3..8625cf80903 100644
--- a/src/mongo/db/pipeline/expression_context.cpp
+++ b/src/mongo/db/pipeline/expression_context.cpp
@@ -36,7 +36,6 @@
#include "mongo/db/query/collation/collation_spec.h"
#include "mongo/db/query/collation/collator_factory_interface.h"
#include "mongo/util/intrusive_counter.h"
-#include "mongo/util/scopeguard.h"
namespace mongo {
@@ -126,16 +125,8 @@ ExpressionContext::ExpressionContext(
if (!isMapReduce) {
jsHeapLimitMB = internalQueryJavaScriptHeapSizeLimitMB.load();
}
- if (letParameters) {
- // TODO SERVER-47713: One possible fix is to change the interface of everything that needs
- // an expression context intrusive_ptr to take a raw ptr.
- auto intrusiveThis = boost::intrusive_ptr{this};
- ON_BLOCK_EXIT([&] {
- intrusiveThis.detach();
- unsafeRefDecRefCountTo(0u);
- });
- variables.seedVariablesWithLetParameters(intrusiveThis, *letParameters);
- }
+ if (letParameters)
+ variables.seedVariablesWithLetParameters(this, *letParameters);
}
ExpressionContext::ExpressionContext(OperationContext* opCtx,
@@ -160,16 +151,8 @@ ExpressionContext::ExpressionContext(OperationContext* opCtx,
}
jsHeapLimitMB = internalQueryJavaScriptHeapSizeLimitMB.load();
- if (letParameters) {
- // TODO SERVER-47713: One possible fix is to change the interface of everything that needs
- // an expression context intrusive_ptr to take a raw ptr.
- auto intrusiveThis = boost::intrusive_ptr{this};
- ON_BLOCK_EXIT([&] {
- intrusiveThis.detach();
- unsafeRefDecRefCountTo(0u);
- });
- variables.seedVariablesWithLetParameters(intrusiveThis, *letParameters);
- }
+ if (letParameters)
+ variables.seedVariablesWithLetParameters(this, *letParameters);
}
void ExpressionContext::checkForInterrupt() {
@@ -181,9 +164,8 @@ void ExpressionContext::checkForInterrupt() {
}
}
-ExpressionContext::CollatorStash::CollatorStash(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- std::unique_ptr<CollatorInterface> newCollator)
+ExpressionContext::CollatorStash::CollatorStash(ExpressionContext* const expCtx,
+ std::unique_ptr<CollatorInterface> newCollator)
: _expCtx(expCtx), _originalCollator(std::move(_expCtx->_collator)) {
_expCtx->setCollator(std::move(newCollator));
}
diff --git a/src/mongo/db/pipeline/expression_context.h b/src/mongo/db/pipeline/expression_context.h
index 7a5976a48b7..d3a491119d3 100644
--- a/src/mongo/db/pipeline/expression_context.h
+++ b/src/mongo/db/pipeline/expression_context.h
@@ -88,7 +88,7 @@ public:
* This constructor is private, all CollatorStashes should be created by calling
* ExpressionContext::temporarilyChangeCollator().
*/
- CollatorStash(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ CollatorStash(ExpressionContext* const expCtx,
std::unique_ptr<CollatorInterface> newCollator);
friend class ExpressionContext;
diff --git a/src/mongo/db/pipeline/expression_convert_test.cpp b/src/mongo/db/pipeline/expression_convert_test.cpp
index 05f3de3ccf0..5d9e53fd519 100644
--- a/src/mongo/db/pipeline/expression_convert_test.cpp
+++ b/src/mongo/db/pipeline/expression_convert_test.cpp
@@ -64,7 +64,7 @@ TEST_F(ExpressionConvertTest, ParseAndSerializeWithoutOptionalArguments) {
<< "$path1"
<< "to"
<< "int"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value(fromjson("{$convert: {input: '$path1', to: {$const: 'int'}}}")),
convertExp->serialize(false));
@@ -81,7 +81,7 @@ TEST_F(ExpressionConvertTest, ParseAndSerializeWithOnError) {
<< "to"
<< "int"
<< "onError" << 0));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(
Value(fromjson("{$convert: {input: '$path1', to: {$const: 'int'}, onError: {$const: 0}}}")),
@@ -100,7 +100,7 @@ TEST_F(ExpressionConvertTest, ParseAndSerializeWithOnNull) {
<< "to"
<< "int"
<< "onNull" << 0));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(
Value(fromjson("{$convert: {input: '$path1', to: {$const: 'int'}, onNull: {$const: 0}}}")),
@@ -117,13 +117,13 @@ TEST_F(ExpressionConvertTest, ConvertWithoutInputFailsToParse) {
auto spec = BSON("$convert" << BSON("to"
<< "int"
<< "onError" << 0));
- ASSERT_THROWS_WITH_CHECK(Expression::parseExpression(expCtx, spec, expCtx->variablesParseState),
- AssertionException,
- [](const AssertionException& exception) {
- ASSERT_EQ(exception.code(), ErrorCodes::FailedToParse);
- ASSERT_STRING_CONTAINS(exception.reason(),
- "Missing 'input' parameter to $convert");
- });
+ ASSERT_THROWS_WITH_CHECK(
+ Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState),
+ AssertionException,
+ [](const AssertionException& exception) {
+ ASSERT_EQ(exception.code(), ErrorCodes::FailedToParse);
+ ASSERT_STRING_CONTAINS(exception.reason(), "Missing 'input' parameter to $convert");
+ });
}
TEST_F(ExpressionConvertTest, ConvertWithoutToFailsToParse) {
@@ -132,13 +132,13 @@ TEST_F(ExpressionConvertTest, ConvertWithoutToFailsToParse) {
auto spec = BSON("$convert" << BSON("input"
<< "$path1"
<< "onError" << 0));
- ASSERT_THROWS_WITH_CHECK(Expression::parseExpression(expCtx, spec, expCtx->variablesParseState),
- AssertionException,
- [](const AssertionException& exception) {
- ASSERT_EQ(exception.code(), ErrorCodes::FailedToParse);
- ASSERT_STRING_CONTAINS(exception.reason(),
- "Missing 'to' parameter to $convert");
- });
+ ASSERT_THROWS_WITH_CHECK(
+ Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState),
+ AssertionException,
+ [](const AssertionException& exception) {
+ ASSERT_EQ(exception.code(), ErrorCodes::FailedToParse);
+ ASSERT_STRING_CONTAINS(exception.reason(), "Missing 'to' parameter to $convert");
+ });
}
TEST_F(ExpressionConvertTest, InvalidTypeNameFails) {
@@ -150,7 +150,7 @@ TEST_F(ExpressionConvertTest, InvalidTypeNameFails) {
<< "dinosaur"
<< "onError" << 0));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(Document(), &expCtx->variables),
AssertionException,
@@ -167,7 +167,7 @@ TEST_F(ExpressionConvertTest, NonIntegralTypeFails) {
<< "$path1"
<< "to" << 3.6 << "onError" << 0));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(Document(), &expCtx->variables),
AssertionException,
@@ -189,7 +189,7 @@ TEST_F(ExpressionConvertTest, NonStringNonNumericalTypeFails) {
<< "Tyrannosaurus rex")
<< "onError" << 0));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(Document(), &expCtx->variables),
AssertionException,
@@ -208,7 +208,7 @@ TEST_F(ExpressionConvertTest, InvalidNumericTargetTypeFails) {
<< "$path1"
<< "to" << 100 << "onError" << 0));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(
convertExp->evaluate(Document(), &expCtx->variables),
@@ -228,7 +228,7 @@ TEST_F(ExpressionConvertTest, NegativeNumericTargetTypeFails) {
<< "$path1"
<< "to" << -2 << "onError" << 0));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(
convertExp->evaluate(Document(), &expCtx->variables),
@@ -286,7 +286,8 @@ TEST_F(ExpressionConvertTest, UnsupportedConversionShouldThrowUnlessOnErrorProvi
Document input{{"path1", inputValue}};
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp =
+ Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(input, &expCtx->variables),
AssertionException,
@@ -309,7 +310,8 @@ TEST_F(ExpressionConvertTest, UnsupportedConversionShouldThrowUnlessOnErrorProvi
Document input{{"path1", inputValue}};
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp =
+ Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate(input, &expCtx->variables), "X"_sd, BSONType::String);
@@ -323,7 +325,7 @@ TEST_F(ExpressionConvertTest, ConvertNullishInput) {
<< "$path1"
<< "to"
<< "int"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document nullInput{{"path1", BSONNULL}};
Document undefinedInput{{"path1", BSONUndefined}};
@@ -345,7 +347,7 @@ TEST_F(ExpressionConvertTest, ConvertNullishInputWithOnNull) {
<< "B)"
<< "onError"
<< "Should not be used here"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document nullInput{{"path1", BSONNULL}};
Document undefinedInput{{"path1", BSONUndefined}};
@@ -367,7 +369,7 @@ TEST_F(ExpressionConvertTest, NullishToReturnsNull) {
<< "Should not be used here"
<< "onError"
<< "Also should not be used"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document nullInput{{"path1", BSONNULL}};
Document undefinedInput{{"path1", BSONUndefined}};
@@ -384,7 +386,7 @@ TEST_F(ExpressionConvertTest, NullInputOverridesNullTo) {
auto spec =
BSON("$convert" << BSON("input" << Value(BSONNULL) << "to" << Value(BSONNULL) << "onNull"
<< "X"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate(Document{}, &expCtx->variables), "X"_sd, BSONType::String);
@@ -395,7 +397,7 @@ TEST_F(ExpressionConvertTest, ConvertOptimizesToExpressionConstant) {
auto spec = BSON("$convert" << BSON("input" << 0 << "to"
<< "double"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
convertExp = convertExp->optimize();
auto constResult = dynamic_cast<ExpressionConstant*>(convertExp.get());
@@ -410,7 +412,7 @@ TEST_F(ExpressionConvertTest, ConvertWithOnErrorOptimizesToExpressionConstant) {
<< "objectId"
<< "onError"
<< "X"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
convertExp = convertExp->optimize();
auto constResult = dynamic_cast<ExpressionConstant*>(convertExp.get());
@@ -425,7 +427,7 @@ TEST_F(ExpressionConvertTest, DoubleIdentityConversion) {
<< "$path1"
<< "to"
<< "double"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document doubleInput{{"path1", 2.4}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -455,7 +457,7 @@ TEST_F(ExpressionConvertTest, BoolIdentityConversion) {
<< "$path1"
<< "to"
<< "bool"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document trueBoolInput{{"path1", true}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -473,7 +475,7 @@ TEST_F(ExpressionConvertTest, StringIdentityConversion) {
<< "$path1"
<< "to"
<< "string"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document stringInput{{"path1", "More cowbell"_sd}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -487,7 +489,7 @@ TEST_F(ExpressionConvertTest, ObjectIdIdentityConversion) {
<< "$path1"
<< "to"
<< "objectId"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document oidInput{{"path1", OID("0123456789abcdef01234567")}};
ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(oidInput, &expCtx->variables),
@@ -502,7 +504,7 @@ TEST_F(ExpressionConvertTest, DateIdentityConversion) {
<< "$path1"
<< "to"
<< "date"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document dateInput{{"path1", Date_t{}}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -516,7 +518,7 @@ TEST_F(ExpressionConvertTest, IntIdentityConversion) {
<< "$path1"
<< "to"
<< "int"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document intInput{{"path1", int{123}}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -530,7 +532,7 @@ TEST_F(ExpressionConvertTest, LongIdentityConversion) {
<< "$path1"
<< "to"
<< "long"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document longInput{{"path1", 123LL}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -544,7 +546,7 @@ TEST_F(ExpressionConvertTest, DecimalIdentityConversion) {
<< "$path1"
<< "to"
<< "decimal"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document decimalInput{{"path1", Decimal128("2.4")}};
ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(decimalInput, &expCtx->variables),
@@ -575,7 +577,7 @@ TEST_F(ExpressionConvertTest, ConvertDateToBool) {
<< "$path1"
<< "to"
<< "bool"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
// All date inputs evaluate as true.
Document dateInput{{"path1", Date_t{}}};
@@ -590,7 +592,7 @@ TEST_F(ExpressionConvertTest, ConvertIntToBool) {
<< "$path1"
<< "to"
<< "bool"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document trueIntInput{{"path1", int{1}}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -608,7 +610,7 @@ TEST_F(ExpressionConvertTest, ConvertLongToBool) {
<< "$path1"
<< "to"
<< "bool"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document trueLongInput{{"path1", -1LL}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -626,7 +628,7 @@ TEST_F(ExpressionConvertTest, ConvertDoubleToBool) {
<< "$path1"
<< "to"
<< "bool"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document trueDoubleInput{{"path1", 2.4}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -656,7 +658,7 @@ TEST_F(ExpressionConvertTest, ConvertDecimalToBool) {
<< "$path1"
<< "to"
<< "bool"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document trueDecimalInput{{"path1", Decimal128(5)}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -698,7 +700,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToBool) {
<< "$path1"
<< "to"
<< "bool"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document stringInput{{"path1", "str"_sd}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -716,7 +718,7 @@ TEST_F(ExpressionConvertTest, ConvertObjectIdToBool) {
<< "$path1"
<< "to"
<< "bool"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document oidInput{{"path1", OID("59E8A8D8FEDCBA9876543210")}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -730,7 +732,7 @@ TEST_F(ExpressionConvertTest, ConvertMinKeyToBool) {
<< "$path1"
<< "to"
<< "bool"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document minKeyInput{{"path1", MINKEY}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -744,7 +746,7 @@ TEST_F(ExpressionConvertTest, ConvertObjectToBool) {
<< "$path1"
<< "to"
<< "bool"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document objectInput{{"path1", Document{{"foo", 1}}}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -758,7 +760,7 @@ TEST_F(ExpressionConvertTest, ConvertArrayToBool) {
<< "$path1"
<< "to"
<< "bool"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document arrayInput{{"path1", BSON_ARRAY(1)}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -772,7 +774,7 @@ TEST_F(ExpressionConvertTest, ConvertBinDataToBool) {
<< "$path1"
<< "to"
<< "bool"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
char data[] = "(^_^)";
Document binInput{{"path1", BSONBinData(data, sizeof(data), BinDataType::BinDataGeneral)}};
@@ -787,7 +789,7 @@ TEST_F(ExpressionConvertTest, ConvertRegexToBool) {
<< "$path1"
<< "to"
<< "bool"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document regexInput{{"path1", BSONRegEx("ab*a"_sd)}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -801,7 +803,7 @@ TEST_F(ExpressionConvertTest, ConvertDBRefToBool) {
<< "$path1"
<< "to"
<< "bool"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document refInput{{"path1", BSONDBRef("db.coll"_sd, OID("aaaaaaaaaaaaaaaaaaaaaaaa"))}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -815,7 +817,7 @@ TEST_F(ExpressionConvertTest, ConvertCodeToBool) {
<< "$path1"
<< "to"
<< "bool"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document codeInput{{"path1", BSONCode("print('Hello world!');"_sd)}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -829,7 +831,7 @@ TEST_F(ExpressionConvertTest, ConvertSymbolToBool) {
<< "$path1"
<< "to"
<< "bool"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document symbolInput{{"path1", BSONSymbol("print"_sd)}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -843,7 +845,7 @@ TEST_F(ExpressionConvertTest, ConvertCodeWScopeToBool) {
<< "$path1"
<< "to"
<< "bool"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document codeWScopeInput{
{"path1", BSONCodeWScope("print('Hello again, world!')"_sd, BSONObj())}};
@@ -858,7 +860,7 @@ TEST_F(ExpressionConvertTest, ConvertTimestampToBool) {
<< "$path1"
<< "to"
<< "bool"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document timestampInput{{"path1", Timestamp()}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -872,7 +874,7 @@ TEST_F(ExpressionConvertTest, ConvertMaxKeyToBool) {
<< "$path1"
<< "to"
<< "bool"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document maxKeyInput{{"path1", MAXKEY}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -886,7 +888,7 @@ TEST_F(ExpressionConvertTest, ConvertNumericToDouble) {
<< "$path1"
<< "to"
<< "double"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document intInput{{"path1", int{1}}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -949,7 +951,7 @@ TEST_F(ExpressionConvertTest, ConvertDateToDouble) {
<< "$path1"
<< "to"
<< "double"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document dateInput{{"path1", Date_t::fromMillisSinceEpoch(123)}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -970,7 +972,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDecimalToDouble) {
<< "$path1"
<< "to"
<< "double"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document overflowInput{{"path1", Decimal128("1e309")}};
ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(overflowInput, &expCtx->variables),
@@ -1000,7 +1002,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDecimalToDoubleWithOnError) {
<< "double"
<< "onError"
<< "X"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document overflowInput{{"path1", Decimal128("1e309")}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -1018,7 +1020,7 @@ TEST_F(ExpressionConvertTest, ConvertNumericToDecimal) {
<< "$path1"
<< "to"
<< "decimal"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document intInput{{"path1", int{1}}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -1073,7 +1075,7 @@ TEST_F(ExpressionConvertTest, ConvertDateToDecimal) {
<< "$path1"
<< "to"
<< "decimal"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document dateInput{{"path1", Date_t::fromMillisSinceEpoch(123)}};
ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(dateInput, &expCtx->variables),
@@ -1093,7 +1095,7 @@ TEST_F(ExpressionConvertTest, ConvertDoubleToInt) {
<< "$path1"
<< "to"
<< "int"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document simpleInput{{"path1", 1.0}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -1134,7 +1136,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDoubleToInt) {
<< "$path1"
<< "to"
<< "int"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
int maxInt = std::numeric_limits<int>::max();
double overflowInt =
@@ -1199,7 +1201,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDoubleToIntWithOnError) {
<< "int"
<< "onError"
<< "X"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
int maxInt = std::numeric_limits<int>::max();
double overflowInt =
@@ -1235,7 +1237,7 @@ TEST_F(ExpressionConvertTest, ConvertDoubleToLong) {
<< "$path1"
<< "to"
<< "long"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document simpleInput{{"path1", 1.0}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -1280,7 +1282,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDoubleToLong) {
<< "$path1"
<< "to"
<< "long"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
double overflowLong = BSONElement::kLongLongMaxPlusOneAsDouble;
Document overflowInput{{"path1", overflowLong}};
@@ -1343,7 +1345,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDoubleToLongWithOnError) {
<< "long"
<< "onError"
<< "X"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
double overflowLong = BSONElement::kLongLongMaxPlusOneAsDouble;
Document overflowInput{{"path1", overflowLong}};
@@ -1377,7 +1379,7 @@ TEST_F(ExpressionConvertTest, ConvertDecimalToInt) {
<< "$path1"
<< "to"
<< "int"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document simpleInput{{"path1", Decimal128("1.0")}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -1418,7 +1420,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDecimalToInt) {
<< "$path1"
<< "to"
<< "int"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
int maxInt = std::numeric_limits<int>::max();
Document overflowInput{{"path1", Decimal128(maxInt).add(Decimal128(1))}};
@@ -1488,7 +1490,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDecimalToIntWithOnError) {
<< "int"
<< "onError"
<< "X"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
int maxInt = std::numeric_limits<int>::max();
Document overflowInput{{"path1", Decimal128(maxInt).add(Decimal128(1))}};
@@ -1526,7 +1528,7 @@ TEST_F(ExpressionConvertTest, ConvertDecimalToLong) {
<< "$path1"
<< "to"
<< "long"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document simpleInput{{"path1", Decimal128("1.0")}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -1567,7 +1569,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDecimalToLong) {
<< "$path1"
<< "to"
<< "long"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
long long maxVal = std::numeric_limits<long long>::max();
Document overflowInput{{"path1", Decimal128(std::int64_t{maxVal}).add(Decimal128(1))}};
@@ -1638,7 +1640,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDecimalToLongWithOnError) {
<< "long"
<< "onError"
<< "X"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
long long maxVal = std::numeric_limits<long long>::max();
Document overflowInput{{"path1", Decimal128(std::int64_t{maxVal}).add(Decimal128(1))}};
@@ -1677,7 +1679,7 @@ TEST_F(ExpressionConvertTest, ConvertDateToLong) {
<< "$path1"
<< "to"
<< "long"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document dateInput{{"path1", Date_t::fromMillisSinceEpoch(123LL)}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -1691,7 +1693,7 @@ TEST_F(ExpressionConvertTest, ConvertIntToLong) {
<< "$path1"
<< "to"
<< "long"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document simpleInput{{"path1", 1}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -1715,7 +1717,7 @@ TEST_F(ExpressionConvertTest, ConvertLongToInt) {
<< "$path1"
<< "to"
<< "int"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document simpleInput{{"path1", 1}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -1739,7 +1741,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsLongToInt) {
<< "$path1"
<< "to"
<< "int"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
long long maxInt = std::numeric_limits<int>::max();
Document overflowInput{{"path1", maxInt + 1}};
@@ -1771,7 +1773,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsLongToIntWithOnError) {
<< "int"
<< "onError"
<< "X"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
long long maxInt = std::numeric_limits<int>::max();
Document overflowInput{{"path1", maxInt + 1}};
@@ -1791,7 +1793,7 @@ TEST_F(ExpressionConvertTest, ConvertBoolToInt) {
<< "$path1"
<< "to"
<< "int"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document boolFalse{{"path1", false}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -1809,7 +1811,7 @@ TEST_F(ExpressionConvertTest, ConvertBoolToLong) {
<< "$path1"
<< "to"
<< "long"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document boolFalse{{"path1", false}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -1827,7 +1829,7 @@ TEST_F(ExpressionConvertTest, ConvertNumberToDate) {
<< "$path1"
<< "to"
<< "date"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document longInput{{"path1", 0LL}};
ASSERT_EQ(dateToISOStringUTC(convertExp->evaluate(longInput, &expCtx->variables).getDate()),
@@ -1859,7 +1861,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsNumberToDate) {
<< "$path1"
<< "to"
<< "date"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document doubleOverflowInput{{"path1", 1.0e100}};
ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(doubleOverflowInput, &expCtx->variables),
@@ -1977,7 +1979,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsNumberToDateWithOnError) {
<< "date"
<< "onError"
<< "X"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
// Int is explicitly disallowed for date conversions. Clients must use 64-bit long instead.
Document intInput{{"path1", int{0}}};
@@ -2042,7 +2044,7 @@ TEST_F(ExpressionConvertTest, ConvertObjectIdToDate) {
<< "$path1"
<< "to"
<< "date"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document oidInput{{"path1", OID("59E8A8D8FEDCBA9876543210")}};
@@ -2054,12 +2056,12 @@ TEST_F(ExpressionConvertTest, ConvertStringToInt) {
auto expCtx = getExpCtx();
auto spec = fromjson("{$convert: {input: '5', to: 'int'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), 5, BSONType::NumberInt);
spec = fromjson("{$convert: {input: '" + std::to_string(kIntMax) + "', to: 'int'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), kIntMax, BSONType::NumberInt);
}
@@ -2068,7 +2070,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToIntOverflow) {
auto expCtx = getExpCtx();
auto spec = fromjson("{$convert: {input: '" + std::to_string(kIntMax + 1) + "', to: 'int'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
AssertionException,
[](const AssertionException& exception) {
@@ -2077,7 +2079,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToIntOverflow) {
});
spec = fromjson("{$convert: {input: '" + std::to_string(kIntMin - 1) + "', to: 'int'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
AssertionException,
[](const AssertionException& exception) {
@@ -2092,13 +2094,13 @@ TEST_F(ExpressionConvertTest, ConvertStringToIntOverflowWithOnError) {
auto spec = fromjson("{$convert: {input: '" + std::to_string(kIntMax + 1) +
"', to: 'int', onError: '" + onErrorValue + "'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
spec = fromjson("{$convert: {input: '" + std::to_string(kIntMin - 1) +
"', to: 'int', onError: '" + onErrorValue + "'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
}
@@ -2107,12 +2109,12 @@ TEST_F(ExpressionConvertTest, ConvertStringToLong) {
auto expCtx = getExpCtx();
auto spec = fromjson("{$convert: {input: '5', to: 'long'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), 5LL, BSONType::NumberLong);
spec = fromjson("{$convert: {input: '" + std::to_string(kLongMax) + "', to: 'long'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), kLongMax, BSONType::NumberLong);
}
@@ -2124,7 +2126,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToLongOverflow) {
longMaxPlusOneAsString = longMaxPlusOneAsString.substr(0, longMaxPlusOneAsString.find('.'));
auto spec = fromjson("{$convert: {input: '" + longMaxPlusOneAsString + "', to: 'long'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
AssertionException,
[](const AssertionException& exception) {
@@ -2136,7 +2138,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToLongOverflow) {
longMinMinusOneAsString = longMinMinusOneAsString.substr(0, longMinMinusOneAsString.find('.'));
spec = fromjson("{$convert: {input: '" + longMinMinusOneAsString + "', to: 'long'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
AssertionException,
[](const AssertionException& exception) {
@@ -2149,7 +2151,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToLongFailsForFloats) {
auto expCtx = getExpCtx();
auto spec = fromjson("{$convert: {input: '5.5', to: 'long'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
AssertionException,
[](const AssertionException& exception) {
@@ -2159,7 +2161,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToLongFailsForFloats) {
});
spec = fromjson("{$convert: {input: '5.0', to: 'long'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
AssertionException,
[](const AssertionException& exception) {
@@ -2178,7 +2180,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToLongWithOnError) {
auto spec = fromjson("{$convert: {input: '" + longMaxPlusOneAsString +
"', to: 'long', onError: '" + onErrorValue + "'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
@@ -2187,17 +2189,17 @@ TEST_F(ExpressionConvertTest, ConvertStringToLongWithOnError) {
spec = fromjson("{$convert: {input: '" + longMinMinusOneAsString + "', to: 'long', onError: '" +
onErrorValue + "'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
spec = fromjson("{$convert: {input: '5.5', to: 'long', onError: '" + onErrorValue + "'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
spec = fromjson("{$convert: {input: '5.0', to: 'long', onError: '" + onErrorValue + "'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
}
@@ -2206,27 +2208,27 @@ TEST_F(ExpressionConvertTest, ConvertStringToDouble) {
auto expCtx = getExpCtx();
auto spec = fromjson("{$convert: {input: '5', to: 'double'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), 5.0, BSONType::NumberDouble);
spec = fromjson("{$convert: {input: '5.5', to: 'double'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), 5.5, BSONType::NumberDouble);
spec = fromjson("{$convert: {input: '.5', to: 'double'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), 0.5, BSONType::NumberDouble);
spec = fromjson("{$convert: {input: '+5', to: 'double'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), 5.0, BSONType::NumberDouble);
spec = fromjson("{$convert: {input: '+5.0e42', to: 'double'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), 5.0e42, BSONType::NumberDouble);
}
@@ -2237,13 +2239,13 @@ TEST_F(ExpressionConvertTest, ConvertStringToDoubleWithPrecisionLoss) {
// Note that the least significant bits get lost, because the significand of a double is not
// wide enough for the given input string in its entirety.
auto spec = fromjson("{$convert: {input: '10000000000000000001', to: 'double'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), 1e19, BSONType::NumberDouble);
// Again, some precision is lost in the conversion to double.
spec = fromjson("{$convert: {input: '1.125000000000000000005', to: 'double'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), 1.125, BSONType::NumberDouble);
}
@@ -2252,7 +2254,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToDoubleFailsForInvalidFloats) {
auto expCtx = getExpCtx();
auto spec = fromjson("{$convert: {input: '.5.', to: 'double'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
AssertionException,
[](const AssertionException& exception) {
@@ -2262,7 +2264,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToDoubleFailsForInvalidFloats) {
});
spec = fromjson("{$convert: {input: '5.5f', to: 'double'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
AssertionException,
[](const AssertionException& exception) {
@@ -2277,47 +2279,47 @@ TEST_F(ExpressionConvertTest, ConvertInfinityStringsToDouble) {
auto infValue = std::numeric_limits<double>::infinity();
auto spec = fromjson("{$convert: {input: 'Infinity', to: 'double'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), infValue, BSONType::NumberDouble);
spec = fromjson("{$convert: {input: 'INF', to: 'double'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), infValue, BSONType::NumberDouble);
spec = fromjson("{$convert: {input: 'infinity', to: 'double'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), infValue, BSONType::NumberDouble);
spec = fromjson("{$convert: {input: '+InFiNiTy', to: 'double'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), infValue, BSONType::NumberDouble);
spec = fromjson("{$convert: {input: '-Infinity', to: 'double'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), -infValue, BSONType::NumberDouble);
spec = fromjson("{$convert: {input: '-INF', to: 'double'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), -infValue, BSONType::NumberDouble);
spec = fromjson("{$convert: {input: '-InFiNiTy', to: 'double'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), -infValue, BSONType::NumberDouble);
spec = fromjson("{$convert: {input: '-inf', to: 'double'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), -infValue, BSONType::NumberDouble);
spec = fromjson("{$convert: {input: '-infinity', to: 'double'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), -infValue, BSONType::NumberDouble);
}
@@ -2326,25 +2328,25 @@ TEST_F(ExpressionConvertTest, ConvertZeroStringsToDouble) {
auto expCtx = getExpCtx();
auto spec = fromjson("{$convert: {input: '-0', to: 'double'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
auto result = convertExp->evaluate({}, &expCtx->variables);
ASSERT_VALUE_CONTENTS_AND_TYPE(result, 0, BSONType::NumberDouble);
ASSERT_TRUE(std::signbit(result.getDouble()));
spec = fromjson("{$convert: {input: '-0.0', to: 'double'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
result = convertExp->evaluate({}, &expCtx->variables);
ASSERT_VALUE_CONTENTS_AND_TYPE(result, 0, BSONType::NumberDouble);
ASSERT_TRUE(std::signbit(result.getDouble()));
spec = fromjson("{$convert: {input: '+0', to: 'double'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
result = convertExp->evaluate({}, &expCtx->variables);
ASSERT_VALUE_CONTENTS_AND_TYPE(result, 0, BSONType::NumberDouble);
ASSERT_FALSE(std::signbit(result.getDouble()));
spec = fromjson("{$convert: {input: '+0.0', to: 'double'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
result = convertExp->evaluate({}, &expCtx->variables);
ASSERT_VALUE_CONTENTS_AND_TYPE(result, 0, BSONType::NumberDouble);
ASSERT_FALSE(std::signbit(result.getDouble()));
@@ -2355,29 +2357,29 @@ TEST_F(ExpressionConvertTest, ConvertNanStringsToDouble) {
auto nanValue = std::numeric_limits<double>::quiet_NaN();
auto spec = fromjson("{$convert: {input: 'nan', to: 'double'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
auto result = convertExp->evaluate({}, &expCtx->variables);
ASSERT_TRUE(std::isnan(result.getDouble()));
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), nanValue, BSONType::NumberDouble);
spec = fromjson("{$convert: {input: 'Nan', to: 'double'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
result = convertExp->evaluate({}, &expCtx->variables);
ASSERT_TRUE(std::isnan(result.getDouble()));
spec = fromjson("{$convert: {input: 'NaN', to: 'double'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
result = convertExp->evaluate({}, &expCtx->variables);
ASSERT_TRUE(std::isnan(result.getDouble()));
spec = fromjson("{$convert: {input: '-NAN', to: 'double'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
result = convertExp->evaluate({}, &expCtx->variables);
ASSERT_TRUE(std::isnan(result.getDouble()));
spec = fromjson("{$convert: {input: '+NaN', to: 'double'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
result = convertExp->evaluate({}, &expCtx->variables);
ASSERT_TRUE(std::isnan(result.getDouble()));
}
@@ -2386,7 +2388,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToDoubleOverflow) {
auto expCtx = getExpCtx();
auto spec = fromjson("{$convert: {input: '" + kDoubleOverflow.toString() + "', to: 'double'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
AssertionException,
[](const AssertionException& exception) {
@@ -2396,7 +2398,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToDoubleOverflow) {
spec =
fromjson("{$convert: {input: '" + kDoubleNegativeOverflow.toString() + "', to: 'double'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
AssertionException,
[](const AssertionException& exception) {
@@ -2409,7 +2411,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToDoubleUnderflow) {
auto expCtx = getExpCtx();
auto spec = fromjson("{$convert: {input: '1E-1000', to: 'double'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(
convertExp->evaluate({}, &expCtx->variables),
AssertionException,
@@ -2421,7 +2423,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToDoubleUnderflow) {
});
spec = fromjson("{$convert: {input: '-1E-1000', to: 'double'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(
convertExp->evaluate({}, &expCtx->variables),
AssertionException,
@@ -2439,23 +2441,23 @@ TEST_F(ExpressionConvertTest, ConvertStringToDoubleWithOnError) {
auto spec = fromjson("{$convert: {input: '" + kDoubleOverflow.toString() +
"', to: 'double', onError: '" + onErrorValue + "'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
spec = fromjson("{$convert: {input: '" + kDoubleNegativeOverflow.toString() +
"', to: 'double', onError: '" + onErrorValue + "'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
spec = fromjson("{$convert: {input: '.5.', to: 'double', onError: '" + onErrorValue + "'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
spec = fromjson("{$convert: {input: '5.5f', to: 'double', onError: '" + onErrorValue + "'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
}
@@ -2464,31 +2466,31 @@ TEST_F(ExpressionConvertTest, ConvertStringToDecimal) {
auto expCtx = getExpCtx();
auto spec = fromjson("{$convert: {input: '5', to: 'decimal'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), 5, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '2.02', to: 'decimal'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), Decimal128("2.02"), BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '2.02E200', to: 'decimal'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}, &expCtx->variables),
Decimal128("2.02E200"),
BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '" + Decimal128::kLargestPositive.toString() +
"', to: 'decimal'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}, &expCtx->variables),
Decimal128::kLargestPositive,
BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '" + Decimal128::kLargestNegative.toString() +
"', to: 'decimal'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}, &expCtx->variables),
Decimal128::kLargestNegative,
BSONType::NumberDecimal);
@@ -2500,47 +2502,47 @@ TEST_F(ExpressionConvertTest, ConvertInfinityStringsToDecimal) {
auto negInfValue = Decimal128::kNegativeInfinity;
auto spec = fromjson("{$convert: {input: 'Infinity', to: 'decimal'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), infValue, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: 'INF', to: 'decimal'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), infValue, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: 'infinity', to: 'decimal'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), infValue, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '+InFiNiTy', to: 'decimal'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), infValue, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '-Infinity', to: 'decimal'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), negInfValue, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '-INF', to: 'decimal'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), negInfValue, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '-InFiNiTy', to: 'decimal'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), negInfValue, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '-inf', to: 'decimal'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), negInfValue, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '-infinity', to: 'decimal'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), negInfValue, BSONType::NumberDecimal);
}
@@ -2551,37 +2553,37 @@ TEST_F(ExpressionConvertTest, ConvertNanStringsToDecimal) {
auto negativeNan = Decimal128::kNegativeNaN;
auto spec = fromjson("{$convert: {input: 'nan', to: 'decimal'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), positiveNan, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: 'Nan', to: 'decimal'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), positiveNan, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: 'NaN', to: 'decimal'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), positiveNan, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '+NaN', to: 'decimal'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), positiveNan, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '-NAN', to: 'decimal'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), negativeNan, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '-nan', to: 'decimal'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), negativeNan, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '-NaN', to: 'decimal'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), negativeNan, BSONType::NumberDecimal);
}
@@ -2590,28 +2592,28 @@ TEST_F(ExpressionConvertTest, ConvertZeroStringsToDecimal) {
auto expCtx = getExpCtx();
auto spec = fromjson("{$convert: {input: '-0', to: 'decimal'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
auto result = convertExp->evaluate({}, &expCtx->variables);
ASSERT_VALUE_CONTENTS_AND_TYPE(result, 0, BSONType::NumberDecimal);
ASSERT_TRUE(result.getDecimal().isZero());
ASSERT_TRUE(result.getDecimal().isNegative());
spec = fromjson("{$convert: {input: '-0.0', to: 'decimal'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
result = convertExp->evaluate({}, &expCtx->variables);
ASSERT_VALUE_CONTENTS_AND_TYPE(result, 0, BSONType::NumberDecimal);
ASSERT_TRUE(result.getDecimal().isZero());
ASSERT_TRUE(result.getDecimal().isNegative());
spec = fromjson("{$convert: {input: '+0', to: 'decimal'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
result = convertExp->evaluate({}, &expCtx->variables);
ASSERT_VALUE_CONTENTS_AND_TYPE(result, 0, BSONType::NumberDecimal);
ASSERT_TRUE(result.getDecimal().isZero());
ASSERT_FALSE(result.getDecimal().isNegative());
spec = fromjson("{$convert: {input: '+0.0', to: 'decimal'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
result = convertExp->evaluate({}, &expCtx->variables);
ASSERT_VALUE_CONTENTS_AND_TYPE(result, 0, BSONType::NumberDecimal);
ASSERT_TRUE(result.getDecimal().isZero());
@@ -2622,7 +2624,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToDecimalOverflow) {
auto expCtx = getExpCtx();
auto spec = fromjson("{$convert: {input: '1E6145', to: 'decimal'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
AssertionException,
[](const AssertionException& exception) {
@@ -2633,7 +2635,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToDecimalOverflow) {
});
spec = fromjson("{$convert: {input: '-1E6145', to: 'decimal'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
AssertionException,
[](const AssertionException& exception) {
@@ -2648,7 +2650,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToDecimalUnderflow) {
auto expCtx = getExpCtx();
auto spec = fromjson("{$convert: {input: '1E-6178', to: 'decimal'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
AssertionException,
[](const AssertionException& exception) {
@@ -2659,7 +2661,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToDecimalUnderflow) {
});
spec = fromjson("{$convert: {input: '-1E-6177', to: 'decimal'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
AssertionException,
[](const AssertionException& exception) {
@@ -2675,12 +2677,12 @@ TEST_F(ExpressionConvertTest, ConvertStringToDecimalWithPrecisionLoss) {
auto spec =
fromjson("{$convert: {input: '10000000000000000000000000000000001', to: 'decimal'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), Decimal128("1e34"), BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '1.1250000000000000000000000000000001', to: 'decimal'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), Decimal128("1.125"), BSONType::NumberDecimal);
}
@@ -2691,13 +2693,13 @@ TEST_F(ExpressionConvertTest, ConvertStringToDecimalWithOnError) {
auto spec =
fromjson("{$convert: {input: '1E6145', to: 'decimal', onError: '" + onErrorValue + "'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
spec =
fromjson("{$convert: {input: '-1E-6177', to: 'decimal', onError: '" + onErrorValue + "'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
}
@@ -2710,37 +2712,37 @@ TEST_F(ExpressionConvertTest, ConvertStringToNumberFailsForHexStrings) {
};
auto spec = fromjson("{$convert: {input: '0xFF', to: 'int'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(
convertExp->evaluate({}, &expCtx->variables), AssertionException, invalidHexFailure);
spec = fromjson("{$convert: {input: '0xFF', to: 'long'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(
convertExp->evaluate({}, &expCtx->variables), AssertionException, invalidHexFailure);
spec = fromjson("{$convert: {input: '0xFF', to: 'double'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(
convertExp->evaluate({}, &expCtx->variables), AssertionException, invalidHexFailure);
spec = fromjson("{$convert: {input: '0xFF', to: 'decimal'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(
convertExp->evaluate({}, &expCtx->variables), AssertionException, invalidHexFailure);
spec = fromjson("{$convert: {input: '0x00', to: 'int'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(
convertExp->evaluate({}, &expCtx->variables), AssertionException, invalidHexFailure);
spec = fromjson("{$convert: {input: '0x00', to: 'decimal'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(
convertExp->evaluate({}, &expCtx->variables), AssertionException, invalidHexFailure);
spec = fromjson("{$convert: {input: 'FF', to: 'double'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
AssertionException,
[](const AssertionException& exception) {
@@ -2750,7 +2752,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToNumberFailsForHexStrings) {
});
spec = fromjson("{$convert: {input: 'FF', to: 'decimal'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
AssertionException,
[](const AssertionException& exception) {
@@ -2765,12 +2767,12 @@ TEST_F(ExpressionConvertTest, ConvertStringToOID) {
auto oid = OID::gen();
auto spec = fromjson("{$convert: {input: '" + oid.toString() + "', to: 'objectId'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), oid, BSONType::jstOID);
spec = fromjson("{$convert: {input: '123456789abcdef123456789', to: 'objectId'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}, &expCtx->variables),
OID("123456789abcdef123456789"),
BSONType::jstOID);
@@ -2780,7 +2782,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToOIDFailsForInvalidHexStrings) {
auto expCtx = getExpCtx();
auto spec = fromjson("{$convert: {input: 'InvalidHexButSizeCorrect', to: 'objectId'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
AssertionException,
[](const AssertionException& exception) {
@@ -2790,7 +2792,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToOIDFailsForInvalidHexStrings) {
});
spec = fromjson("{$convert: {input: 'InvalidSize', to: 'objectId'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
AssertionException,
[](const AssertionException& exception) {
@@ -2800,7 +2802,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToOIDFailsForInvalidHexStrings) {
});
spec = fromjson("{$convert: {input: '0x123456789abcdef123456789', to: 'objectId'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
AssertionException,
[](const AssertionException& exception) {
@@ -2817,19 +2819,19 @@ TEST_F(ExpressionConvertTest, ConvertStringToOIDWithOnError) {
auto spec =
fromjson("{$convert: {input: 'InvalidHexButSizeCorrect', to: 'objectId', onError: '" +
onErrorValue + "'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
spec = fromjson("{$convert: {input: 'InvalidSize', to: 'objectId', onError: '" + onErrorValue +
"'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
spec = fromjson("{$convert: {input: '0x123456789abcdef123456789', to: 'objectId', onError: '" +
onErrorValue + "'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
}
@@ -2838,13 +2840,13 @@ TEST_F(ExpressionConvertTest, ConvertStringToDateRejectsUnparsableString) {
auto expCtx = getExpCtx();
auto spec = fromjson("{$convert: {input: '60.Monday1770/06:59', to: 'date'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(convertExp->evaluate({}, &expCtx->variables),
AssertionException,
ErrorCodes::ConversionFailure);
spec = fromjson("{$convert: {input: 'Definitely not a date', to: 'date'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(convertExp->evaluate({}, &expCtx->variables),
AssertionException,
ErrorCodes::ConversionFailure);
@@ -2854,13 +2856,13 @@ TEST_F(ExpressionConvertTest, ConvertStringToDateRejectsTimezoneNameInString) {
auto expCtx = getExpCtx();
auto spec = fromjson("{$convert: {input: '2017-07-13T10:02:57 Europe/London', to: 'date'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(convertExp->evaluate({}, &expCtx->variables),
AssertionException,
ErrorCodes::ConversionFailure);
spec = fromjson("{$convert: {input: 'July 4, 2017 Europe/London', to: 'date'}}");
- convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(convertExp->evaluate({}, &expCtx->variables),
AssertionException,
ErrorCodes::ConversionFailure);
@@ -2870,7 +2872,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToDate) {
auto expCtx = getExpCtx();
auto spec = fromjson("{$convert: {input: '$path1', to: 'date'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
auto result =
convertExp->evaluate({{"path1", Value("2017-07-06T12:35:37Z"_sd)}}, &expCtx->variables);
@@ -2891,7 +2893,7 @@ TEST_F(ExpressionConvertTest, ConvertStringWithTimezoneToDate) {
auto expCtx = getExpCtx();
auto spec = fromjson("{$convert: {input: '$path1', to: 'date'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
auto result = convertExp->evaluate({{"path1", Value("2017-07-14T12:02:44.771 GMT+02:00"_sd)}},
&expCtx->variables);
@@ -2908,7 +2910,7 @@ TEST_F(ExpressionConvertTest, ConvertVerbalStringToDate) {
auto expCtx = getExpCtx();
auto spec = fromjson("{$convert: {input: '$path1', to: 'date'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
auto result = convertExp->evaluate({{"path1", Value("July 4th, 2017"_sd)}}, &expCtx->variables);
ASSERT_EQ(result.getType(), BSONType::Date);
@@ -2929,7 +2931,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToDateWithOnError) {
auto spec =
fromjson("{$convert: {input: '$path1', to: 'date', onError: '" + onErrorValue + "'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
auto result = convertExp->evaluate({{"path1", Value("Not a date"_sd)}}, &expCtx->variables);
ASSERT_VALUE_CONTENTS_AND_TYPE(result, onErrorValue, BSONType::String);
@@ -2948,7 +2950,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToDateWithOnNull) {
auto spec =
fromjson("{$convert: {input: '$path1', to: 'date', onNull: '" + onNullValue + "'}}");
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
auto result = convertExp->evaluate({}, &expCtx->variables);
ASSERT_VALUE_CONTENTS_AND_TYPE(result, onNullValue, BSONType::String);
@@ -2964,7 +2966,7 @@ TEST_F(ExpressionConvertTest, FormatDouble) {
<< "$path1"
<< "to"
<< "string"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document zeroInput{{"path1", 0.0}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -3037,7 +3039,7 @@ TEST_F(ExpressionConvertTest, FormatObjectId) {
<< "$path1"
<< "to"
<< "string"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document zeroInput{{"path1", OID("000000000000000000000000")}};
ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(zeroInput, &expCtx->variables),
@@ -3057,7 +3059,7 @@ TEST_F(ExpressionConvertTest, FormatBool) {
<< "$path1"
<< "to"
<< "string"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document trueInput{{"path1", true}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -3075,7 +3077,7 @@ TEST_F(ExpressionConvertTest, FormatDate) {
<< "$path1"
<< "to"
<< "string"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document epochInput{{"path1", Date_t::fromMillisSinceEpoch(0LL)}};
ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(epochInput, &expCtx->variables),
@@ -3095,7 +3097,7 @@ TEST_F(ExpressionConvertTest, FormatInt) {
<< "$path1"
<< "to"
<< "string"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document zeroInput{{"path1", int{0}}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -3117,7 +3119,7 @@ TEST_F(ExpressionConvertTest, FormatLong) {
<< "$path1"
<< "to"
<< "string"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document zeroInput{{"path1", 0LL}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -3141,7 +3143,7 @@ TEST_F(ExpressionConvertTest, FormatDecimal) {
<< "$path1"
<< "to"
<< "string"));
- auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convertExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
Document zeroInput{{"path1", Decimal128("0")}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
@@ -3253,15 +3255,15 @@ TEST_F(ExpressionConvertShortcutsTest, RejectsMoreThanOneInput) {
auto expCtx = getExpCtx();
BSONObj spec = BSON("$toInt" << BSON_ARRAY(1 << 3));
- ASSERT_THROWS_CODE(Expression::parseExpression(expCtx, spec, expCtx->variablesParseState),
+ ASSERT_THROWS_CODE(Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState),
AssertionException,
50723);
spec = BSON("$toLong" << BSON_ARRAY(1 << 3));
- ASSERT_THROWS_CODE(Expression::parseExpression(expCtx, spec, expCtx->variablesParseState),
+ ASSERT_THROWS_CODE(Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState),
AssertionException,
50723);
spec = BSON("$toDouble" << BSON_ARRAY(1 << 3));
- ASSERT_THROWS_CODE(Expression::parseExpression(expCtx, spec, expCtx->variablesParseState),
+ ASSERT_THROWS_CODE(Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState),
AssertionException,
50723);
}
@@ -3270,15 +3272,15 @@ TEST_F(ExpressionConvertShortcutsTest, RejectsZeroInputs) {
auto expCtx = getExpCtx();
BSONObj spec = BSON("$toInt" << BSONArray());
- ASSERT_THROWS_CODE(Expression::parseExpression(expCtx, spec, expCtx->variablesParseState),
+ ASSERT_THROWS_CODE(Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState),
AssertionException,
50723);
spec = BSON("$toLong" << BSONArray());
- ASSERT_THROWS_CODE(Expression::parseExpression(expCtx, spec, expCtx->variablesParseState),
+ ASSERT_THROWS_CODE(Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState),
AssertionException,
50723);
spec = BSON("$toDouble" << BSONArray());
- ASSERT_THROWS_CODE(Expression::parseExpression(expCtx, spec, expCtx->variablesParseState),
+ ASSERT_THROWS_CODE(Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState),
AssertionException,
50723);
}
@@ -3288,15 +3290,15 @@ TEST_F(ExpressionConvertShortcutsTest, AcceptsSingleArgumentInArrayOrByItself) {
BSONObj spec = BSON("$toInt"
<< "1");
- auto convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convert = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionConvert*>(convert.get()));
spec = BSON("$toInt" << BSON_ARRAY("1"));
- convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convert = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionConvert*>(convert.get()));
spec = BSON("$toInt" << BSON_ARRAY(BSON_ARRAY("1")));
- convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convert = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(convert->evaluate({}, &expCtx->variables),
AssertionException,
ErrorCodes::ConversionFailure);
@@ -3307,7 +3309,7 @@ TEST_F(ExpressionConvertShortcutsTest, ConvertsToInts) {
BSONObj spec = BSON("$toInt"
<< "1");
- auto convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convert = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionConvert*>(convert.get()));
ASSERT_VALUE_CONTENTS_AND_TYPE(
convert->evaluate({}, &expCtx->variables), Value(1), BSONType::NumberInt);
@@ -3318,7 +3320,7 @@ TEST_F(ExpressionConvertShortcutsTest, ConvertsToLongs) {
BSONObj spec = BSON("$toLong"
<< "1");
- auto convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convert = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionConvert*>(convert.get()));
ASSERT_VALUE_CONTENTS_AND_TYPE(
convert->evaluate({}, &expCtx->variables), Value(1), BSONType::NumberLong);
@@ -3329,7 +3331,7 @@ TEST_F(ExpressionConvertShortcutsTest, ConvertsToDoubles) {
BSONObj spec = BSON("$toDouble"
<< "1");
- auto convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convert = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionConvert*>(convert.get()));
ASSERT_VALUE_CONTENTS_AND_TYPE(
convert->evaluate({}, &expCtx->variables), Value(1), BSONType::NumberDouble);
@@ -3340,7 +3342,7 @@ TEST_F(ExpressionConvertShortcutsTest, ConvertsToDecimals) {
BSONObj spec = BSON("$toDecimal"
<< "1");
- auto convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convert = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionConvert*>(convert.get()));
ASSERT_VALUE_CONTENTS_AND_TYPE(
convert->evaluate({}, &expCtx->variables), Value(1), BSONType::NumberDecimal);
@@ -3350,7 +3352,7 @@ TEST_F(ExpressionConvertShortcutsTest, ConvertsToDates) {
auto expCtx = getExpCtx();
BSONObj spec = BSON("$toDate" << 0LL);
- auto convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convert = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionConvert*>(convert.get()));
ASSERT_VALUE_CONTENTS_AND_TYPE(convert->evaluate({}, &expCtx->variables),
Value(Date_t::fromMillisSinceEpoch(0)),
@@ -3362,7 +3364,7 @@ TEST_F(ExpressionConvertShortcutsTest, ConvertsToObjectIds) {
const auto hexString = "deadbeefdeadbeefdeadbeef"_sd;
BSONObj spec = BSON("$toObjectId" << hexString);
- auto convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convert = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionConvert*>(convert.get()));
ASSERT_VALUE_CONTENTS_AND_TYPE(convert->evaluate({}, &expCtx->variables),
Value(OID::createFromString(hexString)),
@@ -3373,7 +3375,7 @@ TEST_F(ExpressionConvertShortcutsTest, ConvertsToString) {
auto expCtx = getExpCtx();
BSONObj spec = BSON("$toString" << 1);
- auto convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convert = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionConvert*>(convert.get()));
ASSERT_VALUE_CONTENTS_AND_TYPE(
convert->evaluate({}, &expCtx->variables), Value("1"_sd), BSONType::String);
@@ -3383,7 +3385,7 @@ TEST_F(ExpressionConvertShortcutsTest, ConvertsToBool) {
auto expCtx = getExpCtx();
BSONObj spec = BSON("$toBool" << 1);
- auto convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convert = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionConvert*>(convert.get()));
ASSERT_VALUE_CONTENTS_AND_TYPE(
convert->evaluate({}, &expCtx->variables), Value(true), BSONType::Bool);
@@ -3393,14 +3395,14 @@ TEST_F(ExpressionConvertShortcutsTest, ReturnsNullOnNullishInput) {
auto expCtx = getExpCtx();
BSONObj spec = BSON("$toBool" << BSONNULL);
- auto convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convert = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionConvert*>(convert.get()));
ASSERT_VALUE_CONTENTS_AND_TYPE(
convert->evaluate({}, &expCtx->variables), Value(BSONNULL), BSONType::jstNULL);
spec = BSON("$toInt"
<< "$missing");
- convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convert = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionConvert*>(convert.get()));
ASSERT_VALUE_CONTENTS_AND_TYPE(
convert->evaluate({}, &expCtx->variables), Value(BSONNULL), BSONType::jstNULL);
@@ -3411,7 +3413,7 @@ TEST_F(ExpressionConvertShortcutsTest, ThrowsOnConversionFailure) {
BSONObj spec = BSON("$toInt"
<< "not an int");
- auto convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto convert = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionConvert*>(convert.get()));
ASSERT_THROWS_CODE(convert->evaluate({}, &expCtx->variables),
AssertionException,
@@ -3419,7 +3421,7 @@ TEST_F(ExpressionConvertShortcutsTest, ThrowsOnConversionFailure) {
spec = BSON("$toObjectId"
<< "not all hex values");
- convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ convert = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionConvert*>(convert.get()));
ASSERT_THROWS_CODE(convert->evaluate({}, &expCtx->variables),
AssertionException,
diff --git a/src/mongo/db/pipeline/expression_date_test.cpp b/src/mongo/db/pipeline/expression_date_test.cpp
index 78fdfac5b8d..3098eec3f5a 100644
--- a/src/mongo/db/pipeline/expression_date_test.cpp
+++ b/src/mongo/db/pipeline/expression_date_test.cpp
@@ -50,7 +50,7 @@ TEST_F(ExpressionDateFromPartsTest, SerializesToObjectSyntax) {
<< "minute" << 37 << "second" << 15 << "millisecond"
<< 414 << "timezone"
<< "America/Los_Angeles"));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
auto expectedSerialization =
Value(Document{{"$dateFromParts",
Document{{"year", Document{{"$const", 2017}}},
@@ -68,13 +68,13 @@ TEST_F(ExpressionDateFromPartsTest, SerializesToObjectSyntax) {
TEST_F(ExpressionDateFromPartsTest, OptimizesToConstantIfAllInputsAreConstant) {
auto expCtx = getExpCtx();
auto spec = BSON("$dateFromParts" << BSON("year" << 2017));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it becomes a constant if both year, month and day are provided, and are both
// constants.
spec = BSON("$dateFromParts" << BSON("year" << 2017 << "month" << 6 << "day" << 27));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it becomes a constant if both year, hour and minute are provided, and are both
@@ -82,20 +82,20 @@ TEST_F(ExpressionDateFromPartsTest, OptimizesToConstantIfAllInputsAreConstant) {
spec = BSON("$dateFromParts" << BSON("year" << BSON("$add" << BSON_ARRAY(1900 << 107)) << "hour"
<< BSON("$add" << BSON_ARRAY(13 << 1)) << "minute"
<< BSON("$add" << BSON_ARRAY(40 << 3))));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it becomes a constant if both year and milliseconds are provided, and year is an
// expressions which evaluate to a constant, with milliseconds a constant
spec = BSON("$dateFromParts" << BSON("year" << BSON("$add" << BSON_ARRAY(1900 << 107))
<< "millisecond" << 514));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it becomes a constant if both isoWeekYear, and isoWeek are provided, and are both
// constants.
spec = BSON("$dateFromParts" << BSON("isoWeekYear" << 2017 << "isoWeek" << 26));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it becomes a constant if both isoWeekYear, isoWeek and isoDayOfWeek are provided,
@@ -104,7 +104,7 @@ TEST_F(ExpressionDateFromPartsTest, OptimizesToConstantIfAllInputsAreConstant) {
<< BSON("$add" << BSON_ARRAY(1017 << 1000)) << "isoWeek"
<< BSON("$add" << BSON_ARRAY(20 << 6)) << "isoDayOfWeek"
<< BSON("$add" << BSON_ARRAY(3 << 2))));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it does *not* become a constant if both year and month are provided, but
@@ -112,21 +112,21 @@ TEST_F(ExpressionDateFromPartsTest, OptimizesToConstantIfAllInputsAreConstant) {
spec = BSON("$dateFromParts" << BSON("year"
<< "$year"
<< "month" << 6));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_FALSE(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it does *not* become a constant if both year and day are provided, but
// day is not a constant.
spec = BSON("$dateFromParts" << BSON("year" << 2017 << "day"
<< "$day"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_FALSE(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it does *not* become a constant if both isoWeekYear and isoDayOfWeek are provided,
// but isoDayOfWeek is not a constant.
spec = BSON("$dateFromParts" << BSON("isoWeekYear" << 2017 << "isoDayOfWeek"
<< "$isoDayOfWeekday"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_FALSE(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
}
@@ -134,27 +134,27 @@ TEST_F(ExpressionDateFromPartsTest, TestThatOutOfRangeValuesRollOver) {
auto expCtx = getExpCtx();
auto spec = BSON("$dateFromParts" << BSON("year" << 2017 << "month" << -1));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
auto dateVal = Date_t::fromMillisSinceEpoch(1477958400000); // 11/1/2016 in ms.
ASSERT_VALUE_EQ(Value(dateVal), dateExp->evaluate({}, &expCtx->variables));
spec = BSON("$dateFromParts" << BSON("year" << 2017 << "day" << -1));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
dateVal = Date_t::fromMillisSinceEpoch(1483056000000); // 12/30/2016
ASSERT_VALUE_EQ(Value(dateVal), dateExp->evaluate({}, &expCtx->variables));
spec = BSON("$dateFromParts" << BSON("year" << 2017 << "hour" << 25));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
dateVal = Date_t::fromMillisSinceEpoch(1483318800000); // 1/2/2017 01:00:00
ASSERT_VALUE_EQ(Value(dateVal), dateExp->evaluate({}, &expCtx->variables));
spec = BSON("$dateFromParts" << BSON("year" << 2017 << "minute" << 61));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
dateVal = Date_t::fromMillisSinceEpoch(1483232460000); // 1/1/2017 01:01:00
ASSERT_VALUE_EQ(Value(dateVal), dateExp->evaluate({}, &expCtx->variables));
spec = BSON("$dateFromParts" << BSON("year" << 2017 << "second" << 61));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
dateVal = Date_t::fromMillisSinceEpoch(1483228861000); // 1/1/2017 00:01:01
ASSERT_VALUE_EQ(Value(dateVal), dateExp->evaluate({}, &expCtx->variables));
}
@@ -174,7 +174,7 @@ TEST_F(ExpressionDateToPartsTest, SerializesToObjectSyntax) {
BSONObj spec = BSON("$dateToParts" << BSON("date" << Date_t{} << "timezone"
<< "Europe/London"
<< "iso8601" << false));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
auto expectedSerialization =
Value(Document{{"$dateToParts",
Document{{"date", Document{{"$const", Date_t{}}}},
@@ -187,14 +187,14 @@ TEST_F(ExpressionDateToPartsTest, SerializesToObjectSyntax) {
TEST_F(ExpressionDateToPartsTest, OptimizesToConstantIfAllInputsAreConstant) {
auto expCtx = getExpCtx();
auto spec = BSON("$dateToParts" << BSON("date" << Date_t{}));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it becomes a constant if both date and timezone are provided, and are both
// constants.
spec = BSON("$dateToParts" << BSON("date" << Date_t{} << "timezone"
<< "UTC"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it becomes a constant if both date and timezone are provided, and are both
@@ -204,20 +204,20 @@ TEST_F(ExpressionDateToPartsTest, OptimizesToConstantIfAllInputsAreConstant) {
<< BSON("$concat" << BSON_ARRAY("Europe"
<< "/"
<< "London"))));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it becomes a constant if both date and iso8601 are provided, and are both
// constants.
spec = BSON("$dateToParts" << BSON("date" << Date_t{} << "iso8601" << true));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it becomes a constant if both date and iso8601 are provided, and are both
// expressions which evaluate to constants.
spec = BSON("$dateToParts" << BSON("date" << BSON("$add" << BSON_ARRAY(Date_t{} << 1000))
<< "iso8601" << BSON("$not" << false)));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it does *not* become a constant if both date and timezone are provided, but
@@ -226,21 +226,21 @@ TEST_F(ExpressionDateToPartsTest, OptimizesToConstantIfAllInputsAreConstant) {
<< "$date"
<< "timezone"
<< "Europe/London"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_FALSE(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it does *not* become a constant if both date and timezone are provided, but
// timezone is not a constant.
spec = BSON("$dateToParts" << BSON("date" << Date_t{} << "timezone"
<< "$tz"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_FALSE(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it does *not* become a constant if both date and iso8601 are provided, but
// iso8601 is not a constant.
spec = BSON("$dateToParts" << BSON("date" << Date_t{} << "iso8601"
<< "$iso8601"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_FALSE(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
}
@@ -286,7 +286,7 @@ TEST_F(DateExpressionTest, ParsingAcceptsAllFormats) {
BSON(expName << BSON("date" << Date_t{} << "timezone"
<< "$tz"))};
for (auto&& syntax : possibleSyntaxes) {
- Expression::parseExpression(expCtx, syntax, expCtx->variablesParseState);
+ Expression::parseExpression(expCtx.get(), syntax, expCtx->variablesParseState);
}
}
}
@@ -297,9 +297,10 @@ TEST_F(DateExpressionTest, ParsingRejectsUnrecognizedFieldsInObjectSpecification
BSONObj spec = BSON(expName << BSON("date" << Date_t{} << "timezone"
<< "Europe/London"
<< "extra" << 4));
- ASSERT_THROWS_CODE(Expression::parseExpression(expCtx, spec, expCtx->variablesParseState),
- AssertionException,
- 40535);
+ ASSERT_THROWS_CODE(
+ Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState),
+ AssertionException,
+ 40535);
}
}
@@ -307,9 +308,10 @@ TEST_F(DateExpressionTest, ParsingRejectsEmptyObjectSpecification) {
auto expCtx = getExpCtx();
for (auto&& expName : dateExpressions) {
BSONObj spec = BSON(expName << BSONObj());
- ASSERT_THROWS_CODE(Expression::parseExpression(expCtx, spec, expCtx->variablesParseState),
- AssertionException,
- 40539);
+ ASSERT_THROWS_CODE(
+ Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState),
+ AssertionException,
+ 40539);
}
}
@@ -318,9 +320,10 @@ TEST_F(DateExpressionTest, RejectsEmptyArray) {
for (auto&& expName : dateExpressions) {
BSONObj spec = BSON(expName << BSONArray());
// It will parse as an ExpressionArray, and fail at runtime.
- ASSERT_THROWS_CODE(Expression::parseExpression(expCtx, spec, expCtx->variablesParseState),
- AssertionException,
- 40536);
+ ASSERT_THROWS_CODE(
+ Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState),
+ AssertionException,
+ 40536);
}
}
@@ -330,9 +333,10 @@ TEST_F(DateExpressionTest, RejectsArraysWithMoreThanOneElement) {
BSONObj spec = BSON(expName << BSON_ARRAY("$date"
<< "$tz"));
// It will parse as an ExpressionArray, and fail at runtime.
- ASSERT_THROWS_CODE(Expression::parseExpression(expCtx, spec, expCtx->variablesParseState),
- AssertionException,
- 40536);
+ ASSERT_THROWS_CODE(
+ Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState),
+ AssertionException,
+ 40536);
}
}
@@ -342,7 +346,7 @@ TEST_F(DateExpressionTest, RejectsArraysWithinObjectSpecification) {
BSONObj spec = BSON(expName << BSON("date" << BSON_ARRAY(Date_t{}) << "timezone"
<< "Europe/London"));
// It will parse as an ExpressionArray, and fail at runtime.
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
auto contextDoc = Document{{"_id", 0}};
ASSERT_THROWS_CODE(
dateExp->evaluate(contextDoc, &expCtx->variables), AssertionException, 16006);
@@ -350,7 +354,7 @@ TEST_F(DateExpressionTest, RejectsArraysWithinObjectSpecification) {
// Test that it rejects an array for the timezone option.
spec =
BSON(expName << BSON("date" << Date_t{} << "timezone" << BSON_ARRAY("Europe/London")));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
contextDoc = Document{{"_id", 0}};
ASSERT_THROWS_CODE(
dateExp->evaluate(contextDoc, &expCtx->variables), AssertionException, 40533);
@@ -361,7 +365,7 @@ TEST_F(DateExpressionTest, RejectsTypesThatCannotCoerceToDate) {
auto expCtx = getExpCtx();
for (auto&& expName : dateExpressions) {
BSONObj spec = BSON(expName << "$stringField");
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
auto contextDoc = Document{{"stringField", "string"_sd}};
ASSERT_THROWS_CODE(
dateExp->evaluate(contextDoc, &expCtx->variables), AssertionException, 16006);
@@ -372,7 +376,7 @@ TEST_F(DateExpressionTest, AcceptsObjectIds) {
auto expCtx = getExpCtx();
for (auto&& expName : dateExpressions) {
BSONObj spec = BSON(expName << "$oid");
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
auto contextDoc = Document{{"oid", OID::gen()}};
dateExp->evaluate(contextDoc, &expCtx->variables); // Should not throw.
}
@@ -382,7 +386,7 @@ TEST_F(DateExpressionTest, AcceptsTimestamps) {
auto expCtx = getExpCtx();
for (auto&& expName : dateExpressions) {
BSONObj spec = BSON(expName << "$ts");
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
auto contextDoc = Document{{"ts", Timestamp{Date_t{}}}};
dateExp->evaluate(contextDoc, &expCtx->variables); // Should not throw.
}
@@ -393,7 +397,7 @@ TEST_F(DateExpressionTest, RejectsNonStringTimezone) {
for (auto&& expName : dateExpressions) {
BSONObj spec = BSON(expName << BSON("date" << Date_t{} << "timezone"
<< "$intField"));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
auto contextDoc = Document{{"intField", 4}};
ASSERT_THROWS_CODE(
dateExp->evaluate(contextDoc, &expCtx->variables), AssertionException, 40533);
@@ -405,7 +409,7 @@ TEST_F(DateExpressionTest, RejectsUnrecognizedTimeZoneSpecification) {
for (auto&& expName : dateExpressions) {
BSONObj spec = BSON(expName << BSON("date" << Date_t{} << "timezone"
<< "UNRECOGNIZED!"));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
auto contextDoc = Document{{"_id", 0}};
ASSERT_THROWS_CODE(
dateExp->evaluate(contextDoc, &expCtx->variables), AssertionException, 40485);
@@ -418,7 +422,7 @@ TEST_F(DateExpressionTest, SerializesToObjectSyntax) {
// Test that it serializes to the full format if given an object specification.
BSONObj spec = BSON(expName << BSON("date" << Date_t{} << "timezone"
<< "Europe/London"));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
auto expectedSerialization =
Value(Document{{expName,
Document{{"date", Document{{"$const", Date_t{}}}},
@@ -430,13 +434,13 @@ TEST_F(DateExpressionTest, SerializesToObjectSyntax) {
spec = BSON(expName << Date_t{});
expectedSerialization =
Value(Document{{expName, Document{{"date", Document{{"$const", Date_t{}}}}}}});
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(dateExp->serialize(true), expectedSerialization);
ASSERT_VALUE_EQ(dateExp->serialize(false), expectedSerialization);
// Test that it serializes to the full format if given a date within an array.
spec = BSON(expName << BSON_ARRAY(Date_t{}));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(dateExp->serialize(true), expectedSerialization);
ASSERT_VALUE_EQ(dateExp->serialize(false), expectedSerialization);
}
@@ -447,14 +451,14 @@ TEST_F(DateExpressionTest, OptimizesToConstantIfAllInputsAreConstant) {
for (auto&& expName : dateExpressions) {
// Test that it becomes a constant if only date is provided, and it is constant.
auto spec = BSON(expName << BSON("date" << Date_t{}));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it becomes a constant if both date and timezone are provided, and are both
// constants.
spec = BSON(expName << BSON("date" << Date_t{} << "timezone"
<< "Europe/London"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it becomes a constant if both date and timezone are provided, and are both
@@ -464,7 +468,7 @@ TEST_F(DateExpressionTest, OptimizesToConstantIfAllInputsAreConstant) {
<< BSON("$concat" << BSON_ARRAY("Europe"
<< "/"
<< "London"))));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it does *not* become a constant if both date and timezone are provided, but
@@ -473,14 +477,14 @@ TEST_F(DateExpressionTest, OptimizesToConstantIfAllInputsAreConstant) {
<< "$date"
<< "timezone"
<< "Europe/London"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_FALSE(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it does *not* become a constant if both date and timezone are provided, but
// timezone is not a constant.
spec = BSON(expName << BSON("date" << Date_t{} << "timezone"
<< "$tz"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_FALSE(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
}
}
@@ -491,7 +495,7 @@ TEST_F(DateExpressionTest, DoesRespectTimeZone) {
for (auto&& expName : dateExpressions) {
auto spec = BSON(expName << BSON("date" << Date_t{} << "timezone"
<< "America/New_York"));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
auto contextDoc = Document{{"_id", 0}};
dateExp->evaluate(contextDoc, &expCtx->variables); // Should not throw.
}
@@ -500,14 +504,14 @@ TEST_F(DateExpressionTest, DoesRespectTimeZone) {
auto date = Date_t::fromMillisSinceEpoch(1496777923000LL); // 2017-06-06T19:38:43:234Z.
auto specWithoutTimezone = BSON("$hour" << BSON("date" << date));
auto hourWithoutTimezone =
- Expression::parseExpression(expCtx, specWithoutTimezone, expCtx->variablesParseState)
+ Expression::parseExpression(expCtx.get(), specWithoutTimezone, expCtx->variablesParseState)
->evaluate({}, &expCtx->variables);
ASSERT_VALUE_EQ(hourWithoutTimezone, Value(19));
auto specWithTimezone = BSON("$hour" << BSON("date" << date << "timezone"
<< "America/New_York"));
auto hourWithTimezone =
- Expression::parseExpression(expCtx, specWithTimezone, expCtx->variablesParseState)
+ Expression::parseExpression(expCtx.get(), specWithTimezone, expCtx->variablesParseState)
->evaluate({}, &expCtx->variables);
ASSERT_VALUE_EQ(hourWithTimezone, Value(15));
}
@@ -522,37 +526,37 @@ TEST_F(DateExpressionTest, DoesResultInNullIfGivenNullishInput) {
// specified.
auto spec = BSON(expName << BSON("date"
<< "$missing"));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(contextDoc, &expCtx->variables));
spec = BSON(expName << BSON("date" << BSONNULL));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(contextDoc, &expCtx->variables));
spec = BSON(expName << BSON("date" << BSONUndefined));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(contextDoc, &expCtx->variables));
// Test that the expression results in null if the date is present but the timezone is
// nullish.
spec = BSON(expName << BSON("date" << Date_t{} << "timezone"
<< "$missing"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(contextDoc, &expCtx->variables));
spec = BSON(expName << BSON("date" << Date_t{} << "timezone" << BSONNULL));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(contextDoc, &expCtx->variables));
spec = BSON(expName << BSON("date" << Date_t{} << "timezone" << BSONUndefined));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(contextDoc, &expCtx->variables));
// Test that the expression results in null if the date and timezone both nullish.
spec = BSON(expName << BSON("date"
<< "$missing"
<< "timezone" << BSONUndefined));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(contextDoc, &expCtx->variables));
// Test that the expression results in null if the date is nullish and timezone is present.
@@ -560,7 +564,7 @@ TEST_F(DateExpressionTest, DoesResultInNullIfGivenNullishInput) {
<< "$missing"
<< "timezone"
<< "Europe/London"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(contextDoc, &expCtx->variables));
}
}
@@ -583,7 +587,7 @@ TEST_F(ExpressionDateToStringTest, SerializesToObjectSyntax) {
<< "%Y-%m-%d"
<< "onNull"
<< "nullDefault"));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
auto expectedSerialization =
Value(Document{{"$dateToString",
Document{{"date", Document{{"$const", Date_t{}}}},
@@ -601,7 +605,7 @@ TEST_F(ExpressionDateToStringTest, OptimizesToConstantIfAllInputsAreConstant) {
// Test that it becomes a constant if date is constant, and both format and timezone are
// missing.
auto spec = BSON("$dateToString" << BSON("date" << Date_t{}));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it becomes a constant if both format and date are constant, and timezone is
@@ -609,7 +613,7 @@ TEST_F(ExpressionDateToStringTest, OptimizesToConstantIfAllInputsAreConstant) {
spec = BSON("$dateToString" << BSON("format"
<< "%Y-%m-%d"
<< "date" << Date_t{}));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it becomes a constant if format, date and timezone are provided, and all are
@@ -618,7 +622,7 @@ TEST_F(ExpressionDateToStringTest, OptimizesToConstantIfAllInputsAreConstant) {
<< "%Y-%m-%d"
<< "date" << Date_t{} << "timezone"
<< "Europe/Amsterdam"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it becomes a constant if format, date and timezone are provided, and all
@@ -630,7 +634,7 @@ TEST_F(ExpressionDateToStringTest, OptimizesToConstantIfAllInputsAreConstant) {
<< BSON("$concat" << BSON_ARRAY("Europe"
<< "/"
<< "London"))));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it becomes a constant if all parameters are constant, including the optional
@@ -641,7 +645,7 @@ TEST_F(ExpressionDateToStringTest, OptimizesToConstantIfAllInputsAreConstant) {
<< "Europe/Amsterdam"
<< "onNull"
<< "null default"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it does *not* become a constant if both format, date and timezone are provided, but
@@ -652,7 +656,7 @@ TEST_F(ExpressionDateToStringTest, OptimizesToConstantIfAllInputsAreConstant) {
<< "$date"
<< "timezone"
<< "Europe/London"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_FALSE(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it does *not* become a constant if both format, date and timezone are provided, but
@@ -661,7 +665,7 @@ TEST_F(ExpressionDateToStringTest, OptimizesToConstantIfAllInputsAreConstant) {
<< "%Y-%m-%d"
<< "date" << Date_t{} << "timezone"
<< "$tz"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_FALSE(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it does *not* become a constant if 'onNull' does not evaluate to a constant.
@@ -669,14 +673,14 @@ TEST_F(ExpressionDateToStringTest, OptimizesToConstantIfAllInputsAreConstant) {
<< "%Y-%m-%d"
<< "date" << Date_t{} << "onNull"
<< "$onNull"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_FALSE(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it does *not* become a constant if 'format' does not evaluate to a constant.
spec = BSON("$dateToString" << BSON("format"
<< "$format"
<< "date" << Date_t{}));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_FALSE(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
}
@@ -687,13 +691,13 @@ TEST_F(ExpressionDateToStringTest, ReturnsOnNullValueWhenInputIsNullish) {
<< "%Y-%m-%d"
<< "date" << BSONNULL << "onNull"
<< "null default"));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value("null default"_sd), dateExp->evaluate({}, &expCtx->variables));
spec = BSON("$dateToString" << BSON("format"
<< "%Y-%m-%d"
<< "date" << BSONNULL << "onNull" << BSONNULL));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate({}, &expCtx->variables));
spec = BSON("$dateToString" << BSON("format"
@@ -702,7 +706,7 @@ TEST_F(ExpressionDateToStringTest, ReturnsOnNullValueWhenInputIsNullish) {
<< "$missing"
<< "onNull"
<< "null default"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value("null default"_sd), dateExp->evaluate({}, &expCtx->variables));
spec = BSON("$dateToString" << BSON("format"
@@ -711,7 +715,7 @@ TEST_F(ExpressionDateToStringTest, ReturnsOnNullValueWhenInputIsNullish) {
<< "$missing"
<< "onNull"
<< "$alsoMissing"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value(), dateExp->evaluate({}, &expCtx->variables));
}
@@ -719,7 +723,7 @@ TEST_F(ExpressionDateToStringTest, ReturnsNullIfInputDateIsNullish) {
auto expCtx = getExpCtx();
auto spec = fromjson("{$dateToString: {date: '$date'}}");
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value(BSONNULL),
dateExp->evaluate(Document{{"date", BSONNULL}}, &expCtx->variables));
ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate({}, &expCtx->variables));
@@ -729,7 +733,7 @@ TEST_F(ExpressionDateToStringTest, ReturnsNullIfFormatIsNullish) {
auto expCtx = getExpCtx();
auto spec = fromjson("{$dateToString: {date: '$date', format: '$format'}}");
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(
Value(BSONNULL),
dateExp->evaluate(Document{{"date", Date_t{}}, {"format", BSONNULL}}, &expCtx->variables));
@@ -741,7 +745,7 @@ TEST_F(ExpressionDateToStringTest, UsesDefaultFormatIfNoneSpecified) {
auto expCtx = getExpCtx();
auto spec = fromjson("{$dateToString: {date: '$date'}}");
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value("1970-01-01T00:00:00.000Z"_sd),
dateExp->evaluate(Document{{"date", Date_t{}}}, &expCtx->variables));
}
@@ -750,7 +754,7 @@ TEST_F(ExpressionDateToStringTest, FailsForInvalidTimezoneRegardlessOfInputDate)
auto expCtx = getExpCtx();
auto spec = fromjson("{$dateToString: {date: '$date', timezone: '$tz'}}");
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(
dateExp->evaluate(Document{{"date", BSONNULL}, {"tz", "invalid"_sd}}, &expCtx->variables),
AssertionException,
@@ -766,12 +770,12 @@ TEST_F(ExpressionDateToStringTest, FailsForInvalidFormatStrings) {
auto spec = BSON("$dateToString" << BSON("date" << Date_t{} << "format"
<< "%n"));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables), AssertionException, 18536);
spec = BSON("$dateToString" << BSON("date" << Date_t{} << "format"
<< "%Y%"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables), AssertionException, 18535);
}
@@ -779,7 +783,7 @@ TEST_F(ExpressionDateToStringTest, FailsForInvalidFormatRegardlessOfInputDate) {
auto expCtx = getExpCtx();
auto spec = fromjson("{$dateToString: {date: '$date', format: '$format', onNull: 0}}");
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(
dateExp->evaluate(Document{{"date", BSONNULL}, {"format", 5}}, &expCtx->variables),
AssertionException,
@@ -812,7 +816,7 @@ TEST_F(ExpressionDateFromStringTest, SerializesToObjectSyntax) {
// Test that it serializes to the full format if given an object specification.
BSONObj spec = BSON("$dateFromString" << BSON("dateString"
<< "2017-07-04T13:06:44Z"));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
auto expectedSerialization = Value(
Document{{"$dateFromString",
Document{{"dateString", Document{{"$const", "2017-07-04T13:06:44Z"_sd}}}}}});
@@ -825,7 +829,7 @@ TEST_F(ExpressionDateFromStringTest, SerializesToObjectSyntax) {
<< "2017-07-04T13:06:44Z"
<< "timezone"
<< "Europe/London"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
expectedSerialization =
Value(Document{{"$dateFromString",
Document{{"dateString", Document{{"$const", "2017-07-04T13:06:44Z"_sd}}},
@@ -840,7 +844,7 @@ TEST_F(ExpressionDateFromStringTest, SerializesToObjectSyntax) {
<< "Europe/London"
<< "format"
<< "%Y-%d-%mT%H:%M:%S"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
expectedSerialization =
Value(Document{{"$dateFromString",
Document{{"dateString", Document{{"$const", "2017-07-04T13:06:44Z"_sd}}},
@@ -860,7 +864,7 @@ TEST_F(ExpressionDateFromStringTest, SerializesToObjectSyntax) {
<< "nullDefault"
<< "onError"
<< "errorDefault"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
expectedSerialization =
Value(Document{{"$dateFromString",
Document{{"dateString", Document{{"$const", "2017-07-04T13:06:44Z"_sd}}},
@@ -879,7 +883,7 @@ TEST_F(ExpressionDateFromStringTest, OptimizesToConstantIfAllInputsAreConstant)
// Test that it becomes a constant if all parameters evaluate to a constant value.
auto spec = BSON("$dateFromString" << BSON("dateString"
<< "2017-07-04T13:09:57Z"));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
Date_t dateVal = Date_t::fromMillisSinceEpoch(1499173797000);
@@ -889,7 +893,7 @@ TEST_F(ExpressionDateFromStringTest, OptimizesToConstantIfAllInputsAreConstant)
<< "2017-07-04T13:09:57"
<< "timezone"
<< "Europe/London"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it becomes a constant with the dateString, timezone, and format being a constant.
@@ -899,7 +903,7 @@ TEST_F(ExpressionDateFromStringTest, OptimizesToConstantIfAllInputsAreConstant)
<< "Europe/London"
<< "format"
<< "%Y-%m-%dT%H:%M:%S"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
dateVal = Date_t::fromMillisSinceEpoch(1499170197000);
@@ -909,14 +913,14 @@ TEST_F(ExpressionDateFromStringTest, OptimizesToConstantIfAllInputsAreConstant)
<< "2017-07-04T13:09:57"
<< "onNull"
<< "Null default"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
spec = BSON("$dateFromString" << BSON("dateString"
<< "2017-07-04T13:09:57"
<< "onError"
<< "Error default"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
spec = BSON("$dateFromString" << BSON("dateString"
@@ -925,13 +929,13 @@ TEST_F(ExpressionDateFromStringTest, OptimizesToConstantIfAllInputsAreConstant)
<< "Error default"
<< "onNull"
<< "null default"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it does *not* become a constant if dateString is not a constant.
spec = BSON("$dateFromString" << BSON("dateString"
<< "$date"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_FALSE(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it does *not* become a constant if timezone is not a constant.
@@ -939,7 +943,7 @@ TEST_F(ExpressionDateFromStringTest, OptimizesToConstantIfAllInputsAreConstant)
<< "2017-07-04T13:09:57Z"
<< "timezone"
<< "$tz"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_FALSE(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it does *not* become a constant if format is not a constant.
@@ -949,7 +953,7 @@ TEST_F(ExpressionDateFromStringTest, OptimizesToConstantIfAllInputsAreConstant)
<< "Europe/London"
<< "format"
<< "$format"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_FALSE(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it does *not* become a constant if onNull is not a constant.
@@ -957,7 +961,7 @@ TEST_F(ExpressionDateFromStringTest, OptimizesToConstantIfAllInputsAreConstant)
<< "2017-07-04T13:09:57Z"
<< "onNull"
<< "$onNull"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_FALSE(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
// Test that it does *not* become a constant if onError is not a constant.
@@ -965,7 +969,7 @@ TEST_F(ExpressionDateFromStringTest, OptimizesToConstantIfAllInputsAreConstant)
<< "2017-07-04T13:09:57Z"
<< "onError"
<< "$onError"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_FALSE(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
}
@@ -974,7 +978,7 @@ TEST_F(ExpressionDateFromStringTest, RejectsUnparsableString) {
auto spec = BSON("$dateFromString" << BSON("dateString"
<< "60.Monday1770/06:59"));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables),
AssertionException,
ErrorCodes::ConversionFailure);
@@ -985,14 +989,14 @@ TEST_F(ExpressionDateFromStringTest, RejectsTimeZoneInString) {
auto spec = BSON("$dateFromString" << BSON("dateString"
<< "2017-07-13T10:02:57 Europe/London"));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables),
AssertionException,
ErrorCodes::ConversionFailure);
spec = BSON("$dateFromString" << BSON("dateString"
<< "July 4, 2017 Europe/London"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables),
AssertionException,
ErrorCodes::ConversionFailure);
@@ -1006,7 +1010,7 @@ TEST_F(ExpressionDateFromStringTest, RejectsTimeZoneInStringAndArgument) {
<< "2017-07-14T15:24:38Z"
<< "timezone"
<< "Europe/London"));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables),
AssertionException,
ErrorCodes::ConversionFailure);
@@ -1016,7 +1020,7 @@ TEST_F(ExpressionDateFromStringTest, RejectsTimeZoneInStringAndArgument) {
<< "2017-07-14T15:24:38 PDT"
<< "timezone"
<< "Europe/London"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables),
AssertionException,
ErrorCodes::ConversionFailure);
@@ -1026,7 +1030,7 @@ TEST_F(ExpressionDateFromStringTest, RejectsTimeZoneInStringAndArgument) {
<< "2017-07-14T15:24:38+02:00"
<< "timezone"
<< "Europe/London"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables),
AssertionException,
ErrorCodes::ConversionFailure);
@@ -1036,7 +1040,7 @@ TEST_F(ExpressionDateFromStringTest, RejectsTimeZoneInStringAndArgument) {
<< "2017-07-14 -0400"
<< "timezone"
<< "GMT"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables),
AssertionException,
ErrorCodes::ConversionFailure);
@@ -1048,13 +1052,13 @@ TEST_F(ExpressionDateFromStringTest, RejectsNonStringFormat) {
auto spec = BSON("$dateFromString" << BSON("dateString"
<< "2017-07-13T10:02:57"
<< "format" << 2));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables), AssertionException, 40684);
spec = BSON("$dateFromString" << BSON("dateString"
<< "July 4, 2017"
<< "format" << true));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables), AssertionException, 40684);
}
@@ -1065,7 +1069,7 @@ TEST_F(ExpressionDateFromStringTest, RejectsStringsThatDoNotMatchFormat) {
<< "2017-07"
<< "format"
<< "%Y-%m-%d"));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables),
AssertionException,
ErrorCodes::ConversionFailure);
@@ -1074,7 +1078,7 @@ TEST_F(ExpressionDateFromStringTest, RejectsStringsThatDoNotMatchFormat) {
<< "2017-07"
<< "format"
<< "%m-%Y"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables),
AssertionException,
ErrorCodes::ConversionFailure);
@@ -1087,7 +1091,7 @@ TEST_F(ExpressionDateFromStringTest, EscapeCharacterAllowsPrefixUsage) {
<< "2017 % 01 % 01"
<< "format"
<< "%Y %% %m %% %d"));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_EQ("2017-01-01T00:00:00.000Z", dateExp->evaluate({}, &expCtx->variables).toString());
}
@@ -1098,20 +1102,20 @@ TEST_F(ExpressionDateFromStringTest, EvaluatesToNullIfFormatIsNullish) {
auto spec = BSON("$dateFromString" << BSON("dateString"
<< "1/1/2017"
<< "format" << BSONNULL));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate({}, &expCtx->variables));
spec = BSON("$dateFromString" << BSON("dateString"
<< "1/1/2017"
<< "format"
<< "$missing"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate({}, &expCtx->variables));
spec = BSON("$dateFromString" << BSON("dateString"
<< "1/1/2017"
<< "format" << BSONUndefined));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate({}, &expCtx->variables));
}
@@ -1122,35 +1126,35 @@ TEST_F(ExpressionDateFromStringTest, ReadWithUTCOffset) {
<< "2017-07-28T10:47:52.912"
<< "timezone"
<< "-01:00"));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_EQ("2017-07-28T11:47:52.912Z", dateExp->evaluate({}, &expCtx->variables).toString());
spec = BSON("$dateFromString" << BSON("dateString"
<< "2017-07-28T10:47:52.912"
<< "timezone"
<< "+01:00"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_EQ("2017-07-28T09:47:52.912Z", dateExp->evaluate({}, &expCtx->variables).toString());
spec = BSON("$dateFromString" << BSON("dateString"
<< "2017-07-28T10:47:52.912"
<< "timezone"
<< "+0445"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_EQ("2017-07-28T06:02:52.912Z", dateExp->evaluate({}, &expCtx->variables).toString());
spec = BSON("$dateFromString" << BSON("dateString"
<< "2017-07-28T10:47:52.912"
<< "timezone"
<< "+10:45"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_EQ("2017-07-28T00:02:52.912Z", dateExp->evaluate({}, &expCtx->variables).toString());
spec = BSON("$dateFromString" << BSON("dateString"
<< "1945-07-28T10:47:52.912"
<< "timezone"
<< "-08:00"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_EQ("1945-07-28T18:47:52.912Z", dateExp->evaluate({}, &expCtx->variables).toString());
}
@@ -1163,7 +1167,7 @@ TEST_F(ExpressionDateFromStringTest, ConvertStringWithUTCOffsetAndFormat) {
<< "-01:00"
<< "format"
<< "%H:%M:%S.%L on %m/%d/%Y"));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_EQ("2017-07-28T11:47:52.912Z", dateExp->evaluate({}, &expCtx->variables).toString());
spec = BSON("$dateFromString" << BSON("dateString"
@@ -1172,7 +1176,7 @@ TEST_F(ExpressionDateFromStringTest, ConvertStringWithUTCOffsetAndFormat) {
<< "+01:00"
<< "format"
<< "%H:%M:%S.%L on %m/%d/%Y"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_EQ("2017-07-28T09:47:52.912Z", dateExp->evaluate({}, &expCtx->variables).toString());
}
@@ -1183,7 +1187,7 @@ TEST_F(ExpressionDateFromStringTest, ConvertStringWithISODateFormat) {
<< "Day 7 Week 53 Year 2017"
<< "format"
<< "Day %u Week %V Year %G"));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_EQ("2018-01-07T00:00:00.000Z", dateExp->evaluate({}, &expCtx->variables).toString());
// Week and day of week default to '1' if not specified.
@@ -1191,14 +1195,14 @@ TEST_F(ExpressionDateFromStringTest, ConvertStringWithISODateFormat) {
<< "Week 53 Year 2017"
<< "format"
<< "Week %V Year %G"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_EQ("2018-01-01T00:00:00.000Z", dateExp->evaluate({}, &expCtx->variables).toString());
spec = BSON("$dateFromString" << BSON("dateString"
<< "Day 7 Year 2017"
<< "format"
<< "Day %u Year %G"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_EQ("2017-01-08T00:00:00.000Z", dateExp->evaluate({}, &expCtx->variables).toString());
}
@@ -1207,25 +1211,25 @@ TEST_F(ExpressionDateFromStringTest, ReturnsOnNullForNullishInput) {
auto spec = BSON("$dateFromString" << BSON("dateString" << BSONNULL << "onNull"
<< "Null default"));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value("Null default"_sd), dateExp->evaluate({}, &expCtx->variables));
spec = BSON("$dateFromString" << BSON("dateString"
<< "$missing"
<< "onNull"
<< "Null default"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value("Null default"_sd), dateExp->evaluate({}, &expCtx->variables));
spec = BSON("$dateFromString" << BSON("dateString"
<< "$missing"
<< "onNull"
<< "$alsoMissing"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value(), dateExp->evaluate({}, &expCtx->variables));
spec = BSON("$dateFromString" << BSON("dateString" << BSONNULL << "onNull" << BSONNULL));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate({}, &expCtx->variables));
}
@@ -1235,14 +1239,14 @@ TEST_F(ExpressionDateFromStringTest, InvalidFormatTakesPrecedenceOverOnNull) {
auto spec = BSON("$dateFromString" << BSON("dateString" << BSONNULL << "onNull"
<< "Null default"
<< "format" << 5));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables), AssertionException, 40684);
spec = BSON("$dateFromString" << BSON("dateString" << BSONNULL << "onNull"
<< "Null default"
<< "format"
<< "%"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables), AssertionException, 18535);
}
@@ -1254,14 +1258,14 @@ TEST_F(ExpressionDateFromStringTest, InvalidFormatTakesPrecedenceOverOnError) {
<< "onError"
<< "Not used default"
<< "format" << 5));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables), AssertionException, 40684);
spec = BSON("$dateFromString" << BSON("dateString" << 5 << "onError"
<< "Not used default"
<< "format"
<< "%"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables), AssertionException, 18535);
}
@@ -1271,14 +1275,14 @@ TEST_F(ExpressionDateFromStringTest, InvalidTimezoneTakesPrecedenceOverOnNull) {
auto spec = BSON("$dateFromString" << BSON("dateString" << BSONNULL << "onNull"
<< "Null default"
<< "timezone" << 5));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables), AssertionException, 40517);
spec = BSON("$dateFromString" << BSON("dateString" << BSONNULL << "onNull"
<< "Null default"
<< "timezone"
<< "invalid timezone string"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables), AssertionException, 40485);
}
@@ -1290,14 +1294,14 @@ TEST_F(ExpressionDateFromStringTest, InvalidTimezoneTakesPrecedenceOverOnError)
<< "onError"
<< "On error default"
<< "timezone" << 5));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables), AssertionException, 40517);
spec = BSON("$dateFromString" << BSON("dateString" << 5 << "onError"
<< "On error default"
<< "timezone"
<< "invalid timezone string"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables), AssertionException, 40485);
}
@@ -1307,13 +1311,13 @@ TEST_F(ExpressionDateFromStringTest, OnNullTakesPrecedenceOverOtherNullishParame
auto spec = BSON("$dateFromString" << BSON("dateString" << BSONNULL << "onNull"
<< "Null default"
<< "timezone" << BSONNULL));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value("Null default"_sd), dateExp->evaluate({}, &expCtx->variables));
spec = BSON("$dateFromString" << BSON("dateString" << BSONNULL << "onNull"
<< "Null default"
<< "format" << BSONNULL));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value("Null default"_sd), dateExp->evaluate({}, &expCtx->variables));
}
@@ -1325,7 +1329,7 @@ TEST_F(ExpressionDateFromStringTest, OnNullOnlyUsedIfInputStringIsNullish) {
<< "onNull"
<< "Null default"
<< "timezone" << BSONNULL));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate({}, &expCtx->variables));
spec = BSON("$dateFromString" << BSON("dateString"
@@ -1333,7 +1337,7 @@ TEST_F(ExpressionDateFromStringTest, OnNullOnlyUsedIfInputStringIsNullish) {
<< "onNull"
<< "Null default"
<< "format" << BSONNULL));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate({}, &expCtx->variables));
}
@@ -1345,7 +1349,7 @@ TEST_F(ExpressionDateFromStringTest, ReturnsOnErrorForParseFailures) {
for (auto date : invalidDates) {
auto spec = BSON("$dateFromString" << BSON("dateString" << date << "onError"
<< "Error default"));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value("Error default"_sd), dateExp->evaluate({}, &expCtx->variables));
}
}
@@ -1359,7 +1363,7 @@ TEST_F(ExpressionDateFromStringTest, ReturnsOnErrorForFormatMismatch) {
auto spec =
BSON("$dateFromString" << BSON("dateString" << date << "format" << format << "onError"
<< "Error default"));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value("Error default"_sd), dateExp->evaluate({}, &expCtx->variables));
}
}
@@ -1371,7 +1375,7 @@ TEST_F(ExpressionDateFromStringTest, OnNullEvaluatedLazily) {
BSON("$dateFromString" << BSON("dateString"
<< "$date"
<< "onNull" << BSON("$divide" << BSON_ARRAY(1 << 0))));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_EQ(
"2018-02-14T00:00:00.000Z",
dateExp->evaluate(Document{{"date", "2018-02-14"_sd}}, &expCtx->variables).toString());
@@ -1385,7 +1389,7 @@ TEST_F(ExpressionDateFromStringTest, OnErrorEvaluatedLazily) {
BSON("$dateFromString" << BSON("dateString"
<< "$date"
<< "onError" << BSON("$divide" << BSON_ARRAY(1 << 0))));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ auto dateExp = Expression::parseExpression(expCtx.get(), spec, expCtx->variablesParseState);
ASSERT_EQ(
"2018-02-14T00:00:00.000Z",
dateExp->evaluate(Document{{"date", "2018-02-14"_sd}}, &expCtx->variables).toString());
diff --git a/src/mongo/db/pipeline/expression_field_path_test.cpp b/src/mongo/db/pipeline/expression_field_path_test.cpp
index ad119de701a..6a104e8cbab 100644
--- a/src/mongo/db/pipeline/expression_field_path_test.cpp
+++ b/src/mongo/db/pipeline/expression_field_path_test.cpp
@@ -73,54 +73,54 @@ namespace FieldPath {
class Invalid {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- ASSERT_THROWS(ExpressionFieldPath::create(expCtx, ""), AssertionException);
+ auto expCtx = ExpressionContextForTest{};
+ ASSERT_THROWS(ExpressionFieldPath::create(&expCtx, ""), AssertionException);
}
};
TEST(FieldPath, NoOptimizationForRootFieldPathWithDottedPath) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
intrusive_ptr<ExpressionFieldPath> expression =
- ExpressionFieldPath::parse(expCtx, "$$ROOT.x.y", expCtx->variablesParseState);
+ ExpressionFieldPath::parse(&expCtx, "$$ROOT.x.y", expCtx.variablesParseState);
// An attempt to optimize returns the Expression itself.
ASSERT_EQUALS(expression, expression->optimize());
}
TEST(FieldPath, NoOptimizationForCurrentFieldPathWithDottedPath) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
intrusive_ptr<ExpressionFieldPath> expression =
- ExpressionFieldPath::parse(expCtx, "$$CURRENT.x.y", expCtx->variablesParseState);
+ ExpressionFieldPath::parse(&expCtx, "$$CURRENT.x.y", expCtx.variablesParseState);
// An attempt to optimize returns the Expression itself.
ASSERT_EQUALS(expression, expression->optimize());
}
TEST(FieldPath, RemoveOptimizesToMissingValue) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
intrusive_ptr<ExpressionFieldPath> expression =
- ExpressionFieldPath::parse(expCtx, "$$REMOVE", expCtx->variablesParseState);
+ ExpressionFieldPath::parse(&expCtx, "$$REMOVE", expCtx.variablesParseState);
auto optimizedExpr = expression->optimize();
ASSERT_VALUE_EQ(
Value(),
- optimizedExpr->evaluate(Document(BSON("x" << BSON("y" << 123))), &expCtx->variables));
+ optimizedExpr->evaluate(Document(BSON("x" << BSON("y" << 123))), &expCtx.variables));
}
TEST(FieldPath, NoOptimizationOnNormalPath) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a");
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> expression = ExpressionFieldPath::create(&expCtx, "a");
// An attempt to optimize returns the Expression itself.
ASSERT_EQUALS(expression, expression->optimize());
}
TEST(FieldPath, OptimizeOnVariableWithConstantScalarValue) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setConstantValue(varId, Value(123));
+ auto expCtx = ExpressionContextForTest{};
+ auto varId = expCtx.variablesParseState.defineVariable("userVar");
+ expCtx.variables.setConstantValue(varId, Value(123));
- auto expr = ExpressionFieldPath::parse(expCtx, "$$userVar", expCtx->variablesParseState);
+ auto expr = ExpressionFieldPath::parse(&expCtx, "$$userVar", expCtx.variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionFieldPath*>(expr.get()));
auto optimizedExpr = expr->optimize();
@@ -128,11 +128,11 @@ TEST(FieldPath, OptimizeOnVariableWithConstantScalarValue) {
}
TEST(FieldPath, OptimizeOnVariableWithConstantArrayValue) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setConstantValue(varId, Value(BSON_ARRAY(1 << 2 << 3)));
+ auto expCtx = ExpressionContextForTest{};
+ auto varId = expCtx.variablesParseState.defineVariable("userVar");
+ expCtx.variables.setConstantValue(varId, Value(BSON_ARRAY(1 << 2 << 3)));
- auto expr = ExpressionFieldPath::parse(expCtx, "$$userVar", expCtx->variablesParseState);
+ auto expr = ExpressionFieldPath::parse(&expCtx, "$$userVar", expCtx.variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionFieldPath*>(expr.get()));
auto optimizedExpr = expr->optimize();
@@ -142,11 +142,11 @@ TEST(FieldPath, OptimizeOnVariableWithConstantArrayValue) {
}
TEST(FieldPath, OptimizeToEmptyArrayOnNumericalPathComponentAndConstantArrayValue) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setConstantValue(varId, Value(BSON_ARRAY(1 << 2 << 3)));
+ auto expCtx = ExpressionContextForTest{};
+ auto varId = expCtx.variablesParseState.defineVariable("userVar");
+ expCtx.variables.setConstantValue(varId, Value(BSON_ARRAY(1 << 2 << 3)));
- auto expr = ExpressionFieldPath::parse(expCtx, "$$userVar.1", expCtx->variablesParseState);
+ auto expr = ExpressionFieldPath::parse(&expCtx, "$$userVar.1", expCtx.variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionFieldPath*>(expr.get()));
auto optimizedExpr = expr->optimize();
@@ -156,11 +156,11 @@ TEST(FieldPath, OptimizeToEmptyArrayOnNumericalPathComponentAndConstantArrayValu
}
TEST(FieldPath, OptimizeOnVariableWithConstantValueAndDottedPath) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setConstantValue(varId, Value(Document{{"x", Document{{"y", 123}}}}));
+ auto expCtx = ExpressionContextForTest{};
+ auto varId = expCtx.variablesParseState.defineVariable("userVar");
+ expCtx.variables.setConstantValue(varId, Value(Document{{"x", Document{{"y", 123}}}}));
- auto expr = ExpressionFieldPath::parse(expCtx, "$$userVar.x.y", expCtx->variablesParseState);
+ auto expr = ExpressionFieldPath::parse(&expCtx, "$$userVar.x.y", expCtx.variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionFieldPath*>(expr.get()));
auto optimizedExpr = expr->optimize();
@@ -170,10 +170,10 @@ TEST(FieldPath, OptimizeOnVariableWithConstantValueAndDottedPath) {
}
TEST(FieldPath, NoOptimizationOnVariableWithNoValue) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- expCtx->variablesParseState.defineVariable("userVar");
+ auto expCtx = ExpressionContextForTest{};
+ expCtx.variablesParseState.defineVariable("userVar");
- auto expr = ExpressionFieldPath::parse(expCtx, "$$userVar", expCtx->variablesParseState);
+ auto expr = ExpressionFieldPath::parse(&expCtx, "$$userVar", expCtx.variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionFieldPath*>(expr.get()));
auto optimizedExpr = expr->optimize();
@@ -181,11 +181,11 @@ TEST(FieldPath, NoOptimizationOnVariableWithNoValue) {
}
TEST(FieldPath, NoOptimizationOnVariableWithMissingValue) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setValue(varId, Value());
+ auto expCtx = ExpressionContextForTest{};
+ auto varId = expCtx.variablesParseState.defineVariable("userVar");
+ expCtx.variables.setValue(varId, Value());
- auto expr = ExpressionFieldPath::parse(expCtx, "$$userVar", expCtx->variablesParseState);
+ auto expr = ExpressionFieldPath::parse(&expCtx, "$$userVar", expCtx.variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionFieldPath*>(expr.get()));
auto optimizedExpr = expr->optimize();
@@ -193,11 +193,11 @@ TEST(FieldPath, NoOptimizationOnVariableWithMissingValue) {
}
TEST(FieldPath, ScalarVariableWithDottedFieldPathOptimizesToConstantMissingValue) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- expCtx->variables.setConstantValue(varId, Value(123));
+ auto expCtx = ExpressionContextForTest{};
+ auto varId = expCtx.variablesParseState.defineVariable("userVar");
+ expCtx.variables.setConstantValue(varId, Value(123));
- auto expr = ExpressionFieldPath::parse(expCtx, "$$userVar.x.y", expCtx->variablesParseState);
+ auto expr = ExpressionFieldPath::parse(&expCtx, "$$userVar.x.y", expCtx.variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionFieldPath*>(expr.get()));
auto optimizedExpr = expr->optimize();
@@ -210,8 +210,8 @@ TEST(FieldPath, ScalarVariableWithDottedFieldPathOptimizesToConstantMissingValue
class Dependencies {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a.b");
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> expression = ExpressionFieldPath::create(&expCtx, "a.b");
DepsTracker dependencies;
expression->addDependencies(&dependencies);
ASSERT_EQUALS(1U, dependencies.fields.size());
@@ -225,9 +225,9 @@ public:
class Missing {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a");
- assertBinaryEqual(fromjson("{}"), toBson(expression->evaluate({}, &expCtx->variables)));
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> expression = ExpressionFieldPath::create(&expCtx, "a");
+ assertBinaryEqual(fromjson("{}"), toBson(expression->evaluate({}, &expCtx.variables)));
}
};
@@ -235,11 +235,11 @@ public:
class Present {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a");
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> expression = ExpressionFieldPath::create(&expCtx, "a");
assertBinaryEqual(
fromjson("{'':123}"),
- toBson(expression->evaluate(fromBson(BSON("a" << 123)), &expCtx->variables)));
+ toBson(expression->evaluate(fromBson(BSON("a" << 123)), &expCtx.variables)));
}
};
@@ -247,11 +247,11 @@ public:
class NestedBelowNull {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a.b");
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> expression = ExpressionFieldPath::create(&expCtx, "a.b");
assertBinaryEqual(
fromjson("{}"),
- toBson(expression->evaluate(fromBson(fromjson("{a:null}")), &expCtx->variables)));
+ toBson(expression->evaluate(fromBson(fromjson("{a:null}")), &expCtx.variables)));
}
};
@@ -259,11 +259,11 @@ public:
class NestedBelowUndefined {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a.b");
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> expression = ExpressionFieldPath::create(&expCtx, "a.b");
assertBinaryEqual(
fromjson("{}"),
- toBson(expression->evaluate(fromBson(fromjson("{a:undefined}")), &expCtx->variables)));
+ toBson(expression->evaluate(fromBson(fromjson("{a:undefined}")), &expCtx.variables)));
}
};
@@ -271,11 +271,11 @@ public:
class NestedBelowMissing {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a.b");
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> expression = ExpressionFieldPath::create(&expCtx, "a.b");
assertBinaryEqual(
fromjson("{}"),
- toBson(expression->evaluate(fromBson(fromjson("{z:1}")), &expCtx->variables)));
+ toBson(expression->evaluate(fromBson(fromjson("{z:1}")), &expCtx.variables)));
}
};
@@ -283,11 +283,11 @@ public:
class NestedBelowInt {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a.b");
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> expression = ExpressionFieldPath::create(&expCtx, "a.b");
assertBinaryEqual(
fromjson("{}"),
- toBson(expression->evaluate(fromBson(BSON("a" << 2)), &expCtx->variables)));
+ toBson(expression->evaluate(fromBson(BSON("a" << 2)), &expCtx.variables)));
}
};
@@ -295,11 +295,11 @@ public:
class NestedValue {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a.b");
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> expression = ExpressionFieldPath::create(&expCtx, "a.b");
assertBinaryEqual(BSON("" << 55),
toBson(expression->evaluate(fromBson(BSON("a" << BSON("b" << 55))),
- &expCtx->variables)));
+ &expCtx.variables)));
}
};
@@ -307,11 +307,11 @@ public:
class NestedBelowEmptyObject {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a.b");
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> expression = ExpressionFieldPath::create(&expCtx, "a.b");
assertBinaryEqual(
fromjson("{}"),
- toBson(expression->evaluate(fromBson(BSON("a" << BSONObj())), &expCtx->variables)));
+ toBson(expression->evaluate(fromBson(BSON("a" << BSONObj())), &expCtx.variables)));
}
};
@@ -319,11 +319,11 @@ public:
class NestedBelowEmptyArray {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a.b");
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> expression = ExpressionFieldPath::create(&expCtx, "a.b");
assertBinaryEqual(
BSON("" << BSONArray()),
- toBson(expression->evaluate(fromBson(BSON("a" << BSONArray())), &expCtx->variables)));
+ toBson(expression->evaluate(fromBson(BSON("a" << BSONArray())), &expCtx.variables)));
}
};
@@ -331,11 +331,11 @@ public:
class NestedBelowArrayWithNull {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a.b");
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> expression = ExpressionFieldPath::create(&expCtx, "a.b");
assertBinaryEqual(
fromjson("{'':[]}"),
- toBson(expression->evaluate(fromBson(fromjson("{a:[null]}")), &expCtx->variables)));
+ toBson(expression->evaluate(fromBson(fromjson("{a:[null]}")), &expCtx.variables)));
}
};
@@ -343,11 +343,11 @@ public:
class NestedBelowArrayWithUndefined {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a.b");
- assertBinaryEqual(fromjson("{'':[]}"),
- toBson(expression->evaluate(fromBson(fromjson("{a:[undefined]}")),
- &expCtx->variables)));
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> expression = ExpressionFieldPath::create(&expCtx, "a.b");
+ assertBinaryEqual(
+ fromjson("{'':[]}"),
+ toBson(expression->evaluate(fromBson(fromjson("{a:[undefined]}")), &expCtx.variables)));
}
};
@@ -355,11 +355,11 @@ public:
class NestedBelowArrayWithInt {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a.b");
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> expression = ExpressionFieldPath::create(&expCtx, "a.b");
assertBinaryEqual(
fromjson("{'':[]}"),
- toBson(expression->evaluate(fromBson(fromjson("{a:[1]}")), &expCtx->variables)));
+ toBson(expression->evaluate(fromBson(fromjson("{a:[1]}")), &expCtx.variables)));
}
};
@@ -367,11 +367,11 @@ public:
class NestedWithinArray {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a.b");
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> expression = ExpressionFieldPath::create(&expCtx, "a.b");
assertBinaryEqual(
fromjson("{'':[9]}"),
- toBson(expression->evaluate(fromBson(fromjson("{a:[{b:9}]}")), &expCtx->variables)));
+ toBson(expression->evaluate(fromBson(fromjson("{a:[{b:9}]}")), &expCtx.variables)));
}
};
@@ -379,12 +379,12 @@ public:
class MultipleArrayValues {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a.b");
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> expression = ExpressionFieldPath::create(&expCtx, "a.b");
assertBinaryEqual(fromjson("{'':[9,20]}"),
toBson(expression->evaluate(
fromBson(fromjson("{a:[{b:9},null,undefined,{g:4},{b:20},{}]}")),
- &expCtx->variables)));
+ &expCtx.variables)));
}
};
@@ -392,15 +392,15 @@ public:
class ExpandNestedArrays {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a.b.c");
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> expression = ExpressionFieldPath::create(&expCtx, "a.b.c");
assertBinaryEqual(fromjson("{'':[[1,2],3,[4],[[5]],[6,7]]}"),
toBson(expression->evaluate(fromBson(fromjson("{a:[{b:[{c:1},{c:2}]},"
"{b:{c:3}},"
"{b:[{c:4}]},"
"{b:[{c:[5]}]},"
"{b:{c:[6,7]}}]}")),
- &expCtx->variables)));
+ &expCtx.variables)));
}
};
@@ -408,8 +408,8 @@ public:
class AddToBsonObj {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a.b.c");
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> expression = ExpressionFieldPath::create(&expCtx, "a.b.c");
assertBinaryEqual(BSON("foo"
<< "$a.b.c"),
BSON("foo" << expression->serialize(false)));
@@ -420,8 +420,8 @@ public:
class AddToBsonArray {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a.b.c");
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> expression = ExpressionFieldPath::create(&expCtx, "a.b.c");
BSONArrayBuilder bab;
bab << expression->serialize(false);
assertBinaryEqual(BSON_ARRAY("$a.b.c"), bab.arr());
diff --git a/src/mongo/db/pipeline/expression_find_internal.h b/src/mongo/db/pipeline/expression_find_internal.h
index fe9f4162c89..1b4ec2444e4 100644
--- a/src/mongo/db/pipeline/expression_find_internal.h
+++ b/src/mongo/db/pipeline/expression_find_internal.h
@@ -44,7 +44,7 @@ namespace mongo {
*/
class ExpressionInternalFindPositional final : public Expression {
public:
- ExpressionInternalFindPositional(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionInternalFindPositional(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> preImageExpr,
boost::intrusive_ptr<Expression> postImageExpr,
FieldPath path,
@@ -122,7 +122,7 @@ private:
*/
class ExpressionInternalFindSlice final : public Expression {
public:
- ExpressionInternalFindSlice(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionInternalFindSlice(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> postImageExpr,
FieldPath path,
boost::optional<int> skip,
@@ -183,7 +183,7 @@ private:
*/
class ExpressionInternalFindElemMatch final : public Expression {
public:
- ExpressionInternalFindElemMatch(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionInternalFindElemMatch(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> child,
FieldPath path,
CopyableMatchExpression matchExpr)
diff --git a/src/mongo/db/pipeline/expression_find_internal_test.cpp b/src/mongo/db/pipeline/expression_find_internal_test.cpp
index 62b79968731..2b743d2b661 100644
--- a/src/mongo/db/pipeline/expression_find_internal_test.cpp
+++ b/src/mongo/db/pipeline/expression_find_internal_test.cpp
@@ -39,8 +39,7 @@ namespace mongo::expression_internal_tests {
constexpr auto kProjectionPostImageVarName =
projection_executor::ProjectionExecutor::kProjectionPostImageVarName;
-auto defineAndSetProjectionPostImageVariable(boost::intrusive_ptr<ExpressionContext> expCtx,
- Value postImage) {
+auto defineAndSetProjectionPostImageVariable(ExpressionContext* const expCtx, Value postImage) {
auto& vps = expCtx->variablesParseState;
auto varId = vps.defineVariable(kProjectionPostImageVarName);
expCtx->variables.setValue(varId, postImage);
@@ -51,14 +50,15 @@ class ExpressionInternalFindPositionalTest : public AggregationContextFixture {
protected:
auto createExpression(BSONObj matchSpec, const std::string& path) {
auto matchExpr = CopyableMatchExpression{matchSpec,
- getExpCtx(),
+ getExpCtxRaw(),
std::make_unique<ExtensionsCallbackNoop>(),
MatchExpressionParser::kBanAllSpecialFeatures};
auto expr = make_intrusive<ExpressionInternalFindPositional>(
- getExpCtx(),
- ExpressionFieldPath::parse(getExpCtx(), "$$ROOT", getExpCtx()->variablesParseState),
- ExpressionFieldPath::parse(
- getExpCtx(), "$$" + kProjectionPostImageVarName, getExpCtx()->variablesParseState),
+ getExpCtxRaw(),
+ ExpressionFieldPath::parse(getExpCtxRaw(), "$$ROOT", getExpCtx()->variablesParseState),
+ ExpressionFieldPath::parse(getExpCtxRaw(),
+ "$$" + kProjectionPostImageVarName,
+ getExpCtx()->variablesParseState),
path,
std::move(matchExpr));
return expr;
@@ -69,9 +69,10 @@ class ExpressionInternalFindSliceTest : public AggregationContextFixture {
protected:
auto createExpression(const std::string& path, boost::optional<int> skip, int limit) {
auto expr = make_intrusive<ExpressionInternalFindSlice>(
- getExpCtx(),
- ExpressionFieldPath::parse(
- getExpCtx(), "$$" + kProjectionPostImageVarName, getExpCtx()->variablesParseState),
+ getExpCtxRaw(),
+ ExpressionFieldPath::parse(getExpCtxRaw(),
+ "$$" + kProjectionPostImageVarName,
+ getExpCtx()->variablesParseState),
path,
skip,
limit);
@@ -83,20 +84,20 @@ class ExpressionInternalFindElemMatchTest : public AggregationContextFixture {
protected:
auto createExpression(BSONObj matchSpec, const std::string& path) {
auto matchExpr = CopyableMatchExpression{matchSpec,
- getExpCtx(),
+ getExpCtxRaw(),
std::make_unique<ExtensionsCallbackNoop>(),
MatchExpressionParser::kBanAllSpecialFeatures};
return make_intrusive<ExpressionInternalFindElemMatch>(
- getExpCtx(),
- ExpressionFieldPath::parse(getExpCtx(), "$$ROOT", getExpCtx()->variablesParseState),
+ getExpCtxRaw(),
+ ExpressionFieldPath::parse(getExpCtxRaw(), "$$ROOT", getExpCtx()->variablesParseState),
path,
std::move(matchExpr));
}
};
TEST_F(ExpressionInternalFindPositionalTest, AppliesProjectionToPostImage) {
- defineAndSetProjectionPostImageVariable(getExpCtx(),
+ defineAndSetProjectionPostImageVariable(getExpCtxRaw(),
Value{fromjson("{bar: 1, foo: [1,2,6,10]}")});
auto expr = createExpression(fromjson("{bar: 1, foo: {$gte: 5}}"), "foo");
@@ -109,7 +110,7 @@ TEST_F(ExpressionInternalFindPositionalTest, AppliesProjectionToPostImage) {
TEST_F(ExpressionInternalFindPositionalTest, RecordsProjectionDependencies) {
auto varId = defineAndSetProjectionPostImageVariable(
- getExpCtx(), Value{fromjson("{bar: 1, foo: [1,2,6,10]}")});
+ getExpCtxRaw(), Value{fromjson("{bar: 1, foo: [1,2,6,10]}")});
auto expr = createExpression(fromjson("{bar: 1, foo: {$gte: 5}}"), "foo");
DepsTracker deps;
@@ -124,7 +125,7 @@ TEST_F(ExpressionInternalFindPositionalTest, RecordsProjectionDependencies) {
}
TEST_F(ExpressionInternalFindPositionalTest, AddsArrayUndottedPathToComputedPaths) {
- defineAndSetProjectionPostImageVariable(getExpCtx(),
+ defineAndSetProjectionPostImageVariable(getExpCtxRaw(),
Value{fromjson("{bar: 1, foo: [1,2,6,10]}")});
auto expr = createExpression(fromjson("{bar: 1, foo: {$gte: 5}}"), "foo");
@@ -139,7 +140,7 @@ TEST_F(ExpressionInternalFindPositionalTest, AddsArrayUndottedPathToComputedPath
TEST_F(ExpressionInternalFindPositionalTest,
AddsOnlyTopLevelFieldOfArrayDottedPathToComputedPaths) {
- defineAndSetProjectionPostImageVariable(getExpCtx(),
+ defineAndSetProjectionPostImageVariable(getExpCtxRaw(),
Value{fromjson("{bar: 1, foo: [1,2,6,10]}")});
auto expr = createExpression(fromjson("{bar: 1, 'foo.bar': {$gte: 5}}"), "foo.bar");
@@ -153,7 +154,7 @@ TEST_F(ExpressionInternalFindPositionalTest,
}
TEST_F(ExpressionInternalFindSliceTest, AppliesProjectionToPostImage) {
- defineAndSetProjectionPostImageVariable(getExpCtx(),
+ defineAndSetProjectionPostImageVariable(getExpCtxRaw(),
Value{fromjson("{bar: 1, foo: [1,2,6,10]}")});
auto expr = createExpression("foo", 1, 2);
@@ -166,7 +167,7 @@ TEST_F(ExpressionInternalFindSliceTest, AppliesProjectionToPostImage) {
TEST_F(ExpressionInternalFindSliceTest, RecordsProjectionDependencies) {
auto varId = defineAndSetProjectionPostImageVariable(
- getExpCtx(), Value{fromjson("{bar: 1, foo: [1,2,6,10]}")});
+ getExpCtxRaw(), Value{fromjson("{bar: 1, foo: [1,2,6,10]}")});
auto expr = createExpression("foo", 1, 2);
DepsTracker deps;
@@ -179,7 +180,7 @@ TEST_F(ExpressionInternalFindSliceTest, RecordsProjectionDependencies) {
}
TEST_F(ExpressionInternalFindSliceTest, AddsArrayUndottedPathToComputedPaths) {
- defineAndSetProjectionPostImageVariable(getExpCtx(),
+ defineAndSetProjectionPostImageVariable(getExpCtxRaw(),
Value{fromjson("{bar: 1, foo: [1,2,6,10]}")});
auto expr = createExpression("foo", 1, 2);
@@ -193,7 +194,7 @@ TEST_F(ExpressionInternalFindSliceTest, AddsArrayUndottedPathToComputedPaths) {
}
TEST_F(ExpressionInternalFindSliceTest, AddsTopLevelFieldOfArrayDottedPathToComputedPaths) {
- defineAndSetProjectionPostImageVariable(getExpCtx(),
+ defineAndSetProjectionPostImageVariable(getExpCtxRaw(),
Value{fromjson("{bar: 1, foo: [1,2,6,10]}")});
auto expr = createExpression("foo.bar", 1, 2);
diff --git a/src/mongo/db/pipeline/expression_function.cpp b/src/mongo/db/pipeline/expression_function.cpp
index 30ac119fab0..8f5074bb1c1 100644
--- a/src/mongo/db/pipeline/expression_function.cpp
+++ b/src/mongo/db/pipeline/expression_function.cpp
@@ -33,7 +33,7 @@ namespace mongo {
REGISTER_EXPRESSION(function, ExpressionFunction::parse);
-ExpressionFunction::ExpressionFunction(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ExpressionFunction::ExpressionFunction(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> passedArgs,
bool assignFirstArgToThis,
std::string funcSource,
@@ -60,10 +60,9 @@ void ExpressionFunction::_doAddDependencies(mongo::DepsTracker* deps) const {
_children[0]->addDependencies(deps);
}
-boost::intrusive_ptr<Expression> ExpressionFunction::parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps) {
+boost::intrusive_ptr<Expression> ExpressionFunction::parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps) {
uassert(4660800,
str::stream() << kExpressionName << " cannot be used inside a validator.",
diff --git a/src/mongo/db/pipeline/expression_function.h b/src/mongo/db/pipeline/expression_function.h
index d42b0723802..5bad4eb38cc 100644
--- a/src/mongo/db/pipeline/expression_function.h
+++ b/src/mongo/db/pipeline/expression_function.h
@@ -40,13 +40,12 @@ namespace mongo {
*/
class ExpressionFunction final : public Expression {
public:
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps);
+ static boost::intrusive_ptr<Expression> parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps);
static boost::intrusive_ptr<ExpressionFunction> create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> passedArgs,
std::string funcSourceString,
std::string lang) {
@@ -60,7 +59,7 @@ public:
// This method is intended for use when you want to bind obj to an argument for desugaring
// $where.
static boost::intrusive_ptr<ExpressionFunction> createForWhere(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> passedArgs,
std::string funcSourceString,
std::string lang) {
@@ -80,7 +79,7 @@ public:
static constexpr auto kJavaScript = "js";
private:
- ExpressionFunction(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionFunction(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> passedArgs,
bool assignFirstArgToThis,
std::string funcSourceString,
diff --git a/src/mongo/db/pipeline/expression_internal_remove_field_tombstones.h b/src/mongo/db/pipeline/expression_internal_remove_field_tombstones.h
index 137f52c2a3b..936c316e0cd 100644
--- a/src/mongo/db/pipeline/expression_internal_remove_field_tombstones.h
+++ b/src/mongo/db/pipeline/expression_internal_remove_field_tombstones.h
@@ -44,9 +44,8 @@ namespace mongo {
*/
class ExpressionInternalRemoveFieldTombstones final : public Expression {
public:
- explicit ExpressionInternalRemoveFieldTombstones(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- boost::intrusive_ptr<Expression> child)
+ explicit ExpressionInternalRemoveFieldTombstones(ExpressionContext* const expCtx,
+ boost::intrusive_ptr<Expression> child)
: Expression{expCtx, {std::move(child)}} {}
Value evaluate(const Document& root, Variables* variables) const final {
@@ -93,4 +92,4 @@ private:
return Value(output.freeze());
}
};
-} // namespace mongo \ No newline at end of file
+} // namespace mongo
diff --git a/src/mongo/db/pipeline/expression_internal_remove_field_tombstones_test.cpp b/src/mongo/db/pipeline/expression_internal_remove_field_tombstones_test.cpp
index 589baa5d577..ff72e8aa4ee 100644
--- a/src/mongo/db/pipeline/expression_internal_remove_field_tombstones_test.cpp
+++ b/src/mongo/db/pipeline/expression_internal_remove_field_tombstones_test.cpp
@@ -42,8 +42,8 @@ class ExpressionInternalRemoveFieldTombstonesTest : public AggregationContextFix
public:
auto createExpression() {
auto expr = make_intrusive<ExpressionInternalRemoveFieldTombstones>(
- getExpCtx(),
- ExpressionFieldPath::parse(getExpCtx(), "$$ROOT", getExpCtx()->variablesParseState));
+ getExpCtxRaw(),
+ ExpressionFieldPath::parse(getExpCtxRaw(), "$$ROOT", getExpCtx()->variablesParseState));
return expr;
}
};
@@ -70,4 +70,4 @@ TEST_F(ExpressionInternalRemoveFieldTombstonesTest, RemovesNestedTombstoneValues
expected);
}
-} // namespace mongo::expression_internal_tests \ No newline at end of file
+} // namespace mongo::expression_internal_tests
diff --git a/src/mongo/db/pipeline/expression_javascript_test.cpp b/src/mongo/db/pipeline/expression_javascript_test.cpp
index 3df1f10d436..299ee506664 100644
--- a/src/mongo/db/pipeline/expression_javascript_test.cpp
+++ b/src/mongo/db/pipeline/expression_javascript_test.cpp
@@ -50,9 +50,12 @@ protected:
_expCtx->mongoProcessInterface = std::make_shared<StandaloneProcessInterface>(nullptr);
}
- boost::intrusive_ptr<ExpressionContextForTest>& getExpCtx() {
+ auto& getExpCtx() {
return _expCtx;
}
+ auto getExpCtxRaw() {
+ return _expCtx.get();
+ }
const VariablesParseState& getVPS() {
return _vps;
@@ -88,7 +91,7 @@ TEST_F(MapReduceFixture, ExpressionFunctionProducesExpectedResult) {
<< "args" << BSON_ARRAY("$a" << 4) << "lang"
<< ExpressionFunction::kJavaScript));
- auto expr = ExpressionFunction::parse(getExpCtx(), bsonExpr.firstElement(), getVPS());
+ auto expr = ExpressionFunction::parse(getExpCtxRaw(), bsonExpr.firstElement(), getVPS());
Value result = expr->evaluate(Document{BSON("a" << 2)}, getVariables());
ASSERT_VALUE_EQ(result, Value(6));
@@ -98,7 +101,7 @@ TEST_F(MapReduceFixture, ExpressionFunctionProducesExpectedResult) {
<< "function(first, second, third) {return first + second + third;};"
<< "args" << BSON_ARRAY(1 << 2 << 4) << "lang"
<< ExpressionFunction::kJavaScript));
- expr = ExpressionFunction::parse(getExpCtx(), bsonExpr.firstElement(), getVPS());
+ expr = ExpressionFunction::parse(getExpCtxRaw(), bsonExpr.firstElement(), getVPS());
result = expr->evaluate(Document{BSONObj{}}, getVariables());
ASSERT_VALUE_EQ(result, Value(7));
@@ -106,7 +109,7 @@ TEST_F(MapReduceFixture, ExpressionFunctionProducesExpectedResult) {
<< "function(first) {return first;};"
<< "args" << BSON_ARRAY(1) << "lang"
<< ExpressionFunction::kJavaScript));
- expr = ExpressionFunction::parse(getExpCtx(), bsonExpr.firstElement(), getVPS());
+ expr = ExpressionFunction::parse(getExpCtxRaw(), bsonExpr.firstElement(), getVPS());
result = expr->evaluate(Document{BSONObj{}}, getVariables());
ASSERT_VALUE_EQ(result, Value(1));
}
@@ -116,7 +119,7 @@ TEST_F(MapReduceFixture, ExpressionFunctionFailsIfArgsDoesNotEvaluateToArray) {
<< "function(first, second) {return first + second;};"
<< "args" << BSON("a" << 1) << "lang"
<< ExpressionFunction::kJavaScript));
- auto expr = ExpressionFunction::parse(getExpCtx(), bsonExpr.firstElement(), getVPS());
+ auto expr = ExpressionFunction::parse(getExpCtxRaw(), bsonExpr.firstElement(), getVPS());
ASSERT_THROWS_CODE(expr->evaluate({}, getVariables()), AssertionException, 31266);
}
@@ -126,7 +129,7 @@ TEST_F(MapReduceFixture, ExpressionFunctionFailsWithInvalidFunction) {
<< "INVALID"
<< "args" << BSON_ARRAY(1 << 2) << "lang"
<< ExpressionFunction::kJavaScript));
- auto expr = ExpressionFunction::parse(getExpCtx(), bsonExpr.firstElement(), getVPS());
+ auto expr = ExpressionFunction::parse(getExpCtxRaw(), bsonExpr.firstElement(), getVPS());
ASSERT_THROWS_CODE(
expr->evaluate({}, getVariables()), AssertionException, ErrorCodes::JSInterpreterFailure);
@@ -134,7 +137,7 @@ TEST_F(MapReduceFixture, ExpressionFunctionFailsWithInvalidFunction) {
TEST_F(MapReduceFixture, ExpressionFunctionFailsIfArgumentIsNotObject) {
auto bsonExpr = BSON("expr" << 1);
- ASSERT_THROWS_CODE(ExpressionFunction::parse(getExpCtx(), bsonExpr.firstElement(), getVPS()),
+ ASSERT_THROWS_CODE(ExpressionFunction::parse(getExpCtxRaw(), bsonExpr.firstElement(), getVPS()),
AssertionException,
31260);
}
@@ -142,7 +145,7 @@ TEST_F(MapReduceFixture, ExpressionFunctionFailsIfArgumentIsNotObject) {
TEST_F(MapReduceFixture, ExpressionFunctionFailsIfBodyNotSpecified) {
auto bsonExpr = BSON(
"expr" << BSON("args" << BSON_ARRAY(1 << 2) << "lang" << ExpressionFunction::kJavaScript));
- ASSERT_THROWS_CODE(ExpressionFunction::parse(getExpCtx(), bsonExpr.firstElement(), getVPS()),
+ ASSERT_THROWS_CODE(ExpressionFunction::parse(getExpCtxRaw(), bsonExpr.firstElement(), getVPS()),
AssertionException,
31261);
}
@@ -150,7 +153,7 @@ TEST_F(MapReduceFixture, ExpressionFunctionFailsIfBodyNotSpecified) {
TEST_F(MapReduceFixture, ExpressionFunctionFailsIfBodyIsNotConstantExpression) {
auto bsonExpr = BSON("expr" << BSON("body" << BSONObj() << "args" << BSON_ARRAY(1 << 2)
<< "lang" << ExpressionFunction::kJavaScript));
- ASSERT_THROWS_CODE(ExpressionFunction::parse(getExpCtx(), bsonExpr.firstElement(), getVPS()),
+ ASSERT_THROWS_CODE(ExpressionFunction::parse(getExpCtxRaw(), bsonExpr.firstElement(), getVPS()),
AssertionException,
31432);
}
@@ -158,7 +161,7 @@ TEST_F(MapReduceFixture, ExpressionFunctionFailsIfBodyIsNotConstantExpression) {
TEST_F(MapReduceFixture, ExpressionFunctionFailsIfBodyIsNotCorrectType) {
auto bsonExpr = BSON("expr" << BSON("body" << 1 << "args" << BSON_ARRAY(1 << 2) << "lang"
<< ExpressionFunction::kJavaScript));
- ASSERT_THROWS_CODE(ExpressionFunction::parse(getExpCtx(), bsonExpr.firstElement(), getVPS()),
+ ASSERT_THROWS_CODE(ExpressionFunction::parse(getExpCtxRaw(), bsonExpr.firstElement(), getVPS()),
AssertionException,
31262);
}
@@ -167,7 +170,7 @@ TEST_F(MapReduceFixture, ExpressionFunctionFailsIfArgsIsNotSpecified) {
auto bsonExpr = BSON("expr" << BSON("body"
<< "function(first) {return first;};"
<< "lang" << ExpressionFunction::kJavaScript));
- ASSERT_THROWS_CODE(ExpressionFunction::parse(getExpCtx(), bsonExpr.firstElement(), getVPS()),
+ ASSERT_THROWS_CODE(ExpressionFunction::parse(getExpCtxRaw(), bsonExpr.firstElement(), getVPS()),
AssertionException,
31263);
}
@@ -176,7 +179,7 @@ TEST_F(MapReduceFixture, ExpressionFunctionFailsIfLangIsNotSpecified) {
auto bsonExpr = BSON("expr" << BSON("body"
<< "function(first) {return first;};"
<< "args" << BSON_ARRAY(1 << 2)));
- ASSERT_THROWS_CODE(ExpressionFunction::parse(getExpCtx(), bsonExpr.firstElement(), getVPS()),
+ ASSERT_THROWS_CODE(ExpressionFunction::parse(getExpCtxRaw(), bsonExpr.firstElement(), getVPS()),
AssertionException,
31418);
}
@@ -187,7 +190,7 @@ TEST_F(MapReduceFixture, ExpressionInternalJsEmitProducesExpectedResult) {
<< "eval"
<< "function() {emit(this.a, 1); emit(this.b, 1)};"));
- auto expr = ExpressionInternalJsEmit::parse(getExpCtx(), bsonExpr.firstElement(), getVPS());
+ auto expr = ExpressionInternalJsEmit::parse(getExpCtxRaw(), bsonExpr.firstElement(), getVPS());
Value result = expr->evaluate(Document{BSON("a" << 3 << "b" << 6)}, getVariables());
ASSERT_VALUE_EQ(result,
@@ -198,7 +201,7 @@ TEST_F(MapReduceFixture, ExpressionInternalJsEmitFailsIfThisArgumentNotSpecified
auto bsonExpr = BSON("expr" << BSON("eval"
<< "function() {emit(this.a, 1); emit(this.b, 1)};"));
ASSERT_THROWS_CODE(
- ExpressionInternalJsEmit::parse(getExpCtx(), bsonExpr.firstElement(), getVPS()),
+ ExpressionInternalJsEmit::parse(getExpCtxRaw(), bsonExpr.firstElement(), getVPS()),
AssertionException,
31223);
}
@@ -207,7 +210,7 @@ TEST_F(MapReduceFixture, ExpressionInternalJsEmitFailsIfThisArgumentIsNotAnObjec
auto bsonExpr =
BSON("expr" << BSON("this" << 123 << "eval"
<< "function() {emit(this.a, 1); emit(this.b, 1)};"));
- auto expr = ExpressionInternalJsEmit::parse(getExpCtx(), bsonExpr.firstElement(), getVPS());
+ auto expr = ExpressionInternalJsEmit::parse(getExpCtxRaw(), bsonExpr.firstElement(), getVPS());
ASSERT_THROWS_CODE(expr->evaluate({}, getVariables()), AssertionException, 31225);
}
@@ -217,7 +220,7 @@ TEST_F(MapReduceFixture, ExpressionInternalJsEmitFailsWithInvalidFunction) {
<< "$$ROOT"
<< "eval"
<< "INVALID"));
- auto expr = ExpressionInternalJsEmit::parse(getExpCtx(), bsonExpr.firstElement(), getVPS());
+ auto expr = ExpressionInternalJsEmit::parse(getExpCtxRaw(), bsonExpr.firstElement(), getVPS());
ASSERT_THROWS_CODE(
expr->evaluate({}, getVariables()), AssertionException, ErrorCodes::JSInterpreterFailure);
@@ -228,7 +231,7 @@ TEST_F(MapReduceFixture, ExpressionInternalJsEmitFailsWithInvalidNumberOfEvalArg
<< "$$ROOT"
<< "eval"
<< "function() {emit(this.a);};"));
- auto expr = ExpressionInternalJsEmit::parse(getExpCtx(), bsonExpr.firstElement(), getVPS());
+ auto expr = ExpressionInternalJsEmit::parse(getExpCtxRaw(), bsonExpr.firstElement(), getVPS());
ASSERT_THROWS_CODE(
expr->evaluate(Document{BSON("a" << 3)}, getVariables()), AssertionException, 31220);
@@ -237,7 +240,7 @@ TEST_F(MapReduceFixture, ExpressionInternalJsEmitFailsWithInvalidNumberOfEvalArg
TEST_F(MapReduceFixture, ExpressionInternalJsEmitFailsIfArgumentIsNotObject) {
auto bsonExpr = BSON("expr" << 1);
ASSERT_THROWS_CODE(
- ExpressionInternalJsEmit::parse(getExpCtx(), bsonExpr.firstElement(), getVPS()),
+ ExpressionInternalJsEmit::parse(getExpCtxRaw(), bsonExpr.firstElement(), getVPS()),
AssertionException,
31221);
}
@@ -246,7 +249,7 @@ TEST_F(MapReduceFixture, ExpressionInternalJsEmitFailsIfEvalNotSpecified) {
auto bsonExpr = BSON("expr" << BSON("this"
<< "$$ROOT"));
ASSERT_THROWS_CODE(
- ExpressionInternalJsEmit::parse(getExpCtx(), bsonExpr.firstElement(), getVPS()),
+ ExpressionInternalJsEmit::parse(getExpCtxRaw(), bsonExpr.firstElement(), getVPS()),
AssertionException,
31222);
}
@@ -256,7 +259,7 @@ TEST_F(MapReduceFixture, ExpressionInternalJsEmitFailsIfEvalIsNotCorrectType) {
<< "$$ROOT"
<< "eval" << 12.3));
ASSERT_THROWS_CODE(
- ExpressionInternalJsEmit::parse(getExpCtx(), bsonExpr.firstElement(), getVPS()),
+ ExpressionInternalJsEmit::parse(getExpCtxRaw(), bsonExpr.firstElement(), getVPS()),
AssertionException,
31224);
}
@@ -268,7 +271,7 @@ TEST_F(MapReduceFixture, ExpressionInternalJsErrorsIfProducesTooManyDocumentsFor
<< "$$ROOT"
<< "eval"
<< "function() {for (var i = 0; i < this.val; ++i) {emit(i, 1);}}"));
- auto expr = ExpressionInternalJsEmit::parse(getExpCtx(), bsonExpr.firstElement(), getVPS());
+ auto expr = ExpressionInternalJsEmit::parse(getExpCtxRaw(), bsonExpr.firstElement(), getVPS());
ASSERT_THROWS_CODE(
expr->evaluate(Document{BSON("val" << 1)}, getVariables()), AssertionException, 31292);
}
diff --git a/src/mongo/db/pipeline/expression_js_emit.cpp b/src/mongo/db/pipeline/expression_js_emit.cpp
index 1544b171e26..6340a53e98f 100644
--- a/src/mongo/db/pipeline/expression_js_emit.cpp
+++ b/src/mongo/db/pipeline/expression_js_emit.cpp
@@ -88,10 +88,9 @@ BSONObj emitFromJS(const BSONObj& args, void* data) {
}
} // namespace
-ExpressionInternalJsEmit::ExpressionInternalJsEmit(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- boost::intrusive_ptr<Expression> thisRef,
- std::string funcSource)
+ExpressionInternalJsEmit::ExpressionInternalJsEmit(ExpressionContext* const expCtx,
+ boost::intrusive_ptr<Expression> thisRef,
+ std::string funcSource)
: Expression(expCtx, {std::move(thisRef)}),
_emitState{{}, internalQueryMaxJsEmitBytes.load(), 0},
_thisRef(_children[0]),
@@ -101,10 +100,9 @@ void ExpressionInternalJsEmit::_doAddDependencies(mongo::DepsTracker* deps) cons
_children[0]->addDependencies(deps);
}
-boost::intrusive_ptr<Expression> ExpressionInternalJsEmit::parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps) {
+boost::intrusive_ptr<Expression> ExpressionInternalJsEmit::parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps) {
uassert(4660801,
str::stream() << kExpressionName << " cannot be used inside a validator.",
@@ -142,7 +140,7 @@ Value ExpressionInternalJsEmit::evaluate(const Document& root, Variables* variab
// If the scope does not exist and is created by the following call, then make sure to
// re-bind emit() and the given function to the new scope.
- ExpressionContext* expCtx = getExpressionContext().get();
+ ExpressionContext* expCtx = getExpressionContext();
auto jsExec = expCtx->getJsExecWithScope();
// Inject the native "emit" function to be called from the user-defined map function. This
diff --git a/src/mongo/db/pipeline/expression_js_emit.h b/src/mongo/db/pipeline/expression_js_emit.h
index 61298e50d3f..0d4788b4b4e 100644
--- a/src/mongo/db/pipeline/expression_js_emit.h
+++ b/src/mongo/db/pipeline/expression_js_emit.h
@@ -42,13 +42,12 @@ class ExpressionInternalJsEmit final : public Expression {
public:
static constexpr auto kExpressionName = "$_internalJsEmit"_sd;
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps);
+ static boost::intrusive_ptr<Expression> parse(ExpressionContext* const expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps);
static boost::intrusive_ptr<ExpressionInternalJsEmit> create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> thisRef,
std::string funcSourceString) {
return new ExpressionInternalJsEmit{expCtx, thisRef, std::move(funcSourceString)};
@@ -85,7 +84,7 @@ public:
} _emitState;
private:
- ExpressionInternalJsEmit(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ ExpressionInternalJsEmit(ExpressionContext* const expCtx,
boost::intrusive_ptr<Expression> thisRef,
std::string funcSourceString);
diff --git a/src/mongo/db/pipeline/expression_nary_test.cpp b/src/mongo/db/pipeline/expression_nary_test.cpp
index 6fa2e6ec07e..3b709c4c7ae 100644
--- a/src/mongo/db/pipeline/expression_nary_test.cpp
+++ b/src/mongo/db/pipeline/expression_nary_test.cpp
@@ -78,16 +78,15 @@ public:
return visitor->visit(this);
}
- static intrusive_ptr<Testable> create(bool associative, bool commutative) {
- return new Testable(associative, commutative);
+ static intrusive_ptr<Testable> create(ExpressionContext* const expCtx,
+ bool associative,
+ bool commutative) {
+ return new Testable(expCtx, associative, commutative);
}
private:
- Testable(bool isAssociative, bool isCommutative)
- : ExpressionNary(
- boost::intrusive_ptr<ExpressionContextForTest>(new ExpressionContextForTest())),
- _isAssociative(isAssociative),
- _isCommutative(isCommutative) {}
+ Testable(ExpressionContext* const expCtx, bool isAssociative, bool isCommutative)
+ : ExpressionNary(expCtx), _isAssociative(isAssociative), _isCommutative(isCommutative) {}
bool _isAssociative;
bool _isCommutative;
};
@@ -123,9 +122,11 @@ static BSONObj expressionToBson(const intrusive_ptr<Expression>& expression) {
class ExpressionBaseTest : public unittest::Test {
public:
void addOperand(intrusive_ptr<ExpressionNary> expr, Value arg) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- expr->addOperand(ExpressionConstant::create(expCtx, arg));
+ expr->addOperand(ExpressionConstant::create(&expCtx, arg));
}
+
+protected:
+ ExpressionContextForTest expCtx;
};
class ExpressionNaryTestOneArg : public ExpressionBaseTest {
@@ -161,9 +162,9 @@ public:
class ExpressionNaryTest : public unittest::Test {
public:
virtual void setUp() override {
- _notAssociativeNorCommutative = Testable::create(false, false);
- _associativeOnly = Testable::create(true, false);
- _associativeAndCommutative = Testable::create(true, true);
+ _notAssociativeNorCommutative = Testable::create(&expCtx, false, false);
+ _associativeOnly = Testable::create(&expCtx, true, false);
+ _associativeAndCommutative = Testable::create(&expCtx, true, true);
}
protected:
@@ -187,29 +188,27 @@ protected:
}
void addOperandArrayToExpr(const intrusive_ptr<Testable>& expr, const BSONArray& operands) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
+ VariablesParseState vps = expCtx.variablesParseState;
BSONObjIterator i(operands);
while (i.more()) {
BSONElement element = i.next();
- expr->addOperand(Expression::parseOperand(expCtx, element, vps));
+ expr->addOperand(Expression::parseOperand(&expCtx, element, vps));
}
}
+ ExpressionContextForTest expCtx;
intrusive_ptr<Testable> _notAssociativeNorCommutative;
intrusive_ptr<Testable> _associativeOnly;
intrusive_ptr<Testable> _associativeAndCommutative;
};
TEST_F(ExpressionNaryTest, AddedConstantOperandIsSerialized) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- _notAssociativeNorCommutative->addOperand(ExpressionConstant::create(expCtx, Value(9)));
+ _notAssociativeNorCommutative->addOperand(ExpressionConstant::create(&expCtx, Value(9)));
assertContents(_notAssociativeNorCommutative, BSON_ARRAY(9));
}
TEST_F(ExpressionNaryTest, AddedFieldPathOperandIsSerialized) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- _notAssociativeNorCommutative->addOperand(ExpressionFieldPath::create(expCtx, "ab.c"));
+ _notAssociativeNorCommutative->addOperand(ExpressionFieldPath::create(&expCtx, "ab.c"));
assertContents(_notAssociativeNorCommutative, BSON_ARRAY("$ab.c"));
}
@@ -218,14 +217,12 @@ TEST_F(ExpressionNaryTest, ValidateEmptyDependencies) {
}
TEST_F(ExpressionNaryTest, ValidateConstantExpressionDependency) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- _notAssociativeNorCommutative->addOperand(ExpressionConstant::create(expCtx, Value(1)));
+ _notAssociativeNorCommutative->addOperand(ExpressionConstant::create(&expCtx, Value(1)));
assertDependencies(_notAssociativeNorCommutative, BSONArray());
}
TEST_F(ExpressionNaryTest, ValidateFieldPathExpressionDependency) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- _notAssociativeNorCommutative->addOperand(ExpressionFieldPath::create(expCtx, "ab.c"));
+ _notAssociativeNorCommutative->addOperand(ExpressionFieldPath::create(&expCtx, "ab.c"));
assertDependencies(_notAssociativeNorCommutative, BSON_ARRAY("ab.c"));
}
@@ -234,26 +231,23 @@ TEST_F(ExpressionNaryTest, ValidateObjectExpressionDependency) {
<< "$x"
<< "q"
<< "$r"));
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
BSONElement specElement = spec.firstElement();
- VariablesParseState vps = expCtx->variablesParseState;
+ VariablesParseState vps = expCtx.variablesParseState;
_notAssociativeNorCommutative->addOperand(
- Expression::parseObject(expCtx, specElement.Obj(), vps));
+ Expression::parseObject(&expCtx, specElement.Obj(), vps));
assertDependencies(_notAssociativeNorCommutative,
BSON_ARRAY("r"
<< "x"));
}
TEST_F(ExpressionNaryTest, SerializationToBsonObj) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- _notAssociativeNorCommutative->addOperand(ExpressionConstant::create(expCtx, Value(5)));
+ _notAssociativeNorCommutative->addOperand(ExpressionConstant::create(&expCtx, Value(5)));
ASSERT_BSONOBJ_EQ(BSON("foo" << BSON("$testable" << BSON_ARRAY(BSON("$const" << 5)))),
BSON("foo" << _notAssociativeNorCommutative->serialize(false)));
}
TEST_F(ExpressionNaryTest, SerializationToBsonArr) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- _notAssociativeNorCommutative->addOperand(ExpressionConstant::create(expCtx, Value(5)));
+ _notAssociativeNorCommutative->addOperand(ExpressionConstant::create(&expCtx, Value(5)));
ASSERT_BSONOBJ_EQ(constify(BSON_ARRAY(BSON("$testable" << BSON_ARRAY(5)))),
BSON_ARRAY(_notAssociativeNorCommutative->serialize(false)));
}
@@ -366,7 +360,7 @@ TEST_F(ExpressionNaryTest, FlattenOptimizationNotDoneOnOtherExpressionsForAssoci
TEST_F(ExpressionNaryTest, FlattenOptimizationNotDoneOnSameButNotAssociativeExpression) {
BSONArrayBuilder specBuilder;
- intrusive_ptr<Testable> innerOperand = Testable::create(false, false);
+ intrusive_ptr<Testable> innerOperand = Testable::create(&expCtx, false, false);
addOperandArrayToExpr(innerOperand, BSON_ARRAY(100 << "$path1" << 101));
specBuilder.append(expressionToBson(innerOperand));
_associativeOnly->addOperand(innerOperand);
@@ -389,7 +383,7 @@ TEST_F(ExpressionNaryTest, FlattenOptimizationNotDoneOnSameButNotAssociativeExpr
TEST_F(ExpressionNaryTest, FlattenInnerOperandsOptimizationOnNotCommutativeNorAssociative) {
BSONArrayBuilder specBuilder;
- intrusive_ptr<Testable> innerOperand = Testable::create(false, false);
+ intrusive_ptr<Testable> innerOperand = Testable::create(&expCtx, false, false);
addOperandArrayToExpr(innerOperand, BSON_ARRAY(100 << "$path1"));
specBuilder.append(expressionToBson(innerOperand));
_notAssociativeNorCommutative->addOperand(innerOperand);
@@ -413,7 +407,7 @@ TEST_F(ExpressionNaryTest, FlattenInnerOperandsOptimizationOnNotCommutativeNorAs
TEST_F(ExpressionNaryTest, FlattenInnerOperandsOptimizationOnAssociativeOnlyFrontOperandNoGroup) {
BSONArrayBuilder specBuilder;
- intrusive_ptr<Testable> innerOperand = Testable::create(true, false);
+ intrusive_ptr<Testable> innerOperand = Testable::create(&expCtx, true, false);
addOperandArrayToExpr(innerOperand, BSON_ARRAY(100 << "$path1"));
specBuilder.append(expressionToBson(innerOperand));
_associativeOnly->addOperand(innerOperand);
@@ -438,7 +432,7 @@ TEST_F(ExpressionNaryTest, FlattenInnerOperandsOptimizationOnAssociativeOnlyFron
TEST_F(ExpressionNaryTest, FlattenInnerOperandsOptimizationOnAssociativeOnlyFrontOperandAndGroup) {
BSONArrayBuilder specBuilder;
- intrusive_ptr<Testable> innerOperand = Testable::create(true, false);
+ intrusive_ptr<Testable> innerOperand = Testable::create(&expCtx, true, false);
addOperandArrayToExpr(innerOperand, BSON_ARRAY(100 << "$path1" << 101));
specBuilder.append(expressionToBson(innerOperand));
_associativeOnly->addOperand(innerOperand);
@@ -466,7 +460,7 @@ TEST_F(ExpressionNaryTest, FlattenInnerOperandsOptimizationOnAssociativeOnlyMidd
addOperandArrayToExpr(_associativeOnly, BSON_ARRAY(200 << "$path3"));
specBuilder << 200 << "$path3";
- intrusive_ptr<Testable> innerOperand = Testable::create(true, false);
+ intrusive_ptr<Testable> innerOperand = Testable::create(&expCtx, true, false);
addOperandArrayToExpr(innerOperand, BSON_ARRAY(100 << "$path1"));
specBuilder.append(expressionToBson(innerOperand));
_associativeOnly->addOperand(innerOperand);
@@ -494,7 +488,7 @@ TEST_F(ExpressionNaryTest, FlattenInnerOperandsOptimizationOnAssociativeOnlyMidd
addOperandArrayToExpr(_associativeOnly, BSON_ARRAY(200 << "$path3" << 201));
specBuilder << 200 << "$path3" << 201;
- intrusive_ptr<Testable> innerOperand = Testable::create(true, false);
+ intrusive_ptr<Testable> innerOperand = Testable::create(&expCtx, true, false);
addOperandArrayToExpr(innerOperand, BSON_ARRAY(100 << "$path1" << 101));
specBuilder.append(expressionToBson(innerOperand));
_associativeOnly->addOperand(innerOperand);
@@ -523,7 +517,7 @@ TEST_F(ExpressionNaryTest, FlattenInnerOperandsOptimizationOnAssociativeOnlyBack
addOperandArrayToExpr(_associativeOnly, BSON_ARRAY(200 << "$path3"));
specBuilder << 200 << "$path3";
- intrusive_ptr<Testable> innerOperand = Testable::create(true, false);
+ intrusive_ptr<Testable> innerOperand = Testable::create(&expCtx, true, false);
addOperandArrayToExpr(innerOperand, BSON_ARRAY(100 << "$path1"));
specBuilder.append(expressionToBson(innerOperand));
_associativeOnly->addOperand(innerOperand);
@@ -548,7 +542,7 @@ TEST_F(ExpressionNaryTest, FlattenInnerOperandsOptimizationOnAssociativeOnlyBack
addOperandArrayToExpr(_associativeOnly, BSON_ARRAY(200 << "$path3" << 201));
specBuilder << 200 << "$path3" << 201;
- intrusive_ptr<Testable> innerOperand = Testable::create(true, false);
+ intrusive_ptr<Testable> innerOperand = Testable::create(&expCtx, true, false);
addOperandArrayToExpr(innerOperand, BSON_ARRAY(100 << "$path1" << 101));
specBuilder.append(expressionToBson(innerOperand));
_associativeOnly->addOperand(innerOperand);
@@ -571,12 +565,12 @@ TEST_F(ExpressionNaryTest, FlattenInnerOperandsOptimizationOnAssociativeOnlyBack
TEST_F(ExpressionNaryTest, FlattenConsecutiveInnerOperandsOptimizationOnAssociativeOnlyNoGroup) {
BSONArrayBuilder specBuilder;
- intrusive_ptr<Testable> innerOperand = Testable::create(true, false);
+ intrusive_ptr<Testable> innerOperand = Testable::create(&expCtx, true, false);
addOperandArrayToExpr(innerOperand, BSON_ARRAY(100 << "$path1"));
specBuilder.append(expressionToBson(innerOperand));
_associativeOnly->addOperand(innerOperand);
- intrusive_ptr<Testable> innerOperand2 = Testable::create(true, false);
+ intrusive_ptr<Testable> innerOperand2 = Testable::create(&expCtx, true, false);
addOperandArrayToExpr(innerOperand2, BSON_ARRAY(200 << "$path2"));
specBuilder.append(expressionToBson(innerOperand2));
_associativeOnly->addOperand(innerOperand2);
@@ -598,12 +592,12 @@ TEST_F(ExpressionNaryTest, FlattenConsecutiveInnerOperandsOptimizationOnAssociat
TEST_F(ExpressionNaryTest, FlattenConsecutiveInnerOperandsOptimizationOnAssociativeAndGroup) {
BSONArrayBuilder specBuilder;
- intrusive_ptr<Testable> innerOperand = Testable::create(true, false);
+ intrusive_ptr<Testable> innerOperand = Testable::create(&expCtx, true, false);
addOperandArrayToExpr(innerOperand, BSON_ARRAY(100 << "$path1" << 101));
specBuilder.append(expressionToBson(innerOperand));
_associativeOnly->addOperand(innerOperand);
- intrusive_ptr<Testable> innerOperand2 = Testable::create(true, false);
+ intrusive_ptr<Testable> innerOperand2 = Testable::create(&expCtx, true, false);
addOperandArrayToExpr(innerOperand2, BSON_ARRAY(200 << "$path2"));
specBuilder.append(expressionToBson(innerOperand2));
_associativeOnly->addOperand(innerOperand2);
@@ -627,7 +621,7 @@ TEST_F(ExpressionNaryTest, FlattenInnerOperandsOptimizationOnCommutativeAndAssoc
addOperandArrayToExpr(_associativeAndCommutative, BSON_ARRAY(200 << "$path3" << 201));
specBuilder << 200 << "$path3" << 201;
- intrusive_ptr<Testable> innerOperand = Testable::create(true, true);
+ intrusive_ptr<Testable> innerOperand = Testable::create(&expCtx, true, true);
addOperandArrayToExpr(innerOperand, BSON_ARRAY(100 << "$path1" << 101));
specBuilder.append(expressionToBson(innerOperand));
_associativeAndCommutative->addOperand(innerOperand);
@@ -653,8 +647,7 @@ TEST_F(ExpressionNaryTest, FlattenInnerOperandsOptimizationOnCommutativeAndAssoc
class ExpressionTruncOneArgTest : public ExpressionNaryTestOneArg {
public:
void assertEval(ImplicitValue input, ImplicitValue output) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- _expr = new ExpressionTrunc(expCtx);
+ _expr = new ExpressionTrunc(&expCtx);
ExpressionNaryTestOneArg::assertEvaluates(input, output);
}
};
@@ -662,8 +655,7 @@ public:
class ExpressionTruncTwoArgTest : public ExpressionNaryTestTwoArg {
public:
void assertEval(ImplicitValue input1, ImplicitValue input2, ImplicitValue output) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- _expr = new ExpressionTrunc(expCtx);
+ _expr = new ExpressionTrunc(&expCtx);
ExpressionNaryTestTwoArg::assertEvaluates(input1, input2, output);
}
};
@@ -820,8 +812,7 @@ TEST_F(ExpressionTruncTwoArgTest, NullArg2) {
class ExpressionSqrtTest : public ExpressionNaryTestOneArg {
public:
virtual void assertEvaluates(Value input, Value output) override {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- _expr = new ExpressionSqrt(expCtx);
+ _expr = new ExpressionSqrt(&expCtx);
ExpressionNaryTestOneArg::assertEvaluates(input, output);
}
};
@@ -866,8 +857,7 @@ TEST_F(ExpressionSqrtTest, SqrtNaNArg) {
class ExpressionExpTest : public ExpressionNaryTestOneArg {
public:
virtual void assertEvaluates(Value input, Value output) override {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- _expr = new ExpressionExp(expCtx);
+ _expr = new ExpressionExp(&expCtx);
ExpressionNaryTestOneArg::assertEvaluates(input, output);
}
@@ -908,8 +898,7 @@ TEST_F(ExpressionExpTest, ExpNaNArg) {
class ExpressionCeilTest : public ExpressionNaryTestOneArg {
public:
virtual void assertEvaluates(Value input, Value output) override {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- _expr = new ExpressionCeil(expCtx);
+ _expr = new ExpressionCeil(&expCtx);
ExpressionNaryTestOneArg::assertEvaluates(input, output);
}
};
@@ -967,8 +956,7 @@ TEST_F(ExpressionCeilTest, NullArg) {
class ExpressionFloorTest : public ExpressionNaryTestOneArg {
public:
virtual void assertEvaluates(Value input, Value output) override {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- _expr = new ExpressionFloor(expCtx);
+ _expr = new ExpressionFloor(&expCtx);
ExpressionNaryTestOneArg::assertEvaluates(input, output);
}
};
@@ -1026,8 +1014,7 @@ TEST_F(ExpressionFloorTest, NullArg) {
class ExpressionRoundOneArgTest : public ExpressionNaryTestOneArg {
public:
void assertEval(ImplicitValue input, ImplicitValue output) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- _expr = new ExpressionRound(expCtx);
+ _expr = new ExpressionRound(&expCtx);
ExpressionNaryTestOneArg::assertEvaluates(input, output);
}
};
@@ -1035,8 +1022,7 @@ public:
class ExpressionRoundTwoArgTest : public ExpressionNaryTestTwoArg {
public:
void assertEval(ImplicitValue input1, ImplicitValue input2, ImplicitValue output) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- _expr = new ExpressionRound(expCtx);
+ _expr = new ExpressionRound(&expCtx);
ExpressionNaryTestTwoArg::assertEvaluates(input1, input2, output);
}
};
@@ -1196,8 +1182,7 @@ TEST_F(ExpressionRoundTwoArgTest, NullArg2) {
class ExpressionBinarySizeTest : public ExpressionNaryTestOneArg {
public:
void assertEval(ImplicitValue input, ImplicitValue output) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- _expr = new ExpressionBinarySize(expCtx);
+ _expr = new ExpressionBinarySize(&expCtx);
ExpressionNaryTestOneArg::assertEvaluates(input, output);
}
};
@@ -1227,13 +1212,11 @@ TEST_F(ExpressionBinarySizeTest, HandlesNullish) {
class ExpressionFirstTest : public ExpressionNaryTestOneArg {
public:
void assertEval(ImplicitValue input, ImplicitValue output) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- _expr = new ExpressionFirst(expCtx);
+ _expr = new ExpressionFirst(&expCtx);
ExpressionNaryTestOneArg::assertEvaluates(input, output);
}
void assertEvalFails(ImplicitValue input) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- _expr = new ExpressionFirst(expCtx);
+ _expr = new ExpressionFirst(&expCtx);
ASSERT_THROWS_CODE(eval(input), DBException, 28689);
}
};
@@ -1264,13 +1247,11 @@ TEST_F(ExpressionFirstTest, RejectsNonArrays) {
class ExpressionLastTest : public ExpressionNaryTestOneArg {
public:
void assertEval(ImplicitValue input, ImplicitValue output) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- _expr = new ExpressionLast(expCtx);
+ _expr = new ExpressionLast(&expCtx);
ExpressionNaryTestOneArg::assertEvaluates(input, output);
}
void assertEvalFails(ImplicitValue input) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- _expr = new ExpressionLast(expCtx);
+ _expr = new ExpressionLast(&expCtx);
ASSERT_THROWS_CODE(eval(input), DBException, 28689);
}
};
diff --git a/src/mongo/db/pipeline/expression_object_test.cpp b/src/mongo/db/pipeline/expression_object_test.cpp
index c0e7e6b2798..5b339bf911b 100644
--- a/src/mongo/db/pipeline/expression_object_test.cpp
+++ b/src/mongo/db/pipeline/expression_object_test.cpp
@@ -56,27 +56,21 @@ Document literal(T&& value) {
return Document{{"$const", Value(std::forward<T>(value))}};
}
-template <typename T>
-intrusive_ptr<ExpressionConstant> makeConstant(T&& val) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- return ExpressionConstant::create(expCtx, Value(std::forward<T>(val)));
-}
-
//
// Parsing.
//
TEST(ExpressionObjectParse, ShouldAcceptEmptyObject) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
- auto object = ExpressionObject::parse(expCtx, BSONObj(), vps);
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
+ auto object = ExpressionObject::parse(&expCtx, BSONObj(), vps);
ASSERT_VALUE_EQ(Value(Document{}), object->serialize(false));
}
TEST(ExpressionObjectParse, ShouldAcceptLiteralsAsValues) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
- auto object = ExpressionObject::parse(expCtx,
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
+ auto object = ExpressionObject::parse(&expCtx,
BSON("a" << 5 << "b"
<< "string"
<< "c" << BSONNULL),
@@ -87,26 +81,26 @@ TEST(ExpressionObjectParse, ShouldAcceptLiteralsAsValues) {
}
TEST(ExpressionObjectParse, ShouldAccept_idAsFieldName) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
- auto object = ExpressionObject::parse(expCtx, BSON("_id" << 5), vps);
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
+ auto object = ExpressionObject::parse(&expCtx, BSON("_id" << 5), vps);
auto expectedResult = Value(Document{{"_id", literal(5)}});
ASSERT_VALUE_EQ(expectedResult, object->serialize(false));
}
TEST(ExpressionObjectParse, ShouldAcceptFieldNameContainingDollar) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
- auto object = ExpressionObject::parse(expCtx, BSON("a$b" << 5), vps);
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
+ auto object = ExpressionObject::parse(&expCtx, BSON("a$b" << 5), vps);
auto expectedResult = Value(Document{{"a$b", literal(5)}});
ASSERT_VALUE_EQ(expectedResult, object->serialize(false));
}
TEST(ExpressionObjectParse, ShouldAcceptNestedObjects) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
auto object =
- ExpressionObject::parse(expCtx, fromjson("{a: {b: 1}, c: {d: {e: 1, f: 1}}}"), vps);
+ ExpressionObject::parse(&expCtx, fromjson("{a: {b: 1}, c: {d: {e: 1, f: 1}}}"), vps);
auto expectedResult =
Value(Document{{"a", Document{{"b", literal(1)}}},
{"c", Document{{"d", Document{{"e", literal(1)}, {"f", literal(1)}}}}}});
@@ -114,18 +108,18 @@ TEST(ExpressionObjectParse, ShouldAcceptNestedObjects) {
}
TEST(ExpressionObjectParse, ShouldAcceptArrays) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
- auto object = ExpressionObject::parse(expCtx, fromjson("{a: [1, 2]}"), vps);
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
+ auto object = ExpressionObject::parse(&expCtx, fromjson("{a: [1, 2]}"), vps);
auto expectedResult =
Value(Document{{"a", vector<Value>{Value(literal(1)), Value(literal(2))}}});
ASSERT_VALUE_EQ(expectedResult, object->serialize(false));
}
TEST(ObjectParsing, ShouldAcceptExpressionAsValue) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
- auto object = ExpressionObject::parse(expCtx, BSON("a" << BSON("$and" << BSONArray())), vps);
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
+ auto object = ExpressionObject::parse(&expCtx, BSON("a" << BSON("$and" << BSONArray())), vps);
ASSERT_VALUE_EQ(object->serialize(false),
Value(Document{{"a", Document{{"$and", BSONArray()}}}}));
}
@@ -135,43 +129,43 @@ TEST(ObjectParsing, ShouldAcceptExpressionAsValue) {
//
TEST(ExpressionObjectParse, ShouldRejectDottedFieldNames) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
- ASSERT_THROWS(ExpressionObject::parse(expCtx, BSON("a.b" << 1), vps), AssertionException);
- ASSERT_THROWS(ExpressionObject::parse(expCtx, BSON("c" << 3 << "a.b" << 1), vps),
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
+ ASSERT_THROWS(ExpressionObject::parse(&expCtx, BSON("a.b" << 1), vps), AssertionException);
+ ASSERT_THROWS(ExpressionObject::parse(&expCtx, BSON("c" << 3 << "a.b" << 1), vps),
AssertionException);
- ASSERT_THROWS(ExpressionObject::parse(expCtx, BSON("a.b" << 1 << "c" << 3), vps),
+ ASSERT_THROWS(ExpressionObject::parse(&expCtx, BSON("a.b" << 1 << "c" << 3), vps),
AssertionException);
}
TEST(ExpressionObjectParse, ShouldRejectDuplicateFieldNames) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
- ASSERT_THROWS(ExpressionObject::parse(expCtx, BSON("a" << 1 << "a" << 1), vps),
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
+ ASSERT_THROWS(ExpressionObject::parse(&expCtx, BSON("a" << 1 << "a" << 1), vps),
AssertionException);
- ASSERT_THROWS(ExpressionObject::parse(expCtx, BSON("a" << 1 << "b" << 2 << "a" << 1), vps),
+ ASSERT_THROWS(ExpressionObject::parse(&expCtx, BSON("a" << 1 << "b" << 2 << "a" << 1), vps),
AssertionException);
ASSERT_THROWS(
- ExpressionObject::parse(expCtx, BSON("a" << BSON("c" << 1) << "b" << 2 << "a" << 1), vps),
+ ExpressionObject::parse(&expCtx, BSON("a" << BSON("c" << 1) << "b" << 2 << "a" << 1), vps),
AssertionException);
ASSERT_THROWS(
- ExpressionObject::parse(expCtx, BSON("a" << 1 << "b" << 2 << "a" << BSON("c" << 1)), vps),
+ ExpressionObject::parse(&expCtx, BSON("a" << 1 << "b" << 2 << "a" << BSON("c" << 1)), vps),
AssertionException);
}
TEST(ExpressionObjectParse, ShouldRejectInvalidFieldName) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
- ASSERT_THROWS(ExpressionObject::parse(expCtx, BSON("$a" << 1), vps), AssertionException);
- ASSERT_THROWS(ExpressionObject::parse(expCtx, BSON("" << 1), vps), AssertionException);
- ASSERT_THROWS(ExpressionObject::parse(expCtx, BSON(std::string("a\0b", 3) << 1), vps),
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
+ ASSERT_THROWS(ExpressionObject::parse(&expCtx, BSON("$a" << 1), vps), AssertionException);
+ ASSERT_THROWS(ExpressionObject::parse(&expCtx, BSON("" << 1), vps), AssertionException);
+ ASSERT_THROWS(ExpressionObject::parse(&expCtx, BSON(std::string("a\0b", 3) << 1), vps),
AssertionException);
}
TEST(ExpressionObjectParse, ShouldRejectInvalidFieldPathAsValue) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
- ASSERT_THROWS(ExpressionObject::parse(expCtx,
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
+ ASSERT_THROWS(ExpressionObject::parse(&expCtx,
BSON("a"
<< "$field."),
vps),
@@ -179,11 +173,11 @@ TEST(ExpressionObjectParse, ShouldRejectInvalidFieldPathAsValue) {
}
TEST(ParseObject, ShouldRejectExpressionAsTheSecondField) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
ASSERT_THROWS(
ExpressionObject::parse(
- expCtx, BSON("a" << BSON("$and" << BSONArray()) << "$or" << BSONArray()), vps),
+ &expCtx, BSON("a" << BSON("$and" << BSONArray()) << "$or" << BSONArray()), vps),
AssertionException);
}
@@ -192,70 +186,74 @@ TEST(ParseObject, ShouldRejectExpressionAsTheSecondField) {
//
TEST(ExpressionObjectEvaluate, EmptyObjectShouldEvaluateToEmptyDocument) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto object = ExpressionObject::create(expCtx, {});
- ASSERT_VALUE_EQ(Value(Document()), object->evaluate(Document(), &(expCtx->variables)));
- ASSERT_VALUE_EQ(Value(Document()), object->evaluate(Document{{"a", 1}}, &(expCtx->variables)));
+ auto expCtx = ExpressionContextForTest{};
+ auto object = ExpressionObject::create(&expCtx, {});
+ ASSERT_VALUE_EQ(Value(Document()), object->evaluate(Document(), &(expCtx.variables)));
+ ASSERT_VALUE_EQ(Value(Document()), object->evaluate(Document{{"a", 1}}, &(expCtx.variables)));
ASSERT_VALUE_EQ(Value(Document()),
- object->evaluate(Document{{"_id", "ID"_sd}}, &(expCtx->variables)));
+ object->evaluate(Document{{"_id", "ID"_sd}}, &(expCtx.variables)));
}
TEST(ExpressionObjectEvaluate, ShouldEvaluateEachField) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto object =
- ExpressionObject::create(expCtx, {{"a", makeConstant(1)}, {"b", makeConstant(5)}});
+ auto expCtx = ExpressionContextForTest{};
+ auto object = ExpressionObject::create(&expCtx,
+ {{"a", ExpressionConstant::create(&expCtx, Value{1})},
+ {"b", ExpressionConstant::create(&expCtx, Value{5})}});
+
+
ASSERT_VALUE_EQ(Value(Document{{"a", 1}, {"b", 5}}),
- object->evaluate(Document(), &(expCtx->variables)));
+ object->evaluate(Document(), &(expCtx.variables)));
ASSERT_VALUE_EQ(Value(Document{{"a", 1}, {"b", 5}}),
- object->evaluate(Document{{"a", 1}}, &(expCtx->variables)));
+ object->evaluate(Document{{"a", 1}}, &(expCtx.variables)));
ASSERT_VALUE_EQ(Value(Document{{"a", 1}, {"b", 5}}),
- object->evaluate(Document{{"_id", "ID"_sd}}, &(expCtx->variables)));
+ object->evaluate(Document{{"_id", "ID"_sd}}, &(expCtx.variables)));
}
TEST(ExpressionObjectEvaluate, OrderOfFieldsInOutputShouldMatchOrderInSpecification) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto object = ExpressionObject::create(expCtx,
- {{"a", ExpressionFieldPath::create(expCtx, "a")},
- {"b", ExpressionFieldPath::create(expCtx, "b")},
- {"c", ExpressionFieldPath::create(expCtx, "c")}});
+ auto expCtx = ExpressionContextForTest{};
+ auto object = ExpressionObject::create(&expCtx,
+ {{"a", ExpressionFieldPath::create(&expCtx, "a")},
+ {"b", ExpressionFieldPath::create(&expCtx, "b")},
+ {"c", ExpressionFieldPath::create(&expCtx, "c")}});
ASSERT_VALUE_EQ(
Value(Document{{"a", "A"_sd}, {"b", "B"_sd}, {"c", "C"_sd}}),
object->evaluate(Document{{"c", "C"_sd}, {"a", "A"_sd}, {"b", "B"_sd}, {"_id", "ID"_sd}},
- &(expCtx->variables)));
+ &(expCtx.variables)));
}
TEST(ExpressionObjectEvaluate, ShouldRemoveFieldsThatHaveMissingValues) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto object = ExpressionObject::create(expCtx,
- {{"a", ExpressionFieldPath::create(expCtx, "a.b")},
- {"b", ExpressionFieldPath::create(expCtx, "missing")}});
- ASSERT_VALUE_EQ(Value(Document{}), object->evaluate(Document(), &(expCtx->variables)));
- ASSERT_VALUE_EQ(Value(Document{}), object->evaluate(Document{{"a", 1}}, &(expCtx->variables)));
+ auto expCtx = ExpressionContextForTest{};
+ auto object =
+ ExpressionObject::create(&expCtx,
+ {{"a", ExpressionFieldPath::create(&expCtx, "a.b")},
+ {"b", ExpressionFieldPath::create(&expCtx, "missing")}});
+ ASSERT_VALUE_EQ(Value(Document{}), object->evaluate(Document(), &(expCtx.variables)));
+ ASSERT_VALUE_EQ(Value(Document{}), object->evaluate(Document{{"a", 1}}, &(expCtx.variables)));
}
TEST(ExpressionObjectEvaluate, ShouldEvaluateFieldsWithinNestedObject) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto object = ExpressionObject::create(
- expCtx,
+ &expCtx,
{{"a",
- ExpressionObject::create(
- expCtx,
- {{"b", makeConstant(1)}, {"c", ExpressionFieldPath::create(expCtx, "_id")}})}});
+ ExpressionObject::create(&expCtx,
+ {{"b", ExpressionConstant::create(&expCtx, Value{1})},
+ {"c", ExpressionFieldPath::create(&expCtx, "_id")}})}});
ASSERT_VALUE_EQ(Value(Document{{"a", Document{{"b", 1}}}}),
- object->evaluate(Document(), &(expCtx->variables)));
+ object->evaluate(Document(), &(expCtx.variables)));
ASSERT_VALUE_EQ(Value(Document{{"a", Document{{"b", 1}, {"c", "ID"_sd}}}}),
- object->evaluate(Document{{"_id", "ID"_sd}}, &(expCtx->variables)));
+ object->evaluate(Document{{"_id", "ID"_sd}}, &(expCtx.variables)));
}
TEST(ExpressionObjectEvaluate, ShouldEvaluateToEmptyDocumentIfAllFieldsAreMissing) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto object =
- ExpressionObject::create(expCtx, {{"a", ExpressionFieldPath::create(expCtx, "missing")}});
- ASSERT_VALUE_EQ(Value(Document{}), object->evaluate(Document(), &(expCtx->variables)));
+ ExpressionObject::create(&expCtx, {{"a", ExpressionFieldPath::create(&expCtx, "missing")}});
+ ASSERT_VALUE_EQ(Value(Document{}), object->evaluate(Document(), &(expCtx.variables)));
- auto objectWithNestedObject = ExpressionObject::create(expCtx, {{"nested", object}});
+ auto objectWithNestedObject = ExpressionObject::create(&expCtx, {{"nested", object}});
ASSERT_VALUE_EQ(Value(Document{{"nested", Document{}}}),
- objectWithNestedObject->evaluate(Document(), &(expCtx->variables)));
+ objectWithNestedObject->evaluate(Document(), &(expCtx.variables)));
}
//
@@ -263,17 +261,18 @@ TEST(ExpressionObjectEvaluate, ShouldEvaluateToEmptyDocumentIfAllFieldsAreMissin
//
TEST(ExpressionObjectDependencies, ConstantValuesShouldNotBeAddedToDependencies) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto object = ExpressionObject::create(expCtx, {{"a", makeConstant(5)}});
+ auto expCtx = ExpressionContextForTest{};
+ auto object =
+ ExpressionObject::create(&expCtx, {{"a", ExpressionConstant::create(&expCtx, Value{5})}});
DepsTracker deps;
object->addDependencies(&deps);
ASSERT_EQ(deps.fields.size(), 0UL);
}
TEST(ExpressionObjectDependencies, FieldPathsShouldBeAddedToDependencies) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto object =
- ExpressionObject::create(expCtx, {{"x", ExpressionFieldPath::create(expCtx, "c.d")}});
+ ExpressionObject::create(&expCtx, {{"x", ExpressionFieldPath::create(&expCtx, "c.d")}});
DepsTracker deps;
object->addDependencies(&deps);
ASSERT_EQ(deps.fields.size(), 1UL);
@@ -281,9 +280,9 @@ TEST(ExpressionObjectDependencies, FieldPathsShouldBeAddedToDependencies) {
};
TEST(ExpressionObjectDependencies, VariablesShouldBeAddedToDependencies) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto varID = expCtx->variablesParseState.defineVariable("var1");
- auto fieldPath = ExpressionFieldPath::parse(expCtx, "$$var1", expCtx->variablesParseState);
+ auto expCtx = ExpressionContextForTest{};
+ auto varID = expCtx.variablesParseState.defineVariable("var1");
+ auto fieldPath = ExpressionFieldPath::parse(&expCtx, "$$var1", expCtx.variablesParseState);
DepsTracker deps;
fieldPath->addDependencies(&deps);
ASSERT_EQ(deps.vars.size(), 1UL);
@@ -291,24 +290,24 @@ TEST(ExpressionObjectDependencies, VariablesShouldBeAddedToDependencies) {
}
TEST(ExpressionObjectDependencies, LocalLetVariablesShouldBeFilteredOutOfDependencies) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- expCtx->variablesParseState.defineVariable("var1");
+ auto expCtx = ExpressionContextForTest{};
+ expCtx.variablesParseState.defineVariable("var1");
auto letSpec = BSON("$let" << BSON("vars" << BSON("var2"
<< "abc")
<< "in"
<< BSON("$multiply" << BSON_ARRAY("$$var1"
<< "$$var2"))));
auto expressionLet =
- ExpressionLet::parse(expCtx, letSpec.firstElement(), expCtx->variablesParseState);
+ ExpressionLet::parse(&expCtx, letSpec.firstElement(), expCtx.variablesParseState);
DepsTracker deps;
expressionLet->addDependencies(&deps);
ASSERT_EQ(deps.vars.size(), 1UL);
- ASSERT_EQ(expCtx->variablesParseState.getVariable("var1"), *deps.vars.begin());
+ ASSERT_EQ(expCtx.variablesParseState.getVariable("var1"), *deps.vars.begin());
}
TEST(ExpressionObjectDependencies, LocalMapVariablesShouldBeFilteredOutOfDependencies) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- expCtx->variablesParseState.defineVariable("var1");
+ auto expCtx = ExpressionContextForTest{};
+ expCtx.variablesParseState.defineVariable("var1");
auto mapSpec = BSON("$map" << BSON("input"
<< "$field1"
<< "as"
@@ -318,16 +317,16 @@ TEST(ExpressionObjectDependencies, LocalMapVariablesShouldBeFilteredOutOfDepende
<< "$$var2"))));
auto expressionMap =
- ExpressionMap::parse(expCtx, mapSpec.firstElement(), expCtx->variablesParseState);
+ ExpressionMap::parse(&expCtx, mapSpec.firstElement(), expCtx.variablesParseState);
DepsTracker deps;
expressionMap->addDependencies(&deps);
ASSERT_EQ(deps.vars.size(), 1UL);
- ASSERT_EQ(expCtx->variablesParseState.getVariable("var1"), *deps.vars.begin());
+ ASSERT_EQ(expCtx.variablesParseState.getVariable("var1"), *deps.vars.begin());
}
TEST(ExpressionObjectDependencies, LocalFilterVariablesShouldBeFilteredOutOfDependencies) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- expCtx->variablesParseState.defineVariable("var1");
+ auto expCtx = ExpressionContextForTest{};
+ expCtx.variablesParseState.defineVariable("var1");
auto filterSpec = BSON("$filter" << BSON("input" << BSON_ARRAY(1 << 2 << 3) << "as"
<< "var2"
<< "cond"
@@ -335,11 +334,11 @@ TEST(ExpressionObjectDependencies, LocalFilterVariablesShouldBeFilteredOutOfDepe
<< "$$var2"))));
auto expressionFilter =
- ExpressionFilter::parse(expCtx, filterSpec.firstElement(), expCtx->variablesParseState);
+ ExpressionFilter::parse(&expCtx, filterSpec.firstElement(), expCtx.variablesParseState);
DepsTracker deps;
expressionFilter->addDependencies(&deps);
ASSERT_EQ(deps.vars.size(), 1UL);
- ASSERT_EQ(expCtx->variablesParseState.getVariable("var1"), *deps.vars.begin());
+ ASSERT_EQ(expCtx.variablesParseState.getVariable("var1"), *deps.vars.begin());
}
//
@@ -348,34 +347,34 @@ TEST(ExpressionObjectDependencies, LocalFilterVariablesShouldBeFilteredOutOfDepe
TEST(ExpressionObjectOptimizations, OptimizingAnObjectShouldOptimizeSubExpressions) {
// Build up the object {a: {$add: [1, 2]}}.
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
auto addExpression =
- ExpressionAdd::parse(expCtx, BSON("$add" << BSON_ARRAY(1 << 2)).firstElement(), vps);
- auto object = ExpressionObject::create(expCtx, {{"a", addExpression}});
+ ExpressionAdd::parse(&expCtx, BSON("$add" << BSON_ARRAY(1 << 2)).firstElement(), vps);
+ auto object = ExpressionObject::create(&expCtx, {{"a", addExpression}});
ASSERT_EQ(object->getChildExpressions().size(), 1UL);
auto optimized = object->optimize();
auto optimizedObject = dynamic_cast<ExpressionConstant*>(optimized.get());
ASSERT_TRUE(optimizedObject);
- ASSERT_VALUE_EQ(optimizedObject->evaluate(Document(), &(expCtx->variables)),
+ ASSERT_VALUE_EQ(optimizedObject->evaluate(Document(), &(expCtx.variables)),
Value(BSON("a" << 3)));
};
TEST(ExpressionObjectOptimizations,
OptimizingAnObjectWithAllConstantsShouldOptimizeToExpressionConstant) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
// All constants should optimize to ExpressionConstant.
- auto objectWithAllConstants = ExpressionObject::parse(expCtx, BSON("b" << 1 << "c" << 1), vps);
+ auto objectWithAllConstants = ExpressionObject::parse(&expCtx, BSON("b" << 1 << "c" << 1), vps);
auto optimizedToAllConstants = objectWithAllConstants->optimize();
auto constants = dynamic_cast<ExpressionConstant*>(optimizedToAllConstants.get());
ASSERT_TRUE(constants);
// Not all constants should not optimize to ExpressionConstant.
- auto objectNotAllConstants = ExpressionObject::parse(expCtx,
+ auto objectNotAllConstants = ExpressionObject::parse(&expCtx,
BSON("b" << 1 << "input"
<< "$inputField"),
vps);
@@ -385,14 +384,14 @@ TEST(ExpressionObjectOptimizations,
// Sub expression should optimize to constant expression.
auto expressionWithConstantObject = ExpressionObject::parse(
- expCtx,
+ &expCtx,
BSON("willBeConstant" << BSON("$add" << BSON_ARRAY(1 << 2)) << "alreadyConstant"
<< "string"),
vps);
auto optimizedWithConstant = expressionWithConstantObject->optimize();
auto optimizedObject = dynamic_cast<ExpressionConstant*>(optimizedWithConstant.get());
ASSERT_TRUE(optimizedObject);
- ASSERT_VALUE_EQ(optimizedObject->evaluate(Document(), &expCtx->variables),
+ ASSERT_VALUE_EQ(optimizedObject->evaluate(Document(), &expCtx.variables),
Value(BSON("willBeConstant" << 3 << "alreadyConstant"
<< "string")));
};
diff --git a/src/mongo/db/pipeline/expression_or_test.cpp b/src/mongo/db/pipeline/expression_or_test.cpp
index 20b0829c004..ca4f5fdf843 100644
--- a/src/mongo/db/pipeline/expression_or_test.cpp
+++ b/src/mongo/db/pipeline/expression_or_test.cpp
@@ -96,19 +96,18 @@ class ExpectedResultBase {
public:
virtual ~ExpectedResultBase() {}
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
BSONObj specObject = BSON("" << spec());
BSONElement specElement = specObject.firstElement();
- VariablesParseState vps = expCtx->variablesParseState;
- intrusive_ptr<Expression> expression = Expression::parseOperand(expCtx, specElement, vps);
+ VariablesParseState vps = expCtx.variablesParseState;
+ intrusive_ptr<Expression> expression = Expression::parseOperand(&expCtx, specElement, vps);
ASSERT_BSONOBJ_EQ(constify(spec()), expressionToBson(expression));
ASSERT_BSONOBJ_EQ(
BSON("" << expectedResult()),
- toBson(expression->evaluate(fromBson(BSON("a" << 1)), &expCtx->variables)));
+ toBson(expression->evaluate(fromBson(BSON("a" << 1)), &expCtx.variables)));
intrusive_ptr<Expression> optimized = expression->optimize();
- ASSERT_BSONOBJ_EQ(
- BSON("" << expectedResult()),
- toBson(optimized->evaluate(fromBson(BSON("a" << 1)), &expCtx->variables)));
+ ASSERT_BSONOBJ_EQ(BSON("" << expectedResult()),
+ toBson(optimized->evaluate(fromBson(BSON("a" << 1)), &expCtx.variables)));
}
protected:
@@ -120,11 +119,11 @@ class OptimizeBase {
public:
virtual ~OptimizeBase() {}
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
BSONObj specObject = BSON("" << spec());
BSONElement specElement = specObject.firstElement();
- VariablesParseState vps = expCtx->variablesParseState;
- intrusive_ptr<Expression> expression = Expression::parseOperand(expCtx, specElement, vps);
+ VariablesParseState vps = expCtx.variablesParseState;
+ intrusive_ptr<Expression> expression = Expression::parseOperand(&expCtx, specElement, vps);
ASSERT_BSONOBJ_EQ(constify(spec()), expressionToBson(expression));
intrusive_ptr<Expression> optimized = expression->optimize();
ASSERT_BSONOBJ_EQ(expectedOptimized(), expressionToBson(optimized));
diff --git a/src/mongo/db/pipeline/expression_replace_test.cpp b/src/mongo/db/pipeline/expression_replace_test.cpp
index f1f55ad2f91..2cfcd1194b4 100644
--- a/src/mongo/db/pipeline/expression_replace_test.cpp
+++ b/src/mongo/db/pipeline/expression_replace_test.cpp
@@ -41,11 +41,11 @@ using std::string;
using namespace mongo;
intrusive_ptr<Expression> parse(const string& expressionName, ImplicitValue operand) {
- auto expCtx = make_intrusive<ExpressionContextForTest>();
- VariablesParseState vps = expCtx->variablesParseState;
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
Value operandValue = operand;
const BSONObj obj = BSON(expressionName << operandValue);
- return Expression::parseExpression(expCtx, obj, vps);
+ return Expression::parseExpression(&expCtx, obj, vps);
}
Value eval(const string& expressionName,
diff --git a/src/mongo/db/pipeline/expression_test.cpp b/src/mongo/db/pipeline/expression_test.cpp
index 9613a4122ef..fcc9e4f5230 100644
--- a/src/mongo/db/pipeline/expression_test.cpp
+++ b/src/mongo/db/pipeline/expression_test.cpp
@@ -64,11 +64,11 @@ using std::vector;
*/
static Value evaluateExpression(const string& expressionName,
const vector<ImplicitValue>& operands) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
const BSONObj obj = BSON(expressionName << ImplicitValue::convertToValue(operands));
- auto expression = Expression::parseExpression(expCtx, obj, vps);
- Value result = expression->evaluate({}, &expCtx->variables);
+ auto expression = Expression::parseExpression(&expCtx, obj, vps);
+ Value result = expression->evaluate({}, &expCtx.variables);
return result;
}
@@ -248,10 +248,10 @@ class ExpectedResultBase {
public:
virtual ~ExpectedResultBase() {}
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<ExpressionNary> expression = new ExpressionAdd(expCtx);
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<ExpressionNary> expression = new ExpressionAdd(&expCtx);
populateOperands(expression);
- ASSERT_BSONOBJ_EQ(expectedResult(), toBson(expression->evaluate({}, &expCtx->variables)));
+ ASSERT_BSONOBJ_EQ(expectedResult(), toBson(expression->evaluate({}, &expCtx.variables)));
}
protected:
@@ -264,10 +264,10 @@ protected:
class NullDocument {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<ExpressionNary> expression = new ExpressionAdd(expCtx);
- expression->addOperand(ExpressionConstant::create(expCtx, Value(2)));
- ASSERT_BSONOBJ_EQ(BSON("" << 2), toBson(expression->evaluate({}, &expCtx->variables)));
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<ExpressionNary> expression = new ExpressionAdd(&expCtx);
+ expression->addOperand(ExpressionConstant::create(&expCtx, Value(2)));
+ ASSERT_BSONOBJ_EQ(BSON("" << 2), toBson(expression->evaluate({}, &expCtx.variables)));
}
};
@@ -283,10 +283,10 @@ class NoOperands : public ExpectedResultBase {
class String {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<ExpressionNary> expression = new ExpressionAdd(expCtx);
- expression->addOperand(ExpressionConstant::create(expCtx, Value("a"_sd)));
- ASSERT_THROWS(expression->evaluate({}, &expCtx->variables), AssertionException);
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<ExpressionNary> expression = new ExpressionAdd(&expCtx);
+ expression->addOperand(ExpressionConstant::create(&expCtx, Value("a"_sd)));
+ ASSERT_THROWS(expression->evaluate({}, &expCtx.variables), AssertionException);
}
};
@@ -294,23 +294,23 @@ public:
class Bool {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<ExpressionNary> expression = new ExpressionAdd(expCtx);
- expression->addOperand(ExpressionConstant::create(expCtx, Value(true)));
- ASSERT_THROWS(expression->evaluate({}, &expCtx->variables), AssertionException);
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<ExpressionNary> expression = new ExpressionAdd(&expCtx);
+ expression->addOperand(ExpressionConstant::create(&expCtx, Value(true)));
+ ASSERT_THROWS(expression->evaluate({}, &expCtx.variables), AssertionException);
}
};
class SingleOperandBase : public ExpectedResultBase {
void populateOperands(intrusive_ptr<ExpressionNary>& expression) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- expression->addOperand(ExpressionConstant::create(expCtx, valueFromBson(operand())));
+ expression->addOperand(ExpressionConstant::create(&expCtx, valueFromBson(operand())));
}
BSONObj expectedResult() {
return operand();
}
protected:
+ ExpressionContextForTest expCtx;
virtual BSONObj operand() = 0;
};
@@ -374,11 +374,11 @@ public:
protected:
void populateOperands(intrusive_ptr<ExpressionNary>& expression) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
expression->addOperand(
- ExpressionConstant::create(expCtx, valueFromBson(_reverse ? operand2() : operand1())));
+ ExpressionConstant::create(&expCtx, valueFromBson(_reverse ? operand2() : operand1())));
expression->addOperand(
- ExpressionConstant::create(expCtx, valueFromBson(_reverse ? operand1() : operand2())));
+ ExpressionConstant::create(&expCtx, valueFromBson(_reverse ? operand1() : operand2())));
}
virtual BSONObj operand1() = 0;
virtual BSONObj operand2() = 0;
@@ -530,10 +530,10 @@ namespace CoerceToBool {
class EvaluateTrue {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> nested = ExpressionConstant::create(expCtx, Value(5));
- intrusive_ptr<Expression> expression = ExpressionCoerceToBool::create(expCtx, nested);
- ASSERT(expression->evaluate({}, &expCtx->variables).getBool());
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> nested = ExpressionConstant::create(&expCtx, Value(5));
+ intrusive_ptr<Expression> expression = ExpressionCoerceToBool::create(&expCtx, nested);
+ ASSERT(expression->evaluate({}, &expCtx.variables).getBool());
}
};
@@ -541,10 +541,10 @@ public:
class EvaluateFalse {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> nested = ExpressionConstant::create(expCtx, Value(0));
- intrusive_ptr<Expression> expression = ExpressionCoerceToBool::create(expCtx, nested);
- ASSERT(!expression->evaluate({}, &expCtx->variables).getBool());
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> nested = ExpressionConstant::create(&expCtx, Value(0));
+ intrusive_ptr<Expression> expression = ExpressionCoerceToBool::create(&expCtx, nested);
+ ASSERT(!expression->evaluate({}, &expCtx.variables).getBool());
}
};
@@ -552,9 +552,9 @@ public:
class Dependencies {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> nested = ExpressionFieldPath::create(expCtx, "a.b");
- intrusive_ptr<Expression> expression = ExpressionCoerceToBool::create(expCtx, nested);
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> nested = ExpressionFieldPath::create(&expCtx, "a.b");
+ intrusive_ptr<Expression> expression = ExpressionCoerceToBool::create(&expCtx, nested);
DepsTracker dependencies;
expression->addDependencies(&dependencies);
ASSERT_EQUALS(1U, dependencies.fields.size());
@@ -568,9 +568,9 @@ public:
class AddToBsonObj {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
intrusive_ptr<Expression> expression =
- ExpressionCoerceToBool::create(expCtx, ExpressionFieldPath::create(expCtx, "foo"));
+ ExpressionCoerceToBool::create(&expCtx, ExpressionFieldPath::create(&expCtx, "foo"));
// serialized as $and because CoerceToBool isn't an ExpressionNary
assertBinaryEqual(fromjson("{field:{$and:['$foo']}}"), toBsonObj(expression));
@@ -586,9 +586,9 @@ private:
class AddToBsonArray {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
intrusive_ptr<Expression> expression =
- ExpressionCoerceToBool::create(expCtx, ExpressionFieldPath::create(expCtx, "foo"));
+ ExpressionCoerceToBool::create(&expCtx, ExpressionFieldPath::create(&expCtx, "foo"));
// serialized as $and because CoerceToBool isn't an ExpressionNary
assertBinaryEqual(BSON_ARRAY(fromjson("{$and:['$foo']}")), toBsonArray(expression));
@@ -613,9 +613,9 @@ namespace Constant {
class Create {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> expression = ExpressionConstant::create(expCtx, Value(5));
- assertBinaryEqual(BSON("" << 5), toBson(expression->evaluate({}, &expCtx->variables)));
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> expression = ExpressionConstant::create(&expCtx, Value(5));
+ assertBinaryEqual(BSON("" << 5), toBson(expression->evaluate({}, &expCtx.variables)));
}
};
@@ -625,13 +625,13 @@ public:
void run() {
BSONObj spec = BSON("IGNORED_FIELD_NAME"
<< "foo");
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
BSONElement specElement = spec.firstElement();
- VariablesParseState vps = expCtx->variablesParseState;
- intrusive_ptr<Expression> expression = ExpressionConstant::parse(expCtx, specElement, vps);
+ VariablesParseState vps = expCtx.variablesParseState;
+ intrusive_ptr<Expression> expression = ExpressionConstant::parse(&expCtx, specElement, vps);
assertBinaryEqual(BSON(""
<< "foo"),
- toBson(expression->evaluate({}, &expCtx->variables)));
+ toBson(expression->evaluate({}, &expCtx.variables)));
}
};
@@ -639,8 +639,8 @@ public:
class Optimize {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> expression = ExpressionConstant::create(expCtx, Value(5));
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> expression = ExpressionConstant::create(&expCtx, Value(5));
// An attempt to optimize returns the Expression itself.
ASSERT_EQUALS(expression, expression->optimize());
}
@@ -650,8 +650,8 @@ public:
class Dependencies {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> expression = ExpressionConstant::create(expCtx, Value(5));
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> expression = ExpressionConstant::create(&expCtx, Value(5));
DepsTracker dependencies;
expression->addDependencies(&dependencies);
ASSERT_EQUALS(0U, dependencies.fields.size());
@@ -664,8 +664,8 @@ public:
class AddToBsonObj {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> expression = ExpressionConstant::create(expCtx, Value(5));
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> expression = ExpressionConstant::create(&expCtx, Value(5));
// The constant is replaced with a $ expression.
assertBinaryEqual(BSON("field" << BSON("$const" << 5)), toBsonObj(expression));
}
@@ -680,8 +680,8 @@ private:
class AddToBsonArray {
public:
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> expression = ExpressionConstant::create(expCtx, Value(5));
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> expression = ExpressionConstant::create(&expCtx, Value(5));
// The constant is copied out as is.
assertBinaryEqual(constify(BSON_ARRAY(5)), toBsonArray(expression));
}
@@ -695,16 +695,16 @@ private:
};
TEST(ExpressionConstantTest, ConstantOfValueMissingRemovesField) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> expression = ExpressionConstant::create(expCtx, Value());
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> expression = ExpressionConstant::create(&expCtx, Value());
assertBinaryEqual(
BSONObj(),
- toBson(expression->evaluate(Document{{"foo", Value("bar"_sd)}}, &expCtx->variables)));
+ toBson(expression->evaluate(Document{{"foo", Value("bar"_sd)}}, &expCtx.variables)));
}
TEST(ExpressionConstantTest, ConstantOfValueMissingSerializesToRemoveSystemVar) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- intrusive_ptr<Expression> expression = ExpressionConstant::create(expCtx, Value());
+ auto expCtx = ExpressionContextForTest{};
+ intrusive_ptr<Expression> expression = ExpressionConstant::create(&expCtx, Value());
assertBinaryEqual(BSON("field"
<< "$$REMOVE"),
BSON("field" << expression->serialize(false)));
@@ -798,15 +798,16 @@ TEST(ExpressionPowTest, LargeExponentValuesWithBaseOfZero) {
}
TEST(ExpressionPowTest, ThrowsWhenBaseZeroAndExpNegative) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
- const auto expr = Expression::parseExpression(expCtx, BSON("$pow" << BSON_ARRAY(0 << -5)), vps);
- ASSERT_THROWS([&] { expr->evaluate({}, &expCtx->variables); }(), AssertionException);
+ const auto expr =
+ Expression::parseExpression(&expCtx, BSON("$pow" << BSON_ARRAY(0 << -5)), vps);
+ ASSERT_THROWS([&] { expr->evaluate({}, &expCtx.variables); }(), AssertionException);
const auto exprWithLong =
- Expression::parseExpression(expCtx, BSON("$pow" << BSON_ARRAY(0LL << -5LL)), vps);
- ASSERT_THROWS([&] { expr->evaluate({}, &expCtx->variables); }(), AssertionException);
+ Expression::parseExpression(&expCtx, BSON("$pow" << BSON_ARRAY(0LL << -5LL)), vps);
+ ASSERT_THROWS([&] { expr->evaluate({}, &expCtx.variables); }(), AssertionException);
}
TEST(ExpressionPowTest, LargeExponentValuesWithBaseOfOne) {
@@ -869,13 +870,13 @@ TEST(ExpressionPowTest, LargeBaseSmallPositiveExponent) {
}
TEST(ExpressionArray, ExpressionArrayWithAllConstantValuesShouldOptimizeToExpressionConstant) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
// ExpressionArray of constant values should optimize to ExpressionConsant.
BSONObj bsonarrayOfConstants = BSON("" << BSON_ARRAY(1 << 2 << 3 << 4));
BSONElement elementArray = bsonarrayOfConstants.firstElement();
- auto expressionArr = ExpressionArray::parse(expCtx, elementArray, vps);
+ auto expressionArr = ExpressionArray::parse(&expCtx, elementArray, vps);
auto optimizedToConstant = expressionArr->optimize();
auto exprConstant = dynamic_cast<ExpressionConstant*>(optimizedToConstant.get());
ASSERT_TRUE(exprConstant);
@@ -883,15 +884,15 @@ TEST(ExpressionArray, ExpressionArrayWithAllConstantValuesShouldOptimizeToExpres
// ExpressionArray with not all constant values should not optimize to ExpressionConstant.
BSONObj bsonarray = BSON("" << BSON_ARRAY(1 << "$x" << 3 << 4));
BSONElement elementArrayNotConstant = bsonarray.firstElement();
- auto expressionArrNotConstant = ExpressionArray::parse(expCtx, elementArrayNotConstant, vps);
+ auto expressionArrNotConstant = ExpressionArray::parse(&expCtx, elementArrayNotConstant, vps);
auto notOptimized = expressionArrNotConstant->optimize();
auto notExprConstant = dynamic_cast<ExpressionConstant*>(notOptimized.get());
ASSERT_FALSE(notExprConstant);
}
TEST(ExpressionArray, ExpressionArrayShouldOptimizeSubExpressionToExpressionConstant) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
// ExpressionArray with constant values and sub expression that evaluates to constant should
@@ -900,7 +901,7 @@ TEST(ExpressionArray, ExpressionArrayShouldOptimizeSubExpressionToExpressionCons
BSON("" << BSON_ARRAY(1 << BSON("$add" << BSON_ARRAY(1 << 1)) << 3 << 4));
BSONElement elementArrayWithSubExpression = bsonarrayWithSubExpression.firstElement();
auto expressionArrWithSubExpression =
- ExpressionArray::parse(expCtx, elementArrayWithSubExpression, vps);
+ ExpressionArray::parse(&expCtx, elementArrayWithSubExpression, vps);
auto optimizedToConstantWithSubExpression = expressionArrWithSubExpression->optimize();
auto constantExpression =
dynamic_cast<ExpressionConstant*>(optimizedToConstantWithSubExpression.get());
@@ -908,10 +909,10 @@ TEST(ExpressionArray, ExpressionArrayShouldOptimizeSubExpressionToExpressionCons
}
TEST(ExpressionIndexOfArray, ExpressionIndexOfArrayShouldOptimizeArguments) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto expIndexOfArray = Expression::parseExpression(
- expCtx, // 2, 1, 1
+ &expCtx, // 2, 1, 1
BSON("$indexOfArray" << BSON_ARRAY(
BSON_ARRAY(BSON("$add" << BSON_ARRAY(1 << 1)) << 1 << 1 << 2)
// Value we are searching for = 2.
@@ -920,7 +921,7 @@ TEST(ExpressionIndexOfArray, ExpressionIndexOfArrayShouldOptimizeArguments) {
<< BSON("$add" << BSON_ARRAY(0 << 1))
// End index = 4.
<< BSON("$add" << BSON_ARRAY(1 << 3)))),
- expCtx->variablesParseState);
+ expCtx.variablesParseState);
auto argsOptimizedToConstants = expIndexOfArray->optimize();
auto shouldBeIndexOfArray = dynamic_cast<ExpressionConstant*>(argsOptimizedToConstants.get());
ASSERT_TRUE(shouldBeIndexOfArray);
@@ -929,11 +930,11 @@ TEST(ExpressionIndexOfArray, ExpressionIndexOfArrayShouldOptimizeArguments) {
TEST(ExpressionIndexOfArray,
ExpressionIndexOfArrayShouldOptimizeNullishInputArrayToExpressionConstant) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
auto expIndex = Expression::parseExpression(
- expCtx, fromjson("{ $indexOfArray : [ undefined , 1, 1]}"), expCtx->variablesParseState);
+ &expCtx, fromjson("{ $indexOfArray : [ undefined , 1, 1]}"), expCtx.variablesParseState);
auto isExpIndexOfArray = dynamic_cast<ExpressionIndexOfArray*>(expIndex.get());
ASSERT_TRUE(isExpIndexOfArray);
@@ -949,87 +950,87 @@ TEST(ExpressionIndexOfArray,
TEST(ExpressionIndexOfArray,
OptimizedExpressionIndexOfArrayWithConstantArgumentsShouldEvaluateProperly) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto expIndexOfArray = Expression::parseExpression(
- expCtx,
+ &expCtx,
// Search for $x.
fromjson("{ $indexOfArray : [ [0, 1, 2, 3, 4, 5, 'val'] , '$x'] }"),
- expCtx->variablesParseState);
+ expCtx.variablesParseState);
auto optimizedIndexOfArray = expIndexOfArray->optimize();
ASSERT_VALUE_EQ(Value(0),
- optimizedIndexOfArray->evaluate(Document{{"x", 0}}, &expCtx->variables));
+ optimizedIndexOfArray->evaluate(Document{{"x", 0}}, &expCtx.variables));
ASSERT_VALUE_EQ(Value(1),
- optimizedIndexOfArray->evaluate(Document{{"x", 1}}, &expCtx->variables));
+ optimizedIndexOfArray->evaluate(Document{{"x", 1}}, &expCtx.variables));
ASSERT_VALUE_EQ(Value(2),
- optimizedIndexOfArray->evaluate(Document{{"x", 2}}, &expCtx->variables));
+ optimizedIndexOfArray->evaluate(Document{{"x", 2}}, &expCtx.variables));
ASSERT_VALUE_EQ(Value(3),
- optimizedIndexOfArray->evaluate(Document{{"x", 3}}, &expCtx->variables));
+ optimizedIndexOfArray->evaluate(Document{{"x", 3}}, &expCtx.variables));
ASSERT_VALUE_EQ(Value(4),
- optimizedIndexOfArray->evaluate(Document{{"x", 4}}, &expCtx->variables));
+ optimizedIndexOfArray->evaluate(Document{{"x", 4}}, &expCtx.variables));
ASSERT_VALUE_EQ(Value(5),
- optimizedIndexOfArray->evaluate(Document{{"x", 5}}, &expCtx->variables));
+ optimizedIndexOfArray->evaluate(Document{{"x", 5}}, &expCtx.variables));
ASSERT_VALUE_EQ(
Value(6),
- optimizedIndexOfArray->evaluate(Document{{"x", string("val")}}, &expCtx->variables));
+ optimizedIndexOfArray->evaluate(Document{{"x", string("val")}}, &expCtx.variables));
auto optimizedIndexNotFound = optimizedIndexOfArray->optimize();
// Should evaluate to -1 if not found.
ASSERT_VALUE_EQ(Value(-1),
- optimizedIndexNotFound->evaluate(Document{{"x", 10}}, &expCtx->variables));
+ optimizedIndexNotFound->evaluate(Document{{"x", 10}}, &expCtx.variables));
ASSERT_VALUE_EQ(Value(-1),
- optimizedIndexNotFound->evaluate(Document{{"x", 100}}, &expCtx->variables));
+ optimizedIndexNotFound->evaluate(Document{{"x", 100}}, &expCtx.variables));
ASSERT_VALUE_EQ(Value(-1),
- optimizedIndexNotFound->evaluate(Document{{"x", 1000}}, &expCtx->variables));
+ optimizedIndexNotFound->evaluate(Document{{"x", 1000}}, &expCtx.variables));
ASSERT_VALUE_EQ(
Value(-1),
- optimizedIndexNotFound->evaluate(Document{{"x", string("string")}}, &expCtx->variables));
+ optimizedIndexNotFound->evaluate(Document{{"x", string("string")}}, &expCtx.variables));
ASSERT_VALUE_EQ(Value(-1),
- optimizedIndexNotFound->evaluate(Document{{"x", -1}}, &expCtx->variables));
+ optimizedIndexNotFound->evaluate(Document{{"x", -1}}, &expCtx.variables));
}
TEST(ExpressionIndexOfArray,
OptimizedExpressionIndexOfArrayWithConstantArgumentsShouldEvaluateProperlyWithRange) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto expIndexOfArray = Expression::parseExpression(
- expCtx,
+ &expCtx,
// Search for 4 between 3 and 5.
fromjson("{ $indexOfArray : [ [0, 1, 2, 3, 4, 5] , '$x', 3, 5] }"),
- expCtx->variablesParseState);
+ expCtx.variablesParseState);
auto optimizedIndexOfArray = expIndexOfArray->optimize();
ASSERT_VALUE_EQ(Value(4),
- optimizedIndexOfArray->evaluate(Document{{"x", 4}}, &expCtx->variables));
+ optimizedIndexOfArray->evaluate(Document{{"x", 4}}, &expCtx.variables));
// Should evaluate to -1 if not found in range.
ASSERT_VALUE_EQ(Value(-1),
- optimizedIndexOfArray->evaluate(Document{{"x", 0}}, &expCtx->variables));
+ optimizedIndexOfArray->evaluate(Document{{"x", 0}}, &expCtx.variables));
}
TEST(ExpressionIndexOfArray,
OptimizedExpressionIndexOfArrayWithConstantArrayShouldEvaluateProperlyWithDuplicateValues) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto expIndexOfArrayWithDuplicateValues =
- Expression::parseExpression(expCtx,
+ Expression::parseExpression(&expCtx,
// Search for 4 between 3 and 5.
fromjson("{ $indexOfArray : [ [0, 1, 2, 2, 3, 4, 5] , '$x'] }"),
- expCtx->variablesParseState);
+ expCtx.variablesParseState);
auto optimizedIndexOfArrayWithDuplicateValues = expIndexOfArrayWithDuplicateValues->optimize();
ASSERT_VALUE_EQ(
Value(2),
- optimizedIndexOfArrayWithDuplicateValues->evaluate(Document{{"x", 2}}, &expCtx->variables));
+ optimizedIndexOfArrayWithDuplicateValues->evaluate(Document{{"x", 2}}, &expCtx.variables));
// Duplicate Values in a range.
auto expIndexInRangeWithhDuplicateValues = Expression::parseExpression(
- expCtx,
+ &expCtx,
// Search for 2 between 4 and 6.
fromjson("{ $indexOfArray : [ [0, 1, 2, 2, 2, 2, 4, 5] , '$x', 4, 6] }"),
- expCtx->variablesParseState);
+ expCtx.variablesParseState);
auto optimizedIndexInRangeWithDuplcateValues = expIndexInRangeWithhDuplicateValues->optimize();
// Should evaluate to 4.
ASSERT_VALUE_EQ(
Value(4),
- optimizedIndexInRangeWithDuplcateValues->evaluate(Document{{"x", 2}}, &expCtx->variables));
+ optimizedIndexInRangeWithDuplcateValues->evaluate(Document{{"x", 2}}, &expCtx.variables));
}
namespace Parse {
@@ -1040,10 +1041,10 @@ namespace Object {
* Parses the object given by 'specification', with the options given by 'parseContextOptions'.
*/
boost::intrusive_ptr<Expression> parseObject(BSONObj specification) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
- return Expression::parseObject(expCtx, specification, vps);
+ return Expression::parseObject(&expCtx, specification, vps);
};
TEST(ParseObject, ShouldAcceptEmptyObject) {
@@ -1074,9 +1075,9 @@ using mongo::Expression;
* Parses an expression from the given BSON specification.
*/
boost::intrusive_ptr<Expression> parseExpression(BSONObj specification) {
- const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
- return Expression::parseExpression(expCtx, specification, vps);
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
+ return Expression::parseExpression(&expCtx, specification, vps);
}
TEST(ParseExpression, ShouldRecognizeConstExpression) {
@@ -1180,10 +1181,10 @@ using mongo::Expression;
* case the field name would be the name of the expression.
*/
intrusive_ptr<Expression> parseOperand(BSONObj specification) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
BSONElement specElement = specification.firstElement();
- VariablesParseState vps = expCtx->variablesParseState;
- return Expression::parseOperand(expCtx, specElement, vps);
+ VariablesParseState vps = expCtx.variablesParseState;
+ return Expression::parseOperand(&expCtx, specElement, vps);
}
TEST(ParseOperand, ShouldRecognizeFieldPath) {
@@ -1245,7 +1246,7 @@ class ExpectedResultBase {
public:
virtual ~ExpectedResultBase() {}
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
const Document spec = getSpec();
const Value args = spec["input"];
if (!spec["expected"].missing()) {
@@ -1254,10 +1255,10 @@ public:
const Document::FieldPair field(fields.next());
const Value expected = field.second;
const BSONObj obj = BSON(field.first << args);
- VariablesParseState vps = expCtx->variablesParseState;
+ VariablesParseState vps = expCtx.variablesParseState;
const intrusive_ptr<Expression> expr =
- Expression::parseExpression(expCtx, obj, vps);
- Value result = expr->evaluate({}, &expCtx->variables);
+ Expression::parseExpression(&expCtx, obj, vps);
+ Value result = expr->evaluate({}, &expCtx.variables);
if (result.getType() == Array) {
result = sortSet(result);
}
@@ -1277,14 +1278,14 @@ public:
size_t n = asserters.size();
for (size_t i = 0; i < n; i++) {
const BSONObj obj = BSON(asserters[i].getString() << args);
- VariablesParseState vps = expCtx->variablesParseState;
+ VariablesParseState vps = expCtx.variablesParseState;
ASSERT_THROWS(
[&] {
// NOTE: parse and evaluatation failures are treated the
// same
const intrusive_ptr<Expression> expr =
- Expression::parseExpression(expCtx, obj, vps);
- expr->evaluate({}, &expCtx->variables);
+ Expression::parseExpression(&expCtx, obj, vps);
+ expr->evaluate({}, &expCtx.variables);
}(),
AssertionException);
}
@@ -1543,14 +1544,14 @@ private:
return BSON("$strcasecmp" << BSON_ARRAY(b() << a()));
}
void assertResult(int expectedResult, const BSONObj& spec) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
BSONObj specObj = BSON("" << spec);
BSONElement specElement = specObj.firstElement();
- VariablesParseState vps = expCtx->variablesParseState;
- intrusive_ptr<Expression> expression = Expression::parseOperand(expCtx, specElement, vps);
+ VariablesParseState vps = expCtx.variablesParseState;
+ intrusive_ptr<Expression> expression = Expression::parseOperand(&expCtx, specElement, vps);
ASSERT_BSONOBJ_EQ(constify(spec), expressionToBson(expression));
ASSERT_BSONOBJ_EQ(BSON("" << expectedResult),
- toBson(expression->evaluate({}, &expCtx->variables)));
+ toBson(expression->evaluate({}, &expCtx.variables)));
}
};
@@ -1670,14 +1671,14 @@ class ExpectedResultBase {
public:
virtual ~ExpectedResultBase() {}
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
BSONObj specObj = BSON("" << spec());
BSONElement specElement = specObj.firstElement();
- VariablesParseState vps = expCtx->variablesParseState;
- intrusive_ptr<Expression> expression = Expression::parseOperand(expCtx, specElement, vps);
+ VariablesParseState vps = expCtx.variablesParseState;
+ intrusive_ptr<Expression> expression = Expression::parseOperand(&expCtx, specElement, vps);
ASSERT_BSONOBJ_EQ(constify(spec()), expressionToBson(expression));
ASSERT_BSONOBJ_EQ(BSON("" << expectedResult()),
- toBson(expression->evaluate({}, &expCtx->variables)));
+ toBson(expression->evaluate({}, &expCtx.variables)));
}
protected:
@@ -1789,13 +1790,13 @@ class NegativeLength : public ExpectedResultBase {
};
TEST(ExpressionSubstrTest, ThrowsWithNegativeStart) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
const auto str = "abcdef"_sd;
const auto expr =
- Expression::parseExpression(expCtx, BSON("$substrCP" << BSON_ARRAY(str << -5 << 1)), vps);
- ASSERT_THROWS([&] { expr->evaluate({}, &expCtx->variables); }(), AssertionException);
+ Expression::parseExpression(&expCtx, BSON("$substrCP" << BSON_ARRAY(str << -5 << 1)), vps);
+ ASSERT_THROWS([&] { expr->evaluate({}, &expCtx.variables); }(), AssertionException);
}
} // namespace SubstrBytes
@@ -1803,23 +1804,23 @@ TEST(ExpressionSubstrTest, ThrowsWithNegativeStart) {
namespace SubstrCP {
TEST(ExpressionSubstrCPTest, DoesThrowWithBadContinuationByte) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
const auto continuationByte = "\x80\x00"_sd;
const auto expr = Expression::parseExpression(
- expCtx, BSON("$substrCP" << BSON_ARRAY(continuationByte << 0 << 1)), vps);
- ASSERT_THROWS([&] { expr->evaluate({}, &expCtx->variables); }(), AssertionException);
+ &expCtx, BSON("$substrCP" << BSON_ARRAY(continuationByte << 0 << 1)), vps);
+ ASSERT_THROWS([&] { expr->evaluate({}, &expCtx.variables); }(), AssertionException);
}
TEST(ExpressionSubstrCPTest, DoesThrowWithInvalidLeadingByte) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
const auto leadingByte = "\xFF\x00"_sd;
const auto expr = Expression::parseExpression(
- expCtx, BSON("$substrCP" << BSON_ARRAY(leadingByte << 0 << 1)), vps);
- ASSERT_THROWS([&] { expr->evaluate({}, &expCtx->variables); }(), AssertionException);
+ &expCtx, BSON("$substrCP" << BSON_ARRAY(leadingByte << 0 << 1)), vps);
+ ASSERT_THROWS([&] { expr->evaluate({}, &expCtx.variables); }(), AssertionException);
}
TEST(ExpressionSubstrCPTest, WithStandardValue) {
@@ -2071,27 +2072,27 @@ TEST(BuiltinRemoveVariableTest, LiteralEscapesRemoveVar) {
}
TEST(BuiltinRemoveVariableTest, RemoveSerializesCorrectly) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
- auto expression = ExpressionFieldPath::parse(expCtx, "$$REMOVE", vps);
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
+ auto expression = ExpressionFieldPath::parse(&expCtx, "$$REMOVE", vps);
ASSERT_BSONOBJ_EQ(BSON("foo"
<< "$$REMOVE"),
BSON("foo" << expression->serialize(false)));
}
TEST(BuiltinRemoveVariableTest, RemoveSerializesCorrectlyWithTrailingPath) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
- auto expression = ExpressionFieldPath::parse(expCtx, "$$REMOVE.a.b", vps);
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
+ auto expression = ExpressionFieldPath::parse(&expCtx, "$$REMOVE.a.b", vps);
ASSERT_BSONOBJ_EQ(BSON("foo"
<< "$$REMOVE.a.b"),
BSON("foo" << expression->serialize(false)));
}
TEST(BuiltinRemoveVariableTest, RemoveSerializesCorrectlyAfterOptimization) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
- auto expression = ExpressionFieldPath::parse(expCtx, "$$REMOVE.a.b", vps);
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
+ auto expression = ExpressionFieldPath::parse(&expCtx, "$$REMOVE.a.b", vps);
auto optimizedExpression = expression->optimize();
ASSERT(dynamic_cast<ExpressionConstant*>(optimizedExpression.get()));
ASSERT_BSONOBJ_EQ(BSON("foo"
@@ -2183,14 +2184,14 @@ class ExpectedResultBase {
public:
virtual ~ExpectedResultBase() {}
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
BSONObj specObj = BSON("" << spec());
BSONElement specElement = specObj.firstElement();
- VariablesParseState vps = expCtx->variablesParseState;
- intrusive_ptr<Expression> expression = Expression::parseOperand(expCtx, specElement, vps);
+ VariablesParseState vps = expCtx.variablesParseState;
+ intrusive_ptr<Expression> expression = Expression::parseOperand(&expCtx, specElement, vps);
ASSERT_BSONOBJ_EQ(constify(spec()), expressionToBson(expression));
ASSERT_BSONOBJ_EQ(BSON("" << expectedResult()),
- toBson(expression->evaluate({}, &expCtx->variables)));
+ toBson(expression->evaluate({}, &expCtx.variables)));
}
protected:
@@ -2241,14 +2242,14 @@ class ExpectedResultBase {
public:
virtual ~ExpectedResultBase() {}
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
BSONObj specObj = BSON("" << spec());
BSONElement specElement = specObj.firstElement();
- VariablesParseState vps = expCtx->variablesParseState;
- intrusive_ptr<Expression> expression = Expression::parseOperand(expCtx, specElement, vps);
+ VariablesParseState vps = expCtx.variablesParseState;
+ intrusive_ptr<Expression> expression = Expression::parseOperand(&expCtx, specElement, vps);
ASSERT_BSONOBJ_EQ(constify(spec()), expressionToBson(expression));
ASSERT_BSONOBJ_EQ(BSON("" << expectedResult()),
- toBson(expression->evaluate({}, &expCtx->variables)));
+ toBson(expression->evaluate({}, &expCtx.variables)));
}
protected:
@@ -2298,7 +2299,7 @@ class ExpectedResultBase {
public:
virtual ~ExpectedResultBase() {}
void run() {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
const Document spec = getSpec();
const Value args = spec["input"];
if (!spec["expected"].missing()) {
@@ -2307,10 +2308,10 @@ public:
const Document::FieldPair field(fields.next());
const Value expected = field.second;
const BSONObj obj = BSON(field.first << args);
- VariablesParseState vps = expCtx->variablesParseState;
+ VariablesParseState vps = expCtx.variablesParseState;
const intrusive_ptr<Expression> expr =
- Expression::parseExpression(expCtx, obj, vps);
- const Value result = expr->evaluate({}, &expCtx->variables);
+ Expression::parseExpression(&expCtx, obj, vps);
+ const Value result = expr->evaluate({}, &expCtx.variables);
if (ValueComparator().evaluate(result != expected)) {
string errMsg = str::stream()
<< "for expression " << field.first.toString() << " with argument "
@@ -2327,14 +2328,14 @@ public:
size_t n = asserters.size();
for (size_t i = 0; i < n; i++) {
const BSONObj obj = BSON(asserters[i].getString() << args);
- VariablesParseState vps = expCtx->variablesParseState;
+ VariablesParseState vps = expCtx.variablesParseState;
ASSERT_THROWS(
[&] {
// NOTE: parse and evaluatation failures are treated the
// same
const intrusive_ptr<Expression> expr =
- Expression::parseExpression(expCtx, obj, vps);
- expr->evaluate({}, &expCtx->variables);
+ Expression::parseExpression(&expCtx, obj, vps);
+ expr->evaluate({}, &expCtx.variables);
}(),
AssertionException);
}
@@ -2400,8 +2401,8 @@ class Null : public ExpectedResultBase {
namespace GetComputedPathsTest {
TEST(GetComputedPathsTest, ExpressionFieldPathDoesNotCountAsRenameWhenUsingRemoveBuiltin) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto expr = ExpressionFieldPath::parse(expCtx, "$$REMOVE", expCtx->variablesParseState);
+ auto expCtx = ExpressionContextForTest{};
+ auto expr = ExpressionFieldPath::parse(&expCtx, "$$REMOVE", expCtx.variablesParseState);
auto computedPaths = expr->getComputedPaths("a", Variables::kRootId);
ASSERT_EQ(computedPaths.paths.size(), 1u);
ASSERT_EQ(computedPaths.paths.count("a"), 1u);
@@ -2409,8 +2410,8 @@ TEST(GetComputedPathsTest, ExpressionFieldPathDoesNotCountAsRenameWhenUsingRemov
}
TEST(GetComputedPathsTest, ExpressionFieldPathDoesNotCountAsRenameWhenOnlyRoot) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto expr = ExpressionFieldPath::parse(expCtx, "$$ROOT", expCtx->variablesParseState);
+ auto expCtx = ExpressionContextForTest{};
+ auto expr = ExpressionFieldPath::parse(&expCtx, "$$ROOT", expCtx.variablesParseState);
auto computedPaths = expr->getComputedPaths("a", Variables::kRootId);
ASSERT_EQ(computedPaths.paths.size(), 1u);
ASSERT_EQ(computedPaths.paths.count("a"), 1u);
@@ -2418,9 +2419,9 @@ TEST(GetComputedPathsTest, ExpressionFieldPathDoesNotCountAsRenameWhenOnlyRoot)
}
TEST(GetComputedPathsTest, ExpressionFieldPathDoesNotCountAsRenameWithNonMatchingUserVariable) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- expCtx->variablesParseState.defineVariable("userVar");
- auto expr = ExpressionFieldPath::parse(expCtx, "$$userVar.b", expCtx->variablesParseState);
+ auto expCtx = ExpressionContextForTest{};
+ expCtx.variablesParseState.defineVariable("userVar");
+ auto expr = ExpressionFieldPath::parse(&expCtx, "$$userVar.b", expCtx.variablesParseState);
auto computedPaths = expr->getComputedPaths("a", Variables::kRootId);
ASSERT_EQ(computedPaths.paths.size(), 1u);
ASSERT_EQ(computedPaths.paths.count("a"), 1u);
@@ -2428,8 +2429,8 @@ TEST(GetComputedPathsTest, ExpressionFieldPathDoesNotCountAsRenameWithNonMatchin
}
TEST(GetComputedPathsTest, ExpressionFieldPathDoesNotCountAsRenameWhenDotted) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto expr = ExpressionFieldPath::parse(expCtx, "$a.b", expCtx->variablesParseState);
+ auto expCtx = ExpressionContextForTest{};
+ auto expr = ExpressionFieldPath::parse(&expCtx, "$a.b", expCtx.variablesParseState);
auto computedPaths = expr->getComputedPaths("c", Variables::kRootId);
ASSERT_EQ(computedPaths.paths.size(), 1u);
ASSERT_EQ(computedPaths.paths.count("c"), 1u);
@@ -2437,8 +2438,8 @@ TEST(GetComputedPathsTest, ExpressionFieldPathDoesNotCountAsRenameWhenDotted) {
}
TEST(GetComputedPathsTest, ExpressionFieldPathDoesCountAsRename) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto expr = ExpressionFieldPath::parse(expCtx, "$a", expCtx->variablesParseState);
+ auto expCtx = ExpressionContextForTest{};
+ auto expr = ExpressionFieldPath::parse(&expCtx, "$a", expCtx.variablesParseState);
auto computedPaths = expr->getComputedPaths("b", Variables::kRootId);
ASSERT(computedPaths.paths.empty());
ASSERT_EQ(computedPaths.renames.size(), 1u);
@@ -2446,8 +2447,8 @@ TEST(GetComputedPathsTest, ExpressionFieldPathDoesCountAsRename) {
}
TEST(GetComputedPathsTest, ExpressionFieldPathDoesCountAsRenameWithExplicitRoot) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto expr = ExpressionFieldPath::parse(expCtx, "$$ROOT.a", expCtx->variablesParseState);
+ auto expCtx = ExpressionContextForTest{};
+ auto expr = ExpressionFieldPath::parse(&expCtx, "$$ROOT.a", expCtx.variablesParseState);
auto computedPaths = expr->getComputedPaths("b", Variables::kRootId);
ASSERT(computedPaths.paths.empty());
ASSERT_EQ(computedPaths.renames.size(), 1u);
@@ -2455,8 +2456,8 @@ TEST(GetComputedPathsTest, ExpressionFieldPathDoesCountAsRenameWithExplicitRoot)
}
TEST(GetComputedPathsTest, ExpressionFieldPathDoesCountAsRenameWithExplicitCurrent) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto expr = ExpressionFieldPath::parse(expCtx, "$$CURRENT.a", expCtx->variablesParseState);
+ auto expCtx = ExpressionContextForTest{};
+ auto expr = ExpressionFieldPath::parse(&expCtx, "$$CURRENT.a", expCtx.variablesParseState);
auto computedPaths = expr->getComputedPaths("b", Variables::kRootId);
ASSERT(computedPaths.paths.empty());
ASSERT_EQ(computedPaths.renames.size(), 1u);
@@ -2464,9 +2465,9 @@ TEST(GetComputedPathsTest, ExpressionFieldPathDoesCountAsRenameWithExplicitCurre
}
TEST(GetComputedPathsTest, ExpressionFieldPathDoesCountAsRenameWithMatchingUserVariable) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto varId = expCtx->variablesParseState.defineVariable("userVar");
- auto expr = ExpressionFieldPath::parse(expCtx, "$$userVar.a", expCtx->variablesParseState);
+ auto expCtx = ExpressionContextForTest{};
+ auto varId = expCtx.variablesParseState.defineVariable("userVar");
+ auto expr = ExpressionFieldPath::parse(&expCtx, "$$userVar.a", expCtx.variablesParseState);
auto computedPaths = expr->getComputedPaths("b", varId);
ASSERT(computedPaths.paths.empty());
ASSERT_EQ(computedPaths.renames.size(), 1u);
@@ -2474,9 +2475,9 @@ TEST(GetComputedPathsTest, ExpressionFieldPathDoesCountAsRenameWithMatchingUserV
}
TEST(GetComputedPathsTest, ExpressionObjectCorrectlyReportsComputedPaths) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto specObject = fromjson("{a: '$b', c: {$add: [1, 3]}}");
- auto expr = Expression::parseObject(expCtx, specObject, expCtx->variablesParseState);
+ auto expr = Expression::parseObject(&expCtx, specObject, expCtx.variablesParseState);
ASSERT(dynamic_cast<ExpressionObject*>(expr.get()));
auto computedPaths = expr->getComputedPaths("d");
ASSERT_EQ(computedPaths.paths.size(), 1u);
@@ -2486,11 +2487,11 @@ TEST(GetComputedPathsTest, ExpressionObjectCorrectlyReportsComputedPaths) {
}
TEST(GetComputedPathsTest, ExpressionObjectCorrectlyReportsComputedPathsNested) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto specObject = fromjson(
"{a: {b: '$c'},"
"d: {$map: {input: '$e', as: 'iter', in: {f: '$$iter.g'}}}}");
- auto expr = Expression::parseObject(expCtx, specObject, expCtx->variablesParseState);
+ auto expr = Expression::parseObject(&expCtx, specObject, expCtx.variablesParseState);
ASSERT(dynamic_cast<ExpressionObject*>(expr.get()));
auto computedPaths = expr->getComputedPaths("h");
ASSERT(computedPaths.paths.empty());
@@ -2500,10 +2501,10 @@ TEST(GetComputedPathsTest, ExpressionObjectCorrectlyReportsComputedPathsNested)
}
TEST(GetComputedPathsTest, ExpressionMapCorrectlyReportsComputedPaths) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto specObject =
fromjson("{$map: {input: '$a', as: 'iter', in: {b: '$$iter.c', d: {$add: [1, 2]}}}}");
- auto expr = Expression::parseObject(expCtx, specObject, expCtx->variablesParseState);
+ auto expr = Expression::parseObject(&expCtx, specObject, expCtx.variablesParseState);
ASSERT(dynamic_cast<ExpressionMap*>(expr.get()));
auto computedPaths = expr->getComputedPaths("e");
ASSERT_EQ(computedPaths.paths.size(), 1u);
@@ -2513,9 +2514,9 @@ TEST(GetComputedPathsTest, ExpressionMapCorrectlyReportsComputedPaths) {
}
TEST(GetComputedPathsTest, ExpressionMapCorrectlyReportsComputedPathsWithDefaultVarName) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto specObject = fromjson("{$map: {input: '$a', in: {b: '$$this.c', d: {$add: [1, 2]}}}}");
- auto expr = Expression::parseObject(expCtx, specObject, expCtx->variablesParseState);
+ auto expr = Expression::parseObject(&expCtx, specObject, expCtx.variablesParseState);
ASSERT(dynamic_cast<ExpressionMap*>(expr.get()));
auto computedPaths = expr->getComputedPaths("e");
ASSERT_EQ(computedPaths.paths.size(), 1u);
@@ -2525,9 +2526,9 @@ TEST(GetComputedPathsTest, ExpressionMapCorrectlyReportsComputedPathsWithDefault
}
TEST(GetComputedPathsTest, ExpressionMapCorrectlyReportsComputedPathsWithNestedExprObject) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto specObject = fromjson("{$map: {input: '$a', in: {b: {c: '$$this.d'}}}}");
- auto expr = Expression::parseObject(expCtx, specObject, expCtx->variablesParseState);
+ auto expr = Expression::parseObject(&expCtx, specObject, expCtx.variablesParseState);
ASSERT(dynamic_cast<ExpressionMap*>(expr.get()));
auto computedPaths = expr->getComputedPaths("e");
ASSERT(computedPaths.paths.empty());
@@ -2536,9 +2537,9 @@ TEST(GetComputedPathsTest, ExpressionMapCorrectlyReportsComputedPathsWithNestedE
}
TEST(GetComputedPathsTest, ExpressionMapNotConsideredRenameWithWrongRootVariable) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto specObject = fromjson("{$map: {input: '$a', as: 'iter', in: {b: '$c'}}}");
- auto expr = Expression::parseObject(expCtx, specObject, expCtx->variablesParseState);
+ auto expr = Expression::parseObject(&expCtx, specObject, expCtx.variablesParseState);
ASSERT(dynamic_cast<ExpressionMap*>(expr.get()));
auto computedPaths = expr->getComputedPaths("d");
ASSERT_EQ(computedPaths.paths.size(), 1u);
@@ -2547,9 +2548,9 @@ TEST(GetComputedPathsTest, ExpressionMapNotConsideredRenameWithWrongRootVariable
}
TEST(GetComputedPathsTest, ExpressionMapNotConsideredRenameWithWrongVariableNoExpressionObject) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto specObject = fromjson("{$map: {input: '$a', as: 'iter', in: '$b'}}");
- auto expr = Expression::parseObject(expCtx, specObject, expCtx->variablesParseState);
+ auto expr = Expression::parseObject(&expCtx, specObject, expCtx.variablesParseState);
ASSERT(dynamic_cast<ExpressionMap*>(expr.get()));
auto computedPaths = expr->getComputedPaths("d");
ASSERT_EQ(computedPaths.paths.size(), 1u);
@@ -2558,9 +2559,9 @@ TEST(GetComputedPathsTest, ExpressionMapNotConsideredRenameWithWrongVariableNoEx
}
TEST(GetComputedPathsTest, ExpressionMapNotConsideredRenameWithDottedInputPath) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto specObject = fromjson("{$map: {input: '$a.b', as: 'iter', in: {c: '$$iter.d'}}}}");
- auto expr = Expression::parseObject(expCtx, specObject, expCtx->variablesParseState);
+ auto expr = Expression::parseObject(&expCtx, specObject, expCtx.variablesParseState);
ASSERT(dynamic_cast<ExpressionMap*>(expr.get()));
auto computedPaths = expr->getComputedPaths("e");
ASSERT_EQ(computedPaths.paths.size(), 1u);
@@ -2572,115 +2573,115 @@ TEST(GetComputedPathsTest, ExpressionMapNotConsideredRenameWithDottedInputPath)
namespace expression_meta_test {
TEST(ExpressionMetaTest, ExpressionMetaSearchScore) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
BSONObj expr = fromjson("{$meta: \"searchScore\"}");
- auto expressionMeta = ExpressionMeta::parse(expCtx, expr.firstElement(), vps);
+ auto expressionMeta = ExpressionMeta::parse(&expCtx, expr.firstElement(), vps);
MutableDocument doc;
doc.metadata().setSearchScore(1.234);
- Value val = expressionMeta->evaluate(doc.freeze(), &expCtx->variables);
+ Value val = expressionMeta->evaluate(doc.freeze(), &expCtx.variables);
ASSERT_EQ(val.getDouble(), 1.234);
}
TEST(ExpressionMetaTest, ExpressionMetaSearchHighlights) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
BSONObj expr = fromjson("{$meta: \"searchHighlights\"}");
- auto expressionMeta = ExpressionMeta::parse(expCtx, expr.firstElement(), vps);
+ auto expressionMeta = ExpressionMeta::parse(&expCtx, expr.firstElement(), vps);
MutableDocument doc;
Document highlights = DOC("this part" << 1 << "is opaque to the server" << 1);
doc.metadata().setSearchHighlights(Value(highlights));
- Value val = expressionMeta->evaluate(doc.freeze(), &expCtx->variables);
+ Value val = expressionMeta->evaluate(doc.freeze(), &expCtx.variables);
ASSERT_DOCUMENT_EQ(val.getDocument(), highlights);
}
TEST(ExpressionMetaTest, ExpressionMetaGeoNearDistance) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
BSONObj expr = fromjson("{$meta: \"geoNearDistance\"}");
auto expressionMeta =
- ExpressionMeta::parse(expCtx, expr.firstElement(), expCtx->variablesParseState);
+ ExpressionMeta::parse(&expCtx, expr.firstElement(), expCtx.variablesParseState);
MutableDocument doc;
doc.metadata().setGeoNearDistance(1.23);
- Value val = expressionMeta->evaluate(doc.freeze(), &expCtx->variables);
+ Value val = expressionMeta->evaluate(doc.freeze(), &expCtx.variables);
ASSERT_EQ(val.getDouble(), 1.23);
}
TEST(ExpressionMetaTest, ExpressionMetaGeoNearPoint) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
BSONObj expr = fromjson("{$meta: \"geoNearPoint\"}");
auto expressionMeta =
- ExpressionMeta::parse(expCtx, expr.firstElement(), expCtx->variablesParseState);
+ ExpressionMeta::parse(&expCtx, expr.firstElement(), expCtx.variablesParseState);
MutableDocument doc;
Document pointDoc = Document{fromjson("{some: 'document'}")};
doc.metadata().setGeoNearPoint(Value(pointDoc));
- Value val = expressionMeta->evaluate(doc.freeze(), &expCtx->variables);
+ Value val = expressionMeta->evaluate(doc.freeze(), &expCtx.variables);
ASSERT_DOCUMENT_EQ(val.getDocument(), pointDoc);
}
TEST(ExpressionMetaTest, ExpressionMetaIndexKey) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
BSONObj expr = fromjson("{$meta: \"indexKey\"}");
auto expressionMeta =
- ExpressionMeta::parse(expCtx, expr.firstElement(), expCtx->variablesParseState);
+ ExpressionMeta::parse(&expCtx, expr.firstElement(), expCtx.variablesParseState);
MutableDocument doc;
BSONObj ixKey = fromjson("{'': 1, '': 'string'}");
doc.metadata().setIndexKey(ixKey);
- Value val = expressionMeta->evaluate(doc.freeze(), &expCtx->variables);
+ Value val = expressionMeta->evaluate(doc.freeze(), &expCtx.variables);
ASSERT_DOCUMENT_EQ(val.getDocument(), Document(ixKey));
}
TEST(ExpressionMetaTest, ExpressionMetaRecordId) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
BSONObj expr = fromjson("{$meta: \"recordId\"}");
auto expressionMeta =
- ExpressionMeta::parse(expCtx, expr.firstElement(), expCtx->variablesParseState);
+ ExpressionMeta::parse(&expCtx, expr.firstElement(), expCtx.variablesParseState);
MutableDocument doc;
doc.metadata().setRecordId(RecordId(123LL));
- Value val = expressionMeta->evaluate(doc.freeze(), &expCtx->variables);
+ Value val = expressionMeta->evaluate(doc.freeze(), &expCtx.variables);
ASSERT_EQ(val.getLong(), 123LL);
}
TEST(ExpressionMetaTest, ExpressionMetaRandVal) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
BSONObj expr = fromjson("{$meta: \"randVal\"}");
auto expressionMeta =
- ExpressionMeta::parse(expCtx, expr.firstElement(), expCtx->variablesParseState);
+ ExpressionMeta::parse(&expCtx, expr.firstElement(), expCtx.variablesParseState);
MutableDocument doc;
doc.metadata().setRandVal(1.23);
- Value val = expressionMeta->evaluate(doc.freeze(), &expCtx->variables);
+ Value val = expressionMeta->evaluate(doc.freeze(), &expCtx.variables);
ASSERT_EQ(val.getDouble(), 1.23);
}
TEST(ExpressionMetaTest, ExpressionMetaSortKey) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
BSONObj expr = fromjson("{$meta: \"sortKey\"}");
auto expressionMeta =
- ExpressionMeta::parse(expCtx, expr.firstElement(), expCtx->variablesParseState);
+ ExpressionMeta::parse(&expCtx, expr.firstElement(), expCtx.variablesParseState);
MutableDocument doc;
Value sortKey = Value(std::vector<Value>{Value(1), Value(2)});
doc.metadata().setSortKey(sortKey, /* isSingleElementSortKey = */ false);
- Value val = expressionMeta->evaluate(doc.freeze(), &expCtx->variables);
+ Value val = expressionMeta->evaluate(doc.freeze(), &expCtx.variables);
ASSERT_VALUE_EQ(val, Value(std::vector<Value>{Value(1), Value(2)}));
}
TEST(ExpressionMetaTest, ExpressionMetaTextScore) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
BSONObj expr = fromjson("{$meta: \"textScore\"}");
auto expressionMeta =
- ExpressionMeta::parse(expCtx, expr.firstElement(), expCtx->variablesParseState);
+ ExpressionMeta::parse(&expCtx, expr.firstElement(), expCtx.variablesParseState);
MutableDocument doc;
doc.metadata().setTextScore(1.23);
- Value val = expressionMeta->evaluate(doc.freeze(), &expCtx->variables);
+ Value val = expressionMeta->evaluate(doc.freeze(), &expCtx.variables);
ASSERT_EQ(val.getDouble(), 1.23);
}
} // namespace expression_meta_test
@@ -2690,8 +2691,8 @@ namespace ExpressionRegexTest {
class ExpressionRegexTest {
public:
template <typename ExpressionRegexSubClass>
- static intrusive_ptr<Expression> generateOptimizedExpression(
- const BSONObj& input, intrusive_ptr<ExpressionContextForTest> expCtx) {
+ static intrusive_ptr<Expression> generateOptimizedExpression(const BSONObj& input,
+ ExpressionContextForTest* expCtx) {
auto expression = ExpressionRegexSubClass::parse(
expCtx, input.firstElement(), expCtx->variablesParseState);
@@ -2702,30 +2703,30 @@ public:
bool optimized,
const std::vector<Value>& expectedFindAllOutput) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
{
// For $regexFindAll.
- auto expression = generateOptimizedExpression<ExpressionRegexFindAll>(input, expCtx);
+ auto expression = generateOptimizedExpression<ExpressionRegexFindAll>(input, &expCtx);
auto regexFindAllExpr = dynamic_cast<ExpressionRegexFindAll*>(expression.get());
ASSERT_EQ(regexFindAllExpr->hasConstantRegex(), optimized);
- Value output = expression->evaluate({}, &expCtx->variables);
+ Value output = expression->evaluate({}, &expCtx.variables);
ASSERT_VALUE_EQ(output, Value(expectedFindAllOutput));
}
{
// For $regexFind.
- auto expression = generateOptimizedExpression<ExpressionRegexFind>(input, expCtx);
+ auto expression = generateOptimizedExpression<ExpressionRegexFind>(input, &expCtx);
auto regexFindExpr = dynamic_cast<ExpressionRegexFind*>(expression.get());
ASSERT_EQ(regexFindExpr->hasConstantRegex(), optimized);
- Value output = expression->evaluate({}, &expCtx->variables);
+ Value output = expression->evaluate({}, &expCtx.variables);
ASSERT_VALUE_EQ(
output, expectedFindAllOutput.empty() ? Value(BSONNULL) : expectedFindAllOutput[0]);
}
{
// For $regexMatch.
- auto expression = generateOptimizedExpression<ExpressionRegexMatch>(input, expCtx);
+ auto expression = generateOptimizedExpression<ExpressionRegexMatch>(input, &expCtx);
auto regexMatchExpr = dynamic_cast<ExpressionRegexMatch*>(expression.get());
ASSERT_EQ(regexMatchExpr->hasConstantRegex(), optimized);
- Value output = expression->evaluate({}, &expCtx->variables);
+ Value output = expression->evaluate({}, &expCtx.variables);
ASSERT_VALUE_EQ(output, expectedFindAllOutput.empty() ? Value(false) : Value(true));
}
}
@@ -2915,37 +2916,37 @@ OldStyleSuiteInitializer<All> myAll;
namespace NowAndClusterTime {
TEST(NowAndClusterTime, BasicTest) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
// $$NOW is the Date type.
{
- auto expression = ExpressionFieldPath::parse(expCtx, "$$NOW", expCtx->variablesParseState);
- Value result = expression->evaluate(Document(), &(expCtx->variables));
+ auto expression = ExpressionFieldPath::parse(&expCtx, "$$NOW", expCtx.variablesParseState);
+ Value result = expression->evaluate(Document(), &expCtx.variables);
ASSERT_EQ(result.getType(), Date);
}
// $$CLUSTER_TIME is the timestamp type.
{
auto expression =
- ExpressionFieldPath::parse(expCtx, "$$CLUSTER_TIME", expCtx->variablesParseState);
- Value result = expression->evaluate(Document(), &(expCtx->variables));
+ ExpressionFieldPath::parse(&expCtx, "$$CLUSTER_TIME", expCtx.variablesParseState);
+ Value result = expression->evaluate(Document(), &expCtx.variables);
ASSERT_EQ(result.getType(), bsonTimestamp);
}
// Multiple references to $$NOW must return the same value.
{
auto expression = Expression::parseExpression(
- expCtx, fromjson("{$eq: [\"$$NOW\", \"$$NOW\"]}"), expCtx->variablesParseState);
- Value result = expression->evaluate(Document(), &(expCtx->variables));
+ &expCtx, fromjson("{$eq: [\"$$NOW\", \"$$NOW\"]}"), expCtx.variablesParseState);
+ Value result = expression->evaluate(Document(), &expCtx.variables);
ASSERT_VALUE_EQ(result, Value{true});
}
// Same is true for the $$CLUSTER_TIME.
{
auto expression =
- Expression::parseExpression(expCtx,
+ Expression::parseExpression(&expCtx,
fromjson("{$eq: [\"$$CLUSTER_TIME\", \"$$CLUSTER_TIME\"]}"),
- expCtx->variablesParseState);
- Value result = expression->evaluate(Document(), &(expCtx->variables));
+ expCtx.variablesParseState);
+ Value result = expression->evaluate(Document(), &expCtx.variables);
ASSERT_VALUE_EQ(result, Value{true});
}
diff --git a/src/mongo/db/pipeline/expression_trigonometric.cpp b/src/mongo/db/pipeline/expression_trigonometric.cpp
index 8a39259df7e..0ee9eeb84b1 100644
--- a/src/mongo/db/pipeline/expression_trigonometric.cpp
+++ b/src/mongo/db/pipeline/expression_trigonometric.cpp
@@ -39,7 +39,7 @@ namespace mongo {
class Expression##className final \
: public ExpressionBoundedTrigonometric<Expression##className, boundType> { \
public: \
- explicit Expression##className(const boost::intrusive_ptr<ExpressionContext>& expCtx) \
+ explicit Expression##className(ExpressionContext* const expCtx) \
: ExpressionBoundedTrigonometric(expCtx) {} \
double getLowerBound() const final { \
return lowerBound; \
@@ -106,29 +106,29 @@ CREATE_BOUNDED_TRIGONOMETRIC_CLASS(Tangent,
/* ----------------------- Unbounded Trigonometric Functions ---------------------------- */
-#define CREATE_TRIGONOMETRIC_CLASS(className, funcName) \
- class Expression##className final \
- : public ExpressionUnboundedTrigonometric<Expression##className> { \
- public: \
- explicit Expression##className(const boost::intrusive_ptr<ExpressionContext>& expCtx) \
- : ExpressionUnboundedTrigonometric(expCtx) {} \
- \
- double doubleFunc(double arg) const final { \
- return std::funcName(arg); \
- } \
- \
- Decimal128 decimalFunc(Decimal128 arg) const final { \
- return arg.funcName(); \
- } \
- \
- const char* getOpName() const final { \
- return "$" #funcName; \
- } \
- \
- void acceptVisitor(ExpressionVisitor* visitor) final { \
- return visitor->visit(this); \
- } \
- }; \
+#define CREATE_TRIGONOMETRIC_CLASS(className, funcName) \
+ class Expression##className final \
+ : public ExpressionUnboundedTrigonometric<Expression##className> { \
+ public: \
+ explicit Expression##className(ExpressionContext* const expCtx) \
+ : ExpressionUnboundedTrigonometric(expCtx) {} \
+ \
+ double doubleFunc(double arg) const final { \
+ return std::funcName(arg); \
+ } \
+ \
+ Decimal128 decimalFunc(Decimal128 arg) const final { \
+ return arg.funcName(); \
+ } \
+ \
+ const char* getOpName() const final { \
+ return "$" #funcName; \
+ } \
+ \
+ void acceptVisitor(ExpressionVisitor* visitor) final { \
+ return visitor->visit(this); \
+ } \
+ }; \
REGISTER_EXPRESSION(funcName, Expression##className::parse);
CREATE_TRIGONOMETRIC_CLASS(ArcTangent, atan);
@@ -144,7 +144,7 @@ CREATE_TRIGONOMETRIC_CLASS(HyperbolicTangent, tanh);
class ExpressionArcTangent2 final : public ExpressionTwoNumericArgs<ExpressionArcTangent2> {
public:
- explicit ExpressionArcTangent2(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionArcTangent2(ExpressionContext* const expCtx)
: ExpressionTwoNumericArgs(expCtx) {}
Value evaluateNumericArgs(const Value& numericArg1, const Value& numericArg2) const final {
@@ -199,7 +199,7 @@ static Value doDegreeRadiansConversion(const Value& numericArg,
class ExpressionDegreesToRadians final
: public ExpressionSingleNumericArg<ExpressionDegreesToRadians> {
public:
- explicit ExpressionDegreesToRadians(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionDegreesToRadians(ExpressionContext* const expCtx)
: ExpressionSingleNumericArg(expCtx) {}
Value evaluateNumericArg(const Value& numericArg) const final {
@@ -220,7 +220,7 @@ REGISTER_EXPRESSION(degreesToRadians, ExpressionDegreesToRadians::parse);
class ExpressionRadiansToDegrees final
: public ExpressionSingleNumericArg<ExpressionRadiansToDegrees> {
public:
- explicit ExpressionRadiansToDegrees(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionRadiansToDegrees(ExpressionContext* const expCtx)
: ExpressionSingleNumericArg(expCtx) {}
Value evaluateNumericArg(const Value& numericArg) const final {
diff --git a/src/mongo/db/pipeline/expression_trigonometric.h b/src/mongo/db/pipeline/expression_trigonometric.h
index cc8ca852f8b..1c4236e7ccc 100644
--- a/src/mongo/db/pipeline/expression_trigonometric.h
+++ b/src/mongo/db/pipeline/expression_trigonometric.h
@@ -103,7 +103,7 @@ struct ExclusiveBoundType {
template <typename BoundedTrigType, typename BoundType>
class ExpressionBoundedTrigonometric : public ExpressionSingleNumericArg<BoundedTrigType> {
public:
- explicit ExpressionBoundedTrigonometric(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionBoundedTrigonometric(ExpressionContext* const expCtx)
: ExpressionSingleNumericArg<BoundedTrigType>(expCtx) {}
std::string toString(double d) const {
@@ -198,7 +198,7 @@ public:
template <typename TrigType>
class ExpressionUnboundedTrigonometric : public ExpressionSingleNumericArg<TrigType> {
public:
- explicit ExpressionUnboundedTrigonometric(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ explicit ExpressionUnboundedTrigonometric(ExpressionContext* const expCtx)
: ExpressionSingleNumericArg<TrigType>(expCtx) {}
/**
diff --git a/src/mongo/db/pipeline/expression_trigonometric_test.cpp b/src/mongo/db/pipeline/expression_trigonometric_test.cpp
index dac735bd242..5a37a78a21a 100644
--- a/src/mongo/db/pipeline/expression_trigonometric_test.cpp
+++ b/src/mongo/db/pipeline/expression_trigonometric_test.cpp
@@ -54,11 +54,11 @@ static void assertApproxEq(const Value& evaluated, const Value& expected) {
// A testing class for testing approximately equal results for one argument numeric expressions.
static void assertEvaluates(const std::string& expressionName, Value input, Value output) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto obj = BSON(expressionName << BSON_ARRAY(input));
- auto vps = expCtx->variablesParseState;
- auto expression = Expression::parseExpression(expCtx, obj, vps);
- Value result = expression->evaluate({}, &expCtx->variables);
+ auto vps = expCtx.variablesParseState;
+ auto expression = Expression::parseExpression(&expCtx, obj, vps);
+ Value result = expression->evaluate({}, &expCtx.variables);
ASSERT_EQUALS(result.getType(), output.getType());
assertApproxEq(result, output);
}
@@ -69,11 +69,11 @@ static void assertEvaluates(const std::string& expressionName,
Value input1,
Value input2,
Value output) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto obj = BSON(expressionName << BSON_ARRAY(input1 << input2));
- auto vps = expCtx->variablesParseState;
- auto expression = Expression::parseExpression(expCtx, obj, vps);
- Value result = expression->evaluate({}, &expCtx->variables);
+ auto vps = expCtx.variablesParseState;
+ auto expression = Expression::parseExpression(&expCtx, obj, vps);
+ Value result = expression->evaluate({}, &expCtx.variables);
ASSERT_EQUALS(result.getType(), output.getType());
assertApproxEq(result, output);
}
diff --git a/src/mongo/db/pipeline/expression_trim_test.cpp b/src/mongo/db/pipeline/expression_trim_test.cpp
index a54ee025014..620b371c5f7 100644
--- a/src/mongo/db/pipeline/expression_trim_test.cpp
+++ b/src/mongo/db/pipeline/expression_trim_test.cpp
@@ -53,67 +53,67 @@ using std::string;
* and returns the result.
*/
static Value evaluateNamedArgExpression(const string& expressionName, const Document& operand) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- VariablesParseState vps = expCtx->variablesParseState;
+ auto expCtx = ExpressionContextForTest{};
+ VariablesParseState vps = expCtx.variablesParseState;
const BSONObj obj = BSON(expressionName << operand);
- auto expression = Expression::parseExpression(expCtx, obj, vps);
- Value result = expression->evaluate({}, &expCtx->variables);
+ auto expression = Expression::parseExpression(&expCtx, obj, vps);
+ Value result = expression->evaluate({}, &expCtx.variables);
return result;
}
namespace Trim {
TEST(ExpressionTrimParsingTest, ThrowsIfSpecIsNotAnObject) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
ASSERT_THROWS(
- Expression::parseExpression(expCtx, BSON("$trim" << 1), expCtx->variablesParseState),
+ Expression::parseExpression(&expCtx, BSON("$trim" << 1), expCtx.variablesParseState),
AssertionException);
ASSERT_THROWS(Expression::parseExpression(
- expCtx, BSON("$trim" << BSON_ARRAY(1 << 2)), expCtx->variablesParseState),
+ &expCtx, BSON("$trim" << BSON_ARRAY(1 << 2)), expCtx.variablesParseState),
AssertionException);
ASSERT_THROWS(Expression::parseExpression(
- expCtx, BSON("$ltrim" << BSONNULL), expCtx->variablesParseState),
+ &expCtx, BSON("$ltrim" << BSONNULL), expCtx.variablesParseState),
AssertionException);
- ASSERT_THROWS(Expression::parseExpression(expCtx,
+ ASSERT_THROWS(Expression::parseExpression(&expCtx,
BSON("$rtrim"
<< "string"),
- expCtx->variablesParseState),
+ expCtx.variablesParseState),
AssertionException);
}
TEST(ExpressionTrimParsingTest, ThrowsIfSpecDoesNotSpecifyInput) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
ASSERT_THROWS(Expression::parseExpression(
- expCtx, BSON("$trim" << BSONObj()), expCtx->variablesParseState),
+ &expCtx, BSON("$trim" << BSONObj()), expCtx.variablesParseState),
AssertionException);
- ASSERT_THROWS(Expression::parseExpression(expCtx,
+ ASSERT_THROWS(Expression::parseExpression(&expCtx,
BSON("$ltrim" << BSON("chars"
<< "xyz")),
- expCtx->variablesParseState),
+ expCtx.variablesParseState),
AssertionException);
}
TEST(ExpressionTrimParsingTest, ThrowsIfSpecContainsUnrecognizedField) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
ASSERT_THROWS(Expression::parseExpression(
- expCtx, BSON("$trim" << BSON("other" << 1)), expCtx->variablesParseState),
+ &expCtx, BSON("$trim" << BSON("other" << 1)), expCtx.variablesParseState),
AssertionException);
- ASSERT_THROWS(Expression::parseExpression(expCtx,
+ ASSERT_THROWS(Expression::parseExpression(&expCtx,
BSON("$ltrim" << BSON("chars"
<< "xyz"
<< "other" << 1)),
- expCtx->variablesParseState),
+ expCtx.variablesParseState),
AssertionException);
- ASSERT_THROWS(Expression::parseExpression(expCtx,
+ ASSERT_THROWS(Expression::parseExpression(&expCtx,
BSON("$rtrim" << BSON("input"
<< "$x"
<< "chars"
<< "xyz"
<< "other" << 1)),
- expCtx->variablesParseState),
+ expCtx.variablesParseState),
AssertionException);
}
@@ -446,19 +446,19 @@ TEST(ExpressionTrimTest, DoesNotTrimAnyThingWithEmptyChars) {
}
TEST(ExpressionTrimTest, TrimComparisonsShouldNotRespectCollation) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
auto caseInsensitive =
std::make_unique<CollatorInterfaceMock>(CollatorInterfaceMock::MockType::kToLowerString);
- expCtx->setCollator(std::move(caseInsensitive));
+ expCtx.setCollator(std::move(caseInsensitive));
- auto trim = Expression::parseExpression(expCtx,
+ auto trim = Expression::parseExpression(&expCtx,
BSON("$trim" << BSON("input"
<< "xxXXxx"
<< "chars"
<< "x")),
- expCtx->variablesParseState);
+ expCtx.variablesParseState);
- ASSERT_VALUE_EQ(trim->evaluate({}, &expCtx->variables), Value("XX"_sd));
+ ASSERT_VALUE_EQ(trim->evaluate({}, &expCtx.variables), Value("XX"_sd));
}
TEST(ExpressionTrimTest, ShouldRejectInvalidUTFInCharsArgument) {
@@ -590,11 +590,11 @@ TEST(ExpressionTrimTest, ShouldReturnNullIfBothCharsAndCharsAreNullish) {
}
TEST(ExpressionTrimTest, DoesOptimizeToConstantWithNoChars) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto trim = Expression::parseExpression(expCtx,
+ auto expCtx = ExpressionContextForTest{};
+ auto trim = Expression::parseExpression(&expCtx,
BSON("$trim" << BSON("input"
<< " abc ")),
- expCtx->variablesParseState);
+ expCtx.variablesParseState);
auto optimized = trim->optimize();
auto constant = dynamic_cast<ExpressionConstant*>(optimized.get());
ASSERT_TRUE(constant);
@@ -602,10 +602,10 @@ TEST(ExpressionTrimTest, DoesOptimizeToConstantWithNoChars) {
// Test that it optimizes to a constant if the input also optimizes to a constant.
trim = Expression::parseExpression(
- expCtx,
+ &expCtx,
BSON("$trim" << BSON("input" << BSON("$concat" << BSON_ARRAY(" "
<< "abc ")))),
- expCtx->variablesParseState);
+ expCtx.variablesParseState);
optimized = trim->optimize();
constant = dynamic_cast<ExpressionConstant*>(optimized.get());
ASSERT_TRUE(constant);
@@ -613,13 +613,13 @@ TEST(ExpressionTrimTest, DoesOptimizeToConstantWithNoChars) {
}
TEST(ExpressionTrimTest, DoesOptimizeToConstantWithCustomChars) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
- auto trim = Expression::parseExpression(expCtx,
+ auto expCtx = ExpressionContextForTest{};
+ auto trim = Expression::parseExpression(&expCtx,
BSON("$trim" << BSON("input"
<< " abc "
<< "chars"
<< " ")),
- expCtx->variablesParseState);
+ expCtx.variablesParseState);
auto optimized = trim->optimize();
auto constant = dynamic_cast<ExpressionConstant*>(optimized.get());
ASSERT_TRUE(constant);
@@ -627,11 +627,11 @@ TEST(ExpressionTrimTest, DoesOptimizeToConstantWithCustomChars) {
// Test that it optimizes to a constant if the chars argument optimizes to a constant.
trim = Expression::parseExpression(
- expCtx,
+ &expCtx,
BSON("$trim" << BSON("input"
<< " abc "
<< "chars" << BSON("$substrCP" << BSON_ARRAY(" " << 1 << 1)))),
- expCtx->variablesParseState);
+ expCtx.variablesParseState);
optimized = trim->optimize();
constant = dynamic_cast<ExpressionConstant*>(optimized.get());
ASSERT_TRUE(constant);
@@ -639,12 +639,12 @@ TEST(ExpressionTrimTest, DoesOptimizeToConstantWithCustomChars) {
// Test that it optimizes to a constant if both arguments optimize to a constant.
trim = Expression::parseExpression(
- expCtx,
+ &expCtx,
BSON("$trim" << BSON("input" << BSON("$concat" << BSON_ARRAY(" "
<< "abc "))
<< "chars"
<< BSON("$substrCP" << BSON_ARRAY(" " << 1 << 1)))),
- expCtx->variablesParseState);
+ expCtx.variablesParseState);
optimized = trim->optimize();
constant = dynamic_cast<ExpressionConstant*>(optimized.get());
ASSERT_TRUE(constant);
@@ -652,47 +652,47 @@ TEST(ExpressionTrimTest, DoesOptimizeToConstantWithCustomChars) {
}
TEST(ExpressionTrimTest, DoesNotOptimizeToConstantWithFieldPaths) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
// 'input' is field path.
- auto trim = Expression::parseExpression(expCtx,
+ auto trim = Expression::parseExpression(&expCtx,
BSON("$trim" << BSON("input"
<< "$inputField")),
- expCtx->variablesParseState);
+ expCtx.variablesParseState);
auto optimized = trim->optimize();
auto constant = dynamic_cast<ExpressionConstant*>(optimized.get());
ASSERT_FALSE(constant);
// 'chars' is field path.
- trim = Expression::parseExpression(expCtx,
+ trim = Expression::parseExpression(&expCtx,
BSON("$trim" << BSON("input"
<< " abc "
<< "chars"
<< "$secondInput")),
- expCtx->variablesParseState);
+ expCtx.variablesParseState);
optimized = trim->optimize();
constant = dynamic_cast<ExpressionConstant*>(optimized.get());
ASSERT_FALSE(constant);
// Both are field paths.
- trim = Expression::parseExpression(expCtx,
+ trim = Expression::parseExpression(&expCtx,
BSON("$trim" << BSON("input"
<< "$inputField"
<< "chars"
<< "$secondInput")),
- expCtx->variablesParseState);
+ expCtx.variablesParseState);
optimized = trim->optimize();
constant = dynamic_cast<ExpressionConstant*>(optimized.get());
ASSERT_FALSE(constant);
}
TEST(ExpressionTrimTest, DoesAddInputDependencies) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
- auto trim = Expression::parseExpression(expCtx,
+ auto trim = Expression::parseExpression(&expCtx,
BSON("$trim" << BSON("input"
<< "$inputField")),
- expCtx->variablesParseState);
+ expCtx.variablesParseState);
DepsTracker deps;
trim->addDependencies(&deps);
ASSERT_EQ(deps.fields.count("inputField"), 1u);
@@ -700,14 +700,14 @@ TEST(ExpressionTrimTest, DoesAddInputDependencies) {
}
TEST(ExpressionTrimTest, DoesAddCharsDependencies) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
- auto trim = Expression::parseExpression(expCtx,
+ auto trim = Expression::parseExpression(&expCtx,
BSON("$trim" << BSON("input"
<< "$inputField"
<< "chars"
<< "$$CURRENT.a")),
- expCtx->variablesParseState);
+ expCtx.variablesParseState);
DepsTracker deps;
trim->addDependencies(&deps);
ASSERT_EQ(deps.fields.count("inputField"), 1u);
@@ -716,12 +716,12 @@ TEST(ExpressionTrimTest, DoesAddCharsDependencies) {
}
TEST(ExpressionTrimTest, DoesSerializeCorrectly) {
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
+ auto expCtx = ExpressionContextForTest{};
- auto trim = Expression::parseExpression(expCtx,
+ auto trim = Expression::parseExpression(&expCtx,
BSON("$trim" << BSON("input"
<< " abc ")),
- expCtx->variablesParseState);
+ expCtx.variablesParseState);
ASSERT_VALUE_EQ(trim->serialize(false), trim->serialize(true));
ASSERT_VALUE_EQ(
trim->serialize(false),
@@ -729,25 +729,25 @@ TEST(ExpressionTrimTest, DoesSerializeCorrectly) {
// Make sure we can re-parse it and evaluate it.
auto reparsedTrim = Expression::parseExpression(
- expCtx, trim->serialize(false).getDocument().toBson(), expCtx->variablesParseState);
- ASSERT_VALUE_EQ(reparsedTrim->evaluate({}, &expCtx->variables), Value("abc"_sd));
+ &expCtx, trim->serialize(false).getDocument().toBson(), expCtx.variablesParseState);
+ ASSERT_VALUE_EQ(reparsedTrim->evaluate({}, &expCtx.variables), Value("abc"_sd));
// Use $ltrim, and specify the 'chars' option.
- trim = Expression::parseExpression(expCtx,
+ trim = Expression::parseExpression(&expCtx,
BSON("$ltrim" << BSON("input"
<< "$inputField"
<< "chars"
<< "$$CURRENT.a")),
- expCtx->variablesParseState);
+ expCtx.variablesParseState);
ASSERT_VALUE_EQ(
trim->serialize(false),
Value(Document{{"$ltrim", Document{{"input", "$inputField"_sd}, {"chars", "$a"_sd}}}}));
// Make sure we can re-parse it and evaluate it.
reparsedTrim = Expression::parseExpression(
- expCtx, trim->serialize(false).getDocument().toBson(), expCtx->variablesParseState);
+ &expCtx, trim->serialize(false).getDocument().toBson(), expCtx.variablesParseState);
ASSERT_VALUE_EQ(reparsedTrim->evaluate(Document{{"inputField", " , 4"_sd}, {"a", " ,"_sd}},
- &expCtx->variables),
+ &expCtx.variables),
Value("4"_sd));
}
} // namespace Trim
diff --git a/src/mongo/db/pipeline/expression_walker_test.cpp b/src/mongo/db/pipeline/expression_walker_test.cpp
index 4c409a468b6..60185ad9834 100644
--- a/src/mongo/db/pipeline/expression_walker_test.cpp
+++ b/src/mongo/db/pipeline/expression_walker_test.cpp
@@ -58,7 +58,7 @@ protected:
auto parseExpression(std::string expressionString) {
return Expression::parseExpression(
- getExpCtx(), fromjson(expressionString), getExpCtx()->variablesParseState);
+ getExpCtxRaw(), fromjson(expressionString), getExpCtx()->variablesParseState);
}
};
diff --git a/src/mongo/db/pipeline/make_js_function.cpp b/src/mongo/db/pipeline/make_js_function.cpp
index 531f0bbab74..8cb1e0d32aa 100644
--- a/src/mongo/db/pipeline/make_js_function.cpp
+++ b/src/mongo/db/pipeline/make_js_function.cpp
@@ -35,8 +35,7 @@ namespace mongo {
// Given a function represented as a string, constructs a JS execution context and attempts to parse
// it as a JS function.
-ScriptingFunction makeJsFunc(boost::intrusive_ptr<ExpressionContext> expCtx,
- const std::string& func) {
+ScriptingFunction makeJsFunc(ExpressionContext* const expCtx, const std::string& func) {
auto jsExec =
expCtx->getJsExecWithScope(); // default arg forceLoadOfStoredProcedures is false here.
ScriptingFunction parsedFunc = jsExec->getScope()->createFunction(func.c_str());
diff --git a/src/mongo/db/pipeline/make_js_function.h b/src/mongo/db/pipeline/make_js_function.h
index 7ae894256dc..9b36b23d9a6 100644
--- a/src/mongo/db/pipeline/make_js_function.h
+++ b/src/mongo/db/pipeline/make_js_function.h
@@ -37,7 +37,6 @@ namespace mongo {
/**
* Parses and returns an executable Javascript function.
*/
-ScriptingFunction makeJsFunc(boost::intrusive_ptr<ExpressionContext> expCtx,
- const std::string& func);
+ScriptingFunction makeJsFunc(ExpressionContext* const expCtx, const std::string& func);
} // namespace mongo
diff --git a/src/mongo/db/pipeline/sharded_union_test.cpp b/src/mongo/db/pipeline/sharded_union_test.cpp
index 8756cb0c119..a3c0ad65af8 100644
--- a/src/mongo/db/pipeline/sharded_union_test.cpp
+++ b/src/mongo/db/pipeline/sharded_union_test.cpp
@@ -202,13 +202,14 @@ TEST_F(ShardedUnionTest, CorrectlySplitsSubPipelineIfRefreshedDistributionRequir
auto&& parser = AccumulationStatement::getParser("$sum", boost::none);
auto accumulatorArg = BSON("" << 1);
auto sumStatement =
- parser(expCtx(), accumulatorArg.firstElement(), expCtx()->variablesParseState);
+ parser(expCtx().get(), accumulatorArg.firstElement(), expCtx()->variablesParseState);
AccumulationStatement countStatement{"count", sumStatement};
auto pipeline = Pipeline::create(
{DocumentSourceMatch::create(fromjson("{_id: {$gte: 0}}"), expCtx()),
- DocumentSourceGroup::create(
- expCtx(), ExpressionConstant::create(expCtx(), Value(BSONNULL)), {countStatement})},
- expCtx());
+ DocumentSourceGroup::create(expCtx(),
+ ExpressionConstant::create(expCtx().get(), Value(BSONNULL)),
+ {countStatement})},
+ expCtx().get());
auto unionWith = DocumentSourceUnionWith(expCtx(), std::move(pipeline));
expCtx()->mongoProcessInterface = std::make_shared<ShardServerProcessInterface>(executor());
auto queue = DocumentSourceQueue::create(expCtx());
@@ -290,12 +291,13 @@ TEST_F(ShardedUnionTest, AvoidsSplittingSubPipelineIfRefreshedDistributionDoesNo
auto&& parser = AccumulationStatement::getParser("$sum", boost::none);
auto accumulatorArg = BSON("" << 1);
auto sumStatement =
- parser(expCtx(), accumulatorArg.firstElement(), expCtx()->variablesParseState);
+ parser(expCtx().get(), accumulatorArg.firstElement(), expCtx()->variablesParseState);
AccumulationStatement countStatement{"count", sumStatement};
auto pipeline = Pipeline::create(
- {DocumentSourceGroup::create(
- expCtx(), ExpressionConstant::create(expCtx(), Value(BSONNULL)), {countStatement})},
- expCtx());
+ {DocumentSourceGroup::create(expCtx(),
+ ExpressionConstant::create(expCtx().get(), Value(BSONNULL)),
+ {countStatement})},
+ expCtx().get());
auto unionWith = DocumentSourceUnionWith(expCtx(), std::move(pipeline));
expCtx()->mongoProcessInterface = std::make_shared<ShardServerProcessInterface>(executor());
auto queue = DocumentSourceQueue::create(expCtx());
@@ -423,12 +425,13 @@ TEST_F(ShardedUnionTest, ForwardsReadConcernToRemotes) {
auto&& parser = AccumulationStatement::getParser("$sum", boost::none);
auto accumulatorArg = BSON("" << 1);
auto sumExpression =
- parser(expCtx(), accumulatorArg.firstElement(), expCtx()->variablesParseState);
+ parser(expCtx().get(), accumulatorArg.firstElement(), expCtx()->variablesParseState);
AccumulationStatement countStatement{"count", sumExpression};
auto pipeline = Pipeline::create(
- {DocumentSourceGroup::create(
- expCtx(), ExpressionConstant::create(expCtx(), Value(BSONNULL)), {countStatement})},
- expCtx());
+ {DocumentSourceGroup::create(expCtx(),
+ ExpressionConstant::create(expCtx().get(), Value(BSONNULL)),
+ {countStatement})},
+ expCtx().get());
auto unionWith = DocumentSourceUnionWith(expCtx(), std::move(pipeline));
expCtx()->mongoProcessInterface = std::make_shared<ShardServerProcessInterface>(executor());
auto queue = DocumentSourceQueue::create(expCtx());
diff --git a/src/mongo/db/pipeline/variables.cpp b/src/mongo/db/pipeline/variables.cpp
index 060bcda8fc4..b64ec45db00 100644
--- a/src/mongo/db/pipeline/variables.cpp
+++ b/src/mongo/db/pipeline/variables.cpp
@@ -239,7 +239,7 @@ BSONObj Variables::serializeLetParameters(const VariablesParseState& vps) const
bob << kIdToBuiltinVarName.at(id) << value;
return bob.appendElements(vps.serialize(*this)).obj();
}
-void Variables::seedVariablesWithLetParameters(boost::intrusive_ptr<ExpressionContext> expCtx,
+void Variables::seedVariablesWithLetParameters(ExpressionContext* const expCtx,
const BSONObj letParams) {
for (auto&& elem : letParams) {
Variables::validateNameForUserWrite(elem.fieldName());
diff --git a/src/mongo/db/pipeline/variables.h b/src/mongo/db/pipeline/variables.h
index b6ff28110d1..b868f51f4e0 100644
--- a/src/mongo/db/pipeline/variables.h
+++ b/src/mongo/db/pipeline/variables.h
@@ -169,7 +169,7 @@ public:
/**
* Seed let parameters with the given BSONObj.
*/
- void seedVariablesWithLetParameters(boost::intrusive_ptr<ExpressionContext> expCtx,
+ void seedVariablesWithLetParameters(ExpressionContext* const expCtx,
const BSONObj letParameters);
bool hasValue(Variables::Id id) const {
diff --git a/src/mongo/db/query/canonical_query.h b/src/mongo/db/query/canonical_query.h
index ca5199e3502..39a6ac8ec47 100644
--- a/src/mongo/db/query/canonical_query.h
+++ b/src/mongo/db/query/canonical_query.h
@@ -208,9 +208,12 @@ public:
return _canHaveNoopMatchNodes;
}
- const boost::intrusive_ptr<ExpressionContext>& getExpCtx() const {
+ auto& getExpCtx() const {
return _expCtx;
}
+ auto getExpCtxRaw() const {
+ return _expCtx.get();
+ }
private:
// You must go through canonicalize to create a CanonicalQuery.
diff --git a/src/mongo/db/query/get_executor.cpp b/src/mongo/db/query/get_executor.cpp
index dbbecb419b5..9a512acafdb 100644
--- a/src/mongo/db/query/get_executor.cpp
+++ b/src/mongo/db/query/get_executor.cpp
@@ -385,7 +385,7 @@ StatusWith<PrepareExecutionResult> prepareExecution(OperationContext* opCtx,
"Collection {ns} does not exist. Using EOF plan: {canonicalQuery_Short}",
"ns"_attr = ns,
"canonicalQuery_Short"_attr = redact(canonicalQuery->toStringShort()));
- root = std::make_unique<EOFStage>(canonicalQuery->getExpCtx().get());
+ root = std::make_unique<EOFStage>(canonicalQuery->getExpCtxRaw());
return PrepareExecutionResult(std::move(canonicalQuery), nullptr, std::move(root));
}
@@ -411,12 +411,12 @@ StatusWith<PrepareExecutionResult> prepareExecution(OperationContext* opCtx,
"canonicalQuery_Short"_attr = redact(canonicalQuery->toStringShort()));
root = std::make_unique<IDHackStage>(
- canonicalQuery->getExpCtx().get(), canonicalQuery.get(), ws, descriptor);
+ canonicalQuery->getExpCtxRaw(), canonicalQuery.get(), ws, descriptor);
// Might have to filter out orphaned docs.
if (plannerParams.options & QueryPlannerParams::INCLUDE_SHARD_FILTER) {
root = std::make_unique<ShardFilterStage>(
- canonicalQuery->getExpCtx().get(),
+ canonicalQuery->getExpCtxRaw(),
CollectionShardingState::get(opCtx, canonicalQuery->nss())
->getOwnershipFilter(
opCtx,
@@ -430,7 +430,7 @@ StatusWith<PrepareExecutionResult> prepareExecution(OperationContext* opCtx,
// Add a SortKeyGeneratorStage if the query requested sortKey metadata.
if (canonicalQuery->metadataDeps()[DocumentMetadataFields::kSortKey]) {
root = std::make_unique<SortKeyGeneratorStage>(
- canonicalQuery->getExpCtx().get(),
+ canonicalQuery->getExpCtxRaw(),
std::move(root),
ws,
canonicalQuery->getQueryRequest().getSort());
@@ -442,7 +442,7 @@ StatusWith<PrepareExecutionResult> prepareExecution(OperationContext* opCtx,
// the exception the $meta sortKey projection, which can be used along with the
// returnKey.
root = std::make_unique<ReturnKeyStage>(
- canonicalQuery->getExpCtx().get(),
+ canonicalQuery->getExpCtxRaw(),
cqProjection
? QueryPlannerCommon::extractSortKeyMetaFieldsFromProjection(*cqProjection)
: std::vector<FieldPath>{},
@@ -462,7 +462,7 @@ StatusWith<PrepareExecutionResult> prepareExecution(OperationContext* opCtx,
std::move(root));
} else {
root = std::make_unique<ProjectionStageSimple>(
- canonicalQuery->getExpCtx().get(),
+ canonicalQuery->getExpCtxRaw(),
canonicalQuery->getQueryRequest().getProj(),
canonicalQuery->getProj(),
ws,
@@ -518,7 +518,7 @@ StatusWith<PrepareExecutionResult> prepareExecution(OperationContext* opCtx,
// 'decisionWorks' is used to determine whether the existing cache entry should
// be evicted, and the query replanned.
auto cachedPlanStage =
- std::make_unique<CachedPlanStage>(canonicalQuery->getExpCtx().get(),
+ std::make_unique<CachedPlanStage>(canonicalQuery->getExpCtxRaw(),
collection,
ws,
canonicalQuery.get(),
@@ -540,7 +540,7 @@ StatusWith<PrepareExecutionResult> prepareExecution(OperationContext* opCtx,
"canonicalQuery_Short"_attr = redact(canonicalQuery->toStringShort()));
root = std::make_unique<SubplanStage>(
- canonicalQuery->getExpCtx().get(), collection, ws, plannerParams, canonicalQuery.get());
+ canonicalQuery->getExpCtxRaw(), collection, ws, plannerParams, canonicalQuery.get());
return PrepareExecutionResult(std::move(canonicalQuery), nullptr, std::move(root));
}
@@ -593,7 +593,7 @@ StatusWith<PrepareExecutionResult> prepareExecution(OperationContext* opCtx,
// Many solutions. Create a MultiPlanStage to pick the best, update the cache,
// and so on. The working set will be shared by all candidate plans.
auto multiPlanStage = std::make_unique<MultiPlanStage>(
- canonicalQuery->getExpCtx().get(), collection, canonicalQuery.get());
+ canonicalQuery->getExpCtxRaw(), collection, canonicalQuery.get());
for (size_t ix = 0; ix < solutions.size(); ++ix) {
if (solutions[ix]->cacheData.get()) {
@@ -870,7 +870,7 @@ StatusWith<unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorDelete(
invariant(root);
root = std::make_unique<DeleteStage>(
- cq->getExpCtx().get(), std::move(deleteStageParams), ws.get(), collection, root.release());
+ cq->getExpCtxRaw(), std::move(deleteStageParams), ws.get(), collection, root.release());
if (projection) {
root = std::make_unique<ProjectionStageDefault>(
@@ -1037,12 +1037,11 @@ StatusWith<unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorUpdate(
updateStageParams.canonicalQuery = cq.get();
const bool isUpsert = updateStageParams.request->isUpsert();
- root =
- (isUpsert
- ? std::make_unique<UpsertStage>(
- cq->getExpCtx().get(), updateStageParams, ws.get(), collection, root.release())
- : std::make_unique<UpdateStage>(
- cq->getExpCtx().get(), updateStageParams, ws.get(), collection, root.release()));
+ root = (isUpsert
+ ? std::make_unique<UpsertStage>(
+ cq->getExpCtxRaw(), updateStageParams, ws.get(), collection, root.release())
+ : std::make_unique<UpdateStage>(
+ cq->getExpCtxRaw(), updateStageParams, ws.get(), collection, root.release()));
if (projection) {
root = std::make_unique<ProjectionStageDefault>(
diff --git a/src/mongo/db/query/projection_parser.cpp b/src/mongo/db/query/projection_parser.cpp
index 5d7d2517287..54f050b7353 100644
--- a/src/mongo/db/query/projection_parser.cpp
+++ b/src/mongo/db/query/projection_parser.cpp
@@ -295,7 +295,7 @@ bool attemptToParseGenericExpression(ParseContext* parseCtx,
}
auto expr = Expression::parseExpression(
- parseCtx->expCtx, subObj, parseCtx->expCtx->variablesParseState);
+ parseCtx->expCtx.get(), subObj, parseCtx->expCtx->variablesParseState);
addNodeAtPath(parent, path, std::make_unique<ExpressionASTNode>(expr));
parseCtx->hasMeta = parseCtx->hasMeta || isMeta;
return true;
@@ -468,7 +468,7 @@ void parseExclusion(ParseContext* ctx, BSONElement elem, ProjectionPathASTNode*
void parseLiteral(ParseContext* ctx, BSONElement elem, ProjectionPathASTNode* parent) {
verifyComputedFieldsAllowed(ctx->policies);
- auto expr = Expression::parseOperand(ctx->expCtx, elem, ctx->expCtx->variablesParseState);
+ auto expr = Expression::parseOperand(ctx->expCtx.get(), elem, ctx->expCtx->variablesParseState);
FieldPath pathFromParent(elem.fieldNameStringData());
addNodeAtPath(parent, pathFromParent, std::make_unique<ExpressionASTNode>(expr));
diff --git a/src/mongo/db/query/sort_pattern.cpp b/src/mongo/db/query/sort_pattern.cpp
index 99590ba1275..a7fff3f9061 100644
--- a/src/mongo/db/query/sort_pattern.cpp
+++ b/src/mongo/db/query/sort_pattern.cpp
@@ -64,8 +64,8 @@ SortPattern::SortPattern(const BSONObj& obj,
} else {
uasserted(31138, str::stream() << "Illegal $meta sort: " << metaElem);
}
- patternPart.expression =
- static_cast<ExpressionMeta*>(ExpressionMeta::parse(pExpCtx, metaElem, vps).get());
+ patternPart.expression = static_cast<ExpressionMeta*>(
+ ExpressionMeta::parse(pExpCtx.get(), metaElem, vps).get());
// If sorting by textScore, sort highest scores first. If sorting by randVal, order
// doesn't matter, so just always use descending.
diff --git a/src/mongo/db/query/stage_builder.cpp b/src/mongo/db/query/stage_builder.cpp
index 3b9dad99a0f..4434c97d928 100644
--- a/src/mongo/db/query/stage_builder.cpp
+++ b/src/mongo/db/query/stage_builder.cpp
@@ -74,7 +74,7 @@ std::unique_ptr<PlanStage> buildStages(OperationContext* opCtx,
const QuerySolution& qsol,
const QuerySolutionNode* root,
WorkingSet* ws) {
- auto* const expCtx = cq.getExpCtx().get();
+ auto* const expCtx = cq.getExpCtxRaw();
switch (root->getType()) {
case STAGE_COLLSCAN: {
const CollectionScanNode* csn = static_cast<const CollectionScanNode*>(root);
@@ -171,7 +171,7 @@ std::unique_ptr<PlanStage> buildStages(OperationContext* opCtx,
case STAGE_PROJECTION_COVERED: {
auto pn = static_cast<const ProjectionNodeCovered*>(root);
auto childStage = buildStages(opCtx, collection, cq, qsol, pn->children[0], ws);
- return std::make_unique<ProjectionStageCovered>(cq.getExpCtx().get(),
+ return std::make_unique<ProjectionStageCovered>(cq.getExpCtxRaw(),
cq.getQueryRequest().getProj(),
cq.getProj(),
ws,
@@ -181,7 +181,7 @@ std::unique_ptr<PlanStage> buildStages(OperationContext* opCtx,
case STAGE_PROJECTION_SIMPLE: {
auto pn = static_cast<const ProjectionNodeSimple*>(root);
auto childStage = buildStages(opCtx, collection, cq, qsol, pn->children[0], ws);
- return std::make_unique<ProjectionStageSimple>(cq.getExpCtx().get(),
+ return std::make_unique<ProjectionStageSimple>(cq.getExpCtxRaw(),
cq.getQueryRequest().getProj(),
cq.getProj(),
ws,
diff --git a/src/mongo/dbtests/query_plan_executor.cpp b/src/mongo/dbtests/query_plan_executor.cpp
index fd7b3f6a111..15c069c04d8 100644
--- a/src/mongo/dbtests/query_plan_executor.cpp
+++ b/src/mongo/dbtests/query_plan_executor.cpp
@@ -116,7 +116,7 @@ public:
// Make the stage.
unique_ptr<PlanStage> root(
- new CollectionScan(cq->getExpCtx().get(), coll, csparams, ws.get(), cq.get()->root()));
+ new CollectionScan(cq->getExpCtxRaw(), coll, csparams, ws.get(), cq.get()->root()));
// Hand the plan off to the executor.
auto statusWithPlanExecutor =