summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/core/command_let_variables.js66
-rw-r--r--jstests/noPassthroughWithMongod/command_let_variables.js19
-rw-r--r--src/mongo/db/ops/update_request.h4
-rw-r--r--src/mongo/db/pipeline/aggregation_request.cpp22
-rw-r--r--src/mongo/db/pipeline/aggregation_request.h24
-rw-r--r--src/mongo/db/pipeline/aggregation_request_test.cpp6
-rw-r--r--src/mongo/db/pipeline/expression_context.cpp2
-rw-r--r--src/mongo/db/pipeline/sharded_agg_helpers.cpp2
-rw-r--r--src/mongo/db/query/find_and_modify_request.cpp8
-rw-r--r--src/mongo/db/views/resolved_view.cpp2
-rw-r--r--src/mongo/s/commands/cluster_map_reduce_agg.cpp4
-rw-r--r--src/mongo/s/query/cluster_aggregation_planner.cpp2
12 files changed, 51 insertions, 110 deletions
diff --git a/jstests/core/command_let_variables.js b/jstests/core/command_let_variables.js
index 844221cd5e2..2ae1b7f5f15 100644
--- a/jstests/core/command_let_variables.js
+++ b/jstests/core/command_let_variables.js
@@ -308,70 +308,4 @@ assert.commandWorked(testDB.runCommand({
let : {variable: "Song Thrush"},
cursor: {}
}));
-
-// Test that update respects different parameters in both the query and update part.
-result = assert.commandWorked(testDB.runCommand({
- update: coll.getName(),
- updates: [{
- q: {$expr: {$eq: ["$Species", "$$target_species"]}},
- u: [{$set: {Species: "$$new_name"}}],
- multi: true
- }],
- let : {target_species: "Chaffinch (Fringilla coelebs)", new_name: "Chaffinch"}
-}));
-assert.eq(result.n, 1);
-assert.eq(result.nModified, 1);
-
-result = assert.commandWorked(testDB.runCommand(
- {find: coll.getName(), filter: {$expr: {$eq: ["$Species", "Chaffinch (Fringilla coelebs)"]}}}));
-assert.eq(result.cursor.firstBatch.length, 0);
-
-result = assert.commandWorked(
- testDB.runCommand({find: coll.getName(), filter: {$expr: {$eq: ["$Species", "Chaffinch"]}}}));
-assert.eq(result.cursor.firstBatch.length, 1);
-
-// Test that update respects runtime constants and parameters.
-result = assert.commandWorked(testDB.runCommand({
- update: coll.getName(),
- updates: [{
- q: {$expr: {$eq: ["$Species", "$$target_species"]}},
- u: [{$set: {Timestamp: "$$NOW"}}, {$set: {Species: "$$new_name"}}],
- multi: true
- }],
- let : {target_species: "Chaffinch", new_name: "Pied Piper"}
-}));
-assert.eq(result.n, 1);
-assert.eq(result.nModified, 1);
-
-result = assert.commandWorked(
- testDB.runCommand({find: coll.getName(), filter: {$expr: {$eq: ["$Species", "Chaffinch"]}}}));
-assert.eq(result.cursor.firstBatch.length, 0, result);
-
-result = assert.commandWorked(
- testDB.runCommand({find: coll.getName(), filter: {$expr: {$eq: ["$Species", "Pied Piper"]}}}));
-assert.eq(result.cursor.firstBatch.length, 1, result);
-
-// Test that undefined let params in the update's query part fail gracefully.
-assert.commandFailedWithCode(testDB.runCommand({
- update: coll.getName(),
- updates: [{
- q: {$expr: {$eq: ["$Species", "$$target_species"]}},
- u: [{$set: {Species: "Homo Erectus"}}],
- multi: true
- }],
- let : {cat: "not_a_bird"}
-}),
- 17276);
-
-// Test that undefined let params in the update's update part fail gracefully.
-assert.commandFailedWithCode(testDB.runCommand({
- update: coll.getName(),
- updates: [{
- q: {$expr: {$eq: ["$Species", "Chaffinch (Fringilla coelebs)"]}},
- u: [{$set: {Species: "$$new_name"}}],
- multi: true
- }],
- let : {cat: "not_a_bird"}
-}),
- 17276);
}());
diff --git a/jstests/noPassthroughWithMongod/command_let_variables.js b/jstests/noPassthroughWithMongod/command_let_variables.js
index 8c5af176046..42f5ee4c2fc 100644
--- a/jstests/noPassthroughWithMongod/command_let_variables.js
+++ b/jstests/noPassthroughWithMongod/command_let_variables.js
@@ -217,4 +217,23 @@ result = db.runCommand({
new: true
});
assert.eq(result.value, {Species: "not_a_bird", suspect: "dino"}, result);
+
+// Update
+assert.commandWorked(db.runCommand({
+ update: coll.getName(),
+ let : {target_species: "Song Thrush (Turdus philomelos)", new_name: "Song Thrush"},
+ updates: [
+ {q: {$expr: {$eq: ["$Species", "$$target_species"]}}, u: [{$set: {Species: "$$new_name"}}]}
+ ]
+}));
+
+assert.commandWorked(db.runCommand({
+ update: coll.getName(),
+ let : {target_species: "Song Thrush (Turdus philomelos)"},
+ updates: [{
+ q: {$expr: {$eq: ["$Species", "$$target_species"]}},
+ u: [{$set: {Location: "$$place"}}],
+ c: {place: "North America"}
+ }]
+}));
}());
diff --git a/src/mongo/db/ops/update_request.h b/src/mongo/db/ops/update_request.h
index 5c917fe277f..a18fe293690 100644
--- a/src/mongo/db/ops/update_request.h
+++ b/src/mongo/db/ops/update_request.h
@@ -272,10 +272,6 @@ public:
builder << " runtimeConstants: " << _runtimeConstants->toBSON().toString();
}
- if (_letParameters) {
- builder << " letParameters: " << _letParameters;
- }
-
builder << " god: " << _god;
builder << " upsert: " << isUpsert();
builder << " multi: " << isMulti();
diff --git a/src/mongo/db/pipeline/aggregation_request.cpp b/src/mongo/db/pipeline/aggregation_request.cpp
index d2a7b9d0fbb..b75fb66a055 100644
--- a/src/mongo/db/pipeline/aggregation_request.cpp
+++ b/src/mongo/db/pipeline/aggregation_request.cpp
@@ -189,7 +189,7 @@ StatusWith<AggregationRequest> AggregationRequest::parseFromBSON(
auto writeConcern = uassertStatusOK(WriteConcernOptions::parse(elem.embeddedObject()));
request.setWriteConcern(writeConcern);
- } else if (kRuntimeConstantsName == fieldName) {
+ } else if (kRuntimeConstants == fieldName) {
// TODO SERVER-46384: Remove 'runtimeConstants' in 4.5 since it is redundant with 'let'
try {
IDLParserErrorContext ctx("internalRuntimeConstants");
@@ -197,18 +197,18 @@ StatusWith<AggregationRequest> AggregationRequest::parseFromBSON(
} catch (const DBException& ex) {
return ex.toStatus();
}
- } else if (kLetName == fieldName) {
+ } else if (kLet == fieldName) {
if (elem.type() != BSONType::Object)
return {ErrorCodes::TypeMismatch,
str::stream()
<< fieldName << " must be an object, not a " << typeName(elem.type())};
- auto bob = BSONObjBuilder{request.getLetParameters()};
+ auto bob = BSONObjBuilder{request.letParameters};
bob.appendElementsUnique(elem.embeddedObject());
- request._letParameters = bob.obj();
- } else if (fieldName == kUse44SortKeysName) {
+ request.letParameters = bob.obj();
+ } else if (fieldName == kUse44SortKeys) {
if (elem.type() != BSONType::Bool) {
return {ErrorCodes::TypeMismatch,
- str::stream() << kUse44SortKeysName << " must be a boolean, not a "
+ str::stream() << kUse44SortKeys << " must be a boolean, not a "
<< typeName(elem.type())};
}
// TODO SERVER-47065: A 4.6 node still has to accept the 'use44SortKeys' field, since it
@@ -219,10 +219,10 @@ StatusWith<AggregationRequest> AggregationRequest::parseFromBSON(
// 4.6 upgrade purposes, since a 4.4 mongoS will always send {useNewUpsert:true} to the
// shards. We do nothing with it because useNewUpsert will be automatically used in 4.6
// when appropriate. Remove this final vestige of useNewUpsert during the 4.7 dev cycle.
- } else if (fieldName == kIsMapReduceCommandName) {
+ } else if (fieldName == kIsMapReduceCommand) {
if (elem.type() != BSONType::Bool) {
return {ErrorCodes::TypeMismatch,
- str::stream() << kIsMapReduceCommandName << " must be a boolean, not a "
+ str::stream() << kIsMapReduceCommand << " must be a boolean, not a "
<< typeName(elem.type())};
}
request.setIsMapReduceCommand(elem.boolean());
@@ -327,9 +327,9 @@ Document AggregationRequest::serializeToCommandObj() const {
{WriteConcernOptions::kWriteConcernField,
_writeConcern ? Value(_writeConcern->toBSON()) : Value()},
// Only serialize runtime constants if any were specified.
- {kRuntimeConstantsName, _runtimeConstants ? Value(_runtimeConstants->toBSON()) : Value()},
- {kIsMapReduceCommandName, _isMapReduceCommand ? Value(true) : Value()},
- {kLetName, !_letParameters.isEmpty() ? Value(_letParameters) : Value()},
+ {kRuntimeConstants, _runtimeConstants ? Value(_runtimeConstants->toBSON()) : Value()},
+ {kIsMapReduceCommand, _isMapReduceCommand ? Value(true) : Value()},
+ {kLet, !letParameters.isEmpty() ? Value(letParameters) : Value()},
};
}
} // namespace mongo
diff --git a/src/mongo/db/pipeline/aggregation_request.h b/src/mongo/db/pipeline/aggregation_request.h
index 7788ec962aa..3e1de8412f6 100644
--- a/src/mongo/db/pipeline/aggregation_request.h
+++ b/src/mongo/db/pipeline/aggregation_request.h
@@ -62,10 +62,10 @@ public:
static constexpr StringData kAllowDiskUseName = "allowDiskUse"_sd;
static constexpr StringData kHintName = "hint"_sd;
static constexpr StringData kExchangeName = "exchange"_sd;
- static constexpr StringData kRuntimeConstantsName = "runtimeConstants"_sd;
- static constexpr StringData kUse44SortKeysName = "use44SortKeys"_sd;
- static constexpr StringData kIsMapReduceCommandName = "isMapReduceCommand"_sd;
- static constexpr StringData kLetName = "let"_sd;
+ static constexpr StringData kRuntimeConstants = "runtimeConstants"_sd;
+ static constexpr StringData kUse44SortKeys = "use44SortKeys"_sd;
+ static constexpr StringData kIsMapReduceCommand = "isMapReduceCommand"_sd;
+ static constexpr StringData kLet = "let"_sd;
static constexpr long long kDefaultBatchSize = 101;
@@ -219,10 +219,6 @@ public:
return _runtimeConstants;
}
- const auto& getLetParameters() const {
- return _letParameters;
- }
-
bool getIsMapReduceCommand() const {
return _isMapReduceCommand;
}
@@ -291,14 +287,14 @@ public:
_runtimeConstants = std::move(runtimeConstants);
}
- void setLetParameters(BSONObj letParameters) {
- _letParameters = letParameters.getOwned();
- }
-
void setIsMapReduceCommand(bool isMapReduce) {
_isMapReduceCommand = isMapReduce;
}
+ // A document containing user-specified let parameter constants; i.e. values that do not change
+ // once computed.
+ BSONObj letParameters;
+
private:
// Required fields.
const NamespaceString _nss;
@@ -349,10 +345,6 @@ private:
// $$NOW).
boost::optional<RuntimeConstants> _runtimeConstants;
- // A document containing user-specified let parameter constants; i.e. values that do not change
- // once computed.
- BSONObj _letParameters;
-
// True when an aggregation was invoked by the MapReduce command.
bool _isMapReduceCommand = false;
};
diff --git a/src/mongo/db/pipeline/aggregation_request_test.cpp b/src/mongo/db/pipeline/aggregation_request_test.cpp
index f16b7a5891b..4618f9035bf 100644
--- a/src/mongo/db/pipeline/aggregation_request_test.cpp
+++ b/src/mongo/db/pipeline/aggregation_request_test.cpp
@@ -192,7 +192,7 @@ TEST(AggregationRequestTest, ShouldSerializeOptionalValuesIfSet) {
request.setIsMapReduceCommand(true);
const auto letParamsObj = BSON("foo"
<< "bar");
- request.setLetParameters(letParamsObj);
+ request.letParameters = letParamsObj;
auto expectedSerialization =
Document{{AggregationRequest::kCommandName, nss.coll()},
@@ -208,8 +208,8 @@ TEST(AggregationRequestTest, ShouldSerializeOptionalValuesIfSet) {
{repl::ReadConcernArgs::kReadConcernFieldName, readConcernObj},
{QueryRequest::kUnwrappedReadPrefField, readPrefObj},
{QueryRequest::cmdOptionMaxTimeMS, 10},
- {AggregationRequest::kIsMapReduceCommandName, true},
- {AggregationRequest::kLetName, letParamsObj}};
+ {AggregationRequest::kIsMapReduceCommand, true},
+ {AggregationRequest::kLet, letParamsObj}};
ASSERT_DOCUMENT_EQ(request.serializeToCommandObj(), expectedSerialization);
}
diff --git a/src/mongo/db/pipeline/expression_context.cpp b/src/mongo/db/pipeline/expression_context.cpp
index bc5b3d26608..f33d6a16e06 100644
--- a/src/mongo/db/pipeline/expression_context.cpp
+++ b/src/mongo/db/pipeline/expression_context.cpp
@@ -65,7 +65,7 @@ ExpressionContext::ExpressionContext(OperationContext* opCtx,
std::move(processInterface),
std::move(resolvedNamespaces),
std::move(collUUID),
- request.getLetParameters(),
+ request.letParameters,
mayDbProfile) {
if (request.getIsMapReduceCommand()) {
diff --git a/src/mongo/db/pipeline/sharded_agg_helpers.cpp b/src/mongo/db/pipeline/sharded_agg_helpers.cpp
index 1058c618cfd..7e02ec30fe3 100644
--- a/src/mongo/db/pipeline/sharded_agg_helpers.cpp
+++ b/src/mongo/db/pipeline/sharded_agg_helpers.cpp
@@ -127,7 +127,7 @@ BSONObj genericTransformForShards(MutableDocument&& cmdForShards,
const boost::optional<RuntimeConstants>& constants,
BSONObj collationObj) {
if (constants) {
- cmdForShards[AggregationRequest::kRuntimeConstantsName] = Value(constants.get().toBSON());
+ cmdForShards[AggregationRequest::kRuntimeConstants] = Value(constants.get().toBSON());
}
cmdForShards[AggregationRequest::kFromMongosName] = Value(expCtx->inMongos);
diff --git a/src/mongo/db/query/find_and_modify_request.cpp b/src/mongo/db/query/find_and_modify_request.cpp
index 582f4753d13..660cc9c95a5 100644
--- a/src/mongo/db/query/find_and_modify_request.cpp
+++ b/src/mongo/db/query/find_and_modify_request.cpp
@@ -48,7 +48,7 @@ const char kHintField[] = "hint";
const char kCollationField[] = "collation";
const char kArrayFiltersField[] = "arrayFilters";
const char kRuntimeConstantsField[] = "runtimeConstants";
-const char kLetField[] = "let";
+const char kLet[] = "let";
const char kRemoveField[] = "remove";
const char kUpdateField[] = "update";
const char kNewField[] = "new";
@@ -138,7 +138,7 @@ BSONObj FindAndModifyRequest::toBSON(const BSONObj& commandPassthroughFields) co
if (_letParameters) {
if (auto letParams = _letParameters.get(); !letParams.isEmpty()) {
- builder.append(kLetField, _letParameters.get());
+ builder.append(kLet, _letParameters.get());
}
}
@@ -253,10 +253,10 @@ StatusWith<FindAndModifyRequest> FindAndModifyRequest::parseFromBSON(NamespaceSt
runtimeConstants =
RuntimeConstants::parse(IDLParserErrorContext(kRuntimeConstantsField),
cmdObj.getObjectField(kRuntimeConstantsField));
- } else if (field == kLetField) {
+ } else if (field == kLet) {
BSONElement letElt;
if (Status letEltStatus =
- bsonExtractTypedField(cmdObj, kLetField, BSONType::Object, &letElt);
+ bsonExtractTypedField(cmdObj, kLet, BSONType::Object, &letElt);
!letEltStatus.isOK()) {
return letEltStatus;
}
diff --git a/src/mongo/db/views/resolved_view.cpp b/src/mongo/db/views/resolved_view.cpp
index 5bb17093d21..714644ecca3 100644
--- a/src/mongo/db/views/resolved_view.cpp
+++ b/src/mongo/db/views/resolved_view.cpp
@@ -112,7 +112,7 @@ AggregationRequest ResolvedView::asExpandedViewAggregation(
expandedRequest.setBypassDocumentValidation(request.shouldBypassDocumentValidation());
expandedRequest.setAllowDiskUse(request.shouldAllowDiskUse());
expandedRequest.setIsMapReduceCommand(request.getIsMapReduceCommand());
- expandedRequest.setLetParameters(request.getLetParameters());
+ expandedRequest.letParameters = request.letParameters;
// Operations on a view must always use the default collation of the view. We must have already
// checked that if the user's request specifies a collation, it matches the collation of the
diff --git a/src/mongo/s/commands/cluster_map_reduce_agg.cpp b/src/mongo/s/commands/cluster_map_reduce_agg.cpp
index 7908cdec77b..224e82dc6ca 100644
--- a/src/mongo/s/commands/cluster_map_reduce_agg.cpp
+++ b/src/mongo/s/commands/cluster_map_reduce_agg.cpp
@@ -118,9 +118,9 @@ Document serializeToCommand(BSONObj originalCmd, const MapReduce& parsedMr, Pipe
Value(Document{{"batchSize", std::numeric_limits<long long>::max()}});
translatedCmd[AggregationRequest::kAllowDiskUseName] = Value(true);
translatedCmd[AggregationRequest::kFromMongosName] = Value(true);
- translatedCmd[AggregationRequest::kRuntimeConstantsName] =
+ translatedCmd[AggregationRequest::kRuntimeConstants] =
Value(pipeline->getContext()->getRuntimeConstants().toBSON());
- translatedCmd[AggregationRequest::kIsMapReduceCommandName] = Value(true);
+ translatedCmd[AggregationRequest::kIsMapReduceCommand] = Value(true);
if (shouldBypassDocumentValidationForCommand(originalCmd)) {
translatedCmd[bypassDocumentValidationCommandOption()] = Value(true);
diff --git a/src/mongo/s/query/cluster_aggregation_planner.cpp b/src/mongo/s/query/cluster_aggregation_planner.cpp
index 5b7ea00286f..5c4716e229f 100644
--- a/src/mongo/s/query/cluster_aggregation_planner.cpp
+++ b/src/mongo/s/query/cluster_aggregation_planner.cpp
@@ -126,7 +126,7 @@ BSONObj createCommandForMergingShard(Document serializedCommand,
mergeCmd["pipeline"] = Value(pipelineForMerging->serialize());
mergeCmd[AggregationRequest::kFromMongosName] = Value(true);
- mergeCmd[AggregationRequest::kRuntimeConstantsName] =
+ mergeCmd[AggregationRequest::kRuntimeConstants] =
Value(mergeCtx->getRuntimeConstants().toBSON());
// If the user didn't specify a collation already, make sure there's a collation attached to