summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCharlie Swanson <charlie.swanson@mongodb.com>2019-05-21 17:22:25 -0400
committerCharlie Swanson <charlie.swanson@mongodb.com>2019-05-22 16:29:09 -0400
commit5594eeb9c42f5a28ebb20c8fcce87a2a1a01f6a5 (patch)
tree8453d01043b1bc67161a4ee684c69e637e989645 /src
parent76cf536d476b50994c75dd16ec5c7caca23759a5 (diff)
downloadmongo-5594eeb9c42f5a28ebb20c8fcce87a2a1a01f6a5.tar.gz
SERVER-41257 Disallow persisting new 4.2 expressions in FCV 4.0
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/pipeline/expression.cpp44
-rw-r--r--src/mongo/db/pipeline/expression.h4
-rw-r--r--src/mongo/db/pipeline/expression_context.cpp1
3 files changed, 45 insertions, 4 deletions
diff --git a/src/mongo/db/pipeline/expression.cpp b/src/mongo/db/pipeline/expression.cpp
index 0e8984a81fa..d6068398342 100644
--- a/src/mongo/db/pipeline/expression.cpp
+++ b/src/mongo/db/pipeline/expression.cpp
@@ -4924,7 +4924,10 @@ Value ExpressionRound::evaluate(const Document& root) const {
root, _children, getOpName(), Decimal128::kRoundTiesToEven, &std::round);
}
-REGISTER_EXPRESSION(round, ExpressionRound::parse);
+REGISTER_EXPRESSION_WITH_MIN_VERSION(
+ round,
+ ExpressionRound::parse,
+ ServerGlobalParams::FeatureCompatibility::Version::kFullyUpgradedTo42);
const char* ExpressionRound::getOpName() const {
return "$round";
}
@@ -4934,6 +4937,30 @@ Value ExpressionTrunc::evaluate(const Document& root) const {
root, _children, getOpName(), Decimal128::kRoundTowardZero, &std::trunc);
}
+intrusive_ptr<Expression> ExpressionTrunc::parse(const intrusive_ptr<ExpressionContext>& expCtx,
+ BSONElement elem,
+ const VariablesParseState& vps) {
+ // In version 4.2 we added new arguments. In all previous versions the expression existed but
+ // only supported a single argument.
+ const bool newArgumentsAllowed =
+ (!expCtx->maxFeatureCompatibilityVersion ||
+ (*expCtx->maxFeatureCompatibilityVersion >=
+ ServerGlobalParams::FeatureCompatibility::Version::kFullyUpgradedTo42));
+ uassert(
+ ErrorCodes::QueryFeatureNotAllowed,
+ // TODO SERVER-31968 we would like to include the current version and the required minimum
+ // version in this error message, but using FeatureCompatibilityVersion::toString() would
+ // introduce a dependency cycle.
+ str::stream()
+ << elem.fieldNameStringData()
+ << " with >1 argument is not allowed in the current feature compatibility version. See "
+ << feature_compatibility_version_documentation::kCompatibilityLink
+ << " for more information.",
+ // Allow non-arrays since they will be rejected anyway by the parser below.
+ elem.type() != BSONType::Array || elem.Array().size() <= 1 || newArgumentsAllowed);
+ return ExpressionRangedArity<ExpressionTrunc, 1, 2>::parse(expCtx, elem, vps);
+}
+
REGISTER_EXPRESSION(trunc, ExpressionTrunc::parse);
const char* ExpressionTrunc::getOpName() const {
return "$trunc";
@@ -6015,7 +6042,10 @@ void ExpressionRegex::_doAddDependencies(DepsTracker* deps) const {
/* -------------------------- ExpressionRegexFind ------------------------------ */
-REGISTER_EXPRESSION(regexFind, ExpressionRegexFind::parse);
+REGISTER_EXPRESSION_WITH_MIN_VERSION(
+ regexFind,
+ ExpressionRegexFind::parse,
+ ServerGlobalParams::FeatureCompatibility::Version::kFullyUpgradedTo42);
boost::intrusive_ptr<Expression> ExpressionRegexFind::parse(
const boost::intrusive_ptr<ExpressionContext>& expCtx,
BSONElement expr,
@@ -6036,7 +6066,10 @@ Value ExpressionRegexFind::evaluate(const Document& root) const {
/* -------------------------- ExpressionRegexFindAll ------------------------------ */
-REGISTER_EXPRESSION(regexFindAll, ExpressionRegexFindAll::parse);
+REGISTER_EXPRESSION_WITH_MIN_VERSION(
+ regexFindAll,
+ ExpressionRegexFindAll::parse,
+ ServerGlobalParams::FeatureCompatibility::Version::kFullyUpgradedTo42);
boost::intrusive_ptr<Expression> ExpressionRegexFindAll::parse(
const boost::intrusive_ptr<ExpressionContext>& expCtx,
BSONElement expr,
@@ -6097,7 +6130,10 @@ Value ExpressionRegexFindAll::evaluate(const Document& root) const {
/* -------------------------- ExpressionRegexMatch ------------------------------ */
-REGISTER_EXPRESSION(regexMatch, ExpressionRegexMatch::parse);
+REGISTER_EXPRESSION_WITH_MIN_VERSION(
+ regexMatch,
+ ExpressionRegexMatch::parse,
+ ServerGlobalParams::FeatureCompatibility::Version::kFullyUpgradedTo42);
boost::intrusive_ptr<Expression> ExpressionRegexMatch::parse(
const boost::intrusive_ptr<ExpressionContext>& expCtx,
BSONElement expr,
diff --git a/src/mongo/db/pipeline/expression.h b/src/mongo/db/pipeline/expression.h
index 7033ee717d1..7ec1700afb3 100644
--- a/src/mongo/db/pipeline/expression.h
+++ b/src/mongo/db/pipeline/expression.h
@@ -2325,6 +2325,10 @@ public:
explicit ExpressionTrunc(const boost::intrusive_ptr<ExpressionContext>& expCtx)
: ExpressionRangedArity<ExpressionTrunc, 1, 2>(expCtx) {}
+ static boost::intrusive_ptr<Expression> parse(
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ BSONElement elem,
+ const VariablesParseState& vps);
Value evaluate(const Document& root) const final;
const char* getOpName() const final;
diff --git a/src/mongo/db/pipeline/expression_context.cpp b/src/mongo/db/pipeline/expression_context.cpp
index 0054e0de98c..9f65c12669f 100644
--- a/src/mongo/db/pipeline/expression_context.cpp
+++ b/src/mongo/db/pipeline/expression_context.cpp
@@ -160,6 +160,7 @@ intrusive_ptr<ExpressionContext> ExpressionContext::copyWith(
expCtx->inMongos = inMongos;
expCtx->allowDiskUse = allowDiskUse;
expCtx->bypassDocumentValidation = bypassDocumentValidation;
+ expCtx->maxFeatureCompatibilityVersion = maxFeatureCompatibilityVersion;
expCtx->subPipelineDepth = subPipelineDepth;
expCtx->tempDir = tempDir;