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 8235112d353 Fix no-tag table attribute deletion (#18176)
8235112d353 is described below

commit 8235112d353c7f800ab8009ab134a302968c3ab7
Author: Caideyipi <[email protected]>
AuthorDate: Mon Jul 13 10:41:47 2026 +0800

    Fix no-tag table attribute deletion (#18176)
---
 .../relational/it/db/it/IoTDBDeletionTableIT.java  |  18 ++++
 .../plan/relational/sql/ast/InsertRows.java        | 115 ++++++++++++++++++++-
 2 files changed, 132 insertions(+), 1 deletion(-)

diff --git 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBDeletionTableIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBDeletionTableIT.java
index 3ac335df1ad..82b6c1a8ff6 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBDeletionTableIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBDeletionTableIT.java
@@ -653,6 +653,24 @@ public class IoTDBDeletionTableIT {
               + "(3, 'blue', 'large', 13),"
               + "(4, 'red', 'small', 14)");
 
+      TestUtils.assertResultSetEqual(
+          statement.executeQuery("show devices from delete_by_attr_no_tag"),
+          "attr1,attr2,",
+          Collections.singleton("red,small,"));
+      TestUtils.assertResultSetEqual(
+          statement.executeQuery(
+              "show devices from delete_by_attr_no_tag "
+                  + "where attr1 = 'red' AND attr2 = 'small'"),
+          "attr1,attr2,",
+          Collections.singleton("red,small,"));
+      statement.execute(
+          "INSERT INTO delete_by_attr_no_tag(time, attr1, attr2, s1) VALUES "
+              + "(2, 'blue', 'large', 12),"
+              + "(4, 'red', 'small', 14)");
+      TestUtils.assertResultSetEqual(
+          statement.executeQuery("show devices from delete_by_attr_no_tag"),
+          "attr1,attr2,",
+          Collections.singleton("red,small,"));
       statement.execute(
           "DELETE FROM delete_by_attr_no_tag "
               + "WHERE time >= 2 AND time <= 4 AND attr1 = 'red' AND attr2 = 
'small'");
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/InsertRows.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/InsertRows.java
index 4eb49df7183..6b5804ba4eb 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/InsertRows.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/InsertRows.java
@@ -31,11 +31,15 @@ import 
org.apache.iotdb.db.queryengine.plan.statement.crud.InsertRowStatement;
 import org.apache.iotdb.db.queryengine.plan.statement.crud.InsertRowsStatement;
 
 import org.apache.tsfile.enums.TSDataType;
+import org.apache.tsfile.utils.Constants;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 
 public class InsertRows extends WrappedInsertStatement {
@@ -100,10 +104,26 @@ public class InsertRows extends WrappedInsertStatement {
 
   @Override
   public void validateDeviceSchema(Metadata metadata, MPPQueryContext context) 
{
+    final Map<String, Map<String, CoalescedDeviceSchemaValidation>> 
validationMap =
+        new LinkedHashMap<>();
     for (InsertRowStatement insertRowStatement :
         getInnerTreeStatement().getInsertRowStatementList()) {
-      
metadata.validateDeviceSchema(createTableSchemaValidation(insertRowStatement), 
context);
+      final ITableDeviceSchemaValidation rowValidation =
+          createTableSchemaValidation(insertRowStatement);
+      validationMap
+          .computeIfAbsent(rowValidation.getDatabase(), key -> new 
LinkedHashMap<>())
+          .computeIfAbsent(
+              rowValidation.getTableName(),
+              tableName ->
+                  new 
CoalescedDeviceSchemaValidation(rowValidation.getDatabase(), tableName))
+          .add(
+              rowValidation.getDeviceIdList().get(0),
+              rowValidation.getAttributeColumnNameList(),
+              rowValidation.getAttributeValueList().get(0));
     }
+    validationMap.values().stream()
+        .flatMap(tableValidationMap -> tableValidationMap.values().stream())
+        .forEach(validation -> metadata.validateDeviceSchema(validation, 
context));
   }
 
   protected ITableDeviceSchemaValidation createTableSchemaValidation(
@@ -157,4 +177,97 @@ public class InsertRows extends WrappedInsertStatement {
       }
     };
   }
+
+  private static class CoalescedDeviceSchemaValidation implements 
ITableDeviceSchemaValidation {
+
+    private final String database;
+    private final String tableName;
+    private final Map<DeviceIdKey, Map<Integer, Object>> 
deviceAttributeValueMap =
+        new LinkedHashMap<>();
+    private final List<String> attributeColumnNameList = new ArrayList<>();
+    private final Map<String, Integer> attributeColumnIndexMap = new 
LinkedHashMap<>();
+
+    private CoalescedDeviceSchemaValidation(final String database, final 
String tableName) {
+      this.database = database;
+      this.tableName = tableName;
+    }
+
+    private void add(
+        final Object[] deviceId,
+        final List<String> attributeColumnNames,
+        final Object[] attributeValues) {
+      final Map<Integer, Object> attributeValueMap =
+          deviceAttributeValueMap.computeIfAbsent(
+              new DeviceIdKey(deviceId), key -> new HashMap<>());
+      for (int i = 0; i < attributeColumnNames.size(); i++) {
+        final int attributeColumnIndex =
+            attributeColumnIndexMap.computeIfAbsent(
+                attributeColumnNames.get(i),
+                attributeColumnName -> {
+                  attributeColumnNameList.add(attributeColumnName);
+                  return attributeColumnNameList.size() - 1;
+                });
+        if (i < attributeValues.length
+            && attributeValues[i] != null
+            && attributeValues[i] != Constants.NONE) {
+          attributeValueMap.put(attributeColumnIndex, attributeValues[i]);
+        }
+      }
+    }
+
+    @Override
+    public String getDatabase() {
+      return database;
+    }
+
+    @Override
+    public String getTableName() {
+      return tableName;
+    }
+
+    @Override
+    public List<Object[]> getDeviceIdList() {
+      final List<Object[]> deviceIdList = new 
ArrayList<>(deviceAttributeValueMap.size());
+      deviceAttributeValueMap.keySet().forEach(key -> 
deviceIdList.add(key.deviceId));
+      return deviceIdList;
+    }
+
+    @Override
+    public List<String> getAttributeColumnNameList() {
+      return attributeColumnNameList;
+    }
+
+    @Override
+    public List<Object[]> getAttributeValueList() {
+      final List<Object[]> attributeValueList = new 
ArrayList<>(deviceAttributeValueMap.size());
+      for (final Map<Integer, Object> attributeValueMap : 
deviceAttributeValueMap.values()) {
+        final Object[] attributeValues = new 
Object[attributeColumnNameList.size()];
+        Arrays.fill(attributeValues, Constants.NONE);
+        attributeValueMap.forEach((index, value) -> attributeValues[index] = 
value);
+        attributeValueList.add(attributeValues);
+      }
+      return attributeValueList;
+    }
+  }
+
+  private static class DeviceIdKey {
+
+    private final Object[] deviceId;
+
+    private DeviceIdKey(final Object[] deviceId) {
+      this.deviceId = (Object[]) deviceId.clone();
+    }
+
+    @Override
+    public boolean equals(final Object object) {
+      return this == object
+          || object instanceof DeviceIdKey
+              && Arrays.equals(deviceId, ((DeviceIdKey) object).deviceId);
+    }
+
+    @Override
+    public int hashCode() {
+      return Arrays.hashCode(deviceId);
+    }
+  }
 }

Reply via email to