summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline/document_source_sort.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/pipeline/document_source_sort.cpp')
-rw-r--r--src/mongo/db/pipeline/document_source_sort.cpp71
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