You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by da...@apache.org on 2019/10/23 11:39:17 UTC

[calcite] branch master updated: [CALCITE-3424] AssertionError thrown for user-defined table function with array argument (Igor Guzenko)

This is an automated email from the ASF dual-hosted git repository.

danny0405 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git


The following commit(s) were added to refs/heads/master by this push:
     new 8ba2d85  [CALCITE-3424] AssertionError thrown for user-defined table function with array argument (Igor Guzenko)
8ba2d85 is described below

commit 8ba2d8512b8f195bb0866af12308beef2b3eed9f
Author: Igor Guzenko <ih...@gmail.com>
AuthorDate: Fri Oct 18 12:11:33 2019 +0300

    [CALCITE-3424] AssertionError thrown for user-defined table function with array argument (Igor Guzenko)
    
    close apache/calcite#1519
---
 .../org/apache/calcite/jdbc/JavaTypeFactoryImpl.java   | 18 +++++++++++++++---
 .../org/apache/calcite/test/TableFunctionTest.java     | 18 ++++++++++++++++++
 core/src/test/java/org/apache/calcite/util/Smalls.java |  6 ++++++
 3 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/core/src/main/java/org/apache/calcite/jdbc/JavaTypeFactoryImpl.java b/core/src/main/java/org/apache/calcite/jdbc/JavaTypeFactoryImpl.java
index 7143c6b..3c6c900 100644
--- a/core/src/main/java/org/apache/calcite/jdbc/JavaTypeFactoryImpl.java
+++ b/core/src/main/java/org/apache/calcite/jdbc/JavaTypeFactoryImpl.java
@@ -34,6 +34,7 @@ import org.apache.calcite.sql.type.IntervalSqlType;
 import org.apache.calcite.sql.type.JavaToSqlTypeConversionRules;
 import org.apache.calcite.sql.type.SqlTypeFactoryImpl;
 import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.calcite.sql.type.SqlTypeUtil;
 import org.apache.calcite.util.Pair;
 import org.apache.calcite.util.Util;
 
@@ -251,9 +252,20 @@ public class JavaTypeFactoryImpl
               type.getFieldNames()),
           type.isNullable());
     } else if (type instanceof JavaType) {
-      return typeFactory.createTypeWithNullability(
-          typeFactory.createSqlType(type.getSqlTypeName()),
-          type.isNullable());
+      SqlTypeName sqlTypeName = type.getSqlTypeName();
+      final RelDataType relDataType;
+      if (SqlTypeUtil.isArray(type)) {
+        final RelDataType elementType = type.getComponentType() == null
+                // type.getJavaClass() is collection with erased generic type
+                ? typeFactory.createSqlType(SqlTypeName.ANY)
+                // elementType returned by JavaType is also of JavaType,
+                // and needs conversion using typeFactory
+                : toSql(typeFactory, type.getComponentType());
+        relDataType = typeFactory.createArrayType(elementType, -1);
+      } else {
+        relDataType = typeFactory.createSqlType(sqlTypeName);
+      }
+      return typeFactory.createTypeWithNullability(relDataType, type.isNullable());
     }
     return type;
   }
diff --git a/core/src/test/java/org/apache/calcite/test/TableFunctionTest.java b/core/src/test/java/org/apache/calcite/test/TableFunctionTest.java
index e9d1f75..fff7486 100644
--- a/core/src/test/java/org/apache/calcite/test/TableFunctionTest.java
+++ b/core/src/test/java/org/apache/calcite/test/TableFunctionTest.java
@@ -105,6 +105,24 @@ public class TableFunctionTest {
     }
   }
 
+  @Test public void testTableFunctionWithArrayParameter() throws SQLException {
+    try (Connection connection = DriverManager.getConnection("jdbc:calcite:")) {
+      CalciteConnection calciteConnection =
+          connection.unwrap(CalciteConnection.class);
+      SchemaPlus rootSchema = calciteConnection.getRootSchema();
+      SchemaPlus schema = rootSchema.add("s", new AbstractSchema());
+      final TableFunction table =
+          TableFunctionImpl.create(Smalls.GENERATE_STRINGS_OF_INPUT_SIZE_METHOD);
+      schema.add("GenerateStringsOfInputSize", table);
+      final String sql = "select *\n"
+          + "from table(\"s\".\"GenerateStringsOfInputSize\"(ARRAY[5,4,3,1,2])) as t(n, c)\n"
+          + "where char_length(c) > 3";
+      ResultSet resultSet = connection.createStatement().executeQuery(sql);
+      assertThat(CalciteAssert.toString(resultSet),
+          equalTo("N=4; C=abcd\n"));
+    }
+  }
+
   /**
    * Tests a table function that implements {@link ScannableTable} and returns
    * a single column.
diff --git a/core/src/test/java/org/apache/calcite/util/Smalls.java b/core/src/test/java/org/apache/calcite/util/Smalls.java
index 9c437e2..270fd24 100644
--- a/core/src/test/java/org/apache/calcite/util/Smalls.java
+++ b/core/src/test/java/org/apache/calcite/util/Smalls.java
@@ -72,6 +72,8 @@ import static org.junit.Assert.assertThat;
 public class Smalls {
   public static final Method GENERATE_STRINGS_METHOD =
       Types.lookupMethod(Smalls.class, "generateStrings", Integer.class);
+  public static final Method GENERATE_STRINGS_OF_INPUT_SIZE_METHOD =
+      Types.lookupMethod(Smalls.class, "generateStringsOfInputSize", List.class);
   public static final Method MAZE_METHOD =
       Types.lookupMethod(MazeTable.class, "generate", int.class, int.class,
           int.class);
@@ -182,6 +184,10 @@ public class Smalls {
     };
   }
 
+  public static QueryableTable generateStringsOfInputSize(final List<Integer> list) {
+    return generateStrings(list.size());
+  }
+
   /** A function that generates multiplication table of {@code ncol} columns x
    * {@code nrow} rows. */
   public static QueryableTable multiplicationTable(final int ncol,