summaryrefslogtreecommitdiff
path: root/src/mongo/db/ops/parsed_update.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/ops/parsed_update.cpp')
-rw-r--r--src/mongo/db/ops/parsed_update.cpp171
1 files changed, 83 insertions, 88 deletions
diff --git a/src/mongo/db/ops/parsed_update.cpp b/src/mongo/db/ops/parsed_update.cpp
index d6a26fdaed2..c2b6c84df7c 100644
--- a/src/mongo/db/ops/parsed_update.cpp
+++ b/src/mongo/db/ops/parsed_update.cpp
@@ -35,103 +35,98 @@
namespace mongo {
- ParsedUpdate::ParsedUpdate(OperationContext* txn, const UpdateRequest* request) :
- _txn(txn),
- _request(request),
- _driver(UpdateDriver::Options()),
- _canonicalQuery() { }
-
- Status ParsedUpdate::parseRequest() {
- // It is invalid to request that the update plan stores a copy of the resulting document
- // if it is a multi-update.
- invariant(!(_request->shouldStoreResultDoc() && _request->isMulti()));
-
- // 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.
- Status status = parseUpdate();
- if (!status.isOK())
- return status;
- status = parseQuery();
- if (!status.isOK())
- return status;
- return Status::OK();
- }
-
- Status ParsedUpdate::parseQuery() {
- dassert(!_canonicalQuery.get());
-
- if (!_driver.needMatchDetails() && CanonicalQuery::isSimpleIdQuery(_request->getQuery())) {
- return Status::OK();
- }
-
- return parseQueryToCQ();
- }
-
- Status ParsedUpdate::parseQueryToCQ() {
- dassert(!_canonicalQuery.get());
-
- CanonicalQuery* cqRaw;
- const WhereCallbackReal whereCallback(_txn, _request->getNamespaceString().db());
-
- Status status = CanonicalQuery::canonicalize(_request->getNamespaceString().ns(),
- _request->getQuery(),
- _request->isExplain(),
- &cqRaw,
- whereCallback);
- if (status.isOK()) {
- _canonicalQuery.reset(cqRaw);
- }
-
+ParsedUpdate::ParsedUpdate(OperationContext* txn, const UpdateRequest* request)
+ : _txn(txn), _request(request), _driver(UpdateDriver::Options()), _canonicalQuery() {}
+
+Status ParsedUpdate::parseRequest() {
+ // It is invalid to request that the update plan stores a copy of the resulting document
+ // if it is a multi-update.
+ invariant(!(_request->shouldStoreResultDoc() && _request->isMulti()));
+
+ // 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.
+ Status status = parseUpdate();
+ if (!status.isOK())
return status;
- }
-
- Status ParsedUpdate::parseUpdate() {
- const NamespaceString& ns(_request->getNamespaceString());
-
- // Should the modifiers validate their embedded docs via okForStorage
- // Only user updates should be checked. Any system or replication stuff should pass through.
- // Config db docs shouldn't get checked for valid field names since the shard key can have
- // a dot (".") in it.
- const bool shouldValidate = !(_request->isFromReplication() ||
- ns.isConfigDB() ||
- _request->isFromMigration());
-
- _driver.setLogOp(true);
- _driver.setModOptions(ModifierInterface::Options(_request->isFromReplication(),
- shouldValidate));
+ status = parseQuery();
+ if (!status.isOK())
+ return status;
+ return Status::OK();
+}
- return _driver.parse(_request->getUpdates(), _request->isMulti());
- }
+Status ParsedUpdate::parseQuery() {
+ dassert(!_canonicalQuery.get());
- bool ParsedUpdate::canYield() const {
- return !_request->isGod() &&
- PlanExecutor::YIELD_AUTO == _request->getYieldPolicy() &&
- !isIsolated();
+ if (!_driver.needMatchDetails() && CanonicalQuery::isSimpleIdQuery(_request->getQuery())) {
+ return Status::OK();
}
- bool ParsedUpdate::isIsolated() const {
- return _canonicalQuery.get()
- ? QueryPlannerCommon::hasNode(_canonicalQuery->root(), MatchExpression::ATOMIC)
- : LiteParsedQuery::isQueryIsolated(_request->getQuery());
- }
+ return parseQueryToCQ();
+}
- bool ParsedUpdate::hasParsedQuery() const {
- return _canonicalQuery.get() != NULL;
- }
+Status ParsedUpdate::parseQueryToCQ() {
+ dassert(!_canonicalQuery.get());
- CanonicalQuery* ParsedUpdate::releaseParsedQuery() {
- invariant(_canonicalQuery.get() != NULL);
- return _canonicalQuery.release();
- }
+ CanonicalQuery* cqRaw;
+ const WhereCallbackReal whereCallback(_txn, _request->getNamespaceString().db());
- const UpdateRequest* ParsedUpdate::getRequest() const {
- return _request;
+ Status status = CanonicalQuery::canonicalize(_request->getNamespaceString().ns(),
+ _request->getQuery(),
+ _request->isExplain(),
+ &cqRaw,
+ whereCallback);
+ if (status.isOK()) {
+ _canonicalQuery.reset(cqRaw);
}
- UpdateDriver* ParsedUpdate::getDriver() {
- return &_driver;
- }
+ return status;
+}
+
+Status ParsedUpdate::parseUpdate() {
+ const NamespaceString& ns(_request->getNamespaceString());
+
+ // Should the modifiers validate their embedded docs via okForStorage
+ // Only user updates should be checked. Any system or replication stuff should pass through.
+ // Config db docs shouldn't get checked for valid field names since the shard key can have
+ // a dot (".") in it.
+ const bool shouldValidate =
+ !(_request->isFromReplication() || ns.isConfigDB() || _request->isFromMigration());
+
+ _driver.setLogOp(true);
+ _driver.setModOptions(
+ ModifierInterface::Options(_request->isFromReplication(), shouldValidate));
+
+ return _driver.parse(_request->getUpdates(), _request->isMulti());
+}
+
+bool ParsedUpdate::canYield() const {
+ return !_request->isGod() && PlanExecutor::YIELD_AUTO == _request->getYieldPolicy() &&
+ !isIsolated();
+}
+
+bool ParsedUpdate::isIsolated() const {
+ return _canonicalQuery.get()
+ ? QueryPlannerCommon::hasNode(_canonicalQuery->root(), MatchExpression::ATOMIC)
+ : LiteParsedQuery::isQueryIsolated(_request->getQuery());
+}
+
+bool ParsedUpdate::hasParsedQuery() const {
+ return _canonicalQuery.get() != NULL;
+}
+
+CanonicalQuery* ParsedUpdate::releaseParsedQuery() {
+ invariant(_canonicalQuery.get() != NULL);
+ return _canonicalQuery.release();
+}
+
+const UpdateRequest* ParsedUpdate::getRequest() const {
+ return _request;
+}
+
+UpdateDriver* ParsedUpdate::getDriver() {
+ return &_driver;
+}
} // namespace mongo