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>