This is an automated email from the ASF dual-hosted git repository.
jt2594838 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 9ca448ef4f4 Fix tree model load type mismatch conversion (#17949)
9ca448ef4f4 is described below
commit 9ca448ef4f40a7fa020137e2dbf81525271be9bc
Author: Caideyipi <[email protected]>
AuthorDate: Tue Jun 16 17:15:35 2026 +0800
Fix tree model load type mismatch conversion (#17949)
* Fix tree load type mismatch conversion
* Fix load-and-alter expected count
---
.../db/it/schema/IoTDBAlterTimeSeriesTypeIT.java | 4 +-
.../load/TreeSchemaAutoCreatorAndVerifier.java | 17 +++---
.../plan/analyze/load/LoadTsFileAnalyzerTest.java | 64 ++++++++++++++++++++++
3 files changed, 75 insertions(+), 10 deletions(-)
diff --git
a/integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBAlterTimeSeriesTypeIT.java
b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBAlterTimeSeriesTypeIT.java
index 80de584b798..969ab28fd7a 100644
---
a/integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBAlterTimeSeriesTypeIT.java
+++
b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBAlterTimeSeriesTypeIT.java
@@ -879,8 +879,8 @@ public class IoTDBAlterTimeSeriesTypeIT {
session.executeQueryStatement("select count(s1) from " + database +
".load_and_alter");
RowRecord rec;
rec = dataSet.next();
- // Before alter, DOUBLE TsFiles loaded directly are invisible under the
existing INT32 schema.
- assertEquals(9, rec.getFields().get(0).getLongV());
+ // Before alter, DOUBLE TsFiles are converted to INT32 and visible under
the existing schema.
+ assertEquals(15, rec.getFields().get(0).getLongV());
assertFalse(dataSet.hasNext());
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/load/TreeSchemaAutoCreatorAndVerifier.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/load/TreeSchemaAutoCreatorAndVerifier.java
index bfebb7db0d7..d4f4210727e 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/load/TreeSchemaAutoCreatorAndVerifier.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/load/TreeSchemaAutoCreatorAndVerifier.java
@@ -483,14 +483,15 @@ public class TreeSchemaAutoCreatorAndVerifier {
}
// check datatype
- if (LOGGER.isDebugEnabled() &&
!tsFileSchema.getType().equals(iotdbSchema.getType())) {
- LOGGER.debug(
- "Measurement {}{}{} datatype not match, TsFile: {}, IoTDB: {}",
- device,
- TsFileConstant.PATH_SEPARATOR,
- iotdbSchema.getMeasurementName(),
- tsFileSchema.getType(),
- iotdbSchema.getType());
+ if (!tsFileSchema.getType().equals(iotdbSchema.getType())) {
+ throw new LoadAnalyzeTypeMismatchException(
+ String.format(
+ "Data type mismatch for measurement %s%s%s, type in TsFile:
%s, type in IoTDB: %s",
+ device,
+ TsFileConstant.PATH_SEPARATOR,
+ iotdbSchema.getMeasurementName(),
+ tsFileSchema.getType(),
+ iotdbSchema.getType()));
}
// check encoding
diff --git
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/load/LoadTsFileAnalyzerTest.java
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/load/LoadTsFileAnalyzerTest.java
index 01406b0fd06..c533b0043e9 100644
---
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/load/LoadTsFileAnalyzerTest.java
+++
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/load/LoadTsFileAnalyzerTest.java
@@ -19,6 +19,7 @@
package org.apache.iotdb.db.queryengine.plan.analyze.load;
+import org.apache.iotdb.commons.path.PartialPath;
import
org.apache.iotdb.commons.queryengine.plan.relational.metadata.ColumnSchema;
import org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory;
import org.apache.iotdb.db.conf.IoTDBDescriptor;
@@ -26,7 +27,10 @@ import
org.apache.iotdb.db.exception.load.LoadAnalyzeTypeMismatchException;
import org.apache.iotdb.db.exception.load.LoadRuntimeOutOfMemoryException;
import org.apache.iotdb.db.queryengine.common.MPPQueryContext;
import org.apache.iotdb.db.queryengine.common.QueryId;
+import org.apache.iotdb.db.queryengine.common.schematree.ClusterSchemaTree;
+import org.apache.iotdb.db.queryengine.common.schematree.ISchemaTree;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.LoadTsFile;
+import org.apache.iotdb.db.queryengine.plan.statement.crud.LoadTsFileStatement;
import org.apache.iotdb.db.storageengine.dataregion.tsfile.TsFileResource;
import org.apache.tsfile.enums.ColumnCategory;
@@ -149,6 +153,51 @@ public class LoadTsFileAnalyzerTest {
}
}
+ @Test
+ public void testTreeSchemaVerifierShouldThrowMismatchWhenVerifyingDataType()
throws Exception {
+ final File tsFile = new File("load-tree-type-mismatch.tsfile");
+ if (tsFile.exists()) {
+ Assert.assertTrue(tsFile.delete());
+ }
+ Assert.assertTrue(tsFile.createNewFile());
+
+ try (final LoadTsFileAnalyzer analyzer =
+ new LoadTsFileAnalyzer(
+ LoadTsFileStatement.createUnchecked(tsFile.getAbsolutePath()),
+ false,
+ new MPPQueryContext(new QueryId("load_tree_test")))) {
+ final TreeSchemaAutoCreatorAndVerifier verifier =
+ new TreeSchemaAutoCreatorAndVerifier(analyzer);
+ try {
+ final IDeviceID device =
IDeviceID.Factory.DEFAULT_FACTORY.create("root.sg.d1");
+ final LoadTsFileTreeSchemaCache schemaCache =
getTreeSchemaCache(verifier);
+ schemaCache.addTimeSeries(device, new MeasurementSchema("s1",
TSDataType.BOOLEAN));
+ schemaCache.addIsAlignedCache(device, true, true);
+
+ final ClusterSchemaTree schemaTree = new ClusterSchemaTree();
+ schemaTree.appendSingleMeasurement(
+ new PartialPath("root.sg.d1.s1"),
+ new MeasurementSchema("s1", TSDataType.INT32),
+ null,
+ null,
+ null,
+ true);
+
+ final InvocationTargetException exception =
+ Assert.assertThrows(
+ InvocationTargetException.class,
+ () -> getVerifyTreeSchemaMethod().invoke(verifier,
schemaTree));
+ Assert.assertTrue(exception.getCause() instanceof
LoadAnalyzeTypeMismatchException);
+ } finally {
+ verifier.close();
+ }
+ } finally {
+ if (tsFile.exists()) {
+ Assert.assertTrue(tsFile.delete());
+ }
+ }
+ }
+
private void writeTableTsFileWithMixedDevices(final File tsFile) throws
Exception {
if (tsFile.exists()) {
Assert.assertTrue(tsFile.delete());
@@ -203,6 +252,14 @@ public class LoadTsFileAnalyzerTest {
tableSchemaCacheField.set(analyzer, schemaCache);
}
+ private LoadTsFileTreeSchemaCache getTreeSchemaCache(
+ final TreeSchemaAutoCreatorAndVerifier verifier) throws Exception {
+ final Field schemaCacheField =
+ TreeSchemaAutoCreatorAndVerifier.class.getDeclaredField("schemaCache");
+ schemaCacheField.setAccessible(true);
+ return (LoadTsFileTreeSchemaCache) schemaCacheField.get(verifier);
+ }
+
private LoadTsFileTableSchemaCache createTableSchemaCache(final boolean
shouldVerifyDataType)
throws LoadRuntimeOutOfMemoryException {
return new LoadTsFileTableSchemaCache(
@@ -219,6 +276,13 @@ public class LoadTsFileAnalyzerTest {
return method;
}
+ private Method getVerifyTreeSchemaMethod() throws NoSuchMethodException {
+ final Method method =
+
TreeSchemaAutoCreatorAndVerifier.class.getDeclaredMethod("verifySchema",
ISchemaTree.class);
+ method.setAccessible(true);
+ return method;
+ }
+
private
org.apache.iotdb.commons.queryengine.plan.relational.metadata.TableSchema
createTableSchema(final TSDataType fieldType) {
return new
org.apache.iotdb.commons.queryengine.plan.relational.metadata.TableSchema(