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

rubenql 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 9a102e77dd [CALCITE-4897] Implicit type conversion is not complete for 
set operation in DML
9a102e77dd is described below

commit 9a102e77dd2f7b566b0a4a8cb0d504c6c572e1e1
Author: xiejiajun <jiajunbernou...@foxmail.com>
AuthorDate: Sat Nov 20 16:37:58 2021 +0800

    [CALCITE-4897] Implicit type conversion is not complete for set operation 
in DML
---
 .../sql/validate/implicit/TypeCoercionImpl.java        |  9 +++++++--
 .../apache/calcite/test/TypeCoercionConverterTest.java | 18 ++++++++++++++++++
 .../apache/calcite/test/TypeCoercionConverterTest.xml  | 17 +++++++++++++++++
 3 files changed, 42 insertions(+), 2 deletions(-)

diff --git 
a/core/src/main/java/org/apache/calcite/sql/validate/implicit/TypeCoercionImpl.java
 
b/core/src/main/java/org/apache/calcite/sql/validate/implicit/TypeCoercionImpl.java
index ce562a9a51..1dd383f8ca 100644
--- 
a/core/src/main/java/org/apache/calcite/sql/validate/implicit/TypeCoercionImpl.java
+++ 
b/core/src/main/java/org/apache/calcite/sql/validate/implicit/TypeCoercionImpl.java
@@ -121,8 +121,13 @@ public class TypeCoercionImpl extends AbstractTypeCoercion 
{
       // Set operations are binary for now.
       final SqlCall operand0 = ((SqlCall) query).operand(0);
       final SqlCall operand1 = ((SqlCall) query).operand(1);
-      final boolean coerced = rowTypeCoercion(scope, operand0, columnIndex, 
targetType)
-          && rowTypeCoercion(scope, operand1, columnIndex, targetType);
+      // Operand1 should be coerced even if operand0 not need to be coerced.
+      // For example, we have one table named t:
+      // INSERT INTO t -- only one column is c(int).
+      // SELECT 1 UNION   -- operand0 not need to be coerced.
+      // SELECT 1.0  -- operand1 should be coerced.
+      boolean coerced = rowTypeCoercion(scope, operand0, columnIndex, 
targetType);
+      coerced = rowTypeCoercion(scope, operand1, columnIndex, targetType) || 
coerced;
       // Update the nested SET operator node type.
       if (coerced) {
         updateInferredColumnType(
diff --git 
a/core/src/test/java/org/apache/calcite/test/TypeCoercionConverterTest.java 
b/core/src/test/java/org/apache/calcite/test/TypeCoercionConverterTest.java
index ac7fbb185e..31584f8dbe 100644
--- a/core/src/test/java/org/apache/calcite/test/TypeCoercionConverterTest.java
+++ b/core/src/test/java/org/apache/calcite/test/TypeCoercionConverterTest.java
@@ -126,6 +126,24 @@ class TypeCoercionConverterTest extends SqlToRelTestBase {
     sql(sql).ok();
   }
 
+  /** Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-4897";>[CALCITE-4897]
+   * Set operation in DML, implicit type conversion is not complete</a>. */
+  @Test void testInsertUnionQuerySourceCoercion() {
+    final String sql = "insert into t1 "
+        + "select 'a', 1, 1.0,"
+        + " 0, 0, 0, 0, TIMESTAMP '2021-11-28 00:00:00', date '2021-11-28', 
x'0A', false union "
+        + "select 'b', 2, 2,"
+        + " 0, 0, 0, 0, TIMESTAMP '2021-11-28 00:00:00', date '2021-11-28', 
x'0A', false union "
+        + "select 'c', CAST(3 AS SMALLINT), 3.0,"
+        + " 0, 0, 0, 0, TIMESTAMP '2021-11-28 00:00:00', date '2021-11-28', 
x'0A', false union "
+        + "select 'd', 4, 4.0,"
+        + " 0, 0, 0, 0, TIMESTAMP '2021-11-28 00:00:00', date '2021-11-28', 
x'0A', false union "
+        + "select 'e', 5, 5.0,"
+        + " 0, 0, 0, 0, TIMESTAMP '2021-11-28 00:00:00', date '2021-11-28', 
x'0A', false";
+    sql(sql).ok();
+  }
+
   @Test void testUpdateQuerySourceCoercion() {
     final String sql = "update t1 set t1_varchar20=123, "
         + "t1_date=TIMESTAMP '2020-01-03 10:14:34', t1_int=12.3";
diff --git 
a/core/src/test/resources/org/apache/calcite/test/TypeCoercionConverterTest.xml 
b/core/src/test/resources/org/apache/calcite/test/TypeCoercionConverterTest.xml
index 7e3fc66395..ad89bd778e 100644
--- 
a/core/src/test/resources/org/apache/calcite/test/TypeCoercionConverterTest.xml
+++ 
b/core/src/test/resources/org/apache/calcite/test/TypeCoercionConverterTest.xml
@@ -114,6 +114,23 @@ t2_double, t2_decimal, t2_int, t2_date, t2_timestamp, 
t2_varchar20, t2_int from
 LogicalTableModify(table=[[CATALOG, SALES, T1]], operation=[INSERT], 
flattened=[false])
   LogicalProject(t1_varchar20=[CAST($1):VARCHAR(20) NOT NULL], 
t1_smallint=[CAST($2):SMALLINT NOT NULL], t1_int=[CAST($3):INTEGER NOT NULL], 
t1_bigint=[CAST($4):BIGINT NOT NULL], t1_float=[CAST($5):FLOAT NOT NULL], 
t1_double=[CAST($6):DOUBLE NOT NULL], t1_decimal=[CAST($2):DECIMAL(19, 0) NOT 
NULL], t1_timestamp=[CAST($8):TIMESTAMP(0) NOT NULL], t1_date=[CAST($7):DATE 
NOT NULL], t1_binary=[CAST($0):BINARY(1) NOT NULL], t1_boolean=[<>($2, 0)])
     LogicalTableScan(table=[[CATALOG, SALES, T2]])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testInsertUnionQuerySourceCoercion">
+    <Resource name="sql">insert into t1 select 'a', 1, 1.0, 0, 0, 0, 0, 
TIMESTAMP '2021-11-28 00:00:00', date '2021-11-28', x'0A', false union select 
'b', 2, 2, 0, 0, 0, 0, TIMESTAMP '2021-11-28 00:00:00', date '2021-11-28', 
x'0A', false union select 'c', CAST(3 AS SMALLINT), 3.0, 0, 0, 0, 0, TIMESTAMP 
'2021-11-28 00:00:00', date '2021-11-28', x'0A', false union select 'd', 4, 
4.0, 0, 0, 0, 0, TIMESTAMP '2021-11-28 00:00:00', date '2021-11-28', x'0A', 
false union select 'e', 5, 5.0, 0, 0 [...]
+    <Resource name="plan">
+      <![CDATA[
+LogicalTableModify(table=[[CATALOG, SALES, T1]], operation=[INSERT], 
flattened=[false])
+  LogicalUnion(all=[false])
+    LogicalUnion(all=[false])
+      LogicalUnion(all=[false])
+        LogicalUnion(all=[false])
+          LogicalValues(tuples=[[{ 'a', 1, 1, 0, 0, 0, 0, 2021-11-28 00:00:00, 
2021-11-28, X'0a', false }]])
+          LogicalValues(tuples=[[{ 'b', 2, 2, 0, 0, 0, 0, 2021-11-28 00:00:00, 
2021-11-28, X'0a', false }]])
+        LogicalValues(tuples=[[{ 'c', 3, 3, 0, 0, 0, 0, 2021-11-28 00:00:00, 
2021-11-28, X'0a', false }]])
+      LogicalValues(tuples=[[{ 'd', 4, 4, 0, 0, 0, 0, 2021-11-28 00:00:00, 
2021-11-28, X'0a', false }]])
+    LogicalValues(tuples=[[{ 'e', 5, 5, 0, 0, 0, 0, 2021-11-28 00:00:00, 
2021-11-28, X'0a', false }]])
 ]]>
     </Resource>
   </TestCase>

Reply via email to