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

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


The following commit(s) were added to refs/heads/master by this push:
     new 01d88b7d120 Fix some bugs in AlignedTVListIterator
01d88b7d120 is described below

commit 01d88b7d120ff12bb043f3a33162990ff527560b
Author: shuwenwei <[email protected]>
AuthorDate: Tue Sep 2 09:32:00 2025 +0800

    Fix some bugs in AlignedTVListIterator
---
 .../db/it/aligned/IoTDBAlignedMemQueryIT.java      | 97 ++++++++++++++++++++++
 .../db/utils/datastructure/AlignedTVList.java      | 58 +++++++------
 .../MergeSortMultiAlignedTVListIterator.java       | 23 +++--
 .../memtable/AlignedTVListIteratorTest.java        | 21 +++--
 4 files changed, 153 insertions(+), 46 deletions(-)

diff --git 
a/integration-test/src/test/java/org/apache/iotdb/db/it/aligned/IoTDBAlignedMemQueryIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/db/it/aligned/IoTDBAlignedMemQueryIT.java
new file mode 100644
index 00000000000..036698c28c0
--- /dev/null
+++ 
b/integration-test/src/test/java/org/apache/iotdb/db/it/aligned/IoTDBAlignedMemQueryIT.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.it.aligned;
+
+import org.apache.iotdb.it.env.EnvFactory;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Locale;
+
+import static org.junit.Assert.assertEquals;
+
+public class IoTDBAlignedMemQueryIT {
+
+  @Before
+  public void setUp() throws Exception {
+    Locale.setDefault(Locale.ENGLISH);
+    EnvFactory.getEnv()
+        .getConfig()
+        .getCommonConfig()
+        .setPartitionInterval(1000)
+        .setMemtableSizeThreshold(10000);
+    EnvFactory.getEnv().initClusterEnvironment();
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    EnvFactory.getEnv().cleanClusterEnvironment();
+  }
+
+  @Test
+  public void test() throws SQLException {
+    try (Connection connection = EnvFactory.getEnv().getConnection();
+        Statement statement = connection.createStatement()) {
+
+      statement.execute("insert into root.vehicle.d0(time,s0) aligned values 
(10,310)");
+      statement.execute("insert into root.vehicle.d0(time,s3) aligned values 
(10,'text')");
+      statement.execute("insert into root.vehicle.d0(time,s4) aligned values 
(10,true)");
+
+      try (ResultSet set = statement.executeQuery("SELECT s0 FROM 
root.vehicle.d0")) {
+        int cnt = 0;
+        while (set.next()) {
+          cnt++;
+        }
+        assertEquals(1, cnt);
+      }
+
+      statement.execute("insert into root.vehicle.d1(time,s0,s1) aligned 
values (1,1,1)");
+      statement.execute("insert into root.vehicle.d1(time,s0) aligned values 
(2,2)");
+      statement.execute("insert into root.vehicle.d1(time,s1) aligned values 
(3,3)");
+
+      try (ResultSet set = statement.executeQuery("SELECT s0 FROM 
root.vehicle.d1")) {
+        int cnt = 0;
+        while (set.next()) {
+          cnt++;
+        }
+        assertEquals(2, cnt);
+      }
+      statement.execute("flush");
+
+      statement.execute("insert into root.vehicle.d1(time,s0,s1) aligned 
values (1,1,1)");
+      statement.execute("insert into root.vehicle.d1(time,s0) aligned values 
(2,2)");
+      statement.execute("insert into root.vehicle.d1(time,s1) aligned values 
(3,3)");
+
+      try (ResultSet set = statement.executeQuery("SELECT s0 FROM 
root.vehicle.d1")) {
+        int cnt = 0;
+        while (set.next()) {
+          cnt++;
+        }
+        assertEquals(2, cnt);
+      }
+    }
+  }
+}
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/AlignedTVList.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/AlignedTVList.java
index 5f45569d4b6..b7474d1583b 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/AlignedTVList.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/AlignedTVList.java
@@ -1705,17 +1705,14 @@ public abstract class AlignedTVList extends TVList {
           probeNext = true;
           return;
         }
-        if (scanOrder.isAscending()) {
-          // When traversing in ASC order, we only need to overwrite the 
previous non-null value
-          // with the non-null value encountered later
-          Arrays.fill(selectedIndices, index);
-        } else {
-          // When traversing in DESC order, we need to keep the non-null value 
encountered first,
-          // and only overwrite it if the previous value is null and current 
value is non-null. In
-          // order to identify the previous null, we use index -1 here to 
represent
-          for (int i = 0; i < selectedIndices.length; i++) {
-            selectedIndices[i] = isNullValue(index, i) ? -1 : index;
-          }
+        // When traversing in ASC order, we only need to overwrite the 
previous non-null value
+        // with the non-null value encountered later.
+        // When traversing in DESC order, we need to keep the non-null value 
encountered first,
+        // and only overwrite it if the previous value is null and current 
value is non-null.
+        for (int i = 0; i < selectedIndices.length; i++) {
+          // In order to identify the previous null, we use index -1 here to 
represent.
+          // The -1 here is also used for checking all null rows
+          selectedIndices[i] = isNullValue(index, i) ? -1 : index;
         }
         findValidRow = true;
 
@@ -1740,35 +1737,36 @@ public abstract class AlignedTVList extends TVList {
             }
           }
         }
-        // For DESC traversal, we previously set some -1. If these values are 
still -1 in the end,
-        // it means that each index is invalid. At this time, we can use any 
one at random.
-        if (!scanOrder.isAscending()) {
-          for (int i = 0; i < selectedIndices.length; i++) {
-            if (selectedIndices[i] == -1) {
-              selectedIndices[i] = index;
-            }
-          }
-        }
 
         // valueColumnsDeletionList is set when AlignedTVList iterator is 
created by
-        // MemPointIterator.single method. Otherwise, all-null rows is checked 
by
+        // MemPointIterator.single method. Otherwise, it is checked by
         // MergeSortMultiAlignedTVListIterator or 
OrderedMultiAlignedTVListIterator.
-        if (valueColumnsDeletionList != null) {
-          BitMap bitMap = new BitMap(dataTypeList.size());
+        if (ignoreAllNullRows) {
+          BitMap bitMap = null;
           time = getTime(getScanOrderIndex(index));
           for (int columnIndex = 0; columnIndex < dataTypeList.size(); 
columnIndex++) {
-            if (isNullValue(index, columnIndex)
-                || isPointDeleted(
-                    time,
-                    valueColumnsDeletionList.get(columnIndex),
-                    valueColumnDeleteCursor.get(columnIndex),
-                    scanOrder)) {
+            if (selectedIndices[columnIndex] == -1
+                || (valueColumnsDeletionList != null
+                    && isPointDeleted(
+                        time,
+                        valueColumnsDeletionList.get(columnIndex),
+                        valueColumnDeleteCursor.get(columnIndex),
+                        scanOrder))) {
+              bitMap = bitMap == null ? new BitMap(dataTypeList.size()) : 
bitMap;
               bitMap.mark(columnIndex);
             }
           }
-          if (ignoreAllNullRows && bitMap.isAllMarked()) {
+          if (bitMap != null && bitMap.isAllMarked()) {
             findValidRow = false;
             index++;
+            continue;
+          }
+        }
+        // We previously set some -1. If these values are still -1 in the end,
+        // it means that each index is invalid. At this time, we can use any 
one at random.
+        for (int i = 0; i < selectedIndices.length; i++) {
+          if (selectedIndices[i] == -1) {
+            selectedIndices[i] = index;
           }
         }
       }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/MergeSortMultiAlignedTVListIterator.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/MergeSortMultiAlignedTVListIterator.java
index b4b12d94386..153cb6856c1 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/MergeSortMultiAlignedTVListIterator.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/MergeSortMultiAlignedTVListIterator.java
@@ -115,11 +115,20 @@ public class MergeSortMultiAlignedTVListIterator extends 
MultiAlignedTVListItera
             .isNullValue(rowIndices[columnIndex], columnIndex)) {
           bitMap.mark(columnIndex);
         }
+        // check valueColumnsDeletionList
+        if (valueColumnsDeletionList != null
+            && isPointDeleted(
+                currentTime,
+                valueColumnsDeletionList.get(columnIndex),
+                valueColumnDeleteCursor.get(columnIndex),
+                scanOrder)) {
+          iteratorIndices[columnIndex] = -1;
+          bitMap.mark(columnIndex);
+        }
       }
       hasNext = true;
 
       // duplicated timestamps
-      boolean[] valueDeleted = new boolean[tsDataTypeList.size()];
       while (!heap.isEmpty() && heap.peek().left == currentTime) {
         Pair<Long, Integer> element = heap.poll();
         probeIterators.add(element.right);
@@ -127,10 +136,14 @@ public class MergeSortMultiAlignedTVListIterator extends 
MultiAlignedTVListItera
         for (int columnIndex = 0; columnIndex < tsDataTypeList.size(); 
columnIndex++) {
           // if current column null, it needs update
           int iteratorIndex = currentIteratorIndex(columnIndex);
-          if (iteratorIndex == -1
-              || alignedTvListIterators
-                  .get(iteratorIndex)
-                  .isNullValue(rowIndices[columnIndex], columnIndex)) {
+          if (iteratorIndex == -1) {
+            // -1 means all point of this timestamp was deleted by Deletion 
and no further
+            // processing is required.
+            continue;
+          }
+          if (alignedTvListIterators
+              .get(iteratorIndex)
+              .isNullValue(rowIndices[columnIndex], columnIndex)) {
             iteratorIndices[columnIndex] = element.right;
             rowIndices[columnIndex] =
                 
alignedTvListIterators.get(element.right).getSelectedIndex(columnIndex);
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AlignedTVListIteratorTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AlignedTVListIteratorTest.java
index 047e7abe088..f0ae227c05f 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AlignedTVListIteratorTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AlignedTVListIteratorTest.java
@@ -109,17 +109,16 @@ public class AlignedTVListIteratorTest {
   public void otherTest() throws IOException {
     Map<TVList, Integer> tvListMap =
         buildAlignedSingleTvListMap(Collections.singletonList(new TimeRange(1, 
1)));
-    //    testAligned(
-    //        tvListMap,
-    //        Ordering.ASC,
-    //        null,
-    //        null,
-    //        PaginationController.UNLIMITED_PAGINATION_CONTROLLER,
-    //        Collections.emptyList(),
-    //        Arrays.asList(Collections.emptyList(), Collections.emptyList(),
-    // Collections.emptyList()),
-    //        false,
-    //        1);
+    testAligned(
+        tvListMap,
+        Ordering.ASC,
+        null,
+        null,
+        PaginationController.UNLIMITED_PAGINATION_CONTROLLER,
+        Collections.emptyList(),
+        Arrays.asList(Collections.emptyList(), Collections.emptyList(), 
Collections.emptyList()),
+        false,
+        1);
     testAligned(
         tvListMap,
         Ordering.DESC,

Reply via email to