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;
       }

Reply via email to