Files
mongo/jstests/cqf/array_match.js
2022-10-07 16:53:33 +00:00

70 lines
2.7 KiB
JavaScript

(function() {
"use strict";
load("jstests/libs/optimizer_utils.js"); // For checkCascadesOptimizerEnabled.
if (!checkCascadesOptimizerEnabled(db)) {
jsTestLog("Skipping test because the optimizer is not enabled");
return;
}
const t = db.cqf_array_match;
t.drop();
for (let i = 0; i < 10; i++) {
assert.commandWorked(t.insert({a: 2, b: 1}));
assert.commandWorked(t.insert({a: [2], b: 1}));
assert.commandWorked(t.insert({a: [[2]], b: 1}));
assert.commandWorked(t.insert({a: [0, 1], b: 1}));
}
assert.commandWorked(t.createIndex({a: 1}));
{
const res = t.explain("executionStats").aggregate([{$match: {a: {$eq: [2]}}}]);
assert.eq(20, res.executionStats.nReturned);
assertValueOnPlanPath("PhysicalScan", res, "child.child.nodeType");
}
{
// These two predicates don't make a contradiction, because they can match different array
// elements. Make sure we don't incorrectly simplify this to always-false.
const res = t.explain("executionStats").aggregate([{$match: {a: 0}}, {$match: {a: 1}}]);
assert.eq(10, res.executionStats.nReturned);
}
// Generate enough documents for index to be preferable.
const bulk = t.initializeUnorderedBulkOp();
for (let i = 0; i < 400; i++) {
bulk.insert({a: i + 10});
}
assert.commandWorked(bulk.execute());
{
const res = t.explain("executionStats").aggregate([{$match: {a: {$eq: [2]}}}]);
assert.eq(20, res.executionStats.nReturned);
const indexUnionNode = navigateToPlanPath(res, "child.child.leftChild.child");
assertValueOnPath("Union", indexUnionNode, "nodeType");
assertValueOnPath("IndexScan", indexUnionNode, "children.0.nodeType");
assertValueOnPath([2], indexUnionNode, "children.0.interval.0.lowBound.bound.value");
assertValueOnPath("IndexScan", indexUnionNode, "children.1.nodeType");
assertValueOnPath(2, indexUnionNode, "children.1.interval.0.lowBound.bound.value");
}
assert.commandWorked(t.dropIndex({a: 1}));
assert.commandWorked(t.createIndex({b: 1, a: 1}));
{
const res = t.explain("executionStats").aggregate([{$match: {b: 1, a: {$eq: [2]}}}]);
assert.eq(20, res.executionStats.nReturned);
// Verify we still get index scan even if the field appears as second index field.
const indexUnionNode = navigateToPlanPath(res, "child.child.leftChild.child");
assertValueOnPath("Union", indexUnionNode, "nodeType");
assertValueOnPath("IndexScan", indexUnionNode, "children.0.nodeType");
assertValueOnPath([2], indexUnionNode, "children.0.interval.1.lowBound.bound.value");
assertValueOnPath("IndexScan", indexUnionNode, "children.1.nodeType");
assertValueOnPath(2, indexUnionNode, "children.1.interval.1.lowBound.bound.value");
}
}());