From ad6dd54a000cfb0e8ec2b1de7f4415e9e5a3df1f Mon Sep 17 00:00:00 2001
From: Alex Duan <417921451@qq.com>
Date: Fri, 7 Apr 2023 18:14:02 +0800
Subject: [PATCH] test: add udf function return with varchar
---
docs/zh/07-develop/09-udf.md | 28 +++++++++-
tests/script/sh/max_vol.c | 101 +++++++++++++++++++++++++++++++++++
2 files changed, 128 insertions(+), 1 deletion(-)
create mode 100644 tests/script/sh/max_vol.c
diff --git a/docs/zh/07-develop/09-udf.md b/docs/zh/07-develop/09-udf.md
index 2eb4b3dee3..8a8ef82009 100644
--- a/docs/zh/07-develop/09-udf.md
+++ b/docs/zh/07-develop/09-udf.md
@@ -231,7 +231,7 @@ bit_add 实现多列的按位与功能。如果只有一列,返回这一列。
-### 聚合函数示例 [l2norm](https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/l2norm.c)
+### 聚合函数示例1 返回值为数值类型 [l2norm](https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/l2norm.c)
l2norm 实现了输入列的所有数据的二阶范数,即对每个数据先平方,再累加求和,最后开方。
@@ -243,3 +243,29 @@ l2norm 实现了输入列的所有数据的二阶范数,即对每个数据先
```
+
+### 聚合函数示例2 返回值为字符串类型 [max_vol](https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/max_vol.c)
+
+max_vol 实现了从多个输入的电压列中找到最大电压,返回由设备ID + 最大电压所在(行,列)+ 最大电压值 组成的组合字符串值
+
+创建表:
+```bash
+create table battery(ts timestamp, vol1 float, vol2 float, vol3 float, deviceId varchar(16));
+```
+创建自定义函数:
+```bash
+create aggregate function max_vol as '/root/udf/libmaxvol.so' outputtype binary(64) bufsize 10240 language 'C';
+```
+使用自定义函数:
+```bash
+select max_vol(vol1,vol2,vol3,deviceid) from battery;
+```
+
+
+max_vol.c
+
+```c
+{{#include tests/script/sh/max_vol.c}}
+```
+
+
\ No newline at end of file
diff --git a/tests/script/sh/max_vol.c b/tests/script/sh/max_vol.c
new file mode 100644
index 0000000000..4f9ecd33a7
--- /dev/null
+++ b/tests/script/sh/max_vol.c
@@ -0,0 +1,101 @@
+#include
+#include
+#include
+#include
+
+#include "taosudf.h"
+
+#define STR_MAX_LEN 256 // inter buffer length
+
+// init
+DLL_EXPORT int32_t max_vol_init()
+{
+ return 0;
+}
+
+// destory
+DLL_EXPORT int32_t max_vol_destroy()
+{
+ return 0;
+}
+
+// start
+DLL_EXPORT int32_t max_vol_start(SUdfInterBuf *buf)
+{
+ memset(buf->buf, 0, sizeof(float) + STR_MAX_LEN);
+ // set init value
+ *((float*)buf->buf) = -10000000;
+ buf->bufLen = sizeof(float) + STR_MAX_LEN;
+ buf->numOfResult = 0;
+ return 0;
+}
+
+DLL_EXPORT int32_t max_vol(SUdfDataBlock *block, SUdfInterBuf *interBuf, SUdfInterBuf *newInterBuf) {
+ float maxValue = *(float *)interBuf->buf;
+ char strBuff[STR_MAX_LEN] = "inter1buf";
+
+ if (block->numOfCols < 2)
+ {
+ return TSDB_CODE_UDF_INVALID_INPUT;
+ }
+
+ // check data type
+ for (int32_t i = 0; i < block->numOfCols; ++i)
+ {
+ SUdfColumn *col = block->udfCols[i];
+ if( i == block->numOfCols - 1) {
+ // last column is device id , must varchar
+ if (col->colMeta.type != TSDB_DATA_TYPE_VARCHAR ) {
+ return TSDB_CODE_UDF_INVALID_INPUT;
+ }
+ } else {
+ if (col->colMeta.type != TSDB_DATA_TYPE_FLOAT) {
+ return TSDB_CODE_UDF_INVALID_INPUT;
+ }
+ }
+ }
+
+ // calc max voltage
+ SUdfColumn *lastCol = block->udfCols[block->numOfCols - 1];
+ for (int32_t i = 0; i < (block->numOfCols - 1); ++i) {
+ for (int32_t j = 0; j < block->numOfRows; ++j) {
+ SUdfColumn *col = block->udfCols[i];
+ if (udfColDataIsNull(col, j)) {
+ continue;
+ }
+ char *data = udfColDataGetData(col, j);
+ float voltage = *(float *)data;
+ if (voltage > maxValue) {
+ maxValue = voltage;
+ char *valData = udfColDataGetData(lastCol, j);
+ // get device id
+ char *deviceId = valData + sizeof(uint16_t);
+ sprintf(strBuff, "%s_(%d,%d)_%f", deviceId, j, i, maxValue);
+ }
+ }
+ }
+
+ *(float*)newInterBuf->buf = maxValue;
+ strcpy(newInterBuf->buf + sizeof(float), strBuff);
+ newInterBuf->bufLen = sizeof(float) + strlen(strBuff)+1;
+ newInterBuf->numOfResult = 1;
+ return 0;
+}
+
+DLL_EXPORT int32_t max_vol_finish(SUdfInterBuf *buf, SUdfInterBuf *resultData)
+{
+ char * str = buf->buf + sizeof(float);
+ // copy to des
+ char * des = resultData->buf + sizeof(uint16_t);
+ strcpy(des, str);
+
+ // set binary type len
+ uint16_t len = strlen(str);
+ *((uint16_t*)resultData->buf) = len;
+
+ // set buf len
+ resultData->bufLen = len + sizeof(uint16_t);
+ // set row count
+ resultData->numOfResult = 1;
+ return 0;
+}
--
GitLab