xuyangzhong created CALCITE-4777:
------------------------------------

             Summary: Casting from decimal to boolean throws an exception
                 Key: CALCITE-4777
                 URL: https://issues.apache.org/jira/browse/CALCITE-4777
             Project: Calcite
          Issue Type: Bug
            Reporter: xuyangzhong


My sql is the following:
{code:java}
// code placeholder
select * from test where cast (0.10915913549909961 as boolean){code}
 

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

 
{code:java}
// 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
{code}
In order to avoid that I used the wrong rule or it caused by my bad coding, i 
write the test case following:

 
{code:java}
// 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);
{code}
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?

 



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to