You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jb...@apache.org on 2017/02/19 16:39:55 UTC

calcite git commit: [CALCITE-1636] JDBC adapter generates wrong SQL for self join with sub-query

Repository: calcite
Updated Branches:
  refs/heads/master 79adbf3b5 -> f7d29063b


[CALCITE-1636] JDBC adapter generates wrong SQL for self join with sub-query

Close apache/calcite#373


Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/f7d29063
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/f7d29063
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/f7d29063

Branch: refs/heads/master
Commit: f7d29063b3a323b21968125f5aea16a0d33a39e6
Parents: 79adbf3
Author: Zhiqiang-He <ab...@qq.com>
Authored: Wed Feb 15 20:20:04 2017 +0800
Committer: Jess Balint <jb...@gmail.com>
Committed: Sun Feb 19 10:39:26 2017 -0600

----------------------------------------------------------------------
 .../calcite/rel/rel2sql/RelToSqlConverter.java  |  7 +++---
 .../calcite/rel/rel2sql/SqlImplementor.java     | 23 ++++++++++++++++----
 .../rel/rel2sql/RelToSqlConverterTest.java      | 17 +++++++++++++++
 3 files changed, 39 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/f7d29063/core/src/main/java/org/apache/calcite/rel/rel2sql/RelToSqlConverter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rel2sql/RelToSqlConverter.java b/core/src/main/java/org/apache/calcite/rel/rel2sql/RelToSqlConverter.java
index 007dbed..c2fe284 100644
--- a/core/src/main/java/org/apache/calcite/rel/rel2sql/RelToSqlConverter.java
+++ b/core/src/main/java/org/apache/calcite/rel/rel2sql/RelToSqlConverter.java
@@ -101,11 +101,10 @@ public class RelToSqlConverter extends SqlImplementor
 
   /** @see #dispatch */
   public Result visit(Join e) {
-    final Result leftResult = visitChild(0, e.getLeft());
-    final Result rightResult = visitChild(1, e.getRight());
+    final Result leftResult = visitChild(0, e.getLeft()).resetAlias();
+    final Result rightResult = visitChild(1, e.getRight()).resetAlias();
     final Context leftContext = leftResult.qualifiedContext();
-    final Context rightContext =
-        rightResult.qualifiedContext();
+    final Context rightContext = rightResult.qualifiedContext();
     SqlNode sqlCondition = null;
     SqlLiteral condType = JoinConditionType.ON.symbol(POS);
     JoinType joinType = joinType(e.getJoinType());

http://git-wip-us.apache.org/repos/asf/calcite/blob/f7d29063/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java b/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java
index 6e6fed4..206716b 100644
--- a/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java
+++ b/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java
@@ -426,7 +426,7 @@ public abstract class SqlImplementor {
         && !aliases.isEmpty()
         && (!dialect.hasImplicitTableAlias()
           || aliases.size() > 1)) {
-      return new Result(node, clauses, alias4, aliases);
+      return new Result(node, clauses, alias4, rel.getRowType(), aliases);
     }
     final String alias5;
     if (alias2 == null
@@ -436,7 +436,7 @@ public abstract class SqlImplementor {
     } else {
       alias5 = null;
     }
-    return new Result(node, clauses, alias5,
+    return new Result(node, clauses, alias5, rel.getRowType(),
         ImmutableMap.of(alias4, rel.getRowType()));
   }
 
@@ -448,7 +448,7 @@ public abstract class SqlImplementor {
     collectAliases(builder, join,
         Iterables.concat(leftResult.aliases.values(),
             rightResult.aliases.values()).iterator());
-    return new Result(join, Expressions.list(Clause.FROM), null,
+    return new Result(join, Expressions.list(Clause.FROM), null, null,
         builder.build());
   }
 
@@ -873,13 +873,15 @@ public abstract class SqlImplementor {
   public class Result {
     final SqlNode node;
     private final String neededAlias;
+    private final RelDataType neededType;
     private final Map<String, RelDataType> aliases;
     final Expressions.FluentList<Clause> clauses;
 
     public Result(SqlNode node, Collection<Clause> clauses, String neededAlias,
-        Map<String, RelDataType> aliases) {
+        RelDataType neededType, Map<String, RelDataType> aliases) {
       this.node = node;
       this.neededAlias = neededAlias;
+      this.neededType = neededType;
       this.aliases = aliases;
       this.clauses = Expressions.list(clauses);
     }
@@ -1031,6 +1033,19 @@ public abstract class SqlImplementor {
     public Context qualifiedContext() {
       return aliasContext(aliases, true);
     }
+
+    /**
+     * In join, when the left and right nodes have been generated,
+     * update their alias with 'neededAlias' if not null.
+     */
+    public Result resetAlias() {
+      if (neededAlias == null) {
+        return this;
+      } else {
+        return new Result(node, clauses, neededAlias, neededType,
+            ImmutableMap.<String, RelDataType>of(neededAlias, neededType));
+      }
+    }
   }
 
   /** Builder. */

http://git-wip-us.apache.org/repos/asf/calcite/blob/f7d29063/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
index 1eb80e1..52bcab5 100644
--- a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
+++ b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
@@ -318,6 +318,23 @@ public class RelToSqlConverterTest {
     sql(query).ok(expected);
   }
 
+  /** Test case for
+   * <a href="https://issues.apache.org/jira/browse/CALCITE-1636">[CALCITE-1636]
+   * JDBC adapter generates wrong SQL for self join with sub-query</a>. */
+  @Test public void testSubQueryAlias() {
+    String query = "select t1.\"customer_id\", t2.\"customer_id\" \n"
+        + "from (select \"customer_id\" from \"sales_fact_1997\") as t1 \n"
+        + "inner join (select \"customer_id\" from \"sales_fact_1997\") t2 \n"
+        + "on t1.\"customer_id\" = t2.\"customer_id\"";
+    final String expected = "SELECT *\n"
+        + "FROM (SELECT sales_fact_1997.customer_id\n"
+        + "FROM foodmart.sales_fact_1997 AS sales_fact_1997) AS t\n"
+        + "INNER JOIN (SELECT sales_fact_19970.customer_id\n"
+        + "FROM foodmart.sales_fact_1997 AS sales_fact_19970) AS t0 ON t.customer_id = t0.customer_id";
+
+    sql(query).dialect(DatabaseProduct.DB2.getDialect()).ok(expected);
+  }
+
   @Test public void testCartesianProduct() {
     String query = "select * from \"department\" , \"employee\"";
     String expected = "SELECT *\n"