Details
-
Bug
-
Resolution: Fixed
-
Minor - P4
-
5.0.3-rc0, 4.2.17, 4.4.10
-
None
-
None
-
Fully Compatible
-
ALL
-
23
Description
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();
|
}
|
Attachments
Issue Links
- related to
-
SERVER-60910 Make BSONArrayBuilder/BSONObjBuilder behavior crash on common mis-uses
-
- Backlog
-