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()");
+ }
+}