You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by mo...@apache.org on 2022/10/27 00:58:30 UTC

[doris] branch branch-1.1-lts updated: [fix](planner) inlineView alias error (#13600) (#13705)

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

morningman pushed a commit to branch branch-1.1-lts
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-1.1-lts by this push:
     new 4ca187c171 [fix](planner) inlineView alias error (#13600) (#13705)
4ca187c171 is described below

commit 4ca187c17172c4b415488a14740b033b6ae0a540
Author: minghong <en...@gmail.com>
AuthorDate: Thu Oct 27 08:58:24 2022 +0800

    [fix](planner) inlineView alias error (#13600) (#13705)
    
    cherry-pick #13600
---
 .../java/org/apache/doris/analysis/Analyzer.java   | 26 +++++++------
 .../org/apache/doris/analysis/BaseTableRef.java    |  2 +-
 .../org/apache/doris/analysis/InlineViewRef.java   | 15 +++++---
 .../java/org/apache/doris/analysis/TableRef.java   | 26 ++++++-------
 .../correctness/test_pushdown_pred_to_view.groovy  |  2 +-
 ...pred_to_view.groovy => test_table_alias.groovy} | 45 ++++++++--------------
 6 files changed, 56 insertions(+), 60 deletions(-)

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 5a17a68731..14a357f4b0 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,18 +143,10 @@ 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;
 
+    private String explicitViewAlias;
     // Flag indicating whether this analyzer belongs to a WITH clause view.
     private boolean isWithClause_ = false;
 
@@ -473,6 +465,18 @@ public class Analyzer {
         return callDepth;
     }
 
+    public void setInlineView(boolean inlineView) {
+        isInlineView = inlineView;
+    }
+
+    public void setExplicitViewAlias(String alias) {
+        explicitViewAlias = alias;
+    }
+
+    public String getExplicitViewAlias() {
+        return explicitViewAlias;
+    }
+
     /**
      * Registers a local view definition with this analyzer. Throws an exception if a view
      * definition with the same alias has already been registered or if the number of
@@ -588,7 +592,7 @@ public class Analyzer {
             slot.setIsMaterialized(true);
             slot.setColumn(col);
             slot.setIsNullable(col.isAllowNull());
-            String key = tableRef.aliases_[0] + "." + col.getName();
+            String key = tableRef.aliases[0] + "." + col.getName();
             slotRefMap.put(key, slot);
         }
         globalState.descTbl.computeStatAndMemLayout();
@@ -746,7 +750,7 @@ public class Analyzer {
             // ===================================================
             // 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) {
+            if (d == null && isInlineView && newTblName.getTbl().equals(explicitViewAlias)) {
                 d = resolveColumnRef(colName);
             }
         }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/BaseTableRef.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/BaseTableRef.java
index 5c0a8f4d47..6df603065c 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/BaseTableRef.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/BaseTableRef.java
@@ -38,7 +38,7 @@ public class BaseTableRef extends TableRef {
         this.name = tableName;
         // Set implicit aliases if no explicit one was given.
         if (hasExplicitAlias()) return;
-        aliases_ = new String[] { name.toString(), tableName.getNoClusterString(), tableName.getTbl() };
+        aliases = new String[] { name.toString(), tableName.getNoClusterString(), tableName.getTbl() };
     }
 
     protected BaseTableRef(BaseTableRef other) {
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 71a83d5fed..16b8853928 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
@@ -104,13 +104,13 @@ public class InlineViewRef extends TableRef {
         setJoinAttrs(origTblRef);
         explicitColLabels = view.getColLabels();
         // Set implicit aliases if no explicit one was given.
-        if (hasExplicitAlias()) return;
+        if (hasExplicitAlias) return;
         // TODO(zc)
         // view_.getTableName().toString().toLowerCase(), view.getName().toLowerCase()
         if (view.isLocalView()) {
-            aliases_ = new String[]{view.getName()};
+            aliases = new String[]{view.getName()};
         } else {
-            aliases_ = new String[]{name.toString(), view.getName()};
+            aliases = new String[]{name.toString(), view.getName()};
         }
         if (origTblRef.getLateralViewRefs() != null) {
             lateralViewRefs = (ArrayList<LateralViewRef>) origTblRef.getLateralViewRefs().clone();
@@ -171,20 +171,23 @@ public class InlineViewRef extends TableRef {
             return;
         }
 
-        if (view == null && !hasExplicitAlias()) {
+        if (view == null && !hasExplicitAlias) {
             ErrorReport.reportAnalysisException(ErrorCode.ERR_DERIVED_MUST_HAVE_ALIAS);
         }
 
         // Analyze the inline view query statement with its own analyzer
         inlineViewAnalyzer = new Analyzer(analyzer);
         inlineViewAnalyzer.setInlineView(true);
+        if (hasExplicitAlias) {
+            inlineViewAnalyzer.setExplicitViewAlias(aliases[0]);
+        }
         queryStmt.analyze(inlineViewAnalyzer);
         correlatedTupleIds_.addAll(queryStmt.getCorrelatedTupleIds(inlineViewAnalyzer));
 
         queryStmt.getMaterializedTupleIds(materializedTupleIds);
-        if (view != null && !hasExplicitAlias() && !view.isLocalView()) {
+        if (view != null && !hasExplicitAlias && !view.isLocalView()) {
             name = analyzer.getFqTableName(name);
-            aliases_ = new String[] { name.toString(), view.getName() };
+            aliases = new String[] { name.toString(), view.getName() };
         }
         //TODO(chenhao16): fix TableName in Db.Table style
         // name.analyze(analyzer);
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/TableRef.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/TableRef.java
index 3f2a279197..b7cbede4e2 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/TableRef.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/TableRef.java
@@ -84,10 +84,10 @@ public class TableRef implements ParseNode, Writable {
     // analysis. By convention, for table refs with multiple implicit aliases, aliases_[0]
     // contains the fully-qualified implicit alias to ensure that aliases_[0] always
     // uniquely identifies this table ref regardless of whether it has an explicit alias.
-    protected String[] aliases_;
+    protected String[] aliases;
 
     // Indicates whether this table ref is given an explicit alias,
-    protected boolean hasExplicitAlias_;
+    protected boolean hasExplicitAlias;
 
     protected JoinOperator joinOp;
     protected List<String> usingColNames;
@@ -151,10 +151,10 @@ public class TableRef implements ParseNode, Writable {
             if (Catalog.isStoredTableNamesLowerCase()) {
                 alias = alias.toLowerCase();
             }
-            aliases_ = new String[]{alias};
-            hasExplicitAlias_ = true;
+            aliases = new String[]{alias};
+            hasExplicitAlias = true;
         } else {
-            hasExplicitAlias_ = false;
+            hasExplicitAlias = false;
         }
         this.partitionNames = partitionNames;
         this.commonHints = commonHints;
@@ -165,8 +165,8 @@ public class TableRef implements ParseNode, Writable {
     // this will reset all the 'analyzed' stuff
     protected TableRef(TableRef other) {
         name = other.name;
-        aliases_ = other.aliases_;
-        hasExplicitAlias_ = other.hasExplicitAlias_;
+        aliases = other.aliases;
+        hasExplicitAlias = other.hasExplicitAlias;
         joinOp = other.joinOp;
         // NOTE: joinHints and sortHints maybe changed after clone. so we new one List.
         joinHints =
@@ -684,7 +684,7 @@ public class TableRef implements ParseNode, Writable {
      * Returns all legal aliases of this table ref.
      */
     public String[] getAliases() {
-        return aliases_;
+        return aliases;
     }
 
     /**
@@ -693,7 +693,7 @@ public class TableRef implements ParseNode, Writable {
      * be ambiguous).
      */
     public String getUniqueAlias() {
-        return aliases_[0];
+        return aliases[0];
     }
 
     /**
@@ -702,7 +702,7 @@ public class TableRef implements ParseNode, Writable {
      * nested collection refs have only a single implicit alias.
      */
     public boolean hasExplicitAlias() {
-        return hasExplicitAlias_;
+        return hasExplicitAlias;
     }
 
     /**
@@ -785,8 +785,8 @@ public class TableRef implements ParseNode, Writable {
         if (partitionNames != null) {
             sb.append(partitionNames.toSql());
         }
-        if (aliases_ != null && aliases_.length > 0) {
-            sb.append(" AS ").append(aliases_[0]);
+        if (aliases != null && aliases.length > 0) {
+            sb.append(" AS ").append(aliases[0]);
         }
         return sb.toString();
     }
@@ -818,7 +818,7 @@ public class TableRef implements ParseNode, Writable {
 
         if (in.readBoolean()) {
             String alias = Text.readString(in);
-            aliases_ = new String[]{alias};
+            aliases = new String[]{alias};
         }
     }
 }
diff --git a/regression-test/suites/correctness/test_pushdown_pred_to_view.groovy b/regression-test/suites/correctness/test_pushdown_pred_to_view.groovy
index 41afda7351..b671f4c03e 100644
--- a/regression-test/suites/correctness/test_pushdown_pred_to_view.groovy
+++ b/regression-test/suites/correctness/test_pushdown_pred_to_view.groovy
@@ -52,7 +52,7 @@ The same resolve error occurs when re-analyze v2.
      """
 
      qt_sql """
-         select * from V as v1 join V as v2 on v1.id=v2.id and v1.id>0;
+         select * from V as v1 join V as v2 where v1.id=v2.id and v1.id>0;
      """
  }
 
diff --git a/regression-test/suites/correctness/test_pushdown_pred_to_view.groovy b/regression-test/suites/correctness/test_table_alias.groovy
similarity index 54%
copy from regression-test/suites/correctness/test_pushdown_pred_to_view.groovy
copy to regression-test/suites/correctness/test_table_alias.groovy
index 41afda7351..7c81a703d3 100644
--- a/regression-test/suites/correctness/test_pushdown_pred_to_view.groovy
+++ b/regression-test/suites/correctness/test_table_alias.groovy
@@ -15,22 +15,10 @@
  // 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 """
+suite("test_table_alias") {
+     sql """ DROP TABLE IF EXISTS tbl_alias """
      sql """
-         CREATE TABLE `T` (
+         CREATE TABLE tbl_alias (
              `id` int
          ) ENGINE=OLAP
          AGGREGATE KEY(`id`)
@@ -42,17 +30,18 @@ The same resolve error occurs when re-analyze v2.
              "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;
-     """
- }
 
+    try {
+        test {
+            sql """
+            select * 
+            from (select t3.id 
+                  from (select * from tbl_alias) t1
+                 ) t2
+            """
+            exception "errCode = 2, detailMessage = Unknown column 'id' in 't3'"            
+        }
+    } finally {
+        sql "drop table if exists tbl_alias"
+    }
+}
\ No newline at end of file


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