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

Caideyipi pushed a commit to branch hotfix/2.0.9.4-sjzt
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 23d560096388799b7c893d8d0edbcc5dcdea5b4c
Author: 罗振羽 <[email protected]>
AuthorDate: Wed Apr 29 08:26:27 2026 +0000

    [TIMECHODB]Fix object file timestamp parsing
    
    (cherry picked from commit 92aa3a4bc7088cc0f31e230c18b7ccb8cc91d4b0)
---
 .../relational/it/session/IoTDBObjectDeleteIT.java | 147 +++++++++++++++++++++
 .../db/storageengine/dataregion/DataRegion.java    |   4 +-
 2 files changed, 150 insertions(+), 1 deletion(-)

diff --git 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/session/IoTDBObjectDeleteIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/session/IoTDBObjectDeleteIT.java
index 0c697424873..e2c7fe73359 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/session/IoTDBObjectDeleteIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/session/IoTDBObjectDeleteIT.java
@@ -262,6 +262,40 @@ public class IoTDBObjectDeleteIT {
     Assert.assertFalse(success);
   }
 
+  @Test
+  public void dropObjectTableWithMultipleRowsTest()
+      throws IoTDBConnectionException, StatementExecutionException, 
IOException {
+    byte[] objectBytes = readTestObjectBytes();
+
+    try (ITableSession session = 
EnvFactory.getEnv().getTableSessionConnection()) {
+      session.executeNonQueryStatement("USE \"db1\"");
+      insertTwoRowsWithObjects(session, objectBytes);
+      assertObjectRowsReadable(session, objectBytes);
+
+      session.executeNonQueryStatement("drop table object_table");
+    }
+
+    Assert.assertFalse(objectFileExists("object_table", "1", "5", "3", "file", 
"1.bin"));
+    Assert.assertFalse(objectFileExists("object_table", "1", "5", "3", "file", 
"2.bin"));
+  }
+
+  @Test
+  public void dropObjectDatabaseTest()
+      throws IoTDBConnectionException, StatementExecutionException, 
IOException {
+    byte[] objectBytes = readTestObjectBytes();
+
+    try (ITableSession session = 
EnvFactory.getEnv().getTableSessionConnection()) {
+      session.executeNonQueryStatement("USE \"db1\"");
+      insertTwoRowsWithObjects(session, objectBytes);
+      assertObjectRowsReadable(session, objectBytes);
+
+      session.executeNonQueryStatement("drop database db1");
+    }
+
+    Assert.assertFalse(objectFileExists("object_table", "1", "5", "3", "file", 
"1.bin"));
+    Assert.assertFalse(objectFileExists("object_table", "1", "5", "3", "file", 
"2.bin"));
+  }
+
   @Test
   public void deleteObjectSegmentsTest()
       throws IoTDBConnectionException, StatementExecutionException, 
IOException {
@@ -360,4 +394,117 @@ public class IoTDBObjectDeleteIT {
   protected String convertPathString(String path) {
     return 
BaseEncoding.base32().omitPadding().encode(path.getBytes(StandardCharsets.UTF_8));
   }
+
+  private byte[] readTestObjectBytes() throws IOException {
+    String testObject =
+        System.getProperty("user.dir")
+            + File.separator
+            + "target"
+            + File.separator
+            + "test-classes"
+            + File.separator
+            + "object-example.pt";
+    return Files.readAllBytes(Paths.get(testObject));
+  }
+
+  private void insertTwoRowsWithObjects(ITableSession session, byte[] 
objectBytes)
+      throws IoTDBConnectionException, StatementExecutionException {
+    List<String> columnNameList =
+        Arrays.asList("region_id", "plant_id", "device_id", "temperature", 
"file");
+    List<TSDataType> dataTypeList =
+        Arrays.asList(
+            TSDataType.STRING,
+            TSDataType.STRING,
+            TSDataType.STRING,
+            TSDataType.FLOAT,
+            TSDataType.OBJECT);
+    List<ColumnCategory> columnTypeList =
+        new ArrayList<>(
+            Arrays.asList(
+                ColumnCategory.TAG,
+                ColumnCategory.TAG,
+                ColumnCategory.TAG,
+                ColumnCategory.FIELD,
+                ColumnCategory.FIELD));
+    Tablet tablet = new Tablet("object_table", columnNameList, dataTypeList, 
columnTypeList, 2);
+
+    int rowIndex = tablet.getRowSize();
+    tablet.addTimestamp(rowIndex, 1);
+    tablet.addValue(rowIndex, 0, "1");
+    tablet.addValue(rowIndex, 1, "5");
+    tablet.addValue(rowIndex, 2, "3");
+    tablet.addValue(rowIndex, 3, 37.6F);
+    tablet.addValue(rowIndex, 4, true, 0, objectBytes);
+
+    rowIndex = tablet.getRowSize();
+    tablet.addTimestamp(rowIndex, 2);
+    tablet.addValue(rowIndex, 0, "1");
+    tablet.addValue(rowIndex, 1, "5");
+    tablet.addValue(rowIndex, 2, "3");
+    tablet.addValue(rowIndex, 3, 38.6F);
+    tablet.addValue(rowIndex, 4, true, 0, objectBytes);
+
+    session.insert(tablet);
+    tablet.reset();
+    session.executeNonQueryStatement("flush");
+  }
+
+  private void assertObjectRowsReadable(ITableSession session, byte[] 
objectBytes)
+      throws IoTDBConnectionException, StatementExecutionException {
+    try (SessionDataSet dataSet =
+        session.executeQueryStatement(
+            "select time, READ_OBJECT(file) as file_content from object_table 
order by time")) {
+      SessionDataSet.DataIterator iterator = dataSet.iterator();
+      Assert.assertTrue(iterator.next());
+      Assert.assertEquals(1L, iterator.getLong("time"));
+      Assert.assertArrayEquals(objectBytes, 
iterator.getBlob("file_content").getValues());
+      Assert.assertTrue(iterator.next());
+      Assert.assertEquals(2L, iterator.getLong("time"));
+      Assert.assertArrayEquals(objectBytes, 
iterator.getBlob("file_content").getValues());
+      Assert.assertFalse(iterator.next());
+    }
+  }
+
+  private boolean objectFileExists(
+      String tableName,
+      String regionId,
+      String plantId,
+      String deviceId,
+      String measurement,
+      String fileName) {
+    for (DataNodeWrapper dataNodeWrapper : 
EnvFactory.getEnv().getDataNodeWrapperList()) {
+      String objectDirStr = dataNodeWrapper.getDataNodeObjectDir();
+      File objectDir = new File(objectDirStr);
+      if (!objectDir.exists() || !objectDir.isDirectory()) {
+        continue;
+      }
+      File[] regionDirs = objectDir.listFiles();
+      if (regionDirs == null) {
+        continue;
+      }
+      for (File regionDir : regionDirs) {
+        if (!regionDir.isDirectory()) {
+          continue;
+        }
+        File objectFile =
+            new File(
+                regionDir,
+                convertPathString(tableName)
+                    + File.separator
+                    + convertPathString(regionId)
+                    + File.separator
+                    + convertPathString(plantId)
+                    + File.separator
+                    + convertPathString(deviceId)
+                    + File.separator
+                    + convertPathString(measurement)
+                    + File.separator
+                    + fileName);
+        if (objectFile.exists() && objectFile.isFile()) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java
index a4dcbcd9f3b..ca7fe6e663b 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java
@@ -3031,7 +3031,9 @@ public class DataRegion implements IDataRegionForQuery {
                                   TimePartitionUtils.getTimePartitionId(
                                       Long.parseLong(
                                           name.substring(
-                                              
-ObjectTypeUtils.OBJECT_FILE_SUFFIX.length())));
+                                              0,
+                                              name.length()
+                                                  - 
ObjectTypeUtils.OBJECT_FILE_SUFFIX.length())));
                               TableDiskUsageIndex.getInstance()
                                   .writeObjectDelta(
                                       databaseName,

Reply via email to