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

dmsysolyatin 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 9b4eff06d6 [CALCITE-5532] CompositeOperandTypeChecker should check 
operands without type coercion first
9b4eff06d6 is described below

commit 9b4eff06d6a16b3013f01d5fe4bceeaff6822603
Author: Dmitry Sysolyatin <[email protected]>
AuthorDate: Thu Feb 16 17:02:04 2023 +0200

    [CALCITE-5532] CompositeOperandTypeChecker should check operands without 
type coercion first
---
 .../sql/type/CompositeOperandTypeChecker.java      | 10 ++++++++++
 .../apache/calcite/test/SqlToRelConverterTest.java | 11 +++++++++++
 .../apache/calcite/test/SqlToRelConverterTest.xml  | 11 +++++++++++
 .../apache/calcite/test/MockSqlOperatorTable.java  | 22 ++++++++++++++++++++++
 4 files changed, 54 insertions(+)

diff --git 
a/core/src/main/java/org/apache/calcite/sql/type/CompositeOperandTypeChecker.java
 
b/core/src/main/java/org/apache/calcite/sql/type/CompositeOperandTypeChecker.java
index a7cb4b2e04..e3a509bf57 100644
--- 
a/core/src/main/java/org/apache/calcite/sql/type/CompositeOperandTypeChecker.java
+++ 
b/core/src/main/java/org/apache/calcite/sql/type/CompositeOperandTypeChecker.java
@@ -383,7 +383,17 @@ public class CompositeOperandTypeChecker implements 
SqlOperandTypeChecker {
     if (!callBinding.isTypeCoercionEnabled()) {
       return false;
     }
+    SqlCallBinding sqlBindingWithoutTypeCoercion =
+        new SqlCallBinding(callBinding.getValidator(), callBinding.getScope(),
+            callBinding.getCall()) {
+          @Override public boolean isTypeCoercionEnabled() {
+            return false;
+          }
+        };
     for (SqlOperandTypeChecker rule : allowedRules) {
+      if (rule.checkOperandTypes(sqlBindingWithoutTypeCoercion, false)) {
+        return true;
+      }
       if (rule instanceof ImplicitCastOperandTypeChecker) {
         ImplicitCastOperandTypeChecker rule1 = 
(ImplicitCastOperandTypeChecker) rule;
         if (rule1.checkOperandTypesWithoutTypeCoercion(callBinding, false)) {
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 a568964de8..29dc091b64 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 package org.apache.calcite.test;
+
 import org.apache.calcite.config.CalciteConnectionConfigImpl;
 import org.apache.calcite.config.CalciteConnectionProperty;
 import org.apache.calcite.config.NullCollation;
@@ -1983,6 +1984,16 @@ class SqlToRelConverterTest extends SqlToRelTestBase {
     sql(sql).withExpand(false).ok();
   }
 
+  /**
+   * Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-5532";>[CALCITE-5532]
+   * CompositeOperandTypeChecker should check operands without type coercion 
first</a>.
+   */
+  @Test void testNoTypeCoercionForExactMatchInCompositeTypeChecker() {
+    String sql = "SELECT COMPARE_STRINGS_OR_NUMERIC_VALUES(1, 1)";
+    sql(sql).ok();
+  }
+
   @Test void testNotCaseInThreeClause() {
     final String sql = "select empno from emp where not case when "
         + "true then deptno in (10,20) else true end";
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 80ec5f83ad..2cc2aa6ca5 100644
--- a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
@@ -5183,6 +5183,17 @@ LogicalProject(SKILL=[ROW($0)])
   LogicalFilter(condition=[=($0, '')])
     LogicalProject(TYPE=[$0.TYPE])
       LogicalTableScan(table=[[CATALOG, SALES, DEPT_SINGLE]])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testNoTypeCoercionForExactMatchInCompositeTypeChecker">
+    <Resource name="sql">
+      <![CDATA[SELECT COMPARE_STRINGS_OR_NUMERIC_VALUES(1, 1)]]>
+    </Resource>
+    <Resource name="plan">
+      <![CDATA[
+LogicalProject(EXPR$0=[COMPARE_STRINGS_OR_NUMERIC_VALUES(1, 1)])
+  LogicalValues(tuples=[[{ 0 }]])
 ]]>
     </Resource>
   </TestCase>
diff --git 
a/testkit/src/main/java/org/apache/calcite/test/MockSqlOperatorTable.java 
b/testkit/src/main/java/org/apache/calcite/test/MockSqlOperatorTable.java
index 513d0f1086..2b65cde83d 100644
--- a/testkit/src/main/java/org/apache/calcite/test/MockSqlOperatorTable.java
+++ b/testkit/src/main/java/org/apache/calcite/test/MockSqlOperatorTable.java
@@ -99,6 +99,7 @@ public class MockSqlOperatorTable extends 
ChainedSqlOperatorTable {
                 new TopNTableFunction(),
                 new SimilarlityTableFunction(),
                 new InvalidTableFunction(),
+                new CompareStringsOrNumericValues(),
                 HIGHER_ORDER_FUNCTION,
                 HIGHER_ORDER_FUNCTION2)));
   }
@@ -627,6 +628,27 @@ public class MockSqlOperatorTable extends 
ChainedSqlOperatorTable {
     }
   }
 
+  /**
+   * "COMPARE_STRINGS_OR_NUMERIC_VALUES" is a user-defined function whose 
arguments can be either
+   * two strings or two numeric values of the same type.
+   */
+  public static class CompareStringsOrNumericValues extends SqlFunction {
+    public CompareStringsOrNumericValues() {
+      super("COMPARE_STRINGS_OR_NUMERIC_VALUES",
+          new SqlIdentifier("COMPARE_STRINGS_OR_NUMERIC_VALUES", 
SqlParserPos.ZERO),
+          SqlKind.OTHER_FUNCTION,
+          null,
+          null,
+          OperandTypes.STRING_SAME_SAME.or(
+              OperandTypes.NUMERIC_NUMERIC.and(OperandTypes.SAME_SAME)),
+          SqlFunctionCategory.USER_DEFINED_FUNCTION);
+    }
+
+    @Override public RelDataType inferReturnType(SqlOperatorBinding opBinding) 
{
+      return opBinding.getOperandType(0);
+    }
+  }
+
   private static final SqlFunction HIGHER_ORDER_FUNCTION =
       SqlBasicFunction.create("HIGHER_ORDER_FUNCTION",
           ReturnTypes.ARG0,

Reply via email to