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

ppa pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new 6ab2b0f654 IGNITE-22779 Sql. Relax type checking for dynamic 
parameters to match type checking for literals (#4251)
6ab2b0f654 is described below

commit 6ab2b0f65438b079d5760486fc44b470e49050d1
Author: Pavel Pereslegin <[email protected]>
AuthorDate: Fri Aug 23 14:00:31 2024 +0300

    IGNITE-22779 Sql. Relax type checking for dynamic parameters to match type 
checking for literals (#4251)
---
 .../sql/engine/ItSqlMultiStatementTest.java        |  7 +-
 .../sql/engine/datatypes/ItCastToBigintTest.java   |  3 -
 .../sql/engine/datatypes/ItCastToIntTest.java      |  3 -
 .../sql/engine/datatypes/ItCastToSmallintTest.java |  3 -
 .../sql/engine/datatypes/ItCastToTinyintTest.java  |  3 -
 .../datatypes/ItCastToTsWithLocalTimeZoneTest.java |  2 -
 .../varbinary/ItVarBinaryExpressionTest.java       | 10 ++-
 .../sql/engine/prepare/IgniteTypeCoercion.java     | 13 +++-
 .../sql/engine/planner/DynamicParametersTest.java  | 91 +++++++++++-----------
 .../ignite/internal/table/ItCriteriaQueryTest.java | 26 +++----
 10 files changed, 77 insertions(+), 84 deletions(-)

diff --git 
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSqlMultiStatementTest.java
 
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSqlMultiStatementTest.java
index be36bcf8a5..b3f614d944 100644
--- 
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSqlMultiStatementTest.java
+++ 
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSqlMultiStatementTest.java
@@ -150,11 +150,10 @@ public class ItSqlMultiStatementTest extends 
BaseSqlMultiStatementTest {
         {
             assertThrowsSqlException(
                     STMT_VALIDATION_ERR,
-                    "operator must have compatible types",
+                    "Values passed to VALUES operator must have compatible 
types",
                     () -> executeScript(
-                            "INSERT INTO test VALUES (?);"
-                                    + "INSERT INTO test VALUES (1)",
-                            "Incompatible param"
+                            "INSERT INTO test VALUES (?), (?)",
+                            "1", 2
                     )
             );
 
diff --git 
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/ItCastToBigintTest.java
 
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/ItCastToBigintTest.java
index 2e7162cbdf..cc8146ff22 100644
--- 
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/ItCastToBigintTest.java
+++ 
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/ItCastToBigintTest.java
@@ -33,7 +33,6 @@ import org.apache.ignite.lang.ErrorGroups.Sql;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
@@ -157,7 +156,6 @@ public class ItCastToBigintTest extends 
BaseSqlIntegrationTest {
 
     @ParameterizedTest
     @MethodSource("valuesWithExpectedResult")
-    @Disabled("https://issues.apache.org/jira/browse/IGNITE-22779";)
     void implicitCastOfDynParamsOnInsert(Object param, Object expectedResult) {
         assertQuery("INSERT INTO test VALUES (?)")
                 .withParam(param)
@@ -171,7 +169,6 @@ public class ItCastToBigintTest extends 
BaseSqlIntegrationTest {
     @SuppressWarnings("ThrowableNotThrown")
     @ParameterizedTest
     @MethodSource("valuesWithOverflow")
-    @Disabled("https://issues.apache.org/jira/browse/IGNITE-22779";)
     void implicitCastOfDynParamsOnInsertWithOverflow(Object param) {
         SqlTestUtils.assertThrowsSqlException(
                 Sql.RUNTIME_ERR,
diff --git 
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/ItCastToIntTest.java
 
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/ItCastToIntTest.java
index 6e8eeebe42..508b56a66a 100644
--- 
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/ItCastToIntTest.java
+++ 
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/ItCastToIntTest.java
@@ -33,7 +33,6 @@ import org.apache.ignite.lang.ErrorGroups.Sql;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
@@ -160,7 +159,6 @@ public class ItCastToIntTest extends BaseSqlIntegrationTest 
{
 
     @ParameterizedTest
     @MethodSource("valuesWithExpectedResult")
-    @Disabled("https://issues.apache.org/jira/browse/IGNITE-22779";)
     void implicitCastOfDynParamsOnInsert(Object param, Object expectedResult) {
         assertQuery("INSERT INTO test VALUES (?)")
                 .withParam(param)
@@ -174,7 +172,6 @@ public class ItCastToIntTest extends BaseSqlIntegrationTest 
{
     @SuppressWarnings("ThrowableNotThrown")
     @ParameterizedTest
     @MethodSource("valuesWithOverflow")
-    @Disabled("https://issues.apache.org/jira/browse/IGNITE-22779";)
     void implicitCastOfDynParamsOnInsertWithOverflow(Object param) {
         SqlTestUtils.assertThrowsSqlException(
                 Sql.RUNTIME_ERR,
diff --git 
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/ItCastToSmallintTest.java
 
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/ItCastToSmallintTest.java
index ebbc41e2e3..46f6012daa 100644
--- 
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/ItCastToSmallintTest.java
+++ 
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/ItCastToSmallintTest.java
@@ -33,7 +33,6 @@ import org.apache.ignite.lang.ErrorGroups.Sql;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
@@ -157,7 +156,6 @@ public class ItCastToSmallintTest extends 
BaseSqlIntegrationTest {
 
     @ParameterizedTest
     @MethodSource("valuesWithExpectedResult")
-    @Disabled("https://issues.apache.org/jira/browse/IGNITE-22779";)
     void implicitCastOfDynParamsOnInsert(Object param, Object expectedResult) {
         assertQuery("INSERT INTO test VALUES (?)")
                 .withParam(param)
@@ -171,7 +169,6 @@ public class ItCastToSmallintTest extends 
BaseSqlIntegrationTest {
     @SuppressWarnings("ThrowableNotThrown")
     @ParameterizedTest
     @MethodSource("valuesWithOverflow")
-    @Disabled("https://issues.apache.org/jira/browse/IGNITE-22779";)
     void implicitCastOfDynParamsOnInsertWithOverflow(Object param) {
         SqlTestUtils.assertThrowsSqlException(
                 Sql.RUNTIME_ERR,
diff --git 
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/ItCastToTinyintTest.java
 
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/ItCastToTinyintTest.java
index d307f1d773..d3331f0222 100644
--- 
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/ItCastToTinyintTest.java
+++ 
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/ItCastToTinyintTest.java
@@ -33,7 +33,6 @@ import org.apache.ignite.lang.ErrorGroups.Sql;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
@@ -157,7 +156,6 @@ public class ItCastToTinyintTest extends 
BaseSqlIntegrationTest {
 
     @ParameterizedTest
     @MethodSource("valuesWithExpectedResult")
-    @Disabled("https://issues.apache.org/jira/browse/IGNITE-22779";)
     void implicitCastOfDynParamsOnInsert(Object param, Object expectedResult) {
         assertQuery("INSERT INTO test VALUES (?)")
                 .withParam(param)
@@ -171,7 +169,6 @@ public class ItCastToTinyintTest extends 
BaseSqlIntegrationTest {
     @SuppressWarnings("ThrowableNotThrown")
     @ParameterizedTest
     @MethodSource("valuesWithOverflow")
-    @Disabled("https://issues.apache.org/jira/browse/IGNITE-22779";)
     void implicitCastOfDynParamsOnInsertWithOverflow(Object param) {
         SqlTestUtils.assertThrowsSqlException(
                 Sql.RUNTIME_ERR,
diff --git 
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/ItCastToTsWithLocalTimeZoneTest.java
 
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/ItCastToTsWithLocalTimeZoneTest.java
index 1b57885d9f..873643126c 100644
--- 
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/ItCastToTsWithLocalTimeZoneTest.java
+++ 
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/ItCastToTsWithLocalTimeZoneTest.java
@@ -38,7 +38,6 @@ import org.apache.ignite.internal.util.Pair;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
@@ -147,7 +146,6 @@ public class ItCastToTsWithLocalTimeZoneTest extends 
BaseSqlIntegrationTest {
 
     @ParameterizedTest
     @MethodSource("valuesWithExpectedResult")
-    @Disabled("https://issues.apache.org/jira/browse/IGNITE-22779";)
     void implicitCastOfDynParamsOnInsert(Object param, int zoneOffset, Object 
expectedResult) {
         ZoneId zone = ZoneOffset.ofHours(zoneOffset);
 
diff --git 
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/varbinary/ItVarBinaryExpressionTest.java
 
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/varbinary/ItVarBinaryExpressionTest.java
index 25b5275d68..9411080db5 100644
--- 
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/varbinary/ItVarBinaryExpressionTest.java
+++ 
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/varbinary/ItVarBinaryExpressionTest.java
@@ -17,7 +17,6 @@
 
 package org.apache.ignite.internal.sql.engine.datatypes.varbinary;
 
-import java.math.BigDecimal;
 import org.apache.calcite.sql.type.SqlTypeName;
 import org.apache.calcite.sql.validate.SqlValidatorException;
 import org.apache.ignite.internal.sql.engine.datatypes.DataTypeTestSpecs;
@@ -104,9 +103,14 @@ public class ItVarBinaryExpressionTest extends 
BaseExpressionDataTypeTest<VarBin
 
     /** Throws correct exception. */
     @Test
-    public void testErroneousParamToLegth() {
+    @Disabled("https://issues.apache.org/jira/browse/IGNITE-19469";)
+    public void testIncorrectTypeParamToLength() {
+        IgniteTestUtils.assertThrowsWithCause(() -> checkQuery("SELECT 
LENGTH(1234)")
+                        .check(), SqlValidatorException.class,
+                "Values passed to LENGTH operator must have compatible types");
+
         IgniteTestUtils.assertThrowsWithCause(() -> checkQuery("SELECT 
LENGTH(?)")
-                .withParams(new BigDecimal(1)).check(), 
SqlValidatorException.class,
+                        .withParams(1234).check(), SqlValidatorException.class,
                 "Values passed to LENGTH operator must have compatible types");
     }
 
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteTypeCoercion.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteTypeCoercion.java
index a606ad6c39..b70888eed8 100644
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteTypeCoercion.java
+++ 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteTypeCoercion.java
@@ -62,6 +62,7 @@ import org.apache.calcite.util.Util;
 import org.apache.ignite.internal.sql.engine.type.IgniteCustomType;
 import 
org.apache.ignite.internal.sql.engine.type.IgniteCustomTypeCoercionRules;
 import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
+import org.apache.ignite.internal.sql.engine.util.IgniteCustomAssignmentsRules;
 import org.apache.ignite.internal.sql.engine.util.IgniteResource;
 import org.apache.ignite.internal.sql.engine.util.TypeUtils;
 import org.jetbrains.annotations.Nullable;
@@ -762,7 +763,11 @@ public class IgniteTypeCoercion extends TypeCoercionImpl {
     // TODO: https://issues.apache.org/jira/browse/IGNITE-19721 - move this 
check to SqlValidator (if possible).
     private void validateAssignment(SqlDynamicParam node, RelDataType 
targetType, ContextType ctxType, IgniteSqlValidator validator) {
         RelDataType paramType = validator.resolveDynamicParameterType(node, 
targetType);
-        boolean compatible = TypeUtils.typeFamiliesAreCompatible(typeFactory, 
targetType, paramType);
+
+        // TODO https://issues.apache.org/jira/browse/IGNITE-23060 This 
condition must be simplified.
+        boolean compatible = TypeUtils.typeFamiliesAreCompatible(typeFactory, 
targetType, paramType)
+                || 
IgniteCustomAssignmentsRules.instance().canApplyFrom(targetType.getSqlTypeName(),
 paramType.getSqlTypeName());
+
         if (compatible) {
             return;
         }
@@ -790,7 +795,11 @@ public class IgniteTypeCoercion extends TypeCoercionImpl {
     private void validateOperand(SqlDynamicParam node, RelDataType targetType, 
SqlOperator operator, IgniteSqlValidator validator) {
 
         RelDataType paramType = validator.resolveDynamicParameterType(node, 
targetType);
-        boolean compatible = TypeUtils.typeFamiliesAreCompatible(typeFactory, 
targetType, paramType);
+
+        // TODO https://issues.apache.org/jira/browse/IGNITE-23060 This 
condition must be simplified.
+        boolean compatible = TypeUtils.typeFamiliesAreCompatible(typeFactory, 
targetType, paramType)
+                || 
IgniteCustomAssignmentsRules.instance().canApplyFrom(targetType.getSqlTypeName(),
 paramType.getSqlTypeName());
+
         if (compatible) {
             return;
         }
diff --git 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/DynamicParametersTest.java
 
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/DynamicParametersTest.java
index 6f0bdf8ca6..1649609dfb 100644
--- 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/DynamicParametersTest.java
+++ 
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/DynamicParametersTest.java
@@ -62,8 +62,8 @@ public class DynamicParametersTest extends 
AbstractPlannerTest {
                 sql("SELECT NULL + ?", 
1).parameterTypes(nullable(NativeTypes.INT32)).project("null:INTEGER"),
                 sql("SELECT ? + NULL", 
1).parameterTypes(nullable(NativeTypes.INT32)).project("null:INTEGER"),
 
-                sql("SELECT 1 + ?", "1").fails("Values passed to + operator 
must have compatible types"),
-                sql("SELECT ? + 1", "1").fails("Values passed to + operator 
must have compatible types"),
+                sql("SELECT 1 + ?", 
"1").parameterTypes(nullable(NativeTypes.STRING)).project("+(1, 
CAST(?0):INTEGER)"),
+                sql("SELECT ? + 1", 
"1").parameterTypes(nullable(NativeTypes.STRING)).project("+(CAST(?0):INTEGER, 
1)"),
 
                 // NULL is allowed in arithmetic expressions, if another 
operand is present.
                 sql("SELECT ? * 2", new Object[]{null})
@@ -83,16 +83,11 @@ public class DynamicParametersTest extends 
AbstractPlannerTest {
         return Stream.of(
                 // comparison
                 sql("SELECT ? > 1", 
1).parameterTypes(nullable(NativeTypes.INT32)).ok(),
+                sql("SELECT ? > 1", 
"1").parameterTypes(nullable(NativeTypes.STRING)).ok(),
+                sql("SELECT 1 > ?", 
"1").parameterTypes(nullable(NativeTypes.STRING)).ok(),
                 sql("SELECT ? > 1", 
Unspecified.UNKNOWN).parameterTypes(nullable(NativeTypes.INT32)).ok(),
                 sql("SELECT 1 > ?", 
Unspecified.UNKNOWN).parameterTypes(nullable(NativeTypes.INT32)).ok(),
                 sql("SELECT ? > ?", Unspecified.UNKNOWN, 
Unspecified.UNKNOWN).fails("Ambiguous operator <UNKNOWN> > <UNKNOWN>"),
-
-                sql("SELECT ? > 1", "1")
-                        .fails("Values passed to > operator must have 
compatible types"),
-
-                sql("SELECT 1 > ?", "1")
-                        .fails("Values passed to > operator must have 
compatible types"),
-
                 sql("SELECT ? > NULL", 
1).parameterTypes(nullable(NativeTypes.INT32)).project("null:BOOLEAN"),
                 sql("SELECT NULL = ?", 
1).parameterTypes(nullable(NativeTypes.INT32)).project("null:BOOLEAN"),
                 sql("SELECT ? = NULL", 
1).parameterTypes(nullable(NativeTypes.INT32)).project("null:BOOLEAN"),
@@ -107,12 +102,8 @@ public class DynamicParametersTest extends 
AbstractPlannerTest {
      */
     @TestFactory
     public Stream<DynamicTest> testInExpression() {
-        String requireExplicitCast =
-                "Values passed to IN operator must have compatible types. 
Dynamic parameter requires adding explicit type cast";
-
         return Stream.of(
                 sql("SELECT ? IN ('1', '2')", 
1).parameterTypes(nullable(NativeTypes.INT32)).project("OR(=(?0, 1), =(?0, 
2))"),
-                sql("SELECT ? IN (1, 2)", "1").fails(requireExplicitCast),
                 sql("SELECT ? IN (1, 2)", 
1).parameterTypes(nullable(NativeTypes.INT32)).project("OR(=(?0, 1), =(?0, 
2))"),
 
                 sql("SELECT ? IN (1)", Unspecified.UNKNOWN)
@@ -135,6 +126,12 @@ public class DynamicParametersTest extends 
AbstractPlannerTest {
                         .parameterTypes(nullable(NativeTypes.INT32))
                         .project("OR(=(?0, 1), =(?0, 2))")
         );
+
+        // TODO https://issues.apache.org/jira/browse/IGNITE-23039 Add support 
for Sarg serialization/deserialization
+        // sql("SELECT ? IN (1, 2)", "1")
+        //        .parameterTypes(nullable(NativeTypes.STRING))
+        //        .project("SEARCH(CAST(?0):INTEGER, Sarg[1, 2])"),
+
         // TODO https://issues.apache.org/jira/browse/IGNITE-22084: Sql. Add 
support for row data type.
         // sql("SELECT (?,?) IN ((1,2))", 1, 2)
         //        .parameterTypes(nullable(NativeTypes.INT32), 
nullable(NativeTypes.INT32))
@@ -164,7 +161,8 @@ public class DynamicParametersTest extends 
AbstractPlannerTest {
                         .project("CASE(=(?0, _UTF-8'1'), CAST(?1):DOUBLE, 
?2)"),
 
                 sql("SELECT CASE ? = ? WHEN true THEN 1 ELSE 2 END", 1, "1")
-                        .fails("Values passed to = operator must have 
compatible types"),
+                        .parameterTypes(nullable(NativeTypes.INT32), 
nullableVarchar)
+                        .project("CASE(=(?0, CAST(?1):INTEGER), 1, 2)"),
 
                 sql("SELECT CASE WHEN ? = '1' THEN ? ELSE ? END", "1", "2", 
2.5)
                         .fails("Illegal mixing of types in CASE or COALESCE 
statement"),
@@ -230,11 +228,14 @@ public class DynamicParametersTest extends 
AbstractPlannerTest {
 
                 checkStatement()
                         .table("t1", "int_col", NativeTypes.INT32)
-                        .sql("SELECT * FROM t1 WHERE int_col = ?", 
"1").fails("Values passed to = operator must have compatible types"),
+                        .sql("SELECT * FROM t1 WHERE int_col = ?", "1")
+                        .parameterTypes(nullable(NativeTypes.STRING))
+                        .ok(),
 
                 checkStatement()
                         .table("t1", "str_col", NativeTypes.STRING)
-                        .sql("SELECT * FROM t1 WHERE str_col = ?", 
1).fails("Values passed to = operator must have compatible types")
+                        .sql("SELECT * FROM t1 WHERE str_col = ?", 1)
+                        .ok()
         );
     }
 
@@ -427,14 +428,15 @@ public class DynamicParametersTest extends 
AbstractPlannerTest {
                         .sql("SELECT NULLIF(?, ?)", Unspecified.UNKNOWN, 
Unspecified.UNKNOWN)
                         .fails("Ambiguous operator <UNKNOWN> = <UNKNOWN>"),
 
-                checkStatement()
-                        .sql("SELECT NULLIF(?, ?)", 1, "1")
-                        .fails("Values passed to = operator must have 
compatible types"),
-
                 checkStatement()
                         .sql("SELECT NULLIF(?, 1)", Unspecified.UNKNOWN)
                         .fails("Unable to determine type of a dynamic 
parameter"),
 
+                checkStatement()
+                        .sql("SELECT NULLIF(?, ?)", 1, "1")
+                        .parameterTypes(nullable(NativeTypes.INT32), 
nullable(NativeTypes.STRING))
+                        .project("CASE(=(?0, CAST(?1):INTEGER), null:INTEGER, 
?0)"),
+
                 checkStatement()
                         .sql("SELECT NULLIF(CAST(? AS INTEGER), 1)", 
Unspecified.UNKNOWN)
                         .parameterTypes(nullable(NativeTypes.INT32))
@@ -534,20 +536,19 @@ public class DynamicParametersTest extends 
AbstractPlannerTest {
                         .parameterTypes(nullable(NativeTypes.INT32))
                         .project("CAST(?0):BIGINT"),
 
-
-                // Incompatible types in dynamic params
-
                 checkStatement()
                         .disableRules(DISABLE_KEY_VALUE_MODIFY_RULES)
                         .table("t1", "c1", NativeTypes.INT32)
                         .sql("INSERT INTO t1 VALUES (?)", "10")
-                        .fails("Values passed to VALUES operator must have 
compatible types"),
+                        .parameterTypes(nullable(NativeTypes.STRING))
+                        .project("CAST(?0):INTEGER"),
 
                 checkStatement()
                         .table("t1", "c1", NativeTypes.INT32, "c2", 
NativeTypes.INT32)
                         .table("t2", "c1", NativeTypes.INT32, "c2", 
NativeTypes.INT32)
                         .sql("INSERT INTO t1 (c1, c2) SELECT c1, ? FROM t2", 
"10")
-                        .fails("Values passed to VALUES operator must have 
compatible types")
+                        .parameterTypes(nullable(NativeTypes.STRING))
+                        .project("$t0", "CAST(?0):INTEGER")
         );
     }
 
@@ -576,19 +577,18 @@ public class DynamicParametersTest extends 
AbstractPlannerTest {
                         .parameterTypes(nullable(NativeTypes.INT32))
                         .project("$t0", "CAST(?0):BIGINT"),
 
+                checkStatement()
+                        .table("t1", "c1", NativeTypes.INT64)
+                        .sql("UPDATE t1 SET c1 = ?", "10")
+                        .parameterTypes(nullable(NativeTypes.STRING))
+                        .project("$t0", "CAST(?0):BIGINT"),
+
                 // null
                 checkStatement()
                         .table("t1", "c1", NativeTypes.INT32)
                         .sql("UPDATE t1 SET c1 = ?", new Object[]{null})
                         .parameterTypes(new NativeType[]{null})
-                        .project("$t0", "CAST(?0):INTEGER"),
-
-                // Incompatible types in dynamic params
-
-                checkStatement()
-                        .table("t1", "c1", NativeTypes.INT32)
-                        .sql("UPDATE t1 SET c1 = ?", "10")
-                        .fails("Assignment from VARCHAR to INTEGER can not be 
performed")
+                        .project("$t0", "CAST(?0):INTEGER")
         );
     }
 
@@ -620,8 +620,6 @@ public class DynamicParametersTest extends 
AbstractPlannerTest {
                         .parameterTypes(nullable(NativeTypes.INT32))
                         .project("$0", "$1", "?0"),
 
-                // null
-
                 checkStatement()
                         .table("t1", "c1", NativeTypes.INT32, "c2", 
NativeTypes.INT32, "c3", NativeTypes.INT32)
                         .table("t2", "c1", NativeTypes.INT32, "c2", 
NativeTypes.INT32, "c3", NativeTypes.INT32)
@@ -629,11 +627,11 @@ public class DynamicParametersTest extends 
AbstractPlannerTest {
                             String sql = "MERGE INTO T2 dst USING t1 src ON 
dst.c1 = src.c1 "
                                     + "WHEN NOT MATCHED THEN INSERT (c1, c2, 
c3) VALUES (src.c1, src.c2, ?)";
                             return sql;
-                        }, new Object[]{null})
-                        .parameterTypes(new NativeType[]{null})
+                        }, "1")
+                        .parameterTypes(nullable(NativeTypes.STRING))
                         .project("$0", "$1", "CAST(?0):INTEGER"),
 
-                // incompatible types
+                // null
 
                 checkStatement()
                         .table("t1", "c1", NativeTypes.INT32, "c2", 
NativeTypes.INT32, "c3", NativeTypes.INT32)
@@ -642,8 +640,9 @@ public class DynamicParametersTest extends 
AbstractPlannerTest {
                             String sql = "MERGE INTO T2 dst USING t1 src ON 
dst.c1 = src.c1 "
                                     + "WHEN NOT MATCHED THEN INSERT (c1, c2, 
c3) VALUES (src.c1, src.c2, ?)";
                             return sql;
-                        }, "1")
-                        .fails("Values passed to VALUES operator must have 
compatible types")
+                        }, new Object[]{null})
+                        .parameterTypes(new NativeType[]{null})
+                        .project("$0", "$1", "CAST(?0):INTEGER")
         );
     }
 
@@ -675,8 +674,6 @@ public class DynamicParametersTest extends 
AbstractPlannerTest {
                         .parameterTypes(nullable(NativeTypes.INT32), 
nullable(NativeTypes.INT64))
                         .project("$3", "$4", "?1", "$0", "$1", "$2", "?0"),
 
-                // Incompatible types
-
                 checkStatement()
                         .table("t1", "c1", NativeTypes.INT32, "c2", 
NativeTypes.INT32, "c3", NativeTypes.INT32)
                         .table("t2", "c1", NativeTypes.INT32, "c2", 
NativeTypes.INT32, "c3", NativeTypes.INT32)
@@ -686,7 +683,8 @@ public class DynamicParametersTest extends 
AbstractPlannerTest {
                                     + "WHEN NOT MATCHED THEN INSERT (c1, c2, 
c3) VALUES (src.c1, src.c2, 1)";
                             return sql;
                         }, "1")
-                        .fails("Assignment from VARCHAR to INTEGER can not be 
performed"),
+                        .parameterTypes(nullable(NativeTypes.STRING))
+                        .project("$3", "$4", "1", "$0", "$1", "$2", 
"CAST(?0):INTEGER"),
 
                 checkStatement()
                         .table("t1", "c1", NativeTypes.INT32, "c2", 
NativeTypes.INT32, "c3", NativeTypes.INT32)
@@ -697,7 +695,8 @@ public class DynamicParametersTest extends 
AbstractPlannerTest {
                                     + "WHEN NOT MATCHED THEN INSERT (c1, c2, 
c3) VALUES (src.c1, src.c2, ?)";
                             return sql;
                         }, 1, "1")
-                        .fails("Values passed to VALUES operator must have 
compatible types")
+                        .parameterTypes(nullable(NativeTypes.INT32), 
nullable(NativeTypes.STRING))
+                        .project("$3", "$4", "CAST(?1):INTEGER", "$0", "$1", 
"$2", "?0")
         );
     }
 
@@ -765,10 +764,10 @@ public class DynamicParametersTest extends 
AbstractPlannerTest {
                         .sql("SELECT SUBSTRING(SUBSTRING(?, 1), 2)", "123456")
                         .project("SUBSTRING(SUBSTRING(?0, 1), 2)"),
 
-                // nested function call - invalid dynamic parameter
+                // nested function call with implicit parameter casting
                 checkStatement()
                         .sql("SELECT SUBSTRING(SUBSTRING(?, 1), 2)", 123456)
-                        .fails("Values passed to SUBSTRING operator must have 
compatible types")
+                        .project("SUBSTRING(SUBSTRING(CAST(?0):VARCHAR 
CHARACTER SET \"UTF-8\", 1), 2)")
         );
     }
 
diff --git 
a/modules/table/src/integrationTest/java/org/apache/ignite/internal/table/ItCriteriaQueryTest.java
 
b/modules/table/src/integrationTest/java/org/apache/ignite/internal/table/ItCriteriaQueryTest.java
index 96c40acfea..e4951e791a 100644
--- 
a/modules/table/src/integrationTest/java/org/apache/ignite/internal/table/ItCriteriaQueryTest.java
+++ 
b/modules/table/src/integrationTest/java/org/apache/ignite/internal/table/ItCriteriaQueryTest.java
@@ -28,7 +28,6 @@ import static 
org.apache.ignite.internal.testframework.IgniteTestUtils.await;
 import static 
org.apache.ignite.internal.testframework.matchers.TupleMatcher.tupleValue;
 import static org.apache.ignite.internal.util.IgniteUtils.closeAll;
 import static org.apache.ignite.lang.ErrorGroups.Common.INTERNAL_ERR;
-import static org.apache.ignite.lang.ErrorGroups.Sql.STMT_VALIDATION_ERR;
 import static org.apache.ignite.lang.util.IgniteNameUtils.quote;
 import static org.apache.ignite.table.criteria.Criteria.columnValue;
 import static org.apache.ignite.table.criteria.Criteria.equalTo;
@@ -153,13 +152,6 @@ public class ItCriteriaQueryTest extends 
ClusterPerClassIntegrationTest {
     @ParameterizedTest
     @MethodSource
     public <T> void testRecordViewQuery(CriteriaQuerySource<T> view, 
Function<T, Tuple> mapper) {
-        assertThrowsWithCode(
-                CriteriaException.class,
-                STMT_VALIDATION_ERR,
-                () -> view.query(null, columnValue("id", equalTo("2"))),
-                "Dynamic parameter requires adding explicit type cast"
-        );
-
         Matcher<Tuple> person0 = allOf(tupleValue("id", is(0)), 
tupleValue("name", Matchers.nullValue()), tupleValue("salary", is(0.0d)),
                 tupleValue("hash", is("hash0".getBytes())));
         Matcher<Tuple> person1 = allOf(tupleValue("id", is(1)), 
tupleValue("name", is("name1")), tupleValue("salary", is(10.0d)),
@@ -175,6 +167,10 @@ public class ItCriteriaQueryTest extends 
ClusterPerClassIntegrationTest {
             assertThat(mapToTupleList(cur, mapper), 
containsInAnyOrder(person2));
         }
 
+        try (Cursor<T> cur = view.query(null, columnValue("id", 
equalTo("2")))) {
+            assertThat(mapToTupleList(cur, mapper), 
containsInAnyOrder(person2));
+        }
+
         try (Cursor<T> cur = view.query(null, columnValue("hash", 
equalTo("hash2".getBytes())))) {
             assertThat(mapToTupleList(cur, mapper), 
containsInAnyOrder(person2));
         }
@@ -259,13 +255,6 @@ public class ItCriteriaQueryTest extends 
ClusterPerClassIntegrationTest {
     @ParameterizedTest
     @MethodSource
     public <T> void testKeyValueView(CriteriaQuerySource<T> view, Function<T, 
Entry<Tuple, Tuple>> mapper) {
-        assertThrowsWithCode(
-                CriteriaException.class,
-                STMT_VALIDATION_ERR,
-                () -> view.query(null, columnValue("id", equalTo("2"))),
-                "Dynamic parameter requires adding explicit type cast"
-        );
-
         Matcher<Tuple> personKey0 = tupleValue("id", is(0));
         Matcher<Tuple> person0 = allOf(tupleValue("name", 
Matchers.nullValue()), tupleValue("salary", is(0.0d)),
                 tupleValue("hash", is("hash0".getBytes())));
@@ -287,6 +276,13 @@ public class ItCriteriaQueryTest extends 
ClusterPerClassIntegrationTest {
             ));
         }
 
+        try (Cursor<T> cur = view.query(null, columnValue("id", 
equalTo("2")))) {
+            assertThat(mapToTupleMap(cur, mapper), allOf(
+                    aMapWithSize(1),
+                    hasEntry(personKey2, person2)
+            ));
+        }
+
         try (Cursor<T> cur = view.query(null, columnValue("id", equalTo(2)))) {
             assertThat(mapToTupleMap(cur, mapper), allOf(
                     aMapWithSize(1),

Reply via email to