diff options
Diffstat (limited to 'jstests/core')
-rw-r--r-- | jstests/core/explain_agg_write_concern.js | 64 | ||||
-rw-r--r-- | jstests/core/views/views_aggregation.js | 42 | ||||
-rw-r--r-- | jstests/core/views/views_count.js | 20 | ||||
-rw-r--r-- | jstests/core/views/views_distinct.js | 17 | ||||
-rw-r--r-- | jstests/core/views/views_find.js | 17 |
5 files changed, 160 insertions, 0 deletions
diff --git a/jstests/core/explain_agg_write_concern.js b/jstests/core/explain_agg_write_concern.js new file mode 100644 index 00000000000..3a70040a525 --- /dev/null +++ b/jstests/core/explain_agg_write_concern.js @@ -0,0 +1,64 @@ +/** + * Tests related to the aggregate commands behavior with writeConcern and writeConcern + explain. + */ +(function() { + "use strict"; + + let coll = db[jsTest.name()]; + let outColl = db[jsTest.name() + "_out"]; + coll.drop(); + outColl.drop(); + + assert.writeOK(coll.insert({_id: 1})); + + // Agg should accept write concern if the last stage is a $out. + assert.commandWorked(db.runCommand({ + aggregate: coll.getName(), + pipeline: [{$out: outColl.getName()}], + cursor: {}, + writeConcern: {w: 1} + })); + assert.eq(1, outColl.find().itcount()); + outColl.drop(); + + // Agg should reject writeConcern if the last stage is not an $out. + assert.commandFailed( + db.runCommand({aggregate: coll.getName(), pipeline: [], cursor: {}, writeConcern: {w: 1}})); + + // Agg should succeed if the last stage is an $out and the explain flag is set. + assert.commandWorked(db.runCommand({ + aggregate: coll.getName(), + pipeline: [{$out: outColl.getName()}], + explain: true, + })); + assert.eq(0, outColl.find().itcount()); + outColl.drop(); + + // Agg should fail if the last stage is an $out and both the explain flag and writeConcern are + // set. + assert.commandFailed(db.runCommand({ + aggregate: coll.getName(), + pipeline: [{$out: outColl.getName()}], + explain: true, + writeConcern: {w: 1} + })); + + // Agg explain helpers with all verbosities (or verbosity omitted) should fail if the last stage + // is an $out and writeConcern is set. + assert.throws(function() { + coll.explain().aggregate([{$out: outColl.getName()}], {writeConcern: {w: 1}}); + }); + assert.throws(function() { + coll.explain("queryPlanner").aggregate([{$out: outColl.getName()}], {writeConcern: {w: 1}}); + }); + assert.throws(function() { + coll.explain("executionStats").aggregate([{$out: outColl.getName()}], { + writeConcern: {w: 1} + }); + }); + assert.throws(function() { + coll.explain("allPlansExecution").aggregate([{$out: outColl.getName()}], { + writeConcern: {w: 1} + }); + }); +}()); diff --git a/jstests/core/views/views_aggregation.js b/jstests/core/views/views_aggregation.js index 4a7e141a49f..a0c5392deb4 100644 --- a/jstests/core/views/views_aggregation.js +++ b/jstests/core/views/views_aggregation.js @@ -119,6 +119,48 @@ {aggregate: "largeView", pipeline: [{$sort: {x: -1}}], cursor: {}, allowDiskUse: true}), "Expected aggregate to succeed since 'allowDiskUse' was specified"); + // Test explain modes on a view. + let explainPlan = assert.commandWorked( + viewsDB.popSortedView.explain("queryPlanner").aggregate([{$limit: 1}, {$match: {pop: 3}}])); + assert.eq(explainPlan.stages[0].$cursor.queryPlanner.namespace, "views_aggregation.coll"); + assert(!explainPlan.stages[0].$cursor.hasOwnProperty("executionStats")); + + explainPlan = assert.commandWorked(viewsDB.popSortedView.explain("executionStats") + .aggregate([{$limit: 1}, {$match: {pop: 3}}])); + assert.eq(explainPlan.stages[0].$cursor.queryPlanner.namespace, "views_aggregation.coll"); + assert(explainPlan.stages[0].$cursor.hasOwnProperty("executionStats")); + assert.eq(explainPlan.stages[0].$cursor.executionStats.nReturned, 1); + assert(!explainPlan.stages[0].$cursor.executionStats.hasOwnProperty("allPlansExecution")); + + explainPlan = assert.commandWorked(viewsDB.popSortedView.explain("allPlansExecution") + .aggregate([{$limit: 1}, {$match: {pop: 3}}])); + assert.eq(explainPlan.stages[0].$cursor.queryPlanner.namespace, "views_aggregation.coll"); + assert(explainPlan.stages[0].$cursor.hasOwnProperty("executionStats")); + assert.eq(explainPlan.stages[0].$cursor.executionStats.nReturned, 1); + assert(explainPlan.stages[0].$cursor.executionStats.hasOwnProperty("allPlansExecution")); + + // Passing a value of true for the explain option to the aggregation command, without using the + // shell explain helper, should continue to work. + explainPlan = assert.commandWorked( + viewsDB.popSortedView.aggregate([{$limit: 1}, {$match: {pop: 3}}], {explain: true})); + assert.eq(explainPlan.stages[0].$cursor.queryPlanner.namespace, "views_aggregation.coll"); + assert(!explainPlan.stages[0].$cursor.hasOwnProperty("executionStats")); + + // Test allPlansExecution explain mode on the base collection. + explainPlan = assert.commandWorked( + viewsDB.coll.explain("allPlansExecution").aggregate([{$limit: 1}, {$match: {pop: 3}}])); + assert.eq(explainPlan.stages[0].$cursor.queryPlanner.namespace, "views_aggregation.coll"); + assert(explainPlan.stages[0].$cursor.hasOwnProperty("executionStats")); + printjson(explainPlan.stages[0].$cursor.executionStats); + assert.eq(explainPlan.stages[0].$cursor.executionStats.nReturned, 5); + assert(explainPlan.stages[0].$cursor.executionStats.hasOwnProperty("allPlansExecution")); + + // The explain:true option should not work when paired with the explain shell helper. + assert.throws(function() { + viewsDB.popSortedView.explain("executionStats") + .aggregate([{$limit: 1}, {$match: {pop: 3}}], {explain: true}); + }); + // The remaining tests involve $lookup and $graphLookup. We cannot lookup into sharded // collections, so skip these tests if running in a sharded configuration. let isMasterResponse = assert.commandWorked(viewsDB.runCommand("isMaster")); diff --git a/jstests/core/views/views_count.js b/jstests/core/views/views_count.js index ddf97ce0bb2..932021e899f 100644 --- a/jstests/core/views/views_count.js +++ b/jstests/core/views/views_count.js @@ -53,6 +53,26 @@ assert.commandWorked(explainPlan); assert.eq(explainPlan["stages"][0]["$cursor"]["queryPlanner"]["namespace"], "views_count.coll"); + // Count with explicit explain modes works on a view. + explainPlan = + assert.commandWorked(lessThanSevenView.explain("queryPlanner").count({x: {$gte: 5}})); + assert.eq(explainPlan.stages[0].$cursor.queryPlanner.namespace, "views_count.coll"); + assert(!explainPlan.stages[0].$cursor.hasOwnProperty("executionStats")); + + explainPlan = + assert.commandWorked(lessThanSevenView.explain("executionStats").count({x: {$gte: 5}})); + assert.eq(explainPlan.stages[0].$cursor.queryPlanner.namespace, "views_count.coll"); + assert(explainPlan.stages[0].$cursor.hasOwnProperty("executionStats")); + assert.eq(explainPlan.stages[0].$cursor.executionStats.nReturned, 2); + assert(!explainPlan.stages[0].$cursor.executionStats.hasOwnProperty("allPlansExecution")); + + explainPlan = + assert.commandWorked(lessThanSevenView.explain("allPlansExecution").count({x: {$gte: 5}})); + assert.eq(explainPlan.stages[0].$cursor.queryPlanner.namespace, "views_count.coll"); + assert(explainPlan.stages[0].$cursor.hasOwnProperty("executionStats")); + assert.eq(explainPlan.stages[0].$cursor.executionStats.nReturned, 2); + assert(explainPlan.stages[0].$cursor.executionStats.hasOwnProperty("allPlansExecution")); + // Count with hint works on a view. assert.commandWorked(viewsDB.runCommand({count: "identityView", hint: "_id_"})); diff --git a/jstests/core/views/views_distinct.js b/jstests/core/views/views_distinct.js index b53a8e9e871..0a0b6002b15 100644 --- a/jstests/core/views/views_distinct.js +++ b/jstests/core/views/views_distinct.js @@ -68,6 +68,23 @@ assert.eq(explainPlan["stages"][0]["$cursor"]["queryPlanner"]["namespace"], "views_distinct.coll"); + // Distinct with explicit explain modes works on a view. + explainPlan = assert.commandWorked(largePopView.explain("queryPlanner").distinct("pop")); + assert.eq(explainPlan.stages[0].$cursor.queryPlanner.namespace, "views_distinct.coll"); + assert(!explainPlan.stages[0].$cursor.hasOwnProperty("executionStats")); + + explainPlan = assert.commandWorked(largePopView.explain("executionStats").distinct("pop")); + assert.eq(explainPlan.stages[0].$cursor.queryPlanner.namespace, "views_distinct.coll"); + assert(explainPlan.stages[0].$cursor.hasOwnProperty("executionStats")); + assert.eq(explainPlan.stages[0].$cursor.executionStats.nReturned, 2); + assert(!explainPlan.stages[0].$cursor.executionStats.hasOwnProperty("allPlansExecution")); + + explainPlan = assert.commandWorked(largePopView.explain("allPlansExecution").distinct("pop")); + assert.eq(explainPlan.stages[0].$cursor.queryPlanner.namespace, "views_distinct.coll"); + assert(explainPlan.stages[0].$cursor.hasOwnProperty("executionStats")); + assert.eq(explainPlan.stages[0].$cursor.executionStats.nReturned, 2); + assert(explainPlan.stages[0].$cursor.executionStats.hasOwnProperty("allPlansExecution")); + // Distinct commands fail when they try to change the collation of a view. assert.commandFailedWithCode( viewsDB.runCommand({distinct: "identityView", key: "state", collation: {locale: "en_US"}}), diff --git a/jstests/core/views/views_find.js b/jstests/core/views/views_find.js index c196e980ce5..da555e454b7 100644 --- a/jstests/core/views/views_find.js +++ b/jstests/core/views/views_find.js @@ -72,6 +72,23 @@ // Views support find with explain. assert.commandWorked(viewsDB.identityView.find().explain()); + // Find with explicit explain modes works on a view. + let explainPlan = assert.commandWorked(viewsDB.identityView.find().explain("queryPlanner")); + assert.eq(explainPlan.stages[0].$cursor.queryPlanner.namespace, "views_find.coll"); + assert(!explainPlan.stages[0].$cursor.hasOwnProperty("executionStats")); + + explainPlan = assert.commandWorked(viewsDB.identityView.find().explain("executionStats")); + assert.eq(explainPlan.stages[0].$cursor.queryPlanner.namespace, "views_find.coll"); + assert(explainPlan.stages[0].$cursor.hasOwnProperty("executionStats")); + assert.eq(explainPlan.stages[0].$cursor.executionStats.nReturned, 5); + assert(!explainPlan.stages[0].$cursor.executionStats.hasOwnProperty("allPlansExecution")); + + explainPlan = assert.commandWorked(viewsDB.identityView.find().explain("allPlansExecution")); + assert.eq(explainPlan.stages[0].$cursor.queryPlanner.namespace, "views_find.coll"); + assert(explainPlan.stages[0].$cursor.hasOwnProperty("executionStats")); + assert.eq(explainPlan.stages[0].$cursor.executionStats.nReturned, 5); + assert(explainPlan.stages[0].$cursor.executionStats.hasOwnProperty("allPlansExecution")); + // Only simple 0 or 1 projections are allowed on views. assert.writeOK(viewsDB.coll.insert({arr: [{x: 1}]})); assert.commandFailedWithCode( |