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

zabetak 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 ed36338148 [CALCITE-6885] SqlToRelConverter#convertUsing should not 
fail if commonTypeForBinaryComparison returns null
ed36338148 is described below

commit ed36338148810497cd6fcaf9ddcd3812ee94a3d9
Author: Ruben Quesada Lopez <[email protected]>
AuthorDate: Wed Mar 12 10:34:19 2025 +0000

    [CALCITE-6885] SqlToRelConverter#convertUsing should not fail if 
commonTypeForBinaryComparison returns null
---
 .../apache/calcite/sql2rel/SqlToRelConverter.java  | 27 ++++++++++----------
 .../apache/calcite/test/SqlToRelConverterTest.java | 29 ++++++++++++++++++++++
 .../apache/calcite/test/SqlToRelConverterTest.xml  | 14 +++++++++++
 3 files changed, 56 insertions(+), 14 deletions(-)

diff --git 
a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java 
b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
index 52a1cfc46d..9033322110 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
@@ -3458,22 +3458,21 @@ private RexNode convertUsing(SqlValidatorNamespace 
leftNamespace,
           validator().getTypeCoercion().commonTypeForBinaryComparison(
               comparedTypes.get(0), comparedTypes.get(1));
       if (resultType == null) {
-        // This should never happen, since the program has been validated.
-        throw new IllegalArgumentException("Cannot join on field `" + name
-            + "` because the types are not comparable: " + comparedTypes);
-      }
-
-      List<RexNode> castedOperands = new ArrayList<>();
-      for (int i = 0; i < operands.size(); i++) {
-        RexNode operand = operands.get(i);
-        RelDataType fieldType = comparedTypes.get(i);
-        RexNode expr = operand;
-        if (!fieldType.equals(resultType)) {
-          expr = rexBuilder.makeCast(resultType, operand, true, false);
+        // Leave call unchanged (as it happens in 
TypeCoercionImpl#binaryComparisonCoercion)
+        list.add(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, operands));
+      } else {
+        List<RexNode> castedOperands = new ArrayList<>();
+        for (int i = 0; i < operands.size(); i++) {
+          RexNode operand = operands.get(i);
+          RelDataType fieldType = comparedTypes.get(i);
+          RexNode expr = operand;
+          if (!fieldType.equals(resultType)) {
+            expr = rexBuilder.makeCast(resultType, operand, true, false);
+          }
+          castedOperands.add(expr);
         }
-        castedOperands.add(expr);
+        list.add(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, 
castedOperands));
       }
-      list.add(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, 
castedOperands));
     }
     return RexUtil.composeConjunction(rexBuilder, list);
   }
diff --git 
a/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java 
b/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
index 2fc6ec0d36..8ca7344fae 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
@@ -38,6 +38,7 @@
 import org.apache.calcite.rel.logical.LogicalSort;
 import org.apache.calcite.rel.logical.LogicalTableModify;
 import org.apache.calcite.rel.rules.CoreRules;
+import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.sql.SqlExplainLevel;
 import org.apache.calcite.sql.fun.SqlLibrary;
@@ -46,6 +47,7 @@
 import org.apache.calcite.sql.validate.SqlConformanceEnum;
 import org.apache.calcite.sql.validate.SqlDelegatingConformance;
 import org.apache.calcite.sql.validate.SqlValidatorUtil;
+import org.apache.calcite.sql.validate.implicit.TypeCoercionImpl;
 import org.apache.calcite.test.catalog.MockCatalogReaderExtended;
 import org.apache.calcite.util.Bug;
 import org.apache.calcite.util.TestUtil;
@@ -4916,6 +4918,33 @@ void checkUserDefinedOrderByOver(NullCollation 
nullCollation) {
     sql(sql).ok();
   }
 
+  /** Test case for <a 
href="https://issues.apache.org/jira/browse/CALCITE-6885";>[CALCITE-6885]
+   * SqlToRelConverter#convertUsing should not fail if 
commonTypeForBinaryComparison
+   * returns null</a>. */
+  @Test void testNaturalJoinCastNoCoercion() {
+    final String sql = "WITH t1(x) AS (VALUES('x')), t2(x) AS (VALUES(0.0))\n"
+        + "SELECT * FROM t1 NATURAL JOIN t2";
+    sql(sql)
+        // Default factory, except for the TypeCoercion
+        .withFactory(f ->
+            f
+                .withValidator((opTab, catalogReader, typeFactory, config) ->
+                    SqlValidatorUtil.newValidator(opTab, catalogReader, 
typeFactory,
+                        config.withIdentifierExpansion(true)
+                            // Ad-hoc coercion that returns null for 
commonTypeForBinaryComparison
+                            .withTypeCoercionFactory((t, v) -> new 
TypeCoercionImpl(t, v) {
+                              @Override public @Nullable RelDataType 
commonTypeForBinaryComparison(
+                                  @Nullable RelDataType type1, @Nullable 
RelDataType type2) {
+                                return null;
+                              }
+                            })))
+                .withSqlToRelConfig(c ->
+                    c.withTrimUnusedFields(true).withExpand(true)
+                        .addRelBuilderConfigTransform(b ->
+                            
b.withAggregateUnique(true).withPruneInputOfAggregate(false))))
+        .ok();
+  }
+
   /** Tests LEFT JOIN LATERAL with multiple columns from outer. */
   @Test void testLeftJoinLateral4() {
     final String sql = "select * from (values (4,5)) as t(c,d)\n"
diff --git 
a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml 
b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
index 07a33d50f8..5229782822 100644
--- a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
@@ -5088,6 +5088,20 @@ LogicalProject(X=[CAST($0):DECIMAL(2, 1) NOT NULL])
       LogicalValues(tuples=[[{ 'x' }]])
     LogicalProject(EXPR$0=[$0], EXPR$00=[CAST($0):DECIMAL(19, 9) NOT NULL])
       LogicalValues(tuples=[[{ 0.0 }]])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testNaturalJoinCastNoCoercion">
+    <Resource name="sql">
+      <![CDATA[WITH t1(x) AS (VALUES('x')), t2(x) AS (VALUES(0.0))
+SELECT * FROM t1 NATURAL JOIN t2]]>
+    </Resource>
+    <Resource name="plan">
+      <![CDATA[
+LogicalProject(X=[CAST($0):DECIMAL(2, 1) NOT NULL])
+  LogicalJoin(condition=[=($0, $1)], joinType=[inner])
+    LogicalValues(tuples=[[{ 'x' }]])
+    LogicalValues(tuples=[[{ 0.0 }]])
 ]]>
     </Resource>
   </TestCase>

Reply via email to