From a21deb83fd71bdc0550cb00007d43645fe48b67a Mon Sep 17 00:00:00 2001 From: Alessandro Solimando Date: Fri, 2 Jan 2026 20:36:36 +0100 Subject: [PATCH] feat: improve DECIMAL type handling (#655) --- .../isthmus/SubstraitTypeSystem.java | 19 ++++-- .../isthmus/SubstraitTypeSystemTest.java | 63 +++++++++++++++++++ 2 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 isthmus/src/test/java/io/substrait/isthmus/SubstraitTypeSystemTest.java diff --git a/isthmus/src/main/java/io/substrait/isthmus/SubstraitTypeSystem.java b/isthmus/src/main/java/io/substrait/isthmus/SubstraitTypeSystem.java index 97498e457..31c40905e 100644 --- a/isthmus/src/main/java/io/substrait/isthmus/SubstraitTypeSystem.java +++ b/isthmus/src/main/java/io/substrait/isthmus/SubstraitTypeSystem.java @@ -35,18 +35,29 @@ public int getMaxPrecision(final SqlTypeName typeName) { case TIMESTAMP: case TIMESTAMP_WITH_LOCAL_TIME_ZONE: return 6; + case DECIMAL: + return 38; } return super.getMaxPrecision(typeName); } @Override - public int getMaxNumericScale() { - return 38; + public int getDefaultPrecision(final SqlTypeName typeName) { + switch (typeName) { + case DECIMAL: + return getMaxPrecision(typeName); + default: + return super.getDefaultPrecision(typeName); + } } @Override - public int getMaxNumericPrecision() { - return 38; + public int getMaxScale(final SqlTypeName typeName) { + switch (typeName) { + case DECIMAL: + return 38; + } + return super.getMaxScale(typeName); } @Override diff --git a/isthmus/src/test/java/io/substrait/isthmus/SubstraitTypeSystemTest.java b/isthmus/src/test/java/io/substrait/isthmus/SubstraitTypeSystemTest.java new file mode 100644 index 000000000..01e7bd0c7 --- /dev/null +++ b/isthmus/src/test/java/io/substrait/isthmus/SubstraitTypeSystemTest.java @@ -0,0 +1,63 @@ +package io.substrait.isthmus; + +import static io.substrait.isthmus.SubstraitTypeSystem.TYPE_FACTORY; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rel.type.RelDataTypeSystem; +import org.apache.calcite.sql.type.SqlTypeName; +import org.junit.jupiter.api.Test; + +class SubstraitTypeSystemTest { + + private final RelDataTypeSystem typeSystem = SubstraitTypeSystem.TYPE_SYSTEM; + + @Test + void decimalMaxPrecision() { + assertEquals(38, typeSystem.getMaxPrecision(SqlTypeName.DECIMAL)); + } + + @Test + void decimalMaxScale() { + assertEquals(38, typeSystem.getMaxScale(SqlTypeName.DECIMAL)); + } + + @Test + void decimalDefaultPrecision() { + assertEquals(38, typeSystem.getDefaultPrecision(SqlTypeName.DECIMAL)); + } + + @Test + void decimalDefaultScale() { + assertEquals(0, typeSystem.getDefaultScale(SqlTypeName.DECIMAL)); + } + + @Test + void timestampMaxPrecision() { + assertEquals(6, typeSystem.getMaxPrecision(SqlTypeName.TIMESTAMP)); + } + + @Test + void timeMaxPrecision() { + assertEquals(6, typeSystem.getMaxPrecision(SqlTypeName.TIME)); + } + + @Test + void canCreateDecimalWithMaxPrecision() { + RelDataType decimalType = TYPE_FACTORY.createSqlType(SqlTypeName.DECIMAL, 38, 10); + assertEquals(38, decimalType.getPrecision()); + assertEquals(10, decimalType.getScale()); + } + + @Test + void decimalMaxPrecisionAndScaleDifferentFromDefaultTypeSystem() { + RelDataTypeSystem defaultTypeSystem = RelDataTypeSystem.DEFAULT; + int defaultMaxPrecision = defaultTypeSystem.getMaxPrecision(SqlTypeName.DECIMAL); + int defaultMaxScale = defaultTypeSystem.getMaxScale(SqlTypeName.DECIMAL); + + assertEquals(19, defaultMaxPrecision); + assertEquals(19, defaultMaxScale); + assertEquals(38, typeSystem.getMaxPrecision(SqlTypeName.DECIMAL)); + assertEquals(38, typeSystem.getMaxScale(SqlTypeName.DECIMAL)); + } +}