This is an automated email from the ASF dual-hosted git repository.
jiangtian 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 c76c5fe3d5a Fixed the bug related to "Fixed the bugs related to device
auto-create alignment ignorance" (#16781)
c76c5fe3d5a is described below
commit c76c5fe3d5a43d5a4a3f5e82b1f42b2699d240fe
Author: Caideyipi <[email protected]>
AuthorDate: Fri Nov 21 14:45:14 2025 +0800
Fixed the bug related to "Fixed the bugs related to device auto-create
alignment ignorance" (#16781)
* gsa
* ff
* ff
---
.../org/apache/iotdb/db/it/IoTDBLoadTsFileIT.java | 102 +++++++++++++++++++++
.../metadata/AlignedTimeSeriesException.java | 35 -------
.../load/TreeSchemaAutoCreatorAndVerifier.java | 4 +
.../analyze/schema/AutoCreateSchemaExecutor.java | 9 +-
4 files changed, 113 insertions(+), 37 deletions(-)
diff --git
a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBLoadTsFileIT.java
b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBLoadTsFileIT.java
index c54adb34711..928c7875b19 100644
---
a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBLoadTsFileIT.java
+++
b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBLoadTsFileIT.java
@@ -263,6 +263,108 @@ public class IoTDBLoadTsFileIT {
}
}
+ @Test
+ // Shall succeed with tablet conversion
+ public void testLoadWithAlignmentMismatch() throws Exception {
+ registerSchema();
+
+ final long writtenPoint1;
+ // device 0, sg 0
+ try (final TsFileGenerator generator =
+ new TsFileGenerator(new File(tmpDir, "1-0-0-0.tsfile"))) {
+ // Wrong, with 04-07 non-exist
+ generator.registerAlignedTimeseries(
+ SchemaConfig.DEVICE_0,
+ Arrays.asList(
+ SchemaConfig.MEASUREMENT_00,
+ SchemaConfig.MEASUREMENT_01,
+ SchemaConfig.MEASUREMENT_02,
+ SchemaConfig.MEASUREMENT_03,
+ SchemaConfig.MEASUREMENT_04,
+ SchemaConfig.MEASUREMENT_05,
+ SchemaConfig.MEASUREMENT_06,
+ SchemaConfig.MEASUREMENT_07));
+ generator.generateData(SchemaConfig.DEVICE_0, 100000, PARTITION_INTERVAL
/ 10_000, false);
+ writtenPoint1 = generator.getTotalNumber();
+ }
+
+ final long writtenPoint2;
+ // device 2, device 3, device4, sg 1
+ try (final TsFileGenerator generator =
+ new TsFileGenerator(new File(tmpDir, "2-0-0-0.tsfile"))) {
+ // right
+ generator.registerTimeseries(
+ SchemaConfig.DEVICE_2,
Collections.singletonList(SchemaConfig.MEASUREMENT_20));
+ // right
+ generator.registerTimeseries(
+ SchemaConfig.DEVICE_3,
Collections.singletonList(SchemaConfig.MEASUREMENT_30));
+ // Wrong, with 06 non-exist
+ generator.registerTimeseries(
+ SchemaConfig.DEVICE_4,
+ Arrays.asList(SchemaConfig.MEASUREMENT_40,
SchemaConfig.MEASUREMENT_06));
+ generator.generateData(SchemaConfig.DEVICE_2, 10000, PARTITION_INTERVAL
/ 10_000, false);
+ generator.generateData(SchemaConfig.DEVICE_3, 10000, PARTITION_INTERVAL
/ 10_000, false);
+ generator.generateData(SchemaConfig.DEVICE_4, 10000, PARTITION_INTERVAL
/ 10_000, true);
+ for (int i = 0; i < 1000; i++) {
+ generator.generateData(SchemaConfig.DEVICE_4, 1, PARTITION_INTERVAL -
10, true);
+ }
+ writtenPoint2 = generator.getTotalNumber();
+ }
+
+ try (final Connection connection = EnvFactory.getEnv().getConnection();
+ final Statement statement = connection.createStatement()) {
+
+ try {
+ statement.execute(
+ String.format(
+ "load \"%s\" with ('database-level'='2',
'convert-on-type-mismatch'='false')",
+ tmpDir.getAbsolutePath() + File.separator + "1-0-0-0.tsfile"));
+ Assert.fail();
+ } catch (final Exception e) {
+ Assert.assertTrue(
+ e.getMessage()
+ .contains(
+ "TimeSeries under this device is not aligned, please use
createTimeSeries or change device. (Path: root.sg.test_0.d_0)."));
+ }
+
+ try {
+ statement.execute(
+ String.format(
+ "load \"%s\" with ('database-level'='2',
'convert-on-type-mismatch'='false')",
+ tmpDir.getAbsolutePath() + File.separator + "2-0-0-0.tsfile"));
+ Assert.fail();
+ } catch (final Exception e) {
+ Assert.assertTrue(
+ e.getMessage()
+ .contains(
+ "TimeSeries under this device is aligned, please use
createAlignedTimeSeries or change device. (Path: root.sg.test_1.a_4)."));
+ }
+
+ statement.execute(String.format("load \"%s\" sglevel=2",
tmpDir.getAbsolutePath()));
+
+ try (final ResultSet resultSet =
+ statement.executeQuery("select count(*) from root.sg.** group by
level=1,2")) {
+ if (resultSet.next()) {
+ long sg1Count = resultSet.getLong("count(root.sg.test_0.*.*)");
+ Assert.assertEquals(writtenPoint1, sg1Count);
+ long sg2Count = resultSet.getLong("count(root.sg.test_1.*.*)");
+ Assert.assertEquals(writtenPoint2, sg2Count);
+ } else {
+ Assert.fail("This ResultSet is empty.");
+ }
+ }
+ }
+
+ // Try to delete after loading. Expect no deadlock
+ try (final Connection connection = EnvFactory.getEnv().getConnection();
+ final Statement statement = connection.createStatement()) {
+ statement.execute(
+ String.format(
+ "delete timeseries %s.%s",
+ SchemaConfig.DEVICE_0,
SchemaConfig.MEASUREMENT_00.getMeasurementName()));
+ }
+ }
+
@Test
public void testLoadAcrossMultipleTimePartitions() throws Exception {
registerSchema();
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/exception/metadata/AlignedTimeSeriesException.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/exception/metadata/AlignedTimeSeriesException.java
deleted file mode 100644
index f159376dfae..00000000000
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/exception/metadata/AlignedTimeSeriesException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.
- */
-
-package org.apache.iotdb.db.exception.metadata;
-
-import org.apache.iotdb.commons.exception.MetadataException;
-import org.apache.iotdb.rpc.TSStatusCode;
-
-public class AlignedTimeSeriesException extends MetadataException {
-
- public AlignedTimeSeriesException(final boolean aligned, final String path) {
- super(
- String.format(
- "TimeSeries under this device is%s aligned, please use
createTimeSeries or change device. (Path: %s)",
- aligned ? "" : " not", path),
- TSStatusCode.ALIGNED_TIMESERIES_ERROR.getStatusCode(),
- true);
- }
-}
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 f0412c36bb8..c174bd7942b 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
@@ -235,6 +235,10 @@ public class TreeSchemaAutoCreatorAndVerifier {
handleException(e, loadTsFileAnalyzer.getStatementString());
}
} catch (Exception e) {
+ if (e.getCause() instanceof LoadAnalyzeTypeMismatchException
+ && loadTsFileAnalyzer.isConvertOnTypeMismatch()) {
+ throw (LoadAnalyzeTypeMismatchException) e.getCause();
+ }
handleException(e, loadTsFileAnalyzer.getStatementString());
}
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/schema/AutoCreateSchemaExecutor.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/schema/AutoCreateSchemaExecutor.java
index a6a3301aea0..61d58310d7a 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/schema/AutoCreateSchemaExecutor.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/schema/AutoCreateSchemaExecutor.java
@@ -29,7 +29,7 @@ import
org.apache.iotdb.commons.service.metric.PerformanceOverviewMetrics;
import org.apache.iotdb.db.auth.AuthorityChecker;
import org.apache.iotdb.db.conf.IoTDBConfig;
import org.apache.iotdb.db.conf.IoTDBDescriptor;
-import org.apache.iotdb.db.exception.metadata.AlignedTimeSeriesException;
+import org.apache.iotdb.db.exception.load.LoadAnalyzeTypeMismatchException;
import org.apache.iotdb.db.exception.sql.SemanticException;
import org.apache.iotdb.db.protocol.session.SessionManager;
import org.apache.iotdb.db.queryengine.common.MPPQueryContext;
@@ -534,7 +534,12 @@ class AutoCreateSchemaExecutor {
} else {
// Load does not tolerate the device alignment mismatch
throw new SemanticException(
- new AlignedTimeSeriesException(!pair.getLeft(),
devicePath.getFullPath()));
+ new LoadAnalyzeTypeMismatchException(
+ String.format(
+ "TimeSeries under this device is%s aligned, please use
create%sTimeSeries or change device. (Path: %s)",
+ !pair.getLeft() ? "" : " not",
+ !pair.getLeft() ? "Aligned" : "",
+ devicePath.getFullPath())));
}
} else {
failedCreationSet.add(subStatus);