Skip to content

Commit

Permalink
Merge pull request #20815 from taosdata/test/TD-AUTOGETN-3.0
Browse files Browse the repository at this point in the history
test: add udf function return with varchar demo
  • Loading branch information
gccgdb1234 committed Apr 12, 2023
2 parents 218f8d3 + e03a6c2 commit 4d90c85
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 2 deletions.
28 changes: 27 additions & 1 deletion docs/zh/07-develop/09-udf.md
Expand Up @@ -231,7 +231,7 @@ bit_add 实现多列的按位与功能。如果只有一列,返回这一列。
</details>
### 聚合函数示例 [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 实现了输入列的所有数据的二阶范数,即对每个数据先平方,再累加求和,最后开方。
Expand All @@ -243,3 +243,29 @@ l2norm 实现了输入列的所有数据的二阶范数,即对每个数据先
```

</details>

### 聚合函数示例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;
```
<details>
<summary>max_vol.c</summary>
```c
{{#include tests/script/sh/max_vol.c}}
```
</details>
2 changes: 1 addition & 1 deletion tests/pytest/util/autogen.py
Expand Up @@ -51,7 +51,7 @@ def gen_columns_sql(self, pre, cnt, binary_len, nchar_len):
metas = []
for i in range(cnt):
colname = f"{pre}{i}"
sel = len(types) % len(types)
sel = i % len(types)
coltype = types[sel]
sql = f"{colname} {coltype}"
if sqls != "":
Expand Down
101 changes: 101 additions & 0 deletions tests/script/sh/max_vol.c
@@ -0,0 +1,101 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#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;
}

0 comments on commit 4d90c85

Please sign in to comment.