diff options
author | Andrii Dobroshynski <andrii.dobroshynski@mongodb.com> | 2021-05-06 16:21:36 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-05-17 21:21:42 +0000 |
commit | 20019cf4ac5c1159e27cc458ad272146c11f139d (patch) | |
tree | 9a7901358bfc12080751e2596d04bb85a62a6b46 /jstests/core | |
parent | 0e4ff78d3ce89a2c15bae8a438a6b553e90f7fb0 (diff) | |
download | mongo-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.js | 3 | ||||
-rw-r--r-- | jstests/core/neq_null_correctly_cache.js | 43 |
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}); +}()); |