summaryrefslogtreecommitdiff
path: root/jstests/aggregation/bugs/server12015.js
blob: af4ee75f92d5801da52e30accc26b9232f58be6d (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
73
74
/**
 * SERVER-12015 Re-enable covered indices in the aggregation pipeline.
 *
 * This test executes some simple pipelines and asserts that they have the same results whether or
 * not there are indices that could cover the projection part of the query, or provide a
 * non-blocking sort.
 */

load("jstests/aggregation/extras/utils.js");  // For orderedArrayEq.

(function() {
    "use strict";
    var coll = db.server12015;
    coll.drop();
    var indexSpec = {
        a: 1,
        b: 1
    };

    assert.writeOK(coll.insert({_id: 0, a: 0, b: 0}));
    assert.writeOK(coll.insert({_id: 1, a: 0, b: 1}));
    assert.writeOK(coll.insert({_id: 2, a: 1, b: 0}));
    assert.writeOK(coll.insert({_id: 3, a: 1, b: 1}));

    /**
     * Helper to test that for a given pipeline, the same results are returned whether or not an
     * index is present.
     */
    function assertResultsMatch(pipeline) {
        // Add a match stage to ensure index scans are considerd for planning (workaround for
        // SERVER-20066).
        pipeline = [{$match: {a: {$gte: 0}}}].concat(pipeline);

        // Once with an index.
        assert.commandWorked(coll.ensureIndex(indexSpec));
        var resultsWithIndex = coll.aggregate(pipeline).toArray();

        // Again without an index.
        assert.commandWorked(coll.dropIndex(indexSpec));
        var resultsWithoutIndex = coll.aggregate(pipeline).toArray();

        assert(orderedArrayEq(resultsWithIndex, resultsWithoutIndex));
    }

    // Uncovered $project, no $sort.
    assertResultsMatch([{$project: {_id: 1, a: 1, b: 1}}]);

    // Covered $project, no $sort.
    assertResultsMatch([{$project: {_id: 0, a: 1}}]);
    assertResultsMatch([{$project: {_id: 0, a: 1, b: 1}}]);
    assertResultsMatch([{$project: {_id: 0, a: 1, b: 1, c: {$literal: 1}}}]);
    assertResultsMatch([{$project: {_id: 0, a: 1, b: 1}}, {$project: {a: 1}}]);
    assertResultsMatch([{$project: {_id: 0, a: 1, b: 1}}, {$group: {_id: null, a: {$sum: "$a"}}}]);

    // Non-blocking $sort, uncovered $project.
    assertResultsMatch([{$sort: {a: -1, b: -1}}, {$project: {_id: 1, a: 1, b: 1}}]);
    assertResultsMatch([{$sort: {a: 1, b: 1}}, {$project: {_id: 1, a: 1, b: 1}}]);
    assertResultsMatch(
        [{$sort: {a: 1, b: 1}}, {$group: {_id: "$_id", arr: {$push: "$a"}, sum: {$sum: "$b"}}}]);

    // Non-blocking $sort, covered $project.
    assertResultsMatch([{$sort: {a: -1, b: -1}}, {$project: {_id: 0, a: 1, b: 1}}]);
    assertResultsMatch([{$sort: {a: 1, b: 1}}, {$project: {_id: 0, a: 1, b: 1}}]);
    assertResultsMatch([{$sort: {a: 1, b: 1}}, {$group: {_id: "$b", arr: {$push: "$a"}}}]);

    // Blocking $sort, uncovered $project.
    assertResultsMatch([{$sort: {b: 1, a: -1}}, {$project: {_id: 1, a: 1, b: 1}}]);
    assertResultsMatch(
        [{$sort: {b: 1, a: -1}}, {$group: {_id: "$_id", arr: {$push: "$a"}, sum: {$sum: "$b"}}}]);

    // Blocking $sort, covered $project.
    assertResultsMatch([{$sort: {b: 1, a: -1}}, {$project: {_id: 0, a: 1, b: 1}}]);
    assertResultsMatch([{$sort: {b: 1, a: -1}}, {$group: {_id: "$b", arr: {$push: "$a"}}}]);
}());