[
https://issues.apache.org/jira/browse/CALCITE-5444?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Soumyakanti Das updated CALCITE-5444:
-------------------------------------
Description:
The java {{BigDecimal.valueOf(0)}} method returns 0:DECIMAL(1,0). While trying
to convert it to {{{}0.0: DECIMAL(1,1){}}}, we encounter an error:
{code:java}
Cannot convert 0 to DECIMAL(1, 1) due to overflow
java.lang.IllegalArgumentException: Cannot convert 0 to DECIMAL(1, 1) due to
overflow
at org.apache.calcite.rex.RexBuilder.makeLiteral(RexBuilder.java:1015)
at
org.apache.calcite.rex.RexProgramTest.testDecimalWithZero(RexProgramTest.java:2662)
{code}
This is because {{intDigits > maxIntDigits}}
[here|https://github.com/apache/calcite/blob/013f034dee3e24083760b4695e2eacfbf592c2cb/core/src/main/java/org/apache/calcite/sql/type/SqlTypeUtil.java#L1812],
which causes an exception
[here|https://github.com/apache/calcite/blob/013f034dee3e24083760b4695e2eacfbf592c2cb/core/src/main/java/org/apache/calcite/rex/RexBuilder.java#L1015].
This can be reproduced by calling makeLiteral directly with a test in
{{RexProgramTest}} like:
{code:java}
@Test void testDecimalWithZero() {
RexLiteral literal = rexBuilder.makeLiteral(BigDecimal.valueOf(0),
typeFactory.createSqlType(SqlTypeName.DECIMAL, 1, 1),
SqlTypeName.DECIMAL);
assertEquals(1, literal.getType().getPrecision());
assertEquals(1, literal.getType().getScale());{code}
This doesn't fail if we add a test to {{{}SqlToRelConverterTest.java{}}}, like,
{code:java}
@Test void testDecimal() {
final String sql = "select cast(cast(0 as decimal(1,0)) as decimal(1, 1))";
sql(sql).ok();
} {code}
because the exception is caught and handled in
[RexExecutable.java|https://github.com/apache/calcite/blob/013f034dee3e24083760b4695e2eacfbf592c2cb/core/src/main/java/org/apache/calcite/rex/RexExecutable.java#L96].
However, we see the exception if we directly call {{makeLiteral}} as shown
above.
Ideally, this is fine, but I think ZERO should be a special case as 1 != 1.0
but 0 == 0.0
The simplest solution could be to modify the {{if}} block
[here|https://github.com/apache/calcite/blob/013f034dee3e24083760b4695e2eacfbf592c2cb/core/src/main/java/org/apache/calcite/sql/type/SqlTypeUtil.java#L1805]
to
{code:java}
if (value == null || value.equals(new BigDecimal("0")) {
return true;
} {code}
was:
The java {{BigDecimal.valueOf(0)}} method returns 0:DECIMAL(1,0). While trying
to convert it to {{{}0.0: DECIMAL(1,1){}}}, we encounter an error:
{code:java}
Cannot convert 0 to DECIMAL(1, 1) due to overflow
java.lang.IllegalArgumentException: Cannot convert 0 to DECIMAL(1, 1) due to
overflow
at org.apache.calcite.rex.RexBuilder.makeLiteral(RexBuilder.java:1015)
at
org.apache.calcite.rex.RexProgramTest.testDecimalWithZero(RexProgramTest.java:2662)
{code}
This is because {{intDigits > maxIntDigits}}
[here|https://github.com/apache/calcite/blob/013f034dee3e24083760b4695e2eacfbf592c2cb/core/src/main/java/org/apache/calcite/sql/type/SqlTypeUtil.java#L1812],
which causes an exception
[here|https://github.com/apache/calcite/blob/013f034dee3e24083760b4695e2eacfbf592c2cb/core/src/main/java/org/apache/calcite/rex/RexBuilder.java#L1015].
This can be reproduced by calling makeLiteral directly like:
{code:java}
@Test void testDecimalWithZero() {
rexBuilder.makeLiteral(BigDecimal.valueOf(0),
typeFactory.createSqlType(SqlTypeName.DECIMAL, 1, 1),
SqlTypeName.DECIMAL);
} {code}
This doesn't fail if we add a test to {{{}SqlToRelConverterTest.java{}}}, like,
{code:java}
@Test void testDecimal() {
final String sql = "select cast(cast(0 as decimal(1,0)) as decimal(1, 1))";
sql(sql).ok();
} {code}
because the exception is caught and handled in
[RexExecutable.java|https://github.com/apache/calcite/blob/013f034dee3e24083760b4695e2eacfbf592c2cb/core/src/main/java/org/apache/calcite/rex/RexExecutable.java#L96].
However, we see the exception if we directly call {{makeLiteral}} as shown
above.
Ideally, this is fine, but I think ZERO should be a special case as 1 != 1.0
but 0 == 0.0
The simplest solution could be to modify the {{if}} block
[here|https://github.com/apache/calcite/blob/013f034dee3e24083760b4695e2eacfbf592c2cb/core/src/main/java/org/apache/calcite/sql/type/SqlTypeUtil.java#L1805]
to
{code:java}
if (value == null || value.equals(new BigDecimal("0")) {
return true;
} {code}
> Error when trying to cast 0:DECIMAL(1,0) to 0:DECIMAL(1,1)
> ----------------------------------------------------------
>
> Key: CALCITE-5444
> URL: https://issues.apache.org/jira/browse/CALCITE-5444
> Project: Calcite
> Issue Type: Bug
> Components: core
> Affects Versions: 1.33.0
> Reporter: Soumyakanti Das
> Assignee: Soumyakanti Das
> Priority: Major
>
> The java {{BigDecimal.valueOf(0)}} method returns 0:DECIMAL(1,0). While
> trying to convert it to {{{}0.0: DECIMAL(1,1){}}}, we encounter an error:
> {code:java}
> Cannot convert 0 to DECIMAL(1, 1) due to overflow
> java.lang.IllegalArgumentException: Cannot convert 0 to DECIMAL(1, 1) due to
> overflow
> at org.apache.calcite.rex.RexBuilder.makeLiteral(RexBuilder.java:1015)
> at
> org.apache.calcite.rex.RexProgramTest.testDecimalWithZero(RexProgramTest.java:2662)
> {code}
> This is because {{intDigits > maxIntDigits}}
> [here|https://github.com/apache/calcite/blob/013f034dee3e24083760b4695e2eacfbf592c2cb/core/src/main/java/org/apache/calcite/sql/type/SqlTypeUtil.java#L1812],
> which causes an exception
> [here|https://github.com/apache/calcite/blob/013f034dee3e24083760b4695e2eacfbf592c2cb/core/src/main/java/org/apache/calcite/rex/RexBuilder.java#L1015].
> This can be reproduced by calling makeLiteral directly with a test in
> {{RexProgramTest}} like:
> {code:java}
> @Test void testDecimalWithZero() {
> RexLiteral literal = rexBuilder.makeLiteral(BigDecimal.valueOf(0),
> typeFactory.createSqlType(SqlTypeName.DECIMAL, 1, 1),
> SqlTypeName.DECIMAL);
> assertEquals(1, literal.getType().getPrecision());
> assertEquals(1, literal.getType().getScale());{code}
> This doesn't fail if we add a test to {{{}SqlToRelConverterTest.java{}}},
> like,
> {code:java}
> @Test void testDecimal() {
> final String sql = "select cast(cast(0 as decimal(1,0)) as decimal(1, 1))";
> sql(sql).ok();
> } {code}
> because the exception is caught and handled in
> [RexExecutable.java|https://github.com/apache/calcite/blob/013f034dee3e24083760b4695e2eacfbf592c2cb/core/src/main/java/org/apache/calcite/rex/RexExecutable.java#L96].
> However, we see the exception if we directly call {{makeLiteral}} as shown
> above.
> Ideally, this is fine, but I think ZERO should be a special case as 1 != 1.0
> but 0 == 0.0
> The simplest solution could be to modify the {{if}} block
> [here|https://github.com/apache/calcite/blob/013f034dee3e24083760b4695e2eacfbf592c2cb/core/src/main/java/org/apache/calcite/sql/type/SqlTypeUtil.java#L1805]
> to
> {code:java}
> if (value == null || value.equals(new BigDecimal("0")) {
> return true;
> } {code}
>
--
This message was sent by Atlassian Jira
(v8.20.10#820010)