summaryrefslogtreecommitdiff
path: root/jstests/core
diff options
context:
space:
mode:
Diffstat (limited to 'jstests/core')
-rw-r--r--jstests/core/explain_agg_write_concern.js64
-rw-r--r--jstests/core/views/views_aggregation.js42
-rw-r--r--jstests/core/views/views_count.js20
-rw-r--r--jstests/core/views/views_distinct.js17
-rw-r--r--jstests/core/views/views_find.js17
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(