From 274f2fddd6a0f975a678e8a953e704f7be6dda14 Mon Sep 17 00:00:00 2001 From: Alya Berciu Date: Wed, 16 Mar 2022 12:11:37 +0000 Subject: SERVER-63141 Ensure stages without dependency tracking are not cached in $lookup --- jstests/aggregation/lookup_let_optimization.js | 45 ++++++++++++++++++++++ .../document_source_sequential_document_cache.cpp | 6 +-- 2 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 jstests/aggregation/lookup_let_optimization.js diff --git a/jstests/aggregation/lookup_let_optimization.js b/jstests/aggregation/lookup_let_optimization.js new file mode 100644 index 00000000000..53bd5b7f3e1 --- /dev/null +++ b/jstests/aggregation/lookup_let_optimization.js @@ -0,0 +1,45 @@ +/** + * This test ensures that stages dependent on a let variable optimizing to a constant in a $lookup + * pipeline are evaluated correctly. + * @tags: [assumes_unsharded_collection] + */ + +load('jstests/aggregation/extras/utils.js'); // For arrayEq. +load("jstests/libs/fixture_helpers.js"); // For FixtureHelpers. + +(function() { + "use strict"; + + const collName = "lookup_let_redact"; + const coll = db[collName]; + coll.drop(); + assert.commandWorked(coll.insert([ + {_id: "true", test: true}, + {_id: "false", test: false}, + ])); + + const verifyAggregationResults = ({pipeline, expected}) => { + assert(arrayEq(coll.aggregate(pipeline).toArray(), expected, true)); + }; + + // Verify $redact. + verifyAggregationResults({ + pipeline: [ + {$lookup: { + from: collName, + let: {iShouldPrune: "$test"}, + pipeline: [ + {$redact: {$cond: {if: "$$iShouldPrune", then: "$$PRUNE", else: "$$DESCEND"}}} + ], + as: "redacted" + }} + ], + expected: [ + {_id: "true", test: true, redacted: []}, // Expect that documents were pruned. + {_id: "false", test: false, redacted: [ // Expect that $redact descended instead. + {_id: "true", test: true}, + {_id: "false", test: false} + ]} + ] +}); +}()); diff --git a/src/mongo/db/pipeline/document_source_sequential_document_cache.cpp b/src/mongo/db/pipeline/document_source_sequential_document_cache.cpp index c3c423af77f..49c038f828c 100644 --- a/src/mongo/db/pipeline/document_source_sequential_document_cache.cpp +++ b/src/mongo/db/pipeline/document_source_sequential_document_cache.cpp @@ -106,9 +106,9 @@ Pipeline::SourceContainer::iterator DocumentSourceSequentialDocumentCache::doOpt // Iterate through the pipeline stages until we find one which references an external variable. for (; prefixSplit != container->end(); ++prefixSplit) { - (*prefixSplit)->getDependencies(&deps); - - if (deps.hasVariableReferenceTo(varIDs)) { + if (((*prefixSplit)->getDependencies(&deps) == + DocumentSource::GetDepsReturn::NOT_SUPPORTED) || + deps.hasVariableReferenceTo(varIDs)) { break; } } -- cgit v1.2.1