This is an automated email from the ASF dual-hosted git repository. amashenkov pushed a commit to branch ignite-26501 in repository https://gitbox.apache.org/repos/asf/ignite-3.git
commit 4c02e3a45f5bb43b11b3197697138a4f8c54b0c4 Author: amashenkov <[email protected]> AuthorDate: Wed Oct 15 17:38:52 2025 +0300 wip --- .../engine/exec/ExecutableTableRegistryImpl.java | 16 ++++----- .../engine/schema/AbstractIgniteDataSource.java | 11 ++++++- .../sql/engine/schema/IgniteDataSource.java | 7 +++- .../sql/engine/schema/IgniteSystemViewImpl.java | 2 +- .../sql/engine/schema/IgniteTableImpl.java | 3 +- .../sql/engine/schema/SqlSchemaManagerImpl.java | 38 +++++++++++++++++++--- .../exec/ExecutableTableRegistrySelfTest.java | 2 +- .../sql/engine/framework/TestBuilders.java | 1 + 8 files changed, 63 insertions(+), 17 deletions(-) diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/ExecutableTableRegistryImpl.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/ExecutableTableRegistryImpl.java index da19f76b94e..146b2a0fbf8 100644 --- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/ExecutableTableRegistryImpl.java +++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/ExecutableTableRegistryImpl.java @@ -81,7 +81,7 @@ public class ExecutableTableRegistryImpl implements ExecutableTableRegistry { public ExecutableTable getTable(int catalogVersion, int tableId) { IgniteTable sqlTable = sqlSchemaManager.table(catalogVersion, tableId); - return tableCache.get(cacheKey(tableId, sqlTable.version()), (k) -> loadTable(sqlTable)); + return tableCache.get(cacheKey(tableId, sqlTable.timestamp()), (k) -> loadTable(sqlTable)); } private ExecutableTable loadTable(IgniteTable sqlTable) { @@ -158,17 +158,17 @@ public class ExecutableTableRegistryImpl implements ExecutableTableRegistry { } } - private static CacheKey cacheKey(int tableId, int version) { - return new CacheKey(tableId, version); + private static CacheKey cacheKey(int tableId, long timestamp) { + return new CacheKey(tableId, timestamp); } private static class CacheKey { private final int tableId; - private final int tableVersion; + private final long timestamp; - CacheKey(int tableId, int tableVersion) { + CacheKey(int tableId, long timestamp) { this.tableId = tableId; - this.tableVersion = tableVersion; + this.timestamp = timestamp; } @Override @@ -180,12 +180,12 @@ public class ExecutableTableRegistryImpl implements ExecutableTableRegistry { return false; } CacheKey cacheKey = (CacheKey) o; - return tableVersion == cacheKey.tableVersion && tableId == cacheKey.tableId; + return timestamp == cacheKey.timestamp && tableId == cacheKey.tableId; } @Override public int hashCode() { - return Objects.hash(tableVersion, tableId); + return Objects.hash(timestamp, tableId); } } diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/AbstractIgniteDataSource.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/AbstractIgniteDataSource.java index fe7ad0e27f3..c506fea4f10 100644 --- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/AbstractIgniteDataSource.java +++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/AbstractIgniteDataSource.java @@ -50,16 +50,19 @@ public abstract class AbstractIgniteDataSource extends AbstractTable private final int version; + private final long timestamp; + private final Statistic statistic; /** Constructor. */ - public AbstractIgniteDataSource(String name, int id, int version, TableDescriptor desc, + public AbstractIgniteDataSource(String name, int id, int version, long timestamp, TableDescriptor desc, Statistic statistic) { this.id = id; this.name = name; this.desc = desc; this.version = version; + this.timestamp = timestamp; this.statistic = statistic; } @@ -75,6 +78,12 @@ public abstract class AbstractIgniteDataSource extends AbstractTable return version; } + /** {@inheritDoc} */ + @Override + public long timestamp() { + return timestamp; + } + /** {@inheritDoc} */ @Override public String name() { diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/IgniteDataSource.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/IgniteDataSource.java index 2cc76cf541c..837dde6c5d2 100644 --- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/IgniteDataSource.java +++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/IgniteDataSource.java @@ -38,12 +38,17 @@ public interface IgniteDataSource extends TranslatableTable, Wrapper { int id(); /** - * Returns the version of the table's schema. + * Returns the version of the table's schema. The version is bumped only, when table structure was modified (e.g. column added/dropped). * * @return the version of the table's schema. */ int version(); + /** + * Return table descriptor modification timestamp. + */ + long timestamp(); + /** * Gets a name of the table. * diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/IgniteSystemViewImpl.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/IgniteSystemViewImpl.java index 41fc38d3213..6a72d34ece4 100644 --- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/IgniteSystemViewImpl.java +++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/IgniteSystemViewImpl.java @@ -37,7 +37,7 @@ public class IgniteSystemViewImpl extends AbstractIgniteDataSource implements Ig /** Constructor. */ public IgniteSystemViewImpl(String name, int id, TableDescriptor desc) { - super(name, id, CatalogTableDescriptor.INITIAL_TABLE_VERSION, desc, new SystemViewStatistic(desc.distribution())); + super(name, id, CatalogTableDescriptor.INITIAL_TABLE_VERSION, 0L, desc, new SystemViewStatistic(desc.distribution())); } /** {@inheritDoc} */ diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/IgniteTableImpl.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/IgniteTableImpl.java index af0b57c80be..ea51a2510a6 100644 --- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/IgniteTableImpl.java +++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/IgniteTableImpl.java @@ -57,6 +57,7 @@ public class IgniteTableImpl extends AbstractIgniteDataSource implements IgniteT String name, int id, int version, + long timestamp, TableDescriptor desc, ImmutableIntList keyColumns, Statistic statistic, @@ -64,7 +65,7 @@ public class IgniteTableImpl extends AbstractIgniteDataSource implements IgniteT int partitions, int zoneId ) { - super(name, id, version, desc, statistic); + super(name, id, version, timestamp, desc, statistic); this.keyColumns = keyColumns; this.indexMap = indexMap; diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/SqlSchemaManagerImpl.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/SqlSchemaManagerImpl.java index 1655be5bd86..c7a2a8da8b5 100644 --- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/SqlSchemaManagerImpl.java +++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/schema/SqlSchemaManagerImpl.java @@ -57,6 +57,7 @@ import org.apache.ignite.internal.catalog.descriptors.CatalogTableColumnDescript import org.apache.ignite.internal.catalog.descriptors.CatalogTableDescriptor; import org.apache.ignite.internal.catalog.descriptors.CatalogZoneDescriptor; import org.apache.ignite.internal.components.NodeProperties; +import org.apache.ignite.internal.hlc.HybridTimestamp; import org.apache.ignite.internal.lang.IgniteInternalException; import org.apache.ignite.internal.schema.DefaultValueGenerator; import org.apache.ignite.internal.sql.engine.schema.IgniteIndex.Type; @@ -87,7 +88,7 @@ public class SqlSchemaManagerImpl implements SqlSchemaManager { * Only data that included in a catalog table descriptor itself is up-to-date. * Table related information from other object is not reliable. */ - private final Cache<Long, IgniteTableImpl> tableCache; + private final Cache<CacheKey, IgniteTableImpl> tableCache; /** Index cache by (indexId, indexStatus). */ private final Cache<Long, IgniteIndex> indexCache; @@ -187,7 +188,7 @@ public class SqlSchemaManagerImpl implements SqlSchemaManager { throw new IgniteInternalException(Common.INTERNAL_ERR, "Table with given id not found: " + tableId); } - long tableKey = cacheKey(tableDescriptor.id(), tableDescriptor.latestSchemaVersion()); + CacheKey tableKey = tableCacheKey(tableDescriptor.id(), tableDescriptor.updateTimestamp()); IgniteTableImpl igniteTable = tableCache.get(tableKey, (x) -> { TableDescriptor descriptor = createTableDescriptorForTable(catalog, tableDescriptor); @@ -209,6 +210,10 @@ public class SqlSchemaManagerImpl implements SqlSchemaManager { return cacheKey | part2; } + private static CacheKey tableCacheKey(int tableId, HybridTimestamp modificationTimestamp) { + return new CacheKey(tableId, modificationTimestamp.longValue()); + } + private IgniteSchemas createRootSchema(Catalog catalog) { SchemaPlus rootSchema = Frameworks.createRootSchema(false); @@ -229,7 +234,7 @@ public class SqlSchemaManagerImpl implements SqlSchemaManager { // Assemble sql-engine.TableDescriptors as they are required by indexes. for (CatalogTableDescriptor tableDescriptor : schemaDescriptor.tables()) { - long tableKey = cacheKey(tableDescriptor.id(), tableDescriptor.latestSchemaVersion()); + CacheKey tableKey = tableCacheKey(tableDescriptor.id(), tableDescriptor.updateTimestamp()); // Load cached table by (id, version) IgniteTableImpl igniteTable = tableCache.get(tableKey, (k) -> { @@ -540,6 +545,7 @@ public class SqlSchemaManagerImpl implements SqlSchemaManager { tableName, tableId, catalogTableDescriptor.latestSchemaVersion(), + catalogTableDescriptor.updateTimestamp().longValue(), tableDescriptor, primaryKeyColumns, statistic, @@ -549,6 +555,30 @@ public class SqlSchemaManagerImpl implements SqlSchemaManager { ); } + private static class CacheKey { + final int id; + final long timestamp; + + private CacheKey(int id, long timestamp) { + this.id = id; + this.timestamp = timestamp; + } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + CacheKey cacheKey = (CacheKey) o; + return id == cacheKey.id && timestamp == cacheKey.timestamp; + } + + @Override + public int hashCode() { + return Objects.hash(id, timestamp); + } + } + private static class ActualIgniteTable extends AbstractIgniteDataSource implements IgniteTable { /** Cached table by id and version. */ @@ -558,7 +588,7 @@ public class SqlSchemaManagerImpl implements SqlSchemaManager { private final Map<String, IgniteIndex> indexMap; ActualIgniteTable(IgniteTableImpl igniteTable, Map<String, IgniteIndex> indexMap) { - super(igniteTable.name(), igniteTable.id(), igniteTable.version(), igniteTable.descriptor(), igniteTable.getStatistic()); + super(igniteTable.name(), igniteTable.id(), igniteTable.version(), igniteTable.timestamp(), igniteTable.descriptor(), igniteTable.getStatistic()); this.table = igniteTable; this.indexMap = indexMap; diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/ExecutableTableRegistrySelfTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/ExecutableTableRegistrySelfTest.java index 57c237ebf21..3ea9ea900f1 100644 --- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/ExecutableTableRegistrySelfTest.java +++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/ExecutableTableRegistrySelfTest.java @@ -156,7 +156,7 @@ public class ExecutableTableRegistrySelfTest extends BaseIgniteAbstractTest { when(schemaRegistry.schema(tableVersion)).thenReturn(schemaDescriptor); IgniteTable sqlTable = new IgniteTableImpl( - "TBL1", tableId, tableVersion, descriptor, ImmutableIntList.of(0), new TestStatistic(1_000.0), Map.of(), 1, 10000 + "TBL1", tableId, tableVersion, tableVersion, descriptor, ImmutableIntList.of(0), new TestStatistic(1_000.0), Map.of(), 1, 10000 ); when(sqlSchemaManager.table(schemaVersion, tableId)).thenReturn(sqlTable); diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/framework/TestBuilders.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/framework/TestBuilders.java index 51ec7069cb1..67184e438e2 100644 --- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/framework/TestBuilders.java +++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/framework/TestBuilders.java @@ -1039,6 +1039,7 @@ public class TestBuilders { Objects.requireNonNull(name), tableId != null ? tableId : TABLE_ID_GEN.incrementAndGet(), 1, + 1L, tableDescriptor, findPrimaryKey(tableDescriptor, indexes.values()), new TestStatistic(size),
