summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Storch <david.storch@mongodb.com>2022-11-18 22:55:41 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-11-18 23:52:45 +0000
commit0d9b3912cee0897af35ec529a687d886f2b5a06d (patch)
treeaaa9739bfa0f6fe3ea9f042762e6481fe732e83b
parent6a984b3bca1abd901080d86ca00a2b07febe806e (diff)
downloadmongo-0d9b3912cee0897af35ec529a687d886f2b5a06d.tar.gz
SERVER-70395 De-stage-ify accumulator stage builder
-rw-r--r--src/mongo/db/query/sbe_stage_builder.cpp15
-rw-r--r--src/mongo/db/query/sbe_stage_builder_accumulator.cpp238
-rw-r--r--src/mongo/db/query/sbe_stage_builder_accumulator.h15
3 files changed, 99 insertions, 169 deletions
diff --git a/src/mongo/db/query/sbe_stage_builder.cpp b/src/mongo/db/query/sbe_stage_builder.cpp
index 5146bdb7244..42683372d81 100644
--- a/src/mongo/db/query/sbe_stage_builder.cpp
+++ b/src/mongo/db/query/sbe_stage_builder.cpp
@@ -2410,8 +2410,7 @@ std::tuple<sbe::value::SlotVector, EvalStage> generateAccumulator(
// One accumulator may be translated to multiple accumulator expressions. For example, The
// $avg will have two accumulators expressions, a sum(..) and a count which is implemented
// as sum(1).
- auto [accExprs, accProjEvalStage] = stage_builder::buildAccumulator(
- state, accStmt, std::move(accArgEvalStage), std::move(argExpr), nodeId);
+ auto accExprs = stage_builder::buildAccumulator(state, accStmt, std::move(argExpr));
sbe::value::SlotVector aggSlots;
for (auto& accExpr : accExprs) {
@@ -2420,7 +2419,7 @@ std::tuple<sbe::value::SlotVector, EvalStage> generateAccumulator(
accSlotToExprMap.emplace(slot, std::move(accExpr));
}
- return {std::move(aggSlots), std::move(accProjEvalStage)};
+ return {std::move(aggSlots), std::move(accArgEvalStage)};
}
std::tuple<std::vector<std::string>, sbe::value::SlotVector, EvalStage> generateGroupFinalStage(
@@ -2457,13 +2456,11 @@ std::tuple<std::vector<std::string>, sbe::value::SlotVector, EvalStage> generate
auto finalSlots{sbe::value::SlotVector{finalGroupBySlot}};
std::vector<std::string> fieldNames{"_id"};
- auto groupFinalEvalStage = std::move(groupEvalStage);
size_t idxAccFirstSlot = dedupedGroupBySlots.size();
for (size_t idxAcc = 0; idxAcc < accStmts.size(); ++idxAcc) {
// Gathers field names for the output object from accumulator statements.
fieldNames.push_back(accStmts[idxAcc].fieldName);
- auto [finalExpr, tempEvalStage] = stage_builder::buildFinalize(
- state, accStmts[idxAcc], aggSlotsVec[idxAcc], std::move(groupFinalEvalStage), nodeId);
+ auto finalExpr = stage_builder::buildFinalize(state, accStmts[idxAcc], aggSlotsVec[idxAcc]);
// The final step may not return an expression if it's trivial. For example, $first and
// $last's final steps are trivial.
@@ -2478,15 +2475,13 @@ std::tuple<std::vector<std::string>, sbe::value::SlotVector, EvalStage> generate
// Some accumulator(s) like $avg generate multiple expressions and slots. So, need to
// advance this index by the number of those slots for each accumulator.
idxAccFirstSlot += aggSlotsVec[idxAcc].size();
-
- groupFinalEvalStage = std::move(tempEvalStage);
}
// Gathers all accumulator results. If there're no project expressions, does not add a project
// stage.
auto retEvalStage = prjSlotToExprMap.empty()
- ? std::move(groupFinalEvalStage)
- : makeProject(std::move(groupFinalEvalStage), std::move(prjSlotToExprMap), nodeId);
+ ? std::move(groupEvalStage)
+ : makeProject(std::move(groupEvalStage), std::move(prjSlotToExprMap), nodeId);
return {std::move(fieldNames), std::move(finalSlots), std::move(retEvalStage)};
}
diff --git a/src/mongo/db/query/sbe_stage_builder_accumulator.cpp b/src/mongo/db/query/sbe_stage_builder_accumulator.cpp
index 8aa4f0f8d2e..08f8cfee02c 100644
--- a/src/mongo/db/query/sbe_stage_builder_accumulator.cpp
+++ b/src/mongo/db/query/sbe_stage_builder_accumulator.cpp
@@ -54,12 +54,10 @@ std::unique_ptr<sbe::EExpression> wrapMinMaxArg(StageBuilderState& state,
std::move(arg));
}
-std::pair<std::vector<std::unique_ptr<sbe::EExpression>>, EvalStage> buildAccumulatorMin(
+std::vector<std::unique_ptr<sbe::EExpression>> buildAccumulatorMin(
StageBuilderState& state,
const AccumulationExpression& expr,
- std::unique_ptr<sbe::EExpression> arg,
- EvalStage inputStage,
- PlanNodeId planNodeId) {
+ std::unique_ptr<sbe::EExpression> arg) {
std::vector<std::unique_ptr<sbe::EExpression>> aggs;
auto collatorSlot = state.data->env->getSlotIfExists("collator"_sd);
if (collatorSlot) {
@@ -69,15 +67,12 @@ std::pair<std::vector<std::unique_ptr<sbe::EExpression>>, EvalStage> buildAccumu
} else {
aggs.push_back(makeFunction("min"_sd, wrapMinMaxArg(state, std::move(arg))));
}
- return {std::move(aggs), std::move(inputStage)};
+ return aggs;
}
-std::pair<std::unique_ptr<sbe::EExpression>, EvalStage> buildFinalizeMin(
- StageBuilderState& state,
- const AccumulationExpression& expr,
- const sbe::value::SlotVector& minSlots,
- EvalStage inputStage,
- PlanNodeId planNodeId) {
+std::unique_ptr<sbe::EExpression> buildFinalizeMin(StageBuilderState& state,
+ const AccumulationExpression& expr,
+ const sbe::value::SlotVector& minSlots) {
// We can get away with not building a project stage since there's no finalize step but we
// will stick the slot into an EVariable in case a $min is one of many group clauses and it
// can be combined into a final project stage.
@@ -85,15 +80,13 @@ std::pair<std::unique_ptr<sbe::EExpression>, EvalStage> buildFinalizeMin(
str::stream() << "Expected one input slot for finalization of min, got: "
<< minSlots.size(),
minSlots.size() == 1);
- return {makeFillEmptyNull(makeVariable(minSlots[0])), std::move(inputStage)};
+ return makeFillEmptyNull(makeVariable(minSlots[0]));
}
-std::pair<std::vector<std::unique_ptr<sbe::EExpression>>, EvalStage> buildAccumulatorMax(
+std::vector<std::unique_ptr<sbe::EExpression>> buildAccumulatorMax(
StageBuilderState& state,
const AccumulationExpression& expr,
- std::unique_ptr<sbe::EExpression> arg,
- EvalStage inputStage,
- PlanNodeId planNodeId) {
+ std::unique_ptr<sbe::EExpression> arg) {
std::vector<std::unique_ptr<sbe::EExpression>> aggs;
auto collatorSlot = state.data->env->getSlotIfExists("collator"_sd);
if (collatorSlot) {
@@ -103,51 +96,42 @@ std::pair<std::vector<std::unique_ptr<sbe::EExpression>>, EvalStage> buildAccumu
} else {
aggs.push_back(makeFunction("max"_sd, wrapMinMaxArg(state, std::move(arg))));
}
- return {std::move(aggs), std::move(inputStage)};
+ return aggs;
}
-std::pair<std::unique_ptr<sbe::EExpression>, EvalStage> buildFinalizeMax(
- StageBuilderState& state,
- const AccumulationExpression& expr,
- const sbe::value::SlotVector& maxSlots,
- EvalStage inputStage,
- PlanNodeId planNodeId) {
+std::unique_ptr<sbe::EExpression> buildFinalizeMax(StageBuilderState& state,
+ const AccumulationExpression& expr,
+ const sbe::value::SlotVector& maxSlots) {
tassert(5755100,
str::stream() << "Expected one input slot for finalization of max, got: "
<< maxSlots.size(),
maxSlots.size() == 1);
- return {makeFillEmptyNull(makeVariable(maxSlots[0])), std::move(inputStage)};
+ return makeFillEmptyNull(makeVariable(maxSlots[0]));
}
-std::pair<std::vector<std::unique_ptr<sbe::EExpression>>, EvalStage> buildAccumulatorFirst(
+std::vector<std::unique_ptr<sbe::EExpression>> buildAccumulatorFirst(
StageBuilderState& state,
const AccumulationExpression& expr,
- std::unique_ptr<sbe::EExpression> arg,
- EvalStage inputStage,
- PlanNodeId planNodeId) {
+ std::unique_ptr<sbe::EExpression> arg) {
std::vector<std::unique_ptr<sbe::EExpression>> aggs;
aggs.push_back(makeFunction("first", makeFillEmptyNull(std::move(arg))));
- return {std::move(aggs), std::move(inputStage)};
+ return aggs;
}
-std::pair<std::vector<std::unique_ptr<sbe::EExpression>>, EvalStage> buildAccumulatorLast(
+std::vector<std::unique_ptr<sbe::EExpression>> buildAccumulatorLast(
StageBuilderState& state,
const AccumulationExpression& expr,
- std::unique_ptr<sbe::EExpression> arg,
- EvalStage inputStage,
- PlanNodeId planNodeId) {
+ std::unique_ptr<sbe::EExpression> arg) {
std::vector<std::unique_ptr<sbe::EExpression>> aggs;
aggs.push_back(makeFunction("last", makeFillEmptyNull(std::move(arg))));
- return {std::move(aggs), std::move(inputStage)};
+ return aggs;
}
-std::pair<std::vector<std::unique_ptr<sbe::EExpression>>, EvalStage> buildAccumulatorAvg(
+std::vector<std::unique_ptr<sbe::EExpression>> buildAccumulatorAvg(
StageBuilderState& state,
const AccumulationExpression& expr,
- std::unique_ptr<sbe::EExpression> arg,
- EvalStage inputStage,
- PlanNodeId planNodeId) {
+ std::unique_ptr<sbe::EExpression> arg) {
std::vector<std::unique_ptr<sbe::EExpression>> aggs;
// 'aggDoubleDoubleSum' will ignore non-numeric values automatically.
@@ -167,15 +151,12 @@ std::pair<std::vector<std::unique_ptr<sbe::EExpression>>, EvalStage> buildAccumu
auto counterExpr = makeFunction("sum", std::move(addend));
aggs.push_back(std::move(counterExpr));
- return {std::move(aggs), std::move(inputStage)};
+ return aggs;
}
-std::pair<std::unique_ptr<sbe::EExpression>, EvalStage> buildFinalizeAvg(
- StageBuilderState& state,
- const AccumulationExpression& expr,
- const sbe::value::SlotVector& aggSlots,
- EvalStage inputStage,
- PlanNodeId planNodeId) {
+std::unique_ptr<sbe::EExpression> buildFinalizeAvg(StageBuilderState& state,
+ const AccumulationExpression& expr,
+ const sbe::value::SlotVector& aggSlots) {
// Slot 0 contains the accumulated sum, and slot 1 contains the count of summed items.
tassert(5754703,
str::stream() << "Expected two slots to finalize avg, got: " << aggSlots.size(),
@@ -195,7 +176,7 @@ std::pair<std::unique_ptr<sbe::EExpression>, EvalStage> buildFinalizeAvg(
makeNewObjFunction(FieldPair{countName, countResult->clone()},
FieldPair{partialSumName, partialSumExpr->clone()});
- return {std::move(partialAvgFinalize), std::move(inputStage)};
+ return partialAvgFinalize;
} else {
// If we've encountered any numeric input, the counter would contain a positive integer.
// Unlike $sum, when there is no numeric input, $avg should return null.
@@ -208,7 +189,7 @@ std::pair<std::unique_ptr<sbe::EExpression>, EvalStage> buildFinalizeAvg(
makeFunction("doubleDoubleSumFinalize", makeVariable(aggSlots[0])),
makeVariable(aggSlots[1])));
- return {std::move(finalizingExpression), std::move(inputStage)};
+ return finalizingExpression;
}
}
@@ -243,30 +224,25 @@ getCountAddend(const AccumulationExpression& expr) {
}
} // namespace
-std::pair<std::vector<std::unique_ptr<sbe::EExpression>>, EvalStage> buildAccumulatorSum(
+std::vector<std::unique_ptr<sbe::EExpression>> buildAccumulatorSum(
StageBuilderState& state,
const AccumulationExpression& expr,
- std::unique_ptr<sbe::EExpression> arg,
- EvalStage inputStage,
- PlanNodeId planNodeId) {
+ std::unique_ptr<sbe::EExpression> arg) {
std::vector<std::unique_ptr<sbe::EExpression>> aggs;
// Optimize for a count-like accumulator like {$sum: 1}.
if (auto [isCount, addendTag, addendVal] = getCountAddend(expr); isCount) {
aggs.push_back(makeFunction("sum", makeConstant(*addendTag, *addendVal)));
- return {std::move(aggs), std::move(inputStage)};
+ return aggs;
}
aggs.push_back(makeFunction("aggDoubleDoubleSum", std::move(arg)));
- return {std::move(aggs), std::move(inputStage)};
+ return aggs;
}
-std::pair<std::unique_ptr<sbe::EExpression>, EvalStage> buildFinalizeSum(
- StageBuilderState& state,
- const AccumulationExpression& expr,
- const sbe::value::SlotVector& sumSlots,
- EvalStage inputStage,
- PlanNodeId planNodeId) {
+std::unique_ptr<sbe::EExpression> buildFinalizeSum(StageBuilderState& state,
+ const AccumulationExpression& expr,
+ const sbe::value::SlotVector& sumSlots) {
tassert(5755300,
str::stream() << "Expected one input slot for finalization of sum, got: "
<< sumSlots.size(),
@@ -286,25 +262,21 @@ std::pair<std::unique_ptr<sbe::EExpression>, EvalStage> buildFinalizeSum(
// More fundamentally, addition is neither commutative nor associative on computer. So, it's
// desirable to keep the full state of the partial sum along the way to maintain the result
// as close to the real truth as possible until all additions are done.
- return {makeFunction("doubleDoublePartialSumFinalize", makeVariable(sumSlots[0])),
- std::move(inputStage)};
+ return makeFunction("doubleDoublePartialSumFinalize", makeVariable(sumSlots[0]));
}
if (auto [isCount, tag, val] = getCountAddend(expr); isCount) {
// The accumulation result is a scalar value. So, the final project is not necessary.
- return {nullptr, std::move(inputStage)};
+ return nullptr;
}
- return {makeFunction("doubleDoubleSumFinalize", makeVariable(sumSlots[0])),
- std::move(inputStage)};
+ return makeFunction("doubleDoubleSumFinalize", makeVariable(sumSlots[0]));
}
-std::pair<std::vector<std::unique_ptr<sbe::EExpression>>, EvalStage> buildAccumulatorAddToSet(
+std::vector<std::unique_ptr<sbe::EExpression>> buildAccumulatorAddToSet(
StageBuilderState& state,
const AccumulationExpression& expr,
- std::unique_ptr<sbe::EExpression> arg,
- EvalStage inputStage,
- PlanNodeId planNodeId) {
+ std::unique_ptr<sbe::EExpression> arg) {
std::vector<std::unique_ptr<sbe::EExpression>> aggs;
const int cap = internalQueryMaxAddToSetBytes.load();
auto collatorSlot = state.data->env->getSlotIfExists("collator"_sd);
@@ -320,15 +292,13 @@ std::pair<std::vector<std::unique_ptr<sbe::EExpression>>, EvalStage> buildAccumu
std::move(arg),
makeConstant(sbe::value::TypeTags::NumberInt32, sbe::value::bitcastFrom<int>(cap))));
}
- return {std::move(aggs), std::move(inputStage)};
+ return aggs;
}
-std::pair<std::unique_ptr<sbe::EExpression>, EvalStage> buildFinalizeCappedAccumulator(
+std::unique_ptr<sbe::EExpression> buildFinalizeCappedAccumulator(
StageBuilderState& state,
const AccumulationExpression& expr,
- const sbe::value::SlotVector& accSlots,
- EvalStage inputStage,
- PlanNodeId planNodeId) {
+ const sbe::value::SlotVector& accSlots) {
tassert(6526500,
str::stream() << "Expected one input slot for finalization of capped accumulator, got: "
<< accSlots.size(),
@@ -343,33 +313,29 @@ std::pair<std::unique_ptr<sbe::EExpression>, EvalStage> buildFinalizeCappedAccum
makeConstant(sbe::value::TypeTags::NumberInt32,
static_cast<int>(sbe::vm::AggArrayWithSize::kValues)));
- return {std::move(pushFinalize), std::move(inputStage)};
+ return pushFinalize;
}
-std::pair<std::vector<std::unique_ptr<sbe::EExpression>>, EvalStage> buildAccumulatorPush(
+std::vector<std::unique_ptr<sbe::EExpression>> buildAccumulatorPush(
StageBuilderState& state,
const AccumulationExpression& expr,
- std::unique_ptr<sbe::EExpression> arg,
- EvalStage inputStage,
- PlanNodeId planNodeId) {
+ std::unique_ptr<sbe::EExpression> arg) {
const int cap = internalQueryMaxPushBytes.load();
std::vector<std::unique_ptr<sbe::EExpression>> aggs;
aggs.push_back(makeFunction(
"addToArrayCapped"_sd,
std::move(arg),
makeConstant(sbe::value::TypeTags::NumberInt32, sbe::value::bitcastFrom<int>(cap))));
- return {std::move(aggs), std::move(inputStage)};
+ return aggs;
}
-std::pair<std::vector<std::unique_ptr<sbe::EExpression>>, EvalStage> buildAccumulatorStdDev(
+std::vector<std::unique_ptr<sbe::EExpression>> buildAccumulatorStdDev(
StageBuilderState& state,
const AccumulationExpression& expr,
- std::unique_ptr<sbe::EExpression> arg,
- EvalStage inputStage,
- PlanNodeId planNodeId) {
+ std::unique_ptr<sbe::EExpression> arg) {
std::vector<std::unique_ptr<sbe::EExpression>> aggs;
aggs.push_back(makeFunction("aggStdDev", std::move(arg)));
- return {std::move(aggs), std::move(inputStage)};
+ return aggs;
}
std::unique_ptr<sbe::EExpression> buildFinalizePartialStdDev(sbe::value::SlotId stdDevSlot) {
@@ -400,69 +366,62 @@ std::unique_ptr<sbe::EExpression> buildFinalizePartialStdDev(sbe::value::SlotId
static_cast<int>(sbe::vm::AggStdDevValueElems::kCount)))});
}
-std::pair<std::unique_ptr<sbe::EExpression>, EvalStage> buildFinalizeStdDevPop(
+std::unique_ptr<sbe::EExpression> buildFinalizeStdDevPop(
StageBuilderState& state,
const AccumulationExpression& expr,
- const sbe::value::SlotVector& stdDevSlots,
- EvalStage inputStage,
- PlanNodeId planNodeId) {
+ const sbe::value::SlotVector& stdDevSlots) {
tassert(5755204,
str::stream() << "Expected one input slot for finalization of stdDevPop, got: "
<< stdDevSlots.size(),
stdDevSlots.size() == 1);
if (state.needsMerge) {
- return {buildFinalizePartialStdDev(stdDevSlots[0]), std::move(inputStage)};
+ return buildFinalizePartialStdDev(stdDevSlots[0]);
} else {
auto stdDevPopFinalize = makeFunction("stdDevPopFinalize", makeVariable(stdDevSlots[0]));
- return {std::move(stdDevPopFinalize), std::move(inputStage)};
+ return stdDevPopFinalize;
}
}
-std::pair<std::unique_ptr<sbe::EExpression>, EvalStage> buildFinalizeStdDevSamp(
+std::unique_ptr<sbe::EExpression> buildFinalizeStdDevSamp(
StageBuilderState& state,
const AccumulationExpression& expr,
- const sbe::value::SlotVector& stdDevSlots,
- EvalStage inputStage,
- PlanNodeId planNodeId) {
+ const sbe::value::SlotVector& stdDevSlots) {
tassert(5755209,
str::stream() << "Expected one input slot for finalization of stdDevSamp, got: "
<< stdDevSlots.size(),
stdDevSlots.size() == 1);
if (state.needsMerge) {
- return {buildFinalizePartialStdDev(stdDevSlots[0]), std::move(inputStage)};
+ return buildFinalizePartialStdDev(stdDevSlots[0]);
} else {
- auto stdDevSampFinalize = makeFunction("stdDevSampFinalize", makeVariable(stdDevSlots[0]));
- return {std::move(stdDevSampFinalize), std::move(inputStage)};
+ return makeFunction("stdDevSampFinalize", makeVariable(stdDevSlots[0]));
}
}
-std::pair<std::vector<std::unique_ptr<sbe::EExpression>>, EvalStage> buildAccumulatorMergeObjects(
+std::vector<std::unique_ptr<sbe::EExpression>> buildAccumulatorMergeObjects(
StageBuilderState& state,
const AccumulationExpression& expr,
- std::unique_ptr<sbe::EExpression> arg,
- EvalStage inputStage,
- PlanNodeId planNodeId) {
+ std::unique_ptr<sbe::EExpression> arg) {
std::vector<std::unique_ptr<sbe::EExpression>> aggs;
- auto filterExpr = makeLocalBind(
- state.frameIdGenerator,
- [](sbe::EVariable input) {
- return makeBinaryOp(
- sbe::EPrimBinary::logicOr,
- generateNullOrMissing(input),
- makeBinaryOp(sbe::EPrimBinary::logicOr,
- makeFunction("isObject", input.clone()),
- sbe::makeE<sbe::EFail>(ErrorCodes::Error{5911200},
- "$mergeObjects only supports objects")));
- },
- arg->clone());
-
- inputStage = makeFilter<false>(std::move(inputStage), std::move(filterExpr), planNodeId);
-
- aggs.push_back(makeFunction("mergeObjects", std::move(arg)));
- return {std::move(aggs), std::move(inputStage)};
+ auto filterExpr =
+ makeLocalBind(state.frameIdGenerator,
+ [](sbe::EVariable input) {
+ auto typeCheckExpr =
+ makeBinaryOp(sbe::EPrimBinary::logicOr,
+ generateNullOrMissing(input),
+ makeFunction("isObject", input.clone()));
+ return sbe::makeE<sbe::EIf>(
+ std::move(typeCheckExpr),
+ makeFunction("mergeObjects", input.clone()),
+ sbe::makeE<sbe::EFail>(ErrorCodes::Error{5911200},
+ "$mergeObjects only supports objects"));
+ },
+ std::move(arg));
+
+ aggs.push_back(std::move(filterExpr));
+ return aggs;
}
}; // namespace
@@ -478,19 +437,12 @@ std::pair<std::unique_ptr<sbe::EExpression>, EvalStage> buildArgument(
return {argExpr.extractExpr(), std::move(outStage)};
}
-std::pair<std::vector<std::unique_ptr<sbe::EExpression>>, EvalStage> buildAccumulator(
+std::vector<std::unique_ptr<sbe::EExpression>> buildAccumulator(
StageBuilderState& state,
const AccumulationStatement& acc,
- EvalStage inputStage,
- std::unique_ptr<sbe::EExpression> inputExpr,
- PlanNodeId planNodeId) {
- using BuildAccumulatorFn =
- std::function<std::pair<std::vector<std::unique_ptr<sbe::EExpression>>, EvalStage>(
- StageBuilderState&,
- const AccumulationExpression&,
- std::unique_ptr<sbe::EExpression>,
- EvalStage,
- PlanNodeId)>;
+ std::unique_ptr<sbe::EExpression> inputExpr) {
+ using BuildAccumulatorFn = std::function<std::vector<std::unique_ptr<sbe::EExpression>>(
+ StageBuilderState&, const AccumulationExpression&, std::unique_ptr<sbe::EExpression>)>;
static const StringDataMap<BuildAccumulatorFn> kAccumulatorBuilders = {
{AccumulatorMin::kName, &buildAccumulatorMin},
@@ -511,26 +463,14 @@ std::pair<std::vector<std::unique_ptr<sbe::EExpression>>, EvalStage> buildAccumu
str::stream() << "Unsupported Accumulator in SBE accumulator builder: " << accExprName,
kAccumulatorBuilders.find(accExprName) != kAccumulatorBuilders.end());
- return std::invoke(kAccumulatorBuilders.at(accExprName),
- state,
- acc.expr,
- std::move(inputExpr),
- std::move(inputStage),
- planNodeId);
+ return std::invoke(kAccumulatorBuilders.at(accExprName), state, acc.expr, std::move(inputExpr));
}
-std::pair<std::unique_ptr<sbe::EExpression>, EvalStage> buildFinalize(
- StageBuilderState& state,
- const AccumulationStatement& acc,
- const sbe::value::SlotVector& aggSlots,
- EvalStage inputStage,
- PlanNodeId planNodeId) {
- using BuildFinalizeFn = std::function<std::pair<std::unique_ptr<sbe::EExpression>, EvalStage>(
- StageBuilderState&,
- const AccumulationExpression&,
- sbe::value::SlotVector,
- EvalStage,
- PlanNodeId)>;
+std::unique_ptr<sbe::EExpression> buildFinalize(StageBuilderState& state,
+ const AccumulationStatement& acc,
+ const sbe::value::SlotVector& aggSlots) {
+ using BuildFinalizeFn = std::function<std::unique_ptr<sbe::EExpression>(
+ StageBuilderState&, const AccumulationExpression&, sbe::value::SlotVector)>;
static const StringDataMap<BuildFinalizeFn> kAccumulatorBuilders = {
{AccumulatorMin::kName, &buildFinalizeMin},
@@ -552,10 +492,10 @@ std::pair<std::unique_ptr<sbe::EExpression>, EvalStage> buildFinalize(
kAccumulatorBuilders.find(accExprName) != kAccumulatorBuilders.end());
if (auto fn = kAccumulatorBuilders.at(accExprName); fn) {
- return std::invoke(fn, state, acc.expr, aggSlots, std::move(inputStage), planNodeId);
+ return std::invoke(fn, state, acc.expr, aggSlots);
} else {
// nullptr for 'EExpression' signifies that no final project is necessary.
- return {nullptr, std::move(inputStage)};
+ return nullptr;
}
}
} // namespace mongo::stage_builder
diff --git a/src/mongo/db/query/sbe_stage_builder_accumulator.h b/src/mongo/db/query/sbe_stage_builder_accumulator.h
index 9f9f896c4bf..6d8b1a5b112 100644
--- a/src/mongo/db/query/sbe_stage_builder_accumulator.h
+++ b/src/mongo/db/query/sbe_stage_builder_accumulator.h
@@ -56,22 +56,17 @@ std::pair<std::unique_ptr<sbe::EExpression>, EvalStage> buildArgument(
* Translates an input AccumulationStatement into an SBE EExpression for accumulation expressions.
* The 'stage' parameter provides the input subtree to build on top of.
*/
-std::pair<std::vector<std::unique_ptr<sbe::EExpression>>, EvalStage> buildAccumulator(
+std::vector<std::unique_ptr<sbe::EExpression>> buildAccumulator(
StageBuilderState& state,
const AccumulationStatement& acc,
- EvalStage stage,
- std::unique_ptr<sbe::EExpression> argExpr,
- PlanNodeId planNodeId);
+ std::unique_ptr<sbe::EExpression> argExpr);
/**
* Translates an input AccumulationStatement into an SBE EExpression that represents an
* AccumulationStatement's finalization step. The 'stage' parameter provides the input subtree to
* build on top of.
*/
-std::pair<std::unique_ptr<sbe::EExpression>, EvalStage> buildFinalize(
- StageBuilderState& state,
- const AccumulationStatement& acc,
- const sbe::value::SlotVector& aggSlots,
- EvalStage stage,
- PlanNodeId planNodeId);
+std::unique_ptr<sbe::EExpression> buildFinalize(StageBuilderState& state,
+ const AccumulationStatement& acc,
+ const sbe::value::SlotVector& aggSlots);
} // namespace mongo::stage_builder