Uploaded image for project: 'Calcite'
  1. Calcite
  2. CALCITE-4777

Casting from DECIMAL to BOOLEAN throws an exception

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Duplicate
    • None
    • None
    • None

    Description

      My sql is the following:

      // code placeholder
      select * from test where cast (0.10915913549909961 as boolean)

       

      I want to simplify the cast. An exception is thrown:

       

      // code placeholder
      Exception in thread "main" java.lang.RuntimeException: while resolving method 'booleanValue' in class class java.math.BigDecimal at org.apache.calcite.linq4j.tree.Expressions.call(Expressions.java:424) at org.apache.calcite.linq4j.tree.Expressions.call(Expressions.java:435) at org.apache.calcite.linq4j.tree.Expressions.unbox(Expressions.java:1453) at org.apache.calcite.adapter.enumerable.EnumUtils.convert(EnumUtils.java:398) at org.apache.calcite.adapter.enumerable.EnumUtils.convert(EnumUtils.java:326) at org.apache.calcite.adapter.enumerable.RexToLixTranslator.translateCast(RexToLixTranslator.java:543) at org.apache.calcite.adapter.enumerable.RexImpTable$CastImplementor.implementSafe(RexImpTable.java:2450) at org.apache.calcite.adapter.enumerable.RexImpTable$AbstractRexCallImplementor.genValueStatement(RexImpTable.java:2894) at org.apache.calcite.adapter.enumerable.RexImpTable$AbstractRexCallImplementor.implement(RexImpTable.java:2859) at org.apache.calcite.adapter.enumerable.RexToLixTranslator.visitCall(RexToLixTranslator.java:1089) at org.apache.calcite.adapter.enumerable.RexToLixTranslator.visitCall(RexToLixTranslator.java:90) at org.apache.calcite.rex.RexCall.accept(RexCall.java:174) at org.apache.calcite.adapter.enumerable.RexToLixTranslator.visitLocalRef(RexToLixTranslator.java:975) at org.apache.calcite.adapter.enumerable.RexToLixTranslator.visitLocalRef(RexToLixTranslator.java:90) at org.apache.calcite.rex.RexLocalRef.accept(RexLocalRef.java:75) at org.apache.calcite.adapter.enumerable.RexToLixTranslator.translate(RexToLixTranslator.java:237) at org.apache.calcite.adapter.enumerable.RexToLixTranslator.translate(RexToLixTranslator.java:231) at org.apache.calcite.adapter.enumerable.RexToLixTranslator.translateList(RexToLixTranslator.java:823) at org.apache.calcite.adapter.enumerable.RexToLixTranslator.translateProjects(RexToLixTranslator.java:198) at org.apache.calcite.rex.RexExecutorImpl.compile(RexExecutorImpl.java:90) at org.apache.calcite.rex.RexExecutorImpl.compile(RexExecutorImpl.java:66) at org.apache.calcite.rex.RexExecutorImpl.reduce(RexExecutorImpl.java:128) at org.apache.calcite.rex.RexSimplify.simplifyCast(RexSimplify.java:2101) at org.apache.calcite.rex.RexSimplify.simplify(RexSimplify.java:326) at org.apache.calcite.rex.RexSimplify.simplifyUnknownAs(RexSimplify.java:287) at org.apache.flink.table.examples.java.tests.CalciteTest.main(CalciteTest.java:47)
      
      Caused by: java.lang.NoSuchMethodException: java.math.BigDecimal.booleanValue() at java.lang.Class.getMethod(Class.java:1786) at org.apache.calcite.linq4j.tree.Expressions.call(Expressions.java:421) ... 25 more
      

      In order to avoid that I used the wrong rule or it caused by my bad coding, i write the test case following:

       

      // code placeholder
      JavaTypeFactory typeFactory = new JavaTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
      RexBuilder rexBuilder = new RexBuilder(typeFactory);
      
      final RexSimplify simplify = new RexSimplify(rexBuilder, RelOptPredicateList.EMPTY, RexUtil.EXECUTOR);
      RelDataType type = new BasicSqlType(typeFactory.getTypeSystem(), SqlTypeName.BOOLEAN);
      RelDataType bb = new BasicSqlType(typeFactory.getTypeSystem(),SqlTypeName.DECIMAL,18,17);
      SqlOperator op = new SqlCastFunction();
      RexLiteral lt = rexBuilder.makeExactLiteral(BigDecimal.valueOf(0.10915913549909961),bb);
      List<RexNode> list = new ArrayList<>();
      list.add(lt);
      
      RexNode rexNode = rexBuilder.makeCall(type,op,list);
      
      simplify.simplifyUnknownAs(rexNode, RexUnknownAs.UNKNOWN);
      

      and it throws the same exception.

       

      Actually, the cast simplify operation will enter the function translateCast in RexToLixTranslator.It misses the "case BOOLEAN" and uses the convert in EnumUtils. However, because the Decimal's Primitive is null and fromNumber is true, the Expression's function named "call" calls the "booleanValue" function in "java.math.BigDecimal", which does not actually exist. So the exception is thrown. 

      I find in SqFunctions, we have a function "toBoolean(Number number)" (which seems never to be used?). This function may very fit dealing with this question, right?

       

      Attachments

        1. calcite.png
          892 kB
          xuyang

        Issue Links

          Activity

            People

              xuyangzhong xuyang
              xuyangzhong xuyang
              Votes:
              0 Vote for this issue
              Watchers:
              8 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Time Tracking

                  Estimated:
                  Original Estimate - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - 0h
                  0h
                  Logged:
                  Time Spent - 2h 40m
                  2h 40m