This is an automated email from the ASF dual-hosted git repository.
snuyanzin 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 53e0968 [CALCITE-4811] Check if input type is a struct in
RelDataTypeFactoryImpl#leastRestrictiveStructuredType
53e0968 is described below
commit 53e09688c71b85817a9c382edd573dbcc7e48aa5
Author: snuyanzin <[email protected]>
AuthorDate: Tue Sep 28 19:37:39 2021 +0200
[CALCITE-4811] Check if input type is a struct in
RelDataTypeFactoryImpl#leastRestrictiveStructuredType
Close apache/calcite#2553
---
.../org/apache/calcite/rel/type/RelDataTypeFactoryImpl.java | 4 ++++
.../main/java/org/apache/calcite/sql/type/SqlTypeUtil.java | 2 +-
.../org/apache/calcite/sql/type/SqlTypeFactoryTest.java | 8 ++++++++
core/src/test/java/org/apache/calcite/test/JdbcTest.java | 13 +++++++++++++
4 files changed, 26 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 818dd60..d4715f2 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
@@ -225,6 +225,10 @@ public abstract class RelDataTypeFactoryImpl implements
RelDataTypeFactory {
protected @Nullable RelDataType leastRestrictiveStructuredType(
final List<RelDataType> types) {
final RelDataType type0 = types.get(0);
+ // precheck that fieldCount is present
+ if (!type0.isStruct()) {
+ return null;
+ }
final int fieldCount = type0.getFieldCount();
// precheck that all types are structs with same number of fields
diff --git a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeUtil.java
b/core/src/main/java/org/apache/calcite/sql/type/SqlTypeUtil.java
index 3fdd416..c4b2cfc 100644
--- a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeUtil.java
+++ b/core/src/main/java/org/apache/calcite/sql/type/SqlTypeUtil.java
@@ -837,7 +837,7 @@ public abstract class SqlTypeUtil {
toType, fromType.getFieldList().get(0).getType(), coerce);
} else if (toTypeName == SqlTypeName.ROW) {
if (fromTypeName != SqlTypeName.ROW) {
- return false;
+ return fromTypeName == SqlTypeName.NULL;
}
int n = toType.getFieldCount();
if (fromType.getFieldCount() != n) {
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 b0f9d56..80a8a86 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
@@ -84,6 +84,14 @@ class SqlTypeFactoryTest {
assertThat(leastRestrictive.isNullable(), is(true));
}
+ @Test void testLeastRestrictiveStructWithNull() {
+ SqlTypeFixture f = new SqlTypeFixture();
+ RelDataType leastRestrictive =
+ f.typeFactory.leastRestrictive(Lists.newArrayList(f.sqlNull,
f.structOfInt));
+ assertThat(leastRestrictive.getSqlTypeName(), is(SqlTypeName.ROW));
+ assertThat(leastRestrictive.isNullable(), is(true));
+ }
+
@Test void testLeastRestrictiveForImpossibleWithArray() {
SqlTypeFixture f = new SqlTypeFixture();
RelDataType leastRestrictive =
diff --git a/core/src/test/java/org/apache/calcite/test/JdbcTest.java
b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
index d0cb2ad..2589947 100644
--- a/core/src/test/java/org/apache/calcite/test/JdbcTest.java
+++ b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
@@ -7742,6 +7742,19 @@ public class JdbcTest {
assertThat.query(query).returns("EXPR$0=4200000000\n");
}
+ /**
+ * Test case for
+ * <a
href="https://issues.apache.org/jira/browse/CALCITE-4811">[CALCITE-4811]
+ * Check for internal content in case of ROW in
+ * RelDataTypeFactoryImpl#leastRestrictiveStructuredType should be after
isStruct check</a>.
+ */
+ @Test public void testCoalesceNullAndRow() {
+ CalciteAssert.that()
+ .query("SELECT COALESCE(NULL, ROW(1)) AS F")
+ .typeIs("[F STRUCT]")
+ .returns("F={1}\n");
+ }
+
private static String sums(int n, boolean c) {
final StringBuilder b = new StringBuilder();
for (int i = 0; i < n; i++) {