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

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


The following commit(s) were added to refs/heads/dev-1.1.2 by this push:
     new 73b4968b78 [fix](optimization)  InferFiltersRule bug: a self inner 
join on a view, which contains where clause, will cause mis-inference. (#11566)
73b4968b78 is described below

commit 73b4968b78d0e5d51591343c6ab62055f687f407
Author: minghong <minghong.z...@163.com>
AuthorDate: Thu Aug 11 17:13:26 2022 +0800

    [fix](optimization)  InferFiltersRule bug: a self inner join on a view, 
which contains where clause, will cause mis-inference. (#11566)
---
 .../java/org/apache/doris/analysis/Analyzer.java   | 26 ++++++++++
 .../org/apache/doris/analysis/InlineViewRef.java   |  2 +-
 .../java/org/apache/doris/analysis/SelectStmt.java |  5 ++
 .../apache/doris/planner/PredicatePushDown.java    |  3 ++
 .../correctness/test_pushdown_pred_to_view.out     |  4 ++
 .../correctness/test_pushdown_pred_to_view.groovy  | 58 ++++++++++++++++++++++
 6 files changed, 97 insertions(+), 1 deletion(-)

diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/Analyzer.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/Analyzer.java
index 932b0b6a0f..3c62fa6112 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/Analyzer.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/Analyzer.java
@@ -143,6 +143,17 @@ public class Analyzer {
     // Flag indicating if this analyzer instance belongs to a subquery.
     private boolean isSubquery = false;
 
+    public boolean isInlineView() {
+        return isInlineView;
+    }
+
+    public void setInlineView(boolean inlineView) {
+        isInlineView = inlineView;
+    }
+
+    // Flag indicating if this analyzer instance belongs to an inlineview.
+    private boolean isInlineView = false;
+
     // Flag indicating whether this analyzer belongs to a WITH clause view.
     private boolean isWithClause_ = false;
 
@@ -722,6 +733,21 @@ public class Analyzer {
             d = resolveColumnRef(colName);
         } else {
             d = resolveColumnRef(newTblName, colName);
+            //in reanalyze, the inferred expr may contain upper level table 
alias, and the upper level alias has not
+            // been PROCESSED. So we resolve this column without tbl name.
+            // For example: a view V "select * from t where t.a>1"
+            // sql: select * from V as t1 join V as t2 on t1.a=t2.a and t1.a 
in (1,2)
+            // after first analyze, sql becomes:
+            //  select * from V as t1 join V as t2 on t1.a=t2.a and t1.a in 
(1,2) and t2.a in (1, 2)
+            // in reanalyze, when we process V as t2, we indeed process sql 
like this:
+            //    select * from t where t.a>1 and t2.a in (1, 2)
+            //  in order to resolve t2.a, we have to ignore "t2"
+            // ===================================================
+            // Someone may concern that if t2 is not alias of t, this fix will 
cause incorrect resolve. In fact,
+            // this does not happen, since we push t2.a in (1.2) down to this 
inline view, t2 must be alias of t.
+            if (d == null && isInlineView) {
+                d = resolveColumnRef(colName);
+            }
         }
         /*
          * Now, we only support the columns in the subquery to associate the 
outer query columns in parent level.
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/InlineViewRef.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/InlineViewRef.java
index ecc5c4360d..71a83d5fed 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/InlineViewRef.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/InlineViewRef.java
@@ -177,7 +177,7 @@ public class InlineViewRef extends TableRef {
 
         // Analyze the inline view query statement with its own analyzer
         inlineViewAnalyzer = new Analyzer(analyzer);
-
+        inlineViewAnalyzer.setInlineView(true);
         queryStmt.analyze(inlineViewAnalyzer);
         
correlatedTupleIds_.addAll(queryStmt.getCorrelatedTupleIds(inlineViewAnalyzer));
 
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/SelectStmt.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/SelectStmt.java
index 10f1b0264e..af0f042cc5 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/SelectStmt.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/SelectStmt.java
@@ -1350,6 +1350,11 @@ public class SelectStmt extends QueryStmt {
             ref.rewriteExprs(rewriter, analyzer);
         }
         // Also equal exprs in the statements of subqueries.
+        // TODO: (minghong) if this a view, even no whereClause,
+        //  we should analyze whereClause to enable filter inference
+        // for example, a view without where clause, `V`,
+        // `select * from T join V on T.id = V.id and T.id=1`
+        // we could infer `V.id=1`
         List<Subquery> subqueryExprs = Lists.newArrayList();
         if (whereClause != null) {
             whereClause = rewriter.rewrite(whereClause, analyzer, 
ExprRewriter.ClauseType.WHERE_CLAUSE);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/planner/PredicatePushDown.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/PredicatePushDown.java
index 76c2ace45f..4f11d1a17e 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/PredicatePushDown.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/PredicatePushDown.java
@@ -129,6 +129,9 @@ public class PredicatePushDown {
         }
     }
 
+    // TODO: (minghong) here is a bug. For example, this is a left join, we 
cannot infer "t2.id = 1"
+    // by "t1.id=1" and "t1.id=t2.id".
+    // we should not do inference work here. it should be done in some rule 
like InferFilterRule.
     // Rewrite the oldPredicate with new leftChild
     // For example: oldPredicate is t1.id = 1, leftChild is t2.id, will return 
t2.id = 1
     private static Expr rewritePredicate(Analyzer analyzer, Expr oldPredicate, 
Expr leftChild) {
diff --git a/regression-test/data/correctness/test_pushdown_pred_to_view.out 
b/regression-test/data/correctness/test_pushdown_pred_to_view.out
new file mode 100644
index 0000000000..a4cca003b9
--- /dev/null
+++ b/regression-test/data/correctness/test_pushdown_pred_to_view.out
@@ -0,0 +1,4 @@
+-- This file is automatically generated. You should know what you did if you 
want to edit this
+-- !sql --
+1      1
+
diff --git 
a/regression-test/suites/correctness/test_pushdown_pred_to_view.groovy 
b/regression-test/suites/correctness/test_pushdown_pred_to_view.groovy
new file mode 100644
index 0000000000..41afda7351
--- /dev/null
+++ b/regression-test/suites/correctness/test_pushdown_pred_to_view.groovy
@@ -0,0 +1,58 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+ // or more contributor license agreements.  See the NOTICE file
+ // distributed with this work for additional information
+ // regarding copyright ownership.  The ASF licenses this file
+ // to you under the Apache License, Version 2.0 (the
+ // "License"); you may not use this file except in compliance
+ // with the License.  You may obtain a copy of the License at
+ //
+ //   http://www.apache.org/licenses/LICENSE-2.0
+ //
+ // Unless required by applicable law or agreed to in writing,
+ // software distributed under the License is distributed on an
+ // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ // KIND, either express or implied.  See the License for the
+ // specific language governing permissions and limitations
+ // under the License.
+
+
+/*
+How to produce the bug:
+suppose we have table T, and a view V: select * from T where T.id>0
+When we execute sql: select * from V as v1 join V as v2 on v1.id=v2.id where 
v1.id in (1,2);
+by InferFilterRule, { v1.id=v2.id , v1.id in (1,2) } => v2.id in (1,2)
+and then we push v1.id in (1,2) and v2.id in (1,2) down to v1 and v2, 
respectively.
+
+In re-analyze phase, we expand v1 with infered condition, we have sql: select 
* from T where T.id>0 and v1.id in (1,2)
+The bug is we cannot resolve v1.id in context of the expanded sql.
+The same resolve error occurs when re-analyze v2.
+*/
+ suite("test_pushdown_pred_to_view") {
+     sql """ DROP TABLE IF EXISTS T """
+     sql """
+         CREATE TABLE `T` (
+             `id` int
+         ) ENGINE=OLAP
+         AGGREGATE KEY(`id`)
+         COMMENT "OLAP"
+         DISTRIBUTED BY HASH(`id`) BUCKETS 1
+         PROPERTIES (
+             "replication_allocation" = "tag.location.default: 1",
+             "in_memory" = "false",
+             "storage_format" = "V2"
+         );
+     """
+     sql "drop view if exists V;"
+     sql """
+         create view V as select * from T where id > 0;
+     """
+
+     sql """
+         insert into T values(1);
+     """
+
+     qt_sql """
+         select * from V as v1 join V as v2 on v1.id=v2.id and v1.id>0;
+     """
+ }
+


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to