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);