[ https://issues.apache.org/jira/browse/KYLIN-5756?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17830479#comment-17830479 ]
pengfei.zhan edited comment on KYLIN-5756 at 3/25/24 1:26 PM: -------------------------------------------------------------- h1. Fix design # When generating java code in calcite, to determine whether the + operator needs to be converted to plus() or whether to directly use addition in java, add a condition that when the parameters on both sides of the plus operator are of string type or numeric type, plus() is used directly. i.e. fix the '1' + 3 + '3' in the previous sql, the java code is plus('1' + 3) + '3'. After the fix it is plus(plus('1' + 3), '3') # Changed the return value of the custom plus function in calcite from Double to bigDecimal. The reasons are as follows: * Constant folding by calcite to generate java code derives whether it is isNullable, if the RexCall with its nullable is false, it will automatic unboxing; * The expression 'a' + 3 is considered to be non-nullable by calcite, because the two arguments are constants and neither of them is null, so the whole thing is considered non-null; * In spark, 'a' + 3 results in null, so our implementation of the plus method gives the same result * In summary, when expression `plus(string, number)` returns Double, the java code for `'a' + 3 + '3' ` is actually `plus(plus('a' + 3).doubleValue(), '3')`, which then throws an NPE when the calculation is performed. This behavior change of isNullable involves a wide range, and it is dangerous to modify it directly, so we changed the return value of plus operator to BigDecimal to avoid unboxing. was (Author: JIRAUSER294653): h1. Fix design # When generating java code in calcite, to determine whether the + operator needs to be converted to plus() or whether to directly use addition in java, add a condition that when the parameters on both sides of the plus operator are of string type or numeric type, plus() is used directly. i.e. fix the '1' + 3 + '3' in the previous sql, the java code is plus('1' + 3) + '3'. After the fix it is plus(plus('1' + 3), '3') # Changed the return value of the custom plus function in calcite from Double to bigDecimal. The reasons are as follows: * Constant folding by calcite to generate java code derives whether it is isNullable, if the RexCall with its nullable is false, it will automatic unboxing; * The expression 'a' + 3 is considered to be non-nullable by calcite, because the two arguments are constants and neither of them is null, so the whole thing is considered non-null; * In spark, 'a' + 3 results in null, so our implementation of the plus method gives the same result * In summary, when expression `plus(string, number)` returns Double, the java code for `'a' + 3 + '3' ` is actually `plus(plus('a' + 3).doubleValue(), '3')`, which then throws an NPE when the calculation is performed. This behavior change of isNullable involves a wide range, and it is dangerous to modify it directly, so we changed the return value of plus operator to BigDecimal to avoid unboxing. > Concat string and number with '+' gives unexpected result > --------------------------------------------------------- > > Key: KYLIN-5756 > URL: https://issues.apache.org/jira/browse/KYLIN-5756 > Project: Kylin > Issue Type: Improvement > Components: Query Engine > Affects Versions: 5.0-beta > Reporter: pengfei.zhan > Assignee: pengfei.zhan > Priority: Major > Fix For: 5.0-beta > > > Concat string and number gives unexpected result. > For example: > 1. concat constant with plus operator, gives unexpected result > {code:java} > 1' + 3 + 3 // 7 (correct) > '1' + 3 + '3' // 4.03 (wrong result) > '1' + '3' + 'a' // error > {code} > 2. concat string and number, the first '+' produces null > {code:java} > 'q' + 1 + 1 // error > {code} -- This message was sent by Atlassian Jira (v8.20.10#820010)