diff options
author | David Storch <david.storch@10gen.com> | 2017-09-27 17:39:31 -0400 |
---|---|---|
committer | David Storch <david.storch@10gen.com> | 2017-09-29 12:15:08 -0400 |
commit | eeb0fa45854de25cd57368585f6b4db10c34ce30 (patch) | |
tree | af588e4c4ea3155ee305984f0eefda88d3b4eed9 /src | |
parent | 0385e6b9514f7856cfbcd4f850930ebbd0895021 (diff) | |
download | mongo-eeb0fa45854de25cd57368585f6b4db10c34ce30.tar.gz |
SERVER-30582 Permit 'local' readConcern for aggregation explain.
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/commands/run_aggregate.cpp | 9 | ||||
-rw-r--r-- | src/mongo/db/pipeline/aggregation_request.cpp | 7 | ||||
-rw-r--r-- | src/mongo/db/pipeline/aggregation_request_test.cpp | 20 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_aggregate.cpp | 4 | ||||
-rw-r--r-- | src/mongo/shell/session.js | 7 |
5 files changed, 26 insertions, 21 deletions
diff --git a/src/mongo/db/commands/run_aggregate.cpp b/src/mongo/db/commands/run_aggregate.cpp index 1077d65a0d2..2ad882ef2f5 100644 --- a/src/mongo/db/commands/run_aggregate.cpp +++ b/src/mongo/db/commands/run_aggregate.cpp @@ -57,6 +57,7 @@ #include "mongo/db/query/get_executor.h" #include "mongo/db/query/plan_summary_stats.h" #include "mongo/db/repl/oplog.h" +#include "mongo/db/repl/read_concern_args.h" #include "mongo/db/service_context.h" #include "mongo/db/storage/storage_options.h" #include "mongo/db/views/view.h" @@ -297,6 +298,14 @@ Status runAggregate(OperationContext* opCtx, // For operations on views, this will be the underlying namespace. NamespaceString nss = request.getNamespaceString(); + if (request.getExplain() && + repl::ReadConcernArgs::get(opCtx).getLevel() != repl::ReadConcernLevel::kLocalReadConcern) { + return {ErrorCodes::InvalidOptions, + str::stream() << "Explain for the aggregate command " + "does not support non-local " + "readConcern levels"}; + } + // Parse the user-specified collation, if any. std::unique_ptr<CollatorInterface> userSpecifiedCollator = request.getCollation().isEmpty() ? nullptr diff --git a/src/mongo/db/pipeline/aggregation_request.cpp b/src/mongo/db/pipeline/aggregation_request.cpp index 7c0e6401cd2..88bb2352a60 100644 --- a/src/mongo/db/pipeline/aggregation_request.cpp +++ b/src/mongo/db/pipeline/aggregation_request.cpp @@ -254,13 +254,6 @@ StatusWith<AggregationRequest> AggregationRequest::parseFromBSON( << "' option is required, except for aggregate with the explain argument"}; } - if (request.getExplain() && !request.getReadConcern().isEmpty()) { - return {ErrorCodes::FailedToParse, - str::stream() << "Aggregation explain does not support the '" - << repl::ReadConcernArgs::kReadConcernFieldName - << "' option"}; - } - if (request.getExplain() && cmdObj[WriteConcernOptions::kWriteConcernField]) { return {ErrorCodes::FailedToParse, str::stream() << "Aggregation explain does not support the'" diff --git a/src/mongo/db/pipeline/aggregation_request_test.cpp b/src/mongo/db/pipeline/aggregation_request_test.cpp index 312e8158121..112d1d3fb17 100644 --- a/src/mongo/db/pipeline/aggregation_request_test.cpp +++ b/src/mongo/db/pipeline/aggregation_request_test.cpp @@ -126,6 +126,19 @@ TEST(AggregationRequestTest, ShouldParseWithSeparateQueryPlannerExplainModeArgAn ASSERT_EQ(request.getBatchSize(), 10); } +TEST(AggregationRequestTest, ShouldParseExplainFlagWithReadConcern) { + NamespaceString nss("a.collection"); + // Non-local readConcern should not be allowed with the explain flag, but this is checked + // elsewhere to avoid having to parse the readConcern in AggregationRequest. + const BSONObj inputBson = + fromjson("{pipeline: [], explain: true, readConcern: {level: 'majority'}}"); + auto request = unittest::assertGet(AggregationRequest::parseFromBSON(nss, inputBson)); + ASSERT_TRUE(request.getExplain()); + ASSERT_BSONOBJ_EQ(request.getReadConcern(), + BSON("level" + << "majority")); +} + // // Serialization // @@ -399,13 +412,6 @@ TEST(AggregationRequestTest, ShouldRejectExplainFalseWithSeparateExplainArg) { .getStatus()); } -TEST(AggregationRequestTest, ShouldRejectExplainWithReadConcernMajority) { - NamespaceString nss("a.collection"); - const BSONObj inputBson = - fromjson("{pipeline: [], explain: true, readConcern: {level: 'majority'}}"); - ASSERT_NOT_OK(AggregationRequest::parseFromBSON(nss, inputBson).getStatus()); -} - TEST(AggregationRequestTest, ShouldRejectExplainExecStatsVerbosityWithReadConcernMajority) { NamespaceString nss("a.collection"); const BSONObj inputBson = fromjson("{pipeline: [], readConcern: {level: 'majority'}}"); diff --git a/src/mongo/s/commands/cluster_aggregate.cpp b/src/mongo/s/commands/cluster_aggregate.cpp index a70227b99a4..864e9d457ac 100644 --- a/src/mongo/s/commands/cluster_aggregate.cpp +++ b/src/mongo/s/commands/cluster_aggregate.cpp @@ -80,6 +80,10 @@ Document wrapAggAsExplain(Document aggregateCommand, ExplainOptions::Verbosity v explainCommandBuilder[QueryRequest::kUnwrappedReadPrefField] = Value(aggregateCommand[QueryRequest::kUnwrappedReadPrefField]); + // readConcern needs to be promoted to the top-level of the request. + explainCommandBuilder[repl::ReadConcernArgs::kReadConcernFieldName] = + Value(aggregateCommand[repl::ReadConcernArgs::kReadConcernFieldName]); + // Add explain command options. for (auto&& explainOption : ExplainOptions::toBSON(verbosity)) { explainCommandBuilder[explainOption.fieldNameStringData()] = Value(explainOption); diff --git a/src/mongo/shell/session.js b/src/mongo/shell/session.js index 7db8f47fbc2..aa1d56afb01 100644 --- a/src/mongo/shell/session.js +++ b/src/mongo/shell/session.js @@ -132,13 +132,6 @@ var { return false; } - if (cmdName === "aggregate" && cmdObjUnwrapped.explain) { - // TODO SERVER-30582: Aggregation's explain doesn't support the "readConcern" - // option. Note that an aggregation with a $out stage as its last stage still - // supports a read concern level of "local". - return false; - } - if (cmdName === "explain") { return kCommandsThatSupportReadConcern.has(Object.keys(cmdObjUnwrapped.explain)[0]); } |