You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@calcite.apache.org by "Julian Hyde (Jira)" <ji...@apache.org> on 2022/12/20 01:16:00 UTC

[jira] [Commented] (CALCITE-5444) Error when trying to cast 0:DECIMAL(1,0) to 0:DECIMAL(1,1)

    [ https://issues.apache.org/jira/browse/CALCITE-5444?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17649522#comment-17649522 ] 

Julian Hyde commented on CALCITE-5444:
--------------------------------------

I think the exception is that the conversion MAY cause an overflow. And this is true; converting a DECIMAL(1, 0) to a DECIMAL(1, 1) may cause an overflow; it doesn't for 0, but it does for other values. The behavior must be based on types, not runtime values. So I think the current behavior is correct.

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