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)); + } }