summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline
diff options
context:
space:
mode:
authorMax Hirschhorn <max.hirschhorn@mongodb.com>2017-11-14 21:49:46 -0500
committerMax Hirschhorn <max.hirschhorn@mongodb.com>2017-11-14 21:49:46 -0500
commitb683d39549b033a516c1c8bdbae7040eafe99266 (patch)
treee631f24f21b8a8536a04a22dac97b531ef32f128 /src/mongo/db/pipeline
parentd5cce0599a6f44f653eca53d728bb52b2f8fae6c (diff)
downloadmongo-b683d39549b033a516c1c8bdbae7040eafe99266.tar.gz
Revert "SERVER-31447 Use correct collation for update lookup"
This reverts commit de0b16077945eb6b6ec161b99f41c3222aade3b8.
Diffstat (limited to 'src/mongo/db/pipeline')
-rw-r--r--src/mongo/db/pipeline/document_source.h14
-rw-r--r--src/mongo/db/pipeline/document_source_lookup_change_post_image.cpp7
-rw-r--r--src/mongo/db/pipeline/document_source_lookup_change_post_image_test.cpp15
-rw-r--r--src/mongo/db/pipeline/expression_context.cpp23
-rw-r--r--src/mongo/db/pipeline/expression_context.h4
-rw-r--r--src/mongo/db/pipeline/pipeline_d.cpp40
-rw-r--r--src/mongo/db/pipeline/stub_mongo_process_interface.h5
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;
}