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