summaryrefslogtreecommitdiff
path: root/src/mongo/db/exec/update.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/exec/update.cpp')
-rw-r--r--src/mongo/db/exec/update.cpp41
1 files changed, 17 insertions, 24 deletions
diff --git a/src/mongo/db/exec/update.cpp b/src/mongo/db/exec/update.cpp
index f3a12e32159..53ba1fc9617 100644
--- a/src/mongo/db/exec/update.cpp
+++ b/src/mongo/db/exec/update.cpp
@@ -176,6 +176,14 @@ UpdateStage::UpdateStage(OperationContext* opCtx,
_doc(params.driver->getDocument()) {
_children.emplace_back(child);
+ // Should the modifiers validate their embedded docs via storage_validation::storageValid()?
+ // Only user updates should be checked. Any system or replication stuff should pass through.
+ // Config db docs also do not get checked.
+ const auto request = _params.request;
+ _enforceOkForStorage =
+ !(request->isFromOplogApplication() || request->getNamespaceString().isConfigDB() ||
+ request->isFromMigration());
+
// Before we even start executing, we know whether or not this is a replacement
// style or $mod style update.
_specificStats.isDocReplacement = params.driver->isDocReplacement();
@@ -206,8 +214,7 @@ BSONObj UpdateStage::transformAndUpdate(const Snapshotted<BSONObj>& oldObj, Reco
bool docWasModified = false;
Status status = Status::OK();
- const bool validateForStorage = getOpCtx()->writesAreReplicated() &&
- !request->isFromMigration() && driver->modOptions().enforceOkForStorage;
+ const bool validateForStorage = getOpCtx()->writesAreReplicated() && _enforceOkForStorage;
FieldRefSet immutablePaths;
if (getOpCtx()->writesAreReplicated() && !request->isFromMigration()) {
if (lifecycle) {
@@ -222,13 +229,8 @@ BSONObj UpdateStage::transformAndUpdate(const Snapshotted<BSONObj>& oldObj, Reco
}
if (!driver->needMatchDetails()) {
// If we don't need match details, avoid doing the rematch
- status = driver->update(StringData(),
- oldObj.value(),
- &_doc,
- validateForStorage,
- immutablePaths,
- &logObj,
- &docWasModified);
+ status = driver->update(
+ StringData(), &_doc, validateForStorage, immutablePaths, &logObj, &docWasModified);
} else {
// If there was a matched field, obtain it.
MatchDetails matchDetails;
@@ -241,13 +243,8 @@ BSONObj UpdateStage::transformAndUpdate(const Snapshotted<BSONObj>& oldObj, Reco
if (matchDetails.hasElemMatchKey())
matchedField = matchDetails.elemMatchKey();
- status = driver->update(matchedField,
- oldObj.value(),
- &_doc,
- validateForStorage,
- immutablePaths,
- &logObj,
- &docWasModified);
+ status = driver->update(
+ matchedField, &_doc, validateForStorage, immutablePaths, &logObj, &docWasModified);
}
if (!status.isOK()) {
@@ -375,6 +372,7 @@ BSONObj UpdateStage::applyUpdateOpsForInsert(OperationContext* opCtx,
mutablebson::Document* doc,
bool isInternalRequest,
const NamespaceString& ns,
+ bool enforceOkForStorage,
UpdateStats* stats) {
// Since this is an insert (no docs found and upsert:true), we will be logging it
// as an insert in the oplog. We don't need the driver's help to build the
@@ -393,18 +391,13 @@ BSONObj UpdateStage::applyUpdateOpsForInsert(OperationContext* opCtx,
}
immutablePaths.keepShortest(&idFieldRef);
- // The original document we compare changes to - immutable paths must not change
- BSONObj original;
-
if (cq) {
uassertStatusOK(driver->populateDocumentWithQueryFields(*cq, immutablePaths, *doc));
if (driver->isDocReplacement())
stats->fastmodinsert = true;
- original = doc->getObject();
} else {
fassert(17354, CanonicalQuery::isSimpleIdQuery(query));
BSONElement idElt = query[idFieldName];
- original = idElt.wrap();
fassert(17352, doc->root().appendElement(idElt));
}
@@ -414,8 +407,7 @@ BSONObj UpdateStage::applyUpdateOpsForInsert(OperationContext* opCtx,
if (isInternalRequest) {
immutablePaths.clear();
}
- Status updateStatus =
- driver->update(StringData(), original, doc, validateForStorage, immutablePaths);
+ Status updateStatus = driver->update(StringData(), doc, validateForStorage, immutablePaths);
if (!updateStatus.isOK()) {
uasserted(16836, updateStatus.reason());
}
@@ -432,7 +424,7 @@ BSONObj UpdateStage::applyUpdateOpsForInsert(OperationContext* opCtx,
// that contains all the immutable keys and can be stored if it isn't coming
// from a migration or via replication.
if (!isInternalRequest) {
- if (driver->modOptions().enforceOkForStorage) {
+ if (enforceOkForStorage) {
storage_validation::storageValid(*doc);
}
checkImmutablePathsPresent(*doc, immutablePaths);
@@ -463,6 +455,7 @@ void UpdateStage::doInsert() {
&_doc,
isInternalRequest,
request->getNamespaceString(),
+ _enforceOkForStorage,
&_specificStats);
_specificStats.objInserted = newObj;