summaryrefslogtreecommitdiff
path: root/jstests/core/query/explain/explain_multi_plan.js
diff options
context:
space:
mode:
Diffstat (limited to 'jstests/core/query/explain/explain_multi_plan.js')
-rw-r--r--jstests/core/query/explain/explain_multi_plan.js82
1 files changed, 82 insertions, 0 deletions
diff --git a/jstests/core/query/explain/explain_multi_plan.js b/jstests/core/query/explain/explain_multi_plan.js
new file mode 100644
index 00000000000..45484510196
--- /dev/null
+++ b/jstests/core/query/explain/explain_multi_plan.js
@@ -0,0 +1,82 @@
+// @tags: [
+// # Cannot implicitly shard accessed collections because of following errmsg: A single
+// # update/delete on a sharded collection must contain an exact match on _id or contain the shard
+// # key.
+// assumes_unsharded_collection,
+// # TODO SERVER-30466
+// does_not_support_causal_consistency,
+// ]
+
+/**
+ * Tests running explain on a variety of explainable commands (find, update, remove, etc.) when
+ * there are multiple plans available. This is a regression test for SERVER-20849 and SERVER-21376.
+ */
+(function() {
+"use strict";
+var coll = db.explainMultiPlan;
+coll.drop();
+
+// Create indices to ensure there are multiple plans available.
+assert.commandWorked(coll.createIndex({a: 1, b: 1}));
+assert.commandWorked(coll.createIndex({a: 1, b: -1}));
+
+// Insert some data to work with.
+var bulk = coll.initializeOrderedBulkOp();
+var nDocs = 100;
+for (var i = 0; i < nDocs; ++i) {
+ bulk.insert({a: i, b: nDocs - i});
+}
+bulk.execute();
+
+// SERVER-20849: The following commands should not crash the server.
+assert.doesNotThrow(function() {
+ coll.explain("allPlansExecution").update({a: {$gte: 1}}, {$set: {x: 0}});
+});
+
+assert.doesNotThrow(function() {
+ coll.explain("allPlansExecution").remove({a: {$gte: 1}});
+});
+
+assert.doesNotThrow(function() {
+ coll.explain("allPlansExecution").findAndModify({query: {a: {$gte: 1}}, remove: true});
+});
+
+assert.doesNotThrow(function() {
+ coll.explain("allPlansExecution").findAndModify({query: {a: {$gte: 1}}, update: {y: 1}});
+});
+
+assert.doesNotThrow(function() {
+ coll.explain("allPlansExecution").find({a: {$gte: 1}}).finish();
+});
+
+assert.doesNotThrow(function() {
+ coll.explain("allPlansExecution").count({a: {$gte: 1}});
+});
+
+assert.doesNotThrow(function() {
+ coll.explain("allPlansExecution").distinct("a", {a: {$gte: 1}});
+});
+
+// SERVER-21376: Make sure the 'rejectedPlans' field is filled in appropriately.
+function assertHasRejectedPlans(explainOutput) {
+ var queryPlannerOutput = explainOutput.queryPlanner;
+
+ // The 'rejectedPlans' section will be in a different place if passed through a mongos.
+ if ("SINGLE_SHARD" == queryPlannerOutput.winningPlan.stage) {
+ var shards = queryPlannerOutput.winningPlan.shards;
+ shards.forEach(function assertShardHasRejectedPlans(shard) {
+ assert.gt(shard.rejectedPlans.length, 0);
+ });
+ } else {
+ assert.gt(queryPlannerOutput.rejectedPlans.length, 0);
+ }
+}
+
+var res = coll.explain("queryPlanner").find({a: {$gte: 1}}).finish();
+assert.commandWorked(res);
+assertHasRejectedPlans(res);
+
+res = coll.explain("executionStats").find({a: {$gte: 1}}).finish();
+assert.commandWorked(res);
+assertHasRejectedPlans(res);
+}());