summaryrefslogtreecommitdiff
path: root/jstests/noPassthroughWithMongod/index_bounds_static_limit.js
blob: dc183a273466a1b510540d75e4bf5535eaae94a6 (plain)
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
70
71
72
// Validate that generic index scan is used in SBE once max limit for statically generated intervals
// is reached.
//
// We issue 'setParameter' command which is not compatible with stepdowns.
// @tags: [does_not_support_stepdowns]
(function() {
"use strict";

load("jstests/libs/analyze_plan.js");  // For explain helpers.
load("jstests/libs/sbe_util.js");      // For checkSBEEnabled.

if (!checkSBEEnabled(db, ["featureFlagSbeFull"])) {
    jsTest.log("Skipping test because SBE is not fully enabled");
    return;
}

const coll = db.index_bounds_static_limit;
coll.drop();

assert.commandWorked(coll.createIndex({a: 1, b: 1, c: 1, d: 1, e: 1}));

// Save the old limit so it can be restored once the tests completes.
const staticLimit = db.adminCommand({
                          getParameter: 1,
                          internalQuerySlotBasedExecutionMaxStaticIndexScanIntervals: 1
                      }).internalQuerySlotBasedExecutionMaxStaticIndexScanIntervals;

const setStaticLimit = function(limit) {
    return db.adminCommand(
        {setParameter: 1, internalQuerySlotBasedExecutionMaxStaticIndexScanIntervals: limit});
};

/**
 * Takes and output of explain("executionStats") command and verifieies whether generic or optimized
 * index scan plan used.
 * @param {*} explain - output of explain("executionStats") command.
 * @param {*} isGeneric - true if generic plan expected and false if an optimized plan expected.
 */
function assertIndexScanPlan(explain, isGeneric) {
    const stages = explain.executionStats.executionStages;

    // Asserts whether this plan is generic or optimized.
    const branchStage = getPlanStage(stages, "branch");
    const filterSlot = branchStage.filter.trim();
    const isGenericSlotValue = `${filterSlot} = ${isGeneric}`;
    const slotValues = explain.queryPlanner.winningPlan.slotBasedPlan.slots;
    assert(slotValues.search(isGenericSlotValue) != -1, explain);

    // Asserts that this plan contains ixseek stage.
    const ixseekStages = getPlanStages(stages, "ixseek");
    assert.neq(0, ixseekStages.length, explain);
}

try {
    // Verify that when the number of statically generated single interval bounds is less than the
    // static limit, the optimized plan is used.
    const optimized =
        coll.find({a: {$in: [1, 2, 3]}, b: {$in: [10, 11, 12]}, c: {$in: [42]}, d: {$lt: 3}})
            .explain("executionStats");
    assertIndexScanPlan(optimized, /*isGeneric*/ false);

    // Verify that when the number of statically generated single interval bounds is greater than
    // the static limit, the generic plan is used.
    setStaticLimit(2);
    const generic =
        coll.find({a: {$in: [1, 2, 3]}, b: {$in: [10, 11, 12]}, c: {$in: [42]}, d: {$lt: 3}})
            .explain("executionStats");
    assertIndexScanPlan(generic, /*isGeneric*/ true);
} finally {
    setStaticLimit(staticLimit);
}
})();