-
Type: Bug
-
Resolution: Fixed
-
Priority: Minor - P4
-
Affects Version/s: 5.0.3-rc0, 4.2.17, 4.4.10
-
Component/s: None
-
None
-
Fully Compatible
-
ALL
-
23
In this mongos explain logic, we continue writing to a BSONArrayBuilder after calling done() on it, and further, after opening a new BSONArrayBuilder. This can cause mongos to return strange (and arguably, garbage) results, where a BSON array's first key is "1" instead of "0." We should change this logic in cluster_explain.cpp to use BSONArrayBuilder correctly.
I've copied and pasted the code below and added my notes:
BSONArrayBuilder execShardsBuilder(executionStagesBob.subarrayStart("shards")); for (size_t i = 0; i < shardResponses.size(); i++) { auto responseData = shardResponses[i].swResponse.getValue().data; BSONObjBuilder singleShardBob(execShardsBuilder.subobjStart()); BSONObj execStats = responseData["executionStats"].Obj(); singleShardBob.append("shardName", shardResponses[i].shardId.toString()); appendElementsIfRoom(&singleShardBob, execStats); singleShardBob.doneFast(); } execShardsBuilder.doneFast(); executionStagesBob.doneFast(); if (!firstShardResponseData["executionStats"].Obj().hasField("allPlansExecution")) { // The shards don't have execution stats for all plans, so we're done. executionStatsBob.doneFast(); return; } // Add the allPlans stats from each shard. BSONArrayBuilder allPlansExecBob(executionStatsBob.subarrayStart("allPlansExecution")); // NOTE(ianb): Notice how 'allPlansExecBob' is never used. for (size_t i = 0; i < shardResponses.size(); i++) { auto responseData = shardResponses[i].swResponse.getValue().data; // NOTE(ianb): Notice how we're using 'execShardsBuilder' even though we already called done() on that above. BSONObjBuilder singleShardBob(execShardsBuilder.subobjStart()); singleShardBob.append("shardName", shardResponses[i].shardId.toString()); BSONObj execStats = responseData["executionStats"].Obj(); vector<BSONElement> allPlans = execStats["allPlansExecution"].Array(); BSONArrayBuilder innerArrayBob(singleShardBob.subarrayStart("allPlans")); for (size_t j = 0; j < allPlans.size(); j++) { appendToArrayIfRoom(&innerArrayBob, allPlans[j]); } innerArrayBob.done(); singleShardBob.doneFast(); } allPlansExecBob.doneFast(); executionStatsBob.doneFast(); }
- related to
-
SERVER-60910 Make BSONArrayBuilder/BSONObjBuilder behavior crash on common mis-uses
- Closed