summaryrefslogtreecommitdiff
path: root/jstests
diff options
context:
space:
mode:
authorDavid Storch <david.storch@mongodb.com>2021-03-11 14:31:02 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-03-24 22:49:55 +0000
commitfc232126bd406e6c85ec45b869c88d7a238e60c5 (patch)
tree4cdff0ad1b14be2907ca27f3fb92a104f3b12948 /jstests
parent2d30db50b66fb8c31432b6f622e010a5b7bce256 (diff)
downloadmongo-fc232126bd406e6c85ec45b869c88d7a238e60c5.tar.gz
SERVER-54710 Improve checks for overlarge BSON when generating explain output
(cherry picked from commit 4fc3991bf64b33ca5f5237722bc563f8eb1a552a) (cherry picked from commit 754b0efe8549fe2d5fa2847676985709c60412a7)
Diffstat (limited to 'jstests')
-rw-r--r--jstests/noPassthrough/explain_output_truncation.js52
1 files changed, 52 insertions, 0 deletions
diff --git a/jstests/noPassthrough/explain_output_truncation.js b/jstests/noPassthrough/explain_output_truncation.js
new file mode 100644
index 00000000000..60fbc5d7d3b
--- /dev/null
+++ b/jstests/noPassthrough/explain_output_truncation.js
@@ -0,0 +1,52 @@
+/**
+ * Test that explain output is correctly truncated when it grows too large.
+ */
+(function() {
+"use strict";
+
+load("jstests/libs/analyze_plan.js");
+
+const dbName = "test";
+const collName = jsTestName();
+const explainSizeParam = "internalQueryExplainSizeThresholdBytes";
+
+const conn = MongoRunner.runMongod({});
+assert.neq(conn, null, "mongod failed to start up");
+
+const testDb = conn.getDB(dbName);
+const coll = testDb[collName];
+coll.drop();
+
+assert.commandWorked(coll.createIndex({a: 1}));
+
+// Explain output should show a simple IXSCAN => FETCH => SORT plan with no truncation.
+let explain = coll.find({a: 1, b: 1}).sort({c: 1}).explain();
+let sortStage = getPlanStage(explain.queryPlanner.winningPlan, "SORT");
+assert.neq(sortStage, null, explain);
+let fetchStage = getPlanStage(sortStage, "FETCH");
+assert.neq(fetchStage, null, explain);
+let ixscanStage = getPlanStage(sortStage, "IXSCAN");
+assert.neq(ixscanStage, null, explain);
+
+// Calculate the size of explain output without the index scan. If the explain size threshold is set
+// near this amount, then the IXSCAN stage will need to be truncated.
+assert.neq(ixscanStage, null, explain);
+const newExplainSize = Object.bsonsize(explain.queryPlanner) - Object.bsonsize(ixscanStage) - 10;
+assert.gt(newExplainSize, 0);
+
+// Reduce the size at which we start truncating explain output. If we explain the same query again,
+// then the FETCH stage should be present, but the IXSCAN stage should be truncated.
+assert.commandWorked(testDb.adminCommand({setParameter: 1, [explainSizeParam]: newExplainSize}));
+
+explain = coll.find({a: 1, b: 1}).sort({c: 1}).explain();
+assert(planHasStage(testDb, explain, "SORT"), explain);
+fetchStage = getPlanStage(explain.queryPlanner.winningPlan, "FETCH");
+assert.neq(fetchStage, null, explain);
+assert(fetchStage.hasOwnProperty("inputStage"), explain);
+assert(fetchStage.inputStage.hasOwnProperty("warning"), explain);
+assert.eq(
+ fetchStage.inputStage.warning, "stats tree exceeded BSON size limit for explain", explain);
+assert(!planHasStage(testDb, explain, "IXSCAN"), explain);
+
+MongoRunner.stopMongod(conn);
+}());