You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2018/12/06 01:18:48 UTC

[2/4] calcite git commit: [CALCITE-2468] Validator throws IndexOutOfBoundsException when trying to infer operand type from STRUCT return type (Rong Rong)

[CALCITE-2468] Validator throws IndexOutOfBoundsException when trying to infer operand type from STRUCT return type (Rong Rong)

Add example in server module's type.iq test.
Fix type inference when operator is AS with a complex row of just 1 element.

Close apache/calcite#932


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

Branch: refs/heads/branch-1.18
Commit: 40d12b7419bd544bd829011a18ac37f6bc529ce7
Parents: 4da9c0d
Author: Rong Rong <wa...@hotmail.com>
Authored: Mon Aug 20 17:16:19 2018 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Wed Dec 5 16:19:32 2018 -0800

----------------------------------------------------------------------
 .../calcite/sql/validate/SqlValidatorImpl.java  | 31 +++++++++++++-------
 .../calcite/test/SqlToRelConverterTest.java     | 10 +++++++
 .../calcite/test/SqlToRelConverterTest.xml      | 12 ++++++++
 server/src/test/resources/sql/type.iq           | 22 ++++++++++++++
 4 files changed, 65 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/40d12b74/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
index 626399f..41fdab5 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
@@ -131,6 +131,7 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 import java.util.function.Supplier;
+import javax.annotation.Nonnull;
 
 import static org.apache.calcite.sql.SqlUtil.stripAs;
 import static org.apache.calcite.util.Static.RESOURCE;
@@ -454,7 +455,9 @@ public class SqlValidatorImpl implements SqlValidatorWithHints {
     selectItems.add(expanded);
     aliases.add(alias);
 
-    inferUnknownTypes(targetType, scope, expanded);
+    if (expanded != null) {
+      inferUnknownTypes(targetType, scope, expanded);
+    }
     final RelDataType type = deriveType(selectScope, expanded);
     setValidatedNodeType(expanded, type);
     fields.add(Pair.of(alias, type));
@@ -1720,9 +1723,12 @@ public class SqlValidatorImpl implements SqlValidatorWithHints {
   }
 
   protected void inferUnknownTypes(
-      RelDataType inferredType,
-      SqlValidatorScope scope,
-      SqlNode node) {
+      @Nonnull RelDataType inferredType,
+      @Nonnull SqlValidatorScope scope,
+      @Nonnull SqlNode node) {
+    Objects.requireNonNull(inferredType);
+    Objects.requireNonNull(scope);
+    Objects.requireNonNull(node);
     final SqlValidatorScope newScope = scopes.get(node);
     if (newScope != null) {
       scope = newScope;
@@ -1790,6 +1796,9 @@ public class SqlValidatorImpl implements SqlValidatorWithHints {
       } else {
         setValidatedNodeType(caseCall.getElseOperand(), returnType);
       }
+    } else if (node.getKind()  == SqlKind.AS) {
+      // For AS operator, only infer the operand not the alias
+      inferUnknownTypes(inferredType, scope, ((SqlCall) node).operand(0));
     } else if (node instanceof SqlCall) {
       final SqlCall call = (SqlCall) node;
       final SqlOperandTypeInference operandTypeInference =
@@ -1797,18 +1806,20 @@ public class SqlValidatorImpl implements SqlValidatorWithHints {
       final SqlCallBinding callBinding = new SqlCallBinding(this, scope, call);
       final List<SqlNode> operands = callBinding.operands();
       final RelDataType[] operandTypes = new RelDataType[operands.size()];
-      if (operandTypeInference == null) {
-        // TODO:  eventually should assert(operandTypeInference != null)
-        // instead; for now just eat it
-        Arrays.fill(operandTypes, unknownType);
-      } else {
+      Arrays.fill(operandTypes, unknownType);
+      // TODO:  eventually should assert(operandTypeInference != null)
+      // instead; for now just eat it
+      if (operandTypeInference != null) {
         operandTypeInference.inferOperandTypes(
             callBinding,
             inferredType,
             operandTypes);
       }
       for (int i = 0; i < operands.size(); ++i) {
-        inferUnknownTypes(operandTypes[i], scope, operands.get(i));
+        final SqlNode operand = operands.get(i);
+        if (operand != null) {
+          inferUnknownTypes(operandTypes[i], scope, operand);
+        }
       }
     }
   }

http://git-wip-us.apache.org/repos/asf/calcite/blob/40d12b74/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java b/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
index 77fa01c..1207020 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
@@ -123,6 +123,16 @@ public class SqlToRelConverterTest extends SqlToRelTestBase {
     sql(sql).ok();
   }
 
+  /** Test case for:
+   * <a href="https://issues.apache.org/jira/browse/CALCITE-2468">[CALCITE-2468]
+   * struct type alias should not cause IOOBE.</a>.
+   */
+  @Test public void testStructTypeAlias() {
+    final String sql = "select t.r AS myRow \n"
+        + "from (select row(row(1)) r from dept) t";
+    sql(sql).ok();
+  }
+
   @Test
   public void testJoinUsingDynamicTable() {
     final String sql = "select * from SALES.NATION t1\n"

http://git-wip-us.apache.org/repos/asf/calcite/blob/40d12b74/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
----------------------------------------------------------------------
diff --git a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
index 9128946..28d2e3f 100644
--- a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
@@ -1459,6 +1459,18 @@ LogicalProject(A=[$0], B=[$1], C=[$2], DEPTNO=[$3], NAME=[$4])
 ]]>
         </Resource>
     </TestCase>
+    <TestCase name="testStructTypeAlias">
+        <Resource name="sql">
+            <![CDATA[select t.r AS myRow
+from (select row(row(1)) r from dept) t]]>
+        </Resource>
+        <Resource name="plan">
+            <![CDATA[
+LogicalProject(MYROW$$0$$0=[1])
+  LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+]]>
+        </Resource>
+    </TestCase>
     <TestCase name="testJoinWithUnion">
         <Resource name="sql">
             <![CDATA[select grade

http://git-wip-us.apache.org/repos/asf/calcite/blob/40d12b74/server/src/test/resources/sql/type.iq
----------------------------------------------------------------------
diff --git a/server/src/test/resources/sql/type.iq b/server/src/test/resources/sql/type.iq
index 64314e9..7103be4 100644
--- a/server/src/test/resources/sql/type.iq
+++ b/server/src/test/resources/sql/type.iq
@@ -49,7 +49,29 @@ select * from t;
 
 !ok
 
+
+# Create a table with complex structure type
+# This is to test struct type inference in
+# <a href="https://issues.apache.org/jira/browse/CALCITE-1222">[CALCITE-2468]
+
+create type mytype1 as (ii int not null);
+(0 rows modified)
+
+!update
+
+# Create a complex table
+create table v (i int not null, j mytype1 not null);
+(0 rows modified)
+
+!update
+
+select i AS myInt, j AS myStruct from v;
+MYINT INTEGER(10) NOT NULL
+MYSTRUCT STRUCT NOT NULL
+!type
+
 drop table t;
+drop table v;
 (0 rows modified)
 
 !update