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

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


The following commit(s) were added to refs/heads/master by this push:
     new 395aa85  [CALCITE-2994] Least restrictive type among structs does not 
consider nullability
395aa85 is described below

commit 395aa85085e0dad1ba14d8761aeb79b2b11c3809
Author: Stamatis Zampetakis <[email protected]>
AuthorDate: Mon Apr 15 17:04:33 2019 +0200

    [CALCITE-2994] Least restrictive type among structs does not consider 
nullability
---
 .../org/apache/calcite/rel/type/RelDataTypeFactoryImpl.java  |  5 ++++-
 .../java/org/apache/calcite/sql/type/SqlTypeFactoryTest.java | 12 ++++++++++++
 .../java/org/apache/calcite/sql/type/SqlTypeFixture.java     | 12 ++++++++++++
 3 files changed, 28 insertions(+), 1 deletion(-)

diff --git 
a/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeFactoryImpl.java 
b/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeFactoryImpl.java
index 26d4980..2fa9701 100644
--- a/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeFactoryImpl.java
+++ b/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeFactoryImpl.java
@@ -221,6 +221,8 @@ public abstract class RelDataTypeFactoryImpl implements 
RelDataTypeFactory {
     final int fieldCount = type0.getFieldCount();
 
     // precheck that all types are structs with same number of fields
+    // and register desired nullability for the result
+    boolean isNullable = false;
     for (RelDataType type : types) {
       if (!type.isStruct()) {
         return null;
@@ -228,6 +230,7 @@ public abstract class RelDataTypeFactoryImpl implements 
RelDataTypeFactory {
       if (type.getFieldList().size() != fieldCount) {
         return null;
       }
+      isNullable |= type.isNullable();
     }
 
     // recursively compute column-wise least restrictive
@@ -249,7 +252,7 @@ public abstract class RelDataTypeFactoryImpl implements 
RelDataTypeFactory {
                 }
               }));
     }
-    return builder.build();
+    return createTypeWithNullability(builder.build(), isNullable);
   }
 
   // copy a non-record type, setting nullability
diff --git 
a/core/src/test/java/org/apache/calcite/sql/type/SqlTypeFactoryTest.java 
b/core/src/test/java/org/apache/calcite/sql/type/SqlTypeFactoryTest.java
index 6af99cf..61d7689 100644
--- a/core/src/test/java/org/apache/calcite/sql/type/SqlTypeFactoryTest.java
+++ b/core/src/test/java/org/apache/calcite/sql/type/SqlTypeFactoryTest.java
@@ -22,6 +22,7 @@ import org.apache.calcite.rel.type.RelDataTypeField;
 import org.apache.calcite.rel.type.RelDataTypeFieldImpl;
 import org.apache.calcite.rel.type.RelRecordType;
 
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 
 import org.junit.Test;
@@ -62,6 +63,17 @@ public class SqlTypeFactoryTest {
     assertThat(leastRestrictive.isNullable(), is(true));
   }
 
+  /** Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-2994";>[CALCITE-2994]
+   * Least restrictive type among structs does not consider nullability</a>. */
+  @Test public void testLeastRestrictiveWithNullableStruct() {
+    SqlTypeFixture f = new SqlTypeFixture();
+    RelDataType leastRestrictive =
+        f.typeFactory.leastRestrictive(ImmutableList.of(f.structOfIntNullable, 
f.structOfInt));
+    assertThat(leastRestrictive.getSqlTypeName(), is(SqlTypeName.ROW));
+    assertThat(leastRestrictive.isNullable(), is(true));
+  }
+
   @Test public void testLeastRestrictiveWithNull() {
     SqlTypeFixture f = new SqlTypeFixture();
     RelDataType leastRestrictive =
diff --git a/core/src/test/java/org/apache/calcite/sql/type/SqlTypeFixture.java 
b/core/src/test/java/org/apache/calcite/sql/type/SqlTypeFixture.java
index df70571..e150653 100644
--- a/core/src/test/java/org/apache/calcite/sql/type/SqlTypeFixture.java
+++ b/core/src/test/java/org/apache/calcite/sql/type/SqlTypeFixture.java
@@ -19,6 +19,8 @@ package org.apache.calcite.sql.type;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeSystem;
 
+import com.google.common.collect.ImmutableList;
+
 /**
  * Reusable {@link RelDataType} fixtures for tests.
  */
@@ -60,6 +62,16 @@ class SqlTypeFixture {
       typeFactory.createArrayType(arrayBigInt, -1), false);
   final RelDataType arrayOfArrayFloat = typeFactory.createTypeWithNullability(
       typeFactory.createArrayType(arrayFloat, -1), false);
+  final RelDataType structOfInt = typeFactory.createTypeWithNullability(
+      typeFactory.createStructType(
+          ImmutableList.of(sqlInt, sqlInt),
+          ImmutableList.of("i", "j")
+      ), false);
+  final RelDataType structOfIntNullable = 
typeFactory.createTypeWithNullability(
+      typeFactory.createStructType(
+          ImmutableList.of(sqlInt, sqlInt),
+          ImmutableList.of("i", "j")
+      ), true);
 }
 
 // End SqlTypeFixture.java

Reply via email to