diff options
Diffstat (limited to 'src/mongo/db/query/sbe_stage_builder_filter.cpp')
-rw-r--r-- | src/mongo/db/query/sbe_stage_builder_filter.cpp | 79 |
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)))), |