diff options
author | Max Hirschhorn <max.hirschhorn@mongodb.com> | 2017-11-14 21:49:46 -0500 |
---|---|---|
committer | Max Hirschhorn <max.hirschhorn@mongodb.com> | 2017-11-14 21:49:46 -0500 |
commit | b683d39549b033a516c1c8bdbae7040eafe99266 (patch) | |
tree | e631f24f21b8a8536a04a22dac97b531ef32f128 /src/mongo/db/pipeline | |
parent | d5cce0599a6f44f653eca53d728bb52b2f8fae6c (diff) | |
download | mongo-b683d39549b033a516c1c8bdbae7040eafe99266.tar.gz |
Revert "SERVER-31447 Use correct collation for update lookup"
This reverts commit de0b16077945eb6b6ec161b99f41c3222aade3b8.
Diffstat (limited to 'src/mongo/db/pipeline')
7 files changed, 30 insertions, 78 deletions
diff --git a/src/mongo/db/pipeline/document_source.h b/src/mongo/db/pipeline/document_source.h index 0ecd0fcf92a..2f6bec9fbcc 100644 --- a/src/mongo/db/pipeline/document_source.h +++ b/src/mongo/db/pipeline/document_source.h @@ -841,15 +841,13 @@ public: virtual std::vector<FieldPath> collectDocumentKeyFields(UUID) const = 0; /** - * Returns zero or one documents with the document key 'documentKey'. 'documentKey' is - * treated as a unique identifier of a document, and may include an _id or all fields from - * the shard key and an _id. Throws if more than one match was found. Returns boost::none if - * no matching documents were found, including cases where the given namespace does not - * exist. + * Returns zero or one documents matching the input filter, or throws if more than one match + * was found. The passed ExpressionContext may use a different namespace than the + * ExpressionContext used to construct the MongoProcessInterface. Returns boost::none if no + * matching documents were found, including cases where the given namespace does not exist. */ - virtual boost::optional<Document> lookupSingleDocument(const NamespaceString& nss, - UUID collectionUUID, - const Document& documentKey) = 0; + virtual boost::optional<Document> lookupSingleDocument( + const boost::intrusive_ptr<ExpressionContext>& expCtx, const Document& filter) = 0; /** * Returns a vector of all local cursors. diff --git a/src/mongo/db/pipeline/document_source_lookup_change_post_image.cpp b/src/mongo/db/pipeline/document_source_lookup_change_post_image.cpp index 7752fbfd751..058a959f588 100644 --- a/src/mongo/db/pipeline/document_source_lookup_change_post_image.cpp +++ b/src/mongo/db/pipeline/document_source_lookup_change_post_image.cpp @@ -105,9 +105,10 @@ Value DocumentSourceLookupChangePostImage::lookupPostImage(const Document& updat auto resumeToken = ResumeToken::parse(updateOp[DocumentSourceChangeStream::kIdField].getDocument()); - invariant(resumeToken.getData().uuid); - auto lookedUpDoc = - _mongoProcessInterface->lookupSingleDocument(nss, *resumeToken.getData().uuid, documentKey); + // TODO SERVER-29134 we need to extract the namespace from the document and set them on the new + // ExpressionContext if we're getting notifications from an entire database. + auto foreignExpCtx = pExpCtx->copyWith(nss, resumeToken.getData().uuid); + auto lookedUpDoc = _mongoProcessInterface->lookupSingleDocument(foreignExpCtx, documentKey); // Check whether the lookup returned any documents. Even if the lookup itself succeeded, it may // not have returned any results if the document was deleted in the time since the update op. diff --git a/src/mongo/db/pipeline/document_source_lookup_change_post_image_test.cpp b/src/mongo/db/pipeline/document_source_lookup_change_post_image_test.cpp index 3d35f875619..05b92297359 100644 --- a/src/mongo/db/pipeline/document_source_lookup_change_post_image_test.cpp +++ b/src/mongo/db/pipeline/document_source_lookup_change_post_image_test.cpp @@ -113,11 +113,9 @@ public: return Status::OK(); } - boost::optional<Document> lookupSingleDocument(const NamespaceString& nss, - UUID collectionUUID, - const Document& documentKey) { - boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest(nss)); - auto swPipeline = makePipeline({BSON("$match" << documentKey)}, expCtx); + boost::optional<Document> lookupSingleDocument( + const boost::intrusive_ptr<ExpressionContext>& expCtx, const Document& filter) { + auto swPipeline = makePipeline({BSON("$match" << filter)}, expCtx); if (swPipeline == ErrorCodes::NamespaceNotFound) { return boost::none; } @@ -126,12 +124,11 @@ public: auto lookedUpDocument = pipeline->getNext(); if (auto next = pipeline->getNext()) { uasserted(ErrorCodes::TooManyMatchingDocuments, - str::stream() << "found more than one document matching " - << documentKey.toString() + str::stream() << "found more than one document matching " << filter.toString() << " [" - << lookedUpDocument->toString() + << (*lookedUpDocument).toString() << ", " - << next->toString() + << (*next).toString() << "]"); } return lookedUpDocument; diff --git a/src/mongo/db/pipeline/expression_context.cpp b/src/mongo/db/pipeline/expression_context.cpp index e2b2e1e758d..64c813ed5a4 100644 --- a/src/mongo/db/pipeline/expression_context.cpp +++ b/src/mongo/db/pipeline/expression_context.cpp @@ -29,7 +29,6 @@ #include "mongo/platform/basic.h" #include "mongo/db/pipeline/expression_context.h" -#include "mongo/db/query/collation/collation_spec.h" #include "mongo/db/query/collation/collator_factory_interface.h" namespace mongo { @@ -122,10 +121,8 @@ void ExpressionContext::setCollator(const CollatorInterface* collator) { _valueComparator = ValueComparator(_collator); } -intrusive_ptr<ExpressionContext> ExpressionContext::copyWith( - NamespaceString ns, - boost::optional<UUID> uuid, - boost::optional<std::unique_ptr<CollatorInterface>> collator) const { +intrusive_ptr<ExpressionContext> ExpressionContext::copyWith(NamespaceString ns, + boost::optional<UUID> uuid) const { intrusive_ptr<ExpressionContext> expCtx = new ExpressionContext(std::move(ns), timeZoneDatabase); @@ -143,17 +140,11 @@ intrusive_ptr<ExpressionContext> ExpressionContext::copyWith( expCtx->opCtx = opCtx; - if (collator) { - expCtx->collation = - *collator ? (*collator)->getSpec().toBSON() : CollationSpec::kSimpleSpec; - expCtx->setCollator(std::move(*collator)); - } else { - expCtx->collation = collation; - if (_ownedCollator) { - expCtx->setCollator(_ownedCollator->clone()); - } else if (_collator) { - expCtx->setCollator(_collator); - } + expCtx->collation = collation; + if (_ownedCollator) { + expCtx->setCollator(_ownedCollator->clone()); + } else if (_collator) { + expCtx->setCollator(_collator); } expCtx->_resolvedNamespaces = _resolvedNamespaces; diff --git a/src/mongo/db/pipeline/expression_context.h b/src/mongo/db/pipeline/expression_context.h index a2e16163a73..59e85edfe90 100644 --- a/src/mongo/db/pipeline/expression_context.h +++ b/src/mongo/db/pipeline/expression_context.h @@ -140,9 +140,7 @@ public: * separate aggregation pipeline on 'ns' with the optional 'uuid'. */ boost::intrusive_ptr<ExpressionContext> copyWith( - NamespaceString ns, - boost::optional<UUID> uuid = boost::none, - boost::optional<std::unique_ptr<CollatorInterface>> collator = boost::none) const; + NamespaceString ns, boost::optional<UUID> uuid = boost::none) const; /** * Returns the ResolvedNamespace corresponding to 'nss'. It is an error to call this method on a diff --git a/src/mongo/db/pipeline/pipeline_d.cpp b/src/mongo/db/pipeline/pipeline_d.cpp index b32f18828d0..d0acba8fb5f 100644 --- a/src/mongo/db/pipeline/pipeline_d.cpp +++ b/src/mongo/db/pipeline/pipeline_d.cpp @@ -384,14 +384,9 @@ public: return result; } - boost::optional<Document> lookupSingleDocument(const NamespaceString& nss, - UUID collectionUUID, - const Document& documentKey) final { - // Be sure to do the lookup using the collection default collation. - auto foreignExpCtx = - _ctx->copyWith(nss, collectionUUID, _getCollectionDefaultCollator(nss, collectionUUID)); - auto swPipeline = makePipeline({BSON("$match" << documentKey)}, foreignExpCtx); - + boost::optional<Document> lookupSingleDocument(const intrusive_ptr<ExpressionContext>& expCtx, + const Document& filter) final { + auto swPipeline = makePipeline({BSON("$match" << filter)}, expCtx); if (swPipeline == ErrorCodes::NamespaceNotFound) { return boost::none; } @@ -400,8 +395,7 @@ public: auto lookedUpDocument = pipeline->getNext(); if (auto next = pipeline->getNext()) { uasserted(ErrorCodes::TooManyMatchingDocuments, - str::stream() << "found more than one document with document key " - << documentKey.toString() + str::stream() << "found more than one document matching " << filter.toString() << " [" << lookedUpDocument->toString() << ", " @@ -416,34 +410,8 @@ public: } private: - /** - * Looks up the collection default collator for the collection given by 'collectionUUID'. A - * collection's default collation is not allowed to change, so we cache the result to allow for - * quick lookups in the future. Looks up the collection by UUID, and returns 'nullptr' if the - * collection does not exist or if the collection's default collation is the simple collation. - */ - std::unique_ptr<CollatorInterface> _getCollectionDefaultCollator(const NamespaceString& nss, - UUID collectionUUID) { - if (_collatorCache.find(collectionUUID) == _collatorCache.end()) { - AutoGetCollection autoColl(_ctx->opCtx, nss, collectionUUID, MODE_IS); - if (!autoColl.getCollection()) { - // This collection doesn't exist - since we looked up by UUID, it will never exist - // in the future, so we cache a null pointer as the default collation. - _collatorCache[collectionUUID] = nullptr; - } else { - auto defaultCollator = autoColl.getCollection()->getDefaultCollator(); - // Clone the collator so that we can safely use the pointer if the collection - // disappears right after we release the lock. - _collatorCache[collectionUUID] = - defaultCollator ? defaultCollator->clone() : nullptr; - } - } - return _collatorCache[collectionUUID] ? _collatorCache[collectionUUID]->clone() : nullptr; - } - intrusive_ptr<ExpressionContext> _ctx; DBDirectClient _client; - std::map<UUID, std::unique_ptr<const CollatorInterface>> _collatorCache; }; /** diff --git a/src/mongo/db/pipeline/stub_mongo_process_interface.h b/src/mongo/db/pipeline/stub_mongo_process_interface.h index c0beb0504ba..1414289ed67 100644 --- a/src/mongo/db/pipeline/stub_mongo_process_interface.h +++ b/src/mongo/db/pipeline/stub_mongo_process_interface.h @@ -118,9 +118,8 @@ public: MONGO_UNREACHABLE; } - boost::optional<Document> lookupSingleDocument(const NamespaceString& nss, - UUID collectionUUID, - const Document& documentKey) { + boost::optional<Document> lookupSingleDocument( + const boost::intrusive_ptr<ExpressionContext>& expCtx, const Document& filter) { MONGO_UNREACHABLE; } |