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

NPE caused by wrong code generation for Timestamp fields

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Minor
    • Resolution: Fixed
    • Affects Version/s: 1.6.0, 1.5.0, 1.4.0-incubating
    • Fix Version/s: 1.16.0
    • Component/s: core
    • Labels:
      None

      Description

      Problem occurs when:

      • Execute a query containing 2 checks on a Timestamp field
      • Table contains records which have NULL values for this field

      Example query:

      select * from aTable where aTimestamp > timestamp '2015-1-1 00:00:00' and aTimestamp < timestamp '2015-2-1 00:00:00';
      
      /*  48 */   public boolean moveNext() {
      /*  49 */     while (inputEnumerator.moveNext()) {
      /*  50 */       final java.sql.Timestamp inp23_ = (java.sql.Timestamp) ((Object[]) inputEnumerator.current())[23];
      /*  51 */       final long v = org.apache.calcite.runtime.SqlFunctions.toLong(inp23_);
      /*  52 */       if (inp23_ != null && v > 1420070400000L && (inp23_ != null && v < 1422748800000L)) {
      /*  53 */         return true;
      /*  54 */       }
      /*  55 */     }
      /*  56 */     return false;
      /*  57 */   }
      

      Stack trace snippet

      Caused by: java.lang.NullPointerException
      	at org.apache.calcite.runtime.SqlFunctions.toLong(SqlFunctions.java:1094)
      	at org.apache.calcite.runtime.SqlFunctions.toLong(SqlFunctions.java:1089)
      	at Baz$1$1.moveNext(ANONYMOUS.java:51)
      	at org.apache.calcite.linq4j.Linq4j$EnumeratorIterator.<init>(Linq4j.java:677)
      	at org.apache.calcite.linq4j.Linq4j.enumeratorIterator(Linq4j.java:103)
      

      The generated code also looks wrong for date fields.

      /*  15 */   public boolean moveNext() {
      /*  16 */     while (inputEnumerator.moveNext()) {
      /*  17 */       final java.sql.Date current = (java.sql.Date) inputEnumerator.current();
      /*  18 */       final int v = org.apache.calcite.runtime.SqlFunctions.toInt(current);
      /*  19 */       if (current != null && v > 2780 && (current != null && v < 5290)) {
      /*  20 */         return true;
      /*  21 */       }
      /*  22 */     }
      /*  23 */     return false;
      /*  24 */   }
      


      Other types of fields do not have this problem. Below is what the generated code looks like in the case of a String field. On line 20 there is a null check. This is the type of check that needs to be generated for Timestamp fields as well.

      select empno from sales.emps where gender > 'A' and gender < 'Z';
      
      /*  17 */  public boolean moveNext() {
      /*  18 */    while (inputEnumerator.moveNext()) {
      /*  19 */      final Object[] current = (Object[]) inputEnumerator.current();
      /*  20 */      final String inp3_ = current[3] == null ? (String) null : current[3].toString();
      /*  21 */      if (inp3_ != null && org.apache.calcite.runtime.SqlFunctions.gt(inp3_, $L4J$C$org_apache_calcite_runtime_SqlFunctions_rtrim_A_) && (inp3_ != null && org.apache.calcite.runtime.SqlFunctions.lt(inp3_, $L4J$C$org_apache_calcite_runtime_SqlFunctions_rtrim_Z_))) {
      /*  22 */        return true;
      /*  23 */      }
      /*  24 */    }
      /*  25 */    return false;
      /*  26 */  }
      

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                julianhyde Julian Hyde
                Reporter:
                frankieb Frankie Bollaert
              • Votes:
                1 Vote for this issue
                Watchers:
                8 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: