doc: add necessary spaces to the udf

This commit is contained in:
Shengliang Guan 2024-08-08 09:59:21 +08:00
parent a07adec754
commit 53771fbebf
1 changed files with 51 additions and 54 deletions

View File

@ -6,7 +6,7 @@ toc_max_heading_level: 4
## UDF 简介 ## UDF 简介
在某些应用场景中应用逻辑需要的查询功能无法直接使用TDengine内置的函数来实现。TDengine允许编写用户自定义函数UDF以便解决特殊应用场景中的使用需求。UDF在集群中注册成功后可以像系统内置函数一样在SQL中调用就使用角度而言没有任何区别。UDF分为标量函数和聚合函数。标量函数对每行数据输出一个值如求绝对值abs、正弦函数sin、字符串拼接函数concat等。聚合函数对多行数据输出一个值如求平均数avg、取最大值max等。 在某些应用场景中,应用逻辑需要的查询功能无法直接使用 TDengine 内置的函数来实现。TDengine 允许编写用户自定义函数UDF以便解决特殊应用场景中的使用需求。UDF 在集群中注册成功后,可以像系统内置函数一样在 SQ L中调用就使用角度而言没有任何区别。UDF 分为标量函数和聚合函数。标量函数对每行数据输出一个值,如求绝对值abs、正弦函数sin、字符串拼接函数concat等。聚合函数对多行数据输出一个值,如求平均数avg、取最大值max等。
TDengine 支持用 C 和 Python 两种编程语言编写 UDF。C 语言编写的 UDF 与内置函数的性能几乎相同Python 语言编写的 UDF 可以利用丰富的 Python 运算库。为了避免 UDF 执行中发生异常影响数据库服务TDengine 使用了进程分离技术,把 UDF 的执行放到另一个进程中完成,即使用户编写的 UDF 崩溃,也不会影响 TDengine 的正常运行。 TDengine 支持用 C 和 Python 两种编程语言编写 UDF。C 语言编写的 UDF 与内置函数的性能几乎相同Python 语言编写的 UDF 可以利用丰富的 Python 运算库。为了避免 UDF 执行中发生异常影响数据库服务TDengine 使用了进程分离技术,把 UDF 的执行放到另一个进程中完成,即使用户编写的 UDF 崩溃,也不会影响 TDengine 的正常运行。
@ -14,14 +14,14 @@ TDengine支持用C和Python两种编程语言编写UDF。C语言编写的UDF与
使用 C 语言实现 UDF 时,需要实现规定的接口函数 使用 C 语言实现 UDF 时,需要实现规定的接口函数
- 标量函数需要实现标量接口函数 scalarfn 。 - 标量函数需要实现标量接口函数 scalarfn 。
- 聚合函数需要实现聚合接口函数 aggfn_start aggfn aggfn_finish。 - 聚合函数需要实现聚合接口函数 aggfn_start、aggfn、aggfn_finish。
- 如果需要初始化,实现 udf_init如果需要清理工作实现 udf_destroy。 - 如果需要初始化,实现 udf_init如果需要清理工作实现 udf_destroy。
接口函数的名称是 UDF 名称,或者是 UDF 名称和特定后缀(`_start`, `_finish`, `_init`, `_destroy`)的连接。列表中的scalarfnaggfn, udf需要替换成udf函数名 接口函数的名称是 UDF 名称,或者是 UDF 名称和特定后缀(`_start`、`_finish`、`_init`、`_destroy`)的连接
### 接口定义 ### 接口定义
在TDengine中UDF的接口函数名称可以是UDF名称也可以是UDF名称和特定后缀如_start、_finish、_init、_destroy的连接。后面内容中描述的函数名称例如scalarfn、aggfn需要替换成UDF名称。 TDengine UDF 的接口函数名称可以是 UDF 名称,也可以是 UDF 名称和特定后缀如_start、_finish、_init、_destroy的连接。后面内容中描述的函数名称例如 scalarfn、aggfn需要替换成 UDF 名称。
#### 标量函数接口 #### 标量函数接口
@ -41,7 +41,7 @@ int32_t scalarfn(SUdfDataBlock* inputDataBlock, SUdfColumn *resultColumn)
- 分组数据相关数据会被分为多个行数据块row data block每个行数据块包含一组具有相同分组键grouping key的数据。 - 分组数据相关数据会被分为多个行数据块row data block每个行数据块包含一组具有相同分组键grouping key的数据。
- 更新中间结果:对于每个数据块,调用 aggfn 函数更新中间结果。aggfn 函数会根据聚合函数的类型(如 sum、avg、count 等)对数据进行相应的计算,并将计算结 - 更新中间结果:对于每个数据块,调用 aggfn 函数更新中间结果。aggfn 函数会根据聚合函数的类型(如 sum、avg、count 等)对数据进行相应的计算,并将计算结
果存储在结果缓冲区中。 果存储在结果缓冲区中。
- 生成最终结果在所有数据块的中间结果更新完成后调用aggfn_finish函数从结果缓冲区中提取最终结果。最终结果通常只包含0条或1条数据具体取决于聚 - 生成最终结果:在所有数据块的中间结果更新完成后,调用 aggfn_finish 函数从结果缓冲区中提取最终结果。最终结果只包含 0 条或 1 条数据,具体取决于聚
合函数的类型和输入数据。 合函数的类型和输入数据。
聚合函数的接口函数原型如下。 聚合函数的接口函数原型如下。
@ -52,7 +52,6 @@ int32_t aggfn(SUdfDataBlock* inputBlock, SUdfInterBuf *interBuf, SUdfInterBuf *n
int32_t aggfn_finish(SUdfInterBuf* interBuf, SUdfInterBuf *result) int32_t aggfn_finish(SUdfInterBuf* interBuf, SUdfInterBuf *result)
``` ```
其中 aggfn 是函数名的占位符。首先调用 aggfn_start 生成结果 buffer然后相关的数据会被分为多个行数据块对每个数据块调用 aggfn 用数据块更新中间结果,最后再调用 aggfn_finish 从中间结果产生最终结果,最终结果只能含 0 或 1 条结果数据。 其中 aggfn 是函数名的占位符。首先调用 aggfn_start 生成结果 buffer然后相关的数据会被分为多个行数据块对每个数据块调用 aggfn 用数据块更新中间结果,最后再调用 aggfn_finish 从中间结果产生最终结果,最终结果只能含 0 或 1 条结果数据。
主要参数说明如下。 主要参数说明如下。
@ -61,7 +60,6 @@ int32_t aggfn_finish(SUdfInterBuf* interBuf, SUdfInterBuf *result)
- newInterBuf新的中间结果缓冲区。 - newInterBuf新的中间结果缓冲区。
- result最终结果。 - result最终结果。
#### 初始化和销毁接口 #### 初始化和销毁接口
初始化和销毁接口是标量函数和聚合函数共同使用的接口,相关 API 如下。 初始化和销毁接口是标量函数和聚合函数共同使用的接口,相关 API 如下。
@ -100,7 +98,7 @@ int32_t aggfn_start(SUdfInterBuf* interBuf) {
int32_t aggfn(SUdfDataBlock* inputBlock, SUdfInterBuf *interBuf, SUdfInterBuf *newInterBuf) { int32_t aggfn(SUdfDataBlock* inputBlock, SUdfInterBuf *interBuf, SUdfInterBuf *newInterBuf) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t int32_t aggfn_finish(SUdfInterBuf* interBuf, SUdfInterBuf *result) { int32_t aggfn_finish(SUdfInterBuf* interBuf, SUdfInterBuf *result) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t aggfn_destroy() { int32_t aggfn_destroy() {
@ -147,7 +145,7 @@ def process(input: datablock) -> tuple[output_type]:
``` ```
主要参数说明如下: 主要参数说明如下:
- input:datablock 类似二维矩阵,通过成员方法 data(row,col)返回位于 row 行,col 列的 python 对象 - input:datablock 类似二维矩阵,通过成员方法 data(row, col) 读取位于 row 行、col 列的 python 对象
- 返回值是一个 Python 对象元组,每个元素类型为输出类型。 - 返回值是一个 Python 对象元组,每个元素类型为输出类型。
#### 聚合函数接口 #### 聚合函数接口
@ -163,7 +161,7 @@ def finish(buf: bytes) -> output_type:
首先,调用 start 函数生成最初的结果缓冲区。这个结果缓冲区用于存储聚合函数的内部状态,随着输入数据的处理而不断更新。 首先,调用 start 函数生成最初的结果缓冲区。这个结果缓冲区用于存储聚合函数的内部状态,随着输入数据的处理而不断更新。
然后输入数据会被分为多个行数据块。对于每个行数据块调用reduce函数并将当前行数据块inputs和当前的中间结果buf作为参数传递。reduce函数会根据输入数据和当前状态来更新聚合函数的内部状态并返回新的中间结果 然后,输入数据会被分为多个行数据块。对于每个行数据块,调用 reduce 函数并将当前行数据块inputs和当前的中间结果buf作为参数传递。reduce 函数会根据输入数据和当前状态来更新聚合函数的内部状态,并返回新的中间结果
最后,当所有行数据块都处理完毕后,调用 finish 函数。这个函数接收最终的中间结果buf作为参数并从中生成最终的输出。由于聚合函数的特性最终输出只能包含 0 条或 1 条数据。这个输出结果将作为聚合函数的计算结果返回给调用者。 最后,当所有行数据块都处理完毕后,调用 finish 函数。这个函数接收最终的中间结果buf作为参数并从中生成最终的输出。由于聚合函数的特性最终输出只能包含 0 条或 1 条数据。这个输出结果将作为聚合函数的计算结果返回给调用者。
@ -649,7 +647,6 @@ CREATE FUNCTION function_name AS library_path OUTPUTTYPE output_type LANGUAGE 'P
实现的 Python 文件路径。路径需要用英文单引号或英文双引号括起来。 实现的 Python 文件路径。路径需要用英文单引号或英文双引号括起来。
- output_type函数计算结果的数据类型名称。 - output_type函数计算结果的数据类型名称。
### 创建聚合函数 ### 创建聚合函数
创建聚合函数的 SQL 语法如下。 创建聚合函数的 SQL 语法如下。