summaryrefslogtreecommitdiff
path: root/jstests/aggregation/max_subpipeline_depth.js
blob: 72407c9a758058b1db589469926c2edb6c849a31 (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
// Tests that a pipeline isn't allowed to specify an arbitrary number of sub-pipelines within
// $lookups and other similar stages.
// @tags: [
//   # TODO SERVER-29159 $lookup doesn't support sharded collections.
//   assumes_unsharded_collection
// ]
(function() {
"use strict";

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

function makeLookupNDeep(n) {
    const lookupTemplate = {$lookup: {from: coll.getName(), as: "results", pipeline: []}};

    let lookupSpec = lookupTemplate;
    for (let i = 0; i < n; ++i) {
        lookupSpec = {$lookup: Object.merge(lookupTemplate.$lookup, {pipeline: [lookupSpec]})};
    }
    return lookupSpec;
}

function makeUnionNDeep(n) {
    const unionTemplate = {$unionWith: {coll: coll.getName(), pipeline: []}};

    let unionSpec = unionTemplate;
    for (let i = 0; i < n; ++i) {
        unionSpec = {$unionWith: Object.merge(unionTemplate.$unionWith, {pipeline: [unionSpec]})};
    }
    return unionSpec;
}

const maxDepth = 20;
assert.commandWorked(db.runCommand(
    {aggregate: coll.getName(), pipeline: [makeLookupNDeep(maxDepth - 1)], cursor: {}}));
assert.commandFailedWithCode(
    db.runCommand({aggregate: coll.getName(), pipeline: [makeLookupNDeep(maxDepth)], cursor: {}}),
    ErrorCodes.MaxSubPipelineDepthExceeded);

assert.commandWorked(db.runCommand(
    {aggregate: coll.getName(), pipeline: [makeUnionNDeep(maxDepth - 1)], cursor: {}}));
assert.commandFailedWithCode(
    db.runCommand({aggregate: coll.getName(), pipeline: [makeUnionNDeep(maxDepth)], cursor: {}}),
    ErrorCodes.MaxSubPipelineDepthExceeded);
}());