提交 3262f7e2 编写于 作者: S Shenglian Zhou

Merge branch 'develop' into feature/szhou/csum-sample-mavg

...@@ -44,13 +44,15 @@ TDengine是一个高效的存储、查询、分析时序大数据的平台,专 ...@@ -44,13 +44,15 @@ TDengine是一个高效的存储、查询、分析时序大数据的平台,专
* [SQL函数](/taos-sql#functions):支持各种聚合函数、选择函数、计算函数,如avg, min, diff等 * [SQL函数](/taos-sql#functions):支持各种聚合函数、选择函数、计算函数,如avg, min, diff等
* [窗口切分聚合](/taos-sql#aggregation):将表中数据按照时间段等方式进行切割后聚合,降维处理 * [窗口切分聚合](/taos-sql#aggregation):将表中数据按照时间段等方式进行切割后聚合,降维处理
* [边界限制](/taos-sql#limitation):库、表、SQL等边界限制条件 * [边界限制](/taos-sql#limitation):库、表、SQL等边界限制条件
* [UDF](/taos-sql/udf):用户定义函数的创建和管理方法
* [错误码](/taos-sql/error-code):TDengine 2.0 错误码以及对应的十进制码 * [错误码](/taos-sql/error-code):TDengine 2.0 错误码以及对应的十进制码
## [高效写入数据](/insert) ## [高效写入数据](/insert)
* [SQL写入](/insert#sql):使用SQL insert命令向一张或多张表写入单条或多条记录 * [SQL 写入](/insert#sql):使用SQL insert命令向一张或多张表写入单条或多条记录
* [Prometheus写入](/insert#prometheus):配置Prometheus, 不用任何代码,将数据直接写入 * [Schemaless 写入](/insert#schemaless):免于预先建表,将数据直接写入时自动维护元数据结构
* [Telegraf写入](/insert#telegraf):配置Telegraf, 不用任何代码,将采集数据直接写入 * [Prometheus 写入](/insert#prometheus):配置Prometheus, 不用任何代码,将数据直接写入
* [Telegraf 写入](/insert#telegraf):配置Telegraf, 不用任何代码,将采集数据直接写入
* [EMQ X Broker](/insert#emq):配置EMQ X,不用任何代码,就可将MQTT数据直接写入 * [EMQ X Broker](/insert#emq):配置EMQ X,不用任何代码,就可将MQTT数据直接写入
* [HiveMQ Broker](/insert#hivemq):配置HiveMQ,不用任何代码,就可将MQTT数据直接写入 * [HiveMQ Broker](/insert#hivemq):配置HiveMQ,不用任何代码,就可将MQTT数据直接写入
......
...@@ -250,7 +250,7 @@ vnode(虚拟数据节点)负责为采集的时序数据提供写入、查询和 ...@@ -250,7 +250,7 @@ vnode(虚拟数据节点)负责为采集的时序数据提供写入、查询和
创建DB时,系统并不会马上分配资源。但当创建一张表时,系统将看是否有已经分配的vnode, 且该vnode是否有空余的表空间,如果有,立即在该有空位的vnode创建表。如果没有,系统将从集群中,根据当前的负载情况,在一个dnode上创建一新的vnode, 然后创建表。如果DB有多个副本,系统不是只创建一个vnode,而是一个vgroup(虚拟数据节点组)。系统对vnode的数目没有任何限制,仅仅受限于物理节点本身的计算和存储资源。 创建DB时,系统并不会马上分配资源。但当创建一张表时,系统将看是否有已经分配的vnode, 且该vnode是否有空余的表空间,如果有,立即在该有空位的vnode创建表。如果没有,系统将从集群中,根据当前的负载情况,在一个dnode上创建一新的vnode, 然后创建表。如果DB有多个副本,系统不是只创建一个vnode,而是一个vgroup(虚拟数据节点组)。系统对vnode的数目没有任何限制,仅仅受限于物理节点本身的计算和存储资源。
每张表的meda data(包含schema, 标签等)也存放于vnode里,而不是集中存放于mnode,实际上这是对Meta数据的分片,这样便于高效并行的进行标签过滤操作。 每张表的meta data(包含schema, 标签等)也存放于vnode里,而不是集中存放于mnode,实际上这是对Meta数据的分片,这样便于高效并行的进行标签过滤操作。
### 数据分区 ### 数据分区
......
...@@ -56,7 +56,6 @@ measurement,tag_set field_set timestamp ...@@ -56,7 +56,6 @@ measurement,tag_set field_set timestamp
- 后缀为 i16,表示为 SMALLINT (INT16) 类型; - 后缀为 i16,表示为 SMALLINT (INT16) 类型;
- 后缀为 i32,表示为 INT (INT32) 类型; - 后缀为 i32,表示为 INT (INT32) 类型;
- 后缀为 i64,表示为 BIGINT (INT64) 类型; - 后缀为 i64,表示为 BIGINT (INT64) 类型;
- 后缀为 b,表示为 BOOL 类型。
* t, T, true, True, TRUE, f, F, false, False 将直接作为 BOOL 型来处理。 * t, T, true, True, TRUE, f, F, false, False 将直接作为 BOOL 型来处理。
timestamp 位置的时间戳通过后缀来声明时间精度,具体如下: timestamp 位置的时间戳通过后缀来声明时间精度,具体如下:
...@@ -72,13 +71,15 @@ timestamp 位置的时间戳通过后缀来声明时间精度,具体如下: ...@@ -72,13 +71,15 @@ timestamp 位置的时间戳通过后缀来声明时间精度,具体如下:
st,t1=3i64,t2=4f64,t3="t3" c1=3i64,c3=L"passit",c2=false,c4=4f64 1626006833639000000ns st,t1=3i64,t2=4f64,t3="t3" c1=3i64,c3=L"passit",c2=false,c4=4f64 1626006833639000000ns
``` ```
需要注意的是,如果描述数据类型后缀时使用了错误的大小写,或者为数据指定的数据类型有误,均可能引发报错提示而导致数据写入失败。
### Schemaless 的处理逻辑 ### Schemaless 的处理逻辑
Schemaless 按照如下原则来处理行数据: Schemaless 按照如下原则来处理行数据:
1. 当 tag_set 中有 ID 字段时,该字段的值将作为数据子表的表名。 1. 当 tag_set 中有 ID 字段时,该字段的值将作为数据子表的表名。
2. 没有 ID 字段时,将使用 `measurement + tag_value1 + tag_value2 + ...` 的 md5 值来作为子表名。 2. 没有 ID 字段时,将使用 `measurement + tag_value1 + tag_value2 + ...` 的 md5 值来作为子表名。
3. 如果指定的超级表名不存在,则 Schemaless 会创建这个超级表。 3. 如果指定的超级表名不存在,则 Schemaless 会创建这个超级表。
4. 如果指定的数据子表不存在,则 Schemaless 会使用 tag values 创建这个数据子表。 4. 如果指定的数据子表不存在,则 Schemaless 会按照步骤 1 或 2 确定的子表名来创建子表。
5. 如果数据行中指定的标签列或普通列不存在,则 Schemaless 会在超级表中增加对应的标签列或普通列(只增不减)。 5. 如果数据行中指定的标签列或普通列不存在,则 Schemaless 会在超级表中增加对应的标签列或普通列(只增不减)。
6. 如果超级表中存在一些标签列或普通列未在一个数据行中被指定取值,那么这些列的值在这一行中会被置为 NULL。 6. 如果超级表中存在一些标签列或普通列未在一个数据行中被指定取值,那么这些列的值在这一行中会被置为 NULL。
7. 对 BINARY 或 NCHAR 列,如果数据行中所提供值的长度超出了列类型的限制,那么 Schemaless 会增加该列允许存储的字符长度上限(只增不减),以保证数据的完整保存。 7. 对 BINARY 或 NCHAR 列,如果数据行中所提供值的长度超出了列类型的限制,那么 Schemaless 会增加该列允许存储的字符长度上限(只增不减),以保证数据的完整保存。
......
...@@ -776,7 +776,7 @@ curl -u username:password -d '<SQL>' <ip>:<PORT>/rest/sql/[db_name] ...@@ -776,7 +776,7 @@ curl -u username:password -d '<SQL>' <ip>:<PORT>/rest/sql/[db_name]
- data: 具体返回的数据,一行一行的呈现,如果不返回结果集,那么就仅有 [[affected_rows]]。data 中每一行的数据列顺序,与 column_meta 中描述数据列的顺序完全一致。 - data: 具体返回的数据,一行一行的呈现,如果不返回结果集,那么就仅有 [[affected_rows]]。data 中每一行的数据列顺序,与 column_meta 中描述数据列的顺序完全一致。
- rows: 表明总共多少行数据。 - rows: 表明总共多少行数据。
column_meta 中的列类型说明: <a class="anchor" id="column_meta"></a>column_meta 中的列类型说明:
* 1:BOOL * 1:BOOL
* 2:TINYINT * 2:TINYINT
* 3:SMALLINT * 3:SMALLINT
......
# UDF(用户定义函数)
在有些应用场景中,应用逻辑需要的查询无法直接使用系统内置的函数来表示。利用 UDF 功能,TDengine 可以插入用户编写的处理代码并在查询中使用它们,就能够很方便地解决特殊应用场景中的使用需求。
从 2.2.0.0 版本开始,TDengine 支持通过 C/C++ 语言进行 UDF 定义。接下来结合示例讲解 UDF 的使用方法。
## 用 C/C++ 语言来定义 UDF
TDengine 提供 3 个 UDF 的源代码示例,分别为:
* [add_one.c](https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/add_one.c)
* [abs_max.c](https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/abs_max.c)
* [sum_double.c](https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/sum_double.c)
### 无需中间变量的标量函数
[add_one.c](https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/add_one.c) 是结构最简单的 UDF 实现。其功能为:对传入的一个数据列(可能因 WHERE 子句进行了筛选)中的每一项,都输出 +1 之后的值,并且要求输入的列数据类型为 INT。
这一具体的处理逻辑在函数 `void add_one(char* data, short itype, short ibytes, int numOfRows, long long* ts, char* dataOutput, char* interBUf, char* tsOutput, int* numOfOutput, short otype, short obytes, SUdfInit* buf)` 中定义。这类用于实现 UDF 的基础计算逻辑的函数,我们称为 udfNormalFunc,也就是对行数据块的标量计算函数。需要注意的是,udfNormalFunc 的参数项是固定的,用于按照约束完成与引擎之间的数据交换。
- udfNormalFunc 中各参数的具体含义是:
* data:存有输入的数据。
* itype:输入数据的类型。这里采用的是短整型表示法,与各种数据类型对应的值可以参见 [column_meta 中的列类型说明](https://www.taosdata.com/cn/documentation/connector#column_meta)。例如 4 用于表示 INT 型。
* iBytes:输入数据中每个值会占用的字节数。
* numOfRows:输入数据的总行数。
* ts:主键时间戳在输入中的列数据。
* dataOutput:输出数据的缓冲区。
* interBuf:系统使用的中间临时缓冲区,通常用户逻辑无需对 interBuf 进行处理。
* tsOutput:主键时间戳在输出时的列数据。
* numOfOutput:输出数据的个数。
* oType:输出数据的类型。取值含义与 itype 参数一致。
* oBytes:输出数据中每个值会占用的字节数。
* buf:计算过程的中间变量缓冲区。
其中 buf 参数需要用到一个自定义结构体 SUdfInit。在这个例子中,因为 add_one 的计算过程无需用到中间变量缓存,所以可以把 SUdfInit 定义成一个空结构体。
### 无需中间变量的聚合函数
[abs_max.c](https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/abs_max.c) 实现的是一个聚合函数,功能是对一组数据按绝对值取最大值。
其计算过程为:与所在查询语句相关的数据会被分为多个行数据块,对每个行数据块调用 udfNormalFunc(在本例的实现代码中,实际函数名是 `abs_max`),再将每个数据块的计算结果调用 udfMergeFunc(本例中,其实际的函数名是 `abs_max_merge`)进行聚合,生成每个子表的聚合结果。如果查询指令涉及超级表,那么最后还会通过 udfFinalizeFunc(本例中,其实际的函数名是 `abs_max_finalize`)再把子表的计算结果聚合为超级表的计算结果。
值得注意的是,udfNormalFunc、udfMergeFunc、udfFinalizeFunc 之间,函数名约定使用相同的前缀,此前缀即 udfNormalFunc 的实际函数名。udfMergeFunc 的函数名后缀 `_merge`、udfFinalizeFunc 的函数名后缀 `_finalize`,是 UDF 实现规则的一部分,系统会按照这些函数名后缀来调用相应功能。
- udfMergeFunc 用于对计算中间结果进行聚合。本例中 udfMergeFunc 对应的实现函数为 `void abs_max_merge(char* data, int32_t numOfRows, char* dataOutput, int32_t* numOfOutput, SUdfInit* buf)`,其中各参数的具体含义是:
* data:udfNormalFunc 的输出组合在一起的数据,也就成为了 udfMergeFunc 的输入。
* numOfRows:data 中数据的行数。
* dataOutput:输出数据的缓冲区。
* numOfOutput:输出数据的个数。
* buf:计算过程的中间变量缓冲区。
- udfFinalizeFunc 用于对计算结果进行最终聚合。本例中 udfFinalizeFunc 对应的实现函数为 `void abs_max_finalize(char* dataOutput, char* interBuf, int* numOfOutput, SUdfInit* buf)`,其中各参数的具体含义是:
* dataOutput:输出数据的缓冲区。对 udfFinalizeFunc 来说,其输入数据也来自于这里。
* interBuf:系统使用的中间临时缓冲区,与 udfNormalFunc 中的同名参数含义一致。
* numOfOutput:输出数据的个数。
* buf:计算过程的中间变量缓冲区。
同样因为 abs_max 的计算过程无需用到中间变量缓存,所以同样是可以把 SUdfInit 定义成一个空结构体。
### 使用中间变量的聚合函数
[sum_double.c](https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/sum_double.c) 也是一个聚合函数,功能是对一组数据输出求和结果的倍数。
出于功能演示的目的,在这个用户定义函数的实现方法中,用到了中间变量缓冲区 buf。因此,在这个源代码文件中,SUdfInit 就不再是一个空的结构体,而是定义了缓冲区的具体存储内容。
也正是因为用到了中间变量缓冲区,因此就需要对这一缓冲区进行初始化和资源释放。具体来说,也即对应 udfInitFunc(本例中,其实际的函数名是 `sum_double_init`)和 udfDestroyFunc(本例中,其实际的函数名是 `sum_double_destroy`)。其函数名命名规则同样是采取以 udfNormalFunc 的实际函数名为前缀,以 `_init``_destroy` 为后缀。系统会在初始化和资源释放时调用对应名称的函数。
- udfInitFunc 用于初始化中间变量缓冲区中的变量和内容。本例中 udfInitFunc 对应的实现函数为 `int sum_double_init(SUdfInit* buf)`,其中各参数的具体含义是:
* buf:计算过程的中间变量缓冲区。
- udfDestroyFunc 用于释放中间变量缓冲区中的变量和内容。本例中 udfDestroyFunc 对应的实现函数为 `void sum_double_destroy(SUdfInit* buf)`,其中各参数的具体含义是:
* buf:计算过程的中间变量缓冲区。
注意,UDF 的实现过程中需要小心处理对中间变量缓冲区的使用,如果使用不当则有可能导致内存泄露或对资源的过度占用,甚至导致系统服务进程崩溃等。
### UDF 实现方式的规则总结
根据所要实现的 UDF 类型不同,用户所要实现的功能函数内容也会有所区别:
* 无需中间变量的标量函数:结构体 SUdfInit 可以为空,需实现 udfNormalFunc。
* 无需中间变量的聚合函数:结构体 SUdfInit 可以为空,需实现 udfNormalFunc、udfMergeFunc、udfFinalizeFunc。
* 使用中间变量的标量函数:结构体 SUdfInit 需要具体定义,并需实现 udfNormalFunc、udfInitFunc、udfDestroyFunc。
* 使用中间变量的聚合函数:结构体 SUdfInit 需要具体定义,并需实现 udfNormalFunc、udfInitFunc、udfDestroyFunc、udfMergeFunc、udfFinalizeFunc。
## 编译 UDF
用户定义函数的 C 语言源代码无法直接被 TDengine 系统使用,而是需要先编译为 .so 链接库,之后才能载入 TDengine 系统。
例如,按照上一章节描述的规则准备好了用户定义函数的源代码 add_one.c,那么可以执行如下指令编译得到动态链接库文件:
```bash
gcc -g -O0 -fPIC -shared add_one.c -o add_one.so
```
这样就准备好了动态链接库 add_one.so 文件,可以供后文创建 UDF 时使用了。
## 在系统中管理和使用 UDF
### 创建 UDF
用户可以通过 SQL 指令在系统中加载客户端所在主机上的 UDF 函数库(不能通过 RESTful 接口或 HTTP 管理界面来进行这一过程)。一旦创建成功,则当前 TDengine 集群的所有用户都可以在 SQL 指令中使用这些函数。UDF 存储在系统的 MNode 节点上,因此即使重启 TDengine 系统,已经创建的 UDF 也仍然可用。
在创建 UDF 时,需要区分标量函数和聚合函数。如果创建时声明了错误的函数类别,则可能导致通过 SQL 指令调用函数时出错。
- 创建标量函数:`CREATE FUNCTION ids(X) AS ids(Y) OUTPUTTYPE typename(Z) bufsize(B);`
* X:标量函数未来在 SQL 指令中被调用时的函数名,必须与函数实现中 udfNormalFunc 的实际名称一致;
* Y:包含 UDF 函数实现的动态链接库的库文件路径(指的是库文件在当前客户端所在主机上的保存路径,通常是指向一个 .so 文件);
* Z:此函数计算结果的数据类型,使用数字表示,含义与上文中 udfNormalFunc 的 itype 参数一致;
* B:系统使用的中间临时缓冲区大小,单位是字节,最小 0,最大 512,通常可以设置为 128。
- 创建聚合函数:`CREATE AGGREGATE FUNCTION ids(X) AS ids(Y) OUTPUTTYPE typename(Z) bufsize(B);`
* X:标量函数未来在 SQL 指令中被调用时的函数名,必须与函数实现中 udfNormalFunc 的实际名称一致;
* Y:包含 UDF 函数实现的动态链接库的库文件路径(指的是库文件在当前客户端所在主机上的保存路径,通常是指向一个 .so 文件);
* Z:此函数计算结果的数据类型,使用数字表示,含义与上文中 udfNormalFunc 的 itype 参数一致;
* B:系统使用的中间临时缓冲区大小,单位是字节,最小 0,最大 512,通常可以设置为 128。
### 管理 UDF
- 删除指定名称的用户定义函数:`DROP FUNCTION ids(X);`
* X:此参数的含义与 CREATE 指令中的 X 参数一致。
- 显示系统中当前可用的所有 UDF:`SHOW FUNCTIONS;`
### 调用 UDF
在 SQL 指令中,可以直接以在系统中创建 UDF 时赋予的函数名来调用用户定义函数。例如:
```sql
SELECT X(c) FROM table/stable;
```
表示对名为 c 的数据列调用名为 X 的用户定义函数。SQL 指令中用户定义函数可以配合 WHERE 等查询特性来使用。
## UDF 的一些使用限制
在当前版本下,使用 UDF 存在如下这些限制:
1. UDF 不能与系统内建的 SQL 函数混合使用;
2. UDF 只支持以单个数据列作为输入;
3. UDF 只要创建成功,就会被持久化存储到 MNode 节点中;
4. 无法通过 RESTful 接口来创建 UDF;
5. UDF 在 SQL 中定义的函数名,必须与 .so 库文件实现中的接口函数名前缀保持一致,也即必须是 udfNormalFunc 的名称,而且不可与 TDengine 中已有的内建 SQL 函数重名。
...@@ -413,11 +413,11 @@ See [video tutorials](https://www.taosdata.com/blog/2020/11/11/1963.html) for th ...@@ -413,11 +413,11 @@ See [video tutorials](https://www.taosdata.com/blog/2020/11/11/1963.html) for th
Users can find the connector package for python2 and python3 in the source code src/connector/python (or tar.gz/connector/python) folder. Users can install it through `pip` command: Users can find the connector package for python2 and python3 in the source code src/connector/python (or tar.gz/connector/python) folder. Users can install it through `pip` command:
`pip install src/connector/python/linux/python2/` `pip install src/connector/python/`
or or
`pip3 install src/connector/python/linux/python3/` `pip3 install src/connector/python/`
#### Windows #### Windows
......
...@@ -128,8 +128,12 @@ function install_lib() { ...@@ -128,8 +128,12 @@ function install_lib() {
${csudo} ln -s ${install_main_dir}/driver/libtaos.* ${lib_link_dir}/libtaos.1.dylib ${csudo} ln -s ${install_main_dir}/driver/libtaos.* ${lib_link_dir}/libtaos.1.dylib
${csudo} ln -s ${lib_link_dir}/libtaos.1.dylib ${lib_link_dir}/libtaos.dylib ${csudo} ln -s ${lib_link_dir}/libtaos.1.dylib ${lib_link_dir}/libtaos.dylib
fi fi
${csudo} ldconfig if [ "$osType" != "Darwin" ]; then
${csudo} ldconfig
else
${csudo} update_dyld_shared_cache
fi
} }
function install_header() { function install_header() {
......
...@@ -281,6 +281,8 @@ static uint8_t convertRelationalOperator(SStrToken *pToken) { ...@@ -281,6 +281,8 @@ static uint8_t convertRelationalOperator(SStrToken *pToken) {
return TSDB_RELATION_LIKE; return TSDB_RELATION_LIKE;
case TK_MATCH: case TK_MATCH:
return TSDB_RELATION_MATCH; return TSDB_RELATION_MATCH;
case TK_NMATCH:
return TSDB_RELATION_NMATCH;
case TK_ISNULL: case TK_ISNULL:
return TSDB_RELATION_ISNULL; return TSDB_RELATION_ISNULL;
case TK_NOTNULL: case TK_NOTNULL:
...@@ -3782,6 +3784,9 @@ static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, ...@@ -3782,6 +3784,9 @@ static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo,
case TK_MATCH: case TK_MATCH:
pColumnFilter->lowerRelOptr = TSDB_RELATION_MATCH; pColumnFilter->lowerRelOptr = TSDB_RELATION_MATCH;
break; break;
case TK_NMATCH:
pColumnFilter->lowerRelOptr = TSDB_RELATION_NMATCH;
break;
case TK_ISNULL: case TK_ISNULL:
pColumnFilter->lowerRelOptr = TSDB_RELATION_ISNULL; pColumnFilter->lowerRelOptr = TSDB_RELATION_ISNULL;
break; break;
...@@ -3846,15 +3851,17 @@ static int32_t tablenameListToString(tSqlExpr* pExpr, SStringBuilder* sb) { ...@@ -3846,15 +3851,17 @@ static int32_t tablenameListToString(tSqlExpr* pExpr, SStringBuilder* sb) {
} }
static int32_t tablenameCondToString(tSqlExpr* pExpr, uint32_t opToken, SStringBuilder* sb) { static int32_t tablenameCondToString(tSqlExpr* pExpr, uint32_t opToken, SStringBuilder* sb) {
assert(opToken == TK_LIKE || opToken == TK_MATCH); assert(opToken == TK_LIKE || opToken == TK_MATCH || opToken == TK_NMATCH);
if (opToken == TK_LIKE) { if (opToken == TK_LIKE) {
taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_LIKE, QUERY_COND_REL_PREFIX_LIKE_LEN); taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_LIKE, QUERY_COND_REL_PREFIX_LIKE_LEN);
taosStringBuilderAppendString(sb, pExpr->value.pz); taosStringBuilderAppendString(sb, pExpr->value.pz);
} else if (opToken == TK_MATCH) { } else if (opToken == TK_MATCH) {
taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_MATCH, QUERY_COND_REL_PREFIX_MATCH_LEN); taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_MATCH, QUERY_COND_REL_PREFIX_MATCH_LEN);
taosStringBuilderAppendString(sb, pExpr->value.pz); taosStringBuilderAppendString(sb, pExpr->value.pz);
} else if (opToken == TK_NMATCH) {
taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_NMATCH, QUERY_COND_REL_PREFIX_NMATCH_LEN);
taosStringBuilderAppendString(sb, pExpr->value.pz);
} }
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
...@@ -3903,12 +3910,13 @@ static int32_t checkColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCol ...@@ -3903,12 +3910,13 @@ static int32_t checkColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCol
&& pExpr->tokenId != TK_NOTNULL && pExpr->tokenId != TK_NOTNULL
&& pExpr->tokenId != TK_LIKE && pExpr->tokenId != TK_LIKE
&& pExpr->tokenId != TK_MATCH && pExpr->tokenId != TK_MATCH
&& pExpr->tokenId != TK_NMATCH
&& pExpr->tokenId != TK_IN) { && pExpr->tokenId != TK_IN) {
ret = invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); ret = invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
goto _err_ret; goto _err_ret;
} }
} else { } else {
if (pExpr->tokenId == TK_LIKE || pExpr->tokenId == TK_MATCH) { if (pExpr->tokenId == TK_LIKE || pExpr->tokenId == TK_MATCH || pExpr->tokenId == TK_NMATCH) {
ret = invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); ret = invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
goto _err_ret; goto _err_ret;
} }
...@@ -3956,7 +3964,7 @@ static int32_t getTablenameCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* ...@@ -3956,7 +3964,7 @@ static int32_t getTablenameCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr*
if (pTableCond->tokenId == TK_IN) { if (pTableCond->tokenId == TK_IN) {
ret = tablenameListToString(pRight, sb); ret = tablenameListToString(pRight, sb);
} else if (pTableCond->tokenId == TK_LIKE || pTableCond->tokenId == TK_MATCH) { } else if (pTableCond->tokenId == TK_LIKE || pTableCond->tokenId == TK_MATCH || pTableCond->tokenId == TK_NMATCH) {
if (pRight->tokenId != TK_STRING) { if (pRight->tokenId != TK_STRING) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
} }
...@@ -4410,7 +4418,7 @@ static bool validateJoinExprNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr ...@@ -4410,7 +4418,7 @@ static bool validateJoinExprNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr
} }
static bool validTableNameOptr(tSqlExpr* pExpr) { static bool validTableNameOptr(tSqlExpr* pExpr) {
const char nameFilterOptr[] = {TK_IN, TK_LIKE, TK_MATCH}; const char nameFilterOptr[] = {TK_IN, TK_LIKE, TK_MATCH, TK_NMATCH};
for (int32_t i = 0; i < tListLen(nameFilterOptr); ++i) { for (int32_t i = 0; i < tListLen(nameFilterOptr); ++i) {
if (pExpr->tokenId == nameFilterOptr[i]) { if (pExpr->tokenId == nameFilterOptr[i]) {
...@@ -4505,13 +4513,13 @@ static int32_t validateLikeExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t ...@@ -4505,13 +4513,13 @@ static int32_t validateLikeExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t
// check for match expression // check for match expression
static int32_t validateMatchExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t index, char* msgBuf) { static int32_t validateMatchExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t index, char* msgBuf) {
const char* msg1 = "regular expression string should be less than %d characters"; const char* msg1 = "regular expression string should be less than %d characters";
const char* msg2 = "illegal column type for match"; const char* msg2 = "illegal column type for match/nmatch";
const char* msg3 = "invalid regular expression"; const char* msg3 = "invalid regular expression";
tSqlExpr* pLeft = pExpr->pLeft; tSqlExpr* pLeft = pExpr->pLeft;
tSqlExpr* pRight = pExpr->pRight; tSqlExpr* pRight = pExpr->pRight;
if (pExpr->tokenId == TK_MATCH) { if (pExpr->tokenId == TK_MATCH || pExpr->tokenId == TK_NMATCH) {
if (pRight->value.nLen > tsMaxRegexStringLen) { if (pRight->value.nLen > tsMaxRegexStringLen) {
char tmp[64] = {0}; char tmp[64] = {0};
sprintf(tmp, msg1, tsMaxRegexStringLen); sprintf(tmp, msg1, tsMaxRegexStringLen);
...@@ -4519,10 +4527,14 @@ static int32_t validateMatchExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_ ...@@ -4519,10 +4527,14 @@ static int32_t validateMatchExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_
} }
SSchema* pSchema = tscGetTableSchema(pTableMeta); SSchema* pSchema = tscGetTableSchema(pTableMeta);
if ((!isTablenameToken(&pLeft->columnName)) && !IS_VAR_DATA_TYPE(pSchema[index].type)) { if ((!isTablenameToken(&pLeft->columnName)) &&(pSchema[index].type != TSDB_DATA_TYPE_BINARY)) {
return invalidOperationMsg(msgBuf, msg2); return invalidOperationMsg(msgBuf, msg2);
} }
if (!(pRight->type == SQL_NODE_VALUE && pRight->value.nType == TSDB_DATA_TYPE_BINARY)) {
return invalidOperationMsg(msgBuf, msg3);
}
int errCode = 0; int errCode = 0;
regex_t regex; regex_t regex;
char regErrBuf[256] = {0}; char regErrBuf[256] = {0};
...@@ -4925,9 +4937,12 @@ static int32_t setTableCondForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, ...@@ -4925,9 +4937,12 @@ static int32_t setTableCondForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo,
STagCond* pTagCond = &pQueryInfo->tagCond; STagCond* pTagCond = &pQueryInfo->tagCond;
pTagCond->tbnameCond.uid = pTableMetaInfo->pTableMeta->id.uid; pTagCond->tbnameCond.uid = pTableMetaInfo->pTableMeta->id.uid;
assert(pExpr->tokenId == TK_LIKE || pExpr->tokenId == TK_MATCH || pExpr->tokenId == TK_IN); assert(pExpr->tokenId == TK_LIKE
|| pExpr->tokenId == TK_MATCH
|| pExpr->tokenId == TK_NMATCH
|| pExpr->tokenId == TK_IN);
if (pExpr->tokenId == TK_LIKE || pExpr->tokenId == TK_MATCH) { if (pExpr->tokenId == TK_LIKE || pExpr->tokenId == TK_MATCH || pExpr->tokenId == TK_NMATCH) {
char* str = taosStringBuilderGetResult(sb, NULL); char* str = taosStringBuilderGetResult(sb, NULL);
pQueryInfo->tagCond.tbnameCond.cond = strdup(str); pQueryInfo->tagCond.tbnameCond.cond = strdup(str);
pQueryInfo->tagCond.tbnameCond.len = (int32_t) strlen(str); pQueryInfo->tagCond.tbnameCond.len = (int32_t) strlen(str);
...@@ -8224,11 +8239,12 @@ static int32_t handleExprInHavingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, S ...@@ -8224,11 +8239,12 @@ static int32_t handleExprInHavingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, S
&& pExpr->tokenId != TK_NOTNULL && pExpr->tokenId != TK_NOTNULL
&& pExpr->tokenId != TK_LIKE && pExpr->tokenId != TK_LIKE
&& pExpr->tokenId != TK_MATCH && pExpr->tokenId != TK_MATCH
&& pExpr->tokenId != TK_NMATCH
) { ) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
} }
} else { } else {
if (pExpr->tokenId == TK_LIKE || pExpr->tokenId == TK_MATCH) { if (pExpr->tokenId == TK_LIKE || pExpr->tokenId == TK_MATCH || pExpr->tokenId == TK_NMATCH) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
} }
......
...@@ -34,10 +34,12 @@ struct SSchema; ...@@ -34,10 +34,12 @@ struct SSchema;
#define QUERY_COND_REL_PREFIX_IN "IN|" #define QUERY_COND_REL_PREFIX_IN "IN|"
#define QUERY_COND_REL_PREFIX_LIKE "LIKE|" #define QUERY_COND_REL_PREFIX_LIKE "LIKE|"
#define QUERY_COND_REL_PREFIX_MATCH "MATCH|" #define QUERY_COND_REL_PREFIX_MATCH "MATCH|"
#define QUERY_COND_REL_PREFIX_NMATCH "NMATCH|"
#define QUERY_COND_REL_PREFIX_IN_LEN 3 #define QUERY_COND_REL_PREFIX_IN_LEN 3
#define QUERY_COND_REL_PREFIX_LIKE_LEN 5 #define QUERY_COND_REL_PREFIX_LIKE_LEN 5
#define QUERY_COND_REL_PREFIX_MATCH_LEN 6 #define QUERY_COND_REL_PREFIX_MATCH_LEN 6
#define QUERY_COND_REL_PREFIX_NMATCH_LEN 7
typedef bool (*__result_filter_fn_t)(const void *, void *); typedef bool (*__result_filter_fn_t)(const void *, void *);
typedef void (*__do_filter_suppl_fn_t)(void *, void *); typedef void (*__do_filter_suppl_fn_t)(void *, void *);
......
...@@ -440,7 +440,16 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) { ...@@ -440,7 +440,16 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) {
memcpy(pVal->pz, tbnameCond + QUERY_COND_REL_PREFIX_MATCH_LEN, len); memcpy(pVal->pz, tbnameCond + QUERY_COND_REL_PREFIX_MATCH_LEN, len);
pVal->nType = TSDB_DATA_TYPE_BINARY; pVal->nType = TSDB_DATA_TYPE_BINARY;
pVal->nLen = (int32_t)len; pVal->nLen = (int32_t)len;
} else if (strncmp(tbnameCond, QUERY_COND_REL_PREFIX_NMATCH, QUERY_COND_REL_PREFIX_NMATCH_LEN) == 0) {
right->nodeType = TSQL_NODE_VALUE;
expr->_node.optr = TSDB_RELATION_NMATCH;
tVariant* pVal = exception_calloc(1, sizeof(tVariant));
right->pVal = pVal;
size_t len = strlen(tbnameCond + QUERY_COND_REL_PREFIX_NMATCH_LEN) + 1;
pVal->pz = exception_malloc(len);
memcpy(pVal->pz, tbnameCond + QUERY_COND_REL_PREFIX_NMATCH_LEN, len);
pVal->nType = TSDB_DATA_TYPE_BINARY;
pVal->nLen = (int32_t)len;
} else if (strncmp(tbnameCond, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN) == 0) { } else if (strncmp(tbnameCond, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN) == 0) {
right->nodeType = TSQL_NODE_VALUE; right->nodeType = TSQL_NODE_VALUE;
expr->_node.optr = TSDB_RELATION_IN; expr->_node.optr = TSDB_RELATION_IN;
......
...@@ -1039,6 +1039,16 @@ static void doInitGlobalConfig(void) { ...@@ -1039,6 +1039,16 @@ static void doInitGlobalConfig(void) {
cfg.unitType = TAOS_CFG_UTYPE_BYTE; cfg.unitType = TAOS_CFG_UTYPE_BYTE;
taosInitConfigOption(cfg); taosInitConfigOption(cfg);
cfg.option = "maxRegexStringLen";
cfg.ptr = &tsMaxRegexStringLen;
cfg.valType = TAOS_CFG_VTYPE_INT32;
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_CLIENT | TSDB_CFG_CTYPE_B_SHOW;
cfg.minValue = 0;
cfg.maxValue = TSDB_MAX_FIELD_LEN;
cfg.ptrLength = 0;
cfg.unitType = TAOS_CFG_UTYPE_BYTE;
taosInitConfigOption(cfg);
cfg.option = "maxNumOfOrderedRes"; cfg.option = "maxNumOfOrderedRes";
cfg.ptr = &tsMaxNumOfOrderedResults; cfg.ptr = &tsMaxNumOfOrderedResults;
cfg.valType = TAOS_CFG_VTYPE_INT32; cfg.valType = TAOS_CFG_VTYPE_INT32;
......
...@@ -113,6 +113,7 @@ ...@@ -113,6 +113,7 @@
</includes> </includes>
<excludes> <excludes>
<exclude>**/AppMemoryLeakTest.java</exclude> <exclude>**/AppMemoryLeakTest.java</exclude>
<exclude>**/JDBCTypeAndTypeCompareTest.java</exclude>
<exclude>**/ConnectMultiTaosdByRestfulWithDifferentTokenTest.java</exclude> <exclude>**/ConnectMultiTaosdByRestfulWithDifferentTokenTest.java</exclude>
<exclude>**/DatetimeBefore1970Test.java</exclude> <exclude>**/DatetimeBefore1970Test.java</exclude>
<exclude>**/FailOverTest.java</exclude> <exclude>**/FailOverTest.java</exclude>
......
package com.taosdata.jdbc.cases;
import org.junit.Test;
import java.sql.*;
public class JDBCTypeAndTypeCompareTest {
@Test
public void test() throws SQLException {
Connection conn = DriverManager.getConnection("jdbc:TAOS://192.168.17.156:6030/", "root", "taosdata");
Statement stmt = conn.createStatement();
stmt.execute("drop database if exists test");
stmt.execute("create database if not exists test");
stmt.execute("use test");
stmt.execute("create table weather(ts timestamp, f1 int, f2 bigint, f3 float, f4 double, f5 smallint, f6 tinyint, f7 bool, f8 binary(10), f9 nchar(10) )");
stmt.execute("insert into weather values(now, 1, 2, 3.0, 4.0, 5, 6, true, 'test','test')");
ResultSet rs = stmt.executeQuery("select * from weather");
ResultSetMetaData meta = rs.getMetaData();
while (rs.next()) {
for (int i = 1; i <= meta.getColumnCount(); i++) {
String columnName = meta.getColumnName(i);
String columnTypeName = meta.getColumnTypeName(i);
Object value = rs.getObject(i);
System.out.printf("columnName : %s, columnTypeName: %s, JDBCType: %s\n", columnName, columnTypeName, value.getClass().getName());
}
}
stmt.close();
conn.close();
}
}
...@@ -165,6 +165,7 @@ do { \ ...@@ -165,6 +165,7 @@ do { \
#define TSDB_RELATION_NOT 13 #define TSDB_RELATION_NOT 13
#define TSDB_RELATION_MATCH 14 #define TSDB_RELATION_MATCH 14
#define TSDB_RELATION_NMATCH 15
#define TSDB_BINARY_OP_ADD 30 #define TSDB_BINARY_OP_ADD 30
#define TSDB_BINARY_OP_SUBTRACT 31 #define TSDB_BINARY_OP_SUBTRACT 31
......
...@@ -38,179 +38,180 @@ ...@@ -38,179 +38,180 @@
#define TK_IS 20 #define TK_IS 20
#define TK_LIKE 21 #define TK_LIKE 21
#define TK_MATCH 22 #define TK_MATCH 22
#define TK_GLOB 23 #define TK_NMATCH 23
#define TK_BETWEEN 24 #define TK_GLOB 24
#define TK_IN 25 #define TK_BETWEEN 25
#define TK_GT 26 #define TK_IN 26
#define TK_GE 27 #define TK_GT 27
#define TK_LT 28 #define TK_GE 28
#define TK_LE 29 #define TK_LT 29
#define TK_BITAND 30 #define TK_LE 30
#define TK_BITOR 31 #define TK_BITAND 31
#define TK_LSHIFT 32 #define TK_BITOR 32
#define TK_RSHIFT 33 #define TK_LSHIFT 33
#define TK_PLUS 34 #define TK_RSHIFT 34
#define TK_MINUS 35 #define TK_PLUS 35
#define TK_DIVIDE 36 #define TK_MINUS 36
#define TK_TIMES 37 #define TK_DIVIDE 37
#define TK_STAR 38 #define TK_TIMES 38
#define TK_SLASH 39 #define TK_STAR 39
#define TK_REM 40 #define TK_SLASH 40
#define TK_CONCAT 41 #define TK_REM 41
#define TK_UMINUS 42 #define TK_CONCAT 42
#define TK_UPLUS 43 #define TK_UMINUS 43
#define TK_BITNOT 44 #define TK_UPLUS 44
#define TK_SHOW 45 #define TK_BITNOT 45
#define TK_DATABASES 46 #define TK_SHOW 46
#define TK_TOPICS 47 #define TK_DATABASES 47
#define TK_FUNCTIONS 48 #define TK_TOPICS 48
#define TK_MNODES 49 #define TK_FUNCTIONS 49
#define TK_DNODES 50 #define TK_MNODES 50
#define TK_ACCOUNTS 51 #define TK_DNODES 51
#define TK_USERS 52 #define TK_ACCOUNTS 52
#define TK_MODULES 53 #define TK_USERS 53
#define TK_QUERIES 54 #define TK_MODULES 54
#define TK_CONNECTIONS 55 #define TK_QUERIES 55
#define TK_STREAMS 56 #define TK_CONNECTIONS 56
#define TK_VARIABLES 57 #define TK_STREAMS 57
#define TK_SCORES 58 #define TK_VARIABLES 58
#define TK_GRANTS 59 #define TK_SCORES 59
#define TK_VNODES 60 #define TK_GRANTS 60
#define TK_DOT 61 #define TK_VNODES 61
#define TK_CREATE 62 #define TK_DOT 62
#define TK_TABLE 63 #define TK_CREATE 63
#define TK_STABLE 64 #define TK_TABLE 64
#define TK_DATABASE 65 #define TK_STABLE 65
#define TK_TABLES 66 #define TK_DATABASE 66
#define TK_STABLES 67 #define TK_TABLES 67
#define TK_VGROUPS 68 #define TK_STABLES 68
#define TK_DROP 69 #define TK_VGROUPS 69
#define TK_TOPIC 70 #define TK_DROP 70
#define TK_FUNCTION 71 #define TK_TOPIC 71
#define TK_DNODE 72 #define TK_FUNCTION 72
#define TK_USER 73 #define TK_DNODE 73
#define TK_ACCOUNT 74 #define TK_USER 74
#define TK_USE 75 #define TK_ACCOUNT 75
#define TK_DESCRIBE 76 #define TK_USE 76
#define TK_DESC 77 #define TK_DESCRIBE 77
#define TK_ALTER 78 #define TK_DESC 78
#define TK_PASS 79 #define TK_ALTER 79
#define TK_PRIVILEGE 80 #define TK_PASS 80
#define TK_LOCAL 81 #define TK_PRIVILEGE 81
#define TK_COMPACT 82 #define TK_LOCAL 82
#define TK_LP 83 #define TK_COMPACT 83
#define TK_RP 84 #define TK_LP 84
#define TK_IF 85 #define TK_RP 85
#define TK_EXISTS 86 #define TK_IF 86
#define TK_AS 87 #define TK_EXISTS 87
#define TK_OUTPUTTYPE 88 #define TK_AS 88
#define TK_AGGREGATE 89 #define TK_OUTPUTTYPE 89
#define TK_BUFSIZE 90 #define TK_AGGREGATE 90
#define TK_PPS 91 #define TK_BUFSIZE 91
#define TK_TSERIES 92 #define TK_PPS 92
#define TK_DBS 93 #define TK_TSERIES 93
#define TK_STORAGE 94 #define TK_DBS 94
#define TK_QTIME 95 #define TK_STORAGE 95
#define TK_CONNS 96 #define TK_QTIME 96
#define TK_STATE 97 #define TK_CONNS 97
#define TK_COMMA 98 #define TK_STATE 98
#define TK_KEEP 99 #define TK_COMMA 99
#define TK_CACHE 100 #define TK_KEEP 100
#define TK_REPLICA 101 #define TK_CACHE 101
#define TK_QUORUM 102 #define TK_REPLICA 102
#define TK_DAYS 103 #define TK_QUORUM 103
#define TK_MINROWS 104 #define TK_DAYS 104
#define TK_MAXROWS 105 #define TK_MINROWS 105
#define TK_BLOCKS 106 #define TK_MAXROWS 106
#define TK_CTIME 107 #define TK_BLOCKS 107
#define TK_WAL 108 #define TK_CTIME 108
#define TK_FSYNC 109 #define TK_WAL 109
#define TK_COMP 110 #define TK_FSYNC 110
#define TK_PRECISION 111 #define TK_COMP 111
#define TK_UPDATE 112 #define TK_PRECISION 112
#define TK_CACHELAST 113 #define TK_UPDATE 113
#define TK_PARTITIONS 114 #define TK_CACHELAST 114
#define TK_UNSIGNED 115 #define TK_PARTITIONS 115
#define TK_TAGS 116 #define TK_UNSIGNED 116
#define TK_USING 117 #define TK_TAGS 117
#define TK_NULL 118 #define TK_USING 118
#define TK_NOW 119 #define TK_NULL 119
#define TK_SELECT 120 #define TK_NOW 120
#define TK_UNION 121 #define TK_SELECT 121
#define TK_ALL 122 #define TK_UNION 122
#define TK_DISTINCT 123 #define TK_ALL 123
#define TK_FROM 124 #define TK_DISTINCT 124
#define TK_VARIABLE 125 #define TK_FROM 125
#define TK_INTERVAL 126 #define TK_VARIABLE 126
#define TK_EVERY 127 #define TK_INTERVAL 127
#define TK_SESSION 128 #define TK_EVERY 128
#define TK_STATE_WINDOW 129 #define TK_SESSION 129
#define TK_FILL 130 #define TK_STATE_WINDOW 130
#define TK_SLIDING 131 #define TK_FILL 131
#define TK_ORDER 132 #define TK_SLIDING 132
#define TK_BY 133 #define TK_ORDER 133
#define TK_ASC 134 #define TK_BY 134
#define TK_GROUP 135 #define TK_ASC 135
#define TK_HAVING 136 #define TK_GROUP 136
#define TK_LIMIT 137 #define TK_HAVING 137
#define TK_OFFSET 138 #define TK_LIMIT 138
#define TK_SLIMIT 139 #define TK_OFFSET 139
#define TK_SOFFSET 140 #define TK_SLIMIT 140
#define TK_WHERE 141 #define TK_SOFFSET 141
#define TK_RESET 142 #define TK_WHERE 142
#define TK_QUERY 143 #define TK_RESET 143
#define TK_SYNCDB 144 #define TK_QUERY 144
#define TK_ADD 145 #define TK_SYNCDB 145
#define TK_COLUMN 146 #define TK_ADD 146
#define TK_MODIFY 147 #define TK_COLUMN 147
#define TK_TAG 148 #define TK_MODIFY 148
#define TK_CHANGE 149 #define TK_TAG 149
#define TK_SET 150 #define TK_CHANGE 150
#define TK_KILL 151 #define TK_SET 151
#define TK_CONNECTION 152 #define TK_KILL 152
#define TK_STREAM 153 #define TK_CONNECTION 153
#define TK_COLON 154 #define TK_STREAM 154
#define TK_ABORT 155 #define TK_COLON 155
#define TK_AFTER 156 #define TK_ABORT 156
#define TK_ATTACH 157 #define TK_AFTER 157
#define TK_BEFORE 158 #define TK_ATTACH 158
#define TK_BEGIN 159 #define TK_BEFORE 159
#define TK_CASCADE 160 #define TK_BEGIN 160
#define TK_CLUSTER 161 #define TK_CASCADE 161
#define TK_CONFLICT 162 #define TK_CLUSTER 162
#define TK_COPY 163 #define TK_CONFLICT 163
#define TK_DEFERRED 164 #define TK_COPY 164
#define TK_DELIMITERS 165 #define TK_DEFERRED 165
#define TK_DETACH 166 #define TK_DELIMITERS 166
#define TK_EACH 167 #define TK_DETACH 167
#define TK_END 168 #define TK_EACH 168
#define TK_EXPLAIN 169 #define TK_END 169
#define TK_FAIL 170 #define TK_EXPLAIN 170
#define TK_FOR 171 #define TK_FAIL 171
#define TK_IGNORE 172 #define TK_FOR 172
#define TK_IMMEDIATE 173 #define TK_IGNORE 173
#define TK_INITIALLY 174 #define TK_IMMEDIATE 174
#define TK_INSTEAD 175 #define TK_INITIALLY 175
#define TK_KEY 176 #define TK_INSTEAD 176
#define TK_OF 177 #define TK_KEY 177
#define TK_RAISE 178 #define TK_OF 178
#define TK_REPLACE 179 #define TK_RAISE 179
#define TK_RESTRICT 180 #define TK_REPLACE 180
#define TK_ROW 181 #define TK_RESTRICT 181
#define TK_STATEMENT 182 #define TK_ROW 182
#define TK_TRIGGER 183 #define TK_STATEMENT 183
#define TK_VIEW 184 #define TK_TRIGGER 184
#define TK_IPTOKEN 185 #define TK_VIEW 185
#define TK_SEMI 186 #define TK_IPTOKEN 186
#define TK_NONE 187 #define TK_SEMI 187
#define TK_PREV 188 #define TK_NONE 188
#define TK_LINEAR 189 #define TK_PREV 189
#define TK_IMPORT 190 #define TK_LINEAR 190
#define TK_TBNAME 191 #define TK_IMPORT 191
#define TK_JOIN 192 #define TK_TBNAME 192
#define TK_INSERT 193 #define TK_JOIN 193
#define TK_INTO 194 #define TK_INSERT 194
#define TK_VALUES 195 #define TK_INTO 195
#define TK_VALUES 196
#define TK_SPACE 300 #define TK_SPACE 300
......
此差异已折叠。
...@@ -70,8 +70,8 @@ extern "C" { ...@@ -70,8 +70,8 @@ extern "C" {
#define TSDB_FUNC_DERIVATIVE 32 #define TSDB_FUNC_DERIVATIVE 32
#define TSDB_FUNC_BLKINFO 33 #define TSDB_FUNC_BLKINFO 33
#define TSDB_FUNC_CSUM 34
#define TSDB_FUNC_HISTOGRAM 34
#define TSDB_FUNC_HLL 35 #define TSDB_FUNC_HLL 35
#define TSDB_FUNC_MODE 36 #define TSDB_FUNC_MODE 36
#define TSDB_FUNC_SAMPLE 37 #define TSDB_FUNC_SAMPLE 37
...@@ -79,7 +79,7 @@ extern "C" { ...@@ -79,7 +79,7 @@ extern "C" {
#define TSDB_FUNC_FLOOR 39 #define TSDB_FUNC_FLOOR 39
#define TSDB_FUNC_ROUND 40 #define TSDB_FUNC_ROUND 40
#define TSDB_FUNC_MAVG 41 #define TSDB_FUNC_MAVG 41
#define TSDB_FUNC_CSUM 42 #define TSDB_FUNC_HISTOGRAM 42
#define TSDB_FUNCSTATE_SO 0x1u // single output #define TSDB_FUNCSTATE_SO 0x1u // single output
#define TSDB_FUNCSTATE_MO 0x2u // dynamic number of output, not multinumber of output e.g., TOP/BOTTOM #define TSDB_FUNCSTATE_MO 0x2u // dynamic number of output, not multinumber of output e.g., TOP/BOTTOM
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
%left OR. %left OR.
%left AND. %left AND.
%right NOT. %right NOT.
%left EQ NE ISNULL NOTNULL IS LIKE MATCH GLOB BETWEEN IN. %left EQ NE ISNULL NOTNULL IS LIKE MATCH NMATCH GLOB BETWEEN IN.
%left GT GE LT LE. %left GT GE LT LE.
%left BITAND BITOR LSHIFT RSHIFT. %left BITAND BITOR LSHIFT RSHIFT.
%left PLUS MINUS. %left PLUS MINUS.
...@@ -753,6 +753,7 @@ expr(A) ::= expr(X) LIKE expr(Y). {A = tSqlExprCreate(X, Y, TK_LIKE); } ...@@ -753,6 +753,7 @@ expr(A) ::= expr(X) LIKE expr(Y). {A = tSqlExprCreate(X, Y, TK_LIKE); }
// match expression // match expression
expr(A) ::= expr(X) MATCH expr(Y). {A = tSqlExprCreate(X, Y, TK_MATCH); } expr(A) ::= expr(X) MATCH expr(Y). {A = tSqlExprCreate(X, Y, TK_MATCH); }
expr(A) ::= expr(X) NMATCH expr(Y). {A = tSqlExprCreate(X, Y, TK_NMATCH); }
//in expression //in expression
expr(A) ::= expr(X) IN LP exprlist(Y) RP. {A = tSqlExprCreate(X, (tSqlExpr*)Y, TK_IN); } expr(A) ::= expr(X) IN LP exprlist(Y) RP. {A = tSqlExprCreate(X, (tSqlExpr*)Y, TK_IN); }
...@@ -919,5 +920,5 @@ cmd ::= KILL QUERY INTEGER(X) COLON(Z) INTEGER(Y). {X.n += (Z.n + Y.n); s ...@@ -919,5 +920,5 @@ cmd ::= KILL QUERY INTEGER(X) COLON(Z) INTEGER(Y). {X.n += (Z.n + Y.n); s
%fallback ID ABORT AFTER ASC ATTACH BEFORE BEGIN CASCADE CLUSTER CONFLICT COPY DATABASE DEFERRED %fallback ID ABORT AFTER ASC ATTACH BEFORE BEGIN CASCADE CLUSTER CONFLICT COPY DATABASE DEFERRED
DELIMITERS DESC DETACH EACH END EXPLAIN FAIL FOR GLOB IGNORE IMMEDIATE INITIALLY INSTEAD DELIMITERS DESC DETACH EACH END EXPLAIN FAIL FOR GLOB IGNORE IMMEDIATE INITIALLY INSTEAD
LIKE MATCH KEY OF OFFSET RAISE REPLACE RESTRICT ROW STATEMENT TRIGGER VIEW ALL LIKE MATCH NMATCH KEY OF OFFSET RAISE REPLACE RESTRICT ROW STATEMENT TRIGGER VIEW ALL
NOW IPTOKEN SEMI NONE PREV LINEAR IMPORT TBNAME JOIN STABLE NULL INSERT INTO VALUES. NOW IPTOKEN SEMI NONE PREV LINEAR IMPORT TBNAME JOIN STABLE NULL INSERT INTO VALUES.
...@@ -4410,9 +4410,164 @@ static void csum_function(SQLFunctionCtx *pCtx) { ...@@ -4410,9 +4410,164 @@ static void csum_function(SQLFunctionCtx *pCtx) {
} }
typedef struct { typedef struct {
int32_t numSamples; int32_t pos;
double sum;
int32_t numPoints;
int64_t* points;
} SMovingAvgInfo;
static bool mavg_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResInfo) {
if (!function_setup(pCtx, pResInfo)) {
return false;
}
SMovingAvgInfo* mavgInfo = GET_ROWCELL_INTERBUF(pResInfo);
mavgInfo->pos = -1;
mavgInfo->sum = 0;
mavgInfo->numPoints = (int32_t)pCtx->param[0].i64;
mavgInfo->points = (int64_t*)((char*)mavgInfo + sizeof(mavgInfo));
return true;
}
static void mavg_function(SQLFunctionCtx *pCtx) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
SMovingAvgInfo* mavgInfo = GET_ROWCELL_INTERBUF(pResInfo);
void* data = GET_INPUT_DATA_LIST(pCtx);
int32_t notNullElems = 0;
int32_t step = GET_FORWARD_DIRECTION_FACTOR(pCtx->order);
int32_t i = (pCtx->order = TSDB_ORDER_ASC) ? 0 : pCtx->size -1;
TSKEY* pTimestamp = pCtx->ptsOutputBuf;
TSKEY* tsList = GET_TS_LIST(pCtx);
switch (pCtx->inputType) {
case TSDB_DATA_TYPE_INT: {
int32_t *pData = (int32_t *)data;
int32_t *pOutput = (int32_t *)pCtx->pOutput;
for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) {
continue;
}
pCumSumInfo->cumSum += pData[i];
*pTimestamp = (tsList != NULL) ? tsList[i] : 0;
SET_DOUBLE_VAL(pOutput, pCumSumInfo->cumSum);
++notNullElems;
pOutput += 1;
pTimestamp += 1;
}
break;
}
case TSDB_DATA_TYPE_BIGINT: {
int64_t *pData = (int64_t *)data;
int64_t *pOutput = (int64_t *)pCtx->pOutput;
for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) {
continue;
}
pCumSumInfo->cumSum += pData[i];
*pTimestamp = (tsList != NULL) ? tsList[i] : 0;
SET_DOUBLE_VAL(pOutput, pCumSumInfo->cumSum);
++notNullElems;
pOutput += 1;
pTimestamp += 1;
}
break;
}
case TSDB_DATA_TYPE_TINYINT: {
int8_t *pData = (int8_t *)data;
int8_t *pOutput = (int8_t *)pCtx->pOutput;
for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) {
continue;
}
pCumSumInfo->cumSum += pData[i];
*pTimestamp = (tsList != NULL) ? tsList[i] : 0;
SET_DOUBLE_VAL(pOutput, pCumSumInfo->cumSum);
++notNullElems;
pOutput += 1;
pTimestamp += 1;
}
break;
}
case TSDB_DATA_TYPE_SMALLINT: {
int16_t *pData = (int16_t *)data;
int16_t *pOutput = (int16_t *)pCtx->pOutput;
for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) {
continue;
}
pCumSumInfo->cumSum += pData[i];
*pTimestamp = (tsList != NULL) ? tsList[i] : 0;
SET_DOUBLE_VAL(pOutput, pCumSumInfo->cumSum);
++notNullElems;
pOutput += 1;
pTimestamp += 1;
}
break;
}
case TSDB_DATA_TYPE_FLOAT: {
float *pData = (float *)data;
float *pOutput = (float *)pCtx->pOutput;
for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) {
continue;
}
pCumSumInfo->cumSum += pData[i];
*pTimestamp = (tsList != NULL) ? tsList[i] : 0;
SET_DOUBLE_VAL(pOutput, pCumSumInfo->cumSum);
++notNullElems;
pOutput += 1;
pTimestamp += 1;
}
break;
}
case TSDB_DATA_TYPE_DOUBLE: {
double *pData = (double *)data;
double *pOutput = (double *)pCtx->pOutput;
for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) {
continue;
}
pCumSumInfo->cumSum += pData[i];
*pTimestamp = (tsList != NULL) ? tsList[i] : 0;
SET_DOUBLE_VAL(pOutput, pCumSumInfo->cumSum);
++notNullElems;
pOutput += 1;
pTimestamp += 1;
}
break;
}
default:
qError("error input type");
}
if (notNullElems <= 0) {
assert(pCtx->hasNull);
} else {
GET_RES_INFO(pCtx)->numOfRes += notNullElems;
GET_RES_INFO(pCtx)->hasResult = DATA_SET_FLAG;
}
}
} SSampleInfo;
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
...@@ -4847,4 +5002,17 @@ SAggFunctionInfo aAggs[] = {{ ...@@ -4847,4 +5002,17 @@ SAggFunctionInfo aAggs[] = {{
blockinfo_func_finalizer, blockinfo_func_finalizer,
block_func_merge, block_func_merge,
dataBlockRequired, dataBlockRequired,
}}; },
{
// 34
"csum",
TSDB_FUNC_CSUM,
TSDB_FUNC_INVALID_ID,
TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_NEED_TS | TSDB_FUNCSTATE_SELECTIVITY,
csum_function_setup,
csum_function,
doFinalizer,
noop1,
dataBlockRequired,
},
};
...@@ -29,6 +29,7 @@ OptrStr gOptrStr[] = { ...@@ -29,6 +29,7 @@ OptrStr gOptrStr[] = {
{TSDB_RELATION_NOT_EQUAL, "!="}, {TSDB_RELATION_NOT_EQUAL, "!="},
{TSDB_RELATION_LIKE, "like"}, {TSDB_RELATION_LIKE, "like"},
{TSDB_RELATION_MATCH, "match"}, {TSDB_RELATION_MATCH, "match"},
{TSDB_RELATION_MATCH, "nmatch"},
{TSDB_RELATION_ISNULL, "is null"}, {TSDB_RELATION_ISNULL, "is null"},
{TSDB_RELATION_NOTNULL, "not null"}, {TSDB_RELATION_NOTNULL, "not null"},
{TSDB_RELATION_IN, "in"}, {TSDB_RELATION_IN, "in"},
...@@ -157,7 +158,7 @@ int8_t filterGetRangeCompFuncFromOptrs(uint8_t optr, uint8_t optr2) { ...@@ -157,7 +158,7 @@ int8_t filterGetRangeCompFuncFromOptrs(uint8_t optr, uint8_t optr2) {
__compar_fn_t gDataCompare[] = {compareInt32Val, compareInt8Val, compareInt16Val, compareInt64Val, compareFloatVal, __compar_fn_t gDataCompare[] = {compareInt32Val, compareInt8Val, compareInt16Val, compareInt64Val, compareFloatVal,
compareDoubleVal, compareLenPrefixedStr, compareStrPatternComp, compareFindItemInSet, compareWStrPatternComp, compareDoubleVal, compareLenPrefixedStr, compareStrPatternComp, compareFindItemInSet, compareWStrPatternComp,
compareLenPrefixedWStr, compareUint8Val, compareUint16Val, compareUint32Val, compareUint64Val, compareLenPrefixedWStr, compareUint8Val, compareUint16Val, compareUint32Val, compareUint64Val,
setCompareBytes1, setCompareBytes2, setCompareBytes4, setCompareBytes8, compareStrRegexComp, setCompareBytes1, setCompareBytes2, setCompareBytes4, setCompareBytes8, compareStrRegexCompMatch, compareStrRegexCompNMatch
}; };
int8_t filterGetCompFuncIdx(int32_t type, int32_t optr) { int8_t filterGetCompFuncIdx(int32_t type, int32_t optr) {
...@@ -198,6 +199,8 @@ int8_t filterGetCompFuncIdx(int32_t type, int32_t optr) { ...@@ -198,6 +199,8 @@ int8_t filterGetCompFuncIdx(int32_t type, int32_t optr) {
case TSDB_DATA_TYPE_BINARY: { case TSDB_DATA_TYPE_BINARY: {
if (optr == TSDB_RELATION_MATCH) { if (optr == TSDB_RELATION_MATCH) {
comparFn = 19; comparFn = 19;
} else if (optr == TSDB_RELATION_NMATCH) {
comparFn = 20;
} else if (optr == TSDB_RELATION_LIKE) { /* wildcard query using like operator */ } else if (optr == TSDB_RELATION_LIKE) { /* wildcard query using like operator */
comparFn = 7; comparFn = 7;
} else if (optr == TSDB_RELATION_IN) { } else if (optr == TSDB_RELATION_IN) {
...@@ -212,6 +215,8 @@ int8_t filterGetCompFuncIdx(int32_t type, int32_t optr) { ...@@ -212,6 +215,8 @@ int8_t filterGetCompFuncIdx(int32_t type, int32_t optr) {
case TSDB_DATA_TYPE_NCHAR: { case TSDB_DATA_TYPE_NCHAR: {
if (optr == TSDB_RELATION_MATCH) { if (optr == TSDB_RELATION_MATCH) {
comparFn = 19; comparFn = 19;
} else if (optr == TSDB_RELATION_NMATCH) {
comparFn = 20;
} else if (optr == TSDB_RELATION_LIKE) { } else if (optr == TSDB_RELATION_LIKE) {
comparFn = 9; comparFn = 9;
} else if (optr == TSDB_RELATION_IN) { } else if (optr == TSDB_RELATION_IN) {
...@@ -1879,6 +1884,9 @@ bool filterDoCompare(__compar_fn_t func, uint8_t optr, void *left, void *right) ...@@ -1879,6 +1884,9 @@ bool filterDoCompare(__compar_fn_t func, uint8_t optr, void *left, void *right)
case TSDB_RELATION_MATCH: { case TSDB_RELATION_MATCH: {
return ret == 0; return ret == 0;
} }
case TSDB_RELATION_NMATCH: {
return ret == 0;
}
case TSDB_RELATION_IN: { case TSDB_RELATION_IN: {
return ret == 1; return ret == 1;
} }
......
此差异已折叠。
...@@ -3708,6 +3708,9 @@ static bool tableFilterFp(const void* pNode, void* param) { ...@@ -3708,6 +3708,9 @@ static bool tableFilterFp(const void* pNode, void* param) {
case TSDB_RELATION_MATCH: { case TSDB_RELATION_MATCH: {
return ret == 0; return ret == 0;
} }
case TSDB_RELATION_NMATCH: {
return ret == 0;
}
case TSDB_RELATION_IN: { case TSDB_RELATION_IN: {
return ret == 1; return ret == 1;
} }
...@@ -4043,6 +4046,8 @@ static int32_t setQueryCond(tQueryInfo *queryColInfo, SQueryCond* pCond) { ...@@ -4043,6 +4046,8 @@ static int32_t setQueryCond(tQueryInfo *queryColInfo, SQueryCond* pCond) {
assert(0); assert(0);
} else if (optr == TSDB_RELATION_MATCH) { } else if (optr == TSDB_RELATION_MATCH) {
assert(0); assert(0);
} else if (optr == TSDB_RELATION_NMATCH) {
assert(0);
} }
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
...@@ -4200,7 +4205,9 @@ static void queryIndexlessColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, S ...@@ -4200,7 +4205,9 @@ static void queryIndexlessColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, S
if (pQueryInfo->sch.colId == TSDB_TBNAME_COLUMN_INDEX) { if (pQueryInfo->sch.colId == TSDB_TBNAME_COLUMN_INDEX) {
if (pQueryInfo->optr == TSDB_RELATION_IN) { if (pQueryInfo->optr == TSDB_RELATION_IN) {
addToResult = pQueryInfo->compare(name, pQueryInfo->q); addToResult = pQueryInfo->compare(name, pQueryInfo->q);
} else if (pQueryInfo->optr == TSDB_RELATION_LIKE || pQueryInfo->optr == TSDB_RELATION_MATCH) { } else if (pQueryInfo->optr == TSDB_RELATION_LIKE ||
pQueryInfo->optr == TSDB_RELATION_MATCH ||
pQueryInfo->optr == TSDB_RELATION_NMATCH) {
addToResult = !pQueryInfo->compare(name, pQueryInfo->q); addToResult = !pQueryInfo->compare(name, pQueryInfo->q);
} }
} else { } else {
...@@ -4232,7 +4239,8 @@ void getTableListfromSkipList(tExprNode *pExpr, SSkipList *pSkipList, SArray *re ...@@ -4232,7 +4239,8 @@ void getTableListfromSkipList(tExprNode *pExpr, SSkipList *pSkipList, SArray *re
param->setupInfoFn(pExpr, param->pExtInfo); param->setupInfoFn(pExpr, param->pExtInfo);
tQueryInfo *pQueryInfo = pExpr->_node.info; tQueryInfo *pQueryInfo = pExpr->_node.info;
if (pQueryInfo->indexed && (pQueryInfo->optr != TSDB_RELATION_LIKE && pQueryInfo->optr != TSDB_RELATION_MATCH if (pQueryInfo->indexed && (pQueryInfo->optr != TSDB_RELATION_LIKE
&& pQueryInfo->optr != TSDB_RELATION_MATCH && pQueryInfo->optr != TSDB_RELATION_NMATCH
&& pQueryInfo->optr != TSDB_RELATION_IN)) { && pQueryInfo->optr != TSDB_RELATION_IN)) {
queryIndexedColumn(pSkipList, pQueryInfo, result); queryIndexedColumn(pSkipList, pQueryInfo, result);
} else { } else {
......
...@@ -84,6 +84,8 @@ int32_t compareLenPrefixedStr(const void *pLeft, const void *pRight); ...@@ -84,6 +84,8 @@ int32_t compareLenPrefixedStr(const void *pLeft, const void *pRight);
int32_t compareLenPrefixedWStr(const void *pLeft, const void *pRight); int32_t compareLenPrefixedWStr(const void *pLeft, const void *pRight);
int32_t compareStrPatternComp(const void* pLeft, const void* pRight); int32_t compareStrPatternComp(const void* pLeft, const void* pRight);
int32_t compareStrRegexComp(const void* pLeft, const void* pRight); int32_t compareStrRegexComp(const void* pLeft, const void* pRight);
int32_t compareStrRegexCompMatch(const void* pLeft, const void* pRight);
int32_t compareStrRegexCompNMatch(const void* pLeft, const void* pRight);
int32_t compareFindItemInSet(const void *pLeft, const void* pRight); int32_t compareFindItemInSet(const void *pLeft, const void* pRight);
int32_t compareWStrPatternComp(const void* pLeft, const void* pRight); int32_t compareWStrPatternComp(const void* pLeft, const void* pRight);
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
extern "C" { extern "C" {
#endif #endif
#define TSDB_CFG_MAX_NUM 122 #define TSDB_CFG_MAX_NUM 123
#define TSDB_CFG_PRINT_LEN 23 #define TSDB_CFG_PRINT_LEN 23
#define TSDB_CFG_OPTION_LEN 24 #define TSDB_CFG_OPTION_LEN 24
#define TSDB_CFG_VALUE_LEN 41 #define TSDB_CFG_VALUE_LEN 41
......
...@@ -350,6 +350,14 @@ int32_t compareStrPatternComp(const void* pLeft, const void* pRight) { ...@@ -350,6 +350,14 @@ int32_t compareStrPatternComp(const void* pLeft, const void* pRight) {
return (ret == TSDB_PATTERN_MATCH) ? 0 : 1; return (ret == TSDB_PATTERN_MATCH) ? 0 : 1;
} }
int32_t compareStrRegexCompMatch(const void* pLeft, const void* pRight) {
return compareStrRegexComp(pLeft, pRight);
}
int32_t compareStrRegexCompNMatch(const void* pLeft, const void* pRight) {
return compareStrRegexComp(pLeft, pRight) ? 0 : 1;
}
int32_t compareStrRegexComp(const void* pLeft, const void* pRight) { int32_t compareStrRegexComp(const void* pLeft, const void* pRight) {
size_t sz = varDataLen(pRight); size_t sz = varDataLen(pRight);
char *pattern = malloc(sz + 1); char *pattern = malloc(sz + 1);
...@@ -449,7 +457,9 @@ __compar_fn_t getComparFunc(int32_t type, int32_t optr) { ...@@ -449,7 +457,9 @@ __compar_fn_t getComparFunc(int32_t type, int32_t optr) {
case TSDB_DATA_TYPE_DOUBLE: comparFn = compareDoubleVal; break; case TSDB_DATA_TYPE_DOUBLE: comparFn = compareDoubleVal; break;
case TSDB_DATA_TYPE_BINARY: { case TSDB_DATA_TYPE_BINARY: {
if (optr == TSDB_RELATION_MATCH) { if (optr == TSDB_RELATION_MATCH) {
comparFn = compareStrRegexComp; comparFn = compareStrRegexCompMatch;
} else if (optr == TSDB_RELATION_NMATCH) {
comparFn = compareStrRegexCompNMatch;
} else if (optr == TSDB_RELATION_LIKE) { /* wildcard query using like operator */ } else if (optr == TSDB_RELATION_LIKE) { /* wildcard query using like operator */
comparFn = compareStrPatternComp; comparFn = compareStrPatternComp;
} else if (optr == TSDB_RELATION_IN) { } else if (optr == TSDB_RELATION_IN) {
...@@ -463,7 +473,9 @@ __compar_fn_t getComparFunc(int32_t type, int32_t optr) { ...@@ -463,7 +473,9 @@ __compar_fn_t getComparFunc(int32_t type, int32_t optr) {
case TSDB_DATA_TYPE_NCHAR: { case TSDB_DATA_TYPE_NCHAR: {
if (optr == TSDB_RELATION_MATCH) { if (optr == TSDB_RELATION_MATCH) {
comparFn = compareStrRegexComp; comparFn = compareStrRegexCompMatch;
} else if (optr == TSDB_RELATION_NMATCH) {
comparFn = compareStrRegexCompNMatch;
} else if (optr == TSDB_RELATION_LIKE) { } else if (optr == TSDB_RELATION_LIKE) {
comparFn = compareWStrPatternComp; comparFn = compareWStrPatternComp;
} else if (optr == TSDB_RELATION_IN) { } else if (optr == TSDB_RELATION_IN) {
......
...@@ -195,6 +195,7 @@ static SKeyword keywordTable[] = { ...@@ -195,6 +195,7 @@ static SKeyword keywordTable[] = {
{"INITIALLY", TK_INITIALLY}, {"INITIALLY", TK_INITIALLY},
{"INSTEAD", TK_INSTEAD}, {"INSTEAD", TK_INSTEAD},
{"MATCH", TK_MATCH}, {"MATCH", TK_MATCH},
{"NMATCH", TK_NMATCH},
{"KEY", TK_KEY}, {"KEY", TK_KEY},
{"OF", TK_OF}, {"OF", TK_OF},
{"RAISE", TK_RAISE}, {"RAISE", TK_RAISE},
......
...@@ -183,6 +183,9 @@ python3 test.py -f tools/taosdemoAllTest/NanoTestCase/taosdemoTestSupportNanosub ...@@ -183,6 +183,9 @@ python3 test.py -f tools/taosdemoAllTest/NanoTestCase/taosdemoTestSupportNanosub
python3 test.py -f tools/taosdemoAllTest/NanoTestCase/taosdemoTestInsertTime_step.py python3 test.py -f tools/taosdemoAllTest/NanoTestCase/taosdemoTestInsertTime_step.py
python3 test.py -f tools/taosdemoAllTest/NanoTestCase/taosdumpTestNanoSupport.py python3 test.py -f tools/taosdemoAllTest/NanoTestCase/taosdumpTestNanoSupport.py
#
python3 ./test.py -f tsdb/tsdbComp.py
# update # update
python3 ./test.py -f update/allow_update.py python3 ./test.py -f update/allow_update.py
python3 ./test.py -f update/allow_update-0.py python3 ./test.py -f update/allow_update-0.py
......
...@@ -42,7 +42,7 @@ class TwoClients: ...@@ -42,7 +42,7 @@ class TwoClients:
tdSql.execute("drop database if exists db3") tdSql.execute("drop database if exists db3")
# insert data with taosc # insert data with c connector
for i in range(10): for i in range(10):
os.system("taosdemo -f manualTest/TD-5114/insertDataDb3Replica2.json -y ") os.system("taosdemo -f manualTest/TD-5114/insertDataDb3Replica2.json -y ")
# # check data correct # # check data correct
......
...@@ -24,7 +24,7 @@ from random import choice ...@@ -24,7 +24,7 @@ from random import choice
class TwoClients: class TwoClients:
def initConnection(self): def initConnection(self):
self.host = "chenhaoran02" self.host = "chenhaoran01"
self.user = "root" self.user = "root"
self.password = "taosdata" self.password = "taosdata"
self.config = "/etc/taos/" self.config = "/etc/taos/"
...@@ -116,8 +116,10 @@ class TwoClients: ...@@ -116,8 +116,10 @@ class TwoClients:
sleep(3) sleep(3)
tdSql.execute(" drop dnode 'chenhaoran02:6030'; ") tdSql.execute(" drop dnode 'chenhaoran02:6030'; ")
sleep(20) sleep(20)
os.system("rm -rf /var/lib/taos/*") # remove data file;
os.system("rm -rf /home/chr/data/data0/*")
print("clear dnode chenhaoran02'data files") print("clear dnode chenhaoran02'data files")
sleep(5)
os.system("nohup /usr/bin/taosd > /dev/null 2>&1 &") os.system("nohup /usr/bin/taosd > /dev/null 2>&1 &")
print("start taosd") print("start taosd")
sleep(10) sleep(10)
......
...@@ -29,13 +29,22 @@ endi ...@@ -29,13 +29,22 @@ endi
sql select tbname from $st_name where tbname match '^ct[[:digit:]]' sql select tbname from $st_name where tbname match '^ct[[:digit:]]'
if $rows != 2 then if $rows != 2 then
return -1 return -1
endi endi
sql select tbname from $st_name where tbname nmatch '^ct[[:digit:]]'
if $rows != 1 then
return -1
endi
sql select tbname from $st_name where tbname match '.*' sql select tbname from $st_name where tbname match '.*'
if $rows !=3 then if $rows != 3 then
return -1
endi
sql select tbname from $st_name where tbname nmatch '.*'
if $rows != 0 then
return -1 return -1
endi endi
...@@ -44,6 +53,11 @@ if $rows != 2 then ...@@ -44,6 +53,11 @@ if $rows != 2 then
return -1 return -1
endi endi
sql select tbname from $st_name where t1b nmatch '[[:lower:]]+'
if $rows != 1 then
return -1
endi
sql insert into $ct1_name values(now, 'this is engine') sql insert into $ct1_name values(now, 'this is engine')
sql insert into $ct2_name values(now, 'this is app egnine') sql insert into $ct2_name values(now, 'this is app egnine')
...@@ -56,6 +70,52 @@ if $rows != 1 then ...@@ -56,6 +70,52 @@ if $rows != 1 then
return -1 return -1
endi endi
sql select c1b from $st_name where c1b nmatch 'engine'
if $data00 != @this is app egnine@ then
return -1
endi
if $rows != 1 then
return -1
endi
sql_error select c1b from $st_name where c1b match e;
sql_error select c1b from $st_name where c1b nmatch e;
sql create table wrong_type(ts timestamp, c0 tinyint, c1 smallint, c2 int, c3 bigint, c4 float, c5 double, c6 bool, c7 nchar(20)) tags(t0 tinyint, t1 smallint, t2 int, t3 bigint, t4 float, t5 double, t6 bool, t7 nchar(10))
sql insert into wrong_type_1 using wrong_type tags(1, 2, 3, 4, 5, 6, true, 'notsupport') values(now, 1, 2, 3, 4, 5, 6, false, 'notsupport')
sql_error select * from wrong_type where ts match '.*'
sql_error select * from wrong_type where ts nmatch '.*'
sql_error select * from wrong_type where c0 match '.*'
sql_error select * from wrong_type where c0 nmatch '.*'
sql_error select * from wrong_type where c1 match '.*'
sql_error select * from wrong_type where c1 nmatch '.*'
sql_error select * from wrong_type where c2 match '.*'
sql_error select * from wrong_type where c2 nmatch '.*'
sql_error select * from wrong_type where c3 match '.*'
sql_error select * from wrong_type where c3 nmatch '.*'
sql_error select * from wrong_type where c4 match '.*'
sql_error select * from wrong_type where c4 nmatch '.*'
sql_error select * from wrong_type where c5 match '.*'
sql_error select * from wrong_type where c5 nmatch '.*'
sql_error select * from wrong_type where c6 match '.*'
sql_error select * from wrong_type where c6 nmatch '.*'
sql_error select * from wrong_type where c7 match '.*'
sql_error select * from wrong_type where c7 nmatch '.*'
sql_error select * from wrong_type where t1 match '.*'
sql_error select * from wrong_type where t1 nmatch '.*'
sql_error select * from wrong_type where t2 match '.*'
sql_error select * from wrong_type where t2 nmatch '.*'
sql_error select * from wrong_type where t3 match '.*'
sql_error select * from wrong_type where t3 nmatch '.*'
sql_error select * from wrong_type where t4 match '.*'
sql_error select * from wrong_type where t4 nmatch '.*'
sql_error select * from wrong_type where t5 match '.*'
sql_error select * from wrong_type where t5 nmatch '.*'
sql_error select * from wrong_type where t6 match '.*'
sql_error select * from wrong_type where t6 nmatch '.*'
sql_error select * from wrong_type where t7 match '.*'
sql_error select * from wrong_type where t7 nmatch '.*'
system sh/exec.sh -n dnode1 -s stop -x SIGINT system sh/exec.sh -n dnode1 -s stop -x SIGINT
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册