summaryrefslogtreecommitdiff
path: root/jstests/noPassthrough/plan_cache_replan_sort.js
blob: 59cc1c41fb8717214cc1ae293e938e3d51043edd (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
/**
 * Test that when replanning happens due to blocking sort's memory limit, we include
 * replanReason: "cached plan returned: ..." in the profiling data.
 * @tags: [requires_profiling]
 */
(function() {
    "use strict";

    load("jstests/libs/profiler.js");

    const conn = MongoRunner.runMongod({
        // Disallow blocking sort, by setting the memory limit very low (1 byte).
        setParameter: "internalQueryExecMaxBlockingSortBytes=1"
    });
    const db = conn.getDB("test");
    const coll = db.plan_cache_replan_sort;
    coll.drop();

    // Ensure a plan with a sort stage gets cached.
    assert.commandWorked(coll.createIndex({x: 1}));
    assert.commandWorked(coll.createIndex({y: 1}));
    const docs = Array.from({length: 20}, (_, i) => ({x: 7, y: i}));
    assert.commandWorked(coll.insert(docs));
    // { x: 5 } is very selective because it matches 0 documents, so the x index will win.
    // This will succeed despite the low memory limit on sort, because the sort stage will see zero
    // documents.
    assert.eq(0, coll.find({x: 5}).sort({y: 1}).itcount());

    const cachedPlans = coll.getPlanCache().getPlansByQuery({x: 5}, {}, {y: 1}).plans;
    assert.lte(1, cachedPlans.length, cachedPlans);
    const winningPlan = cachedPlans[0];
    assert.eq("SORT", winningPlan.reason.stats.stage, cachedPlans);

    // Assert we "replan", by running the same query with different parameters.
    // This time the filter is not selective at all.
    db.setProfilingLevel(2);
    assert.eq(20, coll.find({x: 7}).sort({y: 1}).itcount());

    const profileObj = getLatestProfilerEntry(db, {op: "query"});
    assert.eq(profileObj.ns, coll.getFullName(), profileObj);
    assert.eq(profileObj.replanned, true, profileObj);
    assert.eq(
        profileObj.replanReason,
        "cached plan returned: OperationFailed: Sort operation used more than the maximum 1 bytes of " +
            "RAM. Add an index, or specify a smaller limit.",
        profileObj);

    MongoRunner.stopMongod(conn);
}());