diff options
Diffstat (limited to 'src/mongo/db/pipeline/document_source_sort.cpp')
| -rw-r--r-- | src/mongo/db/pipeline/document_source_sort.cpp | 71 |
1 files changed, 28 insertions, 43 deletions
diff --git a/src/mongo/db/pipeline/document_source_sort.cpp b/src/mongo/db/pipeline/document_source_sort.cpp index 235f98039df..2c07c43c501 100644 --- a/src/mongo/db/pipeline/document_source_sort.cpp +++ b/src/mongo/db/pipeline/document_source_sort.cpp @@ -44,7 +44,6 @@ #include "mongo/db/pipeline/lite_parsed_document_source.h" #include "mongo/db/pipeline/skip_and_limit.h" #include "mongo/db/query/collation/collation_index_key.h" -#include "mongo/db/query/query_shape/serialization_options.h" #include "mongo/db/stats/resource_consumption_metrics.h" #include "mongo/logv2/log.h" #include "mongo/platform/overflow_arithmetic.h" @@ -69,10 +68,10 @@ struct BoundMakerMin { doc.metadata().getTimeseriesBucketMinTime().toMillisSinceEpoch() + offset)}; } - Document serialize(const SerializationOptions& opts) const { + Document serialize() const { // Convert from millis to seconds. return Document{{{"base"_sd, DocumentSourceSort::kMin}, - {DocumentSourceSort::kOffset, opts.serializeLiteral(offset / 1000)}}}; + {DocumentSourceSort::kOffset, (offset / 1000)}}}; } }; @@ -85,10 +84,10 @@ struct BoundMakerMax { doc.metadata().getTimeseriesBucketMaxTime().toMillisSinceEpoch() + offset)}; } - Document serialize(const SerializationOptions& opts) const { + Document serialize() const { // Convert from millis to seconds. return Document{{{"base"_sd, DocumentSourceSort::kMax}, - {DocumentSourceSort::kOffset, opts.serializeLiteral(offset / 1000)}}}; + {DocumentSourceSort::kOffset, (offset / 1000)}}}; } }; struct CompAsc { @@ -143,19 +142,13 @@ REGISTER_DOCUMENT_SOURCE(sort, LiteParsedDocumentSourceDefault::parse, DocumentSourceSort::createFromBson, AllowedWithApiStrict::kAlways); - REGISTER_DOCUMENT_SOURCE_CONDITIONALLY( _internalBoundedSort, LiteParsedDocumentSourceDefault::parse, DocumentSourceSort::parseBoundedSort, - ::mongo::getTestCommandsEnabled() ? AllowedWithApiStrict::kNeverInVersion1 - : AllowedWithApiStrict::kInternal, - ::mongo::getTestCommandsEnabled() ? AllowedWithClientType::kAny - : AllowedWithClientType::kInternal, - // We don't expect mongos or clients to produce this stage: - // We only generate it after multiplanning, which means only within one mongod process. - // So, we should be allowed to parse this stage regardless of FCV. - boost::none /*minVersion*/, + AllowedWithApiStrict::kNeverInVersion1, + AllowedWithClientType::kAny, + feature_flags::gFeatureFlagBucketUnpackWithSort.getVersion(), feature_flags::gFeatureFlagBucketUnpackWithSort.isEnabledAndIgnoreFCV()); DocumentSource::GetNextResult::ReturnStatus DocumentSourceSort::timeSorterPeek() { @@ -287,10 +280,8 @@ boost::intrusive_ptr<DocumentSource> DocumentSourceSort::clone( _sortExecutor->getMaxMemoryBytes()); } -void DocumentSourceSort::serializeToArray(std::vector<Value>& array, - const SerializationOptions& opts) const { - auto explain = opts.verbosity; - +void DocumentSourceSort::serializeToArray( + std::vector<Value>& array, boost::optional<ExplainOptions::Verbosity> explain) const { if (_timeSorter) { tassert(6369900, "$_internalBoundedSort should not absorb a $limit", @@ -298,22 +289,20 @@ void DocumentSourceSort::serializeToArray(std::vector<Value>& array, // {$_internalBoundedSort: {sortKey, bound}} auto sortKey = _sortExecutor->sortPattern().serialize( - SortPattern::SortKeySerialization::kForPipelineSerialization, opts); + SortPattern::SortKeySerialization::kForPipelineSerialization); MutableDocument mutDoc{Document{{ {"$_internalBoundedSort"_sd, Document{{{"sortKey"_sd, std::move(sortKey)}, - {"bound"_sd, _timeSorter->serializeBound(opts)}, - {"limit"_sd, - opts.serializeLiteral(static_cast<long long>(_timeSorter->limit()))}}}}, + {"bound"_sd, _timeSorter->serializeBound()}, + {"limit"_sd, static_cast<long long>(_timeSorter->limit())}}}}, }}}; if (explain >= ExplainOptions::Verbosity::kExecStats) { mutDoc["totalDataSizeSortedBytesEstimate"] = - opts.serializeLiteral(static_cast<long long>(_timeSorter->totalDataSizeBytes())); - mutDoc["usedDisk"] = opts.serializeLiteral(_timeSorter->stats().spilledRanges() > 0); - mutDoc["spills"] = - opts.serializeLiteral(static_cast<long long>(_timeSorter->stats().spilledRanges())); + Value(static_cast<long long>(_timeSorter->totalDataSizeBytes())); + mutDoc["usedDisk"] = Value(_timeSorter->numSpills() > 0); + mutDoc["spills"] = Value(static_cast<long long>(_timeSorter->numSpills())); } array.push_back(Value{mutDoc.freeze()}); @@ -324,31 +313,31 @@ void DocumentSourceSort::serializeToArray(std::vector<Value>& array, if (!explain) { // one Value for $sort and maybe a Value for $limit MutableDocument inner(_sortExecutor->sortPattern().serialize( - SortPattern::SortKeySerialization::kForPipelineSerialization, opts)); + SortPattern::SortKeySerialization::kForPipelineSerialization)); array.push_back(Value(DOC(kStageName << inner.freeze()))); if (_sortExecutor->hasLimit()) { auto limitSrc = DocumentSourceLimit::create(pExpCtx, limit); - limitSrc->serializeToArray(array, opts); + limitSrc->serializeToArray(array); } return; } - MutableDocument mutDoc(DOC( - kStageName << DOC("sortKey" << _sortExecutor->sortPattern().serialize( - SortPattern::SortKeySerialization::kForExplain, opts) - << "limit" - << (_sortExecutor->hasLimit() - ? opts.serializeLiteral(static_cast<long long>(limit)) - : Value())))); + MutableDocument mutDoc( + DOC(kStageName << DOC("sortKey" + << _sortExecutor->sortPattern().serialize( + SortPattern::SortKeySerialization::kForExplain) + << "limit" + << (_sortExecutor->hasLimit() ? Value(static_cast<long long>(limit)) + : Value())))); if (explain >= ExplainOptions::Verbosity::kExecStats) { auto& stats = _sortExecutor->stats(); mutDoc["totalDataSizeSortedBytesEstimate"] = - opts.serializeLiteral(static_cast<long long>(stats.totalDataSizeBytes)); - mutDoc["usedDisk"] = opts.serializeLiteral(stats.spills > 0); - mutDoc["spills"] = opts.serializeLiteral(static_cast<long long>(stats.spills)); + Value(static_cast<long long>(stats.totalDataSizeBytes)); + mutDoc["usedDisk"] = Value(stats.spills > 0); + mutDoc["spills"] = Value(static_cast<long long>(stats.spills)); } array.push_back(Value(mutDoc.freeze())); @@ -493,10 +482,6 @@ intrusive_ptr<DocumentSourceSort> DocumentSourceSort::parseBoundedSort( BSONElement key = args["sortKey"]; uassert(6369904, "$_internalBoundedSort sortKey must be an object", key.type() == Object); - // Empty sort pattern is not allowed for the bounded sort. - uassert(6900501, - "$_internalBoundedSort stage must have at least one sort key", - !key.embeddedObject().isEmpty()); SortPattern pat{key.embeddedObject(), expCtx}; { @@ -664,7 +649,7 @@ boost::optional<DocumentSource::DistributedPlanLogic> DocumentSourceSort::distri } bool DocumentSourceSort::canRunInParallelBeforeWriteStage( - const OrderedPathSet& nameOfShardKeyFieldsUponEntryToStage) const { + const std::set<std::string>& nameOfShardKeyFieldsUponEntryToStage) const { // This is an interesting special case. If there are no further stages which require merging the // streams into one, a $sort should not require it. This is only the case because the sort order // doesn't matter for a pipeline ending with a write stage. We may encounter it here as an |
