summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMihai Andrei <mihai.andrei@10gen.com>2022-03-30 14:54:10 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-03-30 15:47:00 +0000
commit3cf89ad966f8b92e3f2c1884e7d671bedff23174 (patch)
treebb18e1ca00673fe6c85fb194af9454f15d9972c2
parent84befbcce9ba114af5c2eef117042b449c2017a8 (diff)
downloadmongo-3cf89ad966f8b92e3f2c1884e7d671bedff23174.tar.gz
SERVER-61855 Add 5.2 language features to the stable API
-rw-r--r--jstests/core/api_version_new_52_language_features.js96
-rw-r--r--src/mongo/db/pipeline/accumulator_locf.cpp2
-rw-r--r--src/mongo/db/pipeline/accumulator_multi.cpp25
-rw-r--r--src/mongo/db/pipeline/document_source_densify.cpp2
-rw-r--r--src/mongo/db/pipeline/expression.cpp3
-rw-r--r--src/mongo/db/pipeline/window_function/window_function_expression.cpp16
6 files changed, 119 insertions, 25 deletions
diff --git a/jstests/core/api_version_new_52_language_features.js b/jstests/core/api_version_new_52_language_features.js
new file mode 100644
index 00000000000..edd92c565b5
--- /dev/null
+++ b/jstests/core/api_version_new_52_language_features.js
@@ -0,0 +1,96 @@
+/**
+ * Tests that language features introduced in version 5.2 are included in API Version 1.
+ *
+ * @tags: [
+ * requires_fcv_52,
+ * uses_api_parameters,
+ * ]
+ */
+
+(function() {
+"use strict";
+load("jstests/libs/api_version_helpers.js"); // For 'APIVersionHelpers'.
+
+const collName = "api_version_new_52_language_features";
+const coll = db[collName];
+coll.drop();
+assert.commandWorked(coll.insert({a: 1, arr: [2, 1, 4]}));
+
+const stablePipelines = [
+ [{$group: {_id: "$a", out: {$topN: {output: "$a", n: 2, sortBy: {a: 1}}}}}],
+ [{$group: {_id: "$a", out: {$top: {output: "$a", sortBy: {a: 1}}}}}],
+ [{$group: {_id: "$a", out: {$bottomN: {output: "$a", n: 2, sortBy: {a: 1}}}}}],
+ [{$group: {_id: "$a", out: {$bottom: {output: "$a", sortBy: {a: 1}}}}}],
+ [{$group: {_id: "$a", out: {$minN: {input: "$a", n: 2}}}}],
+ [{$group: {_id: "$a", out: {$maxN: {input: "$a", n: 2}}}}],
+ [{$group: {_id: "$a", out: {$firstN: {input: "$a", n: 2}}}}],
+ [{$group: {_id: "$a", out: {$lastN: {input: "$a", n: 2}}}}],
+ [{$set: {x: {$firstN: {input: "$arr", n: 2}}}}],
+ [{$set: {x: {$lastN: {input: "$arr", n: 2}}}}],
+ [{$set: {x: {$minN: {input: "$arr", n: 2}}}}],
+ [{$set: {x: {$maxN: {input: "$arr", n: 2}}}}],
+ [{$set: {x: {$sortArray: {input: "$arr", sortBy: 1}}}}],
+ [{
+ $setWindowFields: {
+ partitionBy: "$a",
+ sortBy: {a: 1},
+ output: {out: {$topN: {output: "$a", n: 2, sortBy: {a: 1}}}}
+ }
+ }],
+ [{
+ $setWindowFields: {
+ partitionBy: "$a",
+ sortBy: {a: 1},
+ output: {out: {$top: {output: "$a", sortBy: {a: 1}}}}
+ }
+ }],
+ [{
+ $setWindowFields: {
+ partitionBy: "$a",
+ sortBy: {a: 1},
+ output: {out: {$bottomN: {output: "$a", n: 2, sortBy: {a: 1}}}}
+ }
+ }],
+ [{
+ $setWindowFields: {
+ partitionBy: "$a",
+ sortBy: {a: 1},
+ output: {out: {$bottom: {output: "$a", sortBy: {a: 1}}}}
+ }
+ }],
+ [{
+ $setWindowFields:
+ {partitionBy: "$a", sortBy: {a: 1}, output: {out: {$minN: {input: "$a", n: 2}}}}
+ }],
+ [{
+ $setWindowFields:
+ {partitionBy: "$a", sortBy: {a: 1}, output: {out: {$maxN: {input: "$a", n: 2}}}}
+ }],
+ [{
+ $setWindowFields:
+ {partitionBy: "$a", sortBy: {a: 1}, output: {out: {$firstN: {input: "$a", n: 2}}}}
+ }],
+ [{
+ $setWindowFields:
+ {partitionBy: "$a", sortBy: {a: 1}, output: {out: {$lastN: {input: "$a", n: 2}}}}
+ }],
+ [{$setWindowFields: {partitionBy: "$a", sortBy: {a: 1}, output: {out: {$locf: "$a"}}}}],
+ [{$densify: {field: "val", partitionByFields: ["a"], range: {step: 1, bounds: "partition"}}}],
+];
+
+for (const pipeline of stablePipelines) {
+ // Assert running a pipeline with stages in API Version 1 succeeds.
+ APIVersionHelpers.assertAggregateSucceedsWithAPIStrict(pipeline, collName);
+
+ // Assert creating a view on a pipeline with stages in API Version 1 succeeds.
+ APIVersionHelpers.assertViewSucceedsWithAPIStrict(pipeline, collName);
+
+ // Assert error is not thrown when running without apiStrict=true.
+ assert.commandWorked(db.runCommand({
+ aggregate: coll.getName(),
+ pipeline: pipeline,
+ apiVersion: "1",
+ cursor: {},
+ }));
+}
+})();
diff --git a/src/mongo/db/pipeline/accumulator_locf.cpp b/src/mongo/db/pipeline/accumulator_locf.cpp
index bca58eff3a2..acd97927975 100644
--- a/src/mongo/db/pipeline/accumulator_locf.cpp
+++ b/src/mongo/db/pipeline/accumulator_locf.cpp
@@ -42,7 +42,7 @@ REGISTER_WINDOW_FUNCTION_CONDITIONALLY(
locf,
mongo::window_function::ExpressionFromLeftUnboundedWindowFunction<AccumulatorLocf>::parse,
feature_flags::gFeatureFlagLocf.getVersion(),
- AllowedWithApiStrict::kNeverInVersion1,
+ AllowedWithApiStrict::kAlways,
feature_flags::gFeatureFlagLocf.isEnabledAndIgnoreFCV());
AccumulatorLocf::AccumulatorLocf(ExpressionContext* const expCtx)
diff --git a/src/mongo/db/pipeline/accumulator_multi.cpp b/src/mongo/db/pipeline/accumulator_multi.cpp
index 8affcdefb2c..db945bff6ec 100644
--- a/src/mongo/db/pipeline/accumulator_multi.cpp
+++ b/src/mongo/db/pipeline/accumulator_multi.cpp
@@ -38,88 +38,87 @@ using MinMaxSense = AccumulatorMinMax::Sense;
// Register macros for the various accumulators/expressions in this file. Note that we check
// 'isEnabledAndIgnoreFCV()' because the feature flag is a property set at startup, while FCV can
// change while the server is running.
-// TODO SERVER-61855 Add these accumulators/expressions to the stable API.
REGISTER_ACCUMULATOR_CONDITIONALLY(
maxN,
AccumulatorMinMaxN::parseMinMaxN<MinMaxSense::kMax>,
- AllowedWithApiStrict::kNeverInVersion1,
+ AllowedWithApiStrict::kAlways,
AllowedWithClientType::kAny,
feature_flags::gFeatureFlagExactTopNAccumulator.getVersion(),
feature_flags::gFeatureFlagExactTopNAccumulator.isEnabledAndIgnoreFCV());
REGISTER_ACCUMULATOR_CONDITIONALLY(
minN,
AccumulatorMinMaxN::parseMinMaxN<MinMaxSense::kMin>,
- AllowedWithApiStrict::kNeverInVersion1,
+ AllowedWithApiStrict::kAlways,
AllowedWithClientType::kAny,
feature_flags::gFeatureFlagExactTopNAccumulator.getVersion(),
feature_flags::gFeatureFlagExactTopNAccumulator.isEnabledAndIgnoreFCV());
REGISTER_EXPRESSION_CONDITIONALLY(
maxN,
AccumulatorMinMaxN::parseExpression<MinMaxSense::kMax>,
- AllowedWithApiStrict::kNeverInVersion1,
+ AllowedWithApiStrict::kAlways,
AllowedWithClientType::kAny,
feature_flags::gFeatureFlagExactTopNAccumulator.getVersion(),
feature_flags::gFeatureFlagExactTopNAccumulator.isEnabledAndIgnoreFCV());
REGISTER_EXPRESSION_CONDITIONALLY(
minN,
AccumulatorMinMaxN::parseExpression<MinMaxSense::kMin>,
- AllowedWithApiStrict::kNeverInVersion1,
+ AllowedWithApiStrict::kAlways,
AllowedWithClientType::kAny,
feature_flags::gFeatureFlagExactTopNAccumulator.getVersion(),
feature_flags::gFeatureFlagExactTopNAccumulator.isEnabledAndIgnoreFCV());
REGISTER_ACCUMULATOR_CONDITIONALLY(
firstN,
AccumulatorFirstLastN::parseFirstLastN<FirstLastSense::kFirst>,
- AllowedWithApiStrict::kNeverInVersion1,
+ AllowedWithApiStrict::kAlways,
AllowedWithClientType::kAny,
feature_flags::gFeatureFlagExactTopNAccumulator.getVersion(),
feature_flags::gFeatureFlagExactTopNAccumulator.isEnabledAndIgnoreFCV());
REGISTER_ACCUMULATOR_CONDITIONALLY(
lastN,
AccumulatorFirstLastN::parseFirstLastN<FirstLastSense::kLast>,
- AllowedWithApiStrict::kNeverInVersion1,
+ AllowedWithApiStrict::kAlways,
AllowedWithClientType::kAny,
feature_flags::gFeatureFlagExactTopNAccumulator.getVersion(),
feature_flags::gFeatureFlagExactTopNAccumulator.isEnabledAndIgnoreFCV());
REGISTER_EXPRESSION_CONDITIONALLY(
firstN,
AccumulatorFirstLastN::parseExpression<FirstLastSense::kFirst>,
- AllowedWithApiStrict::kNeverInVersion1,
+ AllowedWithApiStrict::kAlways,
AllowedWithClientType::kAny,
feature_flags::gFeatureFlagExactTopNAccumulator.getVersion(),
feature_flags::gFeatureFlagExactTopNAccumulator.isEnabledAndIgnoreFCV());
REGISTER_EXPRESSION_CONDITIONALLY(
lastN,
AccumulatorFirstLastN::parseExpression<FirstLastSense::kLast>,
- AllowedWithApiStrict::kNeverInVersion1,
+ AllowedWithApiStrict::kAlways,
AllowedWithClientType::kAny,
feature_flags::gFeatureFlagExactTopNAccumulator.getVersion(),
feature_flags::gFeatureFlagExactTopNAccumulator.isEnabledAndIgnoreFCV());
REGISTER_ACCUMULATOR_CONDITIONALLY(
topN,
(AccumulatorTopBottomN<TopBottomSense::kTop, false>::parseTopBottomN),
- AllowedWithApiStrict::kNeverInVersion1,
+ AllowedWithApiStrict::kAlways,
AllowedWithClientType::kAny,
feature_flags::gFeatureFlagExactTopNAccumulator.getVersion(),
feature_flags::gFeatureFlagExactTopNAccumulator.isEnabledAndIgnoreFCV());
REGISTER_ACCUMULATOR_CONDITIONALLY(
bottomN,
(AccumulatorTopBottomN<TopBottomSense::kBottom, false>::parseTopBottomN),
- AllowedWithApiStrict::kNeverInVersion1,
+ AllowedWithApiStrict::kAlways,
AllowedWithClientType::kAny,
feature_flags::gFeatureFlagExactTopNAccumulator.getVersion(),
feature_flags::gFeatureFlagExactTopNAccumulator.isEnabledAndIgnoreFCV());
REGISTER_ACCUMULATOR_CONDITIONALLY(
top,
(AccumulatorTopBottomN<TopBottomSense::kTop, true>::parseTopBottomN),
- AllowedWithApiStrict::kNeverInVersion1,
+ AllowedWithApiStrict::kAlways,
AllowedWithClientType::kAny,
feature_flags::gFeatureFlagExactTopNAccumulator.getVersion(),
feature_flags::gFeatureFlagExactTopNAccumulator.isEnabledAndIgnoreFCV());
REGISTER_ACCUMULATOR_CONDITIONALLY(
bottom,
(AccumulatorTopBottomN<TopBottomSense::kBottom, true>::parseTopBottomN),
- AllowedWithApiStrict::kNeverInVersion1,
+ AllowedWithApiStrict::kAlways,
AllowedWithClientType::kAny,
feature_flags::gFeatureFlagExactTopNAccumulator.getVersion(),
feature_flags::gFeatureFlagExactTopNAccumulator.isEnabledAndIgnoreFCV());
diff --git a/src/mongo/db/pipeline/document_source_densify.cpp b/src/mongo/db/pipeline/document_source_densify.cpp
index b9dd817aaff..0325dbaa775 100644
--- a/src/mongo/db/pipeline/document_source_densify.cpp
+++ b/src/mongo/db/pipeline/document_source_densify.cpp
@@ -123,7 +123,7 @@ RangeStatement RangeStatement::parse(RangeSpec spec) {
REGISTER_DOCUMENT_SOURCE_WITH_MIN_VERSION(densify,
LiteParsedDocumentSourceDefault::parse,
document_source_densify::createFromBson,
- AllowedWithApiStrict::kNeverInVersion1,
+ AllowedWithApiStrict::kAlways,
multiversion::FeatureCompatibilityVersion::kVersion_5_1)
REGISTER_DOCUMENT_SOURCE_CONDITIONALLY(_internalDensify,
diff --git a/src/mongo/db/pipeline/expression.cpp b/src/mongo/db/pipeline/expression.cpp
index 312897296ea..76ec9a5debb 100644
--- a/src/mongo/db/pipeline/expression.cpp
+++ b/src/mongo/db/pipeline/expression.cpp
@@ -4617,10 +4617,9 @@ Value ExpressionSortArray::evaluate(const Document& root, Variables* variables)
return Value(array);
}
-// TODO: SERVER-61855 Add the expression to the stable API with others that have been introduced.
REGISTER_EXPRESSION_CONDITIONALLY(sortArray,
ExpressionSortArray::parse,
- AllowedWithApiStrict::kNeverInVersion1,
+ AllowedWithApiStrict::kAlways,
AllowedWithClientType::kAny,
feature_flags::gFeatureFlagSortArray.getVersion(),
feature_flags::gFeatureFlagSortArray.isEnabledAndIgnoreFCV());
diff --git a/src/mongo/db/pipeline/window_function/window_function_expression.cpp b/src/mongo/db/pipeline/window_function/window_function_expression.cpp
index 69841e7abe1..54f0552b59b 100644
--- a/src/mongo/db/pipeline/window_function/window_function_expression.cpp
+++ b/src/mongo/db/pipeline/window_function/window_function_expression.cpp
@@ -66,51 +66,51 @@ REGISTER_WINDOW_FUNCTION_CONDITIONALLY(
minN,
(ExpressionN<WindowFunctionMinN, AccumulatorMinN>::parse),
feature_flags::gFeatureFlagExactTopNAccumulator.getVersion(),
- AllowedWithApiStrict::kNeverInVersion1,
+ AllowedWithApiStrict::kAlways,
feature_flags::gFeatureFlagExactTopNAccumulator.isEnabledAndIgnoreFCV());
REGISTER_WINDOW_FUNCTION_CONDITIONALLY(
maxN,
(ExpressionN<WindowFunctionMaxN, AccumulatorMaxN>::parse),
feature_flags::gFeatureFlagExactTopNAccumulator.getVersion(),
- AllowedWithApiStrict::kNeverInVersion1,
+ AllowedWithApiStrict::kAlways,
feature_flags::gFeatureFlagExactTopNAccumulator.isEnabledAndIgnoreFCV());
REGISTER_WINDOW_FUNCTION_CONDITIONALLY(
firstN,
(ExpressionN<WindowFunctionFirstN, AccumulatorFirstN>::parse),
feature_flags::gFeatureFlagExactTopNAccumulator.getVersion(),
- AllowedWithApiStrict::kNeverInVersion1,
+ AllowedWithApiStrict::kAlways,
feature_flags::gFeatureFlagExactTopNAccumulator.isEnabledAndIgnoreFCV());
REGISTER_WINDOW_FUNCTION_CONDITIONALLY(
lastN,
(ExpressionN<WindowFunctionLastN, AccumulatorLastN>::parse),
feature_flags::gFeatureFlagExactTopNAccumulator.getVersion(),
- AllowedWithApiStrict::kNeverInVersion1,
+ AllowedWithApiStrict::kAlways,
feature_flags::gFeatureFlagExactTopNAccumulator.isEnabledAndIgnoreFCV());
REGISTER_WINDOW_FUNCTION_CONDITIONALLY(
topN,
(ExpressionN<WindowFunctionTopN, AccumulatorTopBottomN<TopBottomSense::kTop, false>>::parse),
feature_flags::gFeatureFlagExactTopNAccumulator.getVersion(),
- AllowedWithApiStrict::kNeverInVersion1,
+ AllowedWithApiStrict::kAlways,
feature_flags::gFeatureFlagExactTopNAccumulator.isEnabledAndIgnoreFCV());
REGISTER_WINDOW_FUNCTION_CONDITIONALLY(
bottomN,
(ExpressionN<WindowFunctionBottomN,
AccumulatorTopBottomN<TopBottomSense::kBottom, false>>::parse),
feature_flags::gFeatureFlagExactTopNAccumulator.getVersion(),
- AllowedWithApiStrict::kNeverInVersion1,
+ AllowedWithApiStrict::kAlways,
feature_flags::gFeatureFlagExactTopNAccumulator.isEnabledAndIgnoreFCV());
REGISTER_WINDOW_FUNCTION_CONDITIONALLY(
top,
(ExpressionN<WindowFunctionTop, AccumulatorTopBottomN<TopBottomSense::kTop, true>>::parse),
feature_flags::gFeatureFlagExactTopNAccumulator.getVersion(),
- AllowedWithApiStrict::kNeverInVersion1,
+ AllowedWithApiStrict::kAlways,
feature_flags::gFeatureFlagExactTopNAccumulator.isEnabledAndIgnoreFCV());
REGISTER_WINDOW_FUNCTION_CONDITIONALLY(
bottom,
(ExpressionN<WindowFunctionBottom,
AccumulatorTopBottomN<TopBottomSense::kBottom, true>>::parse),
feature_flags::gFeatureFlagExactTopNAccumulator.getVersion(),
- AllowedWithApiStrict::kNeverInVersion1,
+ AllowedWithApiStrict::kAlways,
feature_flags::gFeatureFlagExactTopNAccumulator.isEnabledAndIgnoreFCV());
StringMap<Expression::ExpressionParserRegistration> Expression::parserMap;