diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/CheckMatchExpression.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/CheckMatchExpression.java index 8f0ad8706f35c5..c5923ab80da8e9 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/CheckMatchExpression.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/CheckMatchExpression.java @@ -47,20 +47,18 @@ public Rule build() { private Plan checkChildren(LogicalFilter filter) { List expressions = filter.getExpressions(); - for (Expression expr : expressions) { - if (expr instanceof Match) { - Match matchExpression = (Match) expr; - SlotReference slotReference = getSlotFromSlotCastOrAliasChain(matchExpression.left()); - if (slotReference == null - || !(matchExpression.right() instanceof Literal)) { - throw new AnalysisException(String.format("Only support match left operand is SlotRef," - + " right operand is Literal. But meet expression %s", matchExpression)); - } - if (slotReference.getDataType().isVariantType() && !slotReference.hasSubColPath()) { - throw new AnalysisException(String.format("VARIANT root column does not support MATCH predicates. " - + "Please query a subcolumn instead, for example %s['field'] MATCH 'xxx'", - slotReference.getName())); - } + List matchExpressions = ExpressionUtils.collectToList(expressions, Match.class::isInstance); + for (Match matchExpression : matchExpressions) { + SlotReference slotReference = getSlotFromSlotCastOrAliasChain(matchExpression.left()); + if (slotReference == null + || !(matchExpression.right() instanceof Literal)) { + throw new AnalysisException(String.format("Only support match left operand is SlotRef," + + " right operand is Literal. But meet expression %s", matchExpression)); + } + if (slotReference.getDataType().isVariantType() && !slotReference.hasSubColPath()) { + throw new AnalysisException(String.format("VARIANT root column does not support MATCH predicates. " + + "Please query a subcolumn instead, for example %s['field'] MATCH 'xxx'", + slotReference.getName())); } } return filter; diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/CheckMatchExpressionTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/CheckMatchExpressionTest.java index a127ed0e7c5508..9b2cc9d9bb1d92 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/CheckMatchExpressionTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/CheckMatchExpressionTest.java @@ -23,6 +23,7 @@ import org.apache.doris.nereids.trees.expressions.Cast; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.MatchAny; +import org.apache.doris.nereids.trees.expressions.Or; import org.apache.doris.nereids.trees.expressions.SlotReference; import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral; import org.apache.doris.nereids.trees.expressions.literal.StringLiteral; @@ -63,6 +64,19 @@ void testRejectsRootVariantMatch() { exception.getMessage()); } + @Test + void testRejectsRootVariantMatchNestedInOr() { + SlotReference textSlot = new SlotReference("response_body", StringType.INSTANCE, true); + SlotReference rootVariantSlot = new SlotReference("response", VariantType.INSTANCE, true, Arrays.asList()); + Or match = new Or( + new MatchAny(textSlot, new StringLiteral("doris")), + new MatchAny(rootVariantSlot, new StringLiteral("doris"))); + + AnalysisException exception = Assertions.assertThrows(AnalysisException.class, () -> invokeCheck(match)); + Assertions.assertTrue(exception.getMessage().contains("VARIANT root column does not support MATCH"), + exception.getMessage()); + } + @Test void testRejectsCastOnRootVariantMatch() { SlotReference rootVariantSlot = new SlotReference("response", VariantType.INSTANCE, true, Arrays.asList()); diff --git a/regression-test/suites/search/test_disable_root_variant_match.groovy b/regression-test/suites/search/test_disable_root_variant_match.groovy index f800e8e23419a0..affb5a82e502a6 100644 --- a/regression-test/suites/search/test_disable_root_variant_match.groovy +++ b/regression-test/suites/search/test_disable_root_variant_match.groovy @@ -26,10 +26,15 @@ suite("test_disable_root_variant_match", "p0") { sql """ CREATE TABLE test_disable_root_variant_match_tbl ( `id` INT NOT NULL, + `response_body` TEXT NULL, `response` variant< MATCH_NAME 'msg' : string, properties("variant_max_subcolumns_count" = "16") > NULL, + INDEX idx_response_body (response_body) USING INVERTED PROPERTIES( + "parser" = "unicode", + "lower_case" = "true" + ), INDEX idx_response (response) USING INVERTED PROPERTIES( "parser" = "unicode", "field_pattern" = "msg", @@ -45,9 +50,9 @@ suite("test_disable_root_variant_match", "p0") { """ sql """INSERT INTO test_disable_root_variant_match_tbl VALUES - (1, '{"msg": "doris community"}'), - (2, '{"msg": "apache software"}'), - (3, '{"msg": "doris variant index"}') + (1, 'doris community', '{"msg": "doris community"}'), + (2, 'apache software', '{"msg": "apache software"}'), + (3, 'doris variant index', '{"msg": "doris variant index"}') """ sql "sync" @@ -63,6 +68,17 @@ suite("test_disable_root_variant_match", "p0") { exception "VARIANT root column does not support MATCH" } + test { + sql """ + SELECT /*+SET_VAR(enable_common_expr_pushdown=true)*/ id + FROM test_disable_root_variant_match_tbl + WHERE response_body MATCH_ANY 'doris' + OR response MATCH_ANY 'doris' + ORDER BY id + """ + exception "VARIANT root column does not support MATCH" + } + def variantSubcolumnMatchResult = sql """ SELECT /*+SET_VAR(enable_common_expr_pushdown=true)*/ id FROM test_disable_root_variant_match_tbl