summaryrefslogtreecommitdiff
path: root/src/mongo/db/query/query_request_helper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/query/query_request_helper.cpp')
-rw-r--r--src/mongo/db/query/query_request_helper.cpp155
1 files changed, 2 insertions, 153 deletions
diff --git a/src/mongo/db/query/query_request_helper.cpp b/src/mongo/db/query/query_request_helper.cpp
index 7db63a1427b..a8405f00e69 100644
--- a/src/mongo/db/query/query_request_helper.cpp
+++ b/src/mongo/db/query/query_request_helper.cpp
@@ -38,6 +38,8 @@
#include "mongo/bson/simple_bsonobj_comparator.h"
#include "mongo/db/commands/test_commands_enabled.h"
#include "mongo/db/dbmessage.h"
+#include "mongo/db/matcher/expression_geo.h"
+#include "mongo/db/query/canonical_query.h"
namespace mongo {
@@ -414,158 +416,5 @@ StatusWith<std::unique_ptr<FindCommandRequest>> fromLegacyQuery(NamespaceStringO
return std::move(findCommand);
}
-StatusWith<BSONObj> asAggregationCommand(const FindCommandRequest& findCommand) {
- BSONObjBuilder aggregationBuilder;
-
- // The find command will translate away ntoreturn above this layer.
- tassert(5746106, "ntoreturn should not be set in the findCommand", !findCommand.getNtoreturn());
-
- // First, check if this query has options that are not supported in aggregation.
- if (!findCommand.getMin().isEmpty()) {
- return {ErrorCodes::InvalidPipelineOperator,
- str::stream() << "Option " << FindCommandRequest::kMinFieldName
- << " not supported in aggregation."};
- }
- if (!findCommand.getMax().isEmpty()) {
- return {ErrorCodes::InvalidPipelineOperator,
- str::stream() << "Option " << FindCommandRequest::kMaxFieldName
- << " not supported in aggregation."};
- }
- if (findCommand.getReturnKey()) {
- return {ErrorCodes::InvalidPipelineOperator,
- str::stream() << "Option " << FindCommandRequest::kReturnKeyFieldName
- << " not supported in aggregation."};
- }
- if (findCommand.getShowRecordId()) {
- return {ErrorCodes::InvalidPipelineOperator,
- str::stream() << "Option " << FindCommandRequest::kShowRecordIdFieldName
- << " not supported in aggregation."};
- }
- if (findCommand.getTailable()) {
- return {ErrorCodes::InvalidPipelineOperator,
- "Tailable cursors are not supported in aggregation."};
- }
- if (findCommand.getNoCursorTimeout()) {
- return {ErrorCodes::InvalidPipelineOperator,
- str::stream() << "Option " << FindCommandRequest::kNoCursorTimeoutFieldName
- << " not supported in aggregation."};
- }
- if (findCommand.getAllowPartialResults()) {
- return {ErrorCodes::InvalidPipelineOperator,
- str::stream() << "Option " << FindCommandRequest::kAllowPartialResultsFieldName
- << " not supported in aggregation."};
- }
- if (findCommand.getSort()[query_request_helper::kNaturalSortField]) {
- return {ErrorCodes::InvalidPipelineOperator,
- str::stream() << "Sort option " << query_request_helper::kNaturalSortField
- << " not supported in aggregation."};
- }
- // The aggregation command normally does not support the 'singleBatch' option, but we make a
- // special exception if 'limit' is set to 1.
- if (findCommand.getSingleBatch() && findCommand.getLimit().value_or(0) != 1LL) {
- return {ErrorCodes::InvalidPipelineOperator,
- str::stream() << "Option " << FindCommandRequest::kSingleBatchFieldName
- << " not supported in aggregation."};
- }
- if (findCommand.getReadOnce()) {
- return {ErrorCodes::InvalidPipelineOperator,
- str::stream() << "Option " << FindCommandRequest::kReadOnceFieldName
- << " not supported in aggregation."};
- }
-
- if (findCommand.getAllowSpeculativeMajorityRead()) {
- return {ErrorCodes::InvalidPipelineOperator,
- str::stream() << "Option "
- << FindCommandRequest::kAllowSpeculativeMajorityReadFieldName
- << " not supported in aggregation."};
- }
-
- if (findCommand.getRequestResumeToken()) {
- return {ErrorCodes::InvalidPipelineOperator,
- str::stream() << "Option " << FindCommandRequest::kRequestResumeTokenFieldName
- << " not supported in aggregation."};
- }
-
- if (!findCommand.getResumeAfter().isEmpty()) {
- return {ErrorCodes::InvalidPipelineOperator,
- str::stream() << "Option " << FindCommandRequest::kResumeAfterFieldName
- << " not supported in aggregation."};
- }
-
- // Now that we've successfully validated this QR, begin building the aggregation command.
- aggregationBuilder.append("aggregate",
- findCommand.getNamespaceOrUUID().nss()
- ? findCommand.getNamespaceOrUUID().nss()->coll()
- : "");
-
- // Construct an aggregation pipeline that finds the equivalent documents to this query request.
- BSONArrayBuilder pipelineBuilder(aggregationBuilder.subarrayStart("pipeline"));
- if (!findCommand.getFilter().isEmpty()) {
- BSONObjBuilder matchBuilder(pipelineBuilder.subobjStart());
- matchBuilder.append("$match", findCommand.getFilter());
- matchBuilder.doneFast();
- }
- if (!findCommand.getSort().isEmpty()) {
- BSONObjBuilder sortBuilder(pipelineBuilder.subobjStart());
- sortBuilder.append("$sort", findCommand.getSort());
- sortBuilder.doneFast();
- }
- if (findCommand.getSkip()) {
- BSONObjBuilder skipBuilder(pipelineBuilder.subobjStart());
- skipBuilder.append("$skip", *findCommand.getSkip());
- skipBuilder.doneFast();
- }
- if (findCommand.getLimit()) {
- BSONObjBuilder limitBuilder(pipelineBuilder.subobjStart());
- limitBuilder.append("$limit", *findCommand.getLimit());
- limitBuilder.doneFast();
- }
- if (!findCommand.getProjection().isEmpty()) {
- BSONObjBuilder projectBuilder(pipelineBuilder.subobjStart());
- projectBuilder.append("$project", findCommand.getProjection());
- projectBuilder.doneFast();
- }
- pipelineBuilder.doneFast();
-
- // The aggregation 'cursor' option is always set, regardless of the presence of batchSize.
- BSONObjBuilder batchSizeBuilder(aggregationBuilder.subobjStart("cursor"));
- if (findCommand.getBatchSize()) {
- batchSizeBuilder.append(FindCommandRequest::kBatchSizeFieldName,
- *findCommand.getBatchSize());
- }
- batchSizeBuilder.doneFast();
-
- // Other options.
- aggregationBuilder.append("collation", findCommand.getCollation());
- int maxTimeMS = findCommand.getMaxTimeMS() ? static_cast<int>(*findCommand.getMaxTimeMS()) : 0;
- if (maxTimeMS > 0) {
- aggregationBuilder.append(cmdOptionMaxTimeMS, maxTimeMS);
- }
- if (!findCommand.getHint().isEmpty()) {
- aggregationBuilder.append(FindCommandRequest::kHintFieldName, findCommand.getHint());
- }
- if (findCommand.getReadConcern()) {
- aggregationBuilder.append("readConcern", *findCommand.getReadConcern());
- }
- if (!findCommand.getUnwrappedReadPref().isEmpty()) {
- aggregationBuilder.append(FindCommandRequest::kUnwrappedReadPrefFieldName,
- findCommand.getUnwrappedReadPref());
- }
- if (findCommand.getAllowDiskUse()) {
- aggregationBuilder.append(FindCommandRequest::kAllowDiskUseFieldName,
- static_cast<bool>(findCommand.getAllowDiskUse()));
- }
- if (findCommand.getLegacyRuntimeConstants()) {
- BSONObjBuilder rtcBuilder(
- aggregationBuilder.subobjStart(FindCommandRequest::kLegacyRuntimeConstantsFieldName));
- findCommand.getLegacyRuntimeConstants()->serialize(&rtcBuilder);
- rtcBuilder.doneFast();
- }
- if (findCommand.getLet()) {
- aggregationBuilder.append(FindCommandRequest::kLetFieldName, *findCommand.getLet());
- }
- return StatusWith<BSONObj>(aggregationBuilder.obj());
-}
-
} // namespace query_request_helper
} // namespace mongo