summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlya Berciu <alyacarina@gmail.com>2022-02-15 15:13:12 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-03-01 13:19:58 +0000
commit762d02f441876037b799bbcdcb250fe13ee6f2a4 (patch)
tree1e5f0928cedc5b56253fbccd27a0359f22985916
parent817d717f266983359022abb074fecdbf8a360f7d (diff)
downloadmongo-762d02f441876037b799bbcdcb250fe13ee6f2a4.tar.gz
SERVER-63141 Ensure stages without dependency tracking are not cached in $lookup
-rw-r--r--etc/backports_required_for_multiversion_tests.yml3
-rw-r--r--jstests/aggregation/lookup_let_optimization.js45
-rw-r--r--src/mongo/db/pipeline/document_source_sequential_document_cache.cpp5
3 files changed, 50 insertions, 3 deletions
diff --git a/etc/backports_required_for_multiversion_tests.yml b/etc/backports_required_for_multiversion_tests.yml
index 0fa0e4b083f..c62d42aab5f 100644
--- a/etc/backports_required_for_multiversion_tests.yml
+++ b/etc/backports_required_for_multiversion_tests.yml
@@ -130,6 +130,9 @@ all:
test_file: jstests/sharding/cancel_coordinate_txn_commit_with_tickets_exhausted.js
- ticket: SERVER-62147
test_file: jstests/core/exhaust.js
+ - ticket: SERVER-63141
+ test_file: jstests/aggregation/lookup_let_optimization.js
+
# Tests that should only be excluded from particular suites should be listed under that suite.
suites:
diff --git a/jstests/aggregation/lookup_let_optimization.js b/jstests/aggregation/lookup_let_optimization.js
new file mode 100644
index 00000000000..8431fb434c2
--- /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 assertArrayEq.
+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}) => {
+ assertArrayEq({actual: coll.aggregate(pipeline).toArray(), expected});
+};
+
+// 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 15627744247..0fb88369117 100644
--- a/src/mongo/db/pipeline/document_source_sequential_document_cache.cpp
+++ b/src/mongo/db/pipeline/document_source_sequential_document_cache.cpp
@@ -112,9 +112,8 @@ 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) == DepsTracker::State::NOT_SUPPORTED) ||
+ deps.hasVariableReferenceTo(varIDs)) {
break;
}
}