This is an automated email from the ASF dual-hosted git repository.

yiguolei pushed a commit to branch branch-4.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-4.1 by this push:
     new d959ea0ae44 branch-4.1 [fix](match) Allow MATCH on aliased variant 
subcolumns (#63811)
d959ea0ae44 is described below

commit d959ea0ae44d0edbe68c79dba08735614edf3447
Author: lihangyu <[email protected]>
AuthorDate: Fri May 29 11:24:52 2026 +0800

    branch-4.1 [fix](match) Allow MATCH on aliased variant subcolumns (#63811)
    
    cherry-pick #63772
---
 .../rules/rewrite/CheckMatchExpression.java        |  7 ++--
 .../rules/rewrite/CheckMatchExpressionTest.java    | 45 ++++++++++++++++++++++
 .../rules/rewrite/VariantPruningLogicTest.java     | 29 ++++++++++++++
 3 files changed, 78 insertions(+), 3 deletions(-)

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 feaad409995..8f0ad8706f3 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
@@ -20,6 +20,7 @@ package org.apache.doris.nereids.rules.rewrite;
 import org.apache.doris.nereids.exceptions.AnalysisException;
 import org.apache.doris.nereids.rules.Rule;
 import org.apache.doris.nereids.rules.RuleType;
+import org.apache.doris.nereids.trees.expressions.Alias;
 import org.apache.doris.nereids.trees.expressions.Cast;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.Match;
@@ -49,7 +50,7 @@ public class CheckMatchExpression extends 
OneRewriteRuleFactory {
         for (Expression expr : expressions) {
             if (expr instanceof Match) {
                 Match matchExpression = (Match) expr;
-                SlotReference slotReference = 
getSlotFromSlotOrCastChain(matchExpression.left());
+                SlotReference slotReference = 
getSlotFromSlotCastOrAliasChain(matchExpression.left());
                 if (slotReference == null
                         || !(matchExpression.right() instanceof Literal)) {
                     throw new AnalysisException(String.format("Only support 
match left operand is SlotRef,"
@@ -65,9 +66,9 @@ public class CheckMatchExpression extends 
OneRewriteRuleFactory {
         return filter;
     }
 
-    private SlotReference getSlotFromSlotOrCastChain(Expression expression) {
+    private SlotReference getSlotFromSlotCastOrAliasChain(Expression 
expression) {
         Expression current = expression;
-        while (current instanceof Cast) {
+        while (current instanceof Cast || current instanceof Alias) {
             current = current.child(0);
         }
         return current instanceof SlotReference ? (SlotReference) current : 
null;
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 fbaa2d97a12..a127ed0e7c5 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
@@ -18,10 +18,13 @@
 package org.apache.doris.nereids.rules.rewrite;
 
 import org.apache.doris.nereids.exceptions.AnalysisException;
+import org.apache.doris.nereids.trees.expressions.Add;
+import org.apache.doris.nereids.trees.expressions.Alias;
 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.SlotReference;
+import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
 import org.apache.doris.nereids.trees.expressions.literal.StringLiteral;
 import org.apache.doris.nereids.trees.plans.logical.LogicalFilter;
 import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
@@ -79,6 +82,48 @@ class CheckMatchExpressionTest {
         Assertions.assertDoesNotThrow(() -> invokeCheck(match));
     }
 
+    @Test
+    void testAllowsAliasOnVariantSubcolumnMatch() {
+        SlotReference variantSubcolumnSlot = new SlotReference("response", 
VariantType.INSTANCE, true, Arrays.asList())
+                .withSubPath(Arrays.asList("trace_id"));
+        MatchAny match = new MatchAny(new Alias(variantSubcolumnSlot, 
"response.trace_id"),
+                new StringLiteral("doris"));
+
+        Assertions.assertDoesNotThrow(() -> invokeCheck(match));
+    }
+
+    @Test
+    void testAllowsCastOnAliasVariantSubcolumnMatch() {
+        SlotReference variantSubcolumnSlot = new SlotReference("response", 
VariantType.INSTANCE, true, Arrays.asList())
+                .withSubPath(Arrays.asList("trace_id"));
+        MatchAny match = new MatchAny(new Cast(new Alias(variantSubcolumnSlot, 
"response.trace_id"),
+                StringType.INSTANCE), new StringLiteral("doris"));
+
+        Assertions.assertDoesNotThrow(() -> invokeCheck(match));
+    }
+
+    @Test
+    void testAllowsAliasAndCastChainOnVariantSubcolumnMatch() {
+        SlotReference variantSubcolumnSlot = new SlotReference("response", 
VariantType.INSTANCE, true, Arrays.asList())
+                .withSubPath(Arrays.asList("trace_id"));
+        Expression left = new Cast(new Alias(new Cast(variantSubcolumnSlot, 
StringType.INSTANCE),
+                "response.trace_id"), StringType.INSTANCE);
+        MatchAny match = new MatchAny(left, new StringLiteral("doris"));
+
+        Assertions.assertDoesNotThrow(() -> invokeCheck(match));
+    }
+
+    @Test
+    void testRejectsAliasOnExpressionMatch() {
+        Expression aliasOnExpression = new Alias(new Add(new 
IntegerLiteral(1), new IntegerLiteral(2)),
+                "response.trace_id");
+        MatchAny match = new MatchAny(aliasOnExpression, new 
StringLiteral("doris"));
+
+        AnalysisException exception = 
Assertions.assertThrows(AnalysisException.class, () -> invokeCheck(match));
+        Assertions.assertTrue(exception.getMessage().contains("Only support 
match left operand is SlotRef"),
+                exception.getMessage());
+    }
+
     private void invokeCheck(Expression expression) throws Throwable {
         LogicalOlapScan scan = PlanConstructor.newLogicalOlapScan(0, "t1", 0);
         LogicalFilter<LogicalOlapScan> filter = new 
LogicalFilter<>(ImmutableSet.of(expression), scan);
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/VariantPruningLogicTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/VariantPruningLogicTest.java
index cba05d26a93..6a23519e069 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/VariantPruningLogicTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/VariantPruningLogicTest.java
@@ -17,7 +17,10 @@
 
 package org.apache.doris.nereids.rules.rewrite;
 
+import org.apache.doris.analysis.Expr;
+import org.apache.doris.analysis.MatchPredicate;
 import org.apache.doris.analysis.SlotDescriptor;
+import org.apache.doris.analysis.SlotRef;
 import org.apache.doris.catalog.Type;
 import org.apache.doris.common.Pair;
 import org.apache.doris.nereids.NereidsPlanner;
@@ -240,4 +243,30 @@ public class VariantPruningLogicTest extends 
TestWithFeService {
         accessPath.data_access_path = new 
TDataAccessPath(ImmutableList.copyOf(path));
         return accessPath;
     }
+
+    @Test
+    public void testMatchOnDotVariantSubColumnUsesSlotRefInScanPredicate() 
throws Exception {
+        String sql = "select id from variant_tbl "
+                + "where cast(v.trace_id as string) match_phrase_prefix 'abc'";
+        List<OlapScanNode> olapScanNodes = collectOlapScanNodes(sql);
+        Assertions.assertEquals(1, olapScanNodes.size());
+
+        List<MatchPredicate> matchPredicates = new ArrayList<>();
+        Expr.collectList(olapScanNodes.get(0).getConjuncts(), 
MatchPredicate.class, matchPredicates);
+        Assertions.assertEquals(1, matchPredicates.size());
+
+        Expr leftWithoutCast = matchPredicates.get(0).getChildWithoutCast(0);
+        Assertions.assertInstanceOf(SlotRef.class, leftWithoutCast, 
matchPredicates.get(0).toString());
+        SlotRef leftSlot = (SlotRef) leftWithoutCast;
+        Assertions.assertEquals(ImmutableList.of("trace_id"), 
leftSlot.getDesc().getSubColLables());
+    }
+
+    private List<OlapScanNode> collectOlapScanNodes(String sql) throws 
Exception {
+        NereidsPlanner planner = (NereidsPlanner) 
executeNereidsSql(sql).planner();
+        List<OlapScanNode> olapScanNodes = new ArrayList<>();
+        for (PlanFragment fragment : planner.getFragments()) {
+            
olapScanNodes.addAll(fragment.getPlanRoot().collectInCurrentFragment(OlapScanNode.class::isInstance));
+        }
+        return olapScanNodes;
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to