1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
/**
* Tests that SBE reports correct rejected plans when calling explain().
* @tags: [
* assumes_unsharded_collection,
* requires_fcv_63,
* ]
*/
(function() {
"use strict";
load("jstests/libs/analyze_plan.js");
load("jstests/libs/collection_drop_recreate.js");
load("jstests/libs/sbe_util.js"); // For 'checkSBEEnabled'.
const isSBEEnabled = checkSBEEnabled(db);
if (!isSBEEnabled) {
jsTestLog("Skipping test because SBE is disabled");
return;
}
const coll = assertDropAndRecreateCollection(db, "sbe_explain_rejected_plans");
assert.commandWorked(coll.createIndex({a: 1}));
assert.commandWorked(coll.createIndex({b: 1}));
assert.commandWorked(coll.createIndex({a: 1, b: 1}));
// Insert data, such that index 'a_1_b_1' is preferred.
for (let a = 0; a < 10; a++) {
for (let b = 0; b < 10; b++) {
assert.commandWorked(coll.insert({a: a, b: b}));
}
}
const a1b1IndexName = "a_1_b_1";
const a1IndexName = "a_1";
const b1IndexName = "b_1";
const explain = coll.find({a: 7, b: 9}).explain("executionStats");
// Verify that the winner plan has index scan stage on 'a_1_b_1'.
let ixscans = getPlanStages(getWinningPlan(explain.queryPlanner), "IXSCAN");
assert.neq(ixscans.length, 0, explain);
for (let ixscan of ixscans) {
assert.eq(ixscan.indexName, a1b1IndexName, explain);
}
// Verify that the winning SBE plan has index scan stage on 'a_1_b_1'.
const executionStages = getExecutionStages(explain);
assert.neq(executionStages.length, 0, explain);
for (let executionStage of executionStages) {
ixscans = getPlanStages(executionStage, "ixseek");
assert.neq(ixscans.length, 0);
for (let ixscan of ixscans) {
assert.eq(ixscan.indexName, a1b1IndexName, ixscan);
}
}
// Verify that rejected plans should have index scan on 'a_1' or 'b_1'.
for (let rejectedPlan of getRejectedPlans(explain)) {
ixscans = getPlanStages(getRejectedPlan(rejectedPlan), "IXSCAN");
assert.neq(ixscans.length, 0, explain);
for (let ixscan of ixscans) {
assert.contains(ixscan.indexName, [a1IndexName, b1IndexName], ixscan);
}
assert(!rejectedPlan.slotBasedPlan.stages.includes("@\"a_1_b_1\""), explain);
assert(rejectedPlan.slotBasedPlan.stages.includes("@\"a_1\"") ||
rejectedPlan.slotBasedPlan.stages.includes("@\"b_1\""),
explain);
}
})();
|