This is an automated email from the ASF dual-hosted git repository.
alexpl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push:
new 2de78560a34 IGNITE-27397 SQL Calcite: Add dynamic configuration to
disable a rule globally - Fixes #12595.
2de78560a34 is described below
commit 2de78560a345bbc45f095dac56b8f99f6c9e64d0
Author: Vladimir Steshin <[email protected]>
AuthorDate: Wed Dec 24 15:17:17 2025 +0300
IGNITE-27397 SQL Calcite: Add dynamic configuration to disable a rule
globally - Fixes #12595.
Signed-off-by: Aleksey Plekhanov <[email protected]>
---
.../query/calcite/CalciteQueryProcessor.java | 8 +-
.../calcite/DistributedCalciteConfiguration.java | 97 +++++++-
.../query/calcite/prepare/IgnitePlanner.java | 43 +++-
.../query/calcite/prepare/PrepareServiceImpl.java | 22 +-
.../CalciteQueryProcessorPropertiesTest.java | 244 +++++++++++++++++++++
.../ignite/testsuites/IntegrationTestSuite.java | 2 +
.../DistributedConfigurationProcessor.java | 1 -
.../query/DistributedSqlConfiguration.java | 82 ++++---
.../query/h2/DistributedIndexingConfiguration.java | 45 ++--
9 files changed, 476 insertions(+), 68 deletions(-)
diff --git
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/CalciteQueryProcessor.java
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/CalciteQueryProcessor.java
index 0d357e0c3b0..5f5adbfdb03 100644
---
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/CalciteQueryProcessor.java
+++
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/CalciteQueryProcessor.java
@@ -398,6 +398,7 @@ public class CalciteQueryProcessor extends
GridProcessorAdapter implements Query
/** {@inheritDoc} */
@Override public void onKernalStart(boolean active) {
onStart(ctx,
+ distrCfg,
executionSvc,
mailboxRegistry,
partSvc,
@@ -407,7 +408,8 @@ public class CalciteQueryProcessor extends
GridProcessorAdapter implements Query
mappingSvc,
qryPlanCache,
exchangeSvc,
- qryReg
+ qryReg,
+ prepareSvc
);
started = true;
@@ -419,6 +421,7 @@ public class CalciteQueryProcessor extends
GridProcessorAdapter implements Query
started = false;
onStop(
+ prepareSvc,
qryReg,
executionSvc,
mailboxRegistry,
@@ -428,7 +431,8 @@ public class CalciteQueryProcessor extends
GridProcessorAdapter implements Query
taskExecutor,
mappingSvc,
qryPlanCache,
- exchangeSvc
+ exchangeSvc,
+ distrCfg
);
}
}
diff --git
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/DistributedCalciteConfiguration.java
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/DistributedCalciteConfiguration.java
index 9be7ba34f6c..6eb8c49c458 100644
---
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/DistributedCalciteConfiguration.java
+++
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/DistributedCalciteConfiguration.java
@@ -17,14 +17,109 @@
package org.apache.ignite.internal.processors.query.calcite;
+import java.util.Objects;
+import java.util.stream.Stream;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.internal.GridKernalContext;
+import
org.apache.ignite.internal.processors.configuration.distributed.DistributePropertyListener;
+import
org.apache.ignite.internal.processors.configuration.distributed.DistributedChangeableProperty;
+import
org.apache.ignite.internal.processors.configuration.distributed.DistributedPropertyDispatcher;
+import
org.apache.ignite.internal.processors.configuration.distributed.SimpleDistributedProperty;
import org.apache.ignite.internal.processors.query.DistributedSqlConfiguration;
+import
org.apache.ignite.internal.processors.query.calcite.prepare.QueryPlanCache;
+import org.apache.ignite.internal.processors.query.calcite.util.Commons;
+import org.apache.ignite.internal.processors.query.calcite.util.LifecycleAware;
+import org.apache.ignite.internal.processors.query.calcite.util.Service;
+import org.apache.ignite.internal.util.typedef.F;
+
+import static
org.apache.ignite.internal.cluster.DistributedConfigurationUtils.setDefaultValue;
/** Distributed Calcite-engine configuration. */
-public class DistributedCalciteConfiguration extends
DistributedSqlConfiguration {
+public class DistributedCalciteConfiguration extends
DistributedSqlConfiguration implements Service, LifecycleAware {
+ /** Globally disabled rules property name. */
+ public static final String DISABLED_RULES_PROPERTY_NAME =
"sql.calcite.disabledRules";
+
+ /** Default value of the disabled rules. */
+ public static final String[] DFLT_DISABLED_RULES = new String[0];
+
+ /** Globally disabled rules. */
+ private volatile DistributedChangeableProperty<String[]> disabledRules;
+
+ /** */
+ private QueryPlanCache qryPlanCache;
+
/** */
public DistributedCalciteConfiguration(GridKernalContext ctx, IgniteLogger
log) {
super(ctx, log);
}
+
+ /** {@inheritDoc} */
+ @Override public void onStart(GridKernalContext ctx) {
+ CalciteQueryProcessor proc =
Objects.requireNonNull(Commons.lookupComponent(ctx,
CalciteQueryProcessor.class));
+
+ assert proc != null;
+
+ qryPlanCache = proc.queryPlanCache();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void onStop() {
+ // No-op.
+ }
+
+ /**
+ * @return Globally disabled planning rules.
+ * @see #DISABLED_RULES_PROPERTY_NAME
+ */
+ public String[] disabledRules() {
+ DistributedChangeableProperty<String[]> disabledRules =
this.disabledRules;
+
+ String[] res = disabledRules == null ? DFLT_DISABLED_RULES :
disabledRules.get();
+
+ return res != null ? res : DFLT_DISABLED_RULES;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void onReadyToRegister(DistributedPropertyDispatcher
dispatcher) {
+ super.onReadyToRegister(dispatcher);
+
+ registerProperty(
+ dispatcher,
+ DISABLED_RULES_PROPERTY_NAME,
+ prop -> disabledRules = prop,
+ () -> new SimpleDistributedProperty<>(
+ DISABLED_RULES_PROPERTY_NAME,
+ str -> Stream.of(str.split(",")).map(String::trim).filter(s ->
!s.isBlank()).toArray(String[]::new),
+ "Comma-separated list of Calcite's disabled planning rules.
NOTE: cleans the planning cache on change."
+ ),
+ log
+ );
+
+ disabledRules.addListener(new DistributePropertyListener<>() {
+ @Override public void onUpdate(String name, String[] oldVal,
String[] newVal) {
+ if (oldVal != null && F.compareArrays(oldVal, newVal) != 0) {
+ if (qryPlanCache != null) {
+ if (log.isInfoEnabled()) {
+ log.info("Cleaning Calcite's cache plan by
changing of the property '"
+ + DISABLED_RULES_PROPERTY_NAME + "'.");
+ }
+
+ qryPlanCache.clear();
+ }
+ }
+ }
+ });
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void onReadyToWrite() {
+ super.onReadyToWrite();
+
+ setDefaultValue(disabledRules, DFLT_DISABLED_RULES, log);
+ }
+
+ /** */
+ DistributedChangeableProperty<String[]> disabledRulesProperty() {
+ return disabledRules;
+ }
}
diff --git
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgnitePlanner.java
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgnitePlanner.java
index 4819eafed4c..553ca3ba89a 100644
---
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgnitePlanner.java
+++
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgnitePlanner.java
@@ -21,6 +21,7 @@ import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringWriter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -29,6 +30,8 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
import com.google.common.collect.ImmutableList;
import org.apache.calcite.plan.Context;
import org.apache.calcite.plan.RelOptCluster;
@@ -80,6 +83,7 @@ import org.apache.calcite.sql2rel.SqlToRelConverter;
import org.apache.calcite.tools.FrameworkConfig;
import org.apache.calcite.tools.Planner;
import org.apache.calcite.tools.Program;
+import org.apache.calcite.tools.RuleSet;
import org.apache.calcite.tools.RuleSets;
import org.apache.calcite.tools.ValidationException;
import org.apache.calcite.util.Pair;
@@ -724,16 +728,7 @@ public class IgnitePlanner implements Planner,
RelOptTable.ViewExpander {
if (F.isEmpty(disabledRuleNames))
return;
- ctx.addRulesFilter(rulesSet -> {
- List<RelOptRule> newSet = new ArrayList<>();
-
- for (RelOptRule r : rulesSet) {
- if (!disabledRuleNames.contains(shortRuleName(r.toString())))
- newSet.add(r);
- }
-
- return RuleSets.ofList(newSet);
- });
+ ctx.addRulesFilter(new DisabledRuleFilter(disabledRuleNames));
}
/** */
@@ -746,6 +741,34 @@ public class IgnitePlanner implements Planner,
RelOptTable.ViewExpander {
return ruleDesc.substring(0, pos);
}
+ /** */
+ public static final class DisabledRuleFilter implements Function<RuleSet,
RuleSet> {
+ /** */
+ private final Set<String> ruleNames;
+
+ /** */
+ public DisabledRuleFilter(Collection<String> ruleNames) {
+ this.ruleNames = ruleNames.stream().map(ruleName ->
ruleName.trim().toUpperCase()).collect(Collectors.toSet());
+ }
+
+ /** */
+ public DisabledRuleFilter(String[] ruleNames) {
+ this(Arrays.asList(ruleNames));
+ }
+
+ /** {@inheritDoc} */
+ @Override public RuleSet apply(RuleSet rules) {
+ List<RelOptRule> newSet = new ArrayList<>();
+
+ for (RelOptRule r : rules) {
+ if
(!ruleNames.contains(shortRuleName(r.toString()).toUpperCase()))
+ newSet.add(r);
+ }
+
+ return RuleSets.ofList(newSet);
+ }
+ }
+
/** */
private static class VolcanoPlannerExt extends VolcanoPlanner {
/** */
diff --git
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/PrepareServiceImpl.java
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/PrepareServiceImpl.java
index 276d8e4ee32..af2ac9506bc 100644
---
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/PrepareServiceImpl.java
+++
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/PrepareServiceImpl.java
@@ -18,7 +18,7 @@
package org.apache.ignite.internal.processors.query.calcite.prepare;
import java.util.List;
-
+import java.util.Objects;
import org.apache.calcite.plan.RelOptPlanner;
import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.rel.type.RelDataType;
@@ -35,11 +35,15 @@ import
org.apache.ignite.cache.query.QueryCancelledException;
import org.apache.ignite.internal.GridKernalContext;
import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode;
import org.apache.ignite.internal.processors.query.IgniteSQLException;
+import
org.apache.ignite.internal.processors.query.calcite.CalciteQueryProcessor;
+import
org.apache.ignite.internal.processors.query.calcite.DistributedCalciteConfiguration;
import
org.apache.ignite.internal.processors.query.calcite.prepare.ddl.DdlSqlToCommandConverter;
import org.apache.ignite.internal.processors.query.calcite.rel.IgniteRel;
import
org.apache.ignite.internal.processors.query.calcite.type.IgniteTypeFactory;
import
org.apache.ignite.internal.processors.query.calcite.util.AbstractService;
+import org.apache.ignite.internal.processors.query.calcite.util.Commons;
import org.apache.ignite.internal.processors.query.calcite.util.TypeUtils;
+import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.T2;
import org.jetbrains.annotations.Nullable;
@@ -58,6 +62,9 @@ public class PrepareServiceImpl extends AbstractService
implements PrepareServic
/** */
private final PlanExtractor planExtractor;
+ /** */
+ private DistributedCalciteConfiguration distrCfg;
+
/**
* @param ctx Kernal.
*/
@@ -71,6 +78,12 @@ public class PrepareServiceImpl extends AbstractService
implements PrepareServic
/** {@inheritDoc} */
@Override public void onStart(GridKernalContext ctx) {
super.onStart(ctx);
+
+ CalciteQueryProcessor proc =
Objects.requireNonNull(Commons.lookupComponent(ctx,
CalciteQueryProcessor.class));
+
+ assert proc != null;
+
+ distrCfg = proc.distributedConfiguration();
}
/** {@inheritDoc} */
@@ -80,6 +93,13 @@ public class PrepareServiceImpl extends AbstractService
implements PrepareServic
ctx.planner().reset();
+ assert distrCfg != null;
+
+ String[] disbledRules = distrCfg.disabledRules();
+
+ if (!F.isEmpty(disbledRules))
+ ctx.addRulesFilter(new
IgnitePlanner.DisabledRuleFilter(disbledRules));
+
if (SqlKind.DDL.contains(sqlNode.getKind()))
return prepareDdl(sqlNode, ctx);
diff --git
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/CalciteQueryProcessorPropertiesTest.java
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/CalciteQueryProcessorPropertiesTest.java
new file mode 100644
index 00000000000..02075e5becc
--- /dev/null
+++
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/CalciteQueryProcessorPropertiesTest.java
@@ -0,0 +1,244 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.function.Predicate;
+import javax.management.DynamicMBean;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.management.api.CommandMBean;
+import
org.apache.ignite.internal.processors.configuration.distributed.DistributedChangeableProperty;
+import org.apache.ignite.internal.processors.query.IgniteSQLException;
+import
org.apache.ignite.internal.processors.query.calcite.integration.AbstractBasicIntegrationTest;
+import
org.apache.ignite.internal.processors.query.calcite.rule.logical.ExposeIndexRule;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.G;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.jetbrains.annotations.Nullable;
+import org.junit.Test;
+
+import static
org.apache.ignite.internal.processors.query.calcite.QueryChecker.containsIndexScan;
+import static
org.apache.ignite.internal.processors.query.calcite.QueryChecker.containsSubPlan;
+import static org.apache.ignite.testframework.GridTestUtils.waitForCondition;
+import static org.hamcrest.CoreMatchers.not;
+
+/** */
+public class CalciteQueryProcessorPropertiesTest extends
AbstractBasicIntegrationTest {
+ /** {@inheritDoc} */
+ @Override protected int nodeCount() {
+ return 2;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTest() throws Exception {
+
changeDistributedProperty(DistributedCalciteConfiguration.DISABLED_RULES_PROPERTY_NAME,
" ",
+ pVal -> F.compareArrays(pVal, new String[0]) == 0);
+ }
+
+ /** */
+ @Test
+ public void testDisableRuleDistributedPropertyCommand() throws Exception {
+ String propName =
DistributedCalciteConfiguration.DISABLED_RULES_PROPERTY_NAME;
+
+ for (Ignite ig : G.allGrids()) {
+ DistributedChangeableProperty<String[]> prop =
distributedProperty(ig, propName);
+
+ assertNotNull(prop);
+ assertNotNull(prop.get());
+ assertTrue(prop.get().length == 0);
+ }
+
+ // Check simple value.
+ changeDistributedProperty(propName, "ExposeIndexRule",
+ pVal -> F.compareArrays(new String[] {"ExposeIndexRule"}, pVal) ==
0);
+
+ // Check setting with spaces.
+ changeDistributedProperty(propName, ",, ExposeIndexRule , ,\t,
CorrelatedNestedLoopJoinRule ",
+ pVal -> F.compareArrays(new String[] {"ExposeIndexRule",
"CorrelatedNestedLoopJoinRule"}, pVal) == 0);
+ }
+
+ /**
+ * Tests the ability to disable planning rules globally.
+ *
+ * @see DistributedCalciteConfiguration#disabledRules()}.
+ */
+ @Test
+ public void testDisableRuleDistributedProperty() throws Exception {
+ try {
+ sql("create table test_tbl1 (c1 int, c2 int, c3 int)");
+ sql("create index idx12 on test_tbl1(c2)");
+ sql("create index idx13 on test_tbl1(c3)");
+
+ assertQuery(client, "select * from test_tbl1 order by c2")
+ .matches(containsIndexScan("PUBLIC", "TEST_TBL1", "IDX12"))
+ .matches(not(containsSubPlan("IgniteSort")))
+ .check();
+ assertQuery(client, "select * from test_tbl1 order by c3")
+ .matches(containsIndexScan("PUBLIC", "TEST_TBL1", "IDX13"))
+ .matches(not(containsSubPlan("IgniteSort")))
+ .check();
+
+ String propName =
DistributedCalciteConfiguration.DISABLED_RULES_PROPERTY_NAME;
+
+ changeDistributedProperty(propName,
ExposeIndexRule.INSTANCE.toString(),
+ pVal -> F.compareArrays(pVal, new String[]
{ExposeIndexRule.INSTANCE.toString()}) == 0);
+
+ // Check that there are no index scans now.
+ assertQuery(client, "select * from test_tbl1 order by c2")
+ .matches(not(containsIndexScan("PUBLIC", "TEST_TBL1",
"IDX12")))
+ .matches(containsSubPlan("IgniteSort"))
+ .check();
+ assertQuery(client, "select * from test_tbl1 order by c3")
+ .matches(not(containsIndexScan("PUBLIC", "TEST_TBL1",
"IDX13")))
+ .matches(containsSubPlan("IgniteSort"))
+ .check();
+
+ changeDistributedProperty(propName, " ", pVal ->
((String[])pVal).length == 0);
+
+ // Check that the index are available again.
+ assertQuery(client, "select * from test_tbl1 order by c2")
+ .matches(containsIndexScan("PUBLIC", "TEST_TBL1", "IDX12"))
+ .matches(not(containsSubPlan("IgniteSort")))
+ .check();
+ assertQuery(client, "select * from test_tbl1 order by c3")
+ .matches(containsIndexScan("PUBLIC", "TEST_TBL1", "IDX13"))
+ .matches(not(containsSubPlan("IgniteSort")))
+ .check();
+ }
+ finally {
+ sql("drop table if exists test_tbl1");
+ }
+ }
+
+ /** */
+ @Test
+ public void testDisabledRulesByHintAndGrlobalProperty() throws Exception {
+ String propName =
DistributedCalciteConfiguration.DISABLED_RULES_PROPERTY_NAME;
+
+ try {
+ sql("create table test_tbl1 (c1 int, c2 int, c3 int)");
+ sql("create index idx12 on test_tbl1(c2)");
+
+ sql("create table test_tbl2 (c1 int, c2 int, c3 int)");
+ sql("create index idx22 on test_tbl2(c3)");
+
+ // Ensure the index is enabled by default.
+ assertQuery(client, "select * from test_tbl1 order by c2")
+ .matches(containsIndexScan("PUBLIC", "TEST_TBL1", "IDX12"))
+ .matches(not(containsSubPlan("IgniteSort")))
+ .check();
+
+ // Ensure the indices are active with MergeJoin by default.
+ assertQuery(client, "select /*+ MERGE_JOIN */ t1.c1,t2.c3 from
test_tbl1 t1, test_tbl2 t2 where t1.c2=t2.c3")
+ .matches(containsSubPlan("IgniteMergeJoin"))
+ .matches(containsIndexScan("PUBLIC", "TEST_TBL1", "IDX12"))
+ .matches(containsIndexScan("PUBLIC", "TEST_TBL2", "IDX22"))
+ .check();
+
+ // The index scan rule is now disabled by the global property.
+ changeDistributedProperty(propName,
ExposeIndexRule.INSTANCE.toString(),
+ pVal -> F.compareArrays(pVal, new String[]
{ExposeIndexRule.INSTANCE.toString()}) == 0);
+
+ assertQuery(client, "select * from test_tbl1 order by c2")
+ .matches(not(containsIndexScan("PUBLIC", "TEST_TBL1",
"IDX12")))
+ .matches(containsSubPlan("IgniteSort"))
+ .check();
+
+ // Test that global property overrides hint.
+ assertQuery(client, "select /*+ FORCE_INDEX(IDX12) */ * from
test_tbl1 order by c2")
+ .matches(not(containsIndexScan("PUBLIC", "TEST_TBL1",
"IDX12")))
+ .matches(containsSubPlan("IgniteSort"))
+ .check();
+
+ // MergeJoin is on, but the indices are disabled by the global
rule.
+ assertQuery(client, "select /*+ MERGE_JOIN */ t1.c1,t2.c3 from
test_tbl1 t1, test_tbl2 t2 where t1.c2=t2.c3")
+ .matches(containsSubPlan("IgniteMergeJoin"))
+ .matches(not(containsIndexScan("PUBLIC", "TEST_TBL1",
"IDX12")))
+ .matches(not(containsIndexScan("PUBLIC", "TEST_TBL2",
"IDX22")))
+ .check();
+
+ String[] disabledRules = new String[] {"MergeJoinConverter"};
+
+ changeDistributedProperty(propName, "MergeJoinConverter", pVal ->
F.compareArrays(pVal, disabledRules) == 0);
+
+ // Ensure that hint and global property are able to work together.
The MergeJoin enforcing hint disables
+ // other join types. But it won't run because its rule is disabled
by the global property. So, the planner is
+ // unable to build plan.
+ GridTestUtils.assertThrows(
+ null,
+ () -> sql("select /*+ MERGE_JOIN */ t1.c1,t2.c3 from test_tbl1
t1, test_tbl2 t2 where t1.c2=t2.c3"),
+ IgniteSQLException.class,
+ "Failed to plan query"
+ );
+ }
+ finally {
+ sql("drop table if exists test_tbl1");
+ sql("drop table if exists test_tbl2");
+ }
+ }
+
+ /** */
+ private static <T extends Serializable> DistributedChangeableProperty<T>
distributedProperty(Ignite ig, String propName) {
+ return
((IgniteEx)ig).context().distributedConfiguration().property(propName);
+ }
+
+ /** */
+ private <T extends Serializable> void changeDistributedProperty(
+ String propName,
+ Object val,
+ @Nullable Predicate<T> newValChacker
+ ) throws Exception {
+ DynamicMBean mbean = getMxBean(
+ client.context().igniteInstanceName(),
+ "management",
+ Collections.singletonList("Property"),
+ "Set",
+ DynamicMBean.class
+ );
+
+ Object[] beanCallParams = new Object[2];
+ String[] callParamsType = new String[2];
+
+ beanCallParams[0] = propName;
+ callParamsType[0] = String.class.getName();
+
+ beanCallParams[1] = val;
+ callParamsType[1] = val == null ? Void.class.getName() :
val.getClass().getName();
+
+ mbean.invoke(CommandMBean.INVOKE, beanCallParams, callParamsType);
+
+ if (newValChacker == null)
+ return;
+
+ assertTrue(waitForCondition(
+ () -> {
+ for (Ignite ig : G.allGrids()) {
+ DistributedChangeableProperty<T> prop0 =
distributedProperty(ig, propName);
+
+ if (!newValChacker.test(prop0.get()))
+ return false;
+ }
+
+ return true;
+ },
+ getTestTimeout()
+ ));
+ }
+}
diff --git
a/modules/calcite/src/test/java/org/apache/ignite/testsuites/IntegrationTestSuite.java
b/modules/calcite/src/test/java/org/apache/ignite/testsuites/IntegrationTestSuite.java
index 47f7480afab..dfaca9b7827 100644
---
a/modules/calcite/src/test/java/org/apache/ignite/testsuites/IntegrationTestSuite.java
+++
b/modules/calcite/src/test/java/org/apache/ignite/testsuites/IntegrationTestSuite.java
@@ -20,6 +20,7 @@ package org.apache.ignite.testsuites;
import
org.apache.ignite.internal.processors.cache.DdlTransactionCalciteSelfTest;
import
org.apache.ignite.internal.processors.cache.QueryEntityValueColumnAliasTest;
import
org.apache.ignite.internal.processors.cache.SessionContextSqlFunctionTest;
+import
org.apache.ignite.internal.processors.query.calcite.CalciteQueryProcessorPropertiesTest;
import
org.apache.ignite.internal.processors.query.calcite.CalciteQueryProcessorTest;
import org.apache.ignite.internal.processors.query.calcite.CancelTest;
import
org.apache.ignite.internal.processors.query.calcite.IndexWithSameNameCalciteTest;
@@ -101,6 +102,7 @@ import org.junit.runners.Suite;
OrToUnionRuleTest.class,
ProjectScanMergeRuleTest.class,
CalciteQueryProcessorTest.class,
+ CalciteQueryProcessorPropertiesTest.class,
CalciteErrorHandlilngIntegrationTest.class,
CalciteBasicSecondaryIndexIntegrationTest.class,
CancelTest.class,
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedConfigurationProcessor.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedConfigurationProcessor.java
index bc01987509a..3c849a18c6a 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedConfigurationProcessor.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedConfigurationProcessor.java
@@ -92,7 +92,6 @@ public class DistributedConfigurationProcessor extends
GridProcessorAdapter impl
//Register and actualize properties waited for this service.
isp.getDistributedConfigurationListeners()
.forEach(listener ->
listener.onReadyToRegister(DistributedConfigurationProcessor.this));
-
}
@Override public void onReadyForWrite(DistributedMetaStorage
metastorage) {
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/DistributedSqlConfiguration.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/DistributedSqlConfiguration.java
index 79367e1522c..6e94bd7337d 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/DistributedSqlConfiguration.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/DistributedSqlConfiguration.java
@@ -17,6 +17,9 @@
package org.apache.ignite.internal.processors.query;
+import java.io.Serializable;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.internal.GridKernalContext;
@@ -44,6 +47,12 @@ public abstract class DistributedSqlConfiguration {
/** Default value of the query timeout. */
public static final int DFLT_QRY_TIMEOUT = 0;
+ /** */
+ protected final GridKernalContext ctx;
+
+ /** */
+ protected final IgniteLogger log;
+
/** Query timeout. */
private volatile DistributedChangeableProperty<Integer> dfltQryTimeout;
@@ -51,43 +60,64 @@ public abstract class DistributedSqlConfiguration {
* @param ctx Kernal context
* @param log Logger.
*/
- protected DistributedSqlConfiguration(
- GridKernalContext ctx,
- IgniteLogger log
- ) {
+ protected DistributedSqlConfiguration(GridKernalContext ctx, IgniteLogger
log) {
+ this.ctx = ctx;
+ this.log = log;
+
ctx.internalSubscriptionProcessor().registerDistributedConfigurationListener(
new DistributedConfigurationLifecycleListener() {
@Override public void
onReadyToRegister(DistributedPropertyDispatcher dispatcher) {
- DistributedChangeableProperty<Integer> prop =
dispatcher.property(QUERY_TIMEOUT_PROPERTY_NAME);
-
- if (prop != null) {
- dfltQryTimeout = prop;
-
- return;
- }
-
- dfltQryTimeout = new SimpleDistributedProperty<>(
- QUERY_TIMEOUT_PROPERTY_NAME,
- SimpleDistributedProperty::parseNonNegativeInteger,
- "Timeout in milliseconds for default query timeout. 0
means there is no timeout."
- );
-
-
dfltQryTimeout.addListener(makeUpdateListener(PROPERTY_UPDATE_MESSAGE, log));
-
- dispatcher.registerProperties(dfltQryTimeout);
+
DistributedSqlConfiguration.this.onReadyToRegister(dispatcher);
}
- @SuppressWarnings("deprecation")
@Override public void onReadyToWrite() {
- setDefaultValue(
- dfltQryTimeout,
-
(int)ctx.config().getSqlConfiguration().getDefaultQueryTimeout(),
- log);
+ DistributedSqlConfiguration.this.onReadyToWrite();
}
}
);
}
+ /** */
+ protected void onReadyToRegister(DistributedPropertyDispatcher dispatcher)
{
+ registerProperty(
+ dispatcher,
+ QUERY_TIMEOUT_PROPERTY_NAME,
+ prop -> dfltQryTimeout = prop,
+ () -> new SimpleDistributedProperty<>(
+ QUERY_TIMEOUT_PROPERTY_NAME,
+ SimpleDistributedProperty::parseNonNegativeInteger,
+ "Timeout in milliseconds for default query timeout. 0 means
there is no timeout."
+ ),
+ log
+ );
+ }
+
+ /** */
+ protected void onReadyToWrite() {
+ setDefaultValue(dfltQryTimeout,
(int)ctx.config().getSqlConfiguration().getDefaultQueryTimeout(), log);
+ }
+
+ /** */
+ protected static <T extends Serializable> void registerProperty(
+ DistributedPropertyDispatcher dispatcher,
+ String propName,
+ Consumer<DistributedChangeableProperty<T>> propSetter,
+ Supplier<DistributedChangeableProperty<T>> newPropCreator,
+ IgniteLogger log
+ ) {
+ DistributedChangeableProperty<T> prop = dispatcher.property(propName);
+
+ if (prop == null) {
+ prop = newPropCreator.get();
+
+ prop.addListener(makeUpdateListener(PROPERTY_UPDATE_MESSAGE, log));
+
+ dispatcher.registerProperty(prop);
+ }
+
+ propSetter.accept(prop);
+ }
+
/**
* @return Default query timeout.
*/
diff --git
a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DistributedIndexingConfiguration.java
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DistributedIndexingConfiguration.java
index 06fbdc8d0ab..680fb032dd5 100644
---
a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DistributedIndexingConfiguration.java
+++
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DistributedIndexingConfiguration.java
@@ -26,7 +26,6 @@ import org.apache.ignite.IgniteLogger;
import org.apache.ignite.internal.GridKernalContext;
import
org.apache.ignite.internal.processors.configuration.distributed.DistributePropertyListener;
import
org.apache.ignite.internal.processors.configuration.distributed.DistributedBooleanProperty;
-import
org.apache.ignite.internal.processors.configuration.distributed.DistributedConfigurationLifecycleListener;
import
org.apache.ignite.internal.processors.configuration.distributed.DistributedPropertyDispatcher;
import
org.apache.ignite.internal.processors.configuration.distributed.SimpleDistributedProperty;
import org.apache.ignite.internal.processors.query.DistributedSqlConfiguration;
@@ -72,34 +71,26 @@ public class DistributedIndexingConfiguration extends
DistributedSqlConfiguratio
* @param ctx Kernal context
* @param log Logger.
*/
- public DistributedIndexingConfiguration(
- GridKernalContext ctx,
- IgniteLogger log
- ) {
+ public DistributedIndexingConfiguration(GridKernalContext ctx,
IgniteLogger log) {
super(ctx, log);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void onReadyToRegister(DistributedPropertyDispatcher
dispatcher) {
+ super.onReadyToRegister(dispatcher);
+
+
disabledSqlFuncs.addListener(makeUpdateListener(PROPERTY_UPDATE_MESSAGE, log));
+
+ dispatcher.registerProperty(disabledSqlFuncs);
+
dispatcher.registerProperty(disableCreateLuceneIndexForStringValueType);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void onReadyToWrite() {
+ super.onReadyToWrite();
-
ctx.internalSubscriptionProcessor().registerDistributedConfigurationListener(
- new DistributedConfigurationLifecycleListener() {
- @Override public void
onReadyToRegister(DistributedPropertyDispatcher dispatcher) {
-
disabledSqlFuncs.addListener(makeUpdateListener(PROPERTY_UPDATE_MESSAGE, log));
-
- dispatcher.registerProperty(disabledSqlFuncs);
-
dispatcher.registerProperty(disableCreateLuceneIndexForStringValueType);
- }
-
- @Override public void onReadyToWrite() {
- setDefaultValue(
- disabledSqlFuncs,
- DFLT_DISABLED_FUNCS,
- log);
-
- setDefaultValue(
- disableCreateLuceneIndexForStringValueType,
- false,
- log);
- }
- }
- );
+ setDefaultValue(disabledSqlFuncs, DFLT_DISABLED_FUNCS, log);
+ setDefaultValue(disableCreateLuceneIndexForStringValueType, false,
log);
}
/**