This is an automated email from the ASF dual-hosted git repository.
justinchen 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 d583362ab98 Optimized the value type check for update device (#16448)
d583362ab98 is described below
commit d583362ab9842bd65abb2c168b5683647e6ac563
Author: Caideyipi <[email protected]>
AuthorDate: Tue Sep 30 18:12:04 2025 +0800
Optimized the value type check for update device (#16448)
---
.../iotdb/relational/it/schema/IoTDBDeviceIT.java | 4 +--
.../relational/analyzer/StatementAnalyzer.java | 31 +++++++++++++++-------
.../metadata/fetcher/SchemaPredicateUtil.java | 28 +++++++++----------
.../plan/relational/planner/TranslationMap.java | 2 +-
.../sql/ast/AbstractQueryDeviceWithCache.java | 3 +--
.../relational/sql/ast/AbstractTraverseDevice.java | 2 +-
.../plan/relational/sql/ast/DeleteDevice.java | 5 ++--
7 files changed, 41 insertions(+), 34 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 7b023b4e9f6..44ea1e66bf7 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
@@ -221,9 +221,7 @@ public class IoTDBDeviceIT {
statement.execute("update table0 set model = cast(device_id as
int32)");
fail("Update shall fail when result type mismatch");
} catch (final Exception e) {
- assertEquals(
- "507: Result type mismatch for attribute 'model', expected class
org.apache.tsfile.utils.Binary, actual class java.lang.Integer",
- e.getMessage());
+ assertEquals("701: Update's attribute value must be STRING, TEXT or
null.", e.getMessage());
}
// Test filter with no effect
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 408c52909e7..6a2b7eb34c1 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
@@ -220,10 +220,14 @@ import com.google.common.collect.Iterables;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Streams;
import org.apache.tsfile.common.conf.TSFileConfig;
+import org.apache.tsfile.read.common.type.BinaryType;
import org.apache.tsfile.read.common.type.RowType;
+import org.apache.tsfile.read.common.type.StringType;
import org.apache.tsfile.read.common.type.TimestampType;
import org.apache.tsfile.read.common.type.Type;
+import org.apache.tsfile.read.common.type.UnknownType;
import org.apache.tsfile.utils.Binary;
+import org.apache.tsfile.utils.Pair;
import java.util.ArrayList;
import java.util.Collection;
@@ -507,7 +511,7 @@ public class StatementAnalyzer {
final TsTable table =
DataNodeTableCache.getInstance().getTable(node.getDatabase(),
node.getTableName());
DataNodeTreeViewSchemaUtils.checkTableInWrite(node.getDatabase(), table);
- if (!node.parseRawExpression(
+ if (!node.parseWhere(
null,
table,
table.getColumnList().stream()
@@ -531,7 +535,8 @@ public class StatementAnalyzer {
assignment -> {
final Expression parsedColumn =
analyzeAndRewriteExpression(
- translationMap, translationMap.getScope(),
assignment.getName());
+ translationMap, translationMap.getScope(),
assignment.getName())
+ .getRight();
if (!(parsedColumn instanceof SymbolReference)
|| table
.getColumnSchema(((SymbolReference)
parsedColumn).getName())
@@ -545,10 +550,16 @@ public class StatementAnalyzer {
}
attributeNames.add((SymbolReference) parsedColumn);
- return new UpdateAssignment(
- parsedColumn,
+ final Pair<Type, Expression> expressionPair =
analyzeAndRewriteExpression(
- translationMap, translationMap.getScope(),
assignment.getValue()));
+ translationMap, translationMap.getScope(),
assignment.getValue());
+ if (!expressionPair.getLeft().equals(StringType.STRING)
+ && !expressionPair.getLeft().equals(BinaryType.TEXT)
+ &&
!expressionPair.getLeft().equals(UnknownType.UNKNOWN)) {
+ throw new SemanticException(
+ "Update's attribute value must be STRING, TEXT or
null.");
+ }
+ return new UpdateAssignment(parsedColumn,
expressionPair.getRight());
})
.collect(Collectors.toList()));
}
@@ -569,7 +580,7 @@ public class StatementAnalyzer {
DataNodeTreeViewSchemaUtils.checkTableInWrite(node.getDatabase(), table);
node.parseModEntries(table);
analyzeTraverseDevice(node, context, node.getWhere().isPresent());
- node.parseRawExpression(
+ node.parseWhere(
null,
table,
table.getColumnList().stream()
@@ -4515,7 +4526,7 @@ public class StatementAnalyzer {
final String tableName = node.getTableName();
if (Objects.isNull(database)) {
- throw new SemanticException("The database must be set before show
devices.");
+ throw new SemanticException("The database must be set.");
}
if (!metadata.tableExists(new QualifiedObjectName(database, tableName)))
{
@@ -4560,11 +4571,11 @@ public class StatementAnalyzer {
return translationMap;
}
- private Expression analyzeAndRewriteExpression(
+ private Pair<Type, Expression> analyzeAndRewriteExpression(
final TranslationMap translationMap, final Scope scope, final
Expression expression) {
- analyzeExpression(expression, scope);
+ final Type type = analyzeExpression(expression,
scope).getType(expression);
scope.getRelationType().getAllFields();
- return translationMap.rewrite(expression);
+ return new Pair<>(type, translationMap.rewrite(expression));
}
@Override
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/SchemaPredicateUtil.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/SchemaPredicateUtil.java
index 0620f3b5383..c794ab3fba7 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/SchemaPredicateUtil.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/SchemaPredicateUtil.java
@@ -58,8 +58,8 @@ public class SchemaPredicateUtil {
final TsTable table,
final MPPQueryContext queryContext,
final boolean isDirectDeviceQuery) {
- final List<Expression> idDeterminedList = new ArrayList<>();
- final List<Expression> idFuzzyList = new ArrayList<>();
+ final List<Expression> tagDeterminedList = new ArrayList<>();
+ final List<Expression> tagFuzzyList = new ArrayList<>();
final CheckSchemaPredicateVisitor visitor = new
CheckSchemaPredicateVisitor();
final CheckSchemaPredicateVisitor.Context context =
new CheckSchemaPredicateVisitor.Context(table, queryContext,
isDirectDeviceQuery);
@@ -70,15 +70,15 @@ public class SchemaPredicateUtil {
if (expression instanceof BetweenPredicate) {
final BetweenPredicate predicate = (BetweenPredicate) expression;
- // Separate the between predicate to simply the logic and to handle
cases like
- // '2' between id1 and attr2 / id1 between '2' and attr1
+ // Separate the between predicate to simplify the logic and to handle
cases like '2' between
+ // id1 and attr2 / id1 between '2' and attr1
separateExpression(
new ComparisonExpression(
ComparisonExpression.Operator.LESS_THAN_OR_EQUAL,
predicate.getMin(),
predicate.getValue()),
- idDeterminedList,
- idFuzzyList,
+ tagDeterminedList,
+ tagFuzzyList,
visitor,
context);
separateExpression(
@@ -86,27 +86,27 @@ public class SchemaPredicateUtil {
ComparisonExpression.Operator.LESS_THAN_OR_EQUAL,
predicate.getValue(),
predicate.getMax()),
- idDeterminedList,
- idFuzzyList,
+ tagDeterminedList,
+ tagFuzzyList,
visitor,
context);
continue;
}
- separateExpression(expression, idDeterminedList, idFuzzyList, visitor,
context);
+ separateExpression(expression, tagDeterminedList, tagFuzzyList, visitor,
context);
}
- return new Pair<>(idDeterminedList, idFuzzyList);
+ return new Pair<>(tagDeterminedList, tagFuzzyList);
}
private static void separateExpression(
final Expression expression,
- final List<Expression> idDeterminedList,
- final List<Expression> idFuzzyList,
+ final List<Expression> tagDeterminedList,
+ final List<Expression> tagFuzzyList,
final CheckSchemaPredicateVisitor visitor,
final CheckSchemaPredicateVisitor.Context context) {
if (Boolean.TRUE.equals(expression.accept(visitor, context))) {
- idFuzzyList.add(expression);
+ tagFuzzyList.add(expression);
} else {
- idDeterminedList.add(expression);
+ tagDeterminedList.add(expression);
}
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/TranslationMap.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/TranslationMap.java
index 0edd20bc36d..0f831b8168b 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/TranslationMap.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/TranslationMap.java
@@ -260,7 +260,7 @@ public class TranslationMap {
return getSymbolForColumn(node)
.map(symbol -> (Expression) symbol.toSymbolReference())
- .orElseGet(() -> node);
+ .orElse(node);
}
@Override
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AbstractQueryDeviceWithCache.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AbstractQueryDeviceWithCache.java
index 327b5703b4e..ab2a1afe76a 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AbstractQueryDeviceWithCache.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AbstractQueryDeviceWithCache.java
@@ -64,8 +64,7 @@ public abstract class AbstractQueryDeviceWithCache extends
AbstractTraverseDevic
final Map<String, List<DeviceEntry>> entries = new HashMap<>();
entries.put(database, new ArrayList<>());
- final boolean needFetch =
- super.parseRawExpression(entries, tableInstance, attributeColumns,
context);
+ final boolean needFetch = super.parseWhere(entries, tableInstance,
attributeColumns, context);
if (!needFetch) {
context.reserveMemoryForFrontEnd(
entries.get(database).stream().map(DeviceEntry::ramBytesUsed).reduce(0L,
Long::sum));
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AbstractTraverseDevice.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AbstractTraverseDevice.java
index 2493418b671..c61945b1b91 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AbstractTraverseDevice.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AbstractTraverseDevice.java
@@ -128,7 +128,7 @@ public abstract class AbstractTraverseDevice extends
Statement {
this.where = where;
}
- public boolean parseRawExpression(
+ public boolean parseWhere(
final Map<String, List<DeviceEntry>> entries,
final TsTable tableInstance,
final List<String> attributeColumns,
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/DeleteDevice.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/DeleteDevice.java
index 10935e97d4e..9b1487b0a48 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/DeleteDevice.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/DeleteDevice.java
@@ -75,13 +75,12 @@ public class DeleteDevice extends AbstractTraverseDevice {
}
@Override
- public boolean parseRawExpression(
+ public boolean parseWhere(
final Map<String, List<DeviceEntry>> entries,
final TsTable tableInstance,
final List<String> attributeColumns,
final MPPQueryContext context) {
- return mayDeleteDevice =
- super.parseRawExpression(entries, tableInstance, attributeColumns,
context);
+ return mayDeleteDevice = super.parseWhere(entries, tableInstance,
attributeColumns, context);
}
public boolean isMayDeleteDevice() {