diff options
author | Nick Zolnierz <nicholas.zolnierz@mongodb.com> | 2019-01-02 10:31:29 -0500 |
---|---|---|
committer | Nick Zolnierz <nicholas.zolnierz@mongodb.com> | 2019-01-04 15:53:02 -0500 |
commit | b83813667df5d783e7f34bea069d8d586946e563 (patch) | |
tree | e4c546d4d17d9fa89088605c4067c03e73175f4d /src/mongo/db | |
parent | bd209676619a5395f849bd75334aa378527d2181 (diff) | |
download | mongo-b83813667df5d783e7f34bea069d8d586946e563.tar.gz |
SERVER-37829 Add Stitch library update functions
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/SConscript | 2 | ||||
-rw-r--r-- | src/mongo/db/field_ref_set.h | 8 | ||||
-rw-r--r-- | src/mongo/db/ops/SConscript | 10 | ||||
-rw-r--r-- | src/mongo/db/ops/parsed_update.cpp | 28 | ||||
-rw-r--r-- | src/mongo/db/ops/parsed_update.h | 13 | ||||
-rw-r--r-- | src/mongo/db/update/update_driver_test.cpp | 6 |
6 files changed, 50 insertions, 17 deletions
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript index 21295d47a74..899c7af2e46 100644 --- a/src/mongo/db/SConscript +++ b/src/mongo/db/SConscript @@ -1121,7 +1121,6 @@ env.Library( 'exec/working_set_common.cpp', 'exec/write_stage_common.cpp', 'ops/parsed_delete.cpp', - 'ops/parsed_update.cpp', 'ops/update_result.cpp', 'pipeline/document_source_cursor.cpp', 'pipeline/document_source_geo_near_cursor.cpp', @@ -1164,6 +1163,7 @@ env.Library( 'index/key_generator', 'logical_session_cache', 'matcher/expressions_mongod_only', + 'ops/parsed_update', 'pipeline/pipeline', 'query/query_common', 'query/query_planner', diff --git a/src/mongo/db/field_ref_set.h b/src/mongo/db/field_ref_set.h index 735683252d2..e64f343c3dd 100644 --- a/src/mongo/db/field_ref_set.h +++ b/src/mongo/db/field_ref_set.h @@ -152,6 +152,14 @@ public: _fieldRefSet.keepShortest(inserted); } + std::vector<std::string> serialize() const { + std::vector<std::string> ret; + for (const auto fieldRef : _fieldRefSet) { + ret.push_back(fieldRef->dottedField().toString()); + } + return ret; + } + bool empty() const { return _fieldRefSet.empty(); } diff --git a/src/mongo/db/ops/SConscript b/src/mongo/db/ops/SConscript index 2218b59ca32..2725c1219d1 100644 --- a/src/mongo/db/ops/SConscript +++ b/src/mongo/db/ops/SConscript @@ -47,6 +47,16 @@ env.Library( ], ) +env.Library( + target='parsed_update', + source='parsed_update.cpp', + LIBDEPS=[ + '$BUILD_DIR/mongo/base', + '$BUILD_DIR/mongo/db/matcher/expressions_mongod_only', + '$BUILD_DIR/mongo/db/update/update_driver', + ], +) + env.CppUnitTest( target='write_ops_parsers_test', source='write_ops_parsers_test.cpp', diff --git a/src/mongo/db/ops/parsed_update.cpp b/src/mongo/db/ops/parsed_update.cpp index 87354810072..56e15faf654 100644 --- a/src/mongo/db/ops/parsed_update.cpp +++ b/src/mongo/db/ops/parsed_update.cpp @@ -65,17 +65,19 @@ Status ParsedUpdate::parseRequest() { _collator = std::move(collator.getValue()); } - Status status = parseArrayFilters(); - if (!status.isOK()) { - return status; + auto statusWithArrayFilters = + parseArrayFilters(_request->getArrayFilters(), _opCtx, _collator.get()); + if (!statusWithArrayFilters.isOK()) { + return statusWithArrayFilters.getStatus(); } + _arrayFilters = std::move(statusWithArrayFilters.getValue()); // We parse the update portion before the query portion because the dispostion of the update // may determine whether or not we need to produce a CanonicalQuery at all. For example, if // the update involves the positional-dollar operator, we must have a CanonicalQuery even if // it isn't required for query execution. parseUpdate(); - status = parseQuery(); + Status status = parseQuery(); if (!status.isOK()) return status; return Status::OK(); @@ -147,15 +149,19 @@ void ParsedUpdate::parseUpdate() { _driver.parse(_request->getUpdates(), _arrayFilters, _request->isMulti()); } -Status ParsedUpdate::parseArrayFilters() { - for (auto rawArrayFilter : _request->getArrayFilters()) { - boost::intrusive_ptr<ExpressionContext> expCtx( - new ExpressionContext(_opCtx, _collator.get())); +StatusWith<std::map<StringData, std::unique_ptr<ExpressionWithPlaceholder>>> +ParsedUpdate::parseArrayFilters(const std::vector<BSONObj>& rawArrayFiltersIn, + OperationContext* opCtx, + CollatorInterface* collator) { + std::map<StringData, std::unique_ptr<ExpressionWithPlaceholder>> arrayFiltersOut; + for (auto rawArrayFilter : rawArrayFiltersIn) { + boost::intrusive_ptr<ExpressionContext> expCtx(new ExpressionContext(opCtx, collator)); auto parsedArrayFilter = MatchExpressionParser::parse(rawArrayFilter, std::move(expCtx), ExtensionsCallbackNoop(), MatchExpressionParser::kBanAllSpecialFeatures); + if (!parsedArrayFilter.isOK()) { return parsedArrayFilter.getStatus().withContext("Error parsing array filter"); } @@ -172,17 +178,17 @@ Status ParsedUpdate::parseArrayFilters() { ErrorCodes::FailedToParse, "Cannot use an expression without a top-level field name in arrayFilters"); } - if (_arrayFilters.find(*fieldName) != _arrayFilters.end()) { + if (arrayFiltersOut.find(*fieldName) != arrayFiltersOut.end()) { return Status(ErrorCodes::FailedToParse, str::stream() << "Found multiple array filters with the same top-level field name " << *fieldName); } - _arrayFilters[*fieldName] = std::move(finalArrayFilter); + arrayFiltersOut[*fieldName] = std::move(finalArrayFilter); } - return Status::OK(); + return std::move(arrayFiltersOut); } PlanExecutor::YieldPolicy ParsedUpdate::yieldPolicy() const { diff --git a/src/mongo/db/ops/parsed_update.h b/src/mongo/db/ops/parsed_update.h index f9a0896a946..5f9ba4d66fd 100644 --- a/src/mongo/db/ops/parsed_update.h +++ b/src/mongo/db/ops/parsed_update.h @@ -62,6 +62,14 @@ class ParsedUpdate { public: /** + * Parses the array filters portion of the update request. + */ + static StatusWith<std::map<StringData, std::unique_ptr<ExpressionWithPlaceholder>>> + parseArrayFilters(const std::vector<BSONObj>& rawArrayFiltersIn, + OperationContext* opCtx, + CollatorInterface* collator); + + /** * Constructs a parsed update. * * The object pointed to by "request" must stay in scope for the life of the constructed @@ -143,11 +151,6 @@ private: */ void parseUpdate(); - /** - * Parses the array filters portion of the update request. - */ - Status parseArrayFilters(); - // Unowned pointer to the transactional context. OperationContext* _opCtx; diff --git a/src/mongo/db/update/update_driver_test.cpp b/src/mongo/db/update/update_driver_test.cpp index 12276487d9f..44a44514d8b 100644 --- a/src/mongo/db/update/update_driver_test.cpp +++ b/src/mongo/db/update/update_driver_test.cpp @@ -561,6 +561,12 @@ public: } }; +TEST_F(ModifiedPathsTestFixture, ReplaceFullDocumentReturnsEmptySet) { + BSONObj spec = fromjson("{a: 1, b: 1}}"); + mutablebson::Document doc(fromjson("{a: 0, b: 0}")); + ASSERT_EQ(getModifiedPaths(&doc, spec), "{}"); +} + TEST_F(ModifiedPathsTestFixture, SetFieldInRoot) { BSONObj spec = fromjson("{$set: {a: 1}}"); mutablebson::Document doc(fromjson("{a: 0}")); |