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

mbudiu 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 de39888754 [CALCITE-6208] Update JSON_VALUE return type inference to 
make explicit array return types be nullable with nullable elements
de39888754 is described below

commit de39888754759d3e6b7ce35770fcff3d8d0e6a4c
Author: Clint Wylie <[email protected]>
AuthorDate: Wed Jan 17 00:30:19 2024 -0800

    [CALCITE-6208] Update JSON_VALUE return type inference to make explicit 
array return types be nullable with nullable elements
---
 .../calcite/sql/fun/SqlJsonValueFunction.java      | 24 ++++++++++++++++------
 .../org/apache/calcite/test/SqlValidatorTest.java  |  8 ++++++++
 2 files changed, 26 insertions(+), 6 deletions(-)

diff --git 
a/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonValueFunction.java 
b/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonValueFunction.java
index 5cc542bb49..84bc1bad68 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonValueFunction.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonValueFunction.java
@@ -30,11 +30,10 @@ import org.apache.calcite.sql.SqlOperandCountRange;
 import org.apache.calcite.sql.SqlOperatorBinding;
 import org.apache.calcite.sql.SqlWriter;
 import org.apache.calcite.sql.type.OperandTypes;
-import org.apache.calcite.sql.type.ReturnTypes;
 import org.apache.calcite.sql.type.SqlOperandCountRanges;
 import org.apache.calcite.sql.type.SqlTypeFamily;
 import org.apache.calcite.sql.type.SqlTypeName;
-import org.apache.calcite.sql.type.SqlTypeTransforms;
+import org.apache.calcite.sql.type.SqlTypeUtil;
 
 import com.google.common.collect.ImmutableList;
 
@@ -54,9 +53,9 @@ public class SqlJsonValueFunction extends SqlFunction {
 
   public SqlJsonValueFunction(String name) {
     super(name, SqlKind.OTHER_FUNCTION,
-        ReturnTypes.cascade(
-            opBinding -> 
explicitTypeSpec(opBinding).orElse(getDefaultType(opBinding)),
-            SqlTypeTransforms.FORCE_NULLABLE),
+        opBinding -> explicitTypeSpec(opBinding)
+            .map(relDataType -> deriveExplicitType(opBinding, relDataType))
+            .orElseGet(() -> getDefaultType(opBinding)),
         null,
         OperandTypes.family(
             ImmutableList.of(SqlTypeFamily.ANY, SqlTypeFamily.CHARACTER),
@@ -64,10 +63,23 @@ public class SqlJsonValueFunction extends SqlFunction {
         SqlFunctionCategory.SYSTEM);
   }
 
+  private static RelDataType deriveExplicitType(SqlOperatorBinding opBinding, 
RelDataType type) {
+    if (SqlTypeName.ARRAY == type.getSqlTypeName()) {
+      RelDataType elementType = 
Objects.requireNonNull(type.getComponentType());
+      RelDataType nullableElementType = deriveExplicitType(opBinding, 
elementType);
+      return SqlTypeUtil.createArrayType(
+          opBinding.getTypeFactory(),
+          nullableElementType,
+          true);
+    }
+    return opBinding.getTypeFactory().createTypeWithNullability(type, true);
+  }
+
   /** Returns VARCHAR(2000) as default. */
   private static RelDataType getDefaultType(SqlOperatorBinding opBinding) {
     final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
-    return typeFactory.createSqlType(SqlTypeName.VARCHAR, 2000);
+    final RelDataType baseType = 
typeFactory.createSqlType(SqlTypeName.VARCHAR, 2000);
+    return typeFactory.createTypeWithNullability(baseType, true);
   }
 
   /**
diff --git a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java 
b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
index fff0fc26e2..8fead2ce72 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
@@ -11417,6 +11417,14 @@ public class SqlValidatorTest extends 
SqlValidatorTestCase {
     expr("json_value('{\"foo\":100}', 'lax $.foo' returning boolean"
         + " default 100 on empty)")
         .columnType("BOOLEAN");
+
+    expr("json_value('{\"foo\":[100, null, 200]}', 'lax $.foo'"
+        + "returning integer array)")
+        .columnType("INTEGER ARRAY");
+
+    expr("json_value('{\"foo\":[[100, null, 200]]}', 'lax $.foo'"
+        + "returning integer array array)")
+        .columnType("INTEGER ARRAY ARRAY");
   }
 
   @Test void testJsonQuery() {

Reply via email to