diff options
author | Alya Berciu <alyacarina@gmail.com> | 2022-03-16 12:11:37 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-03-16 12:38:08 +0000 |
commit | 274f2fddd6a0f975a678e8a953e704f7be6dda14 (patch) | |
tree | abbc82bf2cb91764092f8b80908d43051fbe5fd0 | |
parent | a676602d0382df3077f9b0f95cff3175e9af9ea3 (diff) | |
download | mongo-v4.0.tar.gz |
SERVER-63141 Ensure stages without dependency tracking are not cached in $lookupv4.0
-rw-r--r-- | jstests/aggregation/lookup_let_optimization.js | 45 | ||||
-rw-r--r-- | src/mongo/db/pipeline/document_source_sequential_document_cache.cpp | 6 |
2 files changed, 48 insertions, 3 deletions
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; } } |