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 2cb493871f IGNITE-24134 Sql. Improve performance of KV plan in SQL
(#4986)
2cb493871f is described below
commit 2cb493871f4f0617c60197e922d621a4b37b44b5
Author: korlov42 <[email protected]>
AuthorDate: Mon Dec 30 14:56:02 2024 +0200
IGNITE-24134 Sql. Improve performance of KV plan in SQL (#4986)
---
.../sql/engine/ItSqlUsesKeyValueGetTest.java | 2 +-
.../engine/ItSqlUsesSelectCountOptimizedTest.java | 4 +-
...tCastToIntWithoutFastQueryOptimizationTest.java | 7 +
.../internal/sql/engine/prepare/CacheKey.java | 19 +-
.../sql/engine/prepare/KeyValueGetPlan.java | 191 ++++++++++++++-------
.../sql/engine/prepare/KeyValueModifyPlan.java | 58 +++++--
.../ignite/internal/sql/engine/util/Commons.java | 20 ++-
.../sql/engine/planner/DmlPlannerTest.java | 8 +
.../sql/engine/planner/DynamicParametersTest.java | 7 +
.../sql/engine/planner/ImplicitCastsTest.java | 9 +
.../planner/PartitionPruningMetadataTest.java | 9 +
.../sql/engine/planner/SelectCountPlannerTest.java | 3 +
.../internal/sql/engine/util/QueryCheckerTest.java | 6 +
13 files changed, 263 insertions(+), 80 deletions(-)
diff --git
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSqlUsesKeyValueGetTest.java
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSqlUsesKeyValueGetTest.java
index f4d8d30168..dd8f4b7f7f 100644
---
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSqlUsesKeyValueGetTest.java
+++
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSqlUsesKeyValueGetTest.java
@@ -32,7 +32,7 @@ public class ItSqlUsesKeyValueGetTest 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);"
diff --git
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSqlUsesSelectCountOptimizedTest.java
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSqlUsesSelectCountOptimizedTest.java
index 9897fa2f58..42f14884f1 100644
---
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSqlUsesSelectCountOptimizedTest.java
+++
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItSqlUsesSelectCountOptimizedTest.java
@@ -44,7 +44,8 @@ public class ItSqlUsesSelectCountOptimizedTest extends
BaseSqlIntegrationTest {
@BeforeEach
@AfterEach
public void resetFastOpt() {
- System.setProperty("FAST_QUERY_OPTIMIZATION_ENABLED",
String.valueOf(Commons.fastQueryOptimizationEnabled()));
+ System.clearProperty("FAST_QUERY_OPTIMIZATION_ENABLED");
+ Commons.resetFastQueryOptimizationFlag();
}
@Test
@@ -119,6 +120,7 @@ public class ItSqlUsesSelectCountOptimizedTest extends
BaseSqlIntegrationTest {
// Disable fast query optimization
// TODO: https://issues.apache.org/jira/browse/IGNITE-22821 replace
with feature toggle
System.setProperty("FAST_QUERY_OPTIMIZATION_ENABLED", "false");
+ Commons.resetFastQueryOptimizationFlag();
assertQuery("SELECT COUNT(*) FROM test")
.matches(QueryChecker.containsSubPlan("Aggregate"))
diff --git
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/ItCastToIntWithoutFastQueryOptimizationTest.java
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/ItCastToIntWithoutFastQueryOptimizationTest.java
index 343fa13807..1e57d91f1c 100644
---
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/ItCastToIntWithoutFastQueryOptimizationTest.java
+++
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/ItCastToIntWithoutFastQueryOptimizationTest.java
@@ -19,6 +19,8 @@ package org.apache.ignite.internal.sql.engine.datatypes;
import org.apache.ignite.internal.sql.engine.util.Commons;
import org.apache.ignite.internal.testframework.WithSystemProperty;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
/**
* Set of tests to ensure correctness of CAST expression to INTEGER
@@ -29,4 +31,9 @@ import
org.apache.ignite.internal.testframework.WithSystemProperty;
*/
@WithSystemProperty(key = "FAST_QUERY_OPTIMIZATION_ENABLED", value = "false")
public class ItCastToIntWithoutFastQueryOptimizationTest extends
ItCastToIntTest {
+ @BeforeAll
+ @AfterAll
+ public static void resetFlag() {
+ Commons.resetFastQueryOptimizationFlag();
+ }
}
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/CacheKey.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/CacheKey.java
index 6a58ce4321..1b7f97c6a4 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/CacheKey.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/CacheKey.java
@@ -39,6 +39,8 @@ public class CacheKey {
private final Object[] paramTypes;
+ private int hashCode = 0;
+
/**
* Constructor.
*
@@ -87,11 +89,16 @@ public class CacheKey {
@Override
public int hashCode() {
- int result = catalogVersion;
- result = 31 * result + schemaName.hashCode();
- result = 31 * result + query.hashCode();
- result = 31 * result + (contextKey != null ? contextKey.hashCode() :
0);
- result = 31 * result + Arrays.deepHashCode(paramTypes);
- return result;
+ if (hashCode == 0) {
+ int result = catalogVersion;
+ result = 31 * result + schemaName.hashCode();
+ result = 31 * result + query.hashCode();
+ result = 31 * result + (contextKey != null ? contextKey.hashCode()
: 0);
+ result = 31 * result + Arrays.deepHashCode(paramTypes);
+
+ hashCode = result;
+ }
+
+ return hashCode;
}
}
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/KeyValueGetPlan.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/KeyValueGetPlan.java
index 7f136e084b..a6f699f19c 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/KeyValueGetPlan.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/KeyValueGetPlan.java
@@ -17,13 +17,15 @@
package org.apache.ignite.internal.sql.engine.prepare;
+import static org.apache.ignite.internal.sql.engine.util.Commons.cast;
+
+import java.util.BitSet;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.function.BiFunction;
-import java.util.function.Function;
import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rex.RexNode;
@@ -70,13 +72,10 @@ public class KeyValueGetPlan implements ExplainablePlan,
ExecutablePlan {
private final ResultSetMetadata meta;
private final ParameterMetadata parameterMetadata;
- KeyValueGetPlan(
- PlanId id,
- int catalogVersion,
- IgniteKeyValueGet lookupNode,
- ResultSetMetadata meta,
- ParameterMetadata parameterMetadata
- ) {
+ private volatile Performable<?> operation;
+
+ KeyValueGetPlan(PlanId id, int catalogVersion, IgniteKeyValueGet
lookupNode, ResultSetMetadata meta,
+ ParameterMetadata parameterMetadata) {
this.id = id;
this.catalogVersion = catalogVersion;
this.lookupNode = lookupNode;
@@ -128,66 +127,129 @@ public class KeyValueGetPlan implements ExplainablePlan,
ExecutablePlan {
return lookupNode;
}
- @Override
- public <RowT> AsyncCursor<InternalSqlRow> execute(
- ExecutionContext<RowT> ctx,
- InternalTransaction tx,
- ExecutableTableRegistry tableRegistry,
- @Nullable QueryPrefetchCallback firstPageReadyCallback
- ) {
+ private <RowT> Performable<RowT> operation(ExecutionContext<RowT> ctx,
ExecutableTableRegistry tableRegistry) {
+ Performable<RowT> operation = cast(this.operation);
+
+ if (operation != null) {
+ return operation;
+ }
+
IgniteTable sqlTable = table();
- ExecutableTable execTable = tableRegistry.getTable(catalogVersion,
sqlTable.id());
+ ExecutableTable executableTable =
tableRegistry.getTable(catalogVersion, sqlTable.id());
+ ScannableTable scannableTable = executableTable.scannableTable();
ImmutableBitSet requiredColumns = lookupNode.requiredColumns();
RexNode filterExpr = lookupNode.condition();
List<RexNode> projectionExpr = lookupNode.projects();
- List<RexNode> keyExpressions = lookupNode.keyExpressions();
RelDataType rowType = sqlTable.getRowType(Commons.typeFactory(),
requiredColumns);
- SqlRowProvider<RowT> keySupplier = ctx.expressionFactory()
- .rowSource(keyExpressions);
- SqlPredicate<RowT> filter = filterExpr == null ? null :
ctx.expressionFactory()
- .predicate(filterExpr, rowType);
- SqlProjection<RowT> projection = projectionExpr == null ? null :
ctx.expressionFactory()
- .project(projectionExpr, rowType);
+ SqlPredicate<RowT> filter = filterExpr == null ? null :
ctx.expressionFactory().predicate(filterExpr, rowType);
+ SqlProjection<RowT> projection = projectionExpr == null ? null :
ctx.expressionFactory().project(projectionExpr, rowType);
RowHandler<RowT> rowHandler = ctx.rowHandler();
RowSchema rowSchema =
TypeUtils.rowSchemaFromRelTypes(RelOptUtil.getFieldTypeList(rowType));
RowFactory<RowT> rowFactory = rowHandler.factory(rowSchema);
+ List<RexNode> keyExpressions = lookupNode.keyExpressions();
+ SqlRowProvider<RowT> keySupplier =
ctx.expressionFactory().rowSource(keyExpressions);
+
RelDataType resultType = lookupNode.getRowType();
BiFunction<Integer, Object, Object> internalTypeConverter =
TypeUtils.resultTypeConverter(ctx, resultType);
- ScannableTable scannableTable = execTable.scannableTable();
- Function<RowT, Iterator<InternalSqlRow>> postProcess = row -> {
- if (row == null) {
- return Collections.emptyIterator();
- }
-
- if (filter != null && !filter.test(ctx, row)) {
- return Collections.emptyIterator();
- }
-
- if (projection != null) {
- row = projection.project(ctx, row);
- }
-
- return List.<InternalSqlRow>of(
- new InternalSqlRowImpl<>(row, rowHandler,
internalTypeConverter)
- ).iterator();
- };
-
- CompletableFuture<RowT> lookupResult = scannableTable.primaryKeyLookup(
- ctx, tx, rowFactory, keySupplier.get(ctx),
requiredColumns.toBitSet()
- );
-
- CompletableFuture<Iterator<InternalSqlRow>> result;
- if (projection == null && filter == null) {
- // no arbitrary computations, should be safe to proceed execution
on
- // thread that completes the future
- result = lookupResult.thenApply(postProcess);
- } else {
+ operation = filter == null && projection == null ? new
SimpleLookupExecution<>(scannableTable, rowHandler, rowFactory,
+ keySupplier, requiredColumns.toBitSet(), internalTypeConverter)
+ : new FilterableProjectableLookupExecution<>(scannableTable,
rowHandler, rowFactory, keySupplier,
+ filter, projection, requiredColumns.toBitSet(),
internalTypeConverter);
+
+ this.operation = operation;
+
+ return operation;
+ }
+
+ @Override
+ public <RowT> AsyncCursor<InternalSqlRow> execute(
+ ExecutionContext<RowT> ctx,
+ InternalTransaction tx,
+ ExecutableTableRegistry tableRegistry,
+ @Nullable QueryPrefetchCallback firstPageReadyCallback
+ ) {
+ Performable<RowT> operation = operation(ctx, tableRegistry);
+
+ CompletableFuture<Iterator<InternalSqlRow>> result =
operation.perform(ctx, tx);
+
+ if (firstPageReadyCallback != null) {
+ result.whenComplete((res, err) ->
firstPageReadyCallback.onPrefetchComplete(err));
+ }
+
+ ctx.scheduleTimeout(result);
+
+ return new AsyncWrapper<>(result, Runnable::run);
+ }
+
+ private static class SimpleLookupExecution<RowT> extends Performable<RowT>
{
+ private final ScannableTable table;
+ private final RowHandler<RowT> rowHandler;
+ private final RowFactory<RowT> tableRowFactory;
+ private final SqlRowProvider<RowT> keySupplier;
+ private final BitSet requiredColumns;
+ private final BiFunction<Integer, Object, Object>
internalTypeConverter;
+
+ private SimpleLookupExecution(ScannableTable table, RowHandler<RowT>
rowHandler, RowFactory<RowT> tableRowFactory,
+ SqlRowProvider<RowT> keySupplier, BitSet requiredColumns,
BiFunction<Integer, Object, Object> internalTypeConverter) {
+ this.table = table;
+ this.rowHandler = rowHandler;
+ this.tableRowFactory = tableRowFactory;
+ this.keySupplier = keySupplier;
+ this.requiredColumns = requiredColumns;
+ this.internalTypeConverter = internalTypeConverter;
+ }
+
+ @Override
+ CompletableFuture<Iterator<InternalSqlRow>>
perform(ExecutionContext<RowT> ctx, InternalTransaction tx) {
+ RowT key = keySupplier.get(ctx);
+ return table.primaryKeyLookup(ctx, tx, tableRowFactory, key,
requiredColumns).thenApply(row -> {
+ if (row == null) {
+ return Collections.emptyIterator();
+ }
+
+ return List.<InternalSqlRow>of(new InternalSqlRowImpl<>(row,
rowHandler, internalTypeConverter)).iterator();
+ });
+ }
+ }
+
+ private static class FilterableProjectableLookupExecution<RowT> extends
Performable<RowT> {
+ private final ScannableTable table;
+ private final RowHandler<RowT> rowHandler;
+ private final RowFactory<RowT> tableRowFactory;
+ private final SqlRowProvider<RowT> keySupplier;
+ private final @Nullable SqlPredicate<RowT> filter;
+ private final @Nullable SqlProjection<RowT> projection;
+ private final @Nullable BitSet requiredColumns;
+ private final BiFunction<Integer, Object, Object>
internalTypeConverter;
+
+ private FilterableProjectableLookupExecution(
+ ScannableTable table,
+ RowHandler<RowT> rowHandler,
+ RowFactory<RowT> tableRowFactory,
+ SqlRowProvider<RowT> keySupplier,
+ @Nullable SqlPredicate<RowT> filter,
+ @Nullable SqlProjection<RowT> projection,
+ @Nullable BitSet requiredColumns,
+ BiFunction<Integer, Object, Object> internalTypeConverter
+ ) {
+ this.table = table;
+ this.rowHandler = rowHandler;
+ this.tableRowFactory = tableRowFactory;
+ this.keySupplier = keySupplier;
+ this.filter = filter;
+ this.projection = projection;
+ this.requiredColumns = requiredColumns;
+ this.internalTypeConverter = internalTypeConverter;
+ }
+
+ @Override
+ CompletableFuture<Iterator<InternalSqlRow>>
perform(ExecutionContext<RowT> ctx, InternalTransaction tx) {
Executor executor = task -> ctx.execute(task::run, error -> {
// this executor is used to process future chain, so any
unhandled exception
// should be wrapped with CompletionException and returned as
a result, implying
@@ -196,16 +258,27 @@ public class KeyValueGetPlan implements ExplainablePlan,
ExecutablePlan {
LOG.error("Unexpected error", error);
});
- result = lookupResult.thenApplyAsync(postProcess, executor);
- }
+ RowT key = keySupplier.get(ctx);
+ return table.primaryKeyLookup(ctx, tx, tableRowFactory, key,
requiredColumns).thenApplyAsync(row -> {
+ if (row == null) {
+ return Collections.emptyIterator();
+ }
- if (firstPageReadyCallback != null) {
- result.whenComplete((res, err) ->
firstPageReadyCallback.onPrefetchComplete(err));
- }
+ if (filter != null && !filter.test(ctx, row)) {
+ return Collections.emptyIterator();
+ }
- ctx.scheduleTimeout(result);
+ if (projection != null) {
+ row = projection.project(ctx, row);
+ }
- return new AsyncWrapper<>(result, Runnable::run);
+ return List.<InternalSqlRow>of(new InternalSqlRowImpl<>(row,
rowHandler, internalTypeConverter)).iterator();
+ }, executor);
+ }
+ }
+
+ private abstract static class Performable<RowT> {
+ abstract CompletableFuture<Iterator<InternalSqlRow>>
perform(ExecutionContext<RowT> ctx, @Nullable InternalTransaction tx);
}
public int catalogVersion() {
diff --git
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/KeyValueModifyPlan.java
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/KeyValueModifyPlan.java
index fe7a76f2a1..432a154fec 100644
---
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/KeyValueModifyPlan.java
+++
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/KeyValueModifyPlan.java
@@ -17,6 +17,8 @@
package org.apache.ignite.internal.sql.engine.prepare;
+import static org.apache.ignite.internal.sql.engine.util.Commons.cast;
+
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@@ -54,6 +56,8 @@ public class KeyValueModifyPlan implements ExplainablePlan,
ExecutablePlan {
private final ResultSetMetadata meta;
private final ParameterMetadata parameterMetadata;
+ private volatile InsertExecution<?> operation;
+
KeyValueModifyPlan(
PlanId id,
int catalogVersion,
@@ -112,13 +116,13 @@ public class KeyValueModifyPlan implements
ExplainablePlan, ExecutablePlan {
return modifyNode;
}
- @Override
- public <RowT> AsyncCursor<InternalSqlRow> execute(
- ExecutionContext<RowT> ctx,
- InternalTransaction tx,
- ExecutableTableRegistry tableRegistry,
- @Nullable QueryPrefetchCallback firstPageReadyCallback
- ) {
+ private <RowT> InsertExecution<RowT> operation(ExecutionContext<RowT> ctx,
ExecutableTableRegistry tableRegistry) {
+ InsertExecution<RowT> operation = cast(this.operation);
+
+ if (operation != null) {
+ return operation;
+ }
+
IgniteTable sqlTable = table();
ExecutableTable execTable = tableRegistry.getTable(catalogVersion,
sqlTable.id());
@@ -127,11 +131,25 @@ public class KeyValueModifyPlan implements
ExplainablePlan, ExecutablePlan {
SqlRowProvider<RowT> rowSupplier = ctx.expressionFactory()
.rowSource(expressions);
- UpdatableTable updatableTable = execTable.updatableTable();
+ UpdatableTable table = execTable.updatableTable();
+
+ operation = new InsertExecution<>(table, rowSupplier);
+
+ this.operation = operation;
+
+ return operation;
+ }
- CompletableFuture<Iterator<InternalSqlRow>> result =
updatableTable.insert(
- tx, ctx, rowSupplier.get(ctx)
- ).thenApply(none -> List.<InternalSqlRow>of(new
InternalSqlRowSingleLong(1L)).iterator());
+ @Override
+ public <RowT> AsyncCursor<InternalSqlRow> execute(
+ ExecutionContext<RowT> ctx,
+ InternalTransaction tx,
+ ExecutableTableRegistry tableRegistry,
+ @Nullable QueryPrefetchCallback firstPageReadyCallback
+ ) {
+ InsertExecution<RowT> operation = operation(ctx, tableRegistry);
+
+ CompletableFuture<Iterator<InternalSqlRow>> result =
operation.perform(ctx, tx);
if (firstPageReadyCallback != null) {
result.whenComplete((res, err) ->
firstPageReadyCallback.onPrefetchComplete(err));
@@ -142,6 +160,24 @@ public class KeyValueModifyPlan implements
ExplainablePlan, ExecutablePlan {
return new AsyncWrapper<>(result, Runnable::run);
}
+ private static class InsertExecution<RowT> {
+ private final UpdatableTable table;
+ private final SqlRowProvider<RowT> rowSupplier;
+
+ private InsertExecution(
+ UpdatableTable table,
+ SqlRowProvider<RowT> rowSupplier
+ ) {
+ this.table = table;
+ this.rowSupplier = rowSupplier;
+ }
+
+ CompletableFuture<Iterator<InternalSqlRow>>
perform(ExecutionContext<RowT> ctx, InternalTransaction tx) {
+ return table.insert(tx, ctx, rowSupplier.get(ctx))
+ .thenApply(none -> List.<InternalSqlRow>of(new
InternalSqlRowSingleLong(1L)).iterator());
+ }
+ }
+
public int catalogVersion() {
return catalogVersion;
}
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 8f31786abb..a316bb9248 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
@@ -122,6 +122,7 @@ import org.codehaus.commons.compiler.CompilerFactoryFactory;
import org.codehaus.commons.compiler.IClassBodyEvaluator;
import org.codehaus.commons.compiler.ICompilerFactory;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.TestOnly;
/**
* Utility methods.
@@ -191,6 +192,8 @@ public final class Commons {
.traitDefs(DISTRIBUTED_TRAITS_SET)
.build();
+ private static volatile @Nullable Boolean fastOptimizationsEnabled = null;
+
private Commons() {
}
@@ -771,8 +774,21 @@ public final class Commons {
* @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);
+ Boolean enabled = fastOptimizationsEnabled;
+
+ if (enabled == null) {
+ // TODO: https://issues.apache.org/jira/browse/IGNITE-22821
replace with feature toggle
+ enabled =
IgniteSystemProperties.getBoolean("FAST_QUERY_OPTIMIZATION_ENABLED", true);
+
+ fastOptimizationsEnabled = enabled;
+ }
+
+ return enabled;
+ }
+
+ @TestOnly
+ public static void resetFastQueryOptimizationFlag() {
+ fastOptimizationsEnabled = null;
}
/**
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 a5d17c143e..62fa935a32 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
@@ -43,6 +43,8 @@ import
org.apache.ignite.internal.testframework.IgniteTestUtils;
import org.apache.ignite.internal.testframework.WithSystemProperty;
import org.apache.ignite.internal.type.NativeType;
import org.apache.ignite.internal.type.NativeTypes;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
@@ -52,6 +54,12 @@ import org.junit.jupiter.params.provider.MethodSource;
*/
@WithSystemProperty(key = "FAST_QUERY_OPTIMIZATION_ENABLED", value = "false")
public class DmlPlannerTest extends AbstractPlannerTest {
+ @BeforeAll
+ @AfterAll
+ public static void resetFlag() {
+ Commons.resetFastQueryOptimizationFlag();
+ }
+
/**
* 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 c3e81ce48a..25d7d208ee 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
@@ -36,6 +36,8 @@ import org.apache.ignite.internal.type.NativeType;
import org.apache.ignite.internal.type.NativeTypes;
import org.apache.ignite.internal.type.VarlenNativeType;
import org.jetbrains.annotations.Nullable;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestFactory;
@@ -45,6 +47,11 @@ import org.junit.jupiter.api.TestFactory;
*/
@WithSystemProperty(key = "FAST_QUERY_OPTIMIZATION_ENABLED", value = "false")
public class DynamicParametersTest extends AbstractPlannerTest {
+ @BeforeAll
+ @AfterAll
+ public static void resetFlag() {
+ Commons.resetFastQueryOptimizationFlag();
+ }
/**
* This test case triggers "Conversion to relational algebra failed to
preserve datatypes" assertion,
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 697885ca03..4b0edf1232 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
@@ -50,11 +50,14 @@ import
org.apache.ignite.internal.sql.engine.schema.IgniteSchema;
import org.apache.ignite.internal.sql.engine.schema.IgniteTable;
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.Commons;
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.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
import org.junit.jupiter.params.ParameterizedTest;
@@ -153,6 +156,12 @@ public class ImplicitCastsTest extends AbstractPlannerTest
{
return result.stream();
}
+ @BeforeAll
+ @AfterAll
+ public static void resetFlag() {
+ Commons.resetFastQueryOptimizationFlag();
+ }
+
/** MergeSort join - casts are pushed down to children. **/
@ParameterizedTest
@MethodSource("joinColumnTypes")
diff --git
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/PartitionPruningMetadataTest.java
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/PartitionPruningMetadataTest.java
index 0816a75197..8a038dd0d2 100644
---
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/PartitionPruningMetadataTest.java
+++
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/PartitionPruningMetadataTest.java
@@ -40,8 +40,11 @@ import
org.apache.ignite.internal.sql.engine.schema.IgniteSchema;
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.internal.sql.engine.util.Commons;
import org.apache.ignite.internal.testframework.WithSystemProperty;
import org.apache.ignite.internal.type.NativeTypes;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
@@ -110,6 +113,12 @@ public class PartitionPruningMetadataTest extends
AbstractPlannerTest {
.distribution(IgniteDistributions.affinity(List.of(0), 1, 2))
.build());
+ @BeforeAll
+ @AfterAll
+ public static void resetFlag() {
+ Commons.resetFastQueryOptimizationFlag();
+ }
+
/** Basic test cases for partition pruning metadata extractor, select
case. */
@ParameterizedTest(name = "SELECT: {0}")
@EnumSource(TestCaseBasic.class)
diff --git
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/SelectCountPlannerTest.java
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/SelectCountPlannerTest.java
index 3c60edd927..278dcdcd97 100644
---
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/SelectCountPlannerTest.java
+++
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/SelectCountPlannerTest.java
@@ -44,6 +44,7 @@ import
org.apache.ignite.internal.sql.engine.prepare.ExplainPlan;
import org.apache.ignite.internal.sql.engine.prepare.QueryPlan;
import org.apache.ignite.internal.sql.engine.prepare.SelectCountPlan;
import org.apache.ignite.internal.sql.engine.tx.QueryTransactionContext;
+import org.apache.ignite.internal.sql.engine.util.Commons;
import org.apache.ignite.internal.testframework.SystemPropertiesExtension;
import org.apache.ignite.internal.testframework.WithSystemProperty;
import org.junit.jupiter.api.AfterAll;
@@ -78,6 +79,8 @@ public class SelectCountPlannerTest extends
AbstractPlannerTest {
@AfterEach
void clearCatalog() {
+ Commons.resetFastQueryOptimizationFlag();
+
int version = CLUSTER.catalogManager().latestCatalogVersion();
List<CatalogCommand> commands = new ArrayList<>();
diff --git
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/util/QueryCheckerTest.java
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/util/QueryCheckerTest.java
index 03e7240d61..f9a328a3f9 100644
---
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/util/QueryCheckerTest.java
+++
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/util/QueryCheckerTest.java
@@ -66,6 +66,12 @@ public class QueryCheckerTest extends BaseIgniteAbstractTest
{
.nodes(NODE_NAME)
.build();
+ @BeforeAll
+ @AfterAll
+ public static void resetFlag() {
+ Commons.resetFastQueryOptimizationFlag();
+ }
+
@BeforeAll
static void startCluster() {
CLUSTER.start();