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

panxiaolei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new c8ad62a3cd [Enchancement](materialized-view) enchance materialized 
view where clause match (#18179)
c8ad62a3cd is described below

commit c8ad62a3cda378c40ff4163f08de0c470ea73c32
Author: Pxl <[email protected]>
AuthorDate: Thu Mar 30 13:02:21 2023 +0800

    [Enchancement](materialized-view) enchance materialized view where clause 
match (#18179)
    
    enchance materialized view where clause match
---
 .../apache/doris/analysis/CompoundPredicate.java   | 27 ++++++++++++++++++++++
 .../main/java/org/apache/doris/analysis/Expr.java  | 14 +++++++++++
 .../doris/planner/MaterializedViewSelector.java    |  4 ++--
 .../org/apache/doris/planner/OlapScanNode.java     | 11 +++++----
 .../apache/doris/planner/SingleNodePlanner.java    |  7 ++----
 .../java/org/apache/doris/planner/PlannerTest.java |  2 +-
 .../org/apache/doris/planner/QueryPlanTest.java    | 16 ++++++-------
 .../java/org/apache/doris/policy/PolicyTest.java   | 11 ++++-----
 regression-test/data/mv_p0/where/k123/k123.out     |  4 ++++
 .../suites/mv_p0/where/k123/k123.groovy            |  6 +++++
 10 files changed, 76 insertions(+), 26 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/CompoundPredicate.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/CompoundPredicate.java
index d711114db4..b98b982eb6 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/CompoundPredicate.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/CompoundPredicate.java
@@ -277,4 +277,31 @@ public class CompoundPredicate extends Predicate {
     public String toString() {
         return toSqlImpl();
     }
+
+    @Override
+    public boolean containsSubPredicate(Expr subExpr) throws AnalysisException 
{
+        if (op.equals(Operator.AND)) {
+            for (Expr child : children) {
+                if (child.containsSubPredicate(subExpr)) {
+                    return true;
+                }
+            }
+        }
+        return super.containsSubPredicate(subExpr);
+    }
+
+    @Override
+    public Expr replaceSubPredicate(Expr subExpr) throws AnalysisException {
+        if (op.equals(Operator.AND)) {
+            Expr lhs = children.get(0);
+            Expr rhs = children.get(1);
+            if (lhs.replaceSubPredicate(subExpr) == null) {
+                return rhs;
+            }
+            if (rhs.replaceSubPredicate(subExpr) == null) {
+                return lhs;
+            }
+        }
+        return this;
+    }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java
index c39616fc6d..a2d03c50ae 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java
@@ -2226,6 +2226,20 @@ public abstract class Expr extends TreeNode<Expr> 
implements ParseNode, Cloneabl
         return true;
     }
 
+    public boolean containsSubPredicate(Expr subExpr) throws AnalysisException 
{
+        if (toSqlWithoutTbl().equals(subExpr.toSqlWithoutTbl())) {
+            return true;
+        }
+        return false;
+    }
+
+    public Expr replaceSubPredicate(Expr subExpr) throws AnalysisException {
+        if (toSqlWithoutTbl().equals(subExpr.toSqlWithoutTbl())) {
+            return null;
+        }
+        return this;
+    }
+
     protected Type[] getActualArgTypes(Type[] originType) {
         return Arrays.stream(originType).map(
                 (Type type) -> {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/planner/MaterializedViewSelector.java
 
b/fe/fe-core/src/main/java/org/apache/doris/planner/MaterializedViewSelector.java
index 0996ff30b2..139abb0ba4 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/planner/MaterializedViewSelector.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/planner/MaterializedViewSelector.java
@@ -325,8 +325,8 @@ public class MaterializedViewSelector {
             }
 
             if (entry.getValue().getWhereClause() != null) {
-                if (selectStmt.getOriginalWhereClause() == null || 
!entry.getValue().getWhereClause().toSqlWithoutTbl()
-                        
.equals(selectStmt.getOriginalWhereClause().toSqlWithoutTbl())) {
+                if (selectStmt.getOriginalWhereClause() == null || 
!selectStmt.getOriginalWhereClause()
+                        
.containsSubPredicate(entry.getValue().getWhereClause())) {
                     iterator.remove();
                 }
                 continue;
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/planner/OlapScanNode.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/OlapScanNode.java
index f07adf882c..cfc42fd8ff 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/OlapScanNode.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/OlapScanNode.java
@@ -333,8 +333,11 @@ public class OlapScanNode extends ScanNode {
         return selectedIndexId;
     }
 
-    public void ignoreConjuncts() {
-        vconjunct = null;
+    public void ignoreConjuncts(Expr whereExpr) throws AnalysisException {
+        if (whereExpr == null) {
+            return;
+        }
+        vconjunct = vconjunct.replaceSubPredicate(whereExpr);
     }
 
     /**
@@ -1103,8 +1106,8 @@ public class OlapScanNode extends ScanNode {
         if (useTopnOpt) {
             output.append(prefix).append("TOPN OPT\n");
         }
-        if (!conjuncts.isEmpty()) {
-            output.append(prefix).append("PREDICATES: 
").append(getExplainString(conjuncts)).append("\n");
+        if (vconjunct != null) {
+            output.append(prefix).append("PREDICATES: 
").append(vconjunct.toSql()).append("\n");
         }
         if (!runtimeFilters.isEmpty()) {
             output.append(prefix).append("runtime filters: ");
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java
index 1883cc9094..9b7e716b9d 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java
@@ -1363,12 +1363,9 @@ public class SingleNodePlanner {
                 } else {
                     try {
                         // mv index have where clause, so where expr on scan 
node is unused.
-                        Expr whereExpr = olapScanNode.getOlapTable()
+                        
olapScanNode.ignoreConjuncts(olapScanNode.getOlapTable()
                                 
.getIndexMetaByIndexId(bestIndexInfo.getBestIndexId())
-                                .getWhereClause();
-                        if (whereExpr != null) {
-                            olapScanNode.ignoreConjuncts();
-                        }
+                                .getWhereClause());
 
                         // if the new selected index id is different from the 
old one, scan node will be
                         // updated.
diff --git a/fe/fe-core/src/test/java/org/apache/doris/planner/PlannerTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/planner/PlannerTest.java
index 730aab5674..97812cb0d0 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/planner/PlannerTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/planner/PlannerTest.java
@@ -455,7 +455,7 @@ public class PlannerTest extends TestWithFeService {
         stmtExecutor.execute();
         Planner planner = stmtExecutor.planner();
         String plan = planner.getExplainString(new ExplainOptions(false, 
false));
-        Assertions.assertTrue(plan.contains("PREDICATES: `k1` = 1, `k2` = 
1\n"));
+        Assertions.assertTrue(plan.contains("PREDICATES: `k1` = 1 AND `k2` = 
1\n"));
     }
 
     @Test
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java
index 206456e188..a057325d10 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java
@@ -1654,7 +1654,7 @@ public class QueryPlanTest extends TestWithFeService {
         //default format
         String sql = "select * from test1 where from_unixtime(query_time) > 
'2021-03-02 10:01:28'";
         String explainString = getSQLPlanOrErrorMsg("EXPLAIN " + sql);
-        Assert.assertTrue(explainString.contains("PREDICATES: `query_time` <= 
253402271999, `query_time` > 1614650488"));
+        Assert.assertTrue(explainString.contains("PREDICATES: `query_time` <= 
253402271999 AND `query_time` > 1614650488"));
     }
 
     @Test
@@ -1829,7 +1829,7 @@ public class QueryPlanTest extends TestWithFeService {
         // (false or expr1) and (false or expr2) ==> expr1 and expr2
         String sql9 = "select * from test.test1 where (-2=2 or query_time=2) 
and (-2=2 or stmt_id=2);";
         String explainString9 = getSQLPlanOrErrorMsg("EXPLAIN " + sql9);
-        Assert.assertTrue(explainString9.contains("PREDICATES: `query_time` = 
2, `stmt_id` = 2"));
+        Assert.assertTrue(explainString9.contains("PREDICATES: `query_time` = 
2 AND `stmt_id` = 2"));
 
         // false or (expr and true) ==> expr
         String sql10 = "select * from test.test1 where (2=-2) OR (query_time=0 
AND 1=1);";
@@ -1865,7 +1865,7 @@ public class QueryPlanTest extends TestWithFeService {
             Assert.assertTrue(explainStr.contains("PREDICATES: `date` >= 
'2021-10-07',"
                     + " `date` <= '2021-10-11'"));
         } else {
-            Assert.assertTrue(explainStr.contains("PREDICATES: `date` >= 
'2021-10-07 00:00:00',"
+            Assert.assertTrue(explainStr.contains("PREDICATES: `date` >= 
'2021-10-07 00:00:00' AND"
                     + " `date` <= '2021-10-11 00:00:00'"));
         }
     }
@@ -2210,15 +2210,15 @@ public class QueryPlanTest extends TestWithFeService {
 
         sql = "SELECT * from test1 where (query_time = 1 or query_time = 2) 
and query_time in (3, 4)";
         explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, 
"EXPLAIN " + sql);
-        Assert.assertTrue(explainString.contains("PREDICATES: `query_time` IN 
(1, 2), `query_time` IN (3, 4)\n"));
+        Assert.assertTrue(explainString.contains("PREDICATES: `query_time` IN 
(1, 2) AND `query_time` IN (3, 4)\n"));
 
         sql = "SELECT * from test1 where (query_time = 1 or query_time = 2 or 
scan_bytes = 2) and scan_bytes in (2, 3)";
         explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, 
"EXPLAIN " + sql);
-        Assert.assertTrue(explainString.contains("PREDICATES: `query_time` IN 
(1, 2) OR `scan_bytes` = 2, `scan_bytes` IN (2, 3)\n"));
+        Assert.assertTrue(explainString.contains("PREDICATES: `query_time` IN 
(1, 2) OR `scan_bytes` = 2 AND `scan_bytes` IN (2, 3)\n"));
 
         sql = "SELECT * from test1 where (query_time = 1 or query_time = 2) 
and (scan_bytes = 2 or scan_bytes = 3)";
         explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, 
"EXPLAIN " + sql);
-        Assert.assertTrue(explainString.contains("PREDICATES: `query_time` IN 
(1, 2), `scan_bytes` IN (2, 3)\n"));
+        Assert.assertTrue(explainString.contains("PREDICATES: `query_time` IN 
(1, 2) AND `scan_bytes` IN (2, 3)\n"));
 
         sql = "SELECT * from test1 where query_time = 1 or query_time = 2 or 
query_time = 3 or query_time = 1";
         explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, 
"EXPLAIN " + sql);
@@ -2236,7 +2236,7 @@ public class QueryPlanTest extends TestWithFeService {
 
         sql = "SELECT * from test1 where (query_time = 1 or query_time = 2) 
and query_time in (3, 4)";
         explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, 
"EXPLAIN " + sql);
-        Assert.assertTrue(explainString.contains("PREDICATES: `query_time` IN 
(1, 2), `query_time` IN (3, 4)\n"));
+        Assert.assertTrue(explainString.contains("PREDICATES: `query_time` IN 
(1, 2) AND `query_time` IN (3, 4)\n"));
 
         //test we can handle `!=` and `not in`
         sql = "select * from test1 where (query_time = 1 or query_time = 2 or 
query_time!= 3 or query_time not in (5, 6))";
@@ -2269,7 +2269,7 @@ public class QueryPlanTest extends TestWithFeService {
         sql = "select * from test1 where (stmt_id=1 and state='a') or 
(stmt_id=2 and state='b')";
         explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, 
"EXPLAIN " + sql);
         Assert.assertTrue(explainString.contains(
-                "PREDICATES: `state` IN ('a', 'b'), `stmt_id` IN (1, 2),"
+                "PREDICATES: `state` IN ('a', 'b') AND `stmt_id` IN (1, 2) AND"
                         + " `stmt_id` = 1 AND `state` = 'a' OR `stmt_id` = 2 
AND `state` = 'b'\n"
         ));
     }
diff --git a/fe/fe-core/src/test/java/org/apache/doris/policy/PolicyTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/policy/PolicyTest.java
index 71084fb429..b53bbe46ef 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/policy/PolicyTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/policy/PolicyTest.java
@@ -172,7 +172,7 @@ public class PolicyTest extends TestWithFeService {
         createPolicy("CREATE ROW POLICY test_row_policy4 ON test.table1 AS 
PERMISSIVE TO test_policy USING (k2 = 1)");
         String queryStr = "EXPLAIN select * from test.table1";
         String explainString = getSQLPlanOrErrorMsg(queryStr);
-        Assertions.assertTrue(explainString.contains("`k1` = 1, `k2` = 1, `k2` 
= 2 OR `k2` = 1"));
+        Assertions.assertTrue(explainString.contains("`k1` = 1 AND `k2` = 1 
AND `k2` = 2 OR `k2` = 1"));
         dropPolicy("DROP ROW POLICY test_row_policy1 ON test.table1");
         dropPolicy("DROP ROW POLICY test_row_policy2 ON test.table1");
         dropPolicy("DROP ROW POLICY test_row_policy3 ON test.table1");
@@ -184,14 +184,13 @@ public class PolicyTest extends TestWithFeService {
         createPolicy("CREATE ROW POLICY test_row_policy1 ON test.table1 AS 
RESTRICTIVE TO test_policy USING (k1 = 1)");
         createPolicy("CREATE ROW POLICY test_row_policy2 ON test.table1 AS 
RESTRICTIVE TO test_policy USING (k2 = 1)");
         String joinSql = "select * from table1 join table2 on 
table1.k1=table2.k1";
-        System.out.println(getSQLPlanOrErrorMsg(joinSql));
-        
Assertions.assertTrue(getSQLPlanOrErrorMsg(joinSql).contains("PREDICATES: `k1` 
= 1, `k2` = 1"));
+        
Assertions.assertTrue(getSQLPlanOrErrorMsg(joinSql).contains("PREDICATES: `k1` 
= 1 AND `k2` = 1"));
         String unionSql = "select * from table1 union select * from table2";
-        
Assertions.assertTrue(getSQLPlanOrErrorMsg(unionSql).contains("PREDICATES: `k1` 
= 1, `k2` = 1"));
+        
Assertions.assertTrue(getSQLPlanOrErrorMsg(unionSql).contains("PREDICATES: `k1` 
= 1 AND `k2` = 1"));
         String subQuerySql = "select * from table2 where k1 in (select k1 from 
table1)";
-        
Assertions.assertTrue(getSQLPlanOrErrorMsg(subQuerySql).contains("PREDICATES: 
`k1` = 1, `k2` = 1"));
+        
Assertions.assertTrue(getSQLPlanOrErrorMsg(subQuerySql).contains("PREDICATES: 
`k1` = 1 AND `k2` = 1"));
         String aliasSql = "select * from table1 t1 join table2 t2 on 
t1.k1=t2.k1";
-        
Assertions.assertTrue(getSQLPlanOrErrorMsg(aliasSql).contains("PREDICATES: 
`t1`.`k1` = 1, `t1`.`k2` = 1"));
+        
Assertions.assertTrue(getSQLPlanOrErrorMsg(aliasSql).contains("PREDICATES: 
`t1`.`k1` = 1 AND `t1`.`k2` = 1"));
         dropPolicy("DROP ROW POLICY test_row_policy1 ON test.table1");
         dropPolicy("DROP ROW POLICY test_row_policy2 ON test.table1");
     }
diff --git a/regression-test/data/mv_p0/where/k123/k123.out 
b/regression-test/data/mv_p0/where/k123/k123.out
index fb9659afad..55bd6c538c 100644
--- a/regression-test/data/mv_p0/where/k123/k123.out
+++ b/regression-test/data/mv_p0/where/k123/k123.out
@@ -35,3 +35,7 @@
 1      2
 1      2
 
+-- !select_mv --
+2      4
+2      4
+
diff --git a/regression-test/suites/mv_p0/where/k123/k123.groovy 
b/regression-test/suites/mv_p0/where/k123/k123.groovy
index d80c59b1e2..09201fe31c 100644
--- a/regression-test/suites/mv_p0/where/k123/k123.groovy
+++ b/regression-test/suites/mv_p0/where/k123/k123.groovy
@@ -80,4 +80,10 @@ suite ("k123p") {
         contains "(d_table)"
     }
     qt_select_mv "select k1,k2+k3 from d_table where k4 = 'a' order by k1;"
+
+    explain {
+        sql("""select k1,k2+k3 from d_table where k1 = 2 and k4 = "b";""")
+        contains "(k123p4w)"
+    }
+    qt_select_mv """select k1,k2+k3 from d_table where k1 = 2 and k4 = "b" 
order by k1;"""
 }


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

Reply via email to