You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@calcite.apache.org by "Feng Zhu (JIRA)" <ji...@apache.org> on 2019/06/27 02:53:00 UTC

[jira] [Assigned] (CALCITE-3142) An NPE when rounding a nullable numeric

     [ https://issues.apache.org/jira/browse/CALCITE-3142?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Feng Zhu reassigned CALCITE-3142:
---------------------------------

    Assignee: Feng Zhu

> 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: Muhammad Gelbana
>            Assignee: Feng Zhu
>            Priority: Major
>
> 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
(v7.6.3#76005)