You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ja...@apache.org on 2021/01/06 12:11:01 UTC
[iotdb] branch master updated: [IOTDB-1073] Built-in UDTFs (#2417)
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 b0083ea [IOTDB-1073] Built-in UDTFs (#2417)
b0083ea is described below
commit b0083ea934c4df25ea4136b24d4da81c1eb1f74c
Author: Steve Yurong Su <st...@outlook.com>
AuthorDate: Wed Jan 6 20:10:40 2021 +0800
[IOTDB-1073] Built-in UDTFs (#2417)
Built-in UDTFs
---
docs/UserGuide/Operation Manual/Administration.md | 2 +
.../DML Data Manipulation Language.md | 155 ++++++++++++-
.../Operation Manual/UDF User Defined Function.md | 14 ++
.../UserGuide/Operation Manual/Administration.md | 2 +
.../DML Data Manipulation Language.md | 156 ++++++++++++-
.../Operation Manual/UDF User Defined Function.md | 16 +-
.../apache/iotdb/db/qp/executor/PlanExecutor.java | 2 +-
.../api/customizer/parameter/UDFParameters.java | 6 +-
.../db/query/udf/builtin/BuiltinFunction.java | 39 +++-
.../iotdb/db/query/udf/builtin/UDTFAbs.java} | 64 +++---
.../{BuiltinFunction.java => UDTFAcos.java} | 23 +-
.../{BuiltinFunction.java => UDTFAsin.java} | 23 +-
.../{BuiltinFunction.java => UDTFAtan.java} | 23 +-
.../iotdb/db/query/udf/builtin/UDTFBottomK.java | 105 +++++++++
.../{BuiltinFunction.java => UDTFCeil.java} | 23 +-
.../db/query/udf/builtin/UDTFCommonDerivative.java | 62 +++++
.../udf/builtin/UDTFCommonValueDifference.java | 60 +++++
.../iotdb/db/query/udf/builtin/UDTFContains.java} | 118 +++++-----
.../builtin/{BuiltinFunction.java => UDTFCos.java} | 23 +-
.../{BuiltinFunction.java => UDTFDegrees.java} | 23 +-
.../db/query/udf/builtin/UDTFDerivative.java} | 45 ++--
.../builtin/{BuiltinFunction.java => UDTFExp.java} | 23 +-
.../{BuiltinFunction.java => UDTFFloor.java} | 23 +-
.../builtin/{BuiltinFunction.java => UDTFLog.java} | 23 +-
.../{BuiltinFunction.java => UDTFLog10.java} | 23 +-
.../iotdb/db/query/udf/builtin/UDTFMatches.java} | 119 +++++-----
.../iotdb/db/query/udf/builtin/UDTFMath.java} | 178 +++++++--------
.../udf/builtin/UDTFNonNegativeDerivative.java | 63 ++++++
.../builtin/UDTFNonNegativeValueDifference.java | 61 +++++
.../{BuiltinFunction.java => UDTFRadians.java} | 23 +-
.../{BuiltinFunction.java => UDTFRound.java} | 23 +-
.../iotdb/db/query/udf/builtin/UDTFSelectK.java | 156 +++++++++++++
.../{BuiltinFunction.java => UDTFSign.java} | 23 +-
.../builtin/{BuiltinFunction.java => UDTFSin.java} | 23 +-
.../{BuiltinFunction.java => UDTFSqrt.java} | 23 +-
.../builtin/{BuiltinFunction.java => UDTFTan.java} | 23 +-
.../db/query/udf/builtin/UDTFTimeDifference.java} | 40 ++--
.../iotdb/db/query/udf/builtin/UDTFTopK.java | 103 +++++++++
.../db/query/udf/builtin/UDTFValueDifference.java} | 45 ++--
.../iotdb/db/query/udf/builtin/UDTFValueTrend.java | 73 ++++++
.../query/udf/service/UDFRegistrationService.java | 20 +-
.../iotdb/db/integration/IoTDBUDFManagementIT.java | 21 +-
.../db/integration/IoTDBUDTFBuiltinFunctionIT.java | 250 +++++++++++++++++++++
.../iotdb/db/query/udf/example/Accumulator.java | 6 -
.../apache/iotdb/db/query/udf/example/Adder.java | 6 -
.../apache/iotdb/db/query/udf/example/Counter.java | 6 -
.../org/apache/iotdb/db/query/udf/example/Max.java | 6 -
.../iotdb/db/query/udf/example/Multiplier.java | 6 -
.../SlidingSizeWindowConstructorTester0.java | 6 -
.../SlidingSizeWindowConstructorTester1.java | 6 -
.../SlidingTimeWindowConstructionTester.java | 6 -
.../db/query/udf/example/TerminateTester.java | 6 -
52 files changed, 1684 insertions(+), 713 deletions(-)
diff --git a/docs/UserGuide/Operation Manual/Administration.md b/docs/UserGuide/Operation Manual/Administration.md
index e8d0bce..266d757 100644
--- a/docs/UserGuide/Operation Manual/Administration.md
+++ b/docs/UserGuide/Operation Manual/Administration.md
@@ -141,6 +141,8 @@ At the same time, changes to roles are immediately reflected on all users who ow
|LIST\_ROLE|list all roles; list the privileges of a role; list the three kinds of operation privileges of all users owning a role; path independent|
|GRANT\_ROLE\_PRIVILEGE|grant role privileges; path independent|
|REVOKE\_ROLE\_PRIVILEGE|revoke role privileges; path independent|
+|CREATE_FUNCTION|register UDFs; path independent|
+|DROP_FUNCTION|deregister UDFs; path independent|
</center>
### Username Restrictions
diff --git a/docs/UserGuide/Operation Manual/DML Data Manipulation Language.md b/docs/UserGuide/Operation Manual/DML Data Manipulation Language.md
index 35b8830..0ce9898 100644
--- a/docs/UserGuide/Operation Manual/DML Data Manipulation Language.md
+++ b/docs/UserGuide/Operation Manual/DML Data Manipulation Language.md
@@ -222,7 +222,160 @@ Total line number = 10
It costs 0.016s
```
+### Time Series Generating Functions
+
+The time series generating function takes several time series as input and outputs one time series. Unlike the aggregation function, the result set of the time series generating function has a timestamp column.
+
+All time series generating functions can accept * as input.
+
+IoTDB supports hybrid queries of time series generating function queries and raw data queries.
+
+#### Mathematical Functions
+
+Currently IoTDB supports the following mathematical functions. The behavior of these mathematical functions is consistent with the behavior of these functions in the Java Math standard library.
+
+| Function Name | Allowed Input Series Data Types | Output Series Data Type | Corresponding Implementation in the Java Standard Library |
+| ------------- | ------------------------------- | ----------------------------- | ------------------------------------------------------------ |
+| SIN | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#sin(double) |
+| COS | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#cos(double) |
+| TAN | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#tan(double) |
+| ASIN | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#asin(double) |
+| ACOS | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#acos(double) |
+| ATAN | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#atan(double) |
+| DEGREES | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#toDegrees(double) |
+| RADIANS | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#toRadians(double) |
+| ABS | INT32 / INT64 / FLOAT / DOUBLE | Same type as the input series | Math#abs(int) / Math#abs(long) /Math#abs(float) /Math#abs(double) |
+| SIGN | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#signum(double) |
+| CEIL | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#ceil(double) |
+| FLOOR | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#floor(double) |
+| ROUND | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#rint(double) |
+| EXP | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#exp(double) |
+| LN | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#log(double) |
+| LOG10 | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#log10(double) |
+| SQRT | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#sqrt(double) |
+
+Example:
+
+``` sql
+select s1, sin(s1), cos(s1), tan(s1) from root.sg1.d1 limit 5 offset 1000;
+```
+
+Result:
+
+```
++-----------------------------+-------------------+-------------------+--------------------+-------------------+
+| Time| root.sg1.d1.s1|sin(root.sg1.d1.s1)| cos(root.sg1.d1.s1)|tan(root.sg1.d1.s1)|
++-----------------------------+-------------------+-------------------+--------------------+-------------------+
+|2020-12-10T17:11:49.037+08:00|7360723084922759782| 0.8133527237573284| 0.5817708713544664| 1.3980636773094157|
+|2020-12-10T17:11:49.038+08:00|4377791063319964531|-0.8938962705202537| 0.4482738644511651| -1.994085181866842|
+|2020-12-10T17:11:49.039+08:00|7972485567734642915| 0.9627757585308978|-0.27030138509681073|-3.5618602479083545|
+|2020-12-10T17:11:49.040+08:00|2508858212791964081|-0.6073417341629443| -0.7944406950452296| 0.7644897069734913|
+|2020-12-10T17:11:49.041+08:00|2817297431185141819|-0.8419358900502509| -0.5395775727782725| 1.5603611649667768|
++-----------------------------+-------------------+-------------------+--------------------+-------------------+
+Total line number = 5
+It costs 0.008s
+```
+
+#### String Processing Functions
+
+Currently IoTDB supports the following string processing functions:
+
+| Function Name | Allowed Input Series Data Types | Required Attributes | Output Series Data Type | Description |
+| --------------- | ------------------------------- | ------------------------------------------------------------ | ----------------------- | ------------------------------------------------------ |
+| STRING_CONTAINS | TEXT | `s`: the sequence to search for | BOOLEAN | Determine whether `s` is in the string |
+| STRING_MATCHES | TEXT | `regex`: the regular expression to which the string is to be matched | BOOLEAN | Determine whether the string can be matched by `regex` |
+
+Example:
+
+``` sql
+select s1, string_contains(s1, "s"="warn"), string_matches(s1, "regex"="[^\\s]+37229") from root.sg1.d4;
+```
+
+Result:
+
+```
++-----------------------------+--------------+-------------------------------------------+------------------------------------------------------+
+| Time|root.sg1.d4.s1|string_contains(root.sg1.d4.s1, "s"="warn")|string_matches(root.sg1.d4.s1, "regex"="[^\\s]+37229")|
++-----------------------------+--------------+-------------------------------------------+------------------------------------------------------+
+|1970-01-01T08:00:00.001+08:00| warn:-8721| true| false|
+|1970-01-01T08:00:00.002+08:00| error:-37229| false| true|
+|1970-01-01T08:00:00.003+08:00| warn:1731| true| false|
++-----------------------------+--------------+-------------------------------------------+------------------------------------------------------+
+Total line number = 3
+It costs 0.007s
+```
+
+#### Selector Functions
+
+Currently IoTDB supports the following selector functions:
+
+| Function Name | Allowed Input Series Data Types | Required Attributes | Output Series Data Type | Description |
+| ------------- | ------------------------------------- | ------------------------------------------------------------ | ----------------------------- | ------------------------------------------------------------ |
+| TOP_K | INT32 / INT64 / FLOAT / DOUBLE / TEXT | `k`: the maximum number of selected data points, must be greater than 0 and less than or equal to 1000 | Same type as the input series | Returns `k` data points with the largest values in a time series. |
+| BOTTOM_K | INT32 / INT64 / FLOAT / DOUBLE / TEXT | `k`: the maximum number of selected data points, must be greater than 0 and less than or equal to 1000 | Same type as the input series | Returns `k` data points with the smallest values in a time series. |
+
+Example:
+
+``` sql
+select s1, top_k(s1, "k"="2"), bottom_k(s1, "k"="2") from root.sg1.d2 where time > 2020-12-10T20:36:15.530+08:00;
+```
+
+Result:
+
+```
++-----------------------------+--------------------+------------------------------+---------------------------------+
+| Time| root.sg1.d2.s1|top_k(root.sg1.d2.s1, "k"="2")|bottom_k(root.sg1.d2.s1, "k"="2")|
++-----------------------------+--------------------+------------------------------+---------------------------------+
+|2020-12-10T20:36:15.531+08:00| 1531604122307244742| 1531604122307244742| null|
+|2020-12-10T20:36:15.532+08:00|-7426070874923281101| null| null|
+|2020-12-10T20:36:15.533+08:00|-7162825364312197604| -7162825364312197604| null|
+|2020-12-10T20:36:15.534+08:00|-8581625725655917595| null| -8581625725655917595|
+|2020-12-10T20:36:15.535+08:00|-7667364751255535391| null| -7667364751255535391|
++-----------------------------+--------------------+------------------------------+---------------------------------+
+Total line number = 5
+It costs 0.006s
+```
+
+#### Variation Trend Calculation Functions
+
+Currently IoTDB supports the following variation trend calculation functions:
+
+| Function Name | Allowed Input Series Data Types | Output Series Data Type | Description |
+| ----------------------- | ----------------------------------------------- | ----------------------------- | ------------------------------------------------------------ |
+| TIME_DIFFERENCE | INT32 / INT64 / FLOAT / DOUBLE / BOOLEAN / TEXT | INT64 | Calculates the difference between the time stamp of a data point and the time stamp of the previous data point. There is no corresponding output for the first data point. |
+| DIFFERENCE | INT32 / INT64 / FLOAT / DOUBLE | Same type as the input series | Calculates the difference between the value of a data point and the value of the previous data point. There is no corresponding output for the first data point. |
+| NON_NEGATIVE_DIFFERENCE | INT32 / INT64 / FLOAT / DOUBLE | Same type as the input series | Calculates the absolute value of the difference between the value of a data point and the value of the previous data point. There is no corresponding output for the first data point. |
+| DERIVATIVE | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Calculates the rate of change of a data point compared to the previous data point, the result is equals to DIFFERENCE / TIME_DIFFERENCE. There is no corresponding output for the first data point. |
+| NON_NEGATIVE_DERIVATIVE | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Calculates the absolute value of the rate of change of a data point compared to the previous data point, the result is equals to NON_NEGATIVE_DIFFERENCE / TIME_DIFFERENCE. There is no corresponding output for the first data point. |
+
+Example:
+
+``` sql
+select s1, time_difference(s1), difference(s1), non_negative_difference(s1), derivative(s1), non_negative_derivative(s1) from root.sg1.d1 limit 5 offset 1000;
+```
+
+Result:
+
+```
++-----------------------------+-------------------+-------------------------------+--------------------------+---------------------------------------+--------------------------+---------------------------------------+
+| Time| root.sg1.d1.s1|time_difference(root.sg1.d1.s1)|difference(root.sg1.d1.s1)|non_negative_difference(root.sg1.d1.s1)|derivative(root.sg1.d1.s1)|non_negative_derivative(root.sg1.d1.s1)|
++-----------------------------+-------------------+-------------------------------+--------------------------+---------------------------------------+--------------------------+---------------------------------------+
+|2020-12-10T17:11:49.037+08:00|7360723084922759782| 1| -8431715764844238876| 8431715764844238876| -8.4317157648442388E18| 8.4317157648442388E18|
+|2020-12-10T17:11:49.038+08:00|4377791063319964531| 1| -2982932021602795251| 2982932021602795251| -2.982932021602795E18| 2.982932021602795E18|
+|2020-12-10T17:11:49.039+08:00|7972485567734642915| 1| 3594694504414678384| 3594694504414678384| 3.5946945044146785E18| 3.5946945044146785E18|
+|2020-12-10T17:11:49.040+08:00|2508858212791964081| 1| -5463627354942678834| 5463627354942678834| -5.463627354942679E18| 5.463627354942679E18|
+|2020-12-10T17:11:49.041+08:00|2817297431185141819| 1| 308439218393177738| 308439218393177738| 3.0843921839317773E17| 3.0843921839317773E17|
++-----------------------------+-------------------+-------------------------------+--------------------------+---------------------------------------+--------------------------+---------------------------------------+
+Total line number = 5
+It costs 0.014s
+```
+
+#### User Defined Timeseries Generating Functions
+
+Please refer to [UDF (User Defined Function)](../Operation%20Manual/UDF%20User%20Defined%20Function.md).
+
### Aggregate Query
+
This section mainly introduces the related examples of aggregate query.
#### Count Points
@@ -686,7 +839,7 @@ using PREVIOUSUNTILLAST won't fill time after 2017-11-07T23:59.
### Last point Query
In scenarios when IoT devices updates data in a fast manner, users are more interested in the most recent point of IoT devices.
-
+
The Last point query is to return the most recent data point of the given timeseries in a three column format.
The SQL statement is defined as:
diff --git a/docs/UserGuide/Operation Manual/UDF User Defined Function.md b/docs/UserGuide/Operation Manual/UDF User Defined Function.md
index e744d8b..9ed06e8 100644
--- a/docs/UserGuide/Operation Manual/UDF User Defined Function.md
+++ b/docs/UserGuide/Operation Manual/UDF User Defined Function.md
@@ -407,6 +407,8 @@ CREATE FUNCTION example AS "org.apache.iotdb.udf.ExampleUDTF"
Since UDF instances are dynamically loaded through reflection technology, you do not need to restart the server during the UDF registration process.
+Note: UDF function names are not case sensitive.
+
Note: Please ensure that the function name given to the UDF is different from all built-in function names. A UDF with the same name as a built-in function cannot be registered.
Note: We recommend that you do not use classes that have the same class name but different function logic in different JAR packages. For example, in `UDF(UDAF/UDTF): udf1, udf2`, the JAR package of udf1 is `udf1.jar` and the JAR package of udf2 is `udf2.jar`. Assume that both JAR packages contain the `org.apache.iotdb.udf.ExampleUDTF` class. If you use two UDFs in the same SQL statement at the same time, the system will randomly load either of them and may cause inconsistency in UDF exec [...]
@@ -493,6 +495,18 @@ SHOW FUNCTIONS
+## User Permission Management
+
+There are 3 types of user permissions related to UDF:
+
+* `CREATE_FUNCTION`: Only users with this permission are allowed to register UDFs
+* `DROP_FUNCTION`: Only users with this permission are allowed to deregister UDFs
+* `READ_TIMESERIES`: Only users with this permission are allowed to use UDFs for queries
+
+For more user permissions related content, please refer to [Account Management Statements](../Operation%20Manual/Administration.md).
+
+
+
## Configurable Properties
When querying by a UDF, IoTDB may prompt that there is insufficient memory. You can resolve the issue by configuring `udf_initial_byte_array_length_for_memory_control`, `udf_memory_budget_in_mb` and `udf_reader_transformer_collector_memory_proportion` in `iotdb-engine.properties` and restarting the server.
diff --git a/docs/zh/UserGuide/Operation Manual/Administration.md b/docs/zh/UserGuide/Operation Manual/Administration.md
index 9706b1a..10747a5 100644
--- a/docs/zh/UserGuide/Operation Manual/Administration.md
+++ b/docs/zh/UserGuide/Operation Manual/Administration.md
@@ -118,6 +118,8 @@ INSERT INTO root.ln.wf01.wt01(timestamp, status) values(1509465600000, true)
|LIST\_ROLE|列出所有角色,列出某角色拥有的权限,列出拥有某角色的所有用户三种操作的权限。路径无关|
|GRANT\_ROLE\_PRIVILEGE|grant role priviledges; path independent|
|REVOKE\_ROLE\_PRIVILEGE|撤销角色权限。路径无关|
+|CREATE_FUNCTION|注册UDF。路径无关|
+|DROP_FUNCTION|卸载UDF。路径无关|
</center>
### 用户名限制
diff --git a/docs/zh/UserGuide/Operation Manual/DML Data Manipulation Language.md b/docs/zh/UserGuide/Operation Manual/DML Data Manipulation Language.md
index 3a2e032..a7502d3 100644
--- a/docs/zh/UserGuide/Operation Manual/DML Data Manipulation Language.md
+++ b/docs/zh/UserGuide/Operation Manual/DML Data Manipulation Language.md
@@ -281,7 +281,158 @@ It costs 0.018s
更多语法请参照[SQL REFERENCE](../Operation%20Manual/SQL%20Reference.md)。
+### 时间序列生成函数查询
+
+时间序列生成函数可接受若干原始时间序列作为输入,产生一列时间序列输出。与聚合函数不同的是,时间序列生成函数的结果集带有时间戳列。
+
+所有的时间序列生成函数都可以接受 * 作为输入,都可以与原始查询混合进行。
+
+#### 数学函数
+
+目前IoTDB支持下列数学函数,这些数学函数的行为与这些函数在Java Math标准库中对应实现的行为一致。
+
+| 函数名 | 输入序列类型 | 输出序列类型 | Java标准库中的对应实现 |
+| ------- | ------------------------------ | ------------------------ | ------------------------------------------------------------ |
+| SIN | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#sin(double) |
+| COS | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#cos(double) |
+| TAN | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#tan(double) |
+| ASIN | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#asin(double) |
+| ACOS | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#acos(double) |
+| ATAN | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#atan(double) |
+| DEGREES | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#toDegrees(double) |
+| RADIANS | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#toRadians(double) |
+| ABS | INT32 / INT64 / FLOAT / DOUBLE | 与输入序列的实际类型一致 | Math#abs(int) / Math#abs(long) /Math#abs(float) /Math#abs(double) |
+| SIGN | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#signum(double) |
+| CEIL | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#ceil(double) |
+| FLOOR | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#floor(double) |
+| ROUND | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#rint(double) |
+| EXP | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#exp(double) |
+| LN | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#log(double) |
+| LOG10 | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#log10(double) |
+| SQRT | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | Math#sqrt(double) |
+
+例如:
+
+``` sql
+select s1, sin(s1), cos(s1), tan(s1) from root.sg1.d1 limit 5 offset 1000;
+```
+
+结果:
+
+```
++-----------------------------+-------------------+-------------------+--------------------+-------------------+
+| Time| root.sg1.d1.s1|sin(root.sg1.d1.s1)| cos(root.sg1.d1.s1)|tan(root.sg1.d1.s1)|
++-----------------------------+-------------------+-------------------+--------------------+-------------------+
+|2020-12-10T17:11:49.037+08:00|7360723084922759782| 0.8133527237573284| 0.5817708713544664| 1.3980636773094157|
+|2020-12-10T17:11:49.038+08:00|4377791063319964531|-0.8938962705202537| 0.4482738644511651| -1.994085181866842|
+|2020-12-10T17:11:49.039+08:00|7972485567734642915| 0.9627757585308978|-0.27030138509681073|-3.5618602479083545|
+|2020-12-10T17:11:49.040+08:00|2508858212791964081|-0.6073417341629443| -0.7944406950452296| 0.7644897069734913|
+|2020-12-10T17:11:49.041+08:00|2817297431185141819|-0.8419358900502509| -0.5395775727782725| 1.5603611649667768|
++-----------------------------+-------------------+-------------------+--------------------+-------------------+
+Total line number = 5
+It costs 0.008s
+```
+
+#### 字符串函数
+
+目前IoTDB支持下列字符串处理函数:
+
+| 函数名 | 输入序列类型 | 必要的属性参数 | 输出序列类型 | 功能描述 |
+| --------------- | ------------ | ----------------------------------- | ------------ | ----------------------------------------- |
+| STRING_CONTAINS | TEXT | `s`: 待搜寻的字符串 | BOOLEAN | 判断字符串中是否存在`s` |
+| STRING_MATCHES | TEXT | `regex`: Java标准库风格的正则表达式 | BOOLEAN | 判断字符串是否能够被正则表达式`regex`匹配 |
+
+例如:
+
+``` sql
+select s1, string_contains(s1, "s"="warn"), string_matches(s1, "regex"="[^\\s]+37229") from root.sg1.d4;
+```
+
+结果:
+
+```
++-----------------------------+--------------+-------------------------------------------+------------------------------------------------------+
+| Time|root.sg1.d4.s1|string_contains(root.sg1.d4.s1, "s"="warn")|string_matches(root.sg1.d4.s1, "regex"="[^\\s]+37229")|
++-----------------------------+--------------+-------------------------------------------+------------------------------------------------------+
+|1970-01-01T08:00:00.001+08:00| warn:-8721| true| false|
+|1970-01-01T08:00:00.002+08:00| error:-37229| false| true|
+|1970-01-01T08:00:00.003+08:00| warn:1731| true| false|
++-----------------------------+--------------+-------------------------------------------+------------------------------------------------------+
+Total line number = 3
+It costs 0.007s
+```
+
+#### 选择函数
+
+目前IoTDB支持如下选择函数:
+
+| 函数名 | 输入序列类型 | 必要的属性参数 | 输出序列类型 | 功能描述 |
+| -------- | ------------------------------------- | ---------------------------------------------- | ------------------------ | ------------------------------------------------------------ |
+| TOP_K | INT32 / INT64 / FLOAT / DOUBLE / TEXT | `k`: 最多选择的数据点数,必须大于0小于等于1000 | 与输入序列的实际类型一致 | 返回某时间序列中值最大的`k`个数据点。若多于`k`个数据点的值并列最大,则返回时间戳最小的数据点。 |
+| BOTTOM_K | INT32 / INT64 / FLOAT / DOUBLE / TEXT | `k`: 最多选择的数据点数,必须大于0小于等于1000 | 与输入序列的实际类型一致 | 返回某时间序列中值最小的`k`个数据点。若多于`k`个数据点的值并列最小,则返回时间戳最小的数据点。 |
+
+例如:
+
+``` sql
+select s1, top_k(s1, "k"="2"), bottom_k(s1, "k"="2") from root.sg1.d2 where time > 2020-12-10T20:36:15.530+08:00;
+```
+
+结果:
+
+```
++-----------------------------+--------------------+------------------------------+---------------------------------+
+| Time| root.sg1.d2.s1|top_k(root.sg1.d2.s1, "k"="2")|bottom_k(root.sg1.d2.s1, "k"="2")|
++-----------------------------+--------------------+------------------------------+---------------------------------+
+|2020-12-10T20:36:15.531+08:00| 1531604122307244742| 1531604122307244742| null|
+|2020-12-10T20:36:15.532+08:00|-7426070874923281101| null| null|
+|2020-12-10T20:36:15.533+08:00|-7162825364312197604| -7162825364312197604| null|
+|2020-12-10T20:36:15.534+08:00|-8581625725655917595| null| -8581625725655917595|
+|2020-12-10T20:36:15.535+08:00|-7667364751255535391| null| -7667364751255535391|
++-----------------------------+--------------------+------------------------------+---------------------------------+
+Total line number = 5
+It costs 0.006s
+```
+
+#### 趋势计算函数
+
+目前IoTDB支持如下趋势计算函数:
+
+| 函数名 | 输入序列类型 | 输出序列类型 | 功能描述 |
+| ----------------------- | ----------------------------------------------- | ------------------------ | ------------------------------------------------------------ |
+| TIME_DIFFERENCE | INT32 / INT64 / FLOAT / DOUBLE / BOOLEAN / TEXT | INT64 | 统计序列中某数据点的时间戳与前一数据点时间戳的差。范围内第一个数据点没有对应的结果输出。 |
+| DIFFERENCE | INT32 / INT64 / FLOAT / DOUBLE | 与输入序列的实际类型一致 | 统计序列中某数据点的值与前一数据点的值的差。范围内第一个数据点没有对应的结果输出。 |
+| NON_NEGATIVE_DIFFERENCE | INT32 / INT64 / FLOAT / DOUBLE | 与输入序列的实际类型一致 | 统计序列中某数据点的值与前一数据点的值的差的绝对值。范围内第一个数据点没有对应的结果输出。 |
+| DERIVATIVE | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | 统计序列中某数据点相对于前一数据点的变化率,数量上等同于 DIFFERENCE / TIME_DIFFERENCE。范围内第一个数据点没有对应的结果输出。 |
+| NON_NEGATIVE_DERIVATIVE | INT32 / INT64 / FLOAT / DOUBLE | DOUBLE | 统计序列中某数据点相对于前一数据点的变化率的绝对值,数量上等同于 NON_NEGATIVE_DIFFERENCE / TIME_DIFFERENCE。范围内第一个数据点没有对应的结果输出。 |
+
+例如:
+
+``` sql
+select s1, time_difference(s1), difference(s1), non_negative_difference(s1), derivative(s1), non_negative_derivative(s1) from root.sg1.d1 limit 5 offset 1000;
+```
+
+结果:
+
+```
++-----------------------------+-------------------+-------------------------------+--------------------------+---------------------------------------+--------------------------+---------------------------------------+
+| Time| root.sg1.d1.s1|time_difference(root.sg1.d1.s1)|difference(root.sg1.d1.s1)|non_negative_difference(root.sg1.d1.s1)|derivative(root.sg1.d1.s1)|non_negative_derivative(root.sg1.d1.s1)|
++-----------------------------+-------------------+-------------------------------+--------------------------+---------------------------------------+--------------------------+---------------------------------------+
+|2020-12-10T17:11:49.037+08:00|7360723084922759782| 1| -8431715764844238876| 8431715764844238876| -8.4317157648442388E18| 8.4317157648442388E18|
+|2020-12-10T17:11:49.038+08:00|4377791063319964531| 1| -2982932021602795251| 2982932021602795251| -2.982932021602795E18| 2.982932021602795E18|
+|2020-12-10T17:11:49.039+08:00|7972485567734642915| 1| 3594694504414678384| 3594694504414678384| 3.5946945044146785E18| 3.5946945044146785E18|
+|2020-12-10T17:11:49.040+08:00|2508858212791964081| 1| -5463627354942678834| 5463627354942678834| -5.463627354942679E18| 5.463627354942679E18|
+|2020-12-10T17:11:49.041+08:00|2817297431185141819| 1| 308439218393177738| 308439218393177738| 3.0843921839317773E17| 3.0843921839317773E17|
++-----------------------------+-------------------+-------------------------------+--------------------------+---------------------------------------+--------------------------+---------------------------------------+
+Total line number = 5
+It costs 0.014s
+```
+
+#### 自定义序列生成函数
+
+请参考 [UDF (用户定义函数)](../Operation%20Manual/UDF%20User%20Defined%20Function.md)。
+
### 聚合查询
+
本章节主要介绍聚合查询的相关示例,
主要使用的是IoTDB SELECT语句的聚合查询函数。
@@ -1279,9 +1430,9 @@ It costs 0.012s
```
“禁用对齐”指示结果集中每个时间序列都有3列。
-
+
SQL语句是:
-
+
```
select * from root.sg1 where time > 10 disable align
```
@@ -1458,3 +1609,4 @@ DELETE PARTITION root.ln 0,1,2
手动地将一个时间戳转换为对应的id,其中的`partitionInterval`可以在IoTDB的配置文件中找到(如果您使用的版本支持时间分区)。
请注意该功能目前只是实验性的,如果您不是开发者,使用时请务必谨慎。
+
diff --git a/docs/zh/UserGuide/Operation Manual/UDF User Defined Function.md b/docs/zh/UserGuide/Operation Manual/UDF User Defined Function.md
index 4ace6fe..53e67ff 100644
--- a/docs/zh/UserGuide/Operation Manual/UDF User Defined Function.md
+++ b/docs/zh/UserGuide/Operation Manual/UDF User Defined Function.md
@@ -388,7 +388,7 @@ UDTF的结束方法,您可以在此方法中进行一些资源释放等的操
1. 实现一个完整的UDF类,假定这个类的全类名为`org.apache.iotdb.udf.ExampleUDTF`
2. 将项目打成JAR包,如果您使用Maven管理项目,可以参考上述Maven项目示例的写法
3. 将JAR包放置到目录 `iotdb-server-0.12.0-SNAPSHOT/ext/udf` (也可以是`iotdb-server-0.12.0-SNAPSHOT/ext/udf`的子目录)下。
-
+
> 您可以通过修改配置文件中的`udf_root_dir`来指定UDF加载Jar的根路径。
4. 使用SQL语句注册该UDF,假定赋予该UDF的名字为`example`
@@ -406,6 +406,8 @@ CREATE FUNCTION example AS "org.apache.iotdb.udf.ExampleUDTF"
由于IoTDB的UDF是通过反射技术动态装载的,因此您在装载过程中无需启停服务器。
+注意:UDF函数名称是大小写不敏感的。
+
注意:请不要给UDF函数注册一个内置函数的名字。使用内置函数的名字给UDF注册会失败。
注意:不同的JAR包中最好不要有全类名相同但实现功能逻辑不一样的类。例如 UDF(UDAF/UDTF):`udf1`、`udf2`分别对应资源`udf1.jar`、`udf2.jar`。如果两个JAR包里都包含一个`org.apache.iotdb.udf.ExampleUDTF`类,当同一个SQL中同时使用到这两个UDF时,系统会随机加载其中一个类,导致UDF执行行为不一致。
@@ -494,6 +496,18 @@ SHOW FUNCTIONS
+## 用户权限管理
+
+用户在使用UDF时会涉及到3种权限:
+
+* `CREATE_FUNCTION`:具备该权限的用户才被允许执行UDF注册操作
+* `DROP_FUNCTION`:具备该权限的用户才被允许执行UDF卸载操作
+* `READ_TIMESERIES`:具备该权限的用户才被允许使用UDF进行查询
+
+更多用户权限相关的内容,请参考[权限管理语句](../Operation%20Manual/Administration.md)。
+
+
+
## 配置项
在SQL语句中使用自定义函数时,可能提示内存不足。这种情况下,您可以通过更改配置文件`iotdb-engine.properties`中的`udf_initial_byte_array_length_for_memory_control`,`udf_memory_budget_in_mb`和`udf_reader_transformer_collector_memory_proportion`并重启服务来解决此问题。
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java b/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
index a8decd4..418ad7a 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
@@ -769,7 +769,7 @@ public class PlanExecutor implements IPlanExecutor {
final Binary className = Binary.valueOf("");
for (String functionName : SQLConstant.getNativeFunctionNames()) {
RowRecord rowRecord = new RowRecord(0); // ignore timestamp
- rowRecord.addField(Binary.valueOf(functionName), TSDataType.TEXT);
+ rowRecord.addField(Binary.valueOf(functionName.toUpperCase()), TSDataType.TEXT);
rowRecord.addField(functionType, TSDataType.TEXT);
rowRecord.addField(className, TSDataType.TEXT);
listDataSet.putRecord(rowRecord);
diff --git a/server/src/main/java/org/apache/iotdb/db/query/udf/api/customizer/parameter/UDFParameters.java b/server/src/main/java/org/apache/iotdb/db/query/udf/api/customizer/parameter/UDFParameters.java
index da35cbf..1926095 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/udf/api/customizer/parameter/UDFParameters.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/api/customizer/parameter/UDFParameters.java
@@ -72,8 +72,10 @@ public class UDFParameters {
}
public TSDataType getDataType(int index) throws MetadataException {
- return dataTypes != null ? dataTypes.get(index)
- : SchemaUtils.getSeriesTypeByPath(paths.get(index));
+ if (dataTypes == null) {
+ dataTypes = SchemaUtils.getSeriesTypesByPaths(paths);
+ }
+ return dataTypes.get(index);
}
public TSDataType getDataType(String path) throws MetadataException {
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 c8bb083..1168f08 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
@@ -20,23 +20,56 @@
package org.apache.iotdb.db.query.udf.builtin;
/**
- * All built-in UDFs need to register function names and full class names here.
+ * All built-in UDFs need to register their function names and classes here.
*/
public enum BuiltinFunction {
+
+ SIN("SIN", UDTFSin.class),
+ COS("COS", UDTFCos.class),
+ TAN("TAN", UDTFTan.class),
+ ASIN("ASIN", UDTFAsin.class),
+ ACOS("ACOS", UDTFAcos.class),
+ ATAN("ATAN", UDTFAtan.class),
+ DEGREES("DEGREES", UDTFDegrees.class),
+ RADIANS("RADIANS", UDTFRadians.class),
+ ABS("ABS", UDTFAbs.class),
+ SIGN("SIGN", UDTFSign.class),
+ CEIL("CEIL", UDTFCeil.class),
+ FLOOR("FLOOR", UDTFFloor.class),
+ ROUND("ROUND", UDTFRound.class),
+ EXP("EXP", UDTFExp.class),
+ LN("LN", UDTFLog.class),
+ LOG10("LOG10", UDTFLog10.class),
+ SQRT("SQRT", UDTFSqrt.class),
+ STRING_CONTAINS("STRING_CONTAINS", UDTFContains.class),
+ STRING_MATCHES("STRING_MATCHES", UDTFMatches.class),
+ DIFFERENCE("DIFFERENCE", UDTFCommonValueDifference.class),
+ NON_NEGATIVE_DIFFERENCE("NON_NEGATIVE_DIFFERENCE", UDTFNonNegativeValueDifference.class),
+ TIME_DIFFERENCE("TIME_DIFFERENCE", UDTFTimeDifference.class),
+ DERIVATIVE("DERIVATIVE", UDTFCommonDerivative.class),
+ NON_NEGATIVE_DERIVATIVE("NON_NEGATIVE_DERIVATIVE", UDTFNonNegativeDerivative.class),
+ TOP_K("TOP_K", UDTFTopK.class),
+ BOTTOM_K("BOTTOM_K", UDTFBottomK.class),
;
private final String functionName;
+ private final Class<?> functionClass;
private final String className;
- BuiltinFunction(String functionName, String className) {
+ BuiltinFunction(String functionName, Class<?> functionClass) {
this.functionName = functionName;
- this.className = className;
+ this.functionClass = functionClass;
+ this.className = functionClass.getName();
}
public String getFunctionName() {
return functionName;
}
+ public Class<?> getFunctionClass() {
+ return functionClass;
+ }
+
public String getClassName() {
return className;
}
diff --git a/server/src/test/java/org/apache/iotdb/db/query/udf/example/Max.java b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFAbs.java
similarity index 51%
copy from server/src/test/java/org/apache/iotdb/db/query/udf/example/Max.java
copy to server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFAbs.java
index eea5abb..fff5147 100644
--- a/server/src/test/java/org/apache/iotdb/db/query/udf/example/Max.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFAbs.java
@@ -17,56 +17,54 @@
* under the License.
*/
-package org.apache.iotdb.db.query.udf.example;
+package org.apache.iotdb.db.query.udf.builtin;
import java.io.IOException;
-import org.apache.iotdb.db.query.udf.api.UDTF;
+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.UDFInputSeriesDataTypeNotValidException;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
-public class Max implements UDTF {
-
- private Long time;
- private int value;
+public class UDTFAbs extends UDTFMath {
@Override
- public void validate(UDFParameterValidator validator) throws Exception {
- validator
- .validateInputSeriesNumber(1)
- .validateInputSeriesDataType(0, TSDataType.INT32);
- }
-
- @Override
- public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) {
- System.out.println("Max#beforeStart");
+ public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations)
+ throws MetadataException {
+ dataType = parameters.getDataType(0);
configurations
- .setOutputDataType(TSDataType.INT32)
- .setAccessStrategy(new RowByRowAccessStrategy());
+ .setAccessStrategy(new RowByRowAccessStrategy())
+ .setOutputDataType(dataType);
}
@Override
- public void transform(Row row, PointCollector collector) {
- int candidateValue = row.getInt(0);
- if (time == null || value < candidateValue) {
- time = row.getTime();
- value = candidateValue;
+ public void transform(Row row, PointCollector collector)
+ throws UDFInputSeriesDataTypeNotValidException, IOException {
+ long time = row.getTime();
+ switch (dataType) {
+ case INT32:
+ collector.putInt(time, Math.abs(row.getInt(0)));
+ break;
+ case INT64:
+ collector.putLong(time, Math.abs(row.getLong(0)));
+ break;
+ case FLOAT:
+ collector.putFloat(time, Math.abs(row.getFloat(0)));
+ break;
+ case DOUBLE:
+ collector.putDouble(time, Math.abs(row.getDouble(0)));
+ break;
+ default:
+ // This will not happen.
+ throw new UDFInputSeriesDataTypeNotValidException(0, dataType, TSDataType.INT32,
+ TSDataType.INT64, TSDataType.FLOAT, TSDataType.DOUBLE);
}
}
- @Override
- public void terminate(PointCollector collector) throws IOException {
- if (time != null) {
- collector.putInt(time, value);
- }
- }
-
- @Override
- public void beforeDestroy() {
- System.out.println("Max#beforeDestroy");
+ protected void setTransformer() {
+ throw new UnsupportedOperationException("UDTFAbs#setTransformer()");
}
}
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/UDTFAcos.java
similarity index 65%
copy from server/src/main/java/org/apache/iotdb/db/query/udf/builtin/BuiltinFunction.java
copy to server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFAcos.java
index c8bb083..dbcd5b5 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/UDTFAcos.java
@@ -19,25 +19,10 @@
package org.apache.iotdb.db.query.udf.builtin;
-/**
- * All built-in UDFs need to register function names and full class names here.
- */
-public enum BuiltinFunction {
- ;
-
- private final String functionName;
- private final String className;
-
- BuiltinFunction(String functionName, String className) {
- this.functionName = functionName;
- this.className = className;
- }
-
- public String getFunctionName() {
- return functionName;
- }
+public class UDTFAcos extends UDTFMath {
- public String getClassName() {
- return className;
+ @Override
+ protected void setTransformer() {
+ transformer = Math::acos;
}
}
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/UDTFAsin.java
similarity index 65%
copy from server/src/main/java/org/apache/iotdb/db/query/udf/builtin/BuiltinFunction.java
copy to server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFAsin.java
index c8bb083..7e375da 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/UDTFAsin.java
@@ -19,25 +19,10 @@
package org.apache.iotdb.db.query.udf.builtin;
-/**
- * All built-in UDFs need to register function names and full class names here.
- */
-public enum BuiltinFunction {
- ;
-
- private final String functionName;
- private final String className;
-
- BuiltinFunction(String functionName, String className) {
- this.functionName = functionName;
- this.className = className;
- }
-
- public String getFunctionName() {
- return functionName;
- }
+public class UDTFAsin extends UDTFMath {
- public String getClassName() {
- return className;
+ @Override
+ protected void setTransformer() {
+ transformer = Math::asin;
}
}
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/UDTFAtan.java
similarity index 65%
copy from server/src/main/java/org/apache/iotdb/db/query/udf/builtin/BuiltinFunction.java
copy to server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFAtan.java
index c8bb083..8f03ae8 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/UDTFAtan.java
@@ -19,25 +19,10 @@
package org.apache.iotdb.db.query.udf.builtin;
-/**
- * All built-in UDFs need to register function names and full class names here.
- */
-public enum BuiltinFunction {
- ;
-
- private final String functionName;
- private final String className;
-
- BuiltinFunction(String functionName, String className) {
- this.functionName = functionName;
- this.className = className;
- }
-
- public String getFunctionName() {
- return functionName;
- }
+public class UDTFAtan extends UDTFMath {
- public String getClassName() {
- return className;
+ @Override
+ protected void setTransformer() {
+ transformer = Math::atan;
}
}
diff --git a/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFBottomK.java b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFBottomK.java
new file mode 100644
index 0000000..3d210b2
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFBottomK.java
@@ -0,0 +1,105 @@
+/*
+ * 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 java.util.Comparator;
+import java.util.PriorityQueue;
+import org.apache.commons.collections4.ComparatorUtils;
+import org.apache.iotdb.db.query.udf.api.exception.UDFInputSeriesDataTypeNotValidException;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.utils.Pair;
+
+public class UDTFBottomK extends UDTFSelectK {
+
+ protected void constructPQ() throws UDFInputSeriesDataTypeNotValidException {
+ switch (dataType) {
+ case INT32:
+ intPQ = new PriorityQueue<>(k, Comparator.comparing(o -> -o.right));
+ break;
+ case INT64:
+ longPQ = new PriorityQueue<>(k, Comparator.comparing(o -> -o.right));
+ break;
+ case FLOAT:
+ floatPQ = new PriorityQueue<>(k, Comparator.comparing(o -> -o.right));
+ break;
+ case DOUBLE:
+ doublePQ = new PriorityQueue<>(k, Comparator.comparing(o -> -o.right));
+ break;
+ case TEXT:
+ stringPQ = new PriorityQueue<>(k,
+ ComparatorUtils.reversedComparator(Comparator.comparing(o -> o.right)));
+ break;
+ default:
+ // This will not happen.
+ throw new UDFInputSeriesDataTypeNotValidException(0, dataType, TSDataType.INT32,
+ TSDataType.INT64, TSDataType.FLOAT, TSDataType.DOUBLE, TSDataType.TEXT);
+ }
+ }
+
+ @Override
+ protected void transformInt(long time, int value) {
+ if (intPQ.size() < k) {
+ intPQ.add(new Pair<>(time, value));
+ } else if (value < intPQ.peek().right) {
+ intPQ.poll();
+ intPQ.add(new Pair<>(time, value));
+ }
+ }
+
+ @Override
+ protected void transformLong(long time, long value) {
+ if (longPQ.size() < k) {
+ longPQ.add(new Pair<>(time, value));
+ } else if (value < longPQ.peek().right) {
+ longPQ.poll();
+ longPQ.add(new Pair<>(time, value));
+ }
+ }
+
+ @Override
+ protected void transformFloat(long time, float value) {
+ if (floatPQ.size() < k) {
+ floatPQ.add(new Pair<>(time, value));
+ } else if (value < floatPQ.peek().right) {
+ floatPQ.poll();
+ floatPQ.add(new Pair<>(time, value));
+ }
+ }
+
+ @Override
+ protected void transformDouble(long time, double value) {
+ if (doublePQ.size() < k) {
+ doublePQ.add(new Pair<>(time, value));
+ } else if (value < doublePQ.peek().right) {
+ doublePQ.poll();
+ doublePQ.add(new Pair<>(time, value));
+ }
+ }
+
+ @Override
+ protected void transformString(long time, String value) {
+ if (stringPQ.size() < k) {
+ stringPQ.add(new Pair<>(time, value));
+ } else if (value.compareTo(stringPQ.peek().right) < 0) {
+ stringPQ.poll();
+ stringPQ.add(new Pair<>(time, value));
+ }
+ }
+}
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/UDTFCeil.java
similarity index 65%
copy from server/src/main/java/org/apache/iotdb/db/query/udf/builtin/BuiltinFunction.java
copy to server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFCeil.java
index c8bb083..76b49b4 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/UDTFCeil.java
@@ -19,25 +19,10 @@
package org.apache.iotdb.db.query.udf.builtin;
-/**
- * All built-in UDFs need to register function names and full class names here.
- */
-public enum BuiltinFunction {
- ;
-
- private final String functionName;
- private final String className;
-
- BuiltinFunction(String functionName, String className) {
- this.functionName = functionName;
- this.className = className;
- }
-
- public String getFunctionName() {
- return functionName;
- }
+public class UDTFCeil extends UDTFMath {
- public String getClassName() {
- return className;
+ @Override
+ protected void setTransformer() {
+ transformer = Math::ceil;
}
}
diff --git a/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFCommonDerivative.java b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFCommonDerivative.java
new file mode 100644
index 0000000..b6425f4
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFCommonDerivative.java
@@ -0,0 +1,62 @@
+/*
+ * 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 java.io.IOException;
+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.exception.UDFInputSeriesDataTypeNotValidException;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+
+public class UDTFCommonDerivative extends UDTFDerivative {
+
+ protected void doTransform(Row row, PointCollector collector)
+ throws UDFInputSeriesDataTypeNotValidException, IOException {
+ long currentTime = row.getTime();
+ double timeDelta = (double) currentTime - previousTime;
+ switch (dataType) {
+ case INT32:
+ int currentInt = row.getInt(0);
+ collector.putDouble(currentTime, (currentInt - previousInt) / timeDelta);
+ previousInt = currentInt;
+ break;
+ case INT64:
+ long currentLong = row.getLong(0);
+ collector.putDouble(currentTime, (currentLong - previousLong) / timeDelta);
+ previousLong = currentLong;
+ break;
+ case FLOAT:
+ float currentFloat = row.getFloat(0);
+ collector.putDouble(currentTime, (currentFloat - previousFloat) / timeDelta);
+ previousFloat = currentFloat;
+ break;
+ case DOUBLE:
+ double currentDouble = row.getDouble(0);
+ collector.putDouble(currentTime, (currentDouble - previousDouble) / timeDelta);
+ previousDouble = currentDouble;
+ break;
+ default:
+ // This will not happen.
+ throw new UDFInputSeriesDataTypeNotValidException(0, dataType, TSDataType.INT32,
+ TSDataType.INT64, TSDataType.FLOAT, TSDataType.DOUBLE);
+ }
+ previousTime = currentTime;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFCommonValueDifference.java b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFCommonValueDifference.java
new file mode 100644
index 0000000..88f044e
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFCommonValueDifference.java
@@ -0,0 +1,60 @@
+/*
+ * 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 java.io.IOException;
+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.exception.UDFInputSeriesDataTypeNotValidException;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+
+public class UDTFCommonValueDifference extends UDTFValueDifference {
+
+ protected void doTransform(Row row, PointCollector collector)
+ throws UDFInputSeriesDataTypeNotValidException, IOException {
+ long time = row.getTime();
+ switch (dataType) {
+ case INT32:
+ int currentInt = row.getInt(0);
+ collector.putInt(time, currentInt - previousInt);
+ previousInt = currentInt;
+ break;
+ case INT64:
+ long currentLong = row.getLong(0);
+ collector.putLong(time, currentLong - previousLong);
+ previousLong = currentLong;
+ break;
+ case FLOAT:
+ float currentFloat = row.getFloat(0);
+ collector.putFloat(time, currentFloat - previousFloat);
+ previousFloat = currentFloat;
+ break;
+ case DOUBLE:
+ double currentDouble = row.getDouble(0);
+ collector.putDouble(time, currentDouble - previousDouble);
+ previousDouble = currentDouble;
+ break;
+ default:
+ // This will not happen.
+ throw new UDFInputSeriesDataTypeNotValidException(0, dataType, TSDataType.INT32,
+ TSDataType.INT64, TSDataType.FLOAT, TSDataType.DOUBLE);
+ }
+ }
+}
diff --git a/server/src/test/java/org/apache/iotdb/db/query/udf/example/Multiplier.java b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFContains.java
similarity index 69%
copy from server/src/test/java/org/apache/iotdb/db/query/udf/example/Multiplier.java
copy to server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFContains.java
index 75b9e21..09ee073 100644
--- a/server/src/test/java/org/apache/iotdb/db/query/udf/example/Multiplier.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFContains.java
@@ -1,62 +1,56 @@
-/*
- * 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.example;
-
-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;
-
-public class Multiplier implements UDTF {
-
- private long a;
- private long b;
-
- @Override
- public void validate(UDFParameterValidator validator) throws Exception {
- validator
- .validateInputSeriesNumber(1)
- .validateInputSeriesDataType(0, TSDataType.INT64);
- }
-
- @Override
- public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) {
- System.out.println("Multiplier#beforeStart");
- a = parameters.getLongOrDefault("a", 0);
- b = parameters.getLongOrDefault("b", 0);
- configurations
- .setOutputDataType(TSDataType.INT64)
- .setAccessStrategy(new RowByRowAccessStrategy());
- }
-
- @Override
- public void transform(Row row, PointCollector collector) throws Exception {
- collector.putLong(row.getTime(), row.getLong(0) * a * b);
- }
-
- @Override
- public void beforeDestroy() {
- System.out.println("Multiplier#beforeDestroy");
- }
-}
+/*
+ * 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.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.db.query.udf.api.exception.UDFException;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+
+public class UDTFContains implements UDTF {
+
+ private String s;
+
+ @Override
+ public void validate(UDFParameterValidator validator) throws UDFException {
+ validator
+ .validateInputSeriesNumber(1)
+ .validateRequiredAttribute("s")
+ .validateInputSeriesDataType(0, TSDataType.TEXT);
+ }
+
+ @Override
+ public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) {
+ s = parameters.getString("s");
+ configurations
+ .setAccessStrategy(new RowByRowAccessStrategy())
+ .setOutputDataType(TSDataType.BOOLEAN);
+ }
+
+ @Override
+ public void transform(Row row, PointCollector collector) throws Exception {
+ collector.putBoolean(row.getTime(), row.getString(0).contains(s));
+ }
+}
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/UDTFCos.java
similarity index 65%
copy from server/src/main/java/org/apache/iotdb/db/query/udf/builtin/BuiltinFunction.java
copy to server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFCos.java
index c8bb083..0bfe245 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/UDTFCos.java
@@ -19,25 +19,10 @@
package org.apache.iotdb.db.query.udf.builtin;
-/**
- * All built-in UDFs need to register function names and full class names here.
- */
-public enum BuiltinFunction {
- ;
-
- private final String functionName;
- private final String className;
-
- BuiltinFunction(String functionName, String className) {
- this.functionName = functionName;
- this.className = className;
- }
-
- public String getFunctionName() {
- return functionName;
- }
+public class UDTFCos extends UDTFMath {
- public String getClassName() {
- return className;
+ @Override
+ protected void setTransformer() {
+ transformer = Math::cos;
}
}
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/UDTFDegrees.java
similarity index 65%
copy from server/src/main/java/org/apache/iotdb/db/query/udf/builtin/BuiltinFunction.java
copy to server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFDegrees.java
index c8bb083..712278a 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/UDTFDegrees.java
@@ -19,25 +19,10 @@
package org.apache.iotdb.db.query.udf.builtin;
-/**
- * All built-in UDFs need to register function names and full class names here.
- */
-public enum BuiltinFunction {
- ;
-
- private final String functionName;
- private final String className;
-
- BuiltinFunction(String functionName, String className) {
- this.functionName = functionName;
- this.className = className;
- }
-
- public String getFunctionName() {
- return functionName;
- }
+public class UDTFDegrees extends UDTFMath {
- public String getClassName() {
- return className;
+ @Override
+ protected void setTransformer() {
+ transformer = Math::toDegrees;
}
}
diff --git a/server/src/test/java/org/apache/iotdb/db/query/udf/example/TerminateTester.java b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFDerivative.java
similarity index 62%
copy from server/src/test/java/org/apache/iotdb/db/query/udf/example/TerminateTester.java
copy to server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFDerivative.java
index d5d797f..71f888b 100644
--- a/server/src/test/java/org/apache/iotdb/db/query/udf/example/TerminateTester.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFDerivative.java
@@ -17,48 +17,41 @@
* under the License.
*/
-package org.apache.iotdb.db.query.udf.example;
+package org.apache.iotdb.db.query.udf.builtin;
-import org.apache.iotdb.db.query.udf.api.UDTF;
+import java.io.IOException;
+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.UDFParameters;
import org.apache.iotdb.db.query.udf.api.customizer.strategy.RowByRowAccessStrategy;
+import org.apache.iotdb.db.query.udf.api.exception.UDFInputSeriesDataTypeNotValidException;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
-public class TerminateTester implements UDTF {
+public abstract class UDTFDerivative extends UDTFValueTrend {
- private Long maxTime;
- private int count;
+ protected long previousTime;
@Override
- public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) {
- System.out.println("TerminateTester#beforeStart");
+ public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations)
+ throws MetadataException {
+ dataType = parameters.getDataType(0);
configurations
- .setOutputDataType(TSDataType.INT32)
- .setAccessStrategy(new RowByRowAccessStrategy());
- maxTime = null;
- count = 0;
+ .setAccessStrategy(new RowByRowAccessStrategy())
+ .setOutputDataType(TSDataType.DOUBLE);
}
@Override
- public void transform(Row row, PointCollector collector) throws Exception {
- maxTime = row.getTime();
- ++count;
-
- collector.putInt(maxTime, 1);
- }
-
- @Override
- public void terminate(PointCollector collector) throws Exception {
- if (maxTime != null) {
- collector.putInt(maxTime + 1, count);
+ public void transform(Row row, PointCollector collector)
+ throws UDFInputSeriesDataTypeNotValidException, IOException {
+ if (!hasPrevious) {
+ previousTime = row.getTime();
+ updatePreviousValue(row);
+ hasPrevious = true;
+ return;
}
- }
- @Override
- public void beforeDestroy() {
- System.out.println("TerminateTester#beforeDestroy");
+ doTransform(row, collector);
}
}
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/UDTFExp.java
similarity index 65%
copy from server/src/main/java/org/apache/iotdb/db/query/udf/builtin/BuiltinFunction.java
copy to server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFExp.java
index c8bb083..e0e16ef 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/UDTFExp.java
@@ -19,25 +19,10 @@
package org.apache.iotdb.db.query.udf.builtin;
-/**
- * All built-in UDFs need to register function names and full class names here.
- */
-public enum BuiltinFunction {
- ;
-
- private final String functionName;
- private final String className;
-
- BuiltinFunction(String functionName, String className) {
- this.functionName = functionName;
- this.className = className;
- }
-
- public String getFunctionName() {
- return functionName;
- }
+public class UDTFExp extends UDTFMath {
- public String getClassName() {
- return className;
+ @Override
+ protected void setTransformer() {
+ transformer = Math::exp;
}
}
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/UDTFFloor.java
similarity index 65%
copy from server/src/main/java/org/apache/iotdb/db/query/udf/builtin/BuiltinFunction.java
copy to server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFFloor.java
index c8bb083..92b6063 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/UDTFFloor.java
@@ -19,25 +19,10 @@
package org.apache.iotdb.db.query.udf.builtin;
-/**
- * All built-in UDFs need to register function names and full class names here.
- */
-public enum BuiltinFunction {
- ;
-
- private final String functionName;
- private final String className;
-
- BuiltinFunction(String functionName, String className) {
- this.functionName = functionName;
- this.className = className;
- }
-
- public String getFunctionName() {
- return functionName;
- }
+public class UDTFFloor extends UDTFMath {
- public String getClassName() {
- return className;
+ @Override
+ protected void setTransformer() {
+ transformer = Math::floor;
}
}
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/UDTFLog.java
similarity index 65%
copy from server/src/main/java/org/apache/iotdb/db/query/udf/builtin/BuiltinFunction.java
copy to server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFLog.java
index c8bb083..b968893 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/UDTFLog.java
@@ -19,25 +19,10 @@
package org.apache.iotdb.db.query.udf.builtin;
-/**
- * All built-in UDFs need to register function names and full class names here.
- */
-public enum BuiltinFunction {
- ;
-
- private final String functionName;
- private final String className;
-
- BuiltinFunction(String functionName, String className) {
- this.functionName = functionName;
- this.className = className;
- }
-
- public String getFunctionName() {
- return functionName;
- }
+public class UDTFLog extends UDTFMath {
- public String getClassName() {
- return className;
+ @Override
+ protected void setTransformer() {
+ transformer = Math::log;
}
}
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/UDTFLog10.java
similarity index 65%
copy from server/src/main/java/org/apache/iotdb/db/query/udf/builtin/BuiltinFunction.java
copy to server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFLog10.java
index c8bb083..80d3546 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/UDTFLog10.java
@@ -19,25 +19,10 @@
package org.apache.iotdb.db.query.udf.builtin;
-/**
- * All built-in UDFs need to register function names and full class names here.
- */
-public enum BuiltinFunction {
- ;
-
- private final String functionName;
- private final String className;
-
- BuiltinFunction(String functionName, String className) {
- this.functionName = functionName;
- this.className = className;
- }
-
- public String getFunctionName() {
- return functionName;
- }
+public class UDTFLog10 extends UDTFMath {
- public String getClassName() {
- return className;
+ @Override
+ protected void setTransformer() {
+ transformer = Math::log10;
}
}
diff --git a/server/src/test/java/org/apache/iotdb/db/query/udf/example/Multiplier.java b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFMatches.java
similarity index 69%
copy from server/src/test/java/org/apache/iotdb/db/query/udf/example/Multiplier.java
copy to server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFMatches.java
index 75b9e21..0c47408 100644
--- a/server/src/test/java/org/apache/iotdb/db/query/udf/example/Multiplier.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFMatches.java
@@ -1,62 +1,57 @@
-/*
- * 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.example;
-
-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;
-
-public class Multiplier implements UDTF {
-
- private long a;
- private long b;
-
- @Override
- public void validate(UDFParameterValidator validator) throws Exception {
- validator
- .validateInputSeriesNumber(1)
- .validateInputSeriesDataType(0, TSDataType.INT64);
- }
-
- @Override
- public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) {
- System.out.println("Multiplier#beforeStart");
- a = parameters.getLongOrDefault("a", 0);
- b = parameters.getLongOrDefault("b", 0);
- configurations
- .setOutputDataType(TSDataType.INT64)
- .setAccessStrategy(new RowByRowAccessStrategy());
- }
-
- @Override
- public void transform(Row row, PointCollector collector) throws Exception {
- collector.putLong(row.getTime(), row.getLong(0) * a * b);
- }
-
- @Override
- public void beforeDestroy() {
- System.out.println("Multiplier#beforeDestroy");
- }
-}
+/*
+ * 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 java.util.regex.Pattern;
+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.db.query.udf.api.exception.UDFException;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+
+public class UDTFMatches implements UDTF {
+
+ private Pattern pattern;
+
+ @Override
+ public void validate(UDFParameterValidator validator) throws UDFException {
+ validator
+ .validateInputSeriesNumber(1)
+ .validateRequiredAttribute("regex")
+ .validateInputSeriesDataType(0, TSDataType.TEXT);
+ }
+
+ @Override
+ public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) {
+ pattern = Pattern.compile(parameters.getString("regex"));
+ configurations
+ .setAccessStrategy(new RowByRowAccessStrategy())
+ .setOutputDataType(TSDataType.BOOLEAN);
+ }
+
+ @Override
+ public void transform(Row row, PointCollector collector) throws Exception {
+ collector.putBoolean(row.getTime(), pattern.matcher(row.getString(0)).matches());
+ }
+}
diff --git a/server/src/test/java/org/apache/iotdb/db/query/udf/example/Adder.java b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFMath.java
similarity index 53%
copy from server/src/test/java/org/apache/iotdb/db/query/udf/example/Adder.java
copy to server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFMath.java
index 4b46425..ac5b5ed 100644
--- a/server/src/test/java/org/apache/iotdb/db/query/udf/example/Adder.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFMath.java
@@ -1,89 +1,89 @@
-/*
- * 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.example;
-
-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.exception.write.UnSupportedDataTypeException;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
-
-public class Adder implements UDTF {
-
- private double addend;
-
- @Override
- public void validate(UDFParameterValidator validator) throws Exception {
- validator
- .validateInputSeriesNumber(2)
- .validateInputSeriesDataType(0, TSDataType.INT32, TSDataType.INT64, TSDataType.FLOAT,
- TSDataType.DOUBLE)
- .validateInputSeriesDataType(1, TSDataType.INT32, TSDataType.INT64, TSDataType.FLOAT,
- TSDataType.DOUBLE);
- }
-
- @Override
- public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) {
- System.out.println("Adder#beforeStart");
- addend = parameters.getFloatOrDefault("addend", 0);
- configurations
- .setOutputDataType(TSDataType.INT64)
- .setAccessStrategy(new RowByRowAccessStrategy());
- }
-
- @Override
- public void transform(Row row, PointCollector collector) throws Exception {
- if (row.isNull(0) || row.isNull(1)) {
- return;
- }
- collector.putLong(row.getTime(),
- (long) (extractDoubleValue(row, 0) + extractDoubleValue(row, 1) + addend));
- }
-
- private double extractDoubleValue(Row row, int index) {
- double value;
- switch (row.getDataType(index)) {
- case INT32:
- value = row.getInt(index);
- break;
- case INT64:
- value = (double) row.getLong(index);
- break;
- case FLOAT:
- value = row.getFloat(index);
- break;
- case DOUBLE:
- value = row.getDouble(index);
- break;
- default:
- throw new UnSupportedDataTypeException(row.getDataType(index).toString());
- }
- return value;
- }
-
- @Override
- public void beforeDestroy() {
- System.out.println("Adder#beforeDestroy");
- }
-}
+/*
+ * 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 java.io.IOException;
+import org.apache.iotdb.db.exception.metadata.MetadataException;
+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.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;
+
+public abstract class UDTFMath implements UDTF {
+
+ protected interface Transformer {
+
+ double transform(double operand);
+ }
+
+ protected Transformer transformer;
+
+ protected TSDataType dataType;
+
+ @Override
+ public void validate(UDFParameterValidator validator) throws UDFException {
+ validator
+ .validateInputSeriesNumber(1)
+ .validateInputSeriesDataType(0, TSDataType.INT32, TSDataType.INT64, TSDataType.FLOAT,
+ TSDataType.DOUBLE);
+ }
+
+ @Override
+ public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations)
+ throws MetadataException {
+ dataType = parameters.getDataType(0);
+ configurations
+ .setAccessStrategy(new RowByRowAccessStrategy())
+ .setOutputDataType(TSDataType.DOUBLE);
+ setTransformer();
+ }
+
+ protected abstract void setTransformer();
+
+ @Override
+ public void transform(Row row, PointCollector collector)
+ throws UDFInputSeriesDataTypeNotValidException, IOException {
+ long time = row.getTime();
+ switch (dataType) {
+ case INT32:
+ collector.putDouble(time, transformer.transform(row.getInt(0)));
+ break;
+ case INT64:
+ collector.putDouble(time, transformer.transform(row.getLong(0)));
+ break;
+ case FLOAT:
+ collector.putDouble(time, transformer.transform(row.getFloat(0)));
+ break;
+ case DOUBLE:
+ collector.putDouble(time, transformer.transform(row.getDouble(0)));
+ break;
+ default:
+ // This will not happen.
+ throw new UDFInputSeriesDataTypeNotValidException(0, dataType, TSDataType.INT32,
+ TSDataType.INT64, TSDataType.FLOAT, TSDataType.DOUBLE);
+ }
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFNonNegativeDerivative.java b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFNonNegativeDerivative.java
new file mode 100644
index 0000000..f78adeb
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFNonNegativeDerivative.java
@@ -0,0 +1,63 @@
+/*
+ * 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 java.io.IOException;
+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.exception.UDFInputSeriesDataTypeNotValidException;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+
+public class UDTFNonNegativeDerivative extends UDTFDerivative {
+
+ @Override
+ protected void doTransform(Row row, PointCollector collector)
+ throws UDFInputSeriesDataTypeNotValidException, IOException {
+ long currentTime = row.getTime();
+ double timeDelta = (double) currentTime - previousTime;
+ switch (dataType) {
+ case INT32:
+ int currentInt = row.getInt(0);
+ collector.putDouble(currentTime, Math.abs(currentInt - previousInt) / timeDelta);
+ previousInt = currentInt;
+ break;
+ case INT64:
+ long currentLong = row.getLong(0);
+ collector.putDouble(currentTime, Math.abs(currentLong - previousLong) / timeDelta);
+ previousLong = currentLong;
+ break;
+ case FLOAT:
+ float currentFloat = row.getFloat(0);
+ collector.putDouble(currentTime, Math.abs(currentFloat - previousFloat) / timeDelta);
+ previousFloat = currentFloat;
+ break;
+ case DOUBLE:
+ double currentDouble = row.getDouble(0);
+ collector.putDouble(currentTime, Math.abs(currentDouble - previousDouble) / timeDelta);
+ previousDouble = currentDouble;
+ break;
+ default:
+ // This will not happen.
+ throw new UDFInputSeriesDataTypeNotValidException(0, dataType, TSDataType.INT32,
+ TSDataType.INT64, TSDataType.FLOAT, TSDataType.DOUBLE);
+ }
+ previousTime = currentTime;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFNonNegativeValueDifference.java b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFNonNegativeValueDifference.java
new file mode 100644
index 0000000..8b1ec5c
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFNonNegativeValueDifference.java
@@ -0,0 +1,61 @@
+/*
+ * 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 java.io.IOException;
+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.exception.UDFInputSeriesDataTypeNotValidException;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+
+public class UDTFNonNegativeValueDifference extends UDTFValueDifference {
+
+ @Override
+ protected void doTransform(Row row, PointCollector collector)
+ throws UDFInputSeriesDataTypeNotValidException, IOException {
+ long time = row.getTime();
+ switch (dataType) {
+ case INT32:
+ int currentInt = row.getInt(0);
+ collector.putInt(time, Math.abs(currentInt - previousInt));
+ previousInt = currentInt;
+ break;
+ case INT64:
+ long currentLong = row.getLong(0);
+ collector.putLong(time, Math.abs(currentLong - previousLong));
+ previousLong = currentLong;
+ break;
+ case FLOAT:
+ float currentFloat = row.getFloat(0);
+ collector.putFloat(time, Math.abs(currentFloat - previousFloat));
+ previousFloat = currentFloat;
+ break;
+ case DOUBLE:
+ double currentDouble = row.getDouble(0);
+ collector.putDouble(time, Math.abs(currentDouble - previousDouble));
+ previousDouble = currentDouble;
+ break;
+ default:
+ // This will not happen.
+ throw new UDFInputSeriesDataTypeNotValidException(0, dataType, TSDataType.INT32,
+ TSDataType.INT64, TSDataType.FLOAT, TSDataType.DOUBLE);
+ }
+ }
+}
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/UDTFRadians.java
similarity index 65%
copy from server/src/main/java/org/apache/iotdb/db/query/udf/builtin/BuiltinFunction.java
copy to server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFRadians.java
index c8bb083..150ad0e 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/UDTFRadians.java
@@ -19,25 +19,10 @@
package org.apache.iotdb.db.query.udf.builtin;
-/**
- * All built-in UDFs need to register function names and full class names here.
- */
-public enum BuiltinFunction {
- ;
-
- private final String functionName;
- private final String className;
-
- BuiltinFunction(String functionName, String className) {
- this.functionName = functionName;
- this.className = className;
- }
-
- public String getFunctionName() {
- return functionName;
- }
+public class UDTFRadians extends UDTFMath {
- public String getClassName() {
- return className;
+ @Override
+ protected void setTransformer() {
+ transformer = Math::toRadians;
}
}
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/UDTFRound.java
similarity index 65%
copy from server/src/main/java/org/apache/iotdb/db/query/udf/builtin/BuiltinFunction.java
copy to server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFRound.java
index c8bb083..6587f2a 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/UDTFRound.java
@@ -19,25 +19,10 @@
package org.apache.iotdb.db.query.udf.builtin;
-/**
- * All built-in UDFs need to register function names and full class names here.
- */
-public enum BuiltinFunction {
- ;
-
- private final String functionName;
- private final String className;
-
- BuiltinFunction(String functionName, String className) {
- this.functionName = functionName;
- this.className = className;
- }
-
- public String getFunctionName() {
- return functionName;
- }
+public class UDTFRound extends UDTFMath {
- public String getClassName() {
- return className;
+ @Override
+ protected void setTransformer() {
+ transformer = Math::rint;
}
}
diff --git a/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFSelectK.java b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFSelectK.java
new file mode 100644
index 0000000..1024710
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFSelectK.java
@@ -0,0 +1,156 @@
+/*
+ * 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 java.io.IOException;
+import java.util.Comparator;
+import java.util.PriorityQueue;
+import java.util.stream.Collectors;
+import org.apache.iotdb.db.exception.metadata.MetadataException;
+import org.apache.iotdb.db.exception.query.QueryProcessException;
+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.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 org.apache.iotdb.tsfile.utils.Pair;
+
+public abstract class UDTFSelectK implements UDTF {
+
+ protected int k;
+ protected TSDataType dataType;
+ protected PriorityQueue<Pair<Long, Integer>> intPQ;
+ protected PriorityQueue<Pair<Long, Long>> longPQ;
+ protected PriorityQueue<Pair<Long, Float>> floatPQ;
+ protected PriorityQueue<Pair<Long, Double>> doublePQ;
+ protected PriorityQueue<Pair<Long, String>> stringPQ;
+
+ @Override
+ public void validate(UDFParameterValidator validator) throws UDFException {
+ validator
+ .validateInputSeriesNumber(1)
+ .validateInputSeriesDataType(0, TSDataType.INT32, TSDataType.INT64, TSDataType.FLOAT,
+ TSDataType.DOUBLE, TSDataType.TEXT)
+ .validateRequiredAttribute("k")
+ .validate(k -> 0 < (int) k && (int) k <= 1000,
+ "k has to be greater than 0 and less than or equal to 1000.",
+ validator.getParameters().getInt("k"));
+ }
+
+ @Override
+ public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations)
+ throws MetadataException, UDFInputSeriesDataTypeNotValidException {
+ k = parameters.getInt("k");
+ dataType = parameters.getDataType(0);
+ constructPQ();
+ configurations
+ .setAccessStrategy(new RowByRowAccessStrategy())
+ .setOutputDataType(dataType);
+ }
+
+ protected abstract void constructPQ() throws UDFInputSeriesDataTypeNotValidException;
+
+ @Override
+ public void transform(Row row, PointCollector collector)
+ throws UDFInputSeriesDataTypeNotValidException {
+ switch (dataType) {
+ case INT32:
+ transformInt(row.getTime(), row.getInt(0));
+ break;
+ case INT64:
+ transformLong(row.getTime(), row.getLong(0));
+ break;
+ case FLOAT:
+ transformFloat(row.getTime(), row.getFloat(0));
+ break;
+ case DOUBLE:
+ transformDouble(row.getTime(), row.getDouble(0));
+ break;
+ case TEXT:
+ transformString(row.getTime(), row.getString(0));
+ break;
+ default:
+ // This will not happen.
+ throw new UDFInputSeriesDataTypeNotValidException(0, dataType, TSDataType.INT32,
+ TSDataType.INT64, TSDataType.FLOAT, TSDataType.DOUBLE, TSDataType.TEXT);
+ }
+ }
+
+ protected abstract void transformInt(long time, int value);
+
+ protected abstract void transformLong(long time, long value);
+
+ protected abstract void transformFloat(long time, float value);
+
+ protected abstract void transformDouble(long time, double value);
+
+ protected abstract void transformString(long time, String value);
+
+ @Override
+ public void terminate(PointCollector collector)
+ throws UDFInputSeriesDataTypeNotValidException, IOException, QueryProcessException {
+ switch (dataType) {
+ case INT32:
+ for (Pair<Long, Integer> pair : intPQ.stream()
+ .sorted(Comparator.comparing(p -> p.left))
+ .collect(Collectors.toList())) {
+ collector.putInt(pair.left, pair.right);
+ }
+ break;
+ case INT64:
+ for (Pair<Long, Long> pair : longPQ.stream()
+ .sorted(Comparator.comparing(p -> p.left))
+ .collect(Collectors.toList())) {
+ collector.putLong(pair.left, pair.right);
+ }
+ break;
+ case FLOAT:
+ for (Pair<Long, Float> pair : floatPQ.stream()
+ .sorted(Comparator.comparing(p -> p.left))
+ .collect(Collectors.toList())) {
+ collector.putFloat(pair.left, pair.right);
+ }
+ break;
+ case DOUBLE:
+ for (Pair<Long, Double> pair : doublePQ.stream()
+ .sorted(Comparator.comparing(p -> p.left))
+ .collect(Collectors.toList())) {
+ collector.putDouble(pair.left, pair.right);
+ }
+ break;
+ case TEXT:
+ for (Pair<Long, String> pair : stringPQ.stream()
+ .sorted(Comparator.comparing(p -> p.left))
+ .collect(Collectors.toList())) {
+ collector.putString(pair.left, pair.right);
+ }
+ break;
+ default:
+ // This will not happen.
+ throw new UDFInputSeriesDataTypeNotValidException(0, dataType, TSDataType.INT32,
+ TSDataType.INT64, TSDataType.FLOAT, TSDataType.DOUBLE, TSDataType.TEXT);
+ }
+ }
+}
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/UDTFSign.java
similarity index 65%
copy from server/src/main/java/org/apache/iotdb/db/query/udf/builtin/BuiltinFunction.java
copy to server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFSign.java
index c8bb083..ea93186 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/UDTFSign.java
@@ -19,25 +19,10 @@
package org.apache.iotdb.db.query.udf.builtin;
-/**
- * All built-in UDFs need to register function names and full class names here.
- */
-public enum BuiltinFunction {
- ;
-
- private final String functionName;
- private final String className;
-
- BuiltinFunction(String functionName, String className) {
- this.functionName = functionName;
- this.className = className;
- }
-
- public String getFunctionName() {
- return functionName;
- }
+public class UDTFSign extends UDTFMath {
- public String getClassName() {
- return className;
+ @Override
+ protected void setTransformer() {
+ transformer = Math::signum;
}
}
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/UDTFSin.java
similarity index 65%
copy from server/src/main/java/org/apache/iotdb/db/query/udf/builtin/BuiltinFunction.java
copy to server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFSin.java
index c8bb083..882daac 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/UDTFSin.java
@@ -19,25 +19,10 @@
package org.apache.iotdb.db.query.udf.builtin;
-/**
- * All built-in UDFs need to register function names and full class names here.
- */
-public enum BuiltinFunction {
- ;
-
- private final String functionName;
- private final String className;
-
- BuiltinFunction(String functionName, String className) {
- this.functionName = functionName;
- this.className = className;
- }
-
- public String getFunctionName() {
- return functionName;
- }
+public class UDTFSin extends UDTFMath {
- public String getClassName() {
- return className;
+ @Override
+ protected void setTransformer() {
+ transformer = Math::sin;
}
}
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/UDTFSqrt.java
similarity index 65%
copy from server/src/main/java/org/apache/iotdb/db/query/udf/builtin/BuiltinFunction.java
copy to server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFSqrt.java
index c8bb083..c246f62 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/UDTFSqrt.java
@@ -19,25 +19,10 @@
package org.apache.iotdb.db.query.udf.builtin;
-/**
- * All built-in UDFs need to register function names and full class names here.
- */
-public enum BuiltinFunction {
- ;
-
- private final String functionName;
- private final String className;
-
- BuiltinFunction(String functionName, String className) {
- this.functionName = functionName;
- this.className = className;
- }
-
- public String getFunctionName() {
- return functionName;
- }
+public class UDTFSqrt extends UDTFMath {
- public String getClassName() {
- return className;
+ @Override
+ protected void setTransformer() {
+ transformer = Math::sqrt;
}
}
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/UDTFTan.java
similarity index 65%
copy from server/src/main/java/org/apache/iotdb/db/query/udf/builtin/BuiltinFunction.java
copy to server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFTan.java
index c8bb083..b5f5bf9 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/UDTFTan.java
@@ -19,25 +19,10 @@
package org.apache.iotdb.db.query.udf.builtin;
-/**
- * All built-in UDFs need to register function names and full class names here.
- */
-public enum BuiltinFunction {
- ;
-
- private final String functionName;
- private final String className;
-
- BuiltinFunction(String functionName, String className) {
- this.functionName = functionName;
- this.className = className;
- }
-
- public String getFunctionName() {
- return functionName;
- }
+public class UDTFTan extends UDTFMath {
- public String getClassName() {
- return className;
+ @Override
+ protected void setTransformer() {
+ transformer = Math::tan;
}
}
diff --git a/server/src/test/java/org/apache/iotdb/db/query/udf/example/TerminateTester.java b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFTimeDifference.java
similarity index 68%
copy from server/src/test/java/org/apache/iotdb/db/query/udf/example/TerminateTester.java
copy to server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFTimeDifference.java
index d5d797f..fd128f0 100644
--- a/server/src/test/java/org/apache/iotdb/db/query/udf/example/TerminateTester.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFTimeDifference.java
@@ -17,8 +17,9 @@
* under the License.
*/
-package org.apache.iotdb.db.query.udf.example;
+package org.apache.iotdb.db.query.udf.builtin;
+import java.io.IOException;
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;
@@ -27,38 +28,29 @@ 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;
-public class TerminateTester implements UDTF {
+public class UDTFTimeDifference implements UDTF {
- private Long maxTime;
- private int count;
+ private boolean hasPrevious = false;
+
+ private long previousTime = 0;
@Override
public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) {
- System.out.println("TerminateTester#beforeStart");
configurations
- .setOutputDataType(TSDataType.INT32)
- .setAccessStrategy(new RowByRowAccessStrategy());
- maxTime = null;
- count = 0;
+ .setAccessStrategy(new RowByRowAccessStrategy())
+ .setOutputDataType(TSDataType.INT64);
}
@Override
- public void transform(Row row, PointCollector collector) throws Exception {
- maxTime = row.getTime();
- ++count;
-
- collector.putInt(maxTime, 1);
- }
-
- @Override
- public void terminate(PointCollector collector) throws Exception {
- if (maxTime != null) {
- collector.putInt(maxTime + 1, count);
+ public void transform(Row row, PointCollector collector) throws IOException {
+ if (!hasPrevious) {
+ previousTime = row.getTime();
+ hasPrevious = true;
+ return;
}
- }
- @Override
- public void beforeDestroy() {
- System.out.println("TerminateTester#beforeDestroy");
+ long currentTime = row.getTime();
+ collector.putLong(currentTime, currentTime - previousTime);
+ previousTime = currentTime;
}
}
diff --git a/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFTopK.java b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFTopK.java
new file mode 100644
index 0000000..8a61d9d
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFTopK.java
@@ -0,0 +1,103 @@
+/*
+ * 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 java.util.Comparator;
+import java.util.PriorityQueue;
+import org.apache.iotdb.db.query.udf.api.exception.UDFInputSeriesDataTypeNotValidException;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.utils.Pair;
+
+public class UDTFTopK extends UDTFSelectK {
+
+ protected void constructPQ() throws UDFInputSeriesDataTypeNotValidException {
+ switch (dataType) {
+ case INT32:
+ intPQ = new PriorityQueue<>(k, Comparator.comparing(o -> o.right));
+ break;
+ case INT64:
+ longPQ = new PriorityQueue<>(k, Comparator.comparing(o -> o.right));
+ break;
+ case FLOAT:
+ floatPQ = new PriorityQueue<>(k, Comparator.comparing(o -> o.right));
+ break;
+ case DOUBLE:
+ doublePQ = new PriorityQueue<>(k, Comparator.comparing(o -> o.right));
+ break;
+ case TEXT:
+ stringPQ = new PriorityQueue<>(k, Comparator.comparing(o -> o.right));
+ break;
+ default:
+ // This will not happen.
+ throw new UDFInputSeriesDataTypeNotValidException(0, dataType, TSDataType.INT32,
+ TSDataType.INT64, TSDataType.FLOAT, TSDataType.DOUBLE, TSDataType.TEXT);
+ }
+ }
+
+ @Override
+ protected void transformInt(long time, int value) {
+ if (intPQ.size() < k) {
+ intPQ.add(new Pair<>(time, value));
+ } else if (intPQ.peek().right < value) {
+ intPQ.poll();
+ intPQ.add(new Pair<>(time, value));
+ }
+ }
+
+ @Override
+ protected void transformLong(long time, long value) {
+ if (longPQ.size() < k) {
+ longPQ.add(new Pair<>(time, value));
+ } else if (longPQ.peek().right < value) {
+ longPQ.poll();
+ longPQ.add(new Pair<>(time, value));
+ }
+ }
+
+ @Override
+ protected void transformFloat(long time, float value) {
+ if (floatPQ.size() < k) {
+ floatPQ.add(new Pair<>(time, value));
+ } else if (floatPQ.peek().right < value) {
+ floatPQ.poll();
+ floatPQ.add(new Pair<>(time, value));
+ }
+ }
+
+ @Override
+ protected void transformDouble(long time, double value) {
+ if (doublePQ.size() < k) {
+ doublePQ.add(new Pair<>(time, value));
+ } else if (doublePQ.peek().right < value) {
+ doublePQ.poll();
+ doublePQ.add(new Pair<>(time, value));
+ }
+ }
+
+ @Override
+ protected void transformString(long time, String value) {
+ if (stringPQ.size() < k) {
+ stringPQ.add(new Pair<>(time, value));
+ } else if (stringPQ.peek().right.compareTo(value) < 0) {
+ stringPQ.poll();
+ stringPQ.add(new Pair<>(time, value));
+ }
+ }
+}
diff --git a/server/src/test/java/org/apache/iotdb/db/query/udf/example/TerminateTester.java b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFValueDifference.java
similarity index 59%
copy from server/src/test/java/org/apache/iotdb/db/query/udf/example/TerminateTester.java
copy to server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFValueDifference.java
index d5d797f..cc3cb5e 100644
--- a/server/src/test/java/org/apache/iotdb/db/query/udf/example/TerminateTester.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFValueDifference.java
@@ -17,48 +17,37 @@
* under the License.
*/
-package org.apache.iotdb.db.query.udf.example;
+package org.apache.iotdb.db.query.udf.builtin;
-import org.apache.iotdb.db.query.udf.api.UDTF;
+import java.io.IOException;
+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.UDFParameters;
import org.apache.iotdb.db.query.udf.api.customizer.strategy.RowByRowAccessStrategy;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.db.query.udf.api.exception.UDFInputSeriesDataTypeNotValidException;
-public class TerminateTester implements UDTF {
-
- private Long maxTime;
- private int count;
+public abstract class UDTFValueDifference extends UDTFValueTrend {
@Override
- public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) {
- System.out.println("TerminateTester#beforeStart");
+ public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations)
+ throws MetadataException {
+ dataType = parameters.getDataType(0);
configurations
- .setOutputDataType(TSDataType.INT32)
- .setAccessStrategy(new RowByRowAccessStrategy());
- maxTime = null;
- count = 0;
+ .setAccessStrategy(new RowByRowAccessStrategy())
+ .setOutputDataType(dataType);
}
@Override
- public void transform(Row row, PointCollector collector) throws Exception {
- maxTime = row.getTime();
- ++count;
-
- collector.putInt(maxTime, 1);
- }
-
- @Override
- public void terminate(PointCollector collector) throws Exception {
- if (maxTime != null) {
- collector.putInt(maxTime + 1, count);
+ public void transform(Row row, PointCollector collector)
+ throws UDFInputSeriesDataTypeNotValidException, IOException {
+ if (!hasPrevious) {
+ updatePreviousValue(row);
+ hasPrevious = true;
+ return;
}
- }
- @Override
- public void beforeDestroy() {
- System.out.println("TerminateTester#beforeDestroy");
+ doTransform(row, collector);
}
}
diff --git a/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFValueTrend.java b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFValueTrend.java
new file mode 100644
index 0000000..f2af796
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/builtin/UDTFValueTrend.java
@@ -0,0 +1,73 @@
+/*
+ * 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 java.io.IOException;
+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.parameter.UDFParameterValidator;
+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;
+
+public abstract class UDTFValueTrend implements UDTF {
+
+ protected boolean hasPrevious = false;
+
+ protected int previousInt = 0;
+ protected long previousLong = 0;
+ protected float previousFloat = 0;
+ protected double previousDouble = 0;
+
+ protected TSDataType dataType;
+
+ @Override
+ public void validate(UDFParameterValidator validator) throws UDFException {
+ validator
+ .validateInputSeriesNumber(1)
+ .validateInputSeriesDataType(0, TSDataType.INT32, TSDataType.INT64, TSDataType.FLOAT,
+ TSDataType.DOUBLE);
+ }
+
+ protected void updatePreviousValue(Row row) throws UDFInputSeriesDataTypeNotValidException {
+ switch (dataType) {
+ case INT32:
+ previousInt = row.getInt(0);
+ break;
+ case INT64:
+ previousLong = row.getLong(0);
+ break;
+ case FLOAT:
+ previousFloat = row.getFloat(0);
+ break;
+ case DOUBLE:
+ previousDouble = row.getDouble(0);
+ break;
+ default:
+ // This will not happen.
+ throw new UDFInputSeriesDataTypeNotValidException(0, dataType, TSDataType.INT32,
+ TSDataType.INT64, TSDataType.FLOAT, TSDataType.DOUBLE);
+ }
+ }
+
+ protected abstract void doTransform(Row row, PointCollector collector)
+ throws UDFInputSeriesDataTypeNotValidException, IOException;
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/query/udf/service/UDFRegistrationService.java b/server/src/main/java/org/apache/iotdb/db/query/udf/service/UDFRegistrationService.java
index 62e82ec..5e603a1 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/udf/service/UDFRegistrationService.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/udf/service/UDFRegistrationService.java
@@ -78,6 +78,7 @@ public class UDFRegistrationService implements IService {
public void register(String functionName, String className, boolean isTemporary,
boolean writeToTemporaryLogFile) throws UDFRegistrationException {
+ functionName = functionName.toUpperCase();
validateFunctionName(functionName, className);
checkIfRegistered(functionName, className, isTemporary);
doRegister(functionName, className, isTemporary);
@@ -181,6 +182,7 @@ public class UDFRegistrationService implements IService {
}
public void deregister(String functionName) throws UDFRegistrationException {
+ functionName = functionName.toUpperCase();
UDFRegistrationInformation information = registrationInformation.remove(functionName);
if (information == null) {
String errorMessage = String.format("UDF %s does not exist.", functionName);
@@ -228,11 +230,12 @@ public class UDFRegistrationService implements IService {
}
public UDF reflect(UDFContext context) throws QueryProcessException {
- UDFRegistrationInformation information = registrationInformation.get(context.getName());
+ String functionName = context.getName().toUpperCase();
+ UDFRegistrationInformation information = registrationInformation.get(functionName);
if (information == null) {
String errorMessage = String
.format("Failed to reflect UDF instance, because UDF %s has not been registered.",
- context.getName());
+ functionName);
logger.warn(errorMessage);
throw new QueryProcessException(errorMessage);
}
@@ -246,7 +249,7 @@ public class UDFRegistrationService implements IService {
return (UDF) information.getFunctionClass().getDeclaredConstructor().newInstance();
} catch (InstantiationException | InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {
String errorMessage = String.format("Failed to reflect UDF %s(%s) instance, because %s",
- context.getName(), information.getClassName(), e.toString());
+ functionName, information.getClassName(), e.toString());
logger.warn(errorMessage);
throw new QueryProcessException(errorMessage);
}
@@ -268,14 +271,12 @@ public class UDFRegistrationService implements IService {
}
}
- private void registerBuiltinFunctions() throws ClassNotFoundException {
- ClassLoader classLoader = getClass().getClassLoader();
+ private void registerBuiltinFunctions() {
for (BuiltinFunction builtinFunction : BuiltinFunction.values()) {
String functionName = builtinFunction.getFunctionName();
- String className = builtinFunction.getClassName();
- Class<?> functionClass = Class.forName(className, true, classLoader);
registrationInformation.put(functionName,
- new UDFRegistrationInformation(functionName, className, false, true, functionClass));
+ new UDFRegistrationInformation(functionName, builtinFunction.getClassName(), false, true,
+ builtinFunction.getFunctionClass()));
}
}
@@ -370,13 +371,14 @@ public class UDFRegistrationService implements IService {
throws ClassNotFoundException {
ClassLoader classLoader = getClass().getClassLoader();
Class<?> functionClass = Class.forName(className, true, classLoader);
+ functionName = functionName.toUpperCase();
registrationInformation.put(functionName,
new UDFRegistrationInformation(functionName, className, false, true, functionClass));
}
@TestOnly
public void deregisterBuiltinFunction(String functionName) {
- registrationInformation.remove(functionName);
+ registrationInformation.remove(functionName.toUpperCase());
}
@Override
diff --git a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBUDFManagementIT.java b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBUDFManagementIT.java
index 14923bb..bec06ed 100644
--- a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBUDFManagementIT.java
+++ b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBUDFManagementIT.java
@@ -33,6 +33,7 @@ import java.sql.SQLException;
import java.sql.Statement;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.qp.constant.SQLConstant;
+import org.apache.iotdb.db.query.udf.builtin.BuiltinFunction;
import org.apache.iotdb.db.query.udf.service.UDFRegistrationService;
import org.apache.iotdb.db.service.IoTDB;
import org.apache.iotdb.db.utils.EnvironmentUtils;
@@ -48,6 +49,7 @@ import org.junit.Test;
public class IoTDBUDFManagementIT {
private static final int NATIVE_FUNCTIONS_COUNT = SQLConstant.getNativeFunctionNames().size();
+ private static final int BUILTIN_FUNCTIONS_COUNT = BuiltinFunction.values().length;
@Before
public void setUp() throws Exception {
@@ -87,12 +89,9 @@ public class IoTDBUDFManagementIT {
if (result.contains(FUNCTION_TYPE_NATIVE)) {
continue;
}
-
- Assert.assertEquals(String.format("udf,%s,org.apache.iotdb.db.query.udf.example.Adder,",
- FUNCTION_TYPE_EXTERNAL_UDTF), result);
++count;
}
- Assert.assertEquals(1, count);
+ Assert.assertEquals(1 + BUILTIN_FUNCTIONS_COUNT, count);
resultSet = statement.executeQuery("show temporary functions");
count = 0;
@@ -122,7 +121,7 @@ public class IoTDBUDFManagementIT {
while (resultSet.next()) {
++count;
}
- Assert.assertEquals(1 + NATIVE_FUNCTIONS_COUNT, count);
+ Assert.assertEquals(1 + NATIVE_FUNCTIONS_COUNT + BUILTIN_FUNCTIONS_COUNT, count);
assertEquals(3, resultSet.getMetaData().getColumnCount());
resultSet = statement.executeQuery("show temporary functions");
@@ -143,7 +142,7 @@ public class IoTDBUDFManagementIT {
while (resultSet.next()) {
++count;
}
- Assert.assertEquals(1 + NATIVE_FUNCTIONS_COUNT, count);
+ Assert.assertEquals(1 + NATIVE_FUNCTIONS_COUNT + BUILTIN_FUNCTIONS_COUNT, count);
assertEquals(3, resultSet.getMetaData().getColumnCount());
resultSet = statement.executeQuery("show temporary functions");
@@ -163,7 +162,7 @@ public class IoTDBUDFManagementIT {
while (resultSet.next()) {
++count;
}
- Assert.assertEquals(1 + NATIVE_FUNCTIONS_COUNT, count);
+ Assert.assertEquals(1 + NATIVE_FUNCTIONS_COUNT + BUILTIN_FUNCTIONS_COUNT, count);
assertEquals(3, resultSet.getMetaData().getColumnCount());
resultSet = statement.executeQuery("show temporary functions");
@@ -363,7 +362,7 @@ public class IoTDBUDFManagementIT {
} catch (SQLException throwable) {
throwable.printStackTrace();
assertTrue(
- throwable.getMessage().contains("Built-in function adder can not be deregistered"));
+ throwable.getMessage().contains("Built-in function ADDER can not be deregistered"));
} finally {
UDFRegistrationService.getInstance().deregisterBuiltinFunction("adder");
}
@@ -408,16 +407,14 @@ public class IoTDBUDFManagementIT {
}
if (result.contains(FUNCTION_TYPE_EXTERNAL_UDTF)) {
- Assert.assertEquals(String.format("udf,%s,org.apache.iotdb.db.query.udf.example.Adder,",
+ Assert.assertEquals(String.format("UDF,%s,org.apache.iotdb.db.query.udf.example.Adder,",
FUNCTION_TYPE_EXTERNAL_UDTF), result);
++count;
} else if (result.contains(FUNCTION_TYPE_BUILTIN_UDTF)) {
- Assert.assertEquals(String.format("adder,%s,org.apache.iotdb.db.query.udf.example.Adder,",
- FUNCTION_TYPE_BUILTIN_UDTF), result);
++count;
}
}
- Assert.assertEquals(2, count);
+ Assert.assertEquals(2 + BUILTIN_FUNCTIONS_COUNT, count);
resultSet = statement.executeQuery("show temporary functions");
count = 0;
diff --git a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBUDTFBuiltinFunctionIT.java b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBUDTFBuiltinFunctionIT.java
new file mode 100644
index 0000000..d1160c3
--- /dev/null
+++ b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBUDTFBuiltinFunctionIT.java
@@ -0,0 +1,250 @@
+/*
+ * 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.integration;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import org.apache.iotdb.db.exception.metadata.MetadataException;
+import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.service.IoTDB;
+import org.apache.iotdb.db.utils.EnvironmentUtils;
+import org.apache.iotdb.jdbc.Config;
+import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class IoTDBUDTFBuiltinFunctionIT {
+
+ private static final double E = 0.0001;
+
+ private final static String[] INSERTION_SQLS = {
+ "insert into root.sg.d1(time, s1, s2, s3, s4, s5, s6) values (0, 0, 0, 0, 0, true, '0')",
+ "insert into root.sg.d1(time, s1, s2, s3, s4, s5, s6) values (2, 1, 1, 1, 1, false, '1')",
+ "insert into root.sg.d1(time, s1, s2, s3, s4, s5, s6) values (4, 2, 2, 2, 2, false, '2')",
+ "insert into root.sg.d1(time, s1, s2, s3, s4, s5, s6) values (6, 3, 3, 3, 3, true, '3')",
+ "insert into root.sg.d1(time, s1, s2, s3, s4, s5, s6) values (8, 4, 4, 4, 4, true, '4')",
+ };
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ EnvironmentUtils.envSetUp();
+ Class.forName(Config.JDBC_DRIVER_NAME);
+ createTimeSeries();
+ generateData();
+ }
+
+ private static void createTimeSeries() throws MetadataException {
+ IoTDB.metaManager.setStorageGroup(new PartialPath("root.sg"));
+ IoTDB.metaManager
+ .createTimeseries(new PartialPath("root.sg.d1.s1"), TSDataType.INT32, TSEncoding.PLAIN,
+ CompressionType.UNCOMPRESSED, null);
+ IoTDB.metaManager
+ .createTimeseries(new PartialPath("root.sg.d1.s2"), TSDataType.INT64, TSEncoding.PLAIN,
+ CompressionType.UNCOMPRESSED, null);
+ IoTDB.metaManager
+ .createTimeseries(new PartialPath("root.sg.d1.s3"), TSDataType.FLOAT, TSEncoding.PLAIN,
+ CompressionType.UNCOMPRESSED, null);
+ IoTDB.metaManager
+ .createTimeseries(new PartialPath("root.sg.d1.s4"), TSDataType.DOUBLE, TSEncoding.PLAIN,
+ CompressionType.UNCOMPRESSED, null);
+ IoTDB.metaManager
+ .createTimeseries(new PartialPath("root.sg.d1.s5"), TSDataType.BOOLEAN, TSEncoding.PLAIN,
+ CompressionType.UNCOMPRESSED, null);
+ IoTDB.metaManager
+ .createTimeseries(new PartialPath("root.sg.d1.s6"), TSDataType.TEXT, TSEncoding.PLAIN,
+ CompressionType.UNCOMPRESSED, null);
+ }
+
+ private static void generateData() {
+ try (Connection connection = DriverManager.getConnection(
+ Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root");
+ Statement statement = connection.createStatement()) {
+ for (String dataGenerationSql : INSERTION_SQLS) {
+ statement.execute(dataGenerationSql);
+ }
+ } catch (SQLException throwable) {
+ fail(throwable.getMessage());
+ }
+ }
+
+ @AfterClass
+ public static void tearDown() throws Exception {
+ EnvironmentUtils.cleanEnv();
+ }
+
+ @Test
+ public void testMathFunctions() {
+ testMathFunction("sin", Math::sin);
+ testMathFunction("cos", Math::cos);
+ testMathFunction("tan", Math::tan);
+ testMathFunction("asin", Math::asin);
+ testMathFunction("acos", Math::acos);
+ testMathFunction("atan", Math::atan);
+ testMathFunction("degrees", Math::toDegrees);
+ testMathFunction("radians", Math::toRadians);
+ testMathFunction("abs", Math::abs);
+ testMathFunction("sign", Math::signum);
+ testMathFunction("ceil", Math::ceil);
+ testMathFunction("floor", Math::floor);
+ testMathFunction("round", Math::rint);
+ testMathFunction("exp", Math::exp);
+ testMathFunction("ln", Math::log);
+ testMathFunction("log10", Math::log10);
+ testMathFunction("sqrt", Math::sqrt);
+ }
+
+ private interface MathFunctionProxy {
+
+ double invoke(double x);
+ }
+
+ private void testMathFunction(String functionName, MathFunctionProxy functionProxy) {
+ try (Statement statement = DriverManager.getConnection(
+ Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root").createStatement()) {
+ ResultSet resultSet = statement.executeQuery(String
+ .format("select %s(s1), %s(s2), %s(s3), %s(s4) from root.sg.d1", functionName,
+ functionName, functionName, functionName));
+
+ 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) {
+ double expected = functionProxy.invoke(i);
+ double actual = Double.parseDouble(resultSet.getString(2 + j));
+ assertEquals(expected, actual, E);
+ }
+ }
+ } catch (SQLException throwable) {
+ fail(throwable.getMessage());
+ }
+ }
+
+ @Test
+ public void testSelectorFunctions() {
+ final String TOP_K = "TOP_K";
+ final String BOTTOM_K = "BOTTOM_K";
+ final String K = "'k'='2'";
+
+ try (Statement statement = DriverManager.getConnection(
+ Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root").createStatement()) {
+ ResultSet resultSet = statement.executeQuery(String.format(
+ "select %s(s1, %s), %s(s2, %s), %s(s3, %s), %s(s4, %s), %s(s6, %s) from root.sg.d1",
+ TOP_K, K, TOP_K, K, TOP_K, K, TOP_K, K, TOP_K, K));
+
+ int columnCount = resultSet.getMetaData().getColumnCount();
+ assertEquals(1 + 5, columnCount);
+
+ for (int i = INSERTION_SQLS.length - 2; i < INSERTION_SQLS.length; ++i) {
+ resultSet.next();
+ for (int j = 0; j < 5; ++j) {
+ assertEquals(i, Double.parseDouble(resultSet.getString(2 + j)), E);
+ }
+ }
+ } catch (SQLException throwable) {
+ fail(throwable.getMessage());
+ }
+
+ try (Statement statement = DriverManager.getConnection(
+ Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root").createStatement()) {
+ ResultSet resultSet = statement.executeQuery(String.format(
+ "select %s(s1, %s), %s(s2, %s), %s(s3, %s), %s(s4, %s), %s(s6, %s) from root.sg.d1",
+ BOTTOM_K, K, BOTTOM_K, K, BOTTOM_K, K, BOTTOM_K, K, BOTTOM_K, K));
+
+ int columnCount = resultSet.getMetaData().getColumnCount();
+ assertEquals(1 + 5, columnCount);
+
+ for (int i = 0; i < 2; ++i) {
+ resultSet.next();
+ for (int j = 0; j < 5; ++j) {
+ assertEquals(i, Double.parseDouble(resultSet.getString(2 + j)), E);
+ }
+ }
+ } catch (SQLException throwable) {
+ fail(throwable.getMessage());
+ }
+ }
+
+ @Test
+ public void testStringProcessingFunctions() {
+ try (Statement statement = DriverManager.getConnection(
+ Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root").createStatement()) {
+ ResultSet resultSet = statement.executeQuery(
+ "select STRING_CONTAINS(s6, 's'='0'), STRING_MATCHES(s6, 'regex'='\\d') from root.sg.d1");
+
+ int columnCount = resultSet.getMetaData().getColumnCount();
+ assertEquals(1 + 2, columnCount);
+
+ for (int i = 0; i < INSERTION_SQLS.length; ++i) {
+ resultSet.next();
+ if (i == 0) {
+ assertTrue(Boolean.parseBoolean(resultSet.getString(2)));
+ } else {
+ assertFalse(Boolean.parseBoolean(resultSet.getString(2)));
+ }
+ assertTrue(Boolean.parseBoolean(resultSet.getString(2 + 1)));
+ }
+ } catch (SQLException throwable) {
+ fail(throwable.getMessage());
+ }
+ }
+
+ @Test
+ public void testVariationTrendCalculationFunctions() {
+ testVariationTrendCalculationFunction("TIME_DIFFERENCE", 2);
+ testVariationTrendCalculationFunction("DIFFERENCE", 1);
+ testVariationTrendCalculationFunction("NON_NEGATIVE_DIFFERENCE", 1);
+ testVariationTrendCalculationFunction("DERIVATIVE", 0.5);
+ testVariationTrendCalculationFunction("NON_NEGATIVE_DERIVATIVE", 0.5);
+ }
+
+ public void testVariationTrendCalculationFunction(String functionName, double expected) {
+ try (Statement statement = DriverManager.getConnection(
+ Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root").createStatement()) {
+ ResultSet resultSet = statement.executeQuery(String
+ .format("select %s(s1), %s(s2), %s(s3), %s(s4) from root.sg.d1", functionName,
+ functionName, functionName, functionName));
+
+ int columnCount = resultSet.getMetaData().getColumnCount();
+ assertEquals(1 + 4, columnCount);
+
+ for (int i = 0; i < INSERTION_SQLS.length - 1; ++i) {
+ resultSet.next();
+ for (int j = 0; j < 4; ++j) {
+ assertEquals(expected, Double.parseDouble(resultSet.getString(2 + j)), E);
+ }
+ }
+ } catch (SQLException throwable) {
+ fail(throwable.getMessage());
+ }
+ }
+}
diff --git a/server/src/test/java/org/apache/iotdb/db/query/udf/example/Accumulator.java b/server/src/test/java/org/apache/iotdb/db/query/udf/example/Accumulator.java
index b892e15..e269035 100644
--- a/server/src/test/java/org/apache/iotdb/db/query/udf/example/Accumulator.java
+++ b/server/src/test/java/org/apache/iotdb/db/query/udf/example/Accumulator.java
@@ -46,7 +46,6 @@ public class Accumulator implements UDTF {
@Override
public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) {
- System.out.println("Accumulator#beforeStart");
configurations.setOutputDataType(TSDataType.INT32);
switch (parameters.getStringOrDefault(ACCESS_STRATEGY_KEY, ACCESS_STRATEGY_ROW_BY_ROW)) {
case ACCESS_STRATEGY_SLIDING_SIZE:
@@ -82,9 +81,4 @@ public class Accumulator implements UDTF {
collector.putInt(rowWindow.getRow(0).getTime(), accumulator);
}
}
-
- @Override
- public void beforeDestroy() {
- System.out.println("Accumulator#beforeDestroy");
- }
}
diff --git a/server/src/test/java/org/apache/iotdb/db/query/udf/example/Adder.java b/server/src/test/java/org/apache/iotdb/db/query/udf/example/Adder.java
index 4b46425..3d94fcc 100644
--- a/server/src/test/java/org/apache/iotdb/db/query/udf/example/Adder.java
+++ b/server/src/test/java/org/apache/iotdb/db/query/udf/example/Adder.java
@@ -45,7 +45,6 @@ public class Adder implements UDTF {
@Override
public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) {
- System.out.println("Adder#beforeStart");
addend = parameters.getFloatOrDefault("addend", 0);
configurations
.setOutputDataType(TSDataType.INT64)
@@ -81,9 +80,4 @@ public class Adder implements UDTF {
}
return value;
}
-
- @Override
- public void beforeDestroy() {
- System.out.println("Adder#beforeDestroy");
- }
}
diff --git a/server/src/test/java/org/apache/iotdb/db/query/udf/example/Counter.java b/server/src/test/java/org/apache/iotdb/db/query/udf/example/Counter.java
index 553d801..cb9e38b 100644
--- a/server/src/test/java/org/apache/iotdb/db/query/udf/example/Counter.java
+++ b/server/src/test/java/org/apache/iotdb/db/query/udf/example/Counter.java
@@ -37,7 +37,6 @@ public class Counter implements UDTF {
@Override
public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) {
- System.out.println("Counter#beforeStart");
configurations.setOutputDataType(TSDataType.INT32);
switch (parameters.getStringOrDefault(ACCESS_STRATEGY_KEY, ACCESS_STRATEGY_ROW_BY_ROW)) {
case ACCESS_STRATEGY_SLIDING_SIZE:
@@ -68,9 +67,4 @@ public class Counter implements UDTF {
collector.putInt(rowWindow.getRow(0).getTime(), rowWindow.windowSize());
}
}
-
- @Override
- public void beforeDestroy() {
- System.out.println("Counter#beforeDestroy");
- }
}
diff --git a/server/src/test/java/org/apache/iotdb/db/query/udf/example/Max.java b/server/src/test/java/org/apache/iotdb/db/query/udf/example/Max.java
index eea5abb..9c53e3e 100644
--- a/server/src/test/java/org/apache/iotdb/db/query/udf/example/Max.java
+++ b/server/src/test/java/org/apache/iotdb/db/query/udf/example/Max.java
@@ -43,7 +43,6 @@ public class Max implements UDTF {
@Override
public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) {
- System.out.println("Max#beforeStart");
configurations
.setOutputDataType(TSDataType.INT32)
.setAccessStrategy(new RowByRowAccessStrategy());
@@ -64,9 +63,4 @@ public class Max implements UDTF {
collector.putInt(time, value);
}
}
-
- @Override
- public void beforeDestroy() {
- System.out.println("Max#beforeDestroy");
- }
}
diff --git a/server/src/test/java/org/apache/iotdb/db/query/udf/example/Multiplier.java b/server/src/test/java/org/apache/iotdb/db/query/udf/example/Multiplier.java
index 75b9e21..3b44b83 100644
--- a/server/src/test/java/org/apache/iotdb/db/query/udf/example/Multiplier.java
+++ b/server/src/test/java/org/apache/iotdb/db/query/udf/example/Multiplier.java
@@ -42,7 +42,6 @@ public class Multiplier implements UDTF {
@Override
public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) {
- System.out.println("Multiplier#beforeStart");
a = parameters.getLongOrDefault("a", 0);
b = parameters.getLongOrDefault("b", 0);
configurations
@@ -54,9 +53,4 @@ public class Multiplier implements UDTF {
public void transform(Row row, PointCollector collector) throws Exception {
collector.putLong(row.getTime(), row.getLong(0) * a * b);
}
-
- @Override
- public void beforeDestroy() {
- System.out.println("Multiplier#beforeDestroy");
- }
}
diff --git a/server/src/test/java/org/apache/iotdb/db/query/udf/example/SlidingSizeWindowConstructorTester0.java b/server/src/test/java/org/apache/iotdb/db/query/udf/example/SlidingSizeWindowConstructorTester0.java
index 7cfcae1..97fd26c 100644
--- a/server/src/test/java/org/apache/iotdb/db/query/udf/example/SlidingSizeWindowConstructorTester0.java
+++ b/server/src/test/java/org/apache/iotdb/db/query/udf/example/SlidingSizeWindowConstructorTester0.java
@@ -31,7 +31,6 @@ public class SlidingSizeWindowConstructorTester0 implements UDTF {
@Override
public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) {
- System.out.println("SlidingSizeWindowConstructorTester0#beforeStart");
int windowSize = parameters.getInt("windowSize");
int slidingStep = parameters.getInt("slidingStep");
configurations
@@ -45,9 +44,4 @@ public class SlidingSizeWindowConstructorTester0 implements UDTF {
collector.putInt(rowWindow.getRow(0).getTime(), rowWindow.windowSize());
}
}
-
- @Override
- public void beforeDestroy() {
- System.out.println("SlidingSizeWindowConstructorTester0#beforeDestroy");
- }
}
diff --git a/server/src/test/java/org/apache/iotdb/db/query/udf/example/SlidingSizeWindowConstructorTester1.java b/server/src/test/java/org/apache/iotdb/db/query/udf/example/SlidingSizeWindowConstructorTester1.java
index 0ec5e3e..e5f10f8 100644
--- a/server/src/test/java/org/apache/iotdb/db/query/udf/example/SlidingSizeWindowConstructorTester1.java
+++ b/server/src/test/java/org/apache/iotdb/db/query/udf/example/SlidingSizeWindowConstructorTester1.java
@@ -41,7 +41,6 @@ public class SlidingSizeWindowConstructorTester1 implements UDTF {
@Override
public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) {
- System.out.println("SlidingSizeWindowConstructorTester1#beforeStart");
consumptionPoint = parameters.getInt("consumptionPoint");
configurations
.setOutputDataType(TSDataType.INT32)
@@ -54,9 +53,4 @@ public class SlidingSizeWindowConstructorTester1 implements UDTF {
collector.putInt(row.getTime(), row.getInt(0));
}
}
-
- @Override
- public void beforeDestroy() {
- System.out.println("SlidingSizeWindowConstructorTester1#beforeDestroy");
- }
}
diff --git a/server/src/test/java/org/apache/iotdb/db/query/udf/example/SlidingTimeWindowConstructionTester.java b/server/src/test/java/org/apache/iotdb/db/query/udf/example/SlidingTimeWindowConstructionTester.java
index 49ed420..12c45e5 100644
--- a/server/src/test/java/org/apache/iotdb/db/query/udf/example/SlidingTimeWindowConstructionTester.java
+++ b/server/src/test/java/org/apache/iotdb/db/query/udf/example/SlidingTimeWindowConstructionTester.java
@@ -43,7 +43,6 @@ public class SlidingTimeWindowConstructionTester implements UDTF {
@Override
public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) {
- System.out.println("SlidingTimeWindowConstructionTester#beforeStart");
long timeInterval = parameters.getLong(TIME_INTERVAL_KEY);
configurations
.setOutputDataType(TSDataType.INT32)
@@ -61,9 +60,4 @@ public class SlidingTimeWindowConstructionTester implements UDTF {
collector.putInt(rowWindow.getRow(0).getTime(), accumulator);
}
}
-
- @Override
- public void beforeDestroy() {
- System.out.println("SlidingTimeWindowConstructionTester#beforeDestroy");
- }
}
diff --git a/server/src/test/java/org/apache/iotdb/db/query/udf/example/TerminateTester.java b/server/src/test/java/org/apache/iotdb/db/query/udf/example/TerminateTester.java
index d5d797f..bdd2d4e 100644
--- a/server/src/test/java/org/apache/iotdb/db/query/udf/example/TerminateTester.java
+++ b/server/src/test/java/org/apache/iotdb/db/query/udf/example/TerminateTester.java
@@ -34,7 +34,6 @@ public class TerminateTester implements UDTF {
@Override
public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) {
- System.out.println("TerminateTester#beforeStart");
configurations
.setOutputDataType(TSDataType.INT32)
.setAccessStrategy(new RowByRowAccessStrategy());
@@ -56,9 +55,4 @@ public class TerminateTester implements UDTF {
collector.putInt(maxTime + 1, count);
}
}
-
- @Override
- public void beforeDestroy() {
- System.out.println("TerminateTester#beforeDestroy");
- }
}