You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ro...@apache.org on 2022/01/10 06:39:13 UTC

[iotdb] branch master updated: [IOTDB-2267] UDF: Error code 500 caused by user logic (#4744)

This is an automated email from the ASF dual-hosted git repository.

rong 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 aa108f3  [IOTDB-2267] UDF: Error code 500 caused by user logic (#4744)
aa108f3 is described below

commit aa108f38dfb95df48a9c41f12bf621764f77d6a1
Author: Steve Yurong Su <ro...@apache.org>
AuthorDate: Mon Jan 10 14:38:42 2022 +0800

    [IOTDB-2267] UDF: Error code 500 caused by user logic (#4744)
---
 .../java/org/apache/iotdb/udf/UDTFExample.java     | 19 ++++++++-
 .../apache/iotdb/db/utils/ErrorHandlingUtils.java  | 47 ++++++++++++----------
 2 files changed, 43 insertions(+), 23 deletions(-)

diff --git a/example/udf/src/main/java/org/apache/iotdb/udf/UDTFExample.java b/example/udf/src/main/java/org/apache/iotdb/udf/UDTFExample.java
index 17a534d..66a0748 100644
--- a/example/udf/src/main/java/org/apache/iotdb/udf/UDTFExample.java
+++ b/example/udf/src/main/java/org/apache/iotdb/udf/UDTFExample.java
@@ -23,11 +23,13 @@ import org.apache.iotdb.db.query.udf.api.UDTF;
 import org.apache.iotdb.db.query.udf.api.access.Row;
 import org.apache.iotdb.db.query.udf.api.collector.PointCollector;
 import org.apache.iotdb.db.query.udf.api.customizer.config.UDTFConfigurations;
+import org.apache.iotdb.db.query.udf.api.customizer.parameter.UDFParameterValidator;
 import org.apache.iotdb.db.query.udf.api.customizer.parameter.UDFParameters;
 import org.apache.iotdb.db.query.udf.api.customizer.strategy.RowByRowAccessStrategy;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import java.io.IOException;
+import java.util.Map;
 
 /** This is an internal example of the UDTF implementation. */
 public class UDTFExample implements UDTF {
@@ -39,11 +41,26 @@ public class UDTFExample implements UDTF {
    * INSERT INTO root.sg1.d1(timestamp, s1, s2) VALUES (1, -2, 2);
    * INSERT INTO root.sg1.d1(timestamp, s1, s2) VALUES (2, -3, 3);
    *
-   * CREATE FUNCTION example AS "org.apache.iotdb.udf.UDTFExample";
+   * CREATE FUNCTION example AS 'org.apache.iotdb.udf.UDTFExample';
    * SHOW FUNCTIONS;
    * SELECT s1, example(s1), s2, example(s2) FROM root.sg1.d1;
    */
   @Override
+  public void validate(UDFParameterValidator validator) throws Exception {
+    validator
+        // this udf only accepts 1 time series
+        .validateInputSeriesNumber(1)
+        // the data type of the first input time series should be INT32
+        .validateInputSeriesDataType(0, TSDataType.INT32)
+        // this udf doesn't accept any extra parameters
+        // the validation rule is not required because extra parameters will be ignored
+        .validate(
+            attributes -> ((Map) attributes).isEmpty(),
+            "extra udf parameters are not allowed",
+            validator.getParameters().getAttributes());
+  }
+
+  @Override
   public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) {
     configurations
         .setAccessStrategy(new RowByRowAccessStrategy())
diff --git a/server/src/main/java/org/apache/iotdb/db/utils/ErrorHandlingUtils.java b/server/src/main/java/org/apache/iotdb/db/utils/ErrorHandlingUtils.java
index 80b4285..bebe345 100644
--- a/server/src/main/java/org/apache/iotdb/db/utils/ErrorHandlingUtils.java
+++ b/server/src/main/java/org/apache/iotdb/db/utils/ErrorHandlingUtils.java
@@ -35,7 +35,9 @@ import org.antlr.v4.runtime.misc.ParseCancellationException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.IOException;
 import java.util.Arrays;
+import java.util.concurrent.ExecutionException;
 
 public class ErrorHandlingUtils {
 
@@ -53,7 +55,7 @@ public class ErrorHandlingUtils {
   public static TSStatus onNPEOrUnexpectedException(
       Exception e, String operation, TSStatusCode statusCode) {
     String message = String.format("[%s] Exception occurred: %s failed. ", statusCode, operation);
-    if (e instanceof NullPointerException) {
+    if (e instanceof IOException || e instanceof NullPointerException) {
       LOGGER.error("Status code: {}, operation: {} failed", statusCode, operation, e);
     } else {
       LOGGER.warn("Status code: {}, operation: {} failed", statusCode, operation, e);
@@ -85,31 +87,32 @@ public class ErrorHandlingUtils {
   }
 
   public static TSStatus tryCatchQueryException(Exception e) {
-    if (e instanceof QueryTimeoutRuntimeException) {
-      DETAILED_FAILURE_QUERY_TRACE_LOGGER.warn(e.getMessage(), e);
-      return RpcUtils.getStatus(TSStatusCode.TIME_OUT, getRootCause(e));
-    } else if (e instanceof ParseCancellationException) {
-      DETAILED_FAILURE_QUERY_TRACE_LOGGER.warn(INFO_PARSING_SQL_ERROR, e);
+    Throwable t = e instanceof ExecutionException ? e.getCause() : e;
+    if (t instanceof QueryTimeoutRuntimeException) {
+      DETAILED_FAILURE_QUERY_TRACE_LOGGER.warn(t.getMessage(), t);
+      return RpcUtils.getStatus(TSStatusCode.TIME_OUT, getRootCause(t));
+    } else if (t instanceof ParseCancellationException) {
+      DETAILED_FAILURE_QUERY_TRACE_LOGGER.warn(INFO_PARSING_SQL_ERROR, t);
       return RpcUtils.getStatus(
-          TSStatusCode.SQL_PARSE_ERROR, INFO_PARSING_SQL_ERROR + getRootCause(e));
-    } else if (e instanceof SQLParserException) {
-      DETAILED_FAILURE_QUERY_TRACE_LOGGER.warn(INFO_CHECK_METADATA_ERROR, e);
+          TSStatusCode.SQL_PARSE_ERROR, INFO_PARSING_SQL_ERROR + getRootCause(t));
+    } else if (t instanceof SQLParserException) {
+      DETAILED_FAILURE_QUERY_TRACE_LOGGER.warn(INFO_CHECK_METADATA_ERROR, t);
       return RpcUtils.getStatus(
-          TSStatusCode.METADATA_ERROR, INFO_CHECK_METADATA_ERROR + getRootCause(e));
-    } else if (e instanceof QueryProcessException) {
-      DETAILED_FAILURE_QUERY_TRACE_LOGGER.warn(INFO_QUERY_PROCESS_ERROR, e);
+          TSStatusCode.METADATA_ERROR, INFO_CHECK_METADATA_ERROR + getRootCause(t));
+    } else if (t instanceof QueryProcessException) {
+      DETAILED_FAILURE_QUERY_TRACE_LOGGER.warn(INFO_QUERY_PROCESS_ERROR, t);
       return RpcUtils.getStatus(
-          TSStatusCode.QUERY_PROCESS_ERROR, INFO_QUERY_PROCESS_ERROR + getRootCause(e));
-    } else if (e instanceof QueryInBatchStatementException) {
-      DETAILED_FAILURE_QUERY_TRACE_LOGGER.warn(INFO_NOT_ALLOWED_IN_BATCH_ERROR, e);
+          TSStatusCode.QUERY_PROCESS_ERROR, INFO_QUERY_PROCESS_ERROR + getRootCause(t));
+    } else if (t instanceof QueryInBatchStatementException) {
+      DETAILED_FAILURE_QUERY_TRACE_LOGGER.warn(INFO_NOT_ALLOWED_IN_BATCH_ERROR, t);
       return RpcUtils.getStatus(
-          TSStatusCode.QUERY_NOT_ALLOWED, INFO_NOT_ALLOWED_IN_BATCH_ERROR + getRootCause(e));
-    } else if (e instanceof IoTDBException && !(e instanceof StorageGroupNotReadyException)) {
-      DETAILED_FAILURE_QUERY_TRACE_LOGGER.warn(INFO_QUERY_PROCESS_ERROR, e);
-      return RpcUtils.getStatus(((IoTDBException) e).getErrorCode(), getRootCause(e));
-    } else if (e instanceof TsFileRuntimeException) {
-      DETAILED_FAILURE_QUERY_TRACE_LOGGER.warn(INFO_QUERY_PROCESS_ERROR, e);
-      return RpcUtils.getStatus(TSStatusCode.TSFILE_PROCESSOR_ERROR, getRootCause(e));
+          TSStatusCode.QUERY_NOT_ALLOWED, INFO_NOT_ALLOWED_IN_BATCH_ERROR + getRootCause(t));
+    } else if (t instanceof IoTDBException && !(t instanceof StorageGroupNotReadyException)) {
+      DETAILED_FAILURE_QUERY_TRACE_LOGGER.warn(INFO_QUERY_PROCESS_ERROR, t);
+      return RpcUtils.getStatus(((IoTDBException) t).getErrorCode(), getRootCause(t));
+    } else if (t instanceof TsFileRuntimeException) {
+      DETAILED_FAILURE_QUERY_TRACE_LOGGER.warn(INFO_QUERY_PROCESS_ERROR, t);
+      return RpcUtils.getStatus(TSStatusCode.TSFILE_PROCESSOR_ERROR, getRootCause(t));
     }
     return null;
   }