summaryrefslogtreecommitdiff
path: root/jstests/core/update_modifier_pop.js
blob: c74d7f254bffbe70e9edb773620d456773b25819 (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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// @tags: [requires_non_retryable_writes]

(function() {
    "use strict";

    let coll = db.update_modifier_pop;
    coll.drop();

    assert.writeOK(coll.insert({_id: 0}));

    // $pop with value of 0 fails to parse.
    assert.writeErrorWithCode(coll.update({_id: 0}, {$pop: {"a.b": 0}}), ErrorCodes.FailedToParse);

    // $pop with value of -2 fails to parse.
    assert.writeErrorWithCode(coll.update({_id: 0}, {$pop: {"a.b": -2}}), ErrorCodes.FailedToParse);

    // $pop with value of 2.5 fails to parse.
    assert.writeErrorWithCode(coll.update({_id: 0}, {$pop: {"a.b": 2.5}}),
                              ErrorCodes.FailedToParse);

    // $pop with value of 1.1 fails to parse.
    assert.writeErrorWithCode(coll.update({_id: 0}, {$pop: {"a.b": 1.1}}),
                              ErrorCodes.FailedToParse);

    // $pop with a nested object fails to parse.
    assert.writeErrorWithCode(coll.update({_id: 0}, {$pop: {a: {b: 1}}}), ErrorCodes.FailedToParse);

    // $pop is a no-op when the path does not exist.
    let writeRes = assert.writeOK(coll.update({_id: 0}, {$pop: {"a.b": 1}}));
    assert.eq(writeRes.nMatched, 1);
    if (db.getMongo().writeMode() === "commands") {
        assert.eq(writeRes.nModified, 0);
    }

    // $pop is a no-op when the path partially exists.
    assert.writeOK(coll.remove({}));
    assert.writeOK(coll.insert({_id: 0, a: {c: 1}}));
    writeRes = assert.writeOK(coll.update({_id: 0}, {$pop: {"a.b": 1}}));
    assert.eq(writeRes.nMatched, 1);
    if (db.getMongo().writeMode() === "commands") {
        assert.eq(writeRes.nModified, 0);
    }

    // $pop fails when the path is blocked by a scalar element.
    assert.writeOK(coll.remove({}));
    assert.writeOK(coll.insert({_id: 0, a: {b: 1}}));
    assert.writeError(coll.update({_id: 0}, {$pop: {"a.b.c": 1}}));

    // $pop fails when the path is blocked by an array element.
    assert.writeOK(coll.remove({}));
    assert.writeOK(coll.insert({_id: 0, a: {b: [1, 2]}}));
    assert.writeError(coll.update({_id: 0}, {$pop: {"a.b.c": 1}}));

    // $pop fails when the path exists but is not an array.
    assert.writeOK(coll.remove({}));
    assert.writeOK(coll.insert({_id: 0, a: {b: {c: 1}}}));
    assert.writeError(coll.update({_id: 0}, {$pop: {"a.b": 1}}));

    // $pop is a no-op when the path contains an empty array.
    assert.writeOK(coll.remove({}));
    assert.writeOK(coll.insert({_id: 0, a: {b: []}}));
    writeRes = assert.writeOK(coll.update({_id: 0}, {$pop: {"a.b": 1}}));
    assert.eq(writeRes.nMatched, 1);
    if (db.getMongo().writeMode() === "commands") {
        assert.eq(writeRes.nModified, 0);
    }

    // Successfully pop from the end of an array.
    assert.writeOK(coll.remove({}));
    assert.writeOK(coll.insert({_id: 0, a: {b: [1, 2, 3]}}));
    writeRes = assert.writeOK(coll.update({_id: 0}, {$pop: {"a.b": 1}}));
    assert.eq(writeRes.nMatched, 1);
    if (db.getMongo().writeMode() === "commands") {
        assert.eq(writeRes.nModified, 1);
    }
    assert.eq({_id: 0, a: {b: [1, 2]}}, coll.findOne());

    // Successfully pop from the beginning of an array.
    writeRes = assert.writeOK(coll.update({_id: 0}, {$pop: {"a.b": -1}}));
    assert.eq(writeRes.nMatched, 1);
    if (db.getMongo().writeMode() === "commands") {
        assert.eq(writeRes.nModified, 1);
    }
    assert.eq({_id: 0, a: {b: [2]}}, coll.findOne());

    // $pop with the positional ($) operator.
    assert.writeOK(coll.remove({}));
    assert.writeOK(coll.insert({_id: 0, a: [{b: [1, 2, 3]}, {b: [4, 5, 6]}]}));
    assert.writeOK(coll.update({_id: 0, "a.b": 5}, {$pop: {"a.$.b": 1}}));
    assert.eq({_id: 0, a: [{b: [1, 2, 3]}, {b: [4, 5]}]}, coll.findOne());

    // $pop with arrayFilters.
    if (db.getMongo().writeMode() === "commands") {
        assert.writeOK(coll.remove({}));
        assert.writeOK(coll.insert({_id: 0, a: [{b: [1, 2]}, {b: [4, 5]}, {b: [2, 3]}]}));
        assert.writeOK(
            coll.update({_id: 0}, {$pop: {"a.$[i].b": -1}}, {arrayFilters: [{"i.b": 2}]}));
        assert.eq({_id: 0, a: [{b: [2]}, {b: [4, 5]}, {b: [3]}]}, coll.findOne());
    }

    // $pop from a nested array.
    assert.writeOK(coll.remove({}));
    assert.writeOK(coll.insert({_id: 0, a: [1, [2, 3, 4]]}));
    assert.writeOK(coll.update({_id: 0}, {$pop: {"a.1": 1}}));
    assert.eq({_id: 0, a: [1, [2, 3]]}, coll.findOne());

    // $pop is a no-op when array element in path does not exist.
    assert.writeOK(coll.remove({}));
    assert.writeOK(coll.insert({_id: 0, a: [{b: 0}, {b: 1}]}));
    writeRes = assert.writeOK(coll.update({_id: 0}, {$pop: {"a.2.b": 1}}));
    assert.eq(writeRes.nMatched, 1);
    if (db.getMongo().writeMode() === "commands") {
        assert.eq(writeRes.nModified, 0);
    }
}());