Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
3b37e33
func/regexp_extract: new scalar func and test cases
stephenkgu Apr 21, 2026
6d2e73a
fix ai review issues
stephenkgu Apr 21, 2026
6548192
fix c null-terminated string's mem manipulation
stephenkgu Apr 21, 2026
d770e45
Update source/libs/scalar/src/sclfunc.c
stephenkgu Apr 21, 2026
dc985ca
Update source/libs/scalar/src/sclfunc.c
stephenkgu Apr 21, 2026
c4a5619
Update source/libs/function/src/builtins.c
stephenkgu Apr 21, 2026
6a151e2
Apply suggestions from copilot code review
stephenkgu Apr 21, 2026
c7a78f4
fix group idx range checking with prepared statements
stephenkgu Apr 21, 2026
a41023d
manage mem buffer outside of loop
stephenkgu Apr 21, 2026
b384578
use int64_t to validate group index arg instead of int32_t for potent…
stephenkgu Apr 21, 2026
20f4090
Merge branch '3.0' into fix/6968250338
stephenkgu Apr 22, 2026
3505a52
fix(ext-win): fix external window compilation
stephenkgu Apr 22, 2026
40293fd
Merge branch 'fix/ext-win-compile' into fix/6968250338
stephenkgu Apr 22, 2026
a0f68be
Merge branch '3.0' into fix/6968250338
stephenkgu Apr 22, 2026
f40ccdd
Update source/libs/executor/src/externalwindowoperator.c
stephenkgu Apr 22, 2026
3213b43
Update source/libs/scalar/src/sclfunc.c
stephenkgu Apr 22, 2026
9e090be
Update source/libs/scalar/src/sclfunc.c
stephenkgu Apr 22, 2026
6bdc547
Update test/cases/11-Functions/01-Scalar/test_fun_sca_regexp_extract.py
stephenkgu Apr 22, 2026
b11c324
use cleanup block instead of direct return
stephenkgu Apr 22, 2026
d56a93e
use header extra buffer even though its length contains header already
stephenkgu Apr 22, 2026
5878f49
Update source/libs/function/src/builtins.c
stephenkgu Apr 22, 2026
a7b7194
use macro for maximum of group index instead of hard-coded
stephenkgu Apr 22, 2026
99b7b3a
Merge branch 'fix/6968250338' of https://github.com/taosdata/TDengine…
stephenkgu Apr 22, 2026
872601f
Update test/cases/11-Functions/01-Scalar/test_fun_sca_regexp_extract.py
stephenkgu Apr 22, 2026
0189d82
Update source/libs/function/src/builtins.c
stephenkgu Apr 22, 2026
37f599a
en & zh doc for this func
stephenkgu Apr 22, 2026
9cf7858
Merge branch 'fix/6968250338' of https://github.com/taosdata/TDengine…
stephenkgu Apr 22, 2026
640f580
Update source/libs/function/src/builtins.c
stephenkgu Apr 22, 2026
38ac272
Merge branch 'fix/6968250338' of https://github.com/taosdata/TDengine…
stephenkgu Apr 22, 2026
816ccb5
fix undefined behavior with reg lib
stephenkgu Apr 22, 2026
984b053
move character converting buffer out of loop to dismiss allocating ea…
stephenkgu Apr 23, 2026
ceeb5cb
copy result data to dismiss dangling pointers
stephenkgu Apr 23, 2026
21e6d42
revert set data value with true, the 4th args is isNull, not isCopy
stephenkgu Apr 23, 2026
7a86c29
fix zh, en doc examples and validate with test cases
stephenkgu Apr 23, 2026
9ccae40
Update source/libs/function/src/builtins.c
stephenkgu Apr 23, 2026
7c471c3
pre-formats error message to fix compilation
stephenkgu Apr 23, 2026
5670d20
remove inaccurate comments
stephenkgu Apr 23, 2026
388cfe0
Update docs/zh/14-reference/03-taos-sql/22-function.md
stephenkgu Apr 23, 2026
7203c84
Update docs/en/14-reference/03-taos-sql/22-function.md
stephenkgu Apr 23, 2026
068a98c
Update source/libs/scalar/src/sclfunc.c
stephenkgu Apr 23, 2026
9652c1e
new test case for big group index
stephenkgu Apr 23, 2026
4e13f1d
new test case for null pattern
stephenkgu Apr 23, 2026
7b2b79d
Update source/libs/scalar/src/sclfunc.c
stephenkgu Apr 23, 2026
663e85b
Update docs/en/14-reference/03-taos-sql/22-function.md
stephenkgu Apr 23, 2026
d0728c9
Update docs/zh/14-reference/03-taos-sql/22-function.md
stephenkgu Apr 23, 2026
be87866
Update test/cases/11-Functions/01-Scalar/test_fun_sca_regexp_extract.py
stephenkgu Apr 23, 2026
193997a
Update source/libs/function/src/builtins.c
stephenkgu Apr 23, 2026
b34c9a1
Update test/cases/11-Functions/01-Scalar/test_fun_sca_regexp_extract.py
stephenkgu Apr 23, 2026
6e4743f
log reg exec error message to make production debugging actionalbe
stephenkgu Apr 23, 2026
d8b04ac
fix terrno
stephenkgu Apr 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions docs/en/14-reference/03-taos-sql/22-function.md
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,49 @@ LTRIM(expr)

**Applicable to**: Tables and supertables.

#### REGEXP_EXTRACT

```sql
REGEXP_EXTRACT(expr, pattern [, group_idx])
```

**Function Description**: Applies the POSIX extended regular expression `pattern` to `expr` and returns the substring matched by capture group `group_idx`. Returns NULL when there is no match or when `expr` or `pattern` is NULL.

**Return Type**: Same as `expr` (VARCHAR or NCHAR).

**Applicable Data Types**: `expr`: VARCHAR, NCHAR. `pattern`: VARCHAR, NCHAR.

**Nested Subquery Support**: Applicable to both inner and outer queries.

**Applicable to**: Tables and supertables.

**Usage**:

- If omitted, `group_idx` defaults to `1`.
- If provided as a non-`NULL` value, `group_idx` must be a non-negative integer constant. `0` returns the entire match; `1` returns the first capture group, `2` the second, and so on. The maximum value is 512.
- If `group_idx` is SQL `NULL`, the function returns `NULL`.
- Returns NULL if `group_idx` exceeds the number of capture groups in `pattern`, or if the addressed group did not participate in the match.
- `pattern` must be provided as a constant literal or parameter placeholder; it cannot reference a column or be computed from other expressions.

**Example**:

```sql
taos> SELECT REGEXP_EXTRACT('2026-04-22', '([0-9]{4})-([0-9]{2})-([0-9]{2})', 1);
regexp_extract('2026-04-22', '([0-9]{4})-([0-9]{2})-([0-9]{2})', 1) |
=======================================================================
2026 |

taos> SELECT REGEXP_EXTRACT('2026-04-22', '([0-9]{4})-([0-9]{2})-([0-9]{2})', 0);
regexp_extract('2026-04-22', '([0-9]{4})-([0-9]{2})-([0-9]{2})', 0) |
=======================================================================
2026-04-22 |

taos> SELECT REGEXP_EXTRACT('no-digits-here', '[0-9]+', 1);
regexp_extract('no-digits-here', '[0-9]+', 1) |
===============================================
NULL |
```

#### REGEXP_IN_SET

```sql
Expand Down
83 changes: 62 additions & 21 deletions docs/zh/14-reference/03-taos-sql/22-function.md
Original file line number Diff line number Diff line change
Expand Up @@ -1044,6 +1044,47 @@ taos> select position('d' in 'cba');
0 |
```

#### REGEXP_EXTRACT

```sql
REGEXP_EXTRACT(expr, pattern [, group_idx])
```

**功能说明**:对 `expr` 应用 POSIX 扩展正则表达式 `pattern`,返回第 `group_idx` 个捕获组匹配的子串。无匹配、`expr` 或 `pattern` 为 NULL 时返回 NULL。

**返回结果类型**:与 `expr` 相同(VARCHAR 或 NCHAR)。

**适用数据类型**:`expr`:VARCHAR、NCHAR;`pattern`:VARCHAR、NCHAR。

**嵌套子查询支持**:适用于内层查询和外层查询。

**适用于**:表和超级表。

**使用说明**:

- `group_idx` 通常为非负整数常量,默认为 `1`。`0` 返回整个匹配串,`1` 返回第一个捕获组,`2` 返回第二个,以此类推,最大值为 512。若 `group_idx` 为 SQL `NULL`,则返回 `NULL`。
- 若 `group_idx` 超过 `pattern` 中的捕获组数量,或对应捕获组未参与匹配,返回 NULL。
- `pattern` 必须为常量(字面量或预处理占位符),不可引用列;不支持 `concat('a','b')` 这类常量表达式。

**举例**:

```sql
taos> SELECT REGEXP_EXTRACT('2026-04-22', '([0-9]{4})-([0-9]{2})-([0-9]{2})', 1);
regexp_extract('2026-04-22', '([0-9]{4})-([0-9]{2})-([0-9]{2})', 1) |
=======================================================================
2026 |

taos> SELECT REGEXP_EXTRACT('2026-04-22', '([0-9]{4})-([0-9]{2})-([0-9]{2})', 0);
regexp_extract('2026-04-22', '([0-9]{4})-([0-9]{2})-([0-9]{2})', 0) |
=======================================================================
2026-04-22 |

taos> SELECT REGEXP_EXTRACT('no-digits-here', '[0-9]+', 1);
regexp_extract('no-digits-here', '[0-9]+', 1) |
===============================================
NULL |
```

#### REGEXP_IN_SET

```sql
Expand Down Expand Up @@ -2369,11 +2410,11 @@ LAG(expr, offset[, default_val])
**使用说明**:

- `offset` 必须为大于 0 的整数。
- `default_val` 可选;当目标行不存在时返回该值,未指定时返回 `NULL`。
- `default_val` 需要与 `expr` 类型兼容。
- `LAG` 按输入结果集的行序计算;可以结合 `ORDER BY` 改变计算顺序。
- 支持与 `_rowts`、`tbname`、标签列等一起查询,也支持在子查询和 `PARTITION BY` 场景中使用。
- 与窗口一起使用时,`LAG` 仅在当前窗口内部按窗口内结果顺序计算,不会跨窗口继承上一窗口的状态。
- `default_val` 可选;当目标行不存在时返回该值,未指定时返回 `NULL`。
- `default_val` 需要与 `expr` 类型兼容。
- `LAG` 按输入结果集的行序计算;可以结合 `ORDER BY` 改变计算顺序。
- 支持与 `_rowts`、`tbname`、标签列等一起查询,也支持在子查询和 `PARTITION BY` 场景中使用。
- 与窗口一起使用时,`LAG` 仅在当前窗口内部按窗口内结果顺序计算,不会跨窗口继承上一窗口的状态。

#### LEAD

Expand All @@ -2392,11 +2433,11 @@ LEAD(expr, offset[, default_val])
**使用说明**:

- `offset` 必须为大于 0 的整数。
- `default_val` 可选;当目标行不存在时返回该值,未指定时返回 `NULL`。
- `default_val` 需要与 `expr` 类型兼容。
- `LEAD` 按输入结果集的行序计算;可以结合 `ORDER BY` 改变计算顺序。
- 支持与 `_rowts`、`tbname`、标签列等一起查询,也支持在子查询和 `PARTITION BY` 场景中使用。
- 与窗口一起使用时,`LEAD` 仅在当前窗口内部按窗口内结果顺序计算,不会跨窗口读取下一窗口的数据。
- `default_val` 可选;当目标行不存在时返回该值,未指定时返回 `NULL`。
- `default_val` 需要与 `expr` 类型兼容。
- `LEAD` 按输入结果集的行序计算;可以结合 `ORDER BY` 改变计算顺序。
- 支持与 `_rowts`、`tbname`、标签列等一起查询,也支持在子查询和 `PARTITION BY` 场景中使用。
- 与窗口一起使用时,`LEAD` 仅在当前窗口内部按窗口内结果顺序计算,不会跨窗口读取下一窗口的数据。

#### MAX

Expand Down Expand Up @@ -3155,11 +3196,11 @@ MAVG(expr, k)

**适用于**:表和超级表。

**使用说明**:

- 不支持 +、-、*、/ 运算,如 mavg(col1, k1) + mavg(col2, k1);
- 只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用;
- 与窗口一起使用时,`MAVG` 仅在当前窗口内部按样本顺序计算,不会跨窗口延续上一窗口的样本状态。
**使用说明**:
- 不支持 +、-、*、/ 运算,如 mavg(col1, k1) + mavg(col2, k1);
- 只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用;
- 与窗口一起使用时,`MAVG` 仅在当前窗口内部按样本顺序计算,不会跨窗口延续上一窗口的样本状态。

#### STATECOUNT

Expand All @@ -3182,9 +3223,9 @@ STATECOUNT(expr, oper, val)

**适用于**:表和超级表。

**使用说明**:

- 与窗口一起使用时,`STATECOUNT` 仅统计当前窗口内部的连续记录,不会跨窗口累计。
**使用说明**:
- 与窗口一起使用时,`STATECOUNT` 仅统计当前窗口内部的连续记录,不会跨窗口累计。

#### STATEDURATION

Expand All @@ -3208,9 +3249,9 @@ STATEDURATION(expr, oper, val, unit)

**适用于**:表和超级表。

**使用说明**:

- 与窗口一起使用时,`STATEDURATION` 仅统计当前窗口内部满足条件的连续时长,不会跨窗口累计。
**使用说明**:
- 与窗口一起使用时,`STATEDURATION` 仅统计当前窗口内部满足条件的连续时长,不会跨窗口累计。

### 时间加权统计

Expand Down
1 change: 1 addition & 0 deletions include/libs/function/functionMgt.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ typedef enum EFunctionType {
FUNCTION_TYPE_AES_DECRYPT,
FUNCTION_TYPE_SM4_ENCRYPT,
FUNCTION_TYPE_SM4_DECRYPT,
FUNCTION_TYPE_REGEXP_EXTRACT,

// conversion function
FUNCTION_TYPE_CAST = 2000,
Expand Down
5 changes: 5 additions & 0 deletions include/libs/scalar/scalar.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ int32_t crc32Function(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOut
int32_t findInSetFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t likeInSetFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t regexpInSetFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t regexpExtractFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);

// Maximum capture-group index accepted by regexp_extract() — shared between
// translate-time validation (builtins.c) and runtime validation (sclfunc.c).
#define REGEXP_EXTRACT_MAX_GROUP_IDX 512
int32_t generateTotpSecretFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t generateTotpCodeFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);

Expand Down
4 changes: 2 additions & 2 deletions source/libs/executor/src/externalwindowoperator.c
Original file line number Diff line number Diff line change
Expand Up @@ -2493,8 +2493,8 @@ static int32_t extWinApplyAggPostProjection(SOperatorInfo* pOperator, SExternalW

SSDataBlock* pSlice = pExtW->pProjTmpBlock;
TAOS_CHECK_EXIT(projectApplyFunctions(pExtW->projSupp.pExprInfo, pSlice, pSlice, pExtW->projSupp.pCtx,
pExtW->projSupp.numOfExprs, NULL, GET_STM_RTINFO(pOperator->pTaskInfo),
pOperator->pTaskInfo));
pExtW->projSupp.numOfExprs, NULL,
GET_STM_RTINFO(pOperator->pTaskInfo), pOperator->pTaskInfo));

int32_t numOfCols = taosArrayGetSize(pBlock->pDataBlock);
// TODO(perf): only copy back the slots actually written by projSupp, not all columns.
Expand Down
146 changes: 146 additions & 0 deletions source/libs/function/src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,117 @@ static int32_t translateRand(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
static int32_t translateSleep(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
FUNC_ERR_RET(validateParam(pFunc, pErrBuf, len));
pFunc->node.resType = (SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_INT].bytes, .type = TSDB_DATA_TYPE_INT};

return TSDB_CODE_SUCCESS;
}

static int32_t translateRegexpExtract(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
FUNC_ERR_RET(validateParam(pFunc, pErrBuf, len));
int32_t numOfParams = LIST_LENGTH(pFunc->pParameterList);

// param[1]: pattern must be a literal/parameter constant VALUE node.
// Constant expressions are not accepted here because regexp_extract
// currently validates only VALUE nodes.
SNode* pPatNode = nodesListGetNode(pFunc->pParameterList, 1);
if (QUERY_NODE_VALUE != nodeType(pPatNode)) {
return invaildFuncParaTypeErrMsg(
pErrBuf, len, "regexp_extract: pattern must be a literal or parameter constant");
}

// Validate the regex pattern compiles as POSIX ERE.
// For prepared-statement placeholders, literal may contain the placeholder
// token (for example "?") instead of the bound pattern. Prefer the
// materialized datum when available, and otherwise defer validation to
// runtime for placeholders. For NCHAR patterns datum.p holds UCS-4 vardata;
// convert it to UTF-8 to match the runtime path in regexpExtractFunction.
SValueNode* pPatVal = (SValueNode*)pPatNode;
{
const char* regPattern = NULL;
char* utf8Pat = NULL;
bool freeUtf8Pat = false;
bool deferValidation = (pPatVal->placeholderNo != 0 && pPatVal->datum.p == NULL);

if (!deferValidation) {
if (pPatVal->node.resType.type == TSDB_DATA_TYPE_NCHAR && pPatVal->datum.p != NULL) {
int32_t ncharBytes = varDataLen(pPatVal->datum.p);
utf8Pat = taosMemoryCalloc(ncharBytes + 1, 1);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The buffer allocation for the UTF-8 pattern is insufficient when the input is NCHAR. In TDengine, varDataLen for NCHAR returns the number of characters, but a single UCS-4 character can require up to 4 bytes in UTF-8. Allocating only ncharBytes + 1 bytes can lead to a buffer overflow during taosUcs4ToMbs.

        utf8Pat = taosMemoryCalloc(ncharBytes * 4 + 1, 1);

if (utf8Pat == NULL) return terrno;
int32_t utf8Len = taosUcs4ToMbs((TdUcs4*)varDataVal(pPatVal->datum.p), ncharBytes,
utf8Pat, pPatVal->charsetCxt);
Comment thread
stephenkgu marked this conversation as resolved.
if (utf8Len < 0) {
taosMemoryFree(utf8Pat);
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_PAR_REGULAR_EXPRESSION_ERROR,
"regexp_extract: failed to convert NCHAR pattern to UTF-8");
}
utf8Pat[utf8Len] = '\0';
regPattern = utf8Pat;
freeUtf8Pat = true;
} else if (pPatVal->datum.p != NULL) {
// datum.p is a length-prefixed vardata buffer — not NUL-terminated.
// Build a NUL-terminated copy for regcomp().
int32_t patBytes = varDataLen(pPatVal->datum.p);
utf8Pat = taosMemoryMalloc(patBytes + 1);
if (utf8Pat == NULL) return terrno;
(void)memcpy(utf8Pat, varDataVal(pPatVal->datum.p), patBytes);
utf8Pat[patBytes] = '\0';
regPattern = utf8Pat;
freeUtf8Pat = true;
} else {
regPattern = pPatVal->literal;
}
}

if (regPattern != NULL) {
regex_t re;
int ret = regcomp(&re, regPattern, REG_EXTENDED);
if (ret != 0) {
Comment thread
stephenkgu marked this conversation as resolved.
char msgbuf[256] = {0};
(void)regerror(ret, NULL, msgbuf, sizeof(msgbuf));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

According to the POSIX standard, regerror should be passed the pointer to the regex_t structure that was used in the regcomp call that failed. Passing NULL is not recommended as it may prevent the library from providing a specific error message.

        (void)regerror(ret, &re, msgbuf, sizeof(msgbuf));

// do not call regfree — regcomp failed, re contents are undefined (POSIX)
if (freeUtf8Pat) taosMemoryFree(utf8Pat);
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_PAR_REGULAR_EXPRESSION_ERROR,
"Invalid regex pattern for regexp_extract: %s", msgbuf);
}
regfree(&re); // only reached when regcomp succeeded
Comment thread
stephenkgu marked this conversation as resolved.
}
if (freeUtf8Pat) taosMemoryFree(utf8Pat);
}

// param[2]: group_idx (optional) must be a non-negative integer constant.
// NULL is also allowed by the builtin signature and should propagate like
// other scalar functions, so accept NULL-typed value nodes here and rely
// on runtime to return a NULL result.
if (numOfParams == 3) {
SNode* pIdxNode = nodesListGetNode(pFunc->pParameterList, 2);
if (QUERY_NODE_VALUE != nodeType(pIdxNode)) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, "regexp_extract: group_idx must be a constant integer");
}

SValueNode* pIdxVal = (SValueNode*)pIdxNode;
int32_t idxType = pIdxVal->node.resType.type;

if (TSDB_DATA_TYPE_NULL != idxType) {
if (!IS_INTEGER_TYPE(idxType)) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, "regexp_extract: group_idx must be an integer");
}
// Skip range validation for prepared-statement placeholders — the bound value
// is not yet known; the runtime check in regexpExtractFunction applies instead.
if (pIdxVal->placeholderNo == 0) {
int64_t groupIdx = taosStr2Int64(pIdxVal->literal, NULL, 10);
if (groupIdx < 0 || groupIdx > REGEXP_EXTRACT_MAX_GROUP_IDX) {
char errmsg[64];
(void)snprintf(errmsg, sizeof(errmsg),
"regexp_extract: group_idx must be between 0 and %d",
REGEXP_EXTRACT_MAX_GROUP_IDX);
return invaildFuncParaValueErrMsg(pErrBuf, len, errmsg);
}
}
}
}

// Return type matches str (param[0]): same VARCHAR/NCHAR type and byte width
pFunc->node.resType = *getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0));

return TSDB_CODE_SUCCESS;
}

Expand Down Expand Up @@ -7441,6 +7552,41 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.sprocessFunc = sleepFunction,
.finalizeFunc = NULL
},
{
.name = "regexp_extract",
.type = FUNCTION_TYPE_REGEXP_EXTRACT,
.classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC,
.parameters = {.minParamNum = 2,
.maxParamNum = 3,
.paramInfoPattern = 1,
.inputParaInfo[0][0] = {.isLastParam = false,
.startParam = 1,
.endParam = 1,
.validDataType = FUNC_PARAM_SUPPORT_VARCHAR_TYPE | FUNC_PARAM_SUPPORT_NCHAR_TYPE | FUNC_PARAM_SUPPORT_NULL_TYPE,
.validNodeType = FUNC_PARAM_SUPPORT_EXPR_NODE,
.paramAttribute = FUNC_PARAM_NO_SPECIFIC_ATTRIBUTE,
.valueRangeFlag = FUNC_PARAM_NO_SPECIFIC_VALUE,},
.inputParaInfo[0][1] = {.isLastParam = false,
.startParam = 2,
.endParam = 2,
.validDataType = FUNC_PARAM_SUPPORT_VARCHAR_TYPE | FUNC_PARAM_SUPPORT_NCHAR_TYPE | FUNC_PARAM_SUPPORT_NULL_TYPE,
.validNodeType = FUNC_PARAM_SUPPORT_VALUE_NODE,
.paramAttribute = FUNC_PARAM_NO_SPECIFIC_ATTRIBUTE,
.valueRangeFlag = FUNC_PARAM_NO_SPECIFIC_VALUE,},
.inputParaInfo[0][2] = {.isLastParam = true,
.startParam = 3,
.endParam = 3,
.validDataType = FUNC_PARAM_SUPPORT_INTEGER_TYPE | FUNC_PARAM_SUPPORT_NULL_TYPE,
.validNodeType = FUNC_PARAM_SUPPORT_VALUE_NODE,
.paramAttribute = FUNC_PARAM_NO_SPECIFIC_ATTRIBUTE,
.valueRangeFlag = FUNC_PARAM_NO_SPECIFIC_VALUE,},
.outputParaInfo = {.validDataType = FUNC_PARAM_SUPPORT_VARCHAR_TYPE | FUNC_PARAM_SUPPORT_NCHAR_TYPE}},
.translateFunc = translateRegexpExtract,
.getEnvFunc = NULL,
.initFunc = NULL,
.sprocessFunc = regexpExtractFunction,
.finalizeFunc = NULL,
},
};
// clang-format on

Expand Down
Loading
Loading