Merge pull request #15885 from taosdata/szhou/fix/leave

fix: modify udf document
This commit is contained in:
shenglian-zhou 2022-08-09 13:08:57 +08:00 committed by GitHub
commit 74f46856ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 55 additions and 84 deletions

View File

@ -6,9 +6,11 @@ description: "支持用户编码的聚合函数和标量函数,在查询中嵌
在有些应用场景中,应用逻辑需要的查询无法直接使用系统内置的函数来表示。利用 UDF 功能TDengine 可以插入用户编写的处理代码并在查询中使用它们,就能够很方便地解决特殊应用场景中的使用需求。 UDF 通常以数据表中的一列数据做为输入,同时支持以嵌套子查询的结果作为输入。
从 2.2.0.0 版本开始,TDengine 支持通过 C/C++ 语言进行 UDF 定义。接下来结合示例讲解 UDF 的使用方法。
TDengine 支持通过 C/C++ 语言进行 UDF 定义。接下来结合示例讲解 UDF 的使用方法。
用户可以通过 UDF 实现两类函数: 标量函数和聚合函数。标量函数对每行数据返回一个值,如求绝对值 abs正弦函数 sin字符串拼接函数 concat 等。聚合函数对多行数据进行返回一个值,如求平均数 avg最大值 max 等。实现udf时需要实现规定的接口函数。接口函数的名称是 udf 名称,或者是 udf 名称和特定后缀_start, _finish, _init, _destroy)的连接。scalarfnaggfn, udf需要替换成udf函数名。
用户可以通过 UDF 实现两类函数: 标量函数和聚合函数。标量函数对每行数据返回一个值,如求绝对值 abs正弦函数 sin字符串拼接函数 concat 等。聚合函数对多行数据进行返回一个值,如求平均数 avg最大值 max 等。
实现udf时需要实现规定的接口函数。接口函数的名称是 udf 名称,或者是 udf 名称和特定后缀_start, _finish, _init, _destroy)的连接后。以下列表中的scalarfnaggfn, udf需要替换成udf函数名。
- 标量函数需要实现标量接口函数 scalarfn
- 聚合函数需要实现聚合接口函数 aggfn_start aggfn aggfn_finish。
- 无论标量函数还是聚合函数,如果需要初始化,实现 udf_init如果需要清理工作实现udf_destory。
@ -98,9 +100,9 @@ aggfn为函数名的占位符需要修改为自己的函数名如l2norm。
## 接口函数定义
接口函数的名称是 udf 名称,或者是 udf 名称和特定后缀_start, _finish, _init, _destroy)的连接。scalarfnaggfn, udf需要替换成udf函数名。
接口函数的名称是 udf 名称,或者是 udf 名称和特定后缀_start, _finish, _init, _destroy)的连接。以下描述中函数名称中的 scalarfnaggfn, udf 需要替换成udf函数名。
接口函数返回值表示是否成功,如果错误返回错误代码。错误见taoserror.h
接口函数返回值表示是否成功,如果错误返回错误代码错误代码见taoserror.h。参数类型见数据结构定义。
### 标量接口函数
@ -190,7 +192,7 @@ typedef struct SUdfInterBuf {
- SUdfDataBlock 数据块包含行数 numOfRows 和列数 numCols。udfCols[i] (0 <= i <= numCols-1)表示每一列数据类型为SUdfColumn*。
- SUdfColumn 包含列的数据类型定义 colMeta 和列的数据colData。
- SUdfColumnMeta 成员定义同 taos.h 数据类型定义。
- SUdfColumnData 数据可以变长varLenCol定义变长数据fixLenCol定义定长数据。
- SUdfColumnData 数据可以变长varLenCol定义变长数据fixLenCol定义定长数据。
- SUdfInterBuf 定义中间结构buffer以及buffer中结果个数 numOfResult
为了更好的操作以上数据结构,提供了一些便利函数,定义在 taosudf.h。
@ -207,70 +209,8 @@ gcc -g -O0 -fPIC -shared add_one.c -o add_one.so
这样就准备好了动态链接库 add_one.so 文件,可以供后文创建 UDF 时使用了。为了保证可靠的系统运行,编译器 GCC 推荐使用 7.5 及以上版本。
## 在系统中管理和使用 UDF
### 创建 UDF
用户可以通过 SQL 指令在系统中加载客户端所在主机上的 UDF 函数库(不能通过 RESTful 接口或 HTTP 管理界面来进行这一过程)。一旦创建成功,则当前 TDengine 集群的所有用户都可以在 SQL 指令中使用这些函数。UDF 存储在系统的 MNode 节点上,因此即使重启 TDengine 系统,已经创建的 UDF 也仍然可用。
在创建 UDF 时,需要区分标量函数和聚合函数。如果创建时声明了错误的函数类别,则可能导致通过 SQL 指令调用函数时出错。此外,用户需要保证输入数据类型与 UDF 程序匹配UDF 输出数据类型与 OUTPUTTYPE 匹配。
- 创建标量函数
```sql
CREATE FUNCTION function_name AS library_path OUTPUTTYPE output_type;
```
- function_name标量函数未来在 SQL 中被调用时的函数名,必须与函数实现中 udf 的实际名称一致;
- library_path包含 UDF 函数实现的动态链接库的库文件绝对路径(指的是库文件在当前客户端所在主机上的保存路径,通常是指向一个 .so 文件),这个路径需要用英文单引号或英文双引号括起来;
- output_type此函数计算结果的数据类型名称
例如,如下语句可以把 libbitand.so 创建为系统中可用的 UDF
```sql
CREATE FUNCTION bit_and AS "/home/taos/udf_example/libbitand.so" OUTPUTTYPE INT;
```
- 创建聚合函数:
```sql
CREATE AGGREGATE FUNCTION function_name AS library_path OUTPUTTYPE output_type [ BUFSIZE buffer_size ];
```
- function_name聚合函数未来在 SQL 中被调用时的函数名,必须与函数实现中 udfNormalFunc 的实际名称一致;
- library_path包含 UDF 函数实现的动态链接库的库文件绝对路径(指的是库文件在当前客户端所在主机上的保存路径,通常是指向一个 .so 文件),这个路径需要用英文单引号或英文双引号括起来;
- output_type此函数计算结果的数据类型与上文中 udfNormalFunc 的 itype 参数不同,这里不是使用数字表示法,而是直接写类型名称即可;
- buffer_size中间计算结果的缓冲区大小单位是字节。如果不使用可以不设置。
例如,如下语句可以把 libl2norm.so 创建为系统中可用的 UDF
```sql
CREATE AGGREGATE FUNCTION l2norm AS "/home/taos/udf_example/libl2norm.so" OUTPUTTYPE DOUBLE bufsize 8;
```
### 管理 UDF
- 删除指定名称的用户定义函数:
```
DROP FUNCTION function_name;
```
- function_name此参数的含义与 CREATE 指令中的 function_name 参数一致,也即要删除的函数的名字,例如
```sql
DROP FUNCTION bit_and;
```
- 显示系统中当前可用的所有 UDF
```sql
SHOW FUNCTIONS;
```
### 调用 UDF
在 SQL 指令中,可以直接以在系统中创建 UDF 时赋予的函数名来调用用户定义函数。例如:
```sql
SELECT X(c1,c2) FROM table/stable;
```
表示对名为 c1, c2 的数据列调用名为 X 的用户定义函数。SQL 指令中用户定义函数可以配合 WHERE 等查询特性来使用。
## 管理和使用UDF
关于如何管理和使用UDF参见[UDF使用说明](../12-taos-sql/26-udf.md)
## 示例代码

View File

@ -4,34 +4,65 @@ title: 用户自定义函数
---
除了 TDengine 的内置函数以外用户还可以编写自己的函数逻辑并加入TDengine系统中。
## 创建 UDF
## 创建函数
用户可以通过 SQL 指令在系统中加载客户端所在主机上的 UDF 函数库(不能通过 RESTful 接口或 HTTP 管理界面来进行这一过程)。一旦创建成功,则当前 TDengine 集群的所有用户都可以在 SQL 指令中使用这些函数。UDF 存储在系统的 MNode 节点上,因此即使重启 TDengine 系统,已经创建的 UDF 也仍然可用。
在创建 UDF 时,需要区分标量函数和聚合函数。如果创建时声明了错误的函数类别,则可能导致通过 SQL 指令调用函数时出错。此外,用户需要保证输入数据类型与 UDF 程序匹配UDF 输出数据类型与 OUTPUTTYPE 匹配。
- 创建标量函数
```sql
CREATE [AGGREGATE] FUNCTION func_name AS library_path OUTPUTTYPE type_name [BUFSIZE buffer_size]
CREATE FUNCTION function_name AS library_path OUTPUTTYPE output_type;
```
语法说明:
- function_name标量函数未来在 SQL 中被调用时的函数名,必须与函数实现中 udf 的实际名称一致;
- library_path包含 UDF 函数实现的动态链接库的库文件绝对路径(指的是库文件在当前客户端所在主机上的保存路径,通常是指向一个 .so 文件),这个路径需要用英文单引号或英文双引号括起来;
- output_type此函数计算结果的数据类型名称
AGGREGATE标识此函数是标量函数还是聚集函数。
func_name函数名必须与函数实现中 udf 的实际名称一致。
library_path包含UDF函数实现的动态链接库的绝对路径是在客户端侧主机上的绝对路径。
type_name标识此函数的返回类型。
buffer_size中间结果的缓冲区大小单位是字节。不设置则默认为0。
例如,如下语句可以把 libbitand.so 创建为系统中可用的 UDF
```sql
CREATE FUNCTION bit_and AS "/home/taos/udf_example/libbitand.so" OUTPUTTYPE INT;
```
- 创建聚合函数:
```sql
CREATE AGGREGATE FUNCTION function_name AS library_path OUTPUTTYPE output_type [ BUFSIZE buffer_size ];
```
- function_name聚合函数未来在 SQL 中被调用时的函数名,必须与函数实现中 udfNormalFunc 的实际名称一致;
- library_path包含 UDF 函数实现的动态链接库的库文件绝对路径(指的是库文件在当前客户端所在主机上的保存路径,通常是指向一个 .so 文件),这个路径需要用英文单引号或英文双引号括起来;
- output_type此函数计算结果的数据类型与上文中 udfNormalFunc 的 itype 参数不同,这里不是使用数字表示法,而是直接写类型名称即可;
- buffer_size中间计算结果的缓冲区大小单位是字节。如果不使用可以不设置。
例如,如下语句可以把 libl2norm.so 创建为系统中可用的 UDF
```sql
CREATE AGGREGATE FUNCTION l2norm AS "/home/taos/udf_example/libl2norm.so" OUTPUTTYPE DOUBLE bufsize 8;
```
关于如何开发自定义函数,请参考 [UDF使用说明](../../develop/udf)。
## 删除自定义函数
## 管理 UDF
- 删除指定名称的用户定义函数:
```
DROP FUNCTION function_name;
```
- function_name此参数的含义与 CREATE 指令中的 function_name 参数一致,也即要删除的函数的名字,例如
## 显示 UDF
- function_name此参数的含义与 CREATE 指令中的 function_name 参数一致也即要删除的函数的名字例如bit_and, l2norm
```sql
SHOW FUNCTION;
DROP FUNCTION bit_and;
```
- 显示系统中当前可用的所有 UDF
```sql
SHOW FUNCTIONS;
```
## 调用 UDF
在 SQL 指令中,可以直接以在系统中创建 UDF 时赋予的函数名来调用用户定义函数。例如:
```sql
SELECT X(c1,c2) FROM table/stable;
```
表示对名为 c1, c2 的数据列调用名为 X 的用户定义函数。SQL 指令中用户定义函数可以配合 WHERE 等查询特性来使用。