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

Henri Biestro commented on CALCITE-5444:
----------------------------------------

My bad, I misconstrued the problem and confused it with another (unrelated, 
through JEXL).

However, my understanding of the issue as described is whether BigDecimal.ZERO 
should be valid for any decimal(p, p) - which is not the case today and raises 
an internal exception because the public method isValidDecimalValue returns 
false in that case.

Considering "0.0" or ".0" valid decimal whilst "0" is not seems odd.
It would seem saner to indeed start isValidDecimalValue with something like:

{code}
public static boolean isValidDecimalValue(@Nullable BigDecimal value, 
RelDataType toType) {
    if (value == null || BigDecimal.ZERO.equals(value.stripTrailingZeros())) {
       return true;
   }
{code}

Another test that one could naively expect to succeed:
{code}
  @Test void testDecimal11WithZero() {
    runDecimalLiteral(BigDecimal.ZERO);
    runDecimalLiteral(new BigDecimal("0"));
    runDecimalLiteral(new BigDecimal("0.0"));
    runDecimalLiteral(new BigDecimal(".0"));
  }

  private void runDecimalLiteral(BigDecimal bigd) {
    RexLiteral literal = rexBuilder.makeLiteral(bigd,
        typeFactory.createSqlType(SqlTypeName.DECIMAL, 1, 1),
        SqlTypeName.DECIMAL);
    assertEquals(1, literal.getType().getPrecision());
    assertEquals(1, literal.getType().getScale());
  }
{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)

Reply via email to