This is an automated email from the ASF dual-hosted git repository. shuwenwei pushed a commit to branch cp/18647-dev1.3 in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 38dd721c7f7c47083f63a447cfc93434aaeb7042 Author: shuwenwei <[email protected]> AuthorDate: Wed Sep 16 15:08:23 2026 +0800 Fix non-aligned TVList iterator stale prepared state --- .../iotdb/db/utils/datastructure/TVList.java | 1 + .../memtable/NonAlignedTVListIteratorTest.java | 72 ++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/TVList.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/TVList.java index e0d8e5b6de3..48260213140 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/TVList.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/TVList.java @@ -1239,6 +1239,7 @@ public abstract class TVList implements WALEntryValue { // been applied when constructing the tsBlock TsBlock tsBlock = builder.build(); addTsBlock(tsBlock); + probeNext = false; return tsBlock; } diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/memtable/NonAlignedTVListIteratorTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/memtable/NonAlignedTVListIteratorTest.java index b28979efd67..514fb93db4f 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/memtable/NonAlignedTVListIteratorTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/memtable/NonAlignedTVListIteratorTest.java @@ -26,6 +26,7 @@ import org.apache.iotdb.db.queryengine.common.PlanFragmentId; import org.apache.iotdb.db.queryengine.execution.fragment.FragmentInstanceContext; import org.apache.iotdb.db.queryengine.execution.fragment.FragmentInstanceStateMachine; import org.apache.iotdb.db.queryengine.plan.statement.component.Ordering; +import org.apache.iotdb.db.utils.datastructure.LongTVList; import org.apache.iotdb.db.utils.datastructure.MemPointIterator; import org.apache.iotdb.db.utils.datastructure.TVList; @@ -717,4 +718,75 @@ public class NonAlignedTVListIteratorTest { } Assert.assertEquals(expectedTimestamps, resultTimestamps); } + + @Test + public void testBatchToPointAfterEmptyPageKeepsLatestDuplicateValue() throws IOException { + LongTVList tvList = LongTVList.newList(); + tvList.putLong(1, 1); + tvList.putLong(100, 2); + tvList.putLong(100, 3); + + MemPointIterator iterator = + tvList.iterator( + Ordering.ASC, + tvList.rowCount(), + null, + Collections.emptyList(), + 0, + TSEncoding.PLAIN, + 1024, + null); + + iterator.setCurrentPageTimeRange(new TimeRange(1, 33)); + int firstPageRows = 0; + while (iterator.hasNextBatch()) { + firstPageRows += iterator.nextBatch().getPositionCount(); + } + Assert.assertEquals(1, firstPageRows); + + iterator.setCurrentPageTimeRange(new TimeRange(34, 66)); + Assert.assertFalse(iterator.hasNextBatch()); + + iterator.setCurrentPageTimeRange(new TimeRange(67, 100)); + List<Long> result = new ArrayList<>(); + while (iterator.hasNextTimeValuePair()) { + result.add(iterator.nextTimeValuePair().getValue().getLong()); + } + Assert.assertEquals(Collections.singletonList(3L), result); + } + + @Test + public void testBatchToPointAfterEmptyPageDescendingSkipsDeletedPoint() throws IOException { + LongTVList tvList = LongTVList.newList(); + tvList.putLong(10, 10); + tvList.putLong(100, 100); + + MemPointIterator iterator = + tvList.iterator( + Ordering.DESC, + tvList.rowCount(), + null, + Collections.singletonList(new TimeRange(10, 10)), + 0, + TSEncoding.PLAIN, + 1024, + null); + + iterator.setCurrentPageTimeRange(new TimeRange(67, 100)); + int firstPageRows = 0; + while (iterator.hasNextBatch()) { + firstPageRows += iterator.nextBatch().getPositionCount(); + } + Assert.assertEquals(1, firstPageRows); + + iterator.setCurrentPageTimeRange(new TimeRange(34, 66)); + Assert.assertFalse(iterator.hasNextBatch()); + + iterator.setCurrentPageTimeRange(new TimeRange(1, 33)); + List<Long> result = new ArrayList<>(); + while (iterator.hasNextTimeValuePair()) { + result.add(iterator.nextTimeValuePair().getValue().getLong()); + } + Assert.assertTrue(result.isEmpty()); + } }
