summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--buildscripts/resmokeconfig/suites/aggregation_one_shard_sharded_collections.yml1
-rw-r--r--buildscripts/resmokeconfig/suites/aggregation_sharded_collections_passthrough.yml1
-rw-r--r--jstests/aggregation/bugs/server9840.js99
-rw-r--r--jstests/aggregation/expressions/let.js132
-rw-r--r--jstests/aggregation/sources/graphLookup/variables.js41
-rw-r--r--jstests/aggregation/sources/lookup/lookup_subpipeline.js17
-rw-r--r--jstests/concurrency/fsm_workloads/schema_validator_with_expr_variables.js80
-rw-r--r--src/mongo/db/matcher/expression_expr.cpp7
-rw-r--r--src/mongo/db/pipeline/document_source_bucket_auto.cpp5
-rw-r--r--src/mongo/db/pipeline/document_source_graph_lookup.cpp2
-rw-r--r--src/mongo/db/pipeline/document_source_group.cpp11
-rw-r--r--src/mongo/db/pipeline/document_source_lookup.cpp2
-rw-r--r--src/mongo/db/pipeline/document_source_merge.h2
-rw-r--r--src/mongo/db/pipeline/document_source_redact.cpp2
-rw-r--r--src/mongo/db/pipeline/document_source_replace_root.cpp2
-rw-r--r--src/mongo/db/pipeline/document_source_sort.cpp2
-rw-r--r--src/mongo/db/pipeline/expression.cpp493
-rw-r--r--src/mongo/db/pipeline/expression.h183
-rw-r--r--src/mongo/db/pipeline/expression_convert_test.cpp1300
-rw-r--r--src/mongo/db/pipeline/expression_date_test.cpp235
-rw-r--r--src/mongo/db/pipeline/expression_test.cpp291
-rw-r--r--src/mongo/db/pipeline/expression_trigonometric_test.cpp4
-rw-r--r--src/mongo/db/pipeline/granularity_rounder_powers_of_two.cpp6
-rw-r--r--src/mongo/db/pipeline/parsed_aggregation_projection_node.cpp5
24 files changed, 1164 insertions, 1759 deletions
diff --git a/buildscripts/resmokeconfig/suites/aggregation_one_shard_sharded_collections.yml b/buildscripts/resmokeconfig/suites/aggregation_one_shard_sharded_collections.yml
index 31e4f3bbcdc..089e566dcdc 100644
--- a/buildscripts/resmokeconfig/suites/aggregation_one_shard_sharded_collections.yml
+++ b/buildscripts/resmokeconfig/suites/aggregation_one_shard_sharded_collections.yml
@@ -14,7 +14,6 @@ selector:
- jstests/aggregation/bugs/groupMissing.js
# TODO SERVER-32309: Enable once $lookup with pipeline supports sharded foreign collections.
- jstests/aggregation/sources/lookup/lookup_subpipeline.js
- - jstests/aggregation/sources/graphLookup/variables.js
exclude_with_any_tags:
# Tests tagged with the following will fail because they assume collections are not sharded.
- assumes_no_implicit_collection_creation_after_drop
diff --git a/buildscripts/resmokeconfig/suites/aggregation_sharded_collections_passthrough.yml b/buildscripts/resmokeconfig/suites/aggregation_sharded_collections_passthrough.yml
index 53520f6a460..5f1410e240e 100644
--- a/buildscripts/resmokeconfig/suites/aggregation_sharded_collections_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/aggregation_sharded_collections_passthrough.yml
@@ -25,7 +25,6 @@ selector:
- jstests/aggregation/bugs/groupMissing.js
# TODO SERVER-32309: Enable once $lookup with pipeline supports sharded foreign collections.
- jstests/aggregation/sources/lookup/lookup_subpipeline.js
- - jstests/aggregation/sources/graphLookup/variables.js
exclude_with_any_tags:
# Tests tagged with the following will fail because they assume collections are not sharded.
- assumes_no_implicit_collection_creation_after_drop
diff --git a/jstests/aggregation/bugs/server9840.js b/jstests/aggregation/bugs/server9840.js
new file mode 100644
index 00000000000..4316730370a
--- /dev/null
+++ b/jstests/aggregation/bugs/server9840.js
@@ -0,0 +1,99 @@
+// SERVER-9840 variables in expressions and $let
+
+load('jstests/aggregation/extras/utils.js');
+var t = db.server9840;
+t.drop();
+
+function test(expression, expected) {
+ t.drop();
+ t.insert({zero: 0, one: 1, two: 2, three: 3, nested: {four: 4}});
+
+ // Test in projection:
+ var result = t.aggregate({$project: {_id: 0, res: expression}}).toArray();
+ assert.eq(result, [{res: expected}]);
+
+ // Test in group:
+ var result = t.aggregate({$group: {_id: 0, res: {$sum: expression}}}).toArray();
+ assert.eq(result, [{_id: 0, res: expected}]);
+}
+
+// basics
+test('$two', 2);
+test('$$CURRENT.two', 2);
+test('$$ROOT.two', 2);
+
+// using sub expressions
+test({$add: ['$two', '$$CURRENT.three']}, 5);
+test({$add: ['$$CURRENT.two', '$$ROOT.nested.four']}, 6);
+
+// $let simple
+test({$let: {vars: {a: 10}, in : '$$a'}}, 10);
+test({$let: {vars: {a: '$zero'}, in : '$$a'}}, 0);
+test({$let: {vars: {a: {$add: ['$one', '$two']}, b: 10}, in : {$multiply: ['$$a', '$$b']}}}, 30);
+
+// $let changing CURRENT
+test({$let: {vars: {CURRENT: '$$ROOT.nested'}, in : {$multiply: ['$four', '$$ROOT.two']}}}, 8);
+test({
+ $let: {
+ vars: {CURRENT: '$$CURRENT.nested'}, // using original value of CURRENT
+ in : {$multiply: ['$four', '$$ROOT.two']}
+ }
+},
+ 8);
+test({
+ $let: {
+ vars: {CURRENT: '$nested'}, // same as last
+ in : {$multiply: ['$four', '$$ROOT.two']}
+ }
+},
+ 8);
+test({
+ $let: {
+ vars: {CURRENT: {$const: {ten: 10}}}, // "artificial" object
+ in : {$multiply: ['$ten', '$$ROOT.two']}
+ }
+},
+ 20);
+test({
+ $let: {
+ vars: {CURRENT: '$three'}, // sets current to the number 3 (not an object)
+ in : {$multiply: ['$$CURRENT', '$$ROOT.two']}
+ }
+},
+ 6);
+
+// swapping with $let (ensures there is no ordering dependency in vars)
+test({
+ $let: {
+ vars: {x: 6, y: 10},
+ in : {
+ $let: {
+ vars: {x: '$$y', y: '$$x'}, // now {x:10, y:6}
+ in : {$subtract: ['$$x', '$$y']}
+ }
+ }
+ }
+}, // not commutative!
+ 4); // 10-6 not 6-10 or 6-6
+
+// unicode is allowed
+test({$let: {vars: {'日本語': 10}, in : '$$日本語'}}, 10); // Japanese for "Japanese language"
+
+// Can use ROOT and CURRENT directly with no subfield (SERVER-5916)
+t.drop();
+t.insert({_id: 'obj'});
+assert.eq(t.aggregate({$project: {_id: 0, obj: '$$ROOT'}}).toArray(), [{obj: {_id: 'obj'}}]);
+assert.eq(t.aggregate({$project: {_id: 0, obj: '$$CURRENT'}}).toArray(), [{obj: {_id: 'obj'}}]);
+assert.eq(t.aggregate({$group: {_id: 0, objs: {$push: '$$ROOT'}}}).toArray(),
+ [{_id: 0, objs: [{_id: 'obj'}]}]);
+assert.eq(t.aggregate({$group: {_id: 0, objs: {$push: '$$CURRENT'}}}).toArray(),
+ [{_id: 0, objs: [{_id: 'obj'}]}]);
+
+// check name validity checks
+assertErrorCode(t, {$project: {a: {$let: {vars: {ROOT: 1}, in : '$$ROOT'}}}}, 16867);
+assertErrorCode(t, {$project: {a: {$let: {vars: {FOO: 1}, in : '$$FOO'}}}}, 16867);
+assertErrorCode(t, {$project: {a: {$let: {vars: {_underbar: 1}, in : '$$FOO'}}}}, 16867);
+assertErrorCode(t, {$project: {a: {$let: {vars: {'a.b': 1}, in : '$$FOO'}}}}, 16868);
+assertErrorCode(t, {$project: {a: {$let: {vars: {'a b': 1}, in : '$$FOO'}}}}, 16868);
+assertErrorCode(t, {$project: {a: '$$_underbar'}}, 16870);
+assertErrorCode(t, {$project: {a: '$$with spaces'}}, 16871);
diff --git a/jstests/aggregation/expressions/let.js b/jstests/aggregation/expressions/let.js
deleted file mode 100644
index 5de6db8eebf..00000000000
--- a/jstests/aggregation/expressions/let.js
+++ /dev/null
@@ -1,132 +0,0 @@
-/**
- * Basic integration tests for the $let expression.
- */
-(function() {
- "use strict";
-
- load("jstests/aggregation/extras/utils.js"); // For assertErrorCode.
-
- let coll = db.agg_expr_let;
- coll.drop();
- assert.commandWorked(coll.insert({zero: 0, one: 1, two: 2, three: 3, nested: {four: 4}}));
-
- function testExpr(expression, output) {
- const res = coll.aggregate([{$project: {output: expression}}]).toArray();
- assert.eq(res.length, 1, tojson(res));
- assert.eq(res[0].output, output, tojson(res));
-
- // Test in group:
- const result = coll.aggregate({$group: {_id: 0, res: {$sum: expression}}}).toArray();
- assert.eq(result, [{_id: 0, res: output}]);
- }
-
- // Basic tests.
- testExpr('$two', 2);
- testExpr('$$CURRENT.two', 2);
- testExpr('$$ROOT.two', 2);
-
- // Using sub expressions.
- testExpr({$add: ['$two', '$$CURRENT.three']}, 5);
- testExpr({$add: ['$$CURRENT.two', '$$ROOT.nested.four']}, 6);
-
- // Verify that the variables defined in $let work.
- testExpr({$let: {vars: {a: 10}, in : '$$a'}}, 10);
- testExpr({$let: {vars: {a: '$zero'}, in : '$$a'}}, 0);
- testExpr({$let: {vars: {a: {$add: ['$one', '$two']}, b: 10}, in : {$multiply: ['$$a', '$$b']}}},
- 30);
-
- // Verify that the outer level variable works in inner level $let.
- testExpr({
- $let: {
- vars: {var1: 1},
- in : {$let: {vars: {var2: "$$var1"}, in : {$sum: ["$$var1", "$$var2"]}}}
- }
- },
- 2);
-
- // Verify that the outer level variables get overwritten by inner level variables.
- testExpr({
- $let: {
- vars: {var1: "$one"},
- in : {$let: {vars: {var2: "$$var1", var1: 3}, in : {$sum: ["$$var2", "$$var1"]}}}
- }
- },
- 4);
-
- // $let changing CURRENT
- testExpr({$let: {vars: {CURRENT: '$$ROOT.nested'}, in : {$multiply: ['$four', '$$ROOT.two']}}},
- 8);
- testExpr({
- $let: {
- vars: {CURRENT: '$$CURRENT.nested'}, // using original value of CURRENT
- in : {$multiply: ['$four', '$$ROOT.two']}
- }
- },
- 8);
- testExpr({
- $let: {
- vars: {CURRENT: '$nested'}, // same as last
- in : {$multiply: ['$four', '$$ROOT.two']}
- }
- },
- 8);
- testExpr({
- $let: {
- vars: {CURRENT: {$const: {ten: 10}}}, // "artificial" object
- in : {$multiply: ['$ten', '$$ROOT.two']}
- }
- },
- 20);
- testExpr({
- $let: {
- vars: {CURRENT: '$three'}, // sets current to the number 3 (not an object)
- in : {$multiply: ['$$CURRENT', '$$ROOT.two']}
- }
- },
- 6);
-
- // Swapping with $let (ensures there is no ordering dependency in vars).
- testExpr({
- $let: {
- vars: {x: 6, y: 10},
- in : {
- $let: {
- vars: {x: '$$y', y: '$$x'}, // now {x:10, y:6}
- in : {$subtract: ['$$x', '$$y']}
- }
- }
- }
- }, // Not commutative!
- 4); // 10-6 not 6-10 or 6-6
-
- // Unicode is allowed.
- testExpr({$let: {vars: {'日本語': 10}, in : '$$日本語'}},
- 10); // Japanese for "Japanese language".
-
- // Can use ROOT and CURRENT directly with no subfield (SERVER-5916).
- coll.drop();
- coll.insert({_id: 'obj'});
- assert.eq(coll.aggregate({$project: {_id: 0, obj: '$$ROOT'}}).toArray(), [{obj: {_id: 'obj'}}]);
- assert.eq(coll.aggregate({$project: {_id: 0, obj: '$$CURRENT'}}).toArray(),
- [{obj: {_id: 'obj'}}]);
- assert.eq(coll.aggregate({$group: {_id: 0, objs: {$push: '$$ROOT'}}}).toArray(),
- [{_id: 0, objs: [{_id: 'obj'}]}]);
- assert.eq(coll.aggregate({$group: {_id: 0, objs: {$push: '$$CURRENT'}}}).toArray(),
- [{_id: 0, objs: [{_id: 'obj'}]}]);
-
- // Check name validity checks.
- assertErrorCode(coll, {$project: {a: {$let: {vars: {ROOT: 1}, in : '$$ROOT'}}}}, 16867);
- assertErrorCode(coll, {$project: {a: {$let: {vars: {FOO: 1}, in : '$$FOO'}}}}, 16867);
- assertErrorCode(coll, {$project: {a: {$let: {vars: {_underbar: 1}, in : '$$FOO'}}}}, 16867);
- assertErrorCode(coll, {$project: {a: {$let: {vars: {'a.b': 1}, in : '$$FOO'}}}}, 16868);
- assertErrorCode(coll, {$project: {a: {$let: {vars: {'a b': 1}, in : '$$FOO'}}}}, 16868);
- assertErrorCode(coll, {$project: {a: '$$_underbar'}}, 16870);
- assertErrorCode(coll, {$project: {a: '$$with spaces'}}, 16871);
-
- // Verify that variables defined in '$let' cannot be used to initialize other variables.
- assertErrorCode(
- coll,
- [{$project: {output: {$let: {vars: {var1: "$one", var2: "$$var1"}, in : "$$var1"}}}}],
- 17276);
-
-}());
diff --git a/jstests/aggregation/sources/graphLookup/variables.js b/jstests/aggregation/sources/graphLookup/variables.js
deleted file mode 100644
index 87e2c8b3975..00000000000
--- a/jstests/aggregation/sources/graphLookup/variables.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * Tests to verify that $graphLookup can use the variables defined in an outer scope.
- */
-(function() {
- "use strict";
-
- let local = db.graph_lookup_var_local;
- let foreign = db.graph_lookup_var_foreign;
- local.drop();
- foreign.drop();
-
- foreign.insert({from: "b", to: "a", _id: 0});
- local.insert({});
-
- const basicGraphLookup = {
- $graphLookup: {
- from: "graph_lookup_var_foreign",
- startWith: "$$var1",
- connectFromField: "from",
- connectToField: "to",
- as: "resultsFromGraphLookup"
- }
- };
-
- const lookup = {
- $lookup: {
- from: "graph_lookup_var_local",
- let : {var1: "a"},
- pipeline: [basicGraphLookup],
- as: "resultsFromLookup"
- }
- };
-
- // Verify that $graphLookup can use the variable 'var1' which is defined in parent $lookup.
- let res = local.aggregate([lookup]).toArray();
- assert.eq(res.length, 1);
- assert.eq(res[0].resultsFromLookup.length, 1);
- assert.eq(res[0].resultsFromLookup[0].resultsFromGraphLookup.length, 1);
- assert.eq(res[0].resultsFromLookup[0].resultsFromGraphLookup[0], {_id: 0, from: "b", to: "a"});
-
-})();
diff --git a/jstests/aggregation/sources/lookup/lookup_subpipeline.js b/jstests/aggregation/sources/lookup/lookup_subpipeline.js
index 39d2ff0d850..bb7bddc3eca 100644
--- a/jstests/aggregation/sources/lookup/lookup_subpipeline.js
+++ b/jstests/aggregation/sources/lookup/lookup_subpipeline.js
@@ -376,23 +376,6 @@
}
}],
17276);
- assertErrorCode(
- coll,
- [{$lookup: {let : {var1: 1, var2: "$$var1"}, pipeline: [], from: "from", as: "as"}}],
- 17276);
- assertErrorCode(coll,
- [{
- $lookup: {
- let : {
- var1: {$let: {vars: {var1: 2}, in : "$$var1"}},
- var2: {$let: {vars: {var1: 4}, in : "$$var2"}},
- },
- pipeline: [],
- from: "from",
- as: "as"
- }
- }],
- 17276);
// The dotted path offset of a non-object variable is equivalent referencing an undefined
// field.
diff --git a/jstests/concurrency/fsm_workloads/schema_validator_with_expr_variables.js b/jstests/concurrency/fsm_workloads/schema_validator_with_expr_variables.js
deleted file mode 100644
index ea847215a29..00000000000
--- a/jstests/concurrency/fsm_workloads/schema_validator_with_expr_variables.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * Test to verify that the schema validator works correctly in a multi-threaded environment, when
- * $expr uses expressions which mutate variable values while executing ($let, $map etc).
- * @tags: [requires_non_retryable_writes]
- */
-
-"use strict";
-
-var $config = (function() {
- function setup(db, collName) {
- for (let i = 0; i < 200; ++i) {
- assertAlways.commandWorked(
- db[collName].insert({_id: i, a: i, one: 1, counter: 0, array: [0, i]}));
- }
-
- // Add a validator which checks that field 'a' has value 5 and sum of the elements in field
- // 'array' is 5. The expression is purposefully complex so that it can create a stress on
- // expressions with variables.
- assertAlways.commandWorked(db.runCommand({
- collMod: collName,
- validator: {
- $expr: {
- $and: [
- {
- $eq: [
- 5,
- {
- $let: {
- vars: {item: {$multiply: ["$a", "$one"]}},
- in : {$multiply: ["$$item", "$one"]}
- }
- }
- ]
- },
- {
- $eq: [
- 5,
- {
- $sum: {
- $map:
- {"input": "$array", "as": "item", "in": "$$item"}
- }
- }
- ]
- }
- ]
- }
- }
- }));
- }
-
- const states = {
- applyValidator: function(db, collName) {
- assertAlways.commandWorked(db[collName].update({_id: 5}, {$inc: {counter: 1}}));
- assertAlways.commandFailedWithCode(
- db[collName].update({_id: 4}, {$set: {a: 4}, $inc: {counter: 1}}),
- ErrorCodes.DocumentValidationFailure);
-
- // Update all the documents in the collection.
- assertAlways.commandWorked(db[collName].update(
- {}, {$set: {a: 5, array: [2, 3]}, $inc: {counter: 1}}, {multi: true}));
-
- // Validation fails when elements of 'array' doesn't add up to 5.
- assertAlways.commandFailedWithCode(
- db[collName].update({_id: 4}, {$set: {a: 5, array: [2, 2]}}),
- ErrorCodes.DocumentValidationFailure);
- }
- };
-
- let transitions = {applyValidator: {applyValidator: 1}};
-
- return {
- threadCount: 50,
- iterations: 100,
- states: states,
- startState: "applyValidator",
- transitions: transitions,
- setup: setup
- };
-})();
diff --git a/src/mongo/db/matcher/expression_expr.cpp b/src/mongo/db/matcher/expression_expr.cpp
index f356c4aa25b..f58c1c14ef8 100644
--- a/src/mongo/db/matcher/expression_expr.cpp
+++ b/src/mongo/db/matcher/expression_expr.cpp
@@ -53,13 +53,8 @@ bool ExprMatchExpression::matches(const MatchableDocument* doc, MatchDetails* de
}
Document document(doc->toBSON());
-
- // 'Variables' is not thread safe, and ExprMatchExpression may be used in a validator which
- // processes documents from multiple threads simultaneously. Hence we make a copy of the
- // 'Variables' object per-caller.
- Variables variables = _expCtx->variables;
try {
- auto value = _expression->evaluate(document, &variables);
+ auto value = _expression->evaluate(document);
return value.coerceToBool();
} catch (const DBException&) {
if (MONGO_FAIL_POINT(ExprMatchExpressionMatchesReturnsFalseOnException)) {
diff --git a/src/mongo/db/pipeline/document_source_bucket_auto.cpp b/src/mongo/db/pipeline/document_source_bucket_auto.cpp
index dbbf6c7b1f7..ff5eeeb285a 100644
--- a/src/mongo/db/pipeline/document_source_bucket_auto.cpp
+++ b/src/mongo/db/pipeline/document_source_bucket_auto.cpp
@@ -157,7 +157,7 @@ Value DocumentSourceBucketAuto::extractKey(const Document& doc) {
return Value(BSONNULL);
}
- Value key = _groupByExpression->evaluate(doc, &pExpCtx->variables);
+ Value key = _groupByExpression->evaluate(doc);
if (_granularityRounder) {
uassert(40258,
@@ -190,8 +190,7 @@ void DocumentSourceBucketAuto::addDocumentToBucket(const pair<Value, Document>&
const size_t numAccumulators = _accumulatedFields.size();
for (size_t k = 0; k < numAccumulators; k++) {
- bucket._accums[k]->process(
- _accumulatedFields[k].expression->evaluate(entry.second, &pExpCtx->variables), false);
+ bucket._accums[k]->process(_accumulatedFields[k].expression->evaluate(entry.second), false);
}
}
diff --git a/src/mongo/db/pipeline/document_source_graph_lookup.cpp b/src/mongo/db/pipeline/document_source_graph_lookup.cpp
index 7447f8ae51c..937da2a46cc 100644
--- a/src/mongo/db/pipeline/document_source_graph_lookup.cpp
+++ b/src/mongo/db/pipeline/document_source_graph_lookup.cpp
@@ -335,7 +335,7 @@ void DocumentSourceGraphLookUp::performSearch() {
// Make sure _input is set before calling performSearch().
invariant(_input);
- Value startingValue = _startWith->evaluate(*_input, &pExpCtx->variables);
+ Value startingValue = _startWith->evaluate(*_input);
// If _startWith evaluates to an array, treat each value as a separate starting point.
if (startingValue.isArray()) {
diff --git a/src/mongo/db/pipeline/document_source_group.cpp b/src/mongo/db/pipeline/document_source_group.cpp
index ff46f44aba4..dd14584ecc9 100644
--- a/src/mongo/db/pipeline/document_source_group.cpp
+++ b/src/mongo/db/pipeline/document_source_group.cpp
@@ -73,7 +73,7 @@ Document GroupFromFirstDocumentTransformation::applyTransformation(const Documen
MutableDocument output(_accumulatorExprs.size());
for (auto&& expr : _accumulatorExprs) {
- auto value = expr.second->evaluate(input, &expr.second->getExpressionContext()->variables);
+ auto value = expr.second->evaluate(input);
output.addField(expr.first, value.missing() ? Value(BSONNULL) : value);
}
@@ -495,9 +495,8 @@ DocumentSource::GetNextResult DocumentSourceGroup::initialize() {
dassert(numAccumulators == group.size());
for (size_t i = 0; i < numAccumulators; i++) {
- group[i]->process(
- _accumulatedFields[i].expression->evaluate(rootDocument, &pExpCtx->variables),
- _doingMerge);
+ group[i]->process(_accumulatedFields[i].expression->evaluate(rootDocument),
+ _doingMerge);
_memoryUsageBytes += group[i]->memUsageForSorter();
}
@@ -612,7 +611,7 @@ shared_ptr<Sorter<Value, Value>::Iterator> DocumentSourceGroup::spill() {
Value DocumentSourceGroup::computeId(const Document& root) {
// If only one expression, return result directly
if (_idExpressions.size() == 1) {
- Value retValue = _idExpressions[0]->evaluate(root, &pExpCtx->variables);
+ Value retValue = _idExpressions[0]->evaluate(root);
return retValue.missing() ? Value(BSONNULL) : std::move(retValue);
}
@@ -620,7 +619,7 @@ Value DocumentSourceGroup::computeId(const Document& root) {
vector<Value> vals;
vals.reserve(_idExpressions.size());
for (size_t i = 0; i < _idExpressions.size(); i++) {
- vals.push_back(_idExpressions[i]->evaluate(root, &pExpCtx->variables));
+ vals.push_back(_idExpressions[i]->evaluate(root));
}
return Value(std::move(vals));
}
diff --git a/src/mongo/db/pipeline/document_source_lookup.cpp b/src/mongo/db/pipeline/document_source_lookup.cpp
index b2a81168a77..da994cc3ca7 100644
--- a/src/mongo/db/pipeline/document_source_lookup.cpp
+++ b/src/mongo/db/pipeline/document_source_lookup.cpp
@@ -629,7 +629,7 @@ void DocumentSourceLookUp::resolveLetVariables(const Document& localDoc, Variabl
invariant(variables);
for (auto& letVar : _letVariables) {
- auto value = letVar.expression->evaluate(localDoc, &pExpCtx->variables);
+ auto value = letVar.expression->evaluate(localDoc);
variables->setConstantValue(letVar.id, value);
}
}
diff --git a/src/mongo/db/pipeline/document_source_merge.h b/src/mongo/db/pipeline/document_source_merge.h
index 927c0376245..811ebf97591 100644
--- a/src/mongo/db/pipeline/document_source_merge.h
+++ b/src/mongo/db/pipeline/document_source_merge.h
@@ -181,7 +181,7 @@ private:
BSONObjBuilder bob;
for (auto && [ name, expr ] : *_letVariables) {
- bob << name << expr->evaluate(doc, &pExpCtx->variables);
+ bob << name << expr->evaluate(doc);
}
return bob.obj();
}
diff --git a/src/mongo/db/pipeline/document_source_redact.cpp b/src/mongo/db/pipeline/document_source_redact.cpp
index 3ff60410a95..8c48726aa2f 100644
--- a/src/mongo/db/pipeline/document_source_redact.cpp
+++ b/src/mongo/db/pipeline/document_source_redact.cpp
@@ -135,7 +135,7 @@ Value DocumentSourceRedact::redactValue(const Value& in, const Document& root) {
boost::optional<Document> DocumentSourceRedact::redactObject(const Document& root) {
auto& variables = pExpCtx->variables;
- const Value expressionResult = _expression->evaluate(root, &variables);
+ const Value expressionResult = _expression->evaluate(root);
ValueComparator simpleValueCmp;
if (simpleValueCmp.evaluate(expressionResult == keepVal)) {
diff --git a/src/mongo/db/pipeline/document_source_replace_root.cpp b/src/mongo/db/pipeline/document_source_replace_root.cpp
index 41ff856cdd0..4bbbffdb628 100644
--- a/src/mongo/db/pipeline/document_source_replace_root.cpp
+++ b/src/mongo/db/pipeline/document_source_replace_root.cpp
@@ -60,7 +60,7 @@ public:
Document applyTransformation(const Document& input) final {
// Extract subdocument in the form of a Value.
- Value newRoot = _newRoot->evaluate(input, &_expCtx->variables);
+ Value newRoot = _newRoot->evaluate(input);
// The newRoot expression, if it exists, must evaluate to an object.
uassert(40228,
diff --git a/src/mongo/db/pipeline/document_source_sort.cpp b/src/mongo/db/pipeline/document_source_sort.cpp
index 395d517ce2d..e9f86b947ed 100644
--- a/src/mongo/db/pipeline/document_source_sort.cpp
+++ b/src/mongo/db/pipeline/document_source_sort.cpp
@@ -423,7 +423,7 @@ StatusWith<Value> DocumentSourceSort::extractKeyPart(const Document& doc,
plainKey = key.getValue();
} else {
invariant(patternPart.expression);
- plainKey = patternPart.expression->evaluate(doc, &pExpCtx->variables);
+ plainKey = patternPart.expression->evaluate(doc);
}
return getCollationComparisonKey(plainKey);
diff --git a/src/mongo/db/pipeline/expression.cpp b/src/mongo/db/pipeline/expression.cpp
index c1bf5957066..d6068398342 100644
--- a/src/mongo/db/pipeline/expression.cpp
+++ b/src/mongo/db/pipeline/expression.cpp
@@ -264,7 +264,7 @@ const char* ExpressionAbs::getOpName() const {
/* ------------------------- ExpressionAdd ----------------------------- */
-Value ExpressionAdd::evaluate(const Document& root, Variables* variables) const {
+Value ExpressionAdd::evaluate(const Document& root) const {
// We'll try to return the narrowest possible result value while avoiding overflow, loss
// of precision due to intermediate rounding or implicit use of decimal types. To do that,
// compute a compensated sum for non-decimal values and a separate decimal sum for decimal
@@ -276,7 +276,7 @@ Value ExpressionAdd::evaluate(const Document& root, Variables* variables) const
const size_t n = _children.size();
for (size_t i = 0; i < n; ++i) {
- Value val = _children[i]->evaluate(root, variables);
+ Value val = _children[i]->evaluate(root);
switch (val.getType()) {
case NumberDecimal:
@@ -346,8 +346,8 @@ const char* ExpressionAdd::getOpName() const {
/* ------------------------- ExpressionAllElementsTrue -------------------------- */
-Value ExpressionAllElementsTrue::evaluate(const Document& root, Variables* variables) const {
- const Value arr = _children[0]->evaluate(root, variables);
+Value ExpressionAllElementsTrue::evaluate(const Document& root) const {
+ const Value arr = _children[0]->evaluate(root);
uassert(17040,
str::stream() << getOpName() << "'s argument must be an array, but is "
<< typeName(arr.getType()),
@@ -424,10 +424,10 @@ intrusive_ptr<Expression> ExpressionAnd::optimize() {
return pE;
}
-Value ExpressionAnd::evaluate(const Document& root, Variables* variables) const {
+Value ExpressionAnd::evaluate(const Document& root) const {
const size_t n = _children.size();
for (size_t i = 0; i < n; ++i) {
- Value pValue(_children[i]->evaluate(root, variables));
+ Value pValue(_children[i]->evaluate(root));
if (!pValue.coerceToBool())
return Value(false);
}
@@ -442,8 +442,8 @@ const char* ExpressionAnd::getOpName() const {
/* ------------------------- ExpressionAnyElementTrue -------------------------- */
-Value ExpressionAnyElementTrue::evaluate(const Document& root, Variables* variables) const {
- const Value arr = _children[0]->evaluate(root, variables);
+Value ExpressionAnyElementTrue::evaluate(const Document& root) const {
+ const Value arr = _children[0]->evaluate(root);
uassert(17041,
str::stream() << getOpName() << "'s argument must be an array, but is "
<< typeName(arr.getType()),
@@ -464,11 +464,11 @@ const char* ExpressionAnyElementTrue::getOpName() const {
/* ---------------------- ExpressionArray --------------------------- */
-Value ExpressionArray::evaluate(const Document& root, Variables* variables) const {
+Value ExpressionArray::evaluate(const Document& root) const {
vector<Value> values;
values.reserve(_children.size());
for (auto&& expr : _children) {
- Value elemVal = expr->evaluate(root, variables);
+ Value elemVal = expr->evaluate(root);
values.push_back(elemVal.missing() ? Value(BSONNULL) : std::move(elemVal));
}
return Value(std::move(values));
@@ -495,8 +495,7 @@ intrusive_ptr<Expression> ExpressionArray::optimize() {
// If all values in ExpressionArray are constant evaluate to ExpressionConstant.
if (allValuesConstant) {
- return ExpressionConstant::create(
- getExpressionContext(), evaluate(Document(), &(getExpressionContext()->variables)));
+ return ExpressionConstant::create(getExpressionContext(), evaluate(Document()));
}
return this;
}
@@ -508,9 +507,9 @@ const char* ExpressionArray::getOpName() const {
/* ------------------------- ExpressionArrayElemAt -------------------------- */
-Value ExpressionArrayElemAt::evaluate(const Document& root, Variables* variables) const {
- const Value array = _children[0]->evaluate(root, variables);
- const Value indexArg = _children[1]->evaluate(root, variables);
+Value ExpressionArrayElemAt::evaluate(const Document& root) const {
+ const Value array = _children[0]->evaluate(root);
+ const Value indexArg = _children[1]->evaluate(root);
if (array.nullish() || indexArg.nullish()) {
return Value(BSONNULL);
@@ -550,8 +549,8 @@ const char* ExpressionArrayElemAt::getOpName() const {
/* ------------------------- ExpressionObjectToArray -------------------------- */
-Value ExpressionObjectToArray::evaluate(const Document& root, Variables* variables) const {
- const Value targetVal = _children[0]->evaluate(root, variables);
+Value ExpressionObjectToArray::evaluate(const Document& root) const {
+ const Value targetVal = _children[0]->evaluate(root);
if (targetVal.nullish()) {
return Value(BSONNULL);
@@ -582,8 +581,8 @@ const char* ExpressionObjectToArray::getOpName() const {
}
/* ------------------------- ExpressionArrayToObject -------------------------- */
-Value ExpressionArrayToObject::evaluate(const Document& root, Variables* variables) const {
- const Value input = _children[0]->evaluate(root, variables);
+Value ExpressionArrayToObject::evaluate(const Document& root) const {
+ const Value input = _children[0]->evaluate(root);
if (input.nullish()) {
return Value(BSONNULL);
}
@@ -730,8 +729,8 @@ void ExpressionCoerceToBool::_doAddDependencies(DepsTracker* deps) const {
pExpression->addDependencies(deps);
}
-Value ExpressionCoerceToBool::evaluate(const Document& root, Variables* variables) const {
- Value pResult(pExpression->evaluate(root, variables));
+Value ExpressionCoerceToBool::evaluate(const Document& root) const {
+ Value pResult(pExpression->evaluate(root));
bool b = pResult.coerceToBool();
if (b)
return Value(true);
@@ -810,9 +809,9 @@ static const CmpLookup cmpLookup[7] = {
};
}
-Value ExpressionCompare::evaluate(const Document& root, Variables* variables) const {
- Value pLeft(_children[0]->evaluate(root, variables));
- Value pRight(_children[1]->evaluate(root, variables));
+Value ExpressionCompare::evaluate(const Document& root) const {
+ Value pLeft(_children[0]->evaluate(root));
+ Value pRight(_children[1]->evaluate(root));
int cmp = getExpressionContext()->getValueComparator().compare(pLeft, pRight);
@@ -838,12 +837,12 @@ const char* ExpressionCompare::getOpName() const {
/* ------------------------- ExpressionConcat ----------------------------- */
-Value ExpressionConcat::evaluate(const Document& root, Variables* variables) const {
+Value ExpressionConcat::evaluate(const Document& root) const {
const size_t n = _children.size();
StringBuilder result;
for (size_t i = 0; i < n; ++i) {
- Value val = _children[i]->evaluate(root, variables);
+ Value val = _children[i]->evaluate(root);
if (val.nullish())
return Value(BSONNULL);
@@ -864,12 +863,12 @@ const char* ExpressionConcat::getOpName() const {
/* ------------------------- ExpressionConcatArrays ----------------------------- */
-Value ExpressionConcatArrays::evaluate(const Document& root, Variables* variables) const {
+Value ExpressionConcatArrays::evaluate(const Document& root) const {
const size_t n = _children.size();
vector<Value> values;
for (size_t i = 0; i < n; ++i) {
- Value val = _children[i]->evaluate(root, variables);
+ Value val = _children[i]->evaluate(root);
if (val.nullish()) {
return Value(BSONNULL);
}
@@ -892,10 +891,10 @@ const char* ExpressionConcatArrays::getOpName() const {
/* ----------------------- ExpressionCond ------------------------------ */
-Value ExpressionCond::evaluate(const Document& root, Variables* variables) const {
- Value pCond(_children[0]->evaluate(root, variables));
+Value ExpressionCond::evaluate(const Document& root) const {
+ Value pCond(_children[0]->evaluate(root));
int idx = pCond.coerceToBool() ? 1 : 2;
- return _children[idx]->evaluate(root, variables);
+ return _children[idx]->evaluate(root);
}
intrusive_ptr<Expression> ExpressionCond::parse(
@@ -966,7 +965,7 @@ void ExpressionConstant::_doAddDependencies(DepsTracker* deps) const {
/* nothing to do */
}
-Value ExpressionConstant::evaluate(const Document& root, Variables* variables) const {
+Value ExpressionConstant::evaluate(const Document& root) const {
return _value;
}
@@ -988,15 +987,14 @@ namespace {
boost::optional<TimeZone> makeTimeZone(const TimeZoneDatabase* tzdb,
const Document& root,
- const Expression* timeZone,
- Variables* variables) {
+ const Expression* timeZone) {
invariant(tzdb);
if (!timeZone) {
return mongo::TimeZoneDatabase::utcZone();
}
- auto timeZoneId = timeZone->evaluate(root, variables);
+ auto timeZoneId = timeZone->evaluate(root);
if (timeZoneId.nullish()) {
return boost::none;
@@ -1178,10 +1176,8 @@ intrusive_ptr<Expression> ExpressionDateFromParts::optimize() {
_isoWeek,
_isoDayOfWeek,
_timeZone})) {
-
// Everything is a constant, so we can turn into a constant.
- return ExpressionConstant::create(
- getExpressionContext(), evaluate(Document{}, &(getExpressionContext()->variables)));
+ return ExpressionConstant::create(getExpressionContext(), evaluate(Document{}));
}
return this;
@@ -1207,14 +1203,13 @@ bool ExpressionDateFromParts::evaluateNumberWithDefault(const Document& root,
intrusive_ptr<Expression> field,
StringData fieldName,
long long defaultValue,
- long long* returnValue,
- Variables* variables) const {
+ long long* returnValue) const {
if (!field) {
*returnValue = defaultValue;
return true;
}
- auto fieldValue = field->evaluate(root, variables);
+ auto fieldValue = field->evaluate(root);
if (fieldValue.nullish()) {
return false;
@@ -1232,20 +1227,18 @@ bool ExpressionDateFromParts::evaluateNumberWithDefault(const Document& root,
return true;
}
-Value ExpressionDateFromParts::evaluate(const Document& root, Variables* variables) const {
+Value ExpressionDateFromParts::evaluate(const Document& root) const {
long long hour, minute, second, millisecond;
- if (!evaluateNumberWithDefault(root, _hour, "hour"_sd, 0, &hour, variables) ||
- !evaluateNumberWithDefault(root, _minute, "minute"_sd, 0, &minute, variables) ||
- !evaluateNumberWithDefault(root, _second, "second"_sd, 0, &second, variables) ||
- !evaluateNumberWithDefault(
- root, _millisecond, "millisecond"_sd, 0, &millisecond, variables)) {
+ if (!evaluateNumberWithDefault(root, _hour, "hour"_sd, 0, &hour) ||
+ !evaluateNumberWithDefault(root, _minute, "minute"_sd, 0, &minute) ||
+ !evaluateNumberWithDefault(root, _second, "second"_sd, 0, &second) ||
+ !evaluateNumberWithDefault(root, _millisecond, "millisecond"_sd, 0, &millisecond)) {
// One of the evaluated inputs in nullish.
return Value(BSONNULL);
}
- auto timeZone =
- makeTimeZone(getExpressionContext()->timeZoneDatabase, root, _timeZone.get(), variables);
+ auto timeZone = makeTimeZone(getExpressionContext()->timeZoneDatabase, root, _timeZone.get());
if (!timeZone) {
return Value(BSONNULL);
@@ -1254,9 +1247,9 @@ Value ExpressionDateFromParts::evaluate(const Document& root, Variables* variabl
if (_year) {
long long year, month, day;
- if (!evaluateNumberWithDefault(root, _year, "year"_sd, 1970, &year, variables) ||
- !evaluateNumberWithDefault(root, _month, "month"_sd, 1, &month, variables) ||
- !evaluateNumberWithDefault(root, _day, "day"_sd, 1, &day, variables)) {
+ if (!evaluateNumberWithDefault(root, _year, "year"_sd, 1970, &year) ||
+ !evaluateNumberWithDefault(root, _month, "month"_sd, 1, &month) ||
+ !evaluateNumberWithDefault(root, _day, "day"_sd, 1, &day)) {
// One of the evaluated inputs in nullish.
return Value(BSONNULL);
}
@@ -1275,11 +1268,9 @@ Value ExpressionDateFromParts::evaluate(const Document& root, Variables* variabl
if (_isoWeekYear) {
long long isoWeekYear, isoWeek, isoDayOfWeek;
- if (!evaluateNumberWithDefault(
- root, _isoWeekYear, "isoWeekYear"_sd, 1970, &isoWeekYear, variables) ||
- !evaluateNumberWithDefault(root, _isoWeek, "isoWeek"_sd, 1, &isoWeek, variables) ||
- !evaluateNumberWithDefault(
- root, _isoDayOfWeek, "isoDayOfWeek"_sd, 1, &isoDayOfWeek, variables)) {
+ if (!evaluateNumberWithDefault(root, _isoWeekYear, "isoWeekYear"_sd, 1970, &isoWeekYear) ||
+ !evaluateNumberWithDefault(root, _isoWeek, "isoWeek"_sd, 1, &isoWeek) ||
+ !evaluateNumberWithDefault(root, _isoDayOfWeek, "isoDayOfWeek"_sd, 1, &isoDayOfWeek)) {
// One of the evaluated inputs in nullish.
return Value(BSONNULL);
}
@@ -1414,8 +1405,7 @@ intrusive_ptr<Expression> ExpressionDateFromString::optimize() {
if (ExpressionConstant::allNullOrConstant(
{_dateString, _timeZone, _format, _onNull, _onError})) {
// Everything is a constant, so we can turn into a constant.
- return ExpressionConstant::create(
- getExpressionContext(), evaluate(Document{}, &(getExpressionContext()->variables)));
+ return ExpressionConstant::create(getExpressionContext(), evaluate(Document{}));
}
return this;
}
@@ -1430,14 +1420,14 @@ Value ExpressionDateFromString::serialize(bool explain) const {
{"onError", _onError ? _onError->serialize(explain) : Value()}}}});
}
-Value ExpressionDateFromString::evaluate(const Document& root, Variables* variables) const {
- const Value dateString = _dateString->evaluate(root, variables);
+Value ExpressionDateFromString::evaluate(const Document& root) const {
+ const Value dateString = _dateString->evaluate(root);
Value formatValue;
// Eagerly validate the format parameter, ignoring if nullish since the input string nullish
// behavior takes precedence.
if (_format) {
- formatValue = _format->evaluate(root, variables);
+ formatValue = _format->evaluate(root);
if (!formatValue.nullish()) {
uassert(40684,
str::stream() << "$dateFromString requires that 'format' be a string, found: "
@@ -1452,12 +1442,11 @@ Value ExpressionDateFromString::evaluate(const Document& root, Variables* variab
// Evaluate the timezone parameter before checking for nullish input, as this will throw an
// exception for an invalid timezone string.
- auto timeZone =
- makeTimeZone(getExpressionContext()->timeZoneDatabase, root, _timeZone.get(), variables);
+ auto timeZone = makeTimeZone(getExpressionContext()->timeZoneDatabase, root, _timeZone.get());
// Behavior for nullish input takes precedence over other nullish elements.
if (dateString.nullish()) {
- return _onNull ? _onNull->evaluate(root, variables) : Value(BSONNULL);
+ return _onNull ? _onNull->evaluate(root) : Value(BSONNULL);
}
try {
@@ -1487,7 +1476,7 @@ Value ExpressionDateFromString::evaluate(const Document& root, Variables* variab
getExpressionContext()->timeZoneDatabase->fromString(dateTimeString, timeZone.get()));
} catch (const ExceptionFor<ErrorCodes::ConversionFailure>&) {
if (_onError) {
- return _onError->evaluate(root, variables);
+ return _onError->evaluate(root);
}
throw;
}
@@ -1574,8 +1563,7 @@ intrusive_ptr<Expression> ExpressionDateToParts::optimize() {
if (ExpressionConstant::allNullOrConstant({_date, _iso8601, _timeZone})) {
// Everything is a constant, so we can turn into a constant.
- return ExpressionConstant::create(
- getExpressionContext(), evaluate(Document{}, &(getExpressionContext()->variables)));
+ return ExpressionConstant::create(getExpressionContext(), evaluate(Document{}));
}
return this;
@@ -1589,13 +1577,12 @@ Value ExpressionDateToParts::serialize(bool explain) const {
{"iso8601", _iso8601 ? _iso8601->serialize(explain) : Value()}}}});
}
-boost::optional<int> ExpressionDateToParts::evaluateIso8601Flag(const Document& root,
- Variables* variables) const {
+boost::optional<int> ExpressionDateToParts::evaluateIso8601Flag(const Document& root) const {
if (!_iso8601) {
return false;
}
- auto iso8601Output = _iso8601->evaluate(root, variables);
+ auto iso8601Output = _iso8601->evaluate(root);
if (iso8601Output.nullish()) {
return boost::none;
@@ -1609,16 +1596,15 @@ boost::optional<int> ExpressionDateToParts::evaluateIso8601Flag(const Document&
return iso8601Output.getBool();
}
-Value ExpressionDateToParts::evaluate(const Document& root, Variables* variables) const {
- const Value date = _date->evaluate(root, variables);
+Value ExpressionDateToParts::evaluate(const Document& root) const {
+ const Value date = _date->evaluate(root);
- auto timeZone =
- makeTimeZone(getExpressionContext()->timeZoneDatabase, root, _timeZone.get(), variables);
+ auto timeZone = makeTimeZone(getExpressionContext()->timeZoneDatabase, root, _timeZone.get());
if (!timeZone) {
return Value(BSONNULL);
}
- auto iso8601 = evaluateIso8601Flag(root, variables);
+ auto iso8601 = evaluateIso8601Flag(root);
if (!iso8601) {
return Value(BSONNULL);
}
@@ -1732,8 +1718,7 @@ intrusive_ptr<Expression> ExpressionDateToString::optimize() {
if (ExpressionConstant::allNullOrConstant({_date, _format, _timeZone, _onNull})) {
// Everything is a constant, so we can turn into a constant.
- return ExpressionConstant::create(
- getExpressionContext(), evaluate(Document{}, &(getExpressionContext()->variables)));
+ return ExpressionConstant::create(getExpressionContext(), evaluate(Document{}));
}
return this;
@@ -1748,14 +1733,14 @@ Value ExpressionDateToString::serialize(bool explain) const {
{"onNull", _onNull ? _onNull->serialize(explain) : Value()}}}});
}
-Value ExpressionDateToString::evaluate(const Document& root, Variables* variables) const {
- const Value date = _date->evaluate(root, variables);
+Value ExpressionDateToString::evaluate(const Document& root) const {
+ const Value date = _date->evaluate(root);
Value formatValue;
// Eagerly validate the format parameter, ignoring if nullish since the input date nullish
// behavior takes precedence.
if (_format) {
- formatValue = _format->evaluate(root, variables);
+ formatValue = _format->evaluate(root);
if (!formatValue.nullish()) {
uassert(18533,
str::stream() << "$dateToString requires that 'format' be a string, found: "
@@ -1770,11 +1755,10 @@ Value ExpressionDateToString::evaluate(const Document& root, Variables* variable
// Evaluate the timezone parameter before checking for nullish input, as this will throw an
// exception for an invalid timezone string.
- auto timeZone =
- makeTimeZone(getExpressionContext()->timeZoneDatabase, root, _timeZone.get(), variables);
+ auto timeZone = makeTimeZone(getExpressionContext()->timeZoneDatabase, root, _timeZone.get());
if (date.nullish()) {
- return _onNull ? _onNull->evaluate(root, variables) : Value(BSONNULL);
+ return _onNull ? _onNull->evaluate(root) : Value(BSONNULL);
}
if (!timeZone) {
@@ -1809,9 +1793,9 @@ void ExpressionDateToString::_doAddDependencies(DepsTracker* deps) const {
/* ----------------------- ExpressionDivide ---------------------------- */
-Value ExpressionDivide::evaluate(const Document& root, Variables* variables) const {
- Value lhs = _children[0]->evaluate(root, variables);
- Value rhs = _children[1]->evaluate(root, variables);
+Value ExpressionDivide::evaluate(const Document& root) const {
+ Value lhs = _children[0]->evaluate(root);
+ Value rhs = _children[1]->evaluate(root);
auto assertNonZero = [](bool nonZero) { uassert(16608, "can't $divide by zero", nonZero); };
@@ -1916,8 +1900,7 @@ intrusive_ptr<Expression> ExpressionObject::optimize() {
}
// If all values in ExpressionObject are constant evaluate to ExpressionConstant.
if (allValuesConstant) {
- return ExpressionConstant::create(
- getExpressionContext(), evaluate(Document(), &(getExpressionContext()->variables)));
+ return ExpressionConstant::create(getExpressionContext(), evaluate(Document()));
}
return this;
}
@@ -1928,10 +1911,10 @@ void ExpressionObject::_doAddDependencies(DepsTracker* deps) const {
}
}
-Value ExpressionObject::evaluate(const Document& root, Variables* variables) const {
+Value ExpressionObject::evaluate(const Document& root) const {
MutableDocument outputDoc;
for (auto&& pair : _expressions) {
- outputDoc.addField(pair.first, pair.second->evaluate(root, variables));
+ outputDoc.addField(pair.first, pair.second->evaluate(root));
}
return outputDoc.freezeToValue();
}
@@ -2022,8 +2005,7 @@ intrusive_ptr<Expression> ExpressionFieldPath::optimize() {
}
if (getExpressionContext()->variables.hasConstantValue(_variable)) {
- return ExpressionConstant::create(
- getExpressionContext(), evaluate(Document(), &(getExpressionContext()->variables)));
+ return ExpressionConstant::create(getExpressionContext(), evaluate(Document()));
}
return intrusive_ptr<Expression>(this);
@@ -2090,16 +2072,17 @@ Value ExpressionFieldPath::evaluatePath(size_t index, const Document& input) con
}
}
-Value ExpressionFieldPath::evaluate(const Document& root, Variables* variables) const {
+Value ExpressionFieldPath::evaluate(const Document& root) const {
+ auto& vars = getExpressionContext()->variables;
if (_fieldPath.getPathLength() == 1) // get the whole variable
- return variables->getValue(_variable, root);
+ return vars.getValue(_variable, root);
if (_variable == Variables::kRootId) {
// ROOT is always a document so use optimized code path
return evaluatePath(1, root);
}
- Value var = variables->getValue(_variable, root);
+ Value var = vars.getValue(_variable, root);
switch (var.getType()) {
case Object:
return evaluatePath(1, var.getDocument());
@@ -2218,9 +2201,9 @@ Value ExpressionFilter::serialize(bool explain) const {
<< _filter->serialize(explain))));
}
-Value ExpressionFilter::evaluate(const Document& root, Variables* variables) const {
+Value ExpressionFilter::evaluate(const Document& root) const {
// We are guaranteed at parse time that this isn't using our _varId.
- const Value inputVal = _input->evaluate(root, variables);
+ const Value inputVal = _input->evaluate(root);
if (inputVal.nullish())
return Value(BSONNULL);
@@ -2235,10 +2218,11 @@ Value ExpressionFilter::evaluate(const Document& root, Variables* variables) con
return inputVal;
vector<Value> output;
+ auto& vars = getExpressionContext()->variables;
for (const auto& elem : input) {
- variables->setValue(_varId, elem);
+ vars.setValue(_varId, elem);
- if (_filter->evaluate(root, variables).coerceToBool()) {
+ if (_filter->evaluate(root).coerceToBool()) {
output.push_back(std::move(elem));
}
}
@@ -2361,14 +2345,15 @@ Value ExpressionLet::serialize(bool explain) const {
DOC("$let" << DOC("vars" << vars.freeze() << "in" << _subExpression->serialize(explain))));
}
-Value ExpressionLet::evaluate(const Document& root, Variables* variables) const {
+Value ExpressionLet::evaluate(const Document& root) const {
for (const auto& item : _variables) {
// It is guaranteed at parse-time that these expressions don't use the variable ids we
// are setting
- variables->setValue(item.first, item.second.expression->evaluate(root, variables));
+ getExpressionContext()->variables.setValue(item.first,
+ item.second.expression->evaluate(root));
}
- return _subExpression->evaluate(root, variables);
+ return _subExpression->evaluate(root);
}
void ExpressionLet::_doAddDependencies(DepsTracker* deps) const {
@@ -2456,9 +2441,9 @@ Value ExpressionMap::serialize(bool explain) const {
<< _each->serialize(explain))));
}
-Value ExpressionMap::evaluate(const Document& root, Variables* variables) const {
+Value ExpressionMap::evaluate(const Document& root) const {
// guaranteed at parse time that this isn't using our _varId
- const Value inputVal = _input->evaluate(root, variables);
+ const Value inputVal = _input->evaluate(root);
if (inputVal.nullish())
return Value(BSONNULL);
@@ -2474,9 +2459,9 @@ Value ExpressionMap::evaluate(const Document& root, Variables* variables) const
vector<Value> output;
output.reserve(input.size());
for (size_t i = 0; i < input.size(); i++) {
- variables->setValue(_varId, input[i]);
+ getExpressionContext()->variables.setValue(_varId, input[i]);
- Value toInsert = _each->evaluate(root, variables);
+ Value toInsert = _each->evaluate(root);
if (toInsert.missing())
toInsert = Value(BSONNULL); // can't insert missing values into array
@@ -2563,7 +2548,7 @@ Value ExpressionMeta::serialize(bool explain) const {
MONGO_UNREACHABLE;
}
-Value ExpressionMeta::evaluate(const Document& root, Variables* variables) const {
+Value ExpressionMeta::evaluate(const Document& root) const {
switch (_metaType) {
case MetaType::TEXT_SCORE:
return root.hasTextScore() ? Value(root.getTextScore()) : Value();
@@ -2588,9 +2573,9 @@ void ExpressionMeta::_doAddDependencies(DepsTracker* deps) const {
/* ----------------------- ExpressionMod ---------------------------- */
-Value ExpressionMod::evaluate(const Document& root, Variables* variables) const {
- Value lhs = _children[0]->evaluate(root, variables);
- Value rhs = _children[1]->evaluate(root, variables);
+Value ExpressionMod::evaluate(const Document& root) const {
+ Value lhs = _children[0]->evaluate(root);
+ Value rhs = _children[1]->evaluate(root);
BSONType leftType = lhs.getType();
BSONType rightType = rhs.getType();
@@ -2645,7 +2630,7 @@ const char* ExpressionMod::getOpName() const {
/* ------------------------- ExpressionMultiply ----------------------------- */
-Value ExpressionMultiply::evaluate(const Document& root, Variables* variables) const {
+Value ExpressionMultiply::evaluate(const Document& root) const {
/*
We'll try to return the narrowest possible result value. To do that
without creating intermediate Values, do the arithmetic for double
@@ -2660,7 +2645,7 @@ Value ExpressionMultiply::evaluate(const Document& root, Variables* variables) c
const size_t n = _children.size();
for (size_t i = 0; i < n; ++i) {
- Value val = _children[i]->evaluate(root, variables);
+ Value val = _children[i]->evaluate(root);
if (val.numeric()) {
BSONType oldProductType = productType;
@@ -2708,12 +2693,12 @@ const char* ExpressionMultiply::getOpName() const {
/* ----------------------- ExpressionIfNull ---------------------------- */
-Value ExpressionIfNull::evaluate(const Document& root, Variables* variables) const {
- Value pLeft(_children[0]->evaluate(root, variables));
+Value ExpressionIfNull::evaluate(const Document& root) const {
+ Value pLeft(_children[0]->evaluate(root));
if (!pLeft.nullish())
return pLeft;
- Value pRight(_children[1]->evaluate(root, variables));
+ Value pRight(_children[1]->evaluate(root));
return pRight;
}
@@ -2724,9 +2709,9 @@ const char* ExpressionIfNull::getOpName() const {
/* ----------------------- ExpressionIn ---------------------------- */
-Value ExpressionIn::evaluate(const Document& root, Variables* variables) const {
- Value argument(_children[0]->evaluate(root, variables));
- Value arrayOfValues(_children[1]->evaluate(root, variables));
+Value ExpressionIn::evaluate(const Document& root) const {
+ Value argument(_children[0]->evaluate(root));
+ Value arrayOfValues(_children[1]->evaluate(root));
uassert(40081,
str::stream() << "$in requires an array as a second argument, found: "
@@ -2768,8 +2753,8 @@ void uassertIfNotIntegralAndNonNegative(Value val,
} // namespace
-Value ExpressionIndexOfArray::evaluate(const Document& root, Variables* variables) const {
- Value arrayArg = _children[0]->evaluate(root, variables);
+Value ExpressionIndexOfArray::evaluate(const Document& root) const {
+ Value arrayArg = _children[0]->evaluate(root);
if (arrayArg.nullish()) {
return Value(BSONNULL);
@@ -2781,7 +2766,7 @@ Value ExpressionIndexOfArray::evaluate(const Document& root, Variables* variable
arrayArg.isArray());
std::vector<Value> array = arrayArg.getArray();
- auto args = evaluateAndValidateArguments(root, _children, array.size(), variables);
+ auto args = evaluateAndValidateArguments(root, _children, array.size());
for (int i = args.startIndex; i < args.endIndex; i++) {
if (getExpressionContext()->getValueComparator().evaluate(array[i] ==
args.targetOfSearch)) {
@@ -2794,14 +2779,11 @@ Value ExpressionIndexOfArray::evaluate(const Document& root, Variables* variable
}
ExpressionIndexOfArray::Arguments ExpressionIndexOfArray::evaluateAndValidateArguments(
- const Document& root,
- const ExpressionVector& operands,
- size_t arrayLength,
- Variables* variables) const {
+ const Document& root, const ExpressionVector& operands, size_t arrayLength) const {
int startIndex = 0;
if (operands.size() > 2) {
- Value startIndexArg = operands[2]->evaluate(root, variables);
+ Value startIndexArg = operands[2]->evaluate(root);
uassertIfNotIntegralAndNonNegative(startIndexArg, getOpName(), "starting index");
startIndex = startIndexArg.coerceToInt();
@@ -2809,13 +2791,13 @@ ExpressionIndexOfArray::Arguments ExpressionIndexOfArray::evaluateAndValidateArg
int endIndex = arrayLength;
if (operands.size() > 3) {
- Value endIndexArg = operands[3]->evaluate(root, variables);
+ Value endIndexArg = operands[3]->evaluate(root);
uassertIfNotIntegralAndNonNegative(endIndexArg, getOpName(), "ending index");
// Don't let 'endIndex' exceed the length of the array.
endIndex = std::min(static_cast<int>(arrayLength), endIndexArg.coerceToInt());
}
- return {_children[1]->evaluate(root, variables), startIndex, endIndex};
+ return {_children[1]->evaluate(root), startIndex, endIndex};
}
/**
@@ -2832,9 +2814,9 @@ public:
_children = operands;
}
- virtual Value evaluate(const Document& root, Variables* variables) const {
+ virtual Value evaluate(const Document& root) const {
- auto args = evaluateAndValidateArguments(root, _children, _indexMap.size(), variables);
+ auto args = evaluateAndValidateArguments(root, _children, _indexMap.size());
auto indexVec = _indexMap.find(args.targetOfSearch);
if (indexVec == _indexMap.end())
@@ -2911,8 +2893,8 @@ bool stringHasTokenAtIndex(size_t index, const std::string& input, const std::st
} // namespace
-Value ExpressionIndexOfBytes::evaluate(const Document& root, Variables* variables) const {
- Value stringArg = _children[0]->evaluate(root, variables);
+Value ExpressionIndexOfBytes::evaluate(const Document& root) const {
+ Value stringArg = _children[0]->evaluate(root);
if (stringArg.nullish()) {
return Value(BSONNULL);
@@ -2924,7 +2906,7 @@ Value ExpressionIndexOfBytes::evaluate(const Document& root, Variables* variable
stringArg.getType() == String);
const std::string& input = stringArg.getString();
- Value tokenArg = _children[1]->evaluate(root, variables);
+ Value tokenArg = _children[1]->evaluate(root);
uassert(40092,
str::stream() << "$indexOfBytes requires a string as the second argument, found: "
<< typeName(tokenArg.getType()),
@@ -2933,14 +2915,14 @@ Value ExpressionIndexOfBytes::evaluate(const Document& root, Variables* variable
size_t startIndex = 0;
if (_children.size() > 2) {
- Value startIndexArg = _children[2]->evaluate(root, variables);
+ Value startIndexArg = _children[2]->evaluate(root);
uassertIfNotIntegralAndNonNegative(startIndexArg, getOpName(), "starting index");
startIndex = static_cast<size_t>(startIndexArg.coerceToInt());
}
size_t endIndex = input.size();
if (_children.size() > 3) {
- Value endIndexArg = _children[3]->evaluate(root, variables);
+ Value endIndexArg = _children[3]->evaluate(root);
uassertIfNotIntegralAndNonNegative(endIndexArg, getOpName(), "ending index");
// Don't let 'endIndex' exceed the length of the string.
endIndex = std::min(input.size(), static_cast<size_t>(endIndexArg.coerceToInt()));
@@ -2965,8 +2947,8 @@ const char* ExpressionIndexOfBytes::getOpName() const {
/* ----------------------- ExpressionIndexOfCP --------------------- */
-Value ExpressionIndexOfCP::evaluate(const Document& root, Variables* variables) const {
- Value stringArg = _children[0]->evaluate(root, variables);
+Value ExpressionIndexOfCP::evaluate(const Document& root) const {
+ Value stringArg = _children[0]->evaluate(root);
if (stringArg.nullish()) {
return Value(BSONNULL);
@@ -2978,7 +2960,7 @@ Value ExpressionIndexOfCP::evaluate(const Document& root, Variables* variables)
stringArg.getType() == String);
const std::string& input = stringArg.getString();
- Value tokenArg = _children[1]->evaluate(root, variables);
+ Value tokenArg = _children[1]->evaluate(root);
uassert(40094,
str::stream() << "$indexOfCP requires a string as the second argument, found: "
<< typeName(tokenArg.getType()),
@@ -2987,7 +2969,7 @@ Value ExpressionIndexOfCP::evaluate(const Document& root, Variables* variables)
size_t startCodePointIndex = 0;
if (_children.size() > 2) {
- Value startIndexArg = _children[2]->evaluate(root, variables);
+ Value startIndexArg = _children[2]->evaluate(root);
uassertIfNotIntegralAndNonNegative(startIndexArg, getOpName(), "starting index");
startCodePointIndex = static_cast<size_t>(startIndexArg.coerceToInt());
}
@@ -3010,7 +2992,7 @@ Value ExpressionIndexOfCP::evaluate(const Document& root, Variables* variables)
size_t endCodePointIndex = codePointLength;
if (_children.size() > 3) {
- Value endIndexArg = _children[3]->evaluate(root, variables);
+ Value endIndexArg = _children[3]->evaluate(root);
uassertIfNotIntegralAndNonNegative(endIndexArg, getOpName(), "ending index");
// Don't let 'endCodePointIndex' exceed the number of code points in the string.
@@ -3067,9 +3049,9 @@ const char* ExpressionLn::getOpName() const {
/* ----------------------- ExpressionLog ---------------------------- */
-Value ExpressionLog::evaluate(const Document& root, Variables* variables) const {
- Value argVal = _children[0]->evaluate(root, variables);
- Value baseVal = _children[1]->evaluate(root, variables);
+Value ExpressionLog::evaluate(const Document& root) const {
+ Value argVal = _children[0]->evaluate(root);
+ Value baseVal = _children[1]->evaluate(root);
if (argVal.nullish() || baseVal.nullish())
return Value(BSONNULL);
@@ -3161,8 +3143,8 @@ intrusive_ptr<Expression> ExpressionNary::optimize() {
// If all the operands are constant expressions, collapse the expression into one constant
// expression.
if (constOperandCount == _children.size()) {
- return intrusive_ptr<Expression>(ExpressionConstant::create(
- getExpressionContext(), evaluate(Document(), &(getExpressionContext()->variables))));
+ return intrusive_ptr<Expression>(
+ ExpressionConstant::create(getExpressionContext(), evaluate(Document())));
}
// If the expression is associative, we can collapse all the consecutive constant operands into
@@ -3205,9 +3187,8 @@ intrusive_ptr<Expression> ExpressionNary::optimize() {
if (constExpressions.size() > 1) {
ExpressionVector childrenSave = std::move(_children);
_children = std::move(constExpressions);
- optimizedOperands.emplace_back(ExpressionConstant::create(
- getExpressionContext(),
- evaluate(Document(), &(getExpressionContext()->variables))));
+ optimizedOperands.emplace_back(
+ ExpressionConstant::create(getExpressionContext(), evaluate(Document())));
_children = std::move(childrenSave);
} else {
optimizedOperands.insert(
@@ -3221,9 +3202,8 @@ intrusive_ptr<Expression> ExpressionNary::optimize() {
if (constExpressions.size() > 1) {
_children = std::move(constExpressions);
- optimizedOperands.emplace_back(ExpressionConstant::create(
- getExpressionContext(),
- evaluate(Document(), &(getExpressionContext()->variables))));
+ optimizedOperands.emplace_back(
+ ExpressionConstant::create(getExpressionContext(), evaluate(Document())));
} else {
optimizedOperands.insert(
optimizedOperands.end(), constExpressions.begin(), constExpressions.end());
@@ -3256,8 +3236,8 @@ Value ExpressionNary::serialize(bool explain) const {
/* ------------------------- ExpressionNot ----------------------------- */
-Value ExpressionNot::evaluate(const Document& root, Variables* variables) const {
- Value pOp(_children[0]->evaluate(root, variables));
+Value ExpressionNot::evaluate(const Document& root) const {
+ Value pOp(_children[0]->evaluate(root));
bool b = pOp.coerceToBool();
return Value(!b);
@@ -3270,10 +3250,10 @@ const char* ExpressionNot::getOpName() const {
/* -------------------------- ExpressionOr ----------------------------- */
-Value ExpressionOr::evaluate(const Document& root, Variables* variables) const {
+Value ExpressionOr::evaluate(const Document& root) const {
const size_t n = _children.size();
for (size_t i = 0; i < n; ++i) {
- Value pValue(_children[i]->evaluate(root, variables));
+ Value pValue(_children[i]->evaluate(root));
if (pValue.coerceToBool())
return Value(true);
}
@@ -3443,9 +3423,9 @@ intrusive_ptr<Expression> ExpressionPow::create(
return expr;
}
-Value ExpressionPow::evaluate(const Document& root, Variables* variables) const {
- Value baseVal = _children[0]->evaluate(root, variables);
- Value expVal = _children[1]->evaluate(root, variables);
+Value ExpressionPow::evaluate(const Document& root) const {
+ Value baseVal = _children[0]->evaluate(root);
+ Value expVal = _children[1]->evaluate(root);
if (baseVal.nullish() || expVal.nullish())
return Value(BSONNULL);
@@ -3561,9 +3541,9 @@ const char* ExpressionPow::getOpName() const {
/* ------------------------- ExpressionRange ------------------------------ */
-Value ExpressionRange::evaluate(const Document& root, Variables* variables) const {
- Value startVal(_children[0]->evaluate(root, variables));
- Value endVal(_children[1]->evaluate(root, variables));
+Value ExpressionRange::evaluate(const Document& root) const {
+ Value startVal(_children[0]->evaluate(root));
+ Value endVal(_children[1]->evaluate(root));
uassert(34443,
str::stream() << "$range requires a numeric starting value, found value of type: "
@@ -3590,7 +3570,7 @@ Value ExpressionRange::evaluate(const Document& root, Variables* variables) cons
int step = 1;
if (_children.size() == 3) {
// A step was specified by the user.
- Value stepVal(_children[2]->evaluate(root, variables));
+ Value stepVal(_children[2]->evaluate(root));
uassert(34447,
str::stream() << "$range requires a numeric step value, found value of type:"
@@ -3664,8 +3644,8 @@ intrusive_ptr<Expression> ExpressionReduce::parse(
expCtx, std::move(input), std::move(initial), std::move(in), thisVar, valueVar);
}
-Value ExpressionReduce::evaluate(const Document& root, Variables* variables) const {
- Value inputVal = _input->evaluate(root, variables);
+Value ExpressionReduce::evaluate(const Document& root) const {
+ Value inputVal = _input->evaluate(root);
if (inputVal.nullish()) {
return Value(BSONNULL);
@@ -3676,13 +3656,14 @@ Value ExpressionReduce::evaluate(const Document& root, Variables* variables) con
<< inputVal.toString(),
inputVal.isArray());
- Value accumulatedValue = _initial->evaluate(root, variables);
+ Value accumulatedValue = _initial->evaluate(root);
+ auto& vars = getExpressionContext()->variables;
for (auto&& elem : inputVal.getArray()) {
- variables->setValue(_thisVar, elem);
- variables->setValue(_valueVar, accumulatedValue);
+ vars.setValue(_thisVar, elem);
+ vars.setValue(_valueVar, accumulatedValue);
- accumulatedValue = _in->evaluate(root, variables);
+ accumulatedValue = _in->evaluate(root);
}
return accumulatedValue;
@@ -3710,8 +3691,8 @@ Value ExpressionReduce::serialize(bool explain) const {
/* ------------------------ ExpressionReverseArray ------------------------ */
-Value ExpressionReverseArray::evaluate(const Document& root, Variables* variables) const {
- Value input(_children[0]->evaluate(root, variables));
+Value ExpressionReverseArray::evaluate(const Document& root) const {
+ Value input(_children[0]->evaluate(root));
if (input.nullish()) {
return Value(BSONNULL);
@@ -3747,9 +3728,9 @@ ValueSet arrayToSet(const Value& val, const ValueComparator& valueComparator) {
/* ----------------------- ExpressionSetDifference ---------------------------- */
-Value ExpressionSetDifference::evaluate(const Document& root, Variables* variables) const {
- const Value lhs = _children[0]->evaluate(root, variables);
- const Value rhs = _children[1]->evaluate(root, variables);
+Value ExpressionSetDifference::evaluate(const Document& root) const {
+ const Value lhs = _children[0]->evaluate(root);
+ const Value rhs = _children[1]->evaluate(root);
if (lhs.nullish() || rhs.nullish()) {
return Value(BSONNULL);
@@ -3793,13 +3774,13 @@ void ExpressionSetEquals::validateArguments(const ExpressionVector& args) const
args.size() >= 2);
}
-Value ExpressionSetEquals::evaluate(const Document& root, Variables* variables) const {
+Value ExpressionSetEquals::evaluate(const Document& root) const {
const size_t n = _children.size();
const auto& valueComparator = getExpressionContext()->getValueComparator();
ValueSet lhs = valueComparator.makeOrderedValueSet();
for (size_t i = 0; i < n; i++) {
- const Value nextEntry = _children[i]->evaluate(root, variables);
+ const Value nextEntry = _children[i]->evaluate(root);
uassert(17044,
str::stream() << "All operands of $setEquals must be arrays. One "
<< "argument is of type: "
@@ -3830,12 +3811,12 @@ const char* ExpressionSetEquals::getOpName() const {
/* ----------------------- ExpressionSetIntersection ---------------------------- */
-Value ExpressionSetIntersection::evaluate(const Document& root, Variables* variables) const {
+Value ExpressionSetIntersection::evaluate(const Document& root) const {
const size_t n = _children.size();
const auto& valueComparator = getExpressionContext()->getValueComparator();
ValueSet currentIntersection = valueComparator.makeOrderedValueSet();
for (size_t i = 0; i < n; i++) {
- const Value nextEntry = _children[i]->evaluate(root, variables);
+ const Value nextEntry = _children[i]->evaluate(root);
if (nextEntry.nullish()) {
return Value(BSONNULL);
}
@@ -3891,9 +3872,9 @@ Value setIsSubsetHelper(const vector<Value>& lhs, const ValueSet& rhs) {
}
}
-Value ExpressionSetIsSubset::evaluate(const Document& root, Variables* variables) const {
- const Value lhs = _children[0]->evaluate(root, variables);
- const Value rhs = _children[1]->evaluate(root, variables);
+Value ExpressionSetIsSubset::evaluate(const Document& root) const {
+ const Value lhs = _children[0]->evaluate(root);
+ const Value rhs = _children[1]->evaluate(root);
uassert(17046,
str::stream() << "both operands of $setIsSubset must be arrays. First "
@@ -3926,8 +3907,8 @@ public:
_children = operands;
}
- virtual Value evaluate(const Document& root, Variables* variables) const {
- const Value lhs = _children[0]->evaluate(root, variables);
+ virtual Value evaluate(const Document& root) const {
+ const Value lhs = _children[0]->evaluate(root);
uassert(17310,
str::stream() << "both operands of $setIsSubset must be arrays. First "
@@ -3974,11 +3955,11 @@ const char* ExpressionSetIsSubset::getOpName() const {
/* ----------------------- ExpressionSetUnion ---------------------------- */
-Value ExpressionSetUnion::evaluate(const Document& root, Variables* variables) const {
+Value ExpressionSetUnion::evaluate(const Document& root) const {
ValueSet unionedSet = getExpressionContext()->getValueComparator().makeOrderedValueSet();
const size_t n = _children.size();
for (size_t i = 0; i < n; i++) {
- const Value newEntries = _children[i]->evaluate(root, variables);
+ const Value newEntries = _children[i]->evaluate(root);
if (newEntries.nullish()) {
return Value(BSONNULL);
}
@@ -4000,8 +3981,8 @@ const char* ExpressionSetUnion::getOpName() const {
/* ----------------------- ExpressionIsArray ---------------------------- */
-Value ExpressionIsArray::evaluate(const Document& root, Variables* variables) const {
- Value argument = _children[0]->evaluate(root, variables);
+Value ExpressionIsArray::evaluate(const Document& root) const {
+ Value argument = _children[0]->evaluate(root);
return Value(argument.isArray());
}
@@ -4012,12 +3993,12 @@ const char* ExpressionIsArray::getOpName() const {
/* ----------------------- ExpressionSlice ---------------------------- */
-Value ExpressionSlice::evaluate(const Document& root, Variables* variables) const {
+Value ExpressionSlice::evaluate(const Document& root) const {
const size_t n = _children.size();
- Value arrayVal = _children[0]->evaluate(root, variables);
+ Value arrayVal = _children[0]->evaluate(root);
// Could be either a start index or the length from 0.
- Value arg2 = _children[1]->evaluate(root, variables);
+ Value arg2 = _children[1]->evaluate(root);
if (arrayVal.nullish() || arg2.nullish()) {
return Value(BSONNULL);
@@ -4068,7 +4049,7 @@ Value ExpressionSlice::evaluate(const Document& root, Variables* variables) cons
start = std::min(array.size(), size_t(startInt));
}
- Value countVal = _children[2]->evaluate(root, variables);
+ Value countVal = _children[2]->evaluate(root);
if (countVal.nullish()) {
return Value(BSONNULL);
@@ -4103,8 +4084,8 @@ const char* ExpressionSlice::getOpName() const {
/* ----------------------- ExpressionSize ---------------------------- */
-Value ExpressionSize::evaluate(const Document& root, Variables* variables) const {
- Value array = _children[0]->evaluate(root, variables);
+Value ExpressionSize::evaluate(const Document& root) const {
+ Value array = _children[0]->evaluate(root);
uassert(17124,
str::stream() << "The argument to $size must be an array, but was of type: "
@@ -4120,9 +4101,9 @@ const char* ExpressionSize::getOpName() const {
/* ----------------------- ExpressionSplit --------------------------- */
-Value ExpressionSplit::evaluate(const Document& root, Variables* variables) const {
- Value inputArg = _children[0]->evaluate(root, variables);
- Value separatorArg = _children[1]->evaluate(root, variables);
+Value ExpressionSplit::evaluate(const Document& root) const {
+ Value inputArg = _children[0]->evaluate(root);
+ Value separatorArg = _children[1]->evaluate(root);
if (inputArg.nullish() || separatorArg.nullish()) {
return Value(BSONNULL);
@@ -4198,9 +4179,9 @@ const char* ExpressionSqrt::getOpName() const {
/* ----------------------- ExpressionStrcasecmp ---------------------------- */
-Value ExpressionStrcasecmp::evaluate(const Document& root, Variables* variables) const {
- Value pString1(_children[0]->evaluate(root, variables));
- Value pString2(_children[1]->evaluate(root, variables));
+Value ExpressionStrcasecmp::evaluate(const Document& root) const {
+ Value pString1(_children[0]->evaluate(root));
+ Value pString2(_children[1]->evaluate(root));
/* boost::iequals returns a bool not an int so strings must actually be allocated */
string str1 = boost::to_upper_copy(pString1.coerceToString());
@@ -4222,10 +4203,10 @@ const char* ExpressionStrcasecmp::getOpName() const {
/* ----------------------- ExpressionSubstrBytes ---------------------------- */
-Value ExpressionSubstrBytes::evaluate(const Document& root, Variables* variables) const {
- Value pString(_children[0]->evaluate(root, variables));
- Value pLower(_children[1]->evaluate(root, variables));
- Value pLength(_children[2]->evaluate(root, variables));
+Value ExpressionSubstrBytes::evaluate(const Document& root) const {
+ Value pString(_children[0]->evaluate(root));
+ Value pLower(_children[1]->evaluate(root));
+ Value pLength(_children[2]->evaluate(root));
string str = pString.coerceToString();
uassert(16034,
@@ -4287,10 +4268,10 @@ const char* ExpressionSubstrBytes::getOpName() const {
/* ----------------------- ExpressionSubstrCP ---------------------------- */
-Value ExpressionSubstrCP::evaluate(const Document& root, Variables* variables) const {
- Value inputVal(_children[0]->evaluate(root, variables));
- Value lowerVal(_children[1]->evaluate(root, variables));
- Value lengthVal(_children[2]->evaluate(root, variables));
+Value ExpressionSubstrCP::evaluate(const Document& root) const {
+ Value inputVal(_children[0]->evaluate(root));
+ Value lowerVal(_children[1]->evaluate(root));
+ Value lengthVal(_children[2]->evaluate(root));
std::string str = inputVal.coerceToString();
uassert(34450,
@@ -4362,8 +4343,8 @@ const char* ExpressionSubstrCP::getOpName() const {
/* ----------------------- ExpressionStrLenBytes ------------------------- */
-Value ExpressionStrLenBytes::evaluate(const Document& root, Variables* variables) const {
- Value str(_children[0]->evaluate(root, variables));
+Value ExpressionStrLenBytes::evaluate(const Document& root) const {
+ Value str(_children[0]->evaluate(root));
uassert(34473,
str::stream() << "$strLenBytes requires a string argument, found: "
@@ -4385,8 +4366,8 @@ const char* ExpressionStrLenBytes::getOpName() const {
/* ----------------------- ExpressionStrLenCP ------------------------- */
-Value ExpressionStrLenCP::evaluate(const Document& root, Variables* variables) const {
- Value val(_children[0]->evaluate(root, variables));
+Value ExpressionStrLenCP::evaluate(const Document& root) const {
+ Value val(_children[0]->evaluate(root));
uassert(34471,
str::stream() << "$strLenCP requires a string argument, found: "
@@ -4410,9 +4391,9 @@ const char* ExpressionStrLenCP::getOpName() const {
/* ----------------------- ExpressionSubtract ---------------------------- */
-Value ExpressionSubtract::evaluate(const Document& root, Variables* variables) const {
- Value lhs = _children[0]->evaluate(root, variables);
- Value rhs = _children[1]->evaluate(root, variables);
+Value ExpressionSubtract::evaluate(const Document& root) const {
+ Value lhs = _children[0]->evaluate(root);
+ Value rhs = _children[1]->evaluate(root);
BSONType diffType = Value::getWidestNumeric(rhs.getType(), lhs.getType());
@@ -4460,12 +4441,12 @@ const char* ExpressionSubtract::getOpName() const {
REGISTER_EXPRESSION(switch, ExpressionSwitch::parse);
-Value ExpressionSwitch::evaluate(const Document& root, Variables* variables) const {
+Value ExpressionSwitch::evaluate(const Document& root) const {
for (auto&& branch : _branches) {
- Value caseExpression(branch.first->evaluate(root, variables));
+ Value caseExpression(branch.first->evaluate(root));
if (caseExpression.coerceToBool()) {
- return branch.second->evaluate(root, variables);
+ return branch.second->evaluate(root);
}
}
@@ -4473,7 +4454,7 @@ Value ExpressionSwitch::evaluate(const Document& root, Variables* variables) con
"$switch could not find a matching branch for an input, and no default was specified.",
_default);
- return _default->evaluate(root, variables);
+ return _default->evaluate(root);
}
boost::intrusive_ptr<Expression> ExpressionSwitch::parse(
@@ -4596,8 +4577,8 @@ Value ExpressionSwitch::serialize(bool explain) const {
/* ------------------------- ExpressionToLower ----------------------------- */
-Value ExpressionToLower::evaluate(const Document& root, Variables* variables) const {
- Value pString(_children[0]->evaluate(root, variables));
+Value ExpressionToLower::evaluate(const Document& root) const {
+ Value pString(_children[0]->evaluate(root));
string str = pString.coerceToString();
boost::to_lower(str);
return Value(str);
@@ -4610,8 +4591,8 @@ const char* ExpressionToLower::getOpName() const {
/* ------------------------- ExpressionToUpper -------------------------- */
-Value ExpressionToUpper::evaluate(const Document& root, Variables* variables) const {
- Value pString(_children[0]->evaluate(root, variables));
+Value ExpressionToUpper::evaluate(const Document& root) const {
+ Value pString(_children[0]->evaluate(root));
string str(pString.coerceToString());
boost::to_upper(str);
return Value(str);
@@ -4733,8 +4714,8 @@ std::vector<StringData> extractCodePointsFromChars(StringData utf8String,
}
} // namespace
-Value ExpressionTrim::evaluate(const Document& root, Variables* variables) const {
- auto unvalidatedInput = _input->evaluate(root, variables);
+Value ExpressionTrim::evaluate(const Document& root) const {
+ auto unvalidatedInput = _input->evaluate(root);
if (unvalidatedInput.nullish()) {
return Value(BSONNULL);
}
@@ -4750,7 +4731,7 @@ Value ExpressionTrim::evaluate(const Document& root, Variables* variables) const
if (!_characters) {
return Value(doTrim(input, kDefaultTrimWhitespaceChars));
}
- auto unvalidatedUserChars = _characters->evaluate(root, variables);
+ auto unvalidatedUserChars = _characters->evaluate(root);
if (unvalidatedUserChars.nullish()) {
return Value(BSONNULL);
}
@@ -4829,9 +4810,7 @@ boost::intrusive_ptr<Expression> ExpressionTrim::optimize() {
_characters = _characters->optimize();
}
if (ExpressionConstant::allNullOrConstant({_input, _characters})) {
- return ExpressionConstant::create(
- getExpressionContext(),
- this->evaluate(Document(), &(getExpressionContext()->variables)));
+ return ExpressionConstant::create(getExpressionContext(), this->evaluate(Document()));
}
return this;
}
@@ -4870,11 +4849,10 @@ static Value evaluateRoundOrTrunc(const Document& root,
const std::vector<boost::intrusive_ptr<Expression>>& children,
const std::string& opName,
Decimal128::RoundingMode roundingMode,
- double (*doubleOp)(double),
- Variables* variables) {
+ double (*doubleOp)(double)) {
constexpr auto maxPrecision = 100LL;
constexpr auto minPrecision = -20LL;
- auto numericArg = Value(children[0]->evaluate(root, variables));
+ auto numericArg = Value(children[0]->evaluate(root));
if (numericArg.nullish()) {
return Value(BSONNULL);
}
@@ -4885,7 +4863,7 @@ static Value evaluateRoundOrTrunc(const Document& root,
long long precisionValue = 0;
if (children.size() > 1) {
- auto precisionArg = Value(children[1]->evaluate(root, variables));
+ auto precisionArg = Value(children[1]->evaluate(root));
if (precisionArg.nullish()) {
return Value(BSONNULL);
}
@@ -4941,9 +4919,9 @@ static Value evaluateRoundOrTrunc(const Document& root,
}
}
-Value ExpressionRound::evaluate(const Document& root, Variables* variables) const {
+Value ExpressionRound::evaluate(const Document& root) const {
return evaluateRoundOrTrunc(
- root, _children, getOpName(), Decimal128::kRoundTiesToEven, &std::round, variables);
+ root, _children, getOpName(), Decimal128::kRoundTiesToEven, &std::round);
}
REGISTER_EXPRESSION_WITH_MIN_VERSION(
@@ -4954,9 +4932,9 @@ const char* ExpressionRound::getOpName() const {
return "$round";
}
-Value ExpressionTrunc::evaluate(const Document& root, Variables* variables) const {
+Value ExpressionTrunc::evaluate(const Document& root) const {
return evaluateRoundOrTrunc(
- root, _children, getOpName(), Decimal128::kRoundTowardZero, &std::trunc, variables);
+ root, _children, getOpName(), Decimal128::kRoundTowardZero, &std::trunc);
}
intrusive_ptr<Expression> ExpressionTrunc::parse(const intrusive_ptr<ExpressionContext>& expCtx,
@@ -4990,8 +4968,8 @@ const char* ExpressionTrunc::getOpName() const {
/* ------------------------- ExpressionType ----------------------------- */
-Value ExpressionType::evaluate(const Document& root, Variables* variables) const {
- Value val(_children[0]->evaluate(root, variables));
+Value ExpressionType::evaluate(const Document& root) const {
+ Value val(_children[0]->evaluate(root));
return Value(StringData(typeName(val.getType())));
}
@@ -5074,7 +5052,7 @@ intrusive_ptr<Expression> ExpressionZip::parse(
expCtx, useLongestLength, std::move(children), std::move(inputs), std::move(defaults));
}
-Value ExpressionZip::evaluate(const Document& root, Variables* variables) const {
+Value ExpressionZip::evaluate(const Document& root) const {
// Evaluate input values.
vector<vector<Value>> inputValues;
inputValues.reserve(_inputs.size());
@@ -5082,7 +5060,7 @@ Value ExpressionZip::evaluate(const Document& root, Variables* variables) const
size_t minArraySize = 0;
size_t maxArraySize = 0;
for (size_t i = 0; i < _inputs.size(); i++) {
- Value evalExpr = _inputs[i].get()->evaluate(root, variables);
+ Value evalExpr = _inputs[i].get()->evaluate(root);
if (evalExpr.nullish()) {
return Value(BSONNULL);
}
@@ -5111,7 +5089,7 @@ Value ExpressionZip::evaluate(const Document& root, Variables* variables) const
// If we need default values, evaluate each expression.
if (minArraySize != maxArraySize) {
for (size_t i = 0; i < _defaults.size(); i++) {
- evaluatedDefaults[i] = _defaults[i].get()->evaluate(root, variables);
+ evaluatedDefaults[i] = _defaults[i].get()->evaluate(root);
}
}
@@ -5695,16 +5673,16 @@ intrusive_ptr<Expression> ExpressionConvert::parse(
expCtx, std::move(input), std::move(to), std::move(onError), std::move(onNull));
}
-Value ExpressionConvert::evaluate(const Document& root, Variables* variables) const {
- auto toValue = _to->evaluate(root, variables);
- Value inputValue = _input->evaluate(root, variables);
+Value ExpressionConvert::evaluate(const Document& root) const {
+ auto toValue = _to->evaluate(root);
+ Value inputValue = _input->evaluate(root);
boost::optional<BSONType> targetType;
if (!toValue.nullish()) {
targetType = computeTargetType(toValue);
}
if (inputValue.nullish()) {
- return _onNull ? _onNull->evaluate(root, variables) : Value(BSONNULL);
+ return _onNull ? _onNull->evaluate(root) : Value(BSONNULL);
} else if (!targetType) {
// "to" evaluated to a nullish value.
return Value(BSONNULL);
@@ -5714,7 +5692,7 @@ Value ExpressionConvert::evaluate(const Document& root, Variables* variables) co
return performConversion(*targetType, inputValue);
} catch (const ExceptionFor<ErrorCodes::ConversionFailure>&) {
if (_onError) {
- return _onError->evaluate(root, variables);
+ return _onError->evaluate(root);
} else {
throw;
}
@@ -5737,8 +5715,7 @@ boost::intrusive_ptr<Expression> ExpressionConvert::optimize() {
// and _onNull values could still be legally folded if those values are not needed. Support for
// that case would add more complexity than it's worth, though.
if (ExpressionConstant::allNullOrConstant({_input, _to, _onError, _onNull})) {
- return ExpressionConstant::create(
- getExpressionContext(), evaluate(Document{}, &(getExpressionContext()->variables)));
+ return ExpressionConstant::create(getExpressionContext(), evaluate(Document{}));
}
return this;
@@ -5844,10 +5821,10 @@ auto CommonRegexParse(const boost::intrusive_ptr<ExpressionContext>& expCtx,
/* -------------------------- ExpressionRegex ------------------------------ */
ExpressionRegex::RegexExecutionState ExpressionRegex::buildInitialState(
- const Document& root, Variables* variables) const {
- Value textInput = _input->evaluate(root, variables);
- Value regexPattern = _regex->evaluate(root, variables);
- Value regexOptions = _options ? _options->evaluate(root, variables) : Value(BSONNULL);
+ const Document& root) const {
+ Value textInput = _input->evaluate(root);
+ Value regexPattern = _regex->evaluate(root);
+ Value regexOptions = _options ? _options->evaluate(root) : Value(BSONNULL);
auto executionState = _initialExecStateForConstantRegex.value_or(RegexExecutionState());
@@ -6079,8 +6056,8 @@ boost::intrusive_ptr<Expression> ExpressionRegexFind::parse(
expCtx, std::move(input), std::move(regex), std::move(options), opName);
}
-Value ExpressionRegexFind::evaluate(const Document& root, Variables* variables) const {
- auto executionState = buildInitialState(root, variables);
+Value ExpressionRegexFind::evaluate(const Document& root) const {
+ auto executionState = buildInitialState(root);
if (executionState.nullish()) {
return Value(BSONNULL);
}
@@ -6103,9 +6080,9 @@ boost::intrusive_ptr<Expression> ExpressionRegexFindAll::parse(
expCtx, std::move(input), std::move(regex), std::move(options), opName);
}
-Value ExpressionRegexFindAll::evaluate(const Document& root, Variables* variables) const {
+Value ExpressionRegexFindAll::evaluate(const Document& root) const {
std::vector<Value> output;
- auto executionState = buildInitialState(root, variables);
+ auto executionState = buildInitialState(root);
if (executionState.nullish()) {
return Value(output);
}
@@ -6167,8 +6144,8 @@ boost::intrusive_ptr<Expression> ExpressionRegexMatch::parse(
expCtx, std::move(input), std::move(regex), std::move(options), opName);
}
-Value ExpressionRegexMatch::evaluate(const Document& root, Variables* variables) const {
- auto executionState = buildInitialState(root, variables);
+Value ExpressionRegexMatch::evaluate(const Document& root) const {
+ auto executionState = buildInitialState(root);
// Return output of execute only if regex is not nullish.
return executionState.nullish() ? Value(false) : Value(execute(&executionState) > 0);
}
diff --git a/src/mongo/db/pipeline/expression.h b/src/mongo/db/pipeline/expression.h
index 8b7eecf0c72..3ee13d4ea5e 100644
--- a/src/mongo/db/pipeline/expression.h
+++ b/src/mongo/db/pipeline/expression.h
@@ -146,12 +146,9 @@ public:
virtual Value serialize(bool explain) const = 0;
/**
- * Evaluate the expression with respect to the Document given by 'root' and the Variables given
- * by 'variables'. It is an error to supply a Variables argument whose built-in variables (like
- * $$NOW) are not set. This method is thread-safe, so long as the 'variables' passed in here is
- * not shared between threads.
+ * Evaluate expression with respect to the Document given by 'root', and return the result.
*/
- virtual Value evaluate(const Document& root, Variables* variables) const = 0;
+ virtual Value evaluate(const Document& root) const = 0;
/**
* Returns information about the paths computed by this expression. This only needs to be
@@ -251,10 +248,6 @@ public:
return _children;
}
- const boost::intrusive_ptr<ExpressionContext>& getExpressionContext() const {
- return _expCtx;
- }
-
protected:
using ExpressionVector = std::vector<boost::intrusive_ptr<Expression>>;
@@ -268,6 +261,11 @@ protected:
}
}
+
+ const boost::intrusive_ptr<ExpressionContext>& getExpressionContext() const {
+ return _expCtx;
+ }
+
virtual void _doAddDependencies(DepsTracker* deps) const = 0;
/**
@@ -406,13 +404,13 @@ public:
explicit ExpressionFromAccumulator(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionVariadic<ExpressionFromAccumulator<Accumulator>>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final {
+ Value evaluate(const Document& root) const final {
Accumulator accum(this->getExpressionContext());
const auto n = this->_children.size();
// If a single array arg is given, loop through it passing each member to the accumulator.
// If a single, non-array arg is given, pass it directly to the accumulator.
if (n == 1) {
- Value singleVal = this->_children[0]->evaluate(root, variables);
+ Value singleVal = this->_children[0]->evaluate(root);
if (singleVal.getType() == Array) {
for (const Value& val : singleVal.getArray()) {
accum.process(val, false);
@@ -423,7 +421,7 @@ public:
} else {
// If multiple arguments are given, pass all arguments to the accumulator.
for (auto&& argument : this->_children) {
- accum.process(argument->evaluate(root, variables), false);
+ accum.process(argument->evaluate(root), false);
}
}
return accum.getValue(false);
@@ -462,8 +460,8 @@ public:
virtual ~ExpressionSingleNumericArg() = default;
- Value evaluate(const Document& root, Variables* variables) const final {
- Value arg = this->_children[0]->evaluate(root, variables);
+ Value evaluate(const Document& root) const final {
+ Value arg = this->_children[0]->evaluate(root);
if (arg.nullish())
return Value(BSONNULL);
@@ -496,15 +494,15 @@ public:
* 2. If either input is not numeric, it throws an error.
* 3. Call evaluateNumericArgs on the two numeric args.
*/
- Value evaluate(const Document& root, Variables* variables) const final {
- Value arg1 = this->_children[0]->evaluate(root, variables);
+ Value evaluate(const Document& root) const final {
+ Value arg1 = this->_children[0]->evaluate(root);
if (arg1.nullish())
return Value(BSONNULL);
uassert(51044,
str::stream() << this->getOpName() << " only supports numeric types, not "
<< typeName(arg1.getType()),
arg1.numeric());
- Value arg2 = this->_children[1]->evaluate(root, variables);
+ Value arg2 = this->_children[1]->evaluate(root);
if (arg2.nullish())
return Value(BSONNULL);
uassert(51045,
@@ -527,7 +525,7 @@ public:
class ExpressionConstant final : public Expression {
public:
boost::intrusive_ptr<Expression> optimize() final;
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
Value serialize(bool explain) const final;
const char* getOpName() const;
@@ -595,8 +593,8 @@ class DateExpressionAcceptingTimeZone : public Expression {
public:
virtual ~DateExpressionAcceptingTimeZone() {}
- Value evaluate(const Document& root, Variables* variables) const final {
- auto dateVal = _date->evaluate(root, variables);
+ Value evaluate(const Document& root) const final {
+ auto dateVal = _date->evaluate(root);
if (dateVal.nullish()) {
return Value(BSONNULL);
}
@@ -605,7 +603,7 @@ public:
if (!_timeZone) {
return evaluateDate(date, TimeZoneDatabase::utcZone());
}
- auto timeZoneId = _timeZone->evaluate(root, variables);
+ auto timeZoneId = _timeZone->evaluate(root);
if (timeZoneId.nullish()) {
return Value(BSONNULL);
}
@@ -643,8 +641,7 @@ public:
}
if (ExpressionConstant::allNullOrConstant({_date, _timeZone})) {
// Everything is a constant, so we can turn into a constant.
- return ExpressionConstant::create(
- getExpressionContext(), evaluate(Document{}, &(getExpressionContext()->variables)));
+ return ExpressionConstant::create(getExpressionContext(), evaluate(Document{}));
}
return this;
}
@@ -757,7 +754,7 @@ public:
explicit ExpressionAdd(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionVariadic<ExpressionAdd>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
bool isAssociative() const final {
@@ -779,7 +776,7 @@ public:
explicit ExpressionAllElementsTrue(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionFixedArity<ExpressionAllElementsTrue, 1>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -794,7 +791,7 @@ public:
: ExpressionVariadic<ExpressionAnd>(expCtx) {}
boost::intrusive_ptr<Expression> optimize() final;
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
bool isAssociative() const final {
@@ -816,7 +813,7 @@ public:
explicit ExpressionAnyElementTrue(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionFixedArity<ExpressionAnyElementTrue, 1>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -830,7 +827,7 @@ public:
explicit ExpressionArray(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionVariadic<ExpressionArray>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
Value serialize(bool explain) const final;
boost::intrusive_ptr<Expression> optimize() final;
const char* getOpName() const final;
@@ -846,7 +843,7 @@ public:
explicit ExpressionArrayElemAt(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionFixedArity<ExpressionArrayElemAt, 2>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -859,7 +856,7 @@ public:
explicit ExpressionObjectToArray(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionFixedArity<ExpressionObjectToArray, 1>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -872,7 +869,7 @@ public:
explicit ExpressionArrayToObject(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionFixedArity<ExpressionArrayToObject, 1>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -897,7 +894,7 @@ public:
class ExpressionCoerceToBool final : public Expression {
public:
boost::intrusive_ptr<Expression> optimize() final;
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
Value serialize(bool explain) const final;
static boost::intrusive_ptr<ExpressionCoerceToBool> create(
@@ -938,7 +935,7 @@ public:
ExpressionCompare(const boost::intrusive_ptr<ExpressionContext>& expCtx, CmpOp cmpOp)
: ExpressionFixedArity<ExpressionCompare, 2>(expCtx), cmpOp(cmpOp) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
CmpOp getOp() const {
@@ -971,7 +968,7 @@ public:
explicit ExpressionConcat(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionVariadic<ExpressionConcat>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
bool isAssociative() const final {
@@ -989,7 +986,7 @@ public:
explicit ExpressionConcatArrays(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionVariadic<ExpressionConcatArrays>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
bool isAssociative() const final {
@@ -1006,7 +1003,7 @@ class ExpressionCond final : public ExpressionFixedArity<ExpressionCond, 3> {
public:
explicit ExpressionCond(const boost::intrusive_ptr<ExpressionContext>& expCtx) : Base(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
static boost::intrusive_ptr<Expression> parse(
@@ -1026,7 +1023,7 @@ class ExpressionDateFromString final : public Expression {
public:
boost::intrusive_ptr<Expression> optimize() final;
Value serialize(bool explain) const final;
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document&) const final;
static boost::intrusive_ptr<Expression> parse(
const boost::intrusive_ptr<ExpressionContext>& expCtx,
@@ -1059,7 +1056,7 @@ class ExpressionDateFromParts final : public Expression {
public:
boost::intrusive_ptr<Expression> optimize() final;
Value serialize(bool explain) const final;
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
static boost::intrusive_ptr<Expression> parse(
const boost::intrusive_ptr<ExpressionContext>& expCtx,
@@ -1103,8 +1100,7 @@ private:
boost::intrusive_ptr<Expression> field,
StringData fieldName,
long long defaultValue,
- long long* returnValue,
- Variables* variables) const;
+ long long* returnValue) const;
boost::intrusive_ptr<Expression>& _year;
boost::intrusive_ptr<Expression>& _month;
@@ -1123,7 +1119,7 @@ class ExpressionDateToParts final : public Expression {
public:
boost::intrusive_ptr<Expression> optimize() final;
Value serialize(bool explain) const final;
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
static boost::intrusive_ptr<Expression> parse(
const boost::intrusive_ptr<ExpressionContext>& expCtx,
@@ -1146,7 +1142,7 @@ private:
boost::intrusive_ptr<Expression> timeZone,
boost::intrusive_ptr<Expression> iso8601);
- boost::optional<int> evaluateIso8601Flag(const Document& root, Variables* variables) const;
+ boost::optional<int> evaluateIso8601Flag(const Document& root) const;
boost::intrusive_ptr<Expression>& _date;
boost::intrusive_ptr<Expression>& _timeZone;
@@ -1157,7 +1153,7 @@ class ExpressionDateToString final : public Expression {
public:
boost::intrusive_ptr<Expression> optimize() final;
Value serialize(bool explain) const final;
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
static boost::intrusive_ptr<Expression> parse(
const boost::intrusive_ptr<ExpressionContext>& expCtx,
@@ -1243,7 +1239,7 @@ public:
explicit ExpressionDivide(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionFixedArity<ExpressionDivide, 2>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -1273,7 +1269,7 @@ public:
}
boost::intrusive_ptr<Expression> optimize() final;
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
Value serialize(bool explain) const final;
/*
@@ -1354,7 +1350,7 @@ class ExpressionFilter final : public Expression {
public:
boost::intrusive_ptr<Expression> optimize() final;
Value serialize(bool explain) const final;
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
static boost::intrusive_ptr<Expression> parse(
const boost::intrusive_ptr<ExpressionContext>& expCtx,
@@ -1423,7 +1419,7 @@ public:
explicit ExpressionIfNull(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionFixedArity<ExpressionIfNull, 2>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -1437,7 +1433,7 @@ public:
explicit ExpressionIn(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionFixedArity<ExpressionIn, 2>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -1452,7 +1448,7 @@ public:
: ExpressionRangedArity<ExpressionIndexOfArray, 2, 4>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const;
+ Value evaluate(const Document& root) const;
boost::intrusive_ptr<Expression> optimize() final;
const char* getOpName() const final;
@@ -1479,8 +1475,7 @@ protected:
*/
Arguments evaluateAndValidateArguments(const Document& root,
const ExpressionVector& operands,
- size_t arrayLength,
- Variables* variables) const;
+ size_t arrayLength) const;
private:
class Optimized;
@@ -1492,7 +1487,7 @@ public:
explicit ExpressionIndexOfBytes(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionRangedArity<ExpressionIndexOfBytes, 2, 4>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -1509,7 +1504,7 @@ public:
explicit ExpressionIndexOfCP(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionRangedArity<ExpressionIndexOfCP, 2, 4>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -1522,7 +1517,7 @@ class ExpressionLet final : public Expression {
public:
boost::intrusive_ptr<Expression> optimize() final;
Value serialize(bool explain) const final;
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
static boost::intrusive_ptr<Expression> parse(
const boost::intrusive_ptr<ExpressionContext>& expCtx,
@@ -1570,7 +1565,7 @@ public:
explicit ExpressionLog(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionFixedArity<ExpressionLog, 2>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -1595,7 +1590,7 @@ class ExpressionMap final : public Expression {
public:
boost::intrusive_ptr<Expression> optimize() final;
Value serialize(bool explain) const final;
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
static boost::intrusive_ptr<Expression> parse(
const boost::intrusive_ptr<ExpressionContext>& expCtx,
@@ -1629,7 +1624,7 @@ private:
class ExpressionMeta final : public Expression {
public:
Value serialize(bool explain) const final;
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
static boost::intrusive_ptr<Expression> parse(
const boost::intrusive_ptr<ExpressionContext>& expCtx,
@@ -1697,7 +1692,7 @@ public:
explicit ExpressionMod(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionFixedArity<ExpressionMod, 2>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -1711,7 +1706,7 @@ public:
explicit ExpressionMultiply(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionVariadic<ExpressionMultiply>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
bool isAssociative() const final {
@@ -1751,7 +1746,7 @@ public:
explicit ExpressionNot(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionFixedArity<ExpressionNot, 1>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -1771,7 +1766,7 @@ public:
class ExpressionObject final : public Expression {
public:
boost::intrusive_ptr<Expression> optimize() final;
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
Value serialize(bool explain) const final;
static boost::intrusive_ptr<ExpressionObject> create(
@@ -1822,7 +1817,7 @@ public:
: ExpressionVariadic<ExpressionOr>(expCtx) {}
boost::intrusive_ptr<Expression> optimize() final;
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
bool isAssociative() const final {
@@ -1851,7 +1846,7 @@ public:
}
private:
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
};
@@ -1861,7 +1856,7 @@ public:
explicit ExpressionRange(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionRangedArity<ExpressionRange, 2, 3>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -1885,7 +1880,7 @@ public:
_thisVar(thisVar),
_valueVar(valueVar) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
boost::intrusive_ptr<Expression> optimize() final;
static boost::intrusive_ptr<Expression> parse(
const boost::intrusive_ptr<ExpressionContext>& expCtx,
@@ -1933,7 +1928,7 @@ public:
explicit ExpressionSetDifference(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionFixedArity<ExpressionSetDifference, 2>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -1947,7 +1942,7 @@ public:
explicit ExpressionSetEquals(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionVariadic<ExpressionSetEquals>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void validateArguments(const ExpressionVector& args) const final;
@@ -1962,7 +1957,7 @@ public:
explicit ExpressionSetIntersection(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionVariadic<ExpressionSetIntersection>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
bool isAssociative() const final {
@@ -1986,7 +1981,7 @@ public:
: ExpressionFixedArity<ExpressionSetIsSubset, 2>(expCtx) {}
boost::intrusive_ptr<Expression> optimize() override;
- Value evaluate(const Document& root, Variables* variables) const override;
+ Value evaluate(const Document& root) const override;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -2003,7 +1998,7 @@ public:
explicit ExpressionSetUnion(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionVariadic<ExpressionSetUnion>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
bool isAssociative() const final {
@@ -2025,7 +2020,7 @@ public:
explicit ExpressionSize(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionFixedArity<ExpressionSize, 1>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -2039,7 +2034,7 @@ public:
explicit ExpressionReverseArray(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionFixedArity<ExpressionReverseArray, 1>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -2053,7 +2048,7 @@ public:
explicit ExpressionSlice(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionRangedArity<ExpressionSlice, 2, 3>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -2067,7 +2062,7 @@ public:
explicit ExpressionIsArray(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionFixedArity<ExpressionIsArray, 1>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -2080,7 +2075,7 @@ public:
explicit ExpressionRound(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionRangedArity<ExpressionRound, 1, 2>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -2093,7 +2088,7 @@ public:
explicit ExpressionSplit(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionFixedArity<ExpressionSplit, 2>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -2121,7 +2116,7 @@ public:
explicit ExpressionStrcasecmp(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionFixedArity<ExpressionStrcasecmp, 2>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -2135,7 +2130,7 @@ public:
explicit ExpressionSubstrBytes(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionFixedArity<ExpressionSubstrBytes, 3>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -2149,7 +2144,7 @@ public:
explicit ExpressionSubstrCP(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionFixedArity<ExpressionSubstrCP, 3>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -2163,7 +2158,7 @@ public:
explicit ExpressionStrLenBytes(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionFixedArity<ExpressionStrLenBytes, 1>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -2177,7 +2172,7 @@ public:
explicit ExpressionStrLenCP(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionFixedArity<ExpressionStrLenCP, 1>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -2191,7 +2186,7 @@ public:
explicit ExpressionSubtract(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionFixedArity<ExpressionSubtract, 2>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -2212,7 +2207,7 @@ public:
_default(_children.back()),
_branches(std::move(branches)) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
boost::intrusive_ptr<Expression> optimize() final;
static boost::intrusive_ptr<Expression> parse(
const boost::intrusive_ptr<ExpressionContext>& expCtx,
@@ -2238,7 +2233,7 @@ public:
explicit ExpressionToLower(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionFixedArity<ExpressionToLower, 1>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -2252,7 +2247,7 @@ public:
explicit ExpressionToUpper(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionFixedArity<ExpressionToUpper, 1>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -2284,7 +2279,7 @@ public:
_input(_children[0]),
_characters(_children[1]) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
boost::intrusive_ptr<Expression> optimize() final;
static boost::intrusive_ptr<Expression> parse(
const boost::intrusive_ptr<ExpressionContext>& expCtx,
@@ -2342,7 +2337,7 @@ public:
const boost::intrusive_ptr<ExpressionContext>& expCtx,
BSONElement elem,
const VariablesParseState& vps);
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -2356,7 +2351,7 @@ public:
explicit ExpressionType(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionFixedArity<ExpressionType, 1>(expCtx) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
const char* getOpName() const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
@@ -2468,7 +2463,7 @@ public:
_inputs(std::move(inputs)),
_defaults(std::move(defaults)) {}
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
boost::intrusive_ptr<Expression> optimize() final;
static boost::intrusive_ptr<Expression> parse(
const boost::intrusive_ptr<ExpressionContext>& expCtx,
@@ -2504,7 +2499,7 @@ public:
BSONElement expr,
const VariablesParseState& vpsIn);
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
boost::intrusive_ptr<Expression> optimize() final;
Value serialize(bool explain) const final;
@@ -2572,7 +2567,7 @@ public:
* Validates the structure of input passed in 'inputExpr'. If valid, generates an initial
* execution state. This returned object can later be used for calling execute() or nextMatch().
*/
- RegexExecutionState buildInitialState(const Document& root, Variables* variables) const;
+ RegexExecutionState buildInitialState(const Document& root) const;
/**
* Checks if there is a match for the given input and pattern that are part of 'executionState'.
@@ -2657,7 +2652,7 @@ public:
BSONElement expr,
const VariablesParseState& vpsIn);
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
return visitor->visit(this);
@@ -2673,7 +2668,7 @@ public:
BSONElement expr,
const VariablesParseState& vpsIn);
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
return visitor->visit(this);
}
@@ -2688,7 +2683,7 @@ public:
BSONElement expr,
const VariablesParseState& vpsIn);
- Value evaluate(const Document& root, Variables* variables) const final;
+ Value evaluate(const Document& root) const final;
void acceptVisitor(ExpressionVisitor* visitor) final {
return visitor->visit(this);
diff --git a/src/mongo/db/pipeline/expression_convert_test.cpp b/src/mongo/db/pipeline/expression_convert_test.cpp
index a0a5c2d4a64..b5f22579438 100644
--- a/src/mongo/db/pipeline/expression_convert_test.cpp
+++ b/src/mongo/db/pipeline/expression_convert_test.cpp
@@ -157,7 +157,7 @@ TEST_F(ExpressionConvertTest, InvalidTypeNameFails) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(Document(), &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(Document()),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::BadValue);
@@ -177,7 +177,7 @@ TEST_F(ExpressionConvertTest, NonIntegralTypeFails) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(Document(), &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(Document()),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::FailedToParse);
@@ -200,7 +200,7 @@ TEST_F(ExpressionConvertTest, NonStringNonNumericalTypeFails) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(Document(), &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(Document()),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::FailedToParse);
@@ -223,7 +223,7 @@ TEST_F(ExpressionConvertTest, InvalidNumericTargetTypeFails) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(
- convertExp->evaluate(Document(), &expCtx->variables),
+ convertExp->evaluate(Document()),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::FailedToParse);
@@ -246,7 +246,7 @@ TEST_F(ExpressionConvertTest, NegativeNumericTargetTypeFails) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(
- convertExp->evaluate(Document(), &expCtx->variables),
+ convertExp->evaluate(Document()),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::FailedToParse);
@@ -304,7 +304,7 @@ TEST_F(ExpressionConvertTest, UnsupportedConversionShouldThrowUnlessOnErrorProvi
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(input, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(input),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -329,8 +329,7 @@ TEST_F(ExpressionConvertTest, UnsupportedConversionShouldThrowUnlessOnErrorProvi
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(input, &expCtx->variables), "X"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(input), "X"_sd, BSONType::String);
}
}
@@ -347,9 +346,9 @@ TEST_F(ExpressionConvertTest, ConvertNullishInput) {
Document undefinedInput{{"path1", BSONUndefined}};
Document missingInput{{"path1", Value()}};
- ASSERT_VALUE_EQ(convertExp->evaluate(nullInput, &expCtx->variables), Value(BSONNULL));
- ASSERT_VALUE_EQ(convertExp->evaluate(undefinedInput, &expCtx->variables), Value(BSONNULL));
- ASSERT_VALUE_EQ(convertExp->evaluate(missingInput, &expCtx->variables), Value(BSONNULL));
+ ASSERT_VALUE_EQ(convertExp->evaluate(nullInput), Value(BSONNULL));
+ ASSERT_VALUE_EQ(convertExp->evaluate(undefinedInput), Value(BSONNULL));
+ ASSERT_VALUE_EQ(convertExp->evaluate(missingInput), Value(BSONNULL));
}
TEST_F(ExpressionConvertTest, ConvertNullishInputWithOnNull) {
@@ -369,9 +368,9 @@ TEST_F(ExpressionConvertTest, ConvertNullishInputWithOnNull) {
Document undefinedInput{{"path1", BSONUndefined}};
Document missingInput{{"path1", Value()}};
- ASSERT_VALUE_EQ(convertExp->evaluate(nullInput, &expCtx->variables), Value("B)"_sd));
- ASSERT_VALUE_EQ(convertExp->evaluate(undefinedInput, &expCtx->variables), Value("B)"_sd));
- ASSERT_VALUE_EQ(convertExp->evaluate(missingInput, &expCtx->variables), Value("B)"_sd));
+ ASSERT_VALUE_EQ(convertExp->evaluate(nullInput), Value("B)"_sd));
+ ASSERT_VALUE_EQ(convertExp->evaluate(undefinedInput), Value("B)"_sd));
+ ASSERT_VALUE_EQ(convertExp->evaluate(missingInput), Value("B)"_sd));
}
TEST_F(ExpressionConvertTest, NullishToReturnsNull) {
@@ -391,9 +390,9 @@ TEST_F(ExpressionConvertTest, NullishToReturnsNull) {
Document undefinedInput{{"path1", BSONUndefined}};
Document missingInput{{"path1", Value()}};
- ASSERT_VALUE_EQ(convertExp->evaluate(nullInput, &expCtx->variables), Value(BSONNULL));
- ASSERT_VALUE_EQ(convertExp->evaluate(undefinedInput, &expCtx->variables), Value(BSONNULL));
- ASSERT_VALUE_EQ(convertExp->evaluate(missingInput, &expCtx->variables), Value(BSONNULL));
+ ASSERT_VALUE_EQ(convertExp->evaluate(nullInput), Value(BSONNULL));
+ ASSERT_VALUE_EQ(convertExp->evaluate(undefinedInput), Value(BSONNULL));
+ ASSERT_VALUE_EQ(convertExp->evaluate(missingInput), Value(BSONNULL));
}
TEST_F(ExpressionConvertTest, NullInputOverridesNullTo) {
@@ -404,8 +403,7 @@ TEST_F(ExpressionConvertTest, NullInputOverridesNullTo) {
<< "X"));
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(Document{}, &expCtx->variables), "X"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(Document{}), "X"_sd, BSONType::String);
}
TEST_F(ExpressionConvertTest, ConvertOptimizesToExpressionConstant) {
@@ -446,21 +444,20 @@ TEST_F(ExpressionConvertTest, DoubleIdentityConversion) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document doubleInput{{"path1", 2.4}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(doubleInput, &expCtx->variables), 2.4, BSONType::NumberDouble);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(doubleInput), 2.4, BSONType::NumberDouble);
Document doubleNaN{{"path1", std::numeric_limits<double>::quiet_NaN()}};
- auto result = convertExp->evaluate(doubleNaN, &expCtx->variables);
+ auto result = convertExp->evaluate(doubleNaN);
ASSERT(std::isnan(result.getDouble()));
Document doubleInfinity{{"path1", std::numeric_limits<double>::infinity()}};
- result = convertExp->evaluate(doubleInfinity, &expCtx->variables);
+ result = convertExp->evaluate(doubleInfinity);
ASSERT_EQ(result.getType(), BSONType::NumberDouble);
ASSERT_GT(result.getDouble(), 0.0);
ASSERT(std::isinf(result.getDouble()));
Document doubleNegativeInfinity{{"path1", -std::numeric_limits<double>::infinity()}};
- result = convertExp->evaluate(doubleNegativeInfinity, &expCtx->variables);
+ result = convertExp->evaluate(doubleNegativeInfinity);
ASSERT_EQ(result.getType(), BSONType::NumberDouble);
ASSERT_LT(result.getDouble(), 0.0);
ASSERT(std::isinf(result.getDouble()));
@@ -476,12 +473,10 @@ TEST_F(ExpressionConvertTest, BoolIdentityConversion) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document trueBoolInput{{"path1", true}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(trueBoolInput, &expCtx->variables), true, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(trueBoolInput), true, BSONType::Bool);
Document falseBoolInput{{"path1", false}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(falseBoolInput, &expCtx->variables), false, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(falseBoolInput), false, BSONType::Bool);
}
TEST_F(ExpressionConvertTest, StringIdentityConversion) {
@@ -495,7 +490,7 @@ TEST_F(ExpressionConvertTest, StringIdentityConversion) {
Document stringInput{{"path1", "More cowbell"_sd}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(stringInput, &expCtx->variables), "More cowbell"_sd, BSONType::String);
+ convertExp->evaluate(stringInput), "More cowbell"_sd, BSONType::String);
}
TEST_F(ExpressionConvertTest, ObjectIdIdentityConversion) {
@@ -508,9 +503,8 @@ TEST_F(ExpressionConvertTest, ObjectIdIdentityConversion) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document oidInput{{"path1", OID("0123456789abcdef01234567")}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(oidInput, &expCtx->variables),
- OID("0123456789abcdef01234567"),
- BSONType::jstOID);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(oidInput), OID("0123456789abcdef01234567"), BSONType::jstOID);
}
TEST_F(ExpressionConvertTest, DateIdentityConversion) {
@@ -523,8 +517,7 @@ TEST_F(ExpressionConvertTest, DateIdentityConversion) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document dateInput{{"path1", Date_t{}}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(dateInput, &expCtx->variables), Date_t{}, BSONType::Date);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(dateInput), Date_t{}, BSONType::Date);
}
TEST_F(ExpressionConvertTest, IntIdentityConversion) {
@@ -537,8 +530,7 @@ TEST_F(ExpressionConvertTest, IntIdentityConversion) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document intInput{{"path1", int{123}}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(intInput, &expCtx->variables), int{123}, BSONType::NumberInt);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(intInput), int{123}, BSONType::NumberInt);
}
TEST_F(ExpressionConvertTest, LongIdentityConversion) {
@@ -551,8 +543,7 @@ TEST_F(ExpressionConvertTest, LongIdentityConversion) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document longInput{{"path1", 123LL}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(longInput, &expCtx->variables), 123LL, BSONType::NumberLong);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(longInput), 123LL, BSONType::NumberLong);
}
TEST_F(ExpressionConvertTest, DecimalIdentityConversion) {
@@ -565,25 +556,22 @@ TEST_F(ExpressionConvertTest, DecimalIdentityConversion) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document decimalInput{{"path1", Decimal128("2.4")}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(decimalInput, &expCtx->variables),
- Decimal128("2.4"),
- BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(decimalInput), Decimal128("2.4"), BSONType::NumberDecimal);
Document decimalNaN{{"path1", Decimal128::kPositiveNaN}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(decimalNaN, &expCtx->variables),
- Decimal128::kPositiveNaN,
- BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(decimalNaN), Decimal128::kPositiveNaN, BSONType::NumberDecimal);
Document decimalInfinity{{"path1", Decimal128::kPositiveInfinity}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(decimalInfinity, &expCtx->variables),
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(decimalInfinity),
Decimal128::kPositiveInfinity,
BSONType::NumberDecimal);
Document decimalNegativeInfinity{{"path1", Decimal128::kNegativeInfinity}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(decimalNegativeInfinity, &expCtx->variables),
- Decimal128::kNegativeInfinity,
- BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(decimalNegativeInfinity),
+ Decimal128::kNegativeInfinity,
+ BSONType::NumberDecimal);
}
TEST_F(ExpressionConvertTest, ConvertDateToBool) {
@@ -597,8 +585,7 @@ TEST_F(ExpressionConvertTest, ConvertDateToBool) {
// All date inputs evaluate as true.
Document dateInput{{"path1", Date_t{}}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(dateInput, &expCtx->variables), true, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(dateInput), true, BSONType::Bool);
}
TEST_F(ExpressionConvertTest, ConvertIntToBool) {
@@ -611,12 +598,10 @@ TEST_F(ExpressionConvertTest, ConvertIntToBool) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document trueIntInput{{"path1", int{1}}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(trueIntInput, &expCtx->variables), true, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(trueIntInput), true, BSONType::Bool);
Document falseIntInput{{"path1", int{0}}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(falseIntInput, &expCtx->variables), false, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(falseIntInput), false, BSONType::Bool);
}
TEST_F(ExpressionConvertTest, ConvertLongToBool) {
@@ -629,12 +614,10 @@ TEST_F(ExpressionConvertTest, ConvertLongToBool) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document trueLongInput{{"path1", -1LL}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(trueLongInput, &expCtx->variables), true, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(trueLongInput), true, BSONType::Bool);
Document falseLongInput{{"path1", 0LL}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(falseLongInput, &expCtx->variables), false, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(falseLongInput), false, BSONType::Bool);
}
TEST_F(ExpressionConvertTest, ConvertDoubleToBool) {
@@ -647,24 +630,20 @@ TEST_F(ExpressionConvertTest, ConvertDoubleToBool) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document trueDoubleInput{{"path1", 2.4}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(trueDoubleInput, &expCtx->variables), true, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(trueDoubleInput), true, BSONType::Bool);
Document falseDoubleInput{{"path1", -0.0}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(falseDoubleInput, &expCtx->variables), false, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(falseDoubleInput), false, BSONType::Bool);
Document doubleNaN{{"path1", std::numeric_limits<double>::quiet_NaN()}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(doubleNaN, &expCtx->variables), true, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(doubleNaN), true, BSONType::Bool);
Document doubleInfinity{{"path1", std::numeric_limits<double>::infinity()}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(doubleInfinity, &expCtx->variables), true, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(doubleInfinity), true, BSONType::Bool);
Document doubleNegativeInfinity{{"path1", -std::numeric_limits<double>::infinity()}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(doubleNegativeInfinity, &expCtx->variables), true, BSONType::Bool);
+ convertExp->evaluate(doubleNegativeInfinity), true, BSONType::Bool);
}
TEST_F(ExpressionConvertTest, ConvertDecimalToBool) {
@@ -677,36 +656,29 @@ TEST_F(ExpressionConvertTest, ConvertDecimalToBool) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document trueDecimalInput{{"path1", Decimal128(5)}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(trueDecimalInput, &expCtx->variables), true, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(trueDecimalInput), true, BSONType::Bool);
Document falseDecimalInput{{"path1", Decimal128(0)}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(falseDecimalInput, &expCtx->variables), false, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(falseDecimalInput), false, BSONType::Bool);
Document preciseZero{{"path1", Decimal128("0.00")}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(preciseZero, &expCtx->variables), false, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(preciseZero), false, BSONType::Bool);
Document negativeZero{{"path1", Decimal128("-0.00")}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(negativeZero, &expCtx->variables), false, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(negativeZero), false, BSONType::Bool);
Document decimalNaN{{"path1", Decimal128::kPositiveNaN}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(decimalNaN, &expCtx->variables), true, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(decimalNaN), true, BSONType::Bool);
Document decimalNegativeNaN{{"path1", Decimal128::kNegativeNaN}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(decimalNegativeNaN, &expCtx->variables), true, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(decimalNegativeNaN), true, BSONType::Bool);
Document decimalInfinity{{"path1", Decimal128::kPositiveInfinity}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(decimalInfinity, &expCtx->variables), true, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(decimalInfinity), true, BSONType::Bool);
Document decimalNegativeInfinity{{"path1", Decimal128::kNegativeInfinity}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(decimalNegativeInfinity, &expCtx->variables), true, BSONType::Bool);
+ convertExp->evaluate(decimalNegativeInfinity), true, BSONType::Bool);
}
TEST_F(ExpressionConvertTest, ConvertStringToBool) {
@@ -719,12 +691,10 @@ TEST_F(ExpressionConvertTest, ConvertStringToBool) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document stringInput{{"path1", "str"_sd}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(stringInput, &expCtx->variables), true, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(stringInput), true, BSONType::Bool);
Document emptyStringInput{{"path1", ""_sd}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(emptyStringInput, &expCtx->variables), true, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(emptyStringInput), true, BSONType::Bool);
}
TEST_F(ExpressionConvertTest, ConvertObjectIdToBool) {
@@ -737,8 +707,7 @@ TEST_F(ExpressionConvertTest, ConvertObjectIdToBool) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document oidInput{{"path1", OID("59E8A8D8FEDCBA9876543210")}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(oidInput, &expCtx->variables), true, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(oidInput), true, BSONType::Bool);
}
TEST_F(ExpressionConvertTest, ConvertMinKeyToBool) {
@@ -751,8 +720,7 @@ TEST_F(ExpressionConvertTest, ConvertMinKeyToBool) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document minKeyInput{{"path1", MINKEY}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(minKeyInput, &expCtx->variables), true, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(minKeyInput), true, BSONType::Bool);
}
TEST_F(ExpressionConvertTest, ConvertObjectToBool) {
@@ -765,8 +733,7 @@ TEST_F(ExpressionConvertTest, ConvertObjectToBool) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document objectInput{{"path1", Document{{"foo", 1}}}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(objectInput, &expCtx->variables), true, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(objectInput), true, BSONType::Bool);
}
TEST_F(ExpressionConvertTest, ConvertArrayToBool) {
@@ -779,8 +746,7 @@ TEST_F(ExpressionConvertTest, ConvertArrayToBool) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document arrayInput{{"path1", BSON_ARRAY(1)}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(arrayInput, &expCtx->variables), true, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(arrayInput), true, BSONType::Bool);
}
TEST_F(ExpressionConvertTest, ConvertBinDataToBool) {
@@ -794,8 +760,7 @@ TEST_F(ExpressionConvertTest, ConvertBinDataToBool) {
char data[] = "(^_^)";
Document binInput{{"path1", BSONBinData(data, sizeof(data), BinDataType::BinDataGeneral)}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(binInput, &expCtx->variables), true, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(binInput), true, BSONType::Bool);
}
TEST_F(ExpressionConvertTest, ConvertRegexToBool) {
@@ -808,8 +773,7 @@ TEST_F(ExpressionConvertTest, ConvertRegexToBool) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document regexInput{{"path1", BSONRegEx("ab*a"_sd)}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(regexInput, &expCtx->variables), true, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(regexInput), true, BSONType::Bool);
}
TEST_F(ExpressionConvertTest, ConvertDBRefToBool) {
@@ -822,8 +786,7 @@ TEST_F(ExpressionConvertTest, ConvertDBRefToBool) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document refInput{{"path1", BSONDBRef("db.coll"_sd, OID("aaaaaaaaaaaaaaaaaaaaaaaa"))}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(refInput, &expCtx->variables), true, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(refInput), true, BSONType::Bool);
}
TEST_F(ExpressionConvertTest, ConvertCodeToBool) {
@@ -836,8 +799,7 @@ TEST_F(ExpressionConvertTest, ConvertCodeToBool) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document codeInput{{"path1", BSONCode("print('Hello world!');"_sd)}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(codeInput, &expCtx->variables), true, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(codeInput), true, BSONType::Bool);
}
TEST_F(ExpressionConvertTest, ConvertSymbolToBool) {
@@ -850,8 +812,7 @@ TEST_F(ExpressionConvertTest, ConvertSymbolToBool) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document symbolInput{{"path1", BSONSymbol("print"_sd)}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(symbolInput, &expCtx->variables), true, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(symbolInput), true, BSONType::Bool);
}
TEST_F(ExpressionConvertTest, ConvertCodeWScopeToBool) {
@@ -865,8 +826,7 @@ TEST_F(ExpressionConvertTest, ConvertCodeWScopeToBool) {
Document codeWScopeInput{
{"path1", BSONCodeWScope("print('Hello again, world!')"_sd, BSONObj())}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(codeWScopeInput, &expCtx->variables), true, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(codeWScopeInput), true, BSONType::Bool);
}
TEST_F(ExpressionConvertTest, ConvertTimestampToBool) {
@@ -879,8 +839,7 @@ TEST_F(ExpressionConvertTest, ConvertTimestampToBool) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document timestampInput{{"path1", Timestamp()}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(timestampInput, &expCtx->variables), true, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(timestampInput), true, BSONType::Bool);
}
TEST_F(ExpressionConvertTest, ConvertMaxKeyToBool) {
@@ -893,8 +852,7 @@ TEST_F(ExpressionConvertTest, ConvertMaxKeyToBool) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document maxKeyInput{{"path1", MAXKEY}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(maxKeyInput, &expCtx->variables), true, BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(maxKeyInput), true, BSONType::Bool);
}
TEST_F(ExpressionConvertTest, ConvertNumericToDouble) {
@@ -907,43 +865,39 @@ TEST_F(ExpressionConvertTest, ConvertNumericToDouble) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document intInput{{"path1", int{1}}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(intInput, &expCtx->variables), 1.0, BSONType::NumberDouble);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(intInput), 1.0, BSONType::NumberDouble);
Document longInput{{"path1", 0xf00000000LL}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(longInput, &expCtx->variables), 64424509440.0, BSONType::NumberDouble);
+ convertExp->evaluate(longInput), 64424509440.0, BSONType::NumberDouble);
Document decimalInput{{"path1", Decimal128("5.5")}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(decimalInput, &expCtx->variables), 5.5, BSONType::NumberDouble);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(decimalInput), 5.5, BSONType::NumberDouble);
Document boolFalse{{"path1", false}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(boolFalse, &expCtx->variables), 0.0, BSONType::NumberDouble);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(boolFalse), 0.0, BSONType::NumberDouble);
Document boolTrue{{"path1", true}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(boolTrue, &expCtx->variables), 1.0, BSONType::NumberDouble);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(boolTrue), 1.0, BSONType::NumberDouble);
Document decimalNaN{{"path1", Decimal128::kPositiveNaN}};
- auto result = convertExp->evaluate(decimalNaN, &expCtx->variables);
+ auto result = convertExp->evaluate(decimalNaN);
ASSERT_EQ(result.getType(), BSONType::NumberDouble);
ASSERT(std::isnan(result.getDouble()));
Document decimalNegativeNaN{{"path1", Decimal128::kNegativeNaN}};
- result = convertExp->evaluate(decimalNegativeNaN, &expCtx->variables);
+ result = convertExp->evaluate(decimalNegativeNaN);
ASSERT_EQ(result.getType(), BSONType::NumberDouble);
ASSERT(std::isnan(result.getDouble()));
Document decimalInfinity{{"path1", Decimal128::kPositiveInfinity}};
- result = convertExp->evaluate(decimalInfinity, &expCtx->variables);
+ result = convertExp->evaluate(decimalInfinity);
ASSERT_EQ(result.getType(), BSONType::NumberDouble);
ASSERT_GT(result.getDouble(), 0.0);
ASSERT(std::isinf(result.getDouble()));
Document decimalNegativeInfinity{{"path1", Decimal128::kNegativeInfinity}};
- result = convertExp->evaluate(decimalNegativeInfinity, &expCtx->variables);
+ result = convertExp->evaluate(decimalNegativeInfinity);
ASSERT_EQ(result.getType(), BSONType::NumberDouble);
ASSERT_LT(result.getDouble(), 0.0);
ASSERT(std::isinf(result.getDouble()));
@@ -951,12 +905,12 @@ TEST_F(ExpressionConvertTest, ConvertNumericToDouble) {
// Note that the least significant bits get lost, because the significand of a double is not
// wide enough for the original long long value in its entirety.
Document largeLongInput{{"path1", 0xf0000000000000fLL}};
- result = convertExp->evaluate(largeLongInput, &expCtx->variables);
+ result = convertExp->evaluate(largeLongInput);
ASSERT_EQ(static_cast<long long>(result.getDouble()), 0xf00000000000000LL);
// Again, some precision is lost in the conversion from Decimal128 to double.
Document preciseDecimalInput{{"path1", Decimal128("1.125000000000000000005")}};
- result = convertExp->evaluate(preciseDecimalInput, &expCtx->variables);
+ result = convertExp->evaluate(preciseDecimalInput);
ASSERT_EQ(result.getDouble(), 1.125);
}
@@ -970,15 +924,13 @@ TEST_F(ExpressionConvertTest, ConvertDateToDouble) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document dateInput{{"path1", Date_t::fromMillisSinceEpoch(123)}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(dateInput, &expCtx->variables), 123.0, BSONType::NumberDouble);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(dateInput), 123.0, BSONType::NumberDouble);
// Note that the least significant bits get lost, because the significand of a double is not
// wide enough for the original 64-bit Date_t value in its entirety.
Document largeDateInput{{"path1", Date_t::fromMillisSinceEpoch(0xf0000000000000fLL)}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(largeDateInput, &expCtx->variables),
- 0xf00000000000000LL,
- BSONType::NumberDouble);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(largeDateInput), 0xf00000000000000LL, BSONType::NumberDouble);
}
TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDecimalToDouble) {
@@ -991,7 +943,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDecimalToDouble) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document overflowInput{{"path1", Decimal128("1e309")}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(overflowInput, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(overflowInput),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1000,7 +952,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDecimalToDouble) {
});
Document negativeOverflowInput{{"path1", Decimal128("-1e309")}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(negativeOverflowInput, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(negativeOverflowInput),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1021,12 +973,11 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDecimalToDoubleWithOnError) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document overflowInput{{"path1", Decimal128("1e309")}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(overflowInput, &expCtx->variables), "X"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(overflowInput), "X"_sd, BSONType::String);
Document negativeOverflowInput{{"path1", Decimal128("-1e309")}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(negativeOverflowInput, &expCtx->variables), "X"_sd, BSONType::String);
+ convertExp->evaluate(negativeOverflowInput), "X"_sd, BSONType::String);
}
TEST_F(ExpressionConvertTest, ConvertNumericToDecimal) {
@@ -1040,48 +991,44 @@ TEST_F(ExpressionConvertTest, ConvertNumericToDecimal) {
Document intInput{{"path1", int{1}}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(intInput, &expCtx->variables), Decimal128(1), BSONType::NumberDecimal);
+ convertExp->evaluate(intInput), Decimal128(1), BSONType::NumberDecimal);
Document longInput{{"path1", 0xf00000000LL}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(longInput, &expCtx->variables),
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(longInput),
Decimal128(std::int64_t{0xf00000000LL}),
BSONType::NumberDecimal);
Document doubleInput{{"path1", 0.1}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(doubleInput, &expCtx->variables),
- Decimal128("0.1"),
- BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(doubleInput), Decimal128("0.1"), BSONType::NumberDecimal);
Document boolFalse{{"path1", false}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(boolFalse, &expCtx->variables),
- Decimal128(0),
- BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(boolFalse), Decimal128(0), BSONType::NumberDecimal);
Document boolTrue{{"path1", true}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(boolTrue, &expCtx->variables), Decimal128(1), BSONType::NumberDecimal);
+ convertExp->evaluate(boolTrue), Decimal128(1), BSONType::NumberDecimal);
Document doubleNaN{{"path1", std::numeric_limits<double>::quiet_NaN()}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(doubleNaN, &expCtx->variables),
- Decimal128::kPositiveNaN,
- BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(doubleNaN), Decimal128::kPositiveNaN, BSONType::NumberDecimal);
Document doubleInfinity{{"path1", std::numeric_limits<double>::infinity()}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(doubleInfinity, &expCtx->variables),
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(doubleInfinity),
Decimal128::kPositiveInfinity,
BSONType::NumberDecimal);
Document doubleNegativeInfinity{{"path1", -std::numeric_limits<double>::infinity()}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(doubleNegativeInfinity, &expCtx->variables),
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(doubleNegativeInfinity),
Decimal128::kNegativeInfinity,
BSONType::NumberDecimal);
// Unlike the similar conversion in ConvertNumericToDouble, there is more than enough precision
// to store the exact orignal value in a Decimal128.
Document largeLongInput{{"path1", 0xf0000000000000fLL}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(largeLongInput, &expCtx->variables),
- 0xf0000000000000fLL,
- BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(largeLongInput), 0xf0000000000000fLL, BSONType::NumberDecimal);
}
TEST_F(ExpressionConvertTest, ConvertDateToDecimal) {
@@ -1094,14 +1041,12 @@ TEST_F(ExpressionConvertTest, ConvertDateToDecimal) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document dateInput{{"path1", Date_t::fromMillisSinceEpoch(123)}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(dateInput, &expCtx->variables),
- Decimal128(123),
- BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(dateInput), Decimal128(123), BSONType::NumberDecimal);
Document largeDateInput{{"path1", Date_t::fromMillisSinceEpoch(0xf0000000000000fLL)}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(largeDateInput, &expCtx->variables),
- 0xf0000000000000fLL,
- BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(largeDateInput), 0xf0000000000000fLL, BSONType::NumberDecimal);
}
TEST_F(ExpressionConvertTest, ConvertDoubleToInt) {
@@ -1114,35 +1059,28 @@ TEST_F(ExpressionConvertTest, ConvertDoubleToInt) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document simpleInput{{"path1", 1.0}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(simpleInput, &expCtx->variables), 1, BSONType::NumberInt);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(simpleInput), 1, BSONType::NumberInt);
// Conversions to int should always truncate the fraction (i.e., round towards 0).
Document nonIntegerInput1{{"path1", 2.1}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(nonIntegerInput1, &expCtx->variables), 2, BSONType::NumberInt);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(nonIntegerInput1), 2, BSONType::NumberInt);
Document nonIntegerInput2{{"path1", 2.9}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(nonIntegerInput2, &expCtx->variables), 2, BSONType::NumberInt);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(nonIntegerInput2), 2, BSONType::NumberInt);
Document nonIntegerInput3{{"path1", -2.1}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(nonIntegerInput3, &expCtx->variables), -2, BSONType::NumberInt);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(nonIntegerInput3), -2, BSONType::NumberInt);
Document nonIntegerInput4{{"path1", -2.9}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(nonIntegerInput4, &expCtx->variables), -2, BSONType::NumberInt);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(nonIntegerInput4), -2, BSONType::NumberInt);
int maxInt = std::numeric_limits<int>::max();
Document maxInput{{"path1", static_cast<double>(maxInt)}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(maxInput, &expCtx->variables), maxInt, BSONType::NumberInt);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(maxInput), maxInt, BSONType::NumberInt);
int minInt = std::numeric_limits<int>::lowest();
Document minInput{{"path1", static_cast<double>(minInt)}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(minInput, &expCtx->variables), minInt, BSONType::NumberInt);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(minInput), minInt, BSONType::NumberInt);
}
TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDoubleToInt) {
@@ -1158,7 +1096,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDoubleToInt) {
double overflowInt =
std::nextafter(static_cast<double>(maxInt), std::numeric_limits<double>::max());
Document overflowInput{{"path1", overflowInt}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(overflowInput, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(overflowInput),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1170,7 +1108,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDoubleToInt) {
double negativeOverflowInt =
std::nextafter(static_cast<double>(minInt), std::numeric_limits<double>::lowest());
Document negativeOverflowInput{{"path1", negativeOverflowInt}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(negativeOverflowInput, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(negativeOverflowInput),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1179,7 +1117,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDoubleToInt) {
});
Document nanInput{{"path1", std::numeric_limits<double>::quiet_NaN()}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(nanInput, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(nanInput),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1188,7 +1126,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDoubleToInt) {
});
Document doubleInfinity{{"path1", std::numeric_limits<double>::infinity()}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(doubleInfinity, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(doubleInfinity),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1198,7 +1136,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDoubleToInt) {
});
Document doubleNegativeInfinity{{"path1", -std::numeric_limits<double>::infinity()}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(doubleNegativeInfinity, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(doubleNegativeInfinity),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1223,27 +1161,24 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDoubleToIntWithOnError) {
double overflowInt =
std::nextafter(static_cast<double>(maxInt), std::numeric_limits<double>::max());
Document overflowInput{{"path1", overflowInt}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(overflowInput, &expCtx->variables), "X"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(overflowInput), "X"_sd, BSONType::String);
int minInt = std::numeric_limits<int>::lowest();
double negativeOverflowInt =
std::nextafter(static_cast<double>(minInt), std::numeric_limits<double>::lowest());
Document negativeOverflowInput{{"path1", negativeOverflowInt}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(negativeOverflowInput, &expCtx->variables), "X"_sd, BSONType::String);
+ convertExp->evaluate(negativeOverflowInput), "X"_sd, BSONType::String);
Document nanInput{{"path1", std::numeric_limits<double>::quiet_NaN()}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(nanInput, &expCtx->variables), "X"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(nanInput), "X"_sd, BSONType::String);
Document doubleInfinity{{"path1", std::numeric_limits<double>::infinity()}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(doubleInfinity, &expCtx->variables), "X"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(doubleInfinity), "X"_sd, BSONType::String);
Document doubleNegativeInfinity{{"path1", -std::numeric_limits<double>::infinity()}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(doubleNegativeInfinity, &expCtx->variables), "X"_sd, BSONType::String);
+ convertExp->evaluate(doubleNegativeInfinity), "X"_sd, BSONType::String);
}
TEST_F(ExpressionConvertTest, ConvertDoubleToLong) {
@@ -1256,39 +1191,34 @@ TEST_F(ExpressionConvertTest, ConvertDoubleToLong) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document simpleInput{{"path1", 1.0}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(simpleInput, &expCtx->variables), 1, BSONType::NumberLong);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(simpleInput), 1, BSONType::NumberLong);
// Conversions to int should always truncate the fraction (i.e., round towards 0).
Document nonIntegerInput1{{"path1", 2.1}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(nonIntegerInput1, &expCtx->variables), 2, BSONType::NumberLong);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(nonIntegerInput1), 2, BSONType::NumberLong);
Document nonIntegerInput2{{"path1", 2.9}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(nonIntegerInput2, &expCtx->variables), 2, BSONType::NumberLong);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(nonIntegerInput2), 2, BSONType::NumberLong);
Document nonIntegerInput3{{"path1", -2.1}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(nonIntegerInput3, &expCtx->variables), -2, BSONType::NumberLong);
+ convertExp->evaluate(nonIntegerInput3), -2, BSONType::NumberLong);
Document nonIntegerInput4{{"path1", -2.9}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(nonIntegerInput4, &expCtx->variables), -2, BSONType::NumberLong);
+ convertExp->evaluate(nonIntegerInput4), -2, BSONType::NumberLong);
// maxVal is the highest double value that will not overflow long long.
double maxVal = std::nextafter(BSONElement::kLongLongMaxPlusOneAsDouble, 0.0);
Document maxInput{{"path1", maxVal}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(maxInput, &expCtx->variables),
- static_cast<long long>(maxVal),
- BSONType::NumberLong);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(maxInput), static_cast<long long>(maxVal), BSONType::NumberLong);
// minVal is the lowest double value that will not overflow long long.
double minVal = static_cast<double>(std::numeric_limits<long long>::lowest());
Document minInput{{"path1", minVal}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(minInput, &expCtx->variables),
- static_cast<long long>(minVal),
- BSONType::NumberLong);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(minInput), static_cast<long long>(minVal), BSONType::NumberLong);
}
TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDoubleToLong) {
@@ -1302,7 +1232,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDoubleToLong) {
double overflowLong = BSONElement::kLongLongMaxPlusOneAsDouble;
Document overflowInput{{"path1", overflowLong}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(overflowInput, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(overflowInput),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1314,7 +1244,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDoubleToLong) {
double negativeOverflowLong =
std::nextafter(static_cast<double>(minLong), std::numeric_limits<double>::lowest());
Document negativeOverflowInput{{"path1", negativeOverflowLong}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(negativeOverflowInput, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(negativeOverflowInput),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1323,7 +1253,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDoubleToLong) {
});
Document nanInput{{"path1", std::numeric_limits<double>::quiet_NaN()}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(nanInput, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(nanInput),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1332,7 +1262,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDoubleToLong) {
});
Document doubleInfinity{{"path1", std::numeric_limits<double>::infinity()}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(doubleInfinity, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(doubleInfinity),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1342,7 +1272,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDoubleToLong) {
});
Document doubleNegativeInfinity{{"path1", -std::numeric_limits<double>::infinity()}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(doubleNegativeInfinity, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(doubleNegativeInfinity),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1365,27 +1295,24 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDoubleToLongWithOnError) {
double overflowLong = BSONElement::kLongLongMaxPlusOneAsDouble;
Document overflowInput{{"path1", overflowLong}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(overflowInput, &expCtx->variables), "X"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(overflowInput), "X"_sd, BSONType::String);
double minLong = static_cast<double>(std::numeric_limits<long long>::lowest());
double negativeOverflowLong =
std::nextafter(static_cast<double>(minLong), std::numeric_limits<double>::lowest());
Document negativeOverflowInput{{"path1", negativeOverflowLong}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(negativeOverflowInput, &expCtx->variables), "X"_sd, BSONType::String);
+ convertExp->evaluate(negativeOverflowInput), "X"_sd, BSONType::String);
Document nanInput{{"path1", std::numeric_limits<double>::quiet_NaN()}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(nanInput, &expCtx->variables), "X"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(nanInput), "X"_sd, BSONType::String);
Document doubleInfinity{{"path1", std::numeric_limits<double>::infinity()}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(doubleInfinity, &expCtx->variables), "X"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(doubleInfinity), "X"_sd, BSONType::String);
Document doubleNegativeInfinity{{"path1", -std::numeric_limits<double>::infinity()}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(doubleNegativeInfinity, &expCtx->variables), "X"_sd, BSONType::String);
+ convertExp->evaluate(doubleNegativeInfinity), "X"_sd, BSONType::String);
}
TEST_F(ExpressionConvertTest, ConvertDecimalToInt) {
@@ -1398,35 +1325,28 @@ TEST_F(ExpressionConvertTest, ConvertDecimalToInt) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document simpleInput{{"path1", Decimal128("1.0")}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(simpleInput, &expCtx->variables), 1, BSONType::NumberInt);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(simpleInput), 1, BSONType::NumberInt);
// Conversions to int should always truncate the fraction (i.e., round towards 0).
Document nonIntegerInput1{{"path1", Decimal128("2.1")}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(nonIntegerInput1, &expCtx->variables), 2, BSONType::NumberInt);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(nonIntegerInput1), 2, BSONType::NumberInt);
Document nonIntegerInput2{{"path1", Decimal128("2.9")}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(nonIntegerInput2, &expCtx->variables), 2, BSONType::NumberInt);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(nonIntegerInput2), 2, BSONType::NumberInt);
Document nonIntegerInput3{{"path1", Decimal128("-2.1")}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(nonIntegerInput3, &expCtx->variables), -2, BSONType::NumberInt);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(nonIntegerInput3), -2, BSONType::NumberInt);
Document nonIntegerInput4{{"path1", Decimal128("-2.9")}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(nonIntegerInput3, &expCtx->variables), -2, BSONType::NumberInt);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(nonIntegerInput3), -2, BSONType::NumberInt);
int maxInt = std::numeric_limits<int>::max();
Document maxInput{{"path1", Decimal128(maxInt)}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(maxInput, &expCtx->variables), maxInt, BSONType::NumberInt);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(maxInput), maxInt, BSONType::NumberInt);
int minInt = std::numeric_limits<int>::min();
Document minInput{{"path1", Decimal128(minInt)}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(minInput, &expCtx->variables), minInt, BSONType::NumberInt);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(minInput), minInt, BSONType::NumberInt);
}
TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDecimalToInt) {
@@ -1440,7 +1360,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDecimalToInt) {
int maxInt = std::numeric_limits<int>::max();
Document overflowInput{{"path1", Decimal128(maxInt).add(Decimal128(1))}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(overflowInput, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(overflowInput),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1450,7 +1370,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDecimalToInt) {
int minInt = std::numeric_limits<int>::lowest();
Document negativeOverflowInput{{"path1", Decimal128(minInt).subtract(Decimal128(1))}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(negativeOverflowInput, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(negativeOverflowInput),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1459,7 +1379,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDecimalToInt) {
});
Document nanInput{{"path1", Decimal128::kPositiveNaN}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(nanInput, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(nanInput),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1468,7 +1388,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDecimalToInt) {
});
Document negativeNaNInput{{"path1", Decimal128::kNegativeNaN}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(negativeNaNInput, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(negativeNaNInput),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1477,7 +1397,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDecimalToInt) {
});
Document decimalInfinity{{"path1", Decimal128::kPositiveInfinity}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(decimalInfinity, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(decimalInfinity),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1487,7 +1407,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDecimalToInt) {
});
Document decimalNegativeInfinity{{"path1", Decimal128::kNegativeInfinity}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(decimalNegativeInfinity, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(decimalNegativeInfinity),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1510,31 +1430,26 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDecimalToIntWithOnError) {
int maxInt = std::numeric_limits<int>::max();
Document overflowInput{{"path1", Decimal128(maxInt).add(Decimal128(1))}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(overflowInput, &expCtx->variables), "X"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(overflowInput), "X"_sd, BSONType::String);
int minInt = std::numeric_limits<int>::lowest();
Document negativeOverflowInput{{"path1", Decimal128(minInt).subtract(Decimal128(1))}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(negativeOverflowInput, &expCtx->variables), "X"_sd, BSONType::String);
+ convertExp->evaluate(negativeOverflowInput), "X"_sd, BSONType::String);
Document nanInput{{"path1", Decimal128::kPositiveNaN}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(nanInput, &expCtx->variables), "X"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(nanInput), "X"_sd, BSONType::String);
Document negativeNaNInput{{"path1", Decimal128::kNegativeNaN}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(negativeNaNInput, &expCtx->variables), "X"_sd, BSONType::String);
+ convertExp->evaluate(negativeNaNInput), "X"_sd, BSONType::String);
Document decimalInfinity{{"path1", Decimal128::kPositiveInfinity}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(decimalInfinity, &expCtx->variables), "X"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(decimalInfinity), "X"_sd, BSONType::String);
Document decimalNegativeInfinity{{"path1", Decimal128::kNegativeInfinity}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(decimalNegativeInfinity, &expCtx->variables),
- "X"_sd,
- BSONType::String);
+ convertExp->evaluate(decimalNegativeInfinity), "X"_sd, BSONType::String);
}
TEST_F(ExpressionConvertTest, ConvertDecimalToLong) {
@@ -1547,35 +1462,30 @@ TEST_F(ExpressionConvertTest, ConvertDecimalToLong) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document simpleInput{{"path1", Decimal128("1.0")}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(simpleInput, &expCtx->variables), 1, BSONType::NumberLong);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(simpleInput), 1, BSONType::NumberLong);
// Conversions to long should always truncate the fraction (i.e., round towards 0).
Document nonIntegerInput1{{"path1", Decimal128("2.1")}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(nonIntegerInput1, &expCtx->variables), 2, BSONType::NumberLong);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(nonIntegerInput1), 2, BSONType::NumberLong);
Document nonIntegerInput2{{"path1", Decimal128("2.9")}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(nonIntegerInput2, &expCtx->variables), 2, BSONType::NumberLong);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(nonIntegerInput2), 2, BSONType::NumberLong);
Document nonIntegerInput3{{"path1", Decimal128("-2.1")}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(nonIntegerInput3, &expCtx->variables), -2, BSONType::NumberLong);
+ convertExp->evaluate(nonIntegerInput3), -2, BSONType::NumberLong);
Document nonIntegerInput4{{"path1", Decimal128("-2.9")}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(nonIntegerInput4, &expCtx->variables), -2, BSONType::NumberLong);
+ convertExp->evaluate(nonIntegerInput4), -2, BSONType::NumberLong);
long long maxVal = std::numeric_limits<long long>::max();
Document maxInput{{"path1", Decimal128(std::int64_t{maxVal})}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(maxInput, &expCtx->variables), maxVal, BSONType::NumberLong);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(maxInput), maxVal, BSONType::NumberLong);
long long minVal = std::numeric_limits<long long>::min();
Document minInput{{"path1", Decimal128(std::int64_t{minVal})}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(minInput, &expCtx->variables), minVal, BSONType::NumberLong);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(minInput), minVal, BSONType::NumberLong);
}
TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDecimalToLong) {
@@ -1589,7 +1499,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDecimalToLong) {
long long maxVal = std::numeric_limits<long long>::max();
Document overflowInput{{"path1", Decimal128(std::int64_t{maxVal}).add(Decimal128(1))}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(overflowInput, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(overflowInput),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1600,7 +1510,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDecimalToLong) {
long long minVal = std::numeric_limits<long long>::lowest();
Document negativeOverflowInput{
{"path1", Decimal128(std::int64_t{minVal}).subtract(Decimal128(1))}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(negativeOverflowInput, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(negativeOverflowInput),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1609,7 +1519,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDecimalToLong) {
});
Document nanInput{{"path1", Decimal128::kPositiveNaN}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(nanInput, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(nanInput),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1618,7 +1528,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDecimalToLong) {
});
Document negativeNaNInput{{"path1", Decimal128::kNegativeNaN}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(negativeNaNInput, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(negativeNaNInput),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1627,7 +1537,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDecimalToLong) {
});
Document decimalInfinity{{"path1", Decimal128::kPositiveInfinity}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(decimalInfinity, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(decimalInfinity),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1637,7 +1547,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDecimalToLong) {
});
Document decimalNegativeInfinity{{"path1", Decimal128::kNegativeInfinity}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(decimalNegativeInfinity, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(decimalNegativeInfinity),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1660,32 +1570,27 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsDecimalToLongWithOnError) {
long long maxVal = std::numeric_limits<long long>::max();
Document overflowInput{{"path1", Decimal128(std::int64_t{maxVal}).add(Decimal128(1))}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(overflowInput, &expCtx->variables), "X"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(overflowInput), "X"_sd, BSONType::String);
long long minVal = std::numeric_limits<long long>::lowest();
Document negativeOverflowInput{
{"path1", Decimal128(std::int64_t{minVal}).subtract(Decimal128(1))}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(negativeOverflowInput, &expCtx->variables), "X"_sd, BSONType::String);
+ convertExp->evaluate(negativeOverflowInput), "X"_sd, BSONType::String);
Document nanInput{{"path1", Decimal128::kPositiveNaN}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(nanInput, &expCtx->variables), "X"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(nanInput), "X"_sd, BSONType::String);
Document negativeNaNInput{{"path1", Decimal128::kNegativeNaN}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(negativeNaNInput, &expCtx->variables), "X"_sd, BSONType::String);
+ convertExp->evaluate(negativeNaNInput), "X"_sd, BSONType::String);
Document decimalInfinity{{"path1", Decimal128::kPositiveInfinity}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(decimalInfinity, &expCtx->variables), "X"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(decimalInfinity), "X"_sd, BSONType::String);
Document decimalNegativeInfinity{{"path1", Decimal128::kNegativeInfinity}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(decimalNegativeInfinity, &expCtx->variables),
- "X"_sd,
- BSONType::String);
+ convertExp->evaluate(decimalNegativeInfinity), "X"_sd, BSONType::String);
}
TEST_F(ExpressionConvertTest, ConvertDateToLong) {
@@ -1698,8 +1603,7 @@ TEST_F(ExpressionConvertTest, ConvertDateToLong) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document dateInput{{"path1", Date_t::fromMillisSinceEpoch(123LL)}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(dateInput, &expCtx->variables), 123LL, BSONType::NumberLong);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(dateInput), 123LL, BSONType::NumberLong);
}
TEST_F(ExpressionConvertTest, ConvertIntToLong) {
@@ -1712,18 +1616,15 @@ TEST_F(ExpressionConvertTest, ConvertIntToLong) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document simpleInput{{"path1", 1}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(simpleInput, &expCtx->variables), 1LL, BSONType::NumberLong);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(simpleInput), 1LL, BSONType::NumberLong);
int maxInt = std::numeric_limits<int>::max();
Document maxInput{{"path1", maxInt}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(maxInput, &expCtx->variables), maxInt, BSONType::NumberLong);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(maxInput), maxInt, BSONType::NumberLong);
int minInt = std::numeric_limits<int>::min();
Document minInput{{"path1", minInt}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(minInput, &expCtx->variables), minInt, BSONType::NumberLong);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(minInput), minInt, BSONType::NumberLong);
}
TEST_F(ExpressionConvertTest, ConvertLongToInt) {
@@ -1736,18 +1637,15 @@ TEST_F(ExpressionConvertTest, ConvertLongToInt) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document simpleInput{{"path1", 1}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(simpleInput, &expCtx->variables), 1, BSONType::NumberInt);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(simpleInput), 1, BSONType::NumberInt);
long long maxInt = std::numeric_limits<int>::max();
Document maxInput{{"path1", maxInt}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(maxInput, &expCtx->variables), maxInt, BSONType::NumberInt);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(maxInput), maxInt, BSONType::NumberInt);
long long minInt = std::numeric_limits<int>::min();
Document minInput{{"path1", minInt}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(minInput, &expCtx->variables), minInt, BSONType::NumberInt);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(minInput), minInt, BSONType::NumberInt);
}
TEST_F(ExpressionConvertTest, ConvertOutOfBoundsLongToInt) {
@@ -1761,7 +1659,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsLongToInt) {
long long maxInt = std::numeric_limits<int>::max();
Document overflowInput{{"path1", maxInt + 1}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(overflowInput, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(overflowInput),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1771,7 +1669,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsLongToInt) {
long long minInt = std::numeric_limits<int>::min();
Document negativeOverflowInput{{"path1", minInt - 1}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(negativeOverflowInput, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(negativeOverflowInput),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1793,13 +1691,12 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsLongToIntWithOnError) {
long long maxInt = std::numeric_limits<int>::max();
Document overflowInput{{"path1", maxInt + 1}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(overflowInput, &expCtx->variables), "X"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(overflowInput), "X"_sd, BSONType::String);
long long minInt = std::numeric_limits<int>::min();
Document negativeOverflowInput{{"path1", minInt - 1}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(negativeOverflowInput, &expCtx->variables), "X"_sd, BSONType::String);
+ convertExp->evaluate(negativeOverflowInput), "X"_sd, BSONType::String);
}
TEST_F(ExpressionConvertTest, ConvertBoolToInt) {
@@ -1812,12 +1709,10 @@ TEST_F(ExpressionConvertTest, ConvertBoolToInt) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document boolFalse{{"path1", false}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(boolFalse, &expCtx->variables), 0, BSONType::NumberInt);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(boolFalse), 0, BSONType::NumberInt);
Document boolTrue{{"path1", true}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(boolTrue, &expCtx->variables), 1, BSONType::NumberInt);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(boolTrue), 1, BSONType::NumberInt);
}
TEST_F(ExpressionConvertTest, ConvertBoolToLong) {
@@ -1830,12 +1725,10 @@ TEST_F(ExpressionConvertTest, ConvertBoolToLong) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document boolFalse{{"path1", false}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(boolFalse, &expCtx->variables), 0LL, BSONType::NumberLong);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(boolFalse), 0LL, BSONType::NumberLong);
Document boolTrue{{"path1", true}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(boolTrue, &expCtx->variables), 1LL, BSONType::NumberLong);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(boolTrue), 1LL, BSONType::NumberLong);
}
TEST_F(ExpressionConvertTest, ConvertNumberToDate) {
@@ -1848,25 +1741,23 @@ TEST_F(ExpressionConvertTest, ConvertNumberToDate) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document longInput{{"path1", 0LL}};
- ASSERT_EQ(dateToISOStringUTC(convertExp->evaluate(longInput, &expCtx->variables).getDate()),
+ ASSERT_EQ(dateToISOStringUTC(convertExp->evaluate(longInput).getDate()),
"1970-01-01T00:00:00.000Z");
Document doubleInput{{"path1", 431568000000.0}};
- ASSERT_EQ(dateToISOStringUTC(convertExp->evaluate(doubleInput, &expCtx->variables).getDate()),
+ ASSERT_EQ(dateToISOStringUTC(convertExp->evaluate(doubleInput).getDate()),
"1983-09-05T00:00:00.000Z");
Document doubleInputWithFraction{{"path1", 431568000000.987}};
- ASSERT_EQ(dateToISOStringUTC(
- convertExp->evaluate(doubleInputWithFraction, &expCtx->variables).getDate()),
+ ASSERT_EQ(dateToISOStringUTC(convertExp->evaluate(doubleInputWithFraction).getDate()),
"1983-09-05T00:00:00.000Z");
Document decimalInput{{"path1", Decimal128("872835240000")}};
- ASSERT_EQ(dateToISOStringUTC(convertExp->evaluate(decimalInput, &expCtx->variables).getDate()),
+ ASSERT_EQ(dateToISOStringUTC(convertExp->evaluate(decimalInput).getDate()),
"1997-08-29T06:14:00.000Z");
Document decimalInputWithFraction{{"path1", Decimal128("872835240000.987")}};
- ASSERT_EQ(dateToISOStringUTC(
- convertExp->evaluate(decimalInputWithFraction, &expCtx->variables).getDate()),
+ ASSERT_EQ(dateToISOStringUTC(convertExp->evaluate(decimalInputWithFraction).getDate()),
"1997-08-29T06:14:00.000Z");
}
@@ -1880,7 +1771,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsNumberToDate) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document doubleOverflowInput{{"path1", 1.0e100}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(doubleOverflowInput, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(doubleOverflowInput),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1889,7 +1780,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsNumberToDate) {
});
Document doubleNegativeOverflowInput{{"path1", -1.0e100}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(doubleNegativeOverflowInput, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(doubleNegativeOverflowInput),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1898,7 +1789,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsNumberToDate) {
});
Document doubleNaN{{"path1", std::numeric_limits<double>::quiet_NaN()}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(doubleNaN, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(doubleNaN),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1908,7 +1799,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsNumberToDate) {
});
Document doubleInfinity{{"path1", std::numeric_limits<double>::infinity()}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(doubleInfinity, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(doubleInfinity),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1918,7 +1809,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsNumberToDate) {
});
Document doubleNegativeInfinity{{"path1", -std::numeric_limits<double>::infinity()}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(doubleNegativeInfinity, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(doubleNegativeInfinity),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1928,7 +1819,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsNumberToDate) {
});
Document decimalOverflowInput{{"path1", Decimal128("1.0e100")}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(decimalOverflowInput, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(decimalOverflowInput),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1937,7 +1828,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsNumberToDate) {
});
Document decimalNegativeOverflowInput{{"path1", Decimal128("1.0e100")}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(decimalNegativeOverflowInput, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(decimalNegativeOverflowInput),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1946,7 +1837,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsNumberToDate) {
});
Document decimalNaN{{"path1", Decimal128::kPositiveNaN}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(decimalNaN, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(decimalNaN),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1956,7 +1847,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsNumberToDate) {
});
Document decimalNegativeNaN{{"path1", Decimal128::kNegativeNaN}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(decimalNegativeNaN, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(decimalNegativeNaN),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1966,7 +1857,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsNumberToDate) {
});
Document decimalInfinity{{"path1", Decimal128::kPositiveInfinity}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(decimalInfinity, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(decimalInfinity),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1976,7 +1867,7 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsNumberToDate) {
});
Document decimalNegativeInfinity{{"path1", Decimal128::kNegativeInfinity}};
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(decimalNegativeInfinity, &expCtx->variables),
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate(decimalNegativeInfinity),
AssertionException,
[](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
@@ -1999,58 +1890,47 @@ TEST_F(ExpressionConvertTest, ConvertOutOfBoundsNumberToDateWithOnError) {
// Int is explicitly disallowed for date conversions. Clients must use 64-bit long instead.
Document intInput{{"path1", int{0}}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(intInput, &expCtx->variables), "X"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(intInput), "X"_sd, BSONType::String);
Document doubleOverflowInput{{"path1", 1.0e100}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(doubleOverflowInput, &expCtx->variables), "X"_sd, BSONType::String);
+ convertExp->evaluate(doubleOverflowInput), "X"_sd, BSONType::String);
Document doubleNegativeOverflowInput{{"path1", -1.0e100}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(doubleNegativeOverflowInput, &expCtx->variables),
- "X"_sd,
- BSONType::String);
+ convertExp->evaluate(doubleNegativeOverflowInput), "X"_sd, BSONType::String);
Document doubleNaN{{"path1", std::numeric_limits<double>::quiet_NaN()}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(doubleNaN, &expCtx->variables), "X"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(doubleNaN), "X"_sd, BSONType::String);
Document doubleInfinity{{"path1", std::numeric_limits<double>::infinity()}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(doubleInfinity, &expCtx->variables), "X"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(doubleInfinity), "X"_sd, BSONType::String);
Document doubleNegativeInfinity{{"path1", -std::numeric_limits<double>::infinity()}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(doubleNegativeInfinity, &expCtx->variables), "X"_sd, BSONType::String);
+ convertExp->evaluate(doubleNegativeInfinity), "X"_sd, BSONType::String);
Document decimalOverflowInput{{"path1", Decimal128("1.0e100")}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(decimalOverflowInput, &expCtx->variables), "X"_sd, BSONType::String);
+ convertExp->evaluate(decimalOverflowInput), "X"_sd, BSONType::String);
Document decimalNegativeOverflowInput{{"path1", Decimal128("1.0e100")}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(decimalNegativeOverflowInput, &expCtx->variables),
- "X"_sd,
- BSONType::String);
+ convertExp->evaluate(decimalNegativeOverflowInput), "X"_sd, BSONType::String);
Document decimalNaN{{"path1", Decimal128::kPositiveNaN}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(decimalNaN, &expCtx->variables), "X"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(decimalNaN), "X"_sd, BSONType::String);
Document decimalNegativeNaN{{"path1", Decimal128::kNegativeNaN}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(decimalNegativeNaN, &expCtx->variables), "X"_sd, BSONType::String);
+ convertExp->evaluate(decimalNegativeNaN), "X"_sd, BSONType::String);
Document decimalInfinity{{"path1", Decimal128::kPositiveInfinity}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(decimalInfinity, &expCtx->variables), "X"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(decimalInfinity), "X"_sd, BSONType::String);
Document decimalNegativeInfinity{{"path1", Decimal128::kNegativeInfinity}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(decimalNegativeInfinity, &expCtx->variables),
- "X"_sd,
- BSONType::String);
+ convertExp->evaluate(decimalNegativeInfinity), "X"_sd, BSONType::String);
}
TEST_F(ExpressionConvertTest, ConvertObjectIdToDate) {
@@ -2064,7 +1944,7 @@ TEST_F(ExpressionConvertTest, ConvertObjectIdToDate) {
Document oidInput{{"path1", OID("59E8A8D8FEDCBA9876543210")}};
- ASSERT_EQ(dateToISOStringUTC(convertExp->evaluate(oidInput, &expCtx->variables).getDate()),
+ ASSERT_EQ(dateToISOStringUTC(convertExp->evaluate(oidInput).getDate()),
"2017-10-19T13:30:00.000Z");
}
@@ -2073,13 +1953,11 @@ TEST_F(ExpressionConvertTest, ConvertStringToInt) {
auto spec = fromjson("{$convert: {input: '5', to: 'int'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), 5, BSONType::NumberInt);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), 5, BSONType::NumberInt);
spec = fromjson("{$convert: {input: '" + std::to_string(kIntMax) + "', to: 'int'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), kIntMax, BSONType::NumberInt);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), kIntMax, BSONType::NumberInt);
}
TEST_F(ExpressionConvertTest, ConvertStringToIntOverflow) {
@@ -2087,21 +1965,19 @@ TEST_F(ExpressionConvertTest, ConvertStringToIntOverflow) {
auto spec = fromjson("{$convert: {input: '" + std::to_string(kIntMax + 1) + "', to: 'int'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
- AssertionException,
- [](const AssertionException& exception) {
- ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
- ASSERT_STRING_CONTAINS(exception.reason(), "Overflow");
- });
+ ASSERT_THROWS_WITH_CHECK(
+ convertExp->evaluate({}), AssertionException, [](const AssertionException& exception) {
+ ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
+ ASSERT_STRING_CONTAINS(exception.reason(), "Overflow");
+ });
spec = fromjson("{$convert: {input: '" + std::to_string(kIntMin - 1) + "', to: 'int'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
- AssertionException,
- [](const AssertionException& exception) {
- ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
- ASSERT_STRING_CONTAINS(exception.reason(), "Overflow");
- });
+ ASSERT_THROWS_WITH_CHECK(
+ convertExp->evaluate({}), AssertionException, [](const AssertionException& exception) {
+ ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
+ ASSERT_STRING_CONTAINS(exception.reason(), "Overflow");
+ });
}
TEST_F(ExpressionConvertTest, ConvertStringToIntOverflowWithOnError) {
@@ -2111,14 +1987,12 @@ 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);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), onErrorValue, BSONType::String);
spec = fromjson("{$convert: {input: '" + std::to_string(kIntMin - 1) +
"', to: 'int', onError: '" + onErrorValue + "'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), onErrorValue, BSONType::String);
}
TEST_F(ExpressionConvertTest, ConvertStringToLong) {
@@ -2126,13 +2000,11 @@ TEST_F(ExpressionConvertTest, ConvertStringToLong) {
auto spec = fromjson("{$convert: {input: '5', to: 'long'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), 5LL, BSONType::NumberLong);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), 5LL, BSONType::NumberLong);
spec = fromjson("{$convert: {input: '" + std::to_string(kLongMax) + "', to: 'long'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), kLongMax, BSONType::NumberLong);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), kLongMax, BSONType::NumberLong);
}
TEST_F(ExpressionConvertTest, ConvertStringToLongOverflow) {
@@ -2143,24 +2015,22 @@ TEST_F(ExpressionConvertTest, ConvertStringToLongOverflow) {
auto spec = fromjson("{$convert: {input: '" + longMaxPlusOneAsString + "', to: 'long'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
- AssertionException,
- [](const AssertionException& exception) {
- ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
- ASSERT_STRING_CONTAINS(exception.reason(), "Overflow");
- });
+ ASSERT_THROWS_WITH_CHECK(
+ convertExp->evaluate({}), AssertionException, [](const AssertionException& exception) {
+ ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
+ ASSERT_STRING_CONTAINS(exception.reason(), "Overflow");
+ });
auto longMinMinusOneAsString = std::to_string(kLongNegativeOverflow);
longMinMinusOneAsString = longMinMinusOneAsString.substr(0, longMinMinusOneAsString.find('.'));
spec = fromjson("{$convert: {input: '" + longMinMinusOneAsString + "', to: 'long'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
- AssertionException,
- [](const AssertionException& exception) {
- ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
- ASSERT_STRING_CONTAINS(exception.reason(), "Overflow");
- });
+ ASSERT_THROWS_WITH_CHECK(
+ convertExp->evaluate({}), AssertionException, [](const AssertionException& exception) {
+ ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
+ ASSERT_STRING_CONTAINS(exception.reason(), "Overflow");
+ });
}
TEST_F(ExpressionConvertTest, ConvertStringToLongFailsForFloats) {
@@ -2168,21 +2038,19 @@ TEST_F(ExpressionConvertTest, ConvertStringToLongFailsForFloats) {
auto spec = fromjson("{$convert: {input: '5.5', to: 'long'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
- AssertionException,
- [](const AssertionException& exception) {
- ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
- ASSERT_STRING_CONTAINS(exception.reason(), "Bad digit \".\"");
- });
+ ASSERT_THROWS_WITH_CHECK(
+ convertExp->evaluate({}), AssertionException, [](const AssertionException& exception) {
+ ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
+ ASSERT_STRING_CONTAINS(exception.reason(), "Bad digit \".\"");
+ });
spec = fromjson("{$convert: {input: '5.0', to: 'long'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
- AssertionException,
- [](const AssertionException& exception) {
- ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
- ASSERT_STRING_CONTAINS(exception.reason(), "Bad digit \".\"");
- });
+ ASSERT_THROWS_WITH_CHECK(
+ convertExp->evaluate({}), AssertionException, [](const AssertionException& exception) {
+ ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
+ ASSERT_STRING_CONTAINS(exception.reason(), "Bad digit \".\"");
+ });
}
TEST_F(ExpressionConvertTest, ConvertStringToLongWithOnError) {
@@ -2195,8 +2063,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToLongWithOnError) {
auto spec = fromjson("{$convert: {input: '" + longMaxPlusOneAsString +
"', to: 'long', onError: '" + onErrorValue + "'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), onErrorValue, BSONType::String);
auto longMinMinusOneAsString = std::to_string(kLongNegativeOverflow);
longMinMinusOneAsString = longMinMinusOneAsString.substr(0, longMinMinusOneAsString.find('.'));
@@ -2204,18 +2071,15 @@ TEST_F(ExpressionConvertTest, ConvertStringToLongWithOnError) {
spec = fromjson("{$convert: {input: '" + longMinMinusOneAsString + "', to: 'long', onError: '" +
onErrorValue + "'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), onErrorValue, BSONType::String);
spec = fromjson("{$convert: {input: '5.5', to: 'long', onError: '" + onErrorValue + "'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), onErrorValue, BSONType::String);
spec = fromjson("{$convert: {input: '5.0', to: 'long', onError: '" + onErrorValue + "'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), onErrorValue, BSONType::String);
}
TEST_F(ExpressionConvertTest, ConvertStringToDouble) {
@@ -2223,28 +2087,23 @@ TEST_F(ExpressionConvertTest, ConvertStringToDouble) {
auto spec = fromjson("{$convert: {input: '5', to: 'double'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), 5.0, BSONType::NumberDouble);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), 5.0, BSONType::NumberDouble);
spec = fromjson("{$convert: {input: '5.5', to: 'double'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), 5.5, BSONType::NumberDouble);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), 5.5, BSONType::NumberDouble);
spec = fromjson("{$convert: {input: '.5', to: 'double'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), 0.5, BSONType::NumberDouble);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), 0.5, BSONType::NumberDouble);
spec = fromjson("{$convert: {input: '+5', to: 'double'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), 5.0, BSONType::NumberDouble);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), 5.0, BSONType::NumberDouble);
spec = fromjson("{$convert: {input: '+5.0e42', to: 'double'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), 5.0e42, BSONType::NumberDouble);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), 5.0e42, BSONType::NumberDouble);
}
TEST_F(ExpressionConvertTest, ConvertStringToDoubleWithPrecisionLoss) {
@@ -2254,14 +2113,12 @@ TEST_F(ExpressionConvertTest, ConvertStringToDoubleWithPrecisionLoss) {
// 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);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), 1e19, BSONType::NumberDouble);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), 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);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), 1.125, BSONType::NumberDouble);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), 1.125, BSONType::NumberDouble);
}
TEST_F(ExpressionConvertTest, ConvertStringToDoubleFailsForInvalidFloats) {
@@ -2269,23 +2126,19 @@ TEST_F(ExpressionConvertTest, ConvertStringToDoubleFailsForInvalidFloats) {
auto spec = fromjson("{$convert: {input: '.5.', to: 'double'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
- AssertionException,
- [](const AssertionException& exception) {
- ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
- ASSERT_STRING_CONTAINS(exception.reason(),
- "Did not consume whole number");
- });
+ ASSERT_THROWS_WITH_CHECK(
+ convertExp->evaluate({}), AssertionException, [](const AssertionException& exception) {
+ ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
+ ASSERT_STRING_CONTAINS(exception.reason(), "Did not consume whole number");
+ });
spec = fromjson("{$convert: {input: '5.5f', to: 'double'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
- AssertionException,
- [](const AssertionException& exception) {
- ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
- ASSERT_STRING_CONTAINS(exception.reason(),
- "Did not consume whole number");
- });
+ ASSERT_THROWS_WITH_CHECK(
+ convertExp->evaluate({}), AssertionException, [](const AssertionException& exception) {
+ ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
+ ASSERT_STRING_CONTAINS(exception.reason(), "Did not consume whole number");
+ });
}
TEST_F(ExpressionConvertTest, ConvertInfinityStringsToDouble) {
@@ -2294,48 +2147,39 @@ TEST_F(ExpressionConvertTest, ConvertInfinityStringsToDouble) {
auto spec = fromjson("{$convert: {input: 'Infinity', to: 'double'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), infValue, BSONType::NumberDouble);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), infValue, BSONType::NumberDouble);
spec = fromjson("{$convert: {input: 'INF', to: 'double'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), infValue, BSONType::NumberDouble);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), infValue, BSONType::NumberDouble);
spec = fromjson("{$convert: {input: 'infinity', to: 'double'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), infValue, BSONType::NumberDouble);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), infValue, BSONType::NumberDouble);
spec = fromjson("{$convert: {input: '+InFiNiTy', to: 'double'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), infValue, BSONType::NumberDouble);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), infValue, BSONType::NumberDouble);
spec = fromjson("{$convert: {input: '-Infinity', to: 'double'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), -infValue, BSONType::NumberDouble);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), -infValue, BSONType::NumberDouble);
spec = fromjson("{$convert: {input: '-INF', to: 'double'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), -infValue, BSONType::NumberDouble);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), -infValue, BSONType::NumberDouble);
spec = fromjson("{$convert: {input: '-InFiNiTy', to: 'double'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), -infValue, BSONType::NumberDouble);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), -infValue, BSONType::NumberDouble);
spec = fromjson("{$convert: {input: '-inf', to: 'double'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), -infValue, BSONType::NumberDouble);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), -infValue, BSONType::NumberDouble);
spec = fromjson("{$convert: {input: '-infinity', to: 'double'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), -infValue, BSONType::NumberDouble);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), -infValue, BSONType::NumberDouble);
}
TEST_F(ExpressionConvertTest, ConvertZeroStringsToDouble) {
@@ -2343,25 +2187,25 @@ TEST_F(ExpressionConvertTest, ConvertZeroStringsToDouble) {
auto spec = fromjson("{$convert: {input: '-0', to: 'double'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- auto result = convertExp->evaluate({}, &expCtx->variables);
+ auto result = convertExp->evaluate({});
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);
- result = convertExp->evaluate({}, &expCtx->variables);
+ result = convertExp->evaluate({});
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);
- result = convertExp->evaluate({}, &expCtx->variables);
+ result = convertExp->evaluate({});
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);
- result = convertExp->evaluate({}, &expCtx->variables);
+ result = convertExp->evaluate({});
ASSERT_VALUE_CONTENTS_AND_TYPE(result, 0, BSONType::NumberDouble);
ASSERT_FALSE(std::signbit(result.getDouble()));
}
@@ -2372,29 +2216,28 @@ TEST_F(ExpressionConvertTest, ConvertNanStringsToDouble) {
auto spec = fromjson("{$convert: {input: 'nan', to: 'double'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- auto result = convertExp->evaluate({}, &expCtx->variables);
+ auto result = convertExp->evaluate({});
ASSERT_TRUE(std::isnan(result.getDouble()));
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), nanValue, BSONType::NumberDouble);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), nanValue, BSONType::NumberDouble);
spec = fromjson("{$convert: {input: 'Nan', to: 'double'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- result = convertExp->evaluate({}, &expCtx->variables);
+ result = convertExp->evaluate({});
ASSERT_TRUE(std::isnan(result.getDouble()));
spec = fromjson("{$convert: {input: 'NaN', to: 'double'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- result = convertExp->evaluate({}, &expCtx->variables);
+ result = convertExp->evaluate({});
ASSERT_TRUE(std::isnan(result.getDouble()));
spec = fromjson("{$convert: {input: '-NAN', to: 'double'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- result = convertExp->evaluate({}, &expCtx->variables);
+ result = convertExp->evaluate({});
ASSERT_TRUE(std::isnan(result.getDouble()));
spec = fromjson("{$convert: {input: '+NaN', to: 'double'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- result = convertExp->evaluate({}, &expCtx->variables);
+ result = convertExp->evaluate({});
ASSERT_TRUE(std::isnan(result.getDouble()));
}
@@ -2403,22 +2246,20 @@ TEST_F(ExpressionConvertTest, ConvertStringToDoubleOverflow) {
auto spec = fromjson("{$convert: {input: '" + kDoubleOverflow.toString() + "', to: 'double'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
- AssertionException,
- [](const AssertionException& exception) {
- ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
- ASSERT_STRING_CONTAINS(exception.reason(), "Out of range");
- });
+ ASSERT_THROWS_WITH_CHECK(
+ convertExp->evaluate({}), AssertionException, [](const AssertionException& exception) {
+ ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
+ ASSERT_STRING_CONTAINS(exception.reason(), "Out of range");
+ });
spec =
fromjson("{$convert: {input: '" + kDoubleNegativeOverflow.toString() + "', to: 'double'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
- AssertionException,
- [](const AssertionException& exception) {
- ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
- ASSERT_STRING_CONTAINS(exception.reason(), "Out of range");
- });
+ ASSERT_THROWS_WITH_CHECK(
+ convertExp->evaluate({}), AssertionException, [](const AssertionException& exception) {
+ ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
+ ASSERT_STRING_CONTAINS(exception.reason(), "Out of range");
+ });
}
TEST_F(ExpressionConvertTest, ConvertStringToDoubleUnderflow) {
@@ -2427,9 +2268,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToDoubleUnderflow) {
auto spec = fromjson("{$convert: {input: '1E-1000', to: 'double'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(
- convertExp->evaluate({}, &expCtx->variables),
- AssertionException,
- [](const AssertionException& exception) {
+ convertExp->evaluate({}), AssertionException, [](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
ASSERT_STRING_CONTAINS(
exception.reason(),
@@ -2439,9 +2278,7 @@ TEST_F(ExpressionConvertTest, ConvertStringToDoubleUnderflow) {
spec = fromjson("{$convert: {input: '-1E-1000', to: 'double'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
ASSERT_THROWS_WITH_CHECK(
- convertExp->evaluate({}, &expCtx->variables),
- AssertionException,
- [](const AssertionException& exception) {
+ convertExp->evaluate({}), AssertionException, [](const AssertionException& exception) {
ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
ASSERT_STRING_CONTAINS(exception.reason(),
"Failed to parse number '-1E-1000' in $convert with no onError "
@@ -2456,24 +2293,20 @@ TEST_F(ExpressionConvertTest, ConvertStringToDoubleWithOnError) {
auto spec = fromjson("{$convert: {input: '" + kDoubleOverflow.toString() +
"', to: 'double', onError: '" + onErrorValue + "'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), onErrorValue, BSONType::String);
spec = fromjson("{$convert: {input: '" + kDoubleNegativeOverflow.toString() +
"', to: 'double', onError: '" + onErrorValue + "'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), onErrorValue, BSONType::String);
spec = fromjson("{$convert: {input: '.5.', to: 'double', onError: '" + onErrorValue + "'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), onErrorValue, BSONType::String);
spec = fromjson("{$convert: {input: '5.5f', to: 'double', onError: '" + onErrorValue + "'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), onErrorValue, BSONType::String);
}
TEST_F(ExpressionConvertTest, ConvertStringToDecimal) {
@@ -2481,33 +2314,29 @@ TEST_F(ExpressionConvertTest, ConvertStringToDecimal) {
auto spec = fromjson("{$convert: {input: '5', to: 'decimal'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), 5, BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), 5, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '2.02', to: 'decimal'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), Decimal128("2.02"), BSONType::NumberDecimal);
+ convertExp->evaluate({}), Decimal128("2.02"), BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '2.02E200', to: 'decimal'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}, &expCtx->variables),
- Decimal128("2.02E200"),
- BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate({}), Decimal128("2.02E200"), BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '" + Decimal128::kLargestPositive.toString() +
"', to: 'decimal'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}, &expCtx->variables),
- Decimal128::kLargestPositive,
- BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate({}), Decimal128::kLargestPositive, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '" + Decimal128::kLargestNegative.toString() +
"', to: 'decimal'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}, &expCtx->variables),
- Decimal128::kLargestNegative,
- BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate({}), Decimal128::kLargestNegative, BSONType::NumberDecimal);
}
TEST_F(ExpressionConvertTest, ConvertInfinityStringsToDecimal) {
@@ -2517,48 +2346,39 @@ TEST_F(ExpressionConvertTest, ConvertInfinityStringsToDecimal) {
auto spec = fromjson("{$convert: {input: 'Infinity', to: 'decimal'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), infValue, BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), infValue, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: 'INF', to: 'decimal'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), infValue, BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), infValue, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: 'infinity', to: 'decimal'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), infValue, BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), infValue, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '+InFiNiTy', to: 'decimal'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), infValue, BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), infValue, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '-Infinity', to: 'decimal'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), negInfValue, BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), negInfValue, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '-INF', to: 'decimal'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), negInfValue, BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), negInfValue, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '-InFiNiTy', to: 'decimal'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), negInfValue, BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), negInfValue, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '-inf', to: 'decimal'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), negInfValue, BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), negInfValue, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '-infinity', to: 'decimal'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), negInfValue, BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), negInfValue, BSONType::NumberDecimal);
}
TEST_F(ExpressionConvertTest, ConvertNanStringsToDecimal) {
@@ -2568,38 +2388,31 @@ TEST_F(ExpressionConvertTest, ConvertNanStringsToDecimal) {
auto spec = fromjson("{$convert: {input: 'nan', to: 'decimal'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), positiveNan, BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), positiveNan, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: 'Nan', to: 'decimal'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), positiveNan, BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), positiveNan, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: 'NaN', to: 'decimal'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), positiveNan, BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), positiveNan, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '+NaN', to: 'decimal'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), positiveNan, BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), positiveNan, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '-NAN', to: 'decimal'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), negativeNan, BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), negativeNan, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '-nan', to: 'decimal'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), negativeNan, BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), negativeNan, BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '-NaN', to: 'decimal'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), negativeNan, BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), negativeNan, BSONType::NumberDecimal);
}
TEST_F(ExpressionConvertTest, ConvertZeroStringsToDecimal) {
@@ -2607,28 +2420,28 @@ TEST_F(ExpressionConvertTest, ConvertZeroStringsToDecimal) {
auto spec = fromjson("{$convert: {input: '-0', to: 'decimal'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- auto result = convertExp->evaluate({}, &expCtx->variables);
+ auto result = convertExp->evaluate({});
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);
- result = convertExp->evaluate({}, &expCtx->variables);
+ result = convertExp->evaluate({});
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);
- result = convertExp->evaluate({}, &expCtx->variables);
+ result = convertExp->evaluate({});
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);
- result = convertExp->evaluate({}, &expCtx->variables);
+ result = convertExp->evaluate({});
ASSERT_VALUE_CONTENTS_AND_TYPE(result, 0, BSONType::NumberDecimal);
ASSERT_TRUE(result.getDecimal().isZero());
ASSERT_FALSE(result.getDecimal().isNegative());
@@ -2639,25 +2452,21 @@ TEST_F(ExpressionConvertTest, ConvertStringToDecimalOverflow) {
auto spec = fromjson("{$convert: {input: '1E6145', to: 'decimal'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
- AssertionException,
- [](const AssertionException& exception) {
- ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
- ASSERT_STRING_CONTAINS(
- exception.reason(),
- "Conversion from string to decimal would overflow");
- });
+ ASSERT_THROWS_WITH_CHECK(
+ convertExp->evaluate({}), AssertionException, [](const AssertionException& exception) {
+ ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
+ ASSERT_STRING_CONTAINS(exception.reason(),
+ "Conversion from string to decimal would overflow");
+ });
spec = fromjson("{$convert: {input: '-1E6145', to: 'decimal'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
- AssertionException,
- [](const AssertionException& exception) {
- ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
- ASSERT_STRING_CONTAINS(
- exception.reason(),
- "Conversion from string to decimal would overflow");
- });
+ ASSERT_THROWS_WITH_CHECK(
+ convertExp->evaluate({}), AssertionException, [](const AssertionException& exception) {
+ ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
+ ASSERT_STRING_CONTAINS(exception.reason(),
+ "Conversion from string to decimal would overflow");
+ });
}
TEST_F(ExpressionConvertTest, ConvertStringToDecimalUnderflow) {
@@ -2665,25 +2474,21 @@ TEST_F(ExpressionConvertTest, ConvertStringToDecimalUnderflow) {
auto spec = fromjson("{$convert: {input: '1E-6178', to: 'decimal'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
- AssertionException,
- [](const AssertionException& exception) {
- ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
- ASSERT_STRING_CONTAINS(
- exception.reason(),
- "Conversion from string to decimal would underflow");
- });
+ ASSERT_THROWS_WITH_CHECK(
+ convertExp->evaluate({}), AssertionException, [](const AssertionException& exception) {
+ ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
+ ASSERT_STRING_CONTAINS(exception.reason(),
+ "Conversion from string to decimal would underflow");
+ });
spec = fromjson("{$convert: {input: '-1E-6177', to: 'decimal'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
- AssertionException,
- [](const AssertionException& exception) {
- ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
- ASSERT_STRING_CONTAINS(
- exception.reason(),
- "Conversion from string to decimal would underflow");
- });
+ ASSERT_THROWS_WITH_CHECK(
+ convertExp->evaluate({}), AssertionException, [](const AssertionException& exception) {
+ ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
+ ASSERT_STRING_CONTAINS(exception.reason(),
+ "Conversion from string to decimal would underflow");
+ });
}
TEST_F(ExpressionConvertTest, ConvertStringToDecimalWithPrecisionLoss) {
@@ -2693,12 +2498,12 @@ TEST_F(ExpressionConvertTest, ConvertStringToDecimalWithPrecisionLoss) {
fromjson("{$convert: {input: '10000000000000000000000000000000001', to: 'decimal'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), Decimal128("1e34"), BSONType::NumberDecimal);
+ convertExp->evaluate({}), Decimal128("1e34"), BSONType::NumberDecimal);
spec = fromjson("{$convert: {input: '1.1250000000000000000000000000000001', to: 'decimal'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), Decimal128("1.125"), BSONType::NumberDecimal);
+ convertExp->evaluate({}), Decimal128("1.125"), BSONType::NumberDecimal);
}
TEST_F(ExpressionConvertTest, ConvertStringToDecimalWithOnError) {
@@ -2708,14 +2513,12 @@ TEST_F(ExpressionConvertTest, ConvertStringToDecimalWithOnError) {
auto spec =
fromjson("{$convert: {input: '1E6145', to: 'decimal', onError: '" + onErrorValue + "'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), onErrorValue, BSONType::String);
spec =
fromjson("{$convert: {input: '-1E-6177', to: 'decimal', onError: '" + onErrorValue + "'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), onErrorValue, BSONType::String);
}
TEST_F(ExpressionConvertTest, ConvertStringToNumberFailsForHexStrings) {
@@ -2727,53 +2530,43 @@ TEST_F(ExpressionConvertTest, ConvertStringToNumberFailsForHexStrings) {
auto spec = fromjson("{$convert: {input: '0xFF', to: 'int'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(
- convertExp->evaluate({}, &expCtx->variables), AssertionException, invalidHexFailure);
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}), AssertionException, invalidHexFailure);
spec = fromjson("{$convert: {input: '0xFF', to: 'long'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(
- convertExp->evaluate({}, &expCtx->variables), AssertionException, invalidHexFailure);
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}), AssertionException, invalidHexFailure);
spec = fromjson("{$convert: {input: '0xFF', to: 'double'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(
- convertExp->evaluate({}, &expCtx->variables), AssertionException, invalidHexFailure);
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}), AssertionException, invalidHexFailure);
spec = fromjson("{$convert: {input: '0xFF', to: 'decimal'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(
- convertExp->evaluate({}, &expCtx->variables), AssertionException, invalidHexFailure);
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}), AssertionException, invalidHexFailure);
spec = fromjson("{$convert: {input: '0x00', to: 'int'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(
- convertExp->evaluate({}, &expCtx->variables), AssertionException, invalidHexFailure);
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}), AssertionException, invalidHexFailure);
spec = fromjson("{$convert: {input: '0x00', to: 'decimal'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(
- convertExp->evaluate({}, &expCtx->variables), AssertionException, invalidHexFailure);
+ ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}), AssertionException, invalidHexFailure);
spec = fromjson("{$convert: {input: 'FF', to: 'double'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
- AssertionException,
- [](const AssertionException& exception) {
- ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
- ASSERT_STRING_CONTAINS(exception.reason(),
- "Did not consume whole number");
- });
+ ASSERT_THROWS_WITH_CHECK(
+ convertExp->evaluate({}), AssertionException, [](const AssertionException& exception) {
+ ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
+ ASSERT_STRING_CONTAINS(exception.reason(), "Did not consume whole number");
+ });
spec = fromjson("{$convert: {input: 'FF', to: 'decimal'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
- AssertionException,
- [](const AssertionException& exception) {
- ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
- ASSERT_STRING_CONTAINS(exception.reason(),
- "Failed to parse string to decimal");
- });
+ ASSERT_THROWS_WITH_CHECK(
+ convertExp->evaluate({}), AssertionException, [](const AssertionException& exception) {
+ ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
+ ASSERT_STRING_CONTAINS(exception.reason(), "Failed to parse string to decimal");
+ });
}
TEST_F(ExpressionConvertTest, ConvertStringToOID) {
@@ -2782,14 +2575,12 @@ TEST_F(ExpressionConvertTest, ConvertStringToOID) {
auto spec = fromjson("{$convert: {input: '" + oid.toString() + "', to: 'objectId'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), oid, BSONType::jstOID);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), oid, BSONType::jstOID);
spec = fromjson("{$convert: {input: '123456789abcdef123456789', to: 'objectId'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}, &expCtx->variables),
- OID("123456789abcdef123456789"),
- BSONType::jstOID);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate({}), OID("123456789abcdef123456789"), BSONType::jstOID);
}
TEST_F(ExpressionConvertTest, ConvertStringToOIDFailsForInvalidHexStrings) {
@@ -2797,33 +2588,27 @@ TEST_F(ExpressionConvertTest, ConvertStringToOIDFailsForInvalidHexStrings) {
auto spec = fromjson("{$convert: {input: 'InvalidHexButSizeCorrect', to: 'objectId'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
- AssertionException,
- [](const AssertionException& exception) {
- ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
- ASSERT_STRING_CONTAINS(exception.reason(),
- "Invalid character found in hex string");
- });
+ ASSERT_THROWS_WITH_CHECK(
+ convertExp->evaluate({}), AssertionException, [](const AssertionException& exception) {
+ ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
+ ASSERT_STRING_CONTAINS(exception.reason(), "Invalid character found in hex string");
+ });
spec = fromjson("{$convert: {input: 'InvalidSize', to: 'objectId'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
- AssertionException,
- [](const AssertionException& exception) {
- ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
- ASSERT_STRING_CONTAINS(exception.reason(),
- "Invalid string length for parsing to OID");
- });
+ ASSERT_THROWS_WITH_CHECK(
+ convertExp->evaluate({}), AssertionException, [](const AssertionException& exception) {
+ ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
+ ASSERT_STRING_CONTAINS(exception.reason(), "Invalid string length for parsing to OID");
+ });
spec = fromjson("{$convert: {input: '0x123456789abcdef123456789', to: 'objectId'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_WITH_CHECK(convertExp->evaluate({}, &expCtx->variables),
- AssertionException,
- [](const AssertionException& exception) {
- ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
- ASSERT_STRING_CONTAINS(exception.reason(),
- "Invalid string length for parsing to OID");
- });
+ ASSERT_THROWS_WITH_CHECK(
+ convertExp->evaluate({}), AssertionException, [](const AssertionException& exception) {
+ ASSERT_EQ(exception.code(), ErrorCodes::ConversionFailure);
+ ASSERT_STRING_CONTAINS(exception.reason(), "Invalid string length for parsing to OID");
+ });
}
TEST_F(ExpressionConvertTest, ConvertStringToOIDWithOnError) {
@@ -2834,20 +2619,17 @@ TEST_F(ExpressionConvertTest, ConvertStringToOIDWithOnError) {
fromjson("{$convert: {input: 'InvalidHexButSizeCorrect', to: 'objectId', onError: '" +
onErrorValue + "'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), onErrorValue, BSONType::String);
spec = fromjson("{$convert: {input: 'InvalidSize', to: 'objectId', onError: '" + onErrorValue +
"'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), onErrorValue, BSONType::String);
spec = fromjson("{$convert: {input: '0x123456789abcdef123456789', to: 'objectId', onError: '" +
onErrorValue + "'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate({}, &expCtx->variables), onErrorValue, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate({}), onErrorValue, BSONType::String);
}
TEST_F(ExpressionConvertTest, ConvertStringToDateRejectsUnparsableString) {
@@ -2855,15 +2637,11 @@ TEST_F(ExpressionConvertTest, ConvertStringToDateRejectsUnparsableString) {
auto spec = fromjson("{$convert: {input: '60.Monday1770/06:59', to: 'date'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_CODE(convertExp->evaluate({}, &expCtx->variables),
- AssertionException,
- ErrorCodes::ConversionFailure);
+ ASSERT_THROWS_CODE(convertExp->evaluate({}), AssertionException, ErrorCodes::ConversionFailure);
spec = fromjson("{$convert: {input: 'Definitely not a date', to: 'date'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_CODE(convertExp->evaluate({}, &expCtx->variables),
- AssertionException,
- ErrorCodes::ConversionFailure);
+ ASSERT_THROWS_CODE(convertExp->evaluate({}), AssertionException, ErrorCodes::ConversionFailure);
}
TEST_F(ExpressionConvertTest, ConvertStringToDateRejectsTimezoneNameInString) {
@@ -2871,15 +2649,11 @@ TEST_F(ExpressionConvertTest, ConvertStringToDateRejectsTimezoneNameInString) {
auto spec = fromjson("{$convert: {input: '2017-07-13T10:02:57 Europe/London', to: 'date'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_CODE(convertExp->evaluate({}, &expCtx->variables),
- AssertionException,
- ErrorCodes::ConversionFailure);
+ ASSERT_THROWS_CODE(convertExp->evaluate({}), AssertionException, ErrorCodes::ConversionFailure);
spec = fromjson("{$convert: {input: 'July 4, 2017 Europe/London', to: 'date'}}");
convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_CODE(convertExp->evaluate({}, &expCtx->variables),
- AssertionException,
- ErrorCodes::ConversionFailure);
+ ASSERT_THROWS_CODE(convertExp->evaluate({}), AssertionException, ErrorCodes::ConversionFailure);
}
TEST_F(ExpressionConvertTest, ConvertStringToDate) {
@@ -2888,17 +2662,15 @@ TEST_F(ExpressionConvertTest, ConvertStringToDate) {
auto spec = fromjson("{$convert: {input: '$path1', to: 'date'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- auto result =
- convertExp->evaluate({{"path1", Value("2017-07-06T12:35:37Z"_sd)}}, &expCtx->variables);
+ auto result = convertExp->evaluate({{"path1", Value("2017-07-06T12:35:37Z"_sd)}});
ASSERT_EQ(result.getType(), BSONType::Date);
ASSERT_EQ("2017-07-06T12:35:37.000Z", result.toString());
- result =
- convertExp->evaluate({{"path1", Value("2017-07-06T12:35:37.513Z"_sd)}}, &expCtx->variables);
+ result = convertExp->evaluate({{"path1", Value("2017-07-06T12:35:37.513Z"_sd)}});
ASSERT_EQ(result.getType(), BSONType::Date);
ASSERT_EQ("2017-07-06T12:35:37.513Z", result.toString());
- result = convertExp->evaluate({{"path1", Value("2017-07-06"_sd)}}, &expCtx->variables);
+ result = convertExp->evaluate({{"path1", Value("2017-07-06"_sd)}});
ASSERT_EQ(result.getType(), BSONType::Date);
ASSERT_EQ("2017-07-06T00:00:00.000Z", result.toString());
}
@@ -2909,13 +2681,11 @@ TEST_F(ExpressionConvertTest, ConvertStringWithTimezoneToDate) {
auto spec = fromjson("{$convert: {input: '$path1', to: 'date'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- auto result = convertExp->evaluate({{"path1", Value("2017-07-14T12:02:44.771 GMT+02:00"_sd)}},
- &expCtx->variables);
+ auto result = convertExp->evaluate({{"path1", Value("2017-07-14T12:02:44.771 GMT+02:00"_sd)}});
ASSERT_EQ(result.getType(), BSONType::Date);
ASSERT_EQ("2017-07-14T10:02:44.771Z", result.toString());
- result = convertExp->evaluate({{"path1", Value("2017-07-14T12:02:44.771 A"_sd)}},
- &expCtx->variables);
+ result = convertExp->evaluate({{"path1", Value("2017-07-14T12:02:44.771 A"_sd)}});
ASSERT_EQ(result.getType(), BSONType::Date);
ASSERT_EQ("2017-07-14T11:02:44.771Z", result.toString());
}
@@ -2926,15 +2696,15 @@ TEST_F(ExpressionConvertTest, ConvertVerbalStringToDate) {
auto spec = fromjson("{$convert: {input: '$path1', to: 'date'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- auto result = convertExp->evaluate({{"path1", Value("July 4th, 2017"_sd)}}, &expCtx->variables);
+ auto result = convertExp->evaluate({{"path1", Value("July 4th, 2017"_sd)}});
ASSERT_EQ(result.getType(), BSONType::Date);
ASSERT_EQ("2017-07-04T00:00:00.000Z", result.toString());
- result = convertExp->evaluate({{"path1", Value("July 4th, 2017 12pm"_sd)}}, &expCtx->variables);
+ result = convertExp->evaluate({{"path1", Value("July 4th, 2017 12pm"_sd)}});
ASSERT_EQ(result.getType(), BSONType::Date);
ASSERT_EQ("2017-07-04T12:00:00.000Z", result.toString());
- result = convertExp->evaluate({{"path1", Value("2017-Jul-04 noon"_sd)}}, &expCtx->variables);
+ result = convertExp->evaluate({{"path1", Value("2017-Jul-04 noon"_sd)}});
ASSERT_EQ(result.getType(), BSONType::Date);
ASSERT_EQ("2017-07-04T12:00:00.000Z", result.toString());
}
@@ -2947,14 +2717,13 @@ TEST_F(ExpressionConvertTest, ConvertStringToDateWithOnError) {
fromjson("{$convert: {input: '$path1', to: 'date', onError: '" + onErrorValue + "'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- auto result = convertExp->evaluate({{"path1", Value("Not a date"_sd)}}, &expCtx->variables);
+ auto result = convertExp->evaluate({{"path1", Value("Not a date"_sd)}});
ASSERT_VALUE_CONTENTS_AND_TYPE(result, onErrorValue, BSONType::String);
- result = convertExp->evaluate({{"path1", Value("60.Monday1770/06:59"_sd)}}, &expCtx->variables);
+ result = convertExp->evaluate({{"path1", Value("60.Monday1770/06:59"_sd)}});
ASSERT_VALUE_CONTENTS_AND_TYPE(result, onErrorValue, BSONType::String);
- result = convertExp->evaluate({{"path1", Value("2017-07-13T10:02:57 Europe/London"_sd)}},
- &expCtx->variables);
+ result = convertExp->evaluate({{"path1", Value("2017-07-13T10:02:57 Europe/London"_sd)}});
ASSERT_VALUE_CONTENTS_AND_TYPE(result, onErrorValue, BSONType::String);
}
@@ -2966,10 +2735,10 @@ TEST_F(ExpressionConvertTest, ConvertStringToDateWithOnNull) {
fromjson("{$convert: {input: '$path1', to: 'date', onNull: '" + onNullValue + "'}}");
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- auto result = convertExp->evaluate({}, &expCtx->variables);
+ auto result = convertExp->evaluate({});
ASSERT_VALUE_CONTENTS_AND_TYPE(result, onNullValue, BSONType::String);
- result = convertExp->evaluate({{"path1", Value(BSONNULL)}}, &expCtx->variables);
+ result = convertExp->evaluate({{"path1", Value(BSONNULL)}});
ASSERT_VALUE_CONTENTS_AND_TYPE(result, onNullValue, BSONType::String);
}
@@ -2983,67 +2752,54 @@ TEST_F(ExpressionConvertTest, FormatDouble) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document zeroInput{{"path1", 0.0}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(zeroInput, &expCtx->variables), "0"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(zeroInput), "0"_sd, BSONType::String);
Document negativeZeroInput{{"path1", -0.0}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(negativeZeroInput, &expCtx->variables), "-0"_sd, BSONType::String);
+ convertExp->evaluate(negativeZeroInput), "-0"_sd, BSONType::String);
Document positiveIntegerInput{{"path1", 1337.0}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(positiveIntegerInput, &expCtx->variables),
- "1337"_sd,
- BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(positiveIntegerInput), "1337"_sd, BSONType::String);
Document negativeIntegerInput{{"path1", -1337.0}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(negativeIntegerInput, &expCtx->variables),
- "-1337"_sd,
- BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(negativeIntegerInput), "-1337"_sd, BSONType::String);
Document positiveFractionalInput{{"path1", 0.1337}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(positiveFractionalInput, &expCtx->variables),
- "0.1337"_sd,
- BSONType::String);
+ convertExp->evaluate(positiveFractionalInput), "0.1337"_sd, BSONType::String);
Document negativeFractionalInput{{"path1", -0.1337}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(negativeFractionalInput, &expCtx->variables),
- "-0.1337"_sd,
- BSONType::String);
+ convertExp->evaluate(negativeFractionalInput), "-0.1337"_sd, BSONType::String);
Document positiveLargeInput{{"path1", 1.3e37}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(positiveLargeInput, &expCtx->variables),
- "1.3e+37"_sd,
- BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(positiveLargeInput), "1.3e+37"_sd, BSONType::String);
Document negativeLargeInput{{"path1", -1.3e37}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(negativeLargeInput, &expCtx->variables),
- "-1.3e+37"_sd,
- BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(negativeLargeInput), "-1.3e+37"_sd, BSONType::String);
Document positiveTinyInput{{"path1", 1.3e-37}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(positiveTinyInput, &expCtx->variables),
- "1.3e-37"_sd,
- BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(positiveTinyInput), "1.3e-37"_sd, BSONType::String);
Document negativeTinyInput{{"path1", -1.3e-37}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(negativeTinyInput, &expCtx->variables),
- "-1.3e-37"_sd,
- BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(negativeTinyInput), "-1.3e-37"_sd, BSONType::String);
Document infinityInput{{"path1", std::numeric_limits<double>::infinity()}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(infinityInput, &expCtx->variables), "Infinity"_sd, BSONType::String);
+ convertExp->evaluate(infinityInput), "Infinity"_sd, BSONType::String);
Document negativeInfinityInput{{"path1", -std::numeric_limits<double>::infinity()}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(negativeInfinityInput, &expCtx->variables),
- "-Infinity"_sd,
- BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(negativeInfinityInput), "-Infinity"_sd, BSONType::String);
Document nanInput{{"path1", std::numeric_limits<double>::quiet_NaN()}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(nanInput, &expCtx->variables), "NaN"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(nanInput), "NaN"_sd, BSONType::String);
}
TEST_F(ExpressionConvertTest, FormatObjectId) {
@@ -3056,14 +2812,12 @@ TEST_F(ExpressionConvertTest, FormatObjectId) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document zeroInput{{"path1", OID("000000000000000000000000")}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(zeroInput, &expCtx->variables),
- "000000000000000000000000"_sd,
- BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(zeroInput), "000000000000000000000000"_sd, BSONType::String);
Document simpleInput{{"path1", OID("0123456789abcdef01234567")}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(simpleInput, &expCtx->variables),
- "0123456789abcdef01234567"_sd,
- BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(simpleInput), "0123456789abcdef01234567"_sd, BSONType::String);
}
TEST_F(ExpressionConvertTest, FormatBool) {
@@ -3076,12 +2830,10 @@ TEST_F(ExpressionConvertTest, FormatBool) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document trueInput{{"path1", true}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(trueInput, &expCtx->variables), "true"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(trueInput), "true"_sd, BSONType::String);
Document falseInput{{"path1", false}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(falseInput, &expCtx->variables), "false"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(falseInput), "false"_sd, BSONType::String);
}
TEST_F(ExpressionConvertTest, FormatDate) {
@@ -3094,14 +2846,12 @@ TEST_F(ExpressionConvertTest, FormatDate) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document epochInput{{"path1", Date_t::fromMillisSinceEpoch(0LL)}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(epochInput, &expCtx->variables),
- "1970-01-01T00:00:00.000Z"_sd,
- BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(epochInput), "1970-01-01T00:00:00.000Z"_sd, BSONType::String);
Document dateInput{{"path1", Date_t::fromMillisSinceEpoch(872835240000)}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(dateInput, &expCtx->variables),
- "1997-08-29T06:14:00.000Z"_sd,
- BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(dateInput), "1997-08-29T06:14:00.000Z"_sd, BSONType::String);
}
TEST_F(ExpressionConvertTest, FormatInt) {
@@ -3114,16 +2864,15 @@ TEST_F(ExpressionConvertTest, FormatInt) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document zeroInput{{"path1", int{0}}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(zeroInput, &expCtx->variables), "0"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(zeroInput), "0"_sd, BSONType::String);
Document positiveInput{{"path1", int{1337}}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(positiveInput, &expCtx->variables), "1337"_sd, BSONType::String);
+ convertExp->evaluate(positiveInput), "1337"_sd, BSONType::String);
Document negativeInput{{"path1", int{-1337}}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(negativeInput, &expCtx->variables), "-1337"_sd, BSONType::String);
+ convertExp->evaluate(negativeInput), "-1337"_sd, BSONType::String);
}
TEST_F(ExpressionConvertTest, FormatLong) {
@@ -3136,18 +2885,15 @@ TEST_F(ExpressionConvertTest, FormatLong) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document zeroInput{{"path1", 0LL}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(zeroInput, &expCtx->variables), "0"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(zeroInput), "0"_sd, BSONType::String);
Document positiveInput{{"path1", 1337133713371337LL}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(positiveInput, &expCtx->variables),
- "1337133713371337"_sd,
- BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(positiveInput), "1337133713371337"_sd, BSONType::String);
Document negativeInput{{"path1", -1337133713371337LL}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(negativeInput, &expCtx->variables),
- "-1337133713371337"_sd,
- BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(negativeInput), "-1337133713371337"_sd, BSONType::String);
}
TEST_F(ExpressionConvertTest, FormatDecimal) {
@@ -3160,103 +2906,83 @@ TEST_F(ExpressionConvertTest, FormatDecimal) {
auto convertExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
Document zeroInput{{"path1", Decimal128("0")}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(zeroInput, &expCtx->variables), "0"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(zeroInput), "0"_sd, BSONType::String);
Document negativeZeroInput{{"path1", Decimal128("-0")}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(negativeZeroInput, &expCtx->variables), "-0"_sd, BSONType::String);
+ convertExp->evaluate(negativeZeroInput), "-0"_sd, BSONType::String);
Document preciseZeroInput{{"path1", Decimal128("0.0")}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(preciseZeroInput, &expCtx->variables), "0.0"_sd, BSONType::String);
+ convertExp->evaluate(preciseZeroInput), "0.0"_sd, BSONType::String);
Document negativePreciseZeroInput{{"path1", Decimal128("-0.0")}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(negativePreciseZeroInput, &expCtx->variables),
- "-0.0"_sd,
- BSONType::String);
+ convertExp->evaluate(negativePreciseZeroInput), "-0.0"_sd, BSONType::String);
Document extraPreciseZeroInput{{"path1", Decimal128("0.0000")}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(extraPreciseZeroInput, &expCtx->variables),
- "0.0000"_sd,
- BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(extraPreciseZeroInput), "0.0000"_sd, BSONType::String);
Document positiveIntegerInput{{"path1", Decimal128("1337")}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(positiveIntegerInput, &expCtx->variables),
- "1337"_sd,
- BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(positiveIntegerInput), "1337"_sd, BSONType::String);
Document largeIntegerInput{{"path1", Decimal128("13370000000000000000000000000000000")}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(largeIntegerInput, &expCtx->variables),
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(largeIntegerInput),
"1.337000000000000000000000000000000E+34"_sd,
BSONType::String);
Document negativeIntegerInput{{"path1", Decimal128("-1337")}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(negativeIntegerInput, &expCtx->variables),
- "-1337"_sd,
- BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(negativeIntegerInput), "-1337"_sd, BSONType::String);
Document positiveFractionalInput{{"path1", Decimal128("0.1337")}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(positiveFractionalInput, &expCtx->variables),
- "0.1337"_sd,
- BSONType::String);
+ convertExp->evaluate(positiveFractionalInput), "0.1337"_sd, BSONType::String);
Document positivePreciseFractionalInput{{"path1", Decimal128("0.133700")}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(positivePreciseFractionalInput, &expCtx->variables),
- "0.133700"_sd,
- BSONType::String);
+ convertExp->evaluate(positivePreciseFractionalInput), "0.133700"_sd, BSONType::String);
Document negativeFractionalInput{{"path1", Decimal128("-0.1337")}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(negativeFractionalInput, &expCtx->variables),
- "-0.1337"_sd,
- BSONType::String);
+ convertExp->evaluate(negativeFractionalInput), "-0.1337"_sd, BSONType::String);
Document negativePreciseFractionalInput{{"path1", Decimal128("-0.133700")}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(negativePreciseFractionalInput, &expCtx->variables),
- "-0.133700"_sd,
- BSONType::String);
+ convertExp->evaluate(negativePreciseFractionalInput), "-0.133700"_sd, BSONType::String);
Document positiveLargeInput{{"path1", Decimal128("1.3e37")}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(positiveLargeInput, &expCtx->variables),
- "1.3E+37"_sd,
- BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(positiveLargeInput), "1.3E+37"_sd, BSONType::String);
Document negativeLargeInput{{"path1", Decimal128("-1.3e37")}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(negativeLargeInput, &expCtx->variables),
- "-1.3E+37"_sd,
- BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(negativeLargeInput), "-1.3E+37"_sd, BSONType::String);
Document positiveTinyInput{{"path1", Decimal128("1.3e-37")}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(positiveTinyInput, &expCtx->variables),
- "1.3E-37"_sd,
- BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(positiveTinyInput), "1.3E-37"_sd, BSONType::String);
Document negativeTinyInput{{"path1", Decimal128("-1.3e-37")}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(negativeTinyInput, &expCtx->variables),
- "-1.3E-37"_sd,
- BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(negativeTinyInput), "-1.3E-37"_sd, BSONType::String);
Document infinityInput{{"path1", Decimal128::kPositiveInfinity}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(infinityInput, &expCtx->variables), "Infinity"_sd, BSONType::String);
+ convertExp->evaluate(infinityInput), "Infinity"_sd, BSONType::String);
Document negativeInfinityInput{{"path1", Decimal128::kNegativeInfinity}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(negativeInfinityInput, &expCtx->variables),
- "-Infinity"_sd,
- BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convertExp->evaluate(negativeInfinityInput), "-Infinity"_sd, BSONType::String);
Document nanInput{{"path1", Decimal128::kPositiveNaN}};
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(nanInput, &expCtx->variables), "NaN"_sd, BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convertExp->evaluate(nanInput), "NaN"_sd, BSONType::String);
Document negativeNaNInput{{"path1", Decimal128::kNegativeNaN}};
ASSERT_VALUE_CONTENTS_AND_TYPE(
- convertExp->evaluate(negativeNaNInput, &expCtx->variables), "NaN"_sd, BSONType::String);
+ convertExp->evaluate(negativeNaNInput), "NaN"_sd, BSONType::String);
}
} // namespace ExpressionConvertTest
@@ -3313,9 +3039,7 @@ TEST_F(ExpressionConvertShortcutsTest, AcceptsSingleArgumentInArrayOrByItself) {
spec = BSON("$toInt" << BSON_ARRAY(BSON_ARRAY("1")));
convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_CODE(convert->evaluate({}, &expCtx->variables),
- AssertionException,
- ErrorCodes::ConversionFailure);
+ ASSERT_THROWS_CODE(convert->evaluate({}), AssertionException, ErrorCodes::ConversionFailure);
}
TEST_F(ExpressionConvertShortcutsTest, ConvertsToInts) {
@@ -3325,8 +3049,7 @@ TEST_F(ExpressionConvertShortcutsTest, ConvertsToInts) {
<< "1");
auto convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionConvert*>(convert.get()));
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convert->evaluate({}, &expCtx->variables), Value(1), BSONType::NumberInt);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convert->evaluate({}), Value(1), BSONType::NumberInt);
}
TEST_F(ExpressionConvertShortcutsTest, ConvertsToLongs) {
@@ -3336,8 +3059,7 @@ TEST_F(ExpressionConvertShortcutsTest, ConvertsToLongs) {
<< "1");
auto convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionConvert*>(convert.get()));
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convert->evaluate({}, &expCtx->variables), Value(1), BSONType::NumberLong);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convert->evaluate({}), Value(1), BSONType::NumberLong);
}
TEST_F(ExpressionConvertShortcutsTest, ConvertsToDoubles) {
@@ -3347,8 +3069,7 @@ TEST_F(ExpressionConvertShortcutsTest, ConvertsToDoubles) {
<< "1");
auto convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionConvert*>(convert.get()));
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convert->evaluate({}, &expCtx->variables), Value(1), BSONType::NumberDouble);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convert->evaluate({}), Value(1), BSONType::NumberDouble);
}
TEST_F(ExpressionConvertShortcutsTest, ConvertsToDecimals) {
@@ -3358,8 +3079,7 @@ TEST_F(ExpressionConvertShortcutsTest, ConvertsToDecimals) {
<< "1");
auto convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionConvert*>(convert.get()));
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convert->evaluate({}, &expCtx->variables), Value(1), BSONType::NumberDecimal);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convert->evaluate({}), Value(1), BSONType::NumberDecimal);
}
TEST_F(ExpressionConvertShortcutsTest, ConvertsToDates) {
@@ -3368,9 +3088,8 @@ TEST_F(ExpressionConvertShortcutsTest, ConvertsToDates) {
BSONObj spec = BSON("$toDate" << 0LL);
auto convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionConvert*>(convert.get()));
- ASSERT_VALUE_CONTENTS_AND_TYPE(convert->evaluate({}, &expCtx->variables),
- Value(Date_t::fromMillisSinceEpoch(0)),
- BSONType::Date);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convert->evaluate({}), Value(Date_t::fromMillisSinceEpoch(0)), BSONType::Date);
}
TEST_F(ExpressionConvertShortcutsTest, ConvertsToObjectIds) {
@@ -3380,9 +3099,8 @@ TEST_F(ExpressionConvertShortcutsTest, ConvertsToObjectIds) {
BSONObj spec = BSON("$toObjectId" << hexString);
auto convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionConvert*>(convert.get()));
- ASSERT_VALUE_CONTENTS_AND_TYPE(convert->evaluate({}, &expCtx->variables),
- Value(OID::createFromString(hexString)),
- BSONType::jstOID);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(
+ convert->evaluate({}), Value(OID::createFromString(hexString)), BSONType::jstOID);
}
TEST_F(ExpressionConvertShortcutsTest, ConvertsToString) {
@@ -3391,8 +3109,7 @@ TEST_F(ExpressionConvertShortcutsTest, ConvertsToString) {
BSONObj spec = BSON("$toString" << 1);
auto convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionConvert*>(convert.get()));
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convert->evaluate({}, &expCtx->variables), Value("1"_sd), BSONType::String);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convert->evaluate({}), Value("1"_sd), BSONType::String);
}
TEST_F(ExpressionConvertShortcutsTest, ConvertsToBool) {
@@ -3401,8 +3118,7 @@ TEST_F(ExpressionConvertShortcutsTest, ConvertsToBool) {
BSONObj spec = BSON("$toBool" << 1);
auto convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionConvert*>(convert.get()));
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convert->evaluate({}, &expCtx->variables), Value(true), BSONType::Bool);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convert->evaluate({}), Value(true), BSONType::Bool);
}
TEST_F(ExpressionConvertShortcutsTest, ReturnsNullOnNullishInput) {
@@ -3411,15 +3127,13 @@ TEST_F(ExpressionConvertShortcutsTest, ReturnsNullOnNullishInput) {
BSONObj spec = BSON("$toBool" << BSONNULL);
auto convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionConvert*>(convert.get()));
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convert->evaluate({}, &expCtx->variables), Value(BSONNULL), BSONType::jstNULL);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convert->evaluate({}), Value(BSONNULL), BSONType::jstNULL);
spec = BSON("$toInt"
<< "$missing");
convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionConvert*>(convert.get()));
- ASSERT_VALUE_CONTENTS_AND_TYPE(
- convert->evaluate({}, &expCtx->variables), Value(BSONNULL), BSONType::jstNULL);
+ ASSERT_VALUE_CONTENTS_AND_TYPE(convert->evaluate({}), Value(BSONNULL), BSONType::jstNULL);
}
TEST_F(ExpressionConvertShortcutsTest, ThrowsOnConversionFailure) {
@@ -3429,17 +3143,13 @@ TEST_F(ExpressionConvertShortcutsTest, ThrowsOnConversionFailure) {
<< "not an int");
auto convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionConvert*>(convert.get()));
- ASSERT_THROWS_CODE(convert->evaluate({}, &expCtx->variables),
- AssertionException,
- ErrorCodes::ConversionFailure);
+ ASSERT_THROWS_CODE(convert->evaluate({}), AssertionException, ErrorCodes::ConversionFailure);
spec = BSON("$toObjectId"
<< "not all hex values");
convert = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
ASSERT_TRUE(dynamic_cast<ExpressionConvert*>(convert.get()));
- ASSERT_THROWS_CODE(convert->evaluate({}, &expCtx->variables),
- AssertionException,
- ErrorCodes::ConversionFailure);
+ ASSERT_THROWS_CODE(convert->evaluate({}), AssertionException, ErrorCodes::ConversionFailure);
}
} // namespace ExpressionConvertShortcutsTest
diff --git a/src/mongo/db/pipeline/expression_date_test.cpp b/src/mongo/db/pipeline/expression_date_test.cpp
index 67e798d17af..528c0da9541 100644
--- a/src/mongo/db/pipeline/expression_date_test.cpp
+++ b/src/mongo/db/pipeline/expression_date_test.cpp
@@ -143,27 +143,27 @@ TEST_F(ExpressionDateFromPartsTest, TestThatOutOfRangeValuesRollOver) {
auto spec = BSON("$dateFromParts" << BSON("year" << 2017 << "month" << -1));
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
auto dateVal = Date_t::fromMillisSinceEpoch(1477958400000); // 11/1/2016 in ms.
- ASSERT_VALUE_EQ(Value(dateVal), dateExp->evaluate({}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(dateVal), dateExp->evaluate(Document{}));
spec = BSON("$dateFromParts" << BSON("year" << 2017 << "day" << -1));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
dateVal = Date_t::fromMillisSinceEpoch(1483056000000); // 12/30/2016
- ASSERT_VALUE_EQ(Value(dateVal), dateExp->evaluate({}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(dateVal), dateExp->evaluate(Document{}));
spec = BSON("$dateFromParts" << BSON("year" << 2017 << "hour" << 25));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
dateVal = Date_t::fromMillisSinceEpoch(1483318800000); // 1/2/2017 01:00:00
- ASSERT_VALUE_EQ(Value(dateVal), dateExp->evaluate({}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(dateVal), dateExp->evaluate(Document{}));
spec = BSON("$dateFromParts" << BSON("year" << 2017 << "minute" << 61));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
dateVal = Date_t::fromMillisSinceEpoch(1483232460000); // 1/1/2017 01:01:00
- ASSERT_VALUE_EQ(Value(dateVal), dateExp->evaluate({}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(dateVal), dateExp->evaluate(Document{}));
spec = BSON("$dateFromParts" << BSON("year" << 2017 << "second" << 61));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
dateVal = Date_t::fromMillisSinceEpoch(1483228861000); // 1/1/2017 00:01:01
- ASSERT_VALUE_EQ(Value(dateVal), dateExp->evaluate({}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(dateVal), dateExp->evaluate(Document{}));
}
} // namespace ExpressionDateFromPartsTest
@@ -354,16 +354,14 @@ TEST_F(DateExpressionTest, RejectsArraysWithinObjectSpecification) {
// It will parse as an ExpressionArray, and fail at runtime.
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
auto contextDoc = Document{{"_id", 0}};
- ASSERT_THROWS_CODE(
- dateExp->evaluate(contextDoc, &expCtx->variables), AssertionException, 16006);
+ ASSERT_THROWS_CODE(dateExp->evaluate(contextDoc), AssertionException, 16006);
// 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);
contextDoc = Document{{"_id", 0}};
- ASSERT_THROWS_CODE(
- dateExp->evaluate(contextDoc, &expCtx->variables), AssertionException, 40533);
+ ASSERT_THROWS_CODE(dateExp->evaluate(contextDoc), AssertionException, 40533);
}
}
@@ -373,8 +371,7 @@ TEST_F(DateExpressionTest, RejectsTypesThatCannotCoerceToDate) {
BSONObj spec = BSON(expName << "$stringField");
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
auto contextDoc = Document{{"stringField", "string"_sd}};
- ASSERT_THROWS_CODE(
- dateExp->evaluate(contextDoc, &expCtx->variables), AssertionException, 16006);
+ ASSERT_THROWS_CODE(dateExp->evaluate(contextDoc), AssertionException, 16006);
}
}
@@ -384,7 +381,7 @@ TEST_F(DateExpressionTest, AcceptsObjectIds) {
BSONObj spec = BSON(expName << "$oid");
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
auto contextDoc = Document{{"oid", OID::gen()}};
- dateExp->evaluate(contextDoc, &expCtx->variables); // Should not throw.
+ dateExp->evaluate(contextDoc); // Should not throw.
}
}
@@ -394,7 +391,7 @@ TEST_F(DateExpressionTest, AcceptsTimestamps) {
BSONObj spec = BSON(expName << "$ts");
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
auto contextDoc = Document{{"ts", Timestamp{Date_t{}}}};
- dateExp->evaluate(contextDoc, &expCtx->variables); // Should not throw.
+ dateExp->evaluate(contextDoc); // Should not throw.
}
}
@@ -405,8 +402,7 @@ TEST_F(DateExpressionTest, RejectsNonStringTimezone) {
<< "$intField"));
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
auto contextDoc = Document{{"intField", 4}};
- ASSERT_THROWS_CODE(
- dateExp->evaluate(contextDoc, &expCtx->variables), AssertionException, 40533);
+ ASSERT_THROWS_CODE(dateExp->evaluate(contextDoc), AssertionException, 40533);
}
}
@@ -417,8 +413,7 @@ TEST_F(DateExpressionTest, RejectsUnrecognizedTimeZoneSpecification) {
<< "UNRECOGNIZED!"));
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
auto contextDoc = Document{{"_id", 0}};
- ASSERT_THROWS_CODE(
- dateExp->evaluate(contextDoc, &expCtx->variables), AssertionException, 40485);
+ ASSERT_THROWS_CODE(dateExp->evaluate(contextDoc), AssertionException, 40485);
}
}
@@ -503,7 +498,7 @@ TEST_F(DateExpressionTest, DoesRespectTimeZone) {
<< "America/New_York"));
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
auto contextDoc = Document{{"_id", 0}};
- dateExp->evaluate(contextDoc, &expCtx->variables); // Should not throw.
+ dateExp->evaluate(contextDoc); // Should not throw.
}
// Make sure the time zone is used during evaluation.
@@ -511,14 +506,14 @@ TEST_F(DateExpressionTest, DoesRespectTimeZone) {
auto specWithoutTimezone = BSON("$hour" << BSON("date" << date));
auto hourWithoutTimezone =
Expression::parseExpression(expCtx, specWithoutTimezone, expCtx->variablesParseState)
- ->evaluate({}, &expCtx->variables);
+ ->evaluate({});
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)
- ->evaluate({}, &expCtx->variables);
+ ->evaluate({});
ASSERT_VALUE_EQ(hourWithTimezone, Value(15));
}
@@ -533,30 +528,30 @@ TEST_F(DateExpressionTest, DoesResultInNullIfGivenNullishInput) {
auto spec = BSON(expName << BSON("date"
<< "$missing"));
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(contextDoc, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(contextDoc));
spec = BSON(expName << BSON("date" << BSONNULL));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(contextDoc, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(contextDoc));
spec = BSON(expName << BSON("date" << BSONUndefined));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(contextDoc, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(contextDoc));
// 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);
- ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(contextDoc, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(contextDoc));
spec = BSON(expName << BSON("date" << Date_t{} << "timezone" << BSONNULL));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(contextDoc, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(contextDoc));
spec = BSON(expName << BSON("date" << Date_t{} << "timezone" << BSONUndefined));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(contextDoc, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(contextDoc));
// Test that the expression results in null if the date and timezone both nullish.
spec = BSON(expName << BSON("date"
@@ -564,7 +559,7 @@ TEST_F(DateExpressionTest, DoesResultInNullIfGivenNullishInput) {
<< "timezone"
<< BSONUndefined));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(contextDoc, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(contextDoc));
// Test that the expression results in null if the date is nullish and timezone is present.
spec = BSON(expName << BSON("date"
@@ -572,7 +567,7 @@ TEST_F(DateExpressionTest, DoesResultInNullIfGivenNullishInput) {
<< "timezone"
<< "Europe/London"));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(contextDoc, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(contextDoc));
}
}
@@ -712,7 +707,7 @@ TEST_F(ExpressionDateToStringTest, ReturnsOnNullValueWhenInputIsNullish) {
<< "onNull"
<< "null default"));
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_EQ(Value("null default"_sd), dateExp->evaluate({}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value("null default"_sd), dateExp->evaluate(Document{}));
spec = BSON("$dateToString" << BSON("format"
<< "%Y-%m-%d"
@@ -721,7 +716,7 @@ TEST_F(ExpressionDateToStringTest, ReturnsOnNullValueWhenInputIsNullish) {
<< "onNull"
<< BSONNULL));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate({}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(Document{}));
spec = BSON("$dateToString" << BSON("format"
<< "%Y-%m-%d"
@@ -730,7 +725,7 @@ TEST_F(ExpressionDateToStringTest, ReturnsOnNullValueWhenInputIsNullish) {
<< "onNull"
<< "null default"));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_EQ(Value("null default"_sd), dateExp->evaluate({}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value("null default"_sd), dateExp->evaluate(Document{}));
spec = BSON("$dateToString" << BSON("format"
<< "%Y-%m-%d"
@@ -739,7 +734,7 @@ TEST_F(ExpressionDateToStringTest, ReturnsOnNullValueWhenInputIsNullish) {
<< "onNull"
<< "$alsoMissing"));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_EQ(Value(), dateExp->evaluate({}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(), dateExp->evaluate(Document{}));
}
TEST_F(ExpressionDateToStringTest, ReturnsNullIfInputDateIsNullish) {
@@ -747,9 +742,8 @@ TEST_F(ExpressionDateToStringTest, ReturnsNullIfInputDateIsNullish) {
auto spec = fromjson("{$dateToString: {date: '$date'}}");
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_EQ(Value(BSONNULL),
- dateExp->evaluate(Document{{"date", BSONNULL}}, &expCtx->variables));
- ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate({}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(Document{{"date", BSONNULL}}));
+ ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(Document{}));
}
TEST_F(ExpressionDateToStringTest, ReturnsNullIfFormatIsNullish) {
@@ -757,11 +751,9 @@ TEST_F(ExpressionDateToStringTest, ReturnsNullIfFormatIsNullish) {
auto spec = fromjson("{$dateToString: {date: '$date', format: '$format'}}");
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_EQ(
- Value(BSONNULL),
- dateExp->evaluate(Document{{"date", Date_t{}}, {"format", BSONNULL}}, &expCtx->variables));
ASSERT_VALUE_EQ(Value(BSONNULL),
- dateExp->evaluate(Document{{"date", Date_t{}}}, &expCtx->variables));
+ dateExp->evaluate(Document{{"date", Date_t{}}, {"format", BSONNULL}}));
+ ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(Document{{"date", Date_t{}}}));
}
TEST_F(ExpressionDateToStringTest, UsesDefaultFormatIfNoneSpecified) {
@@ -770,7 +762,7 @@ TEST_F(ExpressionDateToStringTest, UsesDefaultFormatIfNoneSpecified) {
auto spec = fromjson("{$dateToString: {date: '$date'}}");
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
ASSERT_VALUE_EQ(Value("1970-01-01T00:00:00.000Z"_sd),
- dateExp->evaluate(Document{{"date", Date_t{}}}, &expCtx->variables));
+ dateExp->evaluate(Document{{"date", Date_t{}}}));
}
TEST_F(ExpressionDateToStringTest, FailsForInvalidTimezoneRegardlessOfInputDate) {
@@ -778,14 +770,11 @@ TEST_F(ExpressionDateToStringTest, FailsForInvalidTimezoneRegardlessOfInputDate)
auto spec = fromjson("{$dateToString: {date: '$date', timezone: '$tz'}}");
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
+ ASSERT_THROWS_CODE(dateExp->evaluate(Document{{"date", BSONNULL}, {"tz", "invalid"_sd}}),
+ AssertionException,
+ 40485);
ASSERT_THROWS_CODE(
- dateExp->evaluate(Document{{"date", BSONNULL}, {"tz", "invalid"_sd}}, &expCtx->variables),
- AssertionException,
- 40485);
- ASSERT_THROWS_CODE(
- dateExp->evaluate(Document{{"date", BSONNULL}, {"tz", 5}}, &expCtx->variables),
- AssertionException,
- 40517);
+ dateExp->evaluate(Document{{"date", BSONNULL}, {"tz", 5}}), AssertionException, 40517);
}
TEST_F(ExpressionDateToStringTest, FailsForInvalidFormatStrings) {
@@ -794,12 +783,12 @@ TEST_F(ExpressionDateToStringTest, FailsForInvalidFormatStrings) {
auto spec = BSON("$dateToString" << BSON("date" << Date_t{} << "format"
<< "%n"));
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables), AssertionException, 18536);
+ ASSERT_THROWS_CODE(dateExp->evaluate({}), AssertionException, 18536);
spec = BSON("$dateToString" << BSON("date" << Date_t{} << "format"
<< "%Y%"));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables), AssertionException, 18535);
+ ASSERT_THROWS_CODE(dateExp->evaluate({}), AssertionException, 18535);
}
TEST_F(ExpressionDateToStringTest, FailsForInvalidFormatRegardlessOfInputDate) {
@@ -808,21 +797,16 @@ TEST_F(ExpressionDateToStringTest, FailsForInvalidFormatRegardlessOfInputDate) {
auto spec = fromjson("{$dateToString: {date: '$date', format: '$format', onNull: 0}}");
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
ASSERT_THROWS_CODE(
- dateExp->evaluate(Document{{"date", BSONNULL}, {"format", 5}}, &expCtx->variables),
- AssertionException,
- 18533);
- ASSERT_THROWS_CODE(
- dateExp->evaluate(Document{{"date", BSONNULL}, {"format", "%n"_sd}}, &expCtx->variables),
- AssertionException,
- 18536);
- ASSERT_THROWS_CODE(
- dateExp->evaluate(Document{{"date", BSONNULL}, {"format", "%"_sd}}, &expCtx->variables),
- AssertionException,
- 18535);
- ASSERT_THROWS_CODE(
- dateExp->evaluate(Document{{"date", "Invalid date"_sd}, {"format", 5}}, &expCtx->variables),
- AssertionException,
- 18533);
+ dateExp->evaluate(Document{{"date", BSONNULL}, {"format", 5}}), AssertionException, 18533);
+ ASSERT_THROWS_CODE(dateExp->evaluate(Document{{"date", BSONNULL}, {"format", "%n"_sd}}),
+ AssertionException,
+ 18536);
+ ASSERT_THROWS_CODE(dateExp->evaluate(Document{{"date", BSONNULL}, {"format", "%"_sd}}),
+ AssertionException,
+ 18535);
+ ASSERT_THROWS_CODE(dateExp->evaluate(Document{{"date", "Invalid date"_sd}, {"format", 5}}),
+ AssertionException,
+ 18533);
}
} // namespace ExpressionDateToStringTest
@@ -910,7 +894,7 @@ TEST_F(ExpressionDateFromStringTest, OptimizesToConstantIfAllInputsAreConstant)
ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
Date_t dateVal = Date_t::fromMillisSinceEpoch(1499173797000);
- ASSERT_VALUE_EQ(Value(dateVal), dateExp->evaluate({}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(dateVal), dateExp->evaluate(Document{}));
spec = BSON("$dateFromString" << BSON("dateString"
<< "2017-07-04T13:09:57"
@@ -930,7 +914,7 @@ TEST_F(ExpressionDateFromStringTest, OptimizesToConstantIfAllInputsAreConstant)
ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
dateVal = Date_t::fromMillisSinceEpoch(1499170197000);
- ASSERT_VALUE_EQ(Value(dateVal), dateExp->evaluate({}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(dateVal), dateExp->evaluate(Document{}));
spec = BSON("$dateFromString" << BSON("dateString"
<< "2017-07-04T13:09:57"
@@ -1002,9 +986,7 @@ TEST_F(ExpressionDateFromStringTest, RejectsUnparsableString) {
auto spec = BSON("$dateFromString" << BSON("dateString"
<< "60.Monday1770/06:59"));
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables),
- AssertionException,
- ErrorCodes::ConversionFailure);
+ ASSERT_THROWS_CODE(dateExp->evaluate({}), AssertionException, ErrorCodes::ConversionFailure);
}
TEST_F(ExpressionDateFromStringTest, RejectsTimeZoneInString) {
@@ -1013,16 +995,12 @@ 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);
- ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables),
- AssertionException,
- ErrorCodes::ConversionFailure);
+ ASSERT_THROWS_CODE(dateExp->evaluate({}), AssertionException, ErrorCodes::ConversionFailure);
spec = BSON("$dateFromString" << BSON("dateString"
<< "July 4, 2017 Europe/London"));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables),
- AssertionException,
- ErrorCodes::ConversionFailure);
+ ASSERT_THROWS_CODE(dateExp->evaluate({}), AssertionException, ErrorCodes::ConversionFailure);
}
TEST_F(ExpressionDateFromStringTest, RejectsTimeZoneInStringAndArgument) {
@@ -1034,9 +1012,7 @@ TEST_F(ExpressionDateFromStringTest, RejectsTimeZoneInStringAndArgument) {
<< "timezone"
<< "Europe/London"));
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables),
- AssertionException,
- ErrorCodes::ConversionFailure);
+ ASSERT_THROWS_CODE(dateExp->evaluate({}), AssertionException, ErrorCodes::ConversionFailure);
// Test with timezone abbreviation and timezone
spec = BSON("$dateFromString" << BSON("dateString"
@@ -1044,9 +1020,7 @@ TEST_F(ExpressionDateFromStringTest, RejectsTimeZoneInStringAndArgument) {
<< "timezone"
<< "Europe/London"));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables),
- AssertionException,
- ErrorCodes::ConversionFailure);
+ ASSERT_THROWS_CODE(dateExp->evaluate({}), AssertionException, ErrorCodes::ConversionFailure);
// Test with GMT offset and timezone
spec = BSON("$dateFromString" << BSON("dateString"
@@ -1054,9 +1028,7 @@ TEST_F(ExpressionDateFromStringTest, RejectsTimeZoneInStringAndArgument) {
<< "timezone"
<< "Europe/London"));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables),
- AssertionException,
- ErrorCodes::ConversionFailure);
+ ASSERT_THROWS_CODE(dateExp->evaluate({}), AssertionException, ErrorCodes::ConversionFailure);
// Test with GMT offset and GMT timezone
spec = BSON("$dateFromString" << BSON("dateString"
@@ -1064,9 +1036,7 @@ TEST_F(ExpressionDateFromStringTest, RejectsTimeZoneInStringAndArgument) {
<< "timezone"
<< "GMT"));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables),
- AssertionException,
- ErrorCodes::ConversionFailure);
+ ASSERT_THROWS_CODE(dateExp->evaluate({}), AssertionException, ErrorCodes::ConversionFailure);
}
TEST_F(ExpressionDateFromStringTest, RejectsNonStringFormat) {
@@ -1077,14 +1047,14 @@ TEST_F(ExpressionDateFromStringTest, RejectsNonStringFormat) {
<< "format"
<< 2));
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables), AssertionException, 40684);
+ ASSERT_THROWS_CODE(dateExp->evaluate({}), AssertionException, 40684);
spec = BSON("$dateFromString" << BSON("dateString"
<< "July 4, 2017"
<< "format"
<< true));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables), AssertionException, 40684);
+ ASSERT_THROWS_CODE(dateExp->evaluate({}), AssertionException, 40684);
}
TEST_F(ExpressionDateFromStringTest, RejectsStringsThatDoNotMatchFormat) {
@@ -1095,18 +1065,14 @@ TEST_F(ExpressionDateFromStringTest, RejectsStringsThatDoNotMatchFormat) {
<< "format"
<< "%Y-%m-%d"));
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables),
- AssertionException,
- ErrorCodes::ConversionFailure);
+ ASSERT_THROWS_CODE(dateExp->evaluate({}), AssertionException, ErrorCodes::ConversionFailure);
spec = BSON("$dateFromString" << BSON("dateString"
<< "2017-07"
<< "format"
<< "%m-%Y"));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables),
- AssertionException,
- ErrorCodes::ConversionFailure);
+ ASSERT_THROWS_CODE(dateExp->evaluate({}), AssertionException, ErrorCodes::ConversionFailure);
}
TEST_F(ExpressionDateFromStringTest, EscapeCharacterAllowsPrefixUsage) {
@@ -1117,7 +1083,7 @@ TEST_F(ExpressionDateFromStringTest, EscapeCharacterAllowsPrefixUsage) {
<< "format"
<< "%Y %% %m %% %d"));
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_EQ("2017-01-01T00:00:00.000Z", dateExp->evaluate({}, &expCtx->variables).toString());
+ ASSERT_EQ("2017-01-01T00:00:00.000Z", dateExp->evaluate(Document{}).toString());
}
@@ -1129,21 +1095,21 @@ TEST_F(ExpressionDateFromStringTest, EvaluatesToNullIfFormatIsNullish) {
<< "format"
<< BSONNULL));
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate({}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(Document{}));
spec = BSON("$dateFromString" << BSON("dateString"
<< "1/1/2017"
<< "format"
<< "$missing"));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate({}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(Document{}));
spec = BSON("$dateFromString" << BSON("dateString"
<< "1/1/2017"
<< "format"
<< BSONUndefined));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate({}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(Document{}));
}
TEST_F(ExpressionDateFromStringTest, ReadWithUTCOffset) {
@@ -1154,35 +1120,35 @@ TEST_F(ExpressionDateFromStringTest, ReadWithUTCOffset) {
<< "timezone"
<< "-01:00"));
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_EQ("2017-07-28T11:47:52.912Z", dateExp->evaluate({}, &expCtx->variables).toString());
+ ASSERT_EQ("2017-07-28T11:47:52.912Z", dateExp->evaluate(Document{}).toString());
spec = BSON("$dateFromString" << BSON("dateString"
<< "2017-07-28T10:47:52.912"
<< "timezone"
<< "+01:00"));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_EQ("2017-07-28T09:47:52.912Z", dateExp->evaluate({}, &expCtx->variables).toString());
+ ASSERT_EQ("2017-07-28T09:47:52.912Z", dateExp->evaluate(Document{}).toString());
spec = BSON("$dateFromString" << BSON("dateString"
<< "2017-07-28T10:47:52.912"
<< "timezone"
<< "+0445"));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_EQ("2017-07-28T06:02:52.912Z", dateExp->evaluate({}, &expCtx->variables).toString());
+ ASSERT_EQ("2017-07-28T06:02:52.912Z", dateExp->evaluate(Document{}).toString());
spec = BSON("$dateFromString" << BSON("dateString"
<< "2017-07-28T10:47:52.912"
<< "timezone"
<< "+10:45"));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_EQ("2017-07-28T00:02:52.912Z", dateExp->evaluate({}, &expCtx->variables).toString());
+ ASSERT_EQ("2017-07-28T00:02:52.912Z", dateExp->evaluate(Document{}).toString());
spec = BSON("$dateFromString" << BSON("dateString"
<< "1945-07-28T10:47:52.912"
<< "timezone"
<< "-08:00"));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_EQ("1945-07-28T18:47:52.912Z", dateExp->evaluate({}, &expCtx->variables).toString());
+ ASSERT_EQ("1945-07-28T18:47:52.912Z", dateExp->evaluate(Document{}).toString());
}
TEST_F(ExpressionDateFromStringTest, ConvertStringWithUTCOffsetAndFormat) {
@@ -1195,7 +1161,7 @@ TEST_F(ExpressionDateFromStringTest, ConvertStringWithUTCOffsetAndFormat) {
<< "format"
<< "%H:%M:%S.%L on %m/%d/%Y"));
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_EQ("2017-07-28T11:47:52.912Z", dateExp->evaluate({}, &expCtx->variables).toString());
+ ASSERT_EQ("2017-07-28T11:47:52.912Z", dateExp->evaluate(Document{}).toString());
spec = BSON("$dateFromString" << BSON("dateString"
<< "10:47:52.912 on 7/28/2017"
@@ -1204,7 +1170,7 @@ TEST_F(ExpressionDateFromStringTest, ConvertStringWithUTCOffsetAndFormat) {
<< "format"
<< "%H:%M:%S.%L on %m/%d/%Y"));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_EQ("2017-07-28T09:47:52.912Z", dateExp->evaluate({}, &expCtx->variables).toString());
+ ASSERT_EQ("2017-07-28T09:47:52.912Z", dateExp->evaluate(Document{}).toString());
}
TEST_F(ExpressionDateFromStringTest, ConvertStringWithISODateFormat) {
@@ -1215,7 +1181,7 @@ TEST_F(ExpressionDateFromStringTest, ConvertStringWithISODateFormat) {
<< "format"
<< "Day %u Week %V Year %G"));
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_EQ("2018-01-07T00:00:00.000Z", dateExp->evaluate({}, &expCtx->variables).toString());
+ ASSERT_EQ("2018-01-07T00:00:00.000Z", dateExp->evaluate(Document{}).toString());
// Week and day of week default to '1' if not specified.
spec = BSON("$dateFromString" << BSON("dateString"
@@ -1223,14 +1189,14 @@ TEST_F(ExpressionDateFromStringTest, ConvertStringWithISODateFormat) {
<< "format"
<< "Week %V Year %G"));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_EQ("2018-01-01T00:00:00.000Z", dateExp->evaluate({}, &expCtx->variables).toString());
+ ASSERT_EQ("2018-01-01T00:00:00.000Z", dateExp->evaluate(Document{}).toString());
spec = BSON("$dateFromString" << BSON("dateString"
<< "Day 7 Year 2017"
<< "format"
<< "Day %u Year %G"));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_EQ("2017-01-08T00:00:00.000Z", dateExp->evaluate({}, &expCtx->variables).toString());
+ ASSERT_EQ("2017-01-08T00:00:00.000Z", dateExp->evaluate(Document{}).toString());
}
TEST_F(ExpressionDateFromStringTest, ReturnsOnNullForNullishInput) {
@@ -1239,25 +1205,25 @@ TEST_F(ExpressionDateFromStringTest, ReturnsOnNullForNullishInput) {
auto spec = BSON("$dateFromString" << BSON("dateString" << BSONNULL << "onNull"
<< "Null default"));
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_EQ(Value("Null default"_sd), dateExp->evaluate({}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value("Null default"_sd), dateExp->evaluate(Document{}));
spec = BSON("$dateFromString" << BSON("dateString"
<< "$missing"
<< "onNull"
<< "Null default"));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_EQ(Value("Null default"_sd), dateExp->evaluate({}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value("Null default"_sd), dateExp->evaluate(Document{}));
spec = BSON("$dateFromString" << BSON("dateString"
<< "$missing"
<< "onNull"
<< "$alsoMissing"));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_EQ(Value(), dateExp->evaluate({}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(), dateExp->evaluate(Document{}));
spec = BSON("$dateFromString" << BSON("dateString" << BSONNULL << "onNull" << BSONNULL));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate({}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(Document{}));
}
TEST_F(ExpressionDateFromStringTest, InvalidFormatTakesPrecedenceOverOnNull) {
@@ -1268,14 +1234,14 @@ TEST_F(ExpressionDateFromStringTest, InvalidFormatTakesPrecedenceOverOnNull) {
<< "format"
<< 5));
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables), AssertionException, 40684);
+ ASSERT_THROWS_CODE(dateExp->evaluate({}), AssertionException, 40684);
spec = BSON("$dateFromString" << BSON("dateString" << BSONNULL << "onNull"
<< "Null default"
<< "format"
<< "%"));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables), AssertionException, 18535);
+ ASSERT_THROWS_CODE(dateExp->evaluate({}), AssertionException, 18535);
}
TEST_F(ExpressionDateFromStringTest, InvalidFormatTakesPrecedenceOverOnError) {
@@ -1288,14 +1254,14 @@ TEST_F(ExpressionDateFromStringTest, InvalidFormatTakesPrecedenceOverOnError) {
<< "format"
<< 5));
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables), AssertionException, 40684);
+ ASSERT_THROWS_CODE(dateExp->evaluate({}), AssertionException, 40684);
spec = BSON("$dateFromString" << BSON("dateString" << 5 << "onError"
<< "Not used default"
<< "format"
<< "%"));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables), AssertionException, 18535);
+ ASSERT_THROWS_CODE(dateExp->evaluate({}), AssertionException, 18535);
}
TEST_F(ExpressionDateFromStringTest, InvalidTimezoneTakesPrecedenceOverOnNull) {
@@ -1306,14 +1272,14 @@ TEST_F(ExpressionDateFromStringTest, InvalidTimezoneTakesPrecedenceOverOnNull) {
<< "timezone"
<< 5));
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables), AssertionException, 40517);
+ ASSERT_THROWS_CODE(dateExp->evaluate({}), AssertionException, 40517);
spec = BSON("$dateFromString" << BSON("dateString" << BSONNULL << "onNull"
<< "Null default"
<< "timezone"
<< "invalid timezone string"));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables), AssertionException, 40485);
+ ASSERT_THROWS_CODE(dateExp->evaluate({}), AssertionException, 40485);
}
TEST_F(ExpressionDateFromStringTest, InvalidTimezoneTakesPrecedenceOverOnError) {
@@ -1326,14 +1292,14 @@ TEST_F(ExpressionDateFromStringTest, InvalidTimezoneTakesPrecedenceOverOnError)
<< "timezone"
<< 5));
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables), AssertionException, 40517);
+ ASSERT_THROWS_CODE(dateExp->evaluate({}), AssertionException, 40517);
spec = BSON("$dateFromString" << BSON("dateString" << 5 << "onError"
<< "On error default"
<< "timezone"
<< "invalid timezone string"));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables), AssertionException, 40485);
+ ASSERT_THROWS_CODE(dateExp->evaluate({}), AssertionException, 40485);
}
TEST_F(ExpressionDateFromStringTest, OnNullTakesPrecedenceOverOtherNullishParameters) {
@@ -1344,14 +1310,14 @@ TEST_F(ExpressionDateFromStringTest, OnNullTakesPrecedenceOverOtherNullishParame
<< "timezone"
<< BSONNULL));
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_EQ(Value("Null default"_sd), dateExp->evaluate({}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value("Null default"_sd), dateExp->evaluate(Document{}));
spec = BSON("$dateFromString" << BSON("dateString" << BSONNULL << "onNull"
<< "Null default"
<< "format"
<< BSONNULL));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_EQ(Value("Null default"_sd), dateExp->evaluate({}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value("Null default"_sd), dateExp->evaluate(Document{}));
}
TEST_F(ExpressionDateFromStringTest, OnNullOnlyUsedIfInputStringIsNullish) {
@@ -1364,7 +1330,7 @@ TEST_F(ExpressionDateFromStringTest, OnNullOnlyUsedIfInputStringIsNullish) {
<< "timezone"
<< BSONNULL));
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate({}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(Document{}));
spec = BSON("$dateFromString" << BSON("dateString"
<< "2018-02-14"
@@ -1373,7 +1339,7 @@ TEST_F(ExpressionDateFromStringTest, OnNullOnlyUsedIfInputStringIsNullish) {
<< "format"
<< BSONNULL));
dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate({}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(BSONNULL), dateExp->evaluate(Document{}));
}
TEST_F(ExpressionDateFromStringTest, ReturnsOnErrorForParseFailures) {
@@ -1385,7 +1351,7 @@ TEST_F(ExpressionDateFromStringTest, ReturnsOnErrorForParseFailures) {
auto spec = BSON("$dateFromString" << BSON("dateString" << date << "onError"
<< "Error default"));
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_EQ(Value("Error default"_sd), dateExp->evaluate({}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value("Error default"_sd), dateExp->evaluate(Document{}));
}
}
@@ -1399,7 +1365,7 @@ TEST_F(ExpressionDateFromStringTest, ReturnsOnErrorForFormatMismatch) {
BSON("$dateFromString" << BSON("dateString" << date << "format" << format << "onError"
<< "Error default"));
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_VALUE_EQ(Value("Error default"_sd), dateExp->evaluate({}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value("Error default"_sd), dateExp->evaluate(Document{}));
}
}
@@ -1411,10 +1377,9 @@ TEST_F(ExpressionDateFromStringTest, OnNullEvaluatedLazily) {
<< "onNull"
<< BSON("$divide" << BSON_ARRAY(1 << 0))));
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_EQ(
- "2018-02-14T00:00:00.000Z",
- dateExp->evaluate(Document{{"date", "2018-02-14"_sd}}, &expCtx->variables).toString());
- ASSERT_THROWS_CODE(dateExp->evaluate({}, &expCtx->variables), AssertionException, 16608);
+ ASSERT_EQ("2018-02-14T00:00:00.000Z",
+ dateExp->evaluate(Document{{"date", "2018-02-14"_sd}}).toString());
+ ASSERT_THROWS_CODE(dateExp->evaluate(Document{}), AssertionException, 16608);
}
TEST_F(ExpressionDateFromStringTest, OnErrorEvaluatedLazily) {
@@ -1425,11 +1390,9 @@ TEST_F(ExpressionDateFromStringTest, OnErrorEvaluatedLazily) {
<< "onError"
<< BSON("$divide" << BSON_ARRAY(1 << 0))));
auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_EQ(
- "2018-02-14T00:00:00.000Z",
- dateExp->evaluate(Document{{"date", "2018-02-14"_sd}}, &expCtx->variables).toString());
- ASSERT_THROWS_CODE(
- dateExp->evaluate(Document{{"date", 5}}, &expCtx->variables), AssertionException, 16608);
+ ASSERT_EQ("2018-02-14T00:00:00.000Z",
+ dateExp->evaluate(Document{{"date", "2018-02-14"_sd}}).toString());
+ ASSERT_THROWS_CODE(dateExp->evaluate(Document{{"date", 5}}), AssertionException, 16608);
}
} // namespace ExpressionDateFromStringTest
diff --git a/src/mongo/db/pipeline/expression_test.cpp b/src/mongo/db/pipeline/expression_test.cpp
index 8552a8137cf..029320c1b2f 100644
--- a/src/mongo/db/pipeline/expression_test.cpp
+++ b/src/mongo/db/pipeline/expression_test.cpp
@@ -65,7 +65,7 @@ static Value evaluateExpression(const string& expressionName,
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);
+ Value result = expression->evaluate(Document());
return result;
}
@@ -78,7 +78,7 @@ static Value evaluateNamedArgExpression(const string& expressionName, const Docu
VariablesParseState vps = expCtx->variablesParseState;
const BSONObj obj = BSON(expressionName << operand);
auto expression = Expression::parseExpression(expCtx, obj, vps);
- Value result = expression->evaluate({}, &expCtx->variables);
+ Value result = expression->evaluate(Document());
return result;
}
@@ -175,9 +175,8 @@ class ExpressionNaryTestOneArg : public ExpressionBaseTest {
public:
virtual void assertEvaluates(Value input, Value output) {
addOperand(_expr, input);
- ASSERT_VALUE_EQ(output, _expr->evaluate({}, &_expr->getExpressionContext()->variables));
- ASSERT_EQUALS(output.getType(),
- _expr->evaluate({}, &_expr->getExpressionContext()->variables).getType());
+ ASSERT_VALUE_EQ(output, _expr->evaluate(Document()));
+ ASSERT_EQUALS(output.getType(), _expr->evaluate(Document()).getType());
}
intrusive_ptr<ExpressionNary> _expr;
@@ -188,9 +187,8 @@ public:
virtual void assertEvaluates(Value input1, Value input2, Value output) {
addOperand(_expr, input1);
addOperand(_expr, input2);
- ASSERT_VALUE_EQ(output, _expr->evaluate({}, &_expr->getExpressionContext()->variables));
- ASSERT_EQUALS(output.getType(),
- _expr->evaluate({}, &_expr->getExpressionContext()->variables).getType());
+ ASSERT_VALUE_EQ(output, _expr->evaluate(Document()));
+ ASSERT_EQUALS(output.getType(), _expr->evaluate(Document()).getType());
}
intrusive_ptr<ExpressionNary> _expr;
@@ -201,13 +199,13 @@ public:
/** A dummy child of ExpressionNary used for testing. */
class Testable : public ExpressionNary {
public:
- virtual Value evaluate(const Document& root, Variables* variables) const {
+ virtual Value evaluate(const Document& root) const {
// Just put all the values in a list.
// By default, this is not associative/commutative so the results will change if
// instantiated as commutative or associative and operations are reordered.
vector<Value> values;
for (auto&& child : _children)
- values.push_back(child->evaluate(root, variables));
+ values.push_back(child->evaluate(root));
return Value(values);
}
@@ -1382,7 +1380,7 @@ public:
intrusive_ptr<ExpressionContextForTest> expCtx(new 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(Document())));
}
protected:
@@ -1398,7 +1396,7 @@ public:
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)));
+ ASSERT_BSONOBJ_EQ(BSON("" << 2), toBson(expression->evaluate(Document())));
}
};
@@ -1417,7 +1415,7 @@ public:
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);
+ ASSERT_THROWS(expression->evaluate(Document()), AssertionException);
}
};
@@ -1428,7 +1426,7 @@ public:
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);
+ ASSERT_THROWS(expression->evaluate(Document()), AssertionException);
}
};
@@ -1667,13 +1665,11 @@ public:
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)));
+ ASSERT_BSONOBJ_EQ(BSON("" << expectedResult()),
+ toBson(expression->evaluate(fromBson(BSON("a" << 1)))));
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)))));
}
protected:
@@ -1964,7 +1960,7 @@ public:
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());
+ ASSERT(expression->evaluate(Document()).getBool());
}
};
@@ -1975,7 +1971,7 @@ public:
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());
+ ASSERT(!expression->evaluate(Document()).getBool());
}
};
@@ -2083,10 +2079,10 @@ public:
// 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(Document())));
// 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(Document())));
}
protected:
@@ -2323,7 +2319,7 @@ public:
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));
+ ASSERT_VALUE_EQ(expression->evaluate(Document()), Value(true));
}
};
@@ -2456,7 +2452,7 @@ 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)));
+ assertBinaryEqual(BSON("" << 5), toBson(expression->evaluate(Document())));
}
};
@@ -2472,7 +2468,7 @@ public:
intrusive_ptr<Expression> expression = ExpressionConstant::parse(expCtx, specElement, vps);
assertBinaryEqual(BSON(""
<< "foo"),
- toBson(expression->evaluate({}, &expCtx->variables)));
+ toBson(expression->evaluate(Document())));
}
};
@@ -2538,9 +2534,7 @@ private:
TEST(ExpressionConstantTest, ConstantOfValueMissingRemovesField) {
intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
intrusive_ptr<Expression> expression = ExpressionConstant::create(expCtx, Value());
- assertBinaryEqual(
- BSONObj(),
- toBson(expression->evaluate(Document{{"foo", Value("bar"_sd)}}, &expCtx->variables)));
+ assertBinaryEqual(BSONObj(), toBson(expression->evaluate(Document{{"foo", Value("bar"_sd)}})));
}
TEST(ExpressionConstantTest, ConstantOfValueMissingSerializesToRemoveSystemVar) {
@@ -2643,11 +2637,11 @@ TEST(ExpressionPowTest, ThrowsWhenBaseZeroAndExpNegative) {
VariablesParseState vps = expCtx->variablesParseState;
const auto expr = Expression::parseExpression(expCtx, BSON("$pow" << BSON_ARRAY(0 << -5)), vps);
- ASSERT_THROWS([&] { expr->evaluate({}, &expCtx->variables); }(), AssertionException);
+ ASSERT_THROWS([&] { expr->evaluate(Document()); }(), AssertionException);
const auto exprWithLong =
Expression::parseExpression(expCtx, BSON("$pow" << BSON_ARRAY(0LL << -5LL)), vps);
- ASSERT_THROWS([&] { expr->evaluate({}, &expCtx->variables); }(), AssertionException);
+ ASSERT_THROWS([&] { expr->evaluate(Document()); }(), AssertionException);
}
TEST(ExpressionPowTest, LargeExponentValuesWithBaseOfOne) {
@@ -2798,35 +2792,21 @@ TEST(ExpressionIndexOfArray,
fromjson("{ $indexOfArray : [ [0, 1, 2, 3, 4, 5, 'val'] , '$x'] }"),
expCtx->variablesParseState);
auto optimizedIndexOfArray = expIndexOfArray->optimize();
- ASSERT_VALUE_EQ(Value(0),
- optimizedIndexOfArray->evaluate(Document{{"x", 0}}, &expCtx->variables));
- ASSERT_VALUE_EQ(Value(1),
- optimizedIndexOfArray->evaluate(Document{{"x", 1}}, &expCtx->variables));
- ASSERT_VALUE_EQ(Value(2),
- optimizedIndexOfArray->evaluate(Document{{"x", 2}}, &expCtx->variables));
- ASSERT_VALUE_EQ(Value(3),
- optimizedIndexOfArray->evaluate(Document{{"x", 3}}, &expCtx->variables));
- ASSERT_VALUE_EQ(Value(4),
- optimizedIndexOfArray->evaluate(Document{{"x", 4}}, &expCtx->variables));
- ASSERT_VALUE_EQ(Value(5),
- optimizedIndexOfArray->evaluate(Document{{"x", 5}}, &expCtx->variables));
- ASSERT_VALUE_EQ(
- Value(6),
- optimizedIndexOfArray->evaluate(Document{{"x", string("val")}}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(0), optimizedIndexOfArray->evaluate(Document{{"x", 0}}));
+ ASSERT_VALUE_EQ(Value(1), optimizedIndexOfArray->evaluate(Document{{"x", 1}}));
+ ASSERT_VALUE_EQ(Value(2), optimizedIndexOfArray->evaluate(Document{{"x", 2}}));
+ ASSERT_VALUE_EQ(Value(3), optimizedIndexOfArray->evaluate(Document{{"x", 3}}));
+ ASSERT_VALUE_EQ(Value(4), optimizedIndexOfArray->evaluate(Document{{"x", 4}}));
+ ASSERT_VALUE_EQ(Value(5), optimizedIndexOfArray->evaluate(Document{{"x", 5}}));
+ ASSERT_VALUE_EQ(Value(6), optimizedIndexOfArray->evaluate(Document{{"x", string("val")}}));
auto optimizedIndexNotFound = optimizedIndexOfArray->optimize();
// Should evaluate to -1 if not found.
- ASSERT_VALUE_EQ(Value(-1),
- optimizedIndexNotFound->evaluate(Document{{"x", 10}}, &expCtx->variables));
- ASSERT_VALUE_EQ(Value(-1),
- optimizedIndexNotFound->evaluate(Document{{"x", 100}}, &expCtx->variables));
- ASSERT_VALUE_EQ(Value(-1),
- optimizedIndexNotFound->evaluate(Document{{"x", 1000}}, &expCtx->variables));
- ASSERT_VALUE_EQ(
- Value(-1),
- optimizedIndexNotFound->evaluate(Document{{"x", string("string")}}, &expCtx->variables));
- ASSERT_VALUE_EQ(Value(-1),
- optimizedIndexNotFound->evaluate(Document{{"x", -1}}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(-1), optimizedIndexNotFound->evaluate(Document{{"x", 10}}));
+ ASSERT_VALUE_EQ(Value(-1), optimizedIndexNotFound->evaluate(Document{{"x", 100}}));
+ ASSERT_VALUE_EQ(Value(-1), optimizedIndexNotFound->evaluate(Document{{"x", 1000}}));
+ ASSERT_VALUE_EQ(Value(-1), optimizedIndexNotFound->evaluate(Document{{"x", string("string")}}));
+ ASSERT_VALUE_EQ(Value(-1), optimizedIndexNotFound->evaluate(Document{{"x", -1}}));
}
TEST(ExpressionIndexOfArray,
@@ -2839,12 +2819,10 @@ TEST(ExpressionIndexOfArray,
fromjson("{ $indexOfArray : [ [0, 1, 2, 3, 4, 5] , '$x', 3, 5] }"),
expCtx->variablesParseState);
auto optimizedIndexOfArray = expIndexOfArray->optimize();
- ASSERT_VALUE_EQ(Value(4),
- optimizedIndexOfArray->evaluate(Document{{"x", 4}}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(4), optimizedIndexOfArray->evaluate(Document{{"x", 4}}));
// Should evaluate to -1 if not found in range.
- ASSERT_VALUE_EQ(Value(-1),
- optimizedIndexOfArray->evaluate(Document{{"x", 0}}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(-1), optimizedIndexOfArray->evaluate(Document{{"x", 0}}));
}
TEST(ExpressionIndexOfArray,
@@ -2857,9 +2835,8 @@ TEST(ExpressionIndexOfArray,
fromjson("{ $indexOfArray : [ [0, 1, 2, 2, 3, 4, 5] , '$x'] }"),
expCtx->variablesParseState);
auto optimizedIndexOfArrayWithDuplicateValues = expIndexOfArrayWithDuplicateValues->optimize();
- ASSERT_VALUE_EQ(
- Value(2),
- optimizedIndexOfArrayWithDuplicateValues->evaluate(Document{{"x", 2}}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(2),
+ optimizedIndexOfArrayWithDuplicateValues->evaluate(Document{{"x", 2}}));
// Duplicate Values in a range.
auto expIndexInRangeWithhDuplicateValues = Expression::parseExpression(
expCtx,
@@ -2868,9 +2845,8 @@ TEST(ExpressionIndexOfArray,
expCtx->variablesParseState);
auto optimizedIndexInRangeWithDuplcateValues = expIndexInRangeWithhDuplicateValues->optimize();
// Should evaluate to 4.
- ASSERT_VALUE_EQ(
- Value(4),
- optimizedIndexInRangeWithDuplcateValues->evaluate(Document{{"x", 2}}, &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(4),
+ optimizedIndexInRangeWithDuplcateValues->evaluate(Document{{"x", 2}}));
}
namespace FieldPath {
@@ -2909,9 +2885,7 @@ TEST(FieldPath, RemoveOptimizesToMissingValue) {
auto optimizedExpr = expression->optimize();
- ASSERT_VALUE_EQ(
- Value(),
- optimizedExpr->evaluate(Document(BSON("x" << BSON("y" << 123))), &expCtx->variables));
+ ASSERT_VALUE_EQ(Value(), optimizedExpr->evaluate(Document(BSON("x" << BSON("y" << 123)))));
}
TEST(FieldPath, NoOptimizationOnNormalPath) {
@@ -3033,7 +3007,7 @@ public:
void run() {
intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a");
- assertBinaryEqual(fromjson("{}"), toBson(expression->evaluate({}, &expCtx->variables)));
+ assertBinaryEqual(fromjson("{}"), toBson(expression->evaluate(Document())));
}
};
@@ -3043,9 +3017,8 @@ public:
void run() {
intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a");
- assertBinaryEqual(
- fromjson("{'':123}"),
- toBson(expression->evaluate(fromBson(BSON("a" << 123)), &expCtx->variables)));
+ assertBinaryEqual(fromjson("{'':123}"),
+ toBson(expression->evaluate(fromBson(BSON("a" << 123)))));
}
};
@@ -3055,9 +3028,8 @@ 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:null}")), &expCtx->variables)));
+ assertBinaryEqual(fromjson("{}"),
+ toBson(expression->evaluate(fromBson(fromjson("{a:null}")))));
}
};
@@ -3067,9 +3039,8 @@ 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)));
+ assertBinaryEqual(fromjson("{}"),
+ toBson(expression->evaluate(fromBson(fromjson("{a:undefined}")))));
}
};
@@ -3079,9 +3050,8 @@ 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("{z:1}")), &expCtx->variables)));
+ assertBinaryEqual(fromjson("{}"),
+ toBson(expression->evaluate(fromBson(fromjson("{z:1}")))));
}
};
@@ -3091,9 +3061,7 @@ public:
void run() {
intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a.b");
- assertBinaryEqual(
- fromjson("{}"),
- toBson(expression->evaluate(fromBson(BSON("a" << 2)), &expCtx->variables)));
+ assertBinaryEqual(fromjson("{}"), toBson(expression->evaluate(fromBson(BSON("a" << 2)))));
}
};
@@ -3104,8 +3072,7 @@ public:
intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a.b");
assertBinaryEqual(BSON("" << 55),
- toBson(expression->evaluate(fromBson(BSON("a" << BSON("b" << 55))),
- &expCtx->variables)));
+ toBson(expression->evaluate(fromBson(BSON("a" << BSON("b" << 55))))));
}
};
@@ -3115,9 +3082,8 @@ public:
void run() {
intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a.b");
- assertBinaryEqual(
- fromjson("{}"),
- toBson(expression->evaluate(fromBson(BSON("a" << BSONObj())), &expCtx->variables)));
+ assertBinaryEqual(fromjson("{}"),
+ toBson(expression->evaluate(fromBson(BSON("a" << BSONObj())))));
}
};
@@ -3127,9 +3093,8 @@ public:
void run() {
intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a.b");
- assertBinaryEqual(
- BSON("" << BSONArray()),
- toBson(expression->evaluate(fromBson(BSON("a" << BSONArray())), &expCtx->variables)));
+ assertBinaryEqual(BSON("" << BSONArray()),
+ toBson(expression->evaluate(fromBson(BSON("a" << BSONArray())))));
}
};
@@ -3139,9 +3104,8 @@ 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:[null]}")), &expCtx->variables)));
+ assertBinaryEqual(fromjson("{'':[]}"),
+ toBson(expression->evaluate(fromBson(fromjson("{a:[null]}")))));
}
};
@@ -3152,8 +3116,7 @@ public:
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)));
+ toBson(expression->evaluate(fromBson(fromjson("{a:[undefined]}")))));
}
};
@@ -3163,9 +3126,8 @@ 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:[1]}")), &expCtx->variables)));
+ assertBinaryEqual(fromjson("{'':[]}"),
+ toBson(expression->evaluate(fromBson(fromjson("{a:[1]}")))));
}
};
@@ -3175,9 +3137,8 @@ public:
void run() {
intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
intrusive_ptr<Expression> expression = ExpressionFieldPath::create(expCtx, "a.b");
- assertBinaryEqual(
- fromjson("{'':[9]}"),
- toBson(expression->evaluate(fromBson(fromjson("{a:[{b:9}]}")), &expCtx->variables)));
+ assertBinaryEqual(fromjson("{'':[9]}"),
+ toBson(expression->evaluate(fromBson(fromjson("{a:[{b:9}]}")))));
}
};
@@ -3189,8 +3150,7 @@ public:
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)));
+ fromBson(fromjson("{a:[{b:9},null,undefined,{g:4},{b:20},{}]}")))));
}
};
@@ -3205,8 +3165,7 @@ public:
"{b:{c:3}},"
"{b:[{c:4}]},"
"{b:[{c:[5]}]},"
- "{b:{c:[6,7]}}]}")),
- &expCtx->variables)));
+ "{b:{c:[6,7]}}]}")))));
}
};
@@ -3400,22 +3359,19 @@ auto expressionObjectCreateHelper(
TEST(ExpressionObjectEvaluate, EmptyObjectShouldEvaluateToEmptyDocument) {
intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
auto object = expressionObjectCreateHelper(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)));
+ ASSERT_VALUE_EQ(Value(Document()), object->evaluate(Document()));
+ ASSERT_VALUE_EQ(Value(Document()), object->evaluate(Document{{"a", 1}}));
+ ASSERT_VALUE_EQ(Value(Document()), object->evaluate(Document{{"_id", "ID"_sd}}));
}
TEST(ExpressionObjectEvaluate, ShouldEvaluateEachField) {
intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
auto object =
expressionObjectCreateHelper(expCtx, {{"a", makeConstant(1)}, {"b", makeConstant(5)}});
+ ASSERT_VALUE_EQ(Value(Document{{"a", 1}, {"b", 5}}), object->evaluate(Document()));
+ ASSERT_VALUE_EQ(Value(Document{{"a", 1}, {"b", 5}}), object->evaluate(Document{{"a", 1}}));
ASSERT_VALUE_EQ(Value(Document{{"a", 1}, {"b", 5}}),
- object->evaluate(Document(), &(expCtx->variables)));
- ASSERT_VALUE_EQ(Value(Document{{"a", 1}, {"b", 5}}),
- 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}}));
}
TEST(ExpressionObjectEvaluate, OrderOfFieldsInOutputShouldMatchOrderInSpecification) {
@@ -3426,8 +3382,7 @@ TEST(ExpressionObjectEvaluate, OrderOfFieldsInOutputShouldMatchOrderInSpecificat
{"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)));
+ object->evaluate(Document{{"c", "C"_sd}, {"a", "A"_sd}, {"b", "B"_sd}, {"_id", "ID"_sd}}));
}
TEST(ExpressionObjectEvaluate, ShouldRemoveFieldsThatHaveMissingValues) {
@@ -3436,8 +3391,8 @@ TEST(ExpressionObjectEvaluate, ShouldRemoveFieldsThatHaveMissingValues) {
expressionObjectCreateHelper(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)));
+ ASSERT_VALUE_EQ(Value(Document{}), object->evaluate(Document()));
+ ASSERT_VALUE_EQ(Value(Document{}), object->evaluate(Document{{"a", 1}}));
}
TEST(ExpressionObjectEvaluate, ShouldEvaluateFieldsWithinNestedObject) {
@@ -3448,21 +3403,20 @@ TEST(ExpressionObjectEvaluate, ShouldEvaluateFieldsWithinNestedObject) {
expressionObjectCreateHelper(
expCtx,
{{"b", makeConstant(1)}, {"c", ExpressionFieldPath::create(expCtx, "_id")}})}});
- ASSERT_VALUE_EQ(Value(Document{{"a", Document{{"b", 1}}}}),
- object->evaluate(Document(), &(expCtx->variables)));
+ ASSERT_VALUE_EQ(Value(Document{{"a", Document{{"b", 1}}}}), object->evaluate(Document()));
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}}));
}
TEST(ExpressionObjectEvaluate, ShouldEvaluateToEmptyDocumentIfAllFieldsAreMissing) {
intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
auto object = expressionObjectCreateHelper(
expCtx, {{"a", ExpressionFieldPath::create(expCtx, "missing")}});
- ASSERT_VALUE_EQ(Value(Document{}), object->evaluate(Document(), &(expCtx->variables)));
+ ASSERT_VALUE_EQ(Value(Document{}), object->evaluate(Document()));
auto objectWithNestedObject = expressionObjectCreateHelper(expCtx, {{"nested", object}});
ASSERT_VALUE_EQ(Value(Document{{"nested", Document{}}}),
- objectWithNestedObject->evaluate(Document(), &(expCtx->variables)));
+ objectWithNestedObject->evaluate(Document()));
}
//
@@ -3565,8 +3519,7 @@ TEST(ExpressionObjectOptimizations, OptimizingAnObjectShouldOptimizeSubExpressio
auto optimized = object->optimize();
auto optimizedObject = dynamic_cast<ExpressionConstant*>(optimized.get());
ASSERT_TRUE(optimizedObject);
- ASSERT_VALUE_EQ(optimizedObject->evaluate(Document(), &(expCtx->variables)),
- Value(BSON("a" << 3)));
+ ASSERT_VALUE_EQ(optimizedObject->evaluate(Document()), Value(BSON("a" << 3)));
};
TEST(ExpressionObjectOptimizations,
@@ -3599,7 +3552,7 @@ TEST(ExpressionObjectOptimizations,
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()),
Value(BSON("willBeConstant" << 3 << "alreadyConstant"
<< "string")));
};
@@ -3618,13 +3571,11 @@ public:
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)));
+ ASSERT_BSONOBJ_EQ(BSON("" << expectedResult()),
+ toBson(expression->evaluate(fromBson(BSON("a" << 1)))));
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)))));
}
protected:
@@ -4132,7 +4083,7 @@ public:
VariablesParseState vps = expCtx->variablesParseState;
const intrusive_ptr<Expression> expr =
Expression::parseExpression(expCtx, obj, vps);
- Value result = expr->evaluate({}, &expCtx->variables);
+ Value result = expr->evaluate(Document());
if (result.getType() == Array) {
result = sortSet(result);
}
@@ -4159,7 +4110,7 @@ public:
// same
const intrusive_ptr<Expression> expr =
Expression::parseExpression(expCtx, obj, vps);
- expr->evaluate({}, &expCtx->variables);
+ expr->evaluate(Document());
}(),
AssertionException);
}
@@ -4441,8 +4392,7 @@ private:
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)));
+ ASSERT_BSONOBJ_EQ(BSON("" << expectedResult), toBson(expression->evaluate(Document())));
}
};
@@ -4568,8 +4518,7 @@ public:
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)));
+ ASSERT_BSONOBJ_EQ(BSON("" << expectedResult()), toBson(expression->evaluate(Document())));
}
protected:
@@ -4687,7 +4636,7 @@ TEST(ExpressionSubstrTest, ThrowsWithNegativeStart) {
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);
+ ASSERT_THROWS([&] { expr->evaluate(Document()); }(), AssertionException);
}
} // namespace Substr
@@ -4701,7 +4650,7 @@ TEST(ExpressionSubstrCPTest, DoesThrowWithBadContinuationByte) {
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);
+ ASSERT_THROWS([&] { expr->evaluate(Document()); }(), AssertionException);
}
TEST(ExpressionSubstrCPTest, DoesThrowWithInvalidLeadingByte) {
@@ -4711,7 +4660,7 @@ TEST(ExpressionSubstrCPTest, DoesThrowWithInvalidLeadingByte) {
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);
+ ASSERT_THROWS([&] { expr->evaluate(Document()); }(), AssertionException);
}
TEST(ExpressionSubstrCPTest, WithStandardValue) {
@@ -5161,7 +5110,7 @@ TEST(ExpressionTrimTest, TrimComparisonsShouldNotRespectCollation) {
<< "x")),
expCtx->variablesParseState);
- ASSERT_VALUE_EQ(trim->evaluate({}, &expCtx->variables), Value("XX"_sd));
+ ASSERT_VALUE_EQ(trim->evaluate(Document()), Value("XX"_sd));
}
TEST(ExpressionTrimTest, ShouldRejectInvalidUTFInCharsArgument) {
@@ -5434,7 +5383,7 @@ 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));
+ ASSERT_VALUE_EQ(reparsedTrim->evaluate(Document()), Value("abc"_sd));
// Use $ltrim, and specify the 'chars' option.
trim = Expression::parseExpression(expCtx,
@@ -5450,8 +5399,7 @@ TEST(ExpressionTrimTest, DoesSerializeCorrectly) {
// Make sure we can re-parse it and evaluate it.
reparsedTrim = Expression::parseExpression(
expCtx, trim->serialize(false).getDocument().toBson(), expCtx->variablesParseState);
- ASSERT_VALUE_EQ(reparsedTrim->evaluate(Document{{"inputField", " , 4"_sd}, {"a", " ,"_sd}},
- &expCtx->variables),
+ ASSERT_VALUE_EQ(reparsedTrim->evaluate(Document{{"inputField", " , 4"_sd}, {"a", " ,"_sd}}),
Value("4"_sd));
}
} // namespace Trim
@@ -5679,8 +5627,7 @@ public:
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)));
+ ASSERT_BSONOBJ_EQ(BSON("" << expectedResult()), toBson(expression->evaluate(Document())));
}
protected:
@@ -5737,8 +5684,7 @@ public:
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)));
+ ASSERT_BSONOBJ_EQ(BSON("" << expectedResult()), toBson(expression->evaluate(Document())));
}
protected:
@@ -5800,7 +5746,7 @@ public:
VariablesParseState vps = expCtx->variablesParseState;
const intrusive_ptr<Expression> expr =
Expression::parseExpression(expCtx, obj, vps);
- const Value result = expr->evaluate({}, &expCtx->variables);
+ const Value result = expr->evaluate(Document());
if (ValueComparator().evaluate(result != expected)) {
string errMsg = str::stream()
<< "for expression " << field.first.toString() << " with argument "
@@ -5824,7 +5770,7 @@ public:
// same
const intrusive_ptr<Expression> expr =
Expression::parseExpression(expCtx, obj, vps);
- expr->evaluate({}, &expCtx->variables);
+ expr->evaluate(Document());
}(),
AssertionException);
}
@@ -6068,7 +6014,7 @@ TEST(ExpressionMetaTest, ExpressionMetaSearchScore) {
MutableDocument doc;
doc.setSearchScore(1.234);
- Value val = expressionMeta->evaluate(doc.freeze(), &expCtx->variables);
+ Value val = expressionMeta->evaluate(doc.freeze());
ASSERT_EQ(val.getDouble(), 1.234);
}
@@ -6082,7 +6028,7 @@ TEST(ExpressionMetaTest, ExpressionMetaSearchHighlights) {
Document highlights = DOC("this part" << 1 << "is opaque to the server" << 1);
doc.setSearchHighlights(Value(highlights));
- Value val = expressionMeta->evaluate(doc.freeze(), &expCtx->variables);
+ Value val = expressionMeta->evaluate(doc.freeze());
ASSERT_DOCUMENT_EQ(val.getDocument(), highlights);
}
} // namespace expression_meta_test
@@ -6092,9 +6038,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) {
+ intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
auto expression = ExpressionRegexSubClass::parse(
expCtx, input.firstElement(), expCtx->variablesParseState);
return expression->optimize();
@@ -6103,31 +6048,31 @@ public:
static void testAllExpressions(const BSONObj& input,
bool optimized,
const std::vector<Value>& expectedFindAllOutput) {
-
- intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
{
// For $regexFindAll.
- auto expression = generateOptimizedExpression<ExpressionRegexFindAll>(input, expCtx);
+ auto expression = generateOptimizedExpression<ExpressionRegexFindAll>(input);
auto regexFindAllExpr = dynamic_cast<ExpressionRegexFindAll*>(expression.get());
ASSERT_EQ(regexFindAllExpr->hasConstantRegex(), optimized);
- Value output = expression->evaluate({}, &expCtx->variables);
+ Value output = regexFindAllExpr->evaluate(Document());
ASSERT_VALUE_EQ(output, Value(expectedFindAllOutput));
}
+
{
// For $regexFind.
- auto expression = generateOptimizedExpression<ExpressionRegexFind>(input, expCtx);
+ auto expression = generateOptimizedExpression<ExpressionRegexFind>(input);
auto regexFindExpr = dynamic_cast<ExpressionRegexFind*>(expression.get());
ASSERT_EQ(regexFindExpr->hasConstantRegex(), optimized);
- Value output = expression->evaluate({}, &expCtx->variables);
+ Value output = regexFindExpr->evaluate(Document());
ASSERT_VALUE_EQ(
output, expectedFindAllOutput.empty() ? Value(BSONNULL) : expectedFindAllOutput[0]);
}
+
{
// For $regexMatch.
- auto expression = generateOptimizedExpression<ExpressionRegexMatch>(input, expCtx);
+ auto expression = generateOptimizedExpression<ExpressionRegexMatch>(input);
auto regexMatchExpr = dynamic_cast<ExpressionRegexMatch*>(expression.get());
ASSERT_EQ(regexMatchExpr->hasConstantRegex(), optimized);
- Value output = expression->evaluate({}, &expCtx->variables);
+ Value output = regexMatchExpr->evaluate(Document());
ASSERT_VALUE_EQ(output, expectedFindAllOutput.empty() ? Value(false) : Value(true));
}
}
@@ -6435,14 +6380,14 @@ TEST(NowAndClusterTime, BasicTest) {
// $$NOW is the Date type.
{
auto expression = ExpressionFieldPath::parse(expCtx, "$$NOW", expCtx->variablesParseState);
- Value result = expression->evaluate(Document(), &(expCtx->variables));
+ Value result = expression->evaluate(Document());
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));
+ Value result = expression->evaluate(Document());
ASSERT_EQ(result.getType(), bsonTimestamp);
}
@@ -6450,7 +6395,7 @@ TEST(NowAndClusterTime, BasicTest) {
{
auto expression = Expression::parseExpression(
expCtx, fromjson("{$eq: [\"$$NOW\", \"$$NOW\"]}"), expCtx->variablesParseState);
- Value result = expression->evaluate(Document(), &(expCtx->variables));
+ Value result = expression->evaluate(Document());
ASSERT_VALUE_EQ(result, Value{true});
}
@@ -6460,7 +6405,7 @@ TEST(NowAndClusterTime, BasicTest) {
Expression::parseExpression(expCtx,
fromjson("{$eq: [\"$$CLUSTER_TIME\", \"$$CLUSTER_TIME\"]}"),
expCtx->variablesParseState);
- Value result = expression->evaluate(Document(), &(expCtx->variables));
+ Value result = expression->evaluate(Document());
ASSERT_VALUE_EQ(result, Value{true});
}
diff --git a/src/mongo/db/pipeline/expression_trigonometric_test.cpp b/src/mongo/db/pipeline/expression_trigonometric_test.cpp
index 49ea60e1f9b..35756404dd4 100644
--- a/src/mongo/db/pipeline/expression_trigonometric_test.cpp
+++ b/src/mongo/db/pipeline/expression_trigonometric_test.cpp
@@ -58,7 +58,7 @@ static void assertEvaluates(const std::string& expressionName, Value input, Valu
auto obj = BSON(expressionName << BSON_ARRAY(input));
auto vps = expCtx->variablesParseState;
auto expression = Expression::parseExpression(expCtx, obj, vps);
- Value result = expression->evaluate({}, &expCtx->variables);
+ Value result = expression->evaluate(Document());
ASSERT_EQUALS(result.getType(), output.getType());
assertApproxEq(result, output);
}
@@ -73,7 +73,7 @@ static void assertEvaluates(const std::string& expressionName,
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);
+ Value result = expression->evaluate(Document());
ASSERT_EQUALS(result.getType(), output.getType());
assertApproxEq(result, output);
}
diff --git a/src/mongo/db/pipeline/granularity_rounder_powers_of_two.cpp b/src/mongo/db/pipeline/granularity_rounder_powers_of_two.cpp
index aa622f9b014..3a033cc034f 100644
--- a/src/mongo/db/pipeline/granularity_rounder_powers_of_two.cpp
+++ b/src/mongo/db/pipeline/granularity_rounder_powers_of_two.cpp
@@ -81,8 +81,7 @@ Value GranularityRounderPowersOfTwo::roundUp(Value value) {
exp = Value(63 - countLeadingZeros64(number) + 1);
}
- return ExpressionPow::create(getExpCtx(), Value(2), exp)
- ->evaluate(Document(), &getExpCtx()->variables);
+ return ExpressionPow::create(getExpCtx(), Value(2), exp)->evaluate(Document());
}
Value GranularityRounderPowersOfTwo::roundDown(Value value) {
@@ -114,8 +113,7 @@ Value GranularityRounderPowersOfTwo::roundDown(Value value) {
}
}
- return ExpressionPow::create(getExpCtx(), Value(2), exp)
- ->evaluate(Document(), &getExpCtx()->variables);
+ return ExpressionPow::create(getExpCtx(), Value(2), exp)->evaluate(Document());
}
string GranularityRounderPowersOfTwo::getName() {
diff --git a/src/mongo/db/pipeline/parsed_aggregation_projection_node.cpp b/src/mongo/db/pipeline/parsed_aggregation_projection_node.cpp
index 65637d9144b..18b6e243f09 100644
--- a/src/mongo/db/pipeline/parsed_aggregation_projection_node.cpp
+++ b/src/mongo/db/pipeline/parsed_aggregation_projection_node.cpp
@@ -172,10 +172,7 @@ void ProjectionNode::applyExpressions(const Document& root, MutableDocument* out
} else {
auto expressionIt = _expressions.find(field);
invariant(expressionIt != _expressions.end());
- outputDoc->setField(
- field,
- expressionIt->second->evaluate(
- root, &expressionIt->second->getExpressionContext()->variables));
+ outputDoc->setField(field, expressionIt->second->evaluate(root));
}
}
}