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

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


The following commit(s) were added to refs/heads/main by this push:
     new 29fcbf14f1 [CALCITE-5478] Use highest input precision for datetimes in 
SqlTypeFactoryImpl.leastRestrictive
29fcbf14f1 is described below

commit 29fcbf14f1c8f83ca27d307d4b458efa0d4ece5f
Author: Gian Merlino <[email protected]>
AuthorDate: Fri Jan 13 10:21:18 2023 -0800

    [CALCITE-5478] Use highest input precision for datetimes in 
SqlTypeFactoryImpl.leastRestrictive
    
    Close apache/calcite#3029
---
 .../calcite/sql/type/SqlTypeFactoryImpl.java       | 12 ++++++++--
 .../calcite/sql/type/SqlTypeFactoryTest.java       | 28 ++++++++++++++++++++++
 .../apache/calcite/sql/type/SqlTypeFixture.java    |  4 +++-
 .../apache/calcite/sql/type/SqlTypeUtilTest.java   |  4 ++--
 4 files changed, 43 insertions(+), 5 deletions(-)

diff --git 
a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeFactoryImpl.java 
b/core/src/main/java/org/apache/calcite/sql/type/SqlTypeFactoryImpl.java
index 5dda51a331..ff08400ff8 100644
--- a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeFactoryImpl.java
+++ b/core/src/main/java/org/apache/calcite/sql/type/SqlTypeFactoryImpl.java
@@ -504,9 +504,17 @@ public class SqlTypeFactoryImpl extends 
RelDataTypeFactoryImpl {
                 nullCount > 0 || nullableCount > 0);
           }
         }
+
+        if (type.getSqlTypeName() == resultType.getSqlTypeName()
+            && type.getSqlTypeName().allowsPrec()
+            && type.getPrecision() != resultType.getPrecision()) {
+          final int precision =
+              SqlTypeUtil.maxPrecision(resultType.getPrecision(),
+                  type.getPrecision());
+
+          resultType = createSqlType(type.getSqlTypeName(), precision);
+        }
       } else {
-        // TODO:  datetime precision details; for now we let
-        // leastRestrictiveByCast handle it
         return null;
       }
     }
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 9f7ec0a530..ed5c2b1b1b 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
@@ -150,6 +150,34 @@ class SqlTypeFactoryTest {
     assertThat(leastRestrictive.getValueType().getPrecision(), is(10));
   }
 
+  @Test void testLeastRestrictiveForTimestamps() {
+    SqlTypeFixture f = new SqlTypeFixture();
+    RelDataType leastRestrictive =
+        f.typeFactory.leastRestrictive(
+            Lists.newArrayList(f.sqlTimestampPrec0, f.sqlTimestampPrec3));
+    assertThat(leastRestrictive.getSqlTypeName(), is(SqlTypeName.TIMESTAMP));
+    assertThat(leastRestrictive.isNullable(), is(false));
+    assertThat(leastRestrictive.getPrecision(), is(3));
+  }
+
+  @Test void testLeastRestrictiveForTimestamps2() {
+    SqlTypeFixture f = new SqlTypeFixture();
+    RelDataType leastRestrictive =
+        f.typeFactory.leastRestrictive(
+            Lists.newArrayList(f.sqlTimestampPrec3, f.sqlTimestampPrec0));
+    assertThat(leastRestrictive.getSqlTypeName(), is(SqlTypeName.TIMESTAMP));
+    assertThat(leastRestrictive.isNullable(), is(false));
+    assertThat(leastRestrictive.getPrecision(), is(3));
+  }
+
+  @Test void testLeastRestrictiveForTimestampAndDate() {
+    SqlTypeFixture f = new SqlTypeFixture();
+    RelDataType leastRestrictive =
+        f.typeFactory.leastRestrictive(
+            Lists.newArrayList(f.sqlTimestampPrec3, f.sqlDate));
+    assertNull(leastRestrictive);
+  }
+
   @Test void testLeastRestrictiveForImpossibleWithMaps() {
     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 11c9503032..b34f5ed914 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
@@ -50,7 +50,9 @@ class SqlTypeFixture {
       typeFactory.createSqlType(SqlTypeName.ANY), false);
   final RelDataType sqlFloat = typeFactory.createTypeWithNullability(
       typeFactory.createSqlType(SqlTypeName.FLOAT), false);
-  final RelDataType sqlTimestamp = typeFactory.createTypeWithNullability(
+  final RelDataType sqlTimestampPrec0 = typeFactory.createTypeWithNullability(
+      typeFactory.createSqlType(SqlTypeName.TIMESTAMP, 0), false);
+  final RelDataType sqlTimestampPrec3 = typeFactory.createTypeWithNullability(
       typeFactory.createSqlType(SqlTypeName.TIMESTAMP, 3), false);
   final RelDataType sqlGeometry = typeFactory.createTypeWithNullability(
       typeFactory.createSqlType(SqlTypeName.GEOMETRY), false);
diff --git 
a/core/src/test/java/org/apache/calcite/sql/type/SqlTypeUtilTest.java 
b/core/src/test/java/org/apache/calcite/sql/type/SqlTypeUtilTest.java
index b6bddfa267..a2c3fe1ad9 100644
--- a/core/src/test/java/org/apache/calcite/sql/type/SqlTypeUtilTest.java
+++ b/core/src/test/java/org/apache/calcite/sql/type/SqlTypeUtilTest.java
@@ -120,10 +120,10 @@ class SqlTypeUtilTest {
 
     // Initialize a SqlTypeCoercionRules with the new builder mappings.
     SqlTypeCoercionRule typeCoercionRules = 
SqlTypeCoercionRule.instance(builder.map);
-    assertThat(SqlTypeUtil.canCastFrom(f.sqlTimestamp, f.sqlBoolean, true),
+    assertThat(SqlTypeUtil.canCastFrom(f.sqlTimestampPrec3, f.sqlBoolean, 
true),
         is(false));
     SqlTypeCoercionRule.THREAD_PROVIDERS.set(typeCoercionRules);
-    assertThat(SqlTypeUtil.canCastFrom(f.sqlTimestamp, f.sqlBoolean, true),
+    assertThat(SqlTypeUtil.canCastFrom(f.sqlTimestampPrec3, f.sqlBoolean, 
true),
         is(true));
     // Recover the mappings to default.
     SqlTypeCoercionRule.THREAD_PROVIDERS.set(defaultRules);

Reply via email to