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 d8506920bf8 Improve error message when auto-creating timeseries with 
null value (#18209)
d8506920bf8 is described below

commit d8506920bf88fc40a353d776af2c608a0237b979
Author: Jiang Tian <[email protected]>
AuthorDate: Wed Jul 15 14:16:19 2026 +0800

    Improve error message when auto-creating timeseries with null value (#18209)
    
    * Improve error message for null value auto creation
    
    * fix test
---
 .../java/org/apache/iotdb/db/it/IoTDBInsertMultiRowIT.java  | 11 +++++++++++
 .../apache/iotdb/db/it/schema/IoTDBAutoCreateSchemaIT.java  |  2 +-
 .../en/org/apache/iotdb/db/i18n/DataNodeSchemaMessages.java |  3 +++
 .../zh/org/apache/iotdb/db/i18n/DataNodeSchemaMessages.java |  3 +++
 .../iotdb/db/exception/metadata/PathNotExistException.java  | 13 +++++++++++++
 .../plan/statement/crud/InsertBaseStatement.java            | 11 +++++++++--
 .../queryengine/plan/statement/crud/InsertRowStatement.java | 10 ++++++----
 7 files changed, 46 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 18c00b125dd..501c9e626e4 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
@@ -39,6 +39,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
 
+import static org.apache.iotdb.db.it.utils.TestUtils.assertNonQueryTestFail;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -95,6 +96,16 @@ public class IoTDBInsertMultiRowIT {
     statement.close();
   }
 
+  @Test
+  public void testInsertAlignedSeriesAutoCreate() throws SQLException {
+    try (Statement statement = connection.createStatement()) {
+      assertNonQueryTestFail(
+          statement,
+          "insert into root.aligned_auto_create.d1 (time, s1, s2) aligned 
values (0, null, 15.2)",
+          "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 620411b8c78..fe0447e2ab9 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/i18n/en/org/apache/iotdb/db/i18n/DataNodeSchemaMessages.java
 
b/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeSchemaMessages.java
index 746d91496d9..855d42bd5a7 100644
--- 
a/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeSchemaMessages.java
+++ 
b/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeSchemaMessages.java
@@ -659,6 +659,9 @@ public final class DataNodeSchemaMessages {
   public static final String ILLEGAL_PARAMETER_FAILED_CREATE_TIMESERIES_FMT =
       "%s. Failed to create timeseries for path %s";
   public static final String PATH_NOT_EXIST_WRONG_MESSAGE = "Path [%s] does 
not exist";
+  public static final String
+      
EXCEPTION_TIMESERIES_ARG_DOES_NOT_EXIST_AND_ITS_DATA_TYPE_CANNOT_BE_INFERRED_FROM_THE_NULL_VALUE_36406D43
 =
+          "Timeseries [%s] does not exist and its data type cannot be inferred 
from the null value";
   public static final String SOURCE_PATH_NOT_EXIST_WRONG_MESSAGE =
       "The source path [%s] of view [%s] does not exist.";
   public static final String NORMAL_TIMESERIES_NOT_EXIST_WRONG_MESSAGE =
diff --git 
a/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeSchemaMessages.java
 
b/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeSchemaMessages.java
index 2f3cdf8a930..ba99a6e8cd3 100644
--- 
a/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeSchemaMessages.java
+++ 
b/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeSchemaMessages.java
@@ -646,6 +646,9 @@ public final class DataNodeSchemaMessages {
   public static final String ILLEGAL_PARAMETER_FAILED_CREATE_TIMESERIES_FMT =
       "%s。为路径 %s 创建时间序列失败";
   public static final String PATH_NOT_EXIST_WRONG_MESSAGE = "路径 [%s] 不存在";
+  public static final String
+      
EXCEPTION_TIMESERIES_ARG_DOES_NOT_EXIST_AND_ITS_DATA_TYPE_CANNOT_BE_INFERRED_FROM_THE_NULL_VALUE_36406D43
 =
+          "时间序列 [%s] 不存在,且无法从 null 值推断其数据类型";
   public static final String SOURCE_PATH_NOT_EXIST_WRONG_MESSAGE =
       "源路径 [%s] 对应视图 [%s] 不存在。";
   public static final String NORMAL_TIMESERIES_NOT_EXIST_WRONG_MESSAGE =
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 b7692c191e4..8de2b577216 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
@@ -29,6 +29,9 @@ public class PathNotExistException extends MetadataException {
 
   private static final String PATH_NOT_EXIST_WRONG_MESSAGE =
       DataNodeSchemaMessages.PATH_NOT_EXIST_WRONG_MESSAGE;
+  private static final String 
TIMESERIES_NOT_EXIST_AND_DATA_TYPE_CANNOT_BE_INFERRED_FROM_NULL =
+      DataNodeSchemaMessages
+          
.EXCEPTION_TIMESERIES_ARG_DOES_NOT_EXIST_AND_ITS_DATA_TYPE_CANNOT_BE_INFERRED_FROM_THE_NULL_VALUE_36406D43;
   private static final String SOURCE_PATH_NOT_EXIST_WRONG_MESSAGE =
       DataNodeSchemaMessages.SOURCE_PATH_NOT_EXIST_WRONG_MESSAGE;
 
@@ -50,6 +53,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 cc3f7b65f33..06ba84b28b0 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
@@ -230,7 +230,7 @@ public abstract class InsertBaseStatement extends Statement 
implements Accountab
     if (IoTDBDescriptor.getInstance().getConfig().isEnablePartialInsert()) {
       // if enable partial insert, mark failed measurements with exception
       if (measurementSchema == null) {
-        markFailedMeasurement(index, new PathNotExistException(fullPath));
+        markFailedMeasurement(index, createPathNotExistException(fullPath, 
dataType));
       } else if ((dataType != measurementSchema.getType()
           && !checkAndCastDataType(index, measurementSchema.getType()))) {
         markFailedMeasurement(
@@ -246,7 +246,7 @@ public abstract class InsertBaseStatement extends Statement 
implements Accountab
     } else {
       // if not enable partial insert, throw the exception directly
       if (measurementSchema == null) {
-        throw new PathNotExistException(fullPath);
+        throw createPathNotExistException(fullPath, dataType);
       } else if ((dataType != measurementSchema.getType()
           && !checkAndCastDataType(index, measurementSchema.getType()))) {
         throw new DataTypeMismatchException(
@@ -260,6 +260,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 158c4034aaa..ecf25ac991f 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
@@ -259,14 +259,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;
       }

Reply via email to