summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline/document_source_set_window_fields.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/pipeline/document_source_set_window_fields.cpp')
-rw-r--r--src/mongo/db/pipeline/document_source_set_window_fields.cpp45
1 files changed, 21 insertions, 24 deletions
diff --git a/src/mongo/db/pipeline/document_source_set_window_fields.cpp b/src/mongo/db/pipeline/document_source_set_window_fields.cpp
index e32fc78c04b..45223bb1cf4 100644
--- a/src/mongo/db/pipeline/document_source_set_window_fields.cpp
+++ b/src/mongo/db/pipeline/document_source_set_window_fields.cpp
@@ -144,8 +144,8 @@ WindowFunctionStatement WindowFunctionStatement::parse(BSONElement elem,
window_function::Expression::parse(elem.embeddedObject(), sortBy, expCtx));
}
void WindowFunctionStatement::serialize(MutableDocument& outputFields,
- const SerializationOptions& opts) const {
- outputFields[opts.serializeFieldPathFromString(fieldName)] = expr->serialize(opts);
+ boost::optional<ExplainOptions::Verbosity> explain) const {
+ outputFields[fieldName] = expr->serialize(explain);
}
list<intrusive_ptr<DocumentSource>> document_source_set_window_fields::create(
@@ -218,10 +218,12 @@ list<intrusive_ptr<DocumentSource>> document_source_set_window_fields::create(
} else {
// In DocumentSource we don't have a mechanism for generating non-colliding field names,
// so we have to choose the tmp name carefully to make a collision unlikely in practice.
- auto tmp = "__internal_setWindowFields_partition_key";
- simplePartitionBy = FieldPath{tmp};
+ std::array<unsigned char, 16> nonce = UUID::gen().data();
+ // We encode as a base64 string for a shorter, more performant field name (length 22).
+ std::string tmpField = base64::encode(nonce.data(), sizeof(nonce));
+ simplePartitionBy = FieldPath{tmpField};
simplePartitionByExpr = ExpressionFieldPath::createPathFromString(
- expCtx.get(), tmp, expCtx->variablesParseState);
+ expCtx.get(), tmpField, expCtx->variablesParseState);
complexPartitionBy = partitionBy;
}
}
@@ -286,38 +288,39 @@ intrusive_ptr<DocumentSource> DocumentSourceInternalSetWindowFields::optimize()
return this;
}
-Value DocumentSourceInternalSetWindowFields::serialize(const SerializationOptions& opts) const {
+Value DocumentSourceInternalSetWindowFields::serialize(
+ boost::optional<ExplainOptions::Verbosity> explain) const {
MutableDocument spec;
spec[SetWindowFieldsSpec::kPartitionByFieldName] =
- _partitionBy ? (*_partitionBy)->serialize(opts) : Value();
+ _partitionBy ? (*_partitionBy)->serialize(false) : Value();
- auto sortKeySerialization = opts.verbosity
+ auto sortKeySerialization = explain
? SortPattern::SortKeySerialization::kForExplain
: SortPattern::SortKeySerialization::kForPipelineSerialization;
spec[SetWindowFieldsSpec::kSortByFieldName] =
- _sortBy ? Value(_sortBy->serialize(sortKeySerialization, opts)) : Value();
+ _sortBy ? Value(_sortBy->serialize(sortKeySerialization)) : Value();
MutableDocument output;
for (auto&& stmt : _outputFields) {
- stmt.serialize(output, opts);
+ stmt.serialize(output, explain);
}
spec[SetWindowFieldsSpec::kOutputFieldName] = output.freezeToValue();
MutableDocument out;
out[getSourceName()] = Value(spec.freeze());
- if (opts.verbosity && *opts.verbosity >= ExplainOptions::Verbosity::kExecStats) {
+ if (explain && *explain >= ExplainOptions::Verbosity::kExecStats) {
MutableDocument md;
for (auto&& [fieldName, function] : _executableOutputs) {
- md[opts.serializeFieldPathFromString(fieldName)] = opts.serializeLiteral(
- static_cast<long long>(_memoryTracker[fieldName].maxMemoryBytes()));
+ md[fieldName] =
+ Value(static_cast<long long>(_memoryTracker[fieldName].maxMemoryBytes()));
}
out["maxFunctionMemoryUsageBytes"] = Value(md.freezeToValue());
out["maxTotalMemoryUsageBytes"] =
- opts.serializeLiteral(static_cast<long long>(_memoryTracker.maxMemoryBytes()));
- out["usedDisk"] = opts.serializeLiteral(_iterator.usedDisk());
+ Value(static_cast<long long>(_memoryTracker.maxMemoryBytes()));
+ out["usedDisk"] = Value(_iterator.usedDisk());
}
return Value(out.freezeToValue());
@@ -461,12 +464,8 @@ DocumentSource::GetNextResult DocumentSourceInternalSetWindowFields::doGetNext()
return DocumentSource::GetNextResult::makeEOF();
auto curDoc = _iterator.current();
+ // The only way we hit this case is if there are no documents, since otherwise _eof will be set.
if (!curDoc) {
- if (_iterator.isPaused()) {
- return DocumentSource::GetNextResult::makePauseExecution();
- }
- // The only way we hit this case is if there are no documents, since otherwise _eof will be
- // set.
_eof = true;
return DocumentSource::GetNextResult::makeEOF();
}
@@ -474,15 +473,13 @@ DocumentSource::GetNextResult DocumentSourceInternalSetWindowFields::doGetNext()
// Populate the output document with the result from each window function.
auto projSpec = std::make_unique<projection_executor::InclusionNode>(
ProjectionPolicies{ProjectionPolicies::DefaultIdPolicy::kIncludeId});
- for (auto&& outputField : _outputFields) {
+ for (auto&& [fieldName, function] : _executableOutputs) {
try {
// If we hit a uassert while evaluating expressions on user data, delete the temporary
// table before aborting the operation.
- auto& fieldName = outputField.fieldName;
projSpec->addExpressionForPath(
FieldPath(fieldName),
- ExpressionConstant::create(pExpCtx.get(),
- _executableOutputs[fieldName]->getNext()));
+ ExpressionConstant::create(pExpCtx.get(), function->getNext()));
} catch (const DBException&) {
_iterator.finalize();
throw;