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/02/28 14:46:20 UTC

[iotdb] branch master updated: [IOTDB-2595] add buildin UDTF ON_OFF (#5124)

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 2ab97b4  [IOTDB-2595] add buildin UDTF ON_OFF (#5124)
2ab97b4 is described below

commit 2ab97b4545e2eb314ea6f7742354630fbf08e3b7
Author: flashzxi <39...@users.noreply.github.com>
AuthorDate: Mon Feb 28 22:45:05 2022 +0800

    [IOTDB-2595] add buildin UDTF ON_OFF (#5124)
---
 docs/UserGuide/Query-Data/Select-Expression.md     | 45 +++++++++++
 docs/zh/UserGuide/Query-Data/Select-Expression.md  | 42 +++++++++++
 .../db/integration/IoTDBUDTFBuiltinFunctionIT.java | 30 ++++++++
 .../db/query/udf/builtin/BuiltinFunction.java      |  1 +
 .../iotdb/db/query/udf/builtin/UDTFOnOff.java      | 86 ++++++++++++++++++++++
 5 files changed, 204 insertions(+)

diff --git a/docs/UserGuide/Query-Data/Select-Expression.md b/docs/UserGuide/Query-Data/Select-Expression.md
index 1f9bb0c..4a01de2 100644
--- a/docs/UserGuide/Query-Data/Select-Expression.md
+++ b/docs/UserGuide/Query-Data/Select-Expression.md
@@ -335,6 +335,51 @@ Result:
 Total line number = 4
 It costs 0.078s
 ```
+
+### Condition Functions
+Condition functions are used to check whether timeseries data points satisfy some specific condition. 
+
+They return BOOLEANs.
+
+Currently, IoTDB supports the following condition functions:
+
+| Function Name |Allowed Input Series Data Types| Required Attributes                | Output Series Data Type | Series Data Type  Description                                           |
+|---------------|-------------------------------|------------------------------------|-------------------------|-------------------------------------------------------------------------|
+| ON_OFF        | INT32 / INT64 / FLOAT / DOUBLE| `threshold`: a double type variate | BOOLEAN                            | Return `true` if data point `value >= threshold` , else return `false`. |
+
+Example Data:
+```
+IoTDB> select ts from root.test;
++-----------------------------+------------+
+|                         Time|root.test.ts|
++-----------------------------+------------+
+|1970-01-01T08:00:00.001+08:00|           1|
+|1970-01-01T08:00:00.002+08:00|           2|
+|1970-01-01T08:00:00.003+08:00|           3|
+|1970-01-01T08:00:00.004+08:00|           4|
++-----------------------------+------------+
+
+```
+SQL:
+```sql
+select ts, on_off(ts, 'threshold'='2') from root.test;
+```
+
+Output:
+```
+IoTDB> select ts, on_off(ts, 'threshold'='2') from root.test;
++-----------------------------+------------+-------------------------------------+
+|                         Time|root.test.ts|on_off(root.test.ts, "threshold"="2")|
++-----------------------------+------------+-------------------------------------+
+|1970-01-01T08:00:00.001+08:00|           1|                                false|
+|1970-01-01T08:00:00.002+08:00|           2|                                 true|
+|1970-01-01T08:00:00.003+08:00|           3|                                 true|
+|1970-01-01T08:00:00.004+08:00|           4|                                 true|
++-----------------------------+------------+-------------------------------------+
+
+```
+
+
 ### User Defined Timeseries Generating Functions
 
 Please refer to [UDF (User Defined Function)](../Process-Data/UDF-User-Defined-Function.md).
diff --git a/docs/zh/UserGuide/Query-Data/Select-Expression.md b/docs/zh/UserGuide/Query-Data/Select-Expression.md
index 64972e2..8a19d4f 100644
--- a/docs/zh/UserGuide/Query-Data/Select-Expression.md
+++ b/docs/zh/UserGuide/Query-Data/Select-Expression.md
@@ -340,6 +340,48 @@ select cast(text, 'type'='BOOLEAN'), cast(text, 'type'='INT32'), cast(text, 'typ
 Total line number = 4
 It costs 0.078s
 ```
+
+### 条件函数
+条件函数针对每个数据点进行条件判断,返回布尔值
+
+目前IoTDB支持以下条件函数
+
+| 函数名    | 可接收的输入序列类型   | 必要的属性参数                | 输出序列类型     | 功能类型                                             |
+|--------|-------------------|------------------------|------------|--------------------------------------------------|
+| ON_OFF | INT32 / INT64 / FLOAT / DOUBLE| `threshold`:DOUBLE类型参数 | BOOLEAN 类型 | 大于等于`threshold` 的数据点返回true,小于`threshold`的数据点返回false |
+
+测试数据:
+```
+IoTDB> select ts from root.test;
++-----------------------------+------------+
+|                         Time|root.test.ts|
++-----------------------------+------------+
+|1970-01-01T08:00:00.001+08:00|           1|
+|1970-01-01T08:00:00.002+08:00|           2|
+|1970-01-01T08:00:00.003+08:00|           3|
+|1970-01-01T08:00:00.004+08:00|           4|
++-----------------------------+------------+
+
+```
+SQL语句:
+```sql
+select ts, on_off(ts, 'threshold'='2') from root.test;
+```
+
+输出:
+```
+IoTDB> select ts, on_off(ts, 'threshold'='2') from root.test;
++-----------------------------+------------+-------------------------------------+
+|                         Time|root.test.ts|on_off(root.test.ts, "threshold"="2")|
++-----------------------------+------------+-------------------------------------+
+|1970-01-01T08:00:00.001+08:00|           1|                                false|
+|1970-01-01T08:00:00.002+08:00|           2|                                 true|
+|1970-01-01T08:00:00.003+08:00|           3|                                 true|
+|1970-01-01T08:00:00.004+08:00|           4|                                 true|
++-----------------------------+------------+-------------------------------------+
+
+```
+
 ### 自定义时间序列生成函数
 
 请参考 [UDF](../Process-Data/UDF-User-Defined-Function.md)。
diff --git a/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBUDTFBuiltinFunctionIT.java b/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBUDTFBuiltinFunctionIT.java
index 3bdb04a..ca5014a 100644
--- a/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBUDTFBuiltinFunctionIT.java
+++ b/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBUDTFBuiltinFunctionIT.java
@@ -353,4 +353,34 @@ public class IoTDBUDTFBuiltinFunctionIT {
       fail(throwable.getMessage());
     }
   }
+
+  @Test
+  public void testOnOffFunction() {
+    Double[] thresholds = {Double.MAX_VALUE, -1.0, 0.0, 1.0, Double.MAX_VALUE};
+    try (Connection connection = EnvFactory.getEnv().getConnection();
+        Statement statement = connection.createStatement()) {
+      for (Double threshold : thresholds) {
+        ResultSet resultSet =
+            statement.executeQuery(
+                String.format(
+                    "select on_off(s1,'threshold'='%f'), on_off(s2,'threshold'='%f'), on_off(s3,'threshold'='%f'), on_off(s4,'threshold'='%f') from root.sg.d1",
+                    threshold, threshold, threshold, threshold));
+
+        int columnCount = resultSet.getMetaData().getColumnCount();
+        assertEquals(1 + 4, columnCount);
+
+        for (int i = 0; i < INSERTION_SQLS.length; ++i) {
+          resultSet.next();
+          for (int j = 0; j < 4; ++j) {
+            Boolean expected = i >= threshold;
+            Boolean actual = Boolean.parseBoolean(resultSet.getString(2 + j));
+            assertEquals(expected, actual);
+          }
+        }
+        resultSet.close();
+      }
+    } catch (SQLException throwable) {
+      fail(throwable.getMessage());
+    }
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/BuiltinFunction.java b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/BuiltinFunction.java
index 65ac26e..e4fe722 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/BuiltinFunction.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/BuiltinFunction.java
@@ -54,6 +54,7 @@ public enum BuiltinFunction {
   TOP_K("TOP_K", UDTFTopK.class),
   BOTTOM_K("BOTTOM_K", UDTFBottomK.class),
   CAST("CAST", UDTFCast.class),
+  ON_OFF("ON_OFF", UDTFOnOff.class),
   ;
 
   private final String functionName;
diff --git a/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFOnOff.java b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFOnOff.java
new file mode 100644
index 0000000..b7ab030
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFOnOff.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.query.udf.builtin;
+
+import org.apache.iotdb.db.exception.metadata.MetadataException;
+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.db.query.udf.api.exception.UDFException;
+import org.apache.iotdb.db.query.udf.api.exception.UDFInputSeriesDataTypeNotValidException;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+
+import java.io.IOException;
+
+public class UDTFOnOff extends UDTFMath {
+
+  protected double threshold;
+
+  @Override
+  public void validate(UDFParameterValidator validator) throws UDFException {
+    validator
+        .validateInputSeriesNumber(1)
+        .validateInputSeriesDataType(
+            0, TSDataType.INT32, TSDataType.INT64, TSDataType.FLOAT, TSDataType.DOUBLE)
+        .validateRequiredAttribute("threshold");
+  }
+
+  @Override
+  public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations)
+      throws MetadataException {
+    threshold = parameters.getDouble("threshold");
+    dataType = parameters.getDataType(0);
+    configurations
+        .setAccessStrategy(new RowByRowAccessStrategy())
+        .setOutputDataType(TSDataType.BOOLEAN);
+  }
+
+  @Override
+  public void transform(Row row, PointCollector collector)
+      throws UDFInputSeriesDataTypeNotValidException, IOException {
+    long time = row.getTime();
+    switch (dataType) {
+      case INT32:
+        collector.putBoolean(time, row.getInt(0) >= threshold);
+        break;
+      case INT64:
+        collector.putBoolean(time, (row.getLong(0) >= threshold));
+        break;
+      case FLOAT:
+        collector.putBoolean(time, (row.getFloat(0) >= threshold));
+        break;
+      case DOUBLE:
+        collector.putBoolean(time, (row.getDouble(0) >= threshold));
+        break;
+      default:
+        // This will not happen.
+        throw new UDFInputSeriesDataTypeNotValidException(
+            0, dataType, TSDataType.INT32, TSDataType.INT64, TSDataType.FLOAT, TSDataType.DOUBLE);
+    }
+  }
+
+  @Override
+  protected void setTransformer() {
+    throw new UnsupportedOperationException("UDTFOnOff#setTransformer()");
+  }
+}