summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Fefer <ivan.fefer@mongodb.com>2023-02-10 08:46:12 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-02-10 10:25:46 +0000
commitce925dfbbc9459f65b1ad6f91a2d85c02ab69ca4 (patch)
tree135c9a03b76b59349be5f8f1c5719668c6713bf9
parentd72f39af21ee012d54c0f49245790bc6d9119b6d (diff)
downloadmongo-ce925dfbbc9459f65b1ad6f91a2d85c02ab69ca4.tar.gz
SERVER-57123 Reduce number of fillEmpty false in sbe_stage_builder_filter.cpp
-rw-r--r--src/mongo/db/query/sbe_stage_builder_filter.cpp79
1 files changed, 39 insertions, 40 deletions
diff --git a/src/mongo/db/query/sbe_stage_builder_filter.cpp b/src/mongo/db/query/sbe_stage_builder_filter.cpp
index ffc9f38260b..226b14c708f 100644
--- a/src/mongo/db/query/sbe_stage_builder_filter.cpp
+++ b/src/mongo/db/query/sbe_stage_builder_filter.cpp
@@ -301,13 +301,12 @@ std::unique_ptr<sbe::EExpression> generateTraverseF(
fieldExpr = std::make_unique<sbe::EVariable>(*frameId, 0);
}
- // traverseF() can return Nothing in some cases if the lambda returns Nothing. We use
- // fillEmpty() to convert Nothing to false here to guard against such cases.
- auto traverseFExpr = makeFillEmptyFalse(
- makeFunction("traverseF",
- fieldExpr->clone(),
- std::move(lambdaExpr),
- makeConstant(sbe::value::TypeTags::Boolean, needsArrayCheck)));
+ // traverseF() can return Nothing only when the lambda returns Nothing. All expressions that we
+ // generate return Boolean, so there is no need for explicit fillEmpty here.
+ auto traverseFExpr = makeFunction("traverseF",
+ fieldExpr->clone(),
+ std::move(lambdaExpr),
+ makeConstant(sbe::value::TypeTags::Boolean, needsArrayCheck));
// When the predicate can match Nothing, we need to do some extra work for non-leaf fields.
if (needsNothingCheck) {
@@ -774,16 +773,16 @@ public:
auto lambdaExpr = sbe::makeE<sbe::ELocalLambda>(lambdaFrameId, std::move(lambdaBodyExpr));
auto makePredicate = [&](EvalExpr inputExpr) {
- return makeBinaryOp(
- sbe::EPrimBinary::logicAnd,
- makeFillEmptyFalse(makeFunction(
- "isArray",
- inputExpr.getExpr(_context->state.slotVarMap, *_context->state.data->env))),
- makeFillEmptyFalse(makeFunction(
- "traverseF",
- inputExpr.getExpr(_context->state.slotVarMap, *_context->state.data->env),
- std::move(lambdaExpr),
- makeConstant(sbe::value::TypeTags::Boolean, false))));
+ return makeFillEmptyFalse(
+ makeBinaryOp(sbe::EPrimBinary::logicAnd,
+ makeFunction("isArray",
+ inputExpr.getExpr(_context->state.slotVarMap,
+ *_context->state.data->env)),
+ makeFunction("traverseF",
+ inputExpr.getExpr(_context->state.slotVarMap,
+ *_context->state.data->env),
+ std::move(lambdaExpr),
+ makeConstant(sbe::value::TypeTags::Boolean, false))));
};
const auto traversalMode = LeafTraversalMode::kDoNotTraverseLeaf;
@@ -817,16 +816,16 @@ public:
lambdaFrameId, lambdaBodyExpr.extractExpr(_context->state));
auto makePredicate = [&](EvalExpr inputExpr) {
- return makeBinaryOp(
- sbe::EPrimBinary::logicAnd,
- makeFillEmptyFalse(makeFunction(
- "isArray",
- inputExpr.getExpr(_context->state.slotVarMap, *_context->state.data->env))),
- makeFillEmptyFalse(makeFunction(
- "traverseF",
- inputExpr.getExpr(_context->state.slotVarMap, *_context->state.data->env),
- std::move(lambdaExpr),
- makeConstant(sbe::value::TypeTags::Boolean, false))));
+ return makeFillEmptyFalse(
+ makeBinaryOp(sbe::EPrimBinary::logicAnd,
+ makeFunction("isArray",
+ inputExpr.getExpr(_context->state.slotVarMap,
+ *_context->state.data->env)),
+ makeFunction("traverseF",
+ inputExpr.getExpr(_context->state.slotVarMap,
+ *_context->state.data->env),
+ std::move(lambdaExpr),
+ makeConstant(sbe::value::TypeTags::Boolean, false))));
};
const auto traversalMode = LeafTraversalMode::kDoNotTraverseLeaf;
@@ -1455,10 +1454,12 @@ EvalExpr generateBitTestExpr(StageBuilderState& state,
numericBitTestExpr = makeNot(std::move(numericBitTestExpr));
}
- // numericBitTestExpr might produce Nothing, so we wrap it with makeFillEmptyFalse().
- return sbe::makeE<sbe::EIf>(makeFunction("isBinData"_sd, inputExpr.extractExpr(state)),
- std::move(binaryBitTestExpr),
- makeFillEmptyFalse(std::move(numericBitTestExpr)));
+ // isBinData and numericBitTestExpr might produce Nothing, so we wrap everything with
+ // makeFillEmptyFalse().
+ return makeFillEmptyFalse(
+ sbe::makeE<sbe::EIf>(makeFunction("isBinData"_sd, inputExpr.extractExpr(state)),
+ std::move(binaryBitTestExpr),
+ std::move(numericBitTestExpr)));
}
EvalExpr generateModExpr(StageBuilderState& state,
@@ -1494,18 +1495,16 @@ EvalExpr generateModExpr(StageBuilderState& state,
sbe::value::bitcastFrom<int64_t>(expr->getRemainder()));
}
}();
- auto modExpression = makeBinaryOp(
- sbe::EPrimBinary::logicAnd,
- // Return false if the dividend cannot be represented as a 64 bit integer.
- makeNot(generateNullOrMissing(dividendConvertedToNumberInt64)),
- makeFillEmptyFalse(makeBinaryOp(
- sbe::EPrimBinary::eq,
- makeFunction("mod"_sd, dividendConvertedToNumberInt64.clone(), std::move(divisorExpr)),
- std::move(remainderExpr))));
+ auto modExpression = makeFillEmptyFalse(makeBinaryOp(
+ sbe::EPrimBinary::eq,
+ makeFunction("mod"_sd, dividendConvertedToNumberInt64.clone(), std::move(divisorExpr)),
+ std::move(remainderExpr)));
return makeBinaryOp(
sbe::EPrimBinary::logicAnd,
makeNot(makeBinaryOp(sbe::EPrimBinary::logicOr,
- generateNonNumericCheck(dividend.clone(), state),
+ makeBinaryOp(sbe::EPrimBinary::logicOr,
+ generateNullOrMissing(dividend.clone(), state),
+ generateNonNumericCheck(dividend.clone(), state)),
makeBinaryOp(sbe::EPrimBinary::logicOr,
generateNaNCheck(dividend.clone(), state),
generateInfinityCheck(dividend.clone(), state)))),