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 ab9a188b9ba IGNITE-26564 Fix incorrect message for SQL query on 
starting cache - Fixes #12390.
ab9a188b9ba is described below

commit ab9a188b9ba76565c8c112af7069089841a50b8a
Author: Sergey Korotkov <[email protected]>
AuthorDate: Wed Oct 22 15:32:02 2025 +0300

    IGNITE-26564 Fix incorrect message for SQL query on starting cache - Fixes 
#12390.
    
    Signed-off-by: Aleksey Plekhanov <[email protected]>
---
 .../query/h2/twostep/ReducePartitionMapper.java    |   7 ++
 ...nityHistoryForDynamicallyCreatedCachesTest.java | 110 +++++++++++++++++++++
 .../IgniteBinaryCacheQueryTestSuite4.java          |   2 +
 3 files changed, 119 insertions(+)

diff --git 
a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/ReducePartitionMapper.java
 
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/ReducePartitionMapper.java
index ebfe4929dfe..fc51d890d84 100644
--- 
a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/ReducePartitionMapper.java
+++ 
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/ReducePartitionMapper.java
@@ -85,6 +85,13 @@ public class ReducePartitionMapper {
         for (int cacheId : cacheIds) {
             GridCacheContext<?, ?> cctx = cacheContext(cacheId);
 
+            if (cctx.startTopologyVersion().after(topVer)) {
+                throw new CacheException(new 
CacheInvalidStateException("Failed to execute query because " +
+                    "partitions exchange wasn't yet completed after cache 
creation " +
+                    "[cacheName=" + cctx.name() + ", topVer=" + topVer +
+                    ", cacheTopVer=" + 
cctx.affinity().affinityTopologyVersion() + ']'));
+            }
+
             Collection<Integer> lostParts = cctx.topology().lostPartitions();
 
             if (!lostParts.isEmpty()) {
diff --git 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/SqlAffinityHistoryForDynamicallyCreatedCachesTest.java
 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/SqlAffinityHistoryForDynamicallyCreatedCachesTest.java
new file mode 100644
index 00000000000..57b67532c84
--- /dev/null
+++ 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/SqlAffinityHistoryForDynamicallyCreatedCachesTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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;
+
+import java.util.concurrent.CountDownLatch;
+
+import org.apache.ignite.cache.QueryEntity;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.apache.ignite.client.ClientCacheConfiguration;
+import org.apache.ignite.client.ClientException;
+import org.apache.ignite.client.IgniteClient;
+import org.apache.ignite.internal.client.thin.AbstractThinClientTest;
+import 
org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager;
+import 
org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture;
+import 
org.apache.ignite.internal.processors.cache.distributed.dht.preloader.PartitionsExchangeAware;
+import org.junit.Test;
+
+import static org.apache.ignite.testframework.GridTestUtils.assertThrows;
+import static org.apache.ignite.testframework.GridTestUtils.runAsync;
+
+/** */
+public class SqlAffinityHistoryForDynamicallyCreatedCachesTest extends 
AbstractThinClientTest {
+    /** */
+    private static final String CACHE_NAME = "SQL_TABLE";
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        stopAllGrids();
+    }
+
+    /**
+     * Tests that the correct meaningful error is thrown in case of race 
between
+     * concurrent cache creation and SQL query. In particular the error is 
thrown
+     * when partitions exchange is not yet completed after the cache used in 
query
+     * just dynamically created.
+     * <p>
+     * Before the misleading {@code Getting affinity for too old topology 
version that is
+     * already out of history (try to increase 'IGNITE_AFFINITY_HISTORY_SIZE' 
system property)}
+     * error was thrown.
+     */
+    @Test
+    public void testConcurrentCacheCreateAndSqlQuery() throws Exception {
+        startGrids(3);
+
+        GridCachePartitionExchangeManager<Object, Object> exchangeMgr = 
ignite(1).context().cache().context().exchange();
+
+        CountDownLatch exchangeStarted = new CountDownLatch(1);
+        CountDownLatch proceedWithExchange = new CountDownLatch(1);
+
+        PartitionsExchangeAware listener = new PartitionsExchangeAware() {
+            @Override public void 
onInitBeforeTopologyLock(GridDhtPartitionsExchangeFuture fut) {
+                if (fut.hasCachesToStart()) {
+                    exchangeStarted.countDown();
+
+                    try {
+                        proceedWithExchange.await();
+                    }
+                    catch (InterruptedException e) {
+                        // No-op.
+                    }
+                }
+            }
+        };
+
+        exchangeMgr.registerExchangeAwareComponent(listener);
+
+        runAsync(() -> {
+            try (IgniteClient cli = startClient(0)) {
+                cli.createCache(getCacheConfiguration());
+            }
+        }, "create-cache-thread");
+
+        try (IgniteClient cli = startClient(0)) {
+            exchangeStarted.await();
+
+            assertThrows(
+                null,
+                () -> cli.query(new SqlFieldsQuery("select * from " + 
CACHE_NAME)).getAll(),
+                ClientException.class,
+                "partitions exchange wasn't yet completed after cache 
creation");
+        }
+
+        exchangeMgr.unregisterExchangeAwareComponent(listener);
+
+        proceedWithExchange.countDown();
+    }
+
+    /** */
+    private ClientCacheConfiguration getCacheConfiguration() {
+        return new ClientCacheConfiguration()
+            .setName(CACHE_NAME)
+            .setSqlSchema("PUBLIC")
+            .setQueryEntities(new QueryEntity(Integer.class, 
Integer.class).setTableName(CACHE_NAME));
+    }
+}
diff --git 
a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite4.java
 
b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite4.java
index 880641f4767..d66430aecab 100644
--- 
a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite4.java
+++ 
b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite4.java
@@ -31,6 +31,7 @@ import 
org.apache.ignite.internal.processors.query.IgniteSqlCreateTableTemplateT
 import org.apache.ignite.internal.processors.query.LocalQueryLazyTest;
 import org.apache.ignite.internal.processors.query.LongRunningQueryTest;
 import org.apache.ignite.internal.processors.query.SqlAffinityCacheTest;
+import 
org.apache.ignite.internal.processors.query.SqlAffinityHistoryForDynamicallyCreatedCachesTest;
 import 
org.apache.ignite.internal.processors.query.SqlLocalQueryConnectionAndStatementTest;
 import 
org.apache.ignite.internal.processors.query.SqlPartOfComplexPkLookupTest;
 import 
org.apache.ignite.internal.processors.query.SqlQueriesTopologyMappingTest;
@@ -96,6 +97,7 @@ import org.junit.runners.Suite;
 
     IgniteCacheQueryReservationOnUnstableTopologyTest.class,
     SqlAffinityCacheTest.class,
+    SqlAffinityHistoryForDynamicallyCreatedCachesTest.class,
 
     ScanQueryTransactionsUnsupportedModesTest.class,
     ScanQueryTransactionIsolationTest.class,

Reply via email to