summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorKatherine Wu <katherine.wu@mongodb.com>2020-02-07 17:20:59 +0000
committerevergreen <evergreen@mongodb.com>2020-02-07 17:20:59 +0000
commite4b4eabe774fc5ab54e52761ca3293ca2a73340e (patch)
tree896e9ab05afe6deca4f7446991a680576b0d5103 /src/mongo
parent12782dd756988d11b296cb5298ab74ea6ce8a444 (diff)
downloadmongo-e4b4eabe774fc5ab54e52761ca3293ca2a73340e.tar.gz
Revert "SERVER-45453 Change name and usage of '$_internalJs' to '$function'"
This reverts commit 656313f6c949a5c49c42d080548067d5a8c37047.
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/db/commands/mr_common.cpp25
-rw-r--r--src/mongo/db/pipeline/SConscript3
-rw-r--r--src/mongo/db/pipeline/expression_function.cpp112
-rw-r--r--src/mongo/db/pipeline/expression_function.h79
-rw-r--r--src/mongo/db/pipeline/expression_javascript.cpp (renamed from src/mongo/db/pipeline/expression_js_emit.cpp)65
-rw-r--r--src/mongo/db/pipeline/expression_javascript.h (renamed from src/mongo/db/pipeline/expression_js_emit.h)41
-rw-r--r--src/mongo/db/pipeline/expression_javascript_test.cpp88
-rw-r--r--src/mongo/db/pipeline/expression_visitor.h4
8 files changed, 150 insertions, 267 deletions
diff --git a/src/mongo/db/commands/mr_common.cpp b/src/mongo/db/commands/mr_common.cpp
index 098c702f408..fcdf998e125 100644
--- a/src/mongo/db/commands/mr_common.cpp
+++ b/src/mongo/db/commands/mr_common.cpp
@@ -52,8 +52,7 @@
#include "mongo/db/pipeline/document_source_single_document_transformation.h"
#include "mongo/db/pipeline/document_source_sort.h"
#include "mongo/db/pipeline/document_source_unwind.h"
-#include "mongo/db/pipeline/expression_function.h"
-#include "mongo/db/pipeline/expression_js_emit.h"
+#include "mongo/db/pipeline/expression_javascript.h"
#include "mongo/db/query/util/make_data_structure.h"
#include "mongo/util/intrusive_counter.h"
#include "mongo/util/log.h"
@@ -140,15 +139,14 @@ auto translateReduce(boost::intrusive_ptr<ExpressionContext> expCtx, std::string
auto translateFinalize(boost::intrusive_ptr<ExpressionContext> expCtx,
MapReduceJavascriptCodeOrNull codeObj) {
return codeObj.getCode().map([&](auto&& code) {
- auto jsExpression = ExpressionFunction::create(
+ auto jsExpression = ExpressionInternalJs::create(
expCtx,
ExpressionArray::create(
expCtx,
make_vector<boost::intrusive_ptr<Expression>>(
ExpressionFieldPath::parse(expCtx, "$_id", expCtx->variablesParseState),
ExpressionFieldPath::parse(expCtx, "$value", expCtx->variablesParseState))),
- code,
- ExpressionFunction::kJavaScript);
+ code);
auto node = std::make_unique<projection_executor::InclusionNode>(
ProjectionPolicies{ProjectionPolicies::DefaultIdPolicy::kIncludeId});
node->addProjectionForPath(FieldPath{"_id"s});
@@ -189,24 +187,23 @@ auto translateOutReduce(boost::intrusive_ptr<ExpressionContext> expCtx,
// Because of communication for sharding, $merge must hold on to a serializable BSON object
// at the moment so we reparse here. Note that the reduce function signature expects 2
// arguments, the first being the key and the second being the array of values to reduce.
- auto reduceObj =
- BSON("args" << BSON_ARRAY("$_id" << BSON_ARRAY("$value"
- << "$$new.value"))
- << "body" << reduceCode << "lang" << ExpressionFunction::kJavaScript);
+ auto reduceObj = BSON("args" << BSON_ARRAY("$_id" << BSON_ARRAY("$value"
+ << "$$new.value"))
+ << "eval" << reduceCode);
- auto reduceSpec = BSON(DocumentSourceProject::kStageName << BSON(
- "value" << BSON(ExpressionFunction::kExpressionName << reduceObj)));
+ auto reduceSpec =
+ BSON(DocumentSourceProject::kStageName
+ << BSON("value" << BSON(ExpressionInternalJs::kExpressionName << reduceObj)));
auto pipelineSpec = boost::make_optional(std::vector<BSONObj>{reduceSpec});
// Build finalize $project stage if given.
if (finalizeCode && finalizeCode->hasCode()) {
auto finalizeObj = BSON("args" << BSON_ARRAY("$_id"
<< "$value")
- << "body" << finalizeCode->getCode().get() << "lang"
- << ExpressionFunction::kJavaScript);
+ << "eval" << finalizeCode->getCode().get());
auto finalizeSpec =
BSON(DocumentSourceProject::kStageName
- << BSON("value" << BSON(ExpressionFunction::kExpressionName << finalizeObj)));
+ << BSON("value" << BSON(ExpressionInternalJs::kExpressionName << finalizeObj)));
pipelineSpec->emplace_back(std::move(finalizeSpec));
}
diff --git a/src/mongo/db/pipeline/SConscript b/src/mongo/db/pipeline/SConscript
index 45dceed8cf2..fa27da05155 100644
--- a/src/mongo/db/pipeline/SConscript
+++ b/src/mongo/db/pipeline/SConscript
@@ -103,8 +103,7 @@ env.Library(
env.Library(
target='expression_javascript',
source=[
- 'expression_function.cpp',
- 'expression_js_emit.cpp'
+ 'expression_javascript.cpp'
],
LIBDEPS=[
'$BUILD_DIR/mongo/scripting/scripting_common',
diff --git a/src/mongo/db/pipeline/expression_function.cpp b/src/mongo/db/pipeline/expression_function.cpp
deleted file mode 100644
index 399a8847e03..00000000000
--- a/src/mongo/db/pipeline/expression_function.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/**
- * Copyright (C) 2019-present MongoDB, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the Server Side Public License, version 1,
- * as published by MongoDB, Inc.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * Server Side Public License for more details.
- *
- * You should have received a copy of the Server Side Public License
- * along with this program. If not, see
- * <http://www.mongodb.com/licensing/server-side-public-license>.
- *
- * As a special exception, the copyright holders give permission to link the
- * code of portions of this program with the OpenSSL library under certain
- * conditions as described in each individual source file and distribute
- * linked combinations including the program with the OpenSSL library. You
- * must comply with the Server Side Public License in all respects for
- * all of the code used other than as permitted herein. If you modify file(s)
- * with this exception, you may extend this exception to your version of the
- * file(s), but you are not obligated to do so. If you do not wish to do so,
- * delete this exception statement from your version. If you delete this
- * exception statement from all source files in the program, then also delete
- * it in the license file.
- */
-
-#include "mongo/db/pipeline/expression_function.h"
-
-namespace mongo {
-
-REGISTER_EXPRESSION_WITH_MIN_VERSION(
- function,
- ExpressionFunction::parse,
- ServerGlobalParams::FeatureCompatibility::Version::kFullyUpgradedTo44);
-
-ExpressionFunction::ExpressionFunction(const boost::intrusive_ptr<ExpressionContext>& expCtx,
- boost::intrusive_ptr<Expression> passedArgs,
- std::string funcSource,
- std::string lang)
- : Expression(expCtx, {std::move(passedArgs)}),
- _passedArgs(_children[0]),
- _funcSource(std::move(funcSource)),
- _lang(std::move(lang)) {}
-
-Value ExpressionFunction::serialize(bool explain) const {
- return Value(Document{{kExpressionName,
- Document{{"body", _funcSource},
- {"args", _passedArgs->serialize(explain)},
- {"lang", _lang}}}});
-}
-
-void ExpressionFunction::_doAddDependencies(mongo::DepsTracker* deps) const {
- _children[0]->addDependencies(deps);
-}
-
-boost::intrusive_ptr<Expression> ExpressionFunction::parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps) {
-
- uassert(31260,
- str::stream() << kExpressionName
- << " requires an object as an argument, found: " << expr.type(),
- expr.type() == BSONType::Object);
-
- BSONElement bodyField = expr["body"];
-
- uassert(31261, "The body function must be specified.", bodyField);
-
- boost::intrusive_ptr<Expression> bodyExpr = Expression::parseOperand(expCtx, bodyField, vps);
-
- auto bodyConst = dynamic_cast<ExpressionConstant*>(bodyExpr.get());
- uassert(31432, "The body function must be a constant expression", bodyConst);
-
- auto bodyValue = bodyConst->getValue();
- uassert(31262,
- "The body function must evaluate to type string or code",
- bodyValue.getType() == BSONType::String || bodyValue.getType() == BSONType::Code);
-
- BSONElement argsField = expr["args"];
- uassert(31263, "The args field must be specified.", argsField);
- boost::intrusive_ptr<Expression> argsExpr = parseOperand(expCtx, argsField, vps);
-
- BSONElement langField = expr["lang"];
- uassert(31418, "The lang field must be specified.", langField);
- uassert(31419,
- "Currently the only supported language specifier is 'js'.",
- langField.type() == BSONType::String && langField.str() == kJavaScript);
-
- return new ExpressionFunction(expCtx, argsExpr, bodyValue.coerceToString(), langField.str());
-}
-
-Value ExpressionFunction::evaluate(const Document& root, Variables* variables) const {
- auto jsExec = getExpressionContext()->getJsExecWithScope();
-
- ScriptingFunction func = jsExec->getScope()->createFunction(_funcSource.c_str());
- uassert(31265, "The body function did not evaluate", func);
-
- auto argValue = _passedArgs->evaluate(root, variables);
- uassert(31266, "The args field must be of type array", argValue.getType() == BSONType::Array);
-
- int argNum = 0;
- BSONObjBuilder bob;
- for (const auto& arg : argValue.getArray()) {
- arg.addToBsonObj(&bob, "arg" + std::to_string(argNum++));
- }
- return jsExec->callFunction(func, bob.done(), {});
-};
-} // namespace mongo \ No newline at end of file
diff --git a/src/mongo/db/pipeline/expression_function.h b/src/mongo/db/pipeline/expression_function.h
deleted file mode 100644
index 3d8d5e2df7b..00000000000
--- a/src/mongo/db/pipeline/expression_function.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * Copyright (C) 2019-present MongoDB, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the Server Side Public License, version 1,
- * as published by MongoDB, Inc.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * Server Side Public License for more details.
- *
- * You should have received a copy of the Server Side Public License
- * along with this program. If not, see
- * <http://www.mongodb.com/licensing/server-side-public-license>.
- *
- * As a special exception, the copyright holders give permission to link the
- * code of portions of this program with the OpenSSL library under certain
- * conditions as described in each individual source file and distribute
- * linked combinations including the program with the OpenSSL library. You
- * must comply with the Server Side Public License in all respects for
- * all of the code used other than as permitted herein. If you modify file(s)
- * with this exception, you may extend this exception to your version of the
- * file(s), but you are not obligated to do so. If you do not wish to do so,
- * delete this exception statement from your version. If you delete this
- * exception statement from all source files in the program, then also delete
- * it in the license file.
- */
-
-#pragma once
-
-#include "mongo/db/pipeline/expression.h"
-#include "mongo/db/pipeline/javascript_execution.h"
-
-namespace mongo {
-/**
- * This expression takes a function, an array of arguments to pass to it, and the language
- * specifier (currently limited to JavaScript). It returns the return value of the function with
- * the given arguments.
- */
-class ExpressionFunction final : public Expression {
-public:
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps);
-
- static boost::intrusive_ptr<ExpressionFunction> create(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- boost::intrusive_ptr<Expression> passedArgs,
- std::string funcSourceString,
- std::string lang) {
- return new ExpressionFunction{
- expCtx, passedArgs, std::move(funcSourceString), std::move(lang)};
- }
-
- Value evaluate(const Document& root, Variables* variables) const final;
-
- Value serialize(bool explain) const final;
-
- void acceptVisitor(ExpressionVisitor* visitor) final {
- return visitor->visit(this);
- }
-
- static constexpr auto kExpressionName = "$function"_sd;
- static constexpr auto kJavaScript = "js";
-
-private:
- ExpressionFunction(const boost::intrusive_ptr<ExpressionContext>& expCtx,
- boost::intrusive_ptr<Expression> passedArgs,
- std::string funcSourceString,
- std::string lang);
- void _doAddDependencies(DepsTracker* deps) const final override;
-
- const boost::intrusive_ptr<Expression>& _passedArgs;
- std::string _funcSource;
- std::string _lang;
-};
-} // namespace mongo \ No newline at end of file
diff --git a/src/mongo/db/pipeline/expression_js_emit.cpp b/src/mongo/db/pipeline/expression_javascript.cpp
index 4072ecee993..4e3f489e7f2 100644
--- a/src/mongo/db/pipeline/expression_js_emit.cpp
+++ b/src/mongo/db/pipeline/expression_javascript.cpp
@@ -30,13 +30,15 @@
#include "mongo/platform/basic.h"
#include "mongo/db/auth/authorization_session.h"
-#include "mongo/db/pipeline/expression_js_emit.h"
+#include "mongo/db/pipeline/expression_javascript.h"
#include "mongo/db/pipeline/make_js_function.h"
#include "mongo/db/query/query_knobs_gen.h"
namespace mongo {
REGISTER_EXPRESSION(_internalJsEmit, ExpressionInternalJsEmit::parse);
+
+REGISTER_EXPRESSION(_internalJs, ExpressionInternalJs::parse);
namespace {
/**
@@ -127,4 +129,65 @@ Value ExpressionInternalJsEmit::evaluate(const Document& root, Variables* variab
_emitState.reset();
return returnValue;
}
+
+ExpressionInternalJs::ExpressionInternalJs(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ boost::intrusive_ptr<Expression> passedArgs,
+ std::string funcSource)
+ : Expression(expCtx, {std::move(passedArgs)}),
+ _passedArgs(_children[0]),
+ _funcSource(std::move(funcSource)) {}
+
+Value ExpressionInternalJs::serialize(bool explain) const {
+ return Value(
+ Document{{kExpressionName,
+ Document{{"eval", _funcSource}, {"args", _passedArgs->serialize(explain)}}}});
+}
+
+void ExpressionInternalJs::_doAddDependencies(mongo::DepsTracker* deps) const {
+ _children[0]->addDependencies(deps);
+}
+
+boost::intrusive_ptr<Expression> ExpressionInternalJs::parse(
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps) {
+
+ uassert(31260,
+ str::stream() << kExpressionName
+ << " requires an object as an argument, found: " << expr.type(),
+ expr.type() == BSONType::Object);
+
+ BSONElement evalField = expr["eval"];
+
+ uassert(31261, "The eval function must be specified.", evalField);
+ uassert(31262,
+ "The eval function must be of type string or code",
+ evalField.type() == BSONType::String || evalField.type() == BSONType::Code);
+
+ BSONElement argsField = expr["args"];
+ uassert(31263, "The args field must be specified.", argsField);
+ boost::intrusive_ptr<Expression> argsExpr = parseOperand(expCtx, argsField, vps);
+
+ return new ExpressionInternalJs(expCtx, argsExpr, evalField._asCode());
+}
+
+Value ExpressionInternalJs::evaluate(const Document& root, Variables* variables) const {
+ auto& expCtx = getExpressionContext();
+
+ auto jsExec = expCtx->getJsExecWithScope();
+
+ ScriptingFunction func = jsExec->getScope()->createFunction(_funcSource.c_str());
+ uassert(31265, "The eval function did not evaluate", func);
+
+ auto argExpressions = _passedArgs->evaluate(root, variables);
+ uassert(
+ 31266, "The args field must be of type array", argExpressions.getType() == BSONType::Array);
+
+ int argNum = 0;
+ BSONObjBuilder bob;
+ for (const auto& arg : argExpressions.getArray()) {
+ arg.addToBsonObj(&bob, "arg" + std::to_string(argNum++));
+ }
+ return jsExec->callFunction(func, bob.done(), {});
+}
} // namespace mongo
diff --git a/src/mongo/db/pipeline/expression_js_emit.h b/src/mongo/db/pipeline/expression_javascript.h
index b81c73baa75..4368b4985af 100644
--- a/src/mongo/db/pipeline/expression_js_emit.h
+++ b/src/mongo/db/pipeline/expression_javascript.h
@@ -32,6 +32,10 @@
#include "mongo/db/pipeline/expression.h"
#include "mongo/db/pipeline/javascript_execution.h"
+/**
+ * This file contains all expressions which make use of JavaScript execution and depend on the JS
+ * engine to operate.
+ */
namespace mongo {
/**
@@ -95,4 +99,41 @@ private:
std::string _funcSource;
};
+/**
+ * This expression takes a Javascript function and an array of arguments to pass to it. It returns
+ * the return value of the Javascript function with the given arguments.
+ */
+class ExpressionInternalJs final : public Expression {
+public:
+ static boost::intrusive_ptr<Expression> parse(
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps);
+
+ static boost::intrusive_ptr<ExpressionInternalJs> create(
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ boost::intrusive_ptr<Expression> passedArgs,
+ std::string funcSourceString) {
+ return new ExpressionInternalJs{expCtx, passedArgs, std::move(funcSourceString)};
+ }
+
+ Value evaluate(const Document& root, Variables* variables) const final;
+
+ Value serialize(bool explain) const final;
+
+ void acceptVisitor(ExpressionVisitor* visitor) final {
+ return visitor->visit(this);
+ }
+
+ static constexpr auto kExpressionName = "$_internalJs"_sd;
+
+private:
+ ExpressionInternalJs(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ boost::intrusive_ptr<Expression> passedArgs,
+ std::string funcSourceString);
+ void _doAddDependencies(DepsTracker* deps) const final override;
+
+ const boost::intrusive_ptr<Expression>& _passedArgs;
+ std::string _funcSource;
+};
} // namespace mongo
diff --git a/src/mongo/db/pipeline/expression_javascript_test.cpp b/src/mongo/db/pipeline/expression_javascript_test.cpp
index f11d4c0e7ef..43539f7bf75 100644
--- a/src/mongo/db/pipeline/expression_javascript_test.cpp
+++ b/src/mongo/db/pipeline/expression_javascript_test.cpp
@@ -27,13 +27,12 @@
* it in the license file.
*/
-#include "mongo/db/pipeline/expression_js_emit.h"
+#include "mongo/db/pipeline/expression_javascript.h"
#include "mongo/db/commands/test_commands_enabled.h"
#include "mongo/db/exec/document_value/document.h"
#include "mongo/db/exec/document_value/document_value_test_util.h"
#include "mongo/db/pipeline/expression_context_for_test.h"
-#include "mongo/db/pipeline/expression_function.h"
#include "mongo/db/pipeline/process_interface/non_shardsvr_process_interface.h"
#include "mongo/db/query/query_knobs_gen.h"
#include "mongo/db/service_context_d_test_fixture.h"
@@ -83,105 +82,80 @@ void MapReduceFixture::tearDown() {
ServiceContextMongoDTest::tearDown();
}
-TEST_F(MapReduceFixture, ExpressionFunctionProducesExpectedResult) {
- auto bsonExpr = BSON("expr" << BSON("body"
+TEST_F(MapReduceFixture, ExpressionInternalJsProducesExpectedResult) {
+ auto bsonExpr = BSON("expr" << BSON("eval"
<< "function(first, second) {return first + second;};"
- << "args" << BSON_ARRAY("$a" << 4) << "lang"
- << ExpressionFunction::kJavaScript));
+ << "args" << BSON_ARRAY("$a" << 4)));
- auto expr = ExpressionFunction::parse(getExpCtx(), bsonExpr.firstElement(), getVPS());
+ auto expr = ExpressionInternalJs::parse(getExpCtx(), bsonExpr.firstElement(), getVPS());
Value result = expr->evaluate(Document{BSON("a" << 2)}, getVariables());
ASSERT_VALUE_EQ(result, Value(6));
bsonExpr =
- BSON("expr" << BSON("body"
+ BSON("expr" << BSON("eval"
<< "function(first, second, third) {return first + second + third;};"
- << "args" << BSON_ARRAY(1 << 2 << 4) << "lang"
- << ExpressionFunction::kJavaScript));
- expr = ExpressionFunction::parse(getExpCtx(), bsonExpr.firstElement(), getVPS());
+ << "args" << BSON_ARRAY(1 << 2 << 4)));
+ expr = ExpressionInternalJs::parse(getExpCtx(), bsonExpr.firstElement(), getVPS());
result = expr->evaluate(Document{BSONObj{}}, getVariables());
ASSERT_VALUE_EQ(result, Value(7));
- bsonExpr = BSON("expr" << BSON("body"
+ bsonExpr = BSON("expr" << BSON("eval"
<< "function(first) {return first;};"
- << "args" << BSON_ARRAY(1) << "lang"
- << ExpressionFunction::kJavaScript));
- expr = ExpressionFunction::parse(getExpCtx(), bsonExpr.firstElement(), getVPS());
+ << "args" << BSON_ARRAY(1)));
+ expr = ExpressionInternalJs::parse(getExpCtx(), bsonExpr.firstElement(), getVPS());
result = expr->evaluate(Document{BSONObj{}}, getVariables());
ASSERT_VALUE_EQ(result, Value(1));
}
-TEST_F(MapReduceFixture, ExpressionFunctionFailsIfArgsDoesNotEvaluateToArray) {
- auto bsonExpr = BSON("expr" << BSON("body"
+TEST_F(MapReduceFixture, ExpressionInternalJsFailsIfArgsDoesNotEvaluateToArray) {
+ auto bsonExpr = BSON("expr" << BSON("eval"
<< "function(first, second) {return first + second;};"
- << "args" << BSON("a" << 1) << "lang"
- << ExpressionFunction::kJavaScript));
- auto expr = ExpressionFunction::parse(getExpCtx(), bsonExpr.firstElement(), getVPS());
+ << "args" << BSON("a" << 1)));
+ auto expr = ExpressionInternalJs::parse(getExpCtx(), bsonExpr.firstElement(), getVPS());
ASSERT_THROWS_CODE(expr->evaluate({}, getVariables()), AssertionException, 31266);
}
-TEST_F(MapReduceFixture, ExpressionFunctionFailsWithInvalidFunction) {
- auto bsonExpr = BSON("expr" << BSON("body"
+TEST_F(MapReduceFixture, ExpressionInternalJsFailsWithInvalidFunction) {
+ auto bsonExpr = BSON("expr" << BSON("eval"
<< "INVALID"
- << "args" << BSON_ARRAY(1 << 2) << "lang"
- << ExpressionFunction::kJavaScript));
- auto expr = ExpressionFunction::parse(getExpCtx(), bsonExpr.firstElement(), getVPS());
+ << "args" << BSON_ARRAY(1 << 2)));
+ auto expr = ExpressionInternalJs::parse(getExpCtx(), bsonExpr.firstElement(), getVPS());
ASSERT_THROWS_CODE(
expr->evaluate({}, getVariables()), AssertionException, ErrorCodes::JSInterpreterFailure);
}
-TEST_F(MapReduceFixture, ExpressionFunctionFailsIfArgumentIsNotObject) {
+TEST_F(MapReduceFixture, ExpressionInternalJsFailsIfArgumentIsNotObject) {
auto bsonExpr = BSON("expr" << 1);
- ASSERT_THROWS_CODE(ExpressionFunction::parse(getExpCtx(), bsonExpr.firstElement(), getVPS()),
+ ASSERT_THROWS_CODE(ExpressionInternalJs::parse(getExpCtx(), bsonExpr.firstElement(), getVPS()),
AssertionException,
31260);
}
-TEST_F(MapReduceFixture, ExpressionFunctionFailsIfBodyNotSpecified) {
- auto bsonExpr = BSON(
- "expr" << BSON("args" << BSON_ARRAY(1 << 2) << "lang" << ExpressionFunction::kJavaScript));
- ASSERT_THROWS_CODE(ExpressionFunction::parse(getExpCtx(), bsonExpr.firstElement(), getVPS()),
+TEST_F(MapReduceFixture, ExpressionInternalJsFailsIfEvalNotSpecified) {
+ auto bsonExpr = BSON("expr" << BSON("args" << BSON_ARRAY(1 << 2)));
+ ASSERT_THROWS_CODE(ExpressionInternalJs::parse(getExpCtx(), bsonExpr.firstElement(), getVPS()),
AssertionException,
31261);
}
-TEST_F(MapReduceFixture, ExpressionFunctionFailsIfBodyIsNotConstantExpression) {
- auto bsonExpr = BSON("expr" << BSON("body" << BSONObj() << "args" << BSON_ARRAY(1 << 2)
- << "lang" << ExpressionFunction::kJavaScript));
- ASSERT_THROWS_CODE(ExpressionFunction::parse(getExpCtx(), bsonExpr.firstElement(), getVPS()),
- AssertionException,
- 31432);
-}
-
-TEST_F(MapReduceFixture, ExpressionFunctionFailsIfBodyIsNotCorrectType) {
- auto bsonExpr = BSON("expr" << BSON("body" << 1 << "args" << BSON_ARRAY(1 << 2) << "lang"
- << ExpressionFunction::kJavaScript));
- ASSERT_THROWS_CODE(ExpressionFunction::parse(getExpCtx(), bsonExpr.firstElement(), getVPS()),
+TEST_F(MapReduceFixture, ExpressionInternalJsFailsIfEvalIsNotCorrectType) {
+ auto bsonExpr = BSON("expr" << BSON("eval" << BSONObj() << "args" << BSON_ARRAY(1 << 2)));
+ ASSERT_THROWS_CODE(ExpressionInternalJs::parse(getExpCtx(), bsonExpr.firstElement(), getVPS()),
AssertionException,
31262);
}
-TEST_F(MapReduceFixture, ExpressionFunctionFailsIfArgsIsNotSpecified) {
- auto bsonExpr = BSON("expr" << BSON("body"
- << "function(first) {return first;};"
- << "lang" << ExpressionFunction::kJavaScript));
- ASSERT_THROWS_CODE(ExpressionFunction::parse(getExpCtx(), bsonExpr.firstElement(), getVPS()),
+TEST_F(MapReduceFixture, ExpressionInternalJsFailsIfArgsIsNotSpecified) {
+ auto bsonExpr = BSON("expr" << BSON("eval"
+ << "function(first) {return first;};"));
+ ASSERT_THROWS_CODE(ExpressionInternalJs::parse(getExpCtx(), bsonExpr.firstElement(), getVPS()),
AssertionException,
31263);
}
-TEST_F(MapReduceFixture, ExpressionFunctionFailsIfLangIsNotSpecified) {
- auto bsonExpr = BSON("expr" << BSON("body"
- << "function(first) {return first;};"
- << "args" << BSON_ARRAY(1 << 2)));
- ASSERT_THROWS_CODE(ExpressionFunction::parse(getExpCtx(), bsonExpr.firstElement(), getVPS()),
- AssertionException,
- 31418);
-}
-
TEST_F(MapReduceFixture, ExpressionInternalJsEmitProducesExpectedResult) {
auto bsonExpr = BSON("expr" << BSON("this"
<< "$$ROOT"
diff --git a/src/mongo/db/pipeline/expression_visitor.h b/src/mongo/db/pipeline/expression_visitor.h
index 326c8e2e6ce..04100467daf 100644
--- a/src/mongo/db/pipeline/expression_visitor.h
+++ b/src/mongo/db/pipeline/expression_visitor.h
@@ -147,7 +147,7 @@ class ExpressionInternalFindSlice;
class ExpressionInternalFindPositional;
class ExpressionInternalFindElemMatch;
class ExpressionInternalJsEmit;
-class ExpressionFunction;
+class ExpressionInternalJs;
class ExpressionDegreesToRadians;
class ExpressionRadiansToDegrees;
@@ -293,7 +293,7 @@ public:
virtual void visit(ExpressionFromAccumulator<AccumulatorMergeObjects>*) = 0;
virtual void visit(ExpressionTests::Testable*) = 0;
virtual void visit(ExpressionInternalJsEmit*) = 0;
- virtual void visit(ExpressionFunction*) = 0;
+ virtual void visit(ExpressionInternalJs*) = 0;
virtual void visit(ExpressionInternalFindSlice*) = 0;
virtual void visit(ExpressionInternalFindPositional*) = 0;
virtual void visit(ExpressionInternalFindElemMatch*) = 0;