[ https://issues.apache.org/jira/browse/CALCITE-3142?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17040654#comment-17040654 ]
Danny Chen commented on CALCITE-3142: ------------------------------------- Remove the fix version tag because it seems impossible to be resolved in release 1.22. > An NPE when rounding a nullable numeric > --------------------------------------- > > Key: CALCITE-3142 > URL: https://issues.apache.org/jira/browse/CALCITE-3142 > Project: Calcite > Issue Type: Bug > Components: core > Affects Versions: 1.20.0 > Reporter: Mohamed Mohsen > Assignee: Feng Zhu > Priority: Major > Labels: pull-request-available > Attachments: newcodegen.png > > Time Spent: 20m > Remaining Estimate: 0h > > The following query throws a NPE in the generated code because it assumes the > divided value to be an initialized Java object (Not null), which is fine for > the first row, but not for the second. > {code:sql} > SELECT ROUND(CAST((X/Y) AS NUMERIC), 2) FROM (VALUES (1, 2), (NULLIF(5, 5), > NULLIF(5, 5))) A(X, Y){code} > If I modify the query a little bit, it runs ok: > – No casting > {code:sql} > SELECT ROUND((X/Y), 2) FROM (VALUES (1, 2), (NULLIF(5, 5), NULLIF(5, 5))) > A(X, Y){code} > – No rounding > {code:sql} > SELECT (X/Y)::NUMERIC FROM (VALUES (1, 2), (NULLIF(5, 5), NULLIF(5, 5))) A(X, > Y){code} > +This is the optimized generated code+ > {code:java} > final Object[] current = (Object[]) inputEnumerator.current(); > final Integer inp0_ = (Integer) current[0]; > final Integer inp1_ = (Integer) current[1]; > final java.math.BigDecimal v1 = new java.math.BigDecimal( > inp0_.intValue() / inp1_.intValue()); // <<< NPE > return inp0_ == null || inp1_ == null ? (java.math.BigDecimal) null : > org.apache.calcite.runtime.SqlFunctions.sround(v1, 2);{code} > +This is the non-optimized one+ > {code:java} > final Object[] current = (Object[]) inputEnumerator.current(); > final Integer inp0_ = (Integer) current[0]; > final boolean inp0__unboxed = inp0_ == null; > final Integer inp1_ = (Integer) current[1]; > final boolean inp1__unboxed = inp1_ == null; > final boolean v = inp0__unboxed || inp1__unboxed; > final int inp0__unboxed0 = inp0_.intValue(); // <<< NPE > final int inp1__unboxed0 = inp1_.intValue(); // <<< NPE > final int v0 = inp0__unboxed0 / inp1__unboxed0; > final java.math.BigDecimal v1 = new java.math.BigDecimal( > v0); > final java.math.BigDecimal v2 = v ? (java.math.BigDecimal) null : > org.apache.calcite.runtime.SqlFunctions.sround(v1, 2); > return v2;{code} -- This message was sent by Atlassian Jira (v8.3.4#803005)