summaryrefslogtreecommitdiff
path: root/src/mongo/s/query/cluster_aggregate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/s/query/cluster_aggregate.cpp')
-rw-r--r--src/mongo/s/query/cluster_aggregate.cpp45
1 files changed, 22 insertions, 23 deletions
diff --git a/src/mongo/s/query/cluster_aggregate.cpp b/src/mongo/s/query/cluster_aggregate.cpp
index 9149ae33530..2cbb292adc8 100644
--- a/src/mongo/s/query/cluster_aggregate.cpp
+++ b/src/mongo/s/query/cluster_aggregate.cpp
@@ -270,9 +270,28 @@ Status appendExplainResults(sharded_agg_helpers::DispatchShardPipelineResults&&
BSONObjBuilder shardExplains(result->subobjStart("shards"));
for (const auto& shardResult : dispatchResults.remoteExplainOutput) {
invariant(shardResult.shardHostAndPort);
- shardExplains.append(shardResult.shardId.toString(),
- BSON("host" << shardResult.shardHostAndPort->toString() << "stages"
- << shardResult.swResponse.getValue().data["stages"]));
+
+ uassertStatusOK(shardResult.swResponse.getStatus());
+ uassertStatusOK(getStatusFromCommandResult(shardResult.swResponse.getValue().data));
+
+ auto shardId = shardResult.shardId.toString();
+ const auto& data = shardResult.swResponse.getValue().data;
+ BSONObjBuilder explain(shardExplains.subobjStart(shardId));
+ explain << "host" << shardResult.shardHostAndPort->toString();
+ if (auto stagesElement = data["stages"]) {
+ explain << "stages" << stagesElement;
+ } else {
+ auto queryPlannerElement = data["queryPlanner"];
+ uassert(51157,
+ str::stream() << "Malformed explain response received from shard " << shardId
+ << ": "
+ << data.toString(),
+ queryPlannerElement);
+ explain << "queryPlanner" << queryPlannerElement;
+ if (auto executionStatsElement = data["executionStats"]) {
+ explain << "executionStats" << executionStatsElement;
+ }
+ }
}
return Status::OK();
@@ -812,7 +831,6 @@ Status ClusterAggregate::runAggregate(OperationContext* opCtx,
// If the operation is an explain, then we verify that it succeeded on all targeted shards,
// write the results to the output builder, and return immediately.
if (expCtx->explain) {
- uassertAllShardsSupportExplain(shardDispatchResults.remoteExplainOutput);
return appendExplainResults(std::move(shardDispatchResults), expCtx, result);
}
@@ -853,25 +871,6 @@ Status ClusterAggregate::runAggregate(OperationContext* opCtx,
privileges);
}
-void ClusterAggregate::uassertAllShardsSupportExplain(
- const std::vector<AsyncRequestsSender::Response>& shardResults) {
- for (const auto& result : shardResults) {
- auto status = result.swResponse.getStatus();
- if (status.isOK()) {
- status = getStatusFromCommandResult(result.swResponse.getValue().data);
- }
- uassert(17403,
- str::stream() << "Shard " << result.shardId.toString() << " failed: "
- << causedBy(status),
- status.isOK());
-
- uassert(17404,
- str::stream() << "Shard " << result.shardId.toString()
- << " does not support $explain",
- result.swResponse.getValue().data.hasField("stages"));
- }
-}
-
Status ClusterAggregate::aggPassthrough(OperationContext* opCtx,
const Namespaces& namespaces,
const ShardId& shardId,