summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorIan Boros <ian.boros@mongodb.com>2020-08-13 14:08:58 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-08-27 03:08:04 +0000
commit3a32dd0a25105ba547712190ff503a46e91f392e (patch)
tree3bf333229d495a35ffde62aa0ace0e312a720352 /src/mongo/db
parent6791200c0513187dc193895af70cc170db9afc78 (diff)
downloadmongo-3a32dd0a25105ba547712190ff503a46e91f392e.tar.gz
SERVER-50217 change auth op observer to handle $v:1 and $v:2 updates
This commit also removes an implicit constructor for write_ops::UpdateModification.
Diffstat (limited to 'src/mongo/db')
-rw-r--r--src/mongo/db/auth/authz_manager_external_state_mock.cpp3
-rw-r--r--src/mongo/db/auth/role_graph_update.cpp2
-rw-r--r--src/mongo/db/commands/oplog_application_checks.cpp3
-rw-r--r--src/mongo/db/commands/rwc_defaults_commands.cpp2
-rw-r--r--src/mongo/db/commands/user_management_commands.cpp3
-rw-r--r--src/mongo/db/dbhelpers.cpp4
-rw-r--r--src/mongo/db/exec/upsert_stage.cpp2
-rw-r--r--src/mongo/db/ops/write_ops_parsers.cpp6
-rw-r--r--src/mongo/db/ops/write_ops_parsers.h11
-rw-r--r--src/mongo/db/ops/write_ops_retryability_test.cpp36
-rw-r--r--src/mongo/db/persistent_task_store.h2
-rw-r--r--src/mongo/db/pipeline/document_source_merge.cpp4
-rw-r--r--src/mongo/db/pipeline/document_source_merge.h2
-rw-r--r--src/mongo/db/query/find_and_modify_request.cpp2
-rw-r--r--src/mongo/db/query/find_and_modify_request_test.cpp65
-rw-r--r--src/mongo/db/repl/oplog.cpp3
-rw-r--r--src/mongo/db/repl/rs_rollback.cpp3
-rw-r--r--src/mongo/db/repl/storage_interface_impl.cpp9
-rw-r--r--src/mongo/db/s/add_shard_util.cpp3
-rw-r--r--src/mongo/db/s/config/config_server_test_fixture.cpp33
-rw-r--r--src/mongo/db/s/config/sharding_catalog_manager_collection_operations.cpp2
-rw-r--r--src/mongo/db/s/migration_util.cpp8
-rw-r--r--src/mongo/db/s/resharding/resharding_coordinator_service.cpp3
-rw-r--r--src/mongo/db/s/shard_local_test.cpp3
-rw-r--r--src/mongo/db/s/shard_metadata_util.cpp4
-rw-r--r--src/mongo/db/s/sharding_initialization_mongod.cpp3
-rw-r--r--src/mongo/db/s/sharding_state_recovery.cpp3
-rw-r--r--src/mongo/db/s/transaction_coordinator_util.cpp6
-rw-r--r--src/mongo/db/transaction_participant.cpp3
-rw-r--r--src/mongo/db/update/update_driver_test.cpp86
-rw-r--r--src/mongo/db/update/update_serialization_test.cpp2
31 files changed, 209 insertions, 112 deletions
diff --git a/src/mongo/db/auth/authz_manager_external_state_mock.cpp b/src/mongo/db/auth/authz_manager_external_state_mock.cpp
index 57aee1183ea..00d479756a6 100644
--- a/src/mongo/db/auth/authz_manager_external_state_mock.cpp
+++ b/src/mongo/db/auth/authz_manager_external_state_mock.cpp
@@ -197,7 +197,8 @@ Status AuthzManagerExternalStateMock::updateOne(OperationContext* opCtx,
new ExpressionContext(opCtx, std::unique_ptr<CollatorInterface>(nullptr), collectionName));
UpdateDriver driver(std::move(expCtx));
std::map<StringData, std::unique_ptr<ExpressionWithPlaceholder>> arrayFilters;
- driver.parse(updatePattern, arrayFilters);
+ driver.parse(write_ops::UpdateModification::parseFromClassicUpdate(updatePattern),
+ arrayFilters);
BSONObjCollection::iterator iter;
Status status = _findOneIter(opCtx, collectionName, query, &iter);
diff --git a/src/mongo/db/auth/role_graph_update.cpp b/src/mongo/db/auth/role_graph_update.cpp
index f8945340274..85bf11e8de3 100644
--- a/src/mongo/db/auth/role_graph_update.cpp
+++ b/src/mongo/db/auth/role_graph_update.cpp
@@ -208,7 +208,7 @@ Status handleOplogUpdate(OperationContext* opCtx,
// Oplog updates do not have array filters.
std::map<StringData, std::unique_ptr<ExpressionWithPlaceholder>> arrayFilters;
- driver.parse(updatePattern, arrayFilters);
+ driver.parse(write_ops::UpdateModification::parseFromOplogEntry(updatePattern), arrayFilters);
mutablebson::Document roleDocument;
status = RoleGraph::getBSONForRole(roleGraph, roleToUpdate, roleDocument.root());
diff --git a/src/mongo/db/commands/oplog_application_checks.cpp b/src/mongo/db/commands/oplog_application_checks.cpp
index 3cb9dafb0ac..3b7f96fc224 100644
--- a/src/mongo/db/commands/oplog_application_checks.cpp
+++ b/src/mongo/db/commands/oplog_application_checks.cpp
@@ -119,7 +119,8 @@ Status OplogApplicationChecks::checkOperationAuthorization(OperationContext* opC
const bool upsert = b || alwaysUpsert;
- return authSession->checkAuthForUpdate(opCtx, ns, o, o2, upsert);
+ return authSession->checkAuthForUpdate(
+ opCtx, ns, o2, write_ops::UpdateModification::parseFromOplogEntry(o), upsert);
} else if (opType == "d"_sd) {
return authSession->checkAuthForDelete(opCtx, ns, o);
diff --git a/src/mongo/db/commands/rwc_defaults_commands.cpp b/src/mongo/db/commands/rwc_defaults_commands.cpp
index 071227a941a..90f817f29c5 100644
--- a/src/mongo/db/commands/rwc_defaults_commands.cpp
+++ b/src/mongo/db/commands/rwc_defaults_commands.cpp
@@ -59,7 +59,7 @@ void updatePersistedDefaultRWConcernDocument(OperationContext* opCtx, const RWCo
write_ops::UpdateOpEntry entry;
entry.setQ(BSON("_id" << ReadWriteConcernDefaults::kPersistedDocumentId));
// Note the _id is propagated from the query into the upserted document.
- entry.setU(rw.toBSON());
+ entry.setU(write_ops::UpdateModification::parseFromClassicUpdate(rw.toBSON()));
entry.setUpsert(true);
return entry;
}()});
diff --git a/src/mongo/db/commands/user_management_commands.cpp b/src/mongo/db/commands/user_management_commands.cpp
index 15b40b7ddc6..5694a2368cb 100644
--- a/src/mongo/db/commands/user_management_commands.cpp
+++ b/src/mongo/db/commands/user_management_commands.cpp
@@ -274,7 +274,8 @@ Status updateAuthzDocuments(OperationContext* opCtx,
updateOp.setUpdates({[&] {
write_ops::UpdateOpEntry entry;
entry.setQ(query);
- entry.setU(updatePattern);
+ entry.setU(write_ops::UpdateModification::parseFromClassicUpdate(
+ updatePattern));
entry.setMulti(multi);
entry.setUpsert(upsert);
return entry;
diff --git a/src/mongo/db/dbhelpers.cpp b/src/mongo/db/dbhelpers.cpp
index bf19f4bd8bf..36b034e0b05 100644
--- a/src/mongo/db/dbhelpers.cpp
+++ b/src/mongo/db/dbhelpers.cpp
@@ -245,7 +245,7 @@ void Helpers::upsert(OperationContext* opCtx,
request.setNamespaceString(requestNs);
request.setQuery(filter);
- request.setUpdateModification(updateMod);
+ request.setUpdateModification(write_ops::UpdateModification::parseFromClassicUpdate(updateMod));
request.setUpsert();
request.setFromMigration(fromMigrate);
request.setYieldPolicy(PlanYieldPolicy::YieldPolicy::NO_YIELD);
@@ -260,7 +260,7 @@ void Helpers::putSingleton(OperationContext* opCtx, const char* ns, BSONObj obj)
auto request = UpdateRequest();
request.setNamespaceString(requestNs);
- request.setUpdateModification(obj);
+ request.setUpdateModification(write_ops::UpdateModification::parseFromClassicUpdate(obj));
request.setUpsert();
update(opCtx, context.db(), request);
diff --git a/src/mongo/db/exec/upsert_stage.cpp b/src/mongo/db/exec/upsert_stage.cpp
index 831946beed0..a0fd31ca201 100644
--- a/src/mongo/db/exec/upsert_stage.cpp
+++ b/src/mongo/db/exec/upsert_stage.cpp
@@ -247,7 +247,7 @@ void UpsertStage::_generateNewDocumentFromSuppliedDoc(const FieldRefSet& immutab
UpdateDriver replacementDriver(nullptr);
// Create a new replacement-style update from the supplied document.
- replacementDriver.parse({suppliedDoc}, {});
+ replacementDriver.parse(write_ops::UpdateModification::parseFromClassicUpdate(suppliedDoc), {});
replacementDriver.setLogOp(false);
// We do not validate for storage, as we will validate the full document before inserting.
diff --git a/src/mongo/db/ops/write_ops_parsers.cpp b/src/mongo/db/ops/write_ops_parsers.cpp
index 5e0faf1ae8e..1d70e93019a 100644
--- a/src/mongo/db/ops/write_ops_parsers.cpp
+++ b/src/mongo/db/ops/write_ops_parsers.cpp
@@ -236,7 +236,7 @@ write_ops::UpdateModification write_ops::UpdateModification::parseFromOplogEntry
// Treat it as a "classic" update which can either be a full replacement or a
// modifier-style update. Which variant it is will be determined when the update driver is
// constructed.
- return UpdateModification(oField);
+ return UpdateModification(oField, ClassicTag{});
}
// The $v field must be present, but have some unsupported value.
@@ -262,7 +262,7 @@ write_ops::UpdateModification::UpdateModification(BSONElement update) {
_update = PipelineUpdate{uassertStatusOK(AggregationRequest::parsePipelineFromBSON(update))};
}
-write_ops::UpdateModification::UpdateModification(const BSONObj& update) {
+write_ops::UpdateModification::UpdateModification(const BSONObj& update, ClassicTag) {
// Do a sanity check that the $v field is either not provided or has value of 1.
const auto versionElem = update["$v"];
uassert(4772602,
@@ -284,7 +284,7 @@ write_ops::UpdateModification write_ops::UpdateModification::parseFromBSON(BSONE
write_ops::UpdateModification write_ops::UpdateModification::parseLegacyOpUpdateFromBSON(
const BSONObj& obj) {
- return UpdateModification(obj);
+ return UpdateModification(obj, ClassicTag{});
}
int write_ops::UpdateModification::objsize() const {
diff --git a/src/mongo/db/ops/write_ops_parsers.h b/src/mongo/db/ops/write_ops_parsers.h
index 0464a3349df..937b5853912 100644
--- a/src/mongo/db/ops/write_ops_parsers.h
+++ b/src/mongo/db/ops/write_ops_parsers.h
@@ -60,20 +60,27 @@ public:
enum class Type { kClassic, kPipeline, kDelta };
/**
- * Used to indicate that a diff is being passed to the constructor.
+ * Used to indicate that a certain type of update is being passed to the constructor.
*/
struct DiffTag {};
+ struct ClassicTag {};
// Given the 'o' field of an update oplog entry, will return an UpdateModification that can be
// applied.
static UpdateModification parseFromOplogEntry(const BSONObj& oField);
+ static UpdateModification parseFromClassicUpdate(const BSONObj& modifiers) {
+ return UpdateModification(modifiers, ClassicTag{});
+ }
+ static UpdateModification parseFromV2Delta(const doc_diff::Diff& diff) {
+ return UpdateModification(diff, DiffTag{});
+ }
UpdateModification() = default;
UpdateModification(BSONElement update);
UpdateModification(std::vector<BSONObj> pipeline);
UpdateModification(doc_diff::Diff, DiffTag);
// This constructor exists only to provide a fast-path for constructing classic-style updates.
- UpdateModification(const BSONObj& update);
+ UpdateModification(const BSONObj& update, ClassicTag);
/**
* These methods support IDL parsing of the "u" field from the update command and OP_UPDATE.
diff --git a/src/mongo/db/ops/write_ops_retryability_test.cpp b/src/mongo/db/ops/write_ops_retryability_test.cpp
index 4d70242b31f..276eaf1040c 100644
--- a/src/mongo/db/ops/write_ops_retryability_test.cpp
+++ b/src/mongo/db/ops/write_ops_retryability_test.cpp
@@ -176,7 +176,8 @@ protected:
const NamespaceString kNs("test.user");
TEST_F(FindAndModifyRetryability, BasicUpsertReturnNew) {
- auto request = FindAndModifyRequest::makeUpdate(kNs, BSONObj(), BSONObj());
+ auto request = FindAndModifyRequest::makeUpdate(
+ kNs, BSONObj(), write_ops::UpdateModification::parseFromClassicUpdate(BSONObj()));
request.setUpsert(true);
request.setShouldReturnNew(true);
@@ -199,7 +200,8 @@ TEST_F(FindAndModifyRetryability, BasicUpsertReturnNew) {
}
TEST_F(FindAndModifyRetryability, BasicUpsertReturnOld) {
- auto request = FindAndModifyRequest::makeUpdate(kNs, BSONObj(), BSONObj());
+ auto request = FindAndModifyRequest::makeUpdate(
+ kNs, BSONObj(), write_ops::UpdateModification::parseFromClassicUpdate(BSONObj()));
request.setUpsert(true);
request.setShouldReturnNew(false);
@@ -219,7 +221,8 @@ TEST_F(FindAndModifyRetryability, BasicUpsertReturnOld) {
}
TEST_F(FindAndModifyRetryability, NestedUpsert) {
- auto request = FindAndModifyRequest::makeUpdate(kNs, BSONObj(), BSONObj());
+ auto request = FindAndModifyRequest::makeUpdate(
+ kNs, BSONObj(), write_ops::UpdateModification::parseFromClassicUpdate(BSONObj()));
request.setUpsert(true);
request.setShouldReturnNew(true);
@@ -241,7 +244,8 @@ TEST_F(FindAndModifyRetryability, NestedUpsert) {
}
TEST_F(FindAndModifyRetryability, AttemptingToRetryUpsertWithUpdateWithoutUpsertErrors) {
- auto request = FindAndModifyRequest::makeUpdate(kNs, BSONObj(), BSONObj());
+ auto request = FindAndModifyRequest::makeUpdate(
+ kNs, BSONObj(), write_ops::UpdateModification::parseFromClassicUpdate(BSONObj()));
request.setUpsert(false);
auto insertOplog = makeOplogEntry(repl::OpTime(), // optime
@@ -254,7 +258,8 @@ TEST_F(FindAndModifyRetryability, AttemptingToRetryUpsertWithUpdateWithoutUpsert
}
TEST_F(FindAndModifyRetryability, ErrorIfRequestIsPostImageButOplogHasPre) {
- auto request = FindAndModifyRequest::makeUpdate(kNs, BSONObj(), BSONObj());
+ auto request = FindAndModifyRequest::makeUpdate(
+ kNs, BSONObj(), write_ops::UpdateModification::parseFromClassicUpdate(BSONObj()));
request.setShouldReturnNew(true);
repl::OpTime imageOpTime(Timestamp(120, 3), 1);
@@ -278,7 +283,8 @@ TEST_F(FindAndModifyRetryability, ErrorIfRequestIsPostImageButOplogHasPre) {
}
TEST_F(FindAndModifyRetryability, ErrorIfRequestIsUpdateButOplogIsDelete) {
- auto request = FindAndModifyRequest::makeUpdate(kNs, BSONObj(), BSONObj());
+ auto request = FindAndModifyRequest::makeUpdate(
+ kNs, BSONObj(), write_ops::UpdateModification::parseFromClassicUpdate(BSONObj()));
request.setShouldReturnNew(true);
repl::OpTime imageOpTime(Timestamp(120, 3), 1);
@@ -301,7 +307,8 @@ TEST_F(FindAndModifyRetryability, ErrorIfRequestIsUpdateButOplogIsDelete) {
}
TEST_F(FindAndModifyRetryability, ErrorIfRequestIsPreImageButOplogHasPost) {
- auto request = FindAndModifyRequest::makeUpdate(kNs, BSONObj(), BSONObj());
+ auto request = FindAndModifyRequest::makeUpdate(
+ kNs, BSONObj(), write_ops::UpdateModification::parseFromClassicUpdate(BSONObj()));
request.setShouldReturnNew(false);
repl::OpTime imageOpTime(Timestamp(120, 3), 1);
@@ -325,7 +332,8 @@ TEST_F(FindAndModifyRetryability, ErrorIfRequestIsPreImageButOplogHasPost) {
}
TEST_F(FindAndModifyRetryability, UpdateWithPreImage) {
- auto request = FindAndModifyRequest::makeUpdate(kNs, BSONObj(), BSONObj());
+ auto request = FindAndModifyRequest::makeUpdate(
+ kNs, BSONObj(), write_ops::UpdateModification::parseFromClassicUpdate(BSONObj()));
request.setShouldReturnNew(false);
repl::OpTime imageOpTime(Timestamp(120, 3), 1);
@@ -351,7 +359,8 @@ TEST_F(FindAndModifyRetryability, UpdateWithPreImage) {
}
TEST_F(FindAndModifyRetryability, NestedUpdateWithPreImage) {
- auto request = FindAndModifyRequest::makeUpdate(kNs, BSONObj(), BSONObj());
+ auto request = FindAndModifyRequest::makeUpdate(
+ kNs, BSONObj(), write_ops::UpdateModification::parseFromClassicUpdate(BSONObj()));
request.setShouldReturnNew(false);
repl::OpTime imageOpTime(Timestamp(120, 3), 1);
@@ -383,7 +392,8 @@ TEST_F(FindAndModifyRetryability, NestedUpdateWithPreImage) {
}
TEST_F(FindAndModifyRetryability, UpdateWithPostImage) {
- auto request = FindAndModifyRequest::makeUpdate(kNs, BSONObj(), BSONObj());
+ auto request = FindAndModifyRequest::makeUpdate(
+ kNs, BSONObj(), write_ops::UpdateModification::parseFromClassicUpdate(BSONObj()));
request.setShouldReturnNew(true);
repl::OpTime imageOpTime(Timestamp(120, 3), 1);
@@ -409,7 +419,8 @@ TEST_F(FindAndModifyRetryability, UpdateWithPostImage) {
}
TEST_F(FindAndModifyRetryability, NestedUpdateWithPostImage) {
- auto request = FindAndModifyRequest::makeUpdate(kNs, BSONObj(), BSONObj());
+ auto request = FindAndModifyRequest::makeUpdate(
+ kNs, BSONObj(), write_ops::UpdateModification::parseFromClassicUpdate(BSONObj()));
request.setShouldReturnNew(true);
repl::OpTime imageOpTime(Timestamp(120, 3), 1);
@@ -441,7 +452,8 @@ TEST_F(FindAndModifyRetryability, NestedUpdateWithPostImage) {
}
TEST_F(FindAndModifyRetryability, UpdateWithPostImageButOplogDoesNotExistShouldError) {
- auto request = FindAndModifyRequest::makeUpdate(kNs, BSONObj(), BSONObj());
+ auto request = FindAndModifyRequest::makeUpdate(
+ kNs, BSONObj(), write_ops::UpdateModification::parseFromClassicUpdate(BSONObj()));
request.setShouldReturnNew(true);
repl::OpTime imageOpTime(Timestamp(120, 3), 1);
diff --git a/src/mongo/db/persistent_task_store.h b/src/mongo/db/persistent_task_store.h
index 4b0b25af5f6..3c256144f8e 100644
--- a/src/mongo/db/persistent_task_store.h
+++ b/src/mongo/db/persistent_task_store.h
@@ -87,7 +87,7 @@ public:
auto commandResponse = dbClient.runCommand([&] {
write_ops::Update updateOp(_storageNss);
- write_ops::UpdateModification updateModification(update);
+ auto updateModification = write_ops::UpdateModification::parseFromClassicUpdate(update);
write_ops::UpdateOpEntry updateEntry(query.obj, updateModification);
updateEntry.setMulti(false);
updateEntry.setUpsert(upsert);
diff --git a/src/mongo/db/pipeline/document_source_merge.cpp b/src/mongo/db/pipeline/document_source_merge.cpp
index 2b8223d8753..72e3089bd71 100644
--- a/src/mongo/db/pipeline/document_source_merge.cpp
+++ b/src/mongo/db/pipeline/document_source_merge.cpp
@@ -148,8 +148,8 @@ MergeStrategy makeInsertStrategy() {
BatchTransform makeUpdateTransform(const std::string& updateOp) {
return [updateOp](auto& batch) {
for (auto&& obj : batch) {
- std::get<UpdateModification>(obj) =
- BSON(updateOp << std::get<UpdateModification>(obj).getUpdateClassic());
+ std::get<UpdateModification>(obj) = UpdateModification::parseFromClassicUpdate(
+ BSON(updateOp << std::get<UpdateModification>(obj).getUpdateClassic()));
}
};
}
diff --git a/src/mongo/db/pipeline/document_source_merge.h b/src/mongo/db/pipeline/document_source_merge.h
index 6d88c77fefa..f3c76be7e2f 100644
--- a/src/mongo/db/pipeline/document_source_merge.h
+++ b/src/mongo/db/pipeline/document_source_merge.h
@@ -159,7 +159,7 @@ private:
*/
auto makeBatchUpdateModification(const Document& doc) const {
return _pipeline ? write_ops::UpdateModification(*_pipeline)
- : write_ops::UpdateModification(doc.toBson());
+ : write_ops::UpdateModification::parseFromClassicUpdate(doc.toBson());
}
/**
diff --git a/src/mongo/db/query/find_and_modify_request.cpp b/src/mongo/db/query/find_and_modify_request.cpp
index 582f4753d13..9f2a5e6d192 100644
--- a/src/mongo/db/query/find_and_modify_request.cpp
+++ b/src/mongo/db/query/find_and_modify_request.cpp
@@ -367,7 +367,7 @@ void FindAndModifyRequest::setQuery(BSONObj query) {
_query = query.getOwned();
}
void FindAndModifyRequest::setUpdateObj(BSONObj updateObj) {
- _update.emplace(updateObj.getOwned());
+ _update.emplace(write_ops::UpdateModification::parseFromClassicUpdate(updateObj.getOwned()));
}
void FindAndModifyRequest::setShouldReturnNew(bool shouldReturnNew) {
diff --git a/src/mongo/db/query/find_and_modify_request_test.cpp b/src/mongo/db/query/find_and_modify_request_test.cpp
index f9f01b82769..115e0e25178 100644
--- a/src/mongo/db/query/find_and_modify_request_test.cpp
+++ b/src/mongo/db/query/find_and_modify_request_test.cpp
@@ -41,7 +41,10 @@ namespace {
TEST(FindAndModifyRequest, BasicUpdate) {
const BSONObj query(BSON("x" << 1));
const BSONObj update(BSON("y" << 1));
- auto request = FindAndModifyRequest::makeUpdate(NamespaceString("test.user"), query, update);
+ auto request = FindAndModifyRequest::makeUpdate(
+ NamespaceString("test.user"),
+ query,
+ write_ops::UpdateModification::parseFromClassicUpdate(update));
BSONObj expectedObj(fromjson(R"json({
findAndModify: 'user',
@@ -71,7 +74,10 @@ TEST(FindAndModifyRequest, PipelineUpdate) {
TEST(FindAndModifyRequest, UpdateWithUpsert) {
const BSONObj query(BSON("x" << 1));
const BSONObj update(BSON("y" << 1));
- auto request = FindAndModifyRequest::makeUpdate(NamespaceString("test.user"), query, update);
+ auto request = FindAndModifyRequest::makeUpdate(
+ NamespaceString("test.user"),
+ query,
+ write_ops::UpdateModification::parseFromClassicUpdate(update));
request.setUpsert(true);
BSONObj expectedObj(fromjson(R"json({
@@ -87,7 +93,10 @@ TEST(FindAndModifyRequest, UpdateWithUpsert) {
TEST(FindAndModifyRequest, UpdateWithUpsertFalse) {
const BSONObj query(BSON("x" << 1));
const BSONObj update(BSON("y" << 1));
- auto request = FindAndModifyRequest::makeUpdate(NamespaceString("test.user"), query, update);
+ auto request = FindAndModifyRequest::makeUpdate(
+ NamespaceString("test.user"),
+ query,
+ write_ops::UpdateModification::parseFromClassicUpdate(update));
request.setUpsert(false);
BSONObj expectedObj(fromjson(R"json({
@@ -104,7 +113,10 @@ TEST(FindAndModifyRequest, UpdateWithProjection) {
const BSONObj update(BSON("y" << 1));
const BSONObj field(BSON("z" << 1));
- auto request = FindAndModifyRequest::makeUpdate(NamespaceString("test.user"), query, update);
+ auto request = FindAndModifyRequest::makeUpdate(
+ NamespaceString("test.user"),
+ query,
+ write_ops::UpdateModification::parseFromClassicUpdate(update));
request.setFieldProjection(field);
BSONObj expectedObj(fromjson(R"json({
@@ -121,7 +133,10 @@ TEST(FindAndModifyRequest, UpdateWithNewTrue) {
const BSONObj query(BSON("x" << 1));
const BSONObj update(BSON("y" << 1));
- auto request = FindAndModifyRequest::makeUpdate(NamespaceString("test.user"), query, update);
+ auto request = FindAndModifyRequest::makeUpdate(
+ NamespaceString("test.user"),
+ query,
+ write_ops::UpdateModification::parseFromClassicUpdate(update));
request.setShouldReturnNew(true);
BSONObj expectedObj(fromjson(R"json({
@@ -138,7 +153,10 @@ TEST(FindAndModifyRequest, UpdateWithNewFalse) {
const BSONObj query(BSON("x" << 1));
const BSONObj update(BSON("y" << 1));
- auto request = FindAndModifyRequest::makeUpdate(NamespaceString("test.user"), query, update);
+ auto request = FindAndModifyRequest::makeUpdate(
+ NamespaceString("test.user"),
+ query,
+ write_ops::UpdateModification::parseFromClassicUpdate(update));
request.setShouldReturnNew(false);
BSONObj expectedObj(fromjson(R"json({
@@ -155,7 +173,10 @@ TEST(FindAndModifyRequest, UpdateWithSort) {
const BSONObj update(BSON("y" << 1));
const BSONObj sort(BSON("z" << -1));
- auto request = FindAndModifyRequest::makeUpdate(NamespaceString("test.user"), query, update);
+ auto request = FindAndModifyRequest::makeUpdate(
+ NamespaceString("test.user"),
+ query,
+ write_ops::UpdateModification::parseFromClassicUpdate(update));
request.setSort(sort);
BSONObj expectedObj(fromjson(R"json({
@@ -173,7 +194,10 @@ TEST(FindAndModifyRequest, UpdateWithHint) {
const BSONObj update(BSON("y" << 1));
const BSONObj hint(BSON("z" << -1));
- auto request = FindAndModifyRequest::makeUpdate(NamespaceString("test.user"), query, update);
+ auto request = FindAndModifyRequest::makeUpdate(
+ NamespaceString("test.user"),
+ query,
+ write_ops::UpdateModification::parseFromClassicUpdate(update));
request.setHint(hint);
BSONObj expectedObj(fromjson(R"json({
@@ -192,7 +216,10 @@ TEST(FindAndModifyRequest, UpdateWithCollation) {
const BSONObj collation(BSON("locale"
<< "en_US"));
- auto request = FindAndModifyRequest::makeUpdate(NamespaceString("test.user"), query, update);
+ auto request = FindAndModifyRequest::makeUpdate(
+ NamespaceString("test.user"),
+ query,
+ write_ops::UpdateModification::parseFromClassicUpdate(update));
request.setCollation(collation);
BSONObj expectedObj(fromjson(R"json({
@@ -210,7 +237,10 @@ TEST(FindAndModifyRequest, UpdateWithArrayFilters) {
const BSONObj update(BSON("y" << 1));
const std::vector<BSONObj> arrayFilters{BSON("i" << 0)};
- auto request = FindAndModifyRequest::makeUpdate(NamespaceString("test.user"), query, update);
+ auto request = FindAndModifyRequest::makeUpdate(
+ NamespaceString("test.user"),
+ query,
+ write_ops::UpdateModification::parseFromClassicUpdate(update));
request.setArrayFilters(arrayFilters);
BSONObj expectedObj(fromjson(R"json({
@@ -228,7 +258,10 @@ TEST(FindAndModifyRequest, UpdateWithWriteConcern) {
const BSONObj update(BSON("y" << 1));
const WriteConcernOptions writeConcern(2, WriteConcernOptions::SyncMode::FSYNC, 150);
- auto request = FindAndModifyRequest::makeUpdate(NamespaceString("test.user"), query, update);
+ auto request = FindAndModifyRequest::makeUpdate(
+ NamespaceString("test.user"),
+ query,
+ write_ops::UpdateModification::parseFromClassicUpdate(update));
request.setWriteConcern(writeConcern);
BSONObj expectedObj(fromjson(R"json({
@@ -245,7 +278,10 @@ TEST(FindAndModifyRequest, UpdateWithRuntimeConstants) {
const BSONObj query(BSON("x" << 1));
const BSONObj update(BSON("y" << 1));
- auto request = FindAndModifyRequest::makeUpdate(NamespaceString("test.user"), query, update);
+ auto request = FindAndModifyRequest::makeUpdate(
+ NamespaceString("test.user"),
+ query,
+ write_ops::UpdateModification::parseFromClassicUpdate(update));
request.setRuntimeConstants({Date_t(), Timestamp(1, 0)});
BSONObj expectedObj(fromjson(R"json({
@@ -273,7 +309,10 @@ TEST(FindAndModifyRequest, UpdateWithFullSpec) {
const WriteConcernOptions writeConcern(2, WriteConcernOptions::SyncMode::FSYNC, 150);
auto rtc = RuntimeConstants{Date_t(), Timestamp(1, 0)};
- auto request = FindAndModifyRequest::makeUpdate(NamespaceString("test.user"), query, update);
+ auto request = FindAndModifyRequest::makeUpdate(
+ NamespaceString("test.user"),
+ query,
+ write_ops::UpdateModification::parseFromClassicUpdate(update));
request.setFieldProjection(field);
request.setShouldReturnNew(true);
request.setSort(sort);
diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp
index 78bc154592f..7a0a79476e0 100644
--- a/src/mongo/db/repl/oplog.cpp
+++ b/src/mongo/db/repl/oplog.cpp
@@ -1196,7 +1196,8 @@ Status applyOperation_inlock(OperationContext* opCtx,
auto request = UpdateRequest();
request.setNamespaceString(requestNss);
request.setQuery(b.done());
- request.setUpdateModification(o);
+ request.setUpdateModification(
+ write_ops::UpdateModification::parseFromClassicUpdate(o));
request.setUpsert();
request.setFromOplogApplication(true);
diff --git a/src/mongo/db/repl/rs_rollback.cpp b/src/mongo/db/repl/rs_rollback.cpp
index e74f850acfb..fb186e4192c 100644
--- a/src/mongo/db/repl/rs_rollback.cpp
+++ b/src/mongo/db/repl/rs_rollback.cpp
@@ -1863,7 +1863,8 @@ void rollback_internal::syncFixUp(OperationContext* opCtx,
request.setNamespaceString(*nss);
request.setQuery(pattern);
- request.setUpdateModification(idAndDoc.second);
+ request.setUpdateModification(
+ write_ops::UpdateModification::parseFromClassicUpdate(idAndDoc.second));
request.setGod();
request.setUpsert();
diff --git a/src/mongo/db/repl/storage_interface_impl.cpp b/src/mongo/db/repl/storage_interface_impl.cpp
index a6e9efc5011..08269bdfaad 100644
--- a/src/mongo/db/repl/storage_interface_impl.cpp
+++ b/src/mongo/db/repl/storage_interface_impl.cpp
@@ -975,7 +975,8 @@ Status StorageInterfaceImpl::upsertById(OperationContext* opCtx,
auto request = UpdateRequest();
request.setNamespaceString(collection->ns());
request.setQuery(query);
- request.setUpdateModification(update);
+ request.setUpdateModification(
+ write_ops::UpdateModification::parseFromClassicUpdate(update));
request.setUpsert(true);
invariant(!request.isMulti()); // This follows from using an exact _id query.
invariant(!request.shouldReturnAnyDocs());
@@ -1025,7 +1026,8 @@ Status StorageInterfaceImpl::putSingleton(OperationContext* opCtx,
auto request = UpdateRequest();
request.setNamespaceString(nss);
request.setQuery({});
- request.setUpdateModification(update.obj);
+ request.setUpdateModification(
+ write_ops::UpdateModification::parseFromClassicUpdate(update.obj));
request.setUpsert(true);
return _updateWithQuery(opCtx, request, update.timestamp);
}
@@ -1037,7 +1039,8 @@ Status StorageInterfaceImpl::updateSingleton(OperationContext* opCtx,
auto request = UpdateRequest();
request.setNamespaceString(nss);
request.setQuery(query);
- request.setUpdateModification(update.obj);
+ request.setUpdateModification(
+ write_ops::UpdateModification::parseFromClassicUpdate(update.obj));
invariant(!request.isUpsert());
return _updateWithQuery(opCtx, request, update.timestamp);
}
diff --git a/src/mongo/db/s/add_shard_util.cpp b/src/mongo/db/s/add_shard_util.cpp
index 0dae94c0102..d1b9b6da219 100644
--- a/src/mongo/db/s/add_shard_util.cpp
+++ b/src/mongo/db/s/add_shard_util.cpp
@@ -65,7 +65,8 @@ BSONObj createShardIdentityUpsertForAddShard(const AddShard& addShardCmd) {
updateOp.setUpdates({[&] {
write_ops::UpdateOpEntry entry;
entry.setQ(BSON("_id" << kShardIdentityDocumentId));
- entry.setU(addShardCmd.getShardIdentity().toBSON());
+ entry.setU(write_ops::UpdateModification::parseFromClassicUpdate(
+ addShardCmd.getShardIdentity().toBSON()));
entry.setUpsert(true);
return entry;
}()});
diff --git a/src/mongo/db/s/config/config_server_test_fixture.cpp b/src/mongo/db/s/config/config_server_test_fixture.cpp
index 964bdb97428..8710cb63fcd 100644
--- a/src/mongo/db/s/config/config_server_test_fixture.cpp
+++ b/src/mongo/db/s/config/config_server_test_fixture.cpp
@@ -233,22 +233,23 @@ Status ConfigServerTestFixture::updateToConfigCollection(OperationContext* opCtx
const BSONObj& query,
const BSONObj& update,
const bool upsert) {
- auto updateResponse = getConfigShard()->runCommand(opCtx,
- kReadPref,
- ns.db().toString(),
- [&]() {
- write_ops::Update updateOp(ns);
- updateOp.setUpdates({[&] {
- write_ops::UpdateOpEntry entry;
- entry.setQ(query);
- entry.setU(update);
- entry.setUpsert(upsert);
- return entry;
- }()});
- return updateOp.toBSON({});
- }(),
- Shard::kDefaultConfigCommandTimeout,
- Shard::RetryPolicy::kNoRetry);
+ auto updateResponse = getConfigShard()->runCommand(
+ opCtx,
+ kReadPref,
+ ns.db().toString(),
+ [&]() {
+ write_ops::Update updateOp(ns);
+ updateOp.setUpdates({[&] {
+ write_ops::UpdateOpEntry entry;
+ entry.setQ(query);
+ entry.setU(write_ops::UpdateModification::parseFromClassicUpdate(update));
+ entry.setUpsert(upsert);
+ return entry;
+ }()});
+ return updateOp.toBSON({});
+ }(),
+ Shard::kDefaultConfigCommandTimeout,
+ Shard::RetryPolicy::kNoRetry);
BatchedCommandResponse batchResponse;
diff --git a/src/mongo/db/s/config/sharding_catalog_manager_collection_operations.cpp b/src/mongo/db/s/config/sharding_catalog_manager_collection_operations.cpp
index 43ca6be9c7c..d6544e922d2 100644
--- a/src/mongo/db/s/config/sharding_catalog_manager_collection_operations.cpp
+++ b/src/mongo/db/s/config/sharding_catalog_manager_collection_operations.cpp
@@ -152,7 +152,7 @@ Status updateConfigDocumentInTxn(OperationContext* opCtx,
updateOp.setUpdates({[&] {
write_ops::UpdateOpEntry entry;
entry.setQ(query);
- entry.setU(update);
+ entry.setU(write_ops::UpdateModification::parseFromClassicUpdate(update));
entry.setUpsert(upsert);
entry.setMulti(useMultiUpdate);
return entry;
diff --git a/src/mongo/db/s/migration_util.cpp b/src/mongo/db/s/migration_util.cpp
index 95b16ea0254..83eff60f19d 100644
--- a/src/mongo/db/s/migration_util.cpp
+++ b/src/mongo/db/s/migration_util.cpp
@@ -667,8 +667,9 @@ void markAsReadyRangeDeletionTaskOnRecipient(OperationContext* opCtx,
const UUID& migrationId) {
write_ops::Update updateOp(NamespaceString::kRangeDeletionNamespace);
auto queryFilter = BSON(RangeDeletionTask::kIdFieldName << migrationId);
- auto updateModification = write_ops::UpdateModification(
- BSON("$unset" << BSON(RangeDeletionTask::kPendingFieldName << "")));
+ auto updateModification =
+ write_ops::UpdateModification(write_ops::UpdateModification::parseFromClassicUpdate(
+ BSON("$unset" << BSON(RangeDeletionTask::kPendingFieldName << ""))));
write_ops::UpdateOpEntry updateEntry(queryFilter, updateModification);
updateEntry.setMulti(false);
updateEntry.setUpsert(false);
@@ -700,7 +701,8 @@ void advanceTransactionOnRecipient(OperationContext* opCtx,
write_ops::Update updateOp(NamespaceString::kServerConfigurationNamespace);
auto queryFilter = BSON("_id"
<< "migrationCoordinatorStats");
- auto updateModification = write_ops::UpdateModification(BSON("$inc" << BSON("count" << 1)));
+ auto updateModification = write_ops::UpdateModification(
+ write_ops::UpdateModification::parseFromClassicUpdate(BSON("$inc" << BSON("count" << 1))));
write_ops::UpdateOpEntry updateEntry(queryFilter, updateModification);
updateEntry.setMulti(false);
diff --git a/src/mongo/db/s/resharding/resharding_coordinator_service.cpp b/src/mongo/db/s/resharding/resharding_coordinator_service.cpp
index f21e90ccb9f..f43d6c0e031 100644
--- a/src/mongo/db/s/resharding/resharding_coordinator_service.cpp
+++ b/src/mongo/db/s/resharding/resharding_coordinator_service.cpp
@@ -248,7 +248,8 @@ void ReshardingCoordinatorService::ReshardingCoordinator::_runUpdates(
updateOp.setUpdates({[&] {
write_ops::UpdateOpEntry entry;
entry.setQ(_id);
- entry.setU(updatedStateDoc.toBSON());
+ entry.setU(
+ write_ops::UpdateModification::parseFromClassicUpdate(updatedStateDoc.toBSON()));
return entry;
}()});
return updateOp.serialize(
diff --git a/src/mongo/db/s/shard_local_test.cpp b/src/mongo/db/s/shard_local_test.cpp
index d7314c965cf..4945d7a1c04 100644
--- a/src/mongo/db/s/shard_local_test.cpp
+++ b/src/mongo/db/s/shard_local_test.cpp
@@ -100,7 +100,8 @@ void ShardLocalTest::tearDown() {
StatusWith<Shard::CommandResponse> ShardLocalTest::runFindAndModifyRunCommand(NamespaceString nss,
BSONObj find,
BSONObj set) {
- FindAndModifyRequest findAndModifyRequest = FindAndModifyRequest::makeUpdate(nss, find, set);
+ FindAndModifyRequest findAndModifyRequest = FindAndModifyRequest::makeUpdate(
+ nss, find, write_ops::UpdateModification::parseFromClassicUpdate(set));
findAndModifyRequest.setUpsert(true);
findAndModifyRequest.setShouldReturnNew(true);
findAndModifyRequest.setWriteConcern(WriteConcernOptions(
diff --git a/src/mongo/db/s/shard_metadata_util.cpp b/src/mongo/db/s/shard_metadata_util.cpp
index b9f369a7d69..c5f96374520 100644
--- a/src/mongo/db/s/shard_metadata_util.cpp
+++ b/src/mongo/db/s/shard_metadata_util.cpp
@@ -228,7 +228,7 @@ Status updateShardCollectionsEntry(OperationContext* opCtx,
updateOp.setUpdates({[&] {
write_ops::UpdateOpEntry entry;
entry.setQ(query);
- entry.setU(builder.obj());
+ entry.setU(write_ops::UpdateModification::parseFromClassicUpdate(builder.obj()));
entry.setUpsert(upsert);
return entry;
}()});
@@ -271,7 +271,7 @@ Status updateShardDatabasesEntry(OperationContext* opCtx,
updateOp.setUpdates({[&] {
write_ops::UpdateOpEntry entry;
entry.setQ(query);
- entry.setU(builder.obj());
+ entry.setU(write_ops::UpdateModification::parseFromClassicUpdate(builder.obj()));
entry.setUpsert(upsert);
return entry;
}()});
diff --git a/src/mongo/db/s/sharding_initialization_mongod.cpp b/src/mongo/db/s/sharding_initialization_mongod.cpp
index 2012a41690b..0e0fb8d6de0 100644
--- a/src/mongo/db/s/sharding_initialization_mongod.cpp
+++ b/src/mongo/db/s/sharding_initialization_mongod.cpp
@@ -468,7 +468,8 @@ void ShardingInitializationMongoD::updateShardIdentityConfigString(
auto updateReq = UpdateRequest();
updateReq.setNamespaceString(NamespaceString::kServerConfigurationNamespace);
updateReq.setQuery(BSON("_id" << ShardIdentityType::IdName));
- updateReq.setUpdateModification(updateObj);
+ updateReq.setUpdateModification(
+ write_ops::UpdateModification::parseFromClassicUpdate(updateObj));
try {
AutoGetOrCreateDb autoDb(
diff --git a/src/mongo/db/s/sharding_state_recovery.cpp b/src/mongo/db/s/sharding_state_recovery.cpp
index 9ef5345f44a..b2628aa3334 100644
--- a/src/mongo/db/s/sharding_state_recovery.cpp
+++ b/src/mongo/db/s/sharding_state_recovery.cpp
@@ -160,7 +160,8 @@ Status modifyRecoveryDocument(OperationContext* opCtx,
auto updateReq = UpdateRequest();
updateReq.setNamespaceString(NamespaceString::kServerConfigurationNamespace);
updateReq.setQuery(RecoveryDocument::getQuery());
- updateReq.setUpdateModification(updateObj);
+ updateReq.setUpdateModification(
+ write_ops::UpdateModification::parseFromClassicUpdate(updateObj));
updateReq.setUpsert();
UpdateResult result = update(opCtx, autoGetOrCreateDb->getDb(), updateReq);
diff --git a/src/mongo/db/s/transaction_coordinator_util.cpp b/src/mongo/db/s/transaction_coordinator_util.cpp
index e682b5c56d1..0e1cfa83006 100644
--- a/src/mongo/db/s/transaction_coordinator_util.cpp
+++ b/src/mongo/db/s/transaction_coordinator_util.cpp
@@ -145,7 +145,7 @@ repl::OpTime persistParticipantListBlocking(OperationContext* opCtx,
TransactionCoordinatorDocument doc;
doc.setId(std::move(sessionInfo));
doc.setParticipants(std::move(participantList));
- entry.setU(doc.toBSON());
+ entry.setU(write_ops::UpdateModification::parseFromClassicUpdate(doc.toBSON()));
entry.setUpsert(true);
return entry;
@@ -337,13 +337,13 @@ repl::OpTime persistDecisionBlocking(OperationContext* opCtx,
<< buildParticipantListMatchesConditions(participantList) << "$or"
<< BSON_ARRAY(noDecision << sameDecision)));
- entry.setU([&] {
+ entry.setU(write_ops::UpdateModification::parseFromClassicUpdate([&] {
TransactionCoordinatorDocument doc;
doc.setId(sessionInfo);
doc.setParticipants(std::move(participantList));
doc.setDecision(decision);
return doc.toBSON();
- }());
+ }()));
return entry;
}()});
diff --git a/src/mongo/db/transaction_participant.cpp b/src/mongo/db/transaction_participant.cpp
index d90a57692eb..f4e650b47f3 100644
--- a/src/mongo/db/transaction_participant.cpp
+++ b/src/mongo/db/transaction_participant.cpp
@@ -2355,7 +2355,8 @@ UpdateRequest TransactionParticipant::Participant::_makeUpdateRequest(
auto updateRequest = UpdateRequest();
updateRequest.setNamespaceString(NamespaceString::kSessionTransactionsTableNamespace);
- updateRequest.setUpdateModification(sessionTxnRecord.toBSON());
+ updateRequest.setUpdateModification(
+ write_ops::UpdateModification::parseFromClassicUpdate(sessionTxnRecord.toBSON()));
updateRequest.setQuery(BSON(SessionTxnRecord::kSessionIdFieldName << _sessionId().toBSON()));
updateRequest.setUpsert(true);
diff --git a/src/mongo/db/update/update_driver_test.cpp b/src/mongo/db/update/update_driver_test.cpp
index f490fec9a24..f93d5343661 100644
--- a/src/mongo/db/update/update_driver_test.cpp
+++ b/src/mongo/db/update/update_driver_test.cpp
@@ -62,11 +62,15 @@ namespace {
using str::stream;
using unittest::assertGet;
+write_ops::UpdateModification makeUpdateMod(const BSONObj& bson) {
+ return write_ops::UpdateModification::parseFromClassicUpdate(bson);
+}
+
TEST(Parse, Normal) {
boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
UpdateDriver driver(expCtx);
std::map<StringData, std::unique_ptr<ExpressionWithPlaceholder>> arrayFilters;
- ASSERT_DOES_NOT_THROW(driver.parse(fromjson("{$set:{a:1}}"), arrayFilters));
+ ASSERT_DOES_NOT_THROW(driver.parse(makeUpdateMod(fromjson("{$set:{a:1}}")), arrayFilters));
ASSERT_FALSE(driver.type() == UpdateDriver::UpdateType::kReplacement);
}
@@ -74,7 +78,7 @@ TEST(Parse, MultiMods) {
boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
UpdateDriver driver(expCtx);
std::map<StringData, std::unique_ptr<ExpressionWithPlaceholder>> arrayFilters;
- ASSERT_DOES_NOT_THROW(driver.parse(fromjson("{$set:{a:1, b:1}}"), arrayFilters));
+ ASSERT_DOES_NOT_THROW(driver.parse(makeUpdateMod(fromjson("{$set:{a:1, b:1}}")), arrayFilters));
ASSERT_FALSE(driver.type() == UpdateDriver::UpdateType::kReplacement);
}
@@ -82,7 +86,8 @@ TEST(Parse, MixingMods) {
boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
UpdateDriver driver(expCtx);
std::map<StringData, std::unique_ptr<ExpressionWithPlaceholder>> arrayFilters;
- ASSERT_DOES_NOT_THROW(driver.parse(fromjson("{$set:{a:1}, $unset:{b:1}}"), arrayFilters));
+ ASSERT_DOES_NOT_THROW(
+ driver.parse(makeUpdateMod(fromjson("{$set:{a:1}, $unset:{b:1}}")), arrayFilters));
ASSERT_FALSE(driver.type() == UpdateDriver::UpdateType::kReplacement);
}
@@ -90,7 +95,8 @@ TEST(Parse, ObjectReplacment) {
boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
UpdateDriver driver(expCtx);
std::map<StringData, std::unique_ptr<ExpressionWithPlaceholder>> arrayFilters;
- ASSERT_DOES_NOT_THROW(driver.parse(fromjson("{obj: \"obj replacement\"}"), arrayFilters));
+ ASSERT_DOES_NOT_THROW(
+ driver.parse(makeUpdateMod(fromjson("{obj: \"obj replacement\"}")), arrayFilters));
ASSERT_TRUE(driver.type() == UpdateDriver::UpdateType::kReplacement);
}
@@ -122,14 +128,14 @@ TEST(Parse, EmptyMod) {
UpdateDriver driver(expCtx);
std::map<StringData, std::unique_ptr<ExpressionWithPlaceholder>> arrayFilters;
// Verifies that {$set: {}} is accepted.
- ASSERT_DOES_NOT_THROW(driver.parse(fromjson("{$set: {}}"), arrayFilters));
+ ASSERT_DOES_NOT_THROW(driver.parse(makeUpdateMod(fromjson("{$set: {}}")), arrayFilters));
}
TEST(Parse, WrongMod) {
boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
UpdateDriver driver(expCtx);
std::map<StringData, std::unique_ptr<ExpressionWithPlaceholder>> arrayFilters;
- ASSERT_THROWS_CODE_AND_WHAT(driver.parse(fromjson("{$xyz:{a:1}}"), arrayFilters),
+ ASSERT_THROWS_CODE_AND_WHAT(driver.parse(makeUpdateMod(fromjson("{$xyz:{a:1}}")), arrayFilters),
AssertionException,
ErrorCodes::FailedToParse,
"Unknown modifier: $xyz. Expected a valid update modifier or "
@@ -140,11 +146,12 @@ TEST(Parse, WrongType) {
boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
UpdateDriver driver(expCtx);
std::map<StringData, std::unique_ptr<ExpressionWithPlaceholder>> arrayFilters;
- ASSERT_THROWS_CODE_AND_WHAT(driver.parse(fromjson("{$set:[{a:1}]}"), arrayFilters),
- AssertionException,
- ErrorCodes::FailedToParse,
- "Modifiers operate on fields but we found type array instead. For "
- "example: {$mod: {<field>: ...}} not {$set: [ { a: 1 } ]}");
+ ASSERT_THROWS_CODE_AND_WHAT(
+ driver.parse(makeUpdateMod(fromjson("{$set:[{a:1}]}")), arrayFilters),
+ AssertionException,
+ ErrorCodes::FailedToParse,
+ "Modifiers operate on fields but we found type array instead. For "
+ "example: {$mod: {<field>: ...}} not {$set: [ { a: 1 } ]}");
}
TEST(Parse, ModsWithLaterObjReplacement) {
@@ -152,7 +159,8 @@ TEST(Parse, ModsWithLaterObjReplacement) {
UpdateDriver driver(expCtx);
std::map<StringData, std::unique_ptr<ExpressionWithPlaceholder>> arrayFilters;
ASSERT_THROWS_CODE_AND_WHAT(
- driver.parse(fromjson("{$set:{a:1}, obj: \"obj replacement\"}"), arrayFilters),
+ driver.parse(makeUpdateMod(fromjson("{$set:{a:1}, obj: \"obj replacement\"}")),
+ arrayFilters),
AssertionException,
ErrorCodes::FailedToParse,
"Unknown modifier: obj. Expected a valid update modifier or pipeline-style update "
@@ -163,7 +171,8 @@ TEST(Parse, SetOnInsert) {
boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
UpdateDriver driver(expCtx);
std::map<StringData, std::unique_ptr<ExpressionWithPlaceholder>> arrayFilters;
- ASSERT_DOES_NOT_THROW(driver.parse(fromjson("{$setOnInsert:{a:1}}"), arrayFilters));
+ ASSERT_DOES_NOT_THROW(
+ driver.parse(makeUpdateMod(fromjson("{$setOnInsert:{a:1}}")), arrayFilters));
ASSERT_FALSE(driver.type() == UpdateDriver::UpdateType::kReplacement);
}
@@ -174,7 +183,7 @@ TEST(Collator, SetCollationUpdatesModifierInterfaces) {
UpdateDriver driver(expCtx);
std::map<StringData, std::unique_ptr<ExpressionWithPlaceholder>> arrayFilters;
- ASSERT_DOES_NOT_THROW(driver.parse(updateDocument, arrayFilters));
+ ASSERT_DOES_NOT_THROW(driver.parse(makeUpdateMod(updateDocument), arrayFilters));
const bool validateForStorage = true;
const FieldRefSet emptyImmutablePaths;
@@ -209,8 +218,8 @@ public:
new ExpressionContext(_opCtx.get(), nullptr, NamespaceString("foo")))),
_driverRepl(new UpdateDriver(
new ExpressionContext(_opCtx.get(), nullptr, NamespaceString("foo")))) {
- _driverOps->parse(fromjson("{$set:{'_':1}}"), _arrayFilters);
- _driverRepl->parse(fromjson("{}"), _arrayFilters);
+ _driverOps->parse(makeUpdateMod(fromjson("{$set:{'_':1}}")), _arrayFilters);
+ _driverRepl->parse(makeUpdateMod(fromjson("{}")), _arrayFilters);
}
mutablebson::Document& doc() {
@@ -578,6 +587,7 @@ public:
ASSERT(expr->getPlaceholder());
arrayFilters[expr->getPlaceholder().get()] = std::move(expr);
}
+
_driver->setFromOplogApplication(fromOplog);
_driver->refreshIndexKeys(indexData);
_driver->parse(updateSpec, arrayFilters);
@@ -607,61 +617,61 @@ public:
TEST_F(ModifiedPathsTestFixture, SetFieldInRoot) {
BSONObj spec = fromjson("{$set: {a: 1}}");
mutablebson::Document doc(fromjson("{a: 0}"));
- runUpdate(&doc, spec);
+ runUpdate(&doc, makeUpdateMod(spec));
ASSERT_EQ(_modifiedPaths, "{a}");
}
TEST_F(ModifiedPathsTestFixture, IncFieldInRoot) {
BSONObj spec = fromjson("{$inc: {a: 1}}");
mutablebson::Document doc(fromjson("{a: 0}"));
- runUpdate(&doc, spec);
+ runUpdate(&doc, makeUpdateMod(spec));
ASSERT_EQ(_modifiedPaths, "{a}");
}
TEST_F(ModifiedPathsTestFixture, UnsetFieldInRoot) {
BSONObj spec = fromjson("{$unset: {a: ''}}");
mutablebson::Document doc(fromjson("{a: 0}"));
- runUpdate(&doc, spec);
+ runUpdate(&doc, makeUpdateMod(spec));
ASSERT_EQ(_modifiedPaths, "{a}");
}
TEST_F(ModifiedPathsTestFixture, UpdateArrayElement) {
BSONObj spec = fromjson("{$set: {'a.0.b': 1}}");
mutablebson::Document doc(fromjson("{a: [{b: 0}]}"));
- runUpdate(&doc, spec);
+ runUpdate(&doc, makeUpdateMod(spec));
ASSERT_EQ(_modifiedPaths, "{a.0.b}");
}
TEST_F(ModifiedPathsTestFixture, SetBeyondTheEndOfArrayShouldReturnPathToArray) {
BSONObj spec = fromjson("{$set: {'a.1.b': 1}}");
mutablebson::Document doc(fromjson("{a: [{b: 0}]}"));
- runUpdate(&doc, spec);
+ runUpdate(&doc, makeUpdateMod(spec));
ASSERT_EQ(_modifiedPaths, "{a}");
}
TEST_F(ModifiedPathsTestFixture, InsertingAndUpdatingArrayShouldReturnPathToArray) {
BSONObj spec = fromjson("{$set: {'a.0.b': 1, 'a.1.c': 2}}");
mutablebson::Document doc(fromjson("{a: [{b: 0}]}"));
- runUpdate(&doc, spec);
+ runUpdate(&doc, makeUpdateMod(spec));
ASSERT_EQ(_modifiedPaths, "{a}");
spec = fromjson("{$set: {'a.10.b': 1, 'a.1.c': 2}}");
mutablebson::Document doc2(fromjson("{a: [{b: 0}, {b: 0}]}"));
- runUpdate(&doc2, spec);
+ runUpdate(&doc2, makeUpdateMod(spec));
ASSERT_EQ(_modifiedPaths, "{a}");
}
TEST_F(ModifiedPathsTestFixture, UpdateWithPositionalOperator) {
BSONObj spec = fromjson("{$set: {'a.$': 1}}");
mutablebson::Document doc(fromjson("{a: [0, 1, 2]}"));
- runUpdate(&doc, spec, "0"_sd);
+ runUpdate(&doc, makeUpdateMod(spec), "0"_sd);
ASSERT_EQ(_modifiedPaths, "{a.0}");
}
TEST_F(ModifiedPathsTestFixture, UpdateWithPositionalOperatorToNestedField) {
BSONObj spec = fromjson("{$set: {'a.$.b': 1}}");
mutablebson::Document doc(fromjson("{a: [{b: 1}, {b: 2}]}"));
- runUpdate(&doc, spec, "1"_sd);
+ runUpdate(&doc, makeUpdateMod(spec), "1"_sd);
ASSERT_EQ(_modifiedPaths, "{a.1.b}");
}
@@ -669,7 +679,7 @@ TEST_F(ModifiedPathsTestFixture, ArrayFilterThatMatchesNoElements) {
BSONObj spec = fromjson("{$set: {'a.$[i]': 1}}");
BSONObj arrayFilter = fromjson("{i: 0}");
mutablebson::Document doc(fromjson("{a: [1, 2, 3]}"));
- runUpdate(&doc, spec, ""_sd, {arrayFilter});
+ runUpdate(&doc, makeUpdateMod(spec), ""_sd, {arrayFilter});
ASSERT_EQ(_modifiedPaths, "{a}");
}
@@ -677,7 +687,7 @@ TEST_F(ModifiedPathsTestFixture, ArrayFilterThatMatchesNoElements) {
TEST_F(ModifiedPathsTestFixture, ReplaceFullDocumentAlwaysAffectsIndex) {
BSONObj spec = fromjson("{a: 1, b: 1}}");
mutablebson::Document doc(fromjson("{a: 0, b: 0}"));
- runUpdate(&doc, spec);
+ runUpdate(&doc, makeUpdateMod(spec));
ASSERT_EQ(_modifiedPaths, "{}");
}
@@ -692,13 +702,21 @@ TEST_F(ModifiedPathsTestFixture, PipelineUpdatesAlwaysAffectsIndex) {
TEST_F(ModifiedPathsTestFixture, DeltaUpdateNotAffectingIndex) {
BSONObj spec = fromjson("{d: {a: false}}");
mutablebson::Document doc(fromjson("{a: [{b: 0}]}"));
- runUpdate(&doc, write_ops::UpdateModification(spec, {}), ""_sd, {}, true /* fromOplog */);
+ runUpdate(&doc,
+ write_ops::UpdateModification::parseFromV2Delta(spec),
+ ""_sd,
+ {},
+ true /* fromOplog */);
ASSERT(!_driver->modsAffectIndices());
UpdateIndexData indexData;
indexData.addPath(FieldRef("p"));
- runUpdate(
- &doc, write_ops::UpdateModification(spec, {}), ""_sd, {}, true /* fromOplog */, &indexData);
+ runUpdate(&doc,
+ write_ops::UpdateModification::parseFromV2Delta(spec),
+ ""_sd,
+ {},
+ true /* fromOplog */,
+ &indexData);
ASSERT(!_driver->modsAffectIndices());
}
@@ -708,8 +726,12 @@ TEST_F(ModifiedPathsTestFixture, DeltaUpdateAffectingIndex) {
UpdateIndexData indexData;
indexData.addPath(FieldRef("q"));
indexData.addPath(FieldRef("a.p"));
- runUpdate(
- &doc, write_ops::UpdateModification(spec, {}), ""_sd, {}, true /* fromOplog */, &indexData);
+ runUpdate(&doc,
+ write_ops::UpdateModification::parseFromV2Delta(spec),
+ ""_sd,
+ {},
+ true /* fromOplog */,
+ &indexData);
ASSERT(_driver->modsAffectIndices());
}
diff --git a/src/mongo/db/update/update_serialization_test.cpp b/src/mongo/db/update/update_serialization_test.cpp
index 734d8c19e6a..8fa262ab46a 100644
--- a/src/mongo/db/update/update_serialization_test.cpp
+++ b/src/mongo/db/update/update_serialization_test.cpp
@@ -55,7 +55,7 @@ auto updateRoundTrip(const char* json, const std::vector<std::string> filterName
std::map<StringData, std::unique_ptr<ExpressionWithPlaceholder>> filters;
for (const auto& name : filterNames)
filters[name] = nullptr;
- driver.parse(bson, filters);
+ driver.parse(write_ops::UpdateModification::parseFromClassicUpdate(bson), filters);
return mongo::tojson(driver.serialize().getDocument().toBson(),
mongo::JsonStringFormat::LegacyStrict);
}