summaryrefslogtreecommitdiff
path: root/jstests/core
diff options
context:
space:
mode:
authorAndrii Dobroshynski <andrii.dobroshynski@mongodb.com>2021-05-06 16:21:36 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-05-17 21:21:42 +0000
commit20019cf4ac5c1159e27cc458ad272146c11f139d (patch)
tree9a7901358bfc12080751e2596d04bb85a62a6b46 /jstests/core
parent0e4ff78d3ce89a2c15bae8a438a6b553e90f7fb0 (diff)
downloadmongo-20019cf4ac5c1159e27cc458ad272146c11f139d.tar.gz
SERVER-56468 Fix bug causing incorrect plan cache entry for {$ne: null} predicate, leading to missing query results
Diffstat (limited to 'jstests/core')
-rw-r--r--jstests/core/array_index_and_nonIndex_consistent.js3
-rw-r--r--jstests/core/neq_null_correctly_cache.js43
2 files changed, 46 insertions, 0 deletions
diff --git a/jstests/core/array_index_and_nonIndex_consistent.js b/jstests/core/array_index_and_nonIndex_consistent.js
index 2e6eeef7a4e..5ee0bcc08a7 100644
--- a/jstests/core/array_index_and_nonIndex_consistent.js
+++ b/jstests/core/array_index_and_nonIndex_consistent.js
@@ -79,6 +79,9 @@ queryList.forEach(function(q) {
{$not: {$gt: q}},
{$not: {$gte: q}},
{$not: {$eq: q}},
+ {$elemMatch: {$not: {$eq: q}}},
+ {$elemMatch: {$not: {$gte: q}}},
+ {$elemMatch: {$not: {$lte: q}}},
];
const projOutId = {_id: 0, val: 1};
queryPreds.forEach(function(pred) {
diff --git a/jstests/core/neq_null_correctly_cache.js b/jstests/core/neq_null_correctly_cache.js
new file mode 100644
index 00000000000..8b2089b3d4d
--- /dev/null
+++ b/jstests/core/neq_null_correctly_cache.js
@@ -0,0 +1,43 @@
+/**
+ * Tests that queries with a negation of a comparison to 'null' with '$eq', '$gte', and 'lte' do
+ * not incorrectly re-use query plans in cache that may be cause incorrect behavior due to null
+ * semantics. This test was initially designed to reproduce incorrect plan cache behavior bug in
+ * SERVER-56468.
+ * @tags: [
+ * does_not_support_stepdowns
+ * ]
+ */
+
+(function() {
+"use strict";
+
+const coll = db.neq_null_correctly_cache;
+coll.drop();
+
+assert.commandWorked(coll.createIndex({val: 1}));
+assert.commandWorked(coll.insertMany([{val: []}, {val: true}, {val: true}]));
+
+function runTest(testQueryPred, cachedQueryPred) {
+ coll.getPlanCache().clear();
+
+ // The 'testQueryPred' is always a null equality query of some form. All three of the documents
+ // in the collection should match this not-equal-to-null predicate.
+ assert.eq(3,
+ coll.find({val: {$not: testQueryPred}}, {_id: 0, val: 1}).sort({val: 1}).itcount());
+
+ // Run a query twice to create an active plan cache entry.
+ for (let i = 0; i < 2; ++i) {
+ assert.eq(
+ 1,
+ coll.find({val: {$not: cachedQueryPred}}, {_id: 0, val: 1}).sort({val: 1}).itcount());
+ }
+ // The results from the original query should not have changed, despite any possible changes in
+ // the state of the plan cache from the previous query.
+ assert.eq(3,
+ coll.find({val: {$not: testQueryPred}}, {_id: 0, val: 1}).sort({val: 1}).itcount());
+}
+
+runTest({$eq: null}, {$eq: true});
+runTest({$gte: null}, {$gte: true});
+runTest({$lte: null}, {$lte: true});
+}());