diff --git a/src/graph/optimizer/rule/OptimizeTagIndexScanByFilterRule.cpp b/src/graph/optimizer/rule/OptimizeTagIndexScanByFilterRule.cpp index 79160207799..1abca012cfe 100644 --- a/src/graph/optimizer/rule/OptimizeTagIndexScanByFilterRule.cpp +++ b/src/graph/optimizer/rule/OptimizeTagIndexScanByFilterRule.cpp @@ -119,21 +119,27 @@ StatusOr OptimizeTagIndexScanByFilterRule::transform( } // case2: logical AND expr - if (condition->kind() == ExprKind::kLogicalAnd) { + size_t operandIndex = 0; + if (conditionType == ExprKind::kLogicalAnd) { for (auto& operand : static_cast(condition)->operands()) { if (operand->kind() == ExprKind::kRelIn) { auto inExpr = static_cast(operand); - // Do not apply this rule if the IN expr has a valid index or it has only 1 element in the - // list + // Do not apply this rule if the IN expr has a valid index or it has more than 1 element in + // the list if (static_cast(inExpr->right())->size() > 1) { return TransformResult::noTransform(); } else { - transformedExpr = graph::ExpressionUtils::rewriteInExpr(condition); + // If the inner IN expr has only 1 element, rewrite it to an relEQ expression and there is + // no need to check wether it has a index + auto relEqExpr = graph::ExpressionUtils::rewriteInExpr(inExpr); + static_cast(transformedExpr)->setOperand(operandIndex, relEqExpr); + continue; } if (OptimizerUtils::relExprHasIndex(inExpr, indexItems)) { return TransformResult::noTransform(); } } + ++operandIndex; } } diff --git a/tests/tck/features/lookup/TagIndexFullScan.feature b/tests/tck/features/lookup/TagIndexFullScan.feature index 71021b65c95..e42778756a8 100644 --- a/tests/tck/features/lookup/TagIndexFullScan.feature +++ b/tests/tck/features/lookup/TagIndexFullScan.feature @@ -160,6 +160,20 @@ Feature: Lookup tag index full scan | 3 | Project | 4 | | | 4 | IndexScan | 0 | | | 0 | Start | | | + # c AND (a IN b) where b contains only 1 element + # (https://github.com/vesoft-inc/nebula/issues/3524) + When profiling query: + """ + LOOKUP ON player WHERE player.age IN [40] AND player.name == "Kobe Bryant" YIELD id(vertex) as id, player.age + """ + Then the result should be, in any order: + | id | player.age | + | "Kobe Bryant" | 40 | + And the execution plan should be: + | id | name | dependencies | operator info | + | 3 | Project | 4 | | + | 4 | TagIndexPrefixScan | 0 | | + | 0 | Start | | | Scenario: Tag with complex relational IN filter Given an empty graph