[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/b4b04d29 Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/b4b04d29 Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/b4b04d29 Branch: refs/heads/master Commit: b4b04d29cb63ceea123ec41dd3247a0555f9c150 Parents: 361096b Author: Frankie Bollaert <[email protected]> Authored: Mon Jan 11 11:23:46 2016 +0100 Committer: Julian Hyde <[email protected]> Committed: Tue Jan 12 13:47:17 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/b4b04d29/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/b4b04d29/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/b4b04d29/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++) {
