summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDrew Paroski <drew.paroski@mongodb.com>2022-08-31 19:25:04 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-09-01 00:58:04 +0000
commit0d37d07a97b4a91e9d501f1c8a53b005a6f7dff1 (patch)
tree80f0c08c2dc97e10cdc347cf65417c02305d0ed9
parent3c9d1ed677835a92ac66ff96171cb2d5436dfd33 (diff)
downloadmongo-0d37d07a97b4a91e9d501f1c8a53b005a6f7dff1.tar.gz
SERVER-69296 Use traverseF() for $anyElementTrue in "sbe_stage_builder_expression.cpp"
-rw-r--r--src/mongo/db/query/sbe_stage_builder_expression.cpp49
-rw-r--r--src/mongo/db/query/sbe_stage_builder_expression.h2
2 files changed, 19 insertions, 32 deletions
diff --git a/src/mongo/db/query/sbe_stage_builder_expression.cpp b/src/mongo/db/query/sbe_stage_builder_expression.cpp
index f0d78e1c913..939c9b87bff 100644
--- a/src/mongo/db/query/sbe_stage_builder_expression.cpp
+++ b/src/mongo/db/query/sbe_stage_builder_expression.cpp
@@ -850,40 +850,27 @@ public:
visitMultiBranchLogicExpression(expr, sbe::EPrimBinary::logicAnd);
}
void visit(const ExpressionAnyElementTrue* expr) final {
- auto [inputSlot, stage] = projectEvalExpr(_context->popEvalExpr(),
- _context->extractCurrentEvalStage(),
- _context->planNodeId,
- _context->state.slotIdGenerator);
+ auto frameId = _context->state.frameId();
+ auto binds = sbe::makeEs(_context->popExpr());
+ sbe::EVariable inputRef(frameId, 0);
+
+ auto lambdaFrame = _context->state.frameId();
+ sbe::EVariable lambdaParam(lambdaFrame, 0);
+ auto lambdaExpr =
+ sbe::makeE<sbe::ELocalLambda>(lambdaFrame, generateCoerceToBoolExpression(lambdaParam));
- auto fromBranch = makeFilter<false>(
- std::move(stage),
+ auto resultExpr = makeBinaryOp(
+ sbe::EPrimBinary::logicAnd,
makeBinaryOp(sbe::EPrimBinary::logicOr,
- makeFillEmptyFalse(makeFunction("isArray", makeVariable(inputSlot))),
+ makeFillEmptyFalse(makeFunction("isArray", inputRef.clone())),
makeFail(5159200, "$anyElementTrue's argument must be an array")),
- _context->planNodeId);
+ makeFunction("traverseF",
+ inputRef.clone(),
+ std::move(lambdaExpr),
+ sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::Boolean, false)));
- auto innerOutputSlot = _context->state.slotId();
- auto innerBranch = makeProject(makeLimitCoScanStage(_context->planNodeId),
- _context->planNodeId,
- innerOutputSlot,
- generateCoerceToBoolExpression(inputSlot));
-
- auto traverseSlot = _context->state.slotId();
- auto traverseStage = makeTraverse(std::move(fromBranch),
- std::move(innerBranch),
- inputSlot,
- traverseSlot,
- innerOutputSlot,
- makeBinaryOp(sbe::EPrimBinary::logicOr,
- makeVariable(traverseSlot),
- makeVariable(innerOutputSlot)),
- makeVariable(traverseSlot),
- _context->planNodeId,
- 1,
- _context->getLexicalEnvironment());
-
- _context->pushExpr(makeFillEmptyFalse(makeVariable(traverseSlot)),
- std::move(traverseStage));
+ _context->pushExpr(
+ sbe::makeE<sbe::ELocalBind>(frameId, std::move(binds), std::move(resultExpr)));
}
void visit(const ExpressionArray* expr) final {
unsupportedExpression(expr->getOpName());
@@ -3917,7 +3904,7 @@ private:
};
} // namespace
-std::unique_ptr<sbe::EExpression> generateCoerceToBoolExpression(sbe::EVariable branchRef) {
+std::unique_ptr<sbe::EExpression> generateCoerceToBoolExpression(const sbe::EVariable& branchRef) {
auto makeNotNullOrUndefinedCheck = [&branchRef]() {
return makeNot(makeFunction(
"typeMatch",
diff --git a/src/mongo/db/query/sbe_stage_builder_expression.h b/src/mongo/db/query/sbe_stage_builder_expression.h
index 4995df04a5c..3d148113f89 100644
--- a/src/mongo/db/query/sbe_stage_builder_expression.h
+++ b/src/mongo/db/query/sbe_stage_builder_expression.h
@@ -53,5 +53,5 @@ EvalExprStagePair generateExpression(StageBuilderState& state,
* can be of any type to a Boolean value based on MQL's definition of truth for the branch of any
* logical expression.
*/
-std::unique_ptr<sbe::EExpression> generateCoerceToBoolExpression(sbe::EVariable branchRef);
+std::unique_ptr<sbe::EExpression> generateCoerceToBoolExpression(const sbe::EVariable& branchRef);
} // namespace mongo::stage_builder