summaryrefslogtreecommitdiff
path: root/src/mongo/db/ops/update_driver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/ops/update_driver.cpp')
-rw-r--r--src/mongo/db/ops/update_driver.cpp20
1 files changed, 15 insertions, 5 deletions
diff --git a/src/mongo/db/ops/update_driver.cpp b/src/mongo/db/ops/update_driver.cpp
index a99376174a8..94292e24874 100644
--- a/src/mongo/db/ops/update_driver.cpp
+++ b/src/mongo/db/ops/update_driver.cpp
@@ -288,11 +288,21 @@ Status UpdateDriver::update(StringData matchedField,
// is not a no-op and it is in a valid context -- then we switch back to a
// non-in-place mode.
//
- // TODO: make mightBeIndexed and fieldRef like each other.
- if (!_affectIndices && !execInfo.noOp && _indexedFields &&
- _indexedFields->mightBeIndexed(execInfo.fieldRef[i]->dottedField())) {
- _affectIndices = true;
- doc->disableInPlaceUpdates();
+ // To determine if indexes are affected: If we did not create a new element in an array,
+ // check whether the full path affects indexes. If we did create a new element in an
+ // array, check whether the array itself might affect any indexes. This is necessary
+ // because if there is an index {"a.b": 1}, and we set "a.1.c" and implicitly create an
+ // array element in "a", then we may need to add a null key to the index {"a.b": 1},
+ // even though "a.1.c" does not appear to affect the index.
+ if (!_affectIndices && !execInfo.noOp && _indexedFields) {
+ auto pathLengthForIndexCheck = execInfo.indexOfArrayWithNewElement[i]
+ ? *execInfo.indexOfArrayWithNewElement[i] + 1
+ : execInfo.fieldRef[i]->numParts();
+ if (_indexedFields->mightBeIndexed(
+ execInfo.fieldRef[i]->dottedSubstring(0, pathLengthForIndexCheck))) {
+ _affectIndices = true;
+ doc->disableInPlaceUpdates();
+ }
}
}