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 197c4f18af9c4eac2472a6f728412d9bfe47ee3d Author: libo <[email protected]> AuthorDate: Thu Nov 13 11:17:23 2025 +0800 Adjust the exception message cause by the WHERE clause, which uses a range comparison on the same field, specifically when the left value of the range is greater than the right value of the range. (#16741) (cherry picked from commit f608a2d2e6a2ddf8b80ae0e36dbc3424a7ca6127) --- .../org/apache/iotdb/db/it/IoTDBDeletionIT.java | 21 +++++++++++++++++++++ .../db/queryengine/plan/parser/ASTVisitor.java | 12 +++++++++--- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBDeletionIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBDeletionIT.java index 576b9c75f21..17ceb9b6962 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBDeletionIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBDeletionIT.java @@ -19,10 +19,12 @@ package org.apache.iotdb.db.it; +import org.apache.iotdb.db.queryengine.plan.parser.ASTVisitor; import org.apache.iotdb.it.env.EnvFactory; import org.apache.iotdb.it.framework.IoTDBTestRunner; import org.apache.iotdb.itbase.category.ClusterIT; import org.apache.iotdb.itbase.category.LocalStandaloneIT; +import org.apache.iotdb.jdbc.IoTDBSQLException; import org.apache.iotdb.rpc.TSStatusCode; import org.junit.AfterClass; @@ -467,6 +469,25 @@ public class IoTDBDeletionIT { } } + @Test + public void testDeleteByRangeComparison() throws SQLException { + try (Connection connection = EnvFactory.getEnv().getConnection(); + Statement statement = connection.createStatement()) { + statement.execute("CREATE DATABASE root.test"); + statement.execute("CREATE ALIGNED TIMESERIES root.test.g_0.d2(s_0 int32)"); + statement.execute("INSERT INTO root.test.g_0.d_2(time,s_0) VALUES(1, 1)"); + + try { + statement.execute("DELETE FROM root.test.g_0.d_2.s_0 WHERE time > 4 AND time < 0"); + } catch (IoTDBSQLException e) { + Assert.assertEquals( + e.getErrorCode() + ": " + ASTVisitor.DELETE_RANGE_COMPARISON_ERROR_MSG, e.getMessage()); + } + + statement.execute("DROP DATABASE root.test"); + } + } + private static void prepareSeries() { try (Connection connection = EnvFactory.getEnv().getConnection(); Statement statement = connection.createStatement()) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java index 123f7dcae52..be30b4e1b37 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java @@ -344,6 +344,9 @@ public class ASTVisitor extends IoTDBSqlParserBaseVisitor<Statement> { private static final String LIMIT_CONFIGURATION_ENABLED_ERROR_MSG = "Limit configuration is not enabled, please enable it first."; + public static final String DELETE_RANGE_COMPARISON_ERROR_MSG = + "For delete statement, where clause use a range comparison on the same field, the left value of the range cannot be greater than the right value of the range, it must be written like this : time > 5 and time < 10"; + private static final String NODE_NAME_IN_INTO_PATH_MATCHER = "([a-zA-Z0-9_${}\\u2E80-\\u9FFF]+)"; private static final Pattern NODE_NAME_IN_INTO_PATH_PATTERN = Pattern.compile(NODE_NAME_IN_INTO_PATH_MATCHER); @@ -2993,9 +2996,12 @@ public class ASTVisitor extends IoTDBSqlParserBaseVisitor<Statement> { parseDeleteTimeRange(((LogicAndExpression) predicate).getLeftExpression()); TimeRange rightTimeRange = parseDeleteTimeRange(((LogicAndExpression) predicate).getRightExpression()); - return new TimeRange( - Math.max(leftTimeRange.getMin(), rightTimeRange.getMin()), - Math.min(leftTimeRange.getMax(), rightTimeRange.getMax())); + long min = Math.max(leftTimeRange.getMin(), rightTimeRange.getMin()); + long max = Math.min(leftTimeRange.getMax(), rightTimeRange.getMax()); + if (min > max) { + throw new SemanticException(DELETE_RANGE_COMPARISON_ERROR_MSG); + } + return new TimeRange(min, max); } else if (predicate instanceof CompareBinaryExpression) { if (((CompareBinaryExpression) predicate).getLeftExpression() instanceof TimestampOperand) { return parseTimeRangeForDeleteTimeRange(
