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 <[email protected]>
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>