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

korlov 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 c832d15a7f IGNITE-22765 Sql. Improve optimization of simple inserts 
(#4104)
c832d15a7f is described below

commit c832d15a7fec3d8c218b5e7c1ec73c311d60cdb6
Author: korlov42 <[email protected]>
AuthorDate: Wed Jul 31 09:47:17 2024 +0300

    IGNITE-22765 Sql. Improve optimization of simple inserts (#4104)
---
 .../sql/engine/ItSqlUsesKeyValuePutTest.java       |  86 ++++++++++++-
 .../internal/sql/engine/prepare/IgnitePlanner.java |   9 +-
 .../engine/prepare/IgniteSqlToRelConvertor.java    |  10 +-
 .../internal/sql/engine/prepare/PlannerHelper.java | 137 ++++++++++++++++++++-
 .../ignite/internal/sql/engine/util/Commons.java   |  12 ++
 .../sql/engine/planner/DmlPlannerTest.java         |   2 +
 .../sql/engine/planner/DynamicParametersTest.java  |   2 +
 .../sql/engine/planner/ImplicitCastsTest.java      |   2 +
 8 files changed, 249 insertions(+), 11 deletions(-)

diff --git 
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSqlUsesKeyValuePutTest.java
 
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSqlUsesKeyValuePutTest.java
index 41c48f0fea..6a8fc5ba7d 100644
--- 
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSqlUsesKeyValuePutTest.java
+++ 
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSqlUsesKeyValuePutTest.java
@@ -22,6 +22,7 @@ import static 
org.apache.ignite.internal.sql.engine.util.QueryChecker.containsSu
 import static 
org.apache.ignite.internal.testframework.IgniteTestUtils.assertThrows;
 
 import org.apache.ignite.internal.sql.BaseSqlIntegrationTest;
+import org.apache.ignite.internal.testframework.WithSystemProperty;
 import org.apache.ignite.sql.SqlException;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeAll;
@@ -34,10 +35,10 @@ public class ItSqlUsesKeyValuePutTest extends 
BaseSqlIntegrationTest {
     private static final int TABLE_SIZE = 10;
 
     @BeforeAll
-    @SuppressWarnings({"ConcatenationWithEmptyString", "resource"})
+    @SuppressWarnings("ConcatenationWithEmptyString")
     static void initSchema() {
         CLUSTER.aliveNode().sql().executeScript(""
-                + "CREATE TABLE simple_key (id INT PRIMARY KEY, val INT);"
+                + "CREATE TABLE simple_key (id INT PRIMARY KEY, val INT 
DEFAULT 42);"
                 + "CREATE TABLE complex_key (id1 INT, id2 INT, val INT, 
PRIMARY KEY(id1, id2));"
         );
     }
@@ -65,6 +66,69 @@ public class ItSqlUsesKeyValuePutTest extends 
BaseSqlIntegrationTest {
         }
     }
 
+    @Test
+    void insertConstantReversFieldOrder() {
+        for (int i = 0; i < TABLE_SIZE; i++) {
+            assertQuery(format("INSERT INTO simple_key (val, id) VALUES ({}, 
{})", i * 10, i))
+                    .matches(containsSubPlan("KeyValueModify"))
+                    .returns(1L)
+                    .check();
+        }
+
+        for (int i = 0; i < TABLE_SIZE; i++) {
+            assertQuery("SELECT * FROM simple_key WHERE id = ?")
+                    .withParams(i)
+                    .returns(i, i * 10)
+                    .check();
+        }
+    }
+
+    @Test
+    @WithSystemProperty(key = "IMPLICIT_PK_ENABLED", value = "true")
+    void insertWithImplicitPk() {
+        sql("CREATE TABLE implicit_pk(val INT)");
+
+        for (int i = 0; i < TABLE_SIZE; i++) {
+            assertQuery(format("INSERT INTO implicit_pk VALUES ({})", i))
+                    .matches(containsSubPlan("KeyValueModify"))
+                    .returns(1L)
+                    .check();
+        }
+
+        for (int i = 0; i < TABLE_SIZE; i++) {
+            assertQuery("SELECT true FROM implicit_pk WHERE val = ?")
+                    .withParams(i)
+                    .returns(true)
+                    .check();
+        }
+    }
+
+    @Test
+    void insertWithDefault() {
+        // implicit default
+        for (int i = 0; i < TABLE_SIZE / 2; i++) {
+            assertQuery(format("INSERT INTO simple_key (id) VALUES ({})", i))
+                    .matches(containsSubPlan("KeyValueModify"))
+                    .returns(1L)
+                    .check();
+        }
+
+        // explicit default
+        for (int i = TABLE_SIZE / 2; i < TABLE_SIZE; i++) {
+            assertQuery(format("INSERT INTO simple_key (id, val) VALUES ({}, 
DEFAULT)", i))
+                    .matches(containsSubPlan("KeyValueModify"))
+                    .returns(1L)
+                    .check();
+        }
+
+        for (int i = 0; i < TABLE_SIZE; i++) {
+            assertQuery("SELECT * FROM simple_key WHERE id = ?")
+                    .withParams(i)
+                    .returns(i, 42)
+                    .check();
+        }
+    }
+
     @Test
     void insertDynamicParamsSimpleKey() {
         for (int i = 0; i < TABLE_SIZE; i++) {
@@ -83,6 +147,24 @@ public class ItSqlUsesKeyValuePutTest extends 
BaseSqlIntegrationTest {
         }
     }
 
+    @Test
+    void insertExpressionSimpleKey() {
+        for (int i = 0; i < TABLE_SIZE; i++) {
+            assertQuery("INSERT INTO simple_key VALUES (?, CASE WHEN ? % 2 = 0 
THEN ? * 3 ELSE ? * 2 END)")
+                    .withParams(i, /* case predicate */ i, /* then branch */ 
i, /* else branch */ i)
+                    .matches(containsSubPlan("KeyValueModify"))
+                    .returns(1L)
+                    .check();
+        }
+
+        for (int i = 0; i < TABLE_SIZE; i++) {
+            assertQuery("SELECT * FROM simple_key WHERE id = ?")
+                    .withParams(i)
+                    .returns(i, i % 2 == 0 ? i * 3 : i * 2)
+                    .check();
+        }
+    }
+
     @Test
     void insertSimpleKeyWithCast() {
         for (int i = 0; i < TABLE_SIZE; i++) {
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgnitePlanner.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgnitePlanner.java
index d8417b9af3..8b39e99baf 100644
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgnitePlanner.java
+++ 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgnitePlanner.java
@@ -337,7 +337,7 @@ public class IgnitePlanner implements Planner, 
RelOptTable.ViewExpander {
     /** {@inheritDoc} */
     @Override
     public RelRoot rel(SqlNode sql) {
-        SqlToRelConverter sqlToRelConverter = sqlToRelConverter(validator(), 
catalogReader, sqlToRelConverterCfg);
+        SqlToRelConverter sqlToRelConverter = sqlToRelConverter();
 
         return sqlToRelConverter.convertQuery(sql, false, true);
     }
@@ -603,11 +603,16 @@ public class IgnitePlanner implements Planner, 
RelOptTable.ViewExpander {
         return relShuttle.visit(rel);
     }
 
-    private SqlToRelConverter sqlToRelConverter(SqlValidator validator, 
CalciteCatalogReader reader,
+    private IgniteSqlToRelConvertor sqlToRelConverter(SqlValidator validator, 
CalciteCatalogReader reader,
             SqlToRelConverter.Config config) {
         return new IgniteSqlToRelConvertor(this, validator, reader, cluster(), 
convertletTbl, config);
     }
 
+    /** Returns converter from ast to rel node tree. */
+    public IgniteSqlToRelConvertor sqlToRelConverter() {
+        return sqlToRelConverter(validator(), catalogReader, 
sqlToRelConverterCfg);
+    }
+
     /**
      * Sets names of the rules which should be excluded from query 
optimization pipeline.
      *
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteSqlToRelConvertor.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteSqlToRelConvertor.java
index 5be7cb7d2d..2b6e480ba4 100644
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteSqlToRelConvertor.java
+++ 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteSqlToRelConvertor.java
@@ -50,6 +50,7 @@ import org.apache.calcite.sql.validate.SqlValidatorImpl;
 import org.apache.calcite.sql.validate.SqlValidatorNamespace;
 import org.apache.calcite.sql.validate.SqlValidatorScope;
 import org.apache.calcite.sql.validate.SqlValidatorUtil;
+import org.apache.calcite.sql2rel.InitializerContext;
 import org.apache.calcite.sql2rel.SqlRexConvertletTable;
 import org.apache.calcite.sql2rel.SqlToRelConverter;
 import org.apache.calcite.tools.RelBuilder;
@@ -59,7 +60,7 @@ import 
org.apache.ignite.internal.sql.engine.schema.IgniteDataSource;
 import org.jetbrains.annotations.Nullable;
 
 /** Converts a SQL parse tree into a relational algebra operators. */
-public class IgniteSqlToRelConvertor extends SqlToRelConverter {
+public class IgniteSqlToRelConvertor extends SqlToRelConverter implements 
InitializerContext {
     private final Deque<SqlCall> datasetStack = new ArrayDeque<>();
 
     private RelBuilder relBuilder;
@@ -95,6 +96,11 @@ public class IgniteSqlToRelConvertor extends 
SqlToRelConverter {
         return rel;
     }
 
+    @Override
+    public SqlNode validateExpression(RelDataType rowType, SqlNode expr) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
     private static class DefaultChecker extends SqlShuttle {
         private boolean hasDefaults(SqlCall call) {
             try {
@@ -307,7 +313,7 @@ public class IgniteSqlToRelConvertor extends 
SqlToRelConverter {
     // replaced with similar one but accepting lamda instead of
     // plain string.
     @Override
-    protected RelOptTable getTargetTable(SqlNode call) {
+    public RelOptTable getTargetTable(SqlNode call) {
         final SqlValidatorNamespace targetNs = getNamespace(call);
         SqlValidatorNamespace namespace;
         if (targetNs.isWrapperFor(SqlValidatorImpl.DmlNamespace.class)) {
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/PlannerHelper.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/PlannerHelper.java
index 92b99a8312..093c58f7d6 100644
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/PlannerHelper.java
+++ 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/PlannerHelper.java
@@ -19,13 +19,17 @@ package org.apache.ignite.internal.sql.engine.prepare;
 
 import static 
org.apache.ignite.internal.sql.engine.hint.IgniteHint.DISABLE_RULE;
 import static 
org.apache.ignite.internal.sql.engine.hint.IgniteHint.ENFORCE_JOIN_ORDER;
+import static 
org.apache.ignite.internal.sql.engine.util.Commons.fastQueryOptimizationEnabled;
 import static org.apache.ignite.internal.sql.engine.util.Commons.shortRuleName;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import org.apache.calcite.plan.RelOptPlanner.CannotPlanException;
+import org.apache.calcite.plan.RelOptTable;
 import org.apache.calcite.plan.RelOptUtil;
 import org.apache.calcite.plan.RelTraitSet;
 import org.apache.calcite.rel.RelCollations;
@@ -36,17 +40,30 @@ import org.apache.calcite.rel.logical.LogicalCorrelate;
 import org.apache.calcite.rel.rules.CoreRules;
 import org.apache.calcite.rex.RexBuilder;
 import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.sql.SqlBasicCall;
+import org.apache.calcite.sql.SqlCall;
+import org.apache.calcite.sql.SqlIdentifier;
+import org.apache.calcite.sql.SqlInsert;
+import org.apache.calcite.sql.SqlKind;
 import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.util.SqlShuttle;
+import org.apache.calcite.util.ControlFlowException;
 import org.apache.calcite.util.Pair;
 import org.apache.ignite.internal.logger.IgniteLogger;
 import org.apache.ignite.internal.logger.Loggers;
 import org.apache.ignite.internal.sql.engine.hint.Hints;
 import org.apache.ignite.internal.sql.engine.rel.IgniteConvention;
+import org.apache.ignite.internal.sql.engine.rel.IgniteKeyValueModify;
+import 
org.apache.ignite.internal.sql.engine.rel.IgniteKeyValueModify.Operation;
 import org.apache.ignite.internal.sql.engine.rel.IgniteProject;
 import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
+import org.apache.ignite.internal.sql.engine.schema.ColumnDescriptor;
+import org.apache.ignite.internal.sql.engine.schema.IgniteTable;
+import org.apache.ignite.internal.sql.engine.schema.TableDescriptor;
 import org.apache.ignite.internal.sql.engine.trait.IgniteDistributions;
 import org.apache.ignite.lang.ErrorGroups.Common;
 import org.apache.ignite.sql.SqlException;
+import org.jetbrains.annotations.Nullable;
 
 /**
  * Utility class that encapsulates the query optimization pipeline.
@@ -83,6 +100,12 @@ public final class PlannerHelper {
      */
     public static IgniteRel optimize(SqlNode sqlNode, IgnitePlanner planner) {
         try {
+            IgniteRel result = tryOptimizeFast(sqlNode, planner);
+
+            if (result != null) {
+                return result;
+            }
+
             // Convert to Relational operators graph
             RelRoot root = planner.rel(sqlNode);
 
@@ -137,20 +160,20 @@ public final class PlannerHelper {
                     .replace(root.collation == null ? RelCollations.EMPTY : 
root.collation)
                     .simplify();
 
-            IgniteRel igniteRel = planner.transform(PlannerPhase.OPTIMIZATION, 
desired, rel);
+            result = planner.transform(PlannerPhase.OPTIMIZATION, desired, 
rel);
 
             if (!root.isRefTrivial()) {
                 List<RexNode> projects = new ArrayList<>();
-                RexBuilder rexBuilder = igniteRel.getCluster().getRexBuilder();
+                RexBuilder rexBuilder = result.getCluster().getRexBuilder();
 
                 for (int field : Pair.left(root.fields)) {
-                    projects.add(rexBuilder.makeInputRef(igniteRel, field));
+                    projects.add(rexBuilder.makeInputRef(result, field));
                 }
 
-                igniteRel = new IgniteProject(igniteRel.getCluster(), desired, 
igniteRel, projects, root.validatedRowType);
+                result = new IgniteProject(result.getCluster(), desired, 
result, projects, root.validatedRowType);
             }
 
-            return igniteRel;
+            return result;
         } catch (Throwable ex) {
             if (LOG.isDebugEnabled()) {
                 LOG.debug("Unexpected error at query optimizer", ex);
@@ -168,6 +191,88 @@ public final class PlannerHelper {
         }
     }
 
+    private static @Nullable IgniteRel tryOptimizeFast(SqlNode sqlNode, 
IgnitePlanner planner) {
+        if (!fastQueryOptimizationEnabled()) {
+            return null;
+        }
+
+        if (sqlNode instanceof SqlInsert) {
+            return tryOptimizeInsert((SqlInsert) sqlNode, planner);
+        }
+
+        return null;
+    }
+
+    private static @Nullable IgniteRel tryOptimizeInsert(SqlInsert insertNode, 
IgnitePlanner planner) {
+        SqlNode sourceNode = insertNode.getSource();
+
+        if (!(sourceNode instanceof SqlBasicCall && sourceNode.getKind() == 
SqlKind.VALUES)) {
+            // only simple `INSERT INTO ... VALUES (...)` statement is 
supported at the moment
+            return null;
+        }
+
+        List<SqlNode> rowConstructors = ((SqlBasicCall) 
sourceNode).getOperandList();
+
+        if (rowConstructors.size() != 1) {
+            // multirow insert currently are not supported by 
IgniteKeyValueModify 
+            return null;
+        }
+
+        IgniteSqlToRelConvertor converter = planner.sqlToRelConverter();
+        RelOptTable targetTable = converter.getTargetTable(insertNode);
+        IgniteTable igniteTable = targetTable.unwrap(IgniteTable.class);
+
+        assert igniteTable != null;
+
+        TableDescriptor descriptor = igniteTable.descriptor();
+        SqlBasicCall rowConstructor = (SqlBasicCall) rowConstructors.get(0);
+
+        Map<String, RexNode> columnToExpression = new HashMap<>();
+        for (int i = 0; i < rowConstructor.getOperandList().size(); i++) {
+            String columnName = ((SqlIdentifier) 
insertNode.getTargetColumnList().get(i)).getSimple();
+            SqlNode operand = rowConstructor.operand(i);
+
+            if (operand.getKind() == SqlKind.DEFAULT) {
+                // We don't need special processing for explicit default.
+                // Let's just skip it, default value will be resolved in the
+                // next for-loop
+                continue;
+            }
+
+            if (SubQueryChecker.hasSubQuery(operand)) {
+                // can't deal with sub-query
+                return null;
+            }
+
+            RexNode expression = converter.convertExpression(operand);
+
+            columnToExpression.put(columnName, expression);
+        }
+
+        List<RexNode> expressions = new ArrayList<>();
+        for (ColumnDescriptor column : descriptor) {
+            if (column.virtual()) {
+                continue;
+            }
+
+            RexNode expression = columnToExpression.get(column.name());
+
+            if (expression == null) {
+                expression = descriptor.newColumnDefaultValue(targetTable, 
column.logicalIndex(), converter);
+            }
+
+            expressions.add(expression);
+        }
+
+        return new IgniteKeyValueModify(
+                planner.cluster(),
+                planner.cluster().traitSetOf(IgniteConvention.INSTANCE),
+                targetTable,
+                Operation.PUT,
+                expressions
+        );
+    }
+
     private static boolean hasTooMuchJoins(RelNode rel) {
         JoinSizeFinder joinSizeFinder = new JoinSizeFinder();
 
@@ -220,4 +325,26 @@ public final class PlannerHelper {
             return Math.max(countOfSources, maxCountOfSourcesInSubQuery);
         }
     }
+
+    private static class SubQueryChecker extends SqlShuttle {
+        private static final SubQueryChecker INSTANCE = new SubQueryChecker();
+
+        static boolean hasSubQuery(SqlNode node) {
+            try {
+                node.accept(INSTANCE);
+            } catch (ControlFlowException e) {
+                return true;
+            }
+
+            return false;
+        }
+
+        @Override public @Nullable SqlNode visit(SqlCall call) {
+            if (call.getKind() == SqlKind.SCALAR_QUERY) {
+                throw new ControlFlowException();
+            }
+
+            return super.visit(call);
+        }
+    }
 }
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/Commons.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/Commons.java
index b53d2a719d..808554d65e 100644
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/Commons.java
+++ 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/Commons.java
@@ -729,6 +729,18 @@ public final class Commons {
         return IgniteSystemProperties.getBoolean("IMPLICIT_PK_ENABLED", false);
     }
 
+    /**
+     * Checks whether a fast path optimizations are enabled or not.
+     *
+     * <p>Note: for test purpose only.
+     *
+     * @return A {@code true} if fast path optimizations are enabled, {@code 
false} otherwise.
+     */
+    public static boolean fastQueryOptimizationEnabled() {
+        // TODO: https://issues.apache.org/jira/browse/IGNITE-22821 replace 
with feature toggle
+        return 
IgniteSystemProperties.getBoolean("FAST_QUERY_OPTIMIZATION_ENABLED", true);
+    }
+
     /**
      * Returns a short version of a rule description.
      *
diff --git 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/DmlPlannerTest.java
 
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/DmlPlannerTest.java
index c3c4e6d5e3..526c23d9ba 100644
--- 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/DmlPlannerTest.java
+++ 
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/DmlPlannerTest.java
@@ -31,6 +31,7 @@ import 
org.apache.ignite.internal.sql.engine.schema.IgniteTable;
 import org.apache.ignite.internal.sql.engine.trait.IgniteDistribution;
 import org.apache.ignite.internal.sql.engine.trait.IgniteDistributions;
 import org.apache.ignite.internal.testframework.IgniteTestUtils;
+import org.apache.ignite.internal.testframework.WithSystemProperty;
 import org.apache.ignite.internal.type.NativeTypes;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
@@ -39,6 +40,7 @@ import org.junit.jupiter.params.provider.MethodSource;
 /**
  * Tests to verify multi-step versions of DML plans.
  */
+@WithSystemProperty(key = "FAST_QUERY_OPTIMIZATION_ENABLED", value = "false")
 public class DmlPlannerTest extends AbstractPlannerTest {
     /**
      * Test for INSERT .. VALUES when table has a single distribution.
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 1376a6b8fa..6f0bdf8ca6 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
@@ -27,6 +27,7 @@ import 
org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
 import org.apache.ignite.internal.sql.engine.util.Commons;
 import org.apache.ignite.internal.sql.engine.util.StatementChecker;
 import org.apache.ignite.internal.sql.engine.util.TypeUtils;
+import org.apache.ignite.internal.testframework.WithSystemProperty;
 import org.apache.ignite.internal.type.NativeType;
 import org.apache.ignite.internal.type.NativeTypes;
 import org.apache.ignite.internal.type.VarlenNativeType;
@@ -38,6 +39,7 @@ import org.junit.jupiter.api.TestFactory;
 /**
  * Test cases for dynamic parameters.
  */
+@WithSystemProperty(key = "FAST_QUERY_OPTIMIZATION_ENABLED", value = "false")
 public class DynamicParametersTest extends AbstractPlannerTest {
 
     /**
diff --git 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/ImplicitCastsTest.java
 
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/ImplicitCastsTest.java
index 06e8890933..357eebb85e 100644
--- 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/ImplicitCastsTest.java
+++ 
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/ImplicitCastsTest.java
@@ -51,6 +51,7 @@ import 
org.apache.ignite.internal.sql.engine.trait.IgniteDistributions;
 import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
 import org.apache.ignite.internal.sql.engine.util.NativeTypeValues;
 import org.apache.ignite.internal.sql.engine.util.StatementChecker;
+import org.apache.ignite.internal.testframework.WithSystemProperty;
 import org.apache.ignite.internal.type.NativeTypes;
 import org.jetbrains.annotations.Nullable;
 import org.junit.jupiter.api.DynamicTest;
@@ -62,6 +63,7 @@ import org.junit.jupiter.params.provider.MethodSource;
 /**
  * Type coercion related tests that ensure that the necessary casts are placed 
where it is necessary.
  */
+@WithSystemProperty(key = "FAST_QUERY_OPTIMIZATION_ENABLED", value = "false")
 public class ImplicitCastsTest extends AbstractPlannerTest {
     private static IgniteTable tableWithColumn(String tableName, String 
columnName, RelDataType columnType) {
         return TestBuilders.table()

Reply via email to