You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by li...@apache.org on 2022/11/16 01:13:49 UTC

[calcite] 02/02: [CALCITE-5310] JSON_OBJECT in scalar sub-query throws AssertionError

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

commit a0ce3275119f804959cda54d6e7a016ab893c359
Author: Benchao Li <li...@gmail.com>
AuthorDate: Thu Oct 6 15:43:51 2022 +0800

    [CALCITE-5310] JSON_OBJECT in scalar sub-query throws AssertionError
    
    Close #2929
---
 core/src/main/java/org/apache/calcite/rex/RexUtil.java     | 14 ++++++++++++++
 .../org/apache/calcite/sql/type/SqlTypeAssignmentRule.java |  3 +++
 .../java/org/apache/calcite/sql2rel/RelDecorrelator.java   |  5 +++--
 core/src/test/resources/sql/sub-query.iq                   | 14 ++++++++++++++
 4 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/core/src/main/java/org/apache/calcite/rex/RexUtil.java b/core/src/main/java/org/apache/calcite/rex/RexUtil.java
index d5b4bc3cc7..b68eb43831 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexUtil.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexUtil.java
@@ -209,6 +209,20 @@ public class RexUtil {
     }
   }
 
+  /**
+   * Returns whether a node represents a {@link SqlTypeName#SYMBOL} literal.
+   */
+  public static boolean isSymbolLiteral(RexNode expr) {
+    switch (expr.getKind()) {
+    case LITERAL:
+      return ((RexLiteral) expr).getTypeName() == SqlTypeName.SYMBOL;
+    case CAST:
+      return isSymbolLiteral(((RexCall) expr).operands.get(0));
+    default:
+      return false;
+    }
+  }
+
   /**
    * Returns whether a node represents a literal.
    *
diff --git a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeAssignmentRule.java b/core/src/main/java/org/apache/calcite/sql/type/SqlTypeAssignmentRule.java
index 41791da14f..6504814355 100644
--- a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeAssignmentRule.java
+++ b/core/src/main/java/org/apache/calcite/sql/type/SqlTypeAssignmentRule.java
@@ -193,6 +193,9 @@ public class SqlTypeAssignmentRule implements SqlTypeMappingRule {
     // MAP is assignable from ...
     rules.add(SqlTypeName.MAP, EnumSet.of(SqlTypeName.MAP));
 
+    // SYMBOL is assignable from ...
+    rules.add(SqlTypeName.SYMBOL, EnumSet.of(SqlTypeName.SYMBOL));
+
     // ANY is assignable from ...
     rule.clear();
     rule.add(SqlTypeName.TINYINT);
diff --git a/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java b/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java
index 1786ffcaa1..7e7f2036ad 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java
@@ -1790,10 +1790,11 @@ public class RelDecorrelator implements ReflectiveVisitor {
 
     @Override public RexNode visitLiteral(RexLiteral literal) {
       // Use nullIndicator to decide whether to project null.
-      // Do nothing if the literal is null.
+      // Do nothing if the literal is null or symbol.
       if (!RexUtil.isNull(literal)
           && projectPulledAboveLeftCorrelator
-          && (nullIndicator != null)) {
+          && (nullIndicator != null)
+          && !RexUtil.isSymbolLiteral(literal)) {
         return createCaseExpression(nullIndicator, null, literal);
       }
       return literal;
diff --git a/core/src/test/resources/sql/sub-query.iq b/core/src/test/resources/sql/sub-query.iq
index a22ee003f9..e464dba2e5 100644
--- a/core/src/test/resources/sql/sub-query.iq
+++ b/core/src/test/resources/sql/sub-query.iq
@@ -3569,4 +3569,18 @@ SELECT ARRAY(SELECT s.x) FROM (SELECT 1 as x) s;
 
 !ok
 
+# Test case for [CALCITE-5310] JSON_OBJECT in scalar sub-query throws AssertionError
+SELECT (SELECT json_object('1': (a.attidentity = 'a'), '2': v) FROM UNNEST(ARRAY[1]) as v) as options
+FROM UNNEST(ARRAY['a', 'b']) AS a(attidentity);
+
++-------------------+
+| OPTIONS           |
++-------------------+
+| {"1":false,"2":1} |
+| {"1":true,"2":1}  |
++-------------------+
+(2 rows)
+
+!ok
+
 # End sub-query.iq