This is an automated email from the ASF dual-hosted git repository.

jackietien pushed a commit to branch force_ci/object_type
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit ccf4346314ed05bfdccf5c264947e7e475b28c0e
Author: Caideyipi <[email protected]>
AuthorDate: Mon Nov 24 10:46:24 2025 +0800

    Optimized the error message when the column is not tag/attribute in device 
related SQLs (#16750)
    
    * logic
    
    * may-fi
    
    * fix
    
    * fix
    
    * Update IoTDBDeviceIT.java
    
    * fixfix
    
    * fix
    
    * fix
    
    * h
    
    * coding
    
    (cherry picked from commit 36154e5030096afe31e985b17f53984b69d8ff27)
---
 .../iotdb/relational/it/schema/IoTDBDeviceIT.java  | 44 +++++++++++++------
 .../relational/analyzer/StatementAnalyzer.java     | 51 +++++++++++++++++++---
 2 files changed, 77 insertions(+), 18 deletions(-)

diff --git 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBDeviceIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBDeviceIT.java
index 44ea1e66bf7..1923210b50d 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBDeviceIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBDeviceIT.java
@@ -38,6 +38,7 @@ import java.sql.Statement;
 import java.util.Collections;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 @RunWith(IoTDBTestRunner.class)
@@ -163,20 +164,11 @@ public class IoTDBDeviceIT {
         assertEquals("550: Table 'test.table2' does not exist.", 
e.getMessage());
       }
 
-      try {
-        statement.executeQuery("show devices from table0 where temperature = 
37.6");
-        fail("Show devices shall fail for measurement predicate");
-      } catch (final Exception e) {
-        assertEquals(
-            "701: The TIME/FIELD columns are currently not allowed in devices 
related operations",
-            e.getMessage());
-      }
-
       try {
         statement.executeQuery("count devices from table0 where a = 1");
         fail("Count devices shall fail for non-exist column");
       } catch (final Exception e) {
-        assertEquals("616: Column 'a' cannot be resolved", e.getMessage());
+        assertEquals("701: Column 'a' is not an attribute or tag column", 
e.getMessage());
       }
 
       // Test fully qualified name
@@ -224,6 +216,34 @@ public class IoTDBDeviceIT {
         assertEquals("701: Update's attribute value must be STRING, TEXT or 
null.", e.getMessage());
       }
 
+      try {
+        statement.execute("show devices from table0 where humidity = 1");
+        fail("Update shall fail for non-tag/attribute columns");
+      } catch (final Exception e) {
+        assertEquals("701: Column 'humidity' is not an attribute or tag 
column", e.getMessage());
+      }
+
+      try {
+        statement.execute("count devices from table0 where humidity = 1");
+        fail("Update shall fail for non-tag/attribute columns");
+      } catch (final Exception e) {
+        assertEquals("701: Column 'humidity' is not an attribute or tag 
column", e.getMessage());
+      }
+
+      try {
+        statement.execute("update table0 set model = '1' where humidity = 1");
+        fail("Update shall fail for non-tag/attribute columns");
+      } catch (final Exception e) {
+        assertEquals("701: Column 'humidity' is not an attribute or tag 
column", e.getMessage());
+      }
+
+      try {
+        statement.execute("update table0 set model = humidity");
+        fail("Update shall fail for non-tag/attribute columns");
+      } catch (final Exception e) {
+        assertTrue(e.getMessage().contains("Column 'humidity' is not an 
attribute or tag column"));
+      }
+
       // Test filter with no effect
       statement.execute("update table0 set model = null where model = 'A' and 
model = 'B'");
 
@@ -270,9 +290,7 @@ public class IoTDBDeviceIT {
         statement.executeQuery("delete devices from table0 where time = 1");
         fail("Delete devices shall fail when specifies non tag column");
       } catch (final Exception e) {
-        assertEquals(
-            "701: The TIME/FIELD columns are currently not allowed in devices 
related operations",
-            e.getMessage());
+        assertEquals("701: Column 'time' is not an attribute or tag column", 
e.getMessage());
       }
     }
   }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
index 01b216fe875..96f68194400 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
@@ -19,6 +19,7 @@
 
 package org.apache.iotdb.db.queryengine.plan.relational.analyzer;
 
+import org.apache.iotdb.commons.exception.IoTDBException;
 import org.apache.iotdb.commons.schema.table.TsTable;
 import org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory;
 import org.apache.iotdb.commons.schema.table.column.TsTableColumnSchema;
@@ -551,9 +552,24 @@ public class StatementAnalyzer {
                       }
                       attributeNames.add((SymbolReference) parsedColumn);
 
-                      final Pair<Type, Expression> expressionPair =
-                          analyzeAndRewriteExpression(
-                              translationMap, translationMap.getScope(), 
assignment.getValue());
+                      final Pair<Type, Expression> expressionPair;
+                      try {
+                        expressionPair =
+                            analyzeAndRewriteExpression(
+                                translationMap, translationMap.getScope(), 
assignment.getValue());
+                      } catch (final Exception e) {
+                        if (e.getMessage().contains("cannot be resolved")) {
+                          throw new SemanticException(
+                              new IoTDBException(
+                                  e.getCause()
+                                      .getMessage()
+                                      .replace(
+                                          "cannot be resolved",
+                                          "is not an attribute or tag column"),
+                                  
TSStatusCode.SEMANTIC_ERROR.getStatusCode()));
+                        }
+                        throw e;
+                      }
                       if (!expressionPair.getLeft().equals(StringType.STRING)
                           && !expressionPair.getLeft().equals(BinaryType.TEXT)
                           && 
!expressionPair.getLeft().equals(UnknownType.UNKNOWN)) {
@@ -4546,11 +4562,24 @@ public class StatementAnalyzer {
 
         final TableSchema originalSchema = tableSchema.get();
         final ImmutableList.Builder<Field> fields = ImmutableList.builder();
+        // We only leave attribute & tag here because the others are not 
allowed in device related
+        // SQLs
         fields.addAll(
             analyzeTableOutputFields(
                 node.getTable(),
                 name,
-                new TableSchema(originalSchema.getTableName(), 
originalSchema.getColumns())));
+                new TableSchema(
+                    originalSchema.getTableName(),
+                    originalSchema.getColumns().stream()
+                        .filter(
+                            columnSchema ->
+                                columnSchema
+                                        .getColumnCategory()
+                                        
.equals(TsTableColumnCategory.ATTRIBUTE)
+                                    || columnSchema
+                                        .getColumnCategory()
+                                        .equals(TsTableColumnCategory.TAG))
+                        .collect(Collectors.toList()))));
         final List<Field> fieldList = fields.build();
         final Scope scope = createAndAssignScope(node, context, fieldList);
         translationMap =
@@ -4564,7 +4593,19 @@ public class StatementAnalyzer {
                 new PlannerContext(metadata, null));
 
         if (node.getWhere().isPresent()) {
-          analyzeWhere(node, translationMap.getScope(), node.getWhere().get());
+          try {
+            analyzeWhere(node, translationMap.getScope(), 
node.getWhere().get());
+          } catch (final Throwable e) {
+            if (e instanceof SemanticException && 
e.getMessage().contains("cannot be resolved")) {
+              throw new SemanticException(
+                  new IoTDBException(
+                      e.getCause()
+                          .getMessage()
+                          .replace("cannot be resolved", "is not an attribute 
or tag column"),
+                      TSStatusCode.SEMANTIC_ERROR.getStatusCode()));
+            }
+            throw e;
+          }
           node.setWhere(translationMap.rewrite(analysis.getWhere(node)));
         }
       }

Reply via email to