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

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


The following commit(s) were added to refs/heads/branch-2.1 by this push:
     new 91dcc0e1940 branch-2.1: [fix](mtmv) Fix generate hyper graph wrongly 
when has filter which can not push down #43539 (#43946)
91dcc0e1940 is described below

commit 91dcc0e194085882709a0552f24dee8c1ec7fc31
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Sat Nov 16 16:08:36 2024 +0800

    branch-2.1: [fix](mtmv) Fix generate hyper graph wrongly when has filter 
which can not push down #43539 (#43946)
    
    Cherry-picked from #43539
    
    Co-authored-by: seawinde <[email protected]>
---
 .../jobs/joinorder/hypergraph/HyperGraph.java      |   2 +-
 .../mv/AbstractMaterializedViewRule.java           |  45 ++++--
 .../mv/join/left_outer/outer_join.out              |  48 +++++++
 .../mv/join/left_outer/outer_join.groovy           | 153 +++++++++++++++++++++
 4 files changed, 237 insertions(+), 11 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/HyperGraph.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/HyperGraph.java
index 19ff555469c..ee8e7553552 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/HyperGraph.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/HyperGraph.java
@@ -425,7 +425,7 @@ public class HyperGraph {
                 LogicalFilter<?> filter = (LogicalFilter<?>) plan;
                 Pair<BitSet, Long> child = this.buildForMv(filter.child());
                 this.addFilter(filter, child);
-                return Pair.of(new BitSet(), child.second);
+                return Pair.of(child.first, child.second);
             }
 
             // process Other Node
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 184d6f359da..884ac0980ad 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
@@ -724,12 +724,14 @@ public abstract class AbstractMaterializedViewRule 
implements ExplorationRuleFac
             SlotMapping queryToViewMapping = viewToQuerySlotMapping.inverse();
             // try to use
             boolean valid = containsNullRejectSlot(requireNoNullableViewSlot,
-                    queryStructInfo.getPredicates().getPulledUpPredicates(), 
queryToViewMapping, cascadesContext);
+                    queryStructInfo.getPredicates().getPulledUpPredicates(), 
queryToViewMapping, queryStructInfo,
+                    viewStructInfo, cascadesContext);
             if (!valid) {
                 queryStructInfo = queryStructInfo.withPredicates(
                         
queryStructInfo.getPredicates().merge(comparisonResult.getQueryAllPulledUpExpressions()));
                 valid = containsNullRejectSlot(requireNoNullableViewSlot,
-                        
queryStructInfo.getPredicates().getPulledUpPredicates(), queryToViewMapping, 
cascadesContext);
+                        
queryStructInfo.getPredicates().getPulledUpPredicates(), queryToViewMapping,
+                        queryStructInfo, viewStructInfo, cascadesContext);
             }
             if (!valid) {
                 return SplitPredicate.INVALID_INSTANCE;
@@ -779,6 +781,8 @@ public abstract class AbstractMaterializedViewRule 
implements ExplorationRuleFac
     private boolean containsNullRejectSlot(Set<Set<Slot>> 
requireNoNullableViewSlot,
             Set<Expression> queryPredicates,
             SlotMapping queryToViewMapping,
+            StructInfo queryStructInfo,
+            StructInfo viewStructInfo,
             CascadesContext cascadesContext) {
         Set<Expression> queryPulledUpPredicates = queryPredicates.stream()
                 .flatMap(expr -> 
ExpressionUtils.extractConjunction(expr).stream())
@@ -791,16 +795,37 @@ public abstract class AbstractMaterializedViewRule 
implements ExplorationRuleFac
                     return expr;
                 })
                 .collect(Collectors.toSet());
-        Set<Expression> nullRejectPredicates = 
ExpressionUtils.inferNotNull(queryPulledUpPredicates, cascadesContext);
-        Set<Expression> queryUsedNeedRejectNullSlotsViewBased = 
nullRejectPredicates.stream()
-                .map(expression -> 
TypeUtils.isNotNull(expression).orElse(null))
-                .filter(Objects::nonNull)
-                .map(expr -> ExpressionUtils.replace((Expression) expr, 
queryToViewMapping.toSlotReferenceMap()))
+        Set<Expression> queryNullRejectPredicates =
+                ExpressionUtils.inferNotNull(queryPulledUpPredicates, 
cascadesContext);
+        if (queryPulledUpPredicates.containsAll(queryNullRejectPredicates)) {
+            // Query has no null reject predicates, return
+            return false;
+        }
+        // Get query null reject predicate slots
+        Set<Expression> queryNullRejectSlotSet = new HashSet<>();
+        for (Expression queryNullRejectPredicate : queryNullRejectPredicates) {
+            Optional<Slot> notNullSlot = 
TypeUtils.isNotNull(queryNullRejectPredicate);
+            if (!notNullSlot.isPresent()) {
+                continue;
+            }
+            queryNullRejectSlotSet.add(notNullSlot.get());
+        }
+        // query slot need shuttle to use table slot, avoid alias influence
+        Set<Expression> queryUsedNeedRejectNullSlotsViewBased = 
ExpressionUtils.shuttleExpressionWithLineage(
+                        new ArrayList<>(queryNullRejectSlotSet), 
queryStructInfo.getTopPlan(), new BitSet()).stream()
+                .map(expr -> ExpressionUtils.replace(expr, 
queryToViewMapping.toSlotReferenceMap()))
                 .collect(Collectors.toSet());
+        // view slot need shuttle to use table slot, avoid alias influence
+        Set<Set<Slot>> shuttledRequireNoNullableViewSlot = new HashSet<>();
+        for (Set<Slot> requireNullableSlots : requireNoNullableViewSlot) {
+            shuttledRequireNoNullableViewSlot.add(
+                    ExpressionUtils.shuttleExpressionWithLineage(new 
ArrayList<>(requireNullableSlots),
+                                    viewStructInfo.getTopPlan(), new 
BitSet()).stream().map(Slot.class::cast)
+                            .collect(Collectors.toSet()));
+        }
         // query pulledUp predicates should have null reject predicates and 
contains any require noNullable slot
-        return !queryPulledUpPredicates.containsAll(nullRejectPredicates)
-                && requireNoNullableViewSlot.stream().noneMatch(set ->
-                Sets.intersection(set, 
queryUsedNeedRejectNullSlotsViewBased).isEmpty());
+        return 
shuttledRequireNoNullableViewSlot.stream().noneMatch(viewRequiredNullSlotSet ->
+                Sets.intersection(viewRequiredNullSlotSet, 
queryUsedNeedRejectNullSlotsViewBased).isEmpty());
     }
 
     /**
diff --git 
a/regression-test/data/nereids_rules_p0/mv/join/left_outer/outer_join.out 
b/regression-test/data/nereids_rules_p0/mv/join/left_outer/outer_join.out
index 225e336b91f..1a1b846054b 100644
--- a/regression-test/data/nereids_rules_p0/mv/join/left_outer/outer_join.out
+++ b/regression-test/data/nereids_rules_p0/mv/join/left_outer/outer_join.out
@@ -325,3 +325,51 @@
 2023-12-11     4       2
 2023-12-12     5       4
 
+-- !query10_0_before --
+2023-12-09     1       yy      2       4
+2023-12-11     2       mm      4       3
+
+-- !query10_0_after --
+2023-12-09     1       yy      2       4
+2023-12-11     2       mm      4       3
+
+-- !query11_0_before --
+2023-12-09     1       yy      95      4
+2023-12-09     1       yy      96      4
+2023-12-09     1       yy      97      4
+2023-12-10     1       yy      100     2
+2023-12-10     1       yy      101     2
+2023-12-10     1       yy      98      2
+2023-12-10     1       yy      99      2
+2023-12-11     2       mm      102     3
+2023-12-11     2       mm      103     3
+2023-12-11     2       mm      104     3
+2023-12-12     2       mi      105     2
+2023-12-12     2       mi      105     2
+2023-12-12     2       mi      106     2
+2023-12-12     2       mi      106     2
+2023-12-12     2       mi      107     2
+2023-12-12     2       mi      107     2
+2023-12-12     2       mi      108     2
+2023-12-12     2       mi      108     2
+
+-- !query11_0_after --
+2023-12-09     1       yy      95      4
+2023-12-09     1       yy      96      4
+2023-12-09     1       yy      97      4
+2023-12-10     1       yy      100     2
+2023-12-10     1       yy      101     2
+2023-12-10     1       yy      98      2
+2023-12-10     1       yy      99      2
+2023-12-11     2       mm      102     3
+2023-12-11     2       mm      103     3
+2023-12-11     2       mm      104     3
+2023-12-12     2       mi      105     2
+2023-12-12     2       mi      105     2
+2023-12-12     2       mi      106     2
+2023-12-12     2       mi      106     2
+2023-12-12     2       mi      107     2
+2023-12-12     2       mi      107     2
+2023-12-12     2       mi      108     2
+2023-12-12     2       mi      108     2
+
diff --git 
a/regression-test/suites/nereids_rules_p0/mv/join/left_outer/outer_join.groovy 
b/regression-test/suites/nereids_rules_p0/mv/join/left_outer/outer_join.groovy
index ed926d59e1f..4065e58c0b5 100644
--- 
a/regression-test/suites/nereids_rules_p0/mv/join/left_outer/outer_join.groovy
+++ 
b/regression-test/suites/nereids_rules_p0/mv/join/left_outer/outer_join.groovy
@@ -195,9 +195,91 @@ suite("outer_join") {
     (2, 3, 10, 11.01, 'supply2');
     """
 
+    sql """drop table if exists orders_same_col;"""
+    sql """
+    CREATE TABLE IF NOT EXISTS orders_same_col  (
+      o_orderkey       INTEGER NOT NULL,
+      o_custkey        INTEGER NOT NULL,
+      o_orderstatus    CHAR(1) NOT NULL,
+      o_totalprice     DECIMALV3(15,2) NOT NULL,
+      o_orderdate      DATE NOT NULL,
+      o_orderpriority  CHAR(15) NOT NULL,  
+      o_clerk          CHAR(15) NOT NULL, 
+      o_shippriority   INTEGER NOT NULL,
+      O_COMMENT        VARCHAR(79) NOT NULL,
+      o_code VARCHAR(6) NOT NULL
+    )
+    DUPLICATE KEY(o_orderkey, o_custkey)
+    DISTRIBUTED BY HASH(o_orderkey) BUCKETS 3
+    PROPERTIES (
+      "replication_num" = "1"
+    );"""
+
+    sql """
+    insert into orders_same_col values
+    (1, 1, 'o', 9.5, '2023-12-08', 'a', 'b', 1, 'yy', '91'),
+    (1, 1, 'o', 10.5, '2023-12-08', 'a', 'b', 1, 'yy', '92'),
+    (1, 1, 'o', 10.5, '2023-12-08', 'a', 'b', 1, 'yy', '93'),
+    (1, 1, 'o', 10.5, '2023-12-08', 'a', 'b', 1, 'yy', '94'),
+    (2, 1, 'o', 11.5, '2023-12-09', 'a', 'b', 1, 'yy', '95'),
+    (2, 1, 'o', 11.5, '2023-12-09', 'a', 'b', 1, 'yy', '96'),
+    (2, 1, 'o', 11.5, '2023-12-09', 'a', 'b', 1, 'yy', '97'),
+    (3, 1, 'o', 12.5, '2023-12-10', 'a', 'b', 1, 'yy', '98'),
+    (3, 1, 'o', 12.5, '2023-12-10', 'a', 'b', 1, 'yy', '99'),
+    (3, 1, 'o', 12.5, '2023-12-10', 'a', 'b', 1, 'yy', '100'),
+    (3, 1, 'o', 33.5, '2023-12-10', 'a', 'b', 1, 'yy', '101'),
+    (4, 2, 'o', 43.2, '2023-12-11', 'c','d',2, 'mm', '102'),
+    (4, 2, 'o', 43.2, '2023-12-11', 'c','d',2, 'mm', '103'),
+    (4, 2, 'o', 43.2, '2023-12-11', 'c','d',2, 'mm', '104'),
+    (5, 2, 'o', 56.2, '2023-12-12', 'c','d',2, 'mi', '105'),
+    (5, 2, 'o', 56.2, '2023-12-12', 'c','d',2, 'mi', '106'),
+    (5, 2, 'o', 56.2, '2023-12-12', 'c','d',2, 'mi', '107'),
+    (5, 2, 'o', 1.2, '2023-12-12', 'c','d',2, 'mi', '108');  
+    """
+
+    sql """drop table if exists lineitem_same_col; """
+    sql """
+    CREATE TABLE IF NOT EXISTS lineitem_same_col (
+      l_orderkey    INTEGER NOT NULL,
+      l_partkey     INTEGER NOT NULL,
+      l_suppkey     INTEGER NOT NULL,
+      l_linenumber  INTEGER NOT NULL,
+      l_quantity    DECIMALV3(15,2) NOT NULL,
+      l_extendedprice  DECIMALV3(15,2) NOT NULL,
+      l_discount    DECIMALV3(15,2) NOT NULL,
+      l_tax         DECIMALV3(15,2) NOT NULL,
+      l_returnflag  CHAR(1) NOT NULL,
+      l_linestatus  CHAR(1) NOT NULL,
+      l_shipdate    DATE NOT NULL,
+      l_commitdate  DATE NOT NULL,
+      l_receiptdate DATE NOT NULL,
+      l_shipinstruct CHAR(25) NOT NULL,
+      l_shipmode     CHAR(10) NOT NULL,
+      l_comment      VARCHAR(44) NOT NULL,
+      o_code VARCHAR(6) NOT NULL
+    )
+    DUPLICATE KEY(l_orderkey, l_partkey, l_suppkey, l_linenumber)
+    DISTRIBUTED BY HASH(l_orderkey) BUCKETS 3
+    PROPERTIES (
+      "replication_num" = "1"
+    );
+    """
+
+    sql """
+    insert into lineitem_same_col values
+    (1, 2, 3, 4, 5.5, 6.5, 7.5, 8.5, 'o', 'k', '2023-12-08', '2023-12-09', 
'2023-12-10', 'a', 'b', 'yyyyyyyyy', '91'),
+    (2, 4, 3, 4, 5.5, 6.5, 7.5, 8.5, 'o', 'k', '2023-12-09', '2023-12-09', 
'2023-12-10', 'a', 'b', 'yyyyyyyyy', '92'),
+    (3, 2, 4, 4, 5.5, 6.5, 7.5, 8.5, 'o', 'k', '2023-12-10', '2023-12-09', 
'2023-12-10', 'a', 'b', 'yyyyyyyyy', '93'),
+    (4, 3, 3, 4, 5.5, 6.5, 7.5, 8.5, 'o', 'k', '2023-12-11', '2023-12-09', 
'2023-12-10', 'a', 'b', 'yyyyyyyyy', '94'),
+    (5, 2, 3, 6, 7.5, 8.5, 9.5, 10.5, 'k', 'o', '2023-12-12', '2023-12-12', 
'2023-12-13', 'c', 'd', 'xxxxxxxxx','95');
+
+    """
+
     sql """analyze table lineitem with sync;"""
     sql """analyze table orders with sync;"""
     sql """analyze table partsupp with sync;"""
+    sql """analyze table orders_same_col with sync;"""
+    sql """analyze table lineitem_same_col with sync;"""
 
     // without filter
     def mv1_0 = "select  lineitem.L_LINENUMBER, orders.O_CUSTKEY " +
@@ -606,4 +688,75 @@ suite("outer_join") {
     async_mv_rewrite_success(db, mv9_0, query9_0, "mv9_0")
     order_qt_query9_0_after "${query9_0}"
     sql """ DROP MATERIALIZED VIEW IF EXISTS mv9_0"""
+
+
+    // Test filter which can not push down through join and there is more than 
two join
+    def mv10_0 = """
+    select
+    o_orderdate,
+    o_shippriority,
+    o_comment,
+    l_orderkey,
+    l_partkey
+    from
+    orders left
+    join lineitem on l_orderkey = o_orderkey
+    left join partsupp on ps_partkey = l_partkey and l_suppkey = ps_suppkey;
+    """
+
+    def query10_0 = """
+    select
+    o_orderdate,
+    o_shippriority,
+    o_comment,
+    l_orderkey,
+    l_partkey
+    from
+    orders left
+    join lineitem on l_orderkey = o_orderkey
+    left join partsupp on ps_partkey = l_partkey and l_suppkey = ps_suppkey
+    where l_partkey is null or l_partkey <> 2;
+    """
+
+    order_qt_query10_0_before "${query10_0}"
+    async_mv_rewrite_success(db, mv10_0, query10_0, "mv10_0")
+    order_qt_query10_0_after "${query10_0}"
+    sql """ DROP MATERIALIZED VIEW IF EXISTS mv10_0"""
+
+
+    // Test where filter contains the same col in both lineitem_same_col and 
orders_same_col
+    def mv11_0 = """
+            select
+              o_orderdate,
+              o_shippriority,
+              o_comment,
+              o.o_code as o_o_code,
+              l_orderkey, 
+              l_partkey,
+              l.o_code as l_o_code
+            from
+              orders_same_col o left
+              join lineitem_same_col l on l_orderkey = o_orderkey
+              left join partsupp on ps_partkey = l_partkey and l_suppkey = 
ps_suppkey;
+    """
+
+    def query11_0 = """
+            select
+              o_orderdate,
+              o_shippriority,
+              o_comment,
+              o.o_code
+              l_orderkey, 
+              l_partkey
+            from
+              orders_same_col o left
+              join lineitem_same_col l on l_orderkey = o_orderkey
+              left join partsupp on ps_partkey = l_partkey and l_suppkey = 
ps_suppkey
+              where l.o_code <> '91';
+    """
+
+    order_qt_query11_0_before "${query11_0}"
+    async_mv_rewrite_success(db, mv11_0, query11_0, "mv11_0")
+    order_qt_query11_0_after "${query11_0}"
+    sql """ DROP MATERIALIZED VIEW IF EXISTS mv11_0"""
 }


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

Reply via email to