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

rpuch 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 8ce05d9ad73 IGNITE-25589 Fix NPE in backward schema compatibility 
validation (#5979)
8ce05d9ad73 is described below

commit 8ce05d9ad73ddf295871aef0b9d1af9e2f815337
Author: Roman Puchkovskiy <roman.puchkovs...@gmail.com>
AuthorDate: Wed Jun 4 18:59:45 2025 +0400

    IGNITE-25589 Fix NPE in backward schema compatibility validation (#5979)
---
 .../schema/CatalogValidationSchemasSource.java     |  2 ++
 .../schema/CatalogValidationSchemasSourceTest.java | 33 ++++++++++++++++++++--
 2 files changed, 32 insertions(+), 3 deletions(-)

diff --git 
a/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/schema/CatalogValidationSchemasSource.java
 
b/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/schema/CatalogValidationSchemasSource.java
index c88d86e6186..4533b0d66a2 100644
--- 
a/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/schema/CatalogValidationSchemasSource.java
+++ 
b/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/schema/CatalogValidationSchemasSource.java
@@ -20,6 +20,7 @@ package 
org.apache.ignite.internal.partition.replicator.schema;
 import static java.util.stream.Collectors.toList;
 
 import java.util.List;
+import java.util.Objects;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
@@ -95,6 +96,7 @@ public class CatalogValidationSchemasSource implements 
ValidationSchemasSource {
     ) {
         return IntStream.rangeClosed(fromCatalogVersionIncluding, 
toCatalogVersionIncluding)
                 .mapToObj(catalogVersion -> 
catalogService.catalog(catalogVersion).table(tableId))
+                .takeWhile(Objects::nonNull)
                 .filter(new Predicate<>() {
                     int prevVersion = Integer.MIN_VALUE;
 
diff --git 
a/modules/partition-replicator/src/test/java/org/apache/ignite/internal/partition/replicator/schema/CatalogValidationSchemasSourceTest.java
 
b/modules/partition-replicator/src/test/java/org/apache/ignite/internal/partition/replicator/schema/CatalogValidationSchemasSourceTest.java
index 62b1e75edd3..d9447b48fdc 100644
--- 
a/modules/partition-replicator/src/test/java/org/apache/ignite/internal/partition/replicator/schema/CatalogValidationSchemasSourceTest.java
+++ 
b/modules/partition-replicator/src/test/java/org/apache/ignite/internal/partition/replicator/schema/CatalogValidationSchemasSourceTest.java
@@ -108,9 +108,15 @@ class CatalogValidationSchemasSourceTest extends 
BaseIgniteAbstractTest {
     }
 
     private void mockCatalogWithSingleTable(int catalogVersion, int tableId) {
-        Catalog catalogV3 = mock(Catalog.class);
-        when(catalogService.catalog(catalogVersion)).thenReturn(catalogV3);
-        when(catalogV3.table(tableId)).thenReturn(tableVersion(tableId, 
catalogVersion));
+        Catalog catalog = mock(Catalog.class);
+        when(catalogService.catalog(catalogVersion)).thenReturn(catalog);
+        when(catalog.table(tableId)).thenReturn(tableVersion(tableId, 
catalogVersion));
+    }
+
+    private void mockCatalogWithoutTable(int catalogVersion, int tableId) {
+        Catalog catalog = mock(Catalog.class);
+        when(catalogService.catalog(catalogVersion)).thenReturn(catalog);
+        when(catalog.table(tableId)).thenReturn(null);
     }
 
     private static CatalogTableDescriptor tableVersion(int tableId, int 
tableVersion) {
@@ -209,4 +215,25 @@ class CatalogValidationSchemasSourceTest extends 
BaseIgniteAbstractTest {
 
         verify(catalogService.catalog(3), times(1)).table(tableId);
     }
+
+    @Test
+    void tableSchemaVersionsBetweenTimestampAndVersionWorksIfTableWasDropped() 
{
+        int tableId = 1;
+
+        HybridTimestamp from = clock.now();
+
+        when(catalogService.latestCatalogVersion()).thenReturn(5);
+        
when(catalogService.activeCatalogVersion(from.longValue())).thenReturn(3);
+
+        mockCatalogWithSingleTable(3, tableId);
+        mockCatalogWithSingleTable(4, tableId);
+        // In version 5, the table is dropped.
+        mockCatalogWithoutTable(5, tableId);
+
+        List<FullTableSchema> fullSchemas = 
schemas.tableSchemaVersionsBetween(tableId, from, 4);
+
+        assertThat(fullSchemas, hasSize(2));
+        assertThat(fullSchemas.get(0).schemaVersion(), is(3));
+        assertThat(fullSchemas.get(1).schemaVersion(), is(4));
+    }
 }

Reply via email to