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

Reply via email to