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

Invalid code generated for ROW_NUMBER function in Enumerable convention

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • None
    • 1.39.0
    • None

    Description

      If a query uses the ROW_NUMBER window aggregate function in Enumerable convention, Java code is generated that does not compile. The following patch is a test case.

      diff --git a/core/src/test/java/org/apache/calcite/test/JdbcTest.java b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
      index 68cd66114..1ef38e874 100644
      --- a/core/src/test/java/org/apache/calcite/test/JdbcTest.java
      +++ b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
      @@ -1296,6 +1296,13 @@ private void checkResultSetMetaData(Connection connection, String sql)
                   + "c0=1998\n");
         }
       
      +  @Test void testRowNumber() {
      +    CalciteAssert.that()
      +        .with(CalciteAssert.Config.JDBC_SCOTT)
      +        .query("select row_number() over () from dept")
      +        .returnsUnordered("1", "2");
      +  }
      +
         /** Test case for
          * <a href="https://issues.apache.org/jira/browse/CALCITE-2894">[CALCITE-2894]
          * NullPointerException thrown by RelMdPercentageOriginalRows when explaining
      

      Gives the following error:

      java.sql.SQLException: Error while executing SQL "select row_number() over () from dept": Error while compiling generated Java code:
      public org.apache.calcite.linq4j.Enumerable bind(final org.apache.calcite.DataContext root) {
        final org.apache.calcite.runtime.ResultSetEnumerable enumerable = org.apache.calcite.runtime.ResultSetEnumerable.of((javax.sql.DataSource) root.getRootSchema().getSubSchema("JDBC_SCOTT").unwrap(javax.sql.DataSource.class), "SELECT\nFROM \"SCOTT\".\"DEPT\"", new org.apache.calcite.linq4j.function.Function1() {
          public org.apache.calcite.linq4j.function.Function0 apply(final java.sql.ResultSet resultSet) {
            return new org.apache.calcite.linq4j.function.Function0() {
                public Object apply() {
                  try {
                    return new Object[0];
                  } catch (java.sql.SQLException e) {
                    throw new RuntimeException(
                      e);
                  }
                }
              }
            ;
          }
          public Object apply(final Object resultSet) {
            return apply(
              (java.sql.ResultSet) resultSet);
          }
        }
        );
        enumerable.setTimeout(root);
        int prevStart;
        int prevEnd;
        final java.util.Comparator comparator = new java.util.Comparator(){
          public int compare(org.apache.calcite.runtime.FlatLists.ComparableList v0, org.apache.calcite.runtime.FlatLists.ComparableList v1) {
            int c;
            return 0;
          }
      
          public int compare(Object o0, Object o1) {
            return this.compare((org.apache.calcite.runtime.FlatLists.ComparableList) o0, (org.apache.calcite.runtime.FlatLists.ComparableList) o1);
          }
      
        };
        final java.util.List _tempList = (java.util.List) enumerable.into(new java.util.ArrayList());
        final java.util.Iterator iterator = org.apache.calcite.runtime.SortedMultiMap.singletonArrayIterator(comparator, _tempList);
        final java.util.ArrayList _list = new java.util.ArrayList(
          _tempList.size());
        long a0w0 = 0L;
        while (iterator.hasNext()) {
          final Object[] _rows = (Object[]) iterator.next();
          prevStart = -1;
          prevEnd = 2147483647;
          for (int i = 0; i < _rows.length; (++i)) {
            if (i != prevEnd) {
              int actualStart = i < prevEnd ? 0 : prevEnd + 1;
              prevEnd = i;
              a0w0 = ((Number)org.apache.calcite.linq4j.tree.Primitive.of(long.class).numberValueRoundDown((i - 0 + 1))).longValue();
            }
            _list.add(a0w0);
          }
        }
        _tempList.clear();
        return org.apache.calcite.linq4j.Linq4j.asEnumerable(_list);
      }
      
      
      public Class getElementType() {
        return long.class;
      }
      

      The same error occurs if you replace 'over ()' with 'over (order by 1 nulls last)'.

      When this bug is fixed, enable code in RelToSqlConverterTest.testNoNeedRewriteOrderByConstantsForOver.

      Attachments

        Issue Links

          Activity

            People

              nobigo xiong duan
              julianhyde Julian Hyde
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: