This is an automated email from the ASF dual-hosted git repository.
jt2594838 pushed a commit to branch dev/1.3
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/dev/1.3 by this push:
new 813de5422cc [Backport][dev/1.3] Improve error message when
auto-creating timeseries with null value (#18210)
813de5422cc is described below
commit 813de5422cc449c8abb12f975159f20a10072061
Author: Jiang Tian <[email protected]>
AuthorDate: Wed Jul 15 16:15:55 2026 +0800
[Backport][dev/1.3] Improve error message when auto-creating timeseries
with null value (#18210)
* Improve error message for null value auto creation
* fix test
* fix test
---
.../org/apache/iotdb/db/it/IoTDBInsertMultiRowIT.java | 17 +++++++++++++++++
.../iotdb/db/it/schema/IoTDBAutoCreateSchemaIT.java | 2 +-
.../db/exception/metadata/PathNotExistException.java | 12 ++++++++++++
.../plan/statement/crud/InsertBaseStatement.java | 13 +++++++++++--
.../plan/statement/crud/InsertRowStatement.java | 10 ++++++----
5 files changed, 47 insertions(+), 7 deletions(-)
diff --git
a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBInsertMultiRowIT.java
b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBInsertMultiRowIT.java
index 6e52368be4c..c2d9687a317 100644
---
a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBInsertMultiRowIT.java
+++
b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBInsertMultiRowIT.java
@@ -95,6 +95,23 @@ public class IoTDBInsertMultiRowIT {
statement.close();
}
+ @Test
+ public void testInsertAlignedSeriesAutoCreate() throws SQLException {
+ try (Statement statement = connection.createStatement()) {
+ try {
+ statement.execute(
+ "insert into root.aligned_auto_create.d1 (time, s1, s2) aligned
values (0, null, 15.2)");
+ fail();
+ } catch (SQLException e) {
+ assertTrue(
+ e.getMessage(),
+ e.getMessage()
+ .contains(
+ "Timeseries [root.aligned_auto_create.d1.s1] does not
exist and its data type cannot be inferred from the null value"));
+ }
+ }
+ }
+
@Test
public void testInsertMultiRow() throws SQLException {
Statement st0 = connection.createStatement();
diff --git
a/integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBAutoCreateSchemaIT.java
b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBAutoCreateSchemaIT.java
index 8d0380bba72..1e595b681a4 100644
---
a/integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBAutoCreateSchemaIT.java
+++
b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBAutoCreateSchemaIT.java
@@ -222,7 +222,7 @@ public class IoTDBAutoCreateSchemaIT extends
AbstractSchemaIT {
try {
statement.execute(sql);
} catch (SQLException e) {
- Assert.assertTrue(e.getMessage().contains("Path [root.sg0.d3.s1]
does not exist"));
+ Assert.assertTrue(e.getMessage().contains("Timeseries
[root.sg0.d3.s1] does not exist"));
}
}
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/exception/metadata/PathNotExistException.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/exception/metadata/PathNotExistException.java
index e04ccd0f1e9..75aa031e606 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/exception/metadata/PathNotExistException.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/exception/metadata/PathNotExistException.java
@@ -27,6 +27,8 @@ import java.util.List;
public class PathNotExistException extends MetadataException {
private static final String PATH_NOT_EXIST_WRONG_MESSAGE = "Path [%s] does
not exist";
+ private static final String
TIMESERIES_NOT_EXIST_AND_DATA_TYPE_CANNOT_BE_INFERRED_FROM_NULL =
+ "Timeseries [%s] does not exist and its data type cannot be inferred
from the null value";
private static final String SOURCE_PATH_NOT_EXIST_WRONG_MESSAGE =
"The source path [%s] of view [%s] does not exist.";
@@ -48,6 +50,16 @@ public class PathNotExistException extends MetadataException
{
TSStatusCode.PATH_NOT_EXIST.getStatusCode());
}
+ private PathNotExistException(String message, int errorCode) {
+ super(message, errorCode);
+ }
+
+ public static PathNotExistException forNullValue(String path) {
+ return new PathNotExistException(
+
String.format(TIMESERIES_NOT_EXIST_AND_DATA_TYPE_CANNOT_BE_INFERRED_FROM_NULL,
path),
+ TSStatusCode.PATH_NOT_EXIST.getStatusCode());
+ }
+
public PathNotExistException(String path, boolean isUserException) {
super(
String.format(PATH_NOT_EXIST_WRONG_MESSAGE, path),
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertBaseStatement.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertBaseStatement.java
index b6c4d6a4382..926143c5f62 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertBaseStatement.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertBaseStatement.java
@@ -170,7 +170,8 @@ public abstract class InsertBaseStatement extends Statement
implements Accountab
if (measurementSchemas[index] == null) {
markFailedMeasurement(
index,
- new
PathNotExistException(devicePath.concatNode(measurements[index]).getFullPath()));
+ createPathNotExistException(
+ devicePath.concatNode(measurements[index]).getFullPath(),
dataTypes[index]));
} else if ((dataTypes[index] != measurementSchemas[index].getType()
&& !checkAndCastDataType(index,
measurementSchemas[index].getType()))) {
markFailedMeasurement(
@@ -186,7 +187,8 @@ public abstract class InsertBaseStatement extends Statement
implements Accountab
} else {
// if not enable partial insert, throw the exception directly
if (measurementSchemas[index] == null) {
- throw new
PathNotExistException(devicePath.concatNode(measurements[index]).getFullPath());
+ throw createPathNotExistException(
+ devicePath.concatNode(measurements[index]).getFullPath(),
dataTypes[index]);
} else if ((dataTypes[index] != measurementSchemas[index].getType()
&& !checkAndCastDataType(index,
measurementSchemas[index].getType()))) {
throw new DataTypeMismatchException(
@@ -200,6 +202,13 @@ public abstract class InsertBaseStatement extends
Statement implements Accountab
}
}
+ protected PathNotExistException createPathNotExistException(
+ String fullPath, TSDataType dataType) {
+ return dataType == null
+ ? PathNotExistException.forNullValue(fullPath)
+ : new PathNotExistException(fullPath);
+ }
+
protected abstract boolean checkAndCastDataType(int columnIndex, TSDataType
dataType);
public abstract long getMinTime();
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertRowStatement.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertRowStatement.java
index faa46cadd9d..a10d539152b 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertRowStatement.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertRowStatement.java
@@ -207,14 +207,16 @@ public class InsertRowStatement extends
InsertBaseStatement implements ISchemaVa
if (measurementSchemas[i] == null) {
if
(!IoTDBDescriptor.getInstance().getConfig().isEnablePartialInsert()) {
throw new QueryProcessException(
- new PathNotExistException(
- devicePath.getFullPath() + IoTDBConstant.PATH_SEPARATOR +
measurements[i]));
+ createPathNotExistException(
+ devicePath.getFullPath() + IoTDBConstant.PATH_SEPARATOR +
measurements[i],
+ getDataType(i)));
} else {
markFailedMeasurement(
i,
new QueryProcessException(
- new PathNotExistException(
- devicePath.getFullPath() + IoTDBConstant.PATH_SEPARATOR
+ measurements[i])));
+ createPathNotExistException(
+ devicePath.getFullPath() + IoTDBConstant.PATH_SEPARATOR
+ measurements[i],
+ getDataType(i))));
}
continue;
}