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 4afd2a0f016 Don't allow IntColumn DataType is DATE when query column 
data of Date type used by Python client (#17015)
4afd2a0f016 is described below

commit 4afd2a0f01635967a2d10b305e61b3fd08401412
Author: libo <[email protected]>
AuthorDate: Thu Jan 15 14:32:18 2026 +0800

    Don't allow IntColumn DataType is DATE when query column data of Date type 
used by Python client (#17015)
---
 .../src/test/cpp/sessionRelationalIT.cpp           |  12 +--
 iotdb-client/client-py/README.md                   |   2 +
 .../client-py/iotdb/tsfile/utils/tsblock_serde.py  |   4 +-
 iotdb-client/client-py/session_example_date.py     | 109 +++++++++++++++++++++
 .../persistence/schema/ConfigMTreeTest.java        |  58 +++++++++++
 .../test/resources/oldsnapshot/cluster_schema.bin  | Bin 0 -> 121 bytes
 .../resources/oldsnapshot/table_cluster_schema.bin | Bin 0 -> 5177 bytes
 .../execution/operator/source/FileLoaderUtils.java |   3 +-
 .../execution/operator/source/SeriesScanUtil.java  |  40 +-------
 .../schemaregion/utils/ResourceByPathUtils.java    |  15 ++-
 .../org/apache/iotdb/db/utils/SchemaUtils.java     |   5 +-
 pom.xml                                            |   2 +-
 12 files changed, 190 insertions(+), 60 deletions(-)

diff --git a/iotdb-client/client-cpp/src/test/cpp/sessionRelationalIT.cpp 
b/iotdb-client/client-cpp/src/test/cpp/sessionRelationalIT.cpp
index 8dff31ba7f4..94f956b56ea 100644
--- a/iotdb-client/client-cpp/src/test/cpp/sessionRelationalIT.cpp
+++ b/iotdb-client/client-cpp/src/test/cpp/sessionRelationalIT.cpp
@@ -159,8 +159,7 @@ TEST_CASE("Test RelationalTabletTsblockRead", 
"[testRelationalTabletTsblockRead]
         "field7 TIMESTAMP field,"
         "field8 DATE field,"
         "field9 BLOB field,"
-        "field10 STRING field,"
-        "field11 OBJECT field)");
+        "field10 STRING field)");
 
     vector<pair<string, TSDataType::TSDataType>> schemaList;
     schemaList.push_back(make_pair("field1", TSDataType::BOOLEAN));
@@ -173,9 +172,8 @@ TEST_CASE("Test RelationalTabletTsblockRead", 
"[testRelationalTabletTsblockRead]
     schemaList.push_back(make_pair("field8", TSDataType::DATE));
     schemaList.push_back(make_pair("field9", TSDataType::BLOB));
     schemaList.push_back(make_pair("field10", TSDataType::STRING));
-    schemaList.push_back(make_pair("field11", TSDataType::OBJECT));
 
-    vector<ColumnCategory> columnTypes(11, ColumnCategory::FIELD);
+    vector<ColumnCategory> columnTypes(10, ColumnCategory::FIELD);
 
     int64_t timestamp = 0;
     int maxRowNumber = 50000;
@@ -194,9 +192,6 @@ TEST_CASE("Test RelationalTabletTsblockRead", 
"[testRelationalTabletTsblockRead]
         tablet.addValue(7, rowIndex, boost::gregorian::date(2025, 5, 15));
         tablet.addValue(8, rowIndex, "blob_" + to_string(row));
         tablet.addValue(9, rowIndex, "string_" + to_string(row));
-        vector<uint8_t> rawData = {0x01, 0x02, 0x03, 0x04};
-        // always non-null
-        tablet.addValue(10, rowIndex, true, 0, rawData);
 
         if (row % 2 == 0) {
             for (int col = 0; col <= 9; col++) {
@@ -232,7 +227,6 @@ TEST_CASE("Test RelationalTabletTsblockRead", 
"[testRelationalTabletTsblockRead]
             REQUIRE_FALSE(dataIter.getDateByIndex(9).is_initialized());
             REQUIRE_FALSE(dataIter.getStringByIndex(10).is_initialized());
             REQUIRE_FALSE(dataIter.getStringByIndex(11).is_initialized());
-            REQUIRE_FALSE(!dataIter.getStringByIndex(12).is_initialized());
         } else {
             REQUIRE(dataIter.getLongByIndex(1).value() == timestamp + rowNum);
             REQUIRE(dataIter.getBooleanByIndex(2).value() == (rowNum % 2 == 
0));
@@ -245,8 +239,6 @@ TEST_CASE("Test RelationalTabletTsblockRead", 
"[testRelationalTabletTsblockRead]
             REQUIRE(dataIter.getDateByIndex(9).value() == 
boost::gregorian::date(2025, 5, 15));
             REQUIRE(dataIter.getStringByIndex(10).value() == "blob_" + 
to_string(rowNum));
             REQUIRE(dataIter.getStringByIndex(11).value() == "string_" + 
to_string(rowNum));
-            // [isEOF (1 byte)] + [offset (8 bytes)] + [content (4 bytes)]
-            REQUIRE(dataIter.getStringByIndex(12).value() != "");
         }
         rowNum++;
     }
diff --git a/iotdb-client/client-py/README.md b/iotdb-client/client-py/README.md
index 2cdf23b5e12..c7dc1b33cc9 100644
--- a/iotdb-client/client-py/README.md
+++ b/iotdb-client/client-py/README.md
@@ -606,3 +606,5 @@ Namely, these are
 * Release to pypi
 
 
+
+
diff --git a/iotdb-client/client-py/iotdb/tsfile/utils/tsblock_serde.py 
b/iotdb-client/client-py/iotdb/tsfile/utils/tsblock_serde.py
index 854be120ffb..937ca9ca326 100644
--- a/iotdb-client/client-py/iotdb/tsfile/utils/tsblock_serde.py
+++ b/iotdb-client/client-py/iotdb/tsfile/utils/tsblock_serde.py
@@ -74,7 +74,7 @@ def read_from_buffer(buffer, size):
 def read_column_types(buffer, value_column_count):
     data_types = np.frombuffer(buffer, dtype=np.uint8, 
count=value_column_count)
     new_buffer = buffer[value_column_count:]
-    if not np.all(np.isin(data_types, (0, 1, 2, 3, 4, 5))):
+    if not np.all(np.isin(data_types, (0, 1, 2, 3, 4, 5, 8, 9, 10, 11))):
         raise Exception("Invalid data type encountered: " + str(data_types))
     return data_types, new_buffer
 
@@ -140,7 +140,7 @@ def read_int32_column(buffer, data_type, position_count):
     else:
         size = np.count_nonzero(~null_indicators)
 
-    if data_type == 1:
+    if (data_type == 1) or (data_type == 9):
         dtype = ">i4"
     elif data_type == 3:
         dtype = ">f4"
diff --git a/iotdb-client/client-py/session_example_date.py 
b/iotdb-client/client-py/session_example_date.py
new file mode 100644
index 00000000000..7d8f65d7c49
--- /dev/null
+++ b/iotdb-client/client-py/session_example_date.py
@@ -0,0 +1,109 @@
+# 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.
+#
+
+# Uncomment the following line to use apache-iotdb module installed by pip3
+import numpy as np
+from datetime import date
+from iotdb.Session import Session
+from iotdb.utils.BitMap import BitMap
+from iotdb.utils.IoTDBConstants import TSDataType, TSEncoding, Compressor
+from iotdb.utils.Tablet import Tablet
+from iotdb.utils.NumpyTablet import NumpyTablet
+
+# creating session connection.
+ip = "127.0.0.1"
+port_ = "6667"
+username_ = "root"
+password_ = "root"
+# session = Session(ip, port_, username_, password_, fetch_size=1024, 
zone_id="Asia/Shanghai", enable_redirection=True)
+session = Session.init_from_node_urls(
+    node_urls=["127.0.0.1:6667", "127.0.0.1:6668", "127.0.0.1:6669"],
+    user="root",
+    password="root",
+    fetch_size=1024,
+    zone_id="Asia/Shanghai",
+    enable_redirection=True,
+)
+session.open(False)
+
+# create and delete databases
+session.set_storage_group("root.sg_test_01")
+
+# setting time series.
+session.create_time_series(
+    "root.sg_test_01.d_01.s_01", TSDataType.BOOLEAN, TSEncoding.PLAIN, 
Compressor.SNAPPY
+)
+
+# insert tablet with new data types
+measurements_new_type = ["s_01", "s_02", "s_03", "s_04"]
+data_types_new_type = [
+    TSDataType.DATE,
+    TSDataType.TIMESTAMP,
+    TSDataType.BLOB,
+    TSDataType.STRING,
+]
+values_new_type = [
+    [date(2024, 1, 1), 1, b"\x12\x34", "test01"],
+    [date(2024, 1, 2), 2, b"\x12\x34", "test02"],
+    [date(2024, 1, 3), 3, b"\x12\x34", "test03"],
+    [date(2024, 1, 4), 4, b"\x12\x34", "test04"],
+]
+timestamps_new_type = [1, 2, 3, 4]
+tablet_new_type = Tablet(
+    "root.sg_test_01.d_04",
+    measurements_new_type,
+    data_types_new_type,
+    values_new_type,
+    timestamps_new_type,
+)
+session.insert_tablet(tablet_new_type)
+np_values_new_type = [
+    np.array([date(2024, 2, 4), date(2024, 3, 4), date(2024, 4, 4), date(2024, 
5, 4)]),
+    np.array([5, 6, 7, 8], TSDataType.INT64.np_dtype()),
+    np.array([b"\x12\x34", b"\x12\x34", b"\x12\x34", b"\x12\x34"]),
+    np.array(["test01", "test02", "test03", "test04"]),
+]
+np_timestamps_new_type = np.array([5, 6, 7, 8], TSDataType.INT64.np_dtype())
+np_tablet_new_type = NumpyTablet(
+    "root.sg_test_01.d_04",
+    measurements_new_type,
+    data_types_new_type,
+    np_values_new_type,
+    np_timestamps_new_type,
+)
+session.insert_tablet(np_tablet_new_type)
+with session.execute_query_statement(
+    "select s_01 from root.sg_test_01.d_04 limit 1"
+) as dataset:
+    print(dataset.get_column_names())
+    while dataset.has_next():
+        print(dataset.next())
+
+with session.execute_query_statement(
+    "select s_01 from root.sg_test_01.d_04 limit 1"
+) as dataset:
+    df = dataset.todf()
+    print(df.to_string())
+
+# delete database
+session.delete_storage_group("root.sg_test_01")
+
+# close session connection.
+session.close()
+
+print("All executions done!!")
diff --git 
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTreeTest.java
 
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTreeTest.java
index 7e5f2d5c239..bf7d0c91ba6 100644
--- 
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTreeTest.java
+++ 
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTreeTest.java
@@ -23,6 +23,7 @@ import 
org.apache.iotdb.commons.exception.IllegalPathException;
 import org.apache.iotdb.commons.exception.MetadataException;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.commons.schema.node.role.IDatabaseMNode;
+import org.apache.iotdb.commons.schema.table.TableNodeStatus;
 import org.apache.iotdb.commons.schema.table.TsTable;
 import org.apache.iotdb.commons.schema.table.column.AttributeColumnSchema;
 import org.apache.iotdb.commons.schema.table.column.FieldColumnSchema;
@@ -42,8 +43,14 @@ import org.junit.Test;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import static org.apache.iotdb.commons.schema.SchemaConstant.ALL_MATCH_SCOPE;
@@ -55,6 +62,8 @@ import static org.junit.Assert.fail;
 public class ConfigMTreeTest {
 
   private ConfigMTree root;
+  private static final String SCHEMA_FILE = "oldsnapshot/cluster_schema.bin";
+  private static final String TABLE_SCHEMA_FILE = 
"oldsnapshot/table_cluster_schema.bin";
 
   @Before
   public void setUp() throws Exception {
@@ -433,4 +442,53 @@ public class ConfigMTreeTest {
       fail();
     }
   }
+
+  @Test
+  public void deserializeSchemaFromSnapshot() {
+    String pathStr = 
this.getClass().getClassLoader().getResource(SCHEMA_FILE).getFile();
+    File schemaFile = new File(pathStr);
+    try (InputStream inputStream = 
Files.newInputStream(schemaFile.getAbsoluteFile().toPath())) {
+      ConfigMTree treeMTree = new ConfigMTree(false);
+      treeMTree.deserialize(inputStream);
+
+      Set<String> databaseSet = new HashSet<>();
+      for (PartialPath path : treeMTree.getAllDatabasePaths(false)) {
+        databaseSet.add(path.getFullPath());
+      }
+      Assert.assertTrue(databaseSet.contains("root.__audit"));
+    } catch (IOException | MetadataException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  @Test
+  public void deserializeTableSchemaFromSnapshot() {
+    String pathStr = 
this.getClass().getClassLoader().getResource(TABLE_SCHEMA_FILE).getFile();
+    File schemaFile = new File(pathStr);
+    try (InputStream inputStream = 
Files.newInputStream(schemaFile.getAbsoluteFile().toPath())) {
+      ConfigMTree tableMTree = new ConfigMTree(true);
+      tableMTree.deserialize(inputStream);
+
+      Set<String> databaseSet = new HashSet<>();
+      for (PartialPath path : tableMTree.getAllDatabasePaths(true)) {
+        databaseSet.add(path.getTailNode());
+      }
+      Assert.assertTrue(databaseSet.contains("test_g_0"));
+
+      Set<String> tableSet = new HashSet<>();
+      for (Map.Entry<String, List<Pair<TsTable, TableNodeStatus>>> entry :
+          tableMTree.getAllTables().entrySet()) {
+        List<Pair<TsTable, TableNodeStatus>> tablePairs = entry.getValue();
+        for (Pair<TsTable, TableNodeStatus> pair : tablePairs) {
+          TsTable tsTable = pair.getLeft();
+          if (tsTable != null) {
+            tableSet.add(tsTable.getTableName());
+          }
+        }
+      }
+      Assert.assertTrue(tableSet.contains("table_0"));
+    } catch (IOException | MetadataException e) {
+      throw new RuntimeException(e);
+    }
+  }
 }
diff --git 
a/iotdb-core/confignode/src/test/resources/oldsnapshot/cluster_schema.bin 
b/iotdb-core/confignode/src/test/resources/oldsnapshot/cluster_schema.bin
new file mode 100644
index 00000000000..0fe7d421e11
Binary files /dev/null and 
b/iotdb-core/confignode/src/test/resources/oldsnapshot/cluster_schema.bin differ
diff --git 
a/iotdb-core/confignode/src/test/resources/oldsnapshot/table_cluster_schema.bin 
b/iotdb-core/confignode/src/test/resources/oldsnapshot/table_cluster_schema.bin
new file mode 100644
index 00000000000..3e954259721
Binary files /dev/null and 
b/iotdb-core/confignode/src/test/resources/oldsnapshot/table_cluster_schema.bin 
differ
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/FileLoaderUtils.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/FileLoaderUtils.java
index d34abd60946..70f3ce5e0e6 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/FileLoaderUtils.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/FileLoaderUtils.java
@@ -118,7 +118,8 @@ public class FileLoaderUtils {
           List<ModEntry> pathModifications =
               context.getPathModifications(
                   resource, seriesPath.getDeviceId(), 
seriesPath.getMeasurement());
-          timeSeriesMetadata.setModified(!pathModifications.isEmpty());
+          timeSeriesMetadata.setModified(
+              timeSeriesMetadata.isModified() || !pathModifications.isEmpty());
           timeSeriesMetadata.setChunkMetadataLoader(
               new DiskChunkMetadataLoader(resource, context, globalTimeFilter, 
pathModifications));
           int modificationCount = pathModifications.size();
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/SeriesScanUtil.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/SeriesScanUtil.java
index 925c2f8f70f..a44a43d0f17 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/SeriesScanUtil.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/SeriesScanUtil.java
@@ -46,14 +46,12 @@ import org.apache.tsfile.block.column.Column;
 import org.apache.tsfile.common.conf.TSFileDescriptor;
 import org.apache.tsfile.enums.TSDataType;
 import org.apache.tsfile.file.metadata.AbstractAlignedChunkMetadata;
-import org.apache.tsfile.file.metadata.AbstractAlignedTimeSeriesMetadata;
 import org.apache.tsfile.file.metadata.ChunkMetadata;
 import org.apache.tsfile.file.metadata.IChunkMetadata;
 import org.apache.tsfile.file.metadata.IDeviceID;
 import org.apache.tsfile.file.metadata.IMetadata;
 import org.apache.tsfile.file.metadata.ITimeSeriesMetadata;
 import org.apache.tsfile.file.metadata.StringArrayDeviceID;
-import org.apache.tsfile.file.metadata.TimeseriesMetadata;
 import org.apache.tsfile.file.metadata.statistics.Statistics;
 import org.apache.tsfile.read.TimeValuePair;
 import org.apache.tsfile.read.common.TimeRange;
@@ -1234,10 +1232,7 @@ public class SeriesScanUtil implements Accountable {
           } else {
             newValueColumns[i] =
                 new IntColumn(
-                    positionCount,
-                    Optional.of(new boolean[positionCount]),
-                    new int[positionCount],
-                    TSDataType.DATE);
+                    positionCount, Optional.of(new boolean[positionCount]), 
new int[positionCount]);
             for (int j = 0; j < valueColumns[i].getPositionCount(); j++) {
               newValueColumns[i].isNull()[j] = true;
             }
@@ -1910,7 +1905,7 @@ public class SeriesScanUtil implements Accountable {
     ITimeSeriesMetadata timeseriesMetadata =
         loadTimeSeriesMetadata(orderUtils.getNextSeqFileResource(true), true);
     // skip if data type is mismatched which may be caused by delete
-    if (timeseriesMetadata != null && typeCompatible(timeseriesMetadata)) {
+    if (timeseriesMetadata != null && 
timeseriesMetadata.typeMatch(getTsDataTypeList())) {
       timeseriesMetadata.setSeq(true);
       seqTimeSeriesMetadata.add(timeseriesMetadata);
       return Optional.of(timeseriesMetadata);
@@ -1919,40 +1914,11 @@ public class SeriesScanUtil implements Accountable {
     }
   }
 
-  private boolean typeCompatible(ITimeSeriesMetadata timeseriesMetadata) {
-    if (timeseriesMetadata instanceof TimeseriesMetadata) {
-      return getTsDataTypeList()
-          .get(0)
-          .isCompatible(((TimeseriesMetadata) 
timeseriesMetadata).getTsDataType());
-    } else {
-      List<TimeseriesMetadata> valueTimeseriesMetadataList =
-          ((AbstractAlignedTimeSeriesMetadata) 
timeseriesMetadata).getValueTimeseriesMetadataList();
-      if (getTsDataTypeList().isEmpty()) {
-        return true;
-      }
-      if (valueTimeseriesMetadataList != null) {
-        int incompactibleCount = 0;
-        for (int i = 0, size = getTsDataTypeList().size(); i < size; i++) {
-          TimeseriesMetadata valueTimeSeriesMetadata = 
valueTimeseriesMetadataList.get(i);
-          if (valueTimeSeriesMetadata != null
-              && !getTsDataTypeList()
-                  .get(i)
-                  .isCompatible(valueTimeSeriesMetadata.getTsDataType())) {
-            valueTimeseriesMetadataList.set(i, null);
-            incompactibleCount++;
-          }
-        }
-        return incompactibleCount != getTsDataTypeList().size();
-      }
-      return true;
-    }
-  }
-
   private Optional<ITimeSeriesMetadata> unpackUnseqTsFileResource() throws 
IOException {
     ITimeSeriesMetadata timeseriesMetadata =
         loadTimeSeriesMetadata(orderUtils.getNextUnseqFileResource(true), 
false);
     // skip if data type is mismatched which may be caused by delete
-    if (timeseriesMetadata != null && typeCompatible(timeseriesMetadata)) {
+    if (timeseriesMetadata != null && 
timeseriesMetadata.typeMatch(getTsDataTypeList())) {
       timeseriesMetadata.setSeq(false);
       unSeqTimeSeriesMetadata.add(timeseriesMetadata);
       return Optional.of(timeseriesMetadata);
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/utils/ResourceByPathUtils.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/utils/ResourceByPathUtils.java
index 2bfbdec4e3b..d7cb2100fa5 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/utils/ResourceByPathUtils.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/utils/ResourceByPathUtils.java
@@ -267,10 +267,9 @@ class AlignedResourceByPathUtils extends 
ResourceByPathUtils {
       isTable = isTable || (alignedChunkMetadata instanceof 
TableDeviceChunkMetadata);
       modified = (modified || alignedChunkMetadata.isModified());
       TSDataType targetDataType = 
alignedFullPath.getSchemaList().get(index).getType();
-      if (targetDataType.equals(TSDataType.STRING)
-          && ((alignedChunkMetadata.getValueChunkMetadataList().get(index) != 
null)
-              && 
(alignedChunkMetadata.getValueChunkMetadataList().get(index).getDataType()
-                  != targetDataType))) {
+      if ((alignedChunkMetadata.getValueChunkMetadataList().get(index) != null)
+          && 
(alignedChunkMetadata.getValueChunkMetadataList().get(index).getDataType()
+              != targetDataType)) {
         // create new statistics object via new data type, and merge 
statistics information
         SchemaUtils.rewriteAlignedChunkMetadataStatistics(
             alignedChunkMetadata, index, targetDataType);
@@ -540,14 +539,14 @@ class MeasurementResourceByPathUtils extends 
ResourceByPathUtils {
         Statistics.getStatsByType(timeSeriesMetadata.getTsDataType());
     // flush chunkMetadataList one by one
     boolean isModified = false;
-    for (IChunkMetadata chunkMetadata : chunkMetadataList) {
+    for (int index = 0; index < chunkMetadataList.size(); index++) {
+      IChunkMetadata chunkMetadata = chunkMetadataList.get(index);
       isModified = (isModified || chunkMetadata.isModified());
       TSDataType targetDataType = fullPath.getMeasurementSchema().getType();
-      if (targetDataType.equals(TSDataType.STRING)
-          && (chunkMetadata.getDataType() != targetDataType)) {
+      if (chunkMetadata != null && (chunkMetadata.getDataType() != 
targetDataType)) {
         // create new statistics object via new data type, and merge 
statistics information
         SchemaUtils.rewriteNonAlignedChunkMetadataStatistics(
-            (ChunkMetadata) chunkMetadata, targetDataType);
+            chunkMetadataList, index, targetDataType);
         chunkMetadata.setModified(true);
       }
       if (!useFakeStatistics) {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/SchemaUtils.java 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/SchemaUtils.java
index 320f00483f5..7fdd16e48e6 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/SchemaUtils.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/SchemaUtils.java
@@ -415,13 +415,16 @@ public class SchemaUtils {
   }
 
   public static void rewriteNonAlignedChunkMetadataStatistics(
-      ChunkMetadata chunkMetadata, TSDataType targetDataType) {
+      List<IChunkMetadata> chunkMetadataList, int index, TSDataType 
targetDataType) {
+    ChunkMetadata chunkMetadata = (ChunkMetadata) chunkMetadataList.get(index);
     if (chunkMetadata != null && 
targetDataType.isCompatible(chunkMetadata.getDataType())) {
       Statistics<?> statistics = Statistics.getStatsByType(targetDataType);
       statistics = getNewStatistics(chunkMetadata, targetDataType, statistics);
 
       chunkMetadata.setTsDataType(targetDataType);
       chunkMetadata.setStatistics(statistics);
+    } else {
+      chunkMetadataList.set(index, null);
     }
   }
 
diff --git a/pom.xml b/pom.xml
index d6261e70af1..6696f783d80 100644
--- a/pom.xml
+++ b/pom.xml
@@ -173,7 +173,7 @@
         <thrift.version>0.14.1</thrift.version>
         <xz.version>1.9</xz.version>
         <zstd-jni.version>1.5.6-3</zstd-jni.version>
-        <tsfile.version>2.2.1-260103-SNAPSHOT</tsfile.version>
+        <tsfile.version>2.2.1-260115-SNAPSHOT</tsfile.version>
     </properties>
     <!--
     if we claim dependencies in dependencyManagement, then we do not claim

Reply via email to