This is an automated email from the ASF dual-hosted git repository. tkalkirill pushed a commit to branch ignite-xxxxx-rowid-poc in repository https://gitbox.apache.org/repos/asf/ignite.git
commit e218a5252a52e8c2c6c48c59325938b6226c5cc5 Author: Kirill Tkalenko <[email protected]> AuthorDate: Wed Feb 18 16:11:58 2026 +0300 IGNITE-xxxxx-rowid-poc First step --- .../calcite/schema/CacheTableDescriptorImpl.java | 89 +++++++++++++++++++++- .../integration/RowIdColumnIntegrationTest.java | 66 ++++++++++++++++ .../ignite/jdbc/thin/JdbcThinMetadataSelfTest.java | 1 + .../internal/processors/query/QueryUtils.java | 58 ++++++++++++++ 4 files changed, 212 insertions(+), 2 deletions(-) diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/CacheTableDescriptorImpl.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/CacheTableDescriptorImpl.java index 2cd164bc815..087a214de70 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/CacheTableDescriptorImpl.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/CacheTableDescriptorImpl.java @@ -19,6 +19,7 @@ package org.apache.ignite.internal.processors.query.calcite.schema; import java.util.ArrayList; import java.util.Arrays; +import java.util.Base64; import java.util.BitSet; import java.util.Collection; import java.util.Collections; @@ -42,6 +43,7 @@ import org.apache.calcite.sql2rel.NullInitializerExpressionFactory; import org.apache.calcite.util.ImmutableBitSet; import org.apache.calcite.util.ImmutableIntList; import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.IgniteException; import org.apache.ignite.binary.BinaryObject; import org.apache.ignite.binary.BinaryObjectBuilder; import org.apache.ignite.cache.CacheWriteSynchronizationMode; @@ -148,11 +150,14 @@ public class CacheTableDescriptorImpl extends NullInitializerExpressionFactory descriptors.add( new KeyValDescriptor(QueryUtils.VAL_FIELD_NAME, typeDesc.valueClass(), false, QueryUtils.VAL_COL)); - int fldIdx = QueryUtils.VAL_COL + 1; + descriptors.add(new RowIdDescriptor()); + + int fldIdx = QueryUtils.ROW_ID_COL + 1; int keyField = QueryUtils.KEY_COL; int valField = QueryUtils.VAL_COL; + // TODO: IGNITE-xxxxx-rowid-poc Пока ничего тут не понял for (String field : fields) { GridQueryProperty prop = typeDesc.property(field); @@ -615,6 +620,78 @@ public class CacheTableDescriptorImpl extends NullInitializerExpressionFactory return true; } + /** */ + private static class RowIdDescriptor implements CacheColumnDescriptor { + /** */ + private volatile RelDataType logicalType; + + /** {@inheritDoc} */ + @Override public boolean field() { + return false; + } + + /** {@inheritDoc} */ + @Override public boolean key() { + return true; + } + + /** {@inheritDoc} */ + @Override public boolean hasDefaultValue() { + return false; + } + + /** {@inheritDoc} */ + @Override public Object defaultValue() { + throw new AssertionError(); + } + + /** {@inheritDoc} */ + @Override public String name() { + return QueryUtils.ROW_ID_FIELD_NAME; + } + + /** {@inheritDoc} */ + @Override public int fieldIndex() { + return QueryUtils.ROW_ID_COL; + } + + /** {@inheritDoc} */ + @Override public RelDataType logicalType(IgniteTypeFactory f) { + if (logicalType == null) { + logicalType = TypeUtils.sqlType(f, storageType(), PRECISION_NOT_SPECIFIED, SCALE_NOT_SPECIFIED, true); + } + + return logicalType; + } + + /** {@inheritDoc} */ + @Override public Class<?> storageType() { + return String.class; + } + + /** {@inheritDoc} */ + @Override public Object value(ExecutionContext<?> ectx, GridCacheContext<?, ?> cctx, CacheDataRow src) { + // TODO: IGNITE-xxxxx-rowid-poc Как-то реализовать + try { + byte[] bytes = src.key().valueBytes(cctx.cacheObjectContext()); + + String base64Str = Base64.getEncoder().encodeToString(bytes); + + //cctx.logger(getClass()).warning(">>>>> Encoded rowid=" + base64Str, new Exception()); + cctx.logger(getClass()).info(">>>>> Encoded rowid=" + base64Str); + + return base64Str; + } catch (IgniteCheckedException e) { + throw new IgniteException("Failed to get rowid", e); + } + } + + /** {@inheritDoc} */ + @Override public void set(Object dst, Object val) { + throw new AssertionError(); + } + } + /** */ private static class KeyValDescriptor implements CacheColumnDescriptor { /** */ @@ -707,7 +784,15 @@ public class CacheTableDescriptorImpl extends NullInitializerExpressionFactory /** {@inheritDoc} */ @Override public Object value(ExecutionContext<?> ectx, GridCacheContext<?, ?> cctx, CacheDataRow src) { - return cctx.unwrapBinaryIfNeeded(isKey ? src.key() : src.value(), ectx.keepBinary(), null); + if (isKey) { + Object o = cctx.unwrapBinaryIfNeeded(src.key(), ectx.keepBinary(), null); + + cctx.logger(getClass()).info(">>>>> Encoded _key=" + o); + + return o; + } else { + return cctx.unwrapBinaryIfNeeded(src.value(), ectx.keepBinary(), null); + } } /** {@inheritDoc} */ diff --git a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/RowIdColumnIntegrationTest.java b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/RowIdColumnIntegrationTest.java new file mode 100644 index 00000000000..1730571a81f --- /dev/null +++ b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/RowIdColumnIntegrationTest.java @@ -0,0 +1,66 @@ +package org.apache.ignite.internal.processors.query.calcite.integration; + +import java.util.List; +import org.apache.ignite.calcite.CalciteQueryEngineConfiguration; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.configuration.SqlConfiguration; +import org.junit.Test; + +/** */ +// TODO: IGNITE-xxxxx-rowid-poc Документация и прочая красота везде +// TODO: IGNITE-xxxxx-rowid-poc Нужно будет сдлеть больше тестов тут или рядом: +// TODO: IGNITE-xxxxx-rowid-poc - pk - составной ключ (несколько колонок) +// TODO: IGNITE-xxxxx-rowid-poc - запрос с keppBinary = {false, true} +// TODO: IGNITE-xxxxx-rowid-poc - будет видна в фукциях в том числе табличных +// TODO: IGNITE-xxxxx-rowid-poc - всякие dml с указанием колонки в условии и прочее +// TODO: IGNITE-xxxxx-rowid-poc - может проветить еще с as t что-то вроде select t.rowid from PERSON as t +// TODO: IGNITE-xxxxx-rowid-poc - jdbc что будет работать все выше сценарии +public class RowIdColumnIntegrationTest extends AbstractBasicIntegrationTest { + /** {@inheritDoc} */ + @Override protected int nodeCount() { + return 1; + } + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { + SqlConfiguration sqlCfg = new SqlConfiguration() + .setQueryEnginesConfiguration(new CalciteQueryEngineConfiguration().setDefault(true)); + + return super.getConfiguration(igniteInstanceName) + .setSqlConfiguration(sqlCfg) + .setCacheConfiguration(new CacheConfiguration<>(DEFAULT_CACHE_NAME)); + } + + /** */ + @Test + public void test() { + //String column = "_key"; + String column = "rowid"; + + sql("create table PERSON(id int primary key, name varchar)"); + + sql("insert into PERSON(id, name) values(?, ?)", 1, "Foo"); + sql("insert into PERSON(id, name) values(?, ?)", 2, "Bar"); + sql("insert into PERSON(id, name) values(?, ?)", 3, "Cat"); + sql("insert into PERSON(id, name) values(?, ?)", 4, "Cat"); + sql("insert into PERSON(id, name) values(?, ?)", 5, "Cat"); + sql("insert into PERSON(id, name) values(?, ?)", 6, "Cat"); + sql("insert into PERSON(id, name) values(?, ?)", 7, "Cat"); + sql("insert into PERSON(id, name) values(?, ?)", 8, "Cat"); + sql("insert into PERSON(id, name) values(?, ?)", 9, "Cat"); + sql("insert into PERSON(id, name) values(?, ?)", 10, "Cat"); + + List<List<?>> selectRes = sql(String.format("select %s, id, name from PERSON order by id", column)); + + log.info(">>>>> Select result: " + selectRes); + + for (List<?> row : selectRes) { + List<List<?>> act = sql(String.format("select id, name from PERSON where %s = ?", column), row.get(0)); + + log.info(">>>>> act: " + act); + + assertEquals(List.of(List.of(row.get(1), row.get(2))), act); + } + } +} diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java index b2de892d55e..7d338a01c8a 100644 --- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java +++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java @@ -231,6 +231,7 @@ public class JdbcThinMetadataSelfTest extends JdbcThinAbstractSelfTest { assertTrue(rs.next()); assertEquals(cacheName, rs.getString(MetadataColumn.TABLE_SCHEMA.columnName())); + // TODO: IGNITE-xxxxx-rowid-poc Потом посмотреть что это assertEquals(KEY_FIELD_NAME, rs.getString(MetadataColumn.COLUMN_NAME.columnName())); assertTrue(rs.next()); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java index a815c4ce450..dd229fd7f97 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java @@ -97,6 +97,9 @@ public class QueryUtils { /** Value column. */ public static final int VAL_COL = 1; + /** */ + public static final int ROW_ID_COL = 2; + /** Default schema. */ public static final String DFLT_SCHEMA = "PUBLIC"; @@ -118,6 +121,9 @@ public class QueryUtils { /** Field name for value. */ public static final String VAL_FIELD_NAME = "_VAL"; + /** */ + public static final String ROW_ID_FIELD_NAME = "ROWID"; + /** Well-known template name for PARTITIONED cache. */ public static final String TEMPLATE_PARTITIONED = "PARTITIONED"; @@ -1875,4 +1881,56 @@ public class QueryUtils { return -1; } } + + public static class RowIdProperty implements GridQueryProperty { + /** {@inheritDoc} */ + @Override public Object value(Object key, Object val) throws IgniteCheckedException { + return key; + } + + /** {@inheritDoc} */ + @Override public void setValue(Object key, Object val, Object propVal) throws IgniteCheckedException { + //No-op + } + + /** {@inheritDoc} */ + @Override public String name() { + return QueryUtils.ROW_ID_FIELD_NAME; + } + + /** {@inheritDoc} */ + @Override public Class<?> type() { + return String.class; + } + + /** {@inheritDoc} */ + @Override public boolean key() { + return true; + } + + /** {@inheritDoc} */ + @Override public GridQueryProperty parent() { + return null; + } + + /** {@inheritDoc} */ + @Override public boolean notNull() { + return true; + } + + /** {@inheritDoc} */ + @Override public Object defaultValue() { + return null; + } + + /** {@inheritDoc} */ + @Override public int precision() { + return -1; + } + + /** {@inheritDoc} */ + @Override public int scale() { + return -1; + } + } }
