summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorNick Zolnierz <nicholas.zolnierz@mongodb.com>2019-01-02 10:31:29 -0500
committerNick Zolnierz <nicholas.zolnierz@mongodb.com>2019-01-04 15:53:02 -0500
commitb83813667df5d783e7f34bea069d8d586946e563 (patch)
treee4c546d4d17d9fa89088605c4067c03e73175f4d /src/mongo/db
parentbd209676619a5395f849bd75334aa378527d2181 (diff)
downloadmongo-b83813667df5d783e7f34bea069d8d586946e563.tar.gz
SERVER-37829 Add Stitch library update functions
Diffstat (limited to 'src/mongo/db')
-rw-r--r--src/mongo/db/SConscript2
-rw-r--r--src/mongo/db/field_ref_set.h8
-rw-r--r--src/mongo/db/ops/SConscript10
-rw-r--r--src/mongo/db/ops/parsed_update.cpp28
-rw-r--r--src/mongo/db/ops/parsed_update.h13
-rw-r--r--src/mongo/db/update/update_driver_test.cpp6
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}"));