diff options
Diffstat (limited to 'src/mongo/db/pipeline/document_source_redact.cpp')
-rw-r--r-- | src/mongo/db/pipeline/document_source_redact.cpp | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/src/mongo/db/pipeline/document_source_redact.cpp b/src/mongo/db/pipeline/document_source_redact.cpp index 7067d27930a..b1d2c9e54f2 100644 --- a/src/mongo/db/pipeline/document_source_redact.cpp +++ b/src/mongo/db/pipeline/document_source_redact.cpp @@ -68,6 +68,32 @@ boost::optional<Document> DocumentSourceRedact::getNext() { return boost::none; } +Pipeline::SourceContainer::iterator DocumentSourceRedact::optimizeAt( + Pipeline::SourceContainer::iterator itr, Pipeline::SourceContainer* container) { + invariant(*itr == this); + + auto nextMatch = dynamic_cast<DocumentSourceMatch*>((*std::next(itr)).get()); + + if (nextMatch) { + const BSONObj redactSafePortion = nextMatch->redactSafePortion(); + + if (!redactSafePortion.isEmpty()) { + // Because R-M turns into M-R-M without modifying the original $match, we cannot step + // backwards and optimize from before the $redact, otherwise this will just loop and + // create an infinite number of $matches. + Pipeline::SourceContainer::iterator returnItr = std::next(itr); + + container->insert( + itr, + DocumentSourceMatch::createFromBson( + BSON("$match" << redactSafePortion).firstElement(), this->pExpCtx)); + + return returnItr; + } + } + return std::next(itr); +} + Value DocumentSourceRedact::redactValue(const Value& in) { const BSONType valueType = in.getType(); if (valueType == Object) { |