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

asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new c172e7cd698 IGNITE-27854 SQL: Fix inline index search on TIME field 
with nanoseconds - Fixes #13085.
c172e7cd698 is described below

commit c172e7cd6981d9955cc18add94216313191358b7
Author: Aleksey Plekhanov <[email protected]>
AuthorDate: Thu Apr 30 09:25:31 2026 +0300

    IGNITE-27854 SQL: Fix inline index search on TIME field with nanoseconds - 
Fixes #13085.
    
    Signed-off-by: Aleksey Plekhanov <[email protected]>
---
 .../internal/processors/query/h2/H2Utils.java      | 19 ++++++++
 .../processors/query/h2/database/H2TreeIndex.java  |  4 +-
 .../CacheQueryEntityWithDateTimeApiFieldsTest.java | 54 +++++++++++-----------
 3 files changed, 49 insertions(+), 28 deletions(-)

diff --git 
a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Utils.java
 
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Utils.java
index 1302fbf9901..322cfb1f6e2 100644
--- 
a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Utils.java
+++ 
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Utils.java
@@ -39,6 +39,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.UUID;
+import java.util.concurrent.TimeUnit;
 import javax.cache.CacheException;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteException;
@@ -604,6 +605,24 @@ public class H2Utils {
         throw new IgniteCheckedException("Failed to wrap value[type=" + type + 
", value=" + obj + "]");
     }
 
+    /**
+     * Unwraps {@link Value} to respective object.
+     *
+     * @param val Value.
+     * @return Unwrapped object.
+     */
+    public static Object unwrap(Value val) {
+        if (val instanceof ValueTime) {
+            // Gets time preserving nanoseconds. Method ValueTime#getObject() 
returns Time object without nanoseconds.
+            ValueTime val0 = (ValueTime)val;
+
+            if (val0.getNanos() % TimeUnit.MILLISECONDS.toNanos(1L) != 0)
+                return LocalDateTimeUtils.valueToLocalTime(val);
+        }
+
+        return val.getObject();
+    }
+
     /**
      * Gets corresponding DB type from java class.
      *
diff --git 
a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndex.java
 
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndex.java
index d885e504d52..9741e864f1a 100644
--- 
a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndex.java
+++ 
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndex.java
@@ -294,7 +294,7 @@ public class H2TreeIndex extends H2TreeIndexBase {
                 else {
                     InlineIndexKeyType colKeyType = 
InlineIndexKeyTypeRegistry.get(colType, queryIndex.keyTypeSettings());
 
-                    IndexKey idxKey = IndexKeyFactory.wrap(v.getObject(), 
v.getType(), cctx.cacheObjectContext(),
+                    IndexKey idxKey = IndexKeyFactory.wrap(H2Utils.unwrap(v), 
v.getType(), cctx.cacheObjectContext(),
                         queryIndex.keyTypeSettings());
 
                     if (colKeyType.isComparableTo(idxKey)) {
@@ -312,7 +312,7 @@ public class H2TreeIndex extends H2TreeIndexBase {
             }
 
             keys[i] = IndexKeyFactory.wrap(
-                v.getObject(), v.getType(), cctx.cacheObjectContext(), 
queryIndex.keyTypeSettings());
+                H2Utils.unwrap(v), v.getType(), cctx.cacheObjectContext(), 
queryIndex.keyTypeSettings());
         }
 
         return new IndexPlainRowImpl(keys, rowHnd);
diff --git 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/CacheQueryEntityWithDateTimeApiFieldsTest.java
 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/CacheQueryEntityWithDateTimeApiFieldsTest.java
index 3aeef8712c4..a917d7cc3ef 100644
--- 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/CacheQueryEntityWithDateTimeApiFieldsTest.java
+++ 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/CacheQueryEntityWithDateTimeApiFieldsTest.java
@@ -35,6 +35,7 @@ import org.apache.ignite.cache.query.SqlFieldsQuery;
 import org.apache.ignite.cache.query.annotations.QuerySqlField;
 import org.apache.ignite.configuration.CacheConfiguration;
 import 
org.apache.ignite.internal.processors.cache.index.AbstractIndexingCommonTest;
+import org.apache.ignite.internal.processors.query.QueryUtils;
 import org.junit.Ignore;
 import org.junit.Test;
 
@@ -111,11 +112,9 @@ public class CacheQueryEntityWithDateTimeApiFieldsTest 
extends AbstractIndexingC
 
     /**
      * Tests insertion of an entity.
-     *
-     * @throws Exception If failed.
      */
     @Test
-    public void testInsertEntityFields() throws Exception {
+    public void testInsertEntityFields() {
         cache.remove(entity.getId());
 
         assertEquals(0, cache.size());
@@ -136,11 +135,9 @@ public class CacheQueryEntityWithDateTimeApiFieldsTest 
extends AbstractIndexingC
 
     /**
      * Tests MERGE statement.
-     *
-     * @throws Exception If failed.
      */
     @Test
-    public void testMergeEntityFields() throws Exception {
+    public void testMergeEntityFields() {
         assertEquals(1, cache.size());
 
         SqlFieldsQuery qry = new SqlFieldsQuery(
@@ -160,11 +157,9 @@ public class CacheQueryEntityWithDateTimeApiFieldsTest 
extends AbstractIndexingC
     /**
      * Tests that DATEDIFF SQL function works for {@link LocalDateTime}
      * fields with the time part set to midnight.
-     *
-     * @throws Exception If failed.
      */
     @Test
-    public void testDateDiffForLocalDateTimeFieldAtMidnight() throws Exception 
{
+    public void testDateDiffForLocalDateTimeFieldAtMidnight() {
         SqlFieldsQuery qry =
             new SqlFieldsQuery("select DATEDIFF('DAY', locDateTime, 
CURRENT_DATE ()) from EntityWithDateTimeFields");
 
@@ -176,11 +171,9 @@ public class CacheQueryEntityWithDateTimeApiFieldsTest 
extends AbstractIndexingC
 
     /**
      * Tests that selection for a {@link LocalTime} field returns {@link Time}.
-     *
-     * @throws Exception If failed.
      */
     @Test
-    public void testSelectLocalTimeFieldReturnsTime() throws Exception {
+    public void testSelectLocalTimeFieldReturnsTime() {
         SqlFieldsQuery qry = new SqlFieldsQuery("select locTime from 
EntityWithDateTimeFields");
 
         List<List<?>> qryResults = cache.query(qry).getAll();
@@ -191,11 +184,9 @@ public class CacheQueryEntityWithDateTimeApiFieldsTest 
extends AbstractIndexingC
 
     /**
      * Tests that selection for a {@link LocalDate} field returns {@link Date}.
-     *
-     * @throws Exception If failed.
      */
     @Test
-    public void testSelectLocalDateFieldReturnsDate() throws Exception {
+    public void testSelectLocalDateFieldReturnsDate() {
         SqlFieldsQuery qry = new SqlFieldsQuery("select locDate from 
EntityWithDateTimeFields");
 
         List<List<?>> qryResults = cache.query(qry).getAll();
@@ -206,11 +197,9 @@ public class CacheQueryEntityWithDateTimeApiFieldsTest 
extends AbstractIndexingC
 
     /**
      * Tests that selection for a {@link LocalDateTime} field returns {@link 
Timestamp}.
-     *
-     * @throws Exception If failed.
      */
     @Test
-    public void testSelectLocalDateTimeFieldReturnsTimestamp() throws 
Exception {
+    public void testSelectLocalDateTimeFieldReturnsTimestamp() {
         SqlFieldsQuery qry = new SqlFieldsQuery("select locDateTime from 
EntityWithDateTimeFields");
 
         List<List<?>> qryResults = cache.query(qry).getAll();
@@ -224,14 +213,27 @@ public class CacheQueryEntityWithDateTimeApiFieldsTest 
extends AbstractIndexingC
      */
     @Test
     public void testSelectByAllFields() {
-        SqlFieldsQuery qry = new SqlFieldsQuery(
-            "select locDate from EntityWithDateTimeFields where locTime = ? 
and locDate = ? and locDateTime = ?"
-        ).setArgs(entity.getLocalTime(), entity.getLocalDate(), 
entity.getLocalDateTime());
-
-        List<List<?>> qryResults = cache.query(qry).getAll();
-
-        assertEquals(1, qryResults.size());
-        assertEquals(Date.valueOf(entity.getLocalDate()), 
qryResults.get(0).get(0));
+        String[] idxs = new String[] {
+            QueryUtils.PRIMARY_KEY_INDEX,
+            "ENTITYWITHDATETIMEFIELDS_LOCTIME_IDX",
+            "ENTITYWITHDATETIMEFIELDS_LOCDATETIME_IDX",
+            "ENTITYWITHDATETIMEFIELDS_LOCDATE_IDX",
+        };
+
+        for (String idx : idxs) {
+            String sql = "select locDate, locTime, locDateTime from 
EntityWithDateTimeFields " +
+                "use index (\"" + idx + "\") where locTime = ? and locDate = ? 
and locDateTime = ?";
+
+            SqlFieldsQuery qry = new SqlFieldsQuery(sql)
+                .setArgs(entity.getLocalTime(), entity.getLocalDate(), 
entity.getLocalDateTime());
+
+            List<List<?>> qryResults = cache.query(qry).getAll();
+
+            assertEquals("Unexpected result size for query [sql=" + sql + ']', 
1, qryResults.size());
+            assertEquals(Date.valueOf(entity.getLocalDate()), 
qryResults.get(0).get(0));
+            assertEquals(Time.valueOf(entity.getLocalTime()), 
qryResults.get(0).get(1));
+            assertEquals(Timestamp.valueOf(entity.getLocalDateTime()), 
qryResults.get(0).get(2));
+        }
     }
 
     /**

Reply via email to