From 6d931766c067dab4260ffdec4a11bb781e13e915 Mon Sep 17 00:00:00 2001 From: Nikolay Izhikov Date: Wed, 31 Jul 2024 12:15:40 +0300 Subject: [PATCH] IGNITE-22767 Fix index scan --- .../query/calcite/exec/IndexScan.java | 12 ++++++--- .../calcite/exec/RuntimeSortedIndex.java | 2 +- .../query/calcite/exec/TableScan.java | 9 ++++--- .../query/calcite/exec/rel/ModifyNode.java | 3 +++ .../tx/TransactionIsolationTest.java | 26 ++++++++++++------- 5 files changed, 36 insertions(+), 16 deletions(-) diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/IndexScan.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/IndexScan.java index 0e514fa9e988f..1854be2098db4 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/IndexScan.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/IndexScan.java @@ -417,8 +417,12 @@ private synchronized void release() { InlineIndexRowHandler rowHnd = idx.segment(0).rowHandler(); - InlineIndexRowFactory rowFactory = isInlineScan() ? - new InlineIndexRowFactory(rowHnd.inlineIndexKeyTypes().toArray(new InlineIndexKeyType[0]), rowHnd) : null; + InlineIndexRowFactory rowFactory = isInlineScan() + ? new InlineIndexRowFactory( + rowHnd.inlineIndexKeyTypes().toArray(new InlineIndexKeyType[0]), + rowHnd, + !F.isEmpty(ectx.getTxWriteEntries())) // Need access to CacheDataRow to corecctly handle transcaction context. + : null; BPlusTree.TreeRowClosure rowFilter = isInlineScan() ? null : createNotExpiredRowFilter(); @@ -444,10 +448,12 @@ private static class InlineIndexRowFactory implements BPlusTree.TreeRowFactory(comp, rows, lowerRow, upperRow, lowerInclude, upperInclude); } /** diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/TableScan.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/TableScan.java index 89565243bc19f..444b9fd25e56b 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/TableScan.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/TableScan.java @@ -263,9 +263,12 @@ private void advance() throws IgniteCheckedException { } } - CacheDataRow row = cur.next() - ? cur.get() - : txIter.hasNext() ? txIter.next() : null; + CacheDataRow row; + + if (cur.next()) + row = cur.get(); + else + row = txIter.hasNext() ? txIter.next() : null; if (row != null) { if (row.expireTime() > 0 && row.expireTime() <= U.currentTimeMillis()) diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/ModifyNode.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/ModifyNode.java index 963bdda27f4a4..c9453c186a773 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/ModifyNode.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/ModifyNode.java @@ -251,6 +251,9 @@ private void invokeInsideTx(GridNearTxLocal userTx, List tuples) th if (cache.get(entry.getKey()) != null) throw conflictKeysException(Collections.singletonList(entry.getKey())); + cache.put(entry.getKey(), entry.getValue()); + + break; case UPDATE: cache.put(entry.getKey(), entry.getValue()); diff --git a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/tx/TransactionIsolationTest.java b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/tx/TransactionIsolationTest.java index 76248565f05ae..986de9ad0c9ce 100644 --- a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/tx/TransactionIsolationTest.java +++ b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/tx/TransactionIsolationTest.java @@ -18,6 +18,7 @@ package org.apache.ignite.internal.processors.tx; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; @@ -148,9 +149,14 @@ public static Collection parameters() { .setValueType(User.class.getName()) .setKeyFieldName("id") .setFields(flds) - .setIndexes(Collections.singleton(new QueryIndex() - .setName("IDX_FIO_USERS") - .setFieldNames(Collections.singleton("fio"), true).setInlineSize(Character.BYTES * 20)))))); + .setIndexes(Arrays.asList( + new QueryIndex() + .setName("IDX_FIO_USERS") + .setFieldNames(Collections.singleton("fio"), true).setInlineSize(Character.BYTES * 20), + new QueryIndex() + .setName("IDX_USER_ID") + .setFieldNames(Collections.singleton("userId"), true) + ))))); cli.createCache(new CacheConfiguration() .setName("TBL") @@ -195,8 +201,6 @@ public void testIndexScan() { for (int j = 0; j < 5; j++) { int id = start + j + 1; - log.info("id = " + id); - insert(F.t(id, new User(id, "User" + j))); // Intentionally repeat FIO to make same indexed keys. } } @@ -207,11 +211,11 @@ public void testIndexScan() { for (int i = 0; i < 5; i++) { int start = i * 10 + 5; + assertEquals(i * 10 + 1, executeSql(cli, "SELECT MIN(userid) FROM USERS.USERS WHERE userid > ?", i * 10).get(0).get(0)); + for (int j = 0; j < 5; j++) { int id = start + j + 1; - log.info("id = " + id); - insert(F.t(id, new User(id, "User" + j))); // Intentionally repeat FIO to make same indexed keys. long expTblSz = 25L + i * 5 + j + 1; @@ -223,6 +227,12 @@ public void testIndexScan() { assertEquals(expTblSz, rows.size()); ensureSorted(rows, true); + + assertEquals( + id, + executeSql(cli, "SELECT MIN(userid) FROM USERS.USERS WHERE userid BETWEEN ? AND ?", id, 500).get(0).get(0) + ); + } } @@ -232,8 +242,6 @@ public void testIndexScan() { for (int j = 0; j < 5; j++) { int id = start + j + 1; - log.info("id = " + id); - delete(id); long expTblSz = 50L - (i * 5 + j + 1);