diff options
author | Gregory Noma <gregory.noma@gmail.com> | 2021-09-01 13:10:51 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-10-07 15:38:57 +0000 |
commit | 3d09afb599a8cb32d1a78957572e5198477b4b46 (patch) | |
tree | c8ef7e1dab8d5ad23a7de39cae80824e86b1e2d6 /src/mongo/db/timeseries | |
parent | b82e60b2e4a54b946b1f4f5a5479a05166689e3a (diff) | |
download | mongo-3d09afb599a8cb32d1a78957572e5198477b4b46.tar.gz |
SERVER-59720 Correctly handle $rename in time-series metaField-only updates
(cherry picked from commit 5de2aec4aee639d03b40bcb133ce1674693552af)
Diffstat (limited to 'src/mongo/db/timeseries')
-rw-r--r-- | src/mongo/db/timeseries/timeseries_update_delete_util.cpp | 29 | ||||
-rw-r--r-- | src/mongo/db/timeseries/timeseries_update_delete_util_test.cpp | 58 |
2 files changed, 62 insertions, 25 deletions
diff --git a/src/mongo/db/timeseries/timeseries_update_delete_util.cpp b/src/mongo/db/timeseries/timeseries_update_delete_util.cpp index e84f93c82f3..a9c3437fc45 100644 --- a/src/mongo/db/timeseries/timeseries_update_delete_util.cpp +++ b/src/mongo/db/timeseries/timeseries_update_delete_util.cpp @@ -179,12 +179,16 @@ bool updateOnlyModifiesMetaField(OperationContext* opCtx, return std::all_of(document.begin(), document.end(), [metaField](const auto& updatePair) { // updatePair = <updateOperator> : {<field1> : <value1>, ... } // updatePair.embeddedObject() = {<field1> : <value1>, ... } - return std::all_of(updatePair.embeddedObject().begin(), - updatePair.embeddedObject().end(), - [metaField](const auto& fieldValuePair) { - return isMetaFieldFirstElementOfDottedPathField( - fieldValuePair.fieldNameStringData(), metaField); - }); + return std::all_of( + updatePair.embeddedObject().begin(), + updatePair.embeddedObject().end(), + [metaField, op = updatePair.fieldNameStringData()](const auto& fieldValuePair) { + return isMetaFieldFirstElementOfDottedPathField( + fieldValuePair.fieldNameStringData(), metaField) && + (op != "$rename" || + isMetaFieldFirstElementOfDottedPathField(fieldValuePair.valuestrsafe(), + metaField)); + }); }); } @@ -223,7 +227,18 @@ write_ops::UpdateModification translateUpdate(const write_ops::UpdateModificatio // and replace it if it is the metaField. for (auto fieldValuePair = updatePair.leftChild(); fieldValuePair.ok(); fieldValuePair = fieldValuePair.rightSibling()) { - replaceQueryMetaFieldName(fieldValuePair, fieldValuePair.getFieldName(), metaField); + auto fieldName = fieldValuePair.getFieldName(); + if (isMetaFieldFirstElementOfDottedPathField(fieldName, metaField)) { + invariantStatusOK(fieldValuePair.rename(getRenamedField(fieldName, "meta"))); + } + + // If this is a $rename, we may also need to translate the value. + if (updatePair.getFieldName() == "$rename" && fieldValuePair.isType(BSONType::String) && + isMetaFieldFirstElementOfDottedPathField(fieldValuePair.getValueString(), + metaField)) { + invariantStatusOK(fieldValuePair.setValueString( + getRenamedField(fieldValuePair.getValueString(), "meta"))); + } } } diff --git a/src/mongo/db/timeseries/timeseries_update_delete_util_test.cpp b/src/mongo/db/timeseries/timeseries_update_delete_util_test.cpp index cbe47b738e6..81f5bc00fb9 100644 --- a/src/mongo/db/timeseries/timeseries_update_delete_util_test.cpp +++ b/src/mongo/db/timeseries/timeseries_update_delete_util_test.cpp @@ -395,20 +395,43 @@ TEST_F(TimeseriesUpdateDeleteUtilTest, UpdateOnlyModifiesMetaField) { << "inc" << BSON(_metaField + "ggg" << 10))), _metaField)); - // TODO: SERVER-59173 Modify this test since renaming the metaField is not allowed. - // {$rename: {"tag.a.a": "A", "tag.b": "B"}} + // {$rename: {"tag.a": "tag.b"}} ASSERT_TRUE(timeseries::updateOnlyModifiesMetaField( _opCtx.get(), _ns, write_ops::UpdateModification::parseFromClassicUpdate( + BSON("$rename" << BSON(_metaField + ".a" << _metaField + ".b"))), + _metaField)); + + // {$rename: {"tag.a": "tag.b", "A": "tag.A"}} + ASSERT_FALSE(timeseries::updateOnlyModifiesMetaField( + _opCtx.get(), + _ns, + write_ops::UpdateModification::parseFromClassicUpdate( + BSON("$rename" << BSON(_metaField + ".a" << _metaField + ".b" + << "A" << _metaField + ".A"))), + _metaField)); + + // {$rename: {"tag": "notTag"}} + ASSERT_FALSE(timeseries::updateOnlyModifiesMetaField( + _opCtx.get(), + _ns, + write_ops::UpdateModification::parseFromClassicUpdate( + BSON("$rename" << BSON(_metaField << ".notTag"))), + _metaField)); + + // {$rename: {"tag.a.a": "A", "tag.b": "B"}} + ASSERT_FALSE(timeseries::updateOnlyModifiesMetaField( + _opCtx.get(), + _ns, + write_ops::UpdateModification::parseFromClassicUpdate( BSON("$rename" << BSON(_metaField + ".a.a" << "A" << _metaField + ".b" << "B"))), _metaField)); - // TODO: SERVER-59173 Modify this test since renaming the metaField is not allowed. // {$rename: {tag.tag.tag: 8}} - ASSERT_TRUE(timeseries::updateOnlyModifiesMetaField( + ASSERT_FALSE(timeseries::updateOnlyModifiesMetaField( _opCtx.get(), _ns, write_ops::UpdateModification::parseFromClassicUpdate( @@ -467,21 +490,20 @@ TEST_F(TimeseriesUpdateDeleteUtilTest, TranslateUpdate) { << "") << "inc" << BSON("nonMetaField" << 10))); - // TODO: SERVER-59173 Remove or modify this test since renaming the metaField is not allowed. - // {$rename: {"tag.a.a": "A", "tag.b": "B"}} - _testClassicUpdateTranslation(BSON("$rename" << BSON(_metaField + ".a.a" - << "A" << _metaField + ".b" - << "B")), - BSON("$rename" << BSON("meta.a.a" - << "A" - << "meta.b" - << "B"))); - - // TODO: SERVER-59173 Remove or modify this test since renaming the metaField is not allowed. - // {$rename: {tag.tag.tag: 8}} + // {$rename: {"tag.a.a": "tag.b.b", "tag.b": "tag.c"}} + _testClassicUpdateTranslation( + BSON("$rename" << BSON(_metaField + ".a.a" << _metaField + ".b.b" << _metaField + ".b" + << _metaField + ".c")), + BSON("$rename" << BSON("meta.a.a" + << "meta.b.b" + << "meta.b" + << "meta.c"))); + + // {$rename: {"tag.tag.tag": "tag.tag.a"}} _testClassicUpdateTranslation( - BSON("$rename" << BSON(_metaField + "." + _metaField + "." + _metaField << 8)), - BSON("$rename" << BSON("meta.tag.tag" << 8))); + BSON("$rename" << BSON(_metaField + "." + _metaField + "." + _metaField << "tag.tag.a")), + BSON("$rename" << BSON("meta.tag.tag" + << "meta.tag.a"))); } // Translate an update with an empty metaField, which violates the translation method's |