summaryrefslogtreecommitdiff
path: root/jstests/core/explain_count.js
diff options
context:
space:
mode:
Diffstat (limited to 'jstests/core/explain_count.js')
-rw-r--r--jstests/core/explain_count.js110
1 files changed, 110 insertions, 0 deletions
diff --git a/jstests/core/explain_count.js b/jstests/core/explain_count.js
new file mode 100644
index 00000000000..d774a8745dc
--- /dev/null
+++ b/jstests/core/explain_count.js
@@ -0,0 +1,110 @@
+// Test running explains on count commands.
+
+var collName = "jstests_explain_count";
+var t = db[collName];
+t.drop();
+
+/**
+ * Given explain output 'explain' at executionStats level verbosity,
+ * confirms that the root stage is COUNT and that the result of the
+ * count is equal to 'nCounted'.
+ */
+function checkCountExplain(explain, nCounted) {
+ printjson(explain);
+ var rootStage = explain.executionStats.executionStages;
+ assert.eq(rootStage.stage, "COUNT", "root stage is not COUNT");
+ assert.eq(rootStage.nCounted, nCounted, "wrong count result");
+}
+
+// Collection does not exist.
+assert.eq(0, t.count());
+var explain = db.runCommand({explain: {count: collName}, verbosity: "executionStats"});
+checkCountExplain(explain, 0);
+
+// Collection does not exist with skip, limit, and/or query.
+assert.eq(0, db.runCommand({count: collName, skip: 3}).n);
+explain = db.runCommand({explain: {count: collName, skip: 3}, verbosity: "executionStats"});
+checkCountExplain(explain, 0);
+
+assert.eq(0, db.runCommand({count: collName, limit: 3}).n);
+explain = db.runCommand({explain: {count: collName, limit: 3}, verbosity: "executionStats"});
+checkCountExplain(explain, 0);
+
+assert.eq(0, db.runCommand({count: collName, limit: -3}).n);
+explain = db.runCommand({explain: {count: collName, limit: -3}, verbosity: "executionStats"});
+checkCountExplain(explain, 0);
+
+assert.eq(0, db.runCommand({count: collName, limit: -3, skip: 4}).n);
+explain = db.runCommand({explain: {count: collName, limit: -3, skip: 4},
+ verbosity: "executionStats"});
+checkCountExplain(explain, 0);
+
+assert.eq(0, db.runCommand({count: collName, query: {a: 1}, limit: -3, skip: 4}).n);
+explain = db.runCommand({explain: {count: collName, query: {a: 1}, limit: -3, skip: 4},
+ verbosity: "executionStats"});
+checkCountExplain(explain, 0);
+
+// Now add a bit of data to the collection.
+t.ensureIndex({a: 1});
+for (var i = 0; i < 10; i++) {
+ t.insert({_id: i, a: 1});
+}
+
+// Trivial count with no skip, limit, or query.
+assert.eq(10, t.count());
+explain = db.runCommand({explain: {count: collName}, verbosity: "executionStats"});
+checkCountExplain(explain, 10);
+
+// Trivial count with skip.
+assert.eq(7, db.runCommand({count: collName, skip: 3}).n);
+explain = db.runCommand({explain: {count: collName, skip: 3}, verbosity: "executionStats"});
+checkCountExplain(explain, 7);
+
+// Trivial count with limit.
+assert.eq(3, db.runCommand({count: collName, limit: 3}).n);
+explain = db.runCommand({explain: {count: collName, limit: 3}, verbosity: "executionStats"});
+checkCountExplain(explain, 3);
+
+// Trivial count with negative limit.
+assert.eq(3, db.runCommand({count: collName, limit: -3}).n);
+explain = db.runCommand({explain: {count: collName, limit: -3}, verbosity: "executionStats"});
+checkCountExplain(explain, 3);
+
+// Trivial count with both limit and skip.
+assert.eq(3, db.runCommand({count: collName, limit: -3, skip: 4}).n);
+explain = db.runCommand({explain: {count: collName, limit: -3, skip: 4},
+ verbosity: "executionStats"});
+checkCountExplain(explain, 3);
+
+// With a query.
+assert.eq(10, db.runCommand({count: collName, query: {a: 1}}).n);
+explain = db.runCommand({explain: {count: collName, query: {a: 1}},
+ verbosity: "executionStats"});
+checkCountExplain(explain, 10);
+
+// With a query and skip.
+assert.eq(7, db.runCommand({count: collName, query: {a: 1}, skip: 3}).n);
+explain = db.runCommand({explain: {count: collName, query: {a: 1}, skip: 3},
+ verbosity: "executionStats"});
+checkCountExplain(explain, 7);
+
+// With a query and limit.
+assert.eq(3, db.runCommand({count: collName, query: {a: 1}, limit: 3}).n);
+explain = db.runCommand({explain: {count: collName, query: {a: 1}, limit: 3},
+ verbosity: "executionStats"});
+checkCountExplain(explain, 3);
+
+// Insert one more doc for the last few tests.
+t.insert({a: 2});
+
+// Case where all results are skipped.
+assert.eq(0, db.runCommand({count: collName, query: {a: 2}, skip: 2}).n);
+explain = db.runCommand({explain: {count: collName, query: {a: 2}, skip: 2},
+ verbosity: "executionStats"});
+checkCountExplain(explain, 0);
+
+// Case where we have a limit, but we don't hit it.
+assert.eq(1, db.runCommand({count: collName, query: {a: 2}, limit: 2}).n);
+explain = db.runCommand({explain: {count: collName, query: {a: 2}, limit: 2},
+ verbosity: "executionStats"});
+checkCountExplain(explain, 1);