|
The fuzzer found another bug. Here's a repro:
const pipeline = [
|
// Variations on this predicate seem to not matter much.
|
{$match: {"num": 3}},
|
|
{
|
$match: {
|
$or: [
|
{"array1": {$eq: []}},
|
|
// Although this predicate is always false, when I comment it out
|
// then the test does not reproduce the bug.
|
{"array2": {$eq: [false]}},
|
]
|
}
|
},
|
];
|
|
const docs = [
|
{
|
_id: 1,
|
"num": 3,
|
|
// This has to be empty array:
|
// Changing the query to {$eq: [5]} and doc to 'array1: [5]'
|
// does not repro.
|
"array1": [],
|
|
// This field's value and presence doesn't matter.
|
// "array2": [123]
|
},
|
];
|
|
const coll = db.cqf_fuzzer_bug;
|
|
coll.drop();
|
assert.commandWorked(coll.insert(docs));
|
|
// The first stage matches.
|
assert.eq(1, coll.aggregate([pipeline[0]]).itcount());
|
// The second stage matches.
|
assert.eq(1, coll.aggregate([pipeline[1]]).itcount());
|
|
// Their composition should also match.
|
assert.eq(1, coll.aggregate(pipeline).itcount());
|
This passes on the default configuration, but the last assertion fails on Bonsai. Each $match individually matches the document, but when put together in one query it doesn't match. So it must be a rewrite combining the predicates incorrectly.
These {$eq: <array>} predicates are interesting because they check the whole array (in addition to checking in element): we generate a disjunction where one branch doesn't use traverse.
|