summaryrefslogtreecommitdiff
path: root/jstests/aggregation/bugs/server8581.js
blob: aa2158c0cedaf8dbcd4a7fcab73e0b679eeff19f (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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
// Check $redact pipeline stage.
load('jstests/aggregation/extras/utils.js');

t = db.jstests_aggregation_redact;
t.drop();

// this document will always be present but its content will change
t.save({ _id: 1,
         level: 1,
         // b will present on level 3, 4, and 5
         b: { level: 3,
              c: 5, // always included when b is included
              // the contents of d test that if we cannot see a document then we cannot see its
              // array-nested subdocument even if we have permissions to see the subdocument.
              // it also tests arrays containing documents we cannot see
              d: [ {level: 1, e: 4},
                   {f: 6},
                   {level: 5, g: 9},
                   "NOT AN OBJECT!!11!", // always included when b is included
                   [2, 3, 4, {level: 1, r: 11}, {level: 5, s: 99}]
                   // nested array should always be included once b is
                   // but the second object should only show up at level 5
                 ]
            },
         // the contents of h test that in order to see a subdocument (j) we must be able to see all
         // parent documents (h and i) even if we have permissions to see the subdocument
         h: { level: 2,
              i: { level: 4,
                   j: { level: 1,
                        k: 8
                      }
                 }
            },
         // l checks that we get an empty document when we can see a document but none of its fields
         l: {
              m: { level: 3,
                   n: 12
                 }
            },
         // o checks that we get an empty array when we can see a array but none of its entries
         o: [{ level: 5,
               p: 19
            }],
         // q is a basic field check and should always be included
         q: 14
      });

// this document will sometimes be missing
t.save({ _id: 2,
         level: 4,
      });

a1 = t.aggregate({$redact:  {$cond: [{$lte: ['$level', 1]}, "$$DESCEND", "$$PRUNE"]}});
a2 = t.aggregate({$redact:  {$cond: [{$lte: ['$level', 2]}, "$$DESCEND", "$$PRUNE"]}});
a3 = t.aggregate({$redact:  {$cond: [{$lte: ['$level', 3]}, "$$DESCEND", "$$PRUNE"]}});
a4 = t.aggregate({$redact:  {$cond: [{$lte: ['$level', 4]}, "$$DESCEND", "$$PRUNE"]}});
a5 = t.aggregate({$redact:  {$cond: [{$lte: ['$level', 5]}, "$$DESCEND", "$$PRUNE"]}});

a1result = [{ _id: 1,
              level: 1,
              l: {},
              o: [],
              q: 14
           }];

a2result = [{ _id: 1,
              level: 1,
              h: { level: 2,
                 },
              l: {},
              o: [],
              q: 14
           }];

a3result = [{ _id: 1,
              level: 1,
              b: { level: 3,
                   c: 5,
                   d: [ {level: 1, e: 4},
                        {f: 6},
                        "NOT AN OBJECT!!11!",
                        [2, 3, 4, {level: 1, r: 11}]
                      ]
                 },
              h: { level: 2,
                 },
              l: {
                   m: { level: 3,
                         n: 12
                      }
                 },
              o: [],
              q: 14
           }];

a4result = [{ _id: 1,
              level: 1,
              b: { level: 3,
                   c: 5,
                   d: [ {level: 1, e: 4},
                        {f: 6},
                        "NOT AN OBJECT!!11!",
                        [2, 3, 4, {level: 1, r: 11}]
                      ]
                 },
              h: { level: 2,
                   i: { level: 4,
                        j: { level: 1,
                             k: 8
                           }
                      }
                 },
              l: {
                   m: { level: 3,
                         n: 12
                      }
                 },
              o: [],
              q: 14
           },
           { _id: 2,
             level: 4,
           }];

a5result = [{ _id: 1,
              level: 1,
              b: { level: 3,
                   c: 5,
                   d: [ {level: 1, e: 4},
                        {f: 6},
                        {level: 5, g: 9},
                        "NOT AN OBJECT!!11!",
                        [2, 3, 4, {level: 1, r: 11}, {level: 5, s: 99}]
                      ]
                 },
              h: { level: 2,
                   i: { level: 4,
                        j: { level: 1,
                             k: 8
                           }
                      }
                 },
              l: {
                   m: { level: 3,
                         n: 12
                      }
                 },
              o: [{ level: 5,
                    p: 19
                 }],
              q: 14
           },
           { _id: 2,
             level: 4,
           }];

assert.eq(a1.toArray(), a1result);
assert.eq(a2.toArray(), a2result);
assert.eq(a3.toArray(), a3result);
assert.eq(a4.toArray(), a4result);
assert.eq(a5.toArray(), a5result);

// Test redacts that are just a variable access (this can happen as a result of optimizations)
assert.eq(t.aggregate({$redact: "$$PRUNE"}).toArray(), []);
assert.eq(t.aggregate({$redact: "$$KEEP"}).toArray(), t.find().toArray());
assert.eq(t.aggregate({$redact: "$$DESCEND"}).toArray(), t.find().toArray());

// test $$KEEP
t.drop();
// entire document should be present at 2 and beyond
t.save({ _id: 1,
         level: 2,
         b: { level: 3,
              c: 2
            },
         d: { level: 1,
              e: 8
            },
         f: 9
      });

b1 = t.aggregate({$redact:  {$cond: [{$lte: ['$level', 1]}, "$$KEEP", "$$PRUNE"]}});
b2 = t.aggregate({$redact:  {$cond: [{$lte: ['$level', 2]}, "$$KEEP", "$$PRUNE"]}});
b3 = t.aggregate({$redact:  {$cond: [{$lte: ['$level', 3]}, "$$KEEP", "$$PRUNE"]}});

b1result = [];

b23result = [{ _id: 1,
              level: 2,
              b: { level: 3,
                   c: 2
                 },
              d: { level: 1,
                   e: 8
                 },
              f: 9
           }];

assert.eq(b1.toArray(), b1result);
assert.eq(b2.toArray(), b23result);
assert.eq(b3.toArray(), b23result);