diff options
author | David Storch <david.storch@10gen.com> | 2018-02-08 14:55:41 -0500 |
---|---|---|
committer | David Storch <david.storch@10gen.com> | 2018-02-12 12:14:21 -0500 |
commit | 228a8e7d410ae01dc2ee8b90a83ddf08aa219bc9 (patch) | |
tree | bb24e97a3e14e8466088a9a1e588cd75e7187cda /jstests | |
parent | 5ccb16c2b8eb80d1eb3fe4e6ba36c092e03eb5d4 (diff) | |
download | mongo-228a8e7d410ae01dc2ee8b90a83ddf08aa219bc9.tar.gz |
SERVER-33005 Fix planner to avoid incorrect OR pushdown through $elemMatch.
The PlanEnumerator now tracks pushdown routes which descend
through an $elemMatch object. These routes are pruned when
subsequently descending through an OR.
(cherry picked from commit 17b4094c4d781ffd486b27869f46eea706e490af)
Diffstat (limited to 'jstests')
-rw-r--r-- | jstests/core/elemmatch_or_pushdown.js | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/jstests/core/elemmatch_or_pushdown.js b/jstests/core/elemmatch_or_pushdown.js new file mode 100644 index 00000000000..f1a1dacd7ad --- /dev/null +++ b/jstests/core/elemmatch_or_pushdown.js @@ -0,0 +1,41 @@ +/** + * Tests that an $elemMatch-$or query is evaluated correctly. Designed to reproduce SERVER-33005. + */ +(function() { + "use strict"; + + const coll = db.elemmatch_or_pushdown; + coll.drop(); + + assert.writeOK(coll.insert({_id: 0, a: 1, b: [{c: 4}]})); + assert.writeOK(coll.insert({_id: 1, a: 2, b: [{c: 4}]})); + assert.writeOK(coll.insert({_id: 2, a: 2, b: [{c: 5}]})); + assert.writeOK(coll.insert({_id: 3, a: 1, b: [{c: 5}]})); + assert.writeOK(coll.insert({_id: 4, a: 1, b: [{c: 6}]})); + assert.writeOK(coll.insert({_id: 5, a: 1, b: [{c: 7}]})); + assert.commandWorked(coll.createIndex({a: 1, "b.c": 1})); + + assert.eq(coll.find({a: 1, b: {$elemMatch: {$or: [{c: 4}, {c: 5}]}}}).sort({_id: 1}).toArray(), + [{_id: 0, a: 1, b: [{c: 4}]}, {_id: 3, a: 1, b: [{c: 5}]}]); + assert.eq(coll.find({a: 1, $or: [{a: 2}, {b: {$elemMatch: {$or: [{c: 4}, {c: 5}]}}}]}) + .sort({_id: 1}) + .toArray(), + [{_id: 0, a: 1, b: [{c: 4}]}, {_id: 3, a: 1, b: [{c: 5}]}]); + + coll.drop(); + assert.writeOK(coll.insert({_id: 0, a: 5, b: [{c: [{f: 8}], d: 6}]})); + assert.writeOK(coll.insert({_id: 1, a: 4, b: [{c: [{f: 8}], d: 6}]})); + assert.writeOK(coll.insert({_id: 2, a: 5, b: [{c: [{f: 8}], d: 7}]})); + assert.writeOK(coll.insert({_id: 3, a: 4, b: [{c: [{f: 9}], d: 6}]})); + assert.writeOK(coll.insert({_id: 4, a: 5, b: [{c: [{f: 8}], e: 7}]})); + assert.writeOK(coll.insert({_id: 5, a: 4, b: [{c: [{f: 8}], e: 7}]})); + assert.writeOK(coll.insert({_id: 6, a: 5, b: [{c: [{f: 8}], e: 8}]})); + assert.writeOK(coll.insert({_id: 7, a: 5, b: [{c: [{f: 9}], e: 7}]})); + assert.commandWorked(coll.createIndex({"b.d": 1, "b.c.f": 1})); + assert.commandWorked(coll.createIndex({"b.e": 1, "b.c.f": 1})); + + assert.eq(coll.find({a: 5, b: {$elemMatch: {c: {$elemMatch: {f: 8}}, $or: [{d: 6}, {e: 7}]}}}) + .sort({_id: 1}) + .toArray(), + [{_id: 0, a: 5, b: [{c: [{f: 8}], d: 6}]}, {_id: 4, a: 5, b: [{c: [{f: 8}], e: 7}]}]); +}()); |