summaryrefslogtreecommitdiff
path: root/jstests/noPassthrough/explain_output_truncation.js
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-11 15:07:17 +0000
commit4fc3991bf64b33ca5f5237722bc563f8eb1a552a (patch)
tree1e4479511c8eda6c40e89ff4ed94a5d8b8b03fd6 /jstests/noPassthrough/explain_output_truncation.js
parent9c17236ba41ecfa46d3404ab92377893092b8351 (diff)
downloadmongo-4fc3991bf64b33ca5f5237722bc563f8eb1a552a.tar.gz
SERVER-54710 Improve checks for overlarge BSON when generating explain output
Diffstat (limited to 'jstests/noPassthrough/explain_output_truncation.js')
-rw-r--r--jstests/noPassthrough/explain_output_truncation.js53
1 files changed, 53 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..563bbaddbda
--- /dev/null
+++ b/jstests/noPassthrough/explain_output_truncation.js
@@ -0,0 +1,53 @@
+/**
+ * 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 winningPlan = getWinningPlan(explain.queryPlanner);
+let sortStage = getPlanStage(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's winning plan 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(winningPlan) - 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(getWinningPlan(explain.queryPlanner), "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);
+}());