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 1d465f6e87d branch-4.1:[fix](mtmv) Avoid invalid slot cast in MV 
null-reject compensation (#66613) (#67266)
1d465f6e87d is described below

commit 1d465f6e87d04844f9424c146e4d14df3e511055
Author: seawinde <[email protected]>
AuthorDate: Fri Aug 28 20:51:34 2026 +0800

    branch-4.1:[fix](mtmv) Avoid invalid slot cast in MV null-reject 
compensation (#66613) (#67266)
    
    pr: #66613
    commitId: a97548f25a8
---
 .../mv/AbstractMaterializedViewRule.java           |  4 +-
 .../exploration/mv/NullRejectInferenceTest.java    | 47 ++++++++++++++++++++++
 2 files changed, 50 insertions(+), 1 deletion(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/AbstractMaterializedViewRule.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/AbstractMaterializedViewRule.java
index 34eacfd90ed..f1bfe8d89e3 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/AbstractMaterializedViewRule.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/AbstractMaterializedViewRule.java
@@ -973,7 +973,9 @@ public abstract class AbstractMaterializedViewRule 
implements ExplorationRuleFac
         for (Set<Slot> requireNullableSlots : requireNoNullableViewSlot) {
             shuttledRequireNoNullableViewSlot.add(
                     ExpressionUtils.shuttleExpressionWithLineage(new 
ArrayList<>(requireNullableSlots),
-                                    
viewStructInfo.getTopPlan()).stream().map(Slot.class::cast)
+                                    viewStructInfo.getTopPlan()).stream()
+                            .filter(Slot.class::isInstance)
+                            .map(Slot.class::cast)
                             .collect(Collectors.toSet()));
         }
         return shuttledRequireNoNullableViewSlot;
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/exploration/mv/NullRejectInferenceTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/exploration/mv/NullRejectInferenceTest.java
index 5fd7628096b..2f7e8c869bc 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/exploration/mv/NullRejectInferenceTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/exploration/mv/NullRejectInferenceTest.java
@@ -184,6 +184,53 @@ class NullRejectInferenceTest extends SqlTestBase {
                 .anyMatch(expression -> isNotNullOnSlot(expression, 
"o_orderdate")));
     }
 
+    @Test
+    void testNullRejectCompensationWithCastJoinConditionFallsBack() {
+        
connectContext.getSessionVariable().setDisableNereidsRules("INFER_PREDICATES,PRUNE_EMPTY_PARTITION");
+        CascadesContext queryContext = createCascadesContext(
+                "select lineitem.l_orderkey, orders.o_orderkey, 
orders.o_orderdate from lineitem "
+                        + "inner join orders on cast(lineitem.l_orderkey as 
bigint) "
+                        + "= cast(orders.o_orderkey as bigint)",
+                connectContext
+        );
+        Plan queryPlan = PlanChecker.from(queryContext)
+                .analyze()
+                .rewrite()
+                .applyExploration(RuleSet.BUSHY_TREE_JOIN_REORDER)
+                .getAllPlan().get(0).child(0);
+
+        CascadesContext viewContext = createCascadesContext(
+                "select lineitem.l_orderkey, orders.o_orderkey, 
orders.o_orderdate from lineitem "
+                        + "left outer join orders on cast(lineitem.l_orderkey 
as bigint) "
+                        + "= cast(orders.o_orderkey as bigint)",
+                connectContext
+        );
+        Plan viewPlan = PlanChecker.from(viewContext)
+                .analyze()
+                .rewrite()
+                .applyExploration(RuleSet.BUSHY_TREE_JOIN_REORDER)
+                .getAllPlan().get(0).child(0);
+
+        StructInfo queryStructInfo = StructInfo.of(queryPlan, queryPlan, 
queryContext);
+        StructInfo viewStructInfo = StructInfo.of(viewPlan, viewPlan, 
viewContext);
+        RelationMapping relationMapping = RelationMapping.generate(
+                queryStructInfo.getRelations(), viewStructInfo.getRelations(), 
8).get(0);
+        SlotMapping queryToView = SlotMapping.generate(relationMapping);
+        SlotMapping viewToQuery = queryToView.inverse();
+        LogicalCompatibilityContext compatibilityContext = 
LogicalCompatibilityContext.from(
+                relationMapping, viewToQuery, queryStructInfo, viewStructInfo);
+        ComparisonResult comparisonResult = StructInfo.isGraphLogicalEquals(
+                queryStructInfo, viewStructInfo, compatibilityContext);
+
+        Assertions.assertFalse(comparisonResult.isInvalid());
+        
Assertions.assertFalse(comparisonResult.getViewNoNullableSlot().isEmpty());
+
+        SplitPredicate compensatePredicates = Assertions.assertDoesNotThrow(
+                () -> TEST_RULE.predicatesCompensateForTest(
+                        queryStructInfo, viewStructInfo, viewToQuery, 
comparisonResult, queryContext));
+        Assertions.assertTrue(compensatePredicates.isInvalid());
+    }
+
     private static boolean isNotNullOnSlot(Expression expression, String 
slotName) {
         if (!(expression instanceof Not) || ((Not) 
expression).isGeneratedIsNotNull()
                 || !(((Not) expression).child() instanceof IsNull)) {


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

Reply via email to