[
https://issues.apache.org/jira/browse/IGNITE-20835?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Pavel Pereslegin updated IGNITE-20835:
--------------------------------------
Description:
Update statements incorrectly use scalar subqueries in target columns, the
issues stems from the fact that scalar subquery in UPDATE are not wrapped in
`SINGLE_VAL` aggregate.
Examples:
{code:java}
@Test
public void ddml2() {
sql("CREATE TABLE vals (id INTEGER PRIMARY KEY, val INTEGER);");
sql("CREATE TABLE other_vals (id INTEGER PRIMARY KEY, other_val
INTEGER);");
sql("INSERT INTO vals VALUES (1, 0);");
sql("INSERT INTO vals VALUES (2, 0);");
sql("INSERT INTO other_vals VALUES (1, 1), (2, 2);");
// works
sql("INSERT INTO other_vals VALUES (3, (SELECT other_val FROM
other_vals WHERE id = 1));");
// works
sql("UPDATE vals SET val = (SELECT other_val FROM other_vals LIMIT 1)
WHERE id = 1");
// Should fail, because a subquery returns more than 1 result.
sql("UPDATE vals SET val = (SELECT other_val FROM other_vals) WHERE id
>= 2");
}
UPDATEs in MERGE statement are also affect by this issue:
{code:java}
@Test
public void ddml2_1() {
sql("CREATE TABLE vals (id INTEGER PRIMARY KEY, val INTEGER);");
sql("CREATE TABLE other_vals (id INTEGER PRIMARY KEY, other_val
INTEGER);");
sql("INSERT INTO vals VALUES (1, 0);");
sql("INSERT INTO vals VALUES (2, 0);");
sql("INSERT INTO other_vals VALUES (1, 1), (2, 2);");
// works
sql("INSERT INTO other_vals VALUES (3, (SELECT other_val FROM
other_vals WHERE id = 1));");
// Fails with PK unique constraint is violated
sql("MERGE INTO vals USING other_vals ON vals.id = other_vals.id "
+ "WHEN MATCHED THEN UPDATE SET val = (SELECT other_val FROM
other_vals WHERE id > 1) "
+ "WHEN NOT MATCHED THEN INSERT (id, val) VALUES (100, -1)");
}
{code}
*UPDATE*
The second issue about type cast separated into IGNITE-23183
was:
Update statements incorrectly use scalar subqueries in target columns, the
issues stems from the fact that scalar subquery in UPDATE are not wrapped in
`SINGLE_VAL` aggregate.
Examples:
{code:java}
@Test
public void ddml2() {
sql("CREATE TABLE vals (id INTEGER PRIMARY KEY, val INTEGER);");
sql("CREATE TABLE other_vals (id INTEGER PRIMARY KEY, other_val
INTEGER);");
sql("INSERT INTO vals VALUES (1, 0);");
sql("INSERT INTO vals VALUES (2, 0);");
sql("INSERT INTO other_vals VALUES (1, 1), (2, 2);");
// works
sql("INSERT INTO other_vals VALUES (3, (SELECT other_val FROM
other_vals WHERE id = 1));");
// works
sql("UPDATE vals SET val = (SELECT other_val FROM other_vals LIMIT 1)
WHERE id = 1");
// Should fail, because a subquery returns more than 1 result.
sql("UPDATE vals SET val = (SELECT other_val FROM other_vals) WHERE id
>= 2");
}
UPDATEs in MERGE statement are also affect by this issue:
{code:java}
@Test
public void ddml2_1() {
sql("CREATE TABLE vals (id INTEGER PRIMARY KEY, val INTEGER);");
sql("CREATE TABLE other_vals (id INTEGER PRIMARY KEY, other_val
INTEGER);");
sql("INSERT INTO vals VALUES (1, 0);");
sql("INSERT INTO vals VALUES (2, 0);");
sql("INSERT INTO other_vals VALUES (1, 1), (2, 2);");
// works
sql("INSERT INTO other_vals VALUES (3, (SELECT other_val FROM
other_vals WHERE id = 1));");
// Fails with PK unique constraint is violated
sql("MERGE INTO vals USING other_vals ON vals.id = other_vals.id "
+ "WHEN MATCHED THEN UPDATE SET val = (SELECT other_val FROM
other_vals WHERE id > 1) "
+ "WHEN NOT MATCHED THEN INSERT (id, val) VALUES (100, -1)");
}
{code}
{code}
If we change val type to BIGINT we get another error:
{code:java}
@Test
public void ddml3() {
sql("CREATE TABLE vals (id INTEGER PRIMARY KEY, val INTEGER);");
sql("CREATE TABLE other_vals (id INTEGER PRIMARY KEY, other_val
BIGINT);");
sql("INSERT INTO vals VALUES (1, 0);");
sql("INSERT INTO vals VALUES (2, 0);");
sql("INSERT INTO other_vals VALUES (1, 1), (2, 2);");
// works
sql("INSERT INTO other_vals VALUES (3, (SELECT other_val FROM
other_vals WHERE id = 1));");
// works
sql("UPDATE vals SET val = (SELECT other_val FROM other_vals LIMIT 1)
WHERE id = 1");
// Error
sql("UPDATE vals SET val = (SELECT other_val FROM other_vals) WHERE id
>= 2");
}
{code}
Error:
{code:java}
Caused by: java.lang.AssertionError
at
org.apache.calcite.sql.validate.implicit.AbstractTypeCoercion.needToCast(AbstractTypeCoercion.java:297)
at
org.apache.calcite.sql.validate.implicit.AbstractTypeCoercion.needToCast(AbstractTypeCoercion.java:250)
at
org.apache.ignite.internal.sql.engine.prepare.IgniteTypeCoercion.needToCast(IgniteTypeCoercion.java:294)
at
org.apache.ignite.internal.sql.engine.prepare.IgniteTypeCoercion.doCoerceColumnType(IgniteTypeCoercion.java:453)
at
org.apache.ignite.internal.sql.engine.prepare.IgniteTypeCoercion.coerceColumnType(IgniteTypeCoercion.java:360)
at
org.apache.calcite.sql.validate.implicit.TypeCoercionImpl.coerceSourceRowType(TypeCoercionImpl.java:676)
at
org.apache.calcite.sql.validate.implicit.TypeCoercionImpl.querySourceCoercion(TypeCoercionImpl.java:646)
at
org.apache.ignite.internal.sql.engine.prepare.IgniteTypeCoercion.querySourceCoercion(IgniteTypeCoercion.java:241)
at
org.apache.calcite.sql.validate.SqlValidatorImpl.checkTypeAssignment(SqlValidatorImpl.java:5112)
at
org.apache.calcite.sql.validate.SqlValidatorImpl.validateUpdate(SqlValidatorImpl.java:5219)
at
org.apache.ignite.internal.sql.engine.prepare.IgniteSqlValidator.validateUpdate(IgniteSqlValidator.java:187)
at org.apache.calcite.sql.SqlUpdate.validate(SqlUpdate.java:190)
at
org.apache.calcite.sql.validate.SqlValidatorImpl.validateScopedExpression(SqlValidatorImpl.java:1090)
at
org.apache.calcite.sql.validate.SqlValidatorImpl.validate(SqlValidatorImpl.java:796)
at
org.apache.ignite.internal.sql.engine.prepare.IgniteSqlValidator.validate(IgniteSqlValidator.java:161)
at
org.apache.ignite.internal.sql.engine.prepare.IgnitePlanner.validate(IgnitePlanner.java:204)
{code}
Insert statement behaves correctly:
{code:java}
@Test
public void ddml0() {
sql("CREATE TABLE vals (id INTEGER PRIMARY KEY, val INTEGER);");
sql("CREATE TABLE other_vals (id INTEGER PRIMARY KEY, other_val INTEGER);");
sql("INSERT INTO vals VALUES (1, 0);");
sql("INSERT INTO vals VALUES (2, 0);");
sql("INSERT INTO other_vals VALUES (1, 1), (2, 2);");
// Fails with `Subquery returned more than 1 value`
sql("INSERT INTO vals VALUES (3, (SELECT other_val FROM other_vals WHERE id
> 0));");
}
{code}
> Sql. Update statements incorrectly use scalar subqueries in target columns
> ----------------------------------------------------------------------------
>
> Key: IGNITE-20835
> URL: https://issues.apache.org/jira/browse/IGNITE-20835
> Project: Ignite
> Issue Type: Bug
> Components: sql
> Reporter: Maksim Zhuravkov
> Assignee: Pavel Pereslegin
> Priority: Major
> Labels: ignite-3
> Fix For: 3.0
>
> Time Spent: 0.5h
> Remaining Estimate: 0h
>
> Update statements incorrectly use scalar subqueries in target columns, the
> issues stems from the fact that scalar subquery in UPDATE are not wrapped in
> `SINGLE_VAL` aggregate.
> Examples:
> {code:java}
> @Test
> public void ddml2() {
> sql("CREATE TABLE vals (id INTEGER PRIMARY KEY, val INTEGER);");
> sql("CREATE TABLE other_vals (id INTEGER PRIMARY KEY, other_val
> INTEGER);");
> sql("INSERT INTO vals VALUES (1, 0);");
> sql("INSERT INTO vals VALUES (2, 0);");
> sql("INSERT INTO other_vals VALUES (1, 1), (2, 2);");
> // works
> sql("INSERT INTO other_vals VALUES (3, (SELECT other_val FROM
> other_vals WHERE id = 1));");
> // works
> sql("UPDATE vals SET val = (SELECT other_val FROM other_vals LIMIT 1)
> WHERE id = 1");
> // Should fail, because a subquery returns more than 1 result.
> sql("UPDATE vals SET val = (SELECT other_val FROM other_vals) WHERE
> id >= 2");
> }
> UPDATEs in MERGE statement are also affect by this issue:
> {code:java}
> @Test
> public void ddml2_1() {
> sql("CREATE TABLE vals (id INTEGER PRIMARY KEY, val INTEGER);");
> sql("CREATE TABLE other_vals (id INTEGER PRIMARY KEY, other_val
> INTEGER);");
> sql("INSERT INTO vals VALUES (1, 0);");
> sql("INSERT INTO vals VALUES (2, 0);");
> sql("INSERT INTO other_vals VALUES (1, 1), (2, 2);");
> // works
> sql("INSERT INTO other_vals VALUES (3, (SELECT other_val FROM
> other_vals WHERE id = 1));");
> // Fails with PK unique constraint is violated
> sql("MERGE INTO vals USING other_vals ON vals.id = other_vals.id "
> + "WHEN MATCHED THEN UPDATE SET val = (SELECT other_val FROM
> other_vals WHERE id > 1) "
> + "WHEN NOT MATCHED THEN INSERT (id, val) VALUES (100, -1)");
> }
> {code}
> *UPDATE*
> The second issue about type cast separated into IGNITE-23183
--
This message was sent by Atlassian Jira
(v8.20.10#820010)