This is an automated email from the ASF dual-hosted git repository.
jackietien 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 b34e05e5da4 fix exception msg in RPR
b34e05e5da4 is described below
commit b34e05e5da4a5b4a7086ff1d43c817e5d8024af2
Author: Le Yang <[email protected]>
AuthorDate: Tue Jun 17 14:26:05 2025 +0800
fix exception msg in RPR
---
.../rowpattern/expression/ArithmeticOperator.java | 7 ++--
.../rowpattern/expression/ComparisonOperator.java | 8 +++--
.../process/rowpattern/expression/Computation.java | 9 ++---
.../rowpattern/expression/LogicalOperator.java | 4 ++-
.../expression/PatternExpressionComputation.java | 3 +-
.../relational/analyzer/ExpressionAnalyzer.java | 19 +++++++---
.../planner/rowpattern/IrRowPattern.java | 40 ++++++++++++----------
.../analyzer/RowPatternRecognitionTest.java | 32 +++++++++++++++++
8 files changed, 86 insertions(+), 36 deletions(-)
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/rowpattern/expression/ArithmeticOperator.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/rowpattern/expression/ArithmeticOperator.java
index fec2ccf4815..59f0cbdc42a 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/rowpattern/expression/ArithmeticOperator.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/rowpattern/expression/ArithmeticOperator.java
@@ -19,6 +19,8 @@
package
org.apache.iotdb.db.queryengine.execution.operator.process.rowpattern.expression;
+import org.apache.iotdb.db.exception.sql.SemanticException;
+
public enum ArithmeticOperator implements BinaryOperator {
ADD {
@Override
@@ -71,11 +73,10 @@ public enum ArithmeticOperator implements BinaryOperator {
try {
return Double.parseDouble((String) obj);
} catch (NumberFormatException e) {
- throw new IllegalArgumentException("Cannot parse String to double: " +
obj);
+ throw new SemanticException("Cannot parse String to double: " + obj);
}
} else {
- throw new IllegalArgumentException(
- "Unsupported type for arithmetic operation: " + obj.getClass());
+ throw new SemanticException("Unsupported type for arithmetic operation:
" + obj.getClass());
}
}
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/rowpattern/expression/ComparisonOperator.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/rowpattern/expression/ComparisonOperator.java
index 5aee7628eca..114286b66ac 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/rowpattern/expression/ComparisonOperator.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/rowpattern/expression/ComparisonOperator.java
@@ -19,6 +19,8 @@
package
org.apache.iotdb.db.queryengine.execution.operator.process.rowpattern.expression;
+import org.apache.iotdb.db.exception.sql.SemanticException;
+
import org.apache.tsfile.utils.Binary;
import java.nio.charset.StandardCharsets;
@@ -85,7 +87,7 @@ public enum ComparisonOperator implements BinaryOperator {
NormalizedValue normRight = normalize(right);
if (normLeft.type != normRight.type) {
- throw new IllegalArgumentException(
+ throw new SemanticException(
"Cannot compare values of different types: " + normLeft.type + " vs.
" + normRight.type);
}
@@ -121,7 +123,7 @@ public enum ComparisonOperator implements BinaryOperator {
case BINARY:
return ((Binary) value).compareTo((Binary) other.value);
default:
- throw new IllegalStateException("Unknown type: " + type);
+ throw new SemanticException("Unknown type: " + type);
}
}
}
@@ -139,7 +141,7 @@ public enum ComparisonOperator implements BinaryOperator {
} else if (obj instanceof Binary) {
return new NormalizedValue(NormalizedValue.Type.BINARY, obj);
} else {
- throw new IllegalArgumentException("Unsupported type: " +
obj.getClass());
+ throw new SemanticException("Unsupported type: " + obj.getClass());
}
}
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/rowpattern/expression/Computation.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/rowpattern/expression/Computation.java
index 93c74c0a4fd..a442647d433 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/rowpattern/expression/Computation.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/rowpattern/expression/Computation.java
@@ -19,6 +19,7 @@
package
org.apache.iotdb.db.queryengine.execution.operator.process.rowpattern.expression;
+import org.apache.iotdb.db.exception.sql.SemanticException;
import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ArithmeticBinaryExpression;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.BooleanLiteral;
import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ComparisonExpression;
@@ -126,7 +127,7 @@ public abstract class Computation {
BooleanLiteral constExpr = (BooleanLiteral) expression;
return new ConstantComputation(constExpr.getValue());
} else {
- throw new IllegalArgumentException(
+ throw new SemanticException(
"Unsupported expression type: " + expression.getClass().getName());
}
}
@@ -145,7 +146,7 @@ public abstract class Computation {
case MODULUS:
return ArithmeticOperator.MODULUS;
default:
- throw new IllegalArgumentException("Unsupported arithmetic operator:
" + operator);
+ throw new SemanticException("Unsupported arithmetic operator: " +
operator);
}
}
@@ -167,7 +168,7 @@ public abstract class Computation {
case IS_DISTINCT_FROM:
return ComparisonOperator.IS_DISTINCT_FROM;
default:
- throw new IllegalArgumentException("Unsupported comparison operator:
" + operator);
+ throw new SemanticException("Unsupported comparison operator: " +
operator);
}
}
@@ -178,7 +179,7 @@ public abstract class Computation {
case OR:
return LogicalOperator.OR;
default:
- throw new IllegalArgumentException("Unsupported logical operator: "
+ operator);
+ throw new SemanticException("Unsupported logical operator: " +
operator);
}
}
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/rowpattern/expression/LogicalOperator.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/rowpattern/expression/LogicalOperator.java
index 724effeda6e..c426cbd1693 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/rowpattern/expression/LogicalOperator.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/rowpattern/expression/LogicalOperator.java
@@ -19,6 +19,8 @@
package
org.apache.iotdb.db.queryengine.execution.operator.process.rowpattern.expression;
+import org.apache.iotdb.db.exception.sql.SemanticException;
+
import java.util.List;
public enum LogicalOperator implements NaryOperator {
@@ -41,7 +43,7 @@ public enum LogicalOperator implements NaryOperator {
public Object apply(List<Object> operands) {
for (Object operand : operands) {
if (!(operand instanceof Boolean)) {
- throw new IllegalArgumentException("OR operator only accepts Boolean
operands");
+ throw new SemanticException("OR operator only accepts Boolean
operands");
}
if ((Boolean) operand) {
return true; // short-circuit
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/rowpattern/expression/PatternExpressionComputation.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/rowpattern/expression/PatternExpressionComputation.java
index c261b7398ba..fff47638ee9 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/rowpattern/expression/PatternExpressionComputation.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/rowpattern/expression/PatternExpressionComputation.java
@@ -19,6 +19,7 @@
package
org.apache.iotdb.db.queryengine.execution.operator.process.rowpattern.expression;
+import org.apache.iotdb.db.exception.sql.SemanticException;
import
org.apache.iotdb.db.queryengine.execution.operator.process.rowpattern.PhysicalValueAccessor;
import
org.apache.iotdb.db.queryengine.execution.operator.process.rowpattern.PhysicalValuePointer;
import
org.apache.iotdb.db.queryengine.execution.operator.process.rowpattern.matcher.ArrayView;
@@ -147,7 +148,7 @@ public class PatternExpressionComputation {
} else if (type instanceof StringType) {
return partition.getBinary(channel, position);
} else {
- throw new IllegalArgumentException("Unsupported type: " +
type.getClass().getSimpleName());
+ throw new SemanticException("Unsupported type: " +
type.getClass().getSimpleName());
}
}
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/ExpressionAnalyzer.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/ExpressionAnalyzer.java
index 92db153ea9f..9032929d2c7 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/ExpressionAnalyzer.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/ExpressionAnalyzer.java
@@ -1009,7 +1009,7 @@ public class ExpressionAnalyzer {
case "NEXT":
return setExpressionType(node, analyzePhysicalNavigation(node,
context, name));
default:
- throw new IllegalStateException("unexpected pattern recognition
function " + name);
+ throw new SemanticException("unexpected pattern recognition
function " + name);
}
} else if (isAggregation) {
@@ -2193,19 +2193,28 @@ public class ExpressionAnalyzer {
public static boolean isPatternRecognitionFunction(FunctionCall node) {
QualifiedName qualifiedName = node.getName();
if (qualifiedName.getParts().size() > 1) {
- return false;
+ throw new SemanticException(
+ "Pattern recognition function name must not be qualified: " +
qualifiedName);
}
Identifier identifier = qualifiedName.getOriginalParts().get(0);
if (identifier.isDelimited()) {
- return false;
+ throw new SemanticException(
+ "Pattern recognition function name must not be delimited: " +
identifier.getValue());
}
String name = identifier.getValue().toUpperCase(ENGLISH);
- return name.equals("RPR_FIRST")
+ if (name.equals("LAST") || name.equals("FIRST")) {
+ throw new SemanticException(
+ "Pattern recognition function names cannot be LAST or FIRST, use
RPR_LAST or RPR_FIRST instead.");
+ } else if (!(name.equals("RPR_FIRST")
|| name.equals("RPR_LAST")
|| name.equals("PREV")
|| name.equals("NEXT")
|| name.equals("CLASSIFIER")
- || name.equals("MATCH_NUMBER");
+ || name.equals("MATCH_NUMBER"))) {
+ throw new SemanticException("Unknown pattern recognition function: " +
name);
+ } else {
+ return true;
+ }
}
public static ExpressionAnalysis analyzePatternRecognitionExpression(
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/rowpattern/IrRowPattern.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/rowpattern/IrRowPattern.java
index dcf5fcdf2c8..35a6597c52f 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/rowpattern/IrRowPattern.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/rowpattern/IrRowPattern.java
@@ -19,6 +19,8 @@
package org.apache.iotdb.db.queryengine.plan.relational.planner.rowpattern;
+import org.apache.iotdb.db.exception.sql.SemanticException;
+
import org.apache.tsfile.utils.ReadWriteIOUtils;
import java.io.DataOutputStream;
@@ -32,61 +34,61 @@ public abstract class IrRowPattern {
public static void serialize(IrRowPattern pattern, ByteBuffer byteBuffer) {
if (pattern instanceof IrAlternation) {
- ReadWriteIOUtils.write(0, byteBuffer); // Type marker for IrAlternation
+ ReadWriteIOUtils.write(0, byteBuffer);
IrAlternation.serialize((IrAlternation) pattern, byteBuffer);
} else if (pattern instanceof IrAnchor) {
- ReadWriteIOUtils.write(1, byteBuffer); // Type marker for IrAnchor
+ ReadWriteIOUtils.write(1, byteBuffer);
IrAnchor.serialize((IrAnchor) pattern, byteBuffer);
} else if (pattern instanceof IrConcatenation) {
- ReadWriteIOUtils.write(2, byteBuffer); // Type marker for IrConcatenation
+ ReadWriteIOUtils.write(2, byteBuffer);
IrConcatenation.serialize((IrConcatenation) pattern, byteBuffer);
} else if (pattern instanceof IrEmpty) {
- ReadWriteIOUtils.write(3, byteBuffer); // Type marker for IrEmpty
+ ReadWriteIOUtils.write(3, byteBuffer);
IrEmpty.serialize((IrEmpty) pattern, byteBuffer);
} else if (pattern instanceof IrExclusion) {
- ReadWriteIOUtils.write(4, byteBuffer); // Type marker for IrExclusion
+ ReadWriteIOUtils.write(4, byteBuffer);
IrExclusion.serialize((IrExclusion) pattern, byteBuffer);
} else if (pattern instanceof IrLabel) {
- ReadWriteIOUtils.write(5, byteBuffer); // Type marker for IrLabel
+ ReadWriteIOUtils.write(5, byteBuffer);
IrLabel.serialize((IrLabel) pattern, byteBuffer);
} else if (pattern instanceof IrPermutation) {
- ReadWriteIOUtils.write(6, byteBuffer); // Type marker for IrPermutation
+ ReadWriteIOUtils.write(6, byteBuffer);
IrPermutation.serialize((IrPermutation) pattern, byteBuffer);
} else if (pattern instanceof IrQuantified) {
- ReadWriteIOUtils.write(7, byteBuffer); // Type marker for IrQuantified
+ ReadWriteIOUtils.write(7, byteBuffer);
IrQuantified.serialize((IrQuantified) pattern, byteBuffer);
} else {
- throw new IllegalArgumentException("Unknown IrRowPattern type");
+ throw new SemanticException("Unknown IrRowPattern type");
}
}
public static void serialize(IrRowPattern pattern, DataOutputStream stream)
throws IOException {
if (pattern instanceof IrAlternation) {
- ReadWriteIOUtils.write(0, stream); // Type marker for IrAlternation
+ ReadWriteIOUtils.write(0, stream);
IrAlternation.serialize((IrAlternation) pattern, stream);
} else if (pattern instanceof IrAnchor) {
- ReadWriteIOUtils.write(1, stream); // Type marker for IrAnchor
+ ReadWriteIOUtils.write(1, stream);
IrAnchor.serialize((IrAnchor) pattern, stream);
} else if (pattern instanceof IrConcatenation) {
- ReadWriteIOUtils.write(2, stream); // Type marker for IrConcatenation
+ ReadWriteIOUtils.write(2, stream);
IrConcatenation.serialize((IrConcatenation) pattern, stream);
} else if (pattern instanceof IrEmpty) {
- ReadWriteIOUtils.write(3, stream); // Type marker for IrEmpty
+ ReadWriteIOUtils.write(3, stream);
IrEmpty.serialize((IrEmpty) pattern, stream);
} else if (pattern instanceof IrExclusion) {
- ReadWriteIOUtils.write(4, stream); // Type marker for IrExclusion
+ ReadWriteIOUtils.write(4, stream);
IrExclusion.serialize((IrExclusion) pattern, stream);
} else if (pattern instanceof IrLabel) {
- ReadWriteIOUtils.write(5, stream); // Type marker for IrLabel
+ ReadWriteIOUtils.write(5, stream);
IrLabel.serialize((IrLabel) pattern, stream);
} else if (pattern instanceof IrPermutation) {
- ReadWriteIOUtils.write(6, stream); // Type marker for IrPermutation
+ ReadWriteIOUtils.write(6, stream);
IrPermutation.serialize((IrPermutation) pattern, stream);
} else if (pattern instanceof IrQuantified) {
- ReadWriteIOUtils.write(7, stream); // Type marker for IrQuantified
+ ReadWriteIOUtils.write(7, stream);
IrQuantified.serialize((IrQuantified) pattern, stream);
} else {
- throw new IllegalArgumentException("Unknown IrRowPattern type");
+ throw new SemanticException("Unknown IrRowPattern type");
}
}
@@ -111,7 +113,7 @@ public abstract class IrRowPattern {
case 7:
return IrQuantified.deserialize(byteBuffer);
default:
- throw new IllegalArgumentException("Unknown IrRowPattern type");
+ throw new SemanticException("Unknown IrRowPattern type");
}
}
}
diff --git
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/RowPatternRecognitionTest.java
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/RowPatternRecognitionTest.java
index 6645707396b..c96747ff720 100644
---
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/RowPatternRecognitionTest.java
+++
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/RowPatternRecognitionTest.java
@@ -224,6 +224,38 @@ public class RowPatternRecognitionTest {
"Pattern exclusion syntax is not allowed when ALL ROWS PER MATCH WITH
UNMATCHED ROWS is specified");
}
+ @Test
+ public void testPatternFunctions() {
+ String sql =
+ "SELECT * "
+ + "FROM table1 "
+ + "MATCH_RECOGNIZE ( "
+ + " ORDER BY time "
+ + " MEASURES "
+ + " %s AS col1 "
+ + " PATTERN (A B+) "
+ + " DEFINE "
+ + " B AS B.s2 > 5"
+ + ") AS m";
+
+ assertTestSuccess(String.format(sql, "RPR_LAST(A.s1)"));
+
+ assertTestFail(
+ String.format(sql, "LAST(A.s1)"),
+ "Pattern recognition function names cannot be LAST or FIRST, use
RPR_LAST or RPR_FIRST instead.");
+ assertTestFail(
+ String.format(sql, "FIRST(A.s1)"),
+ "Pattern recognition function names cannot be LAST or FIRST, use
RPR_LAST or RPR_FIRST instead.");
+ assertTestFail(
+ String.format(sql, "RPR_LAT(A.s1)"), "Unknown pattern recognition
function: RPR_LAT");
+ assertTestFail(
+ String.format(sql, "\"RPP_LAST\"(s2)"),
+ "Pattern recognition function name must not be delimited: RPP_LAST");
+ assertTestFail(
+ String.format(sql, "A.RPP_LAST(s2)"),
+ "Pattern recognition function name must not be qualified: a.rpp_last");
+ }
+
@Test
public void testPatternQuantifiers() {
String sql =