[CALCITE-1051] Underflow exception due to scaling IN clause literals (Frankie Bollaert)
Literals in the IN clause value list are scaled during SqlToRel conversion. When the type of the literal does not have a scale set, as happens with a java.lang.Integer, the default value of the type.scale is chosen, which is Integer.MIN_VALUE. Scaling to this value causes an underflow. Project: http://git-wip-us.apache.org/repos/asf/calcite/repo Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/bda2b0d0 Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/bda2b0d0 Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/bda2b0d0 Branch: refs/heads/branch-1.6 Commit: bda2b0d087d64cc27fb8ae7bc46422965bb75c6a Parents: ebcba3b Author: Frankie Bollaert <[email protected]> Authored: Mon Jan 11 11:23:46 2016 +0100 Committer: Julian Hyde <[email protected]> Committed: Mon Jan 11 19:01:49 2016 -0800 ---------------------------------------------------------------------- .../java/org/apache/calcite/sql/type/SqlTypeUtil.java | 5 +++++ .../org/apache/calcite/sql2rel/SqlToRelConverter.java | 2 +- .../src/test/java/org/apache/calcite/test/CsvTest.java | 11 +++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/calcite/blob/bda2b0d0/core/src/main/java/org/apache/calcite/sql/type/SqlTypeUtil.java ---------------------------------------------------------------------- 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 204b7ea..d8a437d 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 @@ -414,6 +414,11 @@ public abstract class SqlTypeUtil { } } + /** Returns whether a type's scale is set. */ + public static boolean hasScale(RelDataType type) { + return type.getScale() != Integer.MIN_VALUE; + } + /** * Returns the maximum value of an integral type, as a long value */ http://git-wip-us.apache.org/repos/asf/calcite/blob/bda2b0d0/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java index bb37de1..d9189a5 100644 --- a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java +++ b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java @@ -1650,7 +1650,7 @@ public class SqlToRelConverter { Comparable value = literal.getValue(); - if (SqlTypeUtil.isExactNumeric(type)) { + if (SqlTypeUtil.isExactNumeric(type) && SqlTypeUtil.hasScale(type)) { BigDecimal roundedValue = NumberUtil.rescaleBigDecimal( (BigDecimal) value, http://git-wip-us.apache.org/repos/asf/calcite/blob/bda2b0d0/example/csv/src/test/java/org/apache/calcite/test/CsvTest.java ---------------------------------------------------------------------- diff --git a/example/csv/src/test/java/org/apache/calcite/test/CsvTest.java b/example/csv/src/test/java/org/apache/calcite/test/CsvTest.java index a048319..650dce1 100644 --- a/example/csv/src/test/java/org/apache/calcite/test/CsvTest.java +++ b/example/csv/src/test/java/org/apache/calcite/test/CsvTest.java @@ -362,6 +362,17 @@ public class CsvTest { "smart", expect("NAME=Alice")); } + /** Test case for + * <a href="https://issues.apache.org/jira/browse/CALCITE-1051">[CALCITE-1051] + * Underflow exception due to scaling IN clause literals</a>. */ + @Test public void testInToSemiJoinWithoutCast() throws SQLException { + final String sql = "SELECT e.name\n" + + "FROM emps AS e\n" + + "WHERE e.empno in " + + range(130, SqlToRelConverter.IN_SUBQUERY_THRESHOLD); + checkSql(sql, "smart", expect("NAME=Alice")); + } + private String range(int first, int count) { final StringBuilder sb = new StringBuilder(); for (int i = 0; i < count; i++) {
