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

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


The following commit(s) were added to refs/heads/main by this push:
     new c330aa30fd [CALCITE-5407] MongoDB adapter throws NullPointerException 
when converting an array
c330aa30fd is described below

commit c330aa30fde760eba9086a4b7b1e88b87a5f478b
Author: Tim Nieradzik <[email protected]>
AuthorDate: Wed Nov 30 11:50:31 2022 +0300

    [CALCITE-5407] MongoDB adapter throws NullPointerException when converting 
an array
    
    The following conversion does not work as expected:
    
    ```
    cast(_MAP['arr'] as VARCHAR ARRAY)
    ```
    
    This throws the following exception:
    
    ```
    Caused by: java.lang.NullPointerException: componentType of ITEM($0, 'arr')
        at java.base/java.util.Objects.requireNonNull(Objects.java:347)
        at 
org.apache.calcite.sql2rel.StandardConvertletTable.convertCast(StandardConvertletTable.java:603)
        at 
org.apache.calcite.sql2rel.SqlNodeToRexConverterImpl.convertCall(SqlNodeToRexConverterImpl.java:59)
        at 
org.apache.calcite.sql2rel.SqlToRelConverter$Blackboard.visit(SqlToRelConverter.java:5547)
        at 
org.apache.calcite.sql2rel.SqlToRelConverter$Blackboard.visit(SqlToRelConverter.java:4711)
        at org.apache.calcite.sql.SqlCall.accept(SqlCall.java:161)
        at 
org.apache.calcite.sql2rel.SqlToRelConverter$Blackboard.convertExpression(SqlToRelConverter.java:5360)
        at 
org.apache.calcite.sql2rel.SqlToRelConverter.convertSelectList(SqlToRelConverter.java:4524)
        at 
org.apache.calcite.sql2rel.SqlToRelConverter.convertSelectImpl(SqlToRelConverter.java:756)
        at 
org.apache.calcite.sql2rel.SqlToRelConverter.convertSelect(SqlToRelConverter.java:677)
        at 
org.apache.calcite.sql2rel.SqlToRelConverter.convertQueryRecursive(SqlToRelConverter.java:3741)
        at 
org.apache.calcite.sql2rel.SqlToRelConverter.convertQuery(SqlToRelConverter.java:597)
        at org.apache.calcite.prepare.Prepare.prepareSql(Prepare.java:257)
        at org.apache.calcite.prepare.Prepare.prepareSql(Prepare.java:220)
        at 
org.apache.calcite.prepare.CalcitePrepareImpl.prepare2_(CalcitePrepareImpl.java:651)
        at 
org.apache.calcite.prepare.CalcitePrepareImpl.prepare_(CalcitePrepareImpl.java:517)
        at 
org.apache.calcite.prepare.CalcitePrepareImpl.prepareSql(CalcitePrepareImpl.java:487)
        at 
org.apache.calcite.jdbc.CalciteConnectionImpl.parseQuery(CalciteConnectionImpl.java:236)
        at 
org.apache.calcite.jdbc.CalciteMetaImpl.prepareAndExecute(CalciteMetaImpl.java:623)
        at 
org.apache.calcite.avatica.AvaticaConnection.prepareAndExecuteInternal(AvaticaConnection.java:677)
        at 
org.apache.calcite.avatica.AvaticaStatement.executeInternal(AvaticaStatement.java:156)
        ... 67 more
    ```
---
 .../calcite/sql2rel/StandardConvertletTable.java   | 12 +++++++----
 .../calcite/adapter/mongodb/MongoAdapterTest.java  | 25 ++++++++++++++++++++++
 2 files changed, 33 insertions(+), 4 deletions(-)

diff --git 
a/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java 
b/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
index c6c2dfa098..cdf840c2d5 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
@@ -603,10 +603,14 @@ public class StandardConvertletTable extends 
ReflectiveConvertletTable {
       return cx.convertExpression(left);
     }
     if (null != dataType.getCollectionsTypeName()) {
-      final RelDataType argComponentType =
-          requireNonNull(
-              arg.getType().getComponentType(),
-              () -> "componentType of " + arg);
+      RelDataType argComponentType = arg.getType().getComponentType();
+
+      // arg.getType() may be ANY
+      if (argComponentType == null) {
+        argComponentType = 
dataType.getComponentTypeSpec().deriveType(cx.getValidator());
+      }
+
+      requireNonNull(argComponentType, () -> "componentType of " + arg);
 
       RelDataType typeFinal = type;
       final RelDataType componentType = requireNonNull(
diff --git 
a/mongodb/src/test/java/org/apache/calcite/adapter/mongodb/MongoAdapterTest.java
 
b/mongodb/src/test/java/org/apache/calcite/adapter/mongodb/MongoAdapterTest.java
index a9aa191fa6..d2e589985b 100644
--- 
a/mongodb/src/test/java/org/apache/calcite/adapter/mongodb/MongoAdapterTest.java
+++ 
b/mongodb/src/test/java/org/apache/calcite/adapter/mongodb/MongoAdapterTest.java
@@ -32,6 +32,7 @@ import com.mongodb.client.MongoDatabase;
 
 import net.hydromatic.foodmart.data.json.FoodmartJson;
 
+import org.bson.BsonArray;
 import org.bson.BsonDateTime;
 import org.bson.BsonDocument;
 import org.bson.BsonInt32;
@@ -107,6 +108,7 @@ public class MongoAdapterTest implements SchemaFactory {
     doc.put("date", new BsonDateTime(instant.toEpochMilli()));
     doc.put("value", new BsonInt32(1231));
     doc.put("ownerId", new BsonString("531e7789e4b0853ddb861313"));
+    doc.put("arr", new BsonArray(Arrays.asList(new BsonString("a"), new 
BsonString("b"))));
     datatypes.insertOne(doc);
 
     schema = new MongoSchema(database);
@@ -731,6 +733,29 @@ public class MongoAdapterTest implements SchemaFactory {
         .returnsUnordered("EXPR$0=2012-09-05 00:00:00");
   }
 
+  /** Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-5407";>[CALCITE-5407]
+   * Error casting MongoDB array to VARCHAR ARRAY</a>. */
+  @Test void testArrayConversion() {
+    assertModel("{\n"
+        + "  version: '1.0',\n"
+        + "  defaultSchema: 'test',\n"
+        + "   schemas: [\n"
+        + "     {\n"
+        + "       type: 'custom',\n"
+        + "       name: 'test',\n"
+        + "       factory: 
'org.apache.calcite.adapter.mongodb.MongoSchemaFactory',\n"
+        + "       operand: {\n"
+        + "         host: 'localhost',\n"
+        + "         database: 'test'\n"
+        + "       }\n"
+        + "     }\n"
+        + "   ]\n"
+        + "}")
+        .query("select cast(_MAP['arr'] as VARCHAR ARRAY) from \"datatypes\"")
+        .returnsUnordered("EXPR$0=[a, b]");
+  }
+
   /** Test case for
    * <a href="https://issues.apache.org/jira/browse/CALCITE-665";>[CALCITE-665]
    * ClassCastException in MongoDB adapter</a>. */

Reply via email to