This is an automated email from the ASF dual-hosted git repository. haonan pushed a commit to branch fix_insert_all_null_tablet_1.3 in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 37b2b0dbd358b8aec678e5970f98ee662b0713f2 Author: HTHou <[email protected]> AuthorDate: Mon Jan 19 18:42:08 2026 +0800 cherry-pick Fix query error after insert an all null aligned tablet and flush (#14777) --- .../iotdb/session/it/IoTDBSessionInsertNullIT.java | 68 ++++++++++++++++++++++ .../dataregion/flush/MemTableFlushTask.java | 2 +- .../memtable/AlignedWritableMemChunk.java | 23 +++++++- .../memtable/AlignedWritableMemChunkGroup.java | 5 ++ .../memtable/IWritableMemChunkGroup.java | 2 + .../dataregion/memtable/WritableMemChunkGroup.java | 5 ++ 6 files changed, 103 insertions(+), 2 deletions(-) diff --git a/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBSessionInsertNullIT.java b/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBSessionInsertNullIT.java index 503b61f2d7c..9c6b228763c 100644 --- a/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBSessionInsertNullIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBSessionInsertNullIT.java @@ -359,6 +359,74 @@ public class IoTDBSessionInsertNullIT { } } + @Test + public void insertTabletNullTest() { + try (ISession session = EnvFactory.getEnv().getSessionConnection()) { + prepareData(session); + + String deviceId = "root.sg1.clsu.d1"; + Tablet tablet = + new Tablet( + deviceId, + Arrays.asList( + new MeasurementSchema("s1", TSDataType.BOOLEAN), + new MeasurementSchema("s2", TSDataType.INT32)), + 3); + tablet.addTimestamp(0, 300); + tablet.addValue("s1", 0, null); + tablet.addValue("s2", 0, null); + tablet.addTimestamp(1, 400); + tablet.addValue("s1", 1, null); + tablet.addValue("s2", 1, null); + tablet.addTimestamp(2, 500); + tablet.addValue("s1", 2, null); + tablet.addValue("s2", 2, null); + session.insertTablet(tablet); + long nums = queryCountRecords(session, "select count(s1) from " + deviceId); + assertEquals(0, nums); + session.executeNonQueryStatement("flush"); + nums = queryCountRecords(session, "select count(s1) from " + deviceId); + assertEquals(0, nums); + } catch (Exception e) { + e.printStackTrace(); + fail(e.getMessage()); + } + } + + @Test + public void insertAlignedTabletNullTest() { + try (ISession session = EnvFactory.getEnv().getSessionConnection()) { + prepareData(session); + + String deviceId = "root.sg1.clsu.aligned_d1"; + Tablet tablet = + new Tablet( + deviceId, + Arrays.asList( + new MeasurementSchema("s1", TSDataType.BOOLEAN), + new MeasurementSchema("s2", TSDataType.INT32)), + 3); + tablet.addTimestamp(0, 300); + tablet.addValue("s1", 0, null); + tablet.addValue("s2", 0, null); + tablet.addTimestamp(1, 400); + tablet.addValue("s1", 1, null); + tablet.addValue("s2", 1, null); + tablet.addTimestamp(2, 500); + tablet.addValue("s1", 2, null); + tablet.addValue("s2", 2, null); + session.insertAlignedTablet(tablet); + long nums = queryCountRecords(session, "select count(s1) from " + deviceId); + assertEquals(0, nums); + session.executeNonQueryStatement("flush"); + nums = queryCountRecords(session, "select count(s1) from " + deviceId); + assertEquals(0, nums); + } catch (Exception e) { + e.printStackTrace(); + fail(e.getMessage()); + } + } + @Test public void insertTabletNullMeasurementTest() { try (ISession session = EnvFactory.getEnv().getSessionConnection()) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/flush/MemTableFlushTask.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/flush/MemTableFlushTask.java index 61abb78c24f..48efe55c223 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/flush/MemTableFlushTask.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/flush/MemTableFlushTask.java @@ -159,7 +159,7 @@ public class MemTableFlushTask { for (IDeviceID deviceID : deviceIDList) { final Map<String, IWritableMemChunk> value = memTableMap.get(deviceID).getMemChunkMap(); // skip the empty device/chunk group - if (memTableMap.get(deviceID).count() == 0 || value.isEmpty()) { + if (memTableMap.get(deviceID).isEmpty() || value.isEmpty()) { continue; } encodingTaskQueue.put(new StartFlushGroupIOTask(deviceID)); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AlignedWritableMemChunk.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AlignedWritableMemChunk.java index 50ae45b432c..2fca3ca398a 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AlignedWritableMemChunk.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AlignedWritableMemChunk.java @@ -593,7 +593,28 @@ public class AlignedWritableMemChunk extends AbstractWritableMemChunk { @Override public boolean isEmpty() { - return rowCount() == 0; + if (rowCount() == 0) { + return true; + } + if (measurementIndexMap.isEmpty()) { + return true; + } + + if (list.rowCount() > 0) { + BitMap allValueColDeletedMap = list.getAllValueColDeletedMap(); + if (allValueColDeletedMap == null || !allValueColDeletedMap.isAllMarked()) { + return false; + } + } + for (AlignedTVList alignedTvList : sortedList) { + if (alignedTvList.rowCount() > 0) { + BitMap allValueColDeletedMap = alignedTvList.getAllValueColDeletedMap(); + if (allValueColDeletedMap == null || !allValueColDeletedMap.isAllMarked()) { + return false; + } + } + } + return true; } @Override diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AlignedWritableMemChunkGroup.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AlignedWritableMemChunkGroup.java index bc2031c069a..6a9571fbc6c 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AlignedWritableMemChunkGroup.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AlignedWritableMemChunkGroup.java @@ -102,6 +102,11 @@ public class AlignedWritableMemChunkGroup implements IWritableMemChunkGroup { return Collections.singletonMap("", memChunk); } + @Override + public boolean isEmpty() { + return memChunk.isEmpty(); + } + @SuppressWarnings("squid:S3776") @Override public int delete( diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/IWritableMemChunkGroup.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/IWritableMemChunkGroup.java index 79baafe86fd..1738a8b9254 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/IWritableMemChunkGroup.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/IWritableMemChunkGroup.java @@ -48,6 +48,8 @@ public interface IWritableMemChunkGroup extends WALEntryValue { Map<String, IWritableMemChunk> getMemChunkMap(); + boolean isEmpty(); + int delete( PartialPath originalPath, PartialPath devicePath, long startTimestamp, long endTimestamp); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/WritableMemChunkGroup.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/WritableMemChunkGroup.java index 313fcd71540..226c2fd3980 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/WritableMemChunkGroup.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/WritableMemChunkGroup.java @@ -109,6 +109,11 @@ public class WritableMemChunkGroup implements IWritableMemChunkGroup { return memChunkMap; } + @Override + public boolean isEmpty() { + return memChunkMap.isEmpty() || count() == 0; + } + @SuppressWarnings("squid:S3776") @Override public int delete(
