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

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

commit e82aacfb64c366e24546934655475fd91fca9101
Author: Tian Jiang <[email protected]>
AuthorDate: Wed Nov 27 10:08:35 2024 +0800

    Fix query failure if a table deletion involves deviceId with null
---
 .../relational/it/db/it/IoTDBDeletionTableIT.java  | 21 +++++++++++++++++
 .../iotdb/db/metadata/path/PatternTreeMapTest.java | 27 +++++++++++++++++++---
 .../org/apache/iotdb/commons/path/PartialPath.java |  3 ++-
 .../apache/iotdb/commons/path/PatternTreeMap.java  |  2 +-
 4 files changed, 48 insertions(+), 5 deletions(-)

diff --git 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBDeletionTableIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBDeletionTableIT.java
index 1b25695c318..57e7692fda1 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBDeletionTableIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBDeletionTableIT.java
@@ -570,6 +570,27 @@ public class IoTDBDeletionTableIT {
     cleanData(testNum);
   }
 
+  @Test
+  public void testDeviceIdWithNull() throws SQLException {
+    int testNum = 14;
+    try (Connection connection = 
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+        Statement statement = connection.createStatement()) {
+      statement.execute("use test");
+      statement.execute(
+          "create table t" + testNum + " (id1 string id, id2 string id, s1 
int32 measurement)");
+      // id1 is null for this record
+      statement.execute("insert into t" + testNum + " (time, id2, s1) values 
(1, '1', 1)");
+      statement.execute("flush");
+      statement.execute("delete from t" + testNum);
+
+      try (ResultSet set = statement.executeQuery("SELECT * FROM t" + 
testNum)) {
+        assertFalse(set.next());
+      }
+
+      statement.execute("drop table t" + testNum);
+    }
+  }
+
   @Ignore
   @Test
   public void testDeletionWritePerformance() throws SQLException, IOException {
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/metadata/path/PatternTreeMapTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/metadata/path/PatternTreeMapTest.java
index 3292eb8ca86..e32b3c9f5bc 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/metadata/path/PatternTreeMapTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/metadata/path/PatternTreeMapTest.java
@@ -22,12 +22,17 @@ import 
org.apache.iotdb.commons.exception.IllegalPathException;
 import org.apache.iotdb.commons.path.MeasurementPath;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.commons.path.PatternTreeMap;
+import 
org.apache.iotdb.db.storageengine.dataregion.modification.DeletionPredicate;
+import 
org.apache.iotdb.db.storageengine.dataregion.modification.IDPredicate.NOP;
 import org.apache.iotdb.db.storageengine.dataregion.modification.ModEntry;
+import 
org.apache.iotdb.db.storageengine.dataregion.modification.TableDeletionEntry;
 import 
org.apache.iotdb.db.storageengine.dataregion.modification.TreeDeletionEntry;
 import org.apache.iotdb.db.utils.datastructure.PatternTreeMapFactory;
 import 
org.apache.iotdb.db.utils.datastructure.PatternTreeMapFactory.ModsSerializer;
 import 
org.apache.iotdb.db.utils.datastructure.PatternTreeMapFactory.StringSerializer;
 
+import org.apache.tsfile.file.metadata.IDeviceID.Factory;
+import org.apache.tsfile.read.common.TimeRange;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -37,6 +42,9 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
 public class PatternTreeMapTest {
 
   @Test
@@ -213,12 +221,25 @@ public class PatternTreeMapTest {
             new TreeDeletionEntry(new MeasurementPath("root.sg1.d1.*.d3.s4"), 
4, 6)));
   }
 
+  @Test
+  public void testDeviceIdWithNull() {
+    PatternTreeMap<ModEntry, ModsSerializer> patternTreeMap =
+        PatternTreeMapFactory.getModsPatternTreeMap();
+    ModEntry modEntry =
+        new TableDeletionEntry(new DeletionPredicate("table1", new NOP()), new 
TimeRange(0, 100));
+    patternTreeMap.append(modEntry.keyOfPatternTree(), modEntry);
+    List<ModEntry> result =
+        patternTreeMap.getOverlapped(
+            Factory.DEFAULT_FACTORY.create(new String[] {"table1", null, 
"id2"}), "s1");
+    assertEquals(Collections.singletonList(modEntry), result);
+  }
+
   private <T> void checkOverlapped(
       PatternTreeMap<T, ?> patternTreeMap, PartialPath partialPath, List<T> 
expectedList) {
     Set<T> resultSet = new 
HashSet<>(patternTreeMap.getOverlapped(partialPath));
     Assert.assertEquals(expectedList.size(), resultSet.size());
     for (T o : expectedList) {
-      Assert.assertTrue(resultSet.contains(o));
+      assertTrue(resultSet.contains(o));
     }
   }
 
@@ -234,7 +255,7 @@ public class PatternTreeMapTest {
       Set<T> actualSubSet = new HashSet<>(actualList.get(i));
       Assert.assertEquals(expectedSubList.size(), actualSubSet.size());
       for (T o : expectedSubList) {
-        Assert.assertTrue(actualSubSet.contains(o));
+        assertTrue(actualSubSet.contains(o));
       }
     }
   }
@@ -244,7 +265,7 @@ public class PatternTreeMapTest {
     Set<T> resultSet = new 
HashSet<>(patternTreeMap.getDeviceOverlapped(devicePath));
     Assert.assertEquals(expectedList.size(), resultSet.size());
     for (T o : expectedList) {
-      Assert.assertTrue(resultSet.contains(o));
+      assertTrue(resultSet.contains(o));
     }
   }
 }
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/path/PartialPath.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/path/PartialPath.java
index d03e4af88b4..f703096e025 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/path/PartialPath.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/path/PartialPath.java
@@ -72,7 +72,8 @@ public class PartialPath extends Path implements 
Comparable<Path>, Cloneable {
     System.arraycopy(tableNameSegments, 0, nodes, 0, tableNameSegments.length);
     // copy non-table-name segments
     for (int i = 0; i < device.segmentNum() - 1; i++) {
-      nodes[i + tableNameSegments.length] = device.segment(i + 1).toString();
+      nodes[i + tableNameSegments.length] =
+          device.segment(i + 1) != null ? device.segment(i + 1).toString() : 
null;
     }
     this.fullPath = getFullPath();
   }
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/path/PatternTreeMap.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/path/PatternTreeMap.java
index 9f8fd569040..99216d10f45 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/path/PatternTreeMap.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/path/PatternTreeMap.java
@@ -143,7 +143,7 @@ public class PatternTreeMap<V, VSerializer extends 
PathPatternNode.Serializer<V>
     // TODO change this way
     PartialPath devicePath;
     try {
-      devicePath = new PartialPath(deviceID.toString());
+      devicePath = new PartialPath(deviceID);
     } catch (IllegalPathException e) {
       throw new RuntimeException(e);
     }

Reply via email to