diff options
author | Charlie <charlie.swanson@mongodb.com> | 2015-04-14 10:27:18 -0400 |
---|---|---|
committer | Charlie <charlie.swanson@mongodb.com> | 2015-04-14 10:27:18 -0400 |
commit | 7a36b1598c45ea07a4713d4630fee204ff782e96 (patch) | |
tree | 4f8f67db69d5ac3f7412f1d136416f534fefd135 /src/mongo/db/ops/parsed_update.cpp | |
parent | 9637c0ae2721a07386af4fb4c402ee061ed7532f (diff) | |
download | mongo-7a36b1598c45ea07a4713d4630fee204ff782e96.tar.gz |
SERVER-16063 Rewrite the findAndModify command.
Changed UpdateStage to return the prior or newly-updated version of
a document if request. also changed DeleteStage to return the deleted
document if requested.
Added explain support to the findAndModify command.
Diffstat (limited to 'src/mongo/db/ops/parsed_update.cpp')
-rw-r--r-- | src/mongo/db/ops/parsed_update.cpp | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/src/mongo/db/ops/parsed_update.cpp b/src/mongo/db/ops/parsed_update.cpp index 9e084b2dfe5..d4651371e3f 100644 --- a/src/mongo/db/ops/parsed_update.cpp +++ b/src/mongo/db/ops/parsed_update.cpp @@ -42,9 +42,13 @@ namespace mongo { _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())); + // It is invalid to request that the UpdateStage return the prior or newly-updated version + // of a document during a multi-update. + invariant(!(_request->shouldReturnAnyDocs() && _request->isMulti())); + + // It is invalid to request that a ProjectionStage be applied to the UpdateStage if the + // UpdateStage would not return any document. + invariant(_request->getProj().isEmpty() || _request->shouldReturnAnyDocs()); // 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 @@ -75,8 +79,27 @@ namespace mongo { CanonicalQuery* cqRaw; const WhereCallbackReal whereCallback(_txn, _request->getNamespaceString().db()); + // Limit should only used for the findAndModify command when a sort is specified. If a sort + // is requested, we want to use a top-k sort for efficiency reasons, so should pass the + // limit through. Generally, a update stage expects to be able to skip documents that were + // deleted/modified under it, but a limit could inhibit that and give an EOF when the update + // has not actually updated a document. This behavior is fine for findAndModify, but should + // not apply to update in general. + long long limit = (!_request->isMulti() && !_request->getSort().isEmpty()) ? -1 : 0; + + // The projection needs to be applied after the update operation, so we specify an empty + // BSONObj as the projection during canonicalization. + const BSONObj emptyObj; Status status = CanonicalQuery::canonicalize(_request->getNamespaceString().ns(), _request->getQuery(), + _request->getSort(), + emptyObj, // projection + 0, // skip + limit, + emptyObj, // hint + emptyObj, // min + emptyObj, // max + false, // snapshot _request->isExplain(), &cqRaw, whereCallback); |