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

JingsongLi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/paimon.git


The following commit(s) were added to refs/heads/master by this push:
     new 2488a5ed33 [core] Fix readAllDeletionVectors not seeking to correct 
offset (#8211)
2488a5ed33 is described below

commit 2488a5ed33a97cca95fedd286405ec1fe412936f
Author: yugan <[email protected]>
AuthorDate: Fri Jun 12 15:43:29 2026 +0800

    [core] Fix readAllDeletionVectors not seeking to correct offset (#8211)
---
 .../deletionvectors/DeletionVectorsIndexFile.java  |  1 +
 .../DeletionVectorsIndexFileTest.java              | 56 ++++++++++++++++++++++
 2 files changed, 57 insertions(+)

diff --git 
a/paimon-core/src/main/java/org/apache/paimon/deletionvectors/DeletionVectorsIndexFile.java
 
b/paimon-core/src/main/java/org/apache/paimon/deletionvectors/DeletionVectorsIndexFile.java
index f643b0d6e9..e4606adf55 100644
--- 
a/paimon-core/src/main/java/org/apache/paimon/deletionvectors/DeletionVectorsIndexFile.java
+++ 
b/paimon-core/src/main/java/org/apache/paimon/deletionvectors/DeletionVectorsIndexFile.java
@@ -80,6 +80,7 @@ public class DeletionVectorsIndexFile extends IndexFile {
             checkVersion(inputStream);
             DataInputStream dataInputStream = new DataInputStream(inputStream);
             for (DeletionVectorMeta deletionVectorMeta : 
deletionVectorMetas.values()) {
+                inputStream.seek(deletionVectorMeta.offset());
                 deletionVectors.put(
                         deletionVectorMeta.dataFileName(),
                         DeletionVector.read(dataInputStream, (long) 
deletionVectorMeta.length()));
diff --git 
a/paimon-core/src/test/java/org/apache/paimon/deletionvectors/DeletionVectorsIndexFileTest.java
 
b/paimon-core/src/test/java/org/apache/paimon/deletionvectors/DeletionVectorsIndexFileTest.java
index ed342c9025..9a243bf8bf 100644
--- 
a/paimon-core/src/test/java/org/apache/paimon/deletionvectors/DeletionVectorsIndexFileTest.java
+++ 
b/paimon-core/src/test/java/org/apache/paimon/deletionvectors/DeletionVectorsIndexFileTest.java
@@ -34,7 +34,10 @@ import org.junit.jupiter.params.provider.ValueSource;
 import java.io.DataInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Random;
@@ -260,6 +263,59 @@ public class DeletionVectorsIndexFileTest {
         assertThat(dvs2.size()).isEqualTo(100000);
     }
 
+    @ParameterizedTest
+    @ValueSource(booleans = {false, true})
+    public void testReadAllDeletionVectorsWithOutOfOrderDvRanges(boolean 
bitmap64) {
+        IndexPathFactory pathFactory = getPathFactory();
+        DeletionVectorsIndexFile deletionVectorsIndexFile =
+                deletionVectorsIndexFile(pathFactory, bitmap64);
+
+        // write multiple DVs so they are stored sequentially in the index file
+        HashMap<String, DeletionVector> deleteMap = new HashMap<>();
+        Map<String, Integer> expected = new HashMap<>();
+        for (int i = 0; i < 10; i++) {
+            DeletionVector dv = createEmptyDV(bitmap64);
+            dv.delete(i * 100);
+            dv.delete(i * 100 + 1);
+            deleteMap.put("file" + i + ".parquet", dv);
+            expected.put("file" + i + ".parquet", i * 100);
+        }
+
+        List<IndexFileMeta> indexFiles = 
deletionVectorsIndexFile.writeWithRolling(deleteMap);
+        assertThat(indexFiles.size()).isEqualTo(1);
+        IndexFileMeta original = indexFiles.get(0);
+
+        // build a new IndexFileMeta with dvRanges in reverse offset order,
+        // simulating compaction merging dvRanges from multiple sources
+        LinkedHashMap<String, DeletionVectorMeta> originalRanges = 
original.dvRanges();
+        List<Map.Entry<String, DeletionVectorMeta>> entries =
+                new ArrayList<>(originalRanges.entrySet());
+        Collections.reverse(entries);
+        LinkedHashMap<String, DeletionVectorMeta> reversedRanges = new 
LinkedHashMap<>();
+        for (Map.Entry<String, DeletionVectorMeta> entry : entries) {
+            reversedRanges.put(entry.getKey(), entry.getValue());
+        }
+
+        IndexFileMeta reordered =
+                new IndexFileMeta(
+                        original.indexType(),
+                        original.fileName(),
+                        original.fileSize(),
+                        original.rowCount(),
+                        reversedRanges,
+                        original.externalPath());
+
+        // read with out-of-order dvRanges — this would fail without the seek 
fix
+        Map<String, DeletionVector> result =
+                deletionVectorsIndexFile.readAllDeletionVectors(reordered);
+        assertThat(result).hasSize(10);
+        for (Map.Entry<String, Integer> e : expected.entrySet()) {
+            
assertThat(result.get(e.getKey()).isDeleted(e.getValue())).isTrue();
+            assertThat(result.get(e.getKey()).isDeleted(e.getValue() + 
1)).isTrue();
+            assertThat(result.get(e.getKey()).isDeleted(e.getValue() + 
2)).isFalse();
+        }
+    }
+
     @ParameterizedTest
     @ValueSource(booleans = {false, true})
     public void testReadDeletionFile(boolean bitmap64) throws IOException {

Reply via email to