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 =

Reply via email to