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

NullPointerException when rounding a nullable numeric

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Duplicate
    • 1.20.0
    • 1.24.0
    • core

    Description

      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.

      SELECT ROUND(CAST((X/Y) AS NUMERIC), 2) FROM (VALUES (1, 2), (NULLIF(5, 5), NULLIF(5, 5))) A(X, Y)

      If I modify the query a little bit, it runs ok:
      – No casting

      SELECT ROUND((X/Y), 2) FROM (VALUES (1, 2), (NULLIF(5, 5), NULLIF(5, 5))) A(X, Y)

      – No rounding

      SELECT (X/Y)::NUMERIC FROM (VALUES (1, 2), (NULLIF(5, 5), NULLIF(5, 5))) A(X, Y)

      This is the optimized generated code

      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);

      This is the non-optimized one

      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;

      Attachments

        1. newcodegen.png
          51 kB
          Feng Zhu

        Issue Links

          Activity

            People

              donnyzone Feng Zhu
              mgelbana Mohamed Mohsen
              Votes:
              0 Vote for this issue
              Watchers:
              7 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 - 20m
                  20m