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 194920a1f0f IGNITE-27432 SQL Calcite: Add distributed property for 
plan cache size - Fixes #12654.
194920a1f0f is described below

commit 194920a1f0f8eb9b4a5ba0b6a4709667dcc66c16
Author: Aleksey Plekhanov <[email protected]>
AuthorDate: Tue Jan 27 11:22:09 2026 +0300

    IGNITE-27432 SQL Calcite: Add distributed property for plan cache size - 
Fixes #12654.
    
    Signed-off-by: Aleksey Plekhanov <[email protected]>
---
 .../calcite/DistributedCalciteConfiguration.java   | 73 +++++++++++++++-------
 .../query/calcite/exec/ExchangeServiceImpl.java    |  4 +-
 .../query/calcite/exec/ExecutionServiceImpl.java   | 21 +++----
 .../query/calcite/message/MessageServiceImpl.java  |  4 +-
 .../processors/query/calcite/prepare/CacheKey.java |  9 ---
 .../query/calcite/prepare/PrepareServiceImpl.java  |  9 +--
 .../query/calcite/prepare/QueryPlanCacheImpl.java  | 26 ++++----
 .../query/calcite/util/AbstractService.java        | 10 +++
 .../CalciteQueryProcessorPropertiesTest.java       | 39 ++++++++++++
 9 files changed, 121 insertions(+), 74 deletions(-)

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 6eb8c49c458..26c3a7b14c9 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,6 +17,7 @@
 
 package org.apache.ignite.internal.processors.query.calcite;
 
+import java.io.Serializable;
 import java.util.Objects;
 import java.util.stream.Stream;
 import org.apache.ignite.IgniteLogger;
@@ -30,7 +31,6 @@ import 
org.apache.ignite.internal.processors.query.calcite.prepare.QueryPlanCach
 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;
 
@@ -39,12 +39,21 @@ public class DistributedCalciteConfiguration extends 
DistributedSqlConfiguration
     /** Globally disabled rules property name. */
     public static final String DISABLED_RULES_PROPERTY_NAME = 
"sql.calcite.disabledRules";
 
+    /** Plan cache size property name. */
+    public static final String PLAN_CACHE_SIZE_PROPERTY_NAME = 
"sql.calcite.planCacheSize";
+
     /** Default value of the disabled rules. */
     public static final String[] DFLT_DISABLED_RULES = new String[0];
 
+    /** Default value of plan cache size. */
+    public static final int DFLT_PLAN_CACHE_SIZE = 1024;
+
     /** Globally disabled rules. */
     private volatile DistributedChangeableProperty<String[]> disabledRules;
 
+    /** Plan cache size. */
+    private volatile DistributedChangeableProperty<Integer> planCacheSize;
+
     /** */
     private QueryPlanCache qryPlanCache;
 
@@ -72,17 +81,38 @@ public class DistributedCalciteConfiguration extends 
DistributedSqlConfiguration
      * @see #DISABLED_RULES_PROPERTY_NAME
      */
     public String[] disabledRules() {
-        DistributedChangeableProperty<String[]> disabledRules = 
this.disabledRules;
+        return getProperty(disabledRules, DFLT_DISABLED_RULES);
+    }
 
-        String[] res = disabledRules == null ? DFLT_DISABLED_RULES : 
disabledRules.get();
+    /**
+     * @return Plan cache size.
+     */
+    public int planCacheSize() {
+        return getProperty(planCacheSize, DFLT_PLAN_CACHE_SIZE);
+    }
 
-        return res != null ? res : DFLT_DISABLED_RULES;
+    /** */
+    private <T extends Serializable> T 
getProperty(DistributedChangeableProperty<T> prop, T dflt) {
+        T res = prop == null ? dflt : prop.get();
+
+        return res != null ? res : dflt;
     }
 
     /** {@inheritDoc} */
     @Override protected void onReadyToRegister(DistributedPropertyDispatcher 
dispatcher) {
         super.onReadyToRegister(dispatcher);
 
+        DistributePropertyListener<Object> planCacheCleaner = (name, oldVal, 
newVal) -> {
+            if (oldVal != null && !oldVal.equals(newVal)) {
+                if (qryPlanCache != null) {
+                    if (log.isInfoEnabled())
+                        log.info("Cleaning Calcite's cache plan by changing of 
the property '" + name + "'.");
+
+                    qryPlanCache.clear();
+                }
+            }
+        };
+
         registerProperty(
             dispatcher,
             DISABLED_RULES_PROPERTY_NAME,
@@ -95,20 +125,21 @@ public class DistributedCalciteConfiguration extends 
DistributedSqlConfiguration
             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();
-                    }
-                }
-            }
-        });
+        disabledRules.addListener(planCacheCleaner);
+
+        registerProperty(
+            dispatcher,
+            PLAN_CACHE_SIZE_PROPERTY_NAME,
+            prop -> planCacheSize = prop,
+            () -> new SimpleDistributedProperty<>(
+                PLAN_CACHE_SIZE_PROPERTY_NAME,
+                Integer::parseInt,
+                "Calcite's plan cache size. NOTE: cleans the planning cache on 
change."
+            ),
+            log
+        );
+
+        planCacheSize.addListener(planCacheCleaner);
     }
 
     /** {@inheritDoc} */
@@ -116,10 +147,6 @@ public class DistributedCalciteConfiguration extends 
DistributedSqlConfiguration
         super.onReadyToWrite();
 
         setDefaultValue(disabledRules, DFLT_DISABLED_RULES, log);
-    }
-
-    /** */
-    DistributedChangeableProperty<String[]> disabledRulesProperty() {
-        return disabledRules;
+        setDefaultValue(planCacheSize, DFLT_PLAN_CACHE_SIZE, log);
     }
 }
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExchangeServiceImpl.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExchangeServiceImpl.java
index 445a42e7c2c..039b14ed9e9 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExchangeServiceImpl.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExchangeServiceImpl.java
@@ -19,7 +19,6 @@ package 
org.apache.ignite.internal.processors.query.calcite.exec;
 
 import java.util.Collection;
 import java.util.List;
-import java.util.Objects;
 import java.util.UUID;
 import com.google.common.collect.ImmutableMap;
 import org.apache.ignite.IgniteCheckedException;
@@ -176,8 +175,7 @@ public class ExchangeServiceImpl extends AbstractService 
implements ExchangeServ
 
     /** {@inheritDoc} */
     @Override public void onStart(GridKernalContext ctx) {
-        CalciteQueryProcessor proc =
-            Objects.requireNonNull(Commons.lookupComponent(ctx, 
CalciteQueryProcessor.class));
+        CalciteQueryProcessor proc = queryProcessor(ctx);
 
         taskExecutor(proc.taskExecutor());
         mailboxRegistry(proc.mailboxRegistry());
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExecutionServiceImpl.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExecutionServiceImpl.java
index 6b09e00c636..0892f23f590 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExecutionServiceImpl.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExecutionServiceImpl.java
@@ -21,7 +21,6 @@ import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
 import java.util.UUID;
 import java.util.function.Function;
 import java.util.stream.Collectors;
@@ -85,7 +84,6 @@ import 
org.apache.ignite.internal.processors.query.calcite.metadata.FragmentMapp
 import 
org.apache.ignite.internal.processors.query.calcite.metadata.MappingService;
 import 
org.apache.ignite.internal.processors.query.calcite.metadata.RemoteException;
 import 
org.apache.ignite.internal.processors.query.calcite.prepare.BaseQueryContext;
-import org.apache.ignite.internal.processors.query.calcite.prepare.CacheKey;
 import org.apache.ignite.internal.processors.query.calcite.prepare.DdlPlan;
 import 
org.apache.ignite.internal.processors.query.calcite.prepare.ExecutionPlan;
 import org.apache.ignite.internal.processors.query.calcite.prepare.ExplainPlan;
@@ -114,6 +112,7 @@ import 
org.apache.ignite.internal.processors.query.calcite.util.ConvertingClosab
 import 
org.apache.ignite.internal.processors.query.calcite.util.ListFieldsQueryCursor;
 import org.apache.ignite.internal.processors.query.running.HeavyQueriesTracker;
 import org.apache.ignite.internal.processors.security.SecurityUtils;
+import org.apache.ignite.internal.util.GridBoundedConcurrentLinkedHashMap;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.X;
 import org.apache.ignite.internal.util.typedef.internal.U;
@@ -203,6 +202,9 @@ public class ExecutionServiceImpl<Row> extends 
AbstractService implements Execut
     /** */
     private InjectResourcesService injectSvc;
 
+    /** */
+    private final Map<String, FragmentPlan> fragmentPlanCache = new 
GridBoundedConcurrentLinkedHashMap<>(1024);
+
     /**
      * @param ctx Kernal.
      */
@@ -441,9 +443,7 @@ public class ExecutionServiceImpl<Row> extends 
AbstractService implements Execut
         performanceStatisticsProcessor(ctx.performanceStatistics());
         iteratorsHolder(new ClosableIteratorsHolder(log));
 
-        CalciteQueryProcessor proc = Objects.requireNonNull(
-            Commons.lookupComponent(ctx, CalciteQueryProcessor.class));
-
+        CalciteQueryProcessor proc = queryProcessor(ctx);
         queryPlanCache(proc.queryPlanCache());
         schemaHolder(proc.schemaHolder());
         taskExecutor(proc.taskExecutor());
@@ -502,7 +502,7 @@ public class ExecutionServiceImpl<Row> extends 
AbstractService implements Execut
     }
 
     /** */
-    private QueryPlan prepareFragment(BaseQueryContext ctx, String 
jsonFragment) {
+    private FragmentPlan prepareFragment(BaseQueryContext ctx, String 
jsonFragment) {
         return new FragmentPlan(jsonFragment, fromJson(ctx, jsonFragment));
     }
 
@@ -885,12 +885,7 @@ public class ExecutionServiceImpl<Row> extends 
AbstractService implements Execut
                 msg.applicationAttributes() == null ? Contexts.empty() : 
Contexts.of(new SessionContextImpl(msg.applicationAttributes())),
                 msg.schema());
 
-            QueryPlan qryPlan = queryPlanCache().queryPlan(
-                new CacheKey(msg.schema(), msg.root()),
-                () -> prepareFragment(qctx, msg.root())
-            );
-
-            assert qryPlan.type() == QueryPlan.Type.FRAGMENT;
+            FragmentPlan fragmentPlan = 
fragmentPlanCache.computeIfAbsent(msg.root(), k -> prepareFragment(qctx, k));
 
             ExecutionContext<Row> ectx = new ExecutionContext<>(
                 qctx,
@@ -909,7 +904,7 @@ public class ExecutionServiceImpl<Row> extends 
AbstractService implements Execut
                 msg.queryTransactionEntries()
             );
 
-            executeFragment(qry, (FragmentPlan)qryPlan, ectx);
+            executeFragment(qry, fragmentPlan, ectx);
         }
         catch (Throwable ex) {
             U.error(log, "Failed to start query fragment ", ex);
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/MessageServiceImpl.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/MessageServiceImpl.java
index 3b5b8a1f913..1af28d1fe32 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/MessageServiceImpl.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/MessageServiceImpl.java
@@ -21,7 +21,6 @@ import java.util.EnumMap;
 import java.util.Objects;
 import java.util.UUID;
 import java.util.concurrent.ThreadLocalRandom;
-
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.failure.FailureContext;
 import org.apache.ignite.failure.FailureType;
@@ -36,7 +35,6 @@ import 
org.apache.ignite.internal.processors.failure.FailureProcessor;
 import 
org.apache.ignite.internal.processors.query.calcite.CalciteQueryProcessor;
 import 
org.apache.ignite.internal.processors.query.calcite.exec.QueryTaskExecutor;
 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.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteUuid;
 import org.apache.ignite.plugin.extensions.communication.Message;
@@ -128,7 +126,7 @@ public class MessageServiceImpl extends AbstractService 
implements MessageServic
     @Override public void onStart(GridKernalContext ctx) {
         localNodeId(ctx.localNodeId());
 
-        CalciteQueryProcessor proc = 
Objects.requireNonNull(Commons.lookupComponent(ctx, 
CalciteQueryProcessor.class));
+        CalciteQueryProcessor proc = queryProcessor(ctx);
 
         taskExecutor(proc.taskExecutor());
         failureProcessor(proc.failureProcessor());
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/CacheKey.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/CacheKey.java
index f7aef65df62..cdc58203f5b 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/CacheKey.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/CacheKey.java
@@ -19,7 +19,6 @@ package 
org.apache.ignite.internal.processors.query.calcite.prepare;
 
 import java.util.Arrays;
 import java.util.Objects;
-import org.apache.ignite.internal.util.typedef.X;
 
 /**
  *
@@ -52,14 +51,6 @@ public class CacheKey {
             Arrays.stream(params).map(p -> (p != null) ? p.getClass() : 
Void.class).toArray(Class[]::new);
     }
 
-    /**
-     * @param schemaName Schema name.
-     * @param query Query string.
-     */
-    public CacheKey(String schemaName, String query) {
-        this(schemaName, query, null, X.EMPTY_OBJECT_ARRAY);
-    }
-
     /** {@inheritDoc} */
     @Override public boolean equals(Object o) {
         if (this == o)
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 af2ac9506bc..7845259e6e0 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,6 @@
 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,13 +34,11 @@ 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;
@@ -79,11 +76,7 @@ public class PrepareServiceImpl extends AbstractService 
implements PrepareServic
     @Override public void onStart(GridKernalContext ctx) {
         super.onStart(ctx);
 
-        CalciteQueryProcessor proc = 
Objects.requireNonNull(Commons.lookupComponent(ctx, 
CalciteQueryProcessor.class));
-
-        assert proc != null;
-
-        distrCfg = proc.distributedConfiguration();
+        distrCfg = queryProcessor(ctx).distributedConfiguration();
     }
 
     /** {@inheritDoc} */
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/QueryPlanCacheImpl.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/QueryPlanCacheImpl.java
index a1b038abfff..cc743c9c80e 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/QueryPlanCacheImpl.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/QueryPlanCacheImpl.java
@@ -24,10 +24,10 @@ import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.processors.cache.GridCacheContextInfo;
 import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor;
 import org.apache.ignite.internal.processors.query.QueryField;
+import 
org.apache.ignite.internal.processors.query.calcite.DistributedCalciteConfiguration;
 import 
org.apache.ignite.internal.processors.query.calcite.util.AbstractService;
 import 
org.apache.ignite.internal.processors.query.schema.AbstractSchemaChangeListener;
 import 
org.apache.ignite.internal.processors.query.schema.management.IndexDescriptor;
-import 
org.apache.ignite.internal.processors.subscription.GridInternalSubscriptionProcessor;
 import org.apache.ignite.internal.util.GridBoundedConcurrentLinkedHashMap;
 
 /**
@@ -35,10 +35,7 @@ import 
org.apache.ignite.internal.util.GridBoundedConcurrentLinkedHashMap;
  */
 public class QueryPlanCacheImpl extends AbstractService implements 
QueryPlanCache {
     /** */
-    private static final int CACHE_SIZE = 1024;
-
-    /** */
-    private final GridInternalSubscriptionProcessor subscriptionProc;
+    private DistributedCalciteConfiguration distrCfg;
 
     /** */
     private volatile Map<CacheKey, QueryPlan> cache;
@@ -49,20 +46,17 @@ public class QueryPlanCacheImpl extends AbstractService 
implements QueryPlanCach
     public QueryPlanCacheImpl(GridKernalContext ctx) {
         super(ctx);
 
-        cache = new GridBoundedConcurrentLinkedHashMap<>(CACHE_SIZE);
-        subscriptionProc = ctx.internalSubscriptionProcessor();
-
-        init();
-    }
+        ctx.internalSubscriptionProcessor().registerSchemaChangeListener(new 
SchemaListener());
 
-    /** {@inheritDoc} */
-    @Override public void init() {
-        subscriptionProc.registerSchemaChangeListener(new SchemaListener());
+        clear(); // Create cache with default size.
     }
 
     /** {@inheritDoc} */
     @Override public void onStart(GridKernalContext ctx) {
-        // No-op.
+        distrCfg = queryProcessor(ctx).distributedConfiguration();
+
+        if (distrCfg.planCacheSize() != 
DistributedCalciteConfiguration.DFLT_PLAN_CACHE_SIZE)
+            clear(); // Recreate cache with configured size.
     }
 
     /** {@inheritDoc} */
@@ -80,7 +74,9 @@ public class QueryPlanCacheImpl extends AbstractService 
implements QueryPlanCach
 
     /** {@inheritDoc} */
     @Override public void clear() {
-        cache = new GridBoundedConcurrentLinkedHashMap<>(CACHE_SIZE);
+        cache = new GridBoundedConcurrentLinkedHashMap<>(distrCfg == null
+            ? DistributedCalciteConfiguration.DFLT_PLAN_CACHE_SIZE
+            : distrCfg.planCacheSize());
     }
 
     /** Schema change listener. */
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/AbstractService.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/AbstractService.java
index cc640be28e3..630362a5141 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/AbstractService.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/AbstractService.java
@@ -17,8 +17,10 @@
 
 package org.apache.ignite.internal.processors.query.calcite.util;
 
+import java.util.Objects;
 import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.internal.GridKernalContext;
+import 
org.apache.ignite.internal.processors.query.calcite.CalciteQueryProcessor;
 
 /**
  *
@@ -43,4 +45,12 @@ public abstract class AbstractService implements 
LifecycleAware, Service {
     @Override public void onStop() {
         tearDown();
     }
+
+    /**
+     * @param ctx Kernal context.
+     * @return Calcite query processor.
+     */
+    public static CalciteQueryProcessor queryProcessor(GridKernalContext ctx) {
+        return Objects.requireNonNull(Commons.lookupComponent(ctx, 
CalciteQueryProcessor.class));
+    }
 }
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
index 02075e5becc..71b16cc4536 100644
--- 
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
@@ -25,15 +25,19 @@ 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.metric.MetricRegistryImpl;
 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.spi.metric.LongMetric;
 import org.apache.ignite.testframework.GridTestUtils;
 import org.jetbrains.annotations.Nullable;
 import org.junit.Test;
 
+import static 
org.apache.ignite.internal.processors.query.QueryParserMetricsHolder.QUERY_PARSER_METRIC_GROUP_NAME;
+import static 
org.apache.ignite.internal.processors.query.calcite.DistributedCalciteConfiguration.DFLT_PLAN_CACHE_SIZE;
 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;
@@ -194,6 +198,41 @@ public class CalciteQueryProcessorPropertiesTest extends 
AbstractBasicIntegratio
         }
     }
 
+    /** */
+    @Test
+    public void testPlanCacheSize() throws Exception {
+        checkPlanCacheSize(grid(0), DFLT_PLAN_CACHE_SIZE);
+        checkPlanCacheSize(grid(1), DFLT_PLAN_CACHE_SIZE);
+
+        String propName = 
DistributedCalciteConfiguration.PLAN_CACHE_SIZE_PROPERTY_NAME;
+
+        changeDistributedProperty(propName, "100", null);
+
+        checkPlanCacheSize(grid(0), 100);
+        checkPlanCacheSize(grid(1), 100);
+    }
+
+    /** */
+    private void checkPlanCacheSize(IgniteEx grid, int expectedCacheSize) {
+        MetricRegistryImpl mreg = 
grid.context().metric().registry(QUERY_PARSER_METRIC_GROUP_NAME);
+
+        mreg.reset();
+
+        LongMetric hits = mreg.findMetric("hits");
+        LongMetric misses = mreg.findMetric("misses");
+
+        int cnt = DFLT_PLAN_CACHE_SIZE + 1;
+
+        for (int i = 0; i < cnt; i++)
+            sql(grid, "SELECT " + i);
+
+        for (int i = cnt - 1; i >= 0; i--)
+            sql(grid, "SELECT " + i);
+
+        assertEquals(expectedCacheSize, hits.value());
+        assertEquals(cnt * 2 - expectedCacheSize, misses.value());
+    }
+
     /** */
     private static <T extends Serializable> DistributedChangeableProperty<T> 
distributedProperty(Ignite ig, String propName) {
         return 
((IgniteEx)ig).context().distributedConfiguration().property(propName);

Reply via email to