diff options
Diffstat (limited to 'jstests/aggregation/bugs')
89 files changed, 2036 insertions, 2157 deletions
diff --git a/jstests/aggregation/bugs/cond.js b/jstests/aggregation/bugs/cond.js index e71f49e25a5..2b4fa8ff16e 100644 --- a/jstests/aggregation/bugs/cond.js +++ b/jstests/aggregation/bugs/cond.js @@ -5,72 +5,79 @@ load('jstests/aggregation/extras/utils.js'); t = db.jstests_aggregation_cond; t.drop(); -t.save( {} ); +t.save({}); -function assertError( expectedErrorCode, condSpec ) { +function assertError(expectedErrorCode, condSpec) { assertErrorCode(t, {$project: {a: {$cond: condSpec}}}, expectedErrorCode); } -function assertResult( expectedResult, arg ) { - assert.eq( expectedResult, - t.aggregate( { $project:{ a:{ $cond:arg } } } ).toArray()[0].a ); +function assertResult(expectedResult, arg) { + assert.eq(expectedResult, t.aggregate({$project: {a: {$cond: arg}}}).toArray()[0].a); } // Wrong number of args. -assertError( 16020, [] ); -assertError( 16020, [1] ); -assertError( 16020, [false] ); -assertError( 16020, [1,1] ); -assertError( 16020, [1,1,null,1] ); -assertError( 16020, [1,1,1,undefined] ); +assertError(16020, []); +assertError(16020, [1]); +assertError(16020, [false]); +assertError(16020, [1, 1]); +assertError(16020, [1, 1, null, 1]); +assertError(16020, [1, 1, 1, undefined]); // Bad object cases -assertError( 17080, {"else":1, then:1} ); -assertError( 17081, {"if":1, "else":1} ); -assertError( 17082, {"if":1, then:1} ); -assertError( 17083, {asdf:1, then:1} ); +assertError(17080, {"else": 1, then: 1}); +assertError(17081, {"if": 1, "else": 1}); +assertError(17082, {"if": 1, then: 1}); +assertError(17083, {asdf: 1, then: 1}); // Literal expressions. -assertResult( 1, [true, 1, 2] ); -assertResult( 2, [false, 1, 2] ); +assertResult(1, [true, 1, 2]); +assertResult(2, [false, 1, 2]); // Order independence for object case -assertResult(1, {"if":true, "then":1, "else":2}); -assertResult(1, {"if":true, "else":2, "then":1}); -assertResult(1, {"then":1, "if":true, "else":2}); -assertResult(1, {"then":1, "else":2, "if":true}); -assertResult(1, {"else":2, "then":1, "if":true}); -assertResult(1, {"else":2, "if":true, "then":1}); +assertResult(1, {"if": true, "then": 1, "else": 2}); +assertResult(1, {"if": true, "else": 2, "then": 1}); +assertResult(1, {"then": 1, "if": true, "else": 2}); +assertResult(1, {"then": 1, "else": 2, "if": true}); +assertResult(1, {"else": 2, "then": 1, "if": true}); +assertResult(1, {"else": 2, "if": true, "then": 1}); // Computed expressions. -assertResult( 1, [{ $and:[] }, { $add:[ 1 ] }, { $add:[ 1, 1 ] }] ); -assertResult( 2, [{ $or:[] }, { $add:[ 1 ] }, { $add:[ 1, 1 ] }] ); +assertResult(1, [{$and: []}, {$add: [1]}, {$add: [1, 1]}]); +assertResult(2, [{$or: []}, {$add: [1]}, {$add: [1, 1]}]); t.drop(); -t.save( { t:true, f:false, x:'foo', y:'bar' } ); +t.save({t: true, f: false, x: 'foo', y: 'bar'}); // Field path expressions. -assertResult( 'foo', ['$t', '$x', '$y'] ); -assertResult( 'bar', ['$f', '$x', '$y'] ); +assertResult('foo', ['$t', '$x', '$y']); +assertResult('bar', ['$f', '$x', '$y']); t.drop(); -t.save( {} ); +t.save({}); // Coerce to bool. -assertResult( 'a', [1, 'a', 'b'] ); -assertResult( 'a', ['', 'a', 'b'] ); -assertResult( 'b', [0, 'a', 'b'] ); +assertResult('a', [1, 'a', 'b']); +assertResult('a', ['', 'a', 'b']); +assertResult('b', [0, 'a', 'b']); // Nested. t.drop(); -t.save( { noonSense:'am', mealCombined:'no' } ); -t.save( { noonSense:'am', mealCombined:'yes' } ); -t.save( { noonSense:'pm', mealCombined:'yes' } ); -t.save( { noonSense:'pm', mealCombined:'no' } ); -assert.eq( [ 'breakfast', 'brunch', 'linner', 'dinner' ], - t.aggregate( { $project:{ a:{ $cond:[ { $eq:[ '$noonSense', 'am' ] }, - { $cond:[ { $eq:[ '$mealCombined', 'yes' ] }, - 'brunch', 'breakfast' ] }, - { $cond:[ { $eq:[ '$mealCombined', 'yes' ] }, - 'linner', 'dinner' ] } ] } } } ) - .map( function( x ) { return x.a; } ) ); +t.save({noonSense: 'am', mealCombined: 'no'}); +t.save({noonSense: 'am', mealCombined: 'yes'}); +t.save({noonSense: 'pm', mealCombined: 'yes'}); +t.save({noonSense: 'pm', mealCombined: 'no'}); +assert.eq(['breakfast', 'brunch', 'linner', 'dinner'], + t.aggregate({ + $project: { + a: { + $cond: [ + {$eq: ['$noonSense', 'am']}, + {$cond: [{$eq: ['$mealCombined', 'yes']}, 'brunch', 'breakfast']}, + {$cond: [{$eq: ['$mealCombined', 'yes']}, 'linner', 'dinner']} + ] + } + } + }) + .map(function(x) { + return x.a; + })); diff --git a/jstests/aggregation/bugs/firstlast.js b/jstests/aggregation/bugs/firstlast.js index 5b3a92be2b4..ca9e963f6ca 100644 --- a/jstests/aggregation/bugs/firstlast.js +++ b/jstests/aggregation/bugs/firstlast.js @@ -5,106 +5,116 @@ t = db.jstests_aggregation_firstlast; t.drop(); /** Check expected $first and $last result values. */ -function assertFirstLast( expectedFirst, expectedLast, pipeline, expression ) { +function assertFirstLast(expectedFirst, expectedLast, pipeline, expression) { pipeline = pipeline || []; expression = expression || '$b'; - pipeline.push( { $group:{ _id:'$a', - first:{ $first:expression }, - last:{ $last:expression } } } ); - result = t.aggregate( pipeline ).toArray(); - for( var i = 0; i < result.length; ++i ) { - if ( result[ i ]._id == 1 ) { + pipeline.push({$group: {_id: '$a', first: {$first: expression}, last: {$last: expression}}}); + result = t.aggregate(pipeline).toArray(); + for (var i = 0; i < result.length; ++i) { + if (result[i]._id == 1) { // Check results for group _id 1. - assert.eq( expectedFirst, result[ i ].first ); - assert.eq( expectedLast, result[ i ].last ); + assert.eq(expectedFirst, result[i].first); + assert.eq(expectedLast, result[i].last); return; } } - assert( false, "Expected group _id '1' missing." ); + assert(false, "Expected group _id '1' missing."); } // One document. -t.save( { a:1, b:1 } ); -assertFirstLast( 1, 1 ); +t.save({a: 1, b: 1}); +assertFirstLast(1, 1); // Two documents. -t.save( { a:1, b:2 } ); -assertFirstLast( 1, 2 ); +t.save({a: 1, b: 2}); +assertFirstLast(1, 2); // Three documents. -t.save( { a:1, b:3 } ); -assertFirstLast( 1, 3 ); +t.save({a: 1, b: 3}); +assertFirstLast(1, 3); // Another 'a' key value does not affect outcome. t.drop(); -t.save( { a:3, b:0 } ); -t.save( { a:1, b:1 } ); -t.save( { a:1, b:2 } ); -t.save( { a:1, b:3 } ); -t.save( { a:2, b:0 } ); -assertFirstLast( 1, 3 ); +t.save({a: 3, b: 0}); +t.save({a: 1, b: 1}); +t.save({a: 1, b: 2}); +t.save({a: 1, b: 3}); +t.save({a: 2, b: 0}); +assertFirstLast(1, 3); // Additional pipeline stages do not affect outcome if order is maintained. -assertFirstLast( 1, 3, [ { $project:{ x:'$a', y:'$b' } }, { $project:{ a:'$x', b:'$y' } } ] ); +assertFirstLast(1, 3, [{$project: {x: '$a', y: '$b'}}, {$project: {a: '$x', b: '$y'}}]); // Additional pipeline stages affect outcome if order is modified. -assertFirstLast( 3, 1, [ { $sort:{ b:-1 } } ] ); +assertFirstLast(3, 1, [{$sort: {b: -1}}]); // Skip and limit affect the results seen. t.drop(); -t.save( { a:1, b:1 } ); -t.save( { a:1, b:2 } ); -t.save( { a:1, b:3 } ); -assertFirstLast( 1, 2, [ { $limit:2 } ] ); -assertFirstLast( 2, 3, [ { $skip:1 }, { $limit:2 } ] ); -assertFirstLast( 2, 2, [ { $skip:1 }, { $limit:1 } ] ); +t.save({a: 1, b: 1}); +t.save({a: 1, b: 2}); +t.save({a: 1, b: 3}); +assertFirstLast(1, 2, [{$limit: 2}]); +assertFirstLast(2, 3, [{$skip: 1}, {$limit: 2}]); +assertFirstLast(2, 2, [{$skip: 1}, {$limit: 1}]); // Mixed type values. -t.save( { a:1, b:'foo' } ); -assertFirstLast( 1, 'foo' ); +t.save({a: 1, b: 'foo'}); +assertFirstLast(1, 'foo'); t.drop(); -t.save( { a:1, b:'bar' } ); -t.save( { a:1, b:true } ); -assertFirstLast( 'bar', true ); +t.save({a: 1, b: 'bar'}); +t.save({a: 1, b: true}); +assertFirstLast('bar', true); // Value null. t.drop(); -t.save( { a:1, b:null } ); -t.save( { a:1, b:2 } ); -assertFirstLast( null, 2 ); +t.save({a: 1, b: null}); +t.save({a: 1, b: 2}); +assertFirstLast(null, 2); t.drop(); -t.save( { a:1, b:2 } ); -t.save( { a:1, b:null } ); -assertFirstLast( 2, null ); +t.save({a: 1, b: 2}); +t.save({a: 1, b: null}); +assertFirstLast(2, null); t.drop(); -t.save( { a:1, b:null } ); -t.save( { a:1, b:null } ); -assertFirstLast( null, null ); +t.save({a: 1, b: null}); +t.save({a: 1, b: null}); +assertFirstLast(null, null); // Value missing. t.drop(); -t.save( { a:1 } ); -t.save( { a:1, b:2 } ); -assertFirstLast( undefined, 2 ); +t.save({a: 1}); +t.save({a: 1, b: 2}); +assertFirstLast(undefined, 2); t.drop(); -t.save( { a:1, b:2 } ); -t.save( { a:1 } ); -assertFirstLast( 2, undefined ); +t.save({a: 1, b: 2}); +t.save({a: 1}); +assertFirstLast(2, undefined); t.drop(); -t.save( { a:1 } ); -t.save( { a:1 } ); -assertFirstLast( undefined, undefined ); +t.save({a: 1}); +t.save({a: 1}); +assertFirstLast(undefined, undefined); // Dotted field. t.drop(); -t.save( { a:1, b:[ { c:1 }, { c:2 } ] } ); -t.save( { a:1, b:[ { c:6 }, {} ] } ); -assertFirstLast( [ 1, 2 ], [ 6 ], [], '$b.c' ); +t.save({a: 1, b: [{c: 1}, {c: 2}]}); +t.save({a: 1, b: [{c: 6}, {}]}); +assertFirstLast([1, 2], [6], [], '$b.c'); // Computed expressions. t.drop(); -t.save( { a:1, b:1 } ); -t.save( { a:1, b:2 } ); -assertFirstLast( 1, 0, [], { $mod:[ '$b', 2 ] } ); -assertFirstLast( 0, 1, [], { $mod:[ { $add:[ '$b', 1 ] }, 2 ] } ); +t.save({a: 1, b: 1}); +t.save({a: 1, b: 2}); +assertFirstLast(1, + 0, + [], + { +$mod: + ['$b', 2] + }); +assertFirstLast(0, + 1, + [], + { +$mod: + [{$add: ['$b', 1]}, 2] + }); diff --git a/jstests/aggregation/bugs/ifnull.js b/jstests/aggregation/bugs/ifnull.js index a8f0ccf4c66..8967ffe7ab7 100644 --- a/jstests/aggregation/bugs/ifnull.js +++ b/jstests/aggregation/bugs/ifnull.js @@ -5,58 +5,58 @@ load('jstests/aggregation/extras/utils.js'); t = db.jstests_aggregation_ifnull; t.drop(); -t.save( {} ); +t.save({}); -function assertError( expectedErrorCode, ifNullSpec ) { +function assertError(expectedErrorCode, ifNullSpec) { assertErrorCode(t, {$project: {a: {$ifNull: ifNullSpec}}}, expectedErrorCode); } -function assertResult( expectedResult, arg0, arg1 ) { - var res = t.aggregate( { $project:{ a:{ $ifNull:[ arg0, arg1 ] } } } ).toArray()[0]; - assert.eq( expectedResult, res.a ); +function assertResult(expectedResult, arg0, arg1) { + var res = t.aggregate({$project: {a: {$ifNull: [arg0, arg1]}}}).toArray()[0]; + assert.eq(expectedResult, res.a); } // Wrong number of args. -assertError( 16020, [] ); -assertError( 16020, [1] ); -assertError( 16020, [null] ); -assertError( 16020, [1,1,1] ); -assertError( 16020, [1,1,null] ); -assertError( 16020, [1,1,undefined] ); +assertError(16020, []); +assertError(16020, [1]); +assertError(16020, [null]); +assertError(16020, [1, 1, 1]); +assertError(16020, [1, 1, null]); +assertError(16020, [1, 1, undefined]); // First arg non null. -assertResult( 1, 1, 2 ); -assertResult( 2, 2, 1 ); -assertResult( false, false, 1 ); -assertResult( '', '', 1 ); -assertResult( [], [], 1 ); -assertResult( {}, {}, 1 ); -assertResult( 1, 1, null ); -assertResult( 2, 2, undefined ); +assertResult(1, 1, 2); +assertResult(2, 2, 1); +assertResult(false, false, 1); +assertResult('', '', 1); +assertResult([], [], 1); +assertResult({}, {}, 1); +assertResult(1, 1, null); +assertResult(2, 2, undefined); // First arg null. -assertResult( 2, null, 2 ); -assertResult( 1, null, 1 ); -assertResult( null, null, null ); -assertResult( undefined, null, undefined ); +assertResult(2, null, 2); +assertResult(1, null, 1); +assertResult(null, null, null); +assertResult(undefined, null, undefined); // First arg undefined. -assertResult( 2, undefined, 2 ); -assertResult( 1, undefined, 1 ); -assertResult( null, undefined, null ); -assertResult( undefined, undefined, undefined ); +assertResult(2, undefined, 2); +assertResult(1, undefined, 1); +assertResult(null, undefined, null); +assertResult(undefined, undefined, undefined); // Computed expression. -assertResult( 3, { $add:[ 1, 2 ] }, 5 ); -assertResult( 20, '$missingField', { $multiply:[ 4, 5 ] } ); +assertResult(3, {$add: [1, 2]}, 5); +assertResult(20, '$missingField', {$multiply: [4, 5]}); // Divide/mod by 0. -assertError(16608 , [{$divide: [1, 0]}, 0]); -assertError(16610 , [{$mod: [1, 0]}, 0]); +assertError(16608, [{$divide: [1, 0]}, 0]); +assertError(16610, [{$mod: [1, 0]}, 0]); // Nested. t.drop(); -t.save( { d:'foo' } ); -assertResult( 'foo', '$a', { $ifNull:[ '$b', { $ifNull:[ '$c', '$d' ] } ] } ); -t.update( {}, { $set:{ b:'bar' } } ); -assertResult( 'bar', '$a', { $ifNull:[ '$b', { $ifNull:[ '$c', '$d' ] } ] } ); +t.save({d: 'foo'}); +assertResult('foo', '$a', {$ifNull: ['$b', {$ifNull: ['$c', '$d']}]}); +t.update({}, {$set: {b: 'bar'}}); +assertResult('bar', '$a', {$ifNull: ['$b', {$ifNull: ['$c', '$d']}]}); diff --git a/jstests/aggregation/bugs/lookup_unwind_getmore.js b/jstests/aggregation/bugs/lookup_unwind_getmore.js index e15e4155136..6c8d886b78f 100644 --- a/jstests/aggregation/bugs/lookup_unwind_getmore.js +++ b/jstests/aggregation/bugs/lookup_unwind_getmore.js @@ -31,17 +31,17 @@ aggregate: 'source', pipeline: [ { - $lookup: { - from: 'dest', - localField: 'local', - foreignField: 'foreign', - as: 'matches', - } + $lookup: { + from: 'dest', + localField: 'local', + foreignField: 'foreign', + as: 'matches', + } }, { - $unwind: { - path: '$matches', - }, + $unwind: { + path: '$matches', + }, }, ], cursor: { diff --git a/jstests/aggregation/bugs/match.js b/jstests/aggregation/bugs/match.js index 70fb81e9520..fbc467812d7 100644 --- a/jstests/aggregation/bugs/match.js +++ b/jstests/aggregation/bugs/match.js @@ -6,11 +6,16 @@ load('jstests/aggregation/extras/utils.js'); t = db.jstests_aggregation_match; t.drop(); -identityProjection = { _id:'$_id', a:'$a' }; +identityProjection = { + _id: '$_id', + a: '$a' +}; /** Assert that an aggregation generated the expected error. */ -function assertError( expectedCode, matchSpec ) { - matchStage = { $match:matchSpec }; +function assertError(expectedCode, matchSpec) { + matchStage = { + $match: matchSpec + }; // Check where matching is folded in to DocumentSourceCursor. assertErrorCode(t, [matchStage], expectedCode); // Check where matching is not folded in to DocumentSourceCursor. @@ -18,166 +23,174 @@ function assertError( expectedCode, matchSpec ) { } /** Assert that the contents of two arrays are equal, ignoring element ordering. */ -function assertEqualResultsUnordered( one, two ) { - oneStr = one.map( function( x ) { return tojson( x ); } ); - twoStr = two.map( function( x ) { return tojson( x ); } ); +function assertEqualResultsUnordered(one, two) { + oneStr = one.map(function(x) { + return tojson(x); + }); + twoStr = two.map(function(x) { + return tojson(x); + }); oneStr.sort(); twoStr.sort(); - assert.eq( oneStr, twoStr ); + assert.eq(oneStr, twoStr); } /** Assert that an aggregation result is as expected. */ -function assertResults( expectedResults, matchSpec ) { - findResults = t.find( matchSpec ).toArray(); - if ( expectedResults ) { - assertEqualResultsUnordered( expectedResults, findResults ); +function assertResults(expectedResults, matchSpec) { + findResults = t.find(matchSpec).toArray(); + if (expectedResults) { + assertEqualResultsUnordered(expectedResults, findResults); } - matchStage = { $match:matchSpec }; + matchStage = { + $match: matchSpec + }; // Check where matching is folded in to DocumentSourceCursor. - assertEqualResultsUnordered( findResults, t.aggregate( matchStage ).toArray() ); + assertEqualResultsUnordered(findResults, t.aggregate(matchStage).toArray()); // Check where matching is not folded in to DocumentSourceCursor. - assertEqualResultsUnordered( findResults, - t.aggregate( { $project:identityProjection }, - matchStage ).toArray() ); + assertEqualResultsUnordered(findResults, + t.aggregate({$project: identityProjection}, matchStage).toArray()); } // Invalid matcher syntax. -assertError( 2, { a:{ $mod:[ 0 /* invalid */, 0 ] } } ); +assertError(2, {a: {$mod: [0 /* invalid */, 0]}}); // $where not allowed. -assertError( 16395, { $where:'true' } ); +assertError(16395, {$where: 'true'}); // Geo not allowed. -assertError( 16424, { $match:{ a:{ $near:[ 0, 0 ] } } } ); +assertError(16424, {$match: {a: {$near: [0, 0]}}}); // Update modifier not allowed. -if ( 0 ) { // SERVER-6650 -assertError( 0, { a:1, $inc:{ b:1 } } ); +if (0) { // SERVER-6650 + assertError(0, {a: 1, $inc: {b: 1}}); } // Aggregation expression not allowed. -if ( 0 ) { // SERVER-6650 -assertError( 0, { a:1, b:{ $gt:{ $add:[ 1, 1 ] } } } ); +if (0) { // SERVER-6650 + assertError(0, {a: 1, b: {$gt: {$add: [1, 1]}}}); } -function checkMatchResults( indexed ) { - +function checkMatchResults(indexed) { // No results. t.remove({}); - assertResults( [], {} ); + assertResults([], {}); - t.save( { _id:0, a:1 } ); - t.save( { _id:1, a:2 } ); - t.save( { _id:2, a:3 } ); + t.save({_id: 0, a: 1}); + t.save({_id: 1, a: 2}); + t.save({_id: 2, a: 3}); // Empty query. - assertResults( [ { _id:0, a:1 }, { _id:1, a:2 }, { _id:2, a:3 } ], {} ); + assertResults([{_id: 0, a: 1}, {_id: 1, a: 2}, {_id: 2, a: 3}], {}); // Simple queries. - assertResults( [ { _id:0, a:1 } ], { a:1 } ); - assertResults( [ { _id:1, a:2 } ], { a:2 } ); - assertResults( [ { _id:1, a:2 }, { _id:2, a:3 } ], { a:{ $gt:1 } } ); - assertResults( [ { _id:0, a:1 }, { _id:1, a:2 } ], { a:{ $lte:2 } } ); - assertResults( [ { _id:0, a:1 }, { _id:2, a:3 } ], { a:{ $in:[ 1, 3 ] } } ); + assertResults([{_id: 0, a: 1}], {a: 1}); + assertResults([{_id: 1, a: 2}], {a: 2}); + assertResults([{_id: 1, a: 2}, {_id: 2, a: 3}], {a: {$gt: 1}}); + assertResults([{_id: 0, a: 1}, {_id: 1, a: 2}], {a: {$lte: 2}}); + assertResults([{_id: 0, a: 1}, {_id: 2, a: 3}], {a: {$in: [1, 3]}}); // Regular expression. t.remove({}); - t.save( { _id:0, a:'x' } ); - t.save( { _id:1, a:'yx' } ); - assertResults( [ { _id:0, a:'x' } ], { a:/^x/ } ); - assertResults( [ { _id:0, a:'x' }, { _id:1, a:'yx' } ], { a:/x/ } ); + t.save({_id: 0, a: 'x'}); + t.save({_id: 1, a: 'yx'}); + assertResults([{_id: 0, a: 'x'}], {a: /^x/}); + assertResults([{_id: 0, a: 'x'}, {_id: 1, a: 'yx'}], {a: /x/}); // Dotted field. t.remove({}); - t.save( { _id:0, a:{ b:4 } } ); - t.save( { _id:1, a:2 } ); - assertResults( [ { _id:0, a:{ b:4 } } ], { 'a.b':4 } ); + t.save({_id: 0, a: {b: 4}}); + t.save({_id: 1, a: 2}); + assertResults([{_id: 0, a: {b: 4}}], {'a.b': 4}); // Value within an array. t.remove({}); - t.save( { _id:0, a:[ 1, 2, 3 ] } ); - t.save( { _id:1, a:[ 2, 2, 3 ] } ); - t.save( { _id:2, a:[ 2, 2, 2 ] } ); - assertResults( [ { _id:0, a:[ 1, 2, 3 ] }, { _id:1, a:[ 2, 2, 3 ] } ], { a:3 } ); + t.save({_id: 0, a: [1, 2, 3]}); + t.save({_id: 1, a: [2, 2, 3]}); + t.save({_id: 2, a: [2, 2, 2]}); + assertResults([{_id: 0, a: [1, 2, 3]}, {_id: 1, a: [2, 2, 3]}], {a: 3}); // Missing, null, $exists matching. t.remove({}); - t.save( { _id:0 } ); - t.save( { _id:1, a:null } ); - if ( 0 ) { // SERVER-6571 - t.save( { _id:2, a:undefined } ); + t.save({_id: 0}); + t.save({_id: 1, a: null}); + if (0) { // SERVER-6571 + t.save({_id: 2, a: undefined}); } - t.save( { _id:3, a:0 } ); - assertResults( [ { _id:0 }, { _id:1, a:null } ], { a:null } ); - assertResults( null, { a:{ $exists:true } } ); - assertResults( null, { a:{ $exists:false } } ); + t.save({_id: 3, a: 0}); + assertResults([{_id: 0}, {_id: 1, a: null}], {a: null}); + assertResults(null, {a: {$exists: true}}); + assertResults(null, {a: {$exists: false}}); // $elemMatch t.remove({}); - t.save( { _id:0, a:[ 1, 2 ] } ); - t.save( { _id:1, a:[ 1, 2, 3 ] } ); - assertResults( [ { _id:1, a:[ 1, 2, 3 ] } ], { a:{ $elemMatch:{ $gt:1, $mod:[ 2, 1 ] } } } ); + t.save({_id: 0, a: [1, 2]}); + t.save({_id: 1, a: [1, 2, 3]}); + assertResults([{_id: 1, a: [1, 2, 3]}], {a: {$elemMatch: {$gt: 1, $mod: [2, 1]}}}); t.remove({}); - t.save( { _id:0, a:[ { b:1 }, { c:2 } ] } ); - t.save( { _id:1, a:[ { b:1, c:2 } ] } ); - assertResults( [ { _id:1, a:[ { b:1, c:2 } ] } ], { a:{ $elemMatch:{ b:1, c:2 } } } ); + t.save({_id: 0, a: [{b: 1}, {c: 2}]}); + t.save({_id: 1, a: [{b: 1, c: 2}]}); + assertResults([{_id: 1, a: [{b: 1, c: 2}]}], {a: {$elemMatch: {b: 1, c: 2}}}); // $size t.remove({}); - t.save( {} ); - t.save( { a:null } ); - t.save( { a:[] } ); - t.save( { a:[ 1 ] } ); - t.save( { a:[ 1, 2 ] } ); - assertResults( null, { a:{ $size:0 } } ); - assertResults( null, { a:{ $size:1 } } ); - assertResults( null, { a:{ $size:2 } } ); + t.save({}); + t.save({a: null}); + t.save({a: []}); + t.save({a: [1]}); + t.save({a: [1, 2]}); + assertResults(null, {a: {$size: 0}}); + assertResults(null, {a: {$size: 1}}); + assertResults(null, {a: {$size: 2}}); // $type t.remove({}); - t.save( {} ); - t.save( { a:null } ); - if ( 0 ) { // SERVER-6571 - t.save( { a:undefined } ); + t.save({}); + t.save({a: null}); + if (0) { // SERVER-6571 + t.save({a: undefined}); } - t.save( { a:NumberInt( 1 ) } ); - t.save( { a:NumberLong( 2 ) } ); - t.save( { a:66.6 } ); - t.save( { a:'abc' } ); - t.save( { a:/xyz/ } ); - t.save( { a:{ q:1 } } ); - t.save( { a:true } ); - t.save( { a:new Date() } ); - t.save( { a:new ObjectId() } ); - for( type = 1; type <= 18; ++type ) { - assertResults( null, { a:{ $type:type } } ); + t.save({a: NumberInt(1)}); + t.save({a: NumberLong(2)}); + t.save({a: 66.6}); + t.save({a: 'abc'}); + t.save({a: /xyz/}); + t.save({a: {q: 1}}); + t.save({a: true}); + t.save({a: new Date()}); + t.save({a: new ObjectId()}); + for (type = 1; type <= 18; ++type) { + assertResults(null, {a: {$type: type}}); } // $atomic does not affect results. t.remove({}); - t.save( { _id:0, a:1 } ); - t.save( { _id:1, a:2 } ); - t.save( { _id:2, a:3 } ); - assertResults( [ { _id:0, a:1 } ], { a:1, $atomic:true } ); - assertResults( [ { _id:1, a:2 } ], { a:2, $atomic:true } ); - assertResults( [ { _id:1, a:2 }, { _id:2, a:3 } ], { a:{ $gt:1 }, $atomic:true } ); - assertResults( [ { _id:0, a:1 }, { _id:1, a:2 } ], { a:{ $lte:2 }, $atomic:true } ); - assertResults( [ { _id:0, a:1 }, { _id:2, a:3 } ], { a:{ $in:[ 1, 3 ] }, $atomic:true } ); + t.save({_id: 0, a: 1}); + t.save({_id: 1, a: 2}); + t.save({_id: 2, a: 3}); + assertResults([{_id: 0, a: 1}], {a: 1, $atomic: true}); + assertResults([{_id: 1, a: 2}], {a: 2, $atomic: true}); + assertResults([{_id: 1, a: 2}, {_id: 2, a: 3}], {a: {$gt: 1}, $atomic: true}); + assertResults([{_id: 0, a: 1}, {_id: 1, a: 2}], {a: {$lte: 2}, $atomic: true}); + assertResults([{_id: 0, a: 1}, {_id: 2, a: 3}], {a: {$in: [1, 3]}, $atomic: true}); // $and - assertResults( [ { _id:1, a:2 } ], { $and:[ { a:2 }, { _id:1 } ] } ); - assertResults( [], { $and:[ { a:1 }, { _id:1 } ] } ); - assertResults( [ { _id:1, a:2 }, { _id:2, a:3 } ], - { $and:[ { $or:[ { _id:1 }, { a:3 } ] }, { $or:[ { _id:2 }, { a:2 } ] } ] } ); + assertResults([{_id: 1, a: 2}], {$and: [{a: 2}, {_id: 1}]}); + assertResults([], + { + $and: + [{a: 1}, {_id: 1}] + }); + assertResults([{_id: 1, a: 2}, {_id: 2, a: 3}], + {$and: [{$or: [{_id: 1}, {a: 3}]}, {$or: [{_id: 2}, {a: 2}]}]}); // $or - assertResults( [ { _id:0, a:1 }, { _id:2, a:3 } ], { $or:[ { _id:0 }, { a:3 } ] } ); + assertResults([{_id: 0, a: 1}, {_id: 2, a: 3}], {$or: [{_id: 0}, {a: 3}]}); } -checkMatchResults( false ); -t.ensureIndex( { a:1 } ); -checkMatchResults( true ); -t.ensureIndex( { 'a.b':1 } ); -t.ensureIndex( { 'a.c':1 } ); -checkMatchResults( true ); +checkMatchResults(false); +t.ensureIndex({a: 1}); +checkMatchResults(true); +t.ensureIndex({'a.b': 1}); +t.ensureIndex({'a.c': 1}); +checkMatchResults(true); diff --git a/jstests/aggregation/bugs/server10176.js b/jstests/aggregation/bugs/server10176.js index 50d02ce3a8e..5a56585265d 100644 --- a/jstests/aggregation/bugs/server10176.js +++ b/jstests/aggregation/bugs/server10176.js @@ -32,32 +32,33 @@ load('jstests/aggregation/extras/utils.js'); // valid use of $abs: numbers become positive, null/undefined/nonexistent become null - var results = coll.aggregate([{$project: {a: {$abs: "$a" }}}]).toArray(); - assert.eq(results, [ - {_id: 0, a: 5}, - {_id: 1, a: 5}, - {_id: 2, a: 5.5}, - {_id: 3, a: 5.5}, - {_id: 4, a: 5}, - {_id: 5, a: 5}, - {_id: 6, a: NumberLong("5")}, - {_id: 7, a: NumberLong("5")}, - {_id: 8, a: 0}, - {_id: 9, a: 0}, - {_id: 10, a: 0}, - {_id: 11, a: NumberLong(Math.pow(2, 31))}, - {_id: 12, a: Math.pow(2, 31)}, - {_id: 13, a: NumberLong("1152921504606846977")}, - {_id: 14, a: NumberLong("1152921504606846977")}, - {_id: 15, a: null}, - {_id: 16, a: null}, - {_id: 17, a: NaN}, - {_id: 18, a: null}, - ]); + var results = coll.aggregate([{$project: {a: {$abs: "$a"}}}]).toArray(); + assert.eq(results, + [ + {_id: 0, a: 5}, + {_id: 1, a: 5}, + {_id: 2, a: 5.5}, + {_id: 3, a: 5.5}, + {_id: 4, a: 5}, + {_id: 5, a: 5}, + {_id: 6, a: NumberLong("5")}, + {_id: 7, a: NumberLong("5")}, + {_id: 8, a: 0}, + {_id: 9, a: 0}, + {_id: 10, a: 0}, + {_id: 11, a: NumberLong(Math.pow(2, 31))}, + {_id: 12, a: Math.pow(2, 31)}, + {_id: 13, a: NumberLong("1152921504606846977")}, + {_id: 14, a: NumberLong("1152921504606846977")}, + {_id: 15, a: null}, + {_id: 16, a: null}, + {_id: 17, a: NaN}, + {_id: 18, a: null}, + ]); // Invalid // using $abs on string - assertErrorCode(coll, [{$project: {a: {$abs: "string"}}}], 28765); + assertErrorCode(coll, [{$project: {a: {$abs: "string"}}}], 28765); // using $abs on LLONG_MIN (-2 ^ 63) assertErrorCode(coll, [{$project: {a: {$abs: NumberLong("-9223372036854775808")}}}], 28680); diff --git a/jstests/aggregation/bugs/server10530.js b/jstests/aggregation/bugs/server10530.js index eebfd60f15b..9d361dc16a7 100644 --- a/jstests/aggregation/bugs/server10530.js +++ b/jstests/aggregation/bugs/server10530.js @@ -3,9 +3,9 @@ var t = db.server10530; t.drop(); -t.insert({big: Array(1024*1024).toString()}); -t.insert({big: Array(16*1024*1024 - 1024).toString()}); -t.insert({big: Array(1024*1024).toString()}); +t.insert({big: Array(1024 * 1024).toString()}); +t.insert({big: Array(16 * 1024 * 1024 - 1024).toString()}); +t.insert({big: Array(1024 * 1024).toString()}); assert.eq(t.aggregate().itcount(), 3); diff --git a/jstests/aggregation/bugs/server11118.js b/jstests/aggregation/bugs/server11118.js index 1ec99024a82..da4e9862bad 100644 --- a/jstests/aggregation/bugs/server11118.js +++ b/jstests/aggregation/bugs/server11118.js @@ -9,15 +9,9 @@ function testFormat(date, formatStr, expectedStr) { db.dates.drop(); db.dates.insert({date: date}); - var res = db.dates.aggregate([{$project: { - _id: 0, - formatted: { - $dateToString: { - format: formatStr, - date: "$date" - } - } - }}]).toArray(); + var res = db.dates.aggregate([{ + $project: {_id: 0, formatted: {$dateToString: {format: formatStr, date: "$date"}}} + }]).toArray(); assert.eq(res[0].formatted, expectedStr); } @@ -27,21 +21,16 @@ function testFormatError(formatObj, errCode) { db.dates.drop(); db.dates.insert({tm: ISODate()}); - assertErrorCode(db.dates, {$project: { - _id: 0, - formatted: { - $dateToString: formatObj - }}}, errCode); + assertErrorCode(db.dates, {$project: {_id: 0, formatted: {$dateToString: formatObj}}}, errCode); } // Used to verify that only date values are accepted for date parameter function testDateValueError(dateVal, errCode) { - db.dates.drop(); - db.dates.insert({date: dateVal}); + db.dates.drop(); + db.dates.insert({date: dateVal}); - assertErrorCode(db.dates, { $project: - { formatted: { $dateToString : { format: "%Y", date: "$date" }} } - }, errCode); + assertErrorCode( + db.dates, {$project: {formatted: {$dateToString: {format: "%Y", date: "$date"}}}}, errCode); } var now = ISODate(); @@ -50,17 +39,16 @@ var now = ISODate(); testFormat(now, "%%-%Y-%m-%d-%H-%M-%S-%L", [ - "%", - now.getUTCFullYear().zeroPad(4), - (now.getUTCMonth() + 1).zeroPad(2), - now.getUTCDate().zeroPad(2), - now.getUTCHours().zeroPad(2), - now.getUTCMinutes().zeroPad(2), - now.getUTCSeconds().zeroPad(2), - now.getUTCMilliseconds().zeroPad(3) + "%", + now.getUTCFullYear().zeroPad(4), + (now.getUTCMonth() + 1).zeroPad(2), + now.getUTCDate().zeroPad(2), + now.getUTCHours().zeroPad(2), + now.getUTCMinutes().zeroPad(2), + now.getUTCSeconds().zeroPad(2), + now.getUTCMilliseconds().zeroPad(3) ].join("-")); - // Padding tests var padme = ISODate("2001-02-03T04:05:06.007Z"); @@ -77,16 +65,16 @@ testFormat(padme, "%L", padme.getUTCMilliseconds().zeroPad(3)); testFormat(now, "%d%d***%d***%d**%d*%d", [ - now.getUTCDate().zeroPad(2), - now.getUTCDate().zeroPad(2), - "***", - now.getUTCDate().zeroPad(2), - "***", - now.getUTCDate().zeroPad(2), - "**", - now.getUTCDate().zeroPad(2), - "*", - now.getUTCDate().zeroPad(2) + now.getUTCDate().zeroPad(2), + now.getUTCDate().zeroPad(2), + "***", + now.getUTCDate().zeroPad(2), + "***", + now.getUTCDate().zeroPad(2), + "**", + now.getUTCDate().zeroPad(2), + "*", + now.getUTCDate().zeroPad(2) ].join("")); // JS doesn't have equivalents of these format specifiers @@ -105,17 +93,17 @@ testFormatError({format: "%Y", date: "$date", extra: "whyamIhere"}, 18534); testFormatError(["%Y", "$date"], 18629); // Use invalid modifier at middle of string -testFormatError({format:"%Y-%q", date: "$date"}, 18536); +testFormatError({format: "%Y-%q", date: "$date"}, 18536); // Odd number of percent signs at end -testFormatError({format: "%U-%w-%j-%%%", date:"$date"}, 18535); +testFormatError({format: "%U-%w-%j-%%%", date: "$date"}, 18535); // Odd number of percent signs at middle // will get interpreted as an invalid modifier since it will try to use '%A' -testFormatError({format: "AAAAA%%%AAAAAA", date:"$date"}, 18536); +testFormatError({format: "AAAAA%%%AAAAAA", date: "$date"}, 18536); // Format parameter not a string -testFormatError({format: {iamalion: "roar"}, date:"$date"}, 18533); +testFormatError({format: {iamalion: "roar"}, date: "$date"}, 18533); /// /// Additional Tests @@ -126,7 +114,7 @@ var date = ISODate("1999-08-29"); testFormat(date, "%%d", "%d"); -//A very long string of "%"s +// A very long string of "%"s var longstr = Array(1000).join("%%"); var halfstr = Array(1000).join("%"); testFormat(date, longstr, halfstr); diff --git a/jstests/aggregation/bugs/server11675.js b/jstests/aggregation/bugs/server11675.js index 513714f98d7..709120c27ca 100644 --- a/jstests/aggregation/bugs/server11675.js +++ b/jstests/aggregation/bugs/server11675.js @@ -5,8 +5,8 @@ var server11675 = function() { var t = db.server11675; t.drop(); - if (typeof(RUNNING_IN_SHARDED_AGG_TEST) != 'undefined') { // see end of testshard1.js - db.adminCommand( { shardcollection : t.getFullName(), key : { "_id" : 1 } } ); + if (typeof(RUNNING_IN_SHARDED_AGG_TEST) != 'undefined') { // see end of testshard1.js + db.adminCommand({shardcollection: t.getFullName(), key: {"_id": 1}}); } t.insert({_id: 1, text: "apple", words: 1}); @@ -22,7 +22,7 @@ var server11675 = function() { var pipeline = [{$match: query.query}]; if ('project' in query) { - cursor = t.find(query.query, query.project); // no way to add to constructed cursor + cursor = t.find(query.query, query.project); // no way to add to constructed cursor pipeline.push({$project: query.project}); } @@ -46,89 +46,99 @@ var server11675 = function() { assert.docEq(aggRes, findRes); }; - assertSameAsFind({query: {}}); // sanity check - assertSameAsFind({query: {$text:{$search:"apple"}}}); - assertSameAsFind({query: {$and:[{$text:{$search:"apple"}}, {_id:1}]}}); - assertSameAsFind({query: {$text:{$search:"apple"}} - ,project: {_id:1, score: {$meta: "textScore"}} - }); - assertSameAsFind({query: {$text:{$search:"apple banana"}} - ,project: {_id:1, score: {$meta: "textScore"}} - }); - assertSameAsFind({query: {$text:{$search:"apple banana"}} - ,project: {_id:1, score: {$meta: "textScore"}} - ,sort: {score: {$meta: "textScore"}} - }); - assertSameAsFind({query: {$text:{$search:"apple banana"}} - ,project: {_id:1, score: {$meta: "textScore"}} - ,sort: {score: {$meta: "textScore"}} - ,limit: 1 - }); - assertSameAsFind({query: {$text:{$search:"apple banana"}} - ,project: {_id:1, score: {$meta: "textScore"}} - ,sort: {score: {$meta: "textScore"}} - ,skip: 1 - }); - assertSameAsFind({query: {$text:{$search:"apple banana"}} - ,project: {_id:1, score: {$meta: "textScore"}} - ,sort: {score: {$meta: "textScore"}} - ,skip: 1 - ,limit: 1 - }); + assertSameAsFind({query: {}}); // sanity check + assertSameAsFind({query: {$text: {$search: "apple"}}}); + assertSameAsFind({query: {$and: [{$text: {$search: "apple"}}, {_id: 1}]}}); + assertSameAsFind( + {query: {$text: {$search: "apple"}}, project: {_id: 1, score: {$meta: "textScore"}}}); + assertSameAsFind({ + query: {$text: {$search: "apple banana"}}, + project: {_id: 1, score: {$meta: "textScore"}} + }); + assertSameAsFind({ + query: {$text: {$search: "apple banana"}}, + project: {_id: 1, score: {$meta: "textScore"}}, + sort: {score: {$meta: "textScore"}} + }); + assertSameAsFind({ + query: {$text: {$search: "apple banana"}}, + project: {_id: 1, score: {$meta: "textScore"}}, + sort: {score: {$meta: "textScore"}}, + limit: 1 + }); + assertSameAsFind({ + query: {$text: {$search: "apple banana"}}, + project: {_id: 1, score: {$meta: "textScore"}}, + sort: {score: {$meta: "textScore"}}, + skip: 1 + }); + assertSameAsFind({ + query: {$text: {$search: "apple banana"}}, + project: {_id: 1, score: {$meta: "textScore"}}, + sort: {score: {$meta: "textScore"}}, + skip: 1, + limit: 1 + }); // sharded find requires projecting the score to sort, but sharded agg does not. var findRes = t.find({$text: {$search: "apple banana"}}, {textScore: {$meta: 'textScore'}}) - .sort({textScore: {$meta: 'textScore'}}) - .map(function(obj) { - delete obj.textScore; // remove it to match agg output - return obj; - }); - var res = t.aggregate([{$match: {$text: {$search: 'apple banana'}}} - ,{$sort: {textScore: {$meta: 'textScore'}}} - ]).toArray(); + .sort({textScore: {$meta: 'textScore'}}) + .map(function(obj) { + delete obj.textScore; // remove it to match agg output + return obj; + }); + var res = t.aggregate([ + {$match: {$text: {$search: 'apple banana'}}}, + {$sort: {textScore: {$meta: 'textScore'}}} + ]).toArray(); assert.eq(res, findRes); // Make sure {$meta: 'textScore'} can be used as a sub-expression - var res = t.aggregate([{$match: {_id:1, $text: {$search: 'apple'}}} - ,{$project: {words: 1 - ,score: {$meta: 'textScore'} - ,wordsTimesScore: {$multiply: ['$words', {$meta:'textScore'}]} - }} - ]).toArray(); + var res = t.aggregate([ + {$match: {_id: 1, $text: {$search: 'apple'}}}, + { + $project: { + words: 1, + score: {$meta: 'textScore'}, + wordsTimesScore: {$multiply: ['$words', {$meta: 'textScore'}]} + } + } + ]).toArray(); assert.eq(res[0].wordsTimesScore, res[0].words * res[0].score, tojson(res)); // And can be used in $group - var res = t.aggregate([{$match: {_id: 1, $text: {$search: 'apple banana'}}} - ,{$group: {_id: {$meta: 'textScore'} - ,score: {$first: {$meta: 'textScore'}} - }} - ]).toArray(); + var res = t.aggregate([ + {$match: {_id: 1, $text: {$search: 'apple banana'}}}, + {$group: {_id: {$meta: 'textScore'}, score: {$first: {$meta: 'textScore'}}}} + ]).toArray(); assert.eq(res[0]._id, res[0].score, tojson(res)); // Make sure metadata crosses shard -> merger boundary - var res = t.aggregate([{$match: {_id:1, $text: {$search: 'apple'}}} - ,{$project: {scoreOnShard: {$meta: 'textScore'} }} - ,{$limit:1} // force a split. later stages run on merger - ,{$project: {scoreOnShard:1 - ,scoreOnMerger: {$meta: 'textScore'} }} - ]).toArray(); + var res = t.aggregate([ + {$match: {_id: 1, $text: {$search: 'apple'}}}, + {$project: {scoreOnShard: {$meta: 'textScore'}}}, + {$limit: 1} // force a split. later stages run on merger + , + {$project: {scoreOnShard: 1, scoreOnMerger: {$meta: 'textScore'}}} + ]).toArray(); assert.eq(res[0].scoreOnMerger, res[0].scoreOnShard); - var score = res[0].scoreOnMerger; // save for later tests + var score = res[0].scoreOnMerger; // save for later tests // Make sure metadata crosses shard -> merger boundary even if not used on shard - var res = t.aggregate([{$match: {_id:1, $text: {$search: 'apple'}}} - ,{$limit:1} // force a split. later stages run on merger - ,{$project: {scoreOnShard:1 - ,scoreOnMerger: {$meta: 'textScore'} }} - ]).toArray(); + var res = t.aggregate([ + {$match: {_id: 1, $text: {$search: 'apple'}}}, + {$limit: 1} // force a split. later stages run on merger + , + {$project: {scoreOnShard: 1, scoreOnMerger: {$meta: 'textScore'}}} + ]).toArray(); assert.eq(res[0].scoreOnMerger, score); // Make sure metadata works if first $project doesn't use it. - var res = t.aggregate([{$match: {_id:1, $text: {$search: 'apple'}}} - ,{$project: {_id:1}} - ,{$project: {_id:1 - ,score: {$meta: 'textScore'} }} - ]).toArray(); + var res = t.aggregate([ + {$match: {_id: 1, $text: {$search: 'apple'}}}, + {$project: {_id: 1}}, + {$project: {_id: 1, score: {$meta: 'textScore'}}} + ]).toArray(); assert.eq(res[0].score, score); // Make sure the metadata is 'missing()' when it doesn't exist because it was never created @@ -136,24 +146,26 @@ var server11675 = function() { assert(!("score" in res[0])); // Make sure the metadata is 'missing()' when it doesn't exist because the document changed - var res = t.aggregate([{$match: {_id: 1, $text: {$search: 'apple banana'}}}, - {$group: {_id: 1, score: {$first: {$meta: 'textScore'}}}}, - {$project: {_id: 1, scoreAgain: {$meta: 'textScore'}}}, - ]).toArray(); + var res = t.aggregate([ + {$match: {_id: 1, $text: {$search: 'apple banana'}}}, + {$group: {_id: 1, score: {$first: {$meta: 'textScore'}}}}, + {$project: {_id: 1, scoreAgain: {$meta: 'textScore'}}}, + ]).toArray(); assert(!("scoreAgain" in res[0])); // Make sure metadata works after a $unwind t.insert({_id: 5, text: 'mango', words: [1, 2, 3]}); - var res = t.aggregate([{$match: {$text: {$search: 'mango'}}}, - {$project: {score: {$meta: "textScore"}, _id:1, words: 1}}, - {$unwind: '$words'}, - {$project: {scoreAgain: {$meta: "textScore"}, score: 1}} - ]).toArray(); + var res = t.aggregate([ + {$match: {$text: {$search: 'mango'}}}, + {$project: {score: {$meta: "textScore"}, _id: 1, words: 1}}, + {$unwind: '$words'}, + {$project: {scoreAgain: {$meta: "textScore"}, score: 1}} + ]).toArray(); assert.eq(res[0].scoreAgain, res[0].score); // Error checking // $match, but wrong position - assertErrorCode(t, [{$sort: {text: 1}} ,{$match: {$text: {$search: 'apple banana'}}}], 17313); + assertErrorCode(t, [{$sort: {text: 1}}, {$match: {$text: {$search: 'apple banana'}}}], 17313); // wrong $stage, but correct position assertErrorCode(t, [{$project: {searchValue: {$text: {$search: 'apple banana'}}}}], 15999); diff --git a/jstests/aggregation/bugs/server12015.js b/jstests/aggregation/bugs/server12015.js index a9a8d6ab859..af4ee75f92d 100644 --- a/jstests/aggregation/bugs/server12015.js +++ b/jstests/aggregation/bugs/server12015.js @@ -8,11 +8,14 @@ load("jstests/aggregation/extras/utils.js"); // For orderedArrayEq. -(function (){ +(function() { "use strict"; var coll = db.server12015; coll.drop(); - var indexSpec = {a: 1, b: 1}; + 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})); @@ -52,8 +55,8 @@ load("jstests/aggregation/extras/utils.js"); // For orderedArrayEq. // 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"}}}]); + 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}}]); @@ -62,8 +65,8 @@ load("jstests/aggregation/extras/utils.js"); // For orderedArrayEq. // 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"}}}]); + 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}}]); diff --git a/jstests/aggregation/bugs/server13715.js b/jstests/aggregation/bugs/server13715.js index 608e94d37a4..27482cc1c46 100644 --- a/jstests/aggregation/bugs/server13715.js +++ b/jstests/aggregation/bugs/server13715.js @@ -7,19 +7,13 @@ t.drop(); t.save({_id: 0, name: "red", value: 2}); t.save({_id: 1, name: "blue", value: 1}); -var cursor = t.aggregate([ - {$match: {$or: [{name: "red"}, {name: "blue"}]}}, - {$sort: {value: 1}} -]); +var cursor = t.aggregate([{$match: {$or: [{name: "red"}, {name: "blue"}]}}, {$sort: {value: 1}}]); assert.eq(1, cursor.next()["_id"]); assert.eq(0, cursor.next()["_id"]); // Repeat the test with an index. t.ensureIndex({name: 1}); -cursor = t.aggregate([ - {$match: {$or: [{name: "red"}, {name: "blue"}]}}, - {$sort: {value: 1}} -]); +cursor = t.aggregate([{$match: {$or: [{name: "red"}, {name: "blue"}]}}, {$sort: {value: 1}}]); assert.eq(1, cursor.next()["_id"]); assert.eq(0, cursor.next()["_id"]); diff --git a/jstests/aggregation/bugs/server14421.js b/jstests/aggregation/bugs/server14421.js index b5e800ec999..3201e20a81a 100644 --- a/jstests/aggregation/bugs/server14421.js +++ b/jstests/aggregation/bugs/server14421.js @@ -1,11 +1,12 @@ // SERVER-14421 minDistance for $geoNear aggregation operator -(function () { +(function() { 'use strict'; var coll = db.mindistance; coll.drop(); - assert.writeOK(coll.insert([{_id: 0, loc: {type: "Point", coordinates: [0,0]}}, - {_id: 1, loc: {type: "Point", coordinates: [0,0.01]}} - ])); + assert.writeOK(coll.insert([ + {_id: 0, loc: {type: "Point", coordinates: [0, 0]}}, + {_id: 1, loc: {type: "Point", coordinates: [0, 0.01]}} + ])); var response = coll.createIndex({loc: "2dsphere"}); assert.eq(response.ok, 1, "Could not create 2dsphere index"); var results = coll.aggregate([{ @@ -13,7 +14,7 @@ minDistance: 10000, spherical: true, distanceField: "distance", - near: {type: "Point", coordinates: [0,0]} + near: {type: "Point", coordinates: [0, 0]} } }]); assert.eq(results.itcount(), 0); @@ -22,7 +23,7 @@ minDistance: 1, spherical: true, distanceField: "distance", - near: {type: "Point", coordinates: [0,0]} + near: {type: "Point", coordinates: [0, 0]} } }]); assert.eq(results.itcount(), 1); @@ -31,7 +32,7 @@ minDistance: 0, spherical: true, distanceField: "distance", - near: {type: "Point", coordinates: [0,0]} + near: {type: "Point", coordinates: [0, 0]} } }]); assert.eq(results.itcount(), 2); diff --git a/jstests/aggregation/bugs/server14969.js b/jstests/aggregation/bugs/server14969.js index 4d169586d11..629e54505fc 100644 --- a/jstests/aggregation/bugs/server14969.js +++ b/jstests/aggregation/bugs/server14969.js @@ -4,7 +4,7 @@ var docsPerBatch = 3; coll.drop(); // Initialize collection with eight 1M documents, and index on field "a". -var longString = new Array(1024*1024).join('x'); +var longString = new Array(1024 * 1024).join('x'); for (var i = 0; i < 100; ++i) { assert.writeOK(coll.insert({a: 1, bigField: longString})); } @@ -18,15 +18,15 @@ for (var i = 0; i < docsPerBatch; ++i) { } // Drop index "a". -assert.commandWorked(coll.dropIndex({a:1})); +assert.commandWorked(coll.dropIndex({a: 1})); // Issue a getmore against agg cursor. Note that it is not defined whether the server continues to // generate further results for the cursor. try { cursor.hasNext(); cursor.next(); +} catch (e) { } -catch (e) {} // Verify that the server hasn't crashed. assert.commandWorked(db.adminCommand({ping: 1})); diff --git a/jstests/aggregation/bugs/server15810.js b/jstests/aggregation/bugs/server15810.js index d1c903334a2..88ef3b7ca38 100644 --- a/jstests/aggregation/bugs/server15810.js +++ b/jstests/aggregation/bugs/server15810.js @@ -1,4 +1,4 @@ // SERVER-15810: Server crash when running a poorly formed command var res = db.runCommand({aggregate: 1, pipeline: []}); -assert.commandFailed(res); // command must fail +assert.commandFailed(res); // command must fail // TODO(geert): assert(!('code' in res)); // but must not cause massert diff --git a/jstests/aggregation/bugs/server17224.js b/jstests/aggregation/bugs/server17224.js index 33042abab53..888c99b808c 100644 --- a/jstests/aggregation/bugs/server17224.js +++ b/jstests/aggregation/bugs/server17224.js @@ -15,9 +15,10 @@ t.insert({a: new Array(1024 * 1024 - 1105).join('a')}); // do not use cursor form, since it has a different workaroud for this issue. - assert.commandFailed( - db.runCommand({aggregate: t.getName(), - pipeline: [{$match: {}}, {$group: {_id: null, arr: {$push: {a: '$a'}}}}]})); + assert.commandFailed(db.runCommand({ + aggregate: t.getName(), + pipeline: [{$match: {}}, {$group: {_id: null, arr: {$push: {a: '$a'}}}}] + })); // Make sure the server is still up. assert.commandWorked(db.runCommand('ping')); diff --git a/jstests/aggregation/bugs/server17943.js b/jstests/aggregation/bugs/server17943.js index e23d1639a66..10dbac2c37a 100644 --- a/jstests/aggregation/bugs/server17943.js +++ b/jstests/aggregation/bugs/server17943.js @@ -9,8 +9,8 @@ load('jstests/aggregation/extras/utils.js'); var coll = db.agg_filter_expr; coll.drop(); - assert.writeOK(coll.insert({_id: 0, a: [1,2,3,4,5]})); - assert.writeOK(coll.insert({_id: 1, a: [2,4]})); + assert.writeOK(coll.insert({_id: 0, a: [1, 2, 3, 4, 5]})); + assert.writeOK(coll.insert({_id: 1, a: [2, 4]})); assert.writeOK(coll.insert({_id: 2, a: []})); assert.writeOK(coll.insert({_id: 3, a: [1]})); assert.writeOK(coll.insert({_id: 4, a: null})); @@ -18,9 +18,13 @@ load('jstests/aggregation/extras/utils.js'); assert.writeOK(coll.insert({_id: 6})); // Create filter to only accept odd numbers. - filterDoc = {input: '$a', as: 'x', cond: {$eq: [1, {$mod: ['$$x', 2]}]}}; + filterDoc = { + input: '$a', + as: 'x', + cond: {$eq: [1, {$mod: ['$$x', 2]}]} + }; var expectedResults = [ - {_id: 0, b: [1,3,5]}, + {_id: 0, b: [1, 3, 5]}, {_id: 1, b: []}, {_id: 2, b: []}, {_id: 3, b: [1]}, @@ -41,31 +45,57 @@ load('jstests/aggregation/extras/utils.js'); assertErrorCode(coll, [{$project: {b: {$filter: filterDoc}}}], 28646); // Extra field(s). - filterDoc = {input: '$a', as: 'x', cond: true, extra: 1}; + filterDoc = { + input: '$a', + as: 'x', + cond: true, + extra: 1 + }; assertErrorCode(coll, [{$project: {b: {$filter: filterDoc}}}], 28647); // Missing 'input'. - filterDoc = {as: 'x', cond: true}; + filterDoc = { + as: 'x', + cond: true + }; assertErrorCode(coll, [{$project: {b: {$filter: filterDoc}}}], 28648); // Missing 'as'. - filterDoc = {input: '$a', cond: true}; + filterDoc = { + input: '$a', + cond: true + }; assertErrorCode(coll, [{$project: {b: {$filter: filterDoc}}}], 28649); // Missing 'cond'. - filterDoc = {input: '$a', as: 'x'}; + filterDoc = { + input: '$a', + as: 'x' + }; assertErrorCode(coll, [{$project: {b: {$filter: filterDoc}}}], 28650); // 'as' is not a valid variable name. - filterDoc = {input: '$a', as: '$x', cond: true}; + filterDoc = { + input: '$a', + as: '$x', + cond: true + }; assertErrorCode(coll, [{$project: {b: {$filter: filterDoc}}}], 16867); // 'input' is not an array. - filterDoc = {input: 'string', as: 'x', cond: true}; + filterDoc = { + input: 'string', + as: 'x', + cond: true + }; assertErrorCode(coll, [{$project: {b: {$filter: filterDoc}}}], 28651); coll.drop(); assert.writeOK(coll.insert({a: 'string'})); - filterDoc = {input: '$a', as: 'x', cond: true}; + filterDoc = { + input: '$a', + as: 'x', + cond: true + }; assertErrorCode(coll, [{$project: {b: {$filter: filterDoc}}}], 28651); }()); diff --git a/jstests/aggregation/bugs/server18198.js b/jstests/aggregation/bugs/server18198.js index 6d8d827e416..39cb37074e5 100644 --- a/jstests/aggregation/bugs/server18198.js +++ b/jstests/aggregation/bugs/server18198.js @@ -11,32 +11,41 @@ var commandsRan = []; // hook in our patched mongo var mockMongo = { - getSlaveOk: function() { return true; }, + getSlaveOk: function() { + return true; + }, runCommand: function(db, cmd, opts) { - commandsRan.push({db: db, cmd: cmd, opts: opts}); - return {ok: 1.0}; + commandsRan.push({db: db, cmd: cmd, opts: opts}); + return { + ok: 1.0 + }; + }, + getReadPref: function() { + return { + mode: "secondaryPreferred" + }; }, - getReadPref: function() { return {mode: "secondaryPreferred"}; }, - getReadPrefMode: function() { return "secondaryPreferred"; } + getReadPrefMode: function() { + return "secondaryPreferred"; + } }; db._mongo = mockMongo; // this query should not get a read pref - t.aggregate([{$sort: {"x" : 1}}, {$out: "foo"}]); + t.aggregate([{$sort: {"x": 1}}, {$out: "foo"}]); assert.eq(commandsRan.length, 1); // check that it doesn't have a read preference assert(!commandsRan[0].cmd.hasOwnProperty("$readPreference")); commandsRan = []; - t.aggregate([{$sort: {"x" : 1}}]); + t.aggregate([{$sort: {"x": 1}}]); // check another command was run assert.eq(commandsRan.length, 1); // check that it has a read preference assert(commandsRan[0].cmd.hasOwnProperty("$readPreference")); - } - finally { + } finally { db._mongo = mongo; } })(); diff --git a/jstests/aggregation/bugs/server18222.js b/jstests/aggregation/bugs/server18222.js index cd1266a30c4..1a46ff349c8 100644 --- a/jstests/aggregation/bugs/server18222.js +++ b/jstests/aggregation/bugs/server18222.js @@ -1,5 +1,5 @@ // SERVER-18222: Add $isArray aggregation expression. -(function (){ +(function() { 'use strict'; var coll = db.is_array_expr; coll.drop(); @@ -20,13 +20,8 @@ assert.writeOK(coll.insert({_id: 10, x: ['0']})); // Project field is_array to represent whether the field x was an array. - var results = coll.aggregate([{$sort: {_id: 1}}, - { - $project: { - isArray: {$isArray: '$x'} - } - }, - ]).toArray(); + var results = + coll.aggregate([{$sort: {_id: 1}}, {$project: {isArray: {$isArray: '$x'}}}, ]).toArray(); var expectedResults = [ {_id: 0, isArray: false}, {_id: 1, isArray: false}, diff --git a/jstests/aggregation/bugs/server18427.js b/jstests/aggregation/bugs/server18427.js index 2fc9f4b70ad..35fcef8a4ac 100644 --- a/jstests/aggregation/bugs/server18427.js +++ b/jstests/aggregation/bugs/server18427.js @@ -64,15 +64,15 @@ load('jstests/aggregation/extras/utils.js'); // $pow -- if either input is a double return a double. testOp({$pow: [10, 2]}, 100); - testOp({$pow: [1/2, -1]}, 2); + testOp({$pow: [1 / 2, -1]}, 2); testOp({$pow: [-2, 2]}, 4); testOp({$pow: [NumberInt("2"), 2]}, 4); testOp({$pow: [-2, NumberInt("2")]}, 4); // If exponent is negative and base not -1, 0, or 1, return a double. - testOp({$pow: [NumberLong("2"), NumberLong("-1")]}, 1/2); - testOp({$pow: [NumberInt("4"), NumberInt("-1")]}, 1/4); - testOp({$pow: [NumberInt("4"), NumberLong("-1")]}, 1/4); + testOp({$pow: [NumberLong("2"), NumberLong("-1")]}, 1 / 2); + testOp({$pow: [NumberInt("4"), NumberInt("-1")]}, 1 / 4); + testOp({$pow: [NumberInt("4"), NumberLong("-1")]}, 1 / 4); testOp({$pow: [NumberInt("1"), NumberLong("-2")]}, NumberLong("1")); testOp({$pow: [NumberInt("-1"), NumberLong("-2")]}, NumberLong("1")); @@ -92,15 +92,15 @@ load('jstests/aggregation/extras/utils.js'); testOp({$pow: [NumberInt("4"), NumberInt("2")]}, 16); // $exp always returns doubles, since e is a double. - testOp({$exp: [NumberInt("-1")]}, 1/Math.E); + testOp({$exp: [NumberInt("-1")]}, 1 / Math.E); testOp({$exp: [NumberLong("1")]}, Math.E); // Null input results in null. testOp({$pow: [null, 2]}, null); - testOp({$pow: [1/2, null]}, null); + testOp({$pow: [1 / 2, null]}, null); testOp({$exp: [null]}, null); // NaN input results in NaN. testOp({$pow: [NaN, 2]}, NaN); - testOp({$pow: [1/2, NaN]}, NaN); + testOp({$pow: [1 / 2, NaN]}, NaN); testOp({$exp: [NaN]}, NaN); // Invalid inputs - non-numeric/non-null types, or 0 to a negative exponent. diff --git a/jstests/aggregation/bugs/server19095.js b/jstests/aggregation/bugs/server19095.js index 3728c06c06b..7d023ebc271 100644 --- a/jstests/aggregation/bugs/server19095.js +++ b/jstests/aggregation/bugs/server19095.js @@ -8,23 +8,23 @@ load("jstests/aggregation/extras/utils.js"); // Used by testPipeline to sort result documents. All _ids must be primitives. function compareId(a, b) { - if (a._id < b._id) { - return -1; - } - if (a._id > b._id) { - return 1; - } - return 0; + if (a._id < b._id) { + return -1; + } + if (a._id > b._id) { + return 1; + } + return 0; } // Helper for testing that pipeline returns correct set of results. function testPipeline(pipeline, expectedResult, collection) { assert.eq(collection.aggregate(pipeline).toArray().sort(compareId), - expectedResult.sort(compareId)); + expectedResult.sort(compareId)); } function runTest(coll, from) { - var db = null; // Using the db variable is banned in this function. + var db = null; // Using the db variable is banned in this function. assert.writeOK(coll.insert({_id: 0, a: 1})); assert.writeOK(coll.insert({_id: 1, a: null})); @@ -45,14 +45,9 @@ load("jstests/aggregation/extras/utils.js"); {_id: 1, a: null, "same": [{_id: 1, b: null}, {_id: 2}]}, {_id: 2, "same": [{_id: 1, b: null}, {_id: 2}]} ]; - testPipeline([{ - $lookup: { - localField: "a", - foreignField: "b", - from: "from", - as: "same" - } - }], expectedResults, coll); + testPipeline([{$lookup: {localField: "a", foreignField: "b", from: "from", as: "same"}}], + expectedResults, + coll); // If localField is nonexistent, it is treated as if it is null. expectedResults = [ @@ -61,13 +56,10 @@ load("jstests/aggregation/extras/utils.js"); {_id: 2, "same": [{_id: 1, b: null}, {_id: 2}]} ]; testPipeline([{ - $lookup: { - localField: "nonexistent", - foreignField: "b", - from: "from", - as: "same" - } - }], expectedResults, coll); + $lookup: {localField: "nonexistent", foreignField: "b", from: "from", as: "same"} + }], + expectedResults, + coll); // If foreignField is nonexistent, it is treated as if it is null. expectedResults = [ @@ -76,36 +68,24 @@ load("jstests/aggregation/extras/utils.js"); {_id: 2, "same": [{_id: 0, b: 1}, {_id: 1, b: null}, {_id: 2}]} ]; testPipeline([{ - $lookup: { - localField: "a", - foreignField: "nonexistent", - from: "from", - as: "same" - } - }], expectedResults, coll); + $lookup: {localField: "a", foreignField: "nonexistent", from: "from", as: "same"} + }], + expectedResults, + coll); // If there are no matches or the from coll doesn't exist, the result is an empty array. - expectedResults = [ - {_id: 0, a: 1, "same": []}, - {_id: 1, a: null, "same": []}, - {_id: 2, "same": []} - ]; + expectedResults = + [{_id: 0, a: 1, "same": []}, {_id: 1, a: null, "same": []}, {_id: 2, "same": []}]; testPipeline([{ - $lookup: { - localField: "_id", - foreignField: "nonexistent", - from: "from", - as: "same" - } - }], expectedResults, coll); + $lookup: {localField: "_id", foreignField: "nonexistent", from: "from", as: "same"} + }], + expectedResults, + coll); testPipeline([{ - $lookup: { - localField: "a", - foreignField: "b", - from: "nonexistent", - as: "same" - } - }], expectedResults, coll); + $lookup: {localField: "a", foreignField: "b", from: "nonexistent", as: "same"} + }], + expectedResults, + coll); // If field name specified by "as" already exists, it is overwritten. expectedResults = [ @@ -113,42 +93,26 @@ load("jstests/aggregation/extras/utils.js"); {_id: 1, "a": [{_id: 1, b: null}, {_id: 2}]}, {_id: 2, "a": [{_id: 1, b: null}, {_id: 2}]} ]; - testPipeline([{ - $lookup: { - localField: "a", - foreignField: "b", - from: "from", - as: "a" - } - }], expectedResults, coll); - + testPipeline([{$lookup: {localField: "a", foreignField: "b", from: "from", as: "a"}}], + expectedResults, + coll); // Running multiple $lookups in the same pipeline is allowed. expectedResults = [ - {_id: 0, a: 1, "c": [{_id:0, b:1}], "d": [{_id:0, b:1}]}, - {_id: 1, a: null, "c": [{_id:1, b:null}, {_id:2}], "d": [{_id:1, b:null}, {_id:2}]}, - {_id: 2, "c": [{_id:1, b:null}, {_id:2}], "d": [{_id:1, b:null}, {_id:2}]} + {_id: 0, a: 1, "c": [{_id: 0, b: 1}], "d": [{_id: 0, b: 1}]}, + { + _id: 1, + a: null, "c": [{_id: 1, b: null}, {_id: 2}], "d": [{_id: 1, b: null}, {_id: 2}] + }, + {_id: 2, "c": [{_id: 1, b: null}, {_id: 2}], "d": [{_id: 1, b: null}, {_id: 2}]} ]; - testPipeline([{ - $lookup: { - localField: "a", - foreignField: "b", - from: "from", - as: "c" - } - }, { - $project: { - "a": 1, - "c": 1 - } - }, { - $lookup: { - localField: "a", - foreignField: "b", - from: "from", - as: "d" - } - }], expectedResults, coll); + testPipeline([ + {$lookup: {localField: "a", foreignField: "b", from: "from", as: "c"}}, + {$project: {"a": 1, "c": 1}}, + {$lookup: {localField: "a", foreignField: "b", from: "from", as: "d"}} + ], + expectedResults, + coll); // // Coalescing with $unwind. @@ -162,16 +126,12 @@ load("jstests/aggregation/extras/utils.js"); {_id: 2, same: {_id: 1, b: null}}, {_id: 2, same: {_id: 2}} ]; - testPipeline([{ - $lookup: { - localField: "a", - foreignField: "b", - from: "from", - as: "same" - } - }, { - $unwind: {path: "$same"} - }], expectedResults, coll); + testPipeline([ + {$lookup: {localField: "a", foreignField: "b", from: "from", as: "same"}}, + {$unwind: {path: "$same"}} + ], + expectedResults, + coll); // An $unwind on the "as" field, with includeArrayIndex. expectedResults = [ @@ -181,72 +141,39 @@ load("jstests/aggregation/extras/utils.js"); {_id: 2, same: {_id: 1, b: null}, index: NumberLong(0)}, {_id: 2, same: {_id: 2}, index: NumberLong(1)}, ]; - testPipeline([{ - $lookup: { - localField: "a", - foreignField: "b", - from: "from", - as: "same" - } - }, { - $unwind: { - path: "$same", - includeArrayIndex: "index" - } - }], expectedResults, coll); + testPipeline([ + {$lookup: {localField: "a", foreignField: "b", from: "from", as: "same"}}, + {$unwind: {path: "$same", includeArrayIndex: "index"}} + ], + expectedResults, + coll); // Normal $unwind with no matching documents. expectedResults = []; - testPipeline([{ - $lookup: { - localField: "_id", - foreignField: "nonexistent", - from: "from", - as: "same" - } - }, { - $unwind: {path: "$same"} - }], expectedResults, coll); + testPipeline([ + {$lookup: {localField: "_id", foreignField: "nonexistent", from: "from", as: "same"}}, + {$unwind: {path: "$same"}} + ], + expectedResults, + coll); // $unwind with preserveNullAndEmptyArray with no matching documents. - expectedResults = [ - {_id: 0, a: 1}, - {_id: 1, a: null}, - {_id: 2}, - ]; - testPipeline([{ - $lookup: { - localField: "_id", - foreignField: "nonexistent", - from: "from", - as: "same" - } - }, { - $unwind: { - path: "$same", - preserveNullAndEmptyArrays: true - } - }], expectedResults, coll); + expectedResults = [{_id: 0, a: 1}, {_id: 1, a: null}, {_id: 2}, ]; + testPipeline([ + {$lookup: {localField: "_id", foreignField: "nonexistent", from: "from", as: "same"}}, + {$unwind: {path: "$same", preserveNullAndEmptyArrays: true}} + ], + expectedResults, + coll); // $unwind with preserveNullAndEmptyArray, some with matching documents, some without. - expectedResults = [ - {_id: 0, a: 1}, - {_id: 1, a: null, same: {_id: 0, b: 1}}, - {_id: 2}, - ]; - testPipeline([{ - $lookup: { - localField: "_id", - foreignField: "b", - from: "from", - as: "same" - } - }, { - $unwind: { - path: "$same", - preserveNullAndEmptyArrays: true - } - }], expectedResults, coll); + expectedResults = [{_id: 0, a: 1}, {_id: 1, a: null, same: {_id: 0, b: 1}}, {_id: 2}, ]; + testPipeline([ + {$lookup: {localField: "_id", foreignField: "b", from: "from", as: "same"}}, + {$unwind: {path: "$same", preserveNullAndEmptyArrays: true}} + ], + expectedResults, + coll); // $unwind with preserveNullAndEmptyArray and includeArrayIndex, some with matching // documents, some without. @@ -255,20 +182,15 @@ load("jstests/aggregation/extras/utils.js"); {_id: 1, a: null, same: {_id: 0, b: 1}, index: NumberLong(0)}, {_id: 2, index: null}, ]; - testPipeline([{ - $lookup: { - localField: "_id", - foreignField: "b", - from: "from", - as: "same" + testPipeline([ + {$lookup: {localField: "_id", foreignField: "b", from: "from", as: "same"}}, + { + $unwind: + {path: "$same", preserveNullAndEmptyArrays: true, includeArrayIndex: "index"} } - }, { - $unwind: { - path: "$same", - preserveNullAndEmptyArrays: true, - includeArrayIndex: "index" - } - }], expectedResults, coll); + ], + expectedResults, + coll); // // Dependencies. @@ -281,18 +203,12 @@ load("jstests/aggregation/extras/utils.js"); {_id: 1, "same": [{_id: 1, b: null}, {_id: 2}]}, {_id: 2, "same": [{_id: 1, b: null}, {_id: 2}]} ]; - testPipeline([{ - $lookup: { - localField: "a", - foreignField: "b", - from: "from", - as: "same" - } - }, { - $project: { - "same": 1 - } - }], expectedResults, coll); + testPipeline([ + {$lookup: {localField: "a", foreignField: "b", from: "from", as: "same"}}, + {$project: {"same": 1}} + ], + expectedResults, + coll); // // Dotted field paths. @@ -312,14 +228,7 @@ load("jstests/aggregation/extras/utils.js"); assert.writeOK(from.insert({_id: 4, b: {c: 2}})); // Once without a dotted field. - var pipeline = [{ - $lookup: { - localField: "a", - foreignField: "b", - from: "from", - as: "same" - } - }]; + var pipeline = [{$lookup: {localField: "a", foreignField: "b", from: "from", as: "same"}}]; expectedResults = [ {_id: 0, a: 1, "same": [{_id: 0, b: 1}]}, {_id: 1, a: null, "same": [{_id: 1, b: null}, {_id: 2}]}, @@ -329,14 +238,7 @@ load("jstests/aggregation/extras/utils.js"); testPipeline(pipeline, expectedResults, coll); // Look up a dotted field. - pipeline = [{ - $lookup: { - localField: "a.c", - foreignField: "b.c", - from: "from", - as: "same" - } - }]; + pipeline = [{$lookup: {localField: "a.c", foreignField: "b.c", from: "from", as: "same"}}]; // All but the last document in 'coll' have a nullish value for 'a.c'. expectedResults = [ {_id: 0, a: 1, same: [{_id: 0, b: 1}, {_id: 1, b: null}, {_id: 2}]}, @@ -354,25 +256,33 @@ load("jstests/aggregation/extras/utils.js"); from.drop(); assert.writeOK(from.insert({_id: 0, target: 1})); - pipeline = [{ - $lookup: { - localField: "a.b", - foreignField: "target", - from: "from", - as: "same.documents", - } - }, { - // Expected input to $unwind: - // {_id: 0, a: {b: 1}, same: {documents: [{_id: 0, target: 1}]}} - // {_id: 1, same: {documents: []}} - $unwind: { - path: "$same.documents", - preserveNullAndEmptyArrays: true, - includeArrayIndex: "c.d.e", + pipeline = [ + { + $lookup: { + localField: "a.b", + foreignField: "target", + from: "from", + as: "same.documents", + } + }, + { + // Expected input to $unwind: + // {_id: 0, a: {b: 1}, same: {documents: [{_id: 0, target: 1}]}} + // {_id: 1, same: {documents: []}} + $unwind: { + path: "$same.documents", + preserveNullAndEmptyArrays: true, + includeArrayIndex: "c.d.e", + } } - }]; + ]; expectedResults = [ - {_id: 0, a: {b: 1}, same: {documents: {_id: 0, target: 1}}, c: {d: {e: NumberLong(0)}}}, + { + _id: 0, + a: {b: 1}, + same: {documents: {_id: 0, target: 1}}, + c: {d: {e: NumberLong(0)}} + }, {_id: 1, same: {}, c: {d: {e: null}}}, ]; testPipeline(pipeline, expectedResults, coll); @@ -390,16 +300,16 @@ load("jstests/aggregation/extras/utils.js"); assert.writeOK(from.insert({_id: 1, b: "string that matches /a regex/"})); pipeline = [ - {$lookup: { - localField: "a", - foreignField: "b", - from: "from", - as: "b", - }}, - ]; - expectedResults = [ - {_id: 0, a: /a regex/, b: [{_id: 0, b: /a regex/}]} + { + $lookup: { + localField: "a", + foreignField: "b", + from: "from", + as: "b", + } + }, ]; + expectedResults = [{_id: 0, a: /a regex/, b: [{_id: 0, b: /a regex/}]}]; testPipeline(pipeline, expectedResults, coll); // @@ -407,20 +317,21 @@ load("jstests/aggregation/extras/utils.js"); // // All four fields must be specified. - assertErrorCode(coll, [{$lookup: {foreignField:"b", from:"from", as:"same"}}], 4572); - assertErrorCode(coll, [{$lookup: {localField:"a", from:"from", as:"same"}}], 4572); - assertErrorCode(coll, [{$lookup: {localField:"a", foreignField:"b", as:"same"}}], 4572); - assertErrorCode(coll, [{$lookup: {localField:"a", foreignField:"b", from:"from"}}], 4572); + assertErrorCode(coll, [{$lookup: {foreignField: "b", from: "from", as: "same"}}], 4572); + assertErrorCode(coll, [{$lookup: {localField: "a", from: "from", as: "same"}}], 4572); + assertErrorCode(coll, [{$lookup: {localField: "a", foreignField: "b", as: "same"}}], 4572); + assertErrorCode( + coll, [{$lookup: {localField: "a", foreignField: "b", from: "from"}}], 4572); // All four field's values must be strings. - assertErrorCode(coll, [{$lookup: {localField:1, foreignField:"b", from:"from", as:"as"}}] - , 4570); - assertErrorCode(coll, [{$lookup: {localField:"a", foreignField:1, from:"from", as:"as"}}] - , 4570); - assertErrorCode(coll, [{$lookup: {localField:"a", foreignField:"b", from:1, as:"as"}}] - , 4570); - assertErrorCode(coll, [{$lookup: {localField:"a", foreignField: "b", from:"from", as:1}}] - , 4570); + assertErrorCode( + coll, [{$lookup: {localField: 1, foreignField: "b", from: "from", as: "as"}}], 4570); + assertErrorCode( + coll, [{$lookup: {localField: "a", foreignField: 1, from: "from", as: "as"}}], 4570); + assertErrorCode( + coll, [{$lookup: {localField: "a", foreignField: "b", from: 1, as: "as"}}], 4570); + assertErrorCode( + coll, [{$lookup: {localField: "a", foreignField: "b", from: "from", as: 1}}], 4570); // $lookup's field must be an object. assertErrorCode(coll, [{$lookup: "string"}], 4569); @@ -433,21 +344,17 @@ load("jstests/aggregation/extras/utils.js"); // Run tests in a sharded environment. var sharded = new ShardingTest({shards: 2, mongos: 1}); - assert(sharded.adminCommand({enableSharding : "test"})); + assert(sharded.adminCommand({enableSharding: "test"})); sharded.getDB('test').lookUp.drop(); sharded.getDB('test').from.drop(); assert(sharded.adminCommand({shardCollection: "test.lookUp", key: {_id: 'hashed'}})); runTest(sharded.getDB('test').lookUp, sharded.getDB('test').from); // An error is thrown if the from collection is sharded. - assert(sharded.adminCommand({ shardCollection:"test.from", key: {_id: 1}})); - assertErrorCode(sharded.getDB('test').lookUp, [{ - $lookup: { - localField: "a", - foreignField: "b", - from: "from", - as: "same" - } - }], 28769); + assert(sharded.adminCommand({shardCollection: "test.from", key: {_id: 1}})); + assertErrorCode( + sharded.getDB('test').lookUp, + [{$lookup: {localField: "a", foreignField: "b", from: "from", as: "same"}}], + 28769); sharded.stop(); }()); diff --git a/jstests/aggregation/bugs/server20168.js b/jstests/aggregation/bugs/server20168.js index efe15a9a243..2ff8c6e53cd 100644 --- a/jstests/aggregation/bugs/server20168.js +++ b/jstests/aggregation/bugs/server20168.js @@ -19,16 +19,14 @@ assert.writeOK(coll.insert(inputDoc)); // If preserveNullAndEmptyArrays is passed, we should get an output document. - var preservedResults = coll.aggregate( - [{$unwind: {path: unwindPath, preserveNullAndEmptyArrays: true}}] - ).toArray(); + var preservedResults = + coll.aggregate([{$unwind: {path: unwindPath, preserveNullAndEmptyArrays: true}}]) + .toArray(); assert.eq(1, preservedResults.length, "$unwind returned the wrong number of results"); - assert.eq( - preservedResults[0], - outputDoc, - "Unexpected result for an $unwind with preserveNullAndEmptyArrays " + - "(input was " + tojson(inputDoc) + ")" - ); + assert.eq(preservedResults[0], + outputDoc, + "Unexpected result for an $unwind with preserveNullAndEmptyArrays " + + "(input was " + tojson(inputDoc) + ")"); // If not, we should get no outputs. var defaultResults = coll.aggregate([{$unwind: {path: unwindPath}}]).toArray(); diff --git a/jstests/aggregation/bugs/server21632.js b/jstests/aggregation/bugs/server21632.js index b040b4191e6..2148beac282 100644 --- a/jstests/aggregation/bugs/server21632.js +++ b/jstests/aggregation/bugs/server21632.js @@ -24,7 +24,10 @@ // If there is only one document, we should get that document. var paddingStr = "abcdefghijklmnopqrstuvwxyz"; - var firstDoc = {_id: 0, paddingStr: paddingStr}; + var firstDoc = { + _id: 0, + paddingStr: paddingStr + }; assert.writeOK(coll.insert(firstDoc)); assert.eq([firstDoc], coll.aggregate([{$sample: {size: 1}}]).toArray()); assert.eq([firstDoc], coll.aggregate([{$sample: {size: 10}}]).toArray()); diff --git a/jstests/aggregation/bugs/server22093.js b/jstests/aggregation/bugs/server22093.js index a3bc05de53a..aca39a4e789 100644 --- a/jstests/aggregation/bugs/server22093.js +++ b/jstests/aggregation/bugs/server22093.js @@ -22,14 +22,17 @@ load('jstests/libs/analyze_plan.js'); assert.eq(simpleGroup.length, 1); assert.eq(simpleGroup[0]["count"], 15); - var explained = coll.explain().aggregate([{$match: {foo: {$gt: 0}}}, - {$group: {_id: null, count: {$sum: 1}}}]); + var explained = + coll.explain() + .aggregate([{$match: {foo: {$gt: 0}}}, {$group: {_id: null, count: {$sum: 1}}}]); assert(planHasStage(explained.stages[0].$cursor.queryPlanner.winningPlan, "COUNT_SCAN")); - explained = coll.explain().aggregate([{$match: {foo: {$gt: 0}}}, - {$project: {_id: 0, a: {$literal: null}}}, - {$group: {_id: null, count: {$sum: 1}}}]); + explained = coll.explain().aggregate([ + {$match: {foo: {$gt: 0}}}, + {$project: {_id: 0, a: {$literal: null}}}, + {$group: {_id: null, count: {$sum: 1}}} + ]); assert(planHasStage(explained.stages[0].$cursor.queryPlanner.winningPlan, "COUNT_SCAN")); }()); diff --git a/jstests/aggregation/bugs/server3253.js b/jstests/aggregation/bugs/server3253.js index 602e3c4d839..fe47bba565e 100644 --- a/jstests/aggregation/bugs/server3253.js +++ b/jstests/aggregation/bugs/server3253.js @@ -7,7 +7,7 @@ var output = db.server3253_out; var cappedOutput = db.server3253_out_capped; input.drop(); -inputDoesntExist.drop(); // never created +inputDoesntExist.drop(); // never created output.drop(); function collectionExists(coll) { @@ -16,9 +16,12 @@ function collectionExists(coll) { function getOutputIndexes() { return output.getIndexes().sort(function(a, b) { - if (a.name < b.name) { return -1; } - else { return 1; } - }); + if (a.name < b.name) { + return -1; + } else { + return 1; + } + }); } function test(input, pipeline, expected) { @@ -27,10 +30,10 @@ function test(input, pipeline, expected) { var cursor = input.aggregate(pipeline); - assert.eq(cursor.itcount(), 0); // empty cursor returned - assert.eq(output.find().toArray(), expected); // correct results + assert.eq(cursor.itcount(), 0); // empty cursor returned + assert.eq(output.find().toArray(), expected); // correct results var outputIndexes = getOutputIndexes(); - assert.eq(outputIndexes.length, indexes.length); // number of indexes maintained + assert.eq(outputIndexes.length, indexes.length); // number of indexes maintained for (var i = 0; i < outputIndexes.length; i++) { assert.docEq(outputIndexes[i], indexes[i]); } @@ -39,52 +42,52 @@ function test(input, pipeline, expected) { } function listCollections(name) { - var collectionInfosCursor = db.runCommand("listCollections", {filter: { name: name}}); + var collectionInfosCursor = db.runCommand("listCollections", {filter: {name: name}}); return new DBCommandCursor(db.getMongo(), collectionInfosCursor).toArray(); } -input.insert({_id:1}); -input.insert({_id:2}); -input.insert({_id:3}); +input.insert({_id: 1}); +input.insert({_id: 2}); +input.insert({_id: 3}); // insert into output so that the index exists and test() does not fail the first time around -output.insert({_id:1}); +output.insert({_id: 1}); // ensure there are no tmp agg_out collections before we begin assert.eq([], listCollections(/tmp\.agg_out/)); // basic test test(input, - [{$project: {a: {$add: ['$_id', '$_id']}}}], - [{_id:1, a:2},{_id:2, a:4},{_id:3, a:6}]); + [{$project: {a: {$add: ['$_id', '$_id']}}}], + [{_id: 1, a: 2}, {_id: 2, a: 4}, {_id: 3, a: 6}]); // test with indexes assert.eq(output.getIndexes().length, 1); -output.ensureIndex({a:1}); +output.ensureIndex({a: 1}); assert.eq(output.getIndexes().length, 2); test(input, - [{$project: {a: {$multiply: ['$_id', '$_id']}}}], - [{_id:1, a:1},{_id:2, a:4},{_id:3, a:9}]); + [{$project: {a: {$multiply: ['$_id', '$_id']}}}], + [{_id: 1, a: 1}, {_id: 2, a: 4}, {_id: 3, a: 9}]); // test with empty result set and make sure old result is gone, but indexes remain -test(input, - [{$match: {_id: 11}}], - []); +test(input, [{$match: {_id: 11}}], []); assert.eq(output.getIndexes().length, 2); // test with geo index -output.ensureIndex({b:"2d"}); +output.ensureIndex({b: "2d"}); assert.eq(output.getIndexes().length, 3); -test(input, - [{$project: {b: "$_id"}}], - [{_id:1, b:1}, {_id:2, b:2}, {_id:3, b:3}]); +test(input, [{$project: {b: "$_id"}}], [{_id: 1, b: 1}, {_id: 2, b: 2}, {_id: 3, b: 3}]); // test with full text index -output.ensureIndex({c:"text"}); +output.ensureIndex({c: "text"}); assert.eq(output.getIndexes().length, 4); test(input, - [{$project: {c: {$concat: ["hello there ", "_id"]}}}], - [{_id:1, c:"hello there _id"}, {_id:2, c:"hello there _id"}, {_id:3, c:"hello there _id"}]); + [{$project: {c: {$concat: ["hello there ", "_id"]}}}], + [ + {_id: 1, c: "hello there _id"}, + {_id: 2, c: "hello there _id"}, + {_id: 3, c: "hello there _id"} + ]); // test with capped collection cappedOutput.drop(); @@ -92,9 +95,7 @@ db.createCollection(cappedOutput.getName(), {capped: true, size: 2}); assertErrorCode(input, {$out: cappedOutput.getName()}, 17152); // ensure everything works even if input doesn't exist. -test(inputDoesntExist, - [], - []); +test(inputDoesntExist, [], []); // ensure we cant do dangerous things to system collections var outputInSystem = db.system.server3253_out; diff --git a/jstests/aggregation/bugs/server3832.js b/jstests/aggregation/bugs/server3832.js index c5bdf27e36e..b2c59ccd244 100644 --- a/jstests/aggregation/bugs/server3832.js +++ b/jstests/aggregation/bugs/server3832.js @@ -1,89 +1,56 @@ var s3832 = db.c; s3832.drop(); -s3832.save({_id: 1, a:"foo", b:"bar"}); -s3832.save({_id: 2, a:"feh", b:"baz"}); -s3832.save({_id: 3, a:"fee", b:"fum"}); - -var a1 = s3832.aggregate( { $match : { b : "baz" } } ); - -var a1result = [ - { - "_id" : 2, - "a" : "feh", - "b" : "baz" - } -]; +s3832.save({_id: 1, a: "foo", b: "bar"}); +s3832.save({_id: 2, a: "feh", b: "baz"}); +s3832.save({_id: 3, a: "fee", b: "fum"}); -assert.eq(a1.toArray(), a1result, 's3832.a1 failed'); +var a1 = s3832.aggregate({$match: {b: "baz"}}); + +var a1result = [{"_id": 2, "a": "feh", "b": "baz"}]; +assert.eq(a1.toArray(), a1result, 's3832.a1 failed'); -var a2 = s3832.aggregate( { $sort : { a : 1 } } ); +var a2 = s3832.aggregate({$sort: {a: 1}}); var a2result = [ - { - "_id" : 3, - "a" : "fee", - "b" : "fum" - }, - { - "_id" : 2, - "a" : "feh", - "b" : "baz" - }, - { - "_id" : 1, - "a" : "foo", - "b" : "bar" - } + {"_id": 3, "a": "fee", "b": "fum"}, + {"_id": 2, "a": "feh", "b": "baz"}, + {"_id": 1, "a": "foo", "b": "bar"} ]; assert.eq(a2.toArray(), a2result, 's3832.a2 failed'); - -var a3 = s3832.aggregate( - { $match : { b : "baz" } }, - { $sort : { a : 1 } } ); +var a3 = s3832.aggregate({$match: {b: "baz"}}, {$sort: {a: 1}}); assert.eq(a3.toArray(), a1result, 's3832.a3 failed'); +db.s3832.ensureIndex({b: 1}, {name: "s3832_b"}); -db.s3832.ensureIndex({ b : 1 }, { name : "s3832_b" }); - - -var a4 = s3832.aggregate({ $match : { b : "baz" } }); +var a4 = s3832.aggregate({$match: {b: "baz"}}); assert.eq(a4.toArray(), a1result, 's3832.a4 failed'); - -var a5 = s3832.aggregate({ $sort : { a : 1 } }); +var a5 = s3832.aggregate({$sort: {a: 1}}); assert.eq(a5.toArray(), a2result, 's3832.a5 failed'); - -var a6 = s3832.aggregate( - { $match : { b : "baz" } }, - { $sort : { a : 1 } } ); +var a6 = s3832.aggregate({$match: {b: "baz"}}, {$sort: {a: 1}}); assert.eq(a6.toArray(), a1result, 's3832.a6 failed'); - var dropb = db.s3832.dropIndex("s3832_b"); -db.s3832.ensureIndex({ a : 1 }, { name : "s3832_a" }); +db.s3832.ensureIndex({a: 1}, {name: "s3832_a"}); -var a7 = s3832.aggregate({ $match : { b : "baz" } }); +var a7 = s3832.aggregate({$match: {b: "baz"}}); assert.eq(a7.toArray(), a1result, 's3832.a7 failed'); - -var a8 = s3832.aggregate({ $sort : { a : 1 } }); +var a8 = s3832.aggregate({$sort: {a: 1}}); assert.eq(a8.toArray(), a2result, 's3832.a8 failed'); - -var a9 = s3832.aggregate( - { $match : { b : "baz" } }, - { $sort : { a : 1 } } ); +var a9 = s3832.aggregate({$match: {b: "baz"}}, {$sort: {a: 1}}); assert.eq(a9.toArray(), a1result, 's3832.a9 failed'); diff --git a/jstests/aggregation/bugs/server4588.js b/jstests/aggregation/bugs/server4588.js index 95b4ba86273..ba49c78e9ea 100644 --- a/jstests/aggregation/bugs/server4588.js +++ b/jstests/aggregation/bugs/server4588.js @@ -13,18 +13,11 @@ // Without includeArrayIndex. var actualResults = coll.aggregate([{$unwind: {path: "$x"}}]).toArray(); - var expectedResults = [ - {_id: 3, x: 1}, - {_id: 3, x: 2}, - {_id: 3, x: 3}, - {_id: 4, x: 5}, - ]; + var expectedResults = [{_id: 3, x: 1}, {_id: 3, x: 2}, {_id: 3, x: 3}, {_id: 4, x: 5}, ]; assert.eq(expectedResults, actualResults, "Incorrect results for normal $unwind"); // With includeArrayIndex, index inserted into a new field. - actualResults = coll.aggregate([ - {$unwind: {path: "$x", includeArrayIndex: "index"}} - ]).toArray(); + actualResults = coll.aggregate([{$unwind: {path: "$x", includeArrayIndex: "index"}}]).toArray(); expectedResults = [ {_id: 3, x: 1, index: NumberLong(0)}, {_id: 3, x: 2, index: NumberLong(1)}, @@ -35,9 +28,9 @@ // With both includeArrayIndex and preserveNullAndEmptyArrays. // TODO: update this test when SERVER-20168 is resolved. - actualResults = coll.aggregate([ - {$unwind: {path: "$x", includeArrayIndex: "index", preserveNullAndEmptyArrays: true}} - ]).toArray(); + actualResults = coll.aggregate([{ + $unwind: {path: "$x", includeArrayIndex: "index", preserveNullAndEmptyArrays: true} + }]).toArray(); expectedResults = [ {_id: 0, index: null}, {_id: 1, x: null, index: null}, diff --git a/jstests/aggregation/bugs/server4589.js b/jstests/aggregation/bugs/server4589.js index 11e8cad7978..c71a7d802f8 100644 --- a/jstests/aggregation/bugs/server4589.js +++ b/jstests/aggregation/bugs/server4589.js @@ -9,7 +9,7 @@ load('jstests/aggregation/extras/utils.js'); var coll = db.agg_array_elem_at_expr; coll.drop(); - assert.writeOK(coll.insert({a: [1,2,3,4,5]})); + assert.writeOK(coll.insert({a: [1, 2, 3, 4, 5]})); // Normal indexing. var pipeline = [{$project: {_id: 0, x: {$arrayElemAt: ['$a', 2]}}}]; diff --git a/jstests/aggregation/bugs/server4638.js b/jstests/aggregation/bugs/server4638.js index 7d0f4b67e34..4934da94a34 100644 --- a/jstests/aggregation/bugs/server4638.js +++ b/jstests/aggregation/bugs/server4638.js @@ -4,15 +4,13 @@ t = db.server4638; t.drop(); -t.insert( { _id : 0 , x : 0 , undef: undefined } ); +t.insert({_id: 0, x: 0, undef: undefined}); // Make sure having an undefined doesn't break pipelines not using the field -res = t.aggregate( { $project : { x : 1 } } ).toArray(); +res = t.aggregate({$project: {x: 1}}).toArray(); assert.eq(res[0].x, 0); - // Make sure having an undefined doesn't break pipelines that do use the field -res = t.aggregate( { $project : { undef : 1 } } ).toArray(); +res = t.aggregate({$project: {undef: 1}}).toArray(); assert.eq(res[0].undef, undefined); assert.eq(typeof(res[0].undef), "undefined"); - diff --git a/jstests/aggregation/bugs/server4656.js b/jstests/aggregation/bugs/server4656.js index cbb07f81ea5..185f74bec54 100644 --- a/jstests/aggregation/bugs/server4656.js +++ b/jstests/aggregation/bugs/server4656.js @@ -17,20 +17,20 @@ function generateRandom() { } for (var i = 0; i < NUM_OBJS; i++) { - c.insert({inc: i, dec: NUM_OBJS-i, rnd: generateRandom()}); + c.insert({inc: i, dec: NUM_OBJS - i, rnd: generateRandom()}); } -var inc_sorted = c.aggregate({$sort: {inc:1}}).toArray(); -var dec_sorted = c.aggregate({$sort: {dec:1}}).toArray(); -var rnd_sorted = c.aggregate({$sort: {rnd:1}}).toArray(); +var inc_sorted = c.aggregate({$sort: {inc: 1}}).toArray(); +var dec_sorted = c.aggregate({$sort: {dec: 1}}).toArray(); +var rnd_sorted = c.aggregate({$sort: {rnd: 1}}).toArray(); function test(limit, direction) { try { - var res_inc = c.aggregate({$sort: {inc:direction}}, {$limit:limit}).toArray(); - var res_dec = c.aggregate({$sort: {dec:direction}}, {$limit:limit}).toArray(); - var res_rnd = c.aggregate({$sort: {rnd:direction}}, {$limit:limit}).toArray(); + var res_inc = c.aggregate({$sort: {inc: direction}}, {$limit: limit}).toArray(); + var res_dec = c.aggregate({$sort: {dec: direction}}, {$limit: limit}).toArray(); + var res_rnd = c.aggregate({$sort: {rnd: direction}}, {$limit: limit}).toArray(); - var expectedLength = Math.min(limit, NUM_OBJS) ; + var expectedLength = Math.min(limit, NUM_OBJS); assert.eq(res_inc.length, expectedLength); assert.eq(res_dec.length, expectedLength); @@ -42,28 +42,26 @@ function test(limit, direction) { assert.eq(res_dec[i], dec_sorted[i]); assert.eq(res_rnd[i], rnd_sorted[i]); } - } - else { + } else { for (var i = 0; i < expectedLength; i++) { assert.eq(res_inc[i], inc_sorted[NUM_OBJS - 1 - i]); assert.eq(res_dec[i], dec_sorted[NUM_OBJS - 1 - i]); assert.eq(res_rnd[i], rnd_sorted[NUM_OBJS - 1 - i]); } } - } - catch (e) { + } catch (e) { print("failed with limit=" + limit + " direction= " + direction); throw e; } } -test(1, 1); +test(1, 1); test(1, -1); -test(10, 1); +test(10, 1); test(10, -1); -test(50, 1); +test(50, 1); test(50, -1); -test(NUM_OBJS, 1); +test(NUM_OBJS, 1); test(NUM_OBJS, -1); -test(NUM_OBJS + 10, 1); +test(NUM_OBJS + 10, 1); test(NUM_OBJS + 10, -1); diff --git a/jstests/aggregation/bugs/server4738.js b/jstests/aggregation/bugs/server4738.js index 7807daa020c..7a482ab0042 100644 --- a/jstests/aggregation/bugs/server4738.js +++ b/jstests/aggregation/bugs/server4738.js @@ -3,12 +3,13 @@ c = db.blah; c.drop(); c.save({key: 4, v: 3, x: 2}); -var r = c.aggregate( - { "$project" : { - "_id" : 0, - "key" : NumberLong(1), - "v" : 1, /* javascript: really a double */ - "x" : NumberInt(1) - }}); +var r = c.aggregate({ + "$project": { + "_id": 0, + "key": NumberLong(1), + "v": 1, /* javascript: really a double */ + "x": NumberInt(1) + } +}); assert.eq(r.toArray(), [{key: 4, v: 3, x: 2}], "support204 failed"); diff --git a/jstests/aggregation/bugs/server4899.js b/jstests/aggregation/bugs/server4899.js index 5c877ee90dd..b90ed984c2a 100644 --- a/jstests/aggregation/bugs/server4899.js +++ b/jstests/aggregation/bugs/server4899.js @@ -3,18 +3,14 @@ load('jstests/aggregation/extras/utils.js'); c = db.server4899; c.drop(); -c.save({arr:[]}); -c.save({arr:[1]}); -c.save({arr:["asdf", "asdfasdf"]}); -c.save({arr:[1, "asdf", 1234, 4.3, {key:23}]}); -c.save({arr:[3, [31, 31, 13, 13]]}); +c.save({arr: []}); +c.save({arr: [1]}); +c.save({arr: ["asdf", "asdfasdf"]}); +c.save({arr: [1, "asdf", 1234, 4.3, {key: 23}]}); +c.save({arr: [3, [31, 31, 13, 13]]}); result = c.aggregate({$project: {_id: 0, length: {$size: "$arr"}}}); -assert.eq(result.toArray(), [{length:0}, - {length:1}, - {length:2}, - {length:5}, - {length:2}]); +assert.eq(result.toArray(), [{length: 0}, {length: 1}, {length: 2}, {length: 5}, {length: 2}]); -c.save({arr:231}); +c.save({arr: 231}); assertErrorCode(c, {$project: {_id: 0, length: {$size: "$arr"}}}, 17124); diff --git a/jstests/aggregation/bugs/server5012.js b/jstests/aggregation/bugs/server5012.js index 6e2bbd1ecb6..64f55369dc4 100644 --- a/jstests/aggregation/bugs/server5012.js +++ b/jstests/aggregation/bugs/server5012.js @@ -5,26 +5,8 @@ var article = db.article; load('jstests/aggregation/data/articles.js'); // original crash from ticket -var r3 = article.aggregate( - { $project: { - author: 1, - _id: 0 - }}, - { $project: { - Writer: "$author" - }} -); +var r3 = article.aggregate({$project: {author: 1, _id: 0}}, {$project: {Writer: "$author"}}); -var r3result = [ - { - "Writer" : "bob" - }, - { - "Writer" : "dave" - }, - { - "Writer" : "jane" - } -]; +var r3result = [{"Writer": "bob"}, {"Writer": "dave"}, {"Writer": "jane"}]; assert.eq(r3.toArray(), r3result, 's5012 failed'); diff --git a/jstests/aggregation/bugs/server5044.js b/jstests/aggregation/bugs/server5044.js index 3a784afac01..945f31c302c 100644 --- a/jstests/aggregation/bugs/server5044.js +++ b/jstests/aggregation/bugs/server5044.js @@ -4,27 +4,28 @@ var t = db.server5044; function test(data, popExpected, sampExpected) { t.drop(); - assert.writeOK(t.insert({})); // need one document to ensure we get output + assert.writeOK(t.insert({})); // need one document to ensure we get output - for (var i=0; i < data.length; i++) + for (var i = 0; i < data.length; i++) assert.writeOK(t.insert({num: data[i]})); - var res = t.aggregate({$group: {_id: 1, - pop: {$stdDevPop: '$num'}, - samp: {$stdDevSamp: '$num'}, - }}).next(); + var res = t.aggregate({ + $group: { + _id: 1, + pop: {$stdDevPop: '$num'}, + samp: {$stdDevSamp: '$num'}, + } + }).next(); if (popExpected === null) { assert.isnull(res.pop); - } - else { + } else { assert.close(res.pop, popExpected, '', 10 /*decimal places*/); } if (sampExpected === null) { assert.isnull(res.samp); - } - else { + } else { assert.close(res.samp, sampExpected, '', 10 /*decimal places*/); } } @@ -38,11 +39,10 @@ test([1, 'a'], 0, null); test([1, 'a', 1], 0, 0); test([1, 2], .5, Math.sqrt(.5)); -test([1, 2, 3], Math.sqrt(2/3), 1); +test([1, 2, 3], Math.sqrt(2 / 3), 1); // test from http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Example test([4, 7, 13, 16], Math.sqrt(22.5), Math.sqrt(30)); test([1e8 + 4, 1e8 + 7, 1e8 + 13, 1e8 + 16], Math.sqrt(22.5), Math.sqrt(30)); test([1e9 + 4, 1e9 + 7, 1e9 + 13, 1e9 + 16], Math.sqrt(22.5), Math.sqrt(30)); test([1e10 + 4, 1e10 + 7, 1e10 + 13, 1e10 + 16], Math.sqrt(22.5), Math.sqrt(30)); - diff --git a/jstests/aggregation/bugs/server5209.js b/jstests/aggregation/bugs/server5209.js index d0890c2b47a..8c0f017bbc7 100644 --- a/jstests/aggregation/bugs/server5209.js +++ b/jstests/aggregation/bugs/server5209.js @@ -9,12 +9,7 @@ db.aggtype.insert({key: NumberInt(42), value: 11}); db.aggtype.insert({key: NumberLong(42), value: 13}); db.aggtype.insert({key: 42, value: 6}); -var at = db.aggtype.aggregate( - {$group: { - _id: "$key", - s: {$sum: "$value"} - }} -).toArray(); +var at = db.aggtype.aggregate({$group: {_id: "$key", s: {$sum: "$value"}}}).toArray(); assert(at[0].s == 30, 'server5209 failed'); assert(at[1].s == 30, 'server5209 failed'); diff --git a/jstests/aggregation/bugs/server5782.js b/jstests/aggregation/bugs/server5782.js index d4ac2eeb6f1..47bb7dd8826 100644 --- a/jstests/aggregation/bugs/server5782.js +++ b/jstests/aggregation/bugs/server5782.js @@ -4,15 +4,15 @@ db.server5782.drop(); db.server5782.save({string: "foo"}); // check that without $literal we end up comparing a field with itself and the result is true -var result = db.runCommand({aggregate: "server5782", - pipeline:[{$project: - {stringis$string: {$eq:["$string", '$string']}} - }]}); +var result = db.runCommand({ + aggregate: "server5782", + pipeline: [{$project: {stringis$string: {$eq: ["$string", '$string']}}}] +}); assert.eq(result.result[0].stringis$string, true); // check that with $literal we end up comparing a field with '$string' and the result is true -var result = db.runCommand({aggregate: "server5782", - pipeline:[{$project: - {stringis$string: {$eq:["$string", {$literal:'$string'}]}} - }]}); +var result = db.runCommand({ + aggregate: "server5782", + pipeline: [{$project: {stringis$string: {$eq: ["$string", {$literal: '$string'}]}}}] +}); assert.eq(result.result[0].stringis$string, false); diff --git a/jstests/aggregation/bugs/server5932.js b/jstests/aggregation/bugs/server5932.js index 9308cbe6b72..942cab3b0d4 100644 --- a/jstests/aggregation/bugs/server5932.js +++ b/jstests/aggregation/bugs/server5932.js @@ -44,7 +44,7 @@ var bigArray = []; for (var i = 0; i < 1000; i++) bigArray.push(i); -var bigStr = Array(1001).toString(); // 1000 bytes of ',' +var bigStr = Array(1001).toString(); // 1000 bytes of ',' for (var i = 0; i < 100; i++) t.insert({_id: i, bigArray: bigArray, bigStr: bigStr}); @@ -54,35 +54,39 @@ for (var i = 0; i < 100; i++) // // successfully handles results > 16MB (bigArray.length * bytes in bigStr * t.count() == 100MB) -var cursor = aggCursor([{$unwind:'$bigArray'}]); // default settings +var cursor = aggCursor([{$unwind: '$bigArray'}]); // default settings assert.eq(cursor.itcount(), bigArray.length * t.count()); -var cursor = aggCursor([{$unwind:'$bigArray'}], 0); // empty first batch +var cursor = aggCursor([{$unwind: '$bigArray'}], 0); // empty first batch assert.eq(cursor.itcount(), bigArray.length * t.count()); -var cursor = aggCursor([{$unwind:'$bigArray'}], 5, 5); // many small batches +var cursor = aggCursor([{$unwind: '$bigArray'}], 5, 5); // many small batches assert.eq(cursor.itcount(), bigArray.length * t.count()); // empty result set results in cursor.id == 0 unless batchSize is 0; -var res = t.runCommand(buildAggCmd([{$match: {noSuchField: {$exists:true}}}])); +var res = t.runCommand(buildAggCmd([{$match: {noSuchField: {$exists: true}}}])); assert.eq(res.cursor.firstBatch, []); assert.eq(res.cursor.id, 0); -var res = t.runCommand(buildAggCmd([{$match: {noSuchField: {$exists:true}}}], 0)); +var res = t.runCommand(buildAggCmd([{$match: {noSuchField: {$exists: true}}}], 0)); assert.eq(res.cursor.firstBatch, []); assert.neq(res.cursor.id, 0); assert.eq(makeCursor(res).itcount(), 0); // parse errors are caught before first batch, regardless of size -var res = t.runCommand(buildAggCmd([{$noSuchStage:1}], 0)); +var res = t.runCommand(buildAggCmd([{$noSuchStage: 1}], 0)); assert.commandFailed(res); // data dependent errors can get ok:1 but fail in getMore if they don't fail in first batch -var res = t.runCommand(buildAggCmd([{$project:{cantAddString: {$add:[1, '$bigStr']}}}], 1)); +var res = t.runCommand(buildAggCmd([{$project: {cantAddString: {$add: [1, '$bigStr']}}}], 1)); assert.commandFailed(res); -var res = t.runCommand(buildAggCmd([{$project:{cantAddString: {$add:[1, '$bigStr']}}}], 0)); +var res = t.runCommand(buildAggCmd([{$project: {cantAddString: {$add: [1, '$bigStr']}}}], 0)); assert.commandWorked(res); -assert.throws(function() { makeCursor(res).itcount(); }); +assert.throws(function() { + makeCursor(res).itcount(); +}); // error if collection dropped after first batch -var cursor = aggCursor([{$unwind:'$bigArray'}], 0); +var cursor = aggCursor([{$unwind: '$bigArray'}], 0); t.drop(); -assert.throws(function() { cursor.itcount(); }); +assert.throws(function() { + cursor.itcount(); +}); // DON'T ADD NEW TEST TO THIS FILE AFTER THIS ONE (unless you reseed the data) diff --git a/jstests/aggregation/bugs/server5973.js b/jstests/aggregation/bugs/server5973.js index 9ad4549ef80..d1889341f21 100644 --- a/jstests/aggregation/bugs/server5973.js +++ b/jstests/aggregation/bugs/server5973.js @@ -5,9 +5,9 @@ db = db.getSiblingDB('aggdb'); db.test.drop(); -db.test.insert({d:ISODate('1950-01-01')}); -db.test.insert({d:ISODate('1980-01-01')}); +db.test.insert({d: ISODate('1950-01-01')}); +db.test.insert({d: ISODate('1980-01-01')}); -var out = db.test.aggregate({$sort:{d:1}}).toArray(); +var out = db.test.aggregate({$sort: {d: 1}}).toArray(); assert.lt(out[0].d, out[1].d); diff --git a/jstests/aggregation/bugs/server6045.js b/jstests/aggregation/bugs/server6045.js index 1f3d3c04895..852a8bdc093 100644 --- a/jstests/aggregation/bugs/server6045.js +++ b/jstests/aggregation/bugs/server6045.js @@ -29,15 +29,8 @@ db.agg.insert({key: "yarn", value: 42}); // As pipeline assertErrorCode(db.agg, [{}], 16435); // Start of pipeline -assertErrorCode(db.agg, [{$project: {value: 1}} - ,{} - ], 16435); +assertErrorCode(db.agg, [{$project: {value: 1}}, {}], 16435); // End of pipeline -assertErrorCode(db.agg, [{} - ,{$project: {value: 1}} - ], 16435); +assertErrorCode(db.agg, [{}, {$project: {value: 1}}], 16435); // Middle of pipeline -assertErrorCode(db.agg, [{$project: {value: 1}} - ,{} - ,{$project: {value: 1}} - ], 16435); +assertErrorCode(db.agg, [{$project: {value: 1}}, {}, {$project: {value: 1}}], 16435); diff --git a/jstests/aggregation/bugs/server6118.js b/jstests/aggregation/bugs/server6118.js index 7edfda4821f..898e5927b63 100644 --- a/jstests/aggregation/bugs/server6118.js +++ b/jstests/aggregation/bugs/server6118.js @@ -1,41 +1,40 @@ // SERVER-6118: support for sharded sorts (function() { -var s = new ShardingTest({ name: "aggregation_sort1", shards: 2, mongos: 1 }); -s.stopBalancer(); + var s = new ShardingTest({name: "aggregation_sort1", shards: 2, mongos: 1}); + s.stopBalancer(); -s.adminCommand({ enablesharding:"test" }); -s.ensurePrimaryShard('test', 'shard0001'); -s.adminCommand({ shardcollection: "test.data", key:{ _id: 1 } }); + s.adminCommand({enablesharding: "test"}); + s.ensurePrimaryShard('test', 'shard0001'); + s.adminCommand({shardcollection: "test.data", key: {_id: 1}}); -var d = s.getDB( "test" ); + var d = s.getDB("test"); -// Insert _id values 0 - 99 -var N = 100; + // Insert _id values 0 - 99 + var N = 100; -var bulkOp = d.data.initializeOrderedBulkOp(); -for(var i = 0; i < N; ++i) { - bulkOp.insert({ _id: i }); -} -bulkOp.execute(); + var bulkOp = d.data.initializeOrderedBulkOp(); + for (var i = 0; i < N; ++i) { + bulkOp.insert({_id: i}); + } + bulkOp.execute(); -// Split the data into 3 chunks -s.adminCommand( { split:"test.data", middle:{ _id:33 } } ); -s.adminCommand( { split:"test.data", middle:{ _id:66 } } ); + // Split the data into 3 chunks + s.adminCommand({split: "test.data", middle: {_id: 33}}); + s.adminCommand({split: "test.data", middle: {_id: 66}}); -// Migrate the middle chunk to another shard -s.adminCommand({ movechunk: "test.data", - find: { _id: 50 }, - to: s.getOther(s.getPrimaryShard("test")).name }); + // Migrate the middle chunk to another shard + s.adminCommand( + {movechunk: "test.data", find: {_id: 50}, to: s.getOther(s.getPrimaryShard("test")).name}); -// Check that the results are in order. -var result = d.data.aggregate({ $sort: { _id: 1 } }).toArray(); -printjson(result); + // Check that the results are in order. + var result = d.data.aggregate({$sort: {_id: 1}}).toArray(); + printjson(result); -for(var i = 0; i < N; ++i) { - assert.eq(i, result[i]._id); -} + for (var i = 0; i < N; ++i) { + assert.eq(i, result[i]._id); + } -s.stop(); + s.stop(); })(); diff --git a/jstests/aggregation/bugs/server6120.js b/jstests/aggregation/bugs/server6120.js index cd2cf7bc25c..c66b296a5a7 100644 --- a/jstests/aggregation/bugs/server6120.js +++ b/jstests/aggregation/bugs/server6120.js @@ -3,41 +3,41 @@ t = db.jstests_aggregation_server6120; t.drop(); -t.save( {object: {a:1}} ); +t.save({object: {a: 1}}); -function coerceToBool( value ) { - return t.aggregate( { $project:{ boolValue:{ $and:[ value ] } } } ).toArray()[ 0 ].boolValue; +function coerceToBool(value) { + return t.aggregate({$project: {boolValue: {$and: [value]}}}).toArray()[0].boolValue; } -function assertBoolValue( expectedBool, value ) { - assert.eq( expectedBool, coerceToBool( value ) ); +function assertBoolValue(expectedBool, value) { + assert.eq(expectedBool, coerceToBool(value)); } // Bool type. -assertBoolValue( false, false ); -assertBoolValue( true, true ); +assertBoolValue(false, false); +assertBoolValue(true, true); // Numeric types. -assertBoolValue( false, NumberLong( 0 ) ); -assertBoolValue( true, NumberLong( 1 ) ); -assertBoolValue( false, NumberInt( 0 ) ); -assertBoolValue( true, NumberInt( 1 ) ); -assertBoolValue( false, 0.0 ); -assertBoolValue( true, 1.0 ); +assertBoolValue(false, NumberLong(0)); +assertBoolValue(true, NumberLong(1)); +assertBoolValue(false, NumberInt(0)); +assertBoolValue(true, NumberInt(1)); +assertBoolValue(false, 0.0); +assertBoolValue(true, 1.0); // Always false types. -assertBoolValue( false, null ); +assertBoolValue(false, null); // Always true types. -assertBoolValue( true, '' ); -assertBoolValue( true, 'a' ); -assertBoolValue( true, "$object" ); -assertBoolValue( true, [] ); -assertBoolValue( true, [ 1 ] ); -assertBoolValue( true, new ObjectId() ); -assertBoolValue( true, new Date() ); -assertBoolValue( true, /a/ ); -assertBoolValue( true, new Timestamp() ); +assertBoolValue(true, ''); +assertBoolValue(true, 'a'); +assertBoolValue(true, "$object"); +assertBoolValue(true, []); +assertBoolValue(true, [1]); +assertBoolValue(true, new ObjectId()); +assertBoolValue(true, new Date()); +assertBoolValue(true, /a/); +assertBoolValue(true, new Timestamp()); // Missing field. -assertBoolValue( false, '$missingField' ); +assertBoolValue(false, '$missingField'); diff --git a/jstests/aggregation/bugs/server6121.js b/jstests/aggregation/bugs/server6121.js index e0051fe8430..97d5a4d72c9 100644 --- a/jstests/aggregation/bugs/server6121.js +++ b/jstests/aggregation/bugs/server6121.js @@ -19,69 +19,58 @@ load('jstests/aggregation/extras/utils.js'); // Clear db db.s6121.drop(); // Populate db -db.s6121.save({date:new Timestamp(1341337661, 1)}); -db.s6121.save({date:new Date(1341337661000)}); +db.s6121.save({date: new Timestamp(1341337661, 1)}); +db.s6121.save({date: new Date(1341337661000)}); // Aggregate checking various combinations of the constant and the field -var s6121 = db.s6121.aggregate( - {$project: { - _id: 0, - dayOfMonth: {$dayOfMonth: '$date'}, - dayOfWeek: {$dayOfWeek: '$date'}, - dayOfYear: {$dayOfYear: '$date'}, - hour: {$hour: '$date'}, - minute: {$minute: '$date'}, - month: {$month: '$date'}, - second: {$second: '$date'}, - week: {$week: '$date'}, - year: {$year: '$date'} - }} -).toArray(); +var s6121 = db.s6121.aggregate({ + $project: { + _id: 0, + dayOfMonth: {$dayOfMonth: '$date'}, + dayOfWeek: {$dayOfWeek: '$date'}, + dayOfYear: {$dayOfYear: '$date'}, + hour: {$hour: '$date'}, + minute: {$minute: '$date'}, + month: {$month: '$date'}, + second: {$second: '$date'}, + week: {$week: '$date'}, + year: {$year: '$date'} + } +}).toArray(); // Assert the two entries are equal assert.eq(s6121[0], s6121[1], 's6121 failed'); - // Clear db for timestamp to date compare test // For historical reasons the compare the same if they are the same 64-bit representation. // That means that the Timestamp has an "inc" that is the same as the Date has millis. db.s6121.drop(); -db.s6121.save({time:new Timestamp( 0, 1234), date:new Date(1234)}); -db.s6121.save({time:new Timestamp( 1, 1234), date:new Date(1234)}); +db.s6121.save({time: new Timestamp(0, 1234), date: new Date(1234)}); +db.s6121.save({time: new Timestamp(1, 1234), date: new Date(1234)}); printjson(db.s6121.find().toArray()); -var s6121 = db.s6121.aggregate( - {$project: { - _id: 0, - // comparison is different code path based on order (same as in bson) - ts_date: {$eq: ['$time', '$date']}, - date_ts: {$eq: ['$date', '$time']} - }} -); -assert.eq(s6121.toArray(), [{ts_date: false, date_ts: false} - ,{ts_date: false, date_ts: false}]); - +var s6121 = db.s6121.aggregate({ + $project: { + _id: 0, + // comparison is different code path based on order (same as in bson) + ts_date: {$eq: ['$time', '$date']}, + date_ts: {$eq: ['$date', '$time']} + } +}); +assert.eq(s6121.toArray(), [{ts_date: false, date_ts: false}, {ts_date: false, date_ts: false}]); // Clear db for timestamp comparison tests db.s6121.drop(); -db.s6121.save({time:new Timestamp(1341337661, 1), time2:new Timestamp(1341337661, 2)}); -var s6121 = db.s6121.aggregate( - {$project: { - _id: 0, - cmp: {$cmp: ['$time', '$time2']}, - eq: {$eq: ['$time', '$time2']}, - gt: {$gt: ['$time', '$time2']}, - gte: {$gte: ['$time', '$time2']}, - lt: {$lt: ['$time', '$time2']}, - lte: {$lte: ['$time', '$time2']}, - ne: {$ne: ['$time', '$time2']} - }} -); -var s6121result = [{ - cmp: -1, - eq: false, - gt: false, - gte: false, - lt: true, - lte: true, - ne: true -}]; +db.s6121.save({time: new Timestamp(1341337661, 1), time2: new Timestamp(1341337661, 2)}); +var s6121 = db.s6121.aggregate({ + $project: { + _id: 0, + cmp: {$cmp: ['$time', '$time2']}, + eq: {$eq: ['$time', '$time2']}, + gt: {$gt: ['$time', '$time2']}, + gte: {$gte: ['$time', '$time2']}, + lt: {$lt: ['$time', '$time2']}, + lte: {$lte: ['$time', '$time2']}, + ne: {$ne: ['$time', '$time2']} + } +}); +var s6121result = [{cmp: -1, eq: false, gt: false, gte: false, lt: true, lte: true, ne: true}]; // Assert the results are as expected assert.eq(s6121.toArray(), s6121result, 's6121 failed comparing two timestamps'); diff --git a/jstests/aggregation/bugs/server6125.js b/jstests/aggregation/bugs/server6125.js index 3e8625382c5..746c191d8fe 100644 --- a/jstests/aggregation/bugs/server6125.js +++ b/jstests/aggregation/bugs/server6125.js @@ -1,91 +1,97 @@ // -//testing $sort aggregation pipeline for heterogeneity (SERVER-6125) -//method: +// testing $sort aggregation pipeline for heterogeneity (SERVER-6125) +// method: // Create an array with all the different types. (Array is created with correct sort order) // Randomise it (to prevent $sort returning types in same order). -// Save the array members to the db. -// aggregate($sort) +// Save the array members to the db. +// aggregate($sort) // iterate through the array ensuring the _ids are in the correct order - -//to make results array nested (problem 2) -function nestArray( nstArray ) { - for( x = 0; x < nstArray.length; x++ ) { - nstArray[x].a = { b : nstArray[x].a }; + +// to make results array nested (problem 2) +function nestArray(nstArray) { + for (x = 0; x < nstArray.length; x++) { + nstArray[x].a = { + b: nstArray[x].a + }; } } - -//sort and run the tests -function runSort( chkDoc, nest, problem ){ + +// sort and run the tests +function runSort(chkDoc, nest, problem) { var chkArray = setupArray(); - if( nest ){ nestArray( chkArray ); } + if (nest) { + nestArray(chkArray); + } Array.shuffle(chkArray); var t = db.s6125; t.drop(); - t.insert( chkArray ); - - runAsserts( t.aggregate( { $sort : chkDoc } ).toArray(), problem ); + t.insert(chkArray); + + runAsserts(t.aggregate({$sort: chkDoc}).toArray(), problem); } - -//actually run the tests -function runAsserts( chkArray, problem ) { - //check the _id at [0] to determine which way around this has been sorted - //then check for gt / lt. Done rather than neq to preclude a < b > c issues - if( chkArray[ 0 ]._id == 0 ) { - for( var x=0; x<chkArray.length-1; x++ ) { - assert.lt( chkArray[x]._id, chkArray[x + 1]._id ); + +// actually run the tests +function runAsserts(chkArray, problem) { + // check the _id at [0] to determine which way around this has been sorted + // then check for gt / lt. Done rather than neq to preclude a < b > c issues + if (chkArray[0]._id == 0) { + for (var x = 0; x < chkArray.length - 1; x++) { + assert.lt(chkArray[x]._id, chkArray[x + 1]._id); } - } - else if( chkArray[ chkArray.length - 1 ]._id == 0 ) { - for( var x=0; x<chkArray.length-1; x++ ) { - assert.gt( chkArray[x]._id, chkArray[x + 1]._id ); + } else if (chkArray[chkArray.length - 1]._id == 0) { + for (var x = 0; x < chkArray.length - 1; x++) { + assert.gt(chkArray[x]._id, chkArray[x + 1]._id); } - } - else { - assert.eq( true, chkArray[0]._id == 0 || chkArray[chkArray.length-1]._id == 0 ); + } else { + assert.eq(true, chkArray[0]._id == 0 || chkArray[chkArray.length - 1]._id == 0); } } - -//set up data -function setupArray(){ - return [ - { _id : 0, a : MinKey, ty : "MinKey" }, - { _id : 1, a : null, ty : "null" }, - { _id : 2, a : 1, ty : "Number" }, - { _id : 3, a : NumberLong(2), ty : "NumberLong"}, - { _id : 4, a : "3", ty : "String" }, - //Symbol not implemented in JS - { _id : 5, a : {}, ty : "Object" }, - { _id : 6, a : new DBRef( "test.s6125", ObjectId("0102030405060708090A0B0C") ), ty : "DBRef" }, - { _id : 7, a : [ ], ty : "Empty Array" }, - { _id : 8, a : [ 1 , 2 , "a" , "B" ], ty : "Array" }, - { _id : 9, a : BinData(0, "77+9"), ty : "BinData" }, - { _id : 10, a : new ObjectId("0102030405060708090A0B0C"), ty : "ObjectId" }, - { _id : 11, a : true, ty : "Boolean" }, - { _id : 12, a : new Date( 2 ), ty : "Date" }, - { _id : 13, a : new Timestamp( 1/1000 , 1 ), ty : "Timestamp" }, - { _id : 14, a : /regex/, ty : "RegExp" }, - { _id : 15, a : new DBPointer("test.s6125",new ObjectId("0102030405060708090A0B0C")), ty : "DBPointer" }, - { _id : 16, a : function(){}, ty : "Code" }, - //Code with Scope not implemented in JS - { _id : 17, a : MaxKey, ty : "MaxKey"} + +// set up data +function setupArray() { + return [ + {_id: 0, a: MinKey, ty: "MinKey"}, + {_id: 1, a: null, ty: "null"}, + {_id: 2, a: 1, ty: "Number"}, + {_id: 3, a: NumberLong(2), ty: "NumberLong"}, + {_id: 4, a: "3", ty: "String"}, + // Symbol not implemented in JS + {_id: 5, a: {}, ty: "Object"}, + {_id: 6, a: new DBRef("test.s6125", ObjectId("0102030405060708090A0B0C")), ty: "DBRef"}, + {_id: 7, a: [], ty: "Empty Array"}, + {_id: 8, a: [1, 2, "a", "B"], ty: "Array"}, + {_id: 9, a: BinData(0, "77+9"), ty: "BinData"}, + {_id: 10, a: new ObjectId("0102030405060708090A0B0C"), ty: "ObjectId"}, + {_id: 11, a: true, ty: "Boolean"}, + {_id: 12, a: new Date(2), ty: "Date"}, + {_id: 13, a: new Timestamp(1 / 1000, 1), ty: "Timestamp"}, + {_id: 14, a: /regex/, ty: "RegExp"}, + { + _id: 15, + a: new DBPointer("test.s6125", new ObjectId("0102030405060708090A0B0C")), + ty: "DBPointer" + }, + {_id: 16, a: function() {}, ty: "Code"}, + // Code with Scope not implemented in JS + {_id: 17, a: MaxKey, ty: "MaxKey"} ]; } //*** -//Begin testing for SERVER-6125 +// Begin testing for SERVER-6125 //*** Random.setRandomSeed(); -//problem 1, does aggregate $sort work with all types -runSort( { a : 1 }, false, "p1" ); - -//problem 2, does aggregate $sort work with all types nested -runSort( { "a" : 1 }, true, "p2a" ); -runSort( { "a.b" : 1 }, true, "p2b" ); - -//problem 3, check reverse order sort -runSort( { a : -1 }, false, "p3" ); - -//problem 4, reverse order sort with nested array -runSort( { "a" : -1 }, true, "p4a" ); -runSort( { "a.b" : -1 }, true, "p4b" ); +// problem 1, does aggregate $sort work with all types +runSort({a: 1}, false, "p1"); + +// problem 2, does aggregate $sort work with all types nested +runSort({"a": 1}, true, "p2a"); +runSort({"a.b": 1}, true, "p2b"); + +// problem 3, check reverse order sort +runSort({a: -1}, false, "p3"); + +// problem 4, reverse order sort with nested array +runSort({"a": -1}, true, "p4a"); +runSort({"a.b": -1}, true, "p4b"); diff --git a/jstests/aggregation/bugs/server6127.js b/jstests/aggregation/bugs/server6127.js index d353d53ec0a..f217e9a8d93 100644 --- a/jstests/aggregation/bugs/server6127.js +++ b/jstests/aggregation/bugs/server6127.js @@ -16,19 +16,12 @@ db.s6127.drop(); // Populate db -db.s6127.save({a:1}); -db.s6127.save({foo:2}); -db.s6127.save({foo:{bar:3}}); +db.s6127.save({a: 1}); +db.s6127.save({foo: 2}); +db.s6127.save({foo: {bar: 3}}); // Aggregate checking the field foo and the path foo.bar -var s6127 = db.s6127.aggregate( - { $project : { - _id : 0, - 'foo.bar' : 1, - field : "$foo", - path : "$foo.bar" - }} -); +var s6127 = db.s6127.aggregate({$project: {_id: 0, 'foo.bar': 1, field: "$foo", path: "$foo.bar"}}); /* * The first document should contain nothing as neither field exists, the second document should @@ -37,20 +30,13 @@ var s6127 = db.s6127.aggregate( * a field bar */ var s6127result = [ + {}, + {field: 2}, { - }, - { - field : 2 - }, - { - foo : { - bar : 3 - }, - field : { - bar : 3 - }, - path : 3 - + foo: {bar: 3}, + field: {bar: 3}, + path: 3 + } ]; diff --git a/jstests/aggregation/bugs/server6131.js b/jstests/aggregation/bugs/server6131.js index bb2fe28e408..602894ab721 100644 --- a/jstests/aggregation/bugs/server6131.js +++ b/jstests/aggregation/bugs/server6131.js @@ -3,54 +3,74 @@ t = db.jstests_aggregation_server6131; t.drop(); -function assertAggregationResults( expected, aggregation ) { +function assertAggregationResults(expected, aggregation) { assert.eq(expected, t.aggregate(aggregation).toArray()); } t.drop(); // An empty array document is dropped. -t.save( { _id:0, a:1, b:[], c:2 } ); -assertAggregationResults( [], { $unwind:'$b' } ); +t.save({_id: 0, a: 1, b: [], c: 2}); +assertAggregationResults([], + { +$unwind: + '$b' + }); // Values from a nonempty array in another document are unwound. -t.save( { _id:1, b:[ 4, 5 ] } ); -assertAggregationResults( [ { _id:1, b:4 }, - { _id:1, b:5 } ], - { $unwind:'$b' } ); +t.save({_id: 1, b: [4, 5]}); +assertAggregationResults([{_id: 1, b: 4}, {_id: 1, b: 5}], {$unwind: '$b'}); // Another empty array document is dropped. -t.save( { _id:2, b:[] } ); -assertAggregationResults( [ { _id:1, b:4 }, - { _id:1, b:5 } ], - { $unwind:'$b' } ); +t.save({_id: 2, b: []}); +assertAggregationResults([{_id: 1, b: 4}, {_id: 1, b: 5}], {$unwind: '$b'}); t.drop(); // A nested empty array document is dropped. -t.save( { _id:0, a:1, b:{ x:10, y:[], z:20 }, c:2 } ); -assertAggregationResults( [], { $unwind:'$b.y' } ); +t.save({_id: 0, a: 1, b: {x: 10, y: [], z: 20}, c: 2}); +assertAggregationResults([], + { +$unwind: + '$b.y' + }); t.drop(); // A null value document is dropped. -t.save( { _id:0, a:1, b:null, c:2 } ); -assertAggregationResults( [], { $unwind:'$b' } ); +t.save({_id: 0, a: 1, b: null, c: 2}); +assertAggregationResults([], + { +$unwind: + '$b' + }); t.drop(); // A missing value causes the document to be dropped. -t.save( { _id:0, a:1, c:2 } ); -assertAggregationResults( [], { $unwind:'$b' } ); +t.save({_id: 0, a: 1, c: 2}); +assertAggregationResults([], + { +$unwind: + '$b' + }); t.drop(); // A missing value in an existing nested object causes the document to be dropped. -t.save( { _id:0, a:1, b:{ d:4 }, c:2 } ); -assertAggregationResults( [], { $unwind:'$b.y' } ); +t.save({_id: 0, a: 1, b: {d: 4}, c: 2}); +assertAggregationResults([], + { +$unwind: + '$b.y' + }); t.drop(); // A missing value in a missing nested object causes the document to be dropped. -t.save( { _id:0, a:1, b:10, c:2 } ); -assertAggregationResults( [], { $unwind:'$b.y' } ); +t.save({_id: 0, a: 1, b: 10, c: 2}); +assertAggregationResults([], + { +$unwind: + '$b.y' + }); diff --git a/jstests/aggregation/bugs/server6143.js b/jstests/aggregation/bugs/server6143.js index 05e0b2a9de5..375616f00d7 100644 --- a/jstests/aggregation/bugs/server6143.js +++ b/jstests/aggregation/bugs/server6143.js @@ -18,10 +18,7 @@ load('jstests/aggregation/extras/utils.js'); db.s6143.drop(); // Populate db -db.s6143.save({a:null}); +db.s6143.save({a: null}); // Aggregate using a date expression on a null value, assert error -assertErrorCode(db.s6143, - { $project : {dateConvert : {$dayOfWeek:["$a"]}}}, - 16006); - +assertErrorCode(db.s6143, {$project: {dateConvert: {$dayOfWeek: ["$a"]}}}, 16006); diff --git a/jstests/aggregation/bugs/server6147.js b/jstests/aggregation/bugs/server6147.js index 86f58e1c061..b376afa3c75 100644 --- a/jstests/aggregation/bugs/server6147.js +++ b/jstests/aggregation/bugs/server6147.js @@ -16,19 +16,19 @@ db.s6147.drop(); // Populate db -db.s6147.save({a:1}); -db.s6147.save({a:2}); +db.s6147.save({a: 1}); +db.s6147.save({a: 2}); // Aggregate checking various combinations of the constant and the field -var s6147 = db.s6147.aggregate( - { $project : { - _id : 0, - constantAndField : { $ne: [1, "$a"] }, - fieldAndConstant : { $ne: ["$a", 1] }, - constantAndConstant : { $ne: [1, 1] }, - fieldAndField : { $ne: ["$a", "$a"] } - }} -); +var s6147 = db.s6147.aggregate({ + $project: { + _id: 0, + constantAndField: {$ne: [1, "$a"]}, + fieldAndConstant: {$ne: ["$a", 1]}, + constantAndConstant: {$ne: [1, 1]}, + fieldAndField: {$ne: ["$a", "$a"]} + } +}); /* * In both documents the constantAndConstant and fieldAndField should be false since they compare @@ -38,16 +38,16 @@ var s6147 = db.s6147.aggregate( */ var s6147result = [ { - constantAndField : false, - fieldAndConstant : false, - constantAndConstant : false, - fieldAndField : false + constantAndField: false, + fieldAndConstant: false, + constantAndConstant: false, + fieldAndField: false }, { - constantAndField : true, - fieldAndConstant : true, - constantAndConstant : false, - fieldAndField : false + constantAndField: true, + fieldAndConstant: true, + constantAndConstant: false, + fieldAndField: false } ]; diff --git a/jstests/aggregation/bugs/server6165.js b/jstests/aggregation/bugs/server6165.js index c2ad5fc0fe6..7aeba059431 100644 --- a/jstests/aggregation/bugs/server6165.js +++ b/jstests/aggregation/bugs/server6165.js @@ -16,63 +16,65 @@ db.s6165.drop(); db.s6165.save({}); // Aggregate checking various combinations of number types -// The $match portion ensures they are of the correct type as the shell turns +// The $match portion ensures they are of the correct type as the shell turns // the ints back to doubles at the end so we can not check types with asserts -var s6165 = db.s6165.aggregate( - { $project: { - _id: 0, - dub_dub: {$mod: [138.5, 3.0]}, - dub_int: {$mod: [138.5, NumberLong(3)]}, - dub_long: {$mod: [138.5, NumberInt(3)]}, - int_dub: {$mod: [NumberInt(8), 3.25]}, - int_dubint: {$mod: [NumberInt(8), 3.0]}, - int_int: {$mod: [NumberInt(8), NumberInt(3)]}, - int_long: {$mod: [NumberInt(8), NumberLong(3)]}, - long_dub: {$mod: [NumberLong(8), 3.25]}, - long_dubint: {$mod: [NumberLong(8), 3.0]}, - long_dublong: {$mod: [NumberLong(500000000000), 450000000000.0]}, - long_int: {$mod: [NumberLong(8), NumberInt(3)]}, - long_long: {$mod: [NumberLong(8), NumberLong(3)]}, - verylong_verylong: {$mod: [NumberLong(800000000000), NumberLong(300000000000)]} - }}, - { $match: { - // 1 is NumberDouble - dub_dub: {$type: 1}, - dub_int: {$type: 1}, - dub_long: {$type: 1}, - int_dub: {$type: 1}, - // 16 is NumberInt - int_dubint: {$type: 16}, - int_int: {$type: 16}, - // 18 is NumberLong - int_long: {$type: 18}, - long_dub: {$type: 1}, - long_dubint: {$type: 18}, - long_dublong: {$type: 1}, - long_int: {$type: 18}, - long_long: {$type: 18}, - verylong_verylong: {$type: 18} - }} -); +var s6165 = + db.s6165.aggregate( + { + $project: { + _id: 0, + dub_dub: {$mod: [138.5, 3.0]}, + dub_int: {$mod: [138.5, NumberLong(3)]}, + dub_long: {$mod: [138.5, NumberInt(3)]}, + int_dub: {$mod: [NumberInt(8), 3.25]}, + int_dubint: {$mod: [NumberInt(8), 3.0]}, + int_int: {$mod: [NumberInt(8), NumberInt(3)]}, + int_long: {$mod: [NumberInt(8), NumberLong(3)]}, + long_dub: {$mod: [NumberLong(8), 3.25]}, + long_dubint: {$mod: [NumberLong(8), 3.0]}, + long_dublong: {$mod: [NumberLong(500000000000), 450000000000.0]}, + long_int: {$mod: [NumberLong(8), NumberInt(3)]}, + long_long: {$mod: [NumberLong(8), NumberLong(3)]}, + verylong_verylong: {$mod: [NumberLong(800000000000), NumberLong(300000000000)]} + } + }, + { + $match: { + // 1 is NumberDouble + dub_dub: {$type: 1}, + dub_int: {$type: 1}, + dub_long: {$type: 1}, + int_dub: {$type: 1}, + // 16 is NumberInt + int_dubint: {$type: 16}, + int_int: {$type: 16}, + // 18 is NumberLong + int_long: {$type: 18}, + long_dub: {$type: 1}, + long_dubint: {$type: 18}, + long_dublong: {$type: 1}, + long_int: {$type: 18}, + long_long: {$type: 18}, + verylong_verylong: {$type: 18} + } + }); // Correct answers (it is mainly the types that are important here) -var s6165result = [ - { - dub_dub: 0.5, - dub_int: 0.5, - dub_long: 0.5, - int_dub: 1.5, - int_dubint: 2, - int_int: 2, - int_long: NumberLong(2), - long_dub: 1.5, - long_dubint: NumberLong(2), - long_dublong: 50000000000, - long_int: NumberLong(2), - long_long: NumberLong(2), - verylong_verylong: NumberLong(200000000000) - } -]; +var s6165result = [{ + dub_dub: 0.5, + dub_int: 0.5, + dub_long: 0.5, + int_dub: 1.5, + int_dubint: 2, + int_int: 2, + int_long: NumberLong(2), + long_dub: 1.5, + long_dubint: NumberLong(2), + long_dublong: 50000000000, + long_int: NumberLong(2), + long_long: NumberLong(2), + verylong_verylong: NumberLong(200000000000) +}]; // Assert assert.eq(s6165.toArray(), s6165result, 's6165 failed'); diff --git a/jstests/aggregation/bugs/server6177.js b/jstests/aggregation/bugs/server6177.js index 2bdb3f44214..53339c57d22 100644 --- a/jstests/aggregation/bugs/server6177.js +++ b/jstests/aggregation/bugs/server6177.js @@ -6,14 +6,12 @@ load('jstests/aggregation/extras/utils.js'); var c = db.c; c.drop(); -c.save( {} ); +c.save({}); // These currently give different errors -assertErrorCode(c, { $project:{ 'x':{ $add:[ 1 ] }, 'x.b':1 } }, 16401); -assertErrorCode(c, { $project:{ 'x.b': 1, 'x':{ $add:[ 1 ] }} }, 16400); +assertErrorCode(c, {$project: {'x': {$add: [1]}, 'x.b': 1}}, 16401); +assertErrorCode(c, {$project: {'x.b': 1, 'x': {$add: [1]}}}, 16400); // These both give the same error however -assertErrorCode(c, { $project:{'x':{'b':1}, 'x.b': 1} }, 16400); -assertErrorCode(c, { $project:{'x.b': 1, 'x':{'b':1}} }, 16400); - - +assertErrorCode(c, {$project: {'x': {'b': 1}, 'x.b': 1}}, 16400); +assertErrorCode(c, {$project: {'x.b': 1, 'x': {'b': 1}}}, 16400); diff --git a/jstests/aggregation/bugs/server6179.js b/jstests/aggregation/bugs/server6179.js index 4eba802e14e..20158af7fb7 100644 --- a/jstests/aggregation/bugs/server6179.js +++ b/jstests/aggregation/bugs/server6179.js @@ -1,82 +1,51 @@ // SERVER-6179: support for two $groups in sharded agg (function() { -var s = new ShardingTest({ name: "aggregation_multiple_group", shards: 2, mongos: 1 }); -s.stopBalancer(); + var s = new ShardingTest({name: "aggregation_multiple_group", shards: 2, mongos: 1}); + s.stopBalancer(); -s.adminCommand({ enablesharding:"test" }); -s.ensurePrimaryShard('test', 'shard0001'); -s.adminCommand({ shardcollection: "test.data", key:{ _id: 1 } }); + s.adminCommand({enablesharding: "test"}); + s.ensurePrimaryShard('test', 'shard0001'); + s.adminCommand({shardcollection: "test.data", key: {_id: 1}}); -var d = s.getDB( "test" ); + var d = s.getDB("test"); -// Insert _id values 0 - 99 -var N = 100; + // Insert _id values 0 - 99 + var N = 100; -var bulkOp = d.data.initializeOrderedBulkOp(); -for(var i = 0; i < N; ++i) { - bulkOp.insert({ _id: i, i: i%10 }); -} -bulkOp.execute(); - -// Split the data into 3 chunks -s.adminCommand( { split:"test.data", middle:{ _id:33 } } ); -s.adminCommand( { split:"test.data", middle:{ _id:66 } } ); - -// Migrate the middle chunk to another shard -s.adminCommand({ movechunk: "test.data", - find: { _id: 50 }, - to: s.getOther(s.getPrimaryShard("test")).name }); - -// Check that we get results rather than an error -var result = d.data.aggregate({$group: {_id: '$_id', i: {$first: '$i'}}}, - {$group: {_id: '$i', avg_id: {$avg: '$_id'}}}, - {$sort: {_id: 1}}).toArray(); -expected = [ - { - "_id" : 0, - "avg_id" : 45 - }, - { - "_id" : 1, - "avg_id" : 46 - }, - { - "_id" : 2, - "avg_id" : 47 - }, - { - "_id" : 3, - "avg_id" : 48 - }, - { - "_id" : 4, - "avg_id" : 49 - }, - { - "_id" : 5, - "avg_id" : 50 - }, - { - "_id" : 6, - "avg_id" : 51 - }, - { - "_id" : 7, - "avg_id" : 52 - }, - { - "_id" : 8, - "avg_id" : 53 - }, - { - "_id" : 9, - "avg_id" : 54 + var bulkOp = d.data.initializeOrderedBulkOp(); + for (var i = 0; i < N; ++i) { + bulkOp.insert({_id: i, i: i % 10}); } -]; - -assert.eq(result, expected); - -s.stop(); + bulkOp.execute(); + + // Split the data into 3 chunks + s.adminCommand({split: "test.data", middle: {_id: 33}}); + s.adminCommand({split: "test.data", middle: {_id: 66}}); + + // Migrate the middle chunk to another shard + s.adminCommand( + {movechunk: "test.data", find: {_id: 50}, to: s.getOther(s.getPrimaryShard("test")).name}); + + // Check that we get results rather than an error + var result = d.data.aggregate({$group: {_id: '$_id', i: {$first: '$i'}}}, + {$group: {_id: '$i', avg_id: {$avg: '$_id'}}}, + {$sort: {_id: 1}}).toArray(); + expected = [ + {"_id": 0, "avg_id": 45}, + {"_id": 1, "avg_id": 46}, + {"_id": 2, "avg_id": 47}, + {"_id": 3, "avg_id": 48}, + {"_id": 4, "avg_id": 49}, + {"_id": 5, "avg_id": 50}, + {"_id": 6, "avg_id": 51}, + {"_id": 7, "avg_id": 52}, + {"_id": 8, "avg_id": 53}, + {"_id": 9, "avg_id": 54} + ]; + + assert.eq(result, expected); + + s.stop(); })(); diff --git a/jstests/aggregation/bugs/server6181.js b/jstests/aggregation/bugs/server6181.js index 68fc7998435..d48a5dbfe02 100644 --- a/jstests/aggregation/bugs/server6181.js +++ b/jstests/aggregation/bugs/server6181.js @@ -3,10 +3,10 @@ c = db.c; c.drop(); -c.save( { a:2 } ); +c.save({a: 2}); -res = c.aggregate( { $project:{ _id:'$a' } } ); -assert.eq(res.toArray(), [{_id:2}]); +res = c.aggregate({$project: {_id: '$a'}}); +assert.eq(res.toArray(), [{_id: 2}]); -res = c.aggregate( { $project:{ _id:{$add: [1, '$a']} } } ); -assert.eq(res.toArray(), [{_id:3}]); +res = c.aggregate({$project: {_id: {$add: [1, '$a']}}}); +assert.eq(res.toArray(), [{_id: 3}]); diff --git a/jstests/aggregation/bugs/server6184.js b/jstests/aggregation/bugs/server6184.js index fd2e1b397aa..ae0f5ae947c 100644 --- a/jstests/aggregation/bugs/server6184.js +++ b/jstests/aggregation/bugs/server6184.js @@ -3,18 +3,20 @@ c = db.c; c.drop(); -c.save( { a:'missing', b:{ c:'bar', a: 'baz', z:'not there' } } ); +c.save({a: 'missing', b: {c: 'bar', a: 'baz', z: 'not there'}}); function test(projection) { res = c.aggregate({$project: projection}); assert.eq(res.toArray()[0], {b: {c: 'bar', a: 'baz'}}); } -test({_id:0, b: {a:1}, 'b.c': 1}); -test({_id:0, 'b.c': 1, b: {a:1}}); +test({_id: 0, b: {a: 1}, 'b.c': 1}); +test({_id: 0, 'b.c': 1, b: {a: 1}}); // Synthetic fields should be in the order they appear in the $project -one = {$add:[1]}; -res = c.aggregate({$project: {_id:0, 'A.Z':one, A:{Y:one, A:one}, 'A.B': one}}); -assert.eq(res.toArray()[0], {A: {Z:1, Y:1, A:1, B:1}}); +one = { + $add: [1] +}; +res = c.aggregate({$project: {_id: 0, 'A.Z': one, A: {Y: one, A: one}, 'A.B': one}}); +assert.eq(res.toArray()[0], {A: {Z: 1, Y: 1, A: 1, B: 1}}); diff --git a/jstests/aggregation/bugs/server6185.js b/jstests/aggregation/bugs/server6185.js index ab7c821d001..e1b19ad2c1f 100644 --- a/jstests/aggregation/bugs/server6185.js +++ b/jstests/aggregation/bugs/server6185.js @@ -2,11 +2,11 @@ c = db.c; c.drop(); -c.save({a:[1]}); -c.save({a:{c:1}}); -c.save({a:[{c:1},{b:1,c:1},{c:1}]}); -c.save({a:1}); -c.save({b:1}); +c.save({a: [1]}); +c.save({a: {c: 1}}); +c.save({a: [{c: 1}, {b: 1, c: 1}, {c: 1}]}); +c.save({a: 1}); +c.save({b: 1}); // assert the aggregation and the query produce the same thing -assert.eq(c.aggregate({$project:{'a.b':1}}).toArray(), c.find({}, {'a.b':1}).toArray()); +assert.eq(c.aggregate({$project: {'a.b': 1}}).toArray(), c.find({}, {'a.b': 1}).toArray()); diff --git a/jstests/aggregation/bugs/server6186.js b/jstests/aggregation/bugs/server6186.js index 1478641dd21..fb1ea25f34c 100644 --- a/jstests/aggregation/bugs/server6186.js +++ b/jstests/aggregation/bugs/server6186.js @@ -3,37 +3,37 @@ t = db.jstests_aggregation_server6186; t.drop(); -t.save( {} ); +t.save({}); -function substr( string, pos, n ) { - return t.aggregate( { $project:{ a:{ $substr:[ string, pos, n ] } } } ).toArray()[ 0 ].a; +function substr(string, pos, n) { + return t.aggregate({$project: {a: {$substr: [string, pos, n]}}}).toArray()[0].a; } -function expectedSubstr( string, pos, n ) { - if ( pos < 0 ) { +function expectedSubstr(string, pos, n) { + if (pos < 0) { // A negative value is interpreted as a large unsigned int, and is expected to be out of // bounds. return ""; } - if ( n < 0 ) { + if (n < 0) { // A negative value is interpreted as a large unsigned int, expected to exceed the length // of the string. Passing the string length is functionally equivalent. n = string.length; } - return string.substring( pos, pos + n ); + return string.substring(pos, pos + n); } -function assertSubstr( string, pos, n ) { - assert.eq( expectedSubstr( string, pos, n ), substr( string, pos, n ) ); +function assertSubstr(string, pos, n) { + assert.eq(expectedSubstr(string, pos, n), substr(string, pos, n)); } -function checkVariousSubstrings( string ) { - for( pos = -2; pos < 5; ++pos ) { - for( n = -2; n < 7; ++n ) { - assertSubstr( string, pos, n ); +function checkVariousSubstrings(string) { + for (pos = -2; pos < 5; ++pos) { + for (n = -2; n < 7; ++n) { + assertSubstr(string, pos, n); } } } -checkVariousSubstrings( "abc" ); -checkVariousSubstrings( "" ); +checkVariousSubstrings("abc"); +checkVariousSubstrings(""); diff --git a/jstests/aggregation/bugs/server6189.js b/jstests/aggregation/bugs/server6189.js index ff888f8725e..72f3e002a5a 100644 --- a/jstests/aggregation/bugs/server6189.js +++ b/jstests/aggregation/bugs/server6189.js @@ -5,34 +5,42 @@ function test(date, testSynthetics) { print("testing " + date); c.drop(); - c.save( {date: date} ); + c.save({date: date}); var ISOfmt = (date.getUTCMilliseconds() == 0) ? 'ISODate("%Y-%m-%dT%H:%M:%SZ")' : 'ISODate("%Y-%m-%dT%H:%M:%S.%LZ")'; // Can't use aggregate helper or assertErrorCode because we need to handle multiple error types - var res = c.runCommand('aggregate', {pipeline: [ - {$project: { _id: 0 - , year:{ $year: '$date' } - , month:{ $month: '$date' } - , dayOfMonth:{ $dayOfMonth: '$date' } - , hour:{ $hour: '$date' } - , minute:{ $minute: '$date' } - , second:{ $second: '$date' } - - // server-6666 - , millisecond:{ $millisecond: '$date' } - - // server-9289 - , millisecondPlusTen:{ $millisecond: {$add: ['$date', 10]}} - - // $substr will call coerceToString - , string: {$substr: ['$date', 0,1000]} - - // server-11118 - , format: {$dateToString: { format: ISOfmt - , date: '$date'}} - }}]}); + var res = c.runCommand('aggregate', + { + pipeline: [{ + $project: { + _id: 0, + year: {$year: '$date'}, + month: {$month: '$date'}, + dayOfMonth: {$dayOfMonth: '$date'}, + hour: {$hour: '$date'}, + minute: {$minute: '$date'}, + second: {$second: '$date'} + + // server-6666 + , + millisecond: {$millisecond: '$date'} + + // server-9289 + , + millisecondPlusTen: {$millisecond: {$add: ['$date', 10]}} + + // $substr will call coerceToString + , + string: {$substr: ['$date', 0, 1000]} + + // server-11118 + , + format: {$dateToString: {format: ISOfmt, date: '$date'}} + } + }] + }); if (date.valueOf() < 0 && _isWindows() && res.code == 16422) { // some versions of windows (but not all) fail with dates before 1970 @@ -40,52 +48,52 @@ function test(date, testSynthetics) { return; } - if (date.valueOf()/1000 < -2*1024*1024*1024 && res.code == 16421) { + if (date.valueOf() / 1000 < -2 * 1024 * 1024 * 1024 && res.code == 16421) { // we correctly detected that we are outside of the range of a 32-bit time_t print("skipping test of " + date.tojson() + " because it is outside of time_t range"); return; } assert.commandWorked(res); - assert.eq(res.result[0], { year: date.getUTCFullYear() - , month: date.getUTCMonth() + 1 // jan == 1 - , dayOfMonth: date.getUTCDate() - , hour: date.getUTCHours() - , minute: date.getUTCMinutes() - , second: date.getUTCSeconds() - , millisecond: date.getUTCMilliseconds() - , millisecondPlusTen: ((date.getUTCMilliseconds() + 10) % 1000) - , string: date.tojson().slice(9,28) - , format: date.tojson() - } ); + assert.eq(res.result[0], + { + year: date.getUTCFullYear(), + month: date.getUTCMonth() + 1 // jan == 1 + , + dayOfMonth: date.getUTCDate(), + hour: date.getUTCHours(), + minute: date.getUTCMinutes(), + second: date.getUTCSeconds(), + millisecond: date.getUTCMilliseconds(), + millisecondPlusTen: ((date.getUTCMilliseconds() + 10) % 1000), + string: date.tojson().slice(9, 28), + format: date.tojson() + }); if (testSynthetics) { // Tests with this set all have the same value for these fields - res = c.aggregate( { $project:{ _id: 0 - , week:{ $week: '$date' } - , dayOfWeek:{ $dayOfWeek: '$date' } - , dayOfYear:{ $dayOfYear: '$date' } - , format: { $dateToString: { format: '%U-%w-%j' - , date: '$date' } } - } } ); - - assert.eq(res.toArray()[0], { week: 0 - , dayOfWeek: 7 - , dayOfYear: 2 - , format: '00-7-002' - } ); + res = c.aggregate({ + $project: { + _id: 0, + week: {$week: '$date'}, + dayOfWeek: {$dayOfWeek: '$date'}, + dayOfYear: {$dayOfYear: '$date'}, + format: {$dateToString: {format: '%U-%w-%j', date: '$date'}} + } + }); + + assert.eq(res.toArray()[0], {week: 0, dayOfWeek: 7, dayOfYear: 2, format: '00-7-002'}); } } - // Basic test test(ISODate('1960-01-02 03:04:05.006Z'), true); // Testing special rounding rules for seconds -test(ISODate('1960-01-02 03:04:04.999Z'), false); // second = 4 -test(ISODate('1960-01-02 03:04:05.000Z'), true); // second = 5 -test(ISODate('1960-01-02 03:04:05.001Z'), true); // second = 5 -test(ISODate('1960-01-02 03:04:05.999Z'), true); // second = 5 +test(ISODate('1960-01-02 03:04:04.999Z'), false); // second = 4 +test(ISODate('1960-01-02 03:04:05.000Z'), true); // second = 5 +test(ISODate('1960-01-02 03:04:05.001Z'), true); // second = 5 +test(ISODate('1960-01-02 03:04:05.999Z'), true); // second = 5 // Test date before 1900 (negative tm_year values from gmtime) test(ISODate('1860-01-02 03:04:05.006Z'), false); diff --git a/jstests/aggregation/bugs/server6190.js b/jstests/aggregation/bugs/server6190.js index caefaeb1b3e..d32a652e74b 100644 --- a/jstests/aggregation/bugs/server6190.js +++ b/jstests/aggregation/bugs/server6190.js @@ -5,131 +5,132 @@ load('jstests/aggregation/extras/utils.js'); t = db.jstests_aggregation_server6190; t.drop(); -t.save( {} ); +t.save({}); -function week( date ) { - return t.aggregate( { $project:{ a:{ $week:date } } }, - { $match:{ a:{ $type:16 /* Int type expected */ } } } ).toArray()[ 0 ].a; +function week(date) { + return t.aggregate({$project: {a: {$week: date}}}, + {$match: {a: {$type: 16 /* Int type expected */}}}) + .toArray()[0] + .a; } -function assertWeek( expectedWeek, date ) { - assert.eq( expectedWeek, week( date ) ); +function assertWeek(expectedWeek, date) { + assert.eq(expectedWeek, week(date)); } // Sun Jan 1 1984 -assertWeek( 1, new Date(Date.UTC( 1984, 0, 1 )) ); +assertWeek(1, new Date(Date.UTC(1984, 0, 1))); // Mon Jan 2 1984 -assertWeek( 1, new Date(Date.UTC( 1984, 0, 2 )) ); +assertWeek(1, new Date(Date.UTC(1984, 0, 2))); // Sat Jan 7 1984 -assertWeek( 1, new Date(Date.UTC( 1984, 0, 7 )) ); +assertWeek(1, new Date(Date.UTC(1984, 0, 7))); // Sun Jan 8 1984 -assertWeek( 2, new Date(Date.UTC( 1984, 0, 8 )) ); +assertWeek(2, new Date(Date.UTC(1984, 0, 8))); // Sat Feb 18 1984 -assertWeek( 7, new Date(Date.UTC( 1984, 1, 18 )) ); +assertWeek(7, new Date(Date.UTC(1984, 1, 18))); // Sun Feb 19 1984 -assertWeek( 8, new Date(Date.UTC( 1984, 1, 19 )) ); +assertWeek(8, new Date(Date.UTC(1984, 1, 19))); // Mon Jan 1 2007 -assertWeek( 0, new Date(Date.UTC( 2007, 0, 1 )) ); +assertWeek(0, new Date(Date.UTC(2007, 0, 1))); // Tue Jan 2 2007 -assertWeek( 0, new Date(Date.UTC( 2007, 0, 2 )) ); +assertWeek(0, new Date(Date.UTC(2007, 0, 2))); // Sat Jan 6 2007 -assertWeek( 0, new Date(Date.UTC( 2007, 0, 6 )) ); +assertWeek(0, new Date(Date.UTC(2007, 0, 6))); // Sun Jan 7 2007 -assertWeek( 1, new Date(Date.UTC( 2007, 0, 7 )) ); +assertWeek(1, new Date(Date.UTC(2007, 0, 7))); // Mon Jan 8 2007 -assertWeek( 1, new Date(Date.UTC( 2007, 0, 8 )) ); +assertWeek(1, new Date(Date.UTC(2007, 0, 8))); // Sat Jan 13 2007 -assertWeek( 1, new Date(Date.UTC( 2007, 0, 13 )) ); +assertWeek(1, new Date(Date.UTC(2007, 0, 13))); // Sun Jan 14 2007 -assertWeek( 2, new Date(Date.UTC( 2007, 0, 14 )) ); +assertWeek(2, new Date(Date.UTC(2007, 0, 14))); // Sat Mar 3 2007 -assertWeek( 8, new Date(Date.UTC( 2007, 2, 3 )) ); +assertWeek(8, new Date(Date.UTC(2007, 2, 3))); // Sun Mar 4 2007 -assertWeek( 9, new Date(Date.UTC( 2007, 2, 4 )) ); +assertWeek(9, new Date(Date.UTC(2007, 2, 4))); // Tue Jan 1 2008 -assertWeek( 0, new Date(Date.UTC( 2008, 0, 1 )) ); +assertWeek(0, new Date(Date.UTC(2008, 0, 1))); // Sat Jan 5 2008 -assertWeek( 0, new Date(Date.UTC( 2008, 0, 5 )) ); +assertWeek(0, new Date(Date.UTC(2008, 0, 5))); // Sun Jan 6 2008 -assertWeek( 1, new Date(Date.UTC( 2008, 0, 6 )) ); +assertWeek(1, new Date(Date.UTC(2008, 0, 6))); // Sat Apr 26 2008 -assertWeek( 16, new Date(Date.UTC( 2008, 3, 26 )) ); +assertWeek(16, new Date(Date.UTC(2008, 3, 26))); // Sun Apr 27 2008 -assertWeek( 17, new Date(Date.UTC( 2008, 3, 27 )) ); +assertWeek(17, new Date(Date.UTC(2008, 3, 27))); // Wed Jan 1 2003 -assertWeek( 0, new Date(Date.UTC( 2003, 0, 1 )) ); +assertWeek(0, new Date(Date.UTC(2003, 0, 1))); // Sat Jan 4 2003 -assertWeek( 0, new Date(Date.UTC( 2003, 0, 4 )) ); +assertWeek(0, new Date(Date.UTC(2003, 0, 4))); // Sun Jan 5 2003 -assertWeek( 1, new Date(Date.UTC( 2003, 0, 5 )) ); +assertWeek(1, new Date(Date.UTC(2003, 0, 5))); // Sat Dec 27 2003 -assertWeek( 51, new Date(Date.UTC( 2003, 11, 27 )) ); +assertWeek(51, new Date(Date.UTC(2003, 11, 27))); // Sat Dec 28 2003 -assertWeek( 52, new Date(Date.UTC( 2003, 11, 28 )) ); +assertWeek(52, new Date(Date.UTC(2003, 11, 28))); // Thu Jan 1 2009 -assertWeek( 0, new Date(Date.UTC( 2009, 0, 1 )) ); +assertWeek(0, new Date(Date.UTC(2009, 0, 1))); // Sat Jan 3 2009 -assertWeek( 0, new Date(Date.UTC( 2009, 0, 3 )) ); +assertWeek(0, new Date(Date.UTC(2009, 0, 3))); // Sun Jan 4 2008 -assertWeek( 1, new Date(Date.UTC( 2009, 0, 4 )) ); +assertWeek(1, new Date(Date.UTC(2009, 0, 4))); // Sat Oct 31 2009 -assertWeek( 43, new Date(Date.UTC( 2009, 9, 31 )) ); +assertWeek(43, new Date(Date.UTC(2009, 9, 31))); // Sun Nov 1 2008 -assertWeek( 44, new Date(Date.UTC( 2009, 10, 1 )) ); +assertWeek(44, new Date(Date.UTC(2009, 10, 1))); // Fri Jan 1 2010 -assertWeek( 0, new Date(Date.UTC( 2010, 0, 1 )) ); +assertWeek(0, new Date(Date.UTC(2010, 0, 1))); // Sat Jan 2 2010 -assertWeek( 0, new Date(Date.UTC( 2010, 0, 2 )) ); +assertWeek(0, new Date(Date.UTC(2010, 0, 2))); // Sun Jan 3 2010 -assertWeek( 1, new Date(Date.UTC( 2010, 0, 3 )) ); +assertWeek(1, new Date(Date.UTC(2010, 0, 3))); // Sat Sept 18 2010 -assertWeek( 37, new Date(Date.UTC( 2010, 8, 18 )) ); +assertWeek(37, new Date(Date.UTC(2010, 8, 18))); // Sun Sept 19 2010 -assertWeek( 38, new Date(Date.UTC( 2010, 8, 19 )) ); +assertWeek(38, new Date(Date.UTC(2010, 8, 19))); // Sat Jan 1 2011 -assertWeek( 0, new Date(Date.UTC( 2011, 0, 1 )) ); +assertWeek(0, new Date(Date.UTC(2011, 0, 1))); // Sun Jan 2 2011 -assertWeek( 1, new Date(Date.UTC( 2011, 0, 2 )) ); +assertWeek(1, new Date(Date.UTC(2011, 0, 2))); // Sat Aug 20 2011 -assertWeek( 33, new Date(Date.UTC( 2011, 7, 20 )) ); +assertWeek(33, new Date(Date.UTC(2011, 7, 20))); // Sun Aug 21 2011 -assertWeek( 34, new Date(Date.UTC( 2011, 7, 21 )) ); - +assertWeek(34, new Date(Date.UTC(2011, 7, 21))); // Leap year tests. // Sat Feb 27 2016 -assertWeek( 8, new Date(Date.UTC( 2016, 1, 27 )) ); +assertWeek(8, new Date(Date.UTC(2016, 1, 27))); // Sun Feb 28 2016 -assertWeek( 9, new Date(Date.UTC( 2016, 1, 28 )) ); +assertWeek(9, new Date(Date.UTC(2016, 1, 28))); // Mon Feb 29 2016 -assertWeek( 9, new Date(Date.UTC( 2016, 1, 29 )) ); +assertWeek(9, new Date(Date.UTC(2016, 1, 29))); // Tue Mar 1 2016 -assertWeek( 9, new Date(Date.UTC( 2016, 2, 1 )) ); +assertWeek(9, new Date(Date.UTC(2016, 2, 1))); // Sat Feb 28 2032 -assertWeek( 8, new Date(Date.UTC( 2032, 1, 28 )) ); +assertWeek(8, new Date(Date.UTC(2032, 1, 28))); // Sun Feb 29 2032 -assertWeek( 9, new Date(Date.UTC( 2032, 1, 29 )) ); +assertWeek(9, new Date(Date.UTC(2032, 1, 29))); // Mon Mar 1 2032 -assertWeek( 9, new Date(Date.UTC( 2032, 2, 1 )) ); +assertWeek(9, new Date(Date.UTC(2032, 2, 1))); // Fri Feb 28 2020 -assertWeek( 8, new Date(Date.UTC( 2020, 1, 28 )) ); +assertWeek(8, new Date(Date.UTC(2020, 1, 28))); // Sat Feb 29 2020 -assertWeek( 8, new Date(Date.UTC( 2020, 1, 29 )) ); +assertWeek(8, new Date(Date.UTC(2020, 1, 29))); // Sun Mar 1 2020 -assertWeek( 9, new Date(Date.UTC( 2020, 2, 1 )) ); +assertWeek(9, new Date(Date.UTC(2020, 2, 1))); // Timestamp argument. -assertWeek( 1, new Timestamp( new Date(Date.UTC( 1984, 0, 1 )).getTime() / 1000, 0 ) ); -assertWeek( 1, new Timestamp( new Date(Date.UTC( 1984, 0, 1 )).getTime() / 1000, 1000000000 ) ); +assertWeek(1, new Timestamp(new Date(Date.UTC(1984, 0, 1)).getTime() / 1000, 0)); +assertWeek(1, new Timestamp(new Date(Date.UTC(1984, 0, 1)).getTime() / 1000, 1000000000)); // Numeric argument not allowed. assertErrorCode(t, {$project: {a: {$week: 5}}}, 16006); @@ -138,15 +139,16 @@ assertErrorCode(t, {$project: {a: {$week: 5}}}, 16006); assertErrorCode(t, {$project: {a: {$week: 'foo'}}}, 16006); // Array argument format. -assertWeek( 8, [ new Date(Date.UTC( 2016, 1, 27 )) ] ); +assertWeek(8, [new Date(Date.UTC(2016, 1, 27))]); // Wrong number of arguments. assertErrorCode(t, {$project: {a: {$week: []}}}, 16020); -assertErrorCode(t, {$project: {a: {$week: [new Date(Date.UTC(2020, 1, 28)), - new Date(Date.UTC(2020, 1, 29))]}}}, - 16020); +assertErrorCode( + t, + {$project: {a: {$week: [new Date(Date.UTC(2020, 1, 28)), new Date(Date.UTC(2020, 1, 29))]}}}, + 16020); // From a field path expression. t.remove({}); -t.save( { a:new Date(Date.UTC( 2020, 2, 1 )) } ); -assertWeek( 9, '$a' ); +t.save({a: new Date(Date.UTC(2020, 2, 1))}); +assertWeek(9, '$a'); diff --git a/jstests/aggregation/bugs/server6192_server6193.js b/jstests/aggregation/bugs/server6192_server6193.js index 370c55b5a1f..f453a1e7060 100644 --- a/jstests/aggregation/bugs/server6192_server6193.js +++ b/jstests/aggregation/bugs/server6192_server6193.js @@ -3,13 +3,10 @@ var t = db.jstests_aggregation_server6192; t.drop(); -t.save( {x: true} ); +t.save({x: true}); function assertOptimized(pipeline, v) { - var explained = t.runCommand("aggregate", { - pipeline: pipeline, - explain: true - }); + var explained = t.runCommand("aggregate", {pipeline: pipeline, explain: true}); printjson({input: pipeline, output: explained}); @@ -20,10 +17,7 @@ function assertOptimized(pipeline, v) { } function assertNotOptimized(pipeline) { - var explained = t.runCommand("aggregate", { - pipeline: pipeline, - explain: true - }); + var explained = t.runCommand("aggregate", {pipeline: pipeline, explain: true}); printjson({input: pipeline, output: explained}); @@ -34,28 +28,27 @@ function assertNotOptimized(pipeline) { } // short-circuiting for $and -assertOptimized([ {$project: {a: {$and: [0, '$x']}}} ], false); -assertOptimized([ {$project: {a: {$and: [0, 1, '$x']}}} ], false); -assertOptimized([ {$project: {a: {$and: [0, 1, '', '$x']}}} ], false); +assertOptimized([{$project: {a: {$and: [0, '$x']}}}], false); +assertOptimized([{$project: {a: {$and: [0, 1, '$x']}}}], false); +assertOptimized([{$project: {a: {$and: [0, 1, '', '$x']}}}], false); -assertOptimized([ {$project: {a: {$and: [1, 0, '$x']}}} ], false); -assertOptimized([ {$project: {a: {$and: [1, '', 0, '$x']}}} ], false); -assertOptimized([ {$project: {a: {$and: [1, 1, 0, 1]}}} ], false); +assertOptimized([{$project: {a: {$and: [1, 0, '$x']}}}], false); +assertOptimized([{$project: {a: {$and: [1, '', 0, '$x']}}}], false); +assertOptimized([{$project: {a: {$and: [1, 1, 0, 1]}}}], false); // short-circuiting for $or -assertOptimized([ {$project: {a: {$or: [1, '$x']}}} ], true); -assertOptimized([ {$project: {a: {$or: [1, 0, '$x']}}} ], true); -assertOptimized([ {$project: {a: {$or: [1, '', '$x']}}} ], true); +assertOptimized([{$project: {a: {$or: [1, '$x']}}}], true); +assertOptimized([{$project: {a: {$or: [1, 0, '$x']}}}], true); +assertOptimized([{$project: {a: {$or: [1, '', '$x']}}}], true); -assertOptimized([ {$project: {a: {$or: [0, 1, '$x']}}} ], true); -assertOptimized([ {$project: {a: {$or: ['', 0, 1, '$x']}}} ], true); -assertOptimized([ {$project: {a: {$or: [0, 0, 0, 1]}}} ], true); +assertOptimized([{$project: {a: {$or: [0, 1, '$x']}}}], true); +assertOptimized([{$project: {a: {$or: ['', 0, 1, '$x']}}}], true); +assertOptimized([{$project: {a: {$or: [0, 0, 0, 1]}}}], true); // examples that should not short-circuit -assertNotOptimized([ {$project: {a: {$and: [1, '$x']}}} ]); -assertNotOptimized([ {$project: {a: {$or: [0, '$x']}}} ]); -assertNotOptimized([ {$project: {a: {$and: ['$x', '$x']}}} ]); -assertNotOptimized([ {$project: {a: {$or: ['$x', '$x']}}} ]); -assertNotOptimized([ {$project: {a: {$and: ['$x']}}} ]); -assertNotOptimized([ {$project: {a: {$or: ['$x']}}} ]); - +assertNotOptimized([{$project: {a: {$and: [1, '$x']}}}]); +assertNotOptimized([{$project: {a: {$or: [0, '$x']}}}]); +assertNotOptimized([{$project: {a: {$and: ['$x', '$x']}}}]); +assertNotOptimized([{$project: {a: {$or: ['$x', '$x']}}}]); +assertNotOptimized([{$project: {a: {$and: ['$x']}}}]); +assertNotOptimized([{$project: {a: {$or: ['$x']}}}]); diff --git a/jstests/aggregation/bugs/server6194.js b/jstests/aggregation/bugs/server6194.js index c0c72decd82..53c23f60c1f 100644 --- a/jstests/aggregation/bugs/server6194.js +++ b/jstests/aggregation/bugs/server6194.js @@ -2,8 +2,10 @@ c = db.c; c.drop(); -c.save( { x:'3' } ); +c.save({x: '3'}); -project = { $project:{ a:{ $concat:[ '1', { $concat:[ 'foo', '$x', 'bar' ] }, '2' ] } } }; +project = { + $project: {a: {$concat: ['1', {$concat: ['foo', '$x', 'bar']}, '2']}} +}; -assert.eq( '1foo3bar2', c.aggregate( project ).toArray()[ 0 ].a ); +assert.eq('1foo3bar2', c.aggregate(project).toArray()[0].a); diff --git a/jstests/aggregation/bugs/server6195.js b/jstests/aggregation/bugs/server6195.js index 72e0054b4fb..cca80a14ad5 100644 --- a/jstests/aggregation/bugs/server6195.js +++ b/jstests/aggregation/bugs/server6195.js @@ -4,32 +4,35 @@ load('jstests/aggregation/extras/utils.js'); c = db.s6570; c.drop(); -c.save({v:"$", w:".", x:"foo", y:"bar"}); +c.save({v: "$", w: ".", x: "foo", y: "bar"}); -assert.eq(c.aggregate({$project:{str:{$concat:["X", "$x", "Y", "$y"]}}}).toArray()[0].str, "XfooYbar"); -assert.eq(c.aggregate({$project:{str:{$concat:["$v", "X", "$w", "Y"]}}}).toArray()[0].str, "$X.Y"); -assert.eq(c.aggregate({$project:{str:{$concat:["$w", "X", "$v", "Y"]}}}).toArray()[0].str, ".X$Y"); +assert.eq(c.aggregate({$project: {str: {$concat: ["X", "$x", "Y", "$y"]}}}).toArray()[0].str, + "XfooYbar"); +assert.eq(c.aggregate({$project: {str: {$concat: ["$v", "X", "$w", "Y"]}}}).toArray()[0].str, + "$X.Y"); +assert.eq(c.aggregate({$project: {str: {$concat: ["$w", "X", "$v", "Y"]}}}).toArray()[0].str, + ".X$Y"); // Nullish (both with and without other strings) -assert.isnull(c.aggregate({$project:{str:{$concat: ["$missing"] }}}).toArray()[0].str); -assert.isnull(c.aggregate({$project:{str:{$concat: [null] }}}).toArray()[0].str); -assert.isnull(c.aggregate({$project:{str:{$concat: [undefined] }}}).toArray()[0].str); -assert.isnull(c.aggregate({$project:{str:{$concat: ["$x", "$missing", "$y"] }}}).toArray()[0].str); -assert.isnull(c.aggregate({$project:{str:{$concat: ["$x", null, "$y"] }}}).toArray()[0].str); -assert.isnull(c.aggregate({$project:{str:{$concat: ["$x", undefined, "$y"] }}}).toArray()[0].str); +assert.isnull(c.aggregate({$project: {str: {$concat: ["$missing"]}}}).toArray()[0].str); +assert.isnull(c.aggregate({$project: {str: {$concat: [null]}}}).toArray()[0].str); +assert.isnull(c.aggregate({$project: {str: {$concat: [undefined]}}}).toArray()[0].str); +assert.isnull(c.aggregate({$project: {str: {$concat: ["$x", "$missing", "$y"]}}}).toArray()[0].str); +assert.isnull(c.aggregate({$project: {str: {$concat: ["$x", null, "$y"]}}}).toArray()[0].str); +assert.isnull(c.aggregate({$project: {str: {$concat: ["$x", undefined, "$y"]}}}).toArray()[0].str); // assert fail for all other types -assertErrorCode(c, {$project:{str:{$concat: [MinKey]}}}, 16702); -assertErrorCode(c, {$project:{str:{$concat: [1]}}}, 16702); -assertErrorCode(c, {$project:{str:{$concat: [NumberInt(1)]}}}, 16702); -assertErrorCode(c, {$project:{str:{$concat: [NumberLong(1)]}}}, 16702); -assertErrorCode(c, {$project:{str:{$concat: [true]}}}, 16702); -assertErrorCode(c, {$project:{str:{$concat: [function(){}]}}}, 16702); -assertErrorCode(c, {$project:{str:{$concat: [{}]}}}, 16702); -assertErrorCode(c, {$project:{str:{$concat: [[]]}}}, 16702); -assertErrorCode(c, {$project:{str:{$concat: [new Timestamp(0,0)]}}}, 16702); -assertErrorCode(c, {$project:{str:{$concat: [new Date(0)]}}}, 16702); -assertErrorCode(c, {$project:{str:{$concat: [new BinData(0,"")]}}}, 16702); -assertErrorCode(c, {$project:{str:{$concat: [/asdf/]}}}, 16702); -assertErrorCode(c, {$project:{str:{$concat: [MaxKey]}}}, 16702); -assertErrorCode(c, {$project:{str:{$concat: [new ObjectId()]}}}, 16702); +assertErrorCode(c, {$project: {str: {$concat: [MinKey]}}}, 16702); +assertErrorCode(c, {$project: {str: {$concat: [1]}}}, 16702); +assertErrorCode(c, {$project: {str: {$concat: [NumberInt(1)]}}}, 16702); +assertErrorCode(c, {$project: {str: {$concat: [NumberLong(1)]}}}, 16702); +assertErrorCode(c, {$project: {str: {$concat: [true]}}}, 16702); +assertErrorCode(c, {$project: {str: {$concat: [function(){}]}}}, 16702); +assertErrorCode(c, {$project: {str: {$concat: [{}]}}}, 16702); +assertErrorCode(c, {$project: {str: {$concat: [[]]}}}, 16702); +assertErrorCode(c, {$project: {str: {$concat: [new Timestamp(0, 0)]}}}, 16702); +assertErrorCode(c, {$project: {str: {$concat: [new Date(0)]}}}, 16702); +assertErrorCode(c, {$project: {str: {$concat: [new BinData(0, "")]}}}, 16702); +assertErrorCode(c, {$project: {str: {$concat: [/asdf/]}}}, 16702); +assertErrorCode(c, {$project: {str: {$concat: [MaxKey]}}}, 16702); +assertErrorCode(c, {$project: {str: {$concat: [new ObjectId()]}}}, 16702); diff --git a/jstests/aggregation/bugs/server6198.js b/jstests/aggregation/bugs/server6198.js index 5371c1fc221..2d38853f72e 100644 --- a/jstests/aggregation/bugs/server6198.js +++ b/jstests/aggregation/bugs/server6198.js @@ -3,4 +3,4 @@ load('jstests/aggregation/extras/utils.js'); db.server6198.drop(); -assertErrorCode(db.server6198, {$group:{_id:null, "bar.baz": {$addToSet: "$foo"}}}, 16414); +assertErrorCode(db.server6198, {$group: {_id: null, "bar.baz": {$addToSet: "$foo"}}}, 16414); diff --git a/jstests/aggregation/bugs/server6238.js b/jstests/aggregation/bugs/server6238.js index 0d1589f09f0..cd014219f47 100644 --- a/jstests/aggregation/bugs/server6238.js +++ b/jstests/aggregation/bugs/server6238.js @@ -4,12 +4,12 @@ load('jstests/aggregation/extras/utils.js'); c = db.c; c.drop(); -c.insert({a:1}); +c.insert({a: 1}); // assert that we get the proper error in both $project and $group -assertErrorCode(c, {$project:{$a:"$a"}}, 16404); -assertErrorCode(c, {$project:{a:{$b: "$a"}}}, 15999); -assertErrorCode(c, {$project:{a:{"$b": "$a"}}}, 15999); -assertErrorCode(c, {$project:{'a.$b':"$a"}}, 16410); -assertErrorCode(c, {$group:{_id: "$_id", $a:"$a"}}, 15950); -assertErrorCode(c, {$group:{_id: {$a:"$a"}}}, 15999); +assertErrorCode(c, {$project: {$a: "$a"}}, 16404); +assertErrorCode(c, {$project: {a: {$b: "$a"}}}, 15999); +assertErrorCode(c, {$project: {a: {"$b": "$a"}}}, 15999); +assertErrorCode(c, {$project: {'a.$b': "$a"}}, 16410); +assertErrorCode(c, {$group: {_id: "$_id", $a: "$a"}}, 15950); +assertErrorCode(c, {$group: {_id: {$a: "$a"}}}, 15999); diff --git a/jstests/aggregation/bugs/server6239.js b/jstests/aggregation/bugs/server6239.js index d0e3be12816..f9cf35c1ea2 100644 --- a/jstests/aggregation/bugs/server6239.js +++ b/jstests/aggregation/bugs/server6239.js @@ -10,7 +10,7 @@ var num = 54312; db.s6239.drop(); // Populate db -db.s6239.save({date:new Date(millis), num: num}); +db.s6239.save({date: new Date(millis), num: num}); function test(expression, expected) { var res = db.s6239.aggregate({$project: {out: expression}}); diff --git a/jstests/aggregation/bugs/server6240.js b/jstests/aggregation/bugs/server6240.js index 0a13780761a..e3c59e0c649 100644 --- a/jstests/aggregation/bugs/server6240.js +++ b/jstests/aggregation/bugs/server6240.js @@ -20,33 +20,20 @@ load('jstests/aggregation/extras/utils.js'); db.s6240.drop(); // Populate db -db.s6240.save({date:new Date()}); +db.s6240.save({date: new Date()}); // Aggregate using a date value in various math operations // Add -assertErrorCode(db.s6240, - {$project: {add: {$add: ["$date", "$date"]}}}, - 16612); - +assertErrorCode(db.s6240, {$project: {add: {$add: ["$date", "$date"]}}}, 16612); // Divide -assertErrorCode(db.s6240, - {$project: {divide: {$divide: ["$date", 2]}}}, - 16609); +assertErrorCode(db.s6240, {$project: {divide: {$divide: ["$date", 2]}}}, 16609); // Mod -assertErrorCode(db.s6240, - {$project: {mod: {$mod: ["$date", 2]}}}, - 16611); - +assertErrorCode(db.s6240, {$project: {mod: {$mod: ["$date", 2]}}}, 16611); // Multiply -assertErrorCode(db.s6240, - {$project: {multiply: {$multiply: ["$date", 2]}}}, - 16555); - +assertErrorCode(db.s6240, {$project: {multiply: {$multiply: ["$date", 2]}}}, 16555); // Subtract -assertErrorCode(db.s6240, - {$project: {subtract: {$subtract: [2, "$date"]}}}, - 16556); +assertErrorCode(db.s6240, {$project: {subtract: {$subtract: [2, "$date"]}}}, 16556); diff --git a/jstests/aggregation/bugs/server6269.js b/jstests/aggregation/bugs/server6269.js index 181eaa6835f..c92245f6198 100644 --- a/jstests/aggregation/bugs/server6269.js +++ b/jstests/aggregation/bugs/server6269.js @@ -3,12 +3,11 @@ c = db.jstests_aggregation_server6269; c.drop(); -c.save( { _id:0, a:[ 1, 2, 3 ] } ); +c.save({_id: 0, a: [1, 2, 3]}); // The unwound a:1 document is skipped, but the remainder are returned. -assert.eq( [ { _id:0, a:2 }, { _id:0, a:3 } ], - c.aggregate( { $unwind:'$a' }, { $skip:1 } ).toArray() ); +assert.eq([{_id: 0, a: 2}, {_id: 0, a: 3}], c.aggregate({$unwind: '$a'}, {$skip: 1}).toArray()); // Test with two documents. -c.save( { _id:1, a:[ 4, 5, 6 ] } ); -assert.eq( [ { _id:0, a:3 }, { _id:1, a:4 }, { _id:1, a:5 }, { _id:1, a:6 } ], - c.aggregate( { $unwind:'$a' }, { $skip:2 } ).toArray() ); +c.save({_id: 1, a: [4, 5, 6]}); +assert.eq([{_id: 0, a: 3}, {_id: 1, a: 4}, {_id: 1, a: 5}, {_id: 1, a: 6}], + c.aggregate({$unwind: '$a'}, {$skip: 2}).toArray()); diff --git a/jstests/aggregation/bugs/server6275.js b/jstests/aggregation/bugs/server6275.js index a021f7a4af8..39feeb2552e 100644 --- a/jstests/aggregation/bugs/server6275.js +++ b/jstests/aggregation/bugs/server6275.js @@ -1,14 +1,14 @@ // confirm that undefined no longer counts as 0 in $avg c = db.c; c.drop(); -c.save({a:1}); -c.save({a:4}); -c.save({b:1}); -assert.eq(c.aggregate({$group:{_id: null, avg:{$avg:"$a"}}}).toArray()[0].avg, 2.5); +c.save({a: 1}); +c.save({a: 4}); +c.save({b: 1}); +assert.eq(c.aggregate({$group: {_id: null, avg: {$avg: "$a"}}}).toArray()[0].avg, 2.5); // again ensuring numberLongs work properly c.drop(); -c.save({a:NumberLong(1)}); -c.save({a:NumberLong(4)}); -c.save({b:NumberLong(1)}); -assert.eq(c.aggregate({$group:{_id: null, avg:{$avg:"$a"}}}).toArray()[0].avg, 2.5); +c.save({a: NumberLong(1)}); +c.save({a: NumberLong(4)}); +c.save({b: NumberLong(1)}); +assert.eq(c.aggregate({$group: {_id: null, avg: {$avg: "$a"}}}).toArray()[0].avg, 2.5); diff --git a/jstests/aggregation/bugs/server6290.js b/jstests/aggregation/bugs/server6290.js index c27cdc454bd..a9bbd65db77 100644 --- a/jstests/aggregation/bugs/server6290.js +++ b/jstests/aggregation/bugs/server6290.js @@ -6,22 +6,22 @@ load('jstests/aggregation/extras/utils.js'); var t = db.jstests_aggregation_server6290; t.drop(); -t.save( {} ); +t.save({}); // code 15999: invalid operator var error = 15999; // $isoDate is an invalid operator. -assertErrorCode(t, {$project:{ a:{ $isoDate:[ { year:1 } ] } } }, error); +assertErrorCode(t, {$project: {a: {$isoDate: [{year: 1}]}}}, error); // $date is an invalid operator. -assertErrorCode(t, { $project:{ a:{ $date:[ { year:1 } ] } } }, error); +assertErrorCode(t, {$project: {a: {$date: [{year: 1}]}}}, error); // Alternative operands. -assertErrorCode(t, { $project:{ a:{ $isoDate:[] } } }, error); -assertErrorCode(t, { $project:{ a:{ $date:[] } } }, error); -assertErrorCode(t, { $project:{ a:{ $isoDate:'foo' } } }, error); -assertErrorCode(t, { $project:{ a:{ $date:'foo' } } }, error); +assertErrorCode(t, {$project: {a: {$isoDate: []}}}, error); +assertErrorCode(t, {$project: {a: {$date: []}}}, error); +assertErrorCode(t, {$project: {a: {$isoDate: 'foo'}}}, error); +assertErrorCode(t, {$project: {a: {$date: 'foo'}}}, error); // Test with $group. -assertErrorCode(t, { $group:{ _id:0, a:{ $first:{ $isoDate:[ { year:1 } ] } } } }, error); -assertErrorCode(t, { $group:{ _id:0, a:{ $first:{ $date:[ { year:1 } ] } } } }, error); +assertErrorCode(t, {$group: {_id: 0, a: {$first: {$isoDate: [{year: 1}]}}}}, error); +assertErrorCode(t, {$group: {_id: 0, a: {$first: {$date: [{year: 1}]}}}}, error); diff --git a/jstests/aggregation/bugs/server6335.js b/jstests/aggregation/bugs/server6335.js index b4569f1b6b1..a26568280ce 100644 --- a/jstests/aggregation/bugs/server6335.js +++ b/jstests/aggregation/bugs/server6335.js @@ -4,5 +4,4 @@ load('jstests/aggregation/extras/utils.js'); assertErrorCode(db.foo, {$match: {$where: "return true"}}, 16395); -assertErrorCode(db.foo, {$match: {$and:[{$where: "return true"}]}}, 16395); - +assertErrorCode(db.foo, {$match: {$and: [{$where: "return true"}]}}, 16395); diff --git a/jstests/aggregation/bugs/server6361.js b/jstests/aggregation/bugs/server6361.js index 86eddd2b4e8..873c08f43da 100644 --- a/jstests/aggregation/bugs/server6361.js +++ b/jstests/aggregation/bugs/server6361.js @@ -6,22 +6,22 @@ load('jstests/aggregation/extras/utils.js'); c = db.c; c.drop(); -c.insert({a:2, nested: {_id:2, other:2}}); -assertErrorCode(c, {$project: {a:0}}, 16406); +c.insert({a: 2, nested: {_id: 2, other: 2}}); +assertErrorCode(c, {$project: {a: 0}}, 16406); // excluding top-level _id is still allowed -res = c.aggregate({$project: {_id:0, a:1}}); -assert.eq(res.toArray()[0], {a:2}); +res = c.aggregate({$project: {_id: 0, a: 1}}); +assert.eq(res.toArray()[0], {a: 2}); // excluding nested _id is not -assertErrorCode(c, {$project: {'nested._id':0}}, 16406); +assertErrorCode(c, {$project: {'nested._id': 0}}, 16406); // nested _id is not automatically included -res = c.aggregate({$project: {_id:0, 'nested.other':1}}); -assert.eq(res.toArray()[0], {nested: {other:2}}); +res = c.aggregate({$project: {_id: 0, 'nested.other': 1}}); +assert.eq(res.toArray()[0], {nested: {other: 2}}); // not including anything is an error assertErrorCode(c, {$project: {}}, 16403); // even if you exclude _id -assertErrorCode(c, {$project: {'_id':0}}, 16403); +assertErrorCode(c, {$project: {'_id': 0}}, 16403); diff --git a/jstests/aggregation/bugs/server6468.js b/jstests/aggregation/bugs/server6468.js index aea9586973b..09515c746fa 100644 --- a/jstests/aggregation/bugs/server6468.js +++ b/jstests/aggregation/bugs/server6468.js @@ -2,7 +2,7 @@ c = db.c; c.drop(); -c.save( { a:'foo', b:{ c:'bar', z:'not there' } } ); +c.save({a: 'foo', b: {c: 'bar', z: 'not there'}}); function test(projection) { res = c.aggregate({$project: projection}); @@ -10,7 +10,7 @@ function test(projection) { } // These should all mean the same thing -test({_id:0, 'b.c':1}); -test({_id:0, 'b.c':'$b.c'}); -test({_id:0, b: {c:1}}); -test({_id:0, b: {c:'$b.c'}}); +test({_id: 0, 'b.c': 1}); +test({_id: 0, 'b.c': '$b.c'}); +test({_id: 0, b: {c: 1}}); +test({_id: 0, b: {c: '$b.c'}}); diff --git a/jstests/aggregation/bugs/server6529.js b/jstests/aggregation/bugs/server6529.js index a016f9123d1..1bc4119c547 100644 --- a/jstests/aggregation/bugs/server6529.js +++ b/jstests/aggregation/bugs/server6529.js @@ -4,18 +4,25 @@ load('jstests/aggregation/extras/utils.js'); c = db.s6529; c.drop(); -c.save({a:{b:{c:{d:{e:{f:{g:19}}}}}}}); +c.save({a: {b: {c: {d: {e: {f: {g: 19}}}}}}}); // bad project -assertErrorCode(c, {$project:{foo:{$add:[{b:1}]}}}, 16420); +assertErrorCode(c, {$project: {foo: {$add: [{b: 1}]}}}, 16420); // $group shouldnt allow numeric inclusions -assertErrorCode(c, {$group:{_id: {a:1}}}, 17390); +assertErrorCode(c, {$group: {_id: {a: 1}}}, 17390); // but any amount of nesting in a project should work -assert.eq(c.aggregate({$project:{_id:0, a:{b:{c:{d:{e:{f:{g:1}}}}}}}}).toArray(), [{a:{b:{c:{d:{e:{f:{g:19}}}}}}}]); -assert.eq(c.aggregate({$project:{_id:0, a:{b:{c:{d:{e:{f:1}}}}}}}).toArray(), [{a:{b:{c:{d:{e:{f:{g:19}}}}}}}]); -assert.eq(c.aggregate({$project:{_id:0, a:{b:{c:{d:{e:1}}}}}}).toArray(), [{a:{b:{c:{d:{e:{f:{g:19}}}}}}}]); -assert.eq(c.aggregate({$project:{_id:0, a:{b:{c:{d:1}}}}}).toArray(), [{a:{b:{c:{d:{e:{f:{g:19}}}}}}}]); -assert.eq(c.aggregate({$project:{_id:0, a:{b:{c:1}}}}).toArray(), [{a:{b:{c:{d:{e:{f:{g:19}}}}}}}]); -assert.eq(c.aggregate({$project:{_id:0, a:{b:1}}}).toArray(), [{a:{b:{c:{d:{e:{f:{g:19}}}}}}}]); -assert.eq(c.aggregate({$project:{_id:0, a:1}}).toArray(), [{a:{b:{c:{d:{e:{f:{g:19}}}}}}}]); +assert.eq(c.aggregate({$project: {_id: 0, a: {b: {c: {d: {e: {f: {g: 1}}}}}}}}).toArray(), + [{a: {b: {c: {d: {e: {f: {g: 19}}}}}}}]); +assert.eq(c.aggregate({$project: {_id: 0, a: {b: {c: {d: {e: {f: 1}}}}}}}).toArray(), + [{a: {b: {c: {d: {e: {f: {g: 19}}}}}}}]); +assert.eq(c.aggregate({$project: {_id: 0, a: {b: {c: {d: {e: 1}}}}}}).toArray(), + [{a: {b: {c: {d: {e: {f: {g: 19}}}}}}}]); +assert.eq(c.aggregate({$project: {_id: 0, a: {b: {c: {d: 1}}}}}).toArray(), + [{a: {b: {c: {d: {e: {f: {g: 19}}}}}}}]); +assert.eq(c.aggregate({$project: {_id: 0, a: {b: {c: 1}}}}).toArray(), + [{a: {b: {c: {d: {e: {f: {g: 19}}}}}}}]); +assert.eq(c.aggregate({$project: {_id: 0, a: {b: 1}}}).toArray(), + [{a: {b: {c: {d: {e: {f: {g: 19}}}}}}}]); +assert.eq(c.aggregate({$project: {_id: 0, a: 1}}).toArray(), + [{a: {b: {c: {d: {e: {f: {g: 19}}}}}}}]); diff --git a/jstests/aggregation/bugs/server6530.js b/jstests/aggregation/bugs/server6530.js index eb69516255f..de2ec9c0912 100644 --- a/jstests/aggregation/bugs/server6530.js +++ b/jstests/aggregation/bugs/server6530.js @@ -1,5 +1,5 @@ // server-6530: disallow $near queries in $match operations load('jstests/aggregation/extras/utils.js'); -assertErrorCode(db.foo, {$match: {$near: [0,0]}}, 16424); -assertErrorCode(db.foo, {$match: {$nearSphere: [2,2]}}, 16426); +assertErrorCode(db.foo, {$match: {$near: [0, 0]}}, 16424); +assertErrorCode(db.foo, {$match: {$nearSphere: [2, 2]}}, 16426); diff --git a/jstests/aggregation/bugs/server6531.js b/jstests/aggregation/bugs/server6531.js index 6cd74c104be..7d117ce6905 100644 --- a/jstests/aggregation/bugs/server6531.js +++ b/jstests/aggregation/bugs/server6531.js @@ -3,16 +3,20 @@ c = db.s6531; c.drop(); -for (var x=0; x < 10; x++) { - for (var y=0; y < 10; y++) { - c.insert({loc: [x,y]}); +for (var x = 0; x < 10; x++) { + for (var y = 0; y < 10; y++) { + c.insert({loc: [x, y]}); } } function test(variant) { - query = {loc: {$within: {$center: [[5,5], 3]}}}; - sort = {_id: 1}; - aggOut = c.aggregate({$match:query}, {$sort: sort}); + query = { + loc: {$within: {$center: [[5, 5], 3]}} + }; + sort = { + _id: 1 + }; + aggOut = c.aggregate({$match: query}, {$sort: sort}); cursor = c.find(query).sort(sort); assert.eq(aggOut.toArray(), cursor.toArray()); @@ -20,9 +24,9 @@ function test(variant) { test("no index"); -c.ensureIndex({loc:"2d"}); +c.ensureIndex({loc: "2d"}); test("2d index"); -c.dropIndex({loc:"2d"}); -c.ensureIndex({loc:"2dsphere"}); +c.dropIndex({loc: "2d"}); +c.ensureIndex({loc: "2dsphere"}); test("2dsphere index"); diff --git a/jstests/aggregation/bugs/server6556.js b/jstests/aggregation/bugs/server6556.js index 65a78e714b9..721b9fd5a98 100644 --- a/jstests/aggregation/bugs/server6556.js +++ b/jstests/aggregation/bugs/server6556.js @@ -3,17 +3,22 @@ c = db.s6556; c.drop(); -c.save({foo:"as\0df"}); +c.save({foo: "as\0df"}); // compare the whole string, they should match -assert.eq(c.aggregate({$project: {_id: 0, matches: {$eq:["as\0df", "$foo"]}}}).toArray(), [{matches:true}]); +assert.eq(c.aggregate({$project: {_id: 0, matches: {$eq: ["as\0df", "$foo"]}}}).toArray(), + [{matches: true}]); // compare with the substring containing only the up to the null, they should not match -assert.eq(c.aggregate({$project: {_id: 0, matches: {$eq:["as\0df", {$substr:["$foo",0,3]}]}}}).toArray(), [{matches:false}]); +assert.eq(c.aggregate({$project: {_id: 0, matches: {$eq: ["as\0df", {$substr: ["$foo", 0, 3]}]}}}) + .toArray(), + [{matches: false}]); // partial the other way shouldnt work either -assert.eq(c.aggregate({$project: {_id: 0, matches: {$eq:["as", "$foo"]}}}).toArray(), [{matches:false}]); +assert.eq(c.aggregate({$project: {_id: 0, matches: {$eq: ["as", "$foo"]}}}).toArray(), + [{matches: false}]); // neither should one that differs after the null -assert.eq(c.aggregate({$project: {_id: 0, matches: {$eq:["as\0de", "$foo"]}}}).toArray(), [{matches:false}]); +assert.eq(c.aggregate({$project: {_id: 0, matches: {$eq: ["as\0de", "$foo"]}}}).toArray(), + [{matches: false}]); // should assert on fieldpaths with a null -assert.throws( function() { - c.aggregate({$project: {_id: 0, matches: {$eq:["as\0df", "$f\0oo"]}}}); +assert.throws(function() { + c.aggregate({$project: {_id: 0, matches: {$eq: ["as\0df", "$f\0oo"]}}}); }); diff --git a/jstests/aggregation/bugs/server6570.js b/jstests/aggregation/bugs/server6570.js index aef1e75346d..bb58cf0ce84 100644 --- a/jstests/aggregation/bugs/server6570.js +++ b/jstests/aggregation/bugs/server6570.js @@ -3,12 +3,12 @@ load('jstests/aggregation/extras/utils.js'); c = db.s6570; c.drop(); -c.save({x:17, y:"foo"}); +c.save({x: 17, y: "foo"}); -assertErrorCode(c, {$project:{string_fields : { $add:[3, "$y", 4, "$y"] }}}, 16554); -assertErrorCode(c, {$project:{number_fields : { $add:["a", "$x", "b", "$x"] }}}, 16554); -assertErrorCode(c, {$project:{all_strings : { $add:["c", "$y", "d", "$y"] }}}, 16554); -assertErrorCode(c, {$project:{potpourri_1 : { $add:[5, "$y", "e", "$x"] }}}, 16554); -assertErrorCode(c, {$project:{potpourri_2 : { $add:[6, "$x", "f", "$y"] }}}, 16554); -assertErrorCode(c, {$project:{potpourri_3 : { $add:["g", "$y", 7, "$x"] }}}, 16554); -assertErrorCode(c, {$project:{potpourri_4 : { $add:["h", "$x", 8, "$y"] }}}, 16554); +assertErrorCode(c, {$project: {string_fields: {$add: [3, "$y", 4, "$y"]}}}, 16554); +assertErrorCode(c, {$project: {number_fields: {$add: ["a", "$x", "b", "$x"]}}}, 16554); +assertErrorCode(c, {$project: {all_strings: {$add: ["c", "$y", "d", "$y"]}}}, 16554); +assertErrorCode(c, {$project: {potpourri_1: {$add: [5, "$y", "e", "$x"]}}}, 16554); +assertErrorCode(c, {$project: {potpourri_2: {$add: [6, "$x", "f", "$y"]}}}, 16554); +assertErrorCode(c, {$project: {potpourri_3: {$add: ["g", "$y", 7, "$x"]}}}, 16554); +assertErrorCode(c, {$project: {potpourri_4: {$add: ["h", "$x", 8, "$y"]}}}, 16554); diff --git a/jstests/aggregation/bugs/server6779.js b/jstests/aggregation/bugs/server6779.js index e9e4cc25f92..e3b8aaeca08 100644 --- a/jstests/aggregation/bugs/server6779.js +++ b/jstests/aggregation/bugs/server6779.js @@ -4,14 +4,14 @@ function test(op, val) { t = db.server6779; t.drop(); - t.insert({a:true}); - t.insert({a:false}); + t.insert({a: true}); + t.insert({a: false}); obj = {}; obj[op] = ['$a', val]; result = t.aggregate({$project: {_id: 0, bool: obj}}); - assert.eq(result.toArray(), [{bool:true}, {bool:false}]); + assert.eq(result.toArray(), [{bool: true}, {bool: false}]); } test('$and', true); test('$or', false); diff --git a/jstests/aggregation/bugs/server6861.js b/jstests/aggregation/bugs/server6861.js index 4cce3effc6e..28d19445241 100644 --- a/jstests/aggregation/bugs/server6861.js +++ b/jstests/aggregation/bugs/server6861.js @@ -5,23 +5,23 @@ load('jstests/aggregation/extras/utils.js'); t = db.jstests_server6861; t.drop(); -t.save( { a:1 } ); +t.save({a: 1}); -function assertCode( code, expression ) { +function assertCode(code, expression) { assertErrorCode(t, expression, code); } -function assertResult( result, expression ) { - assert.eq( result, t.aggregate( expression ).toArray() ); +function assertResult(result, expression) { + assert.eq(result, t.aggregate(expression).toArray()); } // Correct number of fields. -assertResult( [ { a:1 } ], { $project:{ _id:0, a:1 } } ); +assertResult([{a: 1}], {$project: {_id: 0, a: 1}}); // Incorrect number of fields. -assertCode( 16435, {} ); -assertCode( 16435, { $project:{ _id:0, a:1 }, $group:{ _id:0 } } ); -assertCode( 16435, { $project:{ _id:0, a:1 }, $group:{ _id:0 }, $sort:{ a:1 } } ); +assertCode(16435, {}); +assertCode(16435, {$project: {_id: 0, a: 1}, $group: {_id: 0}}); +assertCode(16435, {$project: {_id: 0, a: 1}, $group: {_id: 0}, $sort: {a: 1}}); // Invalid stage specification. -assertCode( 16436, { $noSuchStage:{ a:1 } } ); +assertCode(16436, {$noSuchStage: {a: 1}}); diff --git a/jstests/aggregation/bugs/server7768.js b/jstests/aggregation/bugs/server7768.js index a6c96d8f912..a820dd7526e 100644 --- a/jstests/aggregation/bugs/server7768.js +++ b/jstests/aggregation/bugs/server7768.js @@ -1,12 +1,13 @@ // SEVER-7768 aggregate cmd shouldn't fail when $readPreference is specified collection = 'server7768'; db[collection].drop(); -db[collection].insert({foo:1}); +db[collection].insert({foo: 1}); // Can't use aggregate helper here because we need to add $readPreference flag -res = db.runCommand({ 'aggregate': collection - , 'pipeline': [{'$project': {'_id': false, 'foo': true}}] - , $readPreference: {'mode': 'primary'} - }); +res = db.runCommand({ + 'aggregate': collection, + 'pipeline': [{'$project': {'_id': false, 'foo': true}}], + $readPreference: {'mode': 'primary'} +}); assert.commandWorked(res); -assert.eq(res.result, [{foo:1}]); +assert.eq(res.result, [{foo: 1}]); diff --git a/jstests/aggregation/bugs/server7781.js b/jstests/aggregation/bugs/server7781.js index 4d2c3c1a3fa..230a8a64c9f 100644 --- a/jstests/aggregation/bugs/server7781.js +++ b/jstests/aggregation/bugs/server7781.js @@ -1,149 +1,169 @@ // SERVER-7781 $geoNear pipeline stage (function() { -load('jstests/libs/geo_near_random.js'); -load('jstests/aggregation/extras/utils.js'); - -var coll = 'server7781'; - -db[coll].drop(); -db[coll].insert({loc:[0,0]}); - -// $geoNear is only allowed as the first stage in a pipeline, nowhere else. -assertErrorCode(db[coll], - [{$match: {x:1}}, {$geoNear:{near: [1,1], spherical: true, distanceField: 'dis'}}], - 28837); - -function checkOutput(cmdOut, aggOut, expectedNum) { - assert.commandWorked(cmdOut, "geoNear command"); - - // the output arrays are accessed differently - cmdOut = cmdOut.results; - aggOut = aggOut.toArray(); - - assert.eq(cmdOut.length, expectedNum); - assert.eq(aggOut.length, expectedNum); - - var allSame = true; - var massaged; // massage geoNear command output to match output from agg pipeline - for (var i=0; i < cmdOut.length; i++) { - massaged = {}; - Object.extend(massaged, cmdOut[i].obj, /*deep=*/true); - massaged.stats = {'dis': cmdOut[i].dis, - 'loc': cmdOut[i].loc}; - - if (!friendlyEqual(massaged, aggOut[i])) { - allSame = false; // don't bail yet since we want to print all differences - print("Difference detected at index " + i + " of " + expectedNum); - print("from geoNear command:" + tojson(massaged)); - print("from aggregate command:" + tojson(aggOut[i])); - } - } + load('jstests/libs/geo_near_random.js'); + load('jstests/aggregation/extras/utils.js'); - assert(allSame); -} - -// We use this to generate points. Using a single global to avoid reseting RNG in each pass. -var pointMaker = new GeoNearRandomTest(coll); + var coll = 'server7781'; -function test(db, sharded, indexType) { db[coll].drop(); - - if (sharded) { // sharded setup - var shards = []; - var config = db.getSiblingDB("config"); - config.shards.find().forEach(function(shard) { shards.push(shard._id); }); - - db.adminCommand({shardCollection: db[coll].getFullName(), key: {rand:1}}); - for (var i=1; i < 10; i++) { - // split at 0.1, 0.2, ... 0.9 - db.adminCommand({split: db[coll].getFullName(), middle: {rand: i/10}}); - db.adminCommand({moveChunk: db[coll].getFullName(), find: {rand: i/10}, - to: shards[i%shards.length]}); + db[coll].insert({loc: [0, 0]}); + + // $geoNear is only allowed as the first stage in a pipeline, nowhere else. + assertErrorCode( + db[coll], + [{$match: {x: 1}}, {$geoNear: {near: [1, 1], spherical: true, distanceField: 'dis'}}], + 28837); + + function checkOutput(cmdOut, aggOut, expectedNum) { + assert.commandWorked(cmdOut, "geoNear command"); + + // the output arrays are accessed differently + cmdOut = cmdOut.results; + aggOut = aggOut.toArray(); + + assert.eq(cmdOut.length, expectedNum); + assert.eq(aggOut.length, expectedNum); + + var allSame = true; + var massaged; // massage geoNear command output to match output from agg pipeline + for (var i = 0; i < cmdOut.length; i++) { + massaged = {}; + Object.extend(massaged, cmdOut[i].obj, /*deep=*/true); + massaged.stats = { + 'dis': cmdOut[i].dis, + 'loc': cmdOut[i].loc + }; + + if (!friendlyEqual(massaged, aggOut[i])) { + allSame = false; // don't bail yet since we want to print all differences + print("Difference detected at index " + i + " of " + expectedNum); + print("from geoNear command:" + tojson(massaged)); + print("from aggregate command:" + tojson(aggOut[i])); + } } - assert.eq(config.chunks.count({'ns': db[coll].getFullName()}), 10); + assert(allSame); } - // insert points - var numPts = 10*1000; - var bulk = db[coll].initializeUnorderedBulkOp(); - for (var i=0; i < numPts; i++) { - bulk.insert({ rand: Math.random(), loc: pointMaker.mkPt() }); + // We use this to generate points. Using a single global to avoid reseting RNG in each pass. + var pointMaker = new GeoNearRandomTest(coll); + + function test(db, sharded, indexType) { + db[coll].drop(); + + if (sharded) { // sharded setup + var shards = []; + var config = db.getSiblingDB("config"); + config.shards.find().forEach(function(shard) { + shards.push(shard._id); + }); + + db.adminCommand({shardCollection: db[coll].getFullName(), key: {rand: 1}}); + for (var i = 1; i < 10; i++) { + // split at 0.1, 0.2, ... 0.9 + db.adminCommand({split: db[coll].getFullName(), middle: {rand: i / 10}}); + db.adminCommand({ + moveChunk: db[coll].getFullName(), + find: {rand: i / 10}, + to: shards[i % shards.length] + }); + } + + assert.eq(config.chunks.count({'ns': db[coll].getFullName()}), 10); + } + + // insert points + var numPts = 10 * 1000; + var bulk = db[coll].initializeUnorderedBulkOp(); + for (var i = 0; i < numPts; i++) { + bulk.insert({rand: Math.random(), loc: pointMaker.mkPt()}); + } + assert.writeOK(bulk.execute()); + + assert.eq(db[coll].count(), numPts); + + db[coll].ensureIndex({loc: indexType}); + + // test with defaults + var queryPoint = pointMaker.mkPt(0.25); // stick to center of map + geoCmd = { + geoNear: coll, + near: queryPoint, + includeLocs: true, + spherical: true + }; + aggCmd = { + $geoNear: { + near: queryPoint, + includeLocs: 'stats.loc', + distanceField: 'stats.dis', + spherical: true + } + }; + checkOutput(db.runCommand(geoCmd), db[coll].aggregate(aggCmd), 100); + + // test with num + queryPoint = pointMaker.mkPt(0.25); + geoCmd.num = 75; + geoCmd.near = queryPoint; + aggCmd.$geoNear.num = 75; + aggCmd.$geoNear.near = queryPoint; + checkOutput(db.runCommand(geoCmd), db[coll].aggregate(aggCmd), 75); + + // test with limit instead of num (they mean the same thing, but want to test both) + queryPoint = pointMaker.mkPt(0.25); + geoCmd.near = queryPoint; + delete geoCmd.num; + geoCmd.limit = 70; + aggCmd.$geoNear.near = queryPoint; + delete aggCmd.$geoNear.num; + aggCmd.$geoNear.limit = 70; + checkOutput(db.runCommand(geoCmd), db[coll].aggregate(aggCmd), 70); + + // test spherical + queryPoint = pointMaker.mkPt(0.25); + geoCmd.spherical = true; + geoCmd.near = queryPoint; + aggCmd.$geoNear.spherical = true; + aggCmd.$geoNear.near = queryPoint; + checkOutput(db.runCommand(geoCmd), db[coll].aggregate(aggCmd), 70); + + // test $geoNear + $limit coalescing + queryPoint = pointMaker.mkPt(0.25); + geoCmd.num = 40; + geoCmd.near = queryPoint; + aggCmd.$geoNear.near = queryPoint; + aggArr = [aggCmd, {$limit: 50}, {$limit: 60}, {$limit: 40}]; + checkOutput(db.runCommand(geoCmd), db[coll].aggregate(aggArr), 40); + + // Test $geoNear with an initial batchSize of 0. Regression test for SERVER-20935. + queryPoint = pointMaker.mkPt(0.25); + geoCmd.spherical = true; + geoCmd.near = queryPoint; + geoCmd.limit = 70; + delete geoCmd.num; + aggCmd.$geoNear.spherical = true; + aggCmd.$geoNear.near = queryPoint; + aggCmd.$geoNear.limit = 70; + delete aggCmd.$geoNear.num; + var cmdRes = db[coll].runCommand("aggregate", {pipeline: [aggCmd], cursor: {batchSize: 0}}); + assert.commandWorked(cmdRes); + var cmdCursor = new DBCommandCursor(db[coll].getMongo(), cmdRes, 0); + checkOutput(db.runCommand(geoCmd), cmdCursor, 70); } - assert.writeOK(bulk.execute()); - - assert.eq(db[coll].count(), numPts); - - db[coll].ensureIndex({loc: indexType}); - - // test with defaults - var queryPoint = pointMaker.mkPt(0.25); // stick to center of map - geoCmd = {geoNear: coll, near: queryPoint, includeLocs: true, spherical: true}; - aggCmd = {$geoNear: {near: queryPoint, includeLocs: 'stats.loc', distanceField: 'stats.dis', spherical: true}}; - checkOutput(db.runCommand(geoCmd), db[coll].aggregate(aggCmd), 100); - - // test with num - queryPoint = pointMaker.mkPt(0.25); - geoCmd.num = 75; - geoCmd.near = queryPoint; - aggCmd.$geoNear.num = 75; - aggCmd.$geoNear.near = queryPoint; - checkOutput(db.runCommand(geoCmd), db[coll].aggregate(aggCmd), 75); - - // test with limit instead of num (they mean the same thing, but want to test both) - queryPoint = pointMaker.mkPt(0.25); - geoCmd.near = queryPoint; - delete geoCmd.num; - geoCmd.limit = 70; - aggCmd.$geoNear.near = queryPoint; - delete aggCmd.$geoNear.num; - aggCmd.$geoNear.limit = 70; - checkOutput(db.runCommand(geoCmd), db[coll].aggregate(aggCmd), 70); - - // test spherical - queryPoint = pointMaker.mkPt(0.25); - geoCmd.spherical = true; - geoCmd.near = queryPoint; - aggCmd.$geoNear.spherical = true; - aggCmd.$geoNear.near = queryPoint; - checkOutput(db.runCommand(geoCmd), db[coll].aggregate(aggCmd), 70); - - // test $geoNear + $limit coalescing - queryPoint = pointMaker.mkPt(0.25); - geoCmd.num = 40; - geoCmd.near = queryPoint; - aggCmd.$geoNear.near = queryPoint; - aggArr = [aggCmd, {$limit: 50}, {$limit:60}, {$limit:40}]; - checkOutput(db.runCommand(geoCmd), db[coll].aggregate(aggArr), 40); - - // Test $geoNear with an initial batchSize of 0. Regression test for SERVER-20935. - queryPoint = pointMaker.mkPt(0.25); - geoCmd.spherical = true; - geoCmd.near = queryPoint; - geoCmd.limit = 70; - delete geoCmd.num; - aggCmd.$geoNear.spherical = true; - aggCmd.$geoNear.near = queryPoint; - aggCmd.$geoNear.limit = 70; - delete aggCmd.$geoNear.num; - var cmdRes = db[coll].runCommand("aggregate", {pipeline: [aggCmd], cursor: {batchSize: 0}}); - assert.commandWorked(cmdRes); - var cmdCursor = new DBCommandCursor(db[coll].getMongo(), cmdRes, 0); - checkOutput(db.runCommand(geoCmd), cmdCursor, 70); -} - -test(db, false, '2d'); -test(db, false, '2dsphere'); - -var sharded = new ShardingTest({shards: 3, mongos: 1}); -sharded.stopBalancer(); -sharded.adminCommand( { enablesharding : "test" } ); -sharded.ensurePrimaryShard('test', 'shard0001'); - -test(sharded.getDB('test'), true, '2d'); -test(sharded.getDB('test'), true, '2dsphere'); - -sharded.stop(); + + test(db, false, '2d'); + test(db, false, '2dsphere'); + + var sharded = new ShardingTest({shards: 3, mongos: 1}); + sharded.stopBalancer(); + sharded.adminCommand({enablesharding: "test"}); + sharded.ensurePrimaryShard('test', 'shard0001'); + + test(sharded.getDB('test'), true, '2d'); + test(sharded.getDB('test'), true, '2dsphere'); + + sharded.stop(); })(); diff --git a/jstests/aggregation/bugs/server7900.js b/jstests/aggregation/bugs/server7900.js index c05c1538e53..20bf085c7a1 100644 --- a/jstests/aggregation/bugs/server7900.js +++ b/jstests/aggregation/bugs/server7900.js @@ -3,9 +3,8 @@ c = db.s7900; c.drop(); -for (var i=0; i < 5; i++) - c.insert({_id:i}); +for (var i = 0; i < 5; i++) + c.insert({_id: i}); -res = c.aggregate({$sort: {_id: -1}}, {$limit: 2}); // uses index for sort +res = c.aggregate({$sort: {_id: -1}}, {$limit: 2}); // uses index for sort assert.eq(res.toArray(), [{_id: 4}, {_id: 3}]); - diff --git a/jstests/aggregation/bugs/server8141.js b/jstests/aggregation/bugs/server8141.js index d450ec14227..9777737517b 100644 --- a/jstests/aggregation/bugs/server8141.js +++ b/jstests/aggregation/bugs/server8141.js @@ -34,8 +34,12 @@ assert.eq(coll.aggregate(pipeline).toArray(), [{d: ['foo']}]); // Nested arrays. - pipeline = [{$project: {_id: 0, d: {$setIntersection: [[[1, 'foo', 'bar']], - [[1, {$toLower: 'FoO'}, '$b']]]}}}]; + pipeline = [{ + $project: { + _id: 0, + d: {$setIntersection: [[[1, 'foo', 'bar']], [[1, {$toLower: 'FoO'}, '$b']]]} + } + }]; assert.eq(coll.aggregate(pipeline).toArray(), [{d: [[1, 'foo', 'bar']]}]); coll.drop(); diff --git a/jstests/aggregation/bugs/server8568.js b/jstests/aggregation/bugs/server8568.js index 7490b286e38..ae9a9ad8202 100644 --- a/jstests/aggregation/bugs/server8568.js +++ b/jstests/aggregation/bugs/server8568.js @@ -17,8 +17,8 @@ load('jstests/aggregation/extras/utils.js'); // Helper for testing that op results in error with code errorCode. function testError(op, errorCode) { - var pipeline = [{$project: {_id: 0, result: op}}]; - assertErrorCode(coll, pipeline, errorCode); + var pipeline = [{$project: {_id: 0, result: op}}]; + assertErrorCode(coll, pipeline, errorCode); } // Valid input: Numeric arg >= 0, null, or NaN. diff --git a/jstests/aggregation/bugs/server8581.js b/jstests/aggregation/bugs/server8581.js index aa2158c0ced..54b97be3d08 100644 --- a/jstests/aggregation/bugs/server8581.js +++ b/jstests/aggregation/bugs/server8581.js @@ -5,154 +5,123 @@ 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 - }); +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, - }]; +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); @@ -168,35 +137,16 @@ 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"]}}); +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 - }]; +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); - diff --git a/jstests/aggregation/bugs/server9289.js b/jstests/aggregation/bugs/server9289.js index 934e5862314..06afc36d5e7 100644 --- a/jstests/aggregation/bugs/server9289.js +++ b/jstests/aggregation/bugs/server9289.js @@ -6,4 +6,5 @@ t.drop(); t.insert({date: ISODate('2013-08-14T21:41:43Z')}); // This would result in a parse error on older servers -assert.eq(t.aggregate({$project: {year: {$year: {$add:['$date',1000]}}}}).toArray()[0].year, 2013); +assert.eq(t.aggregate({$project: {year: {$year: {$add: ['$date', 1000]}}}}).toArray()[0].year, + 2013); diff --git a/jstests/aggregation/bugs/server9444.js b/jstests/aggregation/bugs/server9444.js index d8ab7781681..ad5f4b03ca6 100644 --- a/jstests/aggregation/bugs/server9444.js +++ b/jstests/aggregation/bugs/server9444.js @@ -3,19 +3,19 @@ var t = db.server9444; t.drop(); -var sharded = (typeof(RUNNING_IN_SHARDED_AGG_TEST) != 'undefined'); // see end of testshard1.js +var sharded = (typeof(RUNNING_IN_SHARDED_AGG_TEST) != 'undefined'); // see end of testshard1.js if (sharded) { - db.adminCommand( { shardcollection : t.getFullName(), key : { "_id" : 'hashed' } } ); + db.adminCommand({shardcollection: t.getFullName(), key: {"_id": 'hashed'}}); } var memoryLimitMB = sharded ? 200 : 100; function loadData() { - var bigStr = Array(1024*1024 + 1).toString(); // 1MB of ',' + var bigStr = Array(1024 * 1024 + 1).toString(); // 1MB of ',' for (var i = 0; i < memoryLimitMB + 1; i++) t.insert({_id: i, bigStr: i + bigStr, random: Math.random()}); - assert.gt(t.stats().size, memoryLimitMB * 1024*1024); + assert.gt(t.stats().size, memoryLimitMB * 1024 * 1024); } loadData(); @@ -37,7 +37,7 @@ function test(pipeline, outOfMemoryCode) { // ensure we work when allowDiskUse === true var res = t.aggregate(pipeline, {allowDiskUse: true}); - assert.eq(res.itcount(), t.count()); // all tests output one doc per input doc + assert.eq(res.itcount(), t.count()); // all tests output one doc per input doc } var groupCode = 16945; @@ -48,16 +48,16 @@ test([{$group: {_id: '$_id', bigStr: {$first: '$bigStr'}}}], groupCode); // sorting with _id would use index which doesn't require extsort test([{$sort: {random: 1}}], sortCode); -test([{$sort: {bigStr: 1}}], sortCode); // big key and value +test([{$sort: {bigStr: 1}}], sortCode); // big key and value // make sure sort + large limit won't crash the server (SERVER-10136) -test([{$sort: {bigStr: 1}}, {$limit:1000*1000*1000}], sortLimitCode); +test([{$sort: {bigStr: 1}}, {$limit: 1000 * 1000 * 1000}], sortLimitCode); // test combining two extSorts in both same and different orders -test([{$group: {_id: '$_id', bigStr: {$first: '$bigStr'}}}, {$sort: {_id:1}}], groupCode); -test([{$group: {_id: '$_id', bigStr: {$first: '$bigStr'}}}, {$sort: {_id:-1}}], groupCode); -test([{$group: {_id: '$_id', bigStr: {$first: '$bigStr'}}}, {$sort: {random:1}}], groupCode); -test([{$sort: {random:1}}, {$group: {_id: '$_id', bigStr: {$first: '$bigStr'}}}], sortCode); +test([{$group: {_id: '$_id', bigStr: {$first: '$bigStr'}}}, {$sort: {_id: 1}}], groupCode); +test([{$group: {_id: '$_id', bigStr: {$first: '$bigStr'}}}, {$sort: {_id: -1}}], groupCode); +test([{$group: {_id: '$_id', bigStr: {$first: '$bigStr'}}}, {$sort: {random: 1}}], groupCode); +test([{$sort: {random: 1}}, {$group: {_id: '$_id', bigStr: {$first: '$bigStr'}}}], sortCode); var origDB = db; if (sharded) { @@ -74,4 +74,3 @@ if (sharded) { sh.startBalancer(); db = origDB; } - diff --git a/jstests/aggregation/bugs/server9625.js b/jstests/aggregation/bugs/server9625.js index 009f55b7ef0..4a525aba518 100644 --- a/jstests/aggregation/bugs/server9625.js +++ b/jstests/aggregation/bugs/server9625.js @@ -55,8 +55,8 @@ load('jstests/aggregation/extras/utils.js'); // These expressions are associative and commutative so inner expression can be combined with // outer. - testOp({$sum: ["$a", 2, 3, {$sum : [4, 5]}]}, 15); - testOp({$min: ["$a", 2, 3, {$min : [4, 5]}]}, 1); + testOp({$sum: ["$a", 2, 3, {$sum: [4, 5]}]}, 15); + testOp({$min: ["$a", 2, 3, {$min: [4, 5]}]}, 1); testOp({$max: ["$a", 2, 3, {$max: [4, 5]}]}, 5); // These expressions are not associative and commutative so inner expression cannot be combined diff --git a/jstests/aggregation/bugs/server9840.js b/jstests/aggregation/bugs/server9840.js index 61c95ab9cd0..130066d8af4 100644 --- a/jstests/aggregation/bugs/server9840.js +++ b/jstests/aggregation/bugs/server9840.js @@ -6,15 +6,15 @@ t.drop(); function test(expression, expected) { t.drop(); - t.insert({zero:0, one:1, two:2, three:3, nested: {four: 4}}); + t.insert({zero: 0, one: 1, two: 2, three: 3, nested: {four: 4}}); // Test in projection: - var result = t.aggregate({$project:{_id:0, res: expression}}).toArray(); - assert.eq(result, [{res:expected}]); + var result = t.aggregate({$project: {_id: 0, res: expression}}).toArray(); + assert.eq(result, [{res: expected}]); // Test in group: - var result = t.aggregate({$group:{_id: 0, res: {$sum: expression}}}).toArray(); - assert.eq(result, [{_id: 0, res:expected}]); + var result = t.aggregate({$group: {_id: 0, res: {$sum: expression}}}).toArray(); + assert.eq(result, [{_id: 0, res: expected}]); } // basics @@ -29,55 +29,76 @@ test({$add: ['$$CURRENT.two', '$$ROOT.nested.four']}, 6); // $let simple test({$let: {vars: {a: 10}, in: '$$a'}}, 10); test({$let: {vars: {a: '$zero'}, in: '$$a'}}, 0); -test({$let: {vars: {a: {$add:['$one', '$two']}, - b: 10}, - in: {$multiply:['$$a', '$$b']}}}, - 30); +test({$let: {vars: {a: {$add: ['$one', '$two']}, b: 10}, in: {$multiply: ['$$a', '$$b']}}}, 30); // $let changing CURRENT -test({$let: {vars: {CURRENT: '$$ROOT.nested'}, - in: {$multiply:['$four', '$$ROOT.two']}}}, - 8); -test({$let: {vars: {CURRENT: '$$CURRENT.nested'}, // using original value of CURRENT - in: {$multiply:['$four', '$$ROOT.two']}}}, - 8); -test({$let: {vars: {CURRENT: '$nested'}, // same as last - in: {$multiply:['$four', '$$ROOT.two']}}}, - 8); -test({$let: {vars: {CURRENT: {$const:{ten: 10}}}, // "artificial" object - in: {$multiply:['$ten', '$$ROOT.two']}}}, - 20); -test({$let: {vars: {CURRENT: '$three'}, // sets current to the number 3 (not an object) - in: {$multiply:['$$CURRENT', '$$ROOT.two']}}}, - 6); +test({$let: {vars: {CURRENT: '$$ROOT.nested'}, in: {$multiply: ['$four', '$$ROOT.two']}}}, 8); +test( + { + $let: { + vars: {CURRENT: '$$CURRENT.nested'}, // using original value of CURRENT + in: {$multiply: ['$four', '$$ROOT.two']} + } + }, + 8); +test( + { + $let: { + vars: {CURRENT: '$nested'}, // same as last + in: {$multiply: ['$four', '$$ROOT.two']} + } + }, + 8); +test( + { + $let: { + vars: {CURRENT: {$const: {ten: 10}}}, // "artificial" object + in: {$multiply: ['$ten', '$$ROOT.two']} + } + }, + 20); +test( + { + $let: { + vars: {CURRENT: '$three'}, // sets current to the number 3 (not an object) + in: {$multiply: ['$$CURRENT', '$$ROOT.two']} + } + }, + 6); // swapping with $let (ensures there is no ordering dependency in vars) -test({$let: {vars: {x: 6, y: 10}, - in: {$let: {vars: {x: '$$y', y: '$$x'}, // now {x:10, y:6} - in: {$subtract: ['$$x', '$$y']}}}}}, // not commutative! - 4); // 10-6 not 6-10 or 6-6 - +test( + { + $let: { + vars: {x: 6, y: 10}, + in: { + $let: { + vars: {x: '$$y', y: '$$x'}, // now {x:10, y:6} + in: {$subtract: ['$$x', '$$y']} + } + } + } + }, // not commutative! + 4); // 10-6 not 6-10 or 6-6 // unicode is allowed -test({$let: {vars: {'日本語': 10}, in: '$$日本語'}}, 10); // Japanese for "Japanese language" +test({$let: {vars: {'日本語': 10}, in: '$$日本語'}}, 10); // Japanese for "Japanese language" // Can use ROOT and CURRENT directly with no subfield (SERVER-5916) t.drop(); t.insert({_id: 'obj'}); -assert.eq(t.aggregate({$project: {_id:0, obj: '$$ROOT'}}).toArray(), - [{obj: {_id: 'obj'}}]); -assert.eq(t.aggregate({$project: {_id:0, obj: '$$CURRENT'}}).toArray(), - [{obj: {_id: 'obj'}}]); -assert.eq(t.aggregate({$group: {_id:0, objs: {$push: '$$ROOT'}}}).toArray(), - [{_id: 0, objs: [{_id: 'obj'}]}]); -assert.eq(t.aggregate({$group: {_id:0, objs: {$push: '$$CURRENT'}}}).toArray(), - [{_id: 0, objs: [{_id: 'obj'}]}]); +assert.eq(t.aggregate({$project: {_id: 0, obj: '$$ROOT'}}).toArray(), [{obj: {_id: 'obj'}}]); +assert.eq(t.aggregate({$project: {_id: 0, obj: '$$CURRENT'}}).toArray(), [{obj: {_id: 'obj'}}]); +assert.eq(t.aggregate({$group: {_id: 0, objs: {$push: '$$ROOT'}}}).toArray(), + [{_id: 0, objs: [{_id: 'obj'}]}]); +assert.eq(t.aggregate({$group: {_id: 0, objs: {$push: '$$CURRENT'}}}).toArray(), + [{_id: 0, objs: [{_id: 'obj'}]}]); // check name validity checks -assertErrorCode(t, {$project: {a: {$let:{vars: {ROOT: 1}, in: '$$ROOT'}}}}, 16867); -assertErrorCode(t, {$project: {a: {$let:{vars: {FOO: 1}, in: '$$FOO'}}}}, 16867); -assertErrorCode(t, {$project: {a: {$let:{vars: {_underbar: 1}, in: '$$FOO'}}}}, 16867); -assertErrorCode(t, {$project: {a: {$let:{vars: {'a.b': 1}, in: '$$FOO'}}}}, 16868); -assertErrorCode(t, {$project: {a: {$let:{vars: {'a b': 1}, in: '$$FOO'}}}}, 16868); +assertErrorCode(t, {$project: {a: {$let: {vars: {ROOT: 1}, in: '$$ROOT'}}}}, 16867); +assertErrorCode(t, {$project: {a: {$let: {vars: {FOO: 1}, in: '$$FOO'}}}}, 16867); +assertErrorCode(t, {$project: {a: {$let: {vars: {_underbar: 1}, in: '$$FOO'}}}}, 16867); +assertErrorCode(t, {$project: {a: {$let: {vars: {'a.b': 1}, in: '$$FOO'}}}}, 16868); +assertErrorCode(t, {$project: {a: {$let: {vars: {'a b': 1}, in: '$$FOO'}}}}, 16868); assertErrorCode(t, {$project: {a: '$$_underbar'}}, 16870); assertErrorCode(t, {$project: {a: '$$with spaces'}}, 16871); diff --git a/jstests/aggregation/bugs/server9841.js b/jstests/aggregation/bugs/server9841.js index 46f06021d0c..5bf9b32db93 100644 --- a/jstests/aggregation/bugs/server9841.js +++ b/jstests/aggregation/bugs/server9841.js @@ -4,7 +4,7 @@ load('jstests/aggregation/extras/utils.js'); var t = db.server9841; t.drop(); t.insert({ - simple: [1,2,3,4], + simple: [1, 2, 3, 4], nested: [{a: 1}, {a: 2}], mixed: [{a: 1}, {}, {a: 2}, {a: null}], notArray: 1, @@ -12,29 +12,31 @@ t.insert({ }); function test(expression, expected) { - var result = t.aggregate({$project:{_id:0, res: expression}}).toArray(); - assert.eq(result, [{res:expected}]); + var result = t.aggregate({$project: {_id: 0, res: expression}}).toArray(); + assert.eq(result, [{res: expected}]); } -test({$map: {input: "$simple", as: "var", in: '$$var'}}, [1,2,3,4]); -test({$map: {input: "$simple", as: "var", in: {$add:[10, '$$var']}}}, [11,12,13,14]); +test({$map: {input: "$simple", as: "var", in: '$$var'}}, [1, 2, 3, 4]); +test({$map: {input: "$simple", as: "var", in: {$add: [10, '$$var']}}}, [11, 12, 13, 14]); -test({$map: {input: "$nested", as: "var", in: '$$var.a'}}, [1,2]); -test({$map: {input: "$nested", as: "CURRENT", in: '$a'}}, [1,2]); +test({$map: {input: "$nested", as: "var", in: '$$var.a'}}, [1, 2]); +test({$map: {input: "$nested", as: "CURRENT", in: '$a'}}, [1, 2]); + +test({$map: {input: "$mixed", as: "var", in: '$$var.a'}}, + [1, null, 2, null]); // missing becomes null -test({$map: {input: "$mixed", as: "var", in: '$$var.a'}}, [1,null,2,null]); // missing becomes null - test({$map: {input: "$null", as: "var", in: '$$var'}}, null); // can't set ROOT -assertErrorCode(t, {$project:{a:{$map:{input: "$simple", as: "ROOT", in: '$$ROOT'}}}}, 16867); +assertErrorCode(t, {$project: {a: {$map: {input: "$simple", as: "ROOT", in: '$$ROOT'}}}}, 16867); // error on non-array -assertErrorCode(t, {$project:{a:{$map:{input: "$notArray", as: "var", in: '$$var'}}}}, 16883); +assertErrorCode(t, {$project: {a: {$map: {input: "$notArray", as: "var", in: '$$var'}}}}, 16883); // parse errors (missing or extra fields) -assertErrorCode(t, {$project:{a:{$map:{x:1, input: "$simple", as: "var", in: '$$var'}}}}, 16879); -assertErrorCode(t, {$project:{a:{$map:{as: "var", in: '$$var'}}}}, 16880); -assertErrorCode(t, {$project:{a:{$map:{input: "$simple", in: '$$var'}}}}, 16881); -assertErrorCode(t, {$project:{a:{$map:{input: "$simple", as: "var"}}}}, 16882); - +assertErrorCode(t, + {$project: {a: {$map: {x: 1, input: "$simple", as: "var", in: '$$var'}}}}, + 16879); +assertErrorCode(t, {$project: {a: {$map: {as: "var", in: '$$var'}}}}, 16880); +assertErrorCode(t, {$project: {a: {$map: {input: "$simple", in: '$$var'}}}}, 16881); +assertErrorCode(t, {$project: {a: {$map: {input: "$simple", as: "var"}}}}, 16882); diff --git a/jstests/aggregation/bugs/strcasecmp.js b/jstests/aggregation/bugs/strcasecmp.js index c0f6d9a9256..71a5f2996c9 100644 --- a/jstests/aggregation/bugs/strcasecmp.js +++ b/jstests/aggregation/bugs/strcasecmp.js @@ -3,64 +3,64 @@ t = db.jstests_aggregation_strcasecmp; t.drop(); -t.save( {} ); +t.save({}); -function cmp( a, b ) { - return t.aggregate( { $project:{ a:{ $cmp:[ a, b ] } } } ).toArray()[ 0 ].a; +function cmp(a, b) { + return t.aggregate({$project: {a: {$cmp: [a, b]}}}).toArray()[0].a; } -function strcasecmp( a, b ) { - return t.aggregate( { $project:{ a:{ $strcasecmp:[ a, b ] } } } ).toArray()[ 0 ].a; +function strcasecmp(a, b) { + return t.aggregate({$project: {a: {$strcasecmp: [a, b]}}}).toArray()[0].a; } -function assertException( args ) { - assert.commandFailed(t.runCommand('aggregate', - {pipeline: [{$project: {a: {$strcasecmp: args}}}]})); +function assertException(args) { + assert.commandFailed( + t.runCommand('aggregate', {pipeline: [{$project: {a: {$strcasecmp: args}}}]})); } -function assertStrcasecmp( expected, a, b ) { - assert.eq( expected, strcasecmp( a, b ) ); - assert.eq( -expected, strcasecmp( b, a ) ); +function assertStrcasecmp(expected, a, b) { + assert.eq(expected, strcasecmp(a, b)); + assert.eq(-expected, strcasecmp(b, a)); } -function assertBoth( expectedStrcasecmp, expectedCmp, a, b ) { - assertStrcasecmp( expectedStrcasecmp, a, b ); - assert.eq( expectedCmp, cmp( a, b ) ); - assert.eq( -expectedCmp, cmp( b, a ) ); +function assertBoth(expectedStrcasecmp, expectedCmp, a, b) { + assertStrcasecmp(expectedStrcasecmp, a, b); + assert.eq(expectedCmp, cmp(a, b)); + assert.eq(-expectedCmp, cmp(b, a)); } // Wrong number of arguments. -assertException( [] ); -assertException( [ 'a' ] ); -assertException( [ 'a', 'b', 'c' ] ); +assertException([]); +assertException(['a']); +assertException(['a', 'b', 'c']); // Basic tests. -assertBoth( 0, 0, '', '' ); -assertBoth( -1, -1, '', 'a' ); -assertBoth( 0, -1, 'A', 'a' ); -assertBoth( 1, -1, 'Ab', 'a' ); -assertBoth( 0, -1, 'Ab', 'aB' ); -assertBoth( 1, -1, 'Bb', 'aB' ); -assertBoth( -1, -1, 'Bb', 'cB' ); -assertBoth( 1, -1, 'aB', 'aa' ); -assertBoth( -1, -1, 'aB', 'ac' ); +assertBoth(0, 0, '', ''); +assertBoth(-1, -1, '', 'a'); +assertBoth(0, -1, 'A', 'a'); +assertBoth(1, -1, 'Ab', 'a'); +assertBoth(0, -1, 'Ab', 'aB'); +assertBoth(1, -1, 'Bb', 'aB'); +assertBoth(-1, -1, 'Bb', 'cB'); +assertBoth(1, -1, 'aB', 'aa'); +assertBoth(-1, -1, 'aB', 'ac'); // With non alphabet characters. -assertBoth( 0, -1, 'A$_b1C?', 'a$_b1C?' ); -assertBoth( 1, -1, 'ABC01234', 'abc0123' ); +assertBoth(0, -1, 'A$_b1C?', 'a$_b1C?'); +assertBoth(1, -1, 'ABC01234', 'abc0123'); // String coercion. -assertStrcasecmp( 0, '1', 1 ); -assertStrcasecmp( 0, '1.23', 1.23 ); -assertStrcasecmp( 0, '1970-01-01T00:00:00', new Date( 0 ) ); -assertStrcasecmp( 0, '1970-01-01t00:00:00', new Date( 0 ) ); -assertException( [ 'abc', /abc/ ] ); +assertStrcasecmp(0, '1', 1); +assertStrcasecmp(0, '1.23', 1.23); +assertStrcasecmp(0, '1970-01-01T00:00:00', new Date(0)); +assertStrcasecmp(0, '1970-01-01t00:00:00', new Date(0)); +assertException(['abc', /abc/]); // Extended characters. -assertBoth( 0, -1, '\u0080D\u20ac', '\u0080d\u20ac' ); -assertBoth( 1, 1, 'ó', 'Ó' ); // Not treated as equal currently. +assertBoth(0, -1, '\u0080D\u20ac', '\u0080d\u20ac'); +assertBoth(1, 1, 'ó', 'Ó'); // Not treated as equal currently. // String from field path. t.drop(); -t.save( { x:'abc' } ); -assertBoth( 0, 1, '$x', 'ABC' ); +t.save({x: 'abc'}); +assertBoth(0, 1, '$x', 'ABC'); diff --git a/jstests/aggregation/bugs/substr.js b/jstests/aggregation/bugs/substr.js index 0d4eb72e691..4aee531dd67 100644 --- a/jstests/aggregation/bugs/substr.js +++ b/jstests/aggregation/bugs/substr.js @@ -3,115 +3,118 @@ t = db.jstests_aggregation_substr; t.drop(); -t.save( {} ); +t.save({}); -function assertSubstring( expected, str, offset, len ) { - assert.eq( expected, - t.aggregate( { $project:{ a:{ $substr:[ str, offset, len ] } } } ).toArray()[ 0 ].a ); +function assertSubstring(expected, str, offset, len) { + assert.eq(expected, t.aggregate({$project: {a: {$substr: [str, offset, len]}}}).toArray()[0].a); } -function assertArgsException( args ) { +function assertArgsException(args) { assert.commandFailed(t.runCommand('aggregate', {pipeline: [{$substr: args}]})); } -function assertException( str, offset, len ) { +function assertException(str, offset, len) { assertArgsException([str, offset, len]); } // Wrong number of arguments. -assertArgsException( [] ); -assertArgsException( [ 'foo' ] ); -assertArgsException( [ 'foo', 1 ] ); -assertArgsException( [ 'foo', 1, 1, 1 ] ); +assertArgsException([]); +assertArgsException(['foo']); +assertArgsException(['foo', 1]); +assertArgsException(['foo', 1, 1, 1]); // Basic offset / length checks. -assertSubstring( 'abcd', 'abcd', 0, 4 ); -assertSubstring( 'abcd', 'abcd', 0, 5 ); -assertSubstring( '', 'abcd', -1 /* unsigned */, 4 ); -assertSubstring( 'a', 'abcd', 0, 1 ); -assertSubstring( 'ab', 'abcd', 0, 2 ); -assertSubstring( 'b', 'abcd', 1, 1 ); -assertSubstring( 'd', 'abcd', 3, 1 ); -assertSubstring( '', 'abcd', 4, 1 ); -assertSubstring( '', 'abcd', 3, 0 ); -assertSubstring( 'cd', 'abcd', 2, -1 /* unsigned */ ); +assertSubstring('abcd', 'abcd', 0, 4); +assertSubstring('abcd', 'abcd', 0, 5); +assertSubstring('', 'abcd', -1 /* unsigned */, 4); +assertSubstring('a', 'abcd', 0, 1); +assertSubstring('ab', 'abcd', 0, 2); +assertSubstring('b', 'abcd', 1, 1); +assertSubstring('d', 'abcd', 3, 1); +assertSubstring('', 'abcd', 4, 1); +assertSubstring('', 'abcd', 3, 0); +assertSubstring('cd', 'abcd', 2, -1 /* unsigned */); // See server6186.js for additional offset / length checks. // Additional numeric types for offset / length. -assertSubstring( 'bc', 'abcd', 1, 2 ); -assertSubstring( 'bc', 'abcd', 1.0, 2.0 ); -assertSubstring( 'bc', 'abcd', NumberInt( 1 ), NumberInt( 2 ) ); -assertSubstring( 'bc', 'abcd', NumberLong( 1 ), NumberLong( 2 ) ); -assertSubstring( 'bc', 'abcd', NumberInt( 1 ), NumberLong( 2 ) ); -assertSubstring( 'bc', 'abcd', NumberLong( 1 ), NumberInt( 2 ) ); +assertSubstring('bc', 'abcd', 1, 2); +assertSubstring('bc', 'abcd', 1.0, 2.0); +assertSubstring('bc', 'abcd', NumberInt(1), NumberInt(2)); +assertSubstring('bc', 'abcd', NumberLong(1), NumberLong(2)); +assertSubstring('bc', 'abcd', NumberInt(1), NumberLong(2)); +assertSubstring('bc', 'abcd', NumberLong(1), NumberInt(2)); // Integer component is used. -assertSubstring( 'bc', 'abcd', 1.2, 2.2 ); -assertSubstring( 'bc', 'abcd', 1.9, 2.9 ); +assertSubstring('bc', 'abcd', 1.2, 2.2); +assertSubstring('bc', 'abcd', 1.9, 2.9); // Non numeric types for offset / length. -assertException( 'abcd', false, 2 ); -assertException( 'abcd', 1, true ); -assertException( 'abcd', 'q', 2 ); -assertException( 'abcd', 1, 'r' ); -assertException( 'abcd', null, 3 ); -assertException( 'abcd', 1, undefined ); +assertException('abcd', false, 2); +assertException('abcd', 1, true); +assertException('abcd', 'q', 2); +assertException('abcd', 1, 'r'); +assertException('abcd', null, 3); +assertException('abcd', 1, undefined); // String coercion. -assertSubstring( '123', 123, 0, 3 ); -assertSubstring( '2', 123, 1, 1 ); -assertSubstring( '1970', new Date( 0 ), 0, 4 ); -assertSubstring( '', null, 0, 4 ); -assertException( /abc/, 0, 4 ); +assertSubstring('123', 123, 0, 3); +assertSubstring('2', 123, 1, 1); +assertSubstring('1970', new Date(0), 0, 4); +assertSubstring('', null, 0, 4); +assertException(/abc/, 0, 4); // Field path like string. -assertSubstring( '$a', 'a$a', 1, 2 ); +assertSubstring('$a', 'a$a', 1, 2); // Multi byte utf-8. -assertSubstring( '\u0080', '\u0080', 0, 2 ); +assertSubstring('\u0080', '\u0080', 0, 2); -assertException( '\u0080', 0, 1 ); -assertException( '\u0080', 1, 1 ); +assertException('\u0080', 0, 1); +assertException('\u0080', 1, 1); -assertSubstring( '\u0080', '\u0080\u20ac', 0, 2 ); -assertSubstring( '\u20ac', '\u0080\u20ac', 2, 3 ); +assertSubstring('\u0080', '\u0080\u20ac', 0, 2); +assertSubstring('\u20ac', '\u0080\u20ac', 2, 3); -assertException( '\u0080\u20ac', 1, 3 ); -assertException( '\u0080\u20ac', 1, 4 ); -assertException( '\u0080\u20ac', 0, 3 ); +assertException('\u0080\u20ac', 1, 3); +assertException('\u0080\u20ac', 1, 4); +assertException('\u0080\u20ac', 0, 3); -assertSubstring( '\u0044\u20ac', '\u0080\u0044\u20ac', 2, 4 ); -assertSubstring( '\u0044', '\u0080\u0044\u20ac', 2, 1 ); +assertSubstring('\u0044\u20ac', '\u0080\u0044\u20ac', 2, 4); +assertSubstring('\u0044', '\u0080\u0044\u20ac', 2, 1); // The four byte utf-8 character 𝌆 (have to represent in surrogate halves). -assertSubstring( '\uD834\uDF06', '\uD834\uDF06', 0, 4 ); +assertSubstring('\uD834\uDF06', '\uD834\uDF06', 0, 4); -assertException( '\uD834\uDF06', '\uD834\uDF06', 1, 4 ); -assertException( '\uD834\uDF06', '\uD834\uDF06', 0, 3 ); +assertException('\uD834\uDF06', '\uD834\uDF06', 1, 4); +assertException('\uD834\uDF06', '\uD834\uDF06', 0, 3); // Operands from document. t.drop(); -t.save( { x:'a', y:'abc', z:'abcde', a:0, b:1, c:2, d:3, e:4, f:5 } ); -assertSubstring( 'a', '$x', '$a', '$b' ); -assertSubstring( 'a', '$x', '$a', '$f' ); -assertSubstring( 'b', '$y', '$b', '$b' ); -assertSubstring( 'b', '$z', '$b', '$b' ); -assertSubstring( 'bcd', '$z', '$b', '$d' ); -assertSubstring( 'cde', '$z', '$c', '$f' ); -assertSubstring( 'c', '$y', '$c', '$f' ); +t.save({x: 'a', y: 'abc', z: 'abcde', a: 0, b: 1, c: 2, d: 3, e: 4, f: 5}); +assertSubstring('a', '$x', '$a', '$b'); +assertSubstring('a', '$x', '$a', '$f'); +assertSubstring('b', '$y', '$b', '$b'); +assertSubstring('b', '$z', '$b', '$b'); +assertSubstring('bcd', '$z', '$b', '$d'); +assertSubstring('cde', '$z', '$c', '$f'); +assertSubstring('c', '$y', '$c', '$f'); // Computed operands. -assertSubstring( 'cde', '$z', { $add:[ '$b', '$b' ] }, { $add:[ '$c', '$d' ] } ); -assertSubstring( 'cde', '$z', { $add:[ '$b', 1 ] }, { $add:[ 2, '$d' ] } ); +assertSubstring('cde', '$z', {$add: ['$b', '$b']}, {$add: ['$c', '$d']}); +assertSubstring('cde', '$z', {$add: ['$b', 1]}, {$add: [2, '$d']}); // Nested. -assert.eq( 'e', - t.aggregate( { $project:{ a: - { $substr: - [ { $substr: - [ { $substr: - [ { $substr:[ 'abcdefghij', 1, 6 ] - }, 2, 5 ] - }, 0, 3 ] - }, 1, 1 ] - } } } ).toArray()[ 0 ].a ); +assert.eq('e', + t.aggregate({ + $project: { + a: { + $substr: [ + {$substr: [{$substr: [{$substr: ['abcdefghij', 1, 6]}, 2, 5]}, 0, 3]}, + 1, + 1 + ] + } + } + }) + .toArray()[0] + .a); diff --git a/jstests/aggregation/bugs/upperlower.js b/jstests/aggregation/bugs/upperlower.js index a97c2ec4aa3..60bcba8db20 100644 --- a/jstests/aggregation/bugs/upperlower.js +++ b/jstests/aggregation/bugs/upperlower.js @@ -3,63 +3,62 @@ t = db.jstests_aggregation_upperlower; t.drop(); -t.save( {} ); +t.save({}); -function assertResult( expectedUpper, expectedLower, string ) { - result = t.aggregate( { $project:{ upper:{ $toUpper:string }, - lower:{ $toLower:string } } } ).toArray()[ 0 ]; - assert.eq( expectedUpper, result.upper ); - assert.eq( expectedLower, result.lower ); +function assertResult(expectedUpper, expectedLower, string) { + result = t.aggregate({$project: {upper: {$toUpper: string}, lower: {$toLower: string}}}) + .toArray()[0]; + assert.eq(expectedUpper, result.upper); + assert.eq(expectedLower, result.lower); } -function assertException( string ) { - assert.commandFailed(t.runCommand('aggregate', - {pipeline: [{$project: {upper: {$toUpper: string}}}]})); - assert.commandFailed(t.runCommand('aggregate', - {pipeline: [{$project: {lower: {$toLower: string}}}]})); +function assertException(string) { + assert.commandFailed( + t.runCommand('aggregate', {pipeline: [{$project: {upper: {$toUpper: string}}}]})); + assert.commandFailed( + t.runCommand('aggregate', {pipeline: [{$project: {lower: {$toLower: string}}}]})); } // Wrong number of arguments. -assertException( [] ); -assertException( [ 'a', 'b' ] ); +assertException([]); +assertException(['a', 'b']); // Upper and lower case conversion. -assertResult( '', '', '' ); -assertResult( '', '', [ '' ] ); -assertResult( 'AB', 'ab', 'aB' ); -assertResult( 'AB', 'ab', [ 'Ab' ] ); -assertResult( 'ABZ', 'abz', 'aBz' ); +assertResult('', '', ''); +assertResult('', '', ['']); +assertResult('AB', 'ab', 'aB'); +assertResult('AB', 'ab', ['Ab']); +assertResult('ABZ', 'abz', 'aBz'); // With non alphabet characters. -assertResult( '1', '1', '1' ); -assertResult( '1^A-A_$%.', '1^a-a_$%.', '1^a-A_$%.' ); -assertResult( '1290B', '1290b', '1290b' ); -assertResult( '0XFF0B', '0xff0b', '0XfF0b' ); +assertResult('1', '1', '1'); +assertResult('1^A-A_$%.', '1^a-a_$%.', '1^a-A_$%.'); +assertResult('1290B', '1290b', '1290b'); +assertResult('0XFF0B', '0xff0b', '0XfF0b'); // Type coercion. -assertResult( '555.5', '555.5', 555.5 ); -assertResult( '1970-01-01T00:00:00', '1970-01-01t00:00:00', new Date( 0 ) ); -assertResult( '', '', null ); -assertException( /abc/ ); +assertResult('555.5', '555.5', 555.5); +assertResult('1970-01-01T00:00:00', '1970-01-01t00:00:00', new Date(0)); +assertResult('', '', null); +assertException(/abc/); // Nested. spec = 'aBcDeFg'; -for( i = 0; i < 10; ++i ) { - assertResult( 'ABCDEFG', 'abcdefg', spec ); - if ( i % 2 == 0 ) { - spec = [ { $toUpper:spec } ]; - } - else { - spec = [ { $toLower:spec } ]; +for (i = 0; i < 10; ++i) { + assertResult('ABCDEFG', 'abcdefg', spec); + if (i % 2 == 0) { + spec = [{$toUpper: spec}]; + } else { + spec = [{$toLower: spec}]; } } // Utf8. -assertResult( '\u0080D\u20ac', '\u0080d\u20ac', '\u0080\u0044\u20ac' ); -assertResult( 'ó', 'ó', 'ó' ); // Not handled. -assertResult( 'Ó', 'Ó', 'Ó' ); // Not handled. +assertResult('\u0080D\u20ac', '\u0080d\u20ac', '\u0080\u0044\u20ac'); +assertResult('ó', 'ó', 'ó'); // Not handled. +assertResult('Ó', 'Ó', 'Ó'); // Not handled. // Value from field path. t.drop(); -t.save( { string:'-_aB' } ); -assertResult( '-_AB', '-_ab', '$string' ); +t.save({string: '-_aB'}); +assertResult('-_AB', '-_ab', '$string'); |