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

libenchao 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 c83ac69111 [CALCITE-6040] The operand type inference of 
SqlMapValueConstructor is incorrect
c83ac69111 is described below

commit c83ac69111fd9e75af5e3615af29a72284667a4a
Author: Ran Tao <[email protected]>
AuthorDate: Thu Oct 12 16:19:27 2023 +0800

    [CALCITE-6040] The operand type inference of SqlMapValueConstructor is 
incorrect
---
 .../calcite/sql/fun/SqlMapValueConstructor.java     |  3 ++-
 .../sql/fun/SqlMultisetValueConstructor.java        |  9 ++++++++-
 core/src/test/resources/sql/misc.iq                 | 16 ++++++++++++++++
 .../org/apache/calcite/test/SqlOperatorTest.java    | 21 +++++++++++++++++++++
 4 files changed, 47 insertions(+), 2 deletions(-)

diff --git 
a/core/src/main/java/org/apache/calcite/sql/fun/SqlMapValueConstructor.java 
b/core/src/main/java/org/apache/calcite/sql/fun/SqlMapValueConstructor.java
index 7f3da3bdb2..a497471200 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlMapValueConstructor.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlMapValueConstructor.java
@@ -42,7 +42,8 @@ import static java.util.Objects.requireNonNull;
  */
 public class SqlMapValueConstructor extends SqlMultisetValueConstructor {
   public SqlMapValueConstructor() {
-    super("MAP", SqlKind.MAP_VALUE_CONSTRUCTOR);
+    // no need to deduce NULL operand type
+    super("MAP", SqlKind.MAP_VALUE_CONSTRUCTOR, null);
   }
 
   @SuppressWarnings("argument.type.incompatible")
diff --git 
a/core/src/main/java/org/apache/calcite/sql/fun/SqlMultisetValueConstructor.java
 
b/core/src/main/java/org/apache/calcite/sql/fun/SqlMultisetValueConstructor.java
index 8efd45a3eb..acbafc97e0 100644
--- 
a/core/src/main/java/org/apache/calcite/sql/fun/SqlMultisetValueConstructor.java
+++ 
b/core/src/main/java/org/apache/calcite/sql/fun/SqlMultisetValueConstructor.java
@@ -28,6 +28,7 @@ import org.apache.calcite.sql.SqlWriter;
 import org.apache.calcite.sql.type.InferTypes;
 import org.apache.calcite.sql.type.OperandTypes;
 import org.apache.calcite.sql.type.ReturnTypes;
+import org.apache.calcite.sql.type.SqlOperandTypeInference;
 import org.apache.calcite.sql.type.SqlTypeUtil;
 
 import org.checkerframework.checker.nullness.qual.Nullable;
@@ -54,12 +55,18 @@ public class SqlMultisetValueConstructor extends 
SqlSpecialOperator {
   }
 
   protected SqlMultisetValueConstructor(String name, SqlKind kind) {
+    this(name, kind, InferTypes.FIRST_KNOWN);
+  }
+
+  protected SqlMultisetValueConstructor(
+      String name, SqlKind kind,
+      @Nullable SqlOperandTypeInference operandTypeInference) {
     super(
         name,
         kind, MDX_PRECEDENCE,
         false,
         ReturnTypes.ARG0,
-        InferTypes.FIRST_KNOWN,
+        operandTypeInference,
         OperandTypes.VARIADIC);
   }
 
diff --git a/core/src/test/resources/sql/misc.iq 
b/core/src/test/resources/sql/misc.iq
index 8bdb345b22..74ee82abb8 100644
--- a/core/src/test/resources/sql/misc.iq
+++ b/core/src/test/resources/sql/misc.iq
@@ -2602,4 +2602,20 @@ FROM (
 (1 row)
 
 !ok
+
+# [CALCITE-6040] The operand type inference of SqlMapValueConstructor is 
incorrect
+SELECT
+  map['foo', null],
+  map[null, 'foo'],
+  map[1, 'foo', 2, null],
+  map[1, null, 2, 'foo'];
++------------+------------+-----------------+-----------------+
+| EXPR$0     | EXPR$1     | EXPR$2          | EXPR$3          |
++------------+------------+-----------------+-----------------+
+| {foo=null} | {null=foo} | {1=foo, 2=null} | {1=null, 2=foo} |
++------------+------------+-----------------+-----------------+
+(1 row)
+
+!ok
+
 # End misc.iq
diff --git a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java 
b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
index fd11a31f05..bfc14daab7 100644
--- a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
+++ b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
@@ -10442,6 +10442,27 @@ public class SqlOperatorTest {
     f.checkScalar("map['washington', 1, 'obama', 44]",
         "{washington=1, obama     =44}",
         "(CHAR(10) NOT NULL, INTEGER NOT NULL) MAP NOT NULL");
+
+    // check null key or null value
+    f.checkScalar("map['foo', null]",
+        "{foo=null}",
+        "(CHAR(3) NOT NULL, NULL) MAP NOT NULL");
+    f.checkScalar("map[null, 'foo']",
+        "{null=foo}",
+        "(NULL, CHAR(3) NOT NULL) MAP NOT NULL");
+    f.checkScalar("map[1, 'foo', 2, null]",
+        "{1=foo, 2=null}",
+        "(INTEGER NOT NULL, CHAR(3)) MAP NOT NULL");
+    f.checkScalar("map[1, null, 2, 'foo']",
+        "{1=null, 2=foo}",
+        "(INTEGER NOT NULL, CHAR(3)) MAP NOT NULL");
+    f.checkScalar("map[1, null, 2, null]",
+        "{1=null, 2=null}",
+        "(INTEGER NOT NULL, NULL) MAP NOT NULL");
+    f.checkScalar("map[null, 1, null, 2]",
+        "{null=2}",
+        "(NULL, INTEGER NOT NULL) MAP NOT NULL");
+
     // elements cast
     f.checkScalar("map['A', 1, 'ABC', 2]", "{A  =1, ABC=2}",
         "(CHAR(3) NOT NULL, INTEGER NOT NULL) MAP NOT NULL");

Reply via email to