diff --git a/Jenkinsfile b/Jenkinsfile index 91855a92fb811a7380ea9dca75745d21386f8496..4a584fbb35973cc1da82c235f0f47bebe3c50ca2 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -235,11 +235,18 @@ pipeline { npm install td2.0-connector > /dev/null 2>&1 node nodejsChecker.js host=localhost node test1970.js + cd ${WKC}/tests/connectorTest/nodejsTest/nanosupport + npm install td2.0-connector > /dev/null 2>&1 + node nanosecondTest.js + ''' sh ''' cd ${WKC}/tests/examples/C#/taosdemo mcs -out:taosdemo *.cs > /dev/null 2>&1 echo '' |./taosdemo -c /etc/taos + cd ${WKC}/tests/connectorTest/C#Test/nanosupport + mcs -out:nano *.cs > /dev/null 2>&1 + echo '' |./nano ''' sh ''' cd ${WKC}/tests/gotest diff --git a/documentation20/cn/03.architecture/docs.md b/documentation20/cn/03.architecture/docs.md index 8adafc73c21bc915a4564ccf530441bf33a16bda..3e9877b4465eac2ca05d99c88a620a0c6bf89689 100644 --- a/documentation20/cn/03.architecture/docs.md +++ b/documentation20/cn/03.architecture/docs.md @@ -250,7 +250,7 @@ vnode(虚拟数据节点)负责为采集的时序数据提供写入、查询和 创建DB时,系统并不会马上分配资源。但当创建一张表时,系统将看是否有已经分配的vnode, 且该vnode是否有空余的表空间,如果有,立即在该有空位的vnode创建表。如果没有,系统将从集群中,根据当前的负载情况,在一个dnode上创建一新的vnode, 然后创建表。如果DB有多个副本,系统不是只创建一个vnode,而是一个vgroup(虚拟数据节点组)。系统对vnode的数目没有任何限制,仅仅受限于物理节点本身的计算和存储资源。 -每张表的meda data(包含schema, 标签等)也存放于vnode里,而不是集中存放于mnode,实际上这是对Meta数据的分片,这样便于高效并行的进行标签过滤操作。 +每张表的meta data(包含schema, 标签等)也存放于vnode里,而不是集中存放于mnode,实际上这是对Meta数据的分片,这样便于高效并行的进行标签过滤操作。 ### 数据分区 diff --git a/documentation20/cn/05.insert/docs.md b/documentation20/cn/05.insert/docs.md index f055b0c25ba4811336084d6a2a58d6752b9db1e5..92b60be27cd6a4ff3bfa15c99a669f9503a2b902 100644 --- a/documentation20/cn/05.insert/docs.md +++ b/documentation20/cn/05.insert/docs.md @@ -2,7 +2,7 @@ TDengine支持多种接口写入数据,包括SQL, Prometheus, Telegraf, EMQ MQTT Broker, HiveMQ Broker, CSV文件等,后续还将提供Kafka, OPC等接口。数据可以单条插入,也可以批量插入,可以插入一个数据采集点的数据,也可以同时插入多个数据采集点的数据。支持多线程插入,支持时间乱序数据插入,也支持历史数据插入。 -## SQL写入 +## SQL 写入 应用通过C/C++、JDBC、GO、C#或Python Connector 执行SQL insert语句来插入数据,用户还可以通过TAOS Shell,手动输入SQL insert语句插入数据。比如下面这条insert 就将一条记录写入到表d1001中: ```mysql @@ -27,11 +27,73 @@ INSERT INTO d1001 VALUES (1538548685000, 10.3, 219, 0.31) (1538548695000, 12.6, - 对同一张表,如果新插入记录的时间戳已经存在,默认情形下(UPDATE=0)新记录将被直接抛弃,也就是说,在一张表里,时间戳必须是唯一的。如果应用自动生成记录,很有可能生成的时间戳是一样的,这样,成功插入的记录条数会小于应用插入的记录条数。如果在创建数据库时使用了 UPDATE 1 选项,插入相同时间戳的新记录将覆盖原有记录。 - 写入的数据的时间戳必须大于当前时间减去配置参数keep的时间。如果keep配置为3650天,那么无法写入比3650天还早的数据。写入数据的时间戳也不能大于当前时间加配置参数days。如果days为2,那么无法写入比当前时间还晚2天的数据。 -## Prometheus直接写入 +## Schemaless 写入 + +在物联网应用中,常会采集比较多的数据项,用于实现智能控制、业务分析、设备监控等。由于应用逻辑的版本升级,或者设备自身的硬件调整等原因,数据采集项就有可能比较频繁地出现变动。为了在这种情况下方便地完成数据记录工作,TDengine 从 2.2.0.0 版本开始,提供 Schemaless 写入方式,可以免于预先创建超级表/数据子表,而是随着数据写入,自动创建与数据对应的存储结构。并且在必要时,Schemaless 将自动增加必要的数据列,保证用户写入的数据可以被正确存储。目前,TDengine 的 C/C++ Connector 提供支持 Schemaless 的操作接口,详情请参见 [Schemaless 方式写入接口](https://www.taosdata.com/cn/documentation/connector#schemaless) 章节。这里对 Schemaless 的数据表达格式进行描述。 + +### Schemaless 数据行协议 + +Schemaless 采用一个字符串来表达最终存储的一个数据行(可以向 Schemaless 写入 API 中一次传入多个字符串来实现多个数据行的批量写入),其格式约定如下: +```json +measurement,tag_set field_set timestamp +``` + +其中, +* measurement 将作为数据表名。它与 tag_set 之间使用一个英文逗号来分隔。 +* tag_set 将作为标签数据,其格式形如 `=,=`,也即可以使用英文逗号来分隔多个标签数据。它与 field_set 之间使用一个半角空格来分隔。 +* field_set 将作为普通列数据,其格式形如 `=,=`,同样是使用英文逗号来分隔多个普通列的数据。它与 timestamp 之间使用一个半角空格来分隔。 +* timestamp 即本行数据对应的主键时间戳。 + +在 Schemaless 的数据行协议中,tag_set、field_set 中的每个数据项都需要对自身的数据类型进行描述。具体来说: +* 如果两边有英文双引号,表示 BIANRY(32) 类型。例如 `"abc"`。 +* 如果两边有英文双引号而且带有 L 前缀,表示 NCHAR(32) 类型。例如 `L"报错信息"`。 +* 对空格、等号(=)、逗号(,)、双引号("),前面需要使用反斜杠(\)进行转义。(都指的是英文半角符号) +* 数值类型将通过后缀来区分数据类型: + - 没有后缀,为 FLOAT 类型; + - 后缀为 f32,为 FLOAT 类型; + - 后缀为 f64,为 DOUBLE 类型; + - 后缀为 i8,表示为 TINYINT (INT8) 类型; + - 后缀为 i16,表示为 SMALLINT (INT16) 类型; + - 后缀为 i32,表示为 INT (INT32) 类型; + - 后缀为 i64,表示为 BIGINT (INT64) 类型; + - 后缀为 b,表示为 BOOL 类型。 +* t, T, true, True, TRUE, f, F, false, False 将直接作为 BOOL 型来处理。 + +timestamp 位置的时间戳通过后缀来声明时间精度,具体如下: +* 不带任何后缀的长整数会被当作微秒来处理; +* 当后缀为 s 时,表示秒时间戳; +* 当后缀为 ms 时,表示毫秒时间戳; +* 当后缀为 us 时,表示微秒时间戳; +* 当后缀为 ns 时,表示纳秒时间戳; +* 当时间戳为 0 时,表示采用客户端的当前时间(因此,同一批提交的数据中,时间戳 0 会被解释为同一个时间点,于是就有可能导致时间戳重复)。 + +例如,如下 Schemaless 数据行表示:向名为 st 的超级表下的 t1 标签为 3(BIGINT 类型)、t2 标签为 4(DOUBLE 类型)、t3 标签为 "t3"(BINARY 类型)的数据子表,写入 c1 列为 3(BIGINT 类型)、c2 列为 false(BOOL 类型)、c3 列为 "passit"(NCHAR 类型)、c4 列为 4(DOUBLE 类型)、主键时间戳为 1626006833639000000(纳秒精度)的一行数据。 +```json +st,t1=3i64,t2=4f64,t3="t3" c1=3i64,c3=L"passit",c2=false,c4=4f64 1626006833639000000ns +``` + +### Schemaless 的处理逻辑 + +Schemaless 按照如下原则来处理行数据: +1. 当 tag_set 中有 ID 字段时,该字段的值将作为数据子表的表名。 +2. 没有 ID 字段时,将使用 `measurement + tag_value1 + tag_value2 + ...` 的 md5 值来作为子表名。 +3. 如果指定的超级表名不存在,则 Schemaless 会创建这个超级表。 +4. 如果指定的数据子表不存在,则 Schemaless 会使用 tag values 创建这个数据子表。 +5. 如果数据行中指定的标签列或普通列不存在,则 Schemaless 会在超级表中增加对应的标签列或普通列(只增不减)。 +6. 如果超级表中存在一些标签列或普通列未在一个数据行中被指定取值,那么这些列的值在这一行中会被置为 NULL。 +7. 对 BINARY 或 NCHAR 列,如果数据行中所提供值的长度超出了列类型的限制,那么 Schemaless 会增加该列允许存储的字符长度上限(只增不减),以保证数据的完整保存。 +8. 如果指定的数据子表已经存在,而且本次指定的标签列取值跟已保存的值不一样,那么最新的数据行中的值会覆盖旧的标签列取值。 +9. 整个处理过程中遇到的错误会中断写入过程,并返回错误代码。 + +**注意:**Schemaless 所有的处理逻辑,仍会遵循 TDengine 对数据结构的底层限制,例如每行数据的总长度不能超过 16k 字节。这方面的具体限制约束请参见 [TAOS SQL 边界限制](https://www.taosdata.com/cn/documentation/taos-sql#limitation) 章节。 + +关于 Schemaless 的字符串编码处理、时区设置等,均会沿用 TAOSC 客户端的设置。 + +## Prometheus 直接写入 [Prometheus](https://www.prometheus.io/)作为Cloud Native Computing Fundation毕业的项目,在性能监控以及K8S性能监控领域有着非常广泛的应用。TDengine提供一个小工具[Bailongma](https://github.com/taosdata/Bailongma),只需对Prometheus做简单配置,无需任何代码,就可将Prometheus采集的数据直接写入TDengine,并按规则在TDengine自动创建库和相关表项。博文[用Docker容器快速搭建一个Devops监控Demo](https://www.taosdata.com/blog/2020/02/03/1189.html)即是采用Bailongma将Prometheus和Telegraf的数据写入TDengine中的示例,可以参考。 -### 从源代码编译blm_prometheus +### 从源代码编译 blm_prometheus 用户需要从github下载[Bailongma](https://github.com/taosdata/Bailongma)的源码,使用Golang语言编译器编译生成可执行文件。在开始编译前,需要准备好以下条件: - Linux操作系统的服务器 @@ -46,11 +108,11 @@ go build 一切正常的情况下,就会在对应的目录下生成一个blm_prometheus的可执行程序。 -### 安装Prometheus +### 安装 Prometheus 通过Prometheus的官网下载安装。具体请见:[下载地址](https://prometheus.io/download/)。 -### 配置Prometheus +### 配置 Prometheus 参考Prometheus的[配置文档](https://prometheus.io/docs/prometheus/latest/configuration/configuration/),在Prometheus的配置文件中的部分,增加以下配置: @@ -60,7 +122,8 @@ go build 启动Prometheus后,可以通过taos客户端查询确认数据是否成功写入。 -### 启动blm_prometheus程序 +### 启动 blm_prometheus 程序 + blm_prometheus程序有以下选项,在启动blm_prometheus程序时可以通过设定这些选项来设定blm_prometheus的配置。 ```bash --tdengine-name @@ -94,7 +157,8 @@ remote_write: - url: "http://10.1.2.3:8088/receive" ``` -### 查询prometheus写入数据 +### 查询 prometheus 写入数据 + prometheus产生的数据格式如下: ```json { @@ -105,10 +169,10 @@ prometheus产生的数据格式如下: instance="192.168.99.116:8443", job="kubernetes-apiservers", le="125000", - resource="persistentvolumes", s - cope="cluster", + resource="persistentvolumes", + scope="cluster", verb="LIST", - version=“v1" + version="v1" } } ``` @@ -118,11 +182,11 @@ use prometheus; select * from apiserver_request_latencies_bucket; ``` -## Telegraf直接写入 +## Telegraf 直接写入 [Telegraf](https://www.influxdata.com/time-series-platform/telegraf/)是一流行的IT运维数据采集开源工具,TDengine提供一个小工具[Bailongma](https://github.com/taosdata/Bailongma),只需在Telegraf做简单配置,无需任何代码,就可将Telegraf采集的数据直接写入TDengine,并按规则在TDengine自动创建库和相关表项。博文[用Docker容器快速搭建一个Devops监控Demo](https://www.taosdata.com/blog/2020/02/03/1189.html)即是采用bailongma将Prometheus和Telegraf的数据写入TDengine中的示例,可以参考。 -### 从源代码编译blm_telegraf +### 从源代码编译 blm_telegraf 用户需要从github下载[Bailongma](https://github.com/taosdata/Bailongma)的源码,使用Golang语言编译器编译生成可执行文件。在开始编译前,需要准备好以下条件: @@ -139,11 +203,11 @@ go build 一切正常的情况下,就会在对应的目录下生成一个blm_telegraf的可执行程序。 -### 安装Telegraf +### 安装 Telegraf 目前TDengine支持Telegraf 1.7.4以上的版本。用户可以根据当前的操作系统,到Telegraf官网下载安装包,并执行安装。下载地址如下:https://portal.influxdata.com/downloads 。 -### 配置Telegraf +### 配置 Telegraf 修改Telegraf配置文件/etc/telegraf/telegraf.conf中与TDengine有关的配置项。 @@ -160,7 +224,8 @@ go build 关于如何使用Telegraf采集数据以及更多有关使用Telegraf的信息,请参考Telegraf官方的[文档](https://docs.influxdata.com/telegraf/v1.11/)。 -### 启动blm_telegraf程序 +### 启动 blm_telegraf 程序 + blm_telegraf程序有以下选项,在启动blm_telegraf程序时可以通过设定这些选项来设定blm_telegraf的配置。 ```bash @@ -196,7 +261,7 @@ blm_telegraf对telegraf提供服务的端口号。 url = "http://10.1.2.3:8089/telegraf" ``` -### 查询telegraf写入数据 +### 查询 telegraf 写入数据 telegraf产生的数据格式如下: ```json diff --git a/documentation20/cn/08.connector/docs.md b/documentation20/cn/08.connector/docs.md index 45395c6f45d140e1185235baeeaef96db4ad36b8..f6a00e64cb3168cef79cb61ad0cb65b5db0c1bef 100644 --- a/documentation20/cn/08.connector/docs.md +++ b/documentation20/cn/08.connector/docs.md @@ -64,7 +64,10 @@ TDengine提供了丰富的应用程序开发接口,其中包括C/C++、Java、 编辑taos.cfg文件(默认路径/etc/taos/taos.cfg),将firstEP修改为TDengine服务器的End Point,例如:h1.taos.com:6030 -**提示: 如本机没有部署TDengine服务,仅安装了应用驱动,则taos.cfg中仅需配置firstEP,无需配置FQDN。** +**提示: ** + +1. **如本机没有部署TDengine服务,仅安装了应用驱动,则taos.cfg中仅需配置firstEP,无需配置FQDN。** +2. **为防止与服务器端连接时出现“unable to resolve FQDN”错误,建议确认客户端的hosts文件已经配置正确的FQDN值。** **Windows x64/x86** @@ -96,7 +99,7 @@ TDengine提供了丰富的应用程序开发接口,其中包括C/C++、Java、 **提示:** 1. **如利用FQDN连接服务器,必须确认本机网络环境DNS已配置好,或在hosts文件中添加FQDN寻址记录,如编辑C:\Windows\system32\drivers\etc\hosts,添加如下的记录:`192.168.1.99 h1.taos.com` ** -2.**卸载:运行unins000.exe可卸载TDengine应用驱动。** +2. **卸载:运行unins000.exe可卸载TDengine应用驱动。** ### 安装验证 @@ -309,7 +312,7 @@ TDengine的异步API均采用非阻塞调用模式。应用程序可以用多线 ### 参数绑定 API -除了直接调用 `taos_query` 进行查询,TDengine 也提供了支持参数绑定的 Prepare API,与 MySQL 一样,这些 API 目前也仅支持用问号 `?` 来代表待绑定的参数。 +除了直接调用 `taos_query` 进行查询,TDengine 也提供了支持参数绑定的 Prepare API,与 MySQL 一样,这些 API 目前也仅支持用问号 `?` 来代表待绑定的参数。文档中有时也会把此功能称为“原生接口写入”。 从 2.1.1.0 和 2.1.2.0 版本开始,TDengine 大幅改进了参数绑定接口对数据写入(INSERT)场景的支持。这样在通过参数绑定接口写入数据时,就避免了 SQL 语法解析的资源消耗,从而在绝大多数情况下显著提升写入性能。此时的典型操作步骤如下: 1. 调用 `taos_stmt_init` 创建参数绑定对象; @@ -400,6 +403,25 @@ typedef struct TAOS_MULTI_BIND { (2.1.3.0 版本新增) 用于在其他 stmt API 返回错误(返回错误码或空指针)时获取错误信息。 + +### Schemaless 方式写入接口 + +除了使用 SQL 方式或者使用参数绑定 API 写入数据外,还可以使用 Schemaless 的方式完成写入。Schemaless 可以免于预先创建超级表/数据子表的数据结构,而是可以直接写入数据,TDengine 系统会根据写入的数据内容自动创建和维护所需要的表结构。Schemaless 的使用方式详见 [Schemaless 写入](https://www.taosdata.com/cn/documentation/insert#schemaless) 章节,这里介绍与之配套使用的 C/C++ API。 + +- `int taos_insert_lines(TAOS* taos, char* lines[], int numLines)` + + (2.2.0.0 版本新增) + 以 Schemaless 格式写入多行数据。其中: + * taos:调用 taos_connect 返回的数据库连接。 + * lines:由 char 字符串指针组成的数组,指向本次想要写入数据库的多行数据。 + * numLines:lines 数据的总行数。 + + 返回值为 0 表示写入成功,非零值表示出错。具体错误代码请参见 [taoserror.h](https://github.com/taosdata/TDengine/blob/develop/src/inc/taoserror.h) 文件。 + + 说明: + 1. 此接口是一个同步阻塞式接口,使用时机与 `taos_query()` 一致。 + 2. 在调用此接口之前,必须先调用 `taos_select_db()` 来确定目前是在向哪个 DB 来写入。 + ### 连续查询接口 TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时间段,对一张或多张数据库的表(数据流)进行各种实时聚合计算操作。操作简单,仅有打开、关闭流的API。具体如下: diff --git a/documentation20/cn/11.administrator/docs.md b/documentation20/cn/11.administrator/docs.md index 35eff03423e1400ff3339bb493e1816e9d899056..fe9417a861a5284b25525f16c87ab8d07d43181e 100644 --- a/documentation20/cn/11.administrator/docs.md +++ b/documentation20/cn/11.administrator/docs.md @@ -568,6 +568,35 @@ COMPACT 命令对指定的一个或多个 VGroup 启动碎片重整,系统会 需要注意的是,碎片重整操作会大幅消耗磁盘 I/O。因此在重整进行期间,有可能会影响节点的写入和查询性能,甚至在极端情况下导致短时间的阻写。 + +## 浮点数有损压缩 + +在车联网等物联网智能应用场景中,经常会采集和存储海量的浮点数类型数据,如果能更高效地对此类数据进行压缩,那么不但能够节省数据存储的硬件资源,也能够因降低磁盘 I/O 数据量而提升系统性能表现。 + +从 2.1.6.0 版本开始,TDengine 提供一种名为 TSZ 的新型数据压缩算法,无论设置为有损压缩还是无损压缩,都能够显著提升浮点数类型数据的压缩率表现。目前该功能以可选模块的方式进行发布,可以通过添加特定的编译参数来启用该功能(也即常规安装包中暂未包含该功能)。 + +**需要注意的是,该功能一旦启用,效果是全局的,也即会对系统中所有的 FLOAT、DOUBLE 类型的数据生效。同时,在启用了浮点数有损压缩功能后写入的数据,也无法被未启用该功能的版本载入,并有可能因此而导致数据库服务报错退出。** + +### 创建支持 TSZ 压缩算法的 TDengine 版本 + +TSZ 模块保存在单独的代码仓库 https://github.com/taosdata/TSZ 中。可以通过以下步骤创建包含此模块的 TDengine 版本: +1. TDengine 中的插件目前只支持通过 SSH 的方式拉取和编译,所以需要自己先配置好通过 SSH 拉取 GitHub 代码的环境。 +2. `git clone git@github.com:taosdata/TDengine -b your_branchname --recurse-submodules` 通过 `--recurse-submodules` 使依赖模块的源代码可以被一并下载。 +3. `mkdir debug && cd debug` 进入单独的编译目录。 +4. `cmake .. -DTSZ_ENABLED=true` 其中参数 `-DTSZ_ENABLED=true` 表示在编译过程中加入对 TSZ 插件功能的支持。如果成功激活对 TSZ 模块的编译,那么 CMAKE 过程中也会显示 `build with TSZ enabled` 字样。 +5. 编译成功后,包含 TSZ 浮点压缩功能的插件便已经编译进了 TDengine 中了,可以通过调整 taos.cfg 中的配置参数来使用此功能了。 + +### 通过配置文件来启用 TSZ 压缩算法 + +如果要启用 TSZ 压缩算法,除了在 TDengine 的编译过程需要声明启用 TSZ 模块之外,还需要在 taos.cfg 配置文件中对以下参数进行设置: +* lossyColumns:配置要进行有损压缩的浮点数数据类型。参数值类型为字符串,含义为:空 - 关闭有损压缩;float - 只对 FLOAT 类型进行有损压缩;double - 只对 DOUBLE 类型进行有损压缩;float|double:对 FLOAT 和 DOUBLE 类型都进行有损压缩。默认值是“空”,也即关闭有损压缩。 +* fPrecision:设置 float 类型浮点数压缩精度,小于此值的浮点数尾数部分将被截断。参数值类型为 FLOAT,最小值为 0.0,最大值为 100,000.0。缺省值为 0.00000001(1E-8)。 +* dPrecision:设置 double 类型浮点数压缩精度,小于此值的浮点数尾数部分将被截断。参数值类型为 DOUBLE,最小值为 0.0,最大值为 100,000.0。缺省值为 0.0000000000000001(1E-16)。 +* maxRange:表示数据的最大浮动范围。一般无需调整,在数据具有特定特征时可以配合 range 参数来实现极高的数据压缩率。默认值为 500。 +* range:表示数据大体浮动范围。一般无需调整,在数据具有特定特征时可以配合 maxRange 参数来实现极高的数据压缩率。默认值为 100。 + +**注意:**对 cfg 配置文件中参数值的任何调整,都需要重新启动 taosd 才能生效。并且以上选项为全局配置选项,配置后对所有数据库中所有表的 FLOAT 及 DOUBLE 类型的字段生效。 + ## 文件目录结构 安装TDengine后,默认会在操作系统中生成下列目录或文件: diff --git a/documentation20/cn/12.taos-sql/docs.md b/documentation20/cn/12.taos-sql/docs.md index b96a9c3d285e76384ac8dad64473764bcc76942b..d4ae0be7202c4a452024d58839dacef818cd4c64 100644 --- a/documentation20/cn/12.taos-sql/docs.md +++ b/documentation20/cn/12.taos-sql/docs.md @@ -730,6 +730,34 @@ Query OK, 1 row(s) in set (0.001091s) 5. 从 2.0.17.0 版本开始,条件过滤开始支持 BETWEEN AND 语法,例如 `WHERE col2 BETWEEN 1.5 AND 3.25` 表示查询条件为“1.5 ≤ col2 ≤ 3.25”。 6. 从 2.1.4.0 版本开始,条件过滤开始支持 IN 算子,例如 `WHERE city IN ('Beijing', 'Shanghai')`。说明:BOOL 类型写作 `{true, false}` 或 `{0, 1}` 均可,但不能写作 0、1 之外的整数;FLOAT 和 DOUBLE 类型会受到浮点数精度影响,集合内的值在精度范围内认为和数据行的值完全相等才能匹配成功;TIMESTAMP 类型支持非主键的列。 + +### JOIN 子句 + +从 2.2.0.0 版本开始,TDengine 对内连接(INNER JOIN)中的自然连接(Natural join)操作实现了完整的支持。也即支持“普通表与普通表之间”、“超级表与超级表之间”、“子查询与子查询之间”进行自然连接。自然连接与内连接的主要区别是,自然连接要求参与连接的字段在不同的表/超级表中必须是同名字段。也即,TDengine 在连接关系的表达中,要求必须使用同名数据列/标签列的相等关系。 + +在普通表与普通表之间的 JOIN 操作中,只能使用主键时间戳之间的相等关系。例如: +```sql +SELECT * +FROM temp_tb_1 t1, pressure_tb_1 t2 +WHERE t1.ts = t2.ts +``` + +在超级表与超级表之间的 JOIN 操作中,除了主键时间戳一致的条件外,还要求引入能实现一一对应的标签列的相等关系。例如: +```sql +SELECT * +FROM temp_stable t1, temp_stable t2 +WHERE t1.ts = t2.ts AND t1.deviceid = t2.deviceid AND t1.status=0; +``` + +类似地,也可以对多个子查询的查询结果进行 JOIN 操作。 + +注意,JOIN 操作存在如下限制要求: +1. 参与一条语句中 JOIN 操作的表/超级表最多可以有 10 个。 +2. 在包含 JOIN 操作的查询语句中不支持 FILL。 +3. 暂不支持参与 JOIN 操作的表之间聚合后的四则运算。 +4. 不支持只对其中一部分表做 GROUP BY。 +5. JOIN 查询的不同表的过滤条件之间不能为 OR。 + ### 嵌套查询 @@ -757,7 +785,7 @@ SELECT ... FROM (SELECT ... FROM ...) ...; * 外层查询不支持 GROUP BY。 -### UNION ALL 操作符 +### UNION ALL 子句 ```mysql SELECT ... @@ -1258,9 +1286,13 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 适用于:**表、超级表**。 - 说明:(从 2.0.15.0 版本开始新增此函数)INTERP 必须指定时间断面,如果该时间断面不存在直接对应的数据,那么会根据 FILL 参数的设定进行插值。此外,条件语句里面可附带筛选条件,例如标签、tbname。 + 说明:(从 2.0.15.0 版本开始新增此函数) + + 1)INTERP 必须指定时间断面,如果该时间断面不存在直接对应的数据,那么会根据 FILL 参数的设定进行插值。此外,条件语句里面可附带筛选条件,例如标签、tbname。 + + 2)INTERP 查询要求查询的时间区间必须位于数据集合(表)的所有记录的时间范围之内。如果给定的时间戳位于时间范围之外,即使有插值指令,仍然不返回结果。 - INTERP 查询要求查询的时间区间必须位于数据集合(表)的所有记录的时间范围之内。如果给定的时间戳位于时间范围之外,即使有插值指令,仍然不返回结果。 + 3)单个 INTERP 函数查询只能够针对一个时间点进行查询,如果需要返回等时间间隔的断面数据,可以通过 INTERP 配合 EVERY 的方式来进行查询处理(而不是使用 INTERVAL),其含义是每隔固定长度的时间进行插值。 示例: ```sql @@ -1284,6 +1316,18 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 Query OK, 1 row(s) in set (0.003056s) ``` + 如下所示代码表示在时间区间 `['2017-7-14 18:40:00', '2017-7-14 18:40:00.014']` 中每隔 5 毫秒 进行一次断面计算。 + + ```sql + taos> SELECT INTERP(current) FROM d636 WHERE ts>='2017-7-14 18:40:00' AND ts<='2017-7-14 18:40:00.014' EVERY(5a); + ts | interp(current) | + ================================================= + 2017-07-14 18:40:00.000 | 10.04179 | + 2017-07-14 18:40:00.010 | 10.16123 | + Query OK, 2 row(s) in set (0.003487s) + + ``` + ### 计算函数 - **DIFF** @@ -1470,12 +1514,6 @@ SELECT AVG(current), MAX(current), LEASTSQUARES(current, start_val, step_val), P TAOS SQL 支持对标签、TBNAME 进行 GROUP BY 操作,也支持普通列进行 GROUP BY,前提是:仅限一列且该列的唯一值小于 10 万个。 -**JOIN 操作的限制** - -TAOS SQL 支持表之间按主键时间戳来 join 两张表的列,暂不支持两个表之间聚合后的四则运算。 - -JOIN 查询的不同表的过滤条件之间不能为 OR。 - **IS NOT NULL 与不为空的表达式适用范围** IS NOT NULL 支持所有类型的列。不为空的表达式为 <>"",仅对非数值类型的列适用。 diff --git a/documentation20/en/03.architecture/docs.md b/documentation20/en/03.architecture/docs.md index bc686aebbf0b7696b1355fe45be6d09fcca63411..e0a324acad37d3c9e23d73a1f5762651b32e924d 100644 --- a/documentation20/en/03.architecture/docs.md +++ b/documentation20/en/03.architecture/docs.md @@ -13,7 +13,6 @@ In typical industry IoT, Internet of Vehicles and Operation Monitoring scenarios Collected Metrics Tags - Device ID Time Stamp @@ -108,16 +107,16 @@ Each data record contains the device ID, timestamp, collected metrics (current, As the data points are a series of data points over time, the data points generated by IoT, Internet of Vehicles, and Operation Monitoring have some strong common characteristics: -1. metrics are always structured data; -2. there are rarely delete/update operations on collected data; -3. unlike traditional databases, transaction processing is not required; -4. the ratio of writing over reading is much higher than typical Internet applications; -5. data volume is stable and can be predicted according to the number of devices and sampling rate; -6. the user pays attention to the trend of data, not a specific value at a specific time; -7. there is always a data retention policy; -8. the data query is always executed in a given time range and a subset of space; -9. in addition to storage and query operations, various statistical and real-time computing are also required; -10. data volume is huge, a system may generate over 10 billion data points in a day. +1. Metrics are always structured data; +2. There are rarely delete/update operations on collected data; +3. Unlike traditional databases, transaction processing is not required; +4. The ratio of writing over reading is much higher than typical Internet applications; +5. Data volume is stable and can be predicted according to the number of devices and sampling rate; +6. The user pays attention to the trend of data, not a specific value at a specific time; +7. There is always a data retention policy; +8. The data query is always executed in a given time range and a subset of space; +9. In addition to storage and query operations, various statistical and real-time computing are also required; +10. Data volume is huge, a system may generate over 10 billion data points in a day. By utilizing the above characteristics, TDengine designs the storage and computing engine in a special and optimized way for time-series data, resulting in massive improvements in system efficiency. @@ -160,7 +159,7 @@ Logical structure diagram of TDengine distributed architecture as following: -A complete TDengine system runs on one or more physical nodes. Logically, it includes data node (dnode), TDEngine application driver (taosc) and application (app). There are one or more data nodes in the system, which form a cluster. The application interacts with the TDengine cluster through taosc's API. The following is a brief introduction to each logical unit. +A complete TDengine system runs on one or more physical nodes. Logically, it includes data node (dnode), TDEngine application driver (TAOSC) and application (app). There are one or more data nodes in the system, which form a cluster. The application interacts with the TDengine cluster through TAOSC's API. The following is a brief introduction to each logical unit. **Physical node (pnode)**: A pnode is a computer that runs independently and has its own computing, storage and network capabilities. It can be a physical machine, virtual machine, or Docker container installed with OS. The physical node is identified by its configured FQDN (Fully Qualified Domain Name). TDengine relies entirely on FQDN for network communication. If you don't know about FQDN, please read the blog post "[All about FQDN of TDengine](https://www.taosdata.com/blog/2020/09/11/1824.html)". @@ -172,7 +171,7 @@ A complete TDengine system runs on one or more physical nodes. Logically, it inc **Virtual node group (VGroup)**: Vnodes on different data nodes can form a virtual node group to ensure the high availability of the system. The virtual node group is managed in a master/slave mechanism. Write operations can only be performed on the master vnode, and then replicated to slave vnodes, thus ensuring that one single replica of data is copied on multiple physical nodes. The number of virtual nodes in a vgroup equals the number of data replicas. If the number of replicas of a DB is N, the system must have at least N data nodes. The number of replicas can be specified by the parameter `replica` when creating DB, and the default is 1. Using the multi-replication feature of TDengine, the same high data reliability can be achieved without the need for expensive storage devices such as disk arrays. Virtual node group is created and managed by the management node, and the management node assigns a system unique ID, aka VGroup ID. If two virtual nodes have the same vnode group ID, means that they belong to the same group and the data is backed up to each other. The number of virtual nodes in a virtual node group can be dynamically changed, allowing only one, that is, no data replication. VGroup ID is never changed. Even if a virtual node group is deleted, its ID will not be reused. -**TAOSC**: TAOSC is the driver provided by TDengine to applications, which is responsible for dealing with the interaction between application and cluster, and provides the native interface of C/C++ language, which is embedded in JDBC, C #, Python, Go, Node.js language connection libraries. Applications interact with the whole cluster through taosc instead of directly connecting to data nodes in the cluster. This module is responsible for obtaining and caching metadata; forwarding requests for insertion, query, etc. to the correct data node; when returning the results to the application, taosc also needs to be responsible for the final level of aggregation, sorting, filtering and other operations. For JDBC, C/C++/C #/Python/Go/Node.js interfaces, this module runs on the physical node where the application is located. At the same time, in order to support the fully distributed RESTful interface, taosc has a running instance on each dnode of TDengine cluster. +**TAOSC**: TAOSC is the driver provided by TDengine to applications, which is responsible for dealing with the interaction between application and cluster, and provides the native interface of C/C++ language, which is embedded in JDBC, C #, Python, Go, Node.js language connection libraries. Applications interact with the whole cluster through TAOSC instead of directly connecting to data nodes in the cluster. This module is responsible for obtaining and caching metadata; forwarding requests for insertion, query, etc. to the correct data node; when returning the results to the application, TAOSC also needs to be responsible for the final level of aggregation, sorting, filtering and other operations. For JDBC, C/C++/C #/Python/Go/Node.js interfaces, this module runs on the physical node where the application is located. At the same time, in order to support the fully distributed RESTful interface, TAOSC has a running instance on each dnode of TDengine cluster. ### Node Communication @@ -184,35 +183,39 @@ A complete TDengine system runs on one or more physical nodes. Logically, it inc **Cluster external connection**: TDengine cluster can accommodate one single, multiple or even thousands of data nodes. The application only needs to initiate a connection to any data node in the cluster. The network parameter required for connection is the End Point (FQDN plus configured port number) of a data node. When starting the application taos through CLI, the FQDN of the data node can be specified through the option `-h`, and the configured port number can be specified through `-p`. If the port is not configured, the system configuration parameter serverPort of TDengine will be adopted. -**Inter-cluster communication**: Data nodes connect with each other through TCP/UDP. When a data node starts, it will obtain the EP information of the dnode where the mnode is located, and then establish a connection with the mnode in the system to exchange information. There are three steps to obtain EP information of the mnode: 1. Check whether the mnodeEpList file exists, if it does not exist or cannot be opened normally to obtain EP information of the mnode, skip to the second step; 2: Check the system configuration file taos.cfg to obtain node configuration parameters firstEp and secondEp (the node specified by these two parameters can be a normal node without mnode, in this case, the node will try to redirect to the mnode node when connected). If these two configuration parameters do not exist or do not exist in taos.cfg, or are invalid, skip to the third step; 3: Set your own EP as a mnode EP and run it independently. After obtaining the mnode EP list, the data node initiates the connection. It will successfully join the working cluster after connection. If not successful, it will try the next item in the mnode EP list. If all attempts are made, but the connection still fails, sleep for a few seconds before trying again. +**Inter-cluster communication**: Data nodes connect with each other through TCP/UDP. When a data node starts, it will obtain the EP information of the dnode where the mnode is located, and then establish a connection with the mnode in the system to exchange information. There are three steps to obtain EP information of the mnode: + +1. Check whether the mnodeEpList file exists, if it does not exist or cannot be opened normally to obtain EP information of the mnode, skip to the second step; +2. Check the system configuration file taos.cfg to obtain node configuration parameters firstEp and secondEp (the node specified by these two parameters can be a normal node without mnode, in this case, the node will try to redirect to the mnode node when connected). If these two configuration parameters do not exist or do not exist in taos.cfg, or are invalid, skip to the third step; +3. Set your own EP as a mnode EP and run it independently. After obtaining the mnode EP list, the data node initiates the connection. It will successfully join the working cluster after connection. If not successful, it will try the next item in the mnode EP list. If all attempts are made, but the connection still fails, sleep for a few seconds before trying again. **The choice of MNODE**: TDengine logically has a management node, but there is no separated execution code. The server-side only has a set of execution code taosd. So which data node will be the management node? This is determined automatically by the system without any manual intervention. The principle is as follows: when a data node starts, it will check its End Point and compare it with the obtained mnode EP List. If its EP exists in it, the data node shall start the mnode module and become a mnode. If your own EP is not in the mnode EP List, the mnode module will not start. During the system operation, due to load balancing, downtime and other reasons, mnode may migrate to the new dnode, while totally transparent without manual intervention. The modification of configuration parameters is the decision made by mnode itself according to resources usage. **Add new data nodes:** After the system has a data node, it has become a working system. There are two steps to add a new node into the cluster. Step1: Connect to the existing working data node using TDengine CLI, and then add the End Point of the new data node with the command "create dnode"; Step 2: In the system configuration parameter file taos.cfg of the new data node, set the firstEp and secondEp parameters to the EP of any two data nodes in the existing cluster. Please refer to the detailed user tutorial for detailed steps. In this way, the cluster will be established step by step. -**Redirection**: No matter about dnode or taosc, the connection to the mnode shall be initiated first, but the mnode is automatically created and maintained by the system, so the user does not know which dnode is running the mnode. TDengine only requires a connection to any working dnode in the system. Because any running dnode maintains the currently running mnode EP List, when receiving a connecting request from the newly started dnode or taosc, if it’s not a mnode by self, it will reply to the mnode EP List back. After receiving this list, taosc or the newly started dnode will try to establish the connection again. When the mnode EP List changes, each data node quickly obtains the latest list and notifies taosc through messaging interaction among nodes. +**Redirection**: No matter about dnode or TAOSC, the connection to the mnode shall be initiated first, but the mnode is automatically created and maintained by the system, so the user does not know which dnode is running the mnode. TDengine only requires a connection to any working dnode in the system. Because any running dnode maintains the currently running mnode EP List, when receiving a connecting request from the newly started dnode or TAOSC, if it’s not a mnode by self, it will reply to the mnode EP List back. After receiving this list, TAOSC or the newly started dnode will try to establish the connection again. When the mnode EP List changes, each data node quickly obtains the latest list and notifies TAOSC through messaging interaction among nodes. ### A Typical Data Writinfg Process -To explain the relationship between vnode, mnode, taosc and application and their respective roles, the following is an analysis of a typical data writing process. +To explain the relationship between vnode, mnode, TAOSC and application and their respective roles, the following is an analysis of a typical data writing process. ![ typical process of TDengine](page://images/architecture/message.png)
Picture 2 typical process of TDengine
1. Application initiates a request to insert data through JDBC, ODBC, or other APIs. -2. taosc checks if meta data existing for the table in the cache. If so, go straight to Step 4. If not, taosc sends a get meta-data request to mnode. -3. Mnode returns the meta-data of the table to taosc. Meta-data contains the schema of the table, and also the vgroup information to which the table belongs (the vnode ID and the End Point of the dnode where the table belongs. If the number of replicas is N, there will be N groups of End Points). If taosc does not receive a response from the mnode for a long time, and there are multiple mnodes, taosc will send a request to the next mnode. -4. Taosc initiates an insert request to master vnode. -5. After vnode inserts the data, it gives a reply to taosc, indicating that the insertion is successful. If taosc doesn't get a response from vnode for a long time, taosc will treat this node as offline. In this case, if there are multiple replicas of the inserted database, taosc will issue an insert request to the next vnode in vgroup. -6. Taosc notifies APP that writing is successful. +2. TAOSC checks if meta data existing for the table in the cache. If so, go straight to Step 4. If not, TAOSC sends a get meta-data request to mnode. +3. Mnode returns the meta-data of the table to TAOSC. Meta-data contains the schema of the table, and also the vgroup information to which the table belongs (the vnode ID and the End Point of the dnode where the table belongs. If the number of replicas is N, there will be N groups of End Points). If TAOSC does not receive a response from the mnode for a long time, and there are multiple mnodes, TAOSC will send a request to the next mnode. +4. TAOSC initiates an insert request to master vnode. +5. After vnode inserts the data, it gives a reply to TAOSC, indicating that the insertion is successful. If TAOSC doesn't get a response from vnode for a long time, TAOSC will treat this node as offline. In this case, if there are multiple replicas of the inserted database, TAOSC will issue an insert request to the next vnode in vgroup. +6. TAOSC notifies APP that writing is successful. -For Step 2 and 3, when taosc starts, it does not know the End Point of mnode, so it will directly initiate a request to the configured serving End Point of the cluster. If the dnode that receives the request does not have a mnode configured, it will inform the mnode EP list in a reply message, so that taosc will re-issue a request to obtain meta-data to the EP of another new mnode. +For Step 2 and 3, when TAOSC starts, it does not know the End Point of mnode, so it will directly initiate a request to the configured serving End Point of the cluster. If the dnode that receives the request does not have a mnode configured, it will inform the mnode EP list in a reply message, so that TAOSC will re-issue a request to obtain meta-data to the EP of another new mnode. -For Step 4 and 5, without caching, taosc can't recognize the master in the virtual node group, so assumes that the first vnode is the master and sends a request to it. If this vnode is not the master, it will reply to the actual master as a new target where taosc shall send a request to. Once the reply of successful insertion is obtained, taosc will cache the information of master node. +For Step 4 and 5, without caching, TAOSC can't recognize the master in the virtual node group, so assumes that the first vnode is the master and sends a request to it. If this vnode is not the master, it will reply to the actual master as a new target where TAOSC shall send a request to. Once the reply of successful insertion is obtained, TAOSC will cache the information of master node. -The above is the process of inserting data, and the processes of querying and computing are the same. Taosc encapsulates and hides all these complicated processes, and it is transparent to applications. +The above is the process of inserting data, and the processes of querying and computing are the same. TAOSC encapsulates and hides all these complicated processes, and it is transparent to applications. -Through taosc caching mechanism, mnode needs to be accessed only when a table is accessed for the first time, so mnode will not become a system bottleneck. However, because schema and vgroup may change (such as load balancing), taosc will interact with mnode regularly to automatically update the cache. +Through TAOSC caching mechanism, mnode needs to be accessed only when a table is accessed for the first time, so mnode will not become a system bottleneck. However, because schema and vgroup may change (such as load balancing), TAOSC will interact with mnode regularly to automatically update the cache. ## Storage Model and Data Partitioning/Sharding @@ -259,7 +262,7 @@ The load balancing process does not require any manual intervention, and it is t ## Data Writing and Replication Process -If a database has N replicas, thus a virtual node group has N virtual nodes, but only one as Master and all others are slaves. When the application writes a new record to system, only the Master vnode can accept the writing request. If a slave vnode receives a writing request, the system will notifies taosc to redirect. +If a database has N replicas, thus a virtual node group has N virtual nodes, but only one as Master and all others are slaves. When the application writes a new record to system, only the Master vnode can accept the writing request. If a slave vnode receives a writing request, the system will notifies TAOSC to redirect. ### Master vnode Writing Process @@ -281,9 +284,9 @@ For a slave vnode, the write process as follows: ![TDengine Slave Writing Process](page://images/architecture/write_master.png)
Picture 3 TDengine Slave Writing Process
-1. Slave vnode receives a data insertion request forwarded by Master vnode. +1. Slave vnode receives a data insertion request forwarded by Master vnode; 2. If the system configuration parameter `walLevel` is greater than 0, vnode will write the original request packet into database log file WAL. If walLevel is set to 2 and fsync is set to 0, TDengine will make WAL data written immediately to ensure that even system goes down, all data can be recovered from database log file; -3. Write into memory and add the record to “skip list”; +3. Write into memory and add the record to “skip list”. Compared with Master vnode, slave vnode has no forwarding or reply confirmation step, means two steps less. But writing into memory and WAL is exactly the same. @@ -297,7 +300,7 @@ However, the asynchronous replication has a tiny time window where data can be l 1. Master vnode has finished its 5-step operations, confirmed the success of writing to APP, and then went down; 2. Slave vnode receives the write request, then processing fails before writing to the log in Step 2; -3. Slave vnode will become the new master, thus losing one record +3. Slave vnode will become the new master, thus losing one record. In theory, for asynchronous replication, there is no guarantee to prevent data loss. However, this window is extremely small, only if mater and slave fail at the same time, and just confirm the successful write to the application before. @@ -419,11 +422,11 @@ TDengine creates a separate table for each data collection point, but in practic
Picture 4 Diagram of multi-table aggregation query
1. Application sends a query condition to system; -2. taosc sends the STable name to Meta Node(management node); -3. Management node sends the vnode list owned by the STable back to taosc; -4. taosc sends the computing request together with tag filters to multiple data nodes corresponding to these vnodes; -5. Each vnode first finds out the set of tables within its own node that meet the tag filters from memory, then scans the stored time-series data, completes corresponding aggregation calculations, and returns result to taosc; -6. taosc finally aggregates the results returned by multiple data nodes and send them back to application. +2. TAOSC sends the STable name to Meta Node(management node); +3. Management node sends the vnode list owned by the STable back to TAOSC; +4. TAOSC sends the computing request together with tag filters to multiple data nodes corresponding to these vnodes; +5. Each vnode first finds out the set of tables within its own node that meet the tag filters from memory, then scans the stored time-series data, completes corresponding aggregation calculations, and returns result to TAOSC; +6. TAOSC finally aggregates the results returned by multiple data nodes and send them back to application. Since TDengine stores tag data and time-series data separately in vnode, by filtering tag data in memory, the set of tables that need to participate in aggregation operation is first found, which greatly reduces the volume of data scanned and improves aggregation speed. At the same time, because the data is distributed in multiple vnodes/dnodes, the aggregation operation is carried out concurrently in multiple vnodes, which further improves the aggregation speed. Aggregation functions for ordinary tables and most operations are applicable to STables. The syntax is exactly the same. Please see TAOS SQL for details. diff --git a/documentation20/en/08.connector/docs.md b/documentation20/en/08.connector/docs.md index c111a47450356e81ed1ad1f03192c84b0e471ced..fd9d129e50fa4450aed2fbebe80eddb978ef1263 100644 --- a/documentation20/en/08.connector/docs.md +++ b/documentation20/en/08.connector/docs.md @@ -66,7 +66,11 @@ Run install_client.sh to install. Edit the taos.cfg file (default path/etc/taos/taos.cfg) and change firstEP to End Point of the TDengine server, for example: [h1.taos.com](http://h1.taos.com/):6030. -**Tip: If no TDengine service deployed in this machine, but only the application driver is installed, only firstEP needs to be configured in taos.cfg, and FQDN does not.** +**Tip: ** + +**1. If no TDengine service deployed in this machine, but only the application driver is installed, only firstEP needs to be configured in taos.cfg, and FQDN does not.** + +**2. To prevent “unable to resolve FQDN” error when connecting to the server, ensure that the hosts file of the client has the correct FQDN value.** **Windows x64/x86** @@ -128,7 +132,7 @@ taos> **Windows (x64/x86) environment:** -Under cmd, enter the c:\ tdengine directory and directly execute taos.exe, and you should be able to connect to tdengine service normally and jump to taos shell interface. For example: +Under cmd, enter the c:\TDengine directory and directly execute taos.exe, and you should be able to connect to tdengine service normally and jump to taos shell interface. For example: ```mysql C:\TDengine>taos @@ -409,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: -`pip install src/connector/python/linux/python2/` +`pip install src/connector/python/` or - `pip3 install src/connector/python/linux/python3/` + `pip3 install src/connector/python/` #### Windows diff --git a/documentation20/en/12.taos-sql/docs.md b/documentation20/en/12.taos-sql/docs.md index 630fbd1cdbeab7d9500b88ab979d708b14441f0a..7aaeb6c32b25cef8f0d1bf2f67ef94c3a2a007ee 100644 --- a/documentation20/en/12.taos-sql/docs.md +++ b/documentation20/en/12.taos-sql/docs.md @@ -1,8 +1,8 @@ # TAOS SQL -TDengine provides a SQL-style language, TAOS SQL, to insert or query data. To read through this document, you should have some basic understanding about SQL. +TDengine provides a SQL-style language, TAOS SQL, to insert or query data. This document introduces TAOS SQL and supports other common tips. To read through this document, readers should have basic understanding about SQL. -TAOS SQL is the main way for users to write and query data to TDengine. TAOS SQL is similar to standard SQL to facilitate users to get started quickly. Strictly speaking, TAOS SQL is not and does not attempt to provide SQL standard syntax. In addition, since TDengine does not provide deletion function for time-series data, the relevant function of data deletion is non-existent in TAO SQL. +TAOS SQL is the main tool for users to write and query data into/from TDengine. TAOS SQL provides a syntax style similar to standard SQL to facilitate users to get started quickly. Strictly speaking, TAOS SQL is not and does not attempt to provide SQL standard syntax. In addition, since TDengine does not provide deletion functionality for time-series data, the relevant functions of data deletion is unsupported in TAO SQL. Let’s take a look at the conventions used for syntax descriptions. @@ -37,7 +37,7 @@ With TDengine, the most important thing is timestamp. When creating and insertin - Epch Time: a timestamp value can also be a long integer representing milliseconds since 1970-01-01 08:00:00.000. - Arithmetic operations can be applied to timestamp. For example: now-2h represents a timestamp which is 2 hours ago from the current server time. Units include u( microsecond), a (milliseconds), s (seconds), m (minutes), h (hours), d (days), w (weeks). In `select * from t1 where ts > now-2w and ts <= now-1w`, which queries data of the whole week before two weeks. To specify the interval of down sampling, you can also use n(calendar month) and y(calendar year) as time units. -Default time precision of TDengine is millisecond, you can change it to microseocnd by setting parameter enableMicrosecond. +TDengine's timestamp is set to millisecond accuracy by default. Microsecond/nanosecond accuracy can be set using CREATE DATABASE with PRECISION parameter. (Nanosecond resolution is supported from version 2.1.5.0 onwards.) In TDengine, the following 10 data types can be used in data model of an ordinary table. @@ -1244,4 +1244,4 @@ TAOS SQL supports join columns of two tables by Primary Key timestamp between th **Availability of is no null** -Is not null supports all types of columns. Non-null expression is < > "" and only applies to columns of non-numeric types. \ No newline at end of file +Is not null supports all types of columns. Non-null expression is < > "" and only applies to columns of non-numeric types. diff --git a/packaging/tools/install.sh b/packaging/tools/install.sh index e116d72d2649940f9d272b8d3d01e34576a4049d..9c6a6e62f5b5fda1cfbaf1b5fff9593a5e349271 100755 --- a/packaging/tools/install.sh +++ b/packaging/tools/install.sh @@ -102,6 +102,12 @@ elif echo $osinfo | grep -qwi "centos" ; then elif echo $osinfo | grep -qwi "fedora" ; then # echo "This is fedora system" os_type=2 +elif echo $osinfo | grep -qwi "Linx" ; then +# echo "This is Linx system" + os_type=1 + service_mod=0 + initd_mod=0 + service_config_dir="/etc/systemd/system" else echo " osinfo: ${osinfo}" echo " This is an officially unverified linux system," diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index 0d06e5d39c0ed1916e0c2af7ccce5918e31ac42f..df0cf15fe00eda5bc8e6004e2794733537b8aee0 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -13,13 +13,13 @@ IF (TD_LINUX) # set the static lib name ADD_LIBRARY(taos_static STATIC ${SRC}) - TARGET_LINK_LIBRARIES(taos_static common query trpc tutil pthread m rt ${VAR_TSZ}) + TARGET_LINK_LIBRARIES(taos_static common query trpc tutil pthread m rt cJson ${VAR_TSZ}) SET_TARGET_PROPERTIES(taos_static PROPERTIES OUTPUT_NAME "taos_static") SET_TARGET_PROPERTIES(taos_static PROPERTIES CLEAN_DIRECT_OUTPUT 1) # generate dynamic library (*.so) ADD_LIBRARY(taos SHARED ${SRC}) - TARGET_LINK_LIBRARIES(taos common query trpc tutil pthread m rt) + TARGET_LINK_LIBRARIES(taos common query trpc tutil pthread m rt cJson) IF (TD_LINUX_64) TARGET_LINK_LIBRARIES(taos lua) ENDIF () @@ -39,13 +39,13 @@ ELSEIF (TD_DARWIN) # set the static lib name ADD_LIBRARY(taos_static STATIC ${SRC}) - TARGET_LINK_LIBRARIES(taos_static common query trpc tutil pthread m lua) + TARGET_LINK_LIBRARIES(taos_static common query trpc tutil pthread m lua cJson) SET_TARGET_PROPERTIES(taos_static PROPERTIES OUTPUT_NAME "taos_static") SET_TARGET_PROPERTIES(taos_static PROPERTIES CLEAN_DIRECT_OUTPUT 1) # generate dynamic library (*.dylib) ADD_LIBRARY(taos SHARED ${SRC}) - TARGET_LINK_LIBRARIES(taos common query trpc tutil pthread m lua) + TARGET_LINK_LIBRARIES(taos common query trpc tutil pthread m lua cJson) SET_TARGET_PROPERTIES(taos PROPERTIES CLEAN_DIRECT_OUTPUT 1) #set version of .dylib @@ -63,26 +63,26 @@ ELSEIF (TD_WINDOWS) CONFIGURE_FILE("${TD_COMMUNITY_DIR}/src/client/src/taos.rc.in" "${TD_COMMUNITY_DIR}/src/client/src/taos.rc") ADD_LIBRARY(taos_static STATIC ${SRC}) - TARGET_LINK_LIBRARIES(taos_static trpc tutil query) + TARGET_LINK_LIBRARIES(taos_static trpc tutil query cJson) # generate dynamic library (*.dll) ADD_LIBRARY(taos SHARED ${SRC} ${TD_COMMUNITY_DIR}/src/client/src/taos.rc) IF (NOT TD_GODLL) SET_TARGET_PROPERTIES(taos PROPERTIES LINK_FLAGS /DEF:${TD_COMMUNITY_DIR}/src/client/src/taos.def) ENDIF () - TARGET_LINK_LIBRARIES(taos trpc tutil query lua) + TARGET_LINK_LIBRARIES(taos trpc tutil query lua cJson) ELSEIF (TD_DARWIN) SET(CMAKE_MACOSX_RPATH 1) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/jni/linux) ADD_LIBRARY(taos_static STATIC ${SRC}) - TARGET_LINK_LIBRARIES(taos_static query trpc tutil pthread m lua) + TARGET_LINK_LIBRARIES(taos_static query trpc tutil pthread m lua cJson) SET_TARGET_PROPERTIES(taos_static PROPERTIES OUTPUT_NAME "taos_static") # generate dynamic library (*.dylib) ADD_LIBRARY(taos SHARED ${SRC}) - TARGET_LINK_LIBRARIES(taos query trpc tutil pthread m lua) + TARGET_LINK_LIBRARIES(taos query trpc tutil pthread m lua cJson) SET_TARGET_PROPERTIES(taos PROPERTIES CLEAN_DIRECT_OUTPUT 1) diff --git a/src/client/inc/tscUtil.h b/src/client/inc/tscUtil.h index ebd5de1ab3a7faa85badd81165168347aa65f7b5..c858bd5867c64da4c7397aed2035119ff414d112 100644 --- a/src/client/inc/tscUtil.h +++ b/src/client/inc/tscUtil.h @@ -92,7 +92,7 @@ typedef struct SMergeTsCtx { }SMergeTsCtx; typedef struct SVgroupTableInfo { - SVgroupInfo vgInfo; + SVgroupMsg vgInfo; SArray *itemList; // SArray } SVgroupTableInfo; @@ -174,7 +174,9 @@ void tscClearInterpInfo(SQueryInfo* pQueryInfo); bool tscIsInsertData(char* sqlstr); -int tscAllocPayload(SSqlCmd* pCmd, int size); +// the memory is not reset in case of fast allocate payload function +int32_t tscAllocPayloadFast(SSqlCmd *pCmd, size_t size); +int32_t tscAllocPayload(SSqlCmd* pCmd, int size); TAOS_FIELD tscCreateField(int8_t type, const char* name, int16_t bytes); @@ -288,7 +290,11 @@ void doExecuteQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo); SVgroupsInfo* tscVgroupInfoClone(SVgroupsInfo *pInfo); void* tscVgroupInfoClear(SVgroupsInfo *pInfo); + +#if 0 void tscSVgroupInfoCopy(SVgroupInfo* dst, const SVgroupInfo* src); +#endif + /** * The create object function must be successful expect for the out of memory issue. * diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h index b8eb0a5286a7b72b3ddd1d34b103e5b6239a496c..ff796cdcbf5cdc7a3d9fbc313226cb9e013b0eda 100644 --- a/src/client/inc/tsclient.h +++ b/src/client/inc/tsclient.h @@ -234,7 +234,6 @@ typedef struct STableDataBlocks { typedef struct { STableMeta *pTableMeta; SArray *vgroupIdList; -// SVgroupsInfo *pVgroupsInfo; } STableMetaVgroupInfo; typedef struct SInsertStatementParam { @@ -286,20 +285,14 @@ typedef struct { int32_t resColumnId; } SSqlCmd; -typedef struct SResRec { - int numOfRows; - int numOfTotal; -} SResRec; - typedef struct { int32_t numOfRows; // num of results in current retrieval - int64_t numOfRowsGroup; // num of results of current group int64_t numOfTotal; // num of total results int64_t numOfClauseTotal; // num of total result in current subclause char * pRsp; int32_t rspType; int32_t rspLen; - uint64_t qId; + uint64_t qId; // query id of SQInfo int64_t useconds; int64_t offset; // offset value from vnode during projection query of stable int32_t row; @@ -307,8 +300,6 @@ typedef struct { int16_t precision; bool completed; int32_t code; - int32_t numOfGroups; - SResRec * pGroupRec; char * data; TAOS_ROW tsrow; TAOS_ROW urow; @@ -316,8 +307,7 @@ typedef struct { char ** buffer; // Buffer used to put multibytes encoded using unicode (wchar_t) SColumnIndex* pColumnIndex; - TAOS_FIELD* final; - SArithmeticSupport *pArithSup; // support the arithmetic expression calculation on agg functions + TAOS_FIELD* final; struct SGlobalMerger *pMerger; } SSqlRes; @@ -377,7 +367,6 @@ typedef struct SSqlObj { tsem_t rspSem; SSqlCmd cmd; SSqlRes res; - bool isBind; SSubqueryState subState; struct SSqlObj **pSubs; diff --git a/src/client/src/tscAsync.c b/src/client/src/tscAsync.c index 6b12cd0da04c0f791201182c793d647fc54c00b1..4a621d47c0dcae4c2765d53b0d5b650e22d64a58 100644 --- a/src/client/src/tscAsync.c +++ b/src/client/src/tscAsync.c @@ -60,17 +60,25 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para tscDebugL("0x%"PRIx64" SQL: %s", pSql->self, pSql->sqlstr); pCmd->resColumnId = TSDB_RES_COL_ID; + taosAcquireRef(tscObjRef, pSql->self); + int32_t code = tsParseSql(pSql, true); - if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) return; + + if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { + taosReleaseRef(tscObjRef, pSql->self); + return; + } if (code != TSDB_CODE_SUCCESS) { pSql->res.code = code; tscAsyncResultOnError(pSql); + taosReleaseRef(tscObjRef, pSql->self); return; } SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); executeQuery(pSql, pQueryInfo); + taosReleaseRef(tscObjRef, pSql->self); } // TODO return the correct error code to client in tscQueueAsyncError diff --git a/src/client/src/tscParseLineProtocol.c b/src/client/src/tscParseLineProtocol.c index c9ad7361efa3ade3e3e221a0128a5ad1f3e22ccb..e26e439492cec9c83b624c2bbb2bbc3a95de97b0 100644 --- a/src/client/src/tscParseLineProtocol.c +++ b/src/client/src/tscParseLineProtocol.c @@ -2128,11 +2128,12 @@ int32_t tscParseLines(char* lines[], int numLines, SArray* points, SArray* faile int taos_insert_lines(TAOS* taos, char* lines[], int numLines) { int32_t code = 0; - SSmlLinesInfo* info = calloc(1, sizeof(SSmlLinesInfo)); + SSmlLinesInfo* info = tcalloc(1, sizeof(SSmlLinesInfo)); info->id = genLinesSmlId(); if (numLines <= 0 || numLines > 65536) { tscError("SML:0x%"PRIx64" taos_insert_lines numLines should be between 1 and 65536. numLines: %d", info->id, numLines); + tfree(info); code = TSDB_CODE_TSC_APP_ERROR; return code; } @@ -2140,7 +2141,7 @@ int taos_insert_lines(TAOS* taos, char* lines[], int numLines) { for (int i = 0; i < numLines; ++i) { if (lines[i] == NULL) { tscError("SML:0x%"PRIx64" taos_insert_lines line %d is NULL", info->id, i); - free(info); + tfree(info); code = TSDB_CODE_TSC_APP_ERROR; return code; } @@ -2149,7 +2150,7 @@ int taos_insert_lines(TAOS* taos, char* lines[], int numLines) { SArray* lpPoints = taosArrayInit(numLines, sizeof(TAOS_SML_DATA_POINT)); if (lpPoints == NULL) { tscError("SML:0x%"PRIx64" taos_insert_lines failed to allocate memory", info->id); - free(info); + tfree(info); return TSDB_CODE_TSC_OUT_OF_MEMORY; } @@ -2177,7 +2178,7 @@ cleanup: taosArrayDestroy(lpPoints); - free(info); + tfree(info); return code; } diff --git a/src/client/src/tscParseOpenTSDB.c b/src/client/src/tscParseOpenTSDB.c index 397b5d3e97c2ed7fc1a42bd0e773bcff8f659c65..12f8ec84fd301d2d8851e92826cfcb3d860c1ceb 100644 --- a/src/client/src/tscParseOpenTSDB.c +++ b/src/client/src/tscParseOpenTSDB.c @@ -3,6 +3,7 @@ #include #include +#include "cJSON.h" #include "hash.h" #include "taos.h" @@ -12,9 +13,12 @@ #include "tscParseLine.h" -#define MAX_TELNET_FILEDS_NUM 2 -#define OTS_TIMESTAMP_COLUMN_NAME "ts" -#define OTS_METRIC_VALUE_COLUMN_NAME "value" +#define OTD_MAX_FIELDS_NUM 2 +#define OTD_JSON_SUB_FIELDS_NUM 2 +#define OTD_JSON_FIELDS_NUM 4 + +#define OTD_TIMESTAMP_COLUMN_NAME "ts" +#define OTD_METRIC_VALUE_COLUMN_NAME "value" /* telnet style API parser */ static uint64_t HandleId = 0; @@ -77,12 +81,12 @@ static int32_t parseTelnetTimeStamp(TAOS_SML_KV **pTS, int *num_kvs, const char const char *start, *cur; int32_t ret = TSDB_CODE_SUCCESS; int len = 0; - char key[] = OTS_TIMESTAMP_COLUMN_NAME; + char key[] = OTD_TIMESTAMP_COLUMN_NAME; char *value = NULL; start = cur = *index; //allocate fields for timestamp and value - *pTS = tcalloc(MAX_TELNET_FILEDS_NUM, sizeof(TAOS_SML_KV)); + *pTS = tcalloc(OTD_MAX_FIELDS_NUM, sizeof(TAOS_SML_KV)); while(*cur != '\0') { if (*cur == ' ') { @@ -123,7 +127,7 @@ static int32_t parseTelnetMetricValue(TAOS_SML_KV **pKVs, int *num_kvs, const ch const char *start, *cur; int32_t ret = TSDB_CODE_SUCCESS; int len = 0; - char key[] = OTS_METRIC_VALUE_COLUMN_NAME; + char key[] = OTD_METRIC_VALUE_COLUMN_NAME; char *value = NULL; start = cur = *index; @@ -405,7 +409,7 @@ cleanup: tscDebug("OTD:0x%"PRIx64" taos_insert_telnet_lines finish inserting %d lines. code: %d", info->id, numLines, code); points = TARRAY_GET_START(lpPoints); numPoints = taosArrayGetSize(lpPoints); - for (int i=0; ivaluestring); + if (stableLen > TSDB_TABLE_NAME_LEN) { + tscError("OTD:0x%"PRIx64" Metric cannot exceeds 193 characters in JSON", info->id); + return TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH; + } + + pSml->stableName = tcalloc(stableLen + 1, sizeof(char)); + if (pSml->stableName == NULL){ + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + + if (isdigit(metric->valuestring[0])) { + tscError("OTD:0x%"PRIx64" Metric cannnot start with digit in JSON", info->id); + tfree(pSml->stableName); + return TSDB_CODE_TSC_INVALID_JSON; + } + + tstrncpy(pSml->stableName, metric->valuestring, stableLen + 1); + + return TSDB_CODE_SUCCESS; + +} + +int32_t parseTimestampFromJSONObj(cJSON *root, int64_t *tsVal, SSmlLinesInfo* info) { + int32_t size = cJSON_GetArraySize(root); + if (size != OTD_JSON_SUB_FIELDS_NUM) { + return TSDB_CODE_TSC_INVALID_JSON; + } + + cJSON *value = cJSON_GetObjectItem(root, "value"); + if (!cJSON_IsNumber(value)) { + return TSDB_CODE_TSC_INVALID_JSON; + } + + cJSON *type = cJSON_GetObjectItem(root, "type"); + if (!cJSON_IsString(type)) { + return TSDB_CODE_TSC_INVALID_JSON; + } + + *tsVal = value->valueint; + //if timestamp value is 0 use current system time + if (*tsVal == 0) { + *tsVal = taosGetTimestampNs(); + return TSDB_CODE_SUCCESS; + } + + size_t typeLen = strlen(type->valuestring); + if (typeLen == 1 && type->valuestring[0] == 's') { + //seconds + *tsVal = (int64_t)(*tsVal * 1e9); + } else if (typeLen == 2 && type->valuestring[1] == 's') { + switch (type->valuestring[0]) { + case 'm': + //milliseconds + *tsVal = convertTimePrecision(*tsVal, TSDB_TIME_PRECISION_MILLI, TSDB_TIME_PRECISION_NANO); + break; + case 'u': + //microseconds + *tsVal = convertTimePrecision(*tsVal, TSDB_TIME_PRECISION_MICRO, TSDB_TIME_PRECISION_NANO); + break; + case 'n': + //nanoseconds + *tsVal = *tsVal * 1; + break; + default: + return TSDB_CODE_TSC_INVALID_JSON; + } + } + + return TSDB_CODE_SUCCESS; +} + +int32_t parseTimestampFromJSON(cJSON *root, TAOS_SML_KV **pTS, int *num_kvs, SSmlLinesInfo* info) { + //Timestamp must be the first KV to parse + assert(*num_kvs == 0); + int64_t tsVal; + char key[] = OTD_TIMESTAMP_COLUMN_NAME; + + cJSON *timestamp = cJSON_GetObjectItem(root, "timestamp"); + if (cJSON_IsNumber(timestamp)) { + //timestamp value 0 indicates current system time + if (timestamp->valueint == 0) { + tsVal = taosGetTimestampNs(); + } else { + tsVal = convertTimePrecision(timestamp->valueint, TSDB_TIME_PRECISION_MICRO, TSDB_TIME_PRECISION_NANO); + } + } else if (cJSON_IsObject(timestamp)) { + int32_t ret = parseTimestampFromJSONObj(timestamp, &tsVal, info); + if (ret != TSDB_CODE_SUCCESS) { + tscError("OTD:0x%"PRIx64" Failed to parse timestamp from JSON Obj", info->id); + return ret; + } + } else { + return TSDB_CODE_TSC_INVALID_JSON; + } + + //allocate fields for timestamp and value + *pTS = tcalloc(OTD_MAX_FIELDS_NUM, sizeof(TAOS_SML_KV)); + + + (*pTS)->key = tcalloc(sizeof(key), 1); + memcpy((*pTS)->key, key, sizeof(key)); + + (*pTS)->type = TSDB_DATA_TYPE_TIMESTAMP; + (*pTS)->length = (int16_t)tDataTypes[(*pTS)->type].bytes; + (*pTS)->value = tcalloc((*pTS)->length, 1); + memcpy((*pTS)->value, &tsVal, (*pTS)->length); + + *num_kvs += 1; + return TSDB_CODE_SUCCESS; + +} + +int32_t convertJSONBool(TAOS_SML_KV *pVal, char* typeStr, int64_t valueInt, SSmlLinesInfo* info) { + if (strcasecmp(typeStr, "bool") != 0) { + tscError("OTD:0x%"PRIx64" invalid type(%s) for JSON Bool", info->id, typeStr); + return TSDB_CODE_TSC_INVALID_JSON_TYPE; + } + pVal->type = TSDB_DATA_TYPE_BOOL; + pVal->length = (int16_t)tDataTypes[pVal->type].bytes; + pVal->value = tcalloc(pVal->length, 1); + *(bool *)(pVal->value) = valueInt ? true : false; + + return TSDB_CODE_SUCCESS; +} + +int32_t convertJSONNumber(TAOS_SML_KV *pVal, char* typeStr, cJSON *value, SSmlLinesInfo* info) { + //tinyint + if (strcasecmp(typeStr, "i8") == 0 || + strcasecmp(typeStr, "tinyint") == 0) { + if (!IS_VALID_TINYINT(value->valueint)) { + tscError("OTD:0x%"PRIx64" JSON value(%"PRId64") cannot fit in type(tinyint)", info->id, value->valueint); + return TSDB_CODE_TSC_VALUE_OUT_OF_RANGE; + } + pVal->type = TSDB_DATA_TYPE_TINYINT; + pVal->length = (int16_t)tDataTypes[pVal->type].bytes; + pVal->value = tcalloc(pVal->length, 1); + *(int8_t *)(pVal->value) = (int8_t)(value->valueint); + return TSDB_CODE_SUCCESS; + } + //smallint + if (strcasecmp(typeStr, "i16") == 0 || + strcasecmp(typeStr, "smallint") == 0) { + if (!IS_VALID_SMALLINT(value->valueint)) { + tscError("OTD:0x%"PRIx64" JSON value(%"PRId64") cannot fit in type(smallint)", info->id, value->valueint); + return TSDB_CODE_TSC_VALUE_OUT_OF_RANGE; + } + pVal->type = TSDB_DATA_TYPE_SMALLINT; + pVal->length = (int16_t)tDataTypes[pVal->type].bytes; + pVal->value = tcalloc(pVal->length, 1); + *(int16_t *)(pVal->value) = (int16_t)(value->valueint); + return TSDB_CODE_SUCCESS; + } + //int + if (strcasecmp(typeStr, "i32") == 0 || + strcasecmp(typeStr, "int") == 0) { + if (!IS_VALID_INT(value->valueint)) { + tscError("OTD:0x%"PRIx64" JSON value(%"PRId64") cannot fit in type(int)", info->id, value->valueint); + return TSDB_CODE_TSC_VALUE_OUT_OF_RANGE; + } + pVal->type = TSDB_DATA_TYPE_INT; + pVal->length = (int16_t)tDataTypes[pVal->type].bytes; + pVal->value = tcalloc(pVal->length, 1); + *(int32_t *)(pVal->value) = (int32_t)(value->valueint); + return TSDB_CODE_SUCCESS; + } + //bigint + if (strcasecmp(typeStr, "i64") == 0 || + strcasecmp(typeStr, "bigint") == 0) { + if (!IS_VALID_BIGINT(value->valueint)) { + tscError("OTD:0x%"PRIx64" JSON value(%"PRId64") cannot fit in type(bigint)", info->id, value->valueint); + return TSDB_CODE_TSC_VALUE_OUT_OF_RANGE; + } + pVal->type = TSDB_DATA_TYPE_BIGINT; + pVal->length = (int16_t)tDataTypes[pVal->type].bytes; + pVal->value = tcalloc(pVal->length, 1); + *(int64_t *)(pVal->value) = (int64_t)(value->valueint); + return TSDB_CODE_SUCCESS; + } + //float + if (strcasecmp(typeStr, "f32") == 0 || + strcasecmp(typeStr, "float") == 0) { + if (!IS_VALID_FLOAT(value->valuedouble)) { + tscError("OTD:0x%"PRIx64" JSON value(%f) cannot fit in type(float)", info->id, value->valuedouble); + return TSDB_CODE_TSC_VALUE_OUT_OF_RANGE; + } + pVal->type = TSDB_DATA_TYPE_FLOAT; + pVal->length = (int16_t)tDataTypes[pVal->type].bytes; + pVal->value = tcalloc(pVal->length, 1); + *(float *)(pVal->value) = (float)(value->valuedouble); + return TSDB_CODE_SUCCESS; + } + //double + if (strcasecmp(typeStr, "f64") == 0 || + strcasecmp(typeStr, "double") == 0) { + if (!IS_VALID_DOUBLE(value->valuedouble)) { + tscError("OTD:0x%"PRIx64" JSON value(%f) cannot fit in type(double)", info->id, value->valuedouble); + return TSDB_CODE_TSC_VALUE_OUT_OF_RANGE; + } + pVal->type = TSDB_DATA_TYPE_DOUBLE; + pVal->length = (int16_t)tDataTypes[pVal->type].bytes; + pVal->value = tcalloc(pVal->length, 1); + *(double *)(pVal->value) = (double)(value->valuedouble); + return TSDB_CODE_SUCCESS; + } + + //if reach here means type is unsupported + tscError("OTD:0x%"PRIx64" invalid type(%s) for JSON Number", info->id, typeStr); + return TSDB_CODE_TSC_INVALID_JSON_TYPE; +} + +int32_t convertJSONString(TAOS_SML_KV *pVal, char* typeStr, cJSON *value, SSmlLinesInfo* info) { + if (strcasecmp(typeStr, "binary") == 0) { + pVal->type = TSDB_DATA_TYPE_BINARY; + } else if (strcasecmp(typeStr, "nchar") == 0) { + pVal->type = TSDB_DATA_TYPE_NCHAR; + } else { + tscError("OTD:0x%"PRIx64" invalid type(%s) for JSON String", info->id, typeStr); + return TSDB_CODE_TSC_INVALID_JSON_TYPE; + } + pVal->length = (int16_t)strlen(value->valuestring); + pVal->value = tcalloc(pVal->length + 1, 1); + memcpy(pVal->value, value->valuestring, pVal->length); + return TSDB_CODE_SUCCESS; +} + +int32_t parseValueFromJSONObj(cJSON *root, TAOS_SML_KV *pVal, SSmlLinesInfo* info) { + int32_t ret = TSDB_CODE_SUCCESS; + int32_t size = cJSON_GetArraySize(root); + + if (size != OTD_JSON_SUB_FIELDS_NUM) { + return TSDB_CODE_TSC_INVALID_JSON; + } + + cJSON *value = cJSON_GetObjectItem(root, "value"); + if (value == NULL) { + return TSDB_CODE_TSC_INVALID_JSON; + } + + cJSON *type = cJSON_GetObjectItem(root, "type"); + if (!cJSON_IsString(type)) { + return TSDB_CODE_TSC_INVALID_JSON; + } + + switch (value->type) { + case cJSON_True: + case cJSON_False: { + ret = convertJSONBool(pVal, type->valuestring, value->valueint, info); + if (ret != TSDB_CODE_SUCCESS) { + return ret; + } + break; + } + case cJSON_Number: { + ret = convertJSONNumber(pVal, type->valuestring, value, info); + if (ret != TSDB_CODE_SUCCESS) { + return ret; + } + break; + } + case cJSON_String: { + ret = convertJSONString(pVal, type->valuestring, value, info); + if (ret != TSDB_CODE_SUCCESS) { + return ret; + } + break; + } + default: + return TSDB_CODE_TSC_INVALID_JSON_TYPE; + } + + return TSDB_CODE_SUCCESS; +} + +int32_t parseValueFromJSON(cJSON *root, TAOS_SML_KV *pVal, SSmlLinesInfo* info) { + int type = root->type; + + switch (type) { + case cJSON_True: + case cJSON_False: { + pVal->type = TSDB_DATA_TYPE_BOOL; + pVal->length = (int16_t)tDataTypes[pVal->type].bytes; + pVal->value = tcalloc(pVal->length, 1); + *(bool *)(pVal->value) = root->valueint ? true : false; + break; + } + case cJSON_Number: { + //convert default JSON Number type to float + pVal->type = TSDB_DATA_TYPE_FLOAT; + pVal->length = (int16_t)tDataTypes[pVal->type].bytes; + pVal->value = tcalloc(pVal->length, 1); + *(float *)(pVal->value) = (float)(root->valuedouble); + break; + } + case cJSON_String: { + //convert default JSON String type to nchar + pVal->type = TSDB_DATA_TYPE_NCHAR; + //pVal->length = wcslen((wchar_t *)root->valuestring) * TSDB_NCHAR_SIZE; + pVal->length = (int16_t)strlen(root->valuestring); + pVal->value = tcalloc(pVal->length + 1, 1); + memcpy(pVal->value, root->valuestring, pVal->length); + break; + } + case cJSON_Object: { + int32_t ret = parseValueFromJSONObj(root, pVal, info); + if (ret != TSDB_CODE_SUCCESS) { + tscError("OTD:0x%"PRIx64" Failed to parse timestamp from JSON Obj", info->id); + return ret; + } + break; + } + default: + return TSDB_CODE_TSC_INVALID_JSON; + } + + return TSDB_CODE_SUCCESS; +} + +int32_t parseMetricValueFromJSON(cJSON *root, TAOS_SML_KV **pKVs, int *num_kvs, SSmlLinesInfo* info) { + //skip timestamp + TAOS_SML_KV *pVal = *pKVs + 1; + char key[] = OTD_METRIC_VALUE_COLUMN_NAME; + + cJSON *metricVal = cJSON_GetObjectItem(root, "value"); + if (metricVal == NULL) { + return TSDB_CODE_TSC_INVALID_JSON; + } + + int32_t ret = parseValueFromJSON(metricVal, pVal, info); + if (ret != TSDB_CODE_SUCCESS) { + return ret; + } + + pVal->key = tcalloc(sizeof(key), 1); + memcpy(pVal->key, key, sizeof(key)); + + *num_kvs += 1; + return TSDB_CODE_SUCCESS; + +} + +int32_t parseTagsFromJSON(cJSON *root, TAOS_SML_KV **pKVs, int *num_kvs, char **childTableName, SSmlLinesInfo* info) { + int32_t ret = TSDB_CODE_SUCCESS; + + cJSON *tags = cJSON_GetObjectItem(root, "tags"); + if (tags == NULL || tags->type != cJSON_Object) { + return TSDB_CODE_TSC_INVALID_JSON; + } + + //only pick up the first ID value as child table name + cJSON *id = cJSON_GetObjectItem(tags, "ID"); + if (id != NULL) { + size_t idLen = strlen(id->valuestring); + ret = isValidChildTableName(id->valuestring, (int16_t)idLen); + if (ret != TSDB_CODE_SUCCESS) { + return ret; + } + *childTableName = tcalloc(idLen + 1, sizeof(char)); + memcpy(*childTableName, id->valuestring, idLen); + //remove all ID fields from tags list no case sensitive + while (id != NULL) { + cJSON_DeleteItemFromObject(tags, "ID"); + id = cJSON_GetObjectItem(tags, "ID"); + } + } + + int32_t tagNum = cJSON_GetArraySize(tags); + //at least one tag pair required + if (tagNum <= 0) { + return TSDB_CODE_TSC_INVALID_JSON; + } + + //allocate memory for tags + *pKVs = tcalloc(tagNum, sizeof(TAOS_SML_KV)); + TAOS_SML_KV *pkv = *pKVs; + + for (int32_t i = 0; i < tagNum; ++i) { + cJSON *tag = cJSON_GetArrayItem(tags, i); + if (tag == NULL) { + return TSDB_CODE_TSC_INVALID_JSON; + } + //key + size_t keyLen = strlen(tag->string); + pkv->key = tcalloc(keyLen + 1, sizeof(char)); + strncpy(pkv->key, tag->string, keyLen); + //value + ret = parseValueFromJSON(tag, pkv, info); + if (ret != TSDB_CODE_SUCCESS) { + return ret; + } + *num_kvs += 1; + pkv++; + } + + return ret; + +} + +int32_t tscParseJSONPayload(cJSON *root, TAOS_SML_DATA_POINT* pSml, SSmlLinesInfo* info) { + int32_t ret = TSDB_CODE_SUCCESS; + + if (!cJSON_IsObject(root)) { + tscError("OTD:0x%"PRIx64" data point needs to be JSON object", info->id); + return TSDB_CODE_TSC_INVALID_JSON; + } + + int32_t size = cJSON_GetArraySize(root); + //outmost json fields has to be exactly 4 + if (size != OTD_JSON_FIELDS_NUM) { + tscError("OTD:0x%"PRIx64" Invalid number of JSON fields in data point %d", info->id, size); + return TSDB_CODE_TSC_INVALID_JSON; + } + + //Parse metric + ret = parseMetricFromJSON(root, pSml, info); + if (ret != TSDB_CODE_SUCCESS) { + tscError("OTD:0x%"PRIx64" Unable to parse metric from JSON payload", info->id); + return ret; + } + tscDebug("OTD:0x%"PRIx64" Parse metric from JSON payload finished", info->id); + + //Parse timestamp + ret = parseTimestampFromJSON(root, &pSml->fields, &pSml->fieldNum, info); + if (ret) { + tscError("OTD:0x%"PRIx64" Unable to parse timestamp from JSON payload", info->id); + return ret; + } + tscDebug("OTD:0x%"PRIx64" Parse timestamp from JSON payload finished", info->id); + + //Parse metric value + ret = parseMetricValueFromJSON(root, &pSml->fields, &pSml->fieldNum, info); + if (ret) { + tscError("OTD:0x%"PRIx64" Unable to parse metric value from JSON payload", info->id); + return ret; + } + tscDebug("OTD:0x%"PRIx64" Parse metric value from JSON payload finished", info->id); + + //Parse tags + ret = parseTagsFromJSON(root, &pSml->tags, &pSml->tagNum, &pSml->childTableName, info); + if (ret) { + tscError("OTD:0x%"PRIx64" Unable to parse tags from JSON payload", info->id); + return ret; + } + tscDebug("OTD:0x%"PRIx64" Parse tags from JSON payload finished", info->id); + + return TSDB_CODE_SUCCESS; +} + +int32_t tscParseMultiJSONPayload(char* payload, SArray* points, SSmlLinesInfo* info) { + int32_t payloadNum, ret; + ret = TSDB_CODE_SUCCESS; + + if (payload == NULL) { + tscError("OTD:0x%"PRIx64" empty JSON Payload", info->id); + return TSDB_CODE_TSC_INVALID_JSON; + } + + cJSON *root = cJSON_Parse(payload); + //multiple data points must be sent in JSON array + if (cJSON_IsObject(root)) { + payloadNum = 1; + } else if (cJSON_IsArray(root)) { + payloadNum = cJSON_GetArraySize(root); + } else { + tscError("OTD:0x%"PRIx64" Invalid JSON Payload", info->id); + ret = TSDB_CODE_TSC_INVALID_JSON; + goto PARSE_JSON_OVER; + } + + for (int32_t i = 0; i < payloadNum; ++i) { + TAOS_SML_DATA_POINT point = {0}; + cJSON *dataPoint = (payloadNum == 1) ? root : cJSON_GetArrayItem(root, i); + + ret = tscParseJSONPayload(dataPoint, &point, info); + if (ret != TSDB_CODE_SUCCESS) { + tscError("OTD:0x%"PRIx64" JSON data point parse failed", info->id); + destroySmlDataPoint(&point); + goto PARSE_JSON_OVER; + } else { + tscDebug("OTD:0x%"PRIx64" JSON data point parse success", info->id); + } + taosArrayPush(points, &point); + } + +PARSE_JSON_OVER: + cJSON_Delete(root); + return ret; +} + +int taos_insert_json_payload(TAOS* taos, char* payload) { + int32_t code = 0; + + SSmlLinesInfo* info = tcalloc(1, sizeof(SSmlLinesInfo)); + info->id = genUID(); + + if (payload == NULL) { + tscError("OTD:0x%"PRIx64" taos_insert_json_payload payload is NULL", info->id); + tfree(info); + code = TSDB_CODE_TSC_APP_ERROR; + return code; + } + + SArray* lpPoints = taosArrayInit(1, sizeof(TAOS_SML_DATA_POINT)); + if (lpPoints == NULL) { + tscError("OTD:0x%"PRIx64" taos_insert_json_payload failed to allocate memory", info->id); + tfree(info); + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + + tscDebug("OTD:0x%"PRIx64" taos_insert_telnet_lines begin inserting %d points", info->id, 1); + code = tscParseMultiJSONPayload(payload, lpPoints, info); + size_t numPoints = taosArrayGetSize(lpPoints); + + if (code != 0) { + goto cleanup; + } + + TAOS_SML_DATA_POINT* points = TARRAY_GET_START(lpPoints); + code = tscSmlInsert(taos, points, (int)numPoints, info); + if (code != 0) { + tscError("OTD:0x%"PRIx64" taos_insert_json_payload error: %s", info->id, tstrerror((code))); + } + +cleanup: + tscDebug("OTD:0x%"PRIx64" taos_insert_json_payload finish inserting 1 Point. code: %d", info->id, code); + points = TARRAY_GET_START(lpPoints); + numPoints = taosArrayGetSize(lpPoints); + for (int i = 0; i < numPoints; ++i) { + destroySmlDataPoint(points+i); + } + + taosArrayDestroy(lpPoints); + + tfree(info); + return code; +} diff --git a/src/client/src/tscPrepare.c b/src/client/src/tscPrepare.c index bbddc4bff925de1a7d0b67fd233b6e2e88a618a3..d0ac0ccf4ee4bfa381a78090409a761717ceb4b0 100644 --- a/src/client/src/tscPrepare.c +++ b/src/client/src/tscPrepare.c @@ -1491,7 +1491,6 @@ TAOS_STMT* taos_stmt_init(TAOS* taos) { pSql->signature = pSql; pSql->pTscObj = pObj; pSql->maxRetry = TSDB_MAX_REPLICA; - pSql->isBind = true; pStmt->pSql = pSql; pStmt->last = STMT_INIT; diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 6ce996ab97906b4023acd8112d20d39ea30ccd09..05e752a679ef6925cd25b721f0258309c1ad89d6 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -280,6 +280,8 @@ static uint8_t convertRelationalOperator(SStrToken *pToken) { return TSDB_RELATION_LIKE; case TK_MATCH: return TSDB_RELATION_MATCH; + case TK_NMATCH: + return TSDB_RELATION_NMATCH; case TK_ISNULL: return TSDB_RELATION_ISNULL; case TK_NOTNULL: @@ -3730,6 +3732,9 @@ static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, case TK_MATCH: pColumnFilter->lowerRelOptr = TSDB_RELATION_MATCH; break; + case TK_NMATCH: + pColumnFilter->lowerRelOptr = TSDB_RELATION_NMATCH; + break; case TK_ISNULL: pColumnFilter->lowerRelOptr = TSDB_RELATION_ISNULL; break; @@ -3798,7 +3803,7 @@ static int32_t checkColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCol ((pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) ? 1 : 0); if (!pColFilter->filterstr) { - 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); goto _err_ret; } @@ -4352,13 +4357,13 @@ static int32_t validateLikeExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t // check for match expression 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* msg2 = "illegal column type for match"; + const char* msg2 = "illegal column type for match/nmatch"; const char* msg3 = "invalid regular expression"; tSqlExpr* pLeft = pExpr->pLeft; tSqlExpr* pRight = pExpr->pRight; - if (pExpr->tokenId == TK_MATCH) { + if (pExpr->tokenId == TK_MATCH || pExpr->tokenId == TK_NMATCH) { if (pRight->value.nLen > tsMaxRegexStringLen) { char tmp[64] = {0}; sprintf(tmp, msg1, tsMaxRegexStringLen); @@ -4366,10 +4371,14 @@ static int32_t validateMatchExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_ } 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); } + if (!(pRight->type == SQL_NODE_VALUE && pRight->value.nType == TSDB_DATA_TYPE_BINARY)) { + return invalidOperationMsg(msgBuf, msg3); + } + int errCode = 0; regex_t regex; char regErrBuf[256] = {0}; @@ -7953,11 +7962,12 @@ static int32_t handleExprInHavingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, S && pExpr->tokenId != TK_NOTNULL && pExpr->tokenId != TK_LIKE && pExpr->tokenId != TK_MATCH + && pExpr->tokenId != TK_NMATCH ) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } } 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); } @@ -8414,7 +8424,7 @@ static int32_t doLoadAllTableMeta(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNod if (p->vgroupIdList != NULL) { size_t s = taosArrayGetSize(p->vgroupIdList); - size_t vgroupsz = sizeof(SVgroupInfo) * s + sizeof(SVgroupsInfo); + size_t vgroupsz = sizeof(SVgroupMsg) * s + sizeof(SVgroupsInfo); pTableMetaInfo->vgroupList = calloc(1, vgroupsz); if (pTableMetaInfo->vgroupList == NULL) { return TSDB_CODE_TSC_OUT_OF_MEMORY; @@ -8429,14 +8439,11 @@ static int32_t doLoadAllTableMeta(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNod taosHashGetClone(tscVgroupMap, id, sizeof(*id), NULL, &existVgroupInfo); assert(existVgroupInfo.inUse >= 0); - SVgroupInfo *pVgroup = &pTableMetaInfo->vgroupList->vgroups[j]; + SVgroupMsg *pVgroup = &pTableMetaInfo->vgroupList->vgroups[j]; pVgroup->numOfEps = existVgroupInfo.numOfEps; pVgroup->vgId = existVgroupInfo.vgId; - for (int32_t k = 0; k < existVgroupInfo.numOfEps; ++k) { - pVgroup->epAddr[k].port = existVgroupInfo.ep[k].port; - pVgroup->epAddr[k].fqdn = strndup(existVgroupInfo.ep[k].fqdn, TSDB_FQDN_LEN); - } + memcpy(&pVgroup->epAddr, &existVgroupInfo.ep, sizeof(pVgroup->epAddr)); } } } diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index d81aab85d991644b3f934c8f4c47fefc274570d3..dcfbc857d5d6792b3796a098ea61046439fc5d0f 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -73,7 +73,7 @@ static int32_t removeDupVgid(int32_t *src, int32_t sz) { return ret; } -static void tscSetDnodeEpSet(SRpcEpSet* pEpSet, SVgroupInfo* pVgroupInfo) { +static void tscSetDnodeEpSet(SRpcEpSet* pEpSet, SVgroupMsg* pVgroupInfo) { assert(pEpSet != NULL && pVgroupInfo != NULL && pVgroupInfo->numOfEps > 0); // Issue the query to one of the vnode among a vgroup randomly. @@ -93,6 +93,7 @@ static void tscSetDnodeEpSet(SRpcEpSet* pEpSet, SVgroupInfo* pVgroupInfo) { existed = true; } } + assert(existed); } @@ -718,7 +719,7 @@ static char *doSerializeTableInfo(SQueryTableMsg *pQueryMsg, SSqlObj *pSql, STab int32_t index = pTableMetaInfo->vgroupIndex; assert(index >= 0); - SVgroupInfo* pVgroupInfo = NULL; + SVgroupMsg* pVgroupInfo = NULL; if (pTableMetaInfo->vgroupList && pTableMetaInfo->vgroupList->numOfVgroups > 0) { assert(index < pTableMetaInfo->vgroupList->numOfVgroups); pVgroupInfo = &pTableMetaInfo->vgroupList->vgroups[index]; @@ -856,8 +857,8 @@ static int32_t serializeSqlExpr(SSqlExpr* pExpr, STableMetaInfo* pTableMetaInfo, (*pMsg) += sizeof(SSqlExpr); for (int32_t j = 0; j < pExpr->numOfParams; ++j) { // todo add log - pSqlExpr->param[j].nType = htons((uint16_t)pExpr->param[j].nType); - pSqlExpr->param[j].nLen = htons(pExpr->param[j].nLen); + pSqlExpr->param[j].nType = htonl(pExpr->param[j].nType); + pSqlExpr->param[j].nLen = htonl(pExpr->param[j].nLen); if (pExpr->param[j].nType == TSDB_DATA_TYPE_BINARY) { memcpy((*pMsg), pExpr->param[j].pz, pExpr->param[j].nLen); @@ -875,17 +876,22 @@ static int32_t serializeSqlExpr(SSqlExpr* pExpr, STableMetaInfo* pTableMetaInfo, int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SSqlCmd *pCmd = &pSql->cmd; + SQueryInfo *pQueryInfo = NULL; + STableMeta *pTableMeta = NULL; + STableMetaInfo *pTableMetaInfo = NULL; + int32_t code = TSDB_CODE_SUCCESS; int32_t size = tscEstimateQueryMsgSize(pSql); + assert(size > 0); - if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, size)) { + if (TSDB_CODE_SUCCESS != tscAllocPayloadFast(pCmd, size)) { tscError("%p failed to malloc for query msg", pSql); return TSDB_CODE_TSC_INVALID_OPERATION; // todo add test for this } - SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd); - STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); - STableMeta * pTableMeta = pTableMetaInfo->pTableMeta; + pQueryInfo = tscGetQueryInfo(pCmd); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); + pTableMeta = pTableMetaInfo->pTableMeta; SQueryAttr query = {{0}}; tscCreateQueryFromQueryInfo(pQueryInfo, &query, pSql); @@ -936,14 +942,13 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { pQueryMsg->pointInterpQuery = query.pointInterpQuery; pQueryMsg->needReverseScan = query.needReverseScan; pQueryMsg->stateWindow = query.stateWindow; - pQueryMsg->numOfTags = htonl(numOfTags); pQueryMsg->sqlstrLen = htonl(sqlLen); pQueryMsg->sw.gap = htobe64(query.sw.gap); pQueryMsg->sw.primaryColId = htonl(PRIMARYKEY_TIMESTAMP_COL_INDEX); pQueryMsg->secondStageOutput = htonl(query.numOfExpr2); - pQueryMsg->numOfOutput = htons((int16_t)query.numOfOutput); // this is the stage one output column number + pQueryMsg->numOfOutput = htons((int16_t)query.numOfOutput); // this is the stage one output column number pQueryMsg->numOfGroupCols = htons(pQueryInfo->groupbyExpr.numOfGroupCols); pQueryMsg->queryType = htonl(pQueryInfo->type); @@ -961,7 +966,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { pQueryMsg->tableCols[i].type = htons(pCol->type); //pQueryMsg->tableCols[i].flist.numOfFilters = htons(pCol->flist.numOfFilters); pQueryMsg->tableCols[i].flist.numOfFilters = 0; - + pQueryMsg->tableCols[i].flist.filterInfo = 0; // append the filter information after the basic column information //serializeColFilterInfo(pCol->flist.filterInfo, pCol->flist.numOfFilters, &pMsg); } @@ -974,6 +979,8 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { pMsg += pCond->len; } + } else { + pQueryMsg->colCondLen = 0; } for (int32_t i = 0; i < query.numOfOutput; ++i) { @@ -1053,6 +1060,8 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { pMsg += pCond->len; } + } else { + pQueryMsg->tagCondLen = 0; } if (pQueryInfo->bufLen > 0) { @@ -1076,6 +1085,9 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { pQueryMsg->tsBuf.tsOrder = htonl(pQueryInfo->tsBuf->tsOrder); pQueryMsg->tsBuf.tsLen = htonl(pQueryMsg->tsBuf.tsLen); pQueryMsg->tsBuf.tsNumOfBlocks = htonl(pQueryMsg->tsBuf.tsNumOfBlocks); + } else { + pQueryMsg->tsBuf.tsLen = 0; + pQueryMsg->tsBuf.tsNumOfBlocks = 0; } int32_t numOfOperator = (int32_t) taosArrayGetSize(queryOperator); @@ -1113,6 +1125,9 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { pMsg += pUdfInfo->contLen; } + } else { + pQueryMsg->udfContentOffset = 0; + pQueryMsg->udfContentLen = 0; } memcpy(pMsg, pSql->sqlstr, sqlLen); @@ -2133,7 +2148,7 @@ static SVgroupsInfo* createVgroupInfoFromMsg(char* pMsg, int32_t* size, uint64_t *size = (int32_t)(sizeof(SVgroupMsg) * pVgroupMsg->numOfVgroups + sizeof(SVgroupsMsg)); - size_t vgroupsz = sizeof(SVgroupInfo) * pVgroupMsg->numOfVgroups + sizeof(SVgroupsInfo); + size_t vgroupsz = sizeof(SVgroupMsg) * pVgroupMsg->numOfVgroups + sizeof(SVgroupsInfo); SVgroupsInfo *pVgroupInfo = calloc(1, vgroupsz); assert(pVgroupInfo != NULL); @@ -2143,7 +2158,7 @@ static SVgroupsInfo* createVgroupInfoFromMsg(char* pMsg, int32_t* size, uint64_t } else { for (int32_t j = 0; j < pVgroupInfo->numOfVgroups; ++j) { // just init, no need to lock - SVgroupInfo *pVgroup = &pVgroupInfo->vgroups[j]; + SVgroupMsg *pVgroup = &pVgroupInfo->vgroups[j]; SVgroupMsg *vmsg = &pVgroupMsg->vgroups[j]; vmsg->vgId = htonl(vmsg->vgId); @@ -2155,7 +2170,8 @@ static SVgroupsInfo* createVgroupInfoFromMsg(char* pMsg, int32_t* size, uint64_t pVgroup->vgId = vmsg->vgId; for (int32_t k = 0; k < vmsg->numOfEps; ++k) { pVgroup->epAddr[k].port = vmsg->epAddr[k].port; - pVgroup->epAddr[k].fqdn = strndup(vmsg->epAddr[k].fqdn, TSDB_FQDN_LEN); + tstrncpy(pVgroup->epAddr[k].fqdn, vmsg->epAddr[k].fqdn, TSDB_FQDN_LEN); +// pVgroup->epAddr[k].fqdn = strndup(vmsg->epAddr[k].fqdn, TSDB_FQDN_LEN); } doUpdateVgroupInfo(pVgroup->vgId, vmsg); @@ -2605,7 +2621,11 @@ int tscProcessAlterTableMsgRsp(SSqlObj *pSql) { tfree(pTableMetaInfo->pTableMeta); if (isSuperTable) { // if it is a super table, iterate the hashTable and remove all the childTableMeta - taosHashClear(tscTableMetaMap); + if (pSql->res.pRsp == NULL) { + tscDebug("0x%"PRIx64" unexpected resp from mnode, super table: %s failed to update super table meta ", pSql->self, name); + return 0; + } + return tscProcessTableMetaRsp(pSql); } return 0; diff --git a/src/client/src/tscSubquery.c b/src/client/src/tscSubquery.c index 23ea7ea82d58980870cb831de8c28cb0b5149fd2..99a2a79dc60c89530eb9c2c7f6b5645ca0133ba1 100644 --- a/src/client/src/tscSubquery.c +++ b/src/client/src/tscSubquery.c @@ -623,13 +623,12 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { int16_t colId = tscGetJoinTagColIdByUid(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->id.uid); // set the tag column id for executor to extract correct tag value -#ifndef _TD_NINGSI_60 - pExpr->base.param[0] = (tVariant) {.i64 = colId, .nType = TSDB_DATA_TYPE_BIGINT, .nLen = sizeof(int64_t)}; -#else - pExpr->base.param[0].i64 = colId; - pExpr->base.param[0].nType = TSDB_DATA_TYPE_BIGINT; - pExpr->base.param[0].nLen = sizeof(int64_t); -#endif + tVariant* pVariant = &pExpr->base.param[0]; + + pVariant->i64 = colId; + pVariant->nType = TSDB_DATA_TYPE_BIGINT; + pVariant->nLen = sizeof(int64_t); + pExpr->base.numOfParams = 1; } @@ -748,10 +747,11 @@ void tscBuildVgroupTableInfo(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, SArr SVgroupTableInfo info = {{0}}; for (int32_t m = 0; m < pvg->numOfVgroups; ++m) { if (tt->vgId == pvg->vgroups[m].vgId) { - tscSVgroupInfoCopy(&info.vgInfo, &pvg->vgroups[m]); + memcpy(&info.vgInfo, &pvg->vgroups[m], sizeof(info.vgInfo)); break; } } + assert(info.vgInfo.numOfEps != 0); vgTables = taosArrayInit(4, sizeof(STableIdInfo)); @@ -2467,7 +2467,7 @@ static void doConcurrentlySendSubQueries(SSqlObj* pSql) { SSubqueryState *pState = &pSql->subState; // concurrently sent the query requests. - const int32_t MAX_REQUEST_PER_TASK = 8; + const int32_t MAX_REQUEST_PER_TASK = 4; int32_t numOfTasks = (pState->numOfSub + MAX_REQUEST_PER_TASK - 1)/MAX_REQUEST_PER_TASK; assert(numOfTasks >= 1); @@ -2554,13 +2554,14 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) { trs->pExtMemBuffer = pMemoryBuf; trs->pOrderDescriptor = pDesc; - trs->localBuffer = (tFilePage *)calloc(1, nBufferSize + sizeof(tFilePage)); + trs->localBuffer = (tFilePage *)malloc(nBufferSize + sizeof(tFilePage)); if (trs->localBuffer == NULL) { tscError("0x%"PRIx64" failed to malloc buffer for local buffer, orderOfSub:%d, reason:%s", pSql->self, i, strerror(errno)); tfree(trs); break; } - + + trs->localBuffer->num = 0; trs->subqueryIndex = i; trs->pParentSql = pSql; @@ -2655,7 +2656,7 @@ static int32_t tscReissueSubquery(SRetrieveSupport *oriTrs, SSqlObj *pSql, int32 int32_t subqueryIndex = trsupport->subqueryIndex; STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0); - SVgroupInfo* pVgroup = &pTableMetaInfo->vgroupList->vgroups[0]; + SVgroupMsg* pVgroup = &pTableMetaInfo->vgroupList->vgroups[0]; tExtMemBufferClear(trsupport->pExtMemBuffer[subqueryIndex]); @@ -2883,7 +2884,6 @@ static void tscAllDataRetrievedFromDnode(SRetrieveSupport *trsupport, SSqlObj* p pParentSql->res.precision = pSql->res.precision; pParentSql->res.numOfRows = 0; pParentSql->res.row = 0; - pParentSql->res.numOfGroups = 0; tscFreeRetrieveSup(pSql); @@ -2934,7 +2934,7 @@ static void tscRetrieveFromDnodeCallBack(void *param, TAOS_RES *tres, int numOfR SSubqueryState* pState = &pParentSql->subState; STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0); - SVgroupInfo *pVgroup = &pTableMetaInfo->vgroupList->vgroups[0]; + SVgroupMsg *pVgroup = &pTableMetaInfo->vgroupList->vgroups[0]; if (pParentSql->res.code != TSDB_CODE_SUCCESS) { trsupport->numOfRetry = MAX_NUM_OF_SUBQUERY_RETRY; @@ -3062,7 +3062,7 @@ void tscRetrieveDataRes(void *param, TAOS_RES *tres, int code) { assert(pQueryInfo->numOfTables == 1); STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0); - SVgroupInfo* pVgroup = &pTableMetaInfo->vgroupList->vgroups[trsupport->subqueryIndex]; + SVgroupMsg* pVgroup = &pTableMetaInfo->vgroupList->vgroups[trsupport->subqueryIndex]; // stable query killed or other subquery failed, all query stopped if (pParentSql->res.code != TSDB_CODE_SUCCESS) { @@ -3408,7 +3408,6 @@ static void doBuildResFromSubqueries(SSqlObj* pSql) { return; } -// tscRestoreFuncForSTableQuery(pQueryInfo); int32_t rowSize = tscGetResRowLength(pQueryInfo->exprList); assert(numOfRes * rowSize > 0); diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index 16b37ac50232cd93bdfd56c02b988cc1c038dd55..78c6493923c5b82bf04c245d68040fcb32949886 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -1348,14 +1348,7 @@ static void tscDestroyResPointerInfo(SSqlRes* pRes) { tfree(pRes->buffer); tfree(pRes->urow); - tfree(pRes->pGroupRec); tfree(pRes->pColumnIndex); - - if (pRes->pArithSup != NULL) { - tfree(pRes->pArithSup->data); - tfree(pRes->pArithSup); - } - tfree(pRes->final); pRes->data = NULL; // pRes->data points to the buffer of pRsp, no need to free @@ -2088,32 +2081,35 @@ bool tscIsInsertData(char* sqlstr) { } while (1); } -int tscAllocPayload(SSqlCmd* pCmd, int size) { +int32_t tscAllocPayloadFast(SSqlCmd *pCmd, size_t size) { if (pCmd->payload == NULL) { assert(pCmd->allocSize == 0); - pCmd->payload = (char*)calloc(1, size); - if (pCmd->payload == NULL) { + pCmd->payload = malloc(size); + pCmd->allocSize = (uint32_t) size; + } else if (pCmd->allocSize < size) { + char* tmp = realloc(pCmd->payload, size); + if (tmp == NULL) { return TSDB_CODE_TSC_OUT_OF_MEMORY; } - pCmd->allocSize = size; - } else { - if (pCmd->allocSize < (uint32_t)size) { - char* b = realloc(pCmd->payload, size); - if (b == NULL) { - return TSDB_CODE_TSC_OUT_OF_MEMORY; - } + pCmd->payload = tmp; + pCmd->allocSize = (uint32_t) size; + } - pCmd->payload = b; - pCmd->allocSize = size; - } + assert(pCmd->allocSize >= size); + return TSDB_CODE_SUCCESS; +} + +int32_t tscAllocPayload(SSqlCmd* pCmd, int size) { + assert(size > 0); + int32_t code = tscAllocPayloadFast(pCmd, (size_t) size); + if (code == TSDB_CODE_SUCCESS) { memset(pCmd->payload, 0, pCmd->allocSize); } - assert(pCmd->allocSize >= (uint32_t)size && size > 0); - return TSDB_CODE_SUCCESS; + return code; } TAOS_FIELD tscCreateField(int8_t type, const char* name, int16_t bytes) { @@ -3355,11 +3351,11 @@ void tscFreeVgroupTableInfo(SArray* pVgroupTables) { size_t num = taosArrayGetSize(pVgroupTables); for (size_t i = 0; i < num; i++) { SVgroupTableInfo* pInfo = taosArrayGet(pVgroupTables, i); - +#if 0 for(int32_t j = 0; j < pInfo->vgInfo.numOfEps; ++j) { tfree(pInfo->vgInfo.epAddr[j].fqdn); } - +#endif taosArrayDestroy(pInfo->itemList); } @@ -3373,9 +3369,9 @@ void tscRemoveVgroupTableGroup(SArray* pVgroupTable, int32_t index) { assert(size > index); SVgroupTableInfo* pInfo = taosArrayGet(pVgroupTable, index); - for(int32_t j = 0; j < pInfo->vgInfo.numOfEps; ++j) { - tfree(pInfo->vgInfo.epAddr[j].fqdn); - } +// for(int32_t j = 0; j < pInfo->vgInfo.numOfEps; ++j) { +// tfree(pInfo->vgInfo.epAddr[j].fqdn); +// } taosArrayDestroy(pInfo->itemList); taosArrayRemove(pVgroupTable, index); @@ -3385,9 +3381,12 @@ void tscVgroupTableCopy(SVgroupTableInfo* info, SVgroupTableInfo* pInfo) { memset(info, 0, sizeof(SVgroupTableInfo)); info->vgInfo = pInfo->vgInfo; + +#if 0 for(int32_t j = 0; j < pInfo->vgInfo.numOfEps; ++j) { info->vgInfo.epAddr[j].fqdn = strdup(pInfo->vgInfo.epAddr[j].fqdn); } +#endif if (pInfo->itemList) { info->itemList = taosArrayDup(pInfo->itemList); @@ -3450,13 +3449,9 @@ STableMetaInfo* tscAddTableMetaInfo(SQueryInfo* pQueryInfo, SName* name, STableM } pTableMetaInfo->pTableMeta = pTableMeta; - if (pTableMetaInfo->pTableMeta == NULL) { - pTableMetaInfo->tableMetaSize = 0; - } else { - pTableMetaInfo->tableMetaSize = tscGetTableMetaSize(pTableMeta); - } + pTableMetaInfo->tableMetaSize = (pTableMetaInfo->pTableMeta == NULL)? 0:tscGetTableMetaSize(pTableMeta); + pTableMetaInfo->tableMetaCapacity = (size_t)(pTableMetaInfo->tableMetaSize); - if (vgroupList != NULL) { pTableMetaInfo->vgroupList = tscVgroupInfoClone(vgroupList); @@ -3704,8 +3699,8 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; goto _error; } - pNewQueryInfo->numOfFillVal = pQueryInfo->fieldsInfo.numOfOutput; + pNewQueryInfo->numOfFillVal = pQueryInfo->fieldsInfo.numOfOutput; memcpy(pNewQueryInfo->fillVal, pQueryInfo->fillVal, pQueryInfo->fieldsInfo.numOfOutput * sizeof(int64_t)); } @@ -3746,7 +3741,6 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t pFinalInfo = tscAddTableMetaInfo(pNewQueryInfo, &pTableMetaInfo->name, pTableMeta, pTableMetaInfo->vgroupList, pTableMetaInfo->tagColList, pTableMetaInfo->pVgroupTables); - } else { // transfer the ownership of pTableMeta to the newly create sql object. STableMetaInfo* pPrevInfo = tscGetTableMetaInfoFromCmd(&pPrevSql->cmd, 0); if (pPrevInfo->pTableMeta && pPrevInfo->pTableMeta->tableType < 0) { @@ -3756,8 +3750,8 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t STableMeta* pPrevTableMeta = tscTableMetaDup(pPrevInfo->pTableMeta); SVgroupsInfo* pVgroupsInfo = pPrevInfo->vgroupList; - pFinalInfo = tscAddTableMetaInfo(pNewQueryInfo, &pTableMetaInfo->name, pPrevTableMeta, pVgroupsInfo, pTableMetaInfo->tagColList, - pTableMetaInfo->pVgroupTables); + pFinalInfo = tscAddTableMetaInfo(pNewQueryInfo, &pTableMetaInfo->name, pPrevTableMeta, pVgroupsInfo, + pTableMetaInfo->tagColList, pTableMetaInfo->pVgroupTables); } // this case cannot be happened @@ -4401,8 +4395,8 @@ SVgroupsInfo* tscVgroupInfoClone(SVgroupsInfo *vgroupList) { return NULL; } - size_t size = sizeof(SVgroupsInfo) + sizeof(SVgroupInfo) * vgroupList->numOfVgroups; - SVgroupsInfo* pNew = calloc(1, size); + size_t size = sizeof(SVgroupsInfo) + sizeof(SVgroupMsg) * vgroupList->numOfVgroups; + SVgroupsInfo* pNew = malloc(size); if (pNew == NULL) { return NULL; } @@ -4410,15 +4404,15 @@ SVgroupsInfo* tscVgroupInfoClone(SVgroupsInfo *vgroupList) { pNew->numOfVgroups = vgroupList->numOfVgroups; for(int32_t i = 0; i < vgroupList->numOfVgroups; ++i) { - SVgroupInfo* pNewVInfo = &pNew->vgroups[i]; + SVgroupMsg* pNewVInfo = &pNew->vgroups[i]; - SVgroupInfo* pvInfo = &vgroupList->vgroups[i]; + SVgroupMsg* pvInfo = &vgroupList->vgroups[i]; pNewVInfo->vgId = pvInfo->vgId; pNewVInfo->numOfEps = pvInfo->numOfEps; for(int32_t j = 0; j < pvInfo->numOfEps; ++j) { - pNewVInfo->epAddr[j].fqdn = strdup(pvInfo->epAddr[j].fqdn); pNewVInfo->epAddr[j].port = pvInfo->epAddr[j].port; + tstrncpy(pNewVInfo->epAddr[j].fqdn, pvInfo->epAddr[j].fqdn, TSDB_FQDN_LEN); } } @@ -4430,8 +4424,9 @@ void* tscVgroupInfoClear(SVgroupsInfo *vgroupList) { return NULL; } +#if 0 for(int32_t i = 0; i < vgroupList->numOfVgroups; ++i) { - SVgroupInfo* pVgroupInfo = &vgroupList->vgroups[i]; + SVgroupMsg* pVgroupInfo = &vgroupList->vgroups[i]; for(int32_t j = 0; j < pVgroupInfo->numOfEps; ++j) { tfree(pVgroupInfo->epAddr[j].fqdn); @@ -4442,10 +4437,11 @@ void* tscVgroupInfoClear(SVgroupsInfo *vgroupList) { } } +#endif tfree(vgroupList); return NULL; } - +# if 0 void tscSVgroupInfoCopy(SVgroupInfo* dst, const SVgroupInfo* src) { dst->vgId = src->vgId; dst->numOfEps = src->numOfEps; @@ -4458,6 +4454,8 @@ void tscSVgroupInfoCopy(SVgroupInfo* dst, const SVgroupInfo* src) { } } +#endif + char* serializeTagData(STagData* pTagData, char* pMsg) { int32_t n = (int32_t) strlen(pTagData->name); *(int32_t*) pMsg = htonl(n); @@ -4598,11 +4596,12 @@ STableMeta* tscTableMetaDup(STableMeta* pTableMeta) { SVgroupsInfo* tscVgroupsInfoDup(SVgroupsInfo* pVgroupsInfo) { assert(pVgroupsInfo != NULL); - size_t size = sizeof(SVgroupInfo) * pVgroupsInfo->numOfVgroups + sizeof(SVgroupsInfo); + size_t size = sizeof(SVgroupMsg) * pVgroupsInfo->numOfVgroups + sizeof(SVgroupsInfo); SVgroupsInfo* pInfo = calloc(1, size); pInfo->numOfVgroups = pVgroupsInfo->numOfVgroups; for (int32_t m = 0; m < pVgroupsInfo->numOfVgroups; ++m) { - tscSVgroupInfoCopy(&pInfo->vgroups[m], &pVgroupsInfo->vgroups[m]); + memcpy(&pInfo->vgroups[m], &pVgroupsInfo->vgroups[m], sizeof(SVgroupMsg)); +// tscSVgroupInfoCopy(&pInfo->vgroups[m], &pVgroupsInfo->vgroups[m]); } return pInfo; } diff --git a/src/common/inc/texpr.h b/src/common/inc/texpr.h index d5faecb65ec3a6d7c5ec3125b302d99b280f0e4b..bfeb3a6dfeee22f793c82748611c28ec537e8825 100644 --- a/src/common/inc/texpr.h +++ b/src/common/inc/texpr.h @@ -34,10 +34,12 @@ struct SSchema; #define QUERY_COND_REL_PREFIX_IN "IN|" #define QUERY_COND_REL_PREFIX_LIKE "LIKE|" #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_LIKE_LEN 5 #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 void (*__do_filter_suppl_fn_t)(void *, void *); diff --git a/src/common/inc/tglobal.h b/src/common/inc/tglobal.h index 360a83eea8df9392b059e73ac59075b27a96f7c3..604ce89432bcf662b319fb2ec11f55026450a2be 100644 --- a/src/common/inc/tglobal.h +++ b/src/common/inc/tglobal.h @@ -224,6 +224,8 @@ extern uint32_t maxRange; extern uint32_t curRange; extern char Compressor[]; #endif +// long query +extern int8_t tsDeadLockKillQuery; typedef struct { char dir[TSDB_FILENAME_LEN]; diff --git a/src/common/src/tglobal.c b/src/common/src/tglobal.c index 6e73227233591fa076893174b65a774f229ca4e5..339fa35bb3009db96c9c6e0cabea6b60881f05c5 100644 --- a/src/common/src/tglobal.c +++ b/src/common/src/tglobal.c @@ -279,6 +279,9 @@ uint32_t curRange = 100; // range char Compressor[32] = "ZSTD_COMPRESSOR"; // ZSTD_COMPRESSOR or GZIP_COMPRESSOR #endif +// long query death-lock +int8_t tsDeadLockKillQuery = 0; + int32_t (*monStartSystemFp)() = NULL; void (*monStopSystemFp)() = NULL; void (*monExecuteSQLFp)(char *sql) = NULL; @@ -1036,6 +1039,16 @@ static void doInitGlobalConfig(void) { cfg.unitType = TAOS_CFG_UTYPE_BYTE; 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.ptr = &tsMaxNumOfOrderedResults; cfg.valType = TAOS_CFG_VTYPE_INT32; @@ -1613,7 +1626,17 @@ static void doInitGlobalConfig(void) { cfg.unitType = TAOS_CFG_UTYPE_NONE; taosInitConfigOption(cfg); - assert(tsGlobalConfigNum <= TSDB_CFG_MAX_NUM); + // enable kill long query + cfg.option = "deadLockKillQuery"; + cfg.ptr = &tsDeadLockKillQuery; + cfg.valType = TAOS_CFG_VTYPE_INT8; + cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; + cfg.minValue = 0; + cfg.maxValue = 1; + cfg.ptrLength = 1; + cfg.unitType = TAOS_CFG_UTYPE_NONE; + taosInitConfigOption(cfg); + #ifdef TD_TSZ // lossy compress cfg.option = "lossyColumns"; @@ -1667,6 +1690,9 @@ static void doInitGlobalConfig(void) { cfg.ptrLength = 0; cfg.unitType = TAOS_CFG_UTYPE_NONE; taosInitConfigOption(cfg); + assert(tsGlobalConfigNum == TSDB_CFG_MAX_NUM); +#else + assert(tsGlobalConfigNum == TSDB_CFG_MAX_NUM - 5); #endif } diff --git a/src/connector/jdbc/pom.xml b/src/connector/jdbc/pom.xml index 6b9fc9d96ce16700ee1243ef7c148a423a965d0b..256fa614e0bd0a88e0c676a3ae13c9c177eb5215 100644 --- a/src/connector/jdbc/pom.xml +++ b/src/connector/jdbc/pom.xml @@ -113,6 +113,7 @@ **/AppMemoryLeakTest.java + **/JDBCTypeAndTypeCompareTest.java **/ConnectMultiTaosdByRestfulWithDifferentTokenTest.java **/DatetimeBefore1970Test.java **/FailOverTest.java diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/JDBCTypeAndTypeCompareTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/JDBCTypeAndTypeCompareTest.java new file mode 100644 index 0000000000000000000000000000000000000000..eb3b2985dfaff1b956909a50ca23470279cb48ca --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/JDBCTypeAndTypeCompareTest.java @@ -0,0 +1,34 @@ +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(); + } +} diff --git a/src/connector/python/taos/cinterface.py b/src/connector/python/taos/cinterface.py index aad9d1fdbfd4f900fe2db96dadbf343ea922be22..c5737ea5a07b7678e058307dfe3b47546dd99909 100644 --- a/src/connector/python/taos/cinterface.py +++ b/src/connector/python/taos/cinterface.py @@ -835,8 +835,14 @@ def taos_insert_telnet_lines(connection, lines): p_lines = lines_type(*lines) errno = _libtaos.taos_insert_telnet_lines(connection, p_lines, num_of_lines) if errno != 0: - raise LinesError("insert telnet lines error", errno) + raise TelnetLinesError("insert telnet lines error", errno) +def taos_insert_json_payload(connection, payload): + # type: (c_void_p, list[str] | tuple(str)) -> None + payload = payload.encode("utf-8") + errno = _libtaos.taos_insert_json_payload(connection, payload) + if errno != 0: + raise JsonPayloadError("insert json payload error", errno) class CTaosInterface(object): def __init__(self, config=None): diff --git a/src/connector/python/taos/connection.py b/src/connector/python/taos/connection.py index a8a71ecc3a8a5f2bdc960df364213e80018a70fe..35aca1fb26c1e612c3b3f6b1d8c794495bed0035 100644 --- a/src/connector/python/taos/connection.py +++ b/src/connector/python/taos/connection.py @@ -154,6 +154,25 @@ class TaosConnection(object): """ return taos_insert_telnet_lines(self._conn, lines) + def insert_json_payload(self, payload): + """OpenTSDB HTTP JSON format support + + ## Example + "{ + "metric": "cpu_load_0", + "timestamp": 1626006833610123, + "value": 55.5, + "tags": + { + "host": "ubuntu", + "interface": "eth0", + "Id": "tb0" + } + }" + + """ + return taos_insert_json_payload(self._conn, payload) + def cursor(self): # type: () -> TaosCursor """Return a new Cursor object using the connection.""" diff --git a/src/connector/python/taos/error.py b/src/connector/python/taos/error.py index a30adbb162f1c194bdfcf4cca5c43f01107a9776..f6a9d41f56a3fb071080daaae3bdd840190b154d 100644 --- a/src/connector/python/taos/error.py +++ b/src/connector/python/taos/error.py @@ -83,4 +83,14 @@ class ResultError(DatabaseError): class LinesError(DatabaseError): """taos_insert_lines errors.""" - pass \ No newline at end of file + pass + +class TelnetLinesError(DatabaseError): + """taos_insert_telnet_lines errors.""" + + pass + +class JsonPayloadError(DatabaseError): + """taos_insert_json_payload errors.""" + + pass diff --git a/src/inc/query.h b/src/inc/query.h index fb9cbff8584892b4a6bc6e4a6ce046a7500aef39..0872e3dbaa517ded77dd758b30e69f273c13a580 100644 --- a/src/inc/query.h +++ b/src/inc/query.h @@ -76,6 +76,11 @@ void* qGetResultRetrieveMsg(qinfo_t qinfo); */ int32_t qKillQuery(qinfo_t qinfo); +//kill by qid +int32_t qKillQueryByQId(void* pMgmt, int64_t qId, int32_t waitMs, int32_t waitCount); + +bool qSolveCommitNoBlock(void* pRepo, void* pMgmt); + int32_t qQueryCompleted(qinfo_t qinfo); /** diff --git a/src/inc/taos.h b/src/inc/taos.h index a71e4bf50c600a8c9963e616c5e79cbfbe164556..edb1552b811a2ff4b8c78c19523cc6f2ad82ba74 100644 --- a/src/inc/taos.h +++ b/src/inc/taos.h @@ -174,6 +174,8 @@ DLL_EXPORT int taos_insert_lines(TAOS* taos, char* lines[], int numLines); DLL_EXPORT int taos_insert_telnet_lines(TAOS* taos, char* lines[], int numLines); +DLL_EXPORT int taos_insert_json_payload(TAOS* taos, char* payload); + #ifdef __cplusplus } #endif diff --git a/src/inc/taosdef.h b/src/inc/taosdef.h index b4d60aeba5b45b84835c7a6e345c8594ee221a03..89de733ba123157f6454fb35b26f06202a2095c4 100644 --- a/src/inc/taosdef.h +++ b/src/inc/taosdef.h @@ -165,6 +165,7 @@ do { \ #define TSDB_RELATION_NOT 13 #define TSDB_RELATION_MATCH 14 +#define TSDB_RELATION_NMATCH 15 #define TSDB_BINARY_OP_ADD 30 #define TSDB_BINARY_OP_SUBTRACT 31 diff --git a/src/inc/taoserror.h b/src/inc/taoserror.h index 882aca2b5259385c6c7f308d1764f8da9bea80e9..d59b88c7e698b3e965b5923efdc760e0289f7250 100644 --- a/src/inc/taoserror.h +++ b/src/inc/taoserror.h @@ -35,6 +35,7 @@ int32_t* taosGetErrno(); #define terrno (*taosGetErrno()) #define TSDB_CODE_SUCCESS 0 +#define TSDB_CODE_FAILED -1 // unknown or needn't tell detail error // rpc #define TSDB_CODE_RPC_ACTION_IN_PROGRESS TAOS_DEF_ERROR_CODE(0, 0x0001) //"Action in progress") @@ -107,6 +108,9 @@ int32_t* taosGetErrno(); #define TSDB_CODE_TSC_INVALID_TAG_LENGTH TAOS_DEF_ERROR_CODE(0, 0x021E) //"Invalid tag length") #define TSDB_CODE_TSC_INVALID_COLUMN_LENGTH TAOS_DEF_ERROR_CODE(0, 0x021F) //"Invalid column length") #define TSDB_CODE_TSC_DUP_TAG_NAMES TAOS_DEF_ERROR_CODE(0, 0x0220) //"duplicated tag names") +#define TSDB_CODE_TSC_INVALID_JSON TAOS_DEF_ERROR_CODE(0, 0x0221) //"Invalid JSON format") +#define TSDB_CODE_TSC_INVALID_JSON_TYPE TAOS_DEF_ERROR_CODE(0, 0x0222) //"Invalid JSON data type") +#define TSDB_CODE_TSC_VALUE_OUT_OF_RANGE TAOS_DEF_ERROR_CODE(0, 0x0223) //"Value out of range") // mnode #define TSDB_CODE_MND_MSG_NOT_PROCESSED TAOS_DEF_ERROR_CODE(0, 0x0300) //"Message not processed") diff --git a/src/inc/taosmsg.h b/src/inc/taosmsg.h index 1bb799ad72b97a0e17699b73e74b66b548b5a045..c3c8625fec3290e2d39d64f53a173b43cf21d7e3 100644 --- a/src/inc/taosmsg.h +++ b/src/inc/taosmsg.h @@ -764,27 +764,16 @@ typedef struct SSTableVgroupMsg { int32_t numOfTables; } SSTableVgroupMsg, SSTableVgroupRspMsg; -typedef struct { - int32_t vgId; - int8_t numOfEps; - SEpAddr1 epAddr[TSDB_MAX_REPLICA]; -} SVgroupInfo; - typedef struct { int32_t vgId; int8_t numOfEps; SEpAddrMsg epAddr[TSDB_MAX_REPLICA]; } SVgroupMsg; -typedef struct { - int32_t numOfVgroups; - SVgroupInfo vgroups[]; -} SVgroupsInfo; - typedef struct { int32_t numOfVgroups; SVgroupMsg vgroups[]; -} SVgroupsMsg; +} SVgroupsMsg, SVgroupsInfo; typedef struct STableMetaMsg { int32_t contLen; diff --git a/src/inc/tsdb.h b/src/inc/tsdb.h index 84030dd9a7a937a16461d37f4cf44a174cef021c..4e11e4f2478fe0616701e0d183d38455b9526514 100644 --- a/src/inc/tsdb.h +++ b/src/inc/tsdb.h @@ -39,6 +39,7 @@ extern "C" { #define TSDB_STATUS_COMMIT_START 1 #define TSDB_STATUS_COMMIT_OVER 2 +#define TSDB_STATUS_COMMIT_NOBLOCK 3 //commit no block, need to be solved // TSDB STATE DEFINITION #define TSDB_STATE_OK 0x0 @@ -412,6 +413,11 @@ int tsdbSyncRecv(void *pRepo, SOCKET socketFd); // For TSDB Compact int tsdbCompact(STsdbRepo *pRepo); +// For TSDB Health Monitor + +// no problem return true +bool tsdbNoProblem(STsdbRepo* pRepo); + #ifdef __cplusplus } #endif diff --git a/src/inc/ttokendef.h b/src/inc/ttokendef.h index 501c7a4c699c94091c4c83b2d8e8c41afcfc8ab7..9b0ad2cf13b6df01bda56906891a4de677ff08a3 100644 --- a/src/inc/ttokendef.h +++ b/src/inc/ttokendef.h @@ -38,179 +38,180 @@ #define TK_IS 20 #define TK_LIKE 21 #define TK_MATCH 22 -#define TK_GLOB 23 -#define TK_BETWEEN 24 -#define TK_IN 25 -#define TK_GT 26 -#define TK_GE 27 -#define TK_LT 28 -#define TK_LE 29 -#define TK_BITAND 30 -#define TK_BITOR 31 -#define TK_LSHIFT 32 -#define TK_RSHIFT 33 -#define TK_PLUS 34 -#define TK_MINUS 35 -#define TK_DIVIDE 36 -#define TK_TIMES 37 -#define TK_STAR 38 -#define TK_SLASH 39 -#define TK_REM 40 -#define TK_CONCAT 41 -#define TK_UMINUS 42 -#define TK_UPLUS 43 -#define TK_BITNOT 44 -#define TK_SHOW 45 -#define TK_DATABASES 46 -#define TK_TOPICS 47 -#define TK_FUNCTIONS 48 -#define TK_MNODES 49 -#define TK_DNODES 50 -#define TK_ACCOUNTS 51 -#define TK_USERS 52 -#define TK_MODULES 53 -#define TK_QUERIES 54 -#define TK_CONNECTIONS 55 -#define TK_STREAMS 56 -#define TK_VARIABLES 57 -#define TK_SCORES 58 -#define TK_GRANTS 59 -#define TK_VNODES 60 -#define TK_DOT 61 -#define TK_CREATE 62 -#define TK_TABLE 63 -#define TK_STABLE 64 -#define TK_DATABASE 65 -#define TK_TABLES 66 -#define TK_STABLES 67 -#define TK_VGROUPS 68 -#define TK_DROP 69 -#define TK_TOPIC 70 -#define TK_FUNCTION 71 -#define TK_DNODE 72 -#define TK_USER 73 -#define TK_ACCOUNT 74 -#define TK_USE 75 -#define TK_DESCRIBE 76 -#define TK_DESC 77 -#define TK_ALTER 78 -#define TK_PASS 79 -#define TK_PRIVILEGE 80 -#define TK_LOCAL 81 -#define TK_COMPACT 82 -#define TK_LP 83 -#define TK_RP 84 -#define TK_IF 85 -#define TK_EXISTS 86 -#define TK_AS 87 -#define TK_OUTPUTTYPE 88 -#define TK_AGGREGATE 89 -#define TK_BUFSIZE 90 -#define TK_PPS 91 -#define TK_TSERIES 92 -#define TK_DBS 93 -#define TK_STORAGE 94 -#define TK_QTIME 95 -#define TK_CONNS 96 -#define TK_STATE 97 -#define TK_COMMA 98 -#define TK_KEEP 99 -#define TK_CACHE 100 -#define TK_REPLICA 101 -#define TK_QUORUM 102 -#define TK_DAYS 103 -#define TK_MINROWS 104 -#define TK_MAXROWS 105 -#define TK_BLOCKS 106 -#define TK_CTIME 107 -#define TK_WAL 108 -#define TK_FSYNC 109 -#define TK_COMP 110 -#define TK_PRECISION 111 -#define TK_UPDATE 112 -#define TK_CACHELAST 113 -#define TK_PARTITIONS 114 -#define TK_UNSIGNED 115 -#define TK_TAGS 116 -#define TK_USING 117 -#define TK_NULL 118 -#define TK_NOW 119 -#define TK_SELECT 120 -#define TK_UNION 121 -#define TK_ALL 122 -#define TK_DISTINCT 123 -#define TK_FROM 124 -#define TK_VARIABLE 125 -#define TK_INTERVAL 126 -#define TK_EVERY 127 -#define TK_SESSION 128 -#define TK_STATE_WINDOW 129 -#define TK_FILL 130 -#define TK_SLIDING 131 -#define TK_ORDER 132 -#define TK_BY 133 -#define TK_ASC 134 -#define TK_GROUP 135 -#define TK_HAVING 136 -#define TK_LIMIT 137 -#define TK_OFFSET 138 -#define TK_SLIMIT 139 -#define TK_SOFFSET 140 -#define TK_WHERE 141 -#define TK_RESET 142 -#define TK_QUERY 143 -#define TK_SYNCDB 144 -#define TK_ADD 145 -#define TK_COLUMN 146 -#define TK_MODIFY 147 -#define TK_TAG 148 -#define TK_CHANGE 149 -#define TK_SET 150 -#define TK_KILL 151 -#define TK_CONNECTION 152 -#define TK_STREAM 153 -#define TK_COLON 154 -#define TK_ABORT 155 -#define TK_AFTER 156 -#define TK_ATTACH 157 -#define TK_BEFORE 158 -#define TK_BEGIN 159 -#define TK_CASCADE 160 -#define TK_CLUSTER 161 -#define TK_CONFLICT 162 -#define TK_COPY 163 -#define TK_DEFERRED 164 -#define TK_DELIMITERS 165 -#define TK_DETACH 166 -#define TK_EACH 167 -#define TK_END 168 -#define TK_EXPLAIN 169 -#define TK_FAIL 170 -#define TK_FOR 171 -#define TK_IGNORE 172 -#define TK_IMMEDIATE 173 -#define TK_INITIALLY 174 -#define TK_INSTEAD 175 -#define TK_KEY 176 -#define TK_OF 177 -#define TK_RAISE 178 -#define TK_REPLACE 179 -#define TK_RESTRICT 180 -#define TK_ROW 181 -#define TK_STATEMENT 182 -#define TK_TRIGGER 183 -#define TK_VIEW 184 -#define TK_IPTOKEN 185 -#define TK_SEMI 186 -#define TK_NONE 187 -#define TK_PREV 188 -#define TK_LINEAR 189 -#define TK_IMPORT 190 -#define TK_TBNAME 191 -#define TK_JOIN 192 -#define TK_INSERT 193 -#define TK_INTO 194 -#define TK_VALUES 195 +#define TK_NMATCH 23 +#define TK_GLOB 24 +#define TK_BETWEEN 25 +#define TK_IN 26 +#define TK_GT 27 +#define TK_GE 28 +#define TK_LT 29 +#define TK_LE 30 +#define TK_BITAND 31 +#define TK_BITOR 32 +#define TK_LSHIFT 33 +#define TK_RSHIFT 34 +#define TK_PLUS 35 +#define TK_MINUS 36 +#define TK_DIVIDE 37 +#define TK_TIMES 38 +#define TK_STAR 39 +#define TK_SLASH 40 +#define TK_REM 41 +#define TK_CONCAT 42 +#define TK_UMINUS 43 +#define TK_UPLUS 44 +#define TK_BITNOT 45 +#define TK_SHOW 46 +#define TK_DATABASES 47 +#define TK_TOPICS 48 +#define TK_FUNCTIONS 49 +#define TK_MNODES 50 +#define TK_DNODES 51 +#define TK_ACCOUNTS 52 +#define TK_USERS 53 +#define TK_MODULES 54 +#define TK_QUERIES 55 +#define TK_CONNECTIONS 56 +#define TK_STREAMS 57 +#define TK_VARIABLES 58 +#define TK_SCORES 59 +#define TK_GRANTS 60 +#define TK_VNODES 61 +#define TK_DOT 62 +#define TK_CREATE 63 +#define TK_TABLE 64 +#define TK_STABLE 65 +#define TK_DATABASE 66 +#define TK_TABLES 67 +#define TK_STABLES 68 +#define TK_VGROUPS 69 +#define TK_DROP 70 +#define TK_TOPIC 71 +#define TK_FUNCTION 72 +#define TK_DNODE 73 +#define TK_USER 74 +#define TK_ACCOUNT 75 +#define TK_USE 76 +#define TK_DESCRIBE 77 +#define TK_DESC 78 +#define TK_ALTER 79 +#define TK_PASS 80 +#define TK_PRIVILEGE 81 +#define TK_LOCAL 82 +#define TK_COMPACT 83 +#define TK_LP 84 +#define TK_RP 85 +#define TK_IF 86 +#define TK_EXISTS 87 +#define TK_AS 88 +#define TK_OUTPUTTYPE 89 +#define TK_AGGREGATE 90 +#define TK_BUFSIZE 91 +#define TK_PPS 92 +#define TK_TSERIES 93 +#define TK_DBS 94 +#define TK_STORAGE 95 +#define TK_QTIME 96 +#define TK_CONNS 97 +#define TK_STATE 98 +#define TK_COMMA 99 +#define TK_KEEP 100 +#define TK_CACHE 101 +#define TK_REPLICA 102 +#define TK_QUORUM 103 +#define TK_DAYS 104 +#define TK_MINROWS 105 +#define TK_MAXROWS 106 +#define TK_BLOCKS 107 +#define TK_CTIME 108 +#define TK_WAL 109 +#define TK_FSYNC 110 +#define TK_COMP 111 +#define TK_PRECISION 112 +#define TK_UPDATE 113 +#define TK_CACHELAST 114 +#define TK_PARTITIONS 115 +#define TK_UNSIGNED 116 +#define TK_TAGS 117 +#define TK_USING 118 +#define TK_NULL 119 +#define TK_NOW 120 +#define TK_SELECT 121 +#define TK_UNION 122 +#define TK_ALL 123 +#define TK_DISTINCT 124 +#define TK_FROM 125 +#define TK_VARIABLE 126 +#define TK_INTERVAL 127 +#define TK_EVERY 128 +#define TK_SESSION 129 +#define TK_STATE_WINDOW 130 +#define TK_FILL 131 +#define TK_SLIDING 132 +#define TK_ORDER 133 +#define TK_BY 134 +#define TK_ASC 135 +#define TK_GROUP 136 +#define TK_HAVING 137 +#define TK_LIMIT 138 +#define TK_OFFSET 139 +#define TK_SLIMIT 140 +#define TK_SOFFSET 141 +#define TK_WHERE 142 +#define TK_RESET 143 +#define TK_QUERY 144 +#define TK_SYNCDB 145 +#define TK_ADD 146 +#define TK_COLUMN 147 +#define TK_MODIFY 148 +#define TK_TAG 149 +#define TK_CHANGE 150 +#define TK_SET 151 +#define TK_KILL 152 +#define TK_CONNECTION 153 +#define TK_STREAM 154 +#define TK_COLON 155 +#define TK_ABORT 156 +#define TK_AFTER 157 +#define TK_ATTACH 158 +#define TK_BEFORE 159 +#define TK_BEGIN 160 +#define TK_CASCADE 161 +#define TK_CLUSTER 162 +#define TK_CONFLICT 163 +#define TK_COPY 164 +#define TK_DEFERRED 165 +#define TK_DELIMITERS 166 +#define TK_DETACH 167 +#define TK_EACH 168 +#define TK_END 169 +#define TK_EXPLAIN 170 +#define TK_FAIL 171 +#define TK_FOR 172 +#define TK_IGNORE 173 +#define TK_IMMEDIATE 174 +#define TK_INITIALLY 175 +#define TK_INSTEAD 176 +#define TK_KEY 177 +#define TK_OF 178 +#define TK_RAISE 179 +#define TK_REPLACE 180 +#define TK_RESTRICT 181 +#define TK_ROW 182 +#define TK_STATEMENT 183 +#define TK_TRIGGER 184 +#define TK_VIEW 185 +#define TK_IPTOKEN 186 +#define TK_SEMI 187 +#define TK_NONE 188 +#define TK_PREV 189 +#define TK_LINEAR 190 +#define TK_IMPORT 191 +#define TK_TBNAME 192 +#define TK_JOIN 193 +#define TK_INSERT 194 +#define TK_INTO 195 +#define TK_VALUES 196 #define TK_SPACE 300 diff --git a/src/kit/shell/src/shellDarwin.c b/src/kit/shell/src/shellDarwin.c index 9161860f07dfb0683a47ea4ccb2a759ae49562e7..a1413be1ce4ce6f67516fc09121115f30bbc56f0 100644 --- a/src/kit/shell/src/shellDarwin.c +++ b/src/kit/shell/src/shellDarwin.c @@ -98,6 +98,7 @@ void shellParseArgument(int argc, char *argv[], SShellArguments *arguments) { tstrncpy(g_password, (char *)(argv[i] + 2), SHELL_MAX_PASSWORD_LEN); } arguments->password = g_password; + arguments->is_use_passwd = true; strcpy(argv[i], ""); argc -= 1; } diff --git a/src/kit/taosdemo/taosdemo.c b/src/kit/taosdemo/taosdemo.c index 87102cc1c76206a0c6f779efc9ef22e9607409ef..ae9289e3b0982ef950f5f67674c3b91ae41d0895 100644 --- a/src/kit/taosdemo/taosdemo.c +++ b/src/kit/taosdemo/taosdemo.c @@ -20,6 +20,7 @@ #include #include +#include #define _GNU_SOURCE #define CURL_STATICLIB @@ -87,7 +88,7 @@ extern char configDir[]; #define DOUBLE_BUFF_LEN 42 #define TIMESTAMP_BUFF_LEN 21 -#define MAX_SAMPLES_ONCE_FROM_FILE 10000 +#define MAX_SAMPLES 10000 #define MAX_NUM_COLUMNS (TSDB_MAX_COLUMNS - 1) // exclude first column timestamp #define MAX_DB_COUNT 8 @@ -109,6 +110,14 @@ extern char configDir[]; #define DEFAULT_CHILDTABLES 10000 +#define STMT_BIND_PARAM_BATCH 0 + +char* g_sampleDataBuf = NULL; +#if STMT_BIND_PARAM_BATCH == 1 + // bind param batch +char* g_sampleBindBatchArray = NULL; +#endif + enum TEST_MODE { INSERT_TEST, // 0 QUERY_TEST, // 1 @@ -116,17 +125,17 @@ enum TEST_MODE { INVAID_TEST }; -typedef enum CREATE_SUB_TALBE_MOD_EN { +typedef enum CREATE_SUB_TABLE_MOD_EN { PRE_CREATE_SUBTBL, AUTO_CREATE_SUBTBL, NO_CREATE_SUBTBL -} CREATE_SUB_TALBE_MOD_EN; +} CREATE_SUB_TABLE_MOD_EN; -typedef enum TALBE_EXISTS_EN { +typedef enum TABLE_EXISTS_EN { TBL_NO_EXISTS, TBL_ALREADY_EXISTS, TBL_EXISTS_BUTT -} TALBE_EXISTS_EN; +} TABLE_EXISTS_EN; enum enumSYNC_MODE { SYNC_MODE, @@ -226,21 +235,23 @@ typedef struct SArguments_S { bool performance_print; char * output_file; bool async_mode; - char * datatype[MAX_NUM_COLUMNS + 1]; + char data_type[MAX_NUM_COLUMNS+1]; + char *dataType[MAX_NUM_COLUMNS+1]; uint32_t binwidth; - uint32_t num_of_CPR; - uint32_t num_of_threads; + uint32_t columnCount; + uint64_t lenOfOneRow; + uint32_t nthreads; uint64_t insert_interval; uint64_t timestamp_step; int64_t query_times; - uint32_t interlace_rows; - uint32_t num_of_RPR; // num_of_records_per_req + uint32_t interlaceRows; + uint32_t reqPerReq; // num_of_records_per_req uint64_t max_sql_len; - int64_t num_of_tables; - int64_t num_of_DPT; + int64_t ntables; + int64_t insertRows; int abort; uint32_t disorderRatio; // 0: no disorder, >0: x% - int disorderRange; // ms, us or ns. accordig to database precision + int disorderRange; // ms, us or ns. according to database precision uint32_t method_of_delete; uint64_t totalInsertRows; uint64_t totalAffectedRows; @@ -248,14 +259,15 @@ typedef struct SArguments_S { } SArguments; typedef struct SColumn_S { - char field[TSDB_COL_NAME_LEN]; - char dataType[DATATYPE_BUFF_LEN]; - uint32_t dataLen; - char note[NOTE_BUFF_LEN]; + char field[TSDB_COL_NAME_LEN]; + char data_type; + char dataType[DATATYPE_BUFF_LEN]; + uint32_t dataLen; + char note[NOTE_BUFF_LEN]; } StrColumn; typedef struct SSuperTable_S { - char sTblName[TSDB_TABLE_NAME_LEN]; + char stbName[TSDB_TABLE_NAME_LEN]; char dataSource[SMALL_BUFF_LEN]; // rand_gen or sample char childTblPrefix[TBNAME_PREFIX_LEN]; uint16_t childTblExists; @@ -291,14 +303,16 @@ typedef struct SSuperTable_S { uint64_t lenOfTagOfOneRow; char* sampleDataBuf; - //int sampleRowCount; - //int sampleUsePos; uint32_t tagSource; // 0: rand, 1: tag sample char* tagDataBuf; uint32_t tagSampleCount; uint32_t tagUsePos; +#if STMT_BIND_PARAM_BATCH == 1 + // bind param batch + char *sampleBindBatchArray; +#endif // statistics uint64_t totalInsertRows; uint64_t totalAffectedRows; @@ -378,7 +392,7 @@ typedef struct SDbs_S { } SDbs; typedef struct SpecifiedQueryInfo_S { - uint64_t queryInterval; // 0: unlimit > 0 loop/s + uint64_t queryInterval; // 0: unlimited > 0 loop/s uint32_t concurrent; int sqlCount; uint32_t asyncMode; // 0: sync, 1: async @@ -398,8 +412,8 @@ typedef struct SpecifiedQueryInfo_S { } SpecifiedQueryInfo; typedef struct SuperQueryInfo_S { - char sTblName[TSDB_TABLE_NAME_LEN]; - uint64_t queryInterval; // 0: unlimit > 0 loop/s + char stbName[TSDB_TABLE_NAME_LEN]; + uint64_t queryInterval; // 0: unlimited > 0 loop/s uint32_t threadCnt; uint32_t asyncMode; // 0: sync, 1: async uint64_t subscribeInterval; // ms @@ -437,8 +451,16 @@ typedef struct SQueryMetaInfo_S { typedef struct SThreadInfo_S { TAOS * taos; TAOS_STMT *stmt; - char* sampleBindArray; - int64_t *bind_ts; + int64_t *bind_ts; + +#if STMT_BIND_PARAM_BATCH == 1 + int64_t *bind_ts_array; + char *bindParams; + char *is_null; +#else + char* sampleBindArray; +#endif + int threadID; char db_name[TSDB_DB_NAME_LEN]; uint32_t time_precision; @@ -584,8 +606,8 @@ char *g_rand_current_buff = NULL; char *g_rand_phase_buff = NULL; char *g_randdouble_buff = NULL; -char *g_aggreFunc[] = {"*", "count(*)", "avg(col0)", "sum(col0)", - "max(col0)", "min(col0)", "first(col0)", "last(col0)"}; +char *g_aggreFunc[] = {"*", "count(*)", "avg(C0)", "sum(C0)", + "max(C0)", "min(C0)", "first(C0)", "last(C0)"}; SArguments g_args = { NULL, // metaFile @@ -614,22 +636,26 @@ SArguments g_args = { false, // answer_yes; "./output.txt", // output_file 0, // mode : sync or async + {TSDB_DATA_TYPE_FLOAT, + TSDB_DATA_TYPE_INT, + TSDB_DATA_TYPE_FLOAT}, { - "FLOAT", // datatype - "INT", // datatype - "FLOAT", // datatype. DEFAULT_DATATYPE_NUM is 3 + "FLOAT", // dataType + "INT", // dataType + "FLOAT", // dataType. demo mode has 3 columns }, 64, // binwidth - 4, // num_of_CPR - 10, // num_of_connections/thread + 4, // columnCount, timestamp + float + int + float + 20 + FLOAT_BUFF_LEN + INT_BUFF_LEN + FLOAT_BUFF_LEN, // lenOfOneRow + 8, // num_of_connections/thread 0, // insert_interval DEFAULT_TIMESTAMP_STEP, // timestamp_step 1, // query_times - DEFAULT_INTERLACE_ROWS, // interlace_rows; - 30000, // num_of_RPR + DEFAULT_INTERLACE_ROWS, // interlaceRows; + 30000, // reqPerReq (1024*1024), // max_sql_len - DEFAULT_CHILDTABLES, // num_of_tables - 10000, // num_of_DPT + DEFAULT_CHILDTABLES, // ntables + 10000, // insertRows 0, // abort 0, // disorderRatio 1000, // disorderRange @@ -711,10 +737,10 @@ static void printVersion() { char taosdemo_status[] = TAOSDEMO_STATUS; if (strlen(taosdemo_status) == 0) { - printf("taosdemo verison %s-%s\n", + printf("taosdemo version %s-%s\n", tdengine_ver, taosdemo_ver); } else { - printf("taosdemo verison %s-%s, status:%s\n", + printf("taosdemo version %s-%s, status:%s\n", tdengine_ver, taosdemo_ver, taosdemo_status); } } @@ -791,7 +817,7 @@ static void printHelp() { "The number of records per table. Default is 10000."); printf("%s%s%s%s\n", indent, "-M, --random", "\t\t\t", "The value of records generated are totally random."); - printf("%s\n", "\t\t\t\tThe default is to simulate power equipment senario."); + printf("%s\n", "\t\t\t\tThe default is to simulate power equipment scenario."); printf("%s%s%s%s\n", indent, "-x, --no-insert", "\t\t", "No-insert flag."); printf("%s%s%s%s\n", indent, "-y, --answer-yes", "\t\t", "Default input yes for prompt."); @@ -836,7 +862,7 @@ static void errorWrongValue(char *program, char *wrong_arg, char *wrong_value) fprintf(stderr, "Try `taosdemo --help' or `taosdemo --usage' for more information.\n"); } -static void errorUnreconized(char *program, char *wrong_arg) +static void errorUnrecognized(char *program, char *wrong_arg) { fprintf(stderr, "%s: unrecognized options '%s'\n", program, wrong_arg); fprintf(stderr, "Try `taosdemo --help' or `taosdemo --usage' for more information.\n"); @@ -893,7 +919,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { } else if (0 == strncmp(argv[i], "--file=", strlen("--file="))) { arguments->metaFile = (char *)(argv[i] + strlen("--file=")); } else { - errorUnreconized(argv[0], argv[i]); + errorUnrecognized(argv[0], argv[i]); exit(EXIT_FAILURE); } } else if ((0 == strncmp(argv[i], "-c", strlen("-c"))) @@ -915,7 +941,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { } else if (0 == strncmp(argv[i], "--config-dir=", strlen("--config-dir="))) { tstrncpy(configDir, (char *)(argv[i] + strlen("--config-dir=")), TSDB_FILENAME_LEN); } else { - errorUnreconized(argv[0], argv[i]); + errorUnrecognized(argv[0], argv[i]); exit(EXIT_FAILURE); } } else if ((0 == strncmp(argv[i], "-h", strlen("-h"))) @@ -937,7 +963,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { } else if (0 == strncmp(argv[i], "--host=", strlen("--host="))) { arguments->host = (char *)(argv[i] + strlen("--host=")); } else { - errorUnreconized(argv[0], argv[i]); + errorUnrecognized(argv[0], argv[i]); exit(EXIT_FAILURE); } } else if (strcmp(argv[i], "-PP") == 0) { @@ -971,7 +997,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { } arguments->port = atoi(argv[++i]); } else { - errorUnreconized(argv[0], argv[i]); + errorUnrecognized(argv[0], argv[i]); exit(EXIT_FAILURE); } } else if ((0 == strncmp(argv[i], "-I", strlen("-I"))) @@ -1032,7 +1058,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { } i++; } else { - errorUnreconized(argv[0], argv[i]); + errorUnrecognized(argv[0], argv[i]); exit(EXIT_FAILURE); } } else if ((0 == strncmp(argv[i], "-u", strlen("-u"))) @@ -1054,7 +1080,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { } arguments->user = argv[++i]; } else { - errorUnreconized(argv[0], argv[i]); + errorUnrecognized(argv[0], argv[i]); exit(EXIT_FAILURE); } } else if ((0 == strncmp(argv[i], "-p", strlen("-p"))) @@ -1088,7 +1114,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { } arguments->output_file = argv[++i]; } else { - errorUnreconized(argv[0], argv[i]); + errorUnrecognized(argv[0], argv[i]); exit(EXIT_FAILURE); } } else if ((0 == strncmp(argv[i], "-s", strlen("-s"))) @@ -1110,7 +1136,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { } arguments->sqlFile = argv[++i]; } else { - errorUnreconized(argv[0], argv[i]); + errorUnrecognized(argv[0], argv[i]); exit(EXIT_FAILURE); } } else if ((0 == strncmp(argv[i], "-q", strlen("-q"))) @@ -1148,7 +1174,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { } arguments->async_mode = atoi(argv[++i]); } else { - errorUnreconized(argv[0], argv[i]); + errorUnrecognized(argv[0], argv[i]); exit(EXIT_FAILURE); } } else if ((0 == strncmp(argv[i], "-T", strlen("-T"))) @@ -1161,17 +1187,17 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { errorPrintReqArg2(argv[0], "T"); exit(EXIT_FAILURE); } - arguments->num_of_threads = atoi(argv[++i]); + arguments->nthreads = atoi(argv[++i]); } else if (0 == strncmp(argv[i], "--threads=", strlen("--threads="))) { if (isStringNumber((char *)(argv[i] + strlen("--threads=")))) { - arguments->num_of_threads = atoi((char *)(argv[i]+strlen("--threads="))); + arguments->nthreads = atoi((char *)(argv[i]+strlen("--threads="))); } else { errorPrintReqArg2(argv[0], "--threads"); exit(EXIT_FAILURE); } } else if (0 == strncmp(argv[i], "-T", strlen("-T"))) { if (isStringNumber((char *)(argv[i] + strlen("-T")))) { - arguments->num_of_threads = atoi((char *)(argv[i]+strlen("-T"))); + arguments->nthreads = atoi((char *)(argv[i]+strlen("-T"))); } else { errorPrintReqArg2(argv[0], "-T"); exit(EXIT_FAILURE); @@ -1184,9 +1210,9 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { errorPrintReqArg2(argv[0], "--threads"); exit(EXIT_FAILURE); } - arguments->num_of_threads = atoi(argv[++i]); + arguments->nthreads = atoi(argv[++i]); } else { - errorUnreconized(argv[0], argv[i]); + errorUnrecognized(argv[0], argv[i]); exit(EXIT_FAILURE); } } else if ((0 == strncmp(argv[i], "-i", strlen("-i"))) @@ -1224,7 +1250,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { } arguments->insert_interval = atoi(argv[++i]); } else { - errorUnreconized(argv[0], argv[i]); + errorUnrecognized(argv[0], argv[i]); exit(EXIT_FAILURE); } } else if ((0 == strncmp(argv[i], "-S", strlen("-S"))) @@ -1262,7 +1288,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { } arguments->async_mode = atoi(argv[++i]); } else { - errorUnreconized(argv[0], argv[i]); + errorUnrecognized(argv[0], argv[i]); exit(EXIT_FAILURE); } } else if (strcmp(argv[i], "-qt") == 0) { @@ -1283,17 +1309,17 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { errorPrintReqArg2(argv[0], "B"); exit(EXIT_FAILURE); } - arguments->interlace_rows = atoi(argv[++i]); + arguments->interlaceRows = atoi(argv[++i]); } else if (0 == strncmp(argv[i], "--interlace-rows=", strlen("--interlace-rows="))) { if (isStringNumber((char *)(argv[i] + strlen("--interlace-rows=")))) { - arguments->interlace_rows = atoi((char *)(argv[i]+strlen("--interlace-rows="))); + arguments->interlaceRows = atoi((char *)(argv[i]+strlen("--interlace-rows="))); } else { errorPrintReqArg2(argv[0], "--interlace-rows"); exit(EXIT_FAILURE); } } else if (0 == strncmp(argv[i], "-B", strlen("-B"))) { if (isStringNumber((char *)(argv[i] + strlen("-B")))) { - arguments->interlace_rows = atoi((char *)(argv[i]+strlen("-B"))); + arguments->interlaceRows = atoi((char *)(argv[i]+strlen("-B"))); } else { errorPrintReqArg2(argv[0], "-B"); exit(EXIT_FAILURE); @@ -1306,9 +1332,9 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { errorPrintReqArg2(argv[0], "--interlace-rows"); exit(EXIT_FAILURE); } - arguments->interlace_rows = atoi(argv[++i]); + arguments->interlaceRows = atoi(argv[++i]); } else { - errorUnreconized(argv[0], argv[i]); + errorUnrecognized(argv[0], argv[i]); exit(EXIT_FAILURE); } } else if ((0 == strncmp(argv[i], "-r", strlen("-r"))) @@ -1321,17 +1347,17 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { errorPrintReqArg2(argv[0], "r"); exit(EXIT_FAILURE); } - arguments->num_of_RPR = atoi(argv[++i]); + arguments->reqPerReq = atoi(argv[++i]); } else if (0 == strncmp(argv[i], "--rec-per-req=", strlen("--rec-per-req="))) { if (isStringNumber((char *)(argv[i] + strlen("--rec-per-req=")))) { - arguments->num_of_RPR = atoi((char *)(argv[i]+strlen("--rec-per-req="))); + arguments->reqPerReq = atoi((char *)(argv[i]+strlen("--rec-per-req="))); } else { errorPrintReqArg2(argv[0], "--rec-per-req"); exit(EXIT_FAILURE); } } else if (0 == strncmp(argv[i], "-r", strlen("-r"))) { if (isStringNumber((char *)(argv[i] + strlen("-r")))) { - arguments->num_of_RPR = atoi((char *)(argv[i]+strlen("-r"))); + arguments->reqPerReq = atoi((char *)(argv[i]+strlen("-r"))); } else { errorPrintReqArg2(argv[0], "-r"); exit(EXIT_FAILURE); @@ -1344,9 +1370,9 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { errorPrintReqArg2(argv[0], "--rec-per-req"); exit(EXIT_FAILURE); } - arguments->num_of_RPR = atoi(argv[++i]); + arguments->reqPerReq = atoi(argv[++i]); } else { - errorUnreconized(argv[0], argv[i]); + errorUnrecognized(argv[0], argv[i]); exit(EXIT_FAILURE); } } else if ((0 == strncmp(argv[i], "-t", strlen("-t"))) @@ -1359,17 +1385,17 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { errorPrintReqArg2(argv[0], "t"); exit(EXIT_FAILURE); } - arguments->num_of_tables = atoi(argv[++i]); + arguments->ntables = atoi(argv[++i]); } else if (0 == strncmp(argv[i], "--tables=", strlen("--tables="))) { if (isStringNumber((char *)(argv[i] + strlen("--tables=")))) { - arguments->num_of_tables = atoi((char *)(argv[i]+strlen("--tables="))); + arguments->ntables = atoi((char *)(argv[i]+strlen("--tables="))); } else { errorPrintReqArg2(argv[0], "--tables"); exit(EXIT_FAILURE); } } else if (0 == strncmp(argv[i], "-t", strlen("-t"))) { if (isStringNumber((char *)(argv[i] + strlen("-t")))) { - arguments->num_of_tables = atoi((char *)(argv[i]+strlen("-t"))); + arguments->ntables = atoi((char *)(argv[i]+strlen("-t"))); } else { errorPrintReqArg2(argv[0], "-t"); exit(EXIT_FAILURE); @@ -1382,13 +1408,13 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { errorPrintReqArg2(argv[0], "--tables"); exit(EXIT_FAILURE); } - arguments->num_of_tables = atoi(argv[++i]); + arguments->ntables = atoi(argv[++i]); } else { - errorUnreconized(argv[0], argv[i]); + errorUnrecognized(argv[0], argv[i]); exit(EXIT_FAILURE); } - g_totalChildTables = arguments->num_of_tables; + g_totalChildTables = arguments->ntables; } else if ((0 == strncmp(argv[i], "-n", strlen("-n"))) || (0 == strncmp(argv[i], "--records", strlen("--records")))) { if (2 == strlen(argv[i])) { @@ -1399,17 +1425,17 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { errorPrintReqArg2(argv[0], "n"); exit(EXIT_FAILURE); } - arguments->num_of_DPT = atoi(argv[++i]); + arguments->insertRows = atoi(argv[++i]); } else if (0 == strncmp(argv[i], "--records=", strlen("--records="))) { if (isStringNumber((char *)(argv[i] + strlen("--records=")))) { - arguments->num_of_DPT = atoi((char *)(argv[i]+strlen("--records="))); + arguments->insertRows = atoi((char *)(argv[i]+strlen("--records="))); } else { errorPrintReqArg2(argv[0], "--records"); exit(EXIT_FAILURE); } } else if (0 == strncmp(argv[i], "-n", strlen("-n"))) { if (isStringNumber((char *)(argv[i] + strlen("-n")))) { - arguments->num_of_DPT = atoi((char *)(argv[i]+strlen("-n"))); + arguments->insertRows = atoi((char *)(argv[i]+strlen("-n"))); } else { errorPrintReqArg2(argv[0], "-n"); exit(EXIT_FAILURE); @@ -1422,9 +1448,9 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { errorPrintReqArg2(argv[0], "--records"); exit(EXIT_FAILURE); } - arguments->num_of_DPT = atoi(argv[++i]); + arguments->insertRows = atoi(argv[++i]); } else { - errorUnreconized(argv[0], argv[i]); + errorUnrecognized(argv[0], argv[i]); exit(EXIT_FAILURE); } } else if ((0 == strncmp(argv[i], "-d", strlen("-d"))) @@ -1446,7 +1472,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { } arguments->database = argv[++i]; } else { - errorUnreconized(argv[0], argv[i]); + errorUnrecognized(argv[0], argv[i]); exit(EXIT_FAILURE); } } else if ((0 == strncmp(argv[i], "-l", strlen("-l"))) @@ -1460,17 +1486,17 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { errorPrintReqArg2(argv[0], "l"); exit(EXIT_FAILURE); } - arguments->num_of_CPR = atoi(argv[++i]); + arguments->columnCount = atoi(argv[++i]); } else if (0 == strncmp(argv[i], "--columns=", strlen("--columns="))) { if (isStringNumber((char *)(argv[i] + strlen("--columns=")))) { - arguments->num_of_CPR = atoi((char *)(argv[i]+strlen("--columns="))); + arguments->columnCount = atoi((char *)(argv[i]+strlen("--columns="))); } else { errorPrintReqArg2(argv[0], "--columns"); exit(EXIT_FAILURE); } } else if (0 == strncmp(argv[i], "-l", strlen("-l"))) { if (isStringNumber((char *)(argv[i] + strlen("-l")))) { - arguments->num_of_CPR = atoi((char *)(argv[i]+strlen("-l"))); + arguments->columnCount = atoi((char *)(argv[i]+strlen("-l"))); } else { errorPrintReqArg2(argv[0], "-l"); exit(EXIT_FAILURE); @@ -1483,23 +1509,25 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { errorPrintReqArg2(argv[0], "--columns"); exit(EXIT_FAILURE); } - arguments->num_of_CPR = atoi(argv[++i]); + arguments->columnCount = atoi(argv[++i]); } else { - errorUnreconized(argv[0], argv[i]); + errorUnrecognized(argv[0], argv[i]); exit(EXIT_FAILURE); } - if (arguments->num_of_CPR > MAX_NUM_COLUMNS) { - printf("WARNING: max acceptible columns count is %d\n", MAX_NUM_COLUMNS); + if (arguments->columnCount > MAX_NUM_COLUMNS) { + printf("WARNING: max acceptable columns count is %d\n", MAX_NUM_COLUMNS); prompt(); - arguments->num_of_CPR = MAX_NUM_COLUMNS; + arguments->columnCount = MAX_NUM_COLUMNS; } - for (int col = DEFAULT_DATATYPE_NUM; col < arguments->num_of_CPR; col ++) { - arguments->datatype[col] = "INT"; + for (int col = DEFAULT_DATATYPE_NUM; col < arguments->columnCount; col ++) { + arguments->dataType[col] = "INT"; + arguments->data_type[col] = TSDB_DATA_TYPE_INT; } - for (int col = arguments->num_of_CPR; col < MAX_NUM_COLUMNS; col++) { - arguments->datatype[col] = NULL; + for (int col = arguments->columnCount; col < MAX_NUM_COLUMNS; col++) { + arguments->dataType[col] = NULL; + arguments->data_type[col] = TSDB_DATA_TYPE_NULL; } } else if ((0 == strncmp(argv[i], "-b", strlen("-b"))) || (0 == strncmp(argv[i], "--data-type", strlen("--data-type")))) { @@ -1523,7 +1551,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { } dataType = argv[++i]; } else { - errorUnreconized(argv[0], argv[i]); + errorUnrecognized(argv[0], argv[i]); exit(EXIT_FAILURE); } @@ -1543,8 +1571,32 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { errorPrint("%s", "-b: Invalid data_type!\n"); exit(EXIT_FAILURE); } - arguments->datatype[0] = dataType; - arguments->datatype[1] = NULL; + arguments->dataType[0] = dataType; + if (0 == strcasecmp(dataType, "INT")) { + arguments->data_type[0] = TSDB_DATA_TYPE_INT; + } else if (0 == strcasecmp(dataType, "TINYINT")) { + arguments->data_type[0] = TSDB_DATA_TYPE_TINYINT; + } else if (0 == strcasecmp(dataType, "SMALLINT")) { + arguments->data_type[0] = TSDB_DATA_TYPE_SMALLINT; + } else if (0 == strcasecmp(dataType, "BIGINT")) { + arguments->data_type[0] = TSDB_DATA_TYPE_BIGINT; + } else if (0 == strcasecmp(dataType, "FLOAT")) { + arguments->data_type[0] = TSDB_DATA_TYPE_FLOAT; + } else if (0 == strcasecmp(dataType, "DOUBLE")) { + arguments->data_type[0] = TSDB_DATA_TYPE_DOUBLE; + } else if (0 == strcasecmp(dataType, "BINARY")) { + arguments->data_type[0] = TSDB_DATA_TYPE_BINARY; + } else if (0 == strcasecmp(dataType, "NCHAR")) { + arguments->data_type[0] = TSDB_DATA_TYPE_NCHAR; + } else if (0 == strcasecmp(dataType, "BOOL")) { + arguments->data_type[0] = TSDB_DATA_TYPE_BOOL; + } else if (0 == strcasecmp(dataType, "TIMESTAMP")) { + arguments->data_type[0] = TSDB_DATA_TYPE_TIMESTAMP; + } else { + arguments->data_type[0] = TSDB_DATA_TYPE_NULL; + } + arguments->dataType[1] = NULL; + arguments->data_type[1] = TSDB_DATA_TYPE_NULL; } else { // more than one col int index = 0; @@ -1567,11 +1619,37 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { errorPrint("%s", "-b: Invalid data_type!\n"); exit(EXIT_FAILURE); } - arguments->datatype[index++] = token; + + if (0 == strcasecmp(token, "INT")) { + arguments->data_type[index] = TSDB_DATA_TYPE_INT; + } else if (0 == strcasecmp(token, "FLOAT")) { + arguments->data_type[index] = TSDB_DATA_TYPE_FLOAT; + } else if (0 == strcasecmp(token, "SMALLINT")) { + arguments->data_type[index] = TSDB_DATA_TYPE_SMALLINT; + } else if (0 == strcasecmp(token, "BIGINT")) { + arguments->data_type[index] = TSDB_DATA_TYPE_BIGINT; + } else if (0 == strcasecmp(token, "DOUBLE")) { + arguments->data_type[index] = TSDB_DATA_TYPE_FLOAT; + } else if (0 == strcasecmp(token, "TINYINT")) { + arguments->data_type[index] = TSDB_DATA_TYPE_TINYINT; + } else if (0 == strcasecmp(token, "BINARY")) { + arguments->data_type[index] = TSDB_DATA_TYPE_BINARY; + } else if (0 == strcasecmp(token, "NCHAR")) { + arguments->data_type[index] = TSDB_DATA_TYPE_NCHAR; + } else if (0 == strcasecmp(token, "BOOL")) { + arguments->data_type[index] = TSDB_DATA_TYPE_BOOL; + } else if (0 == strcasecmp(token, "TIMESTAMP")) { + arguments->data_type[index] = TSDB_DATA_TYPE_TIMESTAMP; + } else { + arguments->data_type[index] = TSDB_DATA_TYPE_NULL; + } + arguments->dataType[index] = token; + index ++; token = strsep(&running, ","); if (index >= MAX_NUM_COLUMNS) break; } - arguments->datatype[index] = NULL; + arguments->dataType[index] = NULL; + arguments->data_type[index] = TSDB_DATA_TYPE_NULL; } } else if ((0 == strncmp(argv[i], "-w", strlen("-w"))) || (0 == strncmp(argv[i], "--binwidth", strlen("--binwidth")))) { @@ -1608,7 +1686,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { } arguments->binwidth = atoi(argv[++i]); } else { - errorUnreconized(argv[0], argv[i]); + errorUnrecognized(argv[0], argv[i]); exit(EXIT_FAILURE); } } else if ((0 == strncmp(argv[i], "-m", strlen("-m"))) @@ -1630,7 +1708,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { } arguments->tb_prefix = argv[++i]; } else { - errorUnreconized(argv[0], argv[i]); + errorUnrecognized(argv[0], argv[i]); exit(EXIT_FAILURE); } } else if ((strcmp(argv[i], "-N") == 0) @@ -1695,7 +1773,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { } arguments->disorderRange = atoi(argv[++i]); } else { - errorUnreconized(argv[0], argv[i]); + errorUnrecognized(argv[0], argv[i]); exit(EXIT_FAILURE); } } else if ((0 == strncmp(argv[i], "-O", strlen("-O"))) @@ -1733,7 +1811,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { } arguments->disorderRatio = atoi(argv[++i]); } else { - errorUnreconized(argv[0], argv[i]); + errorUnrecognized(argv[0], argv[i]); exit(EXIT_FAILURE); } @@ -1787,7 +1865,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { } arguments->replica = atoi(argv[++i]); } else { - errorUnreconized(argv[0], argv[i]); + errorUnrecognized(argv[0], argv[i]); exit(EXIT_FAILURE); } @@ -1799,7 +1877,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { } else if (strcmp(argv[i], "-D") == 0) { arguments->method_of_delete = atoi(argv[++i]); if (arguments->method_of_delete > 3) { - errorPrint("%s", "\n\t-D need a valud (0~3) number following!\n"); + errorPrint("%s", "\n\t-D need a value (0~3) number following!\n"); exit(EXIT_FAILURE); } } else if ((strcmp(argv[i], "--version") == 0) @@ -1814,7 +1892,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { printf(" Usage: taosdemo [-f JSONFILE] [-u USER] [-p PASSWORD] [-c CONFIG_DIR]\n\ [-h HOST] [-P PORT] [-I INTERFACE] [-d DATABASE] [-a REPLICA]\n\ [-m TABLEPREFIX] [-s SQLFILE] [-N] [-o OUTPUTFILE] [-q QUERYMODE]\n\ - [-b DATATYPES] [-w WIDTH_OF_BINARY] [-l COLUNNS] [-T THREADNUMBER]\n\ + [-b DATATYPES] [-w WIDTH_OF_BINARY] [-l COLUMNS] [-T THREADNUMBER]\n\ [-i SLEEPTIME] [-S TIME_STEP] [-B INTERLACE_ROWS] [-t TABLES]\n\ [-n RECORDS] [-M] [-x] [-y] [-O ORDERMODE] [-R RANGE] [-a REPLIcA][-g]\n\ [--help] [--usage] [--version]\n"); @@ -1842,7 +1920,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { int columnCount; for (columnCount = 0; columnCount < MAX_NUM_COLUMNS; columnCount ++) { - if (g_args.datatype[columnCount] == NULL) { + if (g_args.dataType[columnCount] == NULL) { break; } } @@ -1850,7 +1928,56 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { if (0 == columnCount) { ERROR_EXIT("data type error!"); } - g_args.num_of_CPR = columnCount; + g_args.columnCount = columnCount; + + g_args.lenOfOneRow = 20; // timestamp + for (int c = 0; c < g_args.columnCount; c++) { + switch(g_args.data_type[c]) { + case TSDB_DATA_TYPE_BINARY: + g_args.lenOfOneRow += g_args.binwidth + 3; + break; + + case TSDB_DATA_TYPE_NCHAR: + g_args.lenOfOneRow += g_args.binwidth + 3; + break; + + case TSDB_DATA_TYPE_INT: + g_args.lenOfOneRow += INT_BUFF_LEN; + break; + + case TSDB_DATA_TYPE_BIGINT: + g_args.lenOfOneRow += BIGINT_BUFF_LEN; + break; + + case TSDB_DATA_TYPE_SMALLINT: + g_args.lenOfOneRow += SMALLINT_BUFF_LEN; + break; + + case TSDB_DATA_TYPE_TINYINT: + g_args.lenOfOneRow += TINYINT_BUFF_LEN; + break; + + case TSDB_DATA_TYPE_BOOL: + g_args.lenOfOneRow += BOOL_BUFF_LEN; + break; + + case TSDB_DATA_TYPE_FLOAT: + g_args.lenOfOneRow += FLOAT_BUFF_LEN; + break; + + case TSDB_DATA_TYPE_DOUBLE: + g_args.lenOfOneRow += DOUBLE_BUFF_LEN; + break; + + case TSDB_DATA_TYPE_TIMESTAMP: + g_args.lenOfOneRow += TIMESTAMP_BUFF_LEN; + break; + + default: + errorPrint2("get error data type : %s\n", g_args.dataType[c]); + exit(EXIT_FAILURE); + } + } if (((arguments->debug_print) && (NULL != arguments->metaFile)) || arguments->verbose_print) { @@ -1863,11 +1990,11 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { printf("# Password: %s\n", arguments->password); printf("# Use metric: %s\n", arguments->use_metric ? "true" : "false"); - if (*(arguments->datatype)) { + if (*(arguments->dataType)) { printf("# Specified data type: "); for (int c = 0; c < MAX_NUM_COLUMNS; c++) - if (arguments->datatype[c]) - printf("%s,", arguments->datatype[c]); + if (arguments->dataType[c]) + printf("%s,", arguments->dataType[c]); else break; printf("\n"); @@ -1875,15 +2002,15 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { printf("# Insertion interval: %"PRIu64"\n", arguments->insert_interval); printf("# Number of records per req: %u\n", - arguments->num_of_RPR); + arguments->reqPerReq); printf("# Max SQL length: %"PRIu64"\n", arguments->max_sql_len); printf("# Length of Binary: %d\n", arguments->binwidth); - printf("# Number of Threads: %d\n", arguments->num_of_threads); + printf("# Number of Threads: %d\n", arguments->nthreads); printf("# Number of Tables: %"PRId64"\n", - arguments->num_of_tables); + arguments->ntables); printf("# Number of Data per Table: %"PRId64"\n", - arguments->num_of_DPT); + arguments->insertRows); printf("# Database name: %s\n", arguments->database); printf("# Table prefix: %s\n", arguments->tb_prefix); if (arguments->disorderRatio) { @@ -1909,31 +2036,20 @@ static void tmfclose(FILE *fp) { static void tmfree(char *buf) { if (NULL != buf) { free(buf); + buf = NULL; } } static int queryDbExec(TAOS *taos, char *command, QUERY_TYPE type, bool quiet) { - int i; - TAOS_RES *res = NULL; - int32_t code = -1; - for (i = 0; i < 5 /* retry */; i++) { - if (NULL != res) { - taos_free_result(res); - res = NULL; - } + verbosePrint("%s() LN%d - command: %s\n", __func__, __LINE__, command); - res = taos_query(taos, command); - code = taos_errno(res); - if (0 == code) { - break; - } - } + TAOS_RES *res = taos_query(taos, command); + int32_t code = taos_errno(res); - verbosePrint("%s() LN%d - command: %s\n", __func__, __LINE__, command); if (code != 0) { if (!quiet) { - errorPrint2("Failed to execute %s, reason: %s\n", + errorPrint2("Failed to execute <%s>, reason: %s\n", command, taos_errstr(res)); } taos_free_result(res); @@ -2338,7 +2454,7 @@ static int printfInsertMeta() { printf("top insert interval: \033[33m%"PRIu64"\033[0m\n", g_args.insert_interval); printf("number of records per req: \033[33m%u\033[0m\n", - g_args.num_of_RPR); + g_args.reqPerReq); printf("max sql length: \033[33m%"PRIu64"\033[0m\n", g_args.max_sql_len); @@ -2349,9 +2465,9 @@ static int printfInsertMeta() { printf(" database[%d] name: \033[33m%s\033[0m\n", i, g_Dbs.db[i].dbName); if (0 == g_Dbs.db[i].drop) { - printf(" drop: \033[33mno\033[0m\n"); + printf(" drop: \033[33m no\033[0m\n"); } else { - printf(" drop: \033[33myes\033[0m\n"); + printf(" drop: \033[33m yes\033[0m\n"); } if (g_Dbs.db[i].dbCfg.blocks > 0) { @@ -2420,7 +2536,7 @@ static int printfInsertMeta() { printf(" super table[\033[33m%"PRIu64"\033[0m]:\n", j); printf(" stbName: \033[33m%s\033[0m\n", - g_Dbs.db[i].superTbls[j].sTblName); + g_Dbs.db[i].superTbls[j].stbName); if (PRE_CREATE_SUBTBL == g_Dbs.db[i].superTbls[j].autoCreateTable) { printf(" autoCreateTable: \033[33m%s\033[0m\n", "no"); @@ -2460,9 +2576,9 @@ static int printfInsertMeta() { g_Dbs.db[i].superTbls[j].insertRows); /* if (0 == g_Dbs.db[i].superTbls[j].multiThreadWriteOneTbl) { - printf(" multiThreadWriteOneTbl: \033[33mno\033[0m\n"); + printf(" multiThreadWriteOneTbl: \033[33m no\033[0m\n"); }else { - printf(" multiThreadWriteOneTbl: \033[33myes\033[0m\n"); + printf(" multiThreadWriteOneTbl: \033[33m yes\033[0m\n"); } */ printf(" interlaceRows: \033[33m%u\033[0m\n", @@ -2543,7 +2659,7 @@ static void printfInsertMetaToFile(FILE* fp) { fprintf(fp, "resultFile: %s\n", g_Dbs.resultFile); fprintf(fp, "thread num of insert data: %d\n", g_Dbs.threadCount); fprintf(fp, "thread num of create table: %d\n", g_Dbs.threadCountForCreateTbl); - fprintf(fp, "number of records per req: %u\n", g_args.num_of_RPR); + fprintf(fp, "number of records per req: %u\n", g_args.reqPerReq); fprintf(fp, "max sql length: %"PRIu64"\n", g_args.max_sql_len); fprintf(fp, "database count: %d\n", g_Dbs.dbCount); @@ -2610,7 +2726,7 @@ static void printfInsertMetaToFile(FILE* fp) { fprintf(fp, " super table[%d]:\n", j); fprintf(fp, " stbName: %s\n", - g_Dbs.db[i].superTbls[j].sTblName); + g_Dbs.db[i].superTbls[j].stbName); if (PRE_CREATE_SUBTBL == g_Dbs.db[i].superTbls[j].autoCreateTable) { fprintf(fp, " autoCreateTable: %s\n", "no"); @@ -2769,7 +2885,7 @@ static void printfQueryMeta() { printf("childTblCount: \033[33m%"PRId64"\033[0m\n", g_queryInfo.superQueryInfo.childTblCount); printf("stable name: \033[33m%s\033[0m\n", - g_queryInfo.superQueryInfo.sTblName); + g_queryInfo.superQueryInfo.stbName); printf("stb query times:\033[33m%"PRIu64"\033[0m\n", g_queryInfo.superQueryInfo.queryTimes); @@ -2840,36 +2956,45 @@ static void xDumpFieldToFile(FILE* fp, const char* val, char buf[TSDB_MAX_BYTES_PER_ROW]; switch (field->type) { case TSDB_DATA_TYPE_BOOL: - fprintf(fp, "%d", ((((int32_t)(*((char *)val))) == 1) ? 1 : 0)); + fprintf(fp, "%d", ((((int32_t)(*((int8_t*)val))) == 1) ? 1 : 0)); break; + case TSDB_DATA_TYPE_TINYINT: fprintf(fp, "%d", *((int8_t *)val)); break; + case TSDB_DATA_TYPE_SMALLINT: fprintf(fp, "%d", *((int16_t *)val)); break; + case TSDB_DATA_TYPE_INT: fprintf(fp, "%d", *((int32_t *)val)); break; + case TSDB_DATA_TYPE_BIGINT: fprintf(fp, "%"PRId64"", *((int64_t *)val)); break; + case TSDB_DATA_TYPE_FLOAT: fprintf(fp, "%.5f", GET_FLOAT_VAL(val)); break; + case TSDB_DATA_TYPE_DOUBLE: fprintf(fp, "%.9f", GET_DOUBLE_VAL(val)); break; + case TSDB_DATA_TYPE_BINARY: case TSDB_DATA_TYPE_NCHAR: memcpy(buf, val, length); buf[length] = 0; fprintf(fp, "\'%s\'", buf); break; + case TSDB_DATA_TYPE_TIMESTAMP: formatTimestamp(buf, *(int64_t*)val, precision); fprintf(fp, "'%s'", buf); break; + default: break; } @@ -3356,29 +3481,50 @@ static int calcRowLen(SSuperTable* superTbls) { for (colIndex = 0; colIndex < superTbls->columnCount; colIndex++) { char* dataType = superTbls->columns[colIndex].dataType; - if (strcasecmp(dataType, "BINARY") == 0) { - lenOfOneRow += superTbls->columns[colIndex].dataLen + 3; - } else if (strcasecmp(dataType, "NCHAR") == 0) { - lenOfOneRow += superTbls->columns[colIndex].dataLen + 3; - } else if (strcasecmp(dataType, "INT") == 0) { - lenOfOneRow += INT_BUFF_LEN; - } else if (strcasecmp(dataType, "BIGINT") == 0) { - lenOfOneRow += BIGINT_BUFF_LEN; - } else if (strcasecmp(dataType, "SMALLINT") == 0) { - lenOfOneRow += SMALLINT_BUFF_LEN; - } else if (strcasecmp(dataType, "TINYINT") == 0) { - lenOfOneRow += TINYINT_BUFF_LEN; - } else if (strcasecmp(dataType, "BOOL") == 0) { - lenOfOneRow += BOOL_BUFF_LEN; - } else if (strcasecmp(dataType, "FLOAT") == 0) { - lenOfOneRow += FLOAT_BUFF_LEN; - } else if (strcasecmp(dataType, "DOUBLE") == 0) { - lenOfOneRow += DOUBLE_BUFF_LEN; - } else if (strcasecmp(dataType, "TIMESTAMP") == 0) { - lenOfOneRow += TIMESTAMP_BUFF_LEN; - } else { - errorPrint2("get error data type : %s\n", dataType); - exit(EXIT_FAILURE); + switch(superTbls->columns[colIndex].data_type) { + case TSDB_DATA_TYPE_BINARY: + lenOfOneRow += superTbls->columns[colIndex].dataLen + 3; + break; + + case TSDB_DATA_TYPE_NCHAR: + lenOfOneRow += superTbls->columns[colIndex].dataLen + 3; + break; + + case TSDB_DATA_TYPE_INT: + lenOfOneRow += INT_BUFF_LEN; + break; + + case TSDB_DATA_TYPE_BIGINT: + lenOfOneRow += BIGINT_BUFF_LEN; + break; + + case TSDB_DATA_TYPE_SMALLINT: + lenOfOneRow += SMALLINT_BUFF_LEN; + break; + + case TSDB_DATA_TYPE_TINYINT: + lenOfOneRow += TINYINT_BUFF_LEN; + break; + + case TSDB_DATA_TYPE_BOOL: + lenOfOneRow += BOOL_BUFF_LEN; + break; + + case TSDB_DATA_TYPE_FLOAT: + lenOfOneRow += FLOAT_BUFF_LEN; + break; + + case TSDB_DATA_TYPE_DOUBLE: + lenOfOneRow += DOUBLE_BUFF_LEN; + break; + + case TSDB_DATA_TYPE_TIMESTAMP: + lenOfOneRow += TIMESTAMP_BUFF_LEN; + break; + + default: + errorPrint2("get error data type : %s\n", dataType); + exit(EXIT_FAILURE); } } @@ -3418,9 +3564,8 @@ static int calcRowLen(SSuperTable* superTbls) { return 0; } - static int getChildNameOfSuperTableWithLimitAndOffset(TAOS * taos, - char* dbName, char* sTblName, char** childTblNameOfSuperTbl, + char* dbName, char* stbName, char** childTblNameOfSuperTbl, int64_t* childTblCountOfSuperTbl, int64_t limit, uint64_t offset) { char command[1024] = "\0"; @@ -3438,7 +3583,7 @@ static int getChildNameOfSuperTableWithLimitAndOffset(TAOS * taos, //get all child table name use cmd: select tbname from superTblName; snprintf(command, 1024, "select tbname from %s.%s %s", - dbName, sTblName, limitBuf); + dbName, stbName, limitBuf); res = taos_query(taos, command); int32_t code = taos_errno(res); @@ -3489,7 +3634,7 @@ static int getChildNameOfSuperTableWithLimitAndOffset(TAOS * taos, taos_free_result(res); taos_close(taos); errorPrint2("%s() LN%d, realloc fail for save child table name of %s.%s\n", - __func__, __LINE__, dbName, sTblName); + __func__, __LINE__, dbName, stbName); exit(EXIT_FAILURE); } } @@ -3504,10 +3649,10 @@ static int getChildNameOfSuperTableWithLimitAndOffset(TAOS * taos, } static int getAllChildNameOfSuperTable(TAOS * taos, char* dbName, - char* sTblName, char** childTblNameOfSuperTbl, + char* stbName, char** childTblNameOfSuperTbl, int64_t* childTblCountOfSuperTbl) { - return getChildNameOfSuperTableWithLimitAndOffset(taos, dbName, sTblName, + return getChildNameOfSuperTableWithLimitAndOffset(taos, dbName, stbName, childTblNameOfSuperTbl, childTblCountOfSuperTbl, -1, 0); } @@ -3521,7 +3666,7 @@ static int getSuperTableFromServer(TAOS * taos, char* dbName, int count = 0; //get schema use cmd: describe superTblName; - snprintf(command, 1024, "describe %s.%s", dbName, superTbls->sTblName); + snprintf(command, 1024, "describe %s.%s", dbName, superTbls->stbName); res = taos_query(taos, command); int32_t code = taos_errno(res); if (code != 0) { @@ -3547,6 +3692,39 @@ static int getSuperTableFromServer(TAOS * taos, char* dbName, (char *)row[TSDB_DESCRIBE_METRIC_TYPE_INDEX], min(DATATYPE_BUFF_LEN, fields[TSDB_DESCRIBE_METRIC_TYPE_INDEX].bytes) + 1); + if (0 == strncasecmp(superTbls->tags[tagIndex].dataType, + "INT", strlen("INT"))) { + superTbls->tags[tagIndex].data_type = TSDB_DATA_TYPE_INT; + } else if (0 == strncasecmp(superTbls->tags[tagIndex].dataType, + "TINYINT", strlen("TINYINT"))) { + superTbls->tags[tagIndex].data_type = TSDB_DATA_TYPE_TINYINT; + } else if (0 == strncasecmp(superTbls->tags[tagIndex].dataType, + "SMALLINT", strlen("SMALLINT"))) { + superTbls->tags[tagIndex].data_type = TSDB_DATA_TYPE_SMALLINT; + } else if (0 == strncasecmp(superTbls->tags[tagIndex].dataType, + "BIGINT", strlen("BIGINT"))) { + superTbls->tags[tagIndex].data_type = TSDB_DATA_TYPE_BIGINT; + } else if (0 == strncasecmp(superTbls->tags[tagIndex].dataType, + "FLOAT", strlen("FLOAT"))) { + superTbls->tags[tagIndex].data_type = TSDB_DATA_TYPE_FLOAT; + } else if (0 == strncasecmp(superTbls->tags[tagIndex].dataType, + "DOUBLE", strlen("DOUBLE"))) { + superTbls->tags[tagIndex].data_type = TSDB_DATA_TYPE_DOUBLE; + } else if (0 == strncasecmp(superTbls->tags[tagIndex].dataType, + "BINARY", strlen("BINARY"))) { + superTbls->tags[tagIndex].data_type = TSDB_DATA_TYPE_BINARY; + } else if (0 == strncasecmp(superTbls->tags[tagIndex].dataType, + "NCHAR", strlen("NCHAR"))) { + superTbls->tags[tagIndex].data_type = TSDB_DATA_TYPE_NCHAR; + } else if (0 == strncasecmp(superTbls->tags[tagIndex].dataType, + "BOOL", strlen("BOOL"))) { + superTbls->tags[tagIndex].data_type = TSDB_DATA_TYPE_BOOL; + } else if (0 == strncasecmp(superTbls->tags[tagIndex].dataType, + "TIMESTAMP", strlen("TIMESTAMP"))) { + superTbls->tags[tagIndex].data_type = TSDB_DATA_TYPE_TIMESTAMP; + } else { + superTbls->tags[tagIndex].data_type = TSDB_DATA_TYPE_NULL; + } superTbls->tags[tagIndex].dataLen = *((int *)row[TSDB_DESCRIBE_METRIC_LENGTH_INDEX]); tstrncpy(superTbls->tags[tagIndex].note, @@ -3558,16 +3736,51 @@ static int getSuperTableFromServer(TAOS * taos, char* dbName, tstrncpy(superTbls->columns[columnIndex].field, (char *)row[TSDB_DESCRIBE_METRIC_FIELD_INDEX], fields[TSDB_DESCRIBE_METRIC_FIELD_INDEX].bytes); + tstrncpy(superTbls->columns[columnIndex].dataType, (char *)row[TSDB_DESCRIBE_METRIC_TYPE_INDEX], min(DATATYPE_BUFF_LEN, fields[TSDB_DESCRIBE_METRIC_TYPE_INDEX].bytes) + 1); + if (0 == strncasecmp(superTbls->columns[columnIndex].dataType, + "INT", strlen("INT"))) { + superTbls->columns[columnIndex].data_type = TSDB_DATA_TYPE_INT; + } else if (0 == strncasecmp(superTbls->columns[columnIndex].dataType, + "TINYINT", strlen("TINYINT"))) { + superTbls->columns[columnIndex].data_type = TSDB_DATA_TYPE_TINYINT; + } else if (0 == strncasecmp(superTbls->columns[columnIndex].dataType, + "SMALLINT", strlen("SMALLINT"))) { + superTbls->columns[columnIndex].data_type = TSDB_DATA_TYPE_SMALLINT; + } else if (0 == strncasecmp(superTbls->columns[columnIndex].dataType, + "BIGINT", strlen("BIGINT"))) { + superTbls->columns[columnIndex].data_type = TSDB_DATA_TYPE_BIGINT; + } else if (0 == strncasecmp(superTbls->columns[columnIndex].dataType, + "FLOAT", strlen("FLOAT"))) { + superTbls->columns[columnIndex].data_type = TSDB_DATA_TYPE_FLOAT; + } else if (0 == strncasecmp(superTbls->columns[columnIndex].dataType, + "DOUBLE", strlen("DOUBLE"))) { + superTbls->columns[columnIndex].data_type = TSDB_DATA_TYPE_DOUBLE; + } else if (0 == strncasecmp(superTbls->columns[columnIndex].dataType, + "BINARY", strlen("BINARY"))) { + superTbls->columns[columnIndex].data_type = TSDB_DATA_TYPE_BINARY; + } else if (0 == strncasecmp(superTbls->columns[columnIndex].dataType, + "NCHAR", strlen("NCHAR"))) { + superTbls->columns[columnIndex].data_type = TSDB_DATA_TYPE_NCHAR; + } else if (0 == strncasecmp(superTbls->columns[columnIndex].dataType, + "BOOL", strlen("BOOL"))) { + superTbls->columns[columnIndex].data_type = TSDB_DATA_TYPE_BOOL; + } else if (0 == strncasecmp(superTbls->columns[columnIndex].dataType, + "TIMESTAMP", strlen("TIMESTAMP"))) { + superTbls->columns[columnIndex].data_type = TSDB_DATA_TYPE_TIMESTAMP; + } else { + superTbls->columns[columnIndex].data_type = TSDB_DATA_TYPE_NULL; + } superTbls->columns[columnIndex].dataLen = *((int *)row[TSDB_DESCRIBE_METRIC_LENGTH_INDEX]); tstrncpy(superTbls->columns[columnIndex].note, (char *)row[TSDB_DESCRIBE_METRIC_NOTE_INDEX], min(NOTE_BUFF_LEN, fields[TSDB_DESCRIBE_METRIC_NOTE_INDEX].bytes) + 1); + columnIndex++; } count++; @@ -3589,7 +3802,7 @@ static int getSuperTableFromServer(TAOS * taos, char* dbName, return -1; } getAllChildNameOfSuperTable(taos, dbName, - superTbls->sTblName, + superTbls->stbName, &superTbls->childTblName, &superTbls->childTblCount); } @@ -3605,7 +3818,6 @@ static int createSuperTable( assert(command); char cols[COL_BUFFER_LEN] = "\0"; - int colIndex; int len = 0; int lenOfOneRow = 0; @@ -3617,67 +3829,87 @@ static int createSuperTable( return -1; } - for (colIndex = 0; colIndex < superTbl->columnCount; colIndex++) { - char* dataType = superTbl->columns[colIndex].dataType; + for (int colIndex = 0; colIndex < superTbl->columnCount; colIndex++) { - if (strcasecmp(dataType, "BINARY") == 0) { - len += snprintf(cols + len, COL_BUFFER_LEN - len, - ",C%d %s(%d)", colIndex, "BINARY", - superTbl->columns[colIndex].dataLen); - lenOfOneRow += superTbl->columns[colIndex].dataLen + 3; - } else if (strcasecmp(dataType, "NCHAR") == 0) { - len += snprintf(cols + len, COL_BUFFER_LEN - len, - ",C%d %s(%d)", colIndex, "NCHAR", - superTbl->columns[colIndex].dataLen); - lenOfOneRow += superTbl->columns[colIndex].dataLen + 3; - } else if (strcasecmp(dataType, "INT") == 0) { - if ((g_args.demo_mode) && (colIndex == 1)) { + switch(superTbl->columns[colIndex].data_type) { + case TSDB_DATA_TYPE_BINARY: len += snprintf(cols + len, COL_BUFFER_LEN - len, - ", VOLTAGE INT"); - } else { - len += snprintf(cols + len, COL_BUFFER_LEN - len, ",C%d %s", colIndex, "INT"); - } - lenOfOneRow += INT_BUFF_LEN; - } else if (strcasecmp(dataType, "BIGINT") == 0) { - len += snprintf(cols + len, COL_BUFFER_LEN - len, ",C%d %s", - colIndex, "BIGINT"); - lenOfOneRow += BIGINT_BUFF_LEN; - } else if (strcasecmp(dataType, "SMALLINT") == 0) { - len += snprintf(cols + len, COL_BUFFER_LEN - len, ",C%d %s", - colIndex, "SMALLINT"); - lenOfOneRow += SMALLINT_BUFF_LEN; - } else if (strcasecmp(dataType, "TINYINT") == 0) { - len += snprintf(cols + len, COL_BUFFER_LEN - len, ",C%d %s", colIndex, "TINYINT"); - lenOfOneRow += TINYINT_BUFF_LEN; - } else if (strcasecmp(dataType, "BOOL") == 0) { - len += snprintf(cols + len, COL_BUFFER_LEN - len, ",C%d %s", colIndex, "BOOL"); - lenOfOneRow += BOOL_BUFF_LEN; - } else if (strcasecmp(dataType, "FLOAT") == 0) { - if (g_args.demo_mode) { - if (colIndex == 0) { - len += snprintf(cols + len, COL_BUFFER_LEN - len, ", CURRENT FLOAT"); - } else if (colIndex == 2) { - len += snprintf(cols + len, COL_BUFFER_LEN - len, ", PHASE FLOAT"); + ",C%d %s(%d)", colIndex, "BINARY", + superTbl->columns[colIndex].dataLen); + lenOfOneRow += superTbl->columns[colIndex].dataLen + 3; + break; + + case TSDB_DATA_TYPE_NCHAR: + len += snprintf(cols + len, COL_BUFFER_LEN - len, + ",C%d %s(%d)", colIndex, "NCHAR", + superTbl->columns[colIndex].dataLen); + lenOfOneRow += superTbl->columns[colIndex].dataLen + 3; + break; + + case TSDB_DATA_TYPE_INT: + if ((g_args.demo_mode) && (colIndex == 1)) { + len += snprintf(cols + len, COL_BUFFER_LEN - len, + ", VOLTAGE INT"); + } else { + len += snprintf(cols + len, COL_BUFFER_LEN - len, ",C%d %s", colIndex, "INT"); } - } else { - len += snprintf(cols + len, COL_BUFFER_LEN - len, ",C%d %s", colIndex, "FLOAT"); - } + lenOfOneRow += INT_BUFF_LEN; + break; - lenOfOneRow += FLOAT_BUFF_LEN; - } else if (strcasecmp(dataType, "DOUBLE") == 0) { - len += snprintf(cols + len, COL_BUFFER_LEN - len, ",C%d %s", - colIndex, "DOUBLE"); - lenOfOneRow += DOUBLE_BUFF_LEN; - } else if (strcasecmp(dataType, "TIMESTAMP") == 0) { - len += snprintf(cols + len, COL_BUFFER_LEN - len, ",C%d %s", - colIndex, "TIMESTAMP"); - lenOfOneRow += TIMESTAMP_BUFF_LEN; - } else { - taos_close(taos); - free(command); - errorPrint2("%s() LN%d, config error data type : %s\n", - __func__, __LINE__, dataType); - exit(EXIT_FAILURE); + case TSDB_DATA_TYPE_BIGINT: + len += snprintf(cols + len, COL_BUFFER_LEN - len, ",C%d %s", + colIndex, "BIGINT"); + lenOfOneRow += BIGINT_BUFF_LEN; + break; + + case TSDB_DATA_TYPE_SMALLINT: + len += snprintf(cols + len, COL_BUFFER_LEN - len, ",C%d %s", + colIndex, "SMALLINT"); + lenOfOneRow += SMALLINT_BUFF_LEN; + break; + + case TSDB_DATA_TYPE_TINYINT: + len += snprintf(cols + len, COL_BUFFER_LEN - len, ",C%d %s", colIndex, "TINYINT"); + lenOfOneRow += TINYINT_BUFF_LEN; + break; + + case TSDB_DATA_TYPE_BOOL: + len += snprintf(cols + len, COL_BUFFER_LEN - len, ",C%d %s", colIndex, "BOOL"); + lenOfOneRow += BOOL_BUFF_LEN; + break; + + case TSDB_DATA_TYPE_FLOAT: + if (g_args.demo_mode) { + if (colIndex == 0) { + len += snprintf(cols + len, COL_BUFFER_LEN - len, ", CURRENT FLOAT"); + } else if (colIndex == 2) { + len += snprintf(cols + len, COL_BUFFER_LEN - len, ", PHASE FLOAT"); + } + } else { + len += snprintf(cols + len, COL_BUFFER_LEN - len, ",C%d %s", colIndex, "FLOAT"); + } + + lenOfOneRow += FLOAT_BUFF_LEN; + break; + + case TSDB_DATA_TYPE_DOUBLE: + len += snprintf(cols + len, COL_BUFFER_LEN - len, ",C%d %s", + colIndex, "DOUBLE"); + lenOfOneRow += DOUBLE_BUFF_LEN; + break; + + case TSDB_DATA_TYPE_TIMESTAMP: + len += snprintf(cols + len, COL_BUFFER_LEN - len, ",C%d %s", + colIndex, "TIMESTAMP"); + lenOfOneRow += TIMESTAMP_BUFF_LEN; + break; + + default: + taos_close(taos); + free(command); + errorPrint2("%s() LN%d, config error data type : %s\n", + __func__, __LINE__, superTbl->columns[colIndex].dataType); + exit(EXIT_FAILURE); } } @@ -3777,16 +4009,16 @@ static int createSuperTable( superTbl->lenOfTagOfOneRow = lenOfTagOfOneRow; snprintf(command, BUFFER_SIZE, - "create table if not exists %s.%s (ts timestamp%s) tags %s", - dbName, superTbl->sTblName, cols, tags); + "CREATE TABLE IF NOT EXISTS %s.%s (ts TIMESTAMP%s) TAGS %s", + dbName, superTbl->stbName, cols, tags); if (0 != queryDbExec(taos, command, NO_INSERT_TYPE, false)) { errorPrint2("create supertable %s failed!\n\n", - superTbl->sTblName); + superTbl->stbName); free(command); return -1; } - debugPrint("create supertable %s success!\n\n", superTbl->sTblName); + debugPrint("create supertable %s success!\n\n", superTbl->stbName); free(command); return 0; } @@ -3810,42 +4042,42 @@ int createDatabasesAndStables(char *command) { int dataLen = 0; dataLen += snprintf(command + dataLen, - BUFFER_SIZE - dataLen, "create database if not exists %s", + BUFFER_SIZE - dataLen, "CREATE DATABASE IF NOT EXISTS %s", g_Dbs.db[i].dbName); if (g_Dbs.db[i].dbCfg.blocks > 0) { dataLen += snprintf(command + dataLen, - BUFFER_SIZE - dataLen, " blocks %d", + BUFFER_SIZE - dataLen, " BLOCKS %d", g_Dbs.db[i].dbCfg.blocks); } if (g_Dbs.db[i].dbCfg.cache > 0) { dataLen += snprintf(command + dataLen, - BUFFER_SIZE - dataLen, " cache %d", + BUFFER_SIZE - dataLen, " CACHE %d", g_Dbs.db[i].dbCfg.cache); } if (g_Dbs.db[i].dbCfg.days > 0) { dataLen += snprintf(command + dataLen, - BUFFER_SIZE - dataLen, " days %d", + BUFFER_SIZE - dataLen, " DAYS %d", g_Dbs.db[i].dbCfg.days); } if (g_Dbs.db[i].dbCfg.keep > 0) { dataLen += snprintf(command + dataLen, - BUFFER_SIZE - dataLen, " keep %d", + BUFFER_SIZE - dataLen, " KEEP %d", g_Dbs.db[i].dbCfg.keep); } if (g_Dbs.db[i].dbCfg.quorum > 1) { dataLen += snprintf(command + dataLen, - BUFFER_SIZE - dataLen, " quorum %d", + BUFFER_SIZE - dataLen, " QUORUM %d", g_Dbs.db[i].dbCfg.quorum); } if (g_Dbs.db[i].dbCfg.replica > 0) { dataLen += snprintf(command + dataLen, - BUFFER_SIZE - dataLen, " replica %d", + BUFFER_SIZE - dataLen, " REPLICA %d", g_Dbs.db[i].dbCfg.replica); } if (g_Dbs.db[i].dbCfg.update > 0) { dataLen += snprintf(command + dataLen, - BUFFER_SIZE - dataLen, " update %d", + BUFFER_SIZE - dataLen, " UPDATE %d", g_Dbs.db[i].dbCfg.update); } //if (g_Dbs.db[i].dbCfg.maxtablesPerVnode > 0) { @@ -3854,17 +4086,17 @@ int createDatabasesAndStables(char *command) { //} if (g_Dbs.db[i].dbCfg.minRows > 0) { dataLen += snprintf(command + dataLen, - BUFFER_SIZE - dataLen, " minrows %d", + BUFFER_SIZE - dataLen, " MINROWS %d", g_Dbs.db[i].dbCfg.minRows); } if (g_Dbs.db[i].dbCfg.maxRows > 0) { dataLen += snprintf(command + dataLen, - BUFFER_SIZE - dataLen, " maxrows %d", + BUFFER_SIZE - dataLen, " MAXROWS %d", g_Dbs.db[i].dbCfg.maxRows); } if (g_Dbs.db[i].dbCfg.comp > 0) { dataLen += snprintf(command + dataLen, - BUFFER_SIZE - dataLen, " comp %d", + BUFFER_SIZE - dataLen, " COMP %d", g_Dbs.db[i].dbCfg.comp); } if (g_Dbs.db[i].dbCfg.walLevel > 0) { @@ -3874,12 +4106,12 @@ int createDatabasesAndStables(char *command) { } if (g_Dbs.db[i].dbCfg.cacheLast > 0) { dataLen += snprintf(command + dataLen, - BUFFER_SIZE - dataLen, " cachelast %d", + BUFFER_SIZE - dataLen, " CACHELAST %d", g_Dbs.db[i].dbCfg.cacheLast); } if (g_Dbs.db[i].dbCfg.fsync > 0) { dataLen += snprintf(command + dataLen, BUFFER_SIZE - dataLen, - " fsync %d", g_Dbs.db[i].dbCfg.fsync); + " FSYNC %d", g_Dbs.db[i].dbCfg.fsync); } if ((0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "ms", 2)) || (0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, @@ -3906,7 +4138,7 @@ int createDatabasesAndStables(char *command) { for (uint64_t j = 0; j < g_Dbs.db[i].superTblCount; j++) { sprintf(command, "describe %s.%s;", g_Dbs.db[i].dbName, - g_Dbs.db[i].superTbls[j].sTblName); + g_Dbs.db[i].superTbls[j].stbName); ret = queryDbExec(taos, command, NO_INSERT_TYPE, true); if ((ret != 0) || (g_Dbs.db[i].drop)) { @@ -3923,7 +4155,7 @@ int createDatabasesAndStables(char *command) { &g_Dbs.db[i].superTbls[j]); if (0 != ret) { errorPrint2("\nget super table %s.%s info failed!\n\n", - g_Dbs.db[i].dbName, g_Dbs.db[i].superTbls[j].sTblName); + g_Dbs.db[i].dbName, g_Dbs.db[i].superTbls[j].stbName); continue; } @@ -3965,7 +4197,7 @@ static void* createTable(void *sarg) i <= pThreadInfo->end_table_to; i++) { if (0 == g_Dbs.use_metric) { snprintf(pThreadInfo->buffer, buff_len, - "create table if not exists %s.%s%"PRIu64" %s;", + "CREATE TABLE IF NOT EXISTS %s.%s%"PRIu64" %s;", pThreadInfo->db_name, g_args.tb_prefix, i, pThreadInfo->cols); @@ -3981,7 +4213,7 @@ static void* createTable(void *sarg) batchNum = 0; memset(pThreadInfo->buffer, 0, buff_len); len += snprintf(pThreadInfo->buffer + len, - buff_len - len, "create table "); + buff_len - len, "CREATE TABLE "); } char* tagsValBuf = NULL; @@ -4006,7 +4238,7 @@ static void* createTable(void *sarg) "if not exists %s.%s%"PRIu64" using %s.%s tags %s ", pThreadInfo->db_name, stbInfo->childTblPrefix, i, pThreadInfo->db_name, - stbInfo->sTblName, tagsValBuf); + stbInfo->stbName, tagsValBuf); free(tagsValBuf); batchNum++; if ((batchNum < stbInfo->batchCreateTableNum) @@ -4151,15 +4383,15 @@ static void createChildTables() { } else { // normal table len = snprintf(tblColsBuf, TSDB_MAX_BYTES_PER_ROW, "(TS TIMESTAMP"); - for (int j = 0; j < g_args.num_of_CPR; j++) { - if ((strncasecmp(g_args.datatype[j], "BINARY", strlen("BINARY")) == 0) - || (strncasecmp(g_args.datatype[j], + for (int j = 0; j < g_args.columnCount; j++) { + if ((strncasecmp(g_args.dataType[j], "BINARY", strlen("BINARY")) == 0) + || (strncasecmp(g_args.dataType[j], "NCHAR", strlen("NCHAR")) == 0)) { snprintf(tblColsBuf + len, TSDB_MAX_BYTES_PER_ROW - len, - ",C%d %s(%d)", j, g_args.datatype[j], g_args.binwidth); + ",C%d %s(%d)", j, g_args.dataType[j], g_args.binwidth); } else { snprintf(tblColsBuf + len, TSDB_MAX_BYTES_PER_ROW - len, - ",C%d %s", j, g_args.datatype[j]); + ",C%d %s", j, g_args.dataType[j]); } len = strlen(tblColsBuf); } @@ -4168,12 +4400,12 @@ static void createChildTables() { verbosePrint("%s() LN%d: dbName: %s num of tb: %"PRId64" schema: %s\n", __func__, __LINE__, - g_Dbs.db[i].dbName, g_args.num_of_tables, tblColsBuf); + g_Dbs.db[i].dbName, g_args.ntables, tblColsBuf); startMultiThreadCreateChildTable( tblColsBuf, g_Dbs.threadCountForCreateTbl, 0, - g_args.num_of_tables, + g_args.ntables, g_Dbs.db[i].dbName, NULL); } @@ -4251,7 +4483,7 @@ static int readTagFromCsvFileToMem(SSuperTable * stbInfo) { /* Read 10000 lines at most. If more than 10000 lines, continue to read after using */ -static int readSampleFromCsvFileToMem( +static int generateSampleFromCsvForStb( SSuperTable* stbInfo) { size_t n = 0; ssize_t readLen = 0; @@ -4267,7 +4499,7 @@ static int readSampleFromCsvFileToMem( assert(stbInfo->sampleDataBuf); memset(stbInfo->sampleDataBuf, 0, - MAX_SAMPLES_ONCE_FROM_FILE * stbInfo->lenOfOneRow); + MAX_SAMPLES * stbInfo->lenOfOneRow); while(1) { readLen = tgetline(&line, &n, fp); if (-1 == readLen) { @@ -4298,7 +4530,7 @@ static int readSampleFromCsvFileToMem( line, readLen); getRows++; - if (getRows == MAX_SAMPLES_ONCE_FROM_FILE) { + if (getRows == MAX_SAMPLES) { break; } } @@ -4377,6 +4609,7 @@ static bool getColumnAndTagTypeFromInsertJsonFile( tstrncpy(superTbls->columns[index].dataType, columnCase.dataType, min(DATATYPE_BUFF_LEN, strlen(columnCase.dataType) + 1)); + superTbls->columns[index].dataLen = columnCase.dataLen; index++; } @@ -4390,6 +4623,42 @@ static bool getColumnAndTagTypeFromInsertJsonFile( superTbls->columnCount = index; + for (int c = 0; c < superTbls->columnCount; c++) { + if (0 == strncasecmp(superTbls->columns[c].dataType, + "INT", strlen("INT"))) { + superTbls->columns[c].data_type = TSDB_DATA_TYPE_INT; + } else if (0 == strncasecmp(superTbls->columns[c].dataType, + "TINYINT", strlen("TINYINT"))) { + superTbls->columns[c].data_type = TSDB_DATA_TYPE_TINYINT; + } else if (0 == strncasecmp(superTbls->columns[c].dataType, + "SMALLINT", strlen("SMALLINT"))) { + superTbls->columns[c].data_type = TSDB_DATA_TYPE_SMALLINT; + } else if (0 == strncasecmp(superTbls->columns[c].dataType, + "BIGINT", strlen("BIGINT"))) { + superTbls->columns[c].data_type = TSDB_DATA_TYPE_BIGINT; + } else if (0 == strncasecmp(superTbls->columns[c].dataType, + "FLOAT", strlen("FLOAT"))) { + superTbls->columns[c].data_type = TSDB_DATA_TYPE_FLOAT; + } else if (0 == strncasecmp(superTbls->columns[c].dataType, + "DOUBLE", strlen("DOUBLE"))) { + superTbls->columns[c].data_type = TSDB_DATA_TYPE_DOUBLE; + } else if (0 == strncasecmp(superTbls->columns[c].dataType, + "BINARY", strlen("BINARY"))) { + superTbls->columns[c].data_type = TSDB_DATA_TYPE_BINARY; + } else if (0 == strncasecmp(superTbls->columns[c].dataType, + "NCHAR", strlen("NCHAR"))) { + superTbls->columns[c].data_type = TSDB_DATA_TYPE_NCHAR; + } else if (0 == strncasecmp(superTbls->columns[c].dataType, + "BOOL", strlen("BOOL"))) { + superTbls->columns[c].data_type = TSDB_DATA_TYPE_BOOL; + } else if (0 == strncasecmp(superTbls->columns[c].dataType, + "TIMESTAMP", strlen("TIMESTAMP"))) { + superTbls->columns[c].data_type = TSDB_DATA_TYPE_TIMESTAMP; + } else { + superTbls->columns[c].data_type = TSDB_DATA_TYPE_NULL; + } + } + count = 1; index = 0; // tags @@ -4459,6 +4728,42 @@ static bool getColumnAndTagTypeFromInsertJsonFile( superTbls->tagCount = index; + for (int t = 0; t < superTbls->tagCount; t++) { + if (0 == strncasecmp(superTbls->tags[t].dataType, + "INT", strlen("INT"))) { + superTbls->tags[t].data_type = TSDB_DATA_TYPE_INT; + } else if (0 == strncasecmp(superTbls->tags[t].dataType, + "TINYINT", strlen("TINYINT"))) { + superTbls->tags[t].data_type = TSDB_DATA_TYPE_TINYINT; + } else if (0 == strncasecmp(superTbls->tags[t].dataType, + "SMALLINT", strlen("SMALLINT"))) { + superTbls->tags[t].data_type = TSDB_DATA_TYPE_SMALLINT; + } else if (0 == strncasecmp(superTbls->tags[t].dataType, + "BIGINT", strlen("BIGINT"))) { + superTbls->tags[t].data_type = TSDB_DATA_TYPE_BIGINT; + } else if (0 == strncasecmp(superTbls->tags[t].dataType, + "FLOAT", strlen("FLOAT"))) { + superTbls->tags[t].data_type = TSDB_DATA_TYPE_FLOAT; + } else if (0 == strncasecmp(superTbls->tags[t].dataType, + "DOUBLE", strlen("DOUBLE"))) { + superTbls->tags[t].data_type = TSDB_DATA_TYPE_DOUBLE; + } else if (0 == strncasecmp(superTbls->tags[t].dataType, + "BINARY", strlen("BINARY"))) { + superTbls->tags[t].data_type = TSDB_DATA_TYPE_BINARY; + } else if (0 == strncasecmp(superTbls->tags[t].dataType, + "NCHAR", strlen("NCHAR"))) { + superTbls->tags[t].data_type = TSDB_DATA_TYPE_NCHAR; + } else if (0 == strncasecmp(superTbls->tags[t].dataType, + "BOOL", strlen("BOOL"))) { + superTbls->tags[t].data_type = TSDB_DATA_TYPE_BOOL; + } else if (0 == strncasecmp(superTbls->tags[t].dataType, + "TIMESTAMP", strlen("TIMESTAMP"))) { + superTbls->tags[t].data_type = TSDB_DATA_TYPE_TIMESTAMP; + } else { + superTbls->tags[t].data_type = TSDB_DATA_TYPE_NULL; + } + } + if ((superTbls->columnCount + superTbls->tagCount + 1 /* ts */) > TSDB_MAX_COLUMNS) { errorPrint("columns + tags is more than allowed max columns count: %d\n", TSDB_MAX_COLUMNS); @@ -4553,15 +4858,15 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { cJSON* interlaceRows = cJSON_GetObjectItem(root, "interlace_rows"); if (interlaceRows && interlaceRows->type == cJSON_Number) { if (interlaceRows->valueint < 0) { - errorPrint("%s", "failed to read json, interlace_rows input mistake\n"); + errorPrint("%s", "failed to read json, interlaceRows input mistake\n"); goto PARSE_OVER; } - g_args.interlace_rows = interlaceRows->valueint; + g_args.interlaceRows = interlaceRows->valueint; } else if (!interlaceRows) { - g_args.interlace_rows = 0; // 0 means progressive mode, > 0 mean interlace mode. max value is less or equ num_of_records_per_req + g_args.interlaceRows = 0; // 0 means progressive mode, > 0 mean interlace mode. max value is less or equ num_of_records_per_req } else { - errorPrint("%s", "failed to read json, interlace_rows input mistake\n"); + errorPrint("%s", "failed to read json, interlaceRows input mistake\n"); goto PARSE_OVER; } @@ -4595,9 +4900,9 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { prompt(); numRecPerReq->valueint = MAX_RECORDS_PER_REQ; } - g_args.num_of_RPR = numRecPerReq->valueint; + g_args.reqPerReq = numRecPerReq->valueint; } else if (!numRecPerReq) { - g_args.num_of_RPR = MAX_RECORDS_PER_REQ; + g_args.reqPerReq = MAX_RECORDS_PER_REQ; } else { errorPrint("%s() LN%d, failed to read json, num_of_records_per_req not found\n", __func__, __LINE__); @@ -4623,13 +4928,13 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { } // rows per table need be less than insert batch - if (g_args.interlace_rows > g_args.num_of_RPR) { + if (g_args.interlaceRows > g_args.reqPerReq) { printf("NOTICE: interlace rows value %u > num_of_records_per_req %u\n\n", - g_args.interlace_rows, g_args.num_of_RPR); + g_args.interlaceRows, g_args.reqPerReq); printf(" interlace rows value will be set to num_of_records_per_req %u\n\n", - g_args.num_of_RPR); + g_args.reqPerReq); prompt(); - g_args.interlace_rows = g_args.num_of_RPR; + g_args.interlaceRows = g_args.reqPerReq; } cJSON* dbs = cJSON_GetObjectItem(root, "databases"); @@ -4831,7 +5136,7 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { goto PARSE_OVER; } - // super_talbes + // super_tables cJSON *stables = cJSON_GetObjectItem(dbinfos, "super_tables"); if (!stables || stables->type != cJSON_Array) { errorPrint("%s", "failed to read json, super_tables not found\n"); @@ -4858,7 +5163,7 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { errorPrint("%s", "failed to read json, stb name not found\n"); goto PARSE_OVER; } - tstrncpy(g_Dbs.db[i].superTbls[j].sTblName, stbName->valuestring, + tstrncpy(g_Dbs.db[i].superTbls[j].stbName, stbName->valuestring, TSDB_TABLE_NAME_LEN); cJSON *prefix = cJSON_GetObjectItem(stbInfo, "childtable_prefix"); @@ -5168,7 +5473,7 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { goto PARSE_OVER; } } else if (!insertInterval) { - verbosePrint("%s() LN%d: stable insert interval be overrided by global %"PRIu64".\n", + verbosePrint("%s() LN%d: stable insert interval be overrode by global %"PRIu64".\n", __func__, __LINE__, g_args.insert_interval); g_Dbs.db[i].superTbls[j].insertInterval = g_args.insert_interval; } else { @@ -5512,7 +5817,7 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { cJSON* stblname = cJSON_GetObjectItem(superQuery, "stblname"); if (stblname && stblname->type == cJSON_String && stblname->valuestring != NULL) { - tstrncpy(g_queryInfo.superQueryInfo.sTblName, stblname->valuestring, + tstrncpy(g_queryInfo.superQueryInfo.stbName, stblname->valuestring, TSDB_TABLE_NAME_LEN); } else { errorPrint("%s", "failed to read json, super table name input error\n"); @@ -5734,23 +6039,37 @@ static int prepareSampleData() { static void postFreeResource() { tmfclose(g_fpOfInsertResult); + for (int i = 0; i < g_Dbs.dbCount; i++) { for (uint64_t j = 0; j < g_Dbs.db[i].superTblCount; j++) { if (0 != g_Dbs.db[i].superTbls[j].colsOfCreateChildTable) { - free(g_Dbs.db[i].superTbls[j].colsOfCreateChildTable); + tmfree(g_Dbs.db[i].superTbls[j].colsOfCreateChildTable); g_Dbs.db[i].superTbls[j].colsOfCreateChildTable = NULL; } if (0 != g_Dbs.db[i].superTbls[j].sampleDataBuf) { - free(g_Dbs.db[i].superTbls[j].sampleDataBuf); + tmfree(g_Dbs.db[i].superTbls[j].sampleDataBuf); g_Dbs.db[i].superTbls[j].sampleDataBuf = NULL; } +#if STMT_BIND_PARAM_BATCH == 1 + for (int c = 0; + c < g_Dbs.db[i].superTbls[j].columnCount; c ++) { + + if (g_Dbs.db[i].superTbls[j].sampleBindBatchArray) { + + tmfree((char *)((uintptr_t)*(uintptr_t*)( + g_Dbs.db[i].superTbls[j].sampleBindBatchArray + + sizeof(char*) * c))); + } + } + tmfree(g_Dbs.db[i].superTbls[j].sampleBindBatchArray); +#endif if (0 != g_Dbs.db[i].superTbls[j].tagDataBuf) { - free(g_Dbs.db[i].superTbls[j].tagDataBuf); + tmfree(g_Dbs.db[i].superTbls[j].tagDataBuf); g_Dbs.db[i].superTbls[j].tagDataBuf = NULL; } if (0 != g_Dbs.db[i].superTbls[j].childTblName) { - free(g_Dbs.db[i].superTbls[j].childTblName); + tmfree(g_Dbs.db[i].superTbls[j].childTblName); g_Dbs.db[i].superTbls[j].childTblName = NULL; } } @@ -5766,13 +6085,26 @@ static void postFreeResource() { tmfree(g_rand_current_buff); tmfree(g_rand_phase_buff); + tmfree(g_sampleDataBuf); + +#if STMT_BIND_PARAM_BATCH == 1 + for (int l = 0; + l < g_args.columnCount; l ++) { + if (g_sampleBindBatchArray) { + tmfree((char *)((uintptr_t)*(uintptr_t*)( + g_sampleBindBatchArray + + sizeof(char*) * l))); + } + } + tmfree(g_sampleBindBatchArray); +#endif } static int getRowDataFromSample( char* dataBuf, int64_t maxLen, int64_t timestamp, SSuperTable* stbInfo, int64_t* sampleUsePos) { - if ((*sampleUsePos) == MAX_SAMPLES_ONCE_FROM_FILE) { + if ((*sampleUsePos) == MAX_SAMPLES) { *sampleUsePos = 0; } @@ -5803,13 +6135,14 @@ static int64_t generateStbRowData( int tmpLen; dataLen += snprintf(pstr + dataLen, maxLen - dataLen, - "(%" PRId64 ",", timestamp); + "(%" PRId64 "", timestamp); for (int i = 0; i < stbInfo->columnCount; i++) { - if ((0 == strncasecmp(stbInfo->columns[i].dataType, - "BINARY", 6)) - || (0 == strncasecmp(stbInfo->columns[i].dataType, - "NCHAR", 5))) { + tstrncpy(pstr + dataLen, ",", 2); + dataLen += 1; + + if ((stbInfo->columns[i].data_type == TSDB_DATA_TYPE_BINARY) + || (stbInfo->columns[i].data_type == TSDB_DATA_TYPE_NCHAR)) { if (stbInfo->columns[i].dataLen > TSDB_MAX_BINARY_LEN) { errorPrint2("binary or nchar length overflow, max size:%u\n", (uint32_t)TSDB_MAX_BINARY_LEN); @@ -5827,80 +6160,91 @@ static int64_t generateStbRowData( return -1; } rand_string(buf, stbInfo->columns[i].dataLen); - dataLen += snprintf(pstr + dataLen, maxLen - dataLen, "\'%s\',", buf); + dataLen += snprintf(pstr + dataLen, maxLen - dataLen, "\'%s\'", buf); tmfree(buf); } else { - char *tmp; + char *tmp = NULL; + switch(stbInfo->columns[i].data_type) { + case TSDB_DATA_TYPE_INT: + if ((g_args.demo_mode) && (i == 1)) { + tmp = demo_voltage_int_str(); + } else { + tmp = rand_int_str(); + } + tmpLen = strlen(tmp); + tstrncpy(pstr + dataLen, tmp, min(tmpLen + 1, INT_BUFF_LEN)); + break; - if (0 == strncasecmp(stbInfo->columns[i].dataType, - "INT", 3)) { - if ((g_args.demo_mode) && (i == 1)) { - tmp = demo_voltage_int_str(); - } else { - tmp = rand_int_str(); - } - tmpLen = strlen(tmp); - tstrncpy(pstr + dataLen, tmp, min(tmpLen + 1, INT_BUFF_LEN)); - } else if (0 == strncasecmp(stbInfo->columns[i].dataType, - "BIGINT", 6)) { - tmp = rand_bigint_str(); - tstrncpy(pstr + dataLen, tmp, BIGINT_BUFF_LEN); - } else if (0 == strncasecmp(stbInfo->columns[i].dataType, - "FLOAT", 5)) { - if (g_args.demo_mode) { - if (i == 0) { - tmp = demo_current_float_str(); + case TSDB_DATA_TYPE_BIGINT: + tmp = rand_bigint_str(); + tstrncpy(pstr + dataLen, tmp, BIGINT_BUFF_LEN); + break; + + case TSDB_DATA_TYPE_FLOAT: + if (g_args.demo_mode) { + if (i == 0) { + tmp = demo_current_float_str(); + } else { + tmp = demo_phase_float_str(); + } } else { - tmp = demo_phase_float_str(); + tmp = rand_float_str(); } - } else { - tmp = rand_float_str(); - } - tmpLen = strlen(tmp); - tstrncpy(pstr + dataLen, tmp, min(tmpLen +1, FLOAT_BUFF_LEN)); - } else if (0 == strncasecmp(stbInfo->columns[i].dataType, - "DOUBLE", 6)) { - tmp = rand_double_str(); - tmpLen = strlen(tmp); - tstrncpy(pstr + dataLen, tmp, min(tmpLen +1, DOUBLE_BUFF_LEN)); - } else if (0 == strncasecmp(stbInfo->columns[i].dataType, - "SMALLINT", 8)) { - tmp = rand_smallint_str(); - tmpLen = strlen(tmp); - tstrncpy(pstr + dataLen, tmp, - min(tmpLen + 1, SMALLINT_BUFF_LEN)); - } else if (0 == strncasecmp(stbInfo->columns[i].dataType, - "TINYINT", 7)) { - tmp = rand_tinyint_str(); - tmpLen = strlen(tmp); - tstrncpy(pstr + dataLen, tmp, min(tmpLen +1, TINYINT_BUFF_LEN)); - } else if (0 == strncasecmp(stbInfo->columns[i].dataType, - "BOOL", 4)) { - tmp = rand_bool_str(); - tmpLen = strlen(tmp); - tstrncpy(pstr + dataLen, tmp, min(tmpLen +1, BOOL_BUFF_LEN)); - } else if (0 == strncasecmp(stbInfo->columns[i].dataType, - "TIMESTAMP", 9)) { - tmp = rand_bigint_str(); - tmpLen = strlen(tmp); - tstrncpy(pstr + dataLen, tmp, min(tmpLen +1, BIGINT_BUFF_LEN)); - } else { - errorPrint2("Not support data type: %s\n", - stbInfo->columns[i].dataType); - return -1; + tmpLen = strlen(tmp); + tstrncpy(pstr + dataLen, tmp, min(tmpLen +1, FLOAT_BUFF_LEN)); + break; + + case TSDB_DATA_TYPE_DOUBLE: + tmp = rand_double_str(); + tmpLen = strlen(tmp); + tstrncpy(pstr + dataLen, tmp, min(tmpLen +1, DOUBLE_BUFF_LEN)); + break; + + case TSDB_DATA_TYPE_SMALLINT: + tmp = rand_smallint_str(); + tmpLen = strlen(tmp); + tstrncpy(pstr + dataLen, tmp, + min(tmpLen + 1, SMALLINT_BUFF_LEN)); + break; + + case TSDB_DATA_TYPE_TINYINT: + tmp = rand_tinyint_str(); + tmpLen = strlen(tmp); + tstrncpy(pstr + dataLen, tmp, min(tmpLen +1, TINYINT_BUFF_LEN)); + break; + + case TSDB_DATA_TYPE_BOOL: + tmp = rand_bool_str(); + tmpLen = strlen(tmp); + tstrncpy(pstr + dataLen, tmp, min(tmpLen +1, BOOL_BUFF_LEN)); + break; + + case TSDB_DATA_TYPE_TIMESTAMP: + tmp = rand_bigint_str(); + tmpLen = strlen(tmp); + tstrncpy(pstr + dataLen, tmp, min(tmpLen +1, BIGINT_BUFF_LEN)); + break; + + case TSDB_DATA_TYPE_NULL: + break; + + default: + errorPrint2("Not support data type: %s\n", + stbInfo->columns[i].dataType); + exit(EXIT_FAILURE); } - dataLen += strlen(tmp); - tstrncpy(pstr + dataLen, ",", 2); - dataLen += 1; + if (tmp) { + dataLen += strlen(tmp); + } } if (dataLen > (remainderBufLen - (128))) return 0; } - tstrncpy(pstr + dataLen - 1, ")", 2); + tstrncpy(pstr + dataLen, ")", 2); verbosePrint("%s() LN%d, dataLen:%"PRId64"\n", __func__, __LINE__, dataLen); verbosePrint("%s() LN%d, recBuf:\n\t%s\n", __func__, __LINE__, recBuf); @@ -5908,53 +6252,83 @@ static int64_t generateStbRowData( return strlen(recBuf); } -static int64_t generateData(char *recBuf, char **data_type, +static int64_t generateData(char *recBuf, char *data_type, int64_t timestamp, int lenOfBinary) { memset(recBuf, 0, MAX_DATA_SIZE); char *pstr = recBuf; pstr += sprintf(pstr, "(%"PRId64"", timestamp); - int columnCount = g_args.num_of_CPR; + int columnCount = g_args.columnCount; + bool b; + char *s; for (int i = 0; i < columnCount; i++) { - if (strcasecmp(data_type[i % columnCount], "TINYINT") == 0) { - pstr += sprintf(pstr, ",%d", rand_tinyint() ); - } else if (strcasecmp(data_type[i % columnCount], "SMALLINT") == 0) { - pstr += sprintf(pstr, ",%d", rand_smallint()); - } else if (strcasecmp(data_type[i % columnCount], "INT") == 0) { - pstr += sprintf(pstr, ",%d", rand_int()); - } else if (strcasecmp(data_type[i % columnCount], "BIGINT") == 0) { - pstr += sprintf(pstr, ",%"PRId64"", rand_bigint()); - } else if (strcasecmp(data_type[i % columnCount], "TIMESTAMP") == 0) { - pstr += sprintf(pstr, ",%"PRId64"", rand_bigint()); - } else if (strcasecmp(data_type[i % columnCount], "FLOAT") == 0) { - pstr += sprintf(pstr, ",%10.4f", rand_float()); - } else if (strcasecmp(data_type[i % columnCount], "DOUBLE") == 0) { - double t = rand_double(); - pstr += sprintf(pstr, ",%20.8f", t); - } else if (strcasecmp(data_type[i % columnCount], "BOOL") == 0) { - bool b = rand_bool() & 1; - pstr += sprintf(pstr, ",%s", b ? "true" : "false"); - } else if (strcasecmp(data_type[i % columnCount], "BINARY") == 0) { - char *s = malloc(lenOfBinary + 1); - if (s == NULL) { - errorPrint2("%s() LN%d, memory allocation %d bytes failed\n", - __func__, __LINE__, lenOfBinary + 1); - exit(EXIT_FAILURE); - } - rand_string(s, lenOfBinary); - pstr += sprintf(pstr, ",\"%s\"", s); - free(s); - } else if (strcasecmp(data_type[i % columnCount], "NCHAR") == 0) { - char *s = malloc(lenOfBinary + 1); - if (s == NULL) { - errorPrint2("%s() LN%d, memory allocation %d bytes failed\n", - __func__, __LINE__, lenOfBinary + 1); + switch (data_type[i]) { + case TSDB_DATA_TYPE_TINYINT: + pstr += sprintf(pstr, ",%d", rand_tinyint() ); + break; + + case TSDB_DATA_TYPE_SMALLINT: + pstr += sprintf(pstr, ",%d", rand_smallint()); + break; + + case TSDB_DATA_TYPE_INT: + pstr += sprintf(pstr, ",%d", rand_int()); + break; + + case TSDB_DATA_TYPE_BIGINT: + pstr += sprintf(pstr, ",%"PRId64"", rand_bigint()); + break; + + case TSDB_DATA_TYPE_TIMESTAMP: + pstr += sprintf(pstr, ",%"PRId64"", rand_bigint()); + break; + + case TSDB_DATA_TYPE_FLOAT: + pstr += sprintf(pstr, ",%10.4f", rand_float()); + break; + + case TSDB_DATA_TYPE_DOUBLE: + pstr += sprintf(pstr, ",%20.8f", rand_double()); + break; + + case TSDB_DATA_TYPE_BOOL: + b = rand_bool() & 1; + pstr += sprintf(pstr, ",%s", b ? "true" : "false"); + break; + + case TSDB_DATA_TYPE_BINARY: + s = malloc(lenOfBinary + 1); + if (s == NULL) { + errorPrint2("%s() LN%d, memory allocation %d bytes failed\n", + __func__, __LINE__, lenOfBinary + 1); + exit(EXIT_FAILURE); + } + rand_string(s, lenOfBinary); + pstr += sprintf(pstr, ",\"%s\"", s); + free(s); + break; + + case TSDB_DATA_TYPE_NCHAR: + s = malloc(lenOfBinary + 1); + if (s == NULL) { + errorPrint2("%s() LN%d, memory allocation %d bytes failed\n", + __func__, __LINE__, lenOfBinary + 1); + exit(EXIT_FAILURE); + } + rand_string(s, lenOfBinary); + pstr += sprintf(pstr, ",\"%s\"", s); + free(s); + break; + + case TSDB_DATA_TYPE_NULL: + break; + + default: + errorPrint2("%s() LN%d, Unknown data type %d\n", + __func__, __LINE__, + data_type[i]); exit(EXIT_FAILURE); - } - rand_string(s, lenOfBinary); - pstr += sprintf(pstr, ",\"%s\"", s); - free(s); } if (strlen(recBuf) > MAX_DATA_SIZE) { @@ -5969,97 +6343,160 @@ static int64_t generateData(char *recBuf, char **data_type, return (int32_t)strlen(recBuf); } -static int generateSampleMemoryFromRand(SSuperTable *stbInfo) +static int generateSampleFromRand( + char *sampleDataBuf, + uint64_t lenOfOneRow, + int columnCount, + StrColumn *columns + ) { char data[MAX_DATA_SIZE]; memset(data, 0, MAX_DATA_SIZE); - char *buff = malloc(stbInfo->lenOfOneRow); + char *buff = malloc(lenOfOneRow); if (NULL == buff) { - errorPrint2("%s() LN%d, memory allocation %"PRId64" bytes failed\n", - __func__, __LINE__, stbInfo->lenOfOneRow); + errorPrint2("%s() LN%d, memory allocation %"PRIu64" bytes failed\n", + __func__, __LINE__, lenOfOneRow); exit(EXIT_FAILURE); } - for (int i=0; i < MAX_SAMPLES_ONCE_FROM_FILE; i++) { + for (int i=0; i < MAX_SAMPLES; i++) { uint64_t pos = 0; - memset(buff, 0, stbInfo->lenOfOneRow); + memset(buff, 0, lenOfOneRow); - for (int c = 0; c < stbInfo->columnCount; c++) { - char *tmp; - if (0 == strncasecmp(stbInfo->columns[c].dataType, - "BINARY", strlen("BINARY"))) { - rand_string(data, stbInfo->columns[c].dataLen); - pos += sprintf(buff + pos, "%s,", data); - } else if (0 == strncasecmp(stbInfo->columns[c].dataType, - "NCHAR", strlen("NCHAR"))) { - rand_string(data, stbInfo->columns[c].dataLen); - pos += sprintf(buff + pos, "%s,", data); - } else if (0 == strncasecmp(stbInfo->columns[c].dataType, - "INT", strlen("INT"))) { - if ((g_args.demo_mode) && (c == 1)) { - tmp = demo_voltage_int_str(); - } else { - tmp = rand_int_str(); - } - pos += sprintf(buff + pos, "%s,", tmp); - } else if (0 == strncasecmp(stbInfo->columns[c].dataType, - "BIGINT", strlen("BIGINT"))) { - pos += sprintf(buff + pos, "%s,", rand_bigint_str()); - } else if (0 == strncasecmp(stbInfo->columns[c].dataType, - "FLOAT", strlen("FLOAT"))) { - if (g_args.demo_mode) { - if (c == 0) { - tmp = demo_current_float_str(); + for (int c = 0; c < columnCount; c++) { + char *tmp = NULL; + + uint32_t dataLen; + char data_type = (columns)?(columns[c].data_type):g_args.data_type[c]; + + switch(data_type) { + case TSDB_DATA_TYPE_BINARY: + dataLen = (columns)?columns[c].dataLen:g_args.binwidth; + rand_string(data, dataLen); + pos += sprintf(buff + pos, "%s,", data); + break; + + case TSDB_DATA_TYPE_NCHAR: + dataLen = (columns)?columns[c].dataLen:g_args.binwidth; + rand_string(data, dataLen); + pos += sprintf(buff + pos, "%s,", data); + break; + + case TSDB_DATA_TYPE_INT: + if ((g_args.demo_mode) && (c == 1)) { + tmp = demo_voltage_int_str(); } else { - tmp = demo_phase_float_str(); + tmp = rand_int_str(); } - } else { - tmp = rand_float_str(); - } - pos += sprintf(buff + pos, "%s,", tmp); - } else if (0 == strncasecmp(stbInfo->columns[c].dataType, - "DOUBLE", strlen("DOUBLE"))) { - pos += sprintf(buff + pos, "%s,", rand_double_str()); - } else if (0 == strncasecmp(stbInfo->columns[c].dataType, - "SMALLINT", strlen("SMALLINT"))) { - pos += sprintf(buff + pos, "%s,", rand_smallint_str()); - } else if (0 == strncasecmp(stbInfo->columns[c].dataType, - "TINYINT", strlen("TINYINT"))) { - pos += sprintf(buff + pos, "%s,", rand_tinyint_str()); - } else if (0 == strncasecmp(stbInfo->columns[c].dataType, - "BOOL", strlen("BOOL"))) { - pos += sprintf(buff + pos, "%s,", rand_bool_str()); - } else if (0 == strncasecmp(stbInfo->columns[c].dataType, - "TIMESTAMP", strlen("TIMESTAMP"))) { - pos += sprintf(buff + pos, "%s,", rand_bigint_str()); + pos += sprintf(buff + pos, "%s,", tmp); + break; + + case TSDB_DATA_TYPE_BIGINT: + pos += sprintf(buff + pos, "%s,", rand_bigint_str()); + break; + + case TSDB_DATA_TYPE_FLOAT: + if (g_args.demo_mode) { + if (c == 0) { + tmp = demo_current_float_str(); + } else { + tmp = demo_phase_float_str(); + } + } else { + tmp = rand_float_str(); + } + pos += sprintf(buff + pos, "%s,", tmp); + break; + + case TSDB_DATA_TYPE_DOUBLE: + pos += sprintf(buff + pos, "%s,", rand_double_str()); + break; + + case TSDB_DATA_TYPE_SMALLINT: + pos += sprintf(buff + pos, "%s,", rand_smallint_str()); + break; + + case TSDB_DATA_TYPE_TINYINT: + pos += sprintf(buff + pos, "%s,", rand_tinyint_str()); + break; + + case TSDB_DATA_TYPE_BOOL: + pos += sprintf(buff + pos, "%s,", rand_bool_str()); + break; + + case TSDB_DATA_TYPE_TIMESTAMP: + pos += sprintf(buff + pos, "%s,", rand_bigint_str()); + break; + + case TSDB_DATA_TYPE_NULL: + break; + + default: + errorPrint2("%s() LN%d, Unknown data type %s\n", + __func__, __LINE__, + (columns)?(columns[c].dataType):g_args.dataType[c]); + exit(EXIT_FAILURE); } } + *(buff + pos - 1) = 0; - memcpy(stbInfo->sampleDataBuf + i * stbInfo->lenOfOneRow, buff, pos); + memcpy(sampleDataBuf + i * lenOfOneRow, buff, pos); } free(buff); return 0; } -static int prepareSampleDataForSTable(SSuperTable *stbInfo) { +static int generateSampleFromRandForNtb() +{ + return generateSampleFromRand( + g_sampleDataBuf, + g_args.lenOfOneRow, + g_args.columnCount, + NULL); +} + +static int generateSampleFromRandForStb(SSuperTable *stbInfo) +{ + return generateSampleFromRand( + stbInfo->sampleDataBuf, + stbInfo->lenOfOneRow, + stbInfo->columnCount, + stbInfo->columns); +} + +static int prepareSampleForNtb() { + g_sampleDataBuf = calloc(g_args.lenOfOneRow * MAX_SAMPLES, 1); + if (NULL == g_sampleDataBuf) { + errorPrint2("%s() LN%d, Failed to calloc %"PRIu64" Bytes, reason:%s\n", + __func__, __LINE__, + g_args.lenOfOneRow * MAX_SAMPLES, + strerror(errno)); + return -1; + } + + return generateSampleFromRandForNtb(); +} + +static int prepareSampleForStb(SSuperTable *stbInfo) { stbInfo->sampleDataBuf = calloc( - stbInfo->lenOfOneRow * MAX_SAMPLES_ONCE_FROM_FILE, 1); + stbInfo->lenOfOneRow * MAX_SAMPLES, 1); if (NULL == stbInfo->sampleDataBuf) { errorPrint2("%s() LN%d, Failed to calloc %"PRIu64" Bytes, reason:%s\n", __func__, __LINE__, - stbInfo->lenOfOneRow * MAX_SAMPLES_ONCE_FROM_FILE, + stbInfo->lenOfOneRow * MAX_SAMPLES, strerror(errno)); return -1; } int ret; - if (0 == strncasecmp(stbInfo->dataSource, "sample", strlen("sample"))) - ret = readSampleFromCsvFileToMem(stbInfo); - else - ret = generateSampleMemoryFromRand(stbInfo); + if (0 == strncasecmp(stbInfo->dataSource, "sample", strlen("sample"))) { + ret = generateSampleFromCsvForStb(stbInfo); + } else { + ret = generateSampleFromRandForStb(stbInfo); + } if (0 != ret) { errorPrint2("%s() LN%d, read sample from csv file failed.\n", @@ -6184,7 +6621,7 @@ static int32_t generateDataTailWithoutStb( int64_t retLen = 0; - char **data_type = g_args.datatype; + char *data_type = g_args.data_type; int lenOfBinary = g_args.binwidth; if (g_args.disorderRatio) { @@ -6370,7 +6807,7 @@ static int generateStbSQLHead( dbName, tableName, dbName, - stbInfo->sTblName, + stbInfo->stbName, tagsValBuf); tmfree(tagsValBuf); } else if (TBL_ALREADY_EXISTS == stbInfo->childTblExists) { @@ -6502,202 +6939,224 @@ static int64_t generateInterlaceDataWithoutStb( static int32_t prepareStmtBindArrayByType( TAOS_BIND *bind, - char *dataType, int32_t dataLen, + char data_type, int32_t dataLen, int32_t timePrec, char *value) { - if (0 == strncasecmp(dataType, - "BINARY", strlen("BINARY"))) { - if (dataLen > TSDB_MAX_BINARY_LEN) { - errorPrint2("binary length overflow, max size:%u\n", - (uint32_t)TSDB_MAX_BINARY_LEN); - return -1; - } - char *bind_binary; + int32_t *bind_int; + int64_t *bind_bigint; + float *bind_float; + double *bind_double; + int8_t *bind_bool; + int64_t *bind_ts2; + int16_t *bind_smallint; + int8_t *bind_tinyint; + + switch(data_type) { + case TSDB_DATA_TYPE_BINARY: + if (dataLen > TSDB_MAX_BINARY_LEN) { + errorPrint2("binary length overflow, max size:%u\n", + (uint32_t)TSDB_MAX_BINARY_LEN); + return -1; + } + char *bind_binary; - bind->buffer_type = TSDB_DATA_TYPE_BINARY; - if (value) { - bind_binary = calloc(1, strlen(value) + 1); - strncpy(bind_binary, value, strlen(value)); - bind->buffer_length = strlen(bind_binary); - } else { - bind_binary = calloc(1, dataLen + 1); - rand_string(bind_binary, dataLen); - bind->buffer_length = dataLen; - } + bind->buffer_type = TSDB_DATA_TYPE_BINARY; + if (value) { + bind_binary = calloc(1, strlen(value) + 1); + strncpy(bind_binary, value, strlen(value)); + bind->buffer_length = strlen(bind_binary); + } else { + bind_binary = calloc(1, dataLen + 1); + rand_string(bind_binary, dataLen); + bind->buffer_length = dataLen; + } - bind->length = &bind->buffer_length; - bind->buffer = bind_binary; - bind->is_null = NULL; - } else if (0 == strncasecmp(dataType, - "NCHAR", strlen("NCHAR"))) { - if (dataLen > TSDB_MAX_BINARY_LEN) { - errorPrint2("nchar length overflow, max size:%u\n", - (uint32_t)TSDB_MAX_BINARY_LEN); - return -1; - } - char *bind_nchar; + bind->length = &bind->buffer_length; + bind->buffer = bind_binary; + bind->is_null = NULL; + break; - bind->buffer_type = TSDB_DATA_TYPE_NCHAR; - if (value) { - bind_nchar = calloc(1, strlen(value) + 1); - strncpy(bind_nchar, value, strlen(value)); - } else { - bind_nchar = calloc(1, dataLen + 1); - rand_string(bind_nchar, dataLen); - } + case TSDB_DATA_TYPE_NCHAR: + if (dataLen > TSDB_MAX_BINARY_LEN) { + errorPrint2("nchar length overflow, max size:%u\n", + (uint32_t)TSDB_MAX_BINARY_LEN); + return -1; + } + char *bind_nchar; - bind->buffer_length = strlen(bind_nchar); - bind->buffer = bind_nchar; - bind->length = &bind->buffer_length; - bind->is_null = NULL; - } else if (0 == strncasecmp(dataType, - "INT", strlen("INT"))) { - int32_t *bind_int = malloc(sizeof(int32_t)); - assert(bind_int); + bind->buffer_type = TSDB_DATA_TYPE_NCHAR; + if (value) { + bind_nchar = calloc(1, strlen(value) + 1); + strncpy(bind_nchar, value, strlen(value)); + } else { + bind_nchar = calloc(1, dataLen + 1); + rand_string(bind_nchar, dataLen); + } - if (value) { - *bind_int = atoi(value); - } else { - *bind_int = rand_int(); - } - bind->buffer_type = TSDB_DATA_TYPE_INT; - bind->buffer_length = sizeof(int32_t); - bind->buffer = bind_int; - bind->length = &bind->buffer_length; - bind->is_null = NULL; - } else if (0 == strncasecmp(dataType, - "BIGINT", strlen("BIGINT"))) { - int64_t *bind_bigint = malloc(sizeof(int64_t)); - assert(bind_bigint); + bind->buffer_length = strlen(bind_nchar); + bind->buffer = bind_nchar; + bind->length = &bind->buffer_length; + bind->is_null = NULL; + break; - if (value) { - *bind_bigint = atoll(value); - } else { - *bind_bigint = rand_bigint(); - } - bind->buffer_type = TSDB_DATA_TYPE_BIGINT; - bind->buffer_length = sizeof(int64_t); - bind->buffer = bind_bigint; - bind->length = &bind->buffer_length; - bind->is_null = NULL; - } else if (0 == strncasecmp(dataType, - "FLOAT", strlen("FLOAT"))) { - float *bind_float = malloc(sizeof(float)); - assert(bind_float); + case TSDB_DATA_TYPE_INT: + bind_int = malloc(sizeof(int32_t)); + assert(bind_int); - if (value) { - *bind_float = (float)atof(value); - } else { - *bind_float = rand_float(); - } - bind->buffer_type = TSDB_DATA_TYPE_FLOAT; - bind->buffer_length = sizeof(float); - bind->buffer = bind_float; - bind->length = &bind->buffer_length; - bind->is_null = NULL; - } else if (0 == strncasecmp(dataType, - "DOUBLE", strlen("DOUBLE"))) { - double *bind_double = malloc(sizeof(double)); - assert(bind_double); + if (value) { + *bind_int = atoi(value); + } else { + *bind_int = rand_int(); + } + bind->buffer_type = TSDB_DATA_TYPE_INT; + bind->buffer_length = sizeof(int32_t); + bind->buffer = bind_int; + bind->length = &bind->buffer_length; + bind->is_null = NULL; + break; - if (value) { - *bind_double = atof(value); - } else { - *bind_double = rand_double(); - } - bind->buffer_type = TSDB_DATA_TYPE_DOUBLE; - bind->buffer_length = sizeof(double); - bind->buffer = bind_double; - bind->length = &bind->buffer_length; - bind->is_null = NULL; - } else if (0 == strncasecmp(dataType, - "SMALLINT", strlen("SMALLINT"))) { - int16_t *bind_smallint = malloc(sizeof(int16_t)); - assert(bind_smallint); + case TSDB_DATA_TYPE_BIGINT: + bind_bigint = malloc(sizeof(int64_t)); + assert(bind_bigint); - if (value) { - *bind_smallint = (int16_t)atoi(value); - } else { - *bind_smallint = rand_smallint(); - } - bind->buffer_type = TSDB_DATA_TYPE_SMALLINT; - bind->buffer_length = sizeof(int16_t); - bind->buffer = bind_smallint; - bind->length = &bind->buffer_length; - bind->is_null = NULL; - } else if (0 == strncasecmp(dataType, - "TINYINT", strlen("TINYINT"))) { - int8_t *bind_tinyint = malloc(sizeof(int8_t)); - assert(bind_tinyint); + if (value) { + *bind_bigint = atoll(value); + } else { + *bind_bigint = rand_bigint(); + } + bind->buffer_type = TSDB_DATA_TYPE_BIGINT; + bind->buffer_length = sizeof(int64_t); + bind->buffer = bind_bigint; + bind->length = &bind->buffer_length; + bind->is_null = NULL; + break; - if (value) { - *bind_tinyint = (int8_t)atoi(value); - } else { - *bind_tinyint = rand_tinyint(); - } - bind->buffer_type = TSDB_DATA_TYPE_TINYINT; - bind->buffer_length = sizeof(int8_t); - bind->buffer = bind_tinyint; - bind->length = &bind->buffer_length; - bind->is_null = NULL; - } else if (0 == strncasecmp(dataType, - "BOOL", strlen("BOOL"))) { - int8_t *bind_bool = malloc(sizeof(int8_t)); - assert(bind_bool); - - if (value) { - if (strncasecmp(value, "true", 4)) { - *bind_bool = true; + case TSDB_DATA_TYPE_FLOAT: + bind_float = malloc(sizeof(float)); + assert(bind_float); + + if (value) { + *bind_float = (float)atof(value); } else { - *bind_bool = false; + *bind_float = rand_float(); } - } else { - *bind_bool = rand_bool(); - } - bind->buffer_type = TSDB_DATA_TYPE_BOOL; - bind->buffer_length = sizeof(int8_t); - bind->buffer = bind_bool; - bind->length = &bind->buffer_length; - bind->is_null = NULL; + bind->buffer_type = TSDB_DATA_TYPE_FLOAT; + bind->buffer_length = sizeof(float); + bind->buffer = bind_float; + bind->length = &bind->buffer_length; + bind->is_null = NULL; + break; + + case TSDB_DATA_TYPE_DOUBLE: + bind_double = malloc(sizeof(double)); + assert(bind_double); + + if (value) { + *bind_double = atof(value); + } else { + *bind_double = rand_double(); + } + bind->buffer_type = TSDB_DATA_TYPE_DOUBLE; + bind->buffer_length = sizeof(double); + bind->buffer = bind_double; + bind->length = &bind->buffer_length; + bind->is_null = NULL; + break; - } else if (0 == strncasecmp(dataType, - "TIMESTAMP", strlen("TIMESTAMP"))) { - int64_t *bind_ts2 = malloc(sizeof(int64_t)); - assert(bind_ts2); - - if (value) { - if (strchr(value, ':') && strchr(value, '-')) { - int i = 0; - while(value[i] != '\0') { - if (value[i] == '\"' || value[i] == '\'') { - value[i] = ' '; + case TSDB_DATA_TYPE_SMALLINT: + bind_smallint = malloc(sizeof(int16_t)); + assert(bind_smallint); + + if (value) { + *bind_smallint = (int16_t)atoi(value); + } else { + *bind_smallint = rand_smallint(); + } + bind->buffer_type = TSDB_DATA_TYPE_SMALLINT; + bind->buffer_length = sizeof(int16_t); + bind->buffer = bind_smallint; + bind->length = &bind->buffer_length; + bind->is_null = NULL; + break; + + case TSDB_DATA_TYPE_TINYINT: + bind_tinyint = malloc(sizeof(int8_t)); + assert(bind_tinyint); + + if (value) { + *bind_tinyint = (int8_t)atoi(value); + } else { + *bind_tinyint = rand_tinyint(); + } + bind->buffer_type = TSDB_DATA_TYPE_TINYINT; + bind->buffer_length = sizeof(int8_t); + bind->buffer = bind_tinyint; + bind->length = &bind->buffer_length; + bind->is_null = NULL; + break; + + case TSDB_DATA_TYPE_BOOL: + bind_bool = malloc(sizeof(int8_t)); + assert(bind_bool); + + if (value) { + if (strncasecmp(value, "true", 4)) { + *bind_bool = true; + } else { + *bind_bool = false; + } + } else { + *bind_bool = rand_bool(); + } + bind->buffer_type = TSDB_DATA_TYPE_BOOL; + bind->buffer_length = sizeof(int8_t); + bind->buffer = bind_bool; + bind->length = &bind->buffer_length; + bind->is_null = NULL; + break; + + case TSDB_DATA_TYPE_TIMESTAMP: + bind_ts2 = malloc(sizeof(int64_t)); + assert(bind_ts2); + + if (value) { + if (strchr(value, ':') && strchr(value, '-')) { + int i = 0; + while(value[i] != '\0') { + if (value[i] == '\"' || value[i] == '\'') { + value[i] = ' '; + } + i++; } - i++; - } - int64_t tmpEpoch; - if (TSDB_CODE_SUCCESS != taosParseTime( - value, &tmpEpoch, strlen(value), - timePrec, 0)) { - free(bind_ts2); - errorPrint2("Input %s, time format error!\n", value); - return -1; + int64_t tmpEpoch; + if (TSDB_CODE_SUCCESS != taosParseTime( + value, &tmpEpoch, strlen(value), + timePrec, 0)) { + free(bind_ts2); + errorPrint2("Input %s, time format error!\n", value); + return -1; + } + *bind_ts2 = tmpEpoch; + } else { + *bind_ts2 = atoll(value); } - *bind_ts2 = tmpEpoch; } else { - *bind_ts2 = atoll(value); + *bind_ts2 = rand_bigint(); } - } else { - *bind_ts2 = rand_bigint(); - } - bind->buffer_type = TSDB_DATA_TYPE_TIMESTAMP; - bind->buffer_length = sizeof(int64_t); - bind->buffer = bind_ts2; - bind->length = &bind->buffer_length; - bind->is_null = NULL; - } else { - errorPrint2("Not support data type: %s\n", dataType); - return -1; + bind->buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + bind->buffer_length = sizeof(int64_t); + bind->buffer = bind_ts2; + bind->length = &bind->buffer_length; + bind->is_null = NULL; + break; + + case TSDB_DATA_TYPE_NULL: + break; + + default: + errorPrint2("Not support data type: %d\n", data_type); + exit(EXIT_FAILURE); } return 0; @@ -6705,209 +7164,230 @@ static int32_t prepareStmtBindArrayByType( static int32_t prepareStmtBindArrayByTypeForRand( TAOS_BIND *bind, - char *dataType, int32_t dataLen, + char data_type, int32_t dataLen, int32_t timePrec, char **ptr, char *value) { - if (0 == strncasecmp(dataType, - "BINARY", strlen("BINARY"))) { - if (dataLen > TSDB_MAX_BINARY_LEN) { - errorPrint2("binary length overflow, max size:%u\n", - (uint32_t)TSDB_MAX_BINARY_LEN); - return -1; - } - char *bind_binary = (char *)*ptr; + int32_t *bind_int; + int64_t *bind_bigint; + float *bind_float; + double *bind_double; + int16_t *bind_smallint; + int8_t *bind_tinyint; + int8_t *bind_bool; + int64_t *bind_ts2; + + switch(data_type) { + case TSDB_DATA_TYPE_BINARY: - bind->buffer_type = TSDB_DATA_TYPE_BINARY; - if (value) { - strncpy(bind_binary, value, strlen(value)); - bind->buffer_length = strlen(bind_binary); - } else { - rand_string(bind_binary, dataLen); - bind->buffer_length = dataLen; - } + if (dataLen > TSDB_MAX_BINARY_LEN) { + errorPrint2("binary length overflow, max size:%u\n", + (uint32_t)TSDB_MAX_BINARY_LEN); + return -1; + } + char *bind_binary = (char *)*ptr; - bind->length = &bind->buffer_length; - bind->buffer = bind_binary; - bind->is_null = NULL; + bind->buffer_type = TSDB_DATA_TYPE_BINARY; + if (value) { + strncpy(bind_binary, value, strlen(value)); + bind->buffer_length = strlen(bind_binary); + } else { + rand_string(bind_binary, dataLen); + bind->buffer_length = dataLen; + } - *ptr += bind->buffer_length; - } else if (0 == strncasecmp(dataType, - "NCHAR", strlen("NCHAR"))) { - if (dataLen > TSDB_MAX_BINARY_LEN) { - errorPrint2("nchar length overflow, max size: %u\n", - (uint32_t)TSDB_MAX_BINARY_LEN); - return -1; - } - char *bind_nchar = (char *)*ptr; + bind->length = &bind->buffer_length; + bind->buffer = bind_binary; + bind->is_null = NULL; - bind->buffer_type = TSDB_DATA_TYPE_NCHAR; - if (value) { - strncpy(bind_nchar, value, strlen(value)); - } else { - rand_string(bind_nchar, dataLen); - } + *ptr += bind->buffer_length; + break; - bind->buffer_length = strlen(bind_nchar); - bind->buffer = bind_nchar; - bind->length = &bind->buffer_length; - bind->is_null = NULL; + case TSDB_DATA_TYPE_NCHAR: + if (dataLen > TSDB_MAX_BINARY_LEN) { + errorPrint2("nchar length overflow, max size: %u\n", + (uint32_t)TSDB_MAX_BINARY_LEN); + return -1; + } + char *bind_nchar = (char *)*ptr; - *ptr += bind->buffer_length; - } else if (0 == strncasecmp(dataType, - "INT", strlen("INT"))) { - int32_t *bind_int = (int32_t *)*ptr; + bind->buffer_type = TSDB_DATA_TYPE_NCHAR; + if (value) { + strncpy(bind_nchar, value, strlen(value)); + } else { + rand_string(bind_nchar, dataLen); + } - if (value) { - *bind_int = atoi(value); - } else { - *bind_int = rand_int(); - } - bind->buffer_type = TSDB_DATA_TYPE_INT; - bind->buffer_length = sizeof(int32_t); - bind->buffer = bind_int; - bind->length = &bind->buffer_length; - bind->is_null = NULL; + bind->buffer_length = strlen(bind_nchar); + bind->buffer = bind_nchar; + bind->length = &bind->buffer_length; + bind->is_null = NULL; - *ptr += bind->buffer_length; - } else if (0 == strncasecmp(dataType, - "BIGINT", strlen("BIGINT"))) { - int64_t *bind_bigint = (int64_t *)*ptr; + *ptr += bind->buffer_length; + break; - if (value) { - *bind_bigint = atoll(value); - } else { - *bind_bigint = rand_bigint(); - } - bind->buffer_type = TSDB_DATA_TYPE_BIGINT; - bind->buffer_length = sizeof(int64_t); - bind->buffer = bind_bigint; - bind->length = &bind->buffer_length; - bind->is_null = NULL; + case TSDB_DATA_TYPE_INT: + bind_int = (int32_t *)*ptr; - *ptr += bind->buffer_length; - } else if (0 == strncasecmp(dataType, - "FLOAT", strlen("FLOAT"))) { - float *bind_float = (float *)*ptr; + if (value) { + *bind_int = atoi(value); + } else { + *bind_int = rand_int(); + } + bind->buffer_type = TSDB_DATA_TYPE_INT; + bind->buffer_length = sizeof(int32_t); + bind->buffer = bind_int; + bind->length = &bind->buffer_length; + bind->is_null = NULL; - if (value) { - *bind_float = (float)atof(value); - } else { - *bind_float = rand_float(); - } - bind->buffer_type = TSDB_DATA_TYPE_FLOAT; - bind->buffer_length = sizeof(float); - bind->buffer = bind_float; - bind->length = &bind->buffer_length; - bind->is_null = NULL; + *ptr += bind->buffer_length; + break; - *ptr += bind->buffer_length; - } else if (0 == strncasecmp(dataType, - "DOUBLE", strlen("DOUBLE"))) { - double *bind_double = (double *)*ptr; + case TSDB_DATA_TYPE_BIGINT: + bind_bigint = (int64_t *)*ptr; - if (value) { - *bind_double = atof(value); - } else { - *bind_double = rand_double(); - } - bind->buffer_type = TSDB_DATA_TYPE_DOUBLE; - bind->buffer_length = sizeof(double); - bind->buffer = bind_double; - bind->length = &bind->buffer_length; - bind->is_null = NULL; + if (value) { + *bind_bigint = atoll(value); + } else { + *bind_bigint = rand_bigint(); + } + bind->buffer_type = TSDB_DATA_TYPE_BIGINT; + bind->buffer_length = sizeof(int64_t); + bind->buffer = bind_bigint; + bind->length = &bind->buffer_length; + bind->is_null = NULL; - *ptr += bind->buffer_length; - } else if (0 == strncasecmp(dataType, - "SMALLINT", strlen("SMALLINT"))) { - int16_t *bind_smallint = (int16_t *)*ptr; + *ptr += bind->buffer_length; + break; - if (value) { - *bind_smallint = (int16_t)atoi(value); - } else { - *bind_smallint = rand_smallint(); - } - bind->buffer_type = TSDB_DATA_TYPE_SMALLINT; - bind->buffer_length = sizeof(int16_t); - bind->buffer = bind_smallint; - bind->length = &bind->buffer_length; - bind->is_null = NULL; + case TSDB_DATA_TYPE_FLOAT: + bind_float = (float *)*ptr; - *ptr += bind->buffer_length; - } else if (0 == strncasecmp(dataType, - "TINYINT", strlen("TINYINT"))) { - int8_t *bind_tinyint = (int8_t *)*ptr; + if (value) { + *bind_float = (float)atof(value); + } else { + *bind_float = rand_float(); + } + bind->buffer_type = TSDB_DATA_TYPE_FLOAT; + bind->buffer_length = sizeof(float); + bind->buffer = bind_float; + bind->length = &bind->buffer_length; + bind->is_null = NULL; - if (value) { - *bind_tinyint = (int8_t)atoi(value); - } else { - *bind_tinyint = rand_tinyint(); - } - bind->buffer_type = TSDB_DATA_TYPE_TINYINT; - bind->buffer_length = sizeof(int8_t); - bind->buffer = bind_tinyint; - bind->length = &bind->buffer_length; - bind->is_null = NULL; + *ptr += bind->buffer_length; + break; - *ptr += bind->buffer_length; - } else if (0 == strncasecmp(dataType, - "BOOL", strlen("BOOL"))) { - int8_t *bind_bool = (int8_t *)*ptr; + case TSDB_DATA_TYPE_DOUBLE: + bind_double = (double *)*ptr; - if (value) { - if (strncasecmp(value, "true", 4)) { - *bind_bool = true; + if (value) { + *bind_double = atof(value); } else { - *bind_bool = false; + *bind_double = rand_double(); } - } else { - *bind_bool = rand_bool(); - } - bind->buffer_type = TSDB_DATA_TYPE_BOOL; - bind->buffer_length = sizeof(int8_t); - bind->buffer = bind_bool; - bind->length = &bind->buffer_length; - bind->is_null = NULL; + bind->buffer_type = TSDB_DATA_TYPE_DOUBLE; + bind->buffer_length = sizeof(double); + bind->buffer = bind_double; + bind->length = &bind->buffer_length; + bind->is_null = NULL; - *ptr += bind->buffer_length; - } else if (0 == strncasecmp(dataType, - "TIMESTAMP", strlen("TIMESTAMP"))) { - int64_t *bind_ts2 = (int64_t *)*ptr; - - if (value) { - if (strchr(value, ':') && strchr(value, '-')) { - int i = 0; - while(value[i] != '\0') { - if (value[i] == '\"' || value[i] == '\'') { - value[i] = ' '; - } - i++; + *ptr += bind->buffer_length; + break; + + case TSDB_DATA_TYPE_SMALLINT: + bind_smallint = (int16_t *)*ptr; + + if (value) { + *bind_smallint = (int16_t)atoi(value); + } else { + *bind_smallint = rand_smallint(); + } + bind->buffer_type = TSDB_DATA_TYPE_SMALLINT; + bind->buffer_length = sizeof(int16_t); + bind->buffer = bind_smallint; + bind->length = &bind->buffer_length; + bind->is_null = NULL; + + *ptr += bind->buffer_length; + break; + + case TSDB_DATA_TYPE_TINYINT: + bind_tinyint = (int8_t *)*ptr; + + if (value) { + *bind_tinyint = (int8_t)atoi(value); + } else { + *bind_tinyint = rand_tinyint(); + } + bind->buffer_type = TSDB_DATA_TYPE_TINYINT; + bind->buffer_length = sizeof(int8_t); + bind->buffer = bind_tinyint; + bind->length = &bind->buffer_length; + bind->is_null = NULL; + + *ptr += bind->buffer_length; + break; + + case TSDB_DATA_TYPE_BOOL: + bind_bool = (int8_t *)*ptr; + + if (value) { + if (strncasecmp(value, "true", 4)) { + *bind_bool = true; + } else { + *bind_bool = false; } - int64_t tmpEpoch; - if (TSDB_CODE_SUCCESS != taosParseTime( - value, &tmpEpoch, strlen(value), - timePrec, 0)) { - errorPrint2("Input %s, time format error!\n", value); - return -1; + } else { + *bind_bool = rand_bool(); + } + bind->buffer_type = TSDB_DATA_TYPE_BOOL; + bind->buffer_length = sizeof(int8_t); + bind->buffer = bind_bool; + bind->length = &bind->buffer_length; + bind->is_null = NULL; + + *ptr += bind->buffer_length; + break; + + case TSDB_DATA_TYPE_TIMESTAMP: + bind_ts2 = (int64_t *)*ptr; + + if (value) { + if (strchr(value, ':') && strchr(value, '-')) { + int i = 0; + while(value[i] != '\0') { + if (value[i] == '\"' || value[i] == '\'') { + value[i] = ' '; + } + i++; + } + int64_t tmpEpoch; + if (TSDB_CODE_SUCCESS != taosParseTime( + value, &tmpEpoch, strlen(value), + timePrec, 0)) { + errorPrint2("Input %s, time format error!\n", value); + return -1; + } + *bind_ts2 = tmpEpoch; + } else { + *bind_ts2 = atoll(value); } - *bind_ts2 = tmpEpoch; } else { - *bind_ts2 = atoll(value); + *bind_ts2 = rand_bigint(); } - } else { - *bind_ts2 = rand_bigint(); - } - bind->buffer_type = TSDB_DATA_TYPE_TIMESTAMP; - bind->buffer_length = sizeof(int64_t); - bind->buffer = bind_ts2; - bind->length = &bind->buffer_length; - bind->is_null = NULL; + bind->buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + bind->buffer_length = sizeof(int64_t); + bind->buffer = bind_ts2; + bind->length = &bind->buffer_length; + bind->is_null = NULL; - *ptr += bind->buffer_length; - } else { - errorPrint2("No support data type: %s\n", dataType); - return -1; + *ptr += bind->buffer_length; + break; + + default: + errorPrint2("No support data type: %d\n", data_type); + return -1; } return 0; @@ -6929,12 +7409,12 @@ static int32_t prepareStmtWithoutStb( return ret; } - char **data_type = g_args.datatype; + char *data_type = g_args.data_type; - char *bindArray = malloc(sizeof(TAOS_BIND) * (g_args.num_of_CPR + 1)); + char *bindArray = malloc(sizeof(TAOS_BIND) * (g_args.columnCount + 1)); if (bindArray == NULL) { errorPrint2("Failed to allocate %d bind params\n", - (g_args.num_of_CPR + 1)); + (g_args.columnCount + 1)); return -1; } @@ -6961,7 +7441,7 @@ static int32_t prepareStmtWithoutStb( bind->length = &bind->buffer_length; bind->is_null = NULL; - for (int i = 0; i < g_args.num_of_CPR; i ++) { + for (int i = 0; i < g_args.columnCount; i ++) { bind = (TAOS_BIND *)((char *)bindArray + (sizeof(TAOS_BIND) * (i + 1))); if ( -1 == prepareStmtBindArrayByType( @@ -7001,29 +7481,20 @@ static int32_t prepareStbStmtBindTag( char *tagsVal, int32_t timePrec) { - char *bindBuffer = calloc(1, DOUBLE_BUFF_LEN); // g_args.binwidth); - if (bindBuffer == NULL) { - errorPrint2("%s() LN%d, Failed to allocate %d bind buffer\n", - __func__, __LINE__, DOUBLE_BUFF_LEN); - return -1; - } - TAOS_BIND *tag; for (int t = 0; t < stbInfo->tagCount; t ++) { tag = (TAOS_BIND *)((char *)bindArray + (sizeof(TAOS_BIND) * t)); if ( -1 == prepareStmtBindArrayByType( tag, - stbInfo->tags[t].dataType, + stbInfo->tags[t].data_type, stbInfo->tags[t].dataLen, timePrec, NULL)) { - free(bindBuffer); return -1; } } - free(bindBuffer); return 0; } @@ -7033,13 +7504,6 @@ static int32_t prepareStbStmtBindRand( int64_t startTime, int32_t recSeq, int32_t timePrec) { - char *bindBuffer = calloc(1, DOUBLE_BUFF_LEN); // g_args.binwidth); - if (bindBuffer == NULL) { - errorPrint2("%s() LN%d, Failed to allocate %d bind buffer\n", - __func__, __LINE__, DOUBLE_BUFF_LEN); - return -1; - } - char data[MAX_DATA_SIZE]; memset(data, 0, MAX_DATA_SIZE); char *ptr = data; @@ -7069,51 +7533,15 @@ static int32_t prepareStbStmtBindRand( ptr += bind->buffer_length; } else if ( -1 == prepareStmtBindArrayByTypeForRand( bind, - stbInfo->columns[i-1].dataType, + stbInfo->columns[i-1].data_type, stbInfo->columns[i-1].dataLen, timePrec, &ptr, NULL)) { - tmfree(bindBuffer); return -1; } } - tmfree(bindBuffer); - return 0; -} - -static int32_t prepareStbStmtBindStartTime( - char *tableName, - int64_t *ts, - char *bindArray, SSuperTable *stbInfo, - int64_t startTime, int32_t recSeq, - int32_t timePrec) -{ - TAOS_BIND *bind; - - bind = (TAOS_BIND *)bindArray; - - int64_t *bind_ts = ts; - - bind->buffer_type = TSDB_DATA_TYPE_TIMESTAMP; - if (stbInfo->disorderRatio) { - *bind_ts = startTime + getTSRandTail( - stbInfo->timeStampStep, recSeq, - stbInfo->disorderRatio, - stbInfo->disorderRange); - } else { - *bind_ts = startTime + stbInfo->timeStampStep * recSeq; - } - - verbosePrint("%s() LN%d, tableName: %s, bind_ts=%"PRId64"\n", - __func__, __LINE__, tableName, *bind_ts); - - bind->buffer_length = sizeof(int64_t); - bind->buffer = bind_ts; - bind->length = &bind->buffer_length; - bind->is_null = NULL; - return 0; } @@ -7229,7 +7657,8 @@ UNUSED_FUNC static int32_t prepareStbStmtRand( return k; } -static int32_t prepareStbStmtWithSample( +#if STMT_BIND_PARAM_BATCH == 1 +static int execBindParamBatch( threadInfo *pThreadInfo, char *tableName, int64_t tableSeq, @@ -7240,94 +7669,182 @@ static int32_t prepareStbStmtWithSample( int64_t *pSamplePos) { int ret; - SSuperTable *stbInfo = pThreadInfo->stbInfo; TAOS_STMT *stmt = pThreadInfo->stmt; - if (AUTO_CREATE_SUBTBL == stbInfo->autoCreateTable) { - char* tagsValBuf = NULL; + SSuperTable *stbInfo = pThreadInfo->stbInfo; + uint32_t columnCount = (stbInfo)?pThreadInfo->stbInfo->columnCount:g_args.columnCount; + + uint32_t thisBatch = MAX_SAMPLES - (*pSamplePos); + + if (thisBatch > batch) { + thisBatch = batch; + } + verbosePrint("%s() LN%d, batch=%d pos=%"PRId64" thisBatch=%d\n", + __func__, __LINE__, batch, *pSamplePos, thisBatch); + + memset(pThreadInfo->bindParams, 0, + (sizeof(TAOS_MULTI_BIND) * (columnCount + 1))); + memset(pThreadInfo->is_null, 0, thisBatch); + + for (int c = 0; c < columnCount + 1; c ++) { + TAOS_MULTI_BIND *param = (TAOS_MULTI_BIND *)(pThreadInfo->bindParams + sizeof(TAOS_MULTI_BIND) * c); + + char data_type; + + if (c == 0) { + data_type = TSDB_DATA_TYPE_TIMESTAMP; + param->buffer_length = sizeof(int64_t); + param->buffer = pThreadInfo->bind_ts_array; - if (0 == stbInfo->tagSource) { - tagsValBuf = generateTagValuesForStb(stbInfo, tableSeq); } else { - tagsValBuf = getTagValueFromTagSample( - stbInfo, - tableSeq % stbInfo->tagSampleCount); - } + data_type = (stbInfo)?stbInfo->columns[c-1].data_type:g_args.data_type[c-1]; - if (NULL == tagsValBuf) { - errorPrint2("%s() LN%d, tag buf failed to allocate memory\n", - __func__, __LINE__); - return -1; - } + char *tmpP; - char *tagsArray = calloc(1, sizeof(TAOS_BIND) * stbInfo->tagCount); - if (NULL == tagsArray) { - tmfree(tagsValBuf); - errorPrint2("%s() LN%d, tag buf failed to allocate memory\n", - __func__, __LINE__); - return -1; - } + switch(data_type) { + case TSDB_DATA_TYPE_BINARY: + case TSDB_DATA_TYPE_NCHAR: + param->buffer_length = + ((stbInfo)?stbInfo->columns[c-1].dataLen:g_args.binwidth); - if (-1 == prepareStbStmtBindTag( - tagsArray, stbInfo, tagsValBuf, pThreadInfo->time_precision - /* is tag */)) { - tmfree(tagsValBuf); - tmfree(tagsArray); - return -1; - } + tmpP = + (char *)((uintptr_t)*(uintptr_t*)(stbInfo->sampleBindBatchArray + +sizeof(char*)*(c-1))); - ret = taos_stmt_set_tbname_tags(stmt, tableName, (TAOS_BIND *)tagsArray); + verbosePrint("%s() LN%d, tmpP=%p pos=%"PRId64" width=%d position=%"PRId64"\n", + __func__, __LINE__, tmpP, *pSamplePos, + (((stbInfo)?stbInfo->columns[c-1].dataLen:g_args.binwidth)), + (*pSamplePos) * + (((stbInfo)?stbInfo->columns[c-1].dataLen:g_args.binwidth))); - tmfree(tagsValBuf); - tmfree(tagsArray); + param->buffer = (void *)(tmpP + *pSamplePos * + (((stbInfo)?stbInfo->columns[c-1].dataLen:g_args.binwidth)) + ); + break; - if (0 != ret) { - errorPrint2("%s() LN%d, stmt_set_tbname_tags() failed! reason: %s\n", - __func__, __LINE__, taos_stmt_errstr(stmt)); - return -1; + case TSDB_DATA_TYPE_INT: + param->buffer_length = sizeof(int32_t); + param->buffer = (stbInfo)? + (void *)((uintptr_t)*(uintptr_t*)(stbInfo->sampleBindBatchArray+sizeof(char*)*(c-1)) + + stbInfo->columns[c-1].dataLen * (*pSamplePos)): + (void *)((uintptr_t)*(uintptr_t*)(g_sampleBindBatchArray+sizeof(char*)*(c-1)) + + sizeof(int32_t)*(*pSamplePos)); + break; + + case TSDB_DATA_TYPE_TINYINT: + param->buffer_length = sizeof(int8_t); + param->buffer = (stbInfo)? + (void *)((uintptr_t)*(uintptr_t*)( + stbInfo->sampleBindBatchArray + +sizeof(char*)*(c-1)) + + stbInfo->columns[c-1].dataLen*(*pSamplePos)): + (void *)((uintptr_t)*(uintptr_t*)( + g_sampleBindBatchArray+sizeof(char*)*(c-1)) + + sizeof(int8_t)*(*pSamplePos)); + break; + + case TSDB_DATA_TYPE_SMALLINT: + param->buffer_length = sizeof(int16_t); + param->buffer = (stbInfo)? + (void *)((uintptr_t)*(uintptr_t*)(stbInfo->sampleBindBatchArray+sizeof(char*)*(c-1)) + + stbInfo->columns[c-1].dataLen * (*pSamplePos)): + (void *)((uintptr_t)*(uintptr_t*)(g_sampleBindBatchArray+sizeof(char*)*(c-1)) + + sizeof(int16_t)*(*pSamplePos)); + break; + + case TSDB_DATA_TYPE_BIGINT: + param->buffer_length = sizeof(int64_t); + param->buffer = (stbInfo)? + (void *)((uintptr_t)*(uintptr_t*)(stbInfo->sampleBindBatchArray+sizeof(char*)*(c-1)) + + stbInfo->columns[c-1].dataLen * (*pSamplePos)): + (void *)((uintptr_t)*(uintptr_t*)(g_sampleBindBatchArray+sizeof(char*)*(c-1)) + + sizeof(int64_t)*(*pSamplePos)); + break; + + case TSDB_DATA_TYPE_BOOL: + param->buffer_length = sizeof(int8_t); + param->buffer = (stbInfo)? + (void *)((uintptr_t)*(uintptr_t*)(stbInfo->sampleBindBatchArray+sizeof(char*)*(c-1)) + + stbInfo->columns[c-1].dataLen * (*pSamplePos)): + (void *)((uintptr_t)*(uintptr_t*)(g_sampleBindBatchArray+sizeof(char*)*(c-1)) + + sizeof(int8_t)*(*pSamplePos)); + break; + + case TSDB_DATA_TYPE_FLOAT: + param->buffer_length = sizeof(float); + param->buffer = (stbInfo)? + (void *)((uintptr_t)*(uintptr_t*)(stbInfo->sampleBindBatchArray+sizeof(char*)*(c-1)) + + stbInfo->columns[c-1].dataLen * (*pSamplePos)): + (void *)((uintptr_t)*(uintptr_t*)(g_sampleBindBatchArray+sizeof(char*)*(c-1)) + + sizeof(float)*(*pSamplePos)); + break; + + case TSDB_DATA_TYPE_DOUBLE: + param->buffer_length = sizeof(double); + param->buffer = (stbInfo)? + (void *)((uintptr_t)*(uintptr_t*)(stbInfo->sampleBindBatchArray+sizeof(char*)*(c-1)) + + stbInfo->columns[c-1].dataLen * (*pSamplePos)): + (void *)((uintptr_t)*(uintptr_t*)(g_sampleBindBatchArray+sizeof(char*)*(c-1)) + + sizeof(double)*(*pSamplePos)); + break; + + case TSDB_DATA_TYPE_TIMESTAMP: + param->buffer_length = sizeof(int64_t); + param->buffer = (stbInfo)? + (void *)((uintptr_t)*(uintptr_t*)(stbInfo->sampleBindBatchArray+sizeof(char*)*(c-1)) + + stbInfo->columns[c-1].dataLen * (*pSamplePos)): + (void *)((uintptr_t)*(uintptr_t*)(g_sampleBindBatchArray+sizeof(char*)*(c-1)) + + sizeof(int64_t)*(*pSamplePos)); + break; + + default: + errorPrint("%s() LN%d, wrong data type: %d\n", + __func__, + __LINE__, + data_type); + exit(EXIT_FAILURE); + + } } - } else { - ret = taos_stmt_set_tbname(stmt, tableName); - if (0 != ret) { - errorPrint2("%s() LN%d, stmt_set_tbname() failed! reason: %s\n", - __func__, __LINE__, taos_stmt_errstr(stmt)); - return -1; + + param->buffer_type = data_type; + param->length = malloc(sizeof(int32_t) * thisBatch); + assert(param->length); + + for (int b = 0; b < thisBatch; b++) { + if (param->buffer_type == TSDB_DATA_TYPE_NCHAR) { + param->length[b] = strlen( + (char *)param->buffer + b * + ((stbInfo)?stbInfo->columns[c].dataLen:g_args.binwidth) + ); + } else { + param->length[b] = param->buffer_length; + } } + param->is_null = pThreadInfo->is_null; + param->num = thisBatch; } uint32_t k; - for (k = 0; k < batch;) { - char *bindArray = (char *)(*((uintptr_t *) - (pThreadInfo->sampleBindArray + (sizeof(char *)) * (*pSamplePos)))); + for (k = 0; k < thisBatch;) { /* columnCount + 1 (ts) */ - if (-1 == prepareStbStmtBindStartTime( - tableName, - pThreadInfo->bind_ts, - bindArray, stbInfo, - startTime, k, - pThreadInfo->time_precision - /* is column */)) { - return -1; - } - ret = taos_stmt_bind_param(stmt, (TAOS_BIND *)bindArray); - if (0 != ret) { - errorPrint2("%s() LN%d, stmt_bind_param() failed! reason: %s\n", - __func__, __LINE__, taos_stmt_errstr(stmt)); - return -1; - } - // if msg > 3MB, break - ret = taos_stmt_add_batch(stmt); - if (0 != ret) { - errorPrint2("%s() LN%d, stmt_add_batch() failed! reason: %s\n", - __func__, __LINE__, taos_stmt_errstr(stmt)); - return -1; + if (stbInfo->disorderRatio) { + *(pThreadInfo->bind_ts_array + k) = startTime + getTSRandTail( + stbInfo->timeStampStep, k, + stbInfo->disorderRatio, + stbInfo->disorderRange); + } else { + *(pThreadInfo->bind_ts_array + k) = startTime + stbInfo->timeStampStep * k; } + debugPrint("%s() LN%d, k=%d ts=%"PRId64"\n", + __func__, __LINE__, + k, *(pThreadInfo->bind_ts_array +k)); k++; recordFrom ++; (*pSamplePos) ++; - if ((*pSamplePos) == MAX_SAMPLES_ONCE_FROM_FILE) { + if ((*pSamplePos) == MAX_SAMPLES) { *pSamplePos = 0; } @@ -7336,92 +7853,1071 @@ static int32_t prepareStbStmtWithSample( } } + ret = taos_stmt_bind_param_batch(stmt, (TAOS_MULTI_BIND *)pThreadInfo->bindParams); + if (0 != ret) { + errorPrint2("%s() LN%d, stmt_bind_param() failed! reason: %s\n", + __func__, __LINE__, taos_stmt_errstr(stmt)); + return -1; + } + + for (int c = 0; c < stbInfo->columnCount + 1; c ++) { + TAOS_MULTI_BIND *param = (TAOS_MULTI_BIND *)(pThreadInfo->bindParams + sizeof(TAOS_MULTI_BIND) * c); + free(param->length); + } + + // if msg > 3MB, break + ret = taos_stmt_add_batch(stmt); + if (0 != ret) { + errorPrint2("%s() LN%d, stmt_add_batch() failed! reason: %s\n", + __func__, __LINE__, taos_stmt_errstr(stmt)); + return -1; + } return k; } -static int32_t generateStbProgressiveData( - SSuperTable *stbInfo, - char *tableName, - int64_t tableSeq, - char *dbName, char *buffer, - int64_t insertRows, - uint64_t recordFrom, int64_t startTime, int64_t *pSamplePos, - int64_t *pRemainderBufLen) +static int parseSamplefileToStmtBatch( + SSuperTable* stbInfo) { - assert(buffer != NULL); - char *pstr = buffer; + // char *sampleDataBuf = (stbInfo)? + // stbInfo->sampleDataBuf:g_sampleDataBuf; + int32_t columnCount = (stbInfo)?stbInfo->columnCount:g_args.columnCount; + char *sampleBindBatchArray = NULL; - memset(pstr, 0, *pRemainderBufLen); + if (stbInfo) { + stbInfo->sampleBindBatchArray = calloc(1, sizeof(uintptr_t *) * columnCount); + sampleBindBatchArray = stbInfo->sampleBindBatchArray; + } else { + g_sampleBindBatchArray = calloc(1, sizeof(uintptr_t *) * columnCount); + sampleBindBatchArray = g_sampleBindBatchArray; + } + assert(sampleBindBatchArray); - int64_t headLen = generateStbSQLHead( - stbInfo, - tableName, tableSeq, dbName, - buffer, *pRemainderBufLen); + for (int c = 0; c < columnCount; c++) { + char data_type = (stbInfo)?stbInfo->columns[c].data_type:g_args.data_type[c]; + + char *tmpP = NULL; + + switch(data_type) { + case TSDB_DATA_TYPE_INT: + tmpP = calloc(1, sizeof(int) * MAX_SAMPLES); + assert(tmpP); + *(uintptr_t*)(sampleBindBatchArray+ sizeof(uintptr_t*)*c) = (uintptr_t)tmpP; + break; + + case TSDB_DATA_TYPE_TINYINT: + tmpP = calloc(1, sizeof(int8_t) * MAX_SAMPLES); + assert(tmpP); + *(uintptr_t*)(sampleBindBatchArray+ sizeof(uintptr_t*)*c) = (uintptr_t)tmpP; + break; + + case TSDB_DATA_TYPE_SMALLINT: + tmpP = calloc(1, sizeof(int16_t) * MAX_SAMPLES); + assert(tmpP); + *(uintptr_t*)(sampleBindBatchArray+ sizeof(uintptr_t*)*c) = (uintptr_t)tmpP; + break; + + case TSDB_DATA_TYPE_BIGINT: + tmpP = calloc(1, sizeof(int64_t) * MAX_SAMPLES); + assert(tmpP); + *(uintptr_t*)(sampleBindBatchArray+ sizeof(uintptr_t*)*c) = (uintptr_t)tmpP; + break; + + case TSDB_DATA_TYPE_BOOL: + tmpP = calloc(1, sizeof(int8_t) * MAX_SAMPLES); + assert(tmpP); + *(uintptr_t*)(sampleBindBatchArray+ sizeof(uintptr_t*)*c) = (uintptr_t)tmpP; + break; + + case TSDB_DATA_TYPE_FLOAT: + tmpP = calloc(1, sizeof(float) * MAX_SAMPLES); + assert(tmpP); + *(uintptr_t*)(sampleBindBatchArray+ sizeof(uintptr_t*)*c) = (uintptr_t)tmpP; + break; + + case TSDB_DATA_TYPE_DOUBLE: + tmpP = calloc(1, sizeof(double) * MAX_SAMPLES); + assert(tmpP); + *(uintptr_t*)(sampleBindBatchArray+ sizeof(uintptr_t*)*c) = (uintptr_t)tmpP; + break; + + case TSDB_DATA_TYPE_BINARY: + case TSDB_DATA_TYPE_NCHAR: + tmpP = calloc(1, MAX_SAMPLES * + (((stbInfo)?stbInfo->columns[c].dataLen:g_args.binwidth))); + assert(tmpP); + *(uintptr_t*)(sampleBindBatchArray+ sizeof(uintptr_t*)*c) = (uintptr_t)tmpP; + break; + + case TSDB_DATA_TYPE_TIMESTAMP: + tmpP = calloc(1, sizeof(int64_t) * MAX_SAMPLES); + assert(tmpP); + *(uintptr_t*)(sampleBindBatchArray+ sizeof(uintptr_t*)*c) = (uintptr_t)tmpP; + break; + + default: + errorPrint("Unknown data type: %s\n", + (stbInfo)?stbInfo->columns[c].dataType:g_args.dataType[c]); + exit(EXIT_FAILURE); + } + } + + char *sampleDataBuf = (stbInfo)?stbInfo->sampleDataBuf:g_sampleDataBuf; + int64_t lenOfOneRow = (stbInfo)?stbInfo->lenOfOneRow:g_args.lenOfOneRow; + + for (int i=0; i < MAX_SAMPLES; i++) { + int cursor = 0; + + for (int c = 0; c < columnCount; c++) { + char data_type = (stbInfo)? + stbInfo->columns[c].data_type: + g_args.data_type[c]; + char *restStr = sampleDataBuf + + lenOfOneRow * i + cursor; + int lengthOfRest = strlen(restStr); + + int index = 0; + for (index = 0; index < lengthOfRest; index ++) { + if (restStr[index] == ',') { + break; + } + } + + char *tmpStr = calloc(1, index + 1); + if (NULL == tmpStr) { + errorPrint2("%s() LN%d, Failed to allocate %d bind buffer\n", + __func__, __LINE__, index + 1); + return -1; + } + + strncpy(tmpStr, restStr, index); + cursor += index + 1; // skip ',' too + char *tmpP; + + switch(data_type) { + case TSDB_DATA_TYPE_INT: + *((int32_t*)((uintptr_t)*(uintptr_t*)(sampleBindBatchArray + +sizeof(char*)*c)+sizeof(int32_t)*i)) = + atoi(tmpStr); + break; + + case TSDB_DATA_TYPE_FLOAT: + *(float*)(((uintptr_t)*(uintptr_t*)(sampleBindBatchArray + +sizeof(char*)*c)+sizeof(float)*i)) = + (float)atof(tmpStr); + break; + + case TSDB_DATA_TYPE_DOUBLE: + *(double*)(((uintptr_t)*(uintptr_t*)(sampleBindBatchArray + +sizeof(char*)*c)+sizeof(double)*i)) = + atof(tmpStr); + break; + + case TSDB_DATA_TYPE_TINYINT: + *((int8_t*)((uintptr_t)*(uintptr_t*)(sampleBindBatchArray + +sizeof(char*)*c)+sizeof(int8_t)*i)) = + (int8_t)atoi(tmpStr); + break; + + case TSDB_DATA_TYPE_SMALLINT: + *((int16_t*)((uintptr_t)*(uintptr_t*)(sampleBindBatchArray + +sizeof(char*)*c)+sizeof(int16_t)*i)) = + (int16_t)atoi(tmpStr); + break; + + case TSDB_DATA_TYPE_BIGINT: + *((int64_t*)((uintptr_t)*(uintptr_t*)(sampleBindBatchArray + +sizeof(char*)*c)+sizeof(int64_t)*i)) = + (int64_t)atol(tmpStr); + break; + + case TSDB_DATA_TYPE_BOOL: + *((int8_t*)((uintptr_t)*(uintptr_t*)(sampleBindBatchArray + +sizeof(char*)*c)+sizeof(int8_t)*i)) = + (int8_t)atoi(tmpStr); + break; + + case TSDB_DATA_TYPE_TIMESTAMP: + *((int64_t*)((uintptr_t)*(uintptr_t*)(sampleBindBatchArray + +sizeof(char*)*c)+sizeof(int64_t)*i)) = + (int64_t)atol(tmpStr); + break; + + case TSDB_DATA_TYPE_BINARY: + case TSDB_DATA_TYPE_NCHAR: + tmpP = (char *)(*(uintptr_t*)(sampleBindBatchArray + +sizeof(char*)*c)); + strcpy(tmpP + i* + (((stbInfo)?stbInfo->columns[c].dataLen:g_args.binwidth)) + , tmpStr); + break; + + default: + break; + } + + free(tmpStr); + } + } + + return 0; +} + +static int parseSampleToStmtBatchForThread( + threadInfo *pThreadInfo, SSuperTable *stbInfo, + uint32_t timePrec, + uint32_t batch) +{ + uint32_t columnCount = (stbInfo)?stbInfo->columnCount:g_args.columnCount; + + pThreadInfo->bind_ts_array = malloc(sizeof(int64_t) * batch); + assert(pThreadInfo->bind_ts_array); + + pThreadInfo->bindParams = malloc(sizeof(TAOS_MULTI_BIND) * (columnCount + 1)); + assert(pThreadInfo->bindParams); + + pThreadInfo->is_null = malloc(batch); + assert(pThreadInfo->is_null); + + return 0; +} + +static int parseStbSampleToStmtBatchForThread( + threadInfo *pThreadInfo, + SSuperTable *stbInfo, + uint32_t timePrec, + uint32_t batch) +{ + return parseSampleToStmtBatchForThread( + pThreadInfo, stbInfo, timePrec, batch); +} + +static int parseNtbSampleToStmtBatchForThread( + threadInfo *pThreadInfo, uint32_t timePrec, uint32_t batch) +{ + return parseSampleToStmtBatchForThread( + pThreadInfo, NULL, timePrec, batch); +} + +#else +static int parseSampleToStmt( + threadInfo *pThreadInfo, + SSuperTable *stbInfo, uint32_t timePrec) +{ + pThreadInfo->sampleBindArray = + calloc(1, sizeof(char *) * MAX_SAMPLES); + if (pThreadInfo->sampleBindArray == NULL) { + errorPrint2("%s() LN%d, Failed to allocate %"PRIu64" bind array buffer\n", + __func__, __LINE__, + (uint64_t)sizeof(char *) * MAX_SAMPLES); + return -1; + } + + int32_t columnCount = (stbInfo)?stbInfo->columnCount:g_args.columnCount; + char *sampleDataBuf = (stbInfo)?stbInfo->sampleDataBuf:g_sampleDataBuf; + int64_t lenOfOneRow = (stbInfo)?stbInfo->lenOfOneRow:g_args.lenOfOneRow; + + for (int i=0; i < MAX_SAMPLES; i++) { + char *bindArray = + calloc(1, sizeof(TAOS_BIND) * (columnCount + 1)); + if (bindArray == NULL) { + errorPrint2("%s() LN%d, Failed to allocate %d bind params\n", + __func__, __LINE__, (columnCount + 1)); + return -1; + } + + TAOS_BIND *bind; + int cursor = 0; + + for (int c = 0; c < columnCount + 1; c++) { + bind = (TAOS_BIND *)((char *)bindArray + (sizeof(TAOS_BIND) * c)); + + if (c == 0) { + bind->buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + bind->buffer_length = sizeof(int64_t); + bind->buffer = NULL; //bind_ts; + bind->length = &bind->buffer_length; + bind->is_null = NULL; + } else { + char data_type = (stbInfo)? + stbInfo->columns[c-1].data_type: + g_args.data_type[c-1]; + int32_t dataLen = (stbInfo)? + stbInfo->columns[c-1].dataLen: + g_args.binwidth; + char *restStr = sampleDataBuf + + lenOfOneRow * i + cursor; + int lengthOfRest = strlen(restStr); + + int index = 0; + for (index = 0; index < lengthOfRest; index ++) { + if (restStr[index] == ',') { + break; + } + } + + char *bindBuffer = calloc(1, index + 1); + if (bindBuffer == NULL) { + errorPrint2("%s() LN%d, Failed to allocate %d bind buffer\n", + __func__, __LINE__, index + 1); + return -1; + } + + strncpy(bindBuffer, restStr, index); + cursor += index + 1; // skip ',' too + + if (-1 == prepareStmtBindArrayByType( + bind, + data_type, + dataLen, + timePrec, + bindBuffer)) { + free(bindBuffer); + return -1; + } + free(bindBuffer); + } + } + *((uintptr_t *)(pThreadInfo->sampleBindArray + (sizeof(char *)) * i)) = + (uintptr_t)bindArray; + } + + return 0; +} + +static int parseStbSampleToStmt( + threadInfo *pThreadInfo, + SSuperTable *stbInfo, uint32_t timePrec) +{ + return parseSampleToStmt( + pThreadInfo, + stbInfo, timePrec); +} + +static int parseNtbSampleToStmt( + threadInfo *pThreadInfo, + uint32_t timePrec) +{ + return parseSampleToStmt( + pThreadInfo, + NULL, + timePrec); +} + +static int32_t prepareStbStmtBindStartTime( + char *tableName, + int64_t *ts, + char *bindArray, SSuperTable *stbInfo, + int64_t startTime, int32_t recSeq) +{ + TAOS_BIND *bind; + + bind = (TAOS_BIND *)bindArray; + + int64_t *bind_ts = ts; + + bind->buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + if (stbInfo->disorderRatio) { + *bind_ts = startTime + getTSRandTail( + stbInfo->timeStampStep, recSeq, + stbInfo->disorderRatio, + stbInfo->disorderRange); + } else { + *bind_ts = startTime + stbInfo->timeStampStep * recSeq; + } + + verbosePrint("%s() LN%d, tableName: %s, bind_ts=%"PRId64"\n", + __func__, __LINE__, tableName, *bind_ts); + + bind->buffer_length = sizeof(int64_t); + bind->buffer = bind_ts; + bind->length = &bind->buffer_length; + bind->is_null = NULL; + + return 0; +} + +static uint32_t execBindParam( + threadInfo *pThreadInfo, + char *tableName, + int64_t tableSeq, + uint32_t batch, + uint64_t insertRows, + uint64_t recordFrom, + int64_t startTime, + int64_t *pSamplePos) +{ + int ret; + SSuperTable *stbInfo = pThreadInfo->stbInfo; + TAOS_STMT *stmt = pThreadInfo->stmt; + + uint32_t k; + for (k = 0; k < batch;) { + char *bindArray = (char *)(*((uintptr_t *) + (pThreadInfo->sampleBindArray + (sizeof(char *)) * (*pSamplePos)))); + /* columnCount + 1 (ts) */ + if (-1 == prepareStbStmtBindStartTime( + tableName, + pThreadInfo->bind_ts, + bindArray, stbInfo, + startTime, k + /* is column */)) { + return -1; + } + ret = taos_stmt_bind_param(stmt, (TAOS_BIND *)bindArray); + if (0 != ret) { + errorPrint2("%s() LN%d, stmt_bind_param() failed! reason: %s\n", + __func__, __LINE__, taos_stmt_errstr(stmt)); + return -1; + } + // if msg > 3MB, break + ret = taos_stmt_add_batch(stmt); + if (0 != ret) { + errorPrint2("%s() LN%d, stmt_add_batch() failed! reason: %s\n", + __func__, __LINE__, taos_stmt_errstr(stmt)); + return -1; + } + + k++; + recordFrom ++; + + (*pSamplePos) ++; + if ((*pSamplePos) == MAX_SAMPLES) { + *pSamplePos = 0; + } + + if (recordFrom >= insertRows) { + break; + } + } + + return k; +} +#endif + +static int32_t prepareStbStmtWithSample( + threadInfo *pThreadInfo, + char *tableName, + int64_t tableSeq, + uint32_t batch, + uint64_t insertRows, + uint64_t recordFrom, + int64_t startTime, + int64_t *pSamplePos) +{ + int ret; + SSuperTable *stbInfo = pThreadInfo->stbInfo; + TAOS_STMT *stmt = pThreadInfo->stmt; + + if (AUTO_CREATE_SUBTBL == stbInfo->autoCreateTable) { + char* tagsValBuf = NULL; + + if (0 == stbInfo->tagSource) { + tagsValBuf = generateTagValuesForStb(stbInfo, tableSeq); + } else { + tagsValBuf = getTagValueFromTagSample( + stbInfo, + tableSeq % stbInfo->tagSampleCount); + } + + if (NULL == tagsValBuf) { + errorPrint2("%s() LN%d, tag buf failed to allocate memory\n", + __func__, __LINE__); + return -1; + } + + char *tagsArray = calloc(1, sizeof(TAOS_BIND) * stbInfo->tagCount); + if (NULL == tagsArray) { + tmfree(tagsValBuf); + errorPrint2("%s() LN%d, tag buf failed to allocate memory\n", + __func__, __LINE__); + return -1; + } + + if (-1 == prepareStbStmtBindTag( + tagsArray, stbInfo, tagsValBuf, pThreadInfo->time_precision + /* is tag */)) { + tmfree(tagsValBuf); + tmfree(tagsArray); + return -1; + } + + ret = taos_stmt_set_tbname_tags(stmt, tableName, (TAOS_BIND *)tagsArray); + + tmfree(tagsValBuf); + tmfree(tagsArray); + + if (0 != ret) { + errorPrint2("%s() LN%d, stmt_set_tbname_tags() failed! reason: %s\n", + __func__, __LINE__, taos_stmt_errstr(stmt)); + return -1; + } + } else { + ret = taos_stmt_set_tbname(stmt, tableName); + if (0 != ret) { + errorPrint2("%s() LN%d, stmt_set_tbname() failed! reason: %s\n", + __func__, __LINE__, taos_stmt_errstr(stmt)); + return -1; + } + } + +#if STMT_BIND_PARAM_BATCH == 1 + return execBindParamBatch( + pThreadInfo, + tableName, + tableSeq, + batch, + insertRows, + recordFrom, + startTime, + pSamplePos); +#else + return execBindParam( + pThreadInfo, + tableName, + tableSeq, + batch, + insertRows, + recordFrom, + startTime, + pSamplePos); +#endif +} + +static int32_t generateStbProgressiveData( + SSuperTable *stbInfo, + char *tableName, + int64_t tableSeq, + char *dbName, char *buffer, + int64_t insertRows, + uint64_t recordFrom, int64_t startTime, int64_t *pSamplePos, + int64_t *pRemainderBufLen) +{ + assert(buffer != NULL); + char *pstr = buffer; + + memset(pstr, 0, *pRemainderBufLen); + + int64_t headLen = generateStbSQLHead( + stbInfo, + tableName, tableSeq, dbName, + buffer, *pRemainderBufLen); + + if (headLen <= 0) { + return 0; + } + pstr += headLen; + *pRemainderBufLen -= headLen; + + int64_t dataLen; + + return generateStbDataTail(stbInfo, + g_args.reqPerReq, pstr, *pRemainderBufLen, + insertRows, recordFrom, + startTime, + pSamplePos, &dataLen); +} + +static int32_t generateProgressiveDataWithoutStb( + char *tableName, + /* int64_t tableSeq, */ + threadInfo *pThreadInfo, char *buffer, + int64_t insertRows, + uint64_t recordFrom, int64_t startTime, /*int64_t *pSamplePos, */ + int64_t *pRemainderBufLen) +{ + assert(buffer != NULL); + char *pstr = buffer; + + memset(buffer, 0, *pRemainderBufLen); + + int64_t headLen = generateSQLHeadWithoutStb( + tableName, pThreadInfo->db_name, + buffer, *pRemainderBufLen); + + if (headLen <= 0) { + return 0; + } + pstr += headLen; + *pRemainderBufLen -= headLen; + + int64_t dataLen; + + return generateDataTailWithoutStb( + g_args.reqPerReq, pstr, *pRemainderBufLen, insertRows, recordFrom, + startTime, + /*pSamplePos, */&dataLen); +} + +static void printStatPerThread(threadInfo *pThreadInfo) +{ + if (0 == pThreadInfo->totalDelay) + pThreadInfo->totalDelay = 1; + + fprintf(stderr, "====thread[%d] completed total inserted rows: %"PRIu64 ", total affected rows: %"PRIu64". %.2f records/second====\n", + pThreadInfo->threadID, + pThreadInfo->totalInsertRows, + pThreadInfo->totalAffectedRows, + (double)(pThreadInfo->totalAffectedRows/((double)pThreadInfo->totalDelay/1000000.0)) + ); +} + +#if STMT_BIND_PARAM_BATCH == 1 +// stmt sync write interlace data +static void* syncWriteInterlaceStmtBatch(threadInfo *pThreadInfo, uint32_t interlaceRows) { + debugPrint("[%d] %s() LN%d: ### stmt interlace write\n", + pThreadInfo->threadID, __func__, __LINE__); + + int64_t insertRows; + uint64_t maxSqlLen; + int64_t nTimeStampStep; + uint64_t insert_interval; + + SSuperTable* stbInfo = pThreadInfo->stbInfo; + + if (stbInfo) { + insertRows = stbInfo->insertRows; + maxSqlLen = stbInfo->maxSqlLen; + nTimeStampStep = stbInfo->timeStampStep; + insert_interval = stbInfo->insertInterval; + } else { + insertRows = g_args.insertRows; + maxSqlLen = g_args.max_sql_len; + nTimeStampStep = g_args.timestamp_step; + insert_interval = g_args.insert_interval; + } + + debugPrint("[%d] %s() LN%d: start_table_from=%"PRIu64" ntables=%"PRId64" insertRows=%"PRIu64"\n", + pThreadInfo->threadID, __func__, __LINE__, + pThreadInfo->start_table_from, + pThreadInfo->ntables, insertRows); + + uint32_t batchPerTbl = interlaceRows; + uint32_t batchPerTblTimes; + + if (interlaceRows > g_args.reqPerReq) + interlaceRows = g_args.reqPerReq; + + if ((interlaceRows > 0) && (pThreadInfo->ntables > 1)) { + batchPerTblTimes = + g_args.reqPerReq / interlaceRows; + } else { + batchPerTblTimes = 1; + } + + pThreadInfo->totalInsertRows = 0; + pThreadInfo->totalAffectedRows = 0; + + uint64_t st = 0; + uint64_t et = UINT64_MAX; + + uint64_t lastPrintTime = taosGetTimestampMs(); + uint64_t startTs = taosGetTimestampMs(); + uint64_t endTs; + + uint64_t tableSeq = pThreadInfo->start_table_from; + int64_t startTime = pThreadInfo->start_time; + + uint64_t generatedRecPerTbl = 0; + bool flagSleep = true; + uint64_t sleepTimeTotal = 0; + + int percentComplete = 0; + int64_t totalRows = insertRows * pThreadInfo->ntables; + + while(pThreadInfo->totalInsertRows < pThreadInfo->ntables * insertRows) { + if ((flagSleep) && (insert_interval)) { + st = taosGetTimestampMs(); + flagSleep = false; + } + + uint32_t recOfBatch = 0; + + int32_t generated; + for (uint64_t i = 0; i < batchPerTblTimes; i ++) { + char tableName[TSDB_TABLE_NAME_LEN]; + + getTableName(tableName, pThreadInfo, tableSeq); + if (0 == strlen(tableName)) { + errorPrint2("[%d] %s() LN%d, getTableName return null\n", + pThreadInfo->threadID, __func__, __LINE__); + return NULL; + } + + if (stbInfo) { + generated = prepareStbStmtWithSample( + pThreadInfo, + tableName, + tableSeq, + batchPerTbl, + insertRows, 0, + startTime, + &(pThreadInfo->samplePos)); + } else { + debugPrint("[%d] %s() LN%d, tableName:%s, batch:%d startTime:%"PRId64"\n", + pThreadInfo->threadID, + __func__, __LINE__, + tableName, batchPerTbl, startTime); + generated = prepareStmtWithoutStb( + pThreadInfo, + tableName, + batchPerTbl, + insertRows, i, + startTime); + } + + debugPrint("[%d] %s() LN%d, generated records is %d\n", + pThreadInfo->threadID, __func__, __LINE__, generated); + if (generated < 0) { + errorPrint2("[%d] %s() LN%d, generated records is %d\n", + pThreadInfo->threadID, __func__, __LINE__, generated); + goto free_of_interlace_stmt; + } else if (generated == 0) { + break; + } + + tableSeq ++; + recOfBatch += batchPerTbl; + + pThreadInfo->totalInsertRows += batchPerTbl; + + verbosePrint("[%d] %s() LN%d batchPerTbl=%d recOfBatch=%d\n", + pThreadInfo->threadID, __func__, __LINE__, + batchPerTbl, recOfBatch); + + if (tableSeq == pThreadInfo->start_table_from + pThreadInfo->ntables) { + // turn to first table + tableSeq = pThreadInfo->start_table_from; + generatedRecPerTbl += batchPerTbl; + + startTime = pThreadInfo->start_time + + generatedRecPerTbl * nTimeStampStep; + + flagSleep = true; + if (generatedRecPerTbl >= insertRows) + break; + + int64_t remainRows = insertRows - generatedRecPerTbl; + if ((remainRows > 0) && (batchPerTbl > remainRows)) + batchPerTbl = remainRows; + + if (pThreadInfo->ntables * batchPerTbl < g_args.reqPerReq) + break; + } + + verbosePrint("[%d] %s() LN%d generatedRecPerTbl=%"PRId64" insertRows=%"PRId64"\n", + pThreadInfo->threadID, __func__, __LINE__, + generatedRecPerTbl, insertRows); + + if ((g_args.reqPerReq - recOfBatch) < batchPerTbl) + break; + } + + verbosePrint("[%d] %s() LN%d recOfBatch=%d totalInsertRows=%"PRIu64"\n", + pThreadInfo->threadID, __func__, __LINE__, recOfBatch, + pThreadInfo->totalInsertRows); + + startTs = taosGetTimestampUs(); + + if (recOfBatch == 0) { + errorPrint2("[%d] %s() LN%d Failed to insert records of batch %d\n", + pThreadInfo->threadID, __func__, __LINE__, + batchPerTbl); + if (batchPerTbl > 0) { + errorPrint("\tIf the batch is %d, the length of the SQL to insert a row must be less then %"PRId64"\n", + batchPerTbl, maxSqlLen / batchPerTbl); + } + goto free_of_interlace_stmt; + } + int64_t affectedRows = execInsert(pThreadInfo, recOfBatch); + + endTs = taosGetTimestampUs(); + uint64_t delay = endTs - startTs; + performancePrint("%s() LN%d, insert execution time is %10.2f ms\n", + __func__, __LINE__, delay / 1000.0); + verbosePrint("[%d] %s() LN%d affectedRows=%"PRId64"\n", + pThreadInfo->threadID, + __func__, __LINE__, affectedRows); + + if (delay > pThreadInfo->maxDelay) pThreadInfo->maxDelay = delay; + if (delay < pThreadInfo->minDelay) pThreadInfo->minDelay = delay; + pThreadInfo->cntDelay++; + pThreadInfo->totalDelay += delay; + + if (recOfBatch != affectedRows) { + errorPrint2("[%d] %s() LN%d execInsert insert %d, affected rows: %"PRId64"\n\n", + pThreadInfo->threadID, __func__, __LINE__, + recOfBatch, affectedRows); + goto free_of_interlace_stmt; + } + + pThreadInfo->totalAffectedRows += affectedRows; + + int currentPercent = pThreadInfo->totalAffectedRows * 100 / totalRows; + if (currentPercent > percentComplete ) { + printf("[%d]:%d%%\n", pThreadInfo->threadID, currentPercent); + percentComplete = currentPercent; + } + int64_t currentPrintTime = taosGetTimestampMs(); + if (currentPrintTime - lastPrintTime > 30*1000) { + printf("thread[%d] has currently inserted rows: %"PRIu64 ", affected rows: %"PRIu64 "\n", + pThreadInfo->threadID, + pThreadInfo->totalInsertRows, + pThreadInfo->totalAffectedRows); + lastPrintTime = currentPrintTime; + } + + if ((insert_interval) && flagSleep) { + et = taosGetTimestampMs(); + + if (insert_interval > (et - st) ) { + uint64_t sleepTime = insert_interval - (et -st); + performancePrint("%s() LN%d sleep: %"PRId64" ms for insert interval\n", + __func__, __LINE__, sleepTime); + taosMsleep(sleepTime); // ms + sleepTimeTotal += insert_interval; + } + } + } + if (percentComplete < 100) + printf("[%d]:%d%%\n", pThreadInfo->threadID, percentComplete); + +free_of_interlace_stmt: + printStatPerThread(pThreadInfo); + return NULL; +} +#else +// stmt sync write interlace data +static void* syncWriteInterlaceStmt(threadInfo *pThreadInfo, uint32_t interlaceRows) { + debugPrint("[%d] %s() LN%d: ### stmt interlace write\n", + pThreadInfo->threadID, __func__, __LINE__); + + int64_t insertRows; + uint64_t maxSqlLen; + int64_t nTimeStampStep; + uint64_t insert_interval; + + SSuperTable* stbInfo = pThreadInfo->stbInfo; + + if (stbInfo) { + insertRows = stbInfo->insertRows; + maxSqlLen = stbInfo->maxSqlLen; + nTimeStampStep = stbInfo->timeStampStep; + insert_interval = stbInfo->insertInterval; + } else { + insertRows = g_args.insertRows; + maxSqlLen = g_args.max_sql_len; + nTimeStampStep = g_args.timestamp_step; + insert_interval = g_args.insert_interval; + } + + debugPrint("[%d] %s() LN%d: start_table_from=%"PRIu64" ntables=%"PRId64" insertRows=%"PRIu64"\n", + pThreadInfo->threadID, __func__, __LINE__, + pThreadInfo->start_table_from, + pThreadInfo->ntables, insertRows); + + uint32_t batchPerTbl = interlaceRows; + uint32_t batchPerTblTimes; + + if (interlaceRows > g_args.reqPerReq) + interlaceRows = g_args.reqPerReq; + + if ((interlaceRows > 0) && (pThreadInfo->ntables > 1)) { + batchPerTblTimes = + g_args.reqPerReq / interlaceRows; + } else { + batchPerTblTimes = 1; + } + + pThreadInfo->totalInsertRows = 0; + pThreadInfo->totalAffectedRows = 0; + + uint64_t st = 0; + uint64_t et = UINT64_MAX; + + uint64_t lastPrintTime = taosGetTimestampMs(); + uint64_t startTs = taosGetTimestampMs(); + uint64_t endTs; + + uint64_t tableSeq = pThreadInfo->start_table_from; + int64_t startTime = pThreadInfo->start_time; + + uint64_t generatedRecPerTbl = 0; + bool flagSleep = true; + uint64_t sleepTimeTotal = 0; + + int percentComplete = 0; + int64_t totalRows = insertRows * pThreadInfo->ntables; + + while(pThreadInfo->totalInsertRows < pThreadInfo->ntables * insertRows) { + if ((flagSleep) && (insert_interval)) { + st = taosGetTimestampMs(); + flagSleep = false; + } + + uint32_t recOfBatch = 0; + + int32_t generated; + for (uint64_t i = 0; i < batchPerTblTimes; i ++) { + char tableName[TSDB_TABLE_NAME_LEN]; + + getTableName(tableName, pThreadInfo, tableSeq); + if (0 == strlen(tableName)) { + errorPrint2("[%d] %s() LN%d, getTableName return null\n", + pThreadInfo->threadID, __func__, __LINE__); + return NULL; + } + + if (stbInfo) { + generated = prepareStbStmtWithSample( + pThreadInfo, + tableName, + tableSeq, + batchPerTbl, + insertRows, 0, + startTime, + &(pThreadInfo->samplePos)); + } else { + debugPrint("[%d] %s() LN%d, tableName:%s, batch:%d startTime:%"PRId64"\n", + pThreadInfo->threadID, + __func__, __LINE__, + tableName, batchPerTbl, startTime); + generated = prepareStmtWithoutStb( + pThreadInfo, + tableName, + batchPerTbl, + insertRows, i, + startTime); + } + + debugPrint("[%d] %s() LN%d, generated records is %d\n", + pThreadInfo->threadID, __func__, __LINE__, generated); + if (generated < 0) { + errorPrint2("[%d] %s() LN%d, generated records is %d\n", + pThreadInfo->threadID, __func__, __LINE__, generated); + goto free_of_interlace_stmt; + } else if (generated == 0) { + break; + } + + tableSeq ++; + recOfBatch += batchPerTbl; + + pThreadInfo->totalInsertRows += batchPerTbl; + + verbosePrint("[%d] %s() LN%d batchPerTbl=%d recOfBatch=%d\n", + pThreadInfo->threadID, __func__, __LINE__, + batchPerTbl, recOfBatch); + + if (tableSeq == pThreadInfo->start_table_from + pThreadInfo->ntables) { + // turn to first table + tableSeq = pThreadInfo->start_table_from; + generatedRecPerTbl += batchPerTbl; + + startTime = pThreadInfo->start_time + + generatedRecPerTbl * nTimeStampStep; + + flagSleep = true; + if (generatedRecPerTbl >= insertRows) + break; + + int64_t remainRows = insertRows - generatedRecPerTbl; + if ((remainRows > 0) && (batchPerTbl > remainRows)) + batchPerTbl = remainRows; + + if (pThreadInfo->ntables * batchPerTbl < g_args.reqPerReq) + break; + } + + verbosePrint("[%d] %s() LN%d generatedRecPerTbl=%"PRId64" insertRows=%"PRId64"\n", + pThreadInfo->threadID, __func__, __LINE__, + generatedRecPerTbl, insertRows); + + if ((g_args.reqPerReq - recOfBatch) < batchPerTbl) + break; + } + + verbosePrint("[%d] %s() LN%d recOfBatch=%d totalInsertRows=%"PRIu64"\n", + pThreadInfo->threadID, __func__, __LINE__, recOfBatch, + pThreadInfo->totalInsertRows); + + startTs = taosGetTimestampUs(); + + if (recOfBatch == 0) { + errorPrint2("[%d] %s() LN%d Failed to insert records of batch %d\n", + pThreadInfo->threadID, __func__, __LINE__, + batchPerTbl); + if (batchPerTbl > 0) { + errorPrint("\tIf the batch is %d, the length of the SQL to insert a row must be less then %"PRId64"\n", + batchPerTbl, maxSqlLen / batchPerTbl); + } + goto free_of_interlace_stmt; + } + int64_t affectedRows = execInsert(pThreadInfo, recOfBatch); - if (headLen <= 0) { - return 0; - } - pstr += headLen; - *pRemainderBufLen -= headLen; + endTs = taosGetTimestampUs(); + uint64_t delay = endTs - startTs; + performancePrint("%s() LN%d, insert execution time is %10.2f ms\n", + __func__, __LINE__, delay / 1000.0); + verbosePrint("[%d] %s() LN%d affectedRows=%"PRId64"\n", + pThreadInfo->threadID, + __func__, __LINE__, affectedRows); - int64_t dataLen; + if (delay > pThreadInfo->maxDelay) pThreadInfo->maxDelay = delay; + if (delay < pThreadInfo->minDelay) pThreadInfo->minDelay = delay; + pThreadInfo->cntDelay++; + pThreadInfo->totalDelay += delay; - return generateStbDataTail(stbInfo, - g_args.num_of_RPR, pstr, *pRemainderBufLen, - insertRows, recordFrom, - startTime, - pSamplePos, &dataLen); -} + if (recOfBatch != affectedRows) { + errorPrint2("[%d] %s() LN%d execInsert insert %d, affected rows: %"PRId64"\n\n", + pThreadInfo->threadID, __func__, __LINE__, + recOfBatch, affectedRows); + goto free_of_interlace_stmt; + } -static int32_t generateProgressiveDataWithoutStb( - char *tableName, - /* int64_t tableSeq, */ - threadInfo *pThreadInfo, char *buffer, - int64_t insertRows, - uint64_t recordFrom, int64_t startTime, /*int64_t *pSamplePos, */ - int64_t *pRemainderBufLen) -{ - assert(buffer != NULL); - char *pstr = buffer; + pThreadInfo->totalAffectedRows += affectedRows; - memset(buffer, 0, *pRemainderBufLen); + int currentPercent = pThreadInfo->totalAffectedRows * 100 / totalRows; + if (currentPercent > percentComplete ) { + printf("[%d]:%d%%\n", pThreadInfo->threadID, currentPercent); + percentComplete = currentPercent; + } + int64_t currentPrintTime = taosGetTimestampMs(); + if (currentPrintTime - lastPrintTime > 30*1000) { + printf("thread[%d] has currently inserted rows: %"PRIu64 ", affected rows: %"PRIu64 "\n", + pThreadInfo->threadID, + pThreadInfo->totalInsertRows, + pThreadInfo->totalAffectedRows); + lastPrintTime = currentPrintTime; + } - int64_t headLen = generateSQLHeadWithoutStb( - tableName, pThreadInfo->db_name, - buffer, *pRemainderBufLen); + if ((insert_interval) && flagSleep) { + et = taosGetTimestampMs(); - if (headLen <= 0) { - return 0; + if (insert_interval > (et - st) ) { + uint64_t sleepTime = insert_interval - (et -st); + performancePrint("%s() LN%d sleep: %"PRId64" ms for insert interval\n", + __func__, __LINE__, sleepTime); + taosMsleep(sleepTime); // ms + sleepTimeTotal += insert_interval; + } + } } - pstr += headLen; - *pRemainderBufLen -= headLen; - - int64_t dataLen; + if (percentComplete < 100) + printf("[%d]:%d%%\n", pThreadInfo->threadID, percentComplete); - return generateDataTailWithoutStb( - g_args.num_of_RPR, pstr, *pRemainderBufLen, insertRows, recordFrom, - startTime, - /*pSamplePos, */&dataLen); +free_of_interlace_stmt: + printStatPerThread(pThreadInfo); + return NULL; } -static void printStatPerThread(threadInfo *pThreadInfo) -{ - fprintf(stderr, "====thread[%d] completed total inserted rows: %"PRIu64 ", total affected rows: %"PRIu64". %.2f records/second====\n", - pThreadInfo->threadID, - pThreadInfo->totalInsertRows, - pThreadInfo->totalAffectedRows, - (pThreadInfo->totalDelay)? - (double)(pThreadInfo->totalAffectedRows/((double)pThreadInfo->totalDelay/1000000.0)): - FLT_MAX); -} +#endif // sync write interlace data -static void* syncWriteInterlace(threadInfo *pThreadInfo) { +static void* syncWriteInterlace(threadInfo *pThreadInfo, uint32_t interlaceRows) { debugPrint("[%d] %s() LN%d: ### interlace write\n", pThreadInfo->threadID, __func__, __LINE__); int64_t insertRows; - uint32_t interlaceRows; uint64_t maxSqlLen; int64_t nTimeStampStep; uint64_t insert_interval; @@ -7430,19 +8926,11 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { if (stbInfo) { insertRows = stbInfo->insertRows; - - if ((stbInfo->interlaceRows == 0) - && (g_args.interlace_rows > 0)) { - interlaceRows = g_args.interlace_rows; - } else { - interlaceRows = stbInfo->interlaceRows; - } maxSqlLen = stbInfo->maxSqlLen; nTimeStampStep = stbInfo->timeStampStep; insert_interval = stbInfo->insertInterval; } else { - insertRows = g_args.num_of_DPT; - interlaceRows = g_args.interlace_rows; + insertRows = g_args.insertRows; maxSqlLen = g_args.max_sql_len; nTimeStampStep = g_args.timestamp_step; insert_interval = g_args.insert_interval; @@ -7452,23 +8940,35 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { pThreadInfo->threadID, __func__, __LINE__, pThreadInfo->start_table_from, pThreadInfo->ntables, insertRows); - - if (interlaceRows > insertRows) - interlaceRows = insertRows; - - if (interlaceRows > g_args.num_of_RPR) - interlaceRows = g_args.num_of_RPR; +#if 1 + if (interlaceRows > g_args.reqPerReq) + interlaceRows = g_args.reqPerReq; uint32_t batchPerTbl = interlaceRows; uint32_t batchPerTblTimes; if ((interlaceRows > 0) && (pThreadInfo->ntables > 1)) { batchPerTblTimes = - g_args.num_of_RPR / interlaceRows; + g_args.reqPerReq / interlaceRows; } else { batchPerTblTimes = 1; } +#else + uint32_t batchPerTbl; + if (interlaceRows > g_args.reqPerReq) + batchPerTbl = g_args.reqPerReq; + else + batchPerTbl = interlaceRows; + + uint32_t batchPerTblTimes; + if ((interlaceRows > 0) && (pThreadInfo->ntables > 1)) { + batchPerTblTimes = + interlaceRows / batchPerTbl; + } else { + batchPerTblTimes = 1; + } +#endif pThreadInfo->buffer = calloc(maxSqlLen, 1); if (NULL == pThreadInfo->buffer) { errorPrint2( "%s() LN%d, Failed to alloc %"PRIu64" Bytes, reason:%s\n", @@ -7501,6 +9001,7 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { st = taosGetTimestampMs(); flagSleep = false; } + // generate data memset(pThreadInfo->buffer, 0, maxSqlLen); uint64_t remainderBufLen = maxSqlLen; @@ -7514,6 +9015,7 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { uint32_t recOfBatch = 0; + int32_t generated; for (uint64_t i = 0; i < batchPerTblTimes; i ++) { char tableName[TSDB_TABLE_NAME_LEN]; @@ -7527,49 +9029,24 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { uint64_t oldRemainderLen = remainderBufLen; - int32_t generated; if (stbInfo) { - if (stbInfo->iface == STMT_IFACE) { - generated = prepareStbStmtWithSample( - pThreadInfo, - tableName, - tableSeq, - batchPerTbl, - insertRows, 0, - startTime, - &(pThreadInfo->samplePos)); - } else { - generated = generateStbInterlaceData( - pThreadInfo, - tableName, batchPerTbl, i, - batchPerTblTimes, - tableSeq, - pstr, - insertRows, - startTime, - &remainderBufLen); - } + generated = generateStbInterlaceData( + pThreadInfo, + tableName, batchPerTbl, i, + batchPerTblTimes, + tableSeq, + pstr, + insertRows, + startTime, + &remainderBufLen); } else { - if (g_args.iface == STMT_IFACE) { - debugPrint("[%d] %s() LN%d, tableName:%s, batch:%d startTime:%"PRId64"\n", - pThreadInfo->threadID, - __func__, __LINE__, - tableName, batchPerTbl, startTime); - generated = prepareStmtWithoutStb( - pThreadInfo, - tableName, - batchPerTbl, - insertRows, i, - startTime); - } else { - generated = generateInterlaceDataWithoutStb( - tableName, batchPerTbl, - tableSeq, - pThreadInfo->db_name, pstr, - insertRows, - startTime, - &remainderBufLen); - } + generated = generateInterlaceDataWithoutStb( + tableName, batchPerTbl, + tableSeq, + pThreadInfo->db_name, pstr, + insertRows, + startTime, + &remainderBufLen); } debugPrint("[%d] %s() LN%d, generated records is %d\n", @@ -7608,7 +9085,7 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { if ((remainRows > 0) && (batchPerTbl > remainRows)) batchPerTbl = remainRows; - if (pThreadInfo->ntables * batchPerTbl < g_args.num_of_RPR) + if (pThreadInfo->ntables * batchPerTbl < g_args.reqPerReq) break; } @@ -7616,7 +9093,7 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { pThreadInfo->threadID, __func__, __LINE__, generatedRecPerTbl, insertRows); - if ((g_args.num_of_RPR - recOfBatch) < batchPerTbl) + if ((g_args.reqPerReq - recOfBatch) < batchPerTbl) break; } @@ -7708,7 +9185,7 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) { int64_t timeStampStep = stbInfo?stbInfo->timeStampStep:g_args.timestamp_step; int64_t insertRows = - (stbInfo)?stbInfo->insertRows:g_args.num_of_DPT; + (stbInfo)?stbInfo->insertRows:g_args.insertRows; verbosePrint("%s() LN%d insertRows=%"PRId64"\n", __func__, __LINE__, insertRows); @@ -7769,7 +9246,9 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) { pThreadInfo, tableName, tableSeq, - g_args.num_of_RPR, + (g_args.reqPerReq>stbInfo->insertRows)? + stbInfo->insertRows: + g_args.reqPerReq, insertRows, i, start_time, &(pThreadInfo->samplePos)); } else { @@ -7786,7 +9265,7 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) { generated = prepareStmtWithoutStb( pThreadInfo, tableName, - g_args.num_of_RPR, + g_args.reqPerReq, insertRows, i, start_time); } else { @@ -7854,7 +9333,7 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) { if (i >= insertRows) break; - } // num_of_DPT + } // insertRows if ((g_args.verbose_print) && (tableSeq == pThreadInfo->ntables - 1) && (stbInfo) @@ -7865,8 +9344,10 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) { __func__, __LINE__, pThreadInfo->samplePos); } } // tableSeq - if (percentComplete < 100) + + if (percentComplete < 100) { printf("[%d]:%d%%\n", pThreadInfo->threadID, percentComplete); + } free_of_progressive: tmfree(pThreadInfo->buffer); @@ -7881,23 +9362,29 @@ static void* syncWrite(void *sarg) { setThreadName("syncWrite"); - uint32_t interlaceRows; + uint32_t interlaceRows = 0; if (stbInfo) { - if ((stbInfo->interlaceRows == 0) - && (g_args.interlace_rows > 0)) { - interlaceRows = g_args.interlace_rows; - } else { + if (stbInfo->interlaceRows < stbInfo->insertRows) interlaceRows = stbInfo->interlaceRows; - } } else { - interlaceRows = g_args.interlace_rows; + if (g_args.interlaceRows < g_args.insertRows) + interlaceRows = g_args.interlaceRows; } if (interlaceRows > 0) { // interlace mode - return syncWriteInterlace(pThreadInfo); - } else { + if (((stbInfo) && (STMT_IFACE == stbInfo->iface)) + || (STMT_IFACE == g_args.iface)) { +#if STMT_BIND_PARAM_BATCH == 1 + return syncWriteInterlaceStmtBatch(pThreadInfo, interlaceRows); +#else + return syncWriteInterlaceStmt(pThreadInfo, interlaceRows); +#endif + } else { + return syncWriteInterlace(pThreadInfo, interlaceRows); + } + }else { // progressive mode return syncWriteProgressive(pThreadInfo); } @@ -7919,11 +9406,11 @@ static void callBack(void *param, TAOS_RES *res, int code) { char *buffer = calloc(1, pThreadInfo->stbInfo->maxSqlLen); char data[MAX_DATA_SIZE]; char *pstr = buffer; - pstr += sprintf(pstr, "insert into %s.%s%"PRId64" values", + pstr += sprintf(pstr, "INSERT INTO %s.%s%"PRId64" VALUES", pThreadInfo->db_name, pThreadInfo->tb_prefix, pThreadInfo->start_table_from); // if (pThreadInfo->counter >= pThreadInfo->stbInfo->insertRows) { - if (pThreadInfo->counter >= g_args.num_of_RPR) { + if (pThreadInfo->counter >= g_args.reqPerReq) { pThreadInfo->start_table_from++; pThreadInfo->counter = 0; } @@ -7934,7 +9421,7 @@ static void callBack(void *param, TAOS_RES *res, int code) { return; } - for (int i = 0; i < g_args.num_of_RPR; i++) { + for (int i = 0; i < g_args.reqPerReq; i++) { int rand_num = taosRandom() % 100; if (0 != pThreadInfo->stbInfo->disorderRatio && rand_num < pThreadInfo->stbInfo->disorderRatio) { @@ -8014,81 +9501,6 @@ static int convertHostToServAddr(char *host, uint16_t port, struct sockaddr_in * return 0; } -static int parseSampleFileToStmt( - threadInfo *pThreadInfo, - SSuperTable *stbInfo, uint32_t timePrec) -{ - pThreadInfo->sampleBindArray = - calloc(1, sizeof(char *) * MAX_SAMPLES_ONCE_FROM_FILE); - if (pThreadInfo->sampleBindArray == NULL) { - errorPrint2("%s() LN%d, Failed to allocate %"PRIu64" bind array buffer\n", - __func__, __LINE__, - (uint64_t)sizeof(char *) * MAX_SAMPLES_ONCE_FROM_FILE); - return -1; - } - - for (int i=0; i < MAX_SAMPLES_ONCE_FROM_FILE; i++) { - char *bindArray = - calloc(1, sizeof(TAOS_BIND) * (stbInfo->columnCount + 1)); - if (bindArray == NULL) { - errorPrint2("%s() LN%d, Failed to allocate %d bind params\n", - __func__, __LINE__, (stbInfo->columnCount + 1)); - return -1; - } - - TAOS_BIND *bind; - int cursor = 0; - - for (int c = 0; c < stbInfo->columnCount + 1; c++) { - bind = (TAOS_BIND *)((char *)bindArray + (sizeof(TAOS_BIND) * c)); - - if (c == 0) { - bind->buffer_type = TSDB_DATA_TYPE_TIMESTAMP; - bind->buffer_length = sizeof(int64_t); - bind->buffer = NULL; //bind_ts; - bind->length = &bind->buffer_length; - bind->is_null = NULL; - } else { - char *restStr = stbInfo->sampleDataBuf - + stbInfo->lenOfOneRow * i + cursor; - int lengthOfRest = strlen(restStr); - - int index = 0; - for (index = 0; index < lengthOfRest; index ++) { - if (restStr[index] == ',') { - break; - } - } - - char *bindBuffer = calloc(1, index + 1); - if (bindBuffer == NULL) { - errorPrint2("%s() LN%d, Failed to allocate %d bind buffer\n", - __func__, __LINE__, DOUBLE_BUFF_LEN); - return -1; - } - - strncpy(bindBuffer, restStr, index); - cursor += index + 1; // skip ',' too - - if (-1 == prepareStmtBindArrayByType( - bind, - stbInfo->columns[c-1].dataType, - stbInfo->columns[c-1].dataLen, - timePrec, - bindBuffer)) { - free(bindBuffer); - return -1; - } - free(bindBuffer); - } - } - *((uintptr_t *)(pThreadInfo->sampleBindArray + (sizeof(char *)) * i)) = - (uintptr_t)bindArray; - } - - return 0; -} - static void startMultiThreadInsertData(int threads, char* db_name, char* precision, SSuperTable* stbInfo) { @@ -8126,12 +9538,17 @@ static void startMultiThreadInsertData(int threads, char* db_name, __func__, __LINE__, start_time); // read sample data from file first + int ret; if (stbInfo) { - if (0 != prepareSampleDataForSTable(stbInfo)) { - errorPrint2("%s() LN%d, prepare sample data for stable failed!\n", - __func__, __LINE__); - exit(EXIT_FAILURE); - } + ret = prepareSampleForStb(stbInfo); + } else { + ret = prepareSampleForNtb(); + } + + if (0 != ret) { + errorPrint2("%s() LN%d, prepare sample data for stable failed!\n", + __func__, __LINE__); + exit(EXIT_FAILURE); } TAOS* taos0 = taos_connect( @@ -8162,6 +9579,12 @@ static void startMultiThreadInsertData(int threads, char* db_name, || ((stbInfo->childTblOffset + stbInfo->childTblLimit) > (stbInfo->childTblCount))) { + + if (stbInfo->childTblCount < stbInfo->childTblOffset) { + printf("WARNING: offset will not be used since the child tables count is less then offset!\n"); + + stbInfo->childTblOffset = 0; + } stbInfo->childTblLimit = stbInfo->childTblCount - stbInfo->childTblOffset; } @@ -8200,12 +9623,13 @@ static void startMultiThreadInsertData(int threads, char* db_name, int64_t childTblCount; getChildNameOfSuperTableWithLimitAndOffset( taos0, - db_name, stbInfo->sTblName, + db_name, stbInfo->stbName, &stbInfo->childTblName, &childTblCount, limit, offset); + ntables = childTblCount; // CBD } else { - ntables = g_args.num_of_tables; + ntables = g_args.ntables; tableFrom = 0; } @@ -8241,6 +9665,38 @@ static void startMultiThreadInsertData(int threads, char* db_name, char *stmtBuffer = calloc(1, BUFFER_SIZE); assert(stmtBuffer); + +#if STMT_BIND_PARAM_BATCH == 1 + uint32_t interlaceRows = 0; + uint32_t batch; + + if (stbInfo) { + if ((stbInfo->interlaceRows == 0) + && (g_args.interlaceRows > 0) + ) { + interlaceRows = g_args.interlaceRows; + + } else { + interlaceRows = stbInfo->interlaceRows; + } + + if (interlaceRows > stbInfo->insertRows) { + interlaceRows = 0; + } + } else { + if (g_args.interlaceRows < g_args.insertRows) + interlaceRows = g_args.interlaceRows; + } + + if (interlaceRows > 0) { + batch = interlaceRows; + } else { + batch = (g_args.reqPerReq>g_args.insertRows)? + g_args.insertRows:g_args.reqPerReq; + } + +#endif + if ((g_args.iface == STMT_IFACE) || ((stbInfo) && (stbInfo->iface == STMT_IFACE))) { @@ -8250,7 +9706,7 @@ static void startMultiThreadInsertData(int threads, char* db_name, && (AUTO_CREATE_SUBTBL == stbInfo->autoCreateTable)) { pstr += sprintf(pstr, "INSERT INTO ? USING %s TAGS(?", - stbInfo->sTblName); + stbInfo->stbName); for (int tag = 0; tag < (stbInfo->tagCount - 1); tag ++ ) { pstr += sprintf(pstr, ",?"); @@ -8260,12 +9716,9 @@ static void startMultiThreadInsertData(int threads, char* db_name, pstr += sprintf(pstr, "INSERT INTO ? VALUES(?"); } - int columnCount; - if (stbInfo) { - columnCount = stbInfo->columnCount; - } else { - columnCount = g_args.num_of_CPR; - } + int columnCount = (stbInfo)? + stbInfo->columnCount: + g_args.columnCount; for (int col = 0; col < columnCount; col ++) { pstr += sprintf(pstr, ",?"); @@ -8273,6 +9726,9 @@ static void startMultiThreadInsertData(int threads, char* db_name, pstr += sprintf(pstr, ")"); debugPrint("%s() LN%d, stmtBuffer: %s", __func__, __LINE__, stmtBuffer); +#if STMT_BIND_PARAM_BATCH == 1 + parseSamplefileToStmtBatch(stbInfo); +#endif } for (int i = 0; i < threads; i++) { @@ -8316,8 +9772,7 @@ static void startMultiThreadInsertData(int threads, char* db_name, exit(EXIT_FAILURE); } - int ret = taos_stmt_prepare(pThreadInfo->stmt, stmtBuffer, 0); - if (ret != 0) { + if (0 != taos_stmt_prepare(pThreadInfo->stmt, stmtBuffer, 0)) { free(pids); free(infos); free(stmtBuffer); @@ -8328,7 +9783,19 @@ static void startMultiThreadInsertData(int threads, char* db_name, pThreadInfo->bind_ts = malloc(sizeof(int64_t)); if (stbInfo) { - parseSampleFileToStmt(pThreadInfo, stbInfo, timePrec); +#if STMT_BIND_PARAM_BATCH == 1 + parseStbSampleToStmtBatchForThread( + pThreadInfo, stbInfo, timePrec, batch); +#else + parseStbSampleToStmt(pThreadInfo, stbInfo, timePrec); +#endif + } else { +#if STMT_BIND_PARAM_BATCH == 1 + parseNtbSampleToStmtBatchForThread( + pThreadInfo, timePrec, batch); +#else + parseNtbSampleToStmt(pThreadInfo, timePrec); +#endif } } } else { @@ -8373,19 +9840,28 @@ static void startMultiThreadInsertData(int threads, char* db_name, for (int i = 0; i < threads; i++) { threadInfo *pThreadInfo = infos + i; + tsem_destroy(&(pThreadInfo->lock_sem)); + taos_close(pThreadInfo->taos); + if (pThreadInfo->stmt) { taos_stmt_close(pThreadInfo->stmt); - tmfree((char *)pThreadInfo->bind_ts); } - tsem_destroy(&(pThreadInfo->lock_sem)); - taos_close(pThreadInfo->taos); + tmfree((char *)pThreadInfo->bind_ts); +#if STMT_BIND_PARAM_BATCH == 1 + tmfree((char *)pThreadInfo->bind_ts_array); + tmfree(pThreadInfo->bindParams); + tmfree(pThreadInfo->is_null); +#else if (pThreadInfo->sampleBindArray) { - for (int k = 0; k < MAX_SAMPLES_ONCE_FROM_FILE; k++) { + for (int k = 0; k < MAX_SAMPLES; k++) { uintptr_t *tmp = (uintptr_t *)(*(uintptr_t *)( pThreadInfo->sampleBindArray + sizeof(uintptr_t *) * k)); - for (int c = 1; c < pThreadInfo->stbInfo->columnCount + 1; c++) { + int columnCount = (pThreadInfo->stbInfo)? + pThreadInfo->stbInfo->columnCount: + g_args.columnCount; + for (int c = 1; c < columnCount + 1; c++) { TAOS_BIND *bind = (TAOS_BIND *)((char *)tmp + (sizeof(TAOS_BIND) * c)); if (bind) tmfree(bind->buffer); @@ -8394,6 +9870,7 @@ static void startMultiThreadInsertData(int threads, char* db_name, } tmfree(pThreadInfo->sampleBindArray); } +#endif debugPrint("%s() LN%d, [%d] totalInsert=%"PRIu64" totalAffected=%"PRIu64"\n", __func__, __LINE__, @@ -8412,7 +9889,6 @@ static void startMultiThreadInsertData(int threads, char* db_name, if (pThreadInfo->maxDelay > maxDelay) maxDelay = pThreadInfo->maxDelay; if (pThreadInfo->minDelay < minDelay) minDelay = pThreadInfo->minDelay; } - cntDelay -= 1; if (cntDelay == 0) cntDelay = 1; avgDelay = (double)totalDelay / cntDelay; @@ -8427,7 +9903,7 @@ static void startMultiThreadInsertData(int threads, char* db_name, fprintf(stderr, "Spent %.4f seconds to insert rows: %"PRIu64", affected rows: %"PRIu64" with %d thread(s) into %s.%s. %.2f records/second\n\n", tInMs, stbInfo->totalInsertRows, stbInfo->totalAffectedRows, - threads, db_name, stbInfo->sTblName, + threads, db_name, stbInfo->stbName, (double)(stbInfo->totalInsertRows/tInMs)); if (g_fpOfInsertResult) { @@ -8435,7 +9911,7 @@ static void startMultiThreadInsertData(int threads, char* db_name, "Spent %.4f seconds to insert rows: %"PRIu64", affected rows: %"PRIu64" with %d thread(s) into %s.%s. %.2f records/second\n\n", tInMs, stbInfo->totalInsertRows, stbInfo->totalAffectedRows, - threads, db_name, stbInfo->sTblName, + threads, db_name, stbInfo->stbName, (double)(stbInfo->totalInsertRows/tInMs)); } } else { @@ -8488,16 +9964,16 @@ static void *readTable(void *sarg) { return NULL; } - int64_t num_of_DPT; + int64_t insertRows; /* if (pThreadInfo->stbInfo) { - num_of_DPT = pThreadInfo->stbInfo->insertRows; // nrecords_per_table; + insertRows = pThreadInfo->stbInfo->insertRows; // nrecords_per_table; } else { */ - num_of_DPT = g_args.num_of_DPT; + insertRows = g_args.insertRows; // } - int64_t num_of_tables = pThreadInfo->ntables; // rinfo->end_table_to - rinfo->start_table_from + 1; - int64_t totalData = num_of_DPT * num_of_tables; + int64_t ntables = pThreadInfo->ntables; // pThreadInfo->end_table_to - pThreadInfo->start_table_from + 1; + int64_t totalData = insertRows * ntables; bool do_aggreFunc = g_Dbs.do_aggreFunc; int n = do_aggreFunc ? (sizeof(g_aggreFunc) / sizeof(g_aggreFunc[0])) : 2; @@ -8510,8 +9986,8 @@ static void *readTable(void *sarg) { for (int j = 0; j < n; j++) { double totalT = 0; uint64_t count = 0; - for (int64_t i = 0; i < num_of_tables; i++) { - sprintf(command, "select %s from %s%"PRId64" where ts>= %" PRIu64, + for (int64_t i = 0; i < ntables; i++) { + sprintf(command, "SELECT %s FROM %s%"PRId64" WHERE ts>= %" PRIu64, g_aggreFunc[j], tb_prefix, i, sTime); double t = taosGetTimestampMs(); @@ -8539,7 +10015,7 @@ static void *readTable(void *sarg) { fprintf(fp, "|%10s | %"PRId64" | %12.2f | %10.2f |\n", g_aggreFunc[j][0] == '*' ? " * " : g_aggreFunc[j], totalData, - (double)(num_of_tables * num_of_DPT) / totalT, totalT * 1000); + (double)(ntables * insertRows) / totalT, totalT * 1000); printf("select %10s took %.6f second(s)\n", g_aggreFunc[j], totalT * 1000); } fprintf(fp, "\n"); @@ -8564,9 +10040,9 @@ static void *readMetric(void *sarg) { return NULL; } - int64_t num_of_DPT = pThreadInfo->stbInfo->insertRows; - int64_t num_of_tables = pThreadInfo->ntables; // rinfo->end_table_to - rinfo->start_table_from + 1; - int64_t totalData = num_of_DPT * num_of_tables; + int64_t insertRows = pThreadInfo->stbInfo->insertRows; + int64_t ntables = pThreadInfo->ntables; // pThreadInfo->end_table_to - pThreadInfo->start_table_from + 1; + int64_t totalData = insertRows * ntables; bool do_aggreFunc = g_Dbs.do_aggreFunc; int n = do_aggreFunc ? (sizeof(g_aggreFunc) / sizeof(g_aggreFunc[0])) : 2; @@ -8580,7 +10056,7 @@ static void *readMetric(void *sarg) { char condition[COND_BUF_LEN] = "\0"; char tempS[64] = "\0"; - int64_t m = 10 < num_of_tables ? 10 : num_of_tables; + int64_t m = 10 < ntables ? 10 : ntables; for (int64_t i = 1; i <= m; i++) { if (i == 1) { @@ -8590,7 +10066,7 @@ static void *readMetric(void *sarg) { } strncat(condition, tempS, COND_BUF_LEN - 1); - sprintf(command, "select %s from meters where %s", g_aggreFunc[j], condition); + sprintf(command, "SELECT %s FROM meters WHERE %s", g_aggreFunc[j], condition); printf("Where condition: %s\n", condition); fprintf(fp, "%s\n", command); @@ -8615,7 +10091,7 @@ static void *readMetric(void *sarg) { t = taosGetTimestampMs() - t; fprintf(fp, "| Speed: %12.2f(per s) | Latency: %.4f(ms) |\n", - num_of_tables * num_of_DPT / (t * 1000.0), t); + ntables * insertRows / (t * 1000.0), t); printf("select %10s took %.6f second(s)\n\n", g_aggreFunc[j], t * 1000.0); taos_free_result(pSql); @@ -8671,7 +10147,7 @@ static int insertTestProcess() { } free(cmdBuffer); - // pretreatement + // pretreatment if (prepareSampleData() != 0) { if (g_fpOfInsertResult) fclose(g_fpOfInsertResult); @@ -8948,7 +10424,7 @@ static int queryTestProcess() { if (0 != g_queryInfo.superQueryInfo.sqlCount) { getAllChildNameOfSuperTable(taos, g_queryInfo.dbName, - g_queryInfo.superQueryInfo.sTblName, + g_queryInfo.superQueryInfo.stbName, &g_queryInfo.superQueryInfo.childTblName, &g_queryInfo.superQueryInfo.childTblCount); } @@ -9004,7 +10480,7 @@ static int queryTestProcess() { } } - pThreadInfo->taos = NULL;// TODO: workaround to use separate taos connection; + pThreadInfo->taos = NULL;// workaround to use separate taos connection; pthread_create(pids + seq, NULL, specifiedTableQuery, pThreadInfo); @@ -9054,7 +10530,7 @@ static int queryTestProcess() { pThreadInfo->ntables = iend_table_to = i < b ? tableFrom + a : tableFrom + a - 1; tableFrom = pThreadInfo->end_table_to + 1; - pThreadInfo->taos = NULL; // TODO: workaround to use separate taos connection; + pThreadInfo->taos = NULL; // workaround to use separate taos connection; pthread_create(pidsOfSub + i, NULL, superTableQuery, pThreadInfo); } @@ -9081,7 +10557,7 @@ static int queryTestProcess() { tmfree((char*)pidsOfSub); tmfree((char*)infosOfSub); - // taos_close(taos);// TODO: workaround to use separate taos connection; + // taos_close(taos);// workaround to use separate taos connection; uint64_t endTs = taosGetTimestampMs(); uint64_t totalQueried = g_queryInfo.specifiedQueryInfo.totalQueried + @@ -9103,7 +10579,7 @@ static void stable_sub_callback( if (param) fetchResult(res, (threadInfo *)param); - // tao_unscribe() will free result. + // tao_unsubscribe() will free result. } static void specified_sub_callback( @@ -9116,7 +10592,7 @@ static void specified_sub_callback( if (param) fetchResult(res, (threadInfo *)param); - // tao_unscribe() will free result. + // tao_unsubscribe() will free result. } static TAOS_SUB* subscribeImpl( @@ -9441,12 +10917,12 @@ static int subscribeTestProcess() { if (0 != g_queryInfo.superQueryInfo.sqlCount) { getAllChildNameOfSuperTable(taos, g_queryInfo.dbName, - g_queryInfo.superQueryInfo.sTblName, + g_queryInfo.superQueryInfo.stbName, &g_queryInfo.superQueryInfo.childTblName, &g_queryInfo.superQueryInfo.childTblCount); } - taos_close(taos); // TODO: workaround to use separate taos connection; + taos_close(taos); // workaround to use separate taos connection; pthread_t *pids = NULL; threadInfo *infos = NULL; @@ -9456,12 +10932,12 @@ static int subscribeTestProcess() { //==== create threads for query for specified table if (g_queryInfo.specifiedQueryInfo.sqlCount <= 0) { - debugPrint("%s() LN%d, sepcified query sqlCount %d.\n", + debugPrint("%s() LN%d, specified query sqlCount %d.\n", __func__, __LINE__, g_queryInfo.specifiedQueryInfo.sqlCount); } else { if (g_queryInfo.specifiedQueryInfo.concurrent <= 0) { - errorPrint2("%s() LN%d, sepcified query sqlCount %d.\n", + errorPrint2("%s() LN%d, specified query sqlCount %d.\n", __func__, __LINE__, g_queryInfo.specifiedQueryInfo.sqlCount); exit(EXIT_FAILURE); @@ -9488,7 +10964,7 @@ static int subscribeTestProcess() { threadInfo *pThreadInfo = infos + seq; pThreadInfo->threadID = seq; pThreadInfo->querySeq = i; - pThreadInfo->taos = NULL; // TODO: workaround to use separate taos connection; + pThreadInfo->taos = NULL; // workaround to use separate taos connection; pthread_create(pids + seq, NULL, specifiedSubscribe, pThreadInfo); } } @@ -9545,7 +11021,7 @@ static int subscribeTestProcess() { pThreadInfo->ntables = jend_table_to = jend_table_to + 1; - pThreadInfo->taos = NULL; // TODO: workaround to use separate taos connection; + pThreadInfo->taos = NULL; // workaround to use separate taos connection; pthread_create(pidsOfStable + seq, NULL, superSubscribe, pThreadInfo); } @@ -9618,8 +11094,8 @@ static void setParaFromArg() { g_Dbs.port = g_args.port; } - g_Dbs.threadCount = g_args.num_of_threads; - g_Dbs.threadCountForCreateTbl = g_args.num_of_threads; + g_Dbs.threadCount = g_args.nthreads; + g_Dbs.threadCountForCreateTbl = g_args.nthreads; g_Dbs.dbCount = 1; g_Dbs.db[0].drop = true; @@ -9636,22 +11112,23 @@ static void setParaFromArg() { g_Dbs.do_aggreFunc = true; char dataString[TSDB_MAX_BYTES_PER_ROW]; - char **data_type = g_args.datatype; + char *data_type = g_args.data_type; + char **dataType = g_args.dataType; memset(dataString, 0, TSDB_MAX_BYTES_PER_ROW); - if (strcasecmp(data_type[0], "BINARY") == 0 - || strcasecmp(data_type[0], "BOOL") == 0 - || strcasecmp(data_type[0], "NCHAR") == 0 ) { + if ((data_type[0] == TSDB_DATA_TYPE_BINARY) + || (data_type[0] == TSDB_DATA_TYPE_BOOL) + || (data_type[0] == TSDB_DATA_TYPE_NCHAR)) { g_Dbs.do_aggreFunc = false; } if (g_args.use_metric) { g_Dbs.db[0].superTblCount = 1; - tstrncpy(g_Dbs.db[0].superTbls[0].sTblName, "meters", TSDB_TABLE_NAME_LEN); - g_Dbs.db[0].superTbls[0].childTblCount = g_args.num_of_tables; - g_Dbs.threadCount = g_args.num_of_threads; - g_Dbs.threadCountForCreateTbl = g_args.num_of_threads; + tstrncpy(g_Dbs.db[0].superTbls[0].stbName, "meters", TSDB_TABLE_NAME_LEN); + g_Dbs.db[0].superTbls[0].childTblCount = g_args.ntables; + g_Dbs.threadCount = g_args.nthreads; + g_Dbs.threadCountForCreateTbl = g_args.nthreads; g_Dbs.asyncMode = g_args.async_mode; g_Dbs.db[0].superTbls[0].autoCreateTable = PRE_CREATE_SUBTBL; @@ -9671,26 +11148,28 @@ static void setParaFromArg() { "2017-07-14 10:40:00.000", MAX_TB_NAME_SIZE); g_Dbs.db[0].superTbls[0].timeStampStep = g_args.timestamp_step; - g_Dbs.db[0].superTbls[0].insertRows = g_args.num_of_DPT; + g_Dbs.db[0].superTbls[0].insertRows = g_args.insertRows; g_Dbs.db[0].superTbls[0].maxSqlLen = g_args.max_sql_len; g_Dbs.db[0].superTbls[0].columnCount = 0; for (int i = 0; i < MAX_NUM_COLUMNS; i++) { - if (data_type[i] == NULL) { + if (data_type[i] == TSDB_DATA_TYPE_NULL) { break; } + g_Dbs.db[0].superTbls[0].columns[i].data_type = data_type[i]; tstrncpy(g_Dbs.db[0].superTbls[0].columns[i].dataType, - data_type[i], min(DATATYPE_BUFF_LEN, strlen(data_type[i]) + 1)); + dataType[i], min(DATATYPE_BUFF_LEN, strlen(dataType[i]) + 1)); g_Dbs.db[0].superTbls[0].columns[i].dataLen = g_args.binwidth; g_Dbs.db[0].superTbls[0].columnCount++; } - if (g_Dbs.db[0].superTbls[0].columnCount > g_args.num_of_CPR) { - g_Dbs.db[0].superTbls[0].columnCount = g_args.num_of_CPR; + if (g_Dbs.db[0].superTbls[0].columnCount > g_args.columnCount) { + g_Dbs.db[0].superTbls[0].columnCount = g_args.columnCount; } else { for (int i = g_Dbs.db[0].superTbls[0].columnCount; - i < g_args.num_of_CPR; i++) { + i < g_args.columnCount; i++) { + g_Dbs.db[0].superTbls[0].columns[i].data_type = TSDB_DATA_TYPE_INT; tstrncpy(g_Dbs.db[0].superTbls[0].columns[i].dataType, "INT", min(DATATYPE_BUFF_LEN, strlen("INT") + 1)); g_Dbs.db[0].superTbls[0].columns[i].dataLen = 0; @@ -9707,7 +11186,7 @@ static void setParaFromArg() { g_Dbs.db[0].superTbls[0].tags[1].dataLen = g_args.binwidth; g_Dbs.db[0].superTbls[0].tagCount = 2; } else { - g_Dbs.threadCountForCreateTbl = g_args.num_of_threads; + g_Dbs.threadCountForCreateTbl = g_args.nthreads; g_Dbs.db[0].superTbls[0].tagCount = 0; } } @@ -9840,8 +11319,8 @@ static void queryResult() { tstrncpy(pThreadInfo->tb_prefix, g_Dbs.db[0].superTbls[0].childTblPrefix, TBNAME_PREFIX_LEN); } else { - pThreadInfo->ntables = g_args.num_of_tables; - pThreadInfo->end_table_to = g_args.num_of_tables -1; + pThreadInfo->ntables = g_args.ntables; + pThreadInfo->end_table_to = g_args.ntables -1; tstrncpy(pThreadInfo->tb_prefix, g_args.tb_prefix, TSDB_TABLE_NAME_LEN); } diff --git a/src/kit/taosdump/taosdump.c b/src/kit/taosdump/taosdump.c index ae2193a82eb447f0e948abc1757c21cab46ccf34..fe7616fa174f5af707892cf3d251689a60111ed6 100644 --- a/src/kit/taosdump/taosdump.c +++ b/src/kit/taosdump/taosdump.c @@ -1209,14 +1209,14 @@ _dump_db_point: fprintf(fp, "USE %s;\n\n", g_dbInfos[0]->name); - int32_t totalNumOfThread = 1; // 0: all normal talbe into .tables.tmp.0 + int32_t totalNumOfThread = 1; // 0: all normal table into .tables.tmp.0 int normalTblFd = -1; int32_t retCode; int superTblCnt = 0 ; for (int i = 1; g_args.arg_list[i]; i++) { if (taosGetTableRecordInfo(g_args.arg_list[i], &tableRecordInfo, taos) < 0) { - errorPrint("input the invalide table %s\n", + errorPrint("input the invalid table %s\n", g_args.arg_list[i]); continue; } @@ -1341,11 +1341,10 @@ static int taosGetTableDes( return count; } - // if chidl-table have tag, using select tagName from table to get tagValue + // if child-table have tag, using select tagName from table to get tagValue for (int i = 0 ; i < count; i++) { if (strcmp(stableDes->cols[i].note, "TAG") != 0) continue; - sprintf(sqlstr, "select %s from %s.%s", stableDes->cols[i].field, dbName, table); @@ -2443,7 +2442,7 @@ static int taosGetFilesNum(const char *directoryName, } if (fileNum <= 0) { - errorPrint("directory:%s is empry\n", directoryName); + errorPrint("directory:%s is empty\n", directoryName); exit(-1); } @@ -2620,9 +2619,9 @@ static int taosDumpInOneFile(TAOS* taos, FILE* fp, char* fcharset, memcpy(cmd + cmd_len, line, read_len); cmd[read_len + cmd_len]= '\0'; if (queryDbImpl(taos, cmd)) { - errorPrint("%s() LN%d, error sql: linenu:%d, file:%s\n", + errorPrint("%s() LN%d, error sql: lineno:%d, file:%s\n", __func__, __LINE__, lineNo, fileName); - fprintf(g_fpOfResult, "error sql: linenu:%d, file:%s\n", lineNo, fileName); + fprintf(g_fpOfResult, "error sql: lineno:%d, file:%s\n", lineNo, fileName); } memset(cmd, 0, TSDB_MAX_ALLOWED_SQL_LEN); diff --git a/src/mnode/src/mnodeTable.c b/src/mnode/src/mnodeTable.c index 68529ab8a240c2313ae9417bef9f4112759b0c9f..a6158906a7cc77b57244594fe51881e5df0b68c8 100644 --- a/src/mnode/src/mnodeTable.c +++ b/src/mnode/src/mnodeTable.c @@ -1231,7 +1231,9 @@ static int32_t mnodeAddSuperTableTagCb(SMnodeMsg *pMsg, int32_t code) { SSTableObj *pStable = (SSTableObj *)pMsg->pTable; mLInfo("msg:%p, app:%p stable %s, add tag result:%s, numOfTags:%d", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, tstrerror(code), pStable->numOfTags); - + if (code == TSDB_CODE_SUCCESS) { + code = mnodeGetSuperTableMeta(pMsg); + } return code; } @@ -1287,6 +1289,9 @@ static int32_t mnodeDropSuperTableTagCb(SMnodeMsg *pMsg, int32_t code) { SSTableObj *pStable = (SSTableObj *)pMsg->pTable; mLInfo("msg:%p, app:%p stable %s, drop tag result:%s", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, tstrerror(code)); + if (code == TSDB_CODE_SUCCESS) { + code = mnodeGetSuperTableMeta(pMsg); + } return code; } @@ -1321,6 +1326,9 @@ static int32_t mnodeModifySuperTableTagNameCb(SMnodeMsg *pMsg, int32_t code) { SSTableObj *pStable = (SSTableObj *)pMsg->pTable; mLInfo("msg:%p, app:%p stable %s, modify tag result:%s", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, tstrerror(code)); + if (code == TSDB_CODE_SUCCESS) { + code = mnodeGetSuperTableMeta(pMsg); + } return code; } @@ -1376,6 +1384,9 @@ static int32_t mnodeAddSuperTableColumnCb(SMnodeMsg *pMsg, int32_t code) { SSTableObj *pStable = (SSTableObj *)pMsg->pTable; mLInfo("msg:%p, app:%p stable %s, add column result:%s", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, tstrerror(code)); + if (code == TSDB_CODE_SUCCESS) { + code = mnodeGetSuperTableMeta(pMsg); + } return code; } @@ -1444,6 +1455,9 @@ static int32_t mnodeDropSuperTableColumnCb(SMnodeMsg *pMsg, int32_t code) { SSTableObj *pStable = (SSTableObj *)pMsg->pTable; mLInfo("msg:%p, app:%p stable %s, delete column result:%s", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, tstrerror(code)); + if (code == TSDB_CODE_SUCCESS) { + code = mnodeGetSuperTableMeta(pMsg); + } return code; } @@ -1489,6 +1503,9 @@ static int32_t mnodeChangeSuperTableColumnCb(SMnodeMsg *pMsg, int32_t code) { SSTableObj *pStable = (SSTableObj *)pMsg->pTable; mLInfo("msg:%p, app:%p stable %s, change column result:%s", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, tstrerror(code)); + if (code == TSDB_CODE_SUCCESS) { + code = mnodeGetSuperTableMeta(pMsg); + } return code; } diff --git a/src/os/src/darwin/darwinSystem.c b/src/os/src/darwin/darwinSystem.c index 6f296c9fef4f8db5249e90892214c3b928873939..f152e36d7b9f41e5ddf97db3f5d0c4cf2d714632 100644 --- a/src/os/src/darwin/darwinSystem.c +++ b/src/os/src/darwin/darwinSystem.c @@ -31,7 +31,6 @@ void taosCloseDll(void *handle) { int taosSetConsoleEcho(bool on) { -#if 0 #define ECHOFLAGS (ECHO | ECHOE | ECHOK | ECHONL) int err; struct termios term; @@ -52,7 +51,6 @@ int taosSetConsoleEcho(bool on) return -1; } -#endif return 0; } diff --git a/src/plugins/http/inc/httpUtil.h b/src/plugins/http/inc/httpUtil.h index 54c95b6980f8241c3ea6c8e563e0e42c7c737286..21690ebca96d35423e126a9e747d8ce6bb5a43a0 100644 --- a/src/plugins/http/inc/httpUtil.h +++ b/src/plugins/http/inc/httpUtil.h @@ -17,6 +17,7 @@ #define TDENGINE_HTTP_UTIL_H bool httpCheckUsedbSql(char *sql); +bool httpCheckAlterSql(char *sql); void httpTimeToString(int32_t t, char *buf, int32_t buflen); bool httpUrlMatch(HttpContext *pContext, int32_t pos, char *cmp); diff --git a/src/plugins/http/src/httpHandle.c b/src/plugins/http/src/httpHandle.c index d51c774ff269d5790868727941a632d133dd6733..9719d93824b50064ec1cf23677c641428434592c 100644 --- a/src/plugins/http/src/httpHandle.c +++ b/src/plugins/http/src/httpHandle.c @@ -35,6 +35,7 @@ bool httpProcessData(HttpContext* pContext) { if (!httpAlterContextState(pContext, HTTP_CONTEXT_STATE_READY, HTTP_CONTEXT_STATE_HANDLING)) { httpTrace("context:%p, fd:%d, state:%s not in ready state, stop process request", pContext, pContext->fd, httpContextStateStr(pContext->state)); + pContext->error = true; httpCloseContextByApp(pContext); return false; } diff --git a/src/plugins/http/src/httpParser.c b/src/plugins/http/src/httpParser.c index 62b1737f6fe7128ee132727b2870fca5f62b737a..7066f19769754e78dffeed6a40b672584c0310f1 100644 --- a/src/plugins/http/src/httpParser.c +++ b/src/plugins/http/src/httpParser.c @@ -1157,10 +1157,6 @@ static int32_t httpParseChar(HttpParser *parser, const char c, int32_t *again) { httpOnError(parser, HTTP_CODE_INTERNAL_SERVER_ERROR, TSDB_CODE_HTTP_PARSE_ERROR_STATE); } - if (ok != 0) { - pContext->error = true; - } - return ok; } diff --git a/src/plugins/http/src/httpResp.c b/src/plugins/http/src/httpResp.c index 79e728dd456fb8a340e50f9d7e9cbd3c409614db..1d05b455cb5c66e4f492140e1f337210da04caef 100644 --- a/src/plugins/http/src/httpResp.c +++ b/src/plugins/http/src/httpResp.c @@ -147,6 +147,8 @@ void httpSendErrorResp(HttpContext *pContext, int32_t errNo) { httpCode = pContext->parser->httpCode; } + pContext->error = true; + char *httpCodeStr = httpGetStatusDesc(httpCode); httpSendErrorRespImp(pContext, httpCode, httpCodeStr, errNo & 0XFFFF, tstrerror(errNo)); } diff --git a/src/plugins/http/src/httpRestJson.c b/src/plugins/http/src/httpRestJson.c index 47f2d4ff5bcc513aafb8ea8f4e2a85db5a35b12a..13596b0e8a4ea4d183cc4bf75917fd08a9dd7290 100644 --- a/src/plugins/http/src/httpRestJson.c +++ b/src/plugins/http/src/httpRestJson.c @@ -16,6 +16,7 @@ #define _DEFAULT_SOURCE #include "os.h" #include "tglobal.h" +#include "tsclient.h" #include "httpLog.h" #include "httpJson.h" #include "httpRestHandle.h" @@ -62,13 +63,21 @@ void restStartSqlJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result) httpJsonItemToken(jsonBuf); httpJsonToken(jsonBuf, JsonArrStt); + SSqlObj *pObj = (SSqlObj *) result; + bool isAlterSql = (pObj->sqlstr == NULL) ? false : httpCheckAlterSql(pObj->sqlstr); + if (num_fields == 0) { httpJsonItemToken(jsonBuf); httpJsonString(jsonBuf, REST_JSON_AFFECT_ROWS, REST_JSON_AFFECT_ROWS_LEN); } else { - for (int32_t i = 0; i < num_fields; ++i) { + if (isAlterSql == true) { httpJsonItemToken(jsonBuf); - httpJsonString(jsonBuf, fields[i].name, (int32_t)strlen(fields[i].name)); + httpJsonString(jsonBuf, REST_JSON_AFFECT_ROWS, REST_JSON_AFFECT_ROWS_LEN); + } else { + for (int32_t i = 0; i < num_fields; ++i) { + httpJsonItemToken(jsonBuf); + httpJsonString(jsonBuf, fields[i].name, (int32_t)strlen(fields[i].name)); + } } } @@ -99,8 +108,14 @@ void restStartSqlJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result) httpJsonItemToken(jsonBuf); httpJsonToken(jsonBuf, JsonArrStt); - httpJsonItemToken(jsonBuf); - httpJsonString(jsonBuf, fields[i].name, (int32_t)strlen(fields[i].name)); + if (isAlterSql == true) { + httpJsonItemToken(jsonBuf); + httpJsonString(jsonBuf, REST_JSON_AFFECT_ROWS, REST_JSON_AFFECT_ROWS_LEN); + } else { + httpJsonItemToken(jsonBuf); + httpJsonString(jsonBuf, fields[i].name, (int32_t)strlen(fields[i].name)); + } + httpJsonItemToken(jsonBuf); httpJsonInt(jsonBuf, fields[i].type); httpJsonItemToken(jsonBuf); diff --git a/src/plugins/http/src/httpServer.c b/src/plugins/http/src/httpServer.c index f02859f165499b0c69b095599dd47890e644c604..13a0835c3960333c6d12aa443025de5fb95d565e 100644 --- a/src/plugins/http/src/httpServer.c +++ b/src/plugins/http/src/httpServer.c @@ -191,8 +191,6 @@ static void httpProcessHttpData(void *param) { if (httpReadData(pContext)) { (*(pThread->processData))(pContext); atomic_fetch_add_32(&pServer->requestNum, 1); - } else { - httpReleaseContext(pContext/*, false*/); } } } @@ -402,13 +400,17 @@ static bool httpReadData(HttpContext *pContext) { } else if (nread < 0) { if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) { httpDebug("context:%p, fd:%d, read from socket error:%d, wait another event", pContext, pContext->fd, errno); - return false; // later again + continue; // later again } else { httpError("context:%p, fd:%d, read from socket error:%d, close connect", pContext, pContext->fd, errno); + taosCloseSocket(pContext->fd); + httpReleaseContext(pContext/*, false */); return false; } } else { httpError("context:%p, fd:%d, nread:%d, wait another event", pContext, pContext->fd, nread); + taosCloseSocket(pContext->fd); + httpReleaseContext(pContext/*, false */); return false; } } diff --git a/src/plugins/http/src/httpSql.c b/src/plugins/http/src/httpSql.c index 0dd451f72dbd78233ac8f73d552b6815e3a3fab8..602767a6563b3ca3430501c0dbcee65333f1d44b 100644 --- a/src/plugins/http/src/httpSql.c +++ b/src/plugins/http/src/httpSql.c @@ -405,7 +405,6 @@ void httpProcessRequestCb(void *param, TAOS_RES *result, int32_t code) { if (pContext->session == NULL) { httpSendErrorResp(pContext, TSDB_CODE_HTTP_SESSION_FULL); - httpCloseContextByApp(pContext); } else { httpExecCmd(pContext); } diff --git a/src/plugins/http/src/httpUtil.c b/src/plugins/http/src/httpUtil.c index ade50bdad6bf6b0a7a2d43bb354851d90686be49..f30ac7326eef20f4abf5558b288f16f6ee313b42 100644 --- a/src/plugins/http/src/httpUtil.c +++ b/src/plugins/http/src/httpUtil.c @@ -21,6 +21,7 @@ #include "httpResp.h" #include "httpSql.h" #include "httpUtil.h" +#include "ttoken.h" bool httpCheckUsedbSql(char *sql) { if (strstr(sql, "use ") != NULL) { @@ -29,6 +30,17 @@ bool httpCheckUsedbSql(char *sql) { return false; } +bool httpCheckAlterSql(char *sql) { + int32_t index = 0; + + do { + SStrToken t0 = tStrGetToken(sql, &index, false); + if (t0.type != TK_LP) { + return t0.type == TK_ALTER; + } + } while (1); +} + void httpTimeToString(int32_t t, char *buf, int32_t buflen) { memset(buf, 0, (size_t)buflen); char ts[32] = {0}; diff --git a/src/query/inc/qExecutor.h b/src/query/inc/qExecutor.h index eb05882665dc613e111335958ca165349bc3cc1b..82f4f34a57c7d6d10a021fb2e426ff83cb3604e6 100644 --- a/src/query/inc/qExecutor.h +++ b/src/query/inc/qExecutor.h @@ -86,11 +86,18 @@ typedef struct SResultRow { char *key; // start key of current result row } SResultRow; +typedef struct SResultRowCell { + uint64_t groupId; + SResultRow *pRow; +} SResultRowCell; + typedef struct SGroupResInfo { int32_t totalGroup; int32_t currentGroup; int32_t index; SArray* pRows; // SArray + bool ordered; + int32_t position; } SGroupResInfo; /** @@ -284,8 +291,9 @@ typedef struct SQueryRuntimeEnv { SDiskbasedResultBuf* pResultBuf; // query result buffer based on blocked-wised disk file SHashObj* pResultRowHashTable; // quick locate the window object for each result SHashObj* pResultRowListSet; // used to check if current ResultRowInfo has ResultRow object or not + SArray* pResultRowArrayList; // The array list that contains the Result rows char* keyBuf; // window key buffer - SResultRowPool* pool; // window result object pool + SResultRowPool* pool; // The window result objects pool, all the resultRow Objects are allocated and managed by this object. char** prevRow; SArray* prevResult; // intermediate result, SArray diff --git a/src/query/inc/sql.y b/src/query/inc/sql.y index d72bcacddcdfe1c9e1a59eff3f94b474a4e4839e..336e8620f210351471bddb9c94d56fcaa7f8a0fc 100644 --- a/src/query/inc/sql.y +++ b/src/query/inc/sql.y @@ -11,7 +11,7 @@ %left OR. %left AND. %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 BITAND BITOR LSHIFT RSHIFT. %left PLUS MINUS. @@ -753,6 +753,7 @@ expr(A) ::= expr(X) LIKE expr(Y). {A = tSqlExprCreate(X, Y, TK_LIKE); } // match expression 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 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 %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 - 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. diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 6af4be6d44cfe44e0c7d54dbf0454faa1660bead..b548bd33784574265cdcbf662943f16ef03c2444 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -544,6 +544,8 @@ static SResultRow* doSetResultOutBufByKey(SQueryRuntimeEnv* pRuntimeEnv, SResult // add a new result set for a new group taosHashPut(pRuntimeEnv->pResultRowHashTable, pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes), &pResult, POINTER_BYTES); + SResultRowCell cell = {.groupId = tableGroupId, .pRow = pResult}; + taosArrayPush(pRuntimeEnv->pResultRowArrayList, &cell); } else { pResult = *p1; } @@ -2107,9 +2109,10 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf pRuntimeEnv->pQueryAttr = pQueryAttr; pRuntimeEnv->pResultRowHashTable = taosHashInit(numOfTables, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK); - pRuntimeEnv->pResultRowListSet = taosHashInit(numOfTables, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK); + pRuntimeEnv->pResultRowListSet = taosHashInit(numOfTables * 10, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK); pRuntimeEnv->keyBuf = malloc(pQueryAttr->maxTableColumnWidth + sizeof(int64_t) + POINTER_BYTES); pRuntimeEnv->pool = initResultRowPool(getResultRowSize(pRuntimeEnv)); + pRuntimeEnv->pResultRowArrayList = taosArrayInit(numOfTables, sizeof(SResultRowCell)); pRuntimeEnv->prevRow = malloc(POINTER_BYTES * pQueryAttr->numOfCols + pQueryAttr->srcRowSize); pRuntimeEnv->tagVal = malloc(pQueryAttr->tagLen); @@ -2384,6 +2387,7 @@ static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) { pRuntimeEnv->pool = destroyResultRowPool(pRuntimeEnv->pool); taosArrayDestroyEx(pRuntimeEnv->prevResult, freeInterResult); + taosArrayDestroy(pRuntimeEnv->pResultRowArrayList); pRuntimeEnv->prevResult = NULL; } @@ -2398,11 +2402,11 @@ bool isQueryKilled(SQInfo *pQInfo) { // query has been executed more than tsShellActivityTimer, and the retrieve has not arrived // abort current query execution. - if (pQInfo->owner != 0 && ((taosGetTimestampSec() - pQInfo->startExecTs) > getMaximumIdleDurationSec()) && + if (pQInfo->owner != 0 && ((taosGetTimestampSec() - pQInfo->startExecTs/1000) > getMaximumIdleDurationSec()) && (!needBuildResAfterQueryComplete(pQInfo))) { assert(pQInfo->startExecTs != 0); - qDebug("QInfo:%" PRIu64 " retrieve not arrive beyond %d sec, abort current query execution, start:%" PRId64 + qDebug("QInfo:%" PRIu64 " retrieve not arrive beyond %d ms, abort current query execution, start:%" PRId64 ", current:%d", pQInfo->qId, 1, pQInfo->startExecTs, taosGetTimestampSec()); return true; } @@ -4833,7 +4837,6 @@ int32_t doInitQInfo(SQInfo* pQInfo, STSBuf* pTsBuf, void* tsdb, void* sourceOptr SQueryAttr *pQueryAttr = pQInfo->runtimeEnv.pQueryAttr; pQueryAttr->tsdb = tsdb; - if (tsdb != NULL) { int32_t code = setupQueryHandle(tsdb, pRuntimeEnv, pQInfo->qId, pQueryAttr->stableQuery); if (code != TSDB_CODE_SUCCESS) { @@ -6404,6 +6407,7 @@ static SSDataBlock* hashGroupbyAggregate(void* param, bool* newgroup) { if (!pRuntimeEnv->pQueryAttr->stableQuery) { sortGroupResByOrderList(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pInfo->binfo.pRes); } + toSSDataBlock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pInfo->binfo.pRes); if (pInfo->binfo.pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pRuntimeEnv->groupResInfo)) { @@ -7623,8 +7627,8 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { pMsg += sizeof(SSqlExpr); for (int32_t j = 0; j < pExprMsg->numOfParams; ++j) { - pExprMsg->param[j].nType = htons(pExprMsg->param[j].nType); - pExprMsg->param[j].nLen = htons(pExprMsg->param[j].nLen); + pExprMsg->param[j].nType = htonl(pExprMsg->param[j].nType); + pExprMsg->param[j].nLen = htonl(pExprMsg->param[j].nLen); if (pExprMsg->param[j].nType == TSDB_DATA_TYPE_BINARY) { pExprMsg->param[j].pz = pMsg; @@ -7671,8 +7675,8 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { pMsg += sizeof(SSqlExpr); for (int32_t j = 0; j < pExprMsg->numOfParams; ++j) { - pExprMsg->param[j].nType = htons(pExprMsg->param[j].nType); - pExprMsg->param[j].nLen = htons(pExprMsg->param[j].nLen); + pExprMsg->param[j].nType = htonl(pExprMsg->param[j].nType); + pExprMsg->param[j].nLen = htonl(pExprMsg->param[j].nLen); if (pExprMsg->param[j].nType == TSDB_DATA_TYPE_BINARY) { pExprMsg->param[j].pz = pMsg; @@ -8421,6 +8425,7 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SGroupbyExpr* pGroupbyExpr, S } pQInfo->qId = qId; + pQInfo->startExecTs = 0; pQInfo->runtimeEnv.pUdfInfo = pUdfInfo; @@ -8659,7 +8664,6 @@ int32_t initQInfo(STsBufInfo* pTsBufInfo, void* tsdb, void* sourceOptr, SQInfo* SArray* prevResult = NULL; if (prevResultLen > 0) { prevResult = interResFromBinary(param->prevResult, prevResultLen); - pRuntimeEnv->prevResult = prevResult; } diff --git a/src/query/src/qFilter.c b/src/query/src/qFilter.c index 31b7f92d39452f89cb87e1ee04ca6c832e394ff9..2737fdf25077407300ee58388c92f3af1467cf7e 100644 --- a/src/query/src/qFilter.c +++ b/src/query/src/qFilter.c @@ -34,7 +34,8 @@ OptrStr gOptrStr[] = { {TSDB_RELATION_AND, "and"}, {TSDB_RELATION_OR, "or"}, {TSDB_RELATION_NOT, "not"}, - {TSDB_RELATION_MATCH, "match"} + {TSDB_RELATION_MATCH, "match"}, + {TSDB_RELATION_NMATCH, "nmatch"}, }; static FORCE_INLINE int32_t filterFieldColDescCompare(const void *desc1, const void *desc2) { @@ -157,7 +158,7 @@ int8_t filterGetRangeCompFuncFromOptrs(uint8_t optr, uint8_t optr2) { __compar_fn_t gDataCompare[] = {compareInt32Val, compareInt8Val, compareInt16Val, compareInt64Val, compareFloatVal, compareDoubleVal, compareLenPrefixedStr, compareStrPatternComp, compareFindItemInSet, compareWStrPatternComp, 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) { @@ -198,6 +199,8 @@ int8_t filterGetCompFuncIdx(int32_t type, int32_t optr) { case TSDB_DATA_TYPE_BINARY: { if (optr == TSDB_RELATION_MATCH) { comparFn = 19; + } else if (optr == TSDB_RELATION_NMATCH) { + comparFn = 20; } else if (optr == TSDB_RELATION_LIKE) { /* wildcard query using like operator */ comparFn = 7; } else if (optr == TSDB_RELATION_IN) { @@ -212,6 +215,8 @@ int8_t filterGetCompFuncIdx(int32_t type, int32_t optr) { case TSDB_DATA_TYPE_NCHAR: { if (optr == TSDB_RELATION_MATCH) { comparFn = 19; + } else if (optr == TSDB_RELATION_NMATCH) { + comparFn = 20; } else if (optr == TSDB_RELATION_LIKE) { comparFn = 9; } else if (optr == TSDB_RELATION_IN) { @@ -1866,6 +1871,9 @@ bool filterDoCompare(__compar_fn_t func, uint8_t optr, void *left, void *right) case TSDB_RELATION_MATCH: { return ret == 0; } + case TSDB_RELATION_NMATCH: { + return ret == 0; + } case TSDB_RELATION_IN: { return ret == 1; } diff --git a/src/query/src/qUtil.c b/src/query/src/qUtil.c index 4caf351799adbf000265566fb22617067efb725d..bc27e094db3dcb85ffa73810e922d73cd42ab3a0 100644 --- a/src/query/src/qUtil.c +++ b/src/query/src/qUtil.c @@ -436,13 +436,13 @@ static int32_t tableResultComparFn(const void *pLeft, const void *pRight, void * } STableQueryInfo** pList = supporter->pTableQueryInfo; - - SResultRowInfo *pWindowResInfo1 = &(pList[left]->resInfo); - SResultRow * pWindowRes1 = getResultRow(pWindowResInfo1, leftPos); + SResultRow* pWindowRes1 = pList[left]->resInfo.pResult[leftPos]; +// SResultRow * pWindowRes1 = getResultRow(&(pList[left]->resInfo), leftPos); TSKEY leftTimestamp = pWindowRes1->win.skey; - SResultRowInfo *pWindowResInfo2 = &(pList[right]->resInfo); - SResultRow * pWindowRes2 = getResultRow(pWindowResInfo2, rightPos); +// SResultRowInfo *pWindowResInfo2 = &(pList[right]->resInfo); +// SResultRow * pWindowRes2 = getResultRow(pWindowResInfo2, rightPos); + SResultRow* pWindowRes2 = pList[right]->resInfo.pResult[rightPos]; TSKEY rightTimestamp = pWindowRes2->win.skey; if (leftTimestamp == rightTimestamp) { @@ -456,7 +456,77 @@ static int32_t tableResultComparFn(const void *pLeft, const void *pRight, void * } } -static int32_t mergeIntoGroupResultImpl(SQueryRuntimeEnv *pRuntimeEnv, SGroupResInfo* pGroupResInfo, SArray *pTableList, +int32_t tsAscOrder(const void* p1, const void* p2) { + SResultRowCell* pc1 = (SResultRowCell*) p1; + SResultRowCell* pc2 = (SResultRowCell*) p2; + + if (pc1->groupId == pc2->groupId) { + if (pc1->pRow->win.skey == pc2->pRow->win.skey) { + return 0; + } else { + return (pc1->pRow->win.skey < pc2->pRow->win.skey)? -1:1; + } + } else { + return (pc1->groupId < pc2->groupId)? -1:1; + } +} + +int32_t tsDescOrder(const void* p1, const void* p2) { + SResultRowCell* pc1 = (SResultRowCell*) p1; + SResultRowCell* pc2 = (SResultRowCell*) p2; + + if (pc1->groupId == pc2->groupId) { + if (pc1->pRow->win.skey == pc2->pRow->win.skey) { + return 0; + } else { + return (pc1->pRow->win.skey < pc2->pRow->win.skey)? 1:-1; + } + } else { + return (pc1->groupId < pc2->groupId)? -1:1; + } +} + +void orderTheResultRows(SQueryRuntimeEnv* pRuntimeEnv) { + __compar_fn_t fn = NULL; + if (pRuntimeEnv->pQueryAttr->order.order == TSDB_ORDER_ASC) { + fn = tsAscOrder; + } else { + fn = tsDescOrder; + } + + taosArraySort(pRuntimeEnv->pResultRowArrayList, fn); +} + +static int32_t mergeIntoGroupResultImplRv(SQueryRuntimeEnv *pRuntimeEnv, SGroupResInfo* pGroupResInfo, uint64_t groupId, int32_t* rowCellInfoOffset) { + if (!pGroupResInfo->ordered) { + orderTheResultRows(pRuntimeEnv); + pGroupResInfo->ordered = true; + } + + if (pGroupResInfo->pRows == NULL) { + pGroupResInfo->pRows = taosArrayInit(100, POINTER_BYTES); + } + + size_t len = taosArrayGetSize(pRuntimeEnv->pResultRowArrayList); + for(; pGroupResInfo->position < len; ++pGroupResInfo->position) { + SResultRowCell* pResultRowCell = taosArrayGet(pRuntimeEnv->pResultRowArrayList, pGroupResInfo->position); + if (pResultRowCell->groupId != groupId) { + break; + } + + int64_t num = getNumOfResultWindowRes(pRuntimeEnv, pResultRowCell->pRow, rowCellInfoOffset); + if (num <= 0) { + continue; + } + + taosArrayPush(pGroupResInfo->pRows, &pResultRowCell->pRow); + pResultRowCell->pRow->numOfRows = (uint32_t) num; + } + + return TSDB_CODE_SUCCESS; +} + +static UNUSED_FUNC int32_t mergeIntoGroupResultImpl(SQueryRuntimeEnv *pRuntimeEnv, SGroupResInfo* pGroupResInfo, SArray *pTableList, int32_t* rowCellInfoOffset) { bool ascQuery = QUERY_IS_ASC_QUERY(pRuntimeEnv->pQueryAttr); @@ -562,12 +632,7 @@ int32_t mergeIntoGroupResult(SGroupResInfo* pGroupResInfo, SQueryRuntimeEnv* pRu int64_t st = taosGetTimestampUs(); while (pGroupResInfo->currentGroup < pGroupResInfo->totalGroup) { - SArray *group = GET_TABLEGROUP(pRuntimeEnv, pGroupResInfo->currentGroup); - - int32_t ret = mergeIntoGroupResultImpl(pRuntimeEnv, pGroupResInfo, group, offset); - if (ret != TSDB_CODE_SUCCESS) { - return ret; - } + mergeIntoGroupResultImplRv(pRuntimeEnv, pGroupResInfo, pGroupResInfo->currentGroup, offset); // this group generates at least one result, return results if (taosArrayGetSize(pGroupResInfo->pRows) > 0) { @@ -583,7 +648,6 @@ int32_t mergeIntoGroupResult(SGroupResInfo* pGroupResInfo, SQueryRuntimeEnv* pRu qDebug("QInfo:%"PRIu64" merge res data into group, index:%d, total group:%d, elapsed time:%" PRId64 "us", GET_QID(pRuntimeEnv), pGroupResInfo->currentGroup, pGroupResInfo->totalGroup, elapsedTime); -// pQInfo->summary.firstStageMergeTime += elapsedTime; return TSDB_CODE_SUCCESS; } diff --git a/src/query/src/queryMain.c b/src/query/src/queryMain.c index 786318425b83c75a55be9d7527fc4f3b4ab93fec..c6e6eddce7d8f56095d5d78f4d1f84ed1d4f3c97 100644 --- a/src/query/src/queryMain.c +++ b/src/query/src/queryMain.c @@ -35,7 +35,7 @@ typedef struct SQueryMgmt { bool closed; } SQueryMgmt; -static void queryMgmtKillQueryFn(void* handle) { +static void queryMgmtKillQueryFn(void* handle, void* param1) { void** fp = (void**)handle; qKillQuery(*fp); } @@ -214,6 +214,51 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, qi return code; } +#ifdef TEST_IMPL +// wait moment +int waitMoment(SQInfo* pQInfo){ + if(pQInfo->sql) { + int ms = 0; + char* pcnt = strstr(pQInfo->sql, " count(*)"); + if(pcnt) return 0; + + char* pos = strstr(pQInfo->sql, " t_"); + if(pos){ + pos += 3; + ms = atoi(pos); + while(*pos >= '0' && *pos <= '9'){ + pos ++; + } + char unit_char = *pos; + if(unit_char == 'h'){ + ms *= 3600*1000; + } else if(unit_char == 'm'){ + ms *= 60*1000; + } else if(unit_char == 's'){ + ms *= 1000; + } + } + if(ms == 0) return 0; + printf("test wait sleep %dms. sql=%s ...\n", ms, pQInfo->sql); + + if(ms < 1000) { + taosMsleep(ms); + } else { + int used_ms = 0; + while(used_ms < ms) { + taosMsleep(1000); + used_ms += 1000; + if(isQueryKilled(pQInfo)){ + printf("test check query is canceled, sleep break.%s\n", pQInfo->sql); + break; + } + } + } + } + return 1; +} +#endif + bool qTableQuery(qinfo_t qinfo, uint64_t *qId) { SQInfo *pQInfo = (SQInfo *)qinfo; assert(pQInfo && pQInfo->signature == pQInfo); @@ -227,7 +272,8 @@ bool qTableQuery(qinfo_t qinfo, uint64_t *qId) { } *qId = pQInfo->qId; - pQInfo->startExecTs = taosGetTimestampSec(); + if(pQInfo->startExecTs == 0) + pQInfo->startExecTs = taosGetTimestampMs(); if (isQueryKilled(pQInfo)) { qDebug("QInfo:0x%"PRIx64" it is already killed, abort", pQInfo->qId); @@ -258,7 +304,9 @@ bool qTableQuery(qinfo_t qinfo, uint64_t *qId) { int64_t st = taosGetTimestampUs(); pRuntimeEnv->outputBuf = pRuntimeEnv->proot->exec(pRuntimeEnv->proot, &newgroup); pQInfo->summary.elapsedTime += (taosGetTimestampUs() - st); - +#ifdef TEST_IMPL + waitMoment(pQInfo); +#endif publishOperatorProfEvent(pRuntimeEnv->proot, QUERY_PROF_AFTER_OPERATOR_EXEC); pRuntimeEnv->resultInfo.total += GET_NUM_OF_RESULTS(pRuntimeEnv); @@ -478,7 +526,7 @@ void qQueryMgmtNotifyClosed(void* pQMgmt) { pQueryMgmt->closed = true; pthread_mutex_unlock(&pQueryMgmt->lock); - taosCacheRefresh(pQueryMgmt->qinfoPool, queryMgmtKillQueryFn); + taosCacheRefresh(pQueryMgmt->qinfoPool, queryMgmtKillQueryFn, NULL); } void qQueryMgmtReOpen(void *pQMgmt) { @@ -573,3 +621,148 @@ void** qReleaseQInfo(void* pMgmt, void* pQInfo, bool freeHandle) { taosCacheRelease(pQueryMgmt->qinfoPool, pQInfo, freeHandle); return 0; } + +//kill by qid +int32_t qKillQueryByQId(void* pMgmt, int64_t qId, int32_t waitMs, int32_t waitCount) { + int32_t error = TSDB_CODE_SUCCESS; + void** handle = qAcquireQInfo(pMgmt, qId); + if(handle == NULL) return terrno; + + SQInfo* pQInfo = (SQInfo*)(*handle); + if (pQInfo == NULL || !isValidQInfo(pQInfo)) { + return TSDB_CODE_QRY_INVALID_QHANDLE; + } + qWarn("QId:0x%"PRIx64" be killed(no memory commit).", pQInfo->qId); + setQueryKilled(pQInfo); + + // wait query stop + int32_t loop = 0; + while (pQInfo->owner != 0) { + taosMsleep(waitMs); + if(loop++ > waitCount){ + error = TSDB_CODE_FAILED; + break; + } + } + + qReleaseQInfo(pMgmt, (void **)&handle, true); + return error; +} + +// local struct +typedef struct { + int64_t qId; + int64_t startExecTs; +} SLongQuery; + +// callbark for sort compare +static int compareLongQuery(const void* p1, const void* p2) { + // sort desc + SLongQuery* plq1 = *(SLongQuery**)p1; + SLongQuery* plq2 = *(SLongQuery**)p2; + if(plq1->startExecTs == plq2->startExecTs) { + return 0; + } else if(plq1->startExecTs > plq2->startExecTs) { + return 1; + } else { + return -1; + } +} + +// callback for taosCacheRefresh +static void cbFoundItem(void* handle, void* param1) { + SQInfo * qInfo = *(SQInfo**) handle; + if(qInfo == NULL) return ; + SArray* qids = (SArray*) param1; + if(qids == NULL) return ; + + bool usedMem = true; + bool usedIMem = true; + SMemTable* mem = qInfo->query.memRef.snapshot.omem; + SMemTable* imem = qInfo->query.memRef.snapshot.imem; + if(mem == NULL || T_REF_VAL_GET(mem) == 0) + usedMem = false; + if(imem == NULL || T_REF_VAL_GET(mem) == 0) + usedIMem = false ; + + if(!usedMem && !usedIMem) + return ; + + // push to qids + SLongQuery* plq = (SLongQuery*)malloc(sizeof(SLongQuery)); + plq->qId = qInfo->qId; + plq->startExecTs = qInfo->startExecTs; + taosArrayPush(qids, &plq); +} + +// longquery +void* qObtainLongQuery(void* param){ + SQueryMgmt* qMgmt = (SQueryMgmt*)param; + if(qMgmt == NULL || qMgmt->qinfoPool == NULL) + return NULL; + SArray* qids = taosArrayInit(4, sizeof(int64_t*)); + if(qids == NULL) return NULL; + // Get each item + taosCacheRefresh(qMgmt->qinfoPool, cbFoundItem, qids); + + size_t cnt = taosArrayGetSize(qids); + if(cnt == 0) { + taosArrayDestroy(qids); + return NULL; + } + if(cnt > 1) + taosArraySort(qids, compareLongQuery); + + return qids; +} + +//solve tsdb no block to commit +bool qFixedNoBlock(void* pRepo, void* pMgmt, int32_t longQueryMs) { + SQueryMgmt *pQueryMgmt = pMgmt; + bool fixed = false; + + // qid top list + SArray *qids = (SArray*)qObtainLongQuery(pQueryMgmt); + if(qids == NULL) return false; + + // kill Query + int64_t now = taosGetTimestampMs(); + size_t cnt = taosArrayGetSize(qids); + size_t i; + SLongQuery* plq; + for(i=0; i < cnt; i++) { + plq = (SLongQuery* )taosArrayGetP(qids, i); + if(plq->startExecTs > now) continue; + if(now - plq->startExecTs >= longQueryMs) { + qKillQueryByQId(pMgmt, plq->qId, 500, 10); // wait 50*100 ms + if(tsdbNoProblem(pRepo)) { + fixed = true; + qWarn("QId:0x%"PRIx64" fixed problem after kill this query.", plq->qId); + break; + } + } + } + + // free qids + for(i=0; i < cnt; i++) { + free(taosArrayGetP(qids, i)); + } + taosArrayDestroy(qids); + return fixed; +} + +//solve tsdb no block to commit +bool qSolveCommitNoBlock(void* pRepo, void* pMgmt) { + qWarn("pRepo=%p start solve problem.", pRepo); + if(qFixedNoBlock(pRepo, pMgmt, 10*60*1000)) { + return true; + } + if(qFixedNoBlock(pRepo, pMgmt, 2*60*1000)){ + return true; + } + if(qFixedNoBlock(pRepo, pMgmt, 30*1000)){ + return true; + } + qWarn("pRepo=%p solve problem failed.", pRepo); + return false; +} diff --git a/src/query/src/sql.c b/src/query/src/sql.c index f66c2968a6cebf805579dc3fe4c123331f9ecfc8..e89b6232f7e42b764df7660f06dcd207bfe6e4de 100644 --- a/src/query/src/sql.c +++ b/src/query/src/sql.c @@ -102,29 +102,29 @@ #endif /************* Begin control #defines *****************************************/ #define YYCODETYPE unsigned short int -#define YYNOCODE 277 +#define YYNOCODE 278 #define YYACTIONTYPE unsigned short int #define ParseTOKENTYPE SStrToken typedef union { int yyinit; ParseTOKENTYPE yy0; - SCreateTableSql* yy56; - int yy70; - SCreatedTableInfo yy84; - SRelationInfo* yy114; - int32_t yy202; - SIntervalVal yy222; - SSqlNode* yy224; - SCreateDbInfo yy246; - tSqlExpr* yy260; - TAOS_FIELD yy363; - SSessionWindowVal yy365; - SCreateAcctInfo yy377; - int64_t yy387; - SArray* yy403; - SLimitVal yy404; - tVariant yy488; - SWindowStateVal yy544; + SRelationInfo* yy8; + SWindowStateVal yy40; + SSqlNode* yy56; + SCreateDbInfo yy90; + int yy96; + int32_t yy104; + SSessionWindowVal yy147; + SCreatedTableInfo yy152; + SLimitVal yy166; + SCreateAcctInfo yy171; + TAOS_FIELD yy183; + int64_t yy325; + SIntervalVal yy400; + SArray* yy421; + tVariant yy430; + SCreateTableSql* yy438; + tSqlExpr* yy439; } YYMINORTYPE; #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 @@ -140,18 +140,18 @@ typedef union { #define ParseCTX_FETCH #define ParseCTX_STORE #define YYFALLBACK 1 -#define YYNSTATE 366 -#define YYNRULE 293 -#define YYNRULE_WITH_ACTION 293 -#define YYNTOKEN 196 -#define YY_MAX_SHIFT 365 -#define YY_MIN_SHIFTREDUCE 574 -#define YY_MAX_SHIFTREDUCE 866 -#define YY_ERROR_ACTION 867 -#define YY_ACCEPT_ACTION 868 -#define YY_NO_ACTION 869 -#define YY_MIN_REDUCE 870 -#define YY_MAX_REDUCE 1162 +#define YYNSTATE 368 +#define YYNRULE 294 +#define YYNRULE_WITH_ACTION 294 +#define YYNTOKEN 197 +#define YY_MAX_SHIFT 367 +#define YY_MIN_SHIFTREDUCE 576 +#define YY_MAX_SHIFTREDUCE 869 +#define YY_ERROR_ACTION 870 +#define YY_ACCEPT_ACTION 871 +#define YY_NO_ACTION 872 +#define YY_MIN_REDUCE 873 +#define YY_MAX_REDUCE 1166 /************* End control #defines *******************************************/ #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) @@ -218,291 +218,292 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (766) +#define YY_ACTTAB_COUNT (773) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 1020, 626, 239, 626, 364, 233, 1026, 1039, 210, 627, - /* 10 */ 662, 627, 38, 58, 59, 38, 62, 63, 1048, 1138, - /* 20 */ 253, 52, 51, 236, 61, 322, 66, 64, 67, 65, - /* 30 */ 1039, 810, 245, 813, 57, 56, 1026, 23, 55, 54, - /* 40 */ 53, 58, 59, 626, 62, 63, 237, 246, 253, 52, - /* 50 */ 51, 627, 61, 322, 66, 64, 67, 65, 868, 365, - /* 60 */ 235, 1022, 57, 56, 1023, 250, 55, 54, 53, 988, - /* 70 */ 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, - /* 80 */ 986, 987, 989, 990, 156, 29, 1045, 81, 575, 576, - /* 90 */ 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, - /* 100 */ 587, 588, 154, 163, 234, 172, 58, 59, 1039, 62, - /* 110 */ 63, 1012, 804, 253, 52, 51, 72, 61, 322, 66, - /* 120 */ 64, 67, 65, 284, 275, 210, 352, 57, 56, 262, - /* 130 */ 163, 55, 54, 53, 58, 60, 1139, 62, 63, 75, - /* 140 */ 177, 253, 52, 51, 626, 61, 322, 66, 64, 67, - /* 150 */ 65, 817, 627, 282, 281, 57, 56, 267, 73, 55, - /* 160 */ 54, 53, 59, 163, 62, 63, 271, 270, 253, 52, - /* 170 */ 51, 320, 61, 322, 66, 64, 67, 65, 1087, 76, - /* 180 */ 294, 247, 57, 56, 207, 1026, 55, 54, 53, 62, - /* 190 */ 63, 38, 249, 253, 52, 51, 320, 61, 322, 66, - /* 200 */ 64, 67, 65, 296, 710, 92, 87, 57, 56, 769, - /* 210 */ 770, 55, 54, 53, 44, 318, 359, 358, 317, 316, - /* 220 */ 315, 357, 314, 313, 312, 356, 311, 355, 354, 24, - /* 230 */ 163, 252, 819, 342, 341, 808, 243, 811, 1086, 814, - /* 240 */ 1023, 252, 819, 45, 208, 808, 213, 811, 254, 814, - /* 250 */ 57, 56, 210, 220, 55, 54, 53, 96, 262, 138, - /* 260 */ 137, 136, 219, 1139, 231, 232, 327, 87, 323, 178, - /* 270 */ 99, 5, 41, 181, 231, 232, 360, 957, 180, 105, - /* 280 */ 110, 101, 109, 363, 362, 147, 66, 64, 67, 65, - /* 290 */ 1009, 1010, 35, 1013, 57, 56, 919, 307, 55, 54, - /* 300 */ 53, 256, 929, 191, 45, 93, 1014, 734, 210, 191, - /* 310 */ 731, 38, 732, 68, 733, 261, 262, 214, 44, 1139, - /* 320 */ 359, 358, 124, 68, 215, 357, 274, 1024, 79, 356, - /* 330 */ 1134, 355, 354, 1133, 352, 227, 122, 116, 127, 258, - /* 340 */ 259, 750, 809, 126, 812, 132, 135, 125, 820, 815, - /* 350 */ 920, 1025, 38, 38, 129, 816, 244, 191, 820, 815, - /* 360 */ 1023, 201, 199, 197, 38, 816, 80, 38, 196, 142, - /* 370 */ 141, 140, 139, 996, 14, 994, 995, 257, 95, 255, - /* 380 */ 997, 330, 329, 786, 998, 38, 999, 1000, 38, 324, - /* 390 */ 38, 263, 84, 260, 85, 337, 336, 331, 332, 38, - /* 400 */ 1011, 1023, 1023, 55, 54, 53, 94, 1132, 98, 333, - /* 410 */ 1, 179, 334, 1023, 3, 192, 1023, 153, 151, 150, - /* 420 */ 82, 747, 276, 735, 736, 34, 754, 766, 776, 278, - /* 430 */ 338, 278, 777, 339, 1023, 340, 39, 1023, 806, 1023, - /* 440 */ 785, 158, 69, 720, 344, 299, 26, 9, 1023, 251, - /* 450 */ 722, 301, 721, 841, 821, 625, 78, 39, 302, 39, - /* 460 */ 229, 16, 818, 15, 69, 97, 69, 25, 25, 25, - /* 470 */ 115, 6, 114, 1158, 18, 807, 17, 739, 737, 740, - /* 480 */ 738, 20, 121, 19, 120, 22, 230, 21, 709, 134, - /* 490 */ 133, 211, 823, 212, 216, 1150, 209, 1097, 217, 218, - /* 500 */ 222, 223, 224, 221, 206, 1096, 241, 1093, 1092, 242, - /* 510 */ 343, 272, 155, 48, 1047, 1058, 1055, 1056, 1060, 157, - /* 520 */ 1040, 279, 1079, 162, 290, 1078, 173, 1021, 174, 1019, - /* 530 */ 175, 176, 934, 283, 238, 152, 167, 165, 304, 305, - /* 540 */ 765, 1037, 164, 306, 309, 310, 285, 46, 204, 42, - /* 550 */ 321, 928, 287, 328, 1157, 112, 1156, 77, 1153, 297, - /* 560 */ 182, 335, 1149, 74, 50, 166, 295, 168, 293, 291, - /* 570 */ 118, 289, 286, 1148, 1145, 183, 954, 43, 40, 47, - /* 580 */ 205, 916, 128, 914, 130, 131, 49, 912, 911, 264, - /* 590 */ 194, 195, 908, 907, 906, 905, 904, 903, 902, 198, - /* 600 */ 200, 899, 897, 895, 893, 202, 890, 203, 308, 886, - /* 610 */ 353, 123, 277, 83, 88, 345, 288, 1080, 346, 347, - /* 620 */ 348, 349, 228, 350, 351, 248, 303, 361, 866, 265, - /* 630 */ 266, 865, 269, 225, 226, 268, 864, 847, 846, 933, - /* 640 */ 932, 106, 107, 273, 278, 10, 298, 742, 280, 86, - /* 650 */ 30, 910, 909, 89, 767, 143, 159, 144, 955, 186, - /* 660 */ 184, 185, 188, 187, 189, 190, 901, 2, 145, 992, - /* 670 */ 900, 892, 171, 169, 33, 170, 956, 146, 891, 4, - /* 680 */ 778, 160, 161, 772, 90, 240, 774, 1002, 91, 292, - /* 690 */ 31, 11, 32, 12, 13, 27, 300, 28, 98, 100, - /* 700 */ 103, 36, 102, 640, 37, 104, 675, 673, 672, 671, - /* 710 */ 669, 668, 667, 664, 630, 319, 108, 7, 824, 822, - /* 720 */ 325, 8, 326, 111, 113, 70, 71, 117, 39, 712, - /* 730 */ 119, 711, 708, 656, 654, 646, 652, 648, 650, 644, - /* 740 */ 642, 678, 677, 676, 674, 670, 666, 665, 193, 628, - /* 750 */ 592, 870, 869, 869, 869, 869, 869, 869, 869, 869, - /* 760 */ 869, 869, 869, 869, 148, 149, + /* 0 */ 23, 628, 366, 235, 1051, 208, 241, 712, 211, 629, + /* 10 */ 1029, 871, 367, 59, 60, 173, 63, 64, 1042, 1142, + /* 20 */ 255, 53, 52, 51, 628, 62, 324, 67, 65, 68, + /* 30 */ 66, 157, 629, 286, 238, 58, 57, 344, 343, 56, + /* 40 */ 55, 54, 59, 60, 247, 63, 64, 252, 1029, 255, + /* 50 */ 53, 52, 51, 209, 62, 324, 67, 65, 68, 66, + /* 60 */ 999, 1042, 997, 998, 58, 57, 664, 1000, 56, 55, + /* 70 */ 54, 1001, 1048, 1002, 1003, 58, 57, 277, 1015, 56, + /* 80 */ 55, 54, 59, 60, 164, 63, 64, 38, 82, 255, + /* 90 */ 53, 52, 51, 88, 62, 324, 67, 65, 68, 66, + /* 100 */ 284, 283, 249, 752, 58, 57, 1029, 211, 56, 55, + /* 110 */ 54, 38, 59, 61, 806, 63, 64, 1042, 1143, 255, + /* 120 */ 53, 52, 51, 628, 62, 324, 67, 65, 68, 66, + /* 130 */ 45, 629, 237, 239, 58, 57, 1026, 164, 56, 55, + /* 140 */ 54, 60, 1023, 63, 64, 771, 772, 255, 53, 52, + /* 150 */ 51, 95, 62, 324, 67, 65, 68, 66, 38, 1090, + /* 160 */ 1025, 296, 58, 57, 322, 83, 56, 55, 54, 577, + /* 170 */ 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, + /* 180 */ 588, 589, 590, 155, 322, 236, 63, 64, 756, 248, + /* 190 */ 255, 53, 52, 51, 628, 62, 324, 67, 65, 68, + /* 200 */ 66, 251, 629, 245, 354, 58, 57, 1026, 215, 56, + /* 210 */ 55, 54, 1089, 44, 320, 361, 360, 319, 318, 317, + /* 220 */ 359, 316, 315, 314, 358, 313, 357, 356, 808, 38, + /* 230 */ 1, 180, 24, 991, 979, 980, 981, 982, 983, 984, + /* 240 */ 985, 986, 987, 988, 989, 990, 992, 993, 256, 214, + /* 250 */ 38, 254, 821, 922, 100, 810, 222, 813, 164, 816, + /* 260 */ 192, 211, 139, 138, 137, 221, 809, 254, 821, 329, + /* 270 */ 88, 810, 1143, 813, 246, 816, 1028, 29, 1026, 67, + /* 280 */ 65, 68, 66, 38, 1162, 233, 234, 58, 57, 325, + /* 290 */ 1017, 56, 55, 54, 38, 333, 56, 55, 54, 1026, + /* 300 */ 269, 233, 234, 258, 5, 41, 182, 45, 211, 273, + /* 310 */ 272, 181, 106, 111, 102, 110, 164, 73, 736, 1143, + /* 320 */ 932, 733, 812, 734, 815, 735, 263, 192, 334, 276, + /* 330 */ 309, 80, 1026, 94, 69, 123, 117, 128, 229, 335, + /* 340 */ 362, 960, 127, 1026, 133, 136, 126, 202, 200, 198, + /* 350 */ 69, 260, 261, 130, 197, 143, 142, 141, 140, 74, + /* 360 */ 44, 97, 361, 360, 788, 923, 38, 359, 38, 822, + /* 370 */ 817, 358, 192, 357, 356, 38, 818, 38, 38, 259, + /* 380 */ 811, 257, 814, 332, 331, 822, 817, 264, 125, 298, + /* 390 */ 264, 93, 818, 326, 1012, 1013, 35, 1016, 178, 14, + /* 400 */ 354, 179, 265, 96, 262, 264, 339, 338, 154, 152, + /* 410 */ 151, 336, 749, 340, 81, 1026, 1027, 1026, 3, 193, + /* 420 */ 341, 787, 342, 346, 1026, 278, 1026, 1026, 365, 364, + /* 430 */ 148, 85, 86, 99, 76, 737, 738, 768, 9, 39, + /* 440 */ 778, 779, 722, 819, 301, 724, 216, 303, 1014, 723, + /* 450 */ 34, 159, 844, 823, 70, 26, 39, 253, 39, 70, + /* 460 */ 79, 98, 627, 70, 135, 134, 25, 25, 280, 280, + /* 470 */ 16, 116, 15, 115, 77, 18, 25, 17, 741, 6, + /* 480 */ 742, 274, 739, 304, 740, 20, 122, 19, 121, 22, + /* 490 */ 217, 21, 711, 1100, 1137, 1136, 1135, 825, 231, 156, + /* 500 */ 232, 820, 212, 213, 218, 210, 1099, 219, 220, 224, + /* 510 */ 225, 226, 223, 207, 1154, 243, 1096, 1095, 244, 345, + /* 520 */ 1050, 1061, 1043, 48, 1058, 1059, 1063, 153, 281, 158, + /* 530 */ 163, 292, 1024, 175, 1082, 174, 1081, 279, 84, 285, + /* 540 */ 1022, 310, 176, 240, 177, 171, 167, 937, 306, 307, + /* 550 */ 308, 767, 311, 312, 1040, 165, 166, 46, 287, 289, + /* 560 */ 297, 299, 205, 168, 42, 78, 75, 50, 323, 931, + /* 570 */ 330, 1161, 113, 1160, 295, 169, 293, 291, 1157, 183, + /* 580 */ 337, 1153, 119, 288, 1152, 1149, 184, 957, 43, 40, + /* 590 */ 47, 206, 919, 129, 49, 917, 131, 132, 915, 914, + /* 600 */ 266, 195, 196, 911, 910, 909, 908, 907, 906, 905, + /* 610 */ 199, 201, 902, 900, 898, 896, 203, 893, 204, 889, + /* 620 */ 355, 124, 89, 290, 1083, 347, 348, 349, 350, 351, + /* 630 */ 352, 353, 363, 869, 230, 250, 305, 267, 268, 868, + /* 640 */ 270, 227, 228, 271, 867, 850, 107, 936, 935, 108, + /* 650 */ 849, 275, 280, 300, 10, 282, 744, 87, 30, 90, + /* 660 */ 913, 912, 904, 186, 958, 190, 185, 187, 144, 191, + /* 670 */ 189, 188, 145, 146, 147, 903, 995, 895, 4, 894, + /* 680 */ 959, 769, 160, 33, 780, 170, 172, 2, 161, 162, + /* 690 */ 774, 91, 242, 776, 92, 1005, 294, 11, 12, 31, + /* 700 */ 32, 13, 27, 302, 28, 99, 101, 104, 36, 103, + /* 710 */ 642, 37, 105, 677, 675, 674, 673, 671, 670, 669, + /* 720 */ 666, 321, 109, 632, 7, 826, 824, 8, 327, 328, + /* 730 */ 112, 114, 71, 72, 118, 714, 39, 120, 713, 710, + /* 740 */ 658, 656, 648, 654, 650, 652, 646, 644, 680, 679, + /* 750 */ 678, 676, 672, 668, 667, 194, 630, 594, 873, 872, + /* 760 */ 872, 872, 872, 872, 872, 872, 872, 872, 872, 872, + /* 770 */ 872, 149, 150, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 198, 1, 244, 1, 198, 199, 248, 246, 265, 9, - /* 10 */ 5, 9, 198, 13, 14, 198, 16, 17, 198, 276, - /* 20 */ 20, 21, 22, 262, 24, 25, 26, 27, 28, 29, - /* 30 */ 246, 5, 244, 7, 34, 35, 248, 265, 38, 39, - /* 40 */ 40, 13, 14, 1, 16, 17, 262, 245, 20, 21, - /* 50 */ 22, 9, 24, 25, 26, 27, 28, 29, 196, 197, - /* 60 */ 243, 247, 34, 35, 247, 205, 38, 39, 40, 222, - /* 70 */ 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, - /* 80 */ 233, 234, 235, 236, 198, 83, 266, 87, 46, 47, - /* 90 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 100 */ 58, 59, 60, 198, 62, 252, 13, 14, 246, 16, - /* 110 */ 17, 0, 84, 20, 21, 22, 98, 24, 25, 26, - /* 120 */ 27, 28, 29, 270, 262, 265, 91, 34, 35, 198, - /* 130 */ 198, 38, 39, 40, 13, 14, 276, 16, 17, 98, - /* 140 */ 209, 20, 21, 22, 1, 24, 25, 26, 27, 28, - /* 150 */ 29, 125, 9, 267, 268, 34, 35, 143, 140, 38, - /* 160 */ 39, 40, 14, 198, 16, 17, 152, 153, 20, 21, - /* 170 */ 22, 85, 24, 25, 26, 27, 28, 29, 273, 138, - /* 180 */ 275, 244, 34, 35, 265, 248, 38, 39, 40, 16, - /* 190 */ 17, 198, 205, 20, 21, 22, 85, 24, 25, 26, - /* 200 */ 27, 28, 29, 271, 5, 273, 83, 34, 35, 126, - /* 210 */ 127, 38, 39, 40, 99, 100, 101, 102, 103, 104, - /* 220 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 45, - /* 230 */ 198, 1, 2, 34, 35, 5, 243, 7, 273, 9, - /* 240 */ 247, 1, 2, 120, 265, 5, 62, 7, 205, 9, - /* 250 */ 34, 35, 265, 69, 38, 39, 40, 206, 198, 75, - /* 260 */ 76, 77, 78, 276, 34, 35, 82, 83, 38, 209, - /* 270 */ 206, 63, 64, 65, 34, 35, 220, 221, 70, 71, - /* 280 */ 72, 73, 74, 66, 67, 68, 26, 27, 28, 29, - /* 290 */ 239, 240, 241, 242, 34, 35, 204, 89, 38, 39, - /* 300 */ 40, 69, 204, 211, 120, 273, 242, 2, 265, 211, - /* 310 */ 5, 198, 7, 83, 9, 69, 198, 265, 99, 276, - /* 320 */ 101, 102, 79, 83, 265, 106, 142, 209, 144, 110, - /* 330 */ 265, 112, 113, 265, 91, 151, 63, 64, 65, 34, - /* 340 */ 35, 38, 5, 70, 7, 72, 73, 74, 118, 119, - /* 350 */ 204, 248, 198, 198, 81, 125, 243, 211, 118, 119, - /* 360 */ 247, 63, 64, 65, 198, 125, 206, 198, 70, 71, - /* 370 */ 72, 73, 74, 222, 83, 224, 225, 145, 87, 147, - /* 380 */ 229, 149, 150, 77, 233, 198, 235, 236, 198, 15, - /* 390 */ 198, 145, 84, 147, 84, 149, 150, 243, 243, 198, - /* 400 */ 240, 247, 247, 38, 39, 40, 249, 265, 117, 243, - /* 410 */ 207, 208, 243, 247, 202, 203, 247, 63, 64, 65, - /* 420 */ 263, 98, 84, 118, 119, 83, 123, 84, 84, 121, - /* 430 */ 243, 121, 84, 243, 247, 243, 98, 247, 1, 247, - /* 440 */ 134, 98, 98, 84, 243, 84, 98, 124, 247, 61, - /* 450 */ 84, 84, 84, 84, 84, 84, 83, 98, 116, 98, - /* 460 */ 265, 146, 125, 148, 98, 98, 98, 98, 98, 98, - /* 470 */ 146, 83, 148, 248, 146, 38, 148, 5, 5, 7, - /* 480 */ 7, 146, 146, 148, 148, 146, 265, 148, 115, 79, - /* 490 */ 80, 265, 118, 265, 265, 248, 265, 238, 265, 265, - /* 500 */ 265, 265, 265, 265, 265, 238, 238, 238, 238, 238, - /* 510 */ 238, 198, 198, 264, 198, 198, 198, 198, 198, 198, - /* 520 */ 246, 246, 274, 198, 198, 274, 250, 246, 198, 198, - /* 530 */ 198, 198, 198, 269, 269, 61, 257, 259, 198, 198, - /* 540 */ 125, 261, 260, 198, 198, 198, 269, 198, 198, 198, - /* 550 */ 198, 198, 269, 198, 198, 198, 198, 137, 198, 132, - /* 560 */ 198, 198, 198, 139, 136, 258, 135, 256, 130, 129, - /* 570 */ 198, 128, 131, 198, 198, 198, 198, 198, 198, 198, - /* 580 */ 198, 198, 198, 198, 198, 198, 141, 198, 198, 198, - /* 590 */ 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, - /* 600 */ 198, 198, 198, 198, 198, 198, 198, 198, 90, 198, - /* 610 */ 114, 97, 200, 200, 200, 96, 200, 200, 52, 93, - /* 620 */ 95, 56, 200, 94, 92, 200, 200, 85, 5, 154, - /* 630 */ 5, 5, 5, 200, 200, 154, 5, 101, 100, 210, - /* 640 */ 210, 206, 206, 143, 121, 83, 116, 84, 98, 122, - /* 650 */ 83, 200, 200, 98, 84, 201, 83, 201, 219, 213, - /* 660 */ 218, 217, 214, 216, 215, 212, 200, 207, 201, 237, - /* 670 */ 200, 200, 253, 255, 251, 254, 221, 201, 200, 202, - /* 680 */ 84, 83, 98, 84, 83, 1, 84, 237, 83, 83, - /* 690 */ 98, 133, 98, 133, 83, 83, 116, 83, 117, 79, - /* 700 */ 71, 88, 87, 5, 88, 87, 9, 5, 5, 5, - /* 710 */ 5, 5, 5, 5, 86, 15, 79, 83, 118, 84, - /* 720 */ 25, 83, 60, 148, 148, 16, 16, 148, 98, 5, - /* 730 */ 148, 5, 84, 5, 5, 5, 5, 5, 5, 5, - /* 740 */ 5, 5, 5, 5, 5, 5, 5, 5, 98, 86, - /* 750 */ 61, 0, 277, 277, 277, 277, 277, 277, 277, 277, - /* 760 */ 277, 277, 277, 277, 21, 21, 277, 277, 277, 277, - /* 770 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - /* 780 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - /* 790 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - /* 800 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - /* 810 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - /* 820 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - /* 830 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - /* 840 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - /* 850 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - /* 860 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - /* 870 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - /* 880 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - /* 890 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - /* 900 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - /* 910 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - /* 920 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - /* 930 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - /* 940 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - /* 950 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - /* 960 */ 277, 277, + /* 0 */ 266, 1, 199, 200, 199, 266, 245, 5, 266, 9, + /* 10 */ 249, 197, 198, 13, 14, 253, 16, 17, 247, 277, + /* 20 */ 20, 21, 22, 23, 1, 25, 26, 27, 28, 29, + /* 30 */ 30, 199, 9, 271, 263, 35, 36, 35, 36, 39, + /* 40 */ 40, 41, 13, 14, 245, 16, 17, 206, 249, 20, + /* 50 */ 21, 22, 23, 266, 25, 26, 27, 28, 29, 30, + /* 60 */ 223, 247, 225, 226, 35, 36, 5, 230, 39, 40, + /* 70 */ 41, 234, 267, 236, 237, 35, 36, 263, 0, 39, + /* 80 */ 40, 41, 13, 14, 199, 16, 17, 199, 88, 20, + /* 90 */ 21, 22, 23, 84, 25, 26, 27, 28, 29, 30, + /* 100 */ 268, 269, 245, 39, 35, 36, 249, 266, 39, 40, + /* 110 */ 41, 199, 13, 14, 85, 16, 17, 247, 277, 20, + /* 120 */ 21, 22, 23, 1, 25, 26, 27, 28, 29, 30, + /* 130 */ 121, 9, 244, 263, 35, 36, 248, 199, 39, 40, + /* 140 */ 41, 14, 199, 16, 17, 127, 128, 20, 21, 22, + /* 150 */ 23, 250, 25, 26, 27, 28, 29, 30, 199, 274, + /* 160 */ 248, 276, 35, 36, 86, 264, 39, 40, 41, 47, + /* 170 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + /* 180 */ 58, 59, 60, 61, 86, 63, 16, 17, 124, 246, + /* 190 */ 20, 21, 22, 23, 1, 25, 26, 27, 28, 29, + /* 200 */ 30, 206, 9, 244, 92, 35, 36, 248, 266, 39, + /* 210 */ 40, 41, 274, 100, 101, 102, 103, 104, 105, 106, + /* 220 */ 107, 108, 109, 110, 111, 112, 113, 114, 1, 199, + /* 230 */ 208, 209, 46, 223, 224, 225, 226, 227, 228, 229, + /* 240 */ 230, 231, 232, 233, 234, 235, 236, 237, 206, 63, + /* 250 */ 199, 1, 2, 205, 207, 5, 70, 7, 199, 9, + /* 260 */ 212, 266, 76, 77, 78, 79, 39, 1, 2, 83, + /* 270 */ 84, 5, 277, 7, 244, 9, 249, 84, 248, 27, + /* 280 */ 28, 29, 30, 199, 249, 35, 36, 35, 36, 39, + /* 290 */ 243, 39, 40, 41, 199, 244, 39, 40, 41, 248, + /* 300 */ 144, 35, 36, 70, 64, 65, 66, 121, 266, 153, + /* 310 */ 154, 71, 72, 73, 74, 75, 199, 99, 2, 277, + /* 320 */ 205, 5, 5, 7, 7, 9, 70, 212, 244, 143, + /* 330 */ 90, 145, 248, 274, 84, 64, 65, 66, 152, 244, + /* 340 */ 221, 222, 71, 248, 73, 74, 75, 64, 65, 66, + /* 350 */ 84, 35, 36, 82, 71, 72, 73, 74, 75, 141, + /* 360 */ 100, 207, 102, 103, 78, 205, 199, 107, 199, 119, + /* 370 */ 120, 111, 212, 113, 114, 199, 126, 199, 199, 146, + /* 380 */ 5, 148, 7, 150, 151, 119, 120, 199, 80, 272, + /* 390 */ 199, 274, 126, 15, 240, 241, 242, 243, 210, 84, + /* 400 */ 92, 210, 146, 88, 148, 199, 150, 151, 64, 65, + /* 410 */ 66, 244, 99, 244, 207, 248, 210, 248, 203, 204, + /* 420 */ 244, 135, 244, 244, 248, 85, 248, 248, 67, 68, + /* 430 */ 69, 85, 85, 118, 99, 119, 120, 85, 125, 99, + /* 440 */ 85, 85, 85, 126, 85, 85, 266, 85, 241, 85, + /* 450 */ 84, 99, 85, 85, 99, 99, 99, 62, 99, 99, + /* 460 */ 84, 99, 85, 99, 80, 81, 99, 99, 122, 122, + /* 470 */ 147, 147, 149, 149, 139, 147, 99, 149, 5, 84, + /* 480 */ 7, 199, 5, 117, 7, 147, 147, 149, 149, 147, + /* 490 */ 266, 149, 116, 239, 266, 266, 266, 119, 266, 199, + /* 500 */ 266, 126, 266, 266, 266, 266, 239, 266, 266, 266, + /* 510 */ 266, 266, 266, 266, 249, 239, 239, 239, 239, 239, + /* 520 */ 199, 199, 247, 265, 199, 199, 199, 62, 247, 199, + /* 530 */ 199, 199, 247, 199, 275, 251, 275, 201, 201, 270, + /* 540 */ 199, 91, 199, 270, 199, 255, 259, 199, 199, 199, + /* 550 */ 199, 126, 199, 199, 262, 261, 260, 199, 270, 270, + /* 560 */ 136, 133, 199, 258, 199, 138, 140, 137, 199, 199, + /* 570 */ 199, 199, 199, 199, 131, 257, 130, 129, 199, 199, + /* 580 */ 199, 199, 199, 132, 199, 199, 199, 199, 199, 199, + /* 590 */ 199, 199, 199, 199, 142, 199, 199, 199, 199, 199, + /* 600 */ 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + /* 610 */ 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + /* 620 */ 115, 98, 201, 201, 201, 97, 53, 94, 96, 57, + /* 630 */ 95, 93, 86, 5, 201, 201, 201, 155, 5, 5, + /* 640 */ 155, 201, 201, 5, 5, 102, 207, 211, 211, 207, + /* 650 */ 101, 144, 122, 117, 84, 99, 85, 123, 84, 99, + /* 660 */ 201, 201, 201, 218, 220, 216, 219, 214, 202, 213, + /* 670 */ 215, 217, 202, 202, 202, 201, 238, 201, 203, 201, + /* 680 */ 222, 85, 84, 252, 85, 256, 254, 208, 84, 99, + /* 690 */ 85, 84, 1, 85, 84, 238, 84, 134, 134, 99, + /* 700 */ 99, 84, 84, 117, 84, 118, 80, 72, 89, 88, + /* 710 */ 5, 89, 88, 9, 5, 5, 5, 5, 5, 5, + /* 720 */ 5, 15, 80, 87, 84, 119, 85, 84, 26, 61, + /* 730 */ 149, 149, 16, 16, 149, 5, 99, 149, 5, 85, + /* 740 */ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + /* 750 */ 5, 5, 5, 5, 5, 99, 87, 62, 0, 278, + /* 760 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + /* 770 */ 278, 21, 21, 278, 278, 278, 278, 278, 278, 278, + /* 780 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + /* 790 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + /* 800 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + /* 810 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + /* 820 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + /* 830 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + /* 840 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + /* 850 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + /* 860 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + /* 870 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + /* 880 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + /* 890 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + /* 900 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + /* 910 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + /* 920 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + /* 930 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + /* 940 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + /* 950 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + /* 960 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, }; -#define YY_SHIFT_COUNT (365) +#define YY_SHIFT_COUNT (367) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (751) +#define YY_SHIFT_MAX (758) static const unsigned short int yy_shift_ofst[] = { - /* 0 */ 184, 115, 115, 219, 219, 86, 230, 240, 240, 2, - /* 10 */ 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - /* 20 */ 143, 143, 143, 0, 42, 240, 305, 305, 305, 123, - /* 30 */ 123, 143, 143, 83, 143, 111, 143, 143, 143, 143, - /* 40 */ 243, 86, 35, 35, 5, 766, 766, 766, 240, 240, - /* 50 */ 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, - /* 60 */ 240, 240, 240, 240, 240, 240, 240, 240, 240, 305, - /* 70 */ 305, 305, 199, 199, 199, 199, 199, 199, 199, 143, - /* 80 */ 143, 143, 303, 143, 143, 143, 123, 123, 143, 143, - /* 90 */ 143, 143, 306, 306, 323, 123, 143, 143, 143, 143, - /* 100 */ 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - /* 110 */ 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - /* 120 */ 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - /* 130 */ 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - /* 140 */ 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - /* 150 */ 143, 143, 143, 143, 143, 474, 474, 474, 415, 415, - /* 160 */ 415, 415, 474, 474, 420, 424, 427, 428, 431, 438, - /* 170 */ 440, 443, 441, 445, 474, 474, 474, 518, 518, 496, - /* 180 */ 86, 86, 474, 474, 514, 519, 566, 526, 525, 565, - /* 190 */ 529, 532, 496, 5, 474, 474, 542, 542, 474, 542, - /* 200 */ 474, 542, 474, 474, 766, 766, 28, 93, 93, 121, - /* 210 */ 93, 148, 173, 208, 260, 260, 260, 260, 260, 273, - /* 220 */ 298, 216, 216, 216, 216, 232, 246, 14, 291, 365, - /* 230 */ 365, 26, 337, 217, 354, 338, 308, 310, 343, 344, - /* 240 */ 348, 18, 41, 359, 361, 366, 367, 368, 342, 369, - /* 250 */ 370, 437, 388, 374, 371, 315, 324, 328, 472, 473, - /* 260 */ 335, 336, 373, 339, 410, 623, 475, 625, 626, 481, - /* 270 */ 627, 631, 536, 538, 500, 523, 530, 562, 527, 563, - /* 280 */ 567, 550, 555, 570, 573, 596, 598, 599, 584, 601, - /* 290 */ 602, 605, 684, 606, 592, 558, 594, 560, 611, 530, - /* 300 */ 612, 580, 614, 581, 620, 613, 615, 629, 698, 616, - /* 310 */ 618, 697, 702, 703, 704, 705, 706, 707, 708, 628, - /* 320 */ 700, 637, 634, 635, 600, 638, 695, 662, 709, 575, - /* 330 */ 576, 630, 630, 630, 630, 710, 579, 582, 630, 630, - /* 340 */ 630, 724, 726, 648, 630, 728, 729, 730, 731, 732, - /* 350 */ 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, - /* 360 */ 650, 663, 743, 744, 689, 751, + /* 0 */ 186, 113, 113, 260, 260, 98, 250, 266, 266, 193, + /* 10 */ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + /* 20 */ 23, 23, 23, 0, 122, 266, 316, 316, 316, 9, + /* 30 */ 9, 23, 23, 18, 23, 78, 23, 23, 23, 23, + /* 40 */ 308, 98, 112, 112, 61, 773, 773, 773, 266, 266, + /* 50 */ 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, + /* 60 */ 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, + /* 70 */ 316, 316, 316, 2, 2, 2, 2, 2, 2, 2, + /* 80 */ 23, 23, 23, 64, 23, 23, 23, 9, 9, 23, + /* 90 */ 23, 23, 23, 286, 286, 313, 9, 23, 23, 23, + /* 100 */ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + /* 110 */ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + /* 120 */ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + /* 130 */ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + /* 140 */ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + /* 150 */ 23, 23, 23, 23, 23, 23, 465, 465, 465, 425, + /* 160 */ 425, 425, 425, 465, 465, 427, 426, 428, 430, 424, + /* 170 */ 443, 446, 448, 451, 452, 465, 465, 465, 450, 450, + /* 180 */ 505, 98, 98, 465, 465, 523, 528, 573, 533, 532, + /* 190 */ 572, 535, 538, 505, 61, 465, 465, 546, 546, 465, + /* 200 */ 546, 465, 546, 465, 465, 773, 773, 29, 69, 69, + /* 210 */ 99, 69, 127, 170, 240, 252, 252, 252, 252, 252, + /* 220 */ 252, 271, 283, 40, 40, 40, 40, 233, 256, 156, + /* 230 */ 315, 257, 257, 317, 375, 361, 344, 340, 346, 347, + /* 240 */ 352, 355, 356, 218, 335, 357, 359, 360, 362, 364, + /* 250 */ 366, 367, 368, 227, 395, 378, 377, 323, 324, 328, + /* 260 */ 473, 477, 338, 339, 376, 342, 384, 628, 482, 633, + /* 270 */ 634, 485, 638, 639, 543, 549, 507, 530, 536, 570, + /* 280 */ 534, 571, 574, 556, 560, 596, 598, 599, 604, 605, + /* 290 */ 590, 607, 608, 610, 691, 612, 600, 563, 601, 564, + /* 300 */ 617, 536, 618, 586, 620, 587, 626, 619, 621, 635, + /* 310 */ 705, 622, 624, 704, 709, 710, 711, 712, 713, 714, + /* 320 */ 715, 636, 706, 642, 640, 641, 606, 643, 702, 668, + /* 330 */ 716, 581, 582, 637, 637, 637, 637, 717, 585, 588, + /* 340 */ 637, 637, 637, 730, 733, 654, 637, 735, 736, 737, + /* 350 */ 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, + /* 360 */ 748, 749, 656, 669, 750, 751, 695, 758, }; -#define YY_REDUCE_COUNT (205) -#define YY_REDUCE_MIN (-257) -#define YY_REDUCE_MAX (478) +#define YY_REDUCE_COUNT (206) +#define YY_REDUCE_MIN (-266) +#define YY_REDUCE_MAX (479) static const short yy_reduce_ofst[] = { - /* 0 */ -138, -153, -153, 151, 151, 51, -140, -13, 43, -114, - /* 10 */ -183, -95, -68, -7, 113, 154, 155, 166, 169, 187, - /* 20 */ 190, 192, 201, -180, -194, -257, -242, -212, -63, -239, - /* 30 */ -216, -35, 32, -147, -198, 64, -69, 60, 118, -186, - /* 40 */ 92, 160, 98, 146, 56, 157, 203, 212, -228, -81, - /* 50 */ -21, 52, 59, 65, 68, 142, 195, 221, 226, 228, - /* 60 */ 229, 231, 233, 234, 235, 236, 237, 238, 239, 103, - /* 70 */ 225, 247, 259, 267, 268, 269, 270, 271, 272, 313, - /* 80 */ 314, 316, 249, 317, 318, 319, 274, 275, 320, 321, - /* 90 */ 325, 326, 248, 251, 276, 281, 330, 331, 332, 333, - /* 100 */ 334, 340, 341, 345, 346, 347, 349, 350, 351, 352, - /* 110 */ 353, 355, 356, 357, 358, 360, 362, 363, 364, 372, - /* 120 */ 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - /* 130 */ 385, 386, 387, 389, 390, 391, 392, 393, 394, 395, - /* 140 */ 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - /* 150 */ 406, 407, 408, 409, 411, 412, 413, 414, 264, 265, - /* 160 */ 277, 283, 416, 417, 280, 282, 278, 307, 279, 311, - /* 170 */ 418, 421, 419, 423, 422, 425, 426, 429, 430, 432, - /* 180 */ 435, 436, 433, 434, 439, 442, 444, 446, 447, 448, - /* 190 */ 449, 453, 450, 455, 451, 452, 454, 456, 466, 467, - /* 200 */ 470, 476, 471, 478, 460, 477, + /* 0 */ -186, 10, 10, -163, -163, 154, -159, -5, 42, -168, + /* 10 */ -112, -115, 117, -41, 30, 51, 84, 95, 167, 169, + /* 20 */ 176, 178, 179, -195, -197, -258, -239, -201, -143, -229, + /* 30 */ -130, -62, 59, -238, -57, 47, 188, 191, 206, -88, + /* 40 */ 48, 207, 115, 160, 119, -99, 22, 215, -266, -261, + /* 50 */ -213, -58, 180, 224, 228, 229, 230, 232, 234, 236, + /* 60 */ 237, 238, 239, 241, 242, 243, 244, 245, 246, 247, + /* 70 */ 27, 35, 265, 254, 267, 276, 277, 278, 279, 280, + /* 80 */ 282, 300, 321, 258, 322, 325, 326, 275, 281, 327, + /* 90 */ 330, 331, 332, 259, 261, 284, 285, 334, 341, 343, + /* 100 */ 345, 348, 349, 350, 351, 353, 354, 358, 363, 365, + /* 110 */ 369, 370, 371, 372, 373, 374, 379, 380, 381, 382, + /* 120 */ 383, 385, 386, 387, 388, 389, 390, 391, 392, 393, + /* 130 */ 394, 396, 397, 398, 399, 400, 401, 402, 403, 404, + /* 140 */ 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + /* 150 */ 415, 416, 417, 418, 419, 420, 336, 337, 421, 269, + /* 160 */ 273, 288, 289, 422, 423, 292, 294, 296, 287, 305, + /* 170 */ 318, 429, 290, 432, 431, 433, 434, 435, 436, 437, + /* 180 */ 438, 439, 442, 440, 441, 444, 447, 445, 453, 454, + /* 190 */ 455, 449, 456, 457, 458, 459, 460, 466, 470, 461, + /* 200 */ 471, 474, 472, 476, 478, 479, 475, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 867, 991, 930, 1001, 917, 927, 1141, 1141, 1141, 867, - /* 10 */ 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, - /* 20 */ 867, 867, 867, 1049, 887, 1141, 867, 867, 867, 867, - /* 30 */ 867, 867, 867, 1064, 867, 927, 867, 867, 867, 867, - /* 40 */ 937, 927, 937, 937, 867, 1044, 975, 993, 867, 867, - /* 50 */ 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, - /* 60 */ 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, - /* 70 */ 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, - /* 80 */ 867, 867, 1051, 1057, 1054, 867, 867, 867, 1059, 867, - /* 90 */ 867, 867, 1083, 1083, 1042, 867, 867, 867, 867, 867, - /* 100 */ 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, - /* 110 */ 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, - /* 120 */ 867, 867, 867, 867, 867, 867, 867, 867, 915, 867, - /* 130 */ 913, 867, 867, 867, 867, 867, 867, 867, 867, 867, - /* 140 */ 867, 867, 867, 867, 867, 867, 867, 898, 867, 867, - /* 150 */ 867, 867, 867, 867, 885, 889, 889, 889, 867, 867, - /* 160 */ 867, 867, 889, 889, 1090, 1094, 1076, 1088, 1084, 1071, - /* 170 */ 1069, 1067, 1075, 1098, 889, 889, 889, 935, 935, 931, - /* 180 */ 927, 927, 889, 889, 953, 951, 949, 941, 947, 943, - /* 190 */ 945, 939, 918, 867, 889, 889, 925, 925, 889, 925, - /* 200 */ 889, 925, 889, 889, 975, 993, 867, 1099, 1089, 867, - /* 210 */ 1140, 1129, 1128, 867, 1136, 1135, 1127, 1126, 1125, 867, - /* 220 */ 867, 1121, 1124, 1123, 1122, 867, 867, 867, 867, 1131, - /* 230 */ 1130, 867, 867, 867, 867, 867, 867, 867, 867, 867, - /* 240 */ 867, 1095, 1091, 867, 867, 867, 867, 867, 867, 867, - /* 250 */ 867, 867, 1101, 867, 867, 867, 867, 867, 867, 867, - /* 260 */ 867, 867, 1003, 867, 867, 867, 867, 867, 867, 867, - /* 270 */ 867, 867, 867, 867, 867, 1041, 867, 867, 867, 867, - /* 280 */ 867, 1053, 1052, 867, 867, 867, 867, 867, 867, 867, - /* 290 */ 867, 867, 867, 867, 1085, 867, 1077, 867, 867, 1015, - /* 300 */ 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, - /* 310 */ 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, - /* 320 */ 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, - /* 330 */ 867, 1159, 1154, 1155, 1152, 867, 867, 867, 1151, 1146, - /* 340 */ 1147, 867, 867, 867, 1144, 867, 867, 867, 867, 867, - /* 350 */ 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, - /* 360 */ 959, 867, 896, 894, 867, 867, + /* 0 */ 870, 994, 933, 1004, 920, 930, 1145, 1145, 1145, 870, + /* 10 */ 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + /* 20 */ 870, 870, 870, 1052, 890, 1145, 870, 870, 870, 870, + /* 30 */ 870, 870, 870, 1067, 870, 930, 870, 870, 870, 870, + /* 40 */ 940, 930, 940, 940, 870, 1047, 978, 996, 870, 870, + /* 50 */ 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + /* 60 */ 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + /* 70 */ 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + /* 80 */ 870, 870, 870, 1054, 1060, 1057, 870, 870, 870, 1062, + /* 90 */ 870, 870, 870, 1086, 1086, 1045, 870, 870, 870, 870, + /* 100 */ 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + /* 110 */ 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + /* 120 */ 870, 870, 870, 870, 870, 870, 870, 870, 870, 918, + /* 130 */ 870, 916, 870, 870, 870, 870, 870, 870, 870, 870, + /* 140 */ 870, 870, 870, 870, 870, 870, 870, 870, 901, 870, + /* 150 */ 870, 870, 870, 870, 870, 888, 892, 892, 892, 870, + /* 160 */ 870, 870, 870, 892, 892, 1093, 1097, 1079, 1091, 1087, + /* 170 */ 1074, 1072, 1070, 1078, 1101, 892, 892, 892, 938, 938, + /* 180 */ 934, 930, 930, 892, 892, 956, 954, 952, 944, 950, + /* 190 */ 946, 948, 942, 921, 870, 892, 892, 928, 928, 892, + /* 200 */ 928, 892, 928, 892, 892, 978, 996, 870, 1102, 1092, + /* 210 */ 870, 1144, 1132, 1131, 870, 1140, 1139, 1138, 1130, 1129, + /* 220 */ 1128, 870, 870, 1124, 1127, 1126, 1125, 870, 870, 870, + /* 230 */ 870, 1134, 1133, 870, 870, 870, 870, 870, 870, 870, + /* 240 */ 870, 870, 870, 1098, 1094, 870, 870, 870, 870, 870, + /* 250 */ 870, 870, 870, 870, 1104, 870, 870, 870, 870, 870, + /* 260 */ 870, 870, 870, 870, 1006, 870, 870, 870, 870, 870, + /* 270 */ 870, 870, 870, 870, 870, 870, 870, 1044, 870, 870, + /* 280 */ 870, 870, 870, 1056, 1055, 870, 870, 870, 870, 870, + /* 290 */ 870, 870, 870, 870, 870, 870, 1088, 870, 1080, 870, + /* 300 */ 870, 1018, 870, 870, 870, 870, 870, 870, 870, 870, + /* 310 */ 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + /* 320 */ 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + /* 330 */ 870, 870, 870, 1163, 1158, 1159, 1156, 870, 870, 870, + /* 340 */ 1155, 1150, 1151, 870, 870, 870, 1148, 870, 870, 870, + /* 350 */ 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + /* 360 */ 870, 870, 962, 870, 899, 897, 870, 870, }; /********** End of lemon-generated parsing tables *****************************/ @@ -545,6 +546,7 @@ static const YYCODETYPE yyFallback[] = { 0, /* IS => nothing */ 1, /* LIKE => ID */ 1, /* MATCH => ID */ + 1, /* NMATCH => ID */ 1, /* GLOB => ID */ 0, /* BETWEEN => nothing */ 0, /* IN => nothing */ @@ -828,260 +830,261 @@ static const char *const yyTokenName[] = { /* 20 */ "IS", /* 21 */ "LIKE", /* 22 */ "MATCH", - /* 23 */ "GLOB", - /* 24 */ "BETWEEN", - /* 25 */ "IN", - /* 26 */ "GT", - /* 27 */ "GE", - /* 28 */ "LT", - /* 29 */ "LE", - /* 30 */ "BITAND", - /* 31 */ "BITOR", - /* 32 */ "LSHIFT", - /* 33 */ "RSHIFT", - /* 34 */ "PLUS", - /* 35 */ "MINUS", - /* 36 */ "DIVIDE", - /* 37 */ "TIMES", - /* 38 */ "STAR", - /* 39 */ "SLASH", - /* 40 */ "REM", - /* 41 */ "CONCAT", - /* 42 */ "UMINUS", - /* 43 */ "UPLUS", - /* 44 */ "BITNOT", - /* 45 */ "SHOW", - /* 46 */ "DATABASES", - /* 47 */ "TOPICS", - /* 48 */ "FUNCTIONS", - /* 49 */ "MNODES", - /* 50 */ "DNODES", - /* 51 */ "ACCOUNTS", - /* 52 */ "USERS", - /* 53 */ "MODULES", - /* 54 */ "QUERIES", - /* 55 */ "CONNECTIONS", - /* 56 */ "STREAMS", - /* 57 */ "VARIABLES", - /* 58 */ "SCORES", - /* 59 */ "GRANTS", - /* 60 */ "VNODES", - /* 61 */ "DOT", - /* 62 */ "CREATE", - /* 63 */ "TABLE", - /* 64 */ "STABLE", - /* 65 */ "DATABASE", - /* 66 */ "TABLES", - /* 67 */ "STABLES", - /* 68 */ "VGROUPS", - /* 69 */ "DROP", - /* 70 */ "TOPIC", - /* 71 */ "FUNCTION", - /* 72 */ "DNODE", - /* 73 */ "USER", - /* 74 */ "ACCOUNT", - /* 75 */ "USE", - /* 76 */ "DESCRIBE", - /* 77 */ "DESC", - /* 78 */ "ALTER", - /* 79 */ "PASS", - /* 80 */ "PRIVILEGE", - /* 81 */ "LOCAL", - /* 82 */ "COMPACT", - /* 83 */ "LP", - /* 84 */ "RP", - /* 85 */ "IF", - /* 86 */ "EXISTS", - /* 87 */ "AS", - /* 88 */ "OUTPUTTYPE", - /* 89 */ "AGGREGATE", - /* 90 */ "BUFSIZE", - /* 91 */ "PPS", - /* 92 */ "TSERIES", - /* 93 */ "DBS", - /* 94 */ "STORAGE", - /* 95 */ "QTIME", - /* 96 */ "CONNS", - /* 97 */ "STATE", - /* 98 */ "COMMA", - /* 99 */ "KEEP", - /* 100 */ "CACHE", - /* 101 */ "REPLICA", - /* 102 */ "QUORUM", - /* 103 */ "DAYS", - /* 104 */ "MINROWS", - /* 105 */ "MAXROWS", - /* 106 */ "BLOCKS", - /* 107 */ "CTIME", - /* 108 */ "WAL", - /* 109 */ "FSYNC", - /* 110 */ "COMP", - /* 111 */ "PRECISION", - /* 112 */ "UPDATE", - /* 113 */ "CACHELAST", - /* 114 */ "PARTITIONS", - /* 115 */ "UNSIGNED", - /* 116 */ "TAGS", - /* 117 */ "USING", - /* 118 */ "NULL", - /* 119 */ "NOW", - /* 120 */ "SELECT", - /* 121 */ "UNION", - /* 122 */ "ALL", - /* 123 */ "DISTINCT", - /* 124 */ "FROM", - /* 125 */ "VARIABLE", - /* 126 */ "INTERVAL", - /* 127 */ "EVERY", - /* 128 */ "SESSION", - /* 129 */ "STATE_WINDOW", - /* 130 */ "FILL", - /* 131 */ "SLIDING", - /* 132 */ "ORDER", - /* 133 */ "BY", - /* 134 */ "ASC", - /* 135 */ "GROUP", - /* 136 */ "HAVING", - /* 137 */ "LIMIT", - /* 138 */ "OFFSET", - /* 139 */ "SLIMIT", - /* 140 */ "SOFFSET", - /* 141 */ "WHERE", - /* 142 */ "RESET", - /* 143 */ "QUERY", - /* 144 */ "SYNCDB", - /* 145 */ "ADD", - /* 146 */ "COLUMN", - /* 147 */ "MODIFY", - /* 148 */ "TAG", - /* 149 */ "CHANGE", - /* 150 */ "SET", - /* 151 */ "KILL", - /* 152 */ "CONNECTION", - /* 153 */ "STREAM", - /* 154 */ "COLON", - /* 155 */ "ABORT", - /* 156 */ "AFTER", - /* 157 */ "ATTACH", - /* 158 */ "BEFORE", - /* 159 */ "BEGIN", - /* 160 */ "CASCADE", - /* 161 */ "CLUSTER", - /* 162 */ "CONFLICT", - /* 163 */ "COPY", - /* 164 */ "DEFERRED", - /* 165 */ "DELIMITERS", - /* 166 */ "DETACH", - /* 167 */ "EACH", - /* 168 */ "END", - /* 169 */ "EXPLAIN", - /* 170 */ "FAIL", - /* 171 */ "FOR", - /* 172 */ "IGNORE", - /* 173 */ "IMMEDIATE", - /* 174 */ "INITIALLY", - /* 175 */ "INSTEAD", - /* 176 */ "KEY", - /* 177 */ "OF", - /* 178 */ "RAISE", - /* 179 */ "REPLACE", - /* 180 */ "RESTRICT", - /* 181 */ "ROW", - /* 182 */ "STATEMENT", - /* 183 */ "TRIGGER", - /* 184 */ "VIEW", - /* 185 */ "IPTOKEN", - /* 186 */ "SEMI", - /* 187 */ "NONE", - /* 188 */ "PREV", - /* 189 */ "LINEAR", - /* 190 */ "IMPORT", - /* 191 */ "TBNAME", - /* 192 */ "JOIN", - /* 193 */ "INSERT", - /* 194 */ "INTO", - /* 195 */ "VALUES", - /* 196 */ "program", - /* 197 */ "cmd", - /* 198 */ "ids", - /* 199 */ "dbPrefix", - /* 200 */ "cpxName", - /* 201 */ "ifexists", - /* 202 */ "alter_db_optr", - /* 203 */ "alter_topic_optr", - /* 204 */ "acct_optr", - /* 205 */ "exprlist", - /* 206 */ "ifnotexists", - /* 207 */ "db_optr", - /* 208 */ "topic_optr", - /* 209 */ "typename", - /* 210 */ "bufsize", - /* 211 */ "pps", - /* 212 */ "tseries", - /* 213 */ "dbs", - /* 214 */ "streams", - /* 215 */ "storage", - /* 216 */ "qtime", - /* 217 */ "users", - /* 218 */ "conns", - /* 219 */ "state", - /* 220 */ "intitemlist", - /* 221 */ "intitem", - /* 222 */ "keep", - /* 223 */ "cache", - /* 224 */ "replica", - /* 225 */ "quorum", - /* 226 */ "days", - /* 227 */ "minrows", - /* 228 */ "maxrows", - /* 229 */ "blocks", - /* 230 */ "ctime", - /* 231 */ "wal", - /* 232 */ "fsync", - /* 233 */ "comp", - /* 234 */ "prec", - /* 235 */ "update", - /* 236 */ "cachelast", - /* 237 */ "partitions", - /* 238 */ "signed", - /* 239 */ "create_table_args", - /* 240 */ "create_stable_args", - /* 241 */ "create_table_list", - /* 242 */ "create_from_stable", - /* 243 */ "columnlist", - /* 244 */ "tagitemlist", - /* 245 */ "tagNamelist", - /* 246 */ "select", - /* 247 */ "column", - /* 248 */ "tagitem", - /* 249 */ "selcollist", - /* 250 */ "from", - /* 251 */ "where_opt", - /* 252 */ "interval_option", - /* 253 */ "sliding_opt", - /* 254 */ "session_option", - /* 255 */ "windowstate_option", - /* 256 */ "fill_opt", - /* 257 */ "groupby_opt", - /* 258 */ "having_opt", - /* 259 */ "orderby_opt", - /* 260 */ "slimit_opt", - /* 261 */ "limit_opt", - /* 262 */ "union", - /* 263 */ "sclp", - /* 264 */ "distinct", - /* 265 */ "expr", - /* 266 */ "as", - /* 267 */ "tablelist", - /* 268 */ "sub", - /* 269 */ "tmvar", - /* 270 */ "intervalKey", - /* 271 */ "sortlist", - /* 272 */ "sortitem", - /* 273 */ "item", - /* 274 */ "sortorder", - /* 275 */ "grouplist", - /* 276 */ "expritem", + /* 23 */ "NMATCH", + /* 24 */ "GLOB", + /* 25 */ "BETWEEN", + /* 26 */ "IN", + /* 27 */ "GT", + /* 28 */ "GE", + /* 29 */ "LT", + /* 30 */ "LE", + /* 31 */ "BITAND", + /* 32 */ "BITOR", + /* 33 */ "LSHIFT", + /* 34 */ "RSHIFT", + /* 35 */ "PLUS", + /* 36 */ "MINUS", + /* 37 */ "DIVIDE", + /* 38 */ "TIMES", + /* 39 */ "STAR", + /* 40 */ "SLASH", + /* 41 */ "REM", + /* 42 */ "CONCAT", + /* 43 */ "UMINUS", + /* 44 */ "UPLUS", + /* 45 */ "BITNOT", + /* 46 */ "SHOW", + /* 47 */ "DATABASES", + /* 48 */ "TOPICS", + /* 49 */ "FUNCTIONS", + /* 50 */ "MNODES", + /* 51 */ "DNODES", + /* 52 */ "ACCOUNTS", + /* 53 */ "USERS", + /* 54 */ "MODULES", + /* 55 */ "QUERIES", + /* 56 */ "CONNECTIONS", + /* 57 */ "STREAMS", + /* 58 */ "VARIABLES", + /* 59 */ "SCORES", + /* 60 */ "GRANTS", + /* 61 */ "VNODES", + /* 62 */ "DOT", + /* 63 */ "CREATE", + /* 64 */ "TABLE", + /* 65 */ "STABLE", + /* 66 */ "DATABASE", + /* 67 */ "TABLES", + /* 68 */ "STABLES", + /* 69 */ "VGROUPS", + /* 70 */ "DROP", + /* 71 */ "TOPIC", + /* 72 */ "FUNCTION", + /* 73 */ "DNODE", + /* 74 */ "USER", + /* 75 */ "ACCOUNT", + /* 76 */ "USE", + /* 77 */ "DESCRIBE", + /* 78 */ "DESC", + /* 79 */ "ALTER", + /* 80 */ "PASS", + /* 81 */ "PRIVILEGE", + /* 82 */ "LOCAL", + /* 83 */ "COMPACT", + /* 84 */ "LP", + /* 85 */ "RP", + /* 86 */ "IF", + /* 87 */ "EXISTS", + /* 88 */ "AS", + /* 89 */ "OUTPUTTYPE", + /* 90 */ "AGGREGATE", + /* 91 */ "BUFSIZE", + /* 92 */ "PPS", + /* 93 */ "TSERIES", + /* 94 */ "DBS", + /* 95 */ "STORAGE", + /* 96 */ "QTIME", + /* 97 */ "CONNS", + /* 98 */ "STATE", + /* 99 */ "COMMA", + /* 100 */ "KEEP", + /* 101 */ "CACHE", + /* 102 */ "REPLICA", + /* 103 */ "QUORUM", + /* 104 */ "DAYS", + /* 105 */ "MINROWS", + /* 106 */ "MAXROWS", + /* 107 */ "BLOCKS", + /* 108 */ "CTIME", + /* 109 */ "WAL", + /* 110 */ "FSYNC", + /* 111 */ "COMP", + /* 112 */ "PRECISION", + /* 113 */ "UPDATE", + /* 114 */ "CACHELAST", + /* 115 */ "PARTITIONS", + /* 116 */ "UNSIGNED", + /* 117 */ "TAGS", + /* 118 */ "USING", + /* 119 */ "NULL", + /* 120 */ "NOW", + /* 121 */ "SELECT", + /* 122 */ "UNION", + /* 123 */ "ALL", + /* 124 */ "DISTINCT", + /* 125 */ "FROM", + /* 126 */ "VARIABLE", + /* 127 */ "INTERVAL", + /* 128 */ "EVERY", + /* 129 */ "SESSION", + /* 130 */ "STATE_WINDOW", + /* 131 */ "FILL", + /* 132 */ "SLIDING", + /* 133 */ "ORDER", + /* 134 */ "BY", + /* 135 */ "ASC", + /* 136 */ "GROUP", + /* 137 */ "HAVING", + /* 138 */ "LIMIT", + /* 139 */ "OFFSET", + /* 140 */ "SLIMIT", + /* 141 */ "SOFFSET", + /* 142 */ "WHERE", + /* 143 */ "RESET", + /* 144 */ "QUERY", + /* 145 */ "SYNCDB", + /* 146 */ "ADD", + /* 147 */ "COLUMN", + /* 148 */ "MODIFY", + /* 149 */ "TAG", + /* 150 */ "CHANGE", + /* 151 */ "SET", + /* 152 */ "KILL", + /* 153 */ "CONNECTION", + /* 154 */ "STREAM", + /* 155 */ "COLON", + /* 156 */ "ABORT", + /* 157 */ "AFTER", + /* 158 */ "ATTACH", + /* 159 */ "BEFORE", + /* 160 */ "BEGIN", + /* 161 */ "CASCADE", + /* 162 */ "CLUSTER", + /* 163 */ "CONFLICT", + /* 164 */ "COPY", + /* 165 */ "DEFERRED", + /* 166 */ "DELIMITERS", + /* 167 */ "DETACH", + /* 168 */ "EACH", + /* 169 */ "END", + /* 170 */ "EXPLAIN", + /* 171 */ "FAIL", + /* 172 */ "FOR", + /* 173 */ "IGNORE", + /* 174 */ "IMMEDIATE", + /* 175 */ "INITIALLY", + /* 176 */ "INSTEAD", + /* 177 */ "KEY", + /* 178 */ "OF", + /* 179 */ "RAISE", + /* 180 */ "REPLACE", + /* 181 */ "RESTRICT", + /* 182 */ "ROW", + /* 183 */ "STATEMENT", + /* 184 */ "TRIGGER", + /* 185 */ "VIEW", + /* 186 */ "IPTOKEN", + /* 187 */ "SEMI", + /* 188 */ "NONE", + /* 189 */ "PREV", + /* 190 */ "LINEAR", + /* 191 */ "IMPORT", + /* 192 */ "TBNAME", + /* 193 */ "JOIN", + /* 194 */ "INSERT", + /* 195 */ "INTO", + /* 196 */ "VALUES", + /* 197 */ "program", + /* 198 */ "cmd", + /* 199 */ "ids", + /* 200 */ "dbPrefix", + /* 201 */ "cpxName", + /* 202 */ "ifexists", + /* 203 */ "alter_db_optr", + /* 204 */ "alter_topic_optr", + /* 205 */ "acct_optr", + /* 206 */ "exprlist", + /* 207 */ "ifnotexists", + /* 208 */ "db_optr", + /* 209 */ "topic_optr", + /* 210 */ "typename", + /* 211 */ "bufsize", + /* 212 */ "pps", + /* 213 */ "tseries", + /* 214 */ "dbs", + /* 215 */ "streams", + /* 216 */ "storage", + /* 217 */ "qtime", + /* 218 */ "users", + /* 219 */ "conns", + /* 220 */ "state", + /* 221 */ "intitemlist", + /* 222 */ "intitem", + /* 223 */ "keep", + /* 224 */ "cache", + /* 225 */ "replica", + /* 226 */ "quorum", + /* 227 */ "days", + /* 228 */ "minrows", + /* 229 */ "maxrows", + /* 230 */ "blocks", + /* 231 */ "ctime", + /* 232 */ "wal", + /* 233 */ "fsync", + /* 234 */ "comp", + /* 235 */ "prec", + /* 236 */ "update", + /* 237 */ "cachelast", + /* 238 */ "partitions", + /* 239 */ "signed", + /* 240 */ "create_table_args", + /* 241 */ "create_stable_args", + /* 242 */ "create_table_list", + /* 243 */ "create_from_stable", + /* 244 */ "columnlist", + /* 245 */ "tagitemlist", + /* 246 */ "tagNamelist", + /* 247 */ "select", + /* 248 */ "column", + /* 249 */ "tagitem", + /* 250 */ "selcollist", + /* 251 */ "from", + /* 252 */ "where_opt", + /* 253 */ "interval_option", + /* 254 */ "sliding_opt", + /* 255 */ "session_option", + /* 256 */ "windowstate_option", + /* 257 */ "fill_opt", + /* 258 */ "groupby_opt", + /* 259 */ "having_opt", + /* 260 */ "orderby_opt", + /* 261 */ "slimit_opt", + /* 262 */ "limit_opt", + /* 263 */ "union", + /* 264 */ "sclp", + /* 265 */ "distinct", + /* 266 */ "expr", + /* 267 */ "as", + /* 268 */ "tablelist", + /* 269 */ "sub", + /* 270 */ "tmvar", + /* 271 */ "intervalKey", + /* 272 */ "sortlist", + /* 273 */ "sortitem", + /* 274 */ "item", + /* 275 */ "sortorder", + /* 276 */ "grouplist", + /* 277 */ "expritem", }; #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ @@ -1356,32 +1359,33 @@ static const char *const yyRuleName[] = { /* 264 */ "expr ::= expr REM expr", /* 265 */ "expr ::= expr LIKE expr", /* 266 */ "expr ::= expr MATCH expr", - /* 267 */ "expr ::= expr IN LP exprlist RP", - /* 268 */ "exprlist ::= exprlist COMMA expritem", - /* 269 */ "exprlist ::= expritem", - /* 270 */ "expritem ::= expr", - /* 271 */ "expritem ::=", - /* 272 */ "cmd ::= RESET QUERY CACHE", - /* 273 */ "cmd ::= SYNCDB ids REPLICA", - /* 274 */ "cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist", - /* 275 */ "cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids", - /* 276 */ "cmd ::= ALTER TABLE ids cpxName MODIFY COLUMN columnlist", - /* 277 */ "cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist", - /* 278 */ "cmd ::= ALTER TABLE ids cpxName DROP TAG ids", - /* 279 */ "cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids", - /* 280 */ "cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem", - /* 281 */ "cmd ::= ALTER TABLE ids cpxName MODIFY TAG columnlist", - /* 282 */ "cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist", - /* 283 */ "cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids", - /* 284 */ "cmd ::= ALTER STABLE ids cpxName MODIFY COLUMN columnlist", - /* 285 */ "cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist", - /* 286 */ "cmd ::= ALTER STABLE ids cpxName DROP TAG ids", - /* 287 */ "cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids", - /* 288 */ "cmd ::= ALTER STABLE ids cpxName SET TAG ids EQ tagitem", - /* 289 */ "cmd ::= ALTER STABLE ids cpxName MODIFY TAG columnlist", - /* 290 */ "cmd ::= KILL CONNECTION INTEGER", - /* 291 */ "cmd ::= KILL STREAM INTEGER COLON INTEGER", - /* 292 */ "cmd ::= KILL QUERY INTEGER COLON INTEGER", + /* 267 */ "expr ::= expr NMATCH expr", + /* 268 */ "expr ::= expr IN LP exprlist RP", + /* 269 */ "exprlist ::= exprlist COMMA expritem", + /* 270 */ "exprlist ::= expritem", + /* 271 */ "expritem ::= expr", + /* 272 */ "expritem ::=", + /* 273 */ "cmd ::= RESET QUERY CACHE", + /* 274 */ "cmd ::= SYNCDB ids REPLICA", + /* 275 */ "cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist", + /* 276 */ "cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids", + /* 277 */ "cmd ::= ALTER TABLE ids cpxName MODIFY COLUMN columnlist", + /* 278 */ "cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist", + /* 279 */ "cmd ::= ALTER TABLE ids cpxName DROP TAG ids", + /* 280 */ "cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids", + /* 281 */ "cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem", + /* 282 */ "cmd ::= ALTER TABLE ids cpxName MODIFY TAG columnlist", + /* 283 */ "cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist", + /* 284 */ "cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids", + /* 285 */ "cmd ::= ALTER STABLE ids cpxName MODIFY COLUMN columnlist", + /* 286 */ "cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist", + /* 287 */ "cmd ::= ALTER STABLE ids cpxName DROP TAG ids", + /* 288 */ "cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids", + /* 289 */ "cmd ::= ALTER STABLE ids cpxName SET TAG ids EQ tagitem", + /* 290 */ "cmd ::= ALTER STABLE ids cpxName MODIFY TAG columnlist", + /* 291 */ "cmd ::= KILL CONNECTION INTEGER", + /* 292 */ "cmd ::= KILL STREAM INTEGER COLON INTEGER", + /* 293 */ "cmd ::= KILL QUERY INTEGER COLON INTEGER", }; #endif /* NDEBUG */ @@ -1507,76 +1511,76 @@ static void yy_destructor( ** inside the C code. */ /********* Begin destructor definitions ***************************************/ - case 205: /* exprlist */ - case 249: /* selcollist */ - case 263: /* sclp */ + case 206: /* exprlist */ + case 250: /* selcollist */ + case 264: /* sclp */ { -#line 761 "sql.y" -tSqlExprListDestroy((yypminor->yy403)); -#line 1517 "sql.c" +#line 762 "sql.y" +tSqlExprListDestroy((yypminor->yy421)); +#line 1521 "sql.c" } break; - case 220: /* intitemlist */ - case 222: /* keep */ - case 243: /* columnlist */ - case 244: /* tagitemlist */ - case 245: /* tagNamelist */ - case 256: /* fill_opt */ - case 257: /* groupby_opt */ - case 259: /* orderby_opt */ - case 271: /* sortlist */ - case 275: /* grouplist */ + case 221: /* intitemlist */ + case 223: /* keep */ + case 244: /* columnlist */ + case 245: /* tagitemlist */ + case 246: /* tagNamelist */ + case 257: /* fill_opt */ + case 258: /* groupby_opt */ + case 260: /* orderby_opt */ + case 272: /* sortlist */ + case 276: /* grouplist */ { #line 256 "sql.y" -taosArrayDestroy((yypminor->yy403)); -#line 1533 "sql.c" +taosArrayDestroy((yypminor->yy421)); +#line 1537 "sql.c" } break; - case 241: /* create_table_list */ + case 242: /* create_table_list */ { #line 364 "sql.y" -destroyCreateTableSql((yypminor->yy56)); -#line 1540 "sql.c" +destroyCreateTableSql((yypminor->yy438)); +#line 1544 "sql.c" } break; - case 246: /* select */ + case 247: /* select */ { #line 484 "sql.y" -destroySqlNode((yypminor->yy224)); -#line 1547 "sql.c" +destroySqlNode((yypminor->yy56)); +#line 1551 "sql.c" } break; - case 250: /* from */ - case 267: /* tablelist */ - case 268: /* sub */ + case 251: /* from */ + case 268: /* tablelist */ + case 269: /* sub */ { #line 539 "sql.y" -destroyRelationInfo((yypminor->yy114)); -#line 1556 "sql.c" +destroyRelationInfo((yypminor->yy8)); +#line 1560 "sql.c" } break; - case 251: /* where_opt */ - case 258: /* having_opt */ - case 265: /* expr */ - case 276: /* expritem */ + case 252: /* where_opt */ + case 259: /* having_opt */ + case 266: /* expr */ + case 277: /* expritem */ { #line 691 "sql.y" -tSqlExprDestroy((yypminor->yy260)); -#line 1566 "sql.c" +tSqlExprDestroy((yypminor->yy439)); +#line 1570 "sql.c" } break; - case 262: /* union */ + case 263: /* union */ { #line 492 "sql.y" -destroyAllSqlNode((yypminor->yy403)); -#line 1573 "sql.c" +destroyAllSqlNode((yypminor->yy421)); +#line 1577 "sql.c" } break; - case 272: /* sortitem */ + case 273: /* sortitem */ { #line 624 "sql.y" -tVariantDestroy(&(yypminor->yy488)); -#line 1580 "sql.c" +tVariantDestroy(&(yypminor->yy430)); +#line 1584 "sql.c" } break; /********* End destructor definitions *****************************************/ @@ -1865,299 +1869,300 @@ static void yy_shift( /* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side ** of that rule */ static const YYCODETYPE yyRuleInfoLhs[] = { - 196, /* (0) program ::= cmd */ - 197, /* (1) cmd ::= SHOW DATABASES */ - 197, /* (2) cmd ::= SHOW TOPICS */ - 197, /* (3) cmd ::= SHOW FUNCTIONS */ - 197, /* (4) cmd ::= SHOW MNODES */ - 197, /* (5) cmd ::= SHOW DNODES */ - 197, /* (6) cmd ::= SHOW ACCOUNTS */ - 197, /* (7) cmd ::= SHOW USERS */ - 197, /* (8) cmd ::= SHOW MODULES */ - 197, /* (9) cmd ::= SHOW QUERIES */ - 197, /* (10) cmd ::= SHOW CONNECTIONS */ - 197, /* (11) cmd ::= SHOW STREAMS */ - 197, /* (12) cmd ::= SHOW VARIABLES */ - 197, /* (13) cmd ::= SHOW SCORES */ - 197, /* (14) cmd ::= SHOW GRANTS */ - 197, /* (15) cmd ::= SHOW VNODES */ - 197, /* (16) cmd ::= SHOW VNODES ids */ - 199, /* (17) dbPrefix ::= */ - 199, /* (18) dbPrefix ::= ids DOT */ - 200, /* (19) cpxName ::= */ - 200, /* (20) cpxName ::= DOT ids */ - 197, /* (21) cmd ::= SHOW CREATE TABLE ids cpxName */ - 197, /* (22) cmd ::= SHOW CREATE STABLE ids cpxName */ - 197, /* (23) cmd ::= SHOW CREATE DATABASE ids */ - 197, /* (24) cmd ::= SHOW dbPrefix TABLES */ - 197, /* (25) cmd ::= SHOW dbPrefix TABLES LIKE ids */ - 197, /* (26) cmd ::= SHOW dbPrefix STABLES */ - 197, /* (27) cmd ::= SHOW dbPrefix STABLES LIKE ids */ - 197, /* (28) cmd ::= SHOW dbPrefix VGROUPS */ - 197, /* (29) cmd ::= SHOW dbPrefix VGROUPS ids */ - 197, /* (30) cmd ::= DROP TABLE ifexists ids cpxName */ - 197, /* (31) cmd ::= DROP STABLE ifexists ids cpxName */ - 197, /* (32) cmd ::= DROP DATABASE ifexists ids */ - 197, /* (33) cmd ::= DROP TOPIC ifexists ids */ - 197, /* (34) cmd ::= DROP FUNCTION ids */ - 197, /* (35) cmd ::= DROP DNODE ids */ - 197, /* (36) cmd ::= DROP USER ids */ - 197, /* (37) cmd ::= DROP ACCOUNT ids */ - 197, /* (38) cmd ::= USE ids */ - 197, /* (39) cmd ::= DESCRIBE ids cpxName */ - 197, /* (40) cmd ::= DESC ids cpxName */ - 197, /* (41) cmd ::= ALTER USER ids PASS ids */ - 197, /* (42) cmd ::= ALTER USER ids PRIVILEGE ids */ - 197, /* (43) cmd ::= ALTER DNODE ids ids */ - 197, /* (44) cmd ::= ALTER DNODE ids ids ids */ - 197, /* (45) cmd ::= ALTER LOCAL ids */ - 197, /* (46) cmd ::= ALTER LOCAL ids ids */ - 197, /* (47) cmd ::= ALTER DATABASE ids alter_db_optr */ - 197, /* (48) cmd ::= ALTER TOPIC ids alter_topic_optr */ - 197, /* (49) cmd ::= ALTER ACCOUNT ids acct_optr */ - 197, /* (50) cmd ::= ALTER ACCOUNT ids PASS ids acct_optr */ - 197, /* (51) cmd ::= COMPACT VNODES IN LP exprlist RP */ - 198, /* (52) ids ::= ID */ - 198, /* (53) ids ::= STRING */ - 201, /* (54) ifexists ::= IF EXISTS */ - 201, /* (55) ifexists ::= */ - 206, /* (56) ifnotexists ::= IF NOT EXISTS */ - 206, /* (57) ifnotexists ::= */ - 197, /* (58) cmd ::= CREATE DNODE ids */ - 197, /* (59) cmd ::= CREATE ACCOUNT ids PASS ids acct_optr */ - 197, /* (60) cmd ::= CREATE DATABASE ifnotexists ids db_optr */ - 197, /* (61) cmd ::= CREATE TOPIC ifnotexists ids topic_optr */ - 197, /* (62) cmd ::= CREATE FUNCTION ids AS ids OUTPUTTYPE typename bufsize */ - 197, /* (63) cmd ::= CREATE AGGREGATE FUNCTION ids AS ids OUTPUTTYPE typename bufsize */ - 197, /* (64) cmd ::= CREATE USER ids PASS ids */ - 210, /* (65) bufsize ::= */ - 210, /* (66) bufsize ::= BUFSIZE INTEGER */ - 211, /* (67) pps ::= */ - 211, /* (68) pps ::= PPS INTEGER */ - 212, /* (69) tseries ::= */ - 212, /* (70) tseries ::= TSERIES INTEGER */ - 213, /* (71) dbs ::= */ - 213, /* (72) dbs ::= DBS INTEGER */ - 214, /* (73) streams ::= */ - 214, /* (74) streams ::= STREAMS INTEGER */ - 215, /* (75) storage ::= */ - 215, /* (76) storage ::= STORAGE INTEGER */ - 216, /* (77) qtime ::= */ - 216, /* (78) qtime ::= QTIME INTEGER */ - 217, /* (79) users ::= */ - 217, /* (80) users ::= USERS INTEGER */ - 218, /* (81) conns ::= */ - 218, /* (82) conns ::= CONNS INTEGER */ - 219, /* (83) state ::= */ - 219, /* (84) state ::= STATE ids */ - 204, /* (85) acct_optr ::= pps tseries storage streams qtime dbs users conns state */ - 220, /* (86) intitemlist ::= intitemlist COMMA intitem */ - 220, /* (87) intitemlist ::= intitem */ - 221, /* (88) intitem ::= INTEGER */ - 222, /* (89) keep ::= KEEP intitemlist */ - 223, /* (90) cache ::= CACHE INTEGER */ - 224, /* (91) replica ::= REPLICA INTEGER */ - 225, /* (92) quorum ::= QUORUM INTEGER */ - 226, /* (93) days ::= DAYS INTEGER */ - 227, /* (94) minrows ::= MINROWS INTEGER */ - 228, /* (95) maxrows ::= MAXROWS INTEGER */ - 229, /* (96) blocks ::= BLOCKS INTEGER */ - 230, /* (97) ctime ::= CTIME INTEGER */ - 231, /* (98) wal ::= WAL INTEGER */ - 232, /* (99) fsync ::= FSYNC INTEGER */ - 233, /* (100) comp ::= COMP INTEGER */ - 234, /* (101) prec ::= PRECISION STRING */ - 235, /* (102) update ::= UPDATE INTEGER */ - 236, /* (103) cachelast ::= CACHELAST INTEGER */ - 237, /* (104) partitions ::= PARTITIONS INTEGER */ - 207, /* (105) db_optr ::= */ - 207, /* (106) db_optr ::= db_optr cache */ - 207, /* (107) db_optr ::= db_optr replica */ - 207, /* (108) db_optr ::= db_optr quorum */ - 207, /* (109) db_optr ::= db_optr days */ - 207, /* (110) db_optr ::= db_optr minrows */ - 207, /* (111) db_optr ::= db_optr maxrows */ - 207, /* (112) db_optr ::= db_optr blocks */ - 207, /* (113) db_optr ::= db_optr ctime */ - 207, /* (114) db_optr ::= db_optr wal */ - 207, /* (115) db_optr ::= db_optr fsync */ - 207, /* (116) db_optr ::= db_optr comp */ - 207, /* (117) db_optr ::= db_optr prec */ - 207, /* (118) db_optr ::= db_optr keep */ - 207, /* (119) db_optr ::= db_optr update */ - 207, /* (120) db_optr ::= db_optr cachelast */ - 208, /* (121) topic_optr ::= db_optr */ - 208, /* (122) topic_optr ::= topic_optr partitions */ - 202, /* (123) alter_db_optr ::= */ - 202, /* (124) alter_db_optr ::= alter_db_optr replica */ - 202, /* (125) alter_db_optr ::= alter_db_optr quorum */ - 202, /* (126) alter_db_optr ::= alter_db_optr keep */ - 202, /* (127) alter_db_optr ::= alter_db_optr blocks */ - 202, /* (128) alter_db_optr ::= alter_db_optr comp */ - 202, /* (129) alter_db_optr ::= alter_db_optr update */ - 202, /* (130) alter_db_optr ::= alter_db_optr cachelast */ - 203, /* (131) alter_topic_optr ::= alter_db_optr */ - 203, /* (132) alter_topic_optr ::= alter_topic_optr partitions */ - 209, /* (133) typename ::= ids */ - 209, /* (134) typename ::= ids LP signed RP */ - 209, /* (135) typename ::= ids UNSIGNED */ - 238, /* (136) signed ::= INTEGER */ - 238, /* (137) signed ::= PLUS INTEGER */ - 238, /* (138) signed ::= MINUS INTEGER */ - 197, /* (139) cmd ::= CREATE TABLE create_table_args */ - 197, /* (140) cmd ::= CREATE TABLE create_stable_args */ - 197, /* (141) cmd ::= CREATE STABLE create_stable_args */ - 197, /* (142) cmd ::= CREATE TABLE create_table_list */ - 241, /* (143) create_table_list ::= create_from_stable */ - 241, /* (144) create_table_list ::= create_table_list create_from_stable */ - 239, /* (145) create_table_args ::= ifnotexists ids cpxName LP columnlist RP */ - 240, /* (146) create_stable_args ::= ifnotexists ids cpxName LP columnlist RP TAGS LP columnlist RP */ - 242, /* (147) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName TAGS LP tagitemlist RP */ - 242, /* (148) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName LP tagNamelist RP TAGS LP tagitemlist RP */ - 245, /* (149) tagNamelist ::= tagNamelist COMMA ids */ - 245, /* (150) tagNamelist ::= ids */ - 239, /* (151) create_table_args ::= ifnotexists ids cpxName AS select */ - 243, /* (152) columnlist ::= columnlist COMMA column */ - 243, /* (153) columnlist ::= column */ - 247, /* (154) column ::= ids typename */ - 244, /* (155) tagitemlist ::= tagitemlist COMMA tagitem */ - 244, /* (156) tagitemlist ::= tagitem */ - 248, /* (157) tagitem ::= INTEGER */ - 248, /* (158) tagitem ::= FLOAT */ - 248, /* (159) tagitem ::= STRING */ - 248, /* (160) tagitem ::= BOOL */ - 248, /* (161) tagitem ::= NULL */ - 248, /* (162) tagitem ::= NOW */ - 248, /* (163) tagitem ::= MINUS INTEGER */ - 248, /* (164) tagitem ::= MINUS FLOAT */ - 248, /* (165) tagitem ::= PLUS INTEGER */ - 248, /* (166) tagitem ::= PLUS FLOAT */ - 246, /* (167) select ::= SELECT selcollist from where_opt interval_option sliding_opt session_option windowstate_option fill_opt groupby_opt having_opt orderby_opt slimit_opt limit_opt */ - 246, /* (168) select ::= LP select RP */ - 262, /* (169) union ::= select */ - 262, /* (170) union ::= union UNION ALL select */ - 197, /* (171) cmd ::= union */ - 246, /* (172) select ::= SELECT selcollist */ - 263, /* (173) sclp ::= selcollist COMMA */ - 263, /* (174) sclp ::= */ - 249, /* (175) selcollist ::= sclp distinct expr as */ - 249, /* (176) selcollist ::= sclp STAR */ - 266, /* (177) as ::= AS ids */ - 266, /* (178) as ::= ids */ - 266, /* (179) as ::= */ - 264, /* (180) distinct ::= DISTINCT */ - 264, /* (181) distinct ::= */ - 250, /* (182) from ::= FROM tablelist */ - 250, /* (183) from ::= FROM sub */ - 268, /* (184) sub ::= LP union RP */ - 268, /* (185) sub ::= LP union RP ids */ - 268, /* (186) sub ::= sub COMMA LP union RP ids */ - 267, /* (187) tablelist ::= ids cpxName */ - 267, /* (188) tablelist ::= ids cpxName ids */ - 267, /* (189) tablelist ::= tablelist COMMA ids cpxName */ - 267, /* (190) tablelist ::= tablelist COMMA ids cpxName ids */ - 269, /* (191) tmvar ::= VARIABLE */ - 252, /* (192) interval_option ::= intervalKey LP tmvar RP */ - 252, /* (193) interval_option ::= intervalKey LP tmvar COMMA tmvar RP */ - 252, /* (194) interval_option ::= */ - 270, /* (195) intervalKey ::= INTERVAL */ - 270, /* (196) intervalKey ::= EVERY */ - 254, /* (197) session_option ::= */ - 254, /* (198) session_option ::= SESSION LP ids cpxName COMMA tmvar RP */ - 255, /* (199) windowstate_option ::= */ - 255, /* (200) windowstate_option ::= STATE_WINDOW LP ids RP */ - 256, /* (201) fill_opt ::= */ - 256, /* (202) fill_opt ::= FILL LP ID COMMA tagitemlist RP */ - 256, /* (203) fill_opt ::= FILL LP ID RP */ - 253, /* (204) sliding_opt ::= SLIDING LP tmvar RP */ - 253, /* (205) sliding_opt ::= */ - 259, /* (206) orderby_opt ::= */ - 259, /* (207) orderby_opt ::= ORDER BY sortlist */ - 271, /* (208) sortlist ::= sortlist COMMA item sortorder */ - 271, /* (209) sortlist ::= item sortorder */ - 273, /* (210) item ::= ids cpxName */ - 274, /* (211) sortorder ::= ASC */ - 274, /* (212) sortorder ::= DESC */ - 274, /* (213) sortorder ::= */ - 257, /* (214) groupby_opt ::= */ - 257, /* (215) groupby_opt ::= GROUP BY grouplist */ - 275, /* (216) grouplist ::= grouplist COMMA item */ - 275, /* (217) grouplist ::= item */ - 258, /* (218) having_opt ::= */ - 258, /* (219) having_opt ::= HAVING expr */ - 261, /* (220) limit_opt ::= */ - 261, /* (221) limit_opt ::= LIMIT signed */ - 261, /* (222) limit_opt ::= LIMIT signed OFFSET signed */ - 261, /* (223) limit_opt ::= LIMIT signed COMMA signed */ - 260, /* (224) slimit_opt ::= */ - 260, /* (225) slimit_opt ::= SLIMIT signed */ - 260, /* (226) slimit_opt ::= SLIMIT signed SOFFSET signed */ - 260, /* (227) slimit_opt ::= SLIMIT signed COMMA signed */ - 251, /* (228) where_opt ::= */ - 251, /* (229) where_opt ::= WHERE expr */ - 265, /* (230) expr ::= LP expr RP */ - 265, /* (231) expr ::= ID */ - 265, /* (232) expr ::= ID DOT ID */ - 265, /* (233) expr ::= ID DOT STAR */ - 265, /* (234) expr ::= INTEGER */ - 265, /* (235) expr ::= MINUS INTEGER */ - 265, /* (236) expr ::= PLUS INTEGER */ - 265, /* (237) expr ::= FLOAT */ - 265, /* (238) expr ::= MINUS FLOAT */ - 265, /* (239) expr ::= PLUS FLOAT */ - 265, /* (240) expr ::= STRING */ - 265, /* (241) expr ::= NOW */ - 265, /* (242) expr ::= VARIABLE */ - 265, /* (243) expr ::= PLUS VARIABLE */ - 265, /* (244) expr ::= MINUS VARIABLE */ - 265, /* (245) expr ::= BOOL */ - 265, /* (246) expr ::= NULL */ - 265, /* (247) expr ::= ID LP exprlist RP */ - 265, /* (248) expr ::= ID LP STAR RP */ - 265, /* (249) expr ::= expr IS NULL */ - 265, /* (250) expr ::= expr IS NOT NULL */ - 265, /* (251) expr ::= expr LT expr */ - 265, /* (252) expr ::= expr GT expr */ - 265, /* (253) expr ::= expr LE expr */ - 265, /* (254) expr ::= expr GE expr */ - 265, /* (255) expr ::= expr NE expr */ - 265, /* (256) expr ::= expr EQ expr */ - 265, /* (257) expr ::= expr BETWEEN expr AND expr */ - 265, /* (258) expr ::= expr AND expr */ - 265, /* (259) expr ::= expr OR expr */ - 265, /* (260) expr ::= expr PLUS expr */ - 265, /* (261) expr ::= expr MINUS expr */ - 265, /* (262) expr ::= expr STAR expr */ - 265, /* (263) expr ::= expr SLASH expr */ - 265, /* (264) expr ::= expr REM expr */ - 265, /* (265) expr ::= expr LIKE expr */ - 265, /* (266) expr ::= expr MATCH expr */ - 265, /* (267) expr ::= expr IN LP exprlist RP */ - 205, /* (268) exprlist ::= exprlist COMMA expritem */ - 205, /* (269) exprlist ::= expritem */ - 276, /* (270) expritem ::= expr */ - 276, /* (271) expritem ::= */ - 197, /* (272) cmd ::= RESET QUERY CACHE */ - 197, /* (273) cmd ::= SYNCDB ids REPLICA */ - 197, /* (274) cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ - 197, /* (275) cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ - 197, /* (276) cmd ::= ALTER TABLE ids cpxName MODIFY COLUMN columnlist */ - 197, /* (277) cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ - 197, /* (278) cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ - 197, /* (279) cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ - 197, /* (280) cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ - 197, /* (281) cmd ::= ALTER TABLE ids cpxName MODIFY TAG columnlist */ - 197, /* (282) cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ - 197, /* (283) cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ - 197, /* (284) cmd ::= ALTER STABLE ids cpxName MODIFY COLUMN columnlist */ - 197, /* (285) cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ - 197, /* (286) cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ - 197, /* (287) cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ - 197, /* (288) cmd ::= ALTER STABLE ids cpxName SET TAG ids EQ tagitem */ - 197, /* (289) cmd ::= ALTER STABLE ids cpxName MODIFY TAG columnlist */ - 197, /* (290) cmd ::= KILL CONNECTION INTEGER */ - 197, /* (291) cmd ::= KILL STREAM INTEGER COLON INTEGER */ - 197, /* (292) cmd ::= KILL QUERY INTEGER COLON INTEGER */ + 197, /* (0) program ::= cmd */ + 198, /* (1) cmd ::= SHOW DATABASES */ + 198, /* (2) cmd ::= SHOW TOPICS */ + 198, /* (3) cmd ::= SHOW FUNCTIONS */ + 198, /* (4) cmd ::= SHOW MNODES */ + 198, /* (5) cmd ::= SHOW DNODES */ + 198, /* (6) cmd ::= SHOW ACCOUNTS */ + 198, /* (7) cmd ::= SHOW USERS */ + 198, /* (8) cmd ::= SHOW MODULES */ + 198, /* (9) cmd ::= SHOW QUERIES */ + 198, /* (10) cmd ::= SHOW CONNECTIONS */ + 198, /* (11) cmd ::= SHOW STREAMS */ + 198, /* (12) cmd ::= SHOW VARIABLES */ + 198, /* (13) cmd ::= SHOW SCORES */ + 198, /* (14) cmd ::= SHOW GRANTS */ + 198, /* (15) cmd ::= SHOW VNODES */ + 198, /* (16) cmd ::= SHOW VNODES ids */ + 200, /* (17) dbPrefix ::= */ + 200, /* (18) dbPrefix ::= ids DOT */ + 201, /* (19) cpxName ::= */ + 201, /* (20) cpxName ::= DOT ids */ + 198, /* (21) cmd ::= SHOW CREATE TABLE ids cpxName */ + 198, /* (22) cmd ::= SHOW CREATE STABLE ids cpxName */ + 198, /* (23) cmd ::= SHOW CREATE DATABASE ids */ + 198, /* (24) cmd ::= SHOW dbPrefix TABLES */ + 198, /* (25) cmd ::= SHOW dbPrefix TABLES LIKE ids */ + 198, /* (26) cmd ::= SHOW dbPrefix STABLES */ + 198, /* (27) cmd ::= SHOW dbPrefix STABLES LIKE ids */ + 198, /* (28) cmd ::= SHOW dbPrefix VGROUPS */ + 198, /* (29) cmd ::= SHOW dbPrefix VGROUPS ids */ + 198, /* (30) cmd ::= DROP TABLE ifexists ids cpxName */ + 198, /* (31) cmd ::= DROP STABLE ifexists ids cpxName */ + 198, /* (32) cmd ::= DROP DATABASE ifexists ids */ + 198, /* (33) cmd ::= DROP TOPIC ifexists ids */ + 198, /* (34) cmd ::= DROP FUNCTION ids */ + 198, /* (35) cmd ::= DROP DNODE ids */ + 198, /* (36) cmd ::= DROP USER ids */ + 198, /* (37) cmd ::= DROP ACCOUNT ids */ + 198, /* (38) cmd ::= USE ids */ + 198, /* (39) cmd ::= DESCRIBE ids cpxName */ + 198, /* (40) cmd ::= DESC ids cpxName */ + 198, /* (41) cmd ::= ALTER USER ids PASS ids */ + 198, /* (42) cmd ::= ALTER USER ids PRIVILEGE ids */ + 198, /* (43) cmd ::= ALTER DNODE ids ids */ + 198, /* (44) cmd ::= ALTER DNODE ids ids ids */ + 198, /* (45) cmd ::= ALTER LOCAL ids */ + 198, /* (46) cmd ::= ALTER LOCAL ids ids */ + 198, /* (47) cmd ::= ALTER DATABASE ids alter_db_optr */ + 198, /* (48) cmd ::= ALTER TOPIC ids alter_topic_optr */ + 198, /* (49) cmd ::= ALTER ACCOUNT ids acct_optr */ + 198, /* (50) cmd ::= ALTER ACCOUNT ids PASS ids acct_optr */ + 198, /* (51) cmd ::= COMPACT VNODES IN LP exprlist RP */ + 199, /* (52) ids ::= ID */ + 199, /* (53) ids ::= STRING */ + 202, /* (54) ifexists ::= IF EXISTS */ + 202, /* (55) ifexists ::= */ + 207, /* (56) ifnotexists ::= IF NOT EXISTS */ + 207, /* (57) ifnotexists ::= */ + 198, /* (58) cmd ::= CREATE DNODE ids */ + 198, /* (59) cmd ::= CREATE ACCOUNT ids PASS ids acct_optr */ + 198, /* (60) cmd ::= CREATE DATABASE ifnotexists ids db_optr */ + 198, /* (61) cmd ::= CREATE TOPIC ifnotexists ids topic_optr */ + 198, /* (62) cmd ::= CREATE FUNCTION ids AS ids OUTPUTTYPE typename bufsize */ + 198, /* (63) cmd ::= CREATE AGGREGATE FUNCTION ids AS ids OUTPUTTYPE typename bufsize */ + 198, /* (64) cmd ::= CREATE USER ids PASS ids */ + 211, /* (65) bufsize ::= */ + 211, /* (66) bufsize ::= BUFSIZE INTEGER */ + 212, /* (67) pps ::= */ + 212, /* (68) pps ::= PPS INTEGER */ + 213, /* (69) tseries ::= */ + 213, /* (70) tseries ::= TSERIES INTEGER */ + 214, /* (71) dbs ::= */ + 214, /* (72) dbs ::= DBS INTEGER */ + 215, /* (73) streams ::= */ + 215, /* (74) streams ::= STREAMS INTEGER */ + 216, /* (75) storage ::= */ + 216, /* (76) storage ::= STORAGE INTEGER */ + 217, /* (77) qtime ::= */ + 217, /* (78) qtime ::= QTIME INTEGER */ + 218, /* (79) users ::= */ + 218, /* (80) users ::= USERS INTEGER */ + 219, /* (81) conns ::= */ + 219, /* (82) conns ::= CONNS INTEGER */ + 220, /* (83) state ::= */ + 220, /* (84) state ::= STATE ids */ + 205, /* (85) acct_optr ::= pps tseries storage streams qtime dbs users conns state */ + 221, /* (86) intitemlist ::= intitemlist COMMA intitem */ + 221, /* (87) intitemlist ::= intitem */ + 222, /* (88) intitem ::= INTEGER */ + 223, /* (89) keep ::= KEEP intitemlist */ + 224, /* (90) cache ::= CACHE INTEGER */ + 225, /* (91) replica ::= REPLICA INTEGER */ + 226, /* (92) quorum ::= QUORUM INTEGER */ + 227, /* (93) days ::= DAYS INTEGER */ + 228, /* (94) minrows ::= MINROWS INTEGER */ + 229, /* (95) maxrows ::= MAXROWS INTEGER */ + 230, /* (96) blocks ::= BLOCKS INTEGER */ + 231, /* (97) ctime ::= CTIME INTEGER */ + 232, /* (98) wal ::= WAL INTEGER */ + 233, /* (99) fsync ::= FSYNC INTEGER */ + 234, /* (100) comp ::= COMP INTEGER */ + 235, /* (101) prec ::= PRECISION STRING */ + 236, /* (102) update ::= UPDATE INTEGER */ + 237, /* (103) cachelast ::= CACHELAST INTEGER */ + 238, /* (104) partitions ::= PARTITIONS INTEGER */ + 208, /* (105) db_optr ::= */ + 208, /* (106) db_optr ::= db_optr cache */ + 208, /* (107) db_optr ::= db_optr replica */ + 208, /* (108) db_optr ::= db_optr quorum */ + 208, /* (109) db_optr ::= db_optr days */ + 208, /* (110) db_optr ::= db_optr minrows */ + 208, /* (111) db_optr ::= db_optr maxrows */ + 208, /* (112) db_optr ::= db_optr blocks */ + 208, /* (113) db_optr ::= db_optr ctime */ + 208, /* (114) db_optr ::= db_optr wal */ + 208, /* (115) db_optr ::= db_optr fsync */ + 208, /* (116) db_optr ::= db_optr comp */ + 208, /* (117) db_optr ::= db_optr prec */ + 208, /* (118) db_optr ::= db_optr keep */ + 208, /* (119) db_optr ::= db_optr update */ + 208, /* (120) db_optr ::= db_optr cachelast */ + 209, /* (121) topic_optr ::= db_optr */ + 209, /* (122) topic_optr ::= topic_optr partitions */ + 203, /* (123) alter_db_optr ::= */ + 203, /* (124) alter_db_optr ::= alter_db_optr replica */ + 203, /* (125) alter_db_optr ::= alter_db_optr quorum */ + 203, /* (126) alter_db_optr ::= alter_db_optr keep */ + 203, /* (127) alter_db_optr ::= alter_db_optr blocks */ + 203, /* (128) alter_db_optr ::= alter_db_optr comp */ + 203, /* (129) alter_db_optr ::= alter_db_optr update */ + 203, /* (130) alter_db_optr ::= alter_db_optr cachelast */ + 204, /* (131) alter_topic_optr ::= alter_db_optr */ + 204, /* (132) alter_topic_optr ::= alter_topic_optr partitions */ + 210, /* (133) typename ::= ids */ + 210, /* (134) typename ::= ids LP signed RP */ + 210, /* (135) typename ::= ids UNSIGNED */ + 239, /* (136) signed ::= INTEGER */ + 239, /* (137) signed ::= PLUS INTEGER */ + 239, /* (138) signed ::= MINUS INTEGER */ + 198, /* (139) cmd ::= CREATE TABLE create_table_args */ + 198, /* (140) cmd ::= CREATE TABLE create_stable_args */ + 198, /* (141) cmd ::= CREATE STABLE create_stable_args */ + 198, /* (142) cmd ::= CREATE TABLE create_table_list */ + 242, /* (143) create_table_list ::= create_from_stable */ + 242, /* (144) create_table_list ::= create_table_list create_from_stable */ + 240, /* (145) create_table_args ::= ifnotexists ids cpxName LP columnlist RP */ + 241, /* (146) create_stable_args ::= ifnotexists ids cpxName LP columnlist RP TAGS LP columnlist RP */ + 243, /* (147) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName TAGS LP tagitemlist RP */ + 243, /* (148) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName LP tagNamelist RP TAGS LP tagitemlist RP */ + 246, /* (149) tagNamelist ::= tagNamelist COMMA ids */ + 246, /* (150) tagNamelist ::= ids */ + 240, /* (151) create_table_args ::= ifnotexists ids cpxName AS select */ + 244, /* (152) columnlist ::= columnlist COMMA column */ + 244, /* (153) columnlist ::= column */ + 248, /* (154) column ::= ids typename */ + 245, /* (155) tagitemlist ::= tagitemlist COMMA tagitem */ + 245, /* (156) tagitemlist ::= tagitem */ + 249, /* (157) tagitem ::= INTEGER */ + 249, /* (158) tagitem ::= FLOAT */ + 249, /* (159) tagitem ::= STRING */ + 249, /* (160) tagitem ::= BOOL */ + 249, /* (161) tagitem ::= NULL */ + 249, /* (162) tagitem ::= NOW */ + 249, /* (163) tagitem ::= MINUS INTEGER */ + 249, /* (164) tagitem ::= MINUS FLOAT */ + 249, /* (165) tagitem ::= PLUS INTEGER */ + 249, /* (166) tagitem ::= PLUS FLOAT */ + 247, /* (167) select ::= SELECT selcollist from where_opt interval_option sliding_opt session_option windowstate_option fill_opt groupby_opt having_opt orderby_opt slimit_opt limit_opt */ + 247, /* (168) select ::= LP select RP */ + 263, /* (169) union ::= select */ + 263, /* (170) union ::= union UNION ALL select */ + 198, /* (171) cmd ::= union */ + 247, /* (172) select ::= SELECT selcollist */ + 264, /* (173) sclp ::= selcollist COMMA */ + 264, /* (174) sclp ::= */ + 250, /* (175) selcollist ::= sclp distinct expr as */ + 250, /* (176) selcollist ::= sclp STAR */ + 267, /* (177) as ::= AS ids */ + 267, /* (178) as ::= ids */ + 267, /* (179) as ::= */ + 265, /* (180) distinct ::= DISTINCT */ + 265, /* (181) distinct ::= */ + 251, /* (182) from ::= FROM tablelist */ + 251, /* (183) from ::= FROM sub */ + 269, /* (184) sub ::= LP union RP */ + 269, /* (185) sub ::= LP union RP ids */ + 269, /* (186) sub ::= sub COMMA LP union RP ids */ + 268, /* (187) tablelist ::= ids cpxName */ + 268, /* (188) tablelist ::= ids cpxName ids */ + 268, /* (189) tablelist ::= tablelist COMMA ids cpxName */ + 268, /* (190) tablelist ::= tablelist COMMA ids cpxName ids */ + 270, /* (191) tmvar ::= VARIABLE */ + 253, /* (192) interval_option ::= intervalKey LP tmvar RP */ + 253, /* (193) interval_option ::= intervalKey LP tmvar COMMA tmvar RP */ + 253, /* (194) interval_option ::= */ + 271, /* (195) intervalKey ::= INTERVAL */ + 271, /* (196) intervalKey ::= EVERY */ + 255, /* (197) session_option ::= */ + 255, /* (198) session_option ::= SESSION LP ids cpxName COMMA tmvar RP */ + 256, /* (199) windowstate_option ::= */ + 256, /* (200) windowstate_option ::= STATE_WINDOW LP ids RP */ + 257, /* (201) fill_opt ::= */ + 257, /* (202) fill_opt ::= FILL LP ID COMMA tagitemlist RP */ + 257, /* (203) fill_opt ::= FILL LP ID RP */ + 254, /* (204) sliding_opt ::= SLIDING LP tmvar RP */ + 254, /* (205) sliding_opt ::= */ + 260, /* (206) orderby_opt ::= */ + 260, /* (207) orderby_opt ::= ORDER BY sortlist */ + 272, /* (208) sortlist ::= sortlist COMMA item sortorder */ + 272, /* (209) sortlist ::= item sortorder */ + 274, /* (210) item ::= ids cpxName */ + 275, /* (211) sortorder ::= ASC */ + 275, /* (212) sortorder ::= DESC */ + 275, /* (213) sortorder ::= */ + 258, /* (214) groupby_opt ::= */ + 258, /* (215) groupby_opt ::= GROUP BY grouplist */ + 276, /* (216) grouplist ::= grouplist COMMA item */ + 276, /* (217) grouplist ::= item */ + 259, /* (218) having_opt ::= */ + 259, /* (219) having_opt ::= HAVING expr */ + 262, /* (220) limit_opt ::= */ + 262, /* (221) limit_opt ::= LIMIT signed */ + 262, /* (222) limit_opt ::= LIMIT signed OFFSET signed */ + 262, /* (223) limit_opt ::= LIMIT signed COMMA signed */ + 261, /* (224) slimit_opt ::= */ + 261, /* (225) slimit_opt ::= SLIMIT signed */ + 261, /* (226) slimit_opt ::= SLIMIT signed SOFFSET signed */ + 261, /* (227) slimit_opt ::= SLIMIT signed COMMA signed */ + 252, /* (228) where_opt ::= */ + 252, /* (229) where_opt ::= WHERE expr */ + 266, /* (230) expr ::= LP expr RP */ + 266, /* (231) expr ::= ID */ + 266, /* (232) expr ::= ID DOT ID */ + 266, /* (233) expr ::= ID DOT STAR */ + 266, /* (234) expr ::= INTEGER */ + 266, /* (235) expr ::= MINUS INTEGER */ + 266, /* (236) expr ::= PLUS INTEGER */ + 266, /* (237) expr ::= FLOAT */ + 266, /* (238) expr ::= MINUS FLOAT */ + 266, /* (239) expr ::= PLUS FLOAT */ + 266, /* (240) expr ::= STRING */ + 266, /* (241) expr ::= NOW */ + 266, /* (242) expr ::= VARIABLE */ + 266, /* (243) expr ::= PLUS VARIABLE */ + 266, /* (244) expr ::= MINUS VARIABLE */ + 266, /* (245) expr ::= BOOL */ + 266, /* (246) expr ::= NULL */ + 266, /* (247) expr ::= ID LP exprlist RP */ + 266, /* (248) expr ::= ID LP STAR RP */ + 266, /* (249) expr ::= expr IS NULL */ + 266, /* (250) expr ::= expr IS NOT NULL */ + 266, /* (251) expr ::= expr LT expr */ + 266, /* (252) expr ::= expr GT expr */ + 266, /* (253) expr ::= expr LE expr */ + 266, /* (254) expr ::= expr GE expr */ + 266, /* (255) expr ::= expr NE expr */ + 266, /* (256) expr ::= expr EQ expr */ + 266, /* (257) expr ::= expr BETWEEN expr AND expr */ + 266, /* (258) expr ::= expr AND expr */ + 266, /* (259) expr ::= expr OR expr */ + 266, /* (260) expr ::= expr PLUS expr */ + 266, /* (261) expr ::= expr MINUS expr */ + 266, /* (262) expr ::= expr STAR expr */ + 266, /* (263) expr ::= expr SLASH expr */ + 266, /* (264) expr ::= expr REM expr */ + 266, /* (265) expr ::= expr LIKE expr */ + 266, /* (266) expr ::= expr MATCH expr */ + 266, /* (267) expr ::= expr NMATCH expr */ + 266, /* (268) expr ::= expr IN LP exprlist RP */ + 206, /* (269) exprlist ::= exprlist COMMA expritem */ + 206, /* (270) exprlist ::= expritem */ + 277, /* (271) expritem ::= expr */ + 277, /* (272) expritem ::= */ + 198, /* (273) cmd ::= RESET QUERY CACHE */ + 198, /* (274) cmd ::= SYNCDB ids REPLICA */ + 198, /* (275) cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ + 198, /* (276) cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ + 198, /* (277) cmd ::= ALTER TABLE ids cpxName MODIFY COLUMN columnlist */ + 198, /* (278) cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ + 198, /* (279) cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ + 198, /* (280) cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ + 198, /* (281) cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ + 198, /* (282) cmd ::= ALTER TABLE ids cpxName MODIFY TAG columnlist */ + 198, /* (283) cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ + 198, /* (284) cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ + 198, /* (285) cmd ::= ALTER STABLE ids cpxName MODIFY COLUMN columnlist */ + 198, /* (286) cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ + 198, /* (287) cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ + 198, /* (288) cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ + 198, /* (289) cmd ::= ALTER STABLE ids cpxName SET TAG ids EQ tagitem */ + 198, /* (290) cmd ::= ALTER STABLE ids cpxName MODIFY TAG columnlist */ + 198, /* (291) cmd ::= KILL CONNECTION INTEGER */ + 198, /* (292) cmd ::= KILL STREAM INTEGER COLON INTEGER */ + 198, /* (293) cmd ::= KILL QUERY INTEGER COLON INTEGER */ }; /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number @@ -2430,32 +2435,33 @@ static const signed char yyRuleInfoNRhs[] = { -3, /* (264) expr ::= expr REM expr */ -3, /* (265) expr ::= expr LIKE expr */ -3, /* (266) expr ::= expr MATCH expr */ - -5, /* (267) expr ::= expr IN LP exprlist RP */ - -3, /* (268) exprlist ::= exprlist COMMA expritem */ - -1, /* (269) exprlist ::= expritem */ - -1, /* (270) expritem ::= expr */ - 0, /* (271) expritem ::= */ - -3, /* (272) cmd ::= RESET QUERY CACHE */ - -3, /* (273) cmd ::= SYNCDB ids REPLICA */ - -7, /* (274) cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ - -7, /* (275) cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ - -7, /* (276) cmd ::= ALTER TABLE ids cpxName MODIFY COLUMN columnlist */ - -7, /* (277) cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ - -7, /* (278) cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ - -8, /* (279) cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ - -9, /* (280) cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ - -7, /* (281) cmd ::= ALTER TABLE ids cpxName MODIFY TAG columnlist */ - -7, /* (282) cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ - -7, /* (283) cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ - -7, /* (284) cmd ::= ALTER STABLE ids cpxName MODIFY COLUMN columnlist */ - -7, /* (285) cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ - -7, /* (286) cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ - -8, /* (287) cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ - -9, /* (288) cmd ::= ALTER STABLE ids cpxName SET TAG ids EQ tagitem */ - -7, /* (289) cmd ::= ALTER STABLE ids cpxName MODIFY TAG columnlist */ - -3, /* (290) cmd ::= KILL CONNECTION INTEGER */ - -5, /* (291) cmd ::= KILL STREAM INTEGER COLON INTEGER */ - -5, /* (292) cmd ::= KILL QUERY INTEGER COLON INTEGER */ + -3, /* (267) expr ::= expr NMATCH expr */ + -5, /* (268) expr ::= expr IN LP exprlist RP */ + -3, /* (269) exprlist ::= exprlist COMMA expritem */ + -1, /* (270) exprlist ::= expritem */ + -1, /* (271) expritem ::= expr */ + 0, /* (272) expritem ::= */ + -3, /* (273) cmd ::= RESET QUERY CACHE */ + -3, /* (274) cmd ::= SYNCDB ids REPLICA */ + -7, /* (275) cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ + -7, /* (276) cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ + -7, /* (277) cmd ::= ALTER TABLE ids cpxName MODIFY COLUMN columnlist */ + -7, /* (278) cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ + -7, /* (279) cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ + -8, /* (280) cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ + -9, /* (281) cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ + -7, /* (282) cmd ::= ALTER TABLE ids cpxName MODIFY TAG columnlist */ + -7, /* (283) cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ + -7, /* (284) cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ + -7, /* (285) cmd ::= ALTER STABLE ids cpxName MODIFY COLUMN columnlist */ + -7, /* (286) cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ + -7, /* (287) cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ + -8, /* (288) cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ + -9, /* (289) cmd ::= ALTER STABLE ids cpxName SET TAG ids EQ tagitem */ + -7, /* (290) cmd ::= ALTER STABLE ids cpxName MODIFY TAG columnlist */ + -3, /* (291) cmd ::= KILL CONNECTION INTEGER */ + -5, /* (292) cmd ::= KILL STREAM INTEGER COLON INTEGER */ + -5, /* (293) cmd ::= KILL QUERY INTEGER COLON INTEGER */ }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -2551,108 +2557,108 @@ static YYACTIONTYPE yy_reduce( case 141: /* cmd ::= CREATE STABLE create_stable_args */ yytestcase(yyruleno==141); #line 63 "sql.y" {} -#line 2555 "sql.c" +#line 2561 "sql.c" break; case 1: /* cmd ::= SHOW DATABASES */ #line 66 "sql.y" { setShowOptions(pInfo, TSDB_MGMT_TABLE_DB, 0, 0);} -#line 2560 "sql.c" +#line 2566 "sql.c" break; case 2: /* cmd ::= SHOW TOPICS */ #line 67 "sql.y" { setShowOptions(pInfo, TSDB_MGMT_TABLE_TP, 0, 0);} -#line 2565 "sql.c" +#line 2571 "sql.c" break; case 3: /* cmd ::= SHOW FUNCTIONS */ #line 68 "sql.y" { setShowOptions(pInfo, TSDB_MGMT_TABLE_FUNCTION, 0, 0);} -#line 2570 "sql.c" +#line 2576 "sql.c" break; case 4: /* cmd ::= SHOW MNODES */ #line 69 "sql.y" { setShowOptions(pInfo, TSDB_MGMT_TABLE_MNODE, 0, 0);} -#line 2575 "sql.c" +#line 2581 "sql.c" break; case 5: /* cmd ::= SHOW DNODES */ #line 70 "sql.y" { setShowOptions(pInfo, TSDB_MGMT_TABLE_DNODE, 0, 0);} -#line 2580 "sql.c" +#line 2586 "sql.c" break; case 6: /* cmd ::= SHOW ACCOUNTS */ #line 71 "sql.y" { setShowOptions(pInfo, TSDB_MGMT_TABLE_ACCT, 0, 0);} -#line 2585 "sql.c" +#line 2591 "sql.c" break; case 7: /* cmd ::= SHOW USERS */ #line 72 "sql.y" { setShowOptions(pInfo, TSDB_MGMT_TABLE_USER, 0, 0);} -#line 2590 "sql.c" +#line 2596 "sql.c" break; case 8: /* cmd ::= SHOW MODULES */ #line 74 "sql.y" { setShowOptions(pInfo, TSDB_MGMT_TABLE_MODULE, 0, 0); } -#line 2595 "sql.c" +#line 2601 "sql.c" break; case 9: /* cmd ::= SHOW QUERIES */ #line 75 "sql.y" { setShowOptions(pInfo, TSDB_MGMT_TABLE_QUERIES, 0, 0); } -#line 2600 "sql.c" +#line 2606 "sql.c" break; case 10: /* cmd ::= SHOW CONNECTIONS */ #line 76 "sql.y" { setShowOptions(pInfo, TSDB_MGMT_TABLE_CONNS, 0, 0);} -#line 2605 "sql.c" +#line 2611 "sql.c" break; case 11: /* cmd ::= SHOW STREAMS */ #line 77 "sql.y" { setShowOptions(pInfo, TSDB_MGMT_TABLE_STREAMS, 0, 0); } -#line 2610 "sql.c" +#line 2616 "sql.c" break; case 12: /* cmd ::= SHOW VARIABLES */ #line 78 "sql.y" { setShowOptions(pInfo, TSDB_MGMT_TABLE_VARIABLES, 0, 0); } -#line 2615 "sql.c" +#line 2621 "sql.c" break; case 13: /* cmd ::= SHOW SCORES */ #line 79 "sql.y" { setShowOptions(pInfo, TSDB_MGMT_TABLE_SCORES, 0, 0); } -#line 2620 "sql.c" +#line 2626 "sql.c" break; case 14: /* cmd ::= SHOW GRANTS */ #line 80 "sql.y" { setShowOptions(pInfo, TSDB_MGMT_TABLE_GRANTS, 0, 0); } -#line 2625 "sql.c" +#line 2631 "sql.c" break; case 15: /* cmd ::= SHOW VNODES */ #line 82 "sql.y" { setShowOptions(pInfo, TSDB_MGMT_TABLE_VNODES, 0, 0); } -#line 2630 "sql.c" +#line 2636 "sql.c" break; case 16: /* cmd ::= SHOW VNODES ids */ #line 83 "sql.y" { setShowOptions(pInfo, TSDB_MGMT_TABLE_VNODES, &yymsp[0].minor.yy0, 0); } -#line 2635 "sql.c" +#line 2641 "sql.c" break; case 17: /* dbPrefix ::= */ #line 87 "sql.y" {yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.type = 0;} -#line 2640 "sql.c" +#line 2646 "sql.c" break; case 18: /* dbPrefix ::= ids DOT */ #line 88 "sql.y" {yylhsminor.yy0 = yymsp[-1].minor.yy0; } -#line 2645 "sql.c" +#line 2651 "sql.c" yymsp[-1].minor.yy0 = yylhsminor.yy0; break; case 19: /* cpxName ::= */ #line 91 "sql.y" {yymsp[1].minor.yy0.n = 0; } -#line 2651 "sql.c" +#line 2657 "sql.c" break; case 20: /* cpxName ::= DOT ids */ #line 92 "sql.y" {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n += 1; } -#line 2656 "sql.c" +#line 2662 "sql.c" break; case 21: /* cmd ::= SHOW CREATE TABLE ids cpxName */ #line 94 "sql.y" @@ -2660,7 +2666,7 @@ static YYACTIONTYPE yy_reduce( yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; setDCLSqlElems(pInfo, TSDB_SQL_SHOW_CREATE_TABLE, 1, &yymsp[-1].minor.yy0); } -#line 2664 "sql.c" +#line 2670 "sql.c" break; case 22: /* cmd ::= SHOW CREATE STABLE ids cpxName */ #line 98 "sql.y" @@ -2668,35 +2674,35 @@ static YYACTIONTYPE yy_reduce( yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; setDCLSqlElems(pInfo, TSDB_SQL_SHOW_CREATE_STABLE, 1, &yymsp[-1].minor.yy0); } -#line 2672 "sql.c" +#line 2678 "sql.c" break; case 23: /* cmd ::= SHOW CREATE DATABASE ids */ #line 103 "sql.y" { setDCLSqlElems(pInfo, TSDB_SQL_SHOW_CREATE_DATABASE, 1, &yymsp[0].minor.yy0); } -#line 2679 "sql.c" +#line 2685 "sql.c" break; case 24: /* cmd ::= SHOW dbPrefix TABLES */ #line 107 "sql.y" { setShowOptions(pInfo, TSDB_MGMT_TABLE_TABLE, &yymsp[-1].minor.yy0, 0); } -#line 2686 "sql.c" +#line 2692 "sql.c" break; case 25: /* cmd ::= SHOW dbPrefix TABLES LIKE ids */ #line 111 "sql.y" { setShowOptions(pInfo, TSDB_MGMT_TABLE_TABLE, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0); } -#line 2693 "sql.c" +#line 2699 "sql.c" break; case 26: /* cmd ::= SHOW dbPrefix STABLES */ #line 115 "sql.y" { setShowOptions(pInfo, TSDB_MGMT_TABLE_METRIC, &yymsp[-1].minor.yy0, 0); } -#line 2700 "sql.c" +#line 2706 "sql.c" break; case 27: /* cmd ::= SHOW dbPrefix STABLES LIKE ids */ #line 119 "sql.y" @@ -2705,7 +2711,7 @@ static YYACTIONTYPE yy_reduce( tSetDbName(&token, &yymsp[-3].minor.yy0); setShowOptions(pInfo, TSDB_MGMT_TABLE_METRIC, &token, &yymsp[0].minor.yy0); } -#line 2709 "sql.c" +#line 2715 "sql.c" break; case 28: /* cmd ::= SHOW dbPrefix VGROUPS */ #line 125 "sql.y" @@ -2714,7 +2720,7 @@ static YYACTIONTYPE yy_reduce( tSetDbName(&token, &yymsp[-1].minor.yy0); setShowOptions(pInfo, TSDB_MGMT_TABLE_VGROUP, &token, 0); } -#line 2718 "sql.c" +#line 2724 "sql.c" break; case 29: /* cmd ::= SHOW dbPrefix VGROUPS ids */ #line 131 "sql.y" @@ -2723,7 +2729,7 @@ static YYACTIONTYPE yy_reduce( tSetDbName(&token, &yymsp[-2].minor.yy0); setShowOptions(pInfo, TSDB_MGMT_TABLE_VGROUP, &token, &yymsp[0].minor.yy0); } -#line 2727 "sql.c" +#line 2733 "sql.c" break; case 30: /* cmd ::= DROP TABLE ifexists ids cpxName */ #line 138 "sql.y" @@ -2731,7 +2737,7 @@ static YYACTIONTYPE yy_reduce( yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; setDropDbTableInfo(pInfo, TSDB_SQL_DROP_TABLE, &yymsp[-1].minor.yy0, &yymsp[-2].minor.yy0, -1, -1); } -#line 2735 "sql.c" +#line 2741 "sql.c" break; case 31: /* cmd ::= DROP STABLE ifexists ids cpxName */ #line 144 "sql.y" @@ -2739,42 +2745,42 @@ static YYACTIONTYPE yy_reduce( yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; setDropDbTableInfo(pInfo, TSDB_SQL_DROP_TABLE, &yymsp[-1].minor.yy0, &yymsp[-2].minor.yy0, -1, TSDB_SUPER_TABLE); } -#line 2743 "sql.c" +#line 2749 "sql.c" break; case 32: /* cmd ::= DROP DATABASE ifexists ids */ #line 149 "sql.y" { setDropDbTableInfo(pInfo, TSDB_SQL_DROP_DB, &yymsp[0].minor.yy0, &yymsp[-1].minor.yy0, TSDB_DB_TYPE_DEFAULT, -1); } -#line 2748 "sql.c" +#line 2754 "sql.c" break; case 33: /* cmd ::= DROP TOPIC ifexists ids */ #line 150 "sql.y" { setDropDbTableInfo(pInfo, TSDB_SQL_DROP_DB, &yymsp[0].minor.yy0, &yymsp[-1].minor.yy0, TSDB_DB_TYPE_TOPIC, -1); } -#line 2753 "sql.c" +#line 2759 "sql.c" break; case 34: /* cmd ::= DROP FUNCTION ids */ #line 151 "sql.y" { setDropFuncInfo(pInfo, TSDB_SQL_DROP_FUNCTION, &yymsp[0].minor.yy0); } -#line 2758 "sql.c" +#line 2764 "sql.c" break; case 35: /* cmd ::= DROP DNODE ids */ #line 153 "sql.y" { setDCLSqlElems(pInfo, TSDB_SQL_DROP_DNODE, 1, &yymsp[0].minor.yy0); } -#line 2763 "sql.c" +#line 2769 "sql.c" break; case 36: /* cmd ::= DROP USER ids */ #line 154 "sql.y" { setDCLSqlElems(pInfo, TSDB_SQL_DROP_USER, 1, &yymsp[0].minor.yy0); } -#line 2768 "sql.c" +#line 2774 "sql.c" break; case 37: /* cmd ::= DROP ACCOUNT ids */ #line 155 "sql.y" { setDCLSqlElems(pInfo, TSDB_SQL_DROP_ACCT, 1, &yymsp[0].minor.yy0); } -#line 2773 "sql.c" +#line 2779 "sql.c" break; case 38: /* cmd ::= USE ids */ #line 158 "sql.y" { setDCLSqlElems(pInfo, TSDB_SQL_USE_DB, 1, &yymsp[0].minor.yy0);} -#line 2778 "sql.c" +#line 2784 "sql.c" break; case 39: /* cmd ::= DESCRIBE ids cpxName */ case 40: /* cmd ::= DESC ids cpxName */ yytestcase(yyruleno==40); @@ -2783,113 +2789,113 @@ static YYACTIONTYPE yy_reduce( yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; setDCLSqlElems(pInfo, TSDB_SQL_DESCRIBE_TABLE, 1, &yymsp[-1].minor.yy0); } -#line 2787 "sql.c" +#line 2793 "sql.c" break; case 41: /* cmd ::= ALTER USER ids PASS ids */ #line 170 "sql.y" { setAlterUserSql(pInfo, TSDB_ALTER_USER_PASSWD, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, NULL); } -#line 2792 "sql.c" +#line 2798 "sql.c" break; case 42: /* cmd ::= ALTER USER ids PRIVILEGE ids */ #line 171 "sql.y" { setAlterUserSql(pInfo, TSDB_ALTER_USER_PRIVILEGES, &yymsp[-2].minor.yy0, NULL, &yymsp[0].minor.yy0);} -#line 2797 "sql.c" +#line 2803 "sql.c" break; case 43: /* cmd ::= ALTER DNODE ids ids */ #line 172 "sql.y" { setDCLSqlElems(pInfo, TSDB_SQL_CFG_DNODE, 2, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0); } -#line 2802 "sql.c" +#line 2808 "sql.c" break; case 44: /* cmd ::= ALTER DNODE ids ids ids */ #line 173 "sql.y" { setDCLSqlElems(pInfo, TSDB_SQL_CFG_DNODE, 3, &yymsp[-2].minor.yy0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0); } -#line 2807 "sql.c" +#line 2813 "sql.c" break; case 45: /* cmd ::= ALTER LOCAL ids */ #line 174 "sql.y" { setDCLSqlElems(pInfo, TSDB_SQL_CFG_LOCAL, 1, &yymsp[0].minor.yy0); } -#line 2812 "sql.c" +#line 2818 "sql.c" break; case 46: /* cmd ::= ALTER LOCAL ids ids */ #line 175 "sql.y" { setDCLSqlElems(pInfo, TSDB_SQL_CFG_LOCAL, 2, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0); } -#line 2817 "sql.c" +#line 2823 "sql.c" break; case 47: /* cmd ::= ALTER DATABASE ids alter_db_optr */ case 48: /* cmd ::= ALTER TOPIC ids alter_topic_optr */ yytestcase(yyruleno==48); #line 176 "sql.y" -{ SStrToken t = {0}; setCreateDbInfo(pInfo, TSDB_SQL_ALTER_DB, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy246, &t);} -#line 2823 "sql.c" +{ SStrToken t = {0}; setCreateDbInfo(pInfo, TSDB_SQL_ALTER_DB, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy90, &t);} +#line 2829 "sql.c" break; case 49: /* cmd ::= ALTER ACCOUNT ids acct_optr */ #line 179 "sql.y" -{ setCreateAcctSql(pInfo, TSDB_SQL_ALTER_ACCT, &yymsp[-1].minor.yy0, NULL, &yymsp[0].minor.yy377);} -#line 2828 "sql.c" +{ setCreateAcctSql(pInfo, TSDB_SQL_ALTER_ACCT, &yymsp[-1].minor.yy0, NULL, &yymsp[0].minor.yy171);} +#line 2834 "sql.c" break; case 50: /* cmd ::= ALTER ACCOUNT ids PASS ids acct_optr */ #line 180 "sql.y" -{ setCreateAcctSql(pInfo, TSDB_SQL_ALTER_ACCT, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy377);} -#line 2833 "sql.c" +{ setCreateAcctSql(pInfo, TSDB_SQL_ALTER_ACCT, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy171);} +#line 2839 "sql.c" break; case 51: /* cmd ::= COMPACT VNODES IN LP exprlist RP */ #line 184 "sql.y" -{ setCompactVnodeSql(pInfo, TSDB_SQL_COMPACT_VNODE, yymsp[-1].minor.yy403);} -#line 2838 "sql.c" +{ setCompactVnodeSql(pInfo, TSDB_SQL_COMPACT_VNODE, yymsp[-1].minor.yy421);} +#line 2844 "sql.c" break; case 52: /* ids ::= ID */ case 53: /* ids ::= STRING */ yytestcase(yyruleno==53); #line 190 "sql.y" {yylhsminor.yy0 = yymsp[0].minor.yy0; } -#line 2844 "sql.c" +#line 2850 "sql.c" yymsp[0].minor.yy0 = yylhsminor.yy0; break; case 54: /* ifexists ::= IF EXISTS */ #line 194 "sql.y" { yymsp[-1].minor.yy0.n = 1;} -#line 2850 "sql.c" +#line 2856 "sql.c" break; case 55: /* ifexists ::= */ case 57: /* ifnotexists ::= */ yytestcase(yyruleno==57); case 181: /* distinct ::= */ yytestcase(yyruleno==181); #line 195 "sql.y" { yymsp[1].minor.yy0.n = 0;} -#line 2857 "sql.c" +#line 2863 "sql.c" break; case 56: /* ifnotexists ::= IF NOT EXISTS */ #line 198 "sql.y" { yymsp[-2].minor.yy0.n = 1;} -#line 2862 "sql.c" +#line 2868 "sql.c" break; case 58: /* cmd ::= CREATE DNODE ids */ #line 203 "sql.y" { setDCLSqlElems(pInfo, TSDB_SQL_CREATE_DNODE, 1, &yymsp[0].minor.yy0);} -#line 2867 "sql.c" +#line 2873 "sql.c" break; case 59: /* cmd ::= CREATE ACCOUNT ids PASS ids acct_optr */ #line 205 "sql.y" -{ setCreateAcctSql(pInfo, TSDB_SQL_CREATE_ACCT, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy377);} -#line 2872 "sql.c" +{ setCreateAcctSql(pInfo, TSDB_SQL_CREATE_ACCT, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy171);} +#line 2878 "sql.c" break; case 60: /* cmd ::= CREATE DATABASE ifnotexists ids db_optr */ case 61: /* cmd ::= CREATE TOPIC ifnotexists ids topic_optr */ yytestcase(yyruleno==61); #line 206 "sql.y" -{ setCreateDbInfo(pInfo, TSDB_SQL_CREATE_DB, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy246, &yymsp[-2].minor.yy0);} -#line 2878 "sql.c" +{ setCreateDbInfo(pInfo, TSDB_SQL_CREATE_DB, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy90, &yymsp[-2].minor.yy0);} +#line 2884 "sql.c" break; case 62: /* cmd ::= CREATE FUNCTION ids AS ids OUTPUTTYPE typename bufsize */ #line 208 "sql.y" -{ setCreateFuncInfo(pInfo, TSDB_SQL_CREATE_FUNCTION, &yymsp[-5].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy363, &yymsp[0].minor.yy0, 1);} -#line 2883 "sql.c" +{ setCreateFuncInfo(pInfo, TSDB_SQL_CREATE_FUNCTION, &yymsp[-5].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy183, &yymsp[0].minor.yy0, 1);} +#line 2889 "sql.c" break; case 63: /* cmd ::= CREATE AGGREGATE FUNCTION ids AS ids OUTPUTTYPE typename bufsize */ #line 209 "sql.y" -{ setCreateFuncInfo(pInfo, TSDB_SQL_CREATE_FUNCTION, &yymsp[-5].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy363, &yymsp[0].minor.yy0, 2);} -#line 2888 "sql.c" +{ setCreateFuncInfo(pInfo, TSDB_SQL_CREATE_FUNCTION, &yymsp[-5].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy183, &yymsp[0].minor.yy0, 2);} +#line 2894 "sql.c" break; case 64: /* cmd ::= CREATE USER ids PASS ids */ #line 210 "sql.y" { setCreateUserSql(pInfo, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);} -#line 2893 "sql.c" +#line 2899 "sql.c" break; case 65: /* bufsize ::= */ case 67: /* pps ::= */ yytestcase(yyruleno==67); @@ -2903,7 +2909,7 @@ static YYACTIONTYPE yy_reduce( case 83: /* state ::= */ yytestcase(yyruleno==83); #line 212 "sql.y" { yymsp[1].minor.yy0.n = 0; } -#line 2907 "sql.c" +#line 2913 "sql.c" break; case 66: /* bufsize ::= BUFSIZE INTEGER */ case 68: /* pps ::= PPS INTEGER */ yytestcase(yyruleno==68); @@ -2917,37 +2923,37 @@ static YYACTIONTYPE yy_reduce( case 84: /* state ::= STATE ids */ yytestcase(yyruleno==84); #line 213 "sql.y" { yymsp[-1].minor.yy0 = yymsp[0].minor.yy0; } -#line 2921 "sql.c" +#line 2927 "sql.c" break; case 85: /* acct_optr ::= pps tseries storage streams qtime dbs users conns state */ #line 243 "sql.y" { - yylhsminor.yy377.maxUsers = (yymsp[-2].minor.yy0.n>0)?atoi(yymsp[-2].minor.yy0.z):-1; - yylhsminor.yy377.maxDbs = (yymsp[-3].minor.yy0.n>0)?atoi(yymsp[-3].minor.yy0.z):-1; - yylhsminor.yy377.maxTimeSeries = (yymsp[-7].minor.yy0.n>0)?atoi(yymsp[-7].minor.yy0.z):-1; - yylhsminor.yy377.maxStreams = (yymsp[-5].minor.yy0.n>0)?atoi(yymsp[-5].minor.yy0.z):-1; - yylhsminor.yy377.maxPointsPerSecond = (yymsp[-8].minor.yy0.n>0)?atoi(yymsp[-8].minor.yy0.z):-1; - yylhsminor.yy377.maxStorage = (yymsp[-6].minor.yy0.n>0)?strtoll(yymsp[-6].minor.yy0.z, NULL, 10):-1; - yylhsminor.yy377.maxQueryTime = (yymsp[-4].minor.yy0.n>0)?strtoll(yymsp[-4].minor.yy0.z, NULL, 10):-1; - yylhsminor.yy377.maxConnections = (yymsp[-1].minor.yy0.n>0)?atoi(yymsp[-1].minor.yy0.z):-1; - yylhsminor.yy377.stat = yymsp[0].minor.yy0; + yylhsminor.yy171.maxUsers = (yymsp[-2].minor.yy0.n>0)?atoi(yymsp[-2].minor.yy0.z):-1; + yylhsminor.yy171.maxDbs = (yymsp[-3].minor.yy0.n>0)?atoi(yymsp[-3].minor.yy0.z):-1; + yylhsminor.yy171.maxTimeSeries = (yymsp[-7].minor.yy0.n>0)?atoi(yymsp[-7].minor.yy0.z):-1; + yylhsminor.yy171.maxStreams = (yymsp[-5].minor.yy0.n>0)?atoi(yymsp[-5].minor.yy0.z):-1; + yylhsminor.yy171.maxPointsPerSecond = (yymsp[-8].minor.yy0.n>0)?atoi(yymsp[-8].minor.yy0.z):-1; + yylhsminor.yy171.maxStorage = (yymsp[-6].minor.yy0.n>0)?strtoll(yymsp[-6].minor.yy0.z, NULL, 10):-1; + yylhsminor.yy171.maxQueryTime = (yymsp[-4].minor.yy0.n>0)?strtoll(yymsp[-4].minor.yy0.z, NULL, 10):-1; + yylhsminor.yy171.maxConnections = (yymsp[-1].minor.yy0.n>0)?atoi(yymsp[-1].minor.yy0.z):-1; + yylhsminor.yy171.stat = yymsp[0].minor.yy0; } -#line 2936 "sql.c" - yymsp[-8].minor.yy377 = yylhsminor.yy377; +#line 2942 "sql.c" + yymsp[-8].minor.yy171 = yylhsminor.yy171; break; case 86: /* intitemlist ::= intitemlist COMMA intitem */ case 155: /* tagitemlist ::= tagitemlist COMMA tagitem */ yytestcase(yyruleno==155); #line 259 "sql.y" -{ yylhsminor.yy403 = tVariantListAppend(yymsp[-2].minor.yy403, &yymsp[0].minor.yy488, -1); } -#line 2943 "sql.c" - yymsp[-2].minor.yy403 = yylhsminor.yy403; +{ yylhsminor.yy421 = tVariantListAppend(yymsp[-2].minor.yy421, &yymsp[0].minor.yy430, -1); } +#line 2949 "sql.c" + yymsp[-2].minor.yy421 = yylhsminor.yy421; break; case 87: /* intitemlist ::= intitem */ case 156: /* tagitemlist ::= tagitem */ yytestcase(yyruleno==156); #line 260 "sql.y" -{ yylhsminor.yy403 = tVariantListAppend(NULL, &yymsp[0].minor.yy488, -1); } -#line 2950 "sql.c" - yymsp[0].minor.yy403 = yylhsminor.yy403; +{ yylhsminor.yy421 = tVariantListAppend(NULL, &yymsp[0].minor.yy430, -1); } +#line 2956 "sql.c" + yymsp[0].minor.yy421 = yylhsminor.yy421; break; case 88: /* intitem ::= INTEGER */ case 157: /* tagitem ::= INTEGER */ yytestcase(yyruleno==157); @@ -2955,14 +2961,14 @@ static YYACTIONTYPE yy_reduce( case 159: /* tagitem ::= STRING */ yytestcase(yyruleno==159); case 160: /* tagitem ::= BOOL */ yytestcase(yyruleno==160); #line 262 "sql.y" -{ toTSDBType(yymsp[0].minor.yy0.type); tVariantCreate(&yylhsminor.yy488, &yymsp[0].minor.yy0); } -#line 2960 "sql.c" - yymsp[0].minor.yy488 = yylhsminor.yy488; +{ toTSDBType(yymsp[0].minor.yy0.type); tVariantCreate(&yylhsminor.yy430, &yymsp[0].minor.yy0); } +#line 2966 "sql.c" + yymsp[0].minor.yy430 = yylhsminor.yy430; break; case 89: /* keep ::= KEEP intitemlist */ #line 266 "sql.y" -{ yymsp[-1].minor.yy403 = yymsp[0].minor.yy403; } -#line 2966 "sql.c" +{ yymsp[-1].minor.yy421 = yymsp[0].minor.yy421; } +#line 2972 "sql.c" break; case 90: /* cache ::= CACHE INTEGER */ case 91: /* replica ::= REPLICA INTEGER */ yytestcase(yyruleno==91); @@ -2981,182 +2987,182 @@ static YYACTIONTYPE yy_reduce( case 104: /* partitions ::= PARTITIONS INTEGER */ yytestcase(yyruleno==104); #line 268 "sql.y" { yymsp[-1].minor.yy0 = yymsp[0].minor.yy0; } -#line 2985 "sql.c" +#line 2991 "sql.c" break; case 105: /* db_optr ::= */ #line 285 "sql.y" -{setDefaultCreateDbOption(&yymsp[1].minor.yy246); yymsp[1].minor.yy246.dbType = TSDB_DB_TYPE_DEFAULT;} -#line 2990 "sql.c" +{setDefaultCreateDbOption(&yymsp[1].minor.yy90); yymsp[1].minor.yy90.dbType = TSDB_DB_TYPE_DEFAULT;} +#line 2996 "sql.c" break; case 106: /* db_optr ::= db_optr cache */ #line 287 "sql.y" -{ yylhsminor.yy246 = yymsp[-1].minor.yy246; yylhsminor.yy246.cacheBlockSize = strtol(yymsp[0].minor.yy0.z, NULL, 10); } -#line 2995 "sql.c" - yymsp[-1].minor.yy246 = yylhsminor.yy246; +{ yylhsminor.yy90 = yymsp[-1].minor.yy90; yylhsminor.yy90.cacheBlockSize = strtol(yymsp[0].minor.yy0.z, NULL, 10); } +#line 3001 "sql.c" + yymsp[-1].minor.yy90 = yylhsminor.yy90; break; case 107: /* db_optr ::= db_optr replica */ case 124: /* alter_db_optr ::= alter_db_optr replica */ yytestcase(yyruleno==124); #line 288 "sql.y" -{ yylhsminor.yy246 = yymsp[-1].minor.yy246; yylhsminor.yy246.replica = strtol(yymsp[0].minor.yy0.z, NULL, 10); } -#line 3002 "sql.c" - yymsp[-1].minor.yy246 = yylhsminor.yy246; +{ yylhsminor.yy90 = yymsp[-1].minor.yy90; yylhsminor.yy90.replica = strtol(yymsp[0].minor.yy0.z, NULL, 10); } +#line 3008 "sql.c" + yymsp[-1].minor.yy90 = yylhsminor.yy90; break; case 108: /* db_optr ::= db_optr quorum */ case 125: /* alter_db_optr ::= alter_db_optr quorum */ yytestcase(yyruleno==125); #line 289 "sql.y" -{ yylhsminor.yy246 = yymsp[-1].minor.yy246; yylhsminor.yy246.quorum = strtol(yymsp[0].minor.yy0.z, NULL, 10); } -#line 3009 "sql.c" - yymsp[-1].minor.yy246 = yylhsminor.yy246; +{ yylhsminor.yy90 = yymsp[-1].minor.yy90; yylhsminor.yy90.quorum = strtol(yymsp[0].minor.yy0.z, NULL, 10); } +#line 3015 "sql.c" + yymsp[-1].minor.yy90 = yylhsminor.yy90; break; case 109: /* db_optr ::= db_optr days */ #line 290 "sql.y" -{ yylhsminor.yy246 = yymsp[-1].minor.yy246; yylhsminor.yy246.daysPerFile = strtol(yymsp[0].minor.yy0.z, NULL, 10); } -#line 3015 "sql.c" - yymsp[-1].minor.yy246 = yylhsminor.yy246; +{ yylhsminor.yy90 = yymsp[-1].minor.yy90; yylhsminor.yy90.daysPerFile = strtol(yymsp[0].minor.yy0.z, NULL, 10); } +#line 3021 "sql.c" + yymsp[-1].minor.yy90 = yylhsminor.yy90; break; case 110: /* db_optr ::= db_optr minrows */ #line 291 "sql.y" -{ yylhsminor.yy246 = yymsp[-1].minor.yy246; yylhsminor.yy246.minRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } -#line 3021 "sql.c" - yymsp[-1].minor.yy246 = yylhsminor.yy246; +{ yylhsminor.yy90 = yymsp[-1].minor.yy90; yylhsminor.yy90.minRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } +#line 3027 "sql.c" + yymsp[-1].minor.yy90 = yylhsminor.yy90; break; case 111: /* db_optr ::= db_optr maxrows */ #line 292 "sql.y" -{ yylhsminor.yy246 = yymsp[-1].minor.yy246; yylhsminor.yy246.maxRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } -#line 3027 "sql.c" - yymsp[-1].minor.yy246 = yylhsminor.yy246; +{ yylhsminor.yy90 = yymsp[-1].minor.yy90; yylhsminor.yy90.maxRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } +#line 3033 "sql.c" + yymsp[-1].minor.yy90 = yylhsminor.yy90; break; case 112: /* db_optr ::= db_optr blocks */ case 127: /* alter_db_optr ::= alter_db_optr blocks */ yytestcase(yyruleno==127); #line 293 "sql.y" -{ yylhsminor.yy246 = yymsp[-1].minor.yy246; yylhsminor.yy246.numOfBlocks = strtol(yymsp[0].minor.yy0.z, NULL, 10); } -#line 3034 "sql.c" - yymsp[-1].minor.yy246 = yylhsminor.yy246; +{ yylhsminor.yy90 = yymsp[-1].minor.yy90; yylhsminor.yy90.numOfBlocks = strtol(yymsp[0].minor.yy0.z, NULL, 10); } +#line 3040 "sql.c" + yymsp[-1].minor.yy90 = yylhsminor.yy90; break; case 113: /* db_optr ::= db_optr ctime */ #line 294 "sql.y" -{ yylhsminor.yy246 = yymsp[-1].minor.yy246; yylhsminor.yy246.commitTime = strtol(yymsp[0].minor.yy0.z, NULL, 10); } -#line 3040 "sql.c" - yymsp[-1].minor.yy246 = yylhsminor.yy246; +{ yylhsminor.yy90 = yymsp[-1].minor.yy90; yylhsminor.yy90.commitTime = strtol(yymsp[0].minor.yy0.z, NULL, 10); } +#line 3046 "sql.c" + yymsp[-1].minor.yy90 = yylhsminor.yy90; break; case 114: /* db_optr ::= db_optr wal */ #line 295 "sql.y" -{ yylhsminor.yy246 = yymsp[-1].minor.yy246; yylhsminor.yy246.walLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } -#line 3046 "sql.c" - yymsp[-1].minor.yy246 = yylhsminor.yy246; +{ yylhsminor.yy90 = yymsp[-1].minor.yy90; yylhsminor.yy90.walLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } +#line 3052 "sql.c" + yymsp[-1].minor.yy90 = yylhsminor.yy90; break; case 115: /* db_optr ::= db_optr fsync */ #line 296 "sql.y" -{ yylhsminor.yy246 = yymsp[-1].minor.yy246; yylhsminor.yy246.fsyncPeriod = strtol(yymsp[0].minor.yy0.z, NULL, 10); } -#line 3052 "sql.c" - yymsp[-1].minor.yy246 = yylhsminor.yy246; +{ yylhsminor.yy90 = yymsp[-1].minor.yy90; yylhsminor.yy90.fsyncPeriod = strtol(yymsp[0].minor.yy0.z, NULL, 10); } +#line 3058 "sql.c" + yymsp[-1].minor.yy90 = yylhsminor.yy90; break; case 116: /* db_optr ::= db_optr comp */ case 128: /* alter_db_optr ::= alter_db_optr comp */ yytestcase(yyruleno==128); #line 297 "sql.y" -{ yylhsminor.yy246 = yymsp[-1].minor.yy246; yylhsminor.yy246.compressionLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } -#line 3059 "sql.c" - yymsp[-1].minor.yy246 = yylhsminor.yy246; +{ yylhsminor.yy90 = yymsp[-1].minor.yy90; yylhsminor.yy90.compressionLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } +#line 3065 "sql.c" + yymsp[-1].minor.yy90 = yylhsminor.yy90; break; case 117: /* db_optr ::= db_optr prec */ #line 298 "sql.y" -{ yylhsminor.yy246 = yymsp[-1].minor.yy246; yylhsminor.yy246.precision = yymsp[0].minor.yy0; } -#line 3065 "sql.c" - yymsp[-1].minor.yy246 = yylhsminor.yy246; +{ yylhsminor.yy90 = yymsp[-1].minor.yy90; yylhsminor.yy90.precision = yymsp[0].minor.yy0; } +#line 3071 "sql.c" + yymsp[-1].minor.yy90 = yylhsminor.yy90; break; case 118: /* db_optr ::= db_optr keep */ case 126: /* alter_db_optr ::= alter_db_optr keep */ yytestcase(yyruleno==126); #line 299 "sql.y" -{ yylhsminor.yy246 = yymsp[-1].minor.yy246; yylhsminor.yy246.keep = yymsp[0].minor.yy403; } -#line 3072 "sql.c" - yymsp[-1].minor.yy246 = yylhsminor.yy246; +{ yylhsminor.yy90 = yymsp[-1].minor.yy90; yylhsminor.yy90.keep = yymsp[0].minor.yy421; } +#line 3078 "sql.c" + yymsp[-1].minor.yy90 = yylhsminor.yy90; break; case 119: /* db_optr ::= db_optr update */ case 129: /* alter_db_optr ::= alter_db_optr update */ yytestcase(yyruleno==129); #line 300 "sql.y" -{ yylhsminor.yy246 = yymsp[-1].minor.yy246; yylhsminor.yy246.update = strtol(yymsp[0].minor.yy0.z, NULL, 10); } -#line 3079 "sql.c" - yymsp[-1].minor.yy246 = yylhsminor.yy246; +{ yylhsminor.yy90 = yymsp[-1].minor.yy90; yylhsminor.yy90.update = strtol(yymsp[0].minor.yy0.z, NULL, 10); } +#line 3085 "sql.c" + yymsp[-1].minor.yy90 = yylhsminor.yy90; break; case 120: /* db_optr ::= db_optr cachelast */ case 130: /* alter_db_optr ::= alter_db_optr cachelast */ yytestcase(yyruleno==130); #line 301 "sql.y" -{ yylhsminor.yy246 = yymsp[-1].minor.yy246; yylhsminor.yy246.cachelast = strtol(yymsp[0].minor.yy0.z, NULL, 10); } -#line 3086 "sql.c" - yymsp[-1].minor.yy246 = yylhsminor.yy246; +{ yylhsminor.yy90 = yymsp[-1].minor.yy90; yylhsminor.yy90.cachelast = strtol(yymsp[0].minor.yy0.z, NULL, 10); } +#line 3092 "sql.c" + yymsp[-1].minor.yy90 = yylhsminor.yy90; break; case 121: /* topic_optr ::= db_optr */ case 131: /* alter_topic_optr ::= alter_db_optr */ yytestcase(yyruleno==131); #line 305 "sql.y" -{ yylhsminor.yy246 = yymsp[0].minor.yy246; yylhsminor.yy246.dbType = TSDB_DB_TYPE_TOPIC; } -#line 3093 "sql.c" - yymsp[0].minor.yy246 = yylhsminor.yy246; +{ yylhsminor.yy90 = yymsp[0].minor.yy90; yylhsminor.yy90.dbType = TSDB_DB_TYPE_TOPIC; } +#line 3099 "sql.c" + yymsp[0].minor.yy90 = yylhsminor.yy90; break; case 122: /* topic_optr ::= topic_optr partitions */ case 132: /* alter_topic_optr ::= alter_topic_optr partitions */ yytestcase(yyruleno==132); #line 306 "sql.y" -{ yylhsminor.yy246 = yymsp[-1].minor.yy246; yylhsminor.yy246.partitions = strtol(yymsp[0].minor.yy0.z, NULL, 10); } -#line 3100 "sql.c" - yymsp[-1].minor.yy246 = yylhsminor.yy246; +{ yylhsminor.yy90 = yymsp[-1].minor.yy90; yylhsminor.yy90.partitions = strtol(yymsp[0].minor.yy0.z, NULL, 10); } +#line 3106 "sql.c" + yymsp[-1].minor.yy90 = yylhsminor.yy90; break; case 123: /* alter_db_optr ::= */ #line 309 "sql.y" -{ setDefaultCreateDbOption(&yymsp[1].minor.yy246); yymsp[1].minor.yy246.dbType = TSDB_DB_TYPE_DEFAULT;} -#line 3106 "sql.c" +{ setDefaultCreateDbOption(&yymsp[1].minor.yy90); yymsp[1].minor.yy90.dbType = TSDB_DB_TYPE_DEFAULT;} +#line 3112 "sql.c" break; case 133: /* typename ::= ids */ #line 329 "sql.y" { yymsp[0].minor.yy0.type = 0; - tSetColumnType (&yylhsminor.yy363, &yymsp[0].minor.yy0); + tSetColumnType (&yylhsminor.yy183, &yymsp[0].minor.yy0); } -#line 3114 "sql.c" - yymsp[0].minor.yy363 = yylhsminor.yy363; +#line 3120 "sql.c" + yymsp[0].minor.yy183 = yylhsminor.yy183; break; case 134: /* typename ::= ids LP signed RP */ #line 335 "sql.y" { - if (yymsp[-1].minor.yy387 <= 0) { + if (yymsp[-1].minor.yy325 <= 0) { yymsp[-3].minor.yy0.type = 0; - tSetColumnType(&yylhsminor.yy363, &yymsp[-3].minor.yy0); + tSetColumnType(&yylhsminor.yy183, &yymsp[-3].minor.yy0); } else { - yymsp[-3].minor.yy0.type = -yymsp[-1].minor.yy387; // negative value of name length - tSetColumnType(&yylhsminor.yy363, &yymsp[-3].minor.yy0); + yymsp[-3].minor.yy0.type = -yymsp[-1].minor.yy325; // negative value of name length + tSetColumnType(&yylhsminor.yy183, &yymsp[-3].minor.yy0); } } -#line 3128 "sql.c" - yymsp[-3].minor.yy363 = yylhsminor.yy363; +#line 3134 "sql.c" + yymsp[-3].minor.yy183 = yylhsminor.yy183; break; case 135: /* typename ::= ids UNSIGNED */ #line 346 "sql.y" { yymsp[-1].minor.yy0.type = 0; yymsp[-1].minor.yy0.n = ((yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z); - tSetColumnType (&yylhsminor.yy363, &yymsp[-1].minor.yy0); + tSetColumnType (&yylhsminor.yy183, &yymsp[-1].minor.yy0); } -#line 3138 "sql.c" - yymsp[-1].minor.yy363 = yylhsminor.yy363; +#line 3144 "sql.c" + yymsp[-1].minor.yy183 = yylhsminor.yy183; break; case 136: /* signed ::= INTEGER */ #line 353 "sql.y" -{ yylhsminor.yy387 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } -#line 3144 "sql.c" - yymsp[0].minor.yy387 = yylhsminor.yy387; +{ yylhsminor.yy325 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } +#line 3150 "sql.c" + yymsp[0].minor.yy325 = yylhsminor.yy325; break; case 137: /* signed ::= PLUS INTEGER */ #line 354 "sql.y" -{ yymsp[-1].minor.yy387 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } -#line 3150 "sql.c" +{ yymsp[-1].minor.yy325 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } +#line 3156 "sql.c" break; case 138: /* signed ::= MINUS INTEGER */ #line 355 "sql.y" -{ yymsp[-1].minor.yy387 = -strtol(yymsp[0].minor.yy0.z, NULL, 10);} -#line 3155 "sql.c" +{ yymsp[-1].minor.yy325 = -strtol(yymsp[0].minor.yy0.z, NULL, 10);} +#line 3161 "sql.c" break; case 142: /* cmd ::= CREATE TABLE create_table_list */ #line 361 "sql.y" -{ pInfo->type = TSDB_SQL_CREATE_TABLE; pInfo->pCreateTableInfo = yymsp[0].minor.yy56;} -#line 3160 "sql.c" +{ pInfo->type = TSDB_SQL_CREATE_TABLE; pInfo->pCreateTableInfo = yymsp[0].minor.yy438;} +#line 3166 "sql.c" break; case 143: /* create_table_list ::= create_from_stable */ #line 365 "sql.y" @@ -3164,121 +3170,121 @@ static YYACTIONTYPE yy_reduce( SCreateTableSql* pCreateTable = calloc(1, sizeof(SCreateTableSql)); pCreateTable->childTableInfo = taosArrayInit(4, sizeof(SCreatedTableInfo)); - taosArrayPush(pCreateTable->childTableInfo, &yymsp[0].minor.yy84); + taosArrayPush(pCreateTable->childTableInfo, &yymsp[0].minor.yy152); pCreateTable->type = TSQL_CREATE_TABLE_FROM_STABLE; - yylhsminor.yy56 = pCreateTable; + yylhsminor.yy438 = pCreateTable; } -#line 3172 "sql.c" - yymsp[0].minor.yy56 = yylhsminor.yy56; +#line 3178 "sql.c" + yymsp[0].minor.yy438 = yylhsminor.yy438; break; case 144: /* create_table_list ::= create_table_list create_from_stable */ #line 374 "sql.y" { - taosArrayPush(yymsp[-1].minor.yy56->childTableInfo, &yymsp[0].minor.yy84); - yylhsminor.yy56 = yymsp[-1].minor.yy56; + taosArrayPush(yymsp[-1].minor.yy438->childTableInfo, &yymsp[0].minor.yy152); + yylhsminor.yy438 = yymsp[-1].minor.yy438; } -#line 3181 "sql.c" - yymsp[-1].minor.yy56 = yylhsminor.yy56; +#line 3187 "sql.c" + yymsp[-1].minor.yy438 = yylhsminor.yy438; break; case 145: /* create_table_args ::= ifnotexists ids cpxName LP columnlist RP */ #line 380 "sql.y" { - yylhsminor.yy56 = tSetCreateTableInfo(yymsp[-1].minor.yy403, NULL, NULL, TSQL_CREATE_TABLE); - setSqlInfo(pInfo, yylhsminor.yy56, NULL, TSDB_SQL_CREATE_TABLE); + yylhsminor.yy438 = tSetCreateTableInfo(yymsp[-1].minor.yy421, NULL, NULL, TSQL_CREATE_TABLE); + setSqlInfo(pInfo, yylhsminor.yy438, NULL, TSDB_SQL_CREATE_TABLE); yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; setCreatedTableName(pInfo, &yymsp[-4].minor.yy0, &yymsp[-5].minor.yy0); } -#line 3193 "sql.c" - yymsp[-5].minor.yy56 = yylhsminor.yy56; +#line 3199 "sql.c" + yymsp[-5].minor.yy438 = yylhsminor.yy438; break; case 146: /* create_stable_args ::= ifnotexists ids cpxName LP columnlist RP TAGS LP columnlist RP */ #line 390 "sql.y" { - yylhsminor.yy56 = tSetCreateTableInfo(yymsp[-5].minor.yy403, yymsp[-1].minor.yy403, NULL, TSQL_CREATE_STABLE); - setSqlInfo(pInfo, yylhsminor.yy56, NULL, TSDB_SQL_CREATE_TABLE); + yylhsminor.yy438 = tSetCreateTableInfo(yymsp[-5].minor.yy421, yymsp[-1].minor.yy421, NULL, TSQL_CREATE_STABLE); + setSqlInfo(pInfo, yylhsminor.yy438, NULL, TSDB_SQL_CREATE_TABLE); yymsp[-8].minor.yy0.n += yymsp[-7].minor.yy0.n; setCreatedTableName(pInfo, &yymsp[-8].minor.yy0, &yymsp[-9].minor.yy0); } -#line 3205 "sql.c" - yymsp[-9].minor.yy56 = yylhsminor.yy56; +#line 3211 "sql.c" + yymsp[-9].minor.yy438 = yylhsminor.yy438; break; case 147: /* create_from_stable ::= ifnotexists ids cpxName USING ids cpxName TAGS LP tagitemlist RP */ #line 401 "sql.y" { yymsp[-5].minor.yy0.n += yymsp[-4].minor.yy0.n; yymsp[-8].minor.yy0.n += yymsp[-7].minor.yy0.n; - yylhsminor.yy84 = createNewChildTableInfo(&yymsp[-5].minor.yy0, NULL, yymsp[-1].minor.yy403, &yymsp[-8].minor.yy0, &yymsp[-9].minor.yy0); + yylhsminor.yy152 = createNewChildTableInfo(&yymsp[-5].minor.yy0, NULL, yymsp[-1].minor.yy421, &yymsp[-8].minor.yy0, &yymsp[-9].minor.yy0); } -#line 3215 "sql.c" - yymsp[-9].minor.yy84 = yylhsminor.yy84; +#line 3221 "sql.c" + yymsp[-9].minor.yy152 = yylhsminor.yy152; break; case 148: /* create_from_stable ::= ifnotexists ids cpxName USING ids cpxName LP tagNamelist RP TAGS LP tagitemlist RP */ #line 407 "sql.y" { yymsp[-8].minor.yy0.n += yymsp[-7].minor.yy0.n; yymsp[-11].minor.yy0.n += yymsp[-10].minor.yy0.n; - yylhsminor.yy84 = createNewChildTableInfo(&yymsp[-8].minor.yy0, yymsp[-5].minor.yy403, yymsp[-1].minor.yy403, &yymsp[-11].minor.yy0, &yymsp[-12].minor.yy0); + yylhsminor.yy152 = createNewChildTableInfo(&yymsp[-8].minor.yy0, yymsp[-5].minor.yy421, yymsp[-1].minor.yy421, &yymsp[-11].minor.yy0, &yymsp[-12].minor.yy0); } -#line 3225 "sql.c" - yymsp[-12].minor.yy84 = yylhsminor.yy84; +#line 3231 "sql.c" + yymsp[-12].minor.yy152 = yylhsminor.yy152; break; case 149: /* tagNamelist ::= tagNamelist COMMA ids */ #line 415 "sql.y" -{taosArrayPush(yymsp[-2].minor.yy403, &yymsp[0].minor.yy0); yylhsminor.yy403 = yymsp[-2].minor.yy403; } -#line 3231 "sql.c" - yymsp[-2].minor.yy403 = yylhsminor.yy403; +{taosArrayPush(yymsp[-2].minor.yy421, &yymsp[0].minor.yy0); yylhsminor.yy421 = yymsp[-2].minor.yy421; } +#line 3237 "sql.c" + yymsp[-2].minor.yy421 = yylhsminor.yy421; break; case 150: /* tagNamelist ::= ids */ #line 416 "sql.y" -{yylhsminor.yy403 = taosArrayInit(4, sizeof(SStrToken)); taosArrayPush(yylhsminor.yy403, &yymsp[0].minor.yy0);} -#line 3237 "sql.c" - yymsp[0].minor.yy403 = yylhsminor.yy403; +{yylhsminor.yy421 = taosArrayInit(4, sizeof(SStrToken)); taosArrayPush(yylhsminor.yy421, &yymsp[0].minor.yy0);} +#line 3243 "sql.c" + yymsp[0].minor.yy421 = yylhsminor.yy421; break; case 151: /* create_table_args ::= ifnotexists ids cpxName AS select */ #line 420 "sql.y" { - yylhsminor.yy56 = tSetCreateTableInfo(NULL, NULL, yymsp[0].minor.yy224, TSQL_CREATE_STREAM); - setSqlInfo(pInfo, yylhsminor.yy56, NULL, TSDB_SQL_CREATE_TABLE); + yylhsminor.yy438 = tSetCreateTableInfo(NULL, NULL, yymsp[0].minor.yy56, TSQL_CREATE_STREAM); + setSqlInfo(pInfo, yylhsminor.yy438, NULL, TSDB_SQL_CREATE_TABLE); yymsp[-3].minor.yy0.n += yymsp[-2].minor.yy0.n; setCreatedTableName(pInfo, &yymsp[-3].minor.yy0, &yymsp[-4].minor.yy0); } -#line 3249 "sql.c" - yymsp[-4].minor.yy56 = yylhsminor.yy56; +#line 3255 "sql.c" + yymsp[-4].minor.yy438 = yylhsminor.yy438; break; case 152: /* columnlist ::= columnlist COMMA column */ #line 431 "sql.y" -{taosArrayPush(yymsp[-2].minor.yy403, &yymsp[0].minor.yy363); yylhsminor.yy403 = yymsp[-2].minor.yy403; } -#line 3255 "sql.c" - yymsp[-2].minor.yy403 = yylhsminor.yy403; +{taosArrayPush(yymsp[-2].minor.yy421, &yymsp[0].minor.yy183); yylhsminor.yy421 = yymsp[-2].minor.yy421; } +#line 3261 "sql.c" + yymsp[-2].minor.yy421 = yylhsminor.yy421; break; case 153: /* columnlist ::= column */ #line 432 "sql.y" -{yylhsminor.yy403 = taosArrayInit(4, sizeof(TAOS_FIELD)); taosArrayPush(yylhsminor.yy403, &yymsp[0].minor.yy363);} -#line 3261 "sql.c" - yymsp[0].minor.yy403 = yylhsminor.yy403; +{yylhsminor.yy421 = taosArrayInit(4, sizeof(TAOS_FIELD)); taosArrayPush(yylhsminor.yy421, &yymsp[0].minor.yy183);} +#line 3267 "sql.c" + yymsp[0].minor.yy421 = yylhsminor.yy421; break; case 154: /* column ::= ids typename */ #line 436 "sql.y" { - tSetColumnInfo(&yylhsminor.yy363, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy363); + tSetColumnInfo(&yylhsminor.yy183, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy183); } -#line 3269 "sql.c" - yymsp[-1].minor.yy363 = yylhsminor.yy363; +#line 3275 "sql.c" + yymsp[-1].minor.yy183 = yylhsminor.yy183; break; case 161: /* tagitem ::= NULL */ #line 451 "sql.y" -{ yymsp[0].minor.yy0.type = 0; tVariantCreate(&yylhsminor.yy488, &yymsp[0].minor.yy0); } -#line 3275 "sql.c" - yymsp[0].minor.yy488 = yylhsminor.yy488; +{ yymsp[0].minor.yy0.type = 0; tVariantCreate(&yylhsminor.yy430, &yymsp[0].minor.yy0); } +#line 3281 "sql.c" + yymsp[0].minor.yy430 = yylhsminor.yy430; break; case 162: /* tagitem ::= NOW */ #line 452 "sql.y" -{ yymsp[0].minor.yy0.type = TSDB_DATA_TYPE_TIMESTAMP; tVariantCreate(&yylhsminor.yy488, &yymsp[0].minor.yy0);} -#line 3281 "sql.c" - yymsp[0].minor.yy488 = yylhsminor.yy488; +{ yymsp[0].minor.yy0.type = TSDB_DATA_TYPE_TIMESTAMP; tVariantCreate(&yylhsminor.yy430, &yymsp[0].minor.yy0);} +#line 3287 "sql.c" + yymsp[0].minor.yy430 = yylhsminor.yy430; break; case 163: /* tagitem ::= MINUS INTEGER */ case 164: /* tagitem ::= MINUS FLOAT */ yytestcase(yyruleno==164); @@ -3289,219 +3295,219 @@ static YYACTIONTYPE yy_reduce( yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = yymsp[0].minor.yy0.type; toTSDBType(yymsp[-1].minor.yy0.type); - tVariantCreate(&yylhsminor.yy488, &yymsp[-1].minor.yy0); + tVariantCreate(&yylhsminor.yy430, &yymsp[-1].minor.yy0); } -#line 3295 "sql.c" - yymsp[-1].minor.yy488 = yylhsminor.yy488; +#line 3301 "sql.c" + yymsp[-1].minor.yy430 = yylhsminor.yy430; break; case 167: /* select ::= SELECT selcollist from where_opt interval_option sliding_opt session_option windowstate_option fill_opt groupby_opt having_opt orderby_opt slimit_opt limit_opt */ #line 485 "sql.y" { - yylhsminor.yy224 = tSetQuerySqlNode(&yymsp[-13].minor.yy0, yymsp[-12].minor.yy403, yymsp[-11].minor.yy114, yymsp[-10].minor.yy260, yymsp[-4].minor.yy403, yymsp[-2].minor.yy403, &yymsp[-9].minor.yy222, &yymsp[-7].minor.yy365, &yymsp[-6].minor.yy544, &yymsp[-8].minor.yy0, yymsp[-5].minor.yy403, &yymsp[0].minor.yy404, &yymsp[-1].minor.yy404, yymsp[-3].minor.yy260); + yylhsminor.yy56 = tSetQuerySqlNode(&yymsp[-13].minor.yy0, yymsp[-12].minor.yy421, yymsp[-11].minor.yy8, yymsp[-10].minor.yy439, yymsp[-4].minor.yy421, yymsp[-2].minor.yy421, &yymsp[-9].minor.yy400, &yymsp[-7].minor.yy147, &yymsp[-6].minor.yy40, &yymsp[-8].minor.yy0, yymsp[-5].minor.yy421, &yymsp[0].minor.yy166, &yymsp[-1].minor.yy166, yymsp[-3].minor.yy439); } -#line 3303 "sql.c" - yymsp[-13].minor.yy224 = yylhsminor.yy224; +#line 3309 "sql.c" + yymsp[-13].minor.yy56 = yylhsminor.yy56; break; case 168: /* select ::= LP select RP */ #line 489 "sql.y" -{yymsp[-2].minor.yy224 = yymsp[-1].minor.yy224;} -#line 3309 "sql.c" +{yymsp[-2].minor.yy56 = yymsp[-1].minor.yy56;} +#line 3315 "sql.c" break; case 169: /* union ::= select */ #line 493 "sql.y" -{ yylhsminor.yy403 = setSubclause(NULL, yymsp[0].minor.yy224); } -#line 3314 "sql.c" - yymsp[0].minor.yy403 = yylhsminor.yy403; +{ yylhsminor.yy421 = setSubclause(NULL, yymsp[0].minor.yy56); } +#line 3320 "sql.c" + yymsp[0].minor.yy421 = yylhsminor.yy421; break; case 170: /* union ::= union UNION ALL select */ #line 494 "sql.y" -{ yylhsminor.yy403 = appendSelectClause(yymsp[-3].minor.yy403, yymsp[0].minor.yy224); } -#line 3320 "sql.c" - yymsp[-3].minor.yy403 = yylhsminor.yy403; +{ yylhsminor.yy421 = appendSelectClause(yymsp[-3].minor.yy421, yymsp[0].minor.yy56); } +#line 3326 "sql.c" + yymsp[-3].minor.yy421 = yylhsminor.yy421; break; case 171: /* cmd ::= union */ #line 496 "sql.y" -{ setSqlInfo(pInfo, yymsp[0].minor.yy403, NULL, TSDB_SQL_SELECT); } -#line 3326 "sql.c" +{ setSqlInfo(pInfo, yymsp[0].minor.yy421, NULL, TSDB_SQL_SELECT); } +#line 3332 "sql.c" break; case 172: /* select ::= SELECT selcollist */ #line 503 "sql.y" { - yylhsminor.yy224 = tSetQuerySqlNode(&yymsp[-1].minor.yy0, yymsp[0].minor.yy403, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + yylhsminor.yy56 = tSetQuerySqlNode(&yymsp[-1].minor.yy0, yymsp[0].minor.yy421, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); } -#line 3333 "sql.c" - yymsp[-1].minor.yy224 = yylhsminor.yy224; +#line 3339 "sql.c" + yymsp[-1].minor.yy56 = yylhsminor.yy56; break; case 173: /* sclp ::= selcollist COMMA */ #line 515 "sql.y" -{yylhsminor.yy403 = yymsp[-1].minor.yy403;} -#line 3339 "sql.c" - yymsp[-1].minor.yy403 = yylhsminor.yy403; +{yylhsminor.yy421 = yymsp[-1].minor.yy421;} +#line 3345 "sql.c" + yymsp[-1].minor.yy421 = yylhsminor.yy421; break; case 174: /* sclp ::= */ case 206: /* orderby_opt ::= */ yytestcase(yyruleno==206); #line 516 "sql.y" -{yymsp[1].minor.yy403 = 0;} -#line 3346 "sql.c" +{yymsp[1].minor.yy421 = 0;} +#line 3352 "sql.c" break; case 175: /* selcollist ::= sclp distinct expr as */ #line 517 "sql.y" { - yylhsminor.yy403 = tSqlExprListAppend(yymsp[-3].minor.yy403, yymsp[-1].minor.yy260, yymsp[-2].minor.yy0.n? &yymsp[-2].minor.yy0:0, yymsp[0].minor.yy0.n?&yymsp[0].minor.yy0:0); + yylhsminor.yy421 = tSqlExprListAppend(yymsp[-3].minor.yy421, yymsp[-1].minor.yy439, yymsp[-2].minor.yy0.n? &yymsp[-2].minor.yy0:0, yymsp[0].minor.yy0.n?&yymsp[0].minor.yy0:0); } -#line 3353 "sql.c" - yymsp[-3].minor.yy403 = yylhsminor.yy403; +#line 3359 "sql.c" + yymsp[-3].minor.yy421 = yylhsminor.yy421; break; case 176: /* selcollist ::= sclp STAR */ #line 521 "sql.y" { tSqlExpr *pNode = tSqlExprCreateIdValue(NULL, TK_ALL); - yylhsminor.yy403 = tSqlExprListAppend(yymsp[-1].minor.yy403, pNode, 0, 0); + yylhsminor.yy421 = tSqlExprListAppend(yymsp[-1].minor.yy421, pNode, 0, 0); } -#line 3362 "sql.c" - yymsp[-1].minor.yy403 = yylhsminor.yy403; +#line 3368 "sql.c" + yymsp[-1].minor.yy421 = yylhsminor.yy421; break; case 177: /* as ::= AS ids */ #line 529 "sql.y" { yymsp[-1].minor.yy0 = yymsp[0].minor.yy0; } -#line 3368 "sql.c" +#line 3374 "sql.c" break; case 178: /* as ::= ids */ #line 530 "sql.y" { yylhsminor.yy0 = yymsp[0].minor.yy0; } -#line 3373 "sql.c" +#line 3379 "sql.c" yymsp[0].minor.yy0 = yylhsminor.yy0; break; case 179: /* as ::= */ #line 531 "sql.y" { yymsp[1].minor.yy0.n = 0; } -#line 3379 "sql.c" +#line 3385 "sql.c" break; case 180: /* distinct ::= DISTINCT */ #line 534 "sql.y" { yylhsminor.yy0 = yymsp[0].minor.yy0; } -#line 3384 "sql.c" +#line 3390 "sql.c" yymsp[0].minor.yy0 = yylhsminor.yy0; break; case 182: /* from ::= FROM tablelist */ case 183: /* from ::= FROM sub */ yytestcase(yyruleno==183); #line 540 "sql.y" -{yymsp[-1].minor.yy114 = yymsp[0].minor.yy114;} -#line 3391 "sql.c" +{yymsp[-1].minor.yy8 = yymsp[0].minor.yy8;} +#line 3397 "sql.c" break; case 184: /* sub ::= LP union RP */ #line 545 "sql.y" -{yymsp[-2].minor.yy114 = addSubqueryElem(NULL, yymsp[-1].minor.yy403, NULL);} -#line 3396 "sql.c" +{yymsp[-2].minor.yy8 = addSubqueryElem(NULL, yymsp[-1].minor.yy421, NULL);} +#line 3402 "sql.c" break; case 185: /* sub ::= LP union RP ids */ #line 546 "sql.y" -{yymsp[-3].minor.yy114 = addSubqueryElem(NULL, yymsp[-2].minor.yy403, &yymsp[0].minor.yy0);} -#line 3401 "sql.c" +{yymsp[-3].minor.yy8 = addSubqueryElem(NULL, yymsp[-2].minor.yy421, &yymsp[0].minor.yy0);} +#line 3407 "sql.c" break; case 186: /* sub ::= sub COMMA LP union RP ids */ #line 547 "sql.y" -{yylhsminor.yy114 = addSubqueryElem(yymsp[-5].minor.yy114, yymsp[-2].minor.yy403, &yymsp[0].minor.yy0);} -#line 3406 "sql.c" - yymsp[-5].minor.yy114 = yylhsminor.yy114; +{yylhsminor.yy8 = addSubqueryElem(yymsp[-5].minor.yy8, yymsp[-2].minor.yy421, &yymsp[0].minor.yy0);} +#line 3412 "sql.c" + yymsp[-5].minor.yy8 = yylhsminor.yy8; break; case 187: /* tablelist ::= ids cpxName */ #line 551 "sql.y" { yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; - yylhsminor.yy114 = setTableNameList(NULL, &yymsp[-1].minor.yy0, NULL); + yylhsminor.yy8 = setTableNameList(NULL, &yymsp[-1].minor.yy0, NULL); } -#line 3415 "sql.c" - yymsp[-1].minor.yy114 = yylhsminor.yy114; +#line 3421 "sql.c" + yymsp[-1].minor.yy8 = yylhsminor.yy8; break; case 188: /* tablelist ::= ids cpxName ids */ #line 556 "sql.y" { yymsp[-2].minor.yy0.n += yymsp[-1].minor.yy0.n; - yylhsminor.yy114 = setTableNameList(NULL, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); + yylhsminor.yy8 = setTableNameList(NULL, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } -#line 3424 "sql.c" - yymsp[-2].minor.yy114 = yylhsminor.yy114; +#line 3430 "sql.c" + yymsp[-2].minor.yy8 = yylhsminor.yy8; break; case 189: /* tablelist ::= tablelist COMMA ids cpxName */ #line 561 "sql.y" { yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; - yylhsminor.yy114 = setTableNameList(yymsp[-3].minor.yy114, &yymsp[-1].minor.yy0, NULL); + yylhsminor.yy8 = setTableNameList(yymsp[-3].minor.yy8, &yymsp[-1].minor.yy0, NULL); } -#line 3433 "sql.c" - yymsp[-3].minor.yy114 = yylhsminor.yy114; +#line 3439 "sql.c" + yymsp[-3].minor.yy8 = yylhsminor.yy8; break; case 190: /* tablelist ::= tablelist COMMA ids cpxName ids */ #line 566 "sql.y" { yymsp[-2].minor.yy0.n += yymsp[-1].minor.yy0.n; - yylhsminor.yy114 = setTableNameList(yymsp[-4].minor.yy114, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); + yylhsminor.yy8 = setTableNameList(yymsp[-4].minor.yy8, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } -#line 3442 "sql.c" - yymsp[-4].minor.yy114 = yylhsminor.yy114; +#line 3448 "sql.c" + yymsp[-4].minor.yy8 = yylhsminor.yy8; break; case 191: /* tmvar ::= VARIABLE */ #line 573 "sql.y" {yylhsminor.yy0 = yymsp[0].minor.yy0;} -#line 3448 "sql.c" +#line 3454 "sql.c" yymsp[0].minor.yy0 = yylhsminor.yy0; break; case 192: /* interval_option ::= intervalKey LP tmvar RP */ #line 576 "sql.y" -{yylhsminor.yy222.interval = yymsp[-1].minor.yy0; yylhsminor.yy222.offset.n = 0; yylhsminor.yy222.token = yymsp[-3].minor.yy202;} -#line 3454 "sql.c" - yymsp[-3].minor.yy222 = yylhsminor.yy222; +{yylhsminor.yy400.interval = yymsp[-1].minor.yy0; yylhsminor.yy400.offset.n = 0; yylhsminor.yy400.token = yymsp[-3].minor.yy104;} +#line 3460 "sql.c" + yymsp[-3].minor.yy400 = yylhsminor.yy400; break; case 193: /* interval_option ::= intervalKey LP tmvar COMMA tmvar RP */ #line 577 "sql.y" -{yylhsminor.yy222.interval = yymsp[-3].minor.yy0; yylhsminor.yy222.offset = yymsp[-1].minor.yy0; yylhsminor.yy222.token = yymsp[-5].minor.yy202;} -#line 3460 "sql.c" - yymsp[-5].minor.yy222 = yylhsminor.yy222; +{yylhsminor.yy400.interval = yymsp[-3].minor.yy0; yylhsminor.yy400.offset = yymsp[-1].minor.yy0; yylhsminor.yy400.token = yymsp[-5].minor.yy104;} +#line 3466 "sql.c" + yymsp[-5].minor.yy400 = yylhsminor.yy400; break; case 194: /* interval_option ::= */ #line 578 "sql.y" -{memset(&yymsp[1].minor.yy222, 0, sizeof(yymsp[1].minor.yy222));} -#line 3466 "sql.c" +{memset(&yymsp[1].minor.yy400, 0, sizeof(yymsp[1].minor.yy400));} +#line 3472 "sql.c" break; case 195: /* intervalKey ::= INTERVAL */ #line 581 "sql.y" -{yymsp[0].minor.yy202 = TK_INTERVAL;} -#line 3471 "sql.c" +{yymsp[0].minor.yy104 = TK_INTERVAL;} +#line 3477 "sql.c" break; case 196: /* intervalKey ::= EVERY */ #line 582 "sql.y" -{yymsp[0].minor.yy202 = TK_EVERY; } -#line 3476 "sql.c" +{yymsp[0].minor.yy104 = TK_EVERY; } +#line 3482 "sql.c" break; case 197: /* session_option ::= */ #line 585 "sql.y" -{yymsp[1].minor.yy365.col.n = 0; yymsp[1].minor.yy365.gap.n = 0;} -#line 3481 "sql.c" +{yymsp[1].minor.yy147.col.n = 0; yymsp[1].minor.yy147.gap.n = 0;} +#line 3487 "sql.c" break; case 198: /* session_option ::= SESSION LP ids cpxName COMMA tmvar RP */ #line 586 "sql.y" { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - yymsp[-6].minor.yy365.col = yymsp[-4].minor.yy0; - yymsp[-6].minor.yy365.gap = yymsp[-1].minor.yy0; + yymsp[-6].minor.yy147.col = yymsp[-4].minor.yy0; + yymsp[-6].minor.yy147.gap = yymsp[-1].minor.yy0; } -#line 3490 "sql.c" +#line 3496 "sql.c" break; case 199: /* windowstate_option ::= */ #line 593 "sql.y" -{ yymsp[1].minor.yy544.col.n = 0; yymsp[1].minor.yy544.col.z = NULL;} -#line 3495 "sql.c" +{ yymsp[1].minor.yy40.col.n = 0; yymsp[1].minor.yy40.col.z = NULL;} +#line 3501 "sql.c" break; case 200: /* windowstate_option ::= STATE_WINDOW LP ids RP */ #line 594 "sql.y" -{ yymsp[-3].minor.yy544.col = yymsp[-1].minor.yy0; } -#line 3500 "sql.c" +{ yymsp[-3].minor.yy40.col = yymsp[-1].minor.yy0; } +#line 3506 "sql.c" break; case 201: /* fill_opt ::= */ #line 598 "sql.y" -{ yymsp[1].minor.yy403 = 0; } -#line 3505 "sql.c" +{ yymsp[1].minor.yy421 = 0; } +#line 3511 "sql.c" break; case 202: /* fill_opt ::= FILL LP ID COMMA tagitemlist RP */ #line 599 "sql.y" @@ -3510,49 +3516,49 @@ static YYACTIONTYPE yy_reduce( toTSDBType(yymsp[-3].minor.yy0.type); tVariantCreate(&A, &yymsp[-3].minor.yy0); - tVariantListInsert(yymsp[-1].minor.yy403, &A, -1, 0); - yymsp[-5].minor.yy403 = yymsp[-1].minor.yy403; + tVariantListInsert(yymsp[-1].minor.yy421, &A, -1, 0); + yymsp[-5].minor.yy421 = yymsp[-1].minor.yy421; } -#line 3517 "sql.c" +#line 3523 "sql.c" break; case 203: /* fill_opt ::= FILL LP ID RP */ #line 608 "sql.y" { toTSDBType(yymsp[-1].minor.yy0.type); - yymsp[-3].minor.yy403 = tVariantListAppendToken(NULL, &yymsp[-1].minor.yy0, -1); + yymsp[-3].minor.yy421 = tVariantListAppendToken(NULL, &yymsp[-1].minor.yy0, -1); } -#line 3525 "sql.c" +#line 3531 "sql.c" break; case 204: /* sliding_opt ::= SLIDING LP tmvar RP */ #line 614 "sql.y" {yymsp[-3].minor.yy0 = yymsp[-1].minor.yy0; } -#line 3530 "sql.c" +#line 3536 "sql.c" break; case 205: /* sliding_opt ::= */ #line 615 "sql.y" {yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = NULL; yymsp[1].minor.yy0.type = 0; } -#line 3535 "sql.c" +#line 3541 "sql.c" break; case 207: /* orderby_opt ::= ORDER BY sortlist */ #line 627 "sql.y" -{yymsp[-2].minor.yy403 = yymsp[0].minor.yy403;} -#line 3540 "sql.c" +{yymsp[-2].minor.yy421 = yymsp[0].minor.yy421;} +#line 3546 "sql.c" break; case 208: /* sortlist ::= sortlist COMMA item sortorder */ #line 629 "sql.y" { - yylhsminor.yy403 = tVariantListAppend(yymsp[-3].minor.yy403, &yymsp[-1].minor.yy488, yymsp[0].minor.yy70); + yylhsminor.yy421 = tVariantListAppend(yymsp[-3].minor.yy421, &yymsp[-1].minor.yy430, yymsp[0].minor.yy96); } -#line 3547 "sql.c" - yymsp[-3].minor.yy403 = yylhsminor.yy403; +#line 3553 "sql.c" + yymsp[-3].minor.yy421 = yylhsminor.yy421; break; case 209: /* sortlist ::= item sortorder */ #line 633 "sql.y" { - yylhsminor.yy403 = tVariantListAppend(NULL, &yymsp[-1].minor.yy488, yymsp[0].minor.yy70); + yylhsminor.yy421 = tVariantListAppend(NULL, &yymsp[-1].minor.yy430, yymsp[0].minor.yy96); } -#line 3555 "sql.c" - yymsp[-1].minor.yy403 = yylhsminor.yy403; +#line 3561 "sql.c" + yymsp[-1].minor.yy421 = yylhsminor.yy421; break; case 210: /* item ::= ids cpxName */ #line 638 "sql.y" @@ -3560,349 +3566,355 @@ static YYACTIONTYPE yy_reduce( toTSDBType(yymsp[-1].minor.yy0.type); yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; - tVariantCreate(&yylhsminor.yy488, &yymsp[-1].minor.yy0); + tVariantCreate(&yylhsminor.yy430, &yymsp[-1].minor.yy0); } -#line 3566 "sql.c" - yymsp[-1].minor.yy488 = yylhsminor.yy488; +#line 3572 "sql.c" + yymsp[-1].minor.yy430 = yylhsminor.yy430; break; case 211: /* sortorder ::= ASC */ #line 646 "sql.y" -{ yymsp[0].minor.yy70 = TSDB_ORDER_ASC; } -#line 3572 "sql.c" +{ yymsp[0].minor.yy96 = TSDB_ORDER_ASC; } +#line 3578 "sql.c" break; case 212: /* sortorder ::= DESC */ #line 647 "sql.y" -{ yymsp[0].minor.yy70 = TSDB_ORDER_DESC;} -#line 3577 "sql.c" +{ yymsp[0].minor.yy96 = TSDB_ORDER_DESC;} +#line 3583 "sql.c" break; case 213: /* sortorder ::= */ #line 648 "sql.y" -{ yymsp[1].minor.yy70 = TSDB_ORDER_ASC; } -#line 3582 "sql.c" +{ yymsp[1].minor.yy96 = TSDB_ORDER_ASC; } +#line 3588 "sql.c" break; case 214: /* groupby_opt ::= */ #line 656 "sql.y" -{ yymsp[1].minor.yy403 = 0;} -#line 3587 "sql.c" +{ yymsp[1].minor.yy421 = 0;} +#line 3593 "sql.c" break; case 215: /* groupby_opt ::= GROUP BY grouplist */ #line 657 "sql.y" -{ yymsp[-2].minor.yy403 = yymsp[0].minor.yy403;} -#line 3592 "sql.c" +{ yymsp[-2].minor.yy421 = yymsp[0].minor.yy421;} +#line 3598 "sql.c" break; case 216: /* grouplist ::= grouplist COMMA item */ #line 659 "sql.y" { - yylhsminor.yy403 = tVariantListAppend(yymsp[-2].minor.yy403, &yymsp[0].minor.yy488, -1); + yylhsminor.yy421 = tVariantListAppend(yymsp[-2].minor.yy421, &yymsp[0].minor.yy430, -1); } -#line 3599 "sql.c" - yymsp[-2].minor.yy403 = yylhsminor.yy403; +#line 3605 "sql.c" + yymsp[-2].minor.yy421 = yylhsminor.yy421; break; case 217: /* grouplist ::= item */ #line 663 "sql.y" { - yylhsminor.yy403 = tVariantListAppend(NULL, &yymsp[0].minor.yy488, -1); + yylhsminor.yy421 = tVariantListAppend(NULL, &yymsp[0].minor.yy430, -1); } -#line 3607 "sql.c" - yymsp[0].minor.yy403 = yylhsminor.yy403; +#line 3613 "sql.c" + yymsp[0].minor.yy421 = yylhsminor.yy421; break; case 218: /* having_opt ::= */ case 228: /* where_opt ::= */ yytestcase(yyruleno==228); - case 271: /* expritem ::= */ yytestcase(yyruleno==271); + case 272: /* expritem ::= */ yytestcase(yyruleno==272); #line 670 "sql.y" -{yymsp[1].minor.yy260 = 0;} -#line 3615 "sql.c" +{yymsp[1].minor.yy439 = 0;} +#line 3621 "sql.c" break; case 219: /* having_opt ::= HAVING expr */ case 229: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==229); #line 671 "sql.y" -{yymsp[-1].minor.yy260 = yymsp[0].minor.yy260;} -#line 3621 "sql.c" +{yymsp[-1].minor.yy439 = yymsp[0].minor.yy439;} +#line 3627 "sql.c" break; case 220: /* limit_opt ::= */ case 224: /* slimit_opt ::= */ yytestcase(yyruleno==224); #line 675 "sql.y" -{yymsp[1].minor.yy404.limit = -1; yymsp[1].minor.yy404.offset = 0;} -#line 3627 "sql.c" +{yymsp[1].minor.yy166.limit = -1; yymsp[1].minor.yy166.offset = 0;} +#line 3633 "sql.c" break; case 221: /* limit_opt ::= LIMIT signed */ case 225: /* slimit_opt ::= SLIMIT signed */ yytestcase(yyruleno==225); #line 676 "sql.y" -{yymsp[-1].minor.yy404.limit = yymsp[0].minor.yy387; yymsp[-1].minor.yy404.offset = 0;} -#line 3633 "sql.c" +{yymsp[-1].minor.yy166.limit = yymsp[0].minor.yy325; yymsp[-1].minor.yy166.offset = 0;} +#line 3639 "sql.c" break; case 222: /* limit_opt ::= LIMIT signed OFFSET signed */ #line 678 "sql.y" -{ yymsp[-3].minor.yy404.limit = yymsp[-2].minor.yy387; yymsp[-3].minor.yy404.offset = yymsp[0].minor.yy387;} -#line 3638 "sql.c" +{ yymsp[-3].minor.yy166.limit = yymsp[-2].minor.yy325; yymsp[-3].minor.yy166.offset = yymsp[0].minor.yy325;} +#line 3644 "sql.c" break; case 223: /* limit_opt ::= LIMIT signed COMMA signed */ #line 680 "sql.y" -{ yymsp[-3].minor.yy404.limit = yymsp[0].minor.yy387; yymsp[-3].minor.yy404.offset = yymsp[-2].minor.yy387;} -#line 3643 "sql.c" +{ yymsp[-3].minor.yy166.limit = yymsp[0].minor.yy325; yymsp[-3].minor.yy166.offset = yymsp[-2].minor.yy325;} +#line 3649 "sql.c" break; case 226: /* slimit_opt ::= SLIMIT signed SOFFSET signed */ #line 686 "sql.y" -{yymsp[-3].minor.yy404.limit = yymsp[-2].minor.yy387; yymsp[-3].minor.yy404.offset = yymsp[0].minor.yy387;} -#line 3648 "sql.c" +{yymsp[-3].minor.yy166.limit = yymsp[-2].minor.yy325; yymsp[-3].minor.yy166.offset = yymsp[0].minor.yy325;} +#line 3654 "sql.c" break; case 227: /* slimit_opt ::= SLIMIT signed COMMA signed */ #line 688 "sql.y" -{yymsp[-3].minor.yy404.limit = yymsp[0].minor.yy387; yymsp[-3].minor.yy404.offset = yymsp[-2].minor.yy387;} -#line 3653 "sql.c" +{yymsp[-3].minor.yy166.limit = yymsp[0].minor.yy325; yymsp[-3].minor.yy166.offset = yymsp[-2].minor.yy325;} +#line 3659 "sql.c" break; case 230: /* expr ::= LP expr RP */ #line 701 "sql.y" -{yylhsminor.yy260 = yymsp[-1].minor.yy260; yylhsminor.yy260->exprToken.z = yymsp[-2].minor.yy0.z; yylhsminor.yy260->exprToken.n = (yymsp[0].minor.yy0.z - yymsp[-2].minor.yy0.z + 1);} -#line 3658 "sql.c" - yymsp[-2].minor.yy260 = yylhsminor.yy260; +{yylhsminor.yy439 = yymsp[-1].minor.yy439; yylhsminor.yy439->exprToken.z = yymsp[-2].minor.yy0.z; yylhsminor.yy439->exprToken.n = (yymsp[0].minor.yy0.z - yymsp[-2].minor.yy0.z + 1);} +#line 3664 "sql.c" + yymsp[-2].minor.yy439 = yylhsminor.yy439; break; case 231: /* expr ::= ID */ #line 703 "sql.y" -{ yylhsminor.yy260 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_ID);} -#line 3664 "sql.c" - yymsp[0].minor.yy260 = yylhsminor.yy260; +{ yylhsminor.yy439 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_ID);} +#line 3670 "sql.c" + yymsp[0].minor.yy439 = yylhsminor.yy439; break; case 232: /* expr ::= ID DOT ID */ #line 704 "sql.y" -{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy260 = tSqlExprCreateIdValue(&yymsp[-2].minor.yy0, TK_ID);} -#line 3670 "sql.c" - yymsp[-2].minor.yy260 = yylhsminor.yy260; +{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy439 = tSqlExprCreateIdValue(&yymsp[-2].minor.yy0, TK_ID);} +#line 3676 "sql.c" + yymsp[-2].minor.yy439 = yylhsminor.yy439; break; case 233: /* expr ::= ID DOT STAR */ #line 705 "sql.y" -{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy260 = tSqlExprCreateIdValue(&yymsp[-2].minor.yy0, TK_ALL);} -#line 3676 "sql.c" - yymsp[-2].minor.yy260 = yylhsminor.yy260; +{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy439 = tSqlExprCreateIdValue(&yymsp[-2].minor.yy0, TK_ALL);} +#line 3682 "sql.c" + yymsp[-2].minor.yy439 = yylhsminor.yy439; break; case 234: /* expr ::= INTEGER */ #line 707 "sql.y" -{ yylhsminor.yy260 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_INTEGER);} -#line 3682 "sql.c" - yymsp[0].minor.yy260 = yylhsminor.yy260; +{ yylhsminor.yy439 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_INTEGER);} +#line 3688 "sql.c" + yymsp[0].minor.yy439 = yylhsminor.yy439; break; case 235: /* expr ::= MINUS INTEGER */ case 236: /* expr ::= PLUS INTEGER */ yytestcase(yyruleno==236); #line 708 "sql.y" -{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_INTEGER; yylhsminor.yy260 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_INTEGER);} -#line 3689 "sql.c" - yymsp[-1].minor.yy260 = yylhsminor.yy260; +{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_INTEGER; yylhsminor.yy439 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_INTEGER);} +#line 3695 "sql.c" + yymsp[-1].minor.yy439 = yylhsminor.yy439; break; case 237: /* expr ::= FLOAT */ #line 710 "sql.y" -{ yylhsminor.yy260 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_FLOAT);} -#line 3695 "sql.c" - yymsp[0].minor.yy260 = yylhsminor.yy260; +{ yylhsminor.yy439 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_FLOAT);} +#line 3701 "sql.c" + yymsp[0].minor.yy439 = yylhsminor.yy439; break; case 238: /* expr ::= MINUS FLOAT */ case 239: /* expr ::= PLUS FLOAT */ yytestcase(yyruleno==239); #line 711 "sql.y" -{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_FLOAT; yylhsminor.yy260 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_FLOAT);} -#line 3702 "sql.c" - yymsp[-1].minor.yy260 = yylhsminor.yy260; +{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_FLOAT; yylhsminor.yy439 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_FLOAT);} +#line 3708 "sql.c" + yymsp[-1].minor.yy439 = yylhsminor.yy439; break; case 240: /* expr ::= STRING */ #line 713 "sql.y" -{ yylhsminor.yy260 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_STRING);} -#line 3708 "sql.c" - yymsp[0].minor.yy260 = yylhsminor.yy260; +{ yylhsminor.yy439 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_STRING);} +#line 3714 "sql.c" + yymsp[0].minor.yy439 = yylhsminor.yy439; break; case 241: /* expr ::= NOW */ #line 714 "sql.y" -{ yylhsminor.yy260 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_NOW); } -#line 3714 "sql.c" - yymsp[0].minor.yy260 = yylhsminor.yy260; +{ yylhsminor.yy439 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_NOW); } +#line 3720 "sql.c" + yymsp[0].minor.yy439 = yylhsminor.yy439; break; case 242: /* expr ::= VARIABLE */ #line 715 "sql.y" -{ yylhsminor.yy260 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_VARIABLE);} -#line 3720 "sql.c" - yymsp[0].minor.yy260 = yylhsminor.yy260; +{ yylhsminor.yy439 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_VARIABLE);} +#line 3726 "sql.c" + yymsp[0].minor.yy439 = yylhsminor.yy439; break; case 243: /* expr ::= PLUS VARIABLE */ case 244: /* expr ::= MINUS VARIABLE */ yytestcase(yyruleno==244); #line 716 "sql.y" -{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_VARIABLE; yylhsminor.yy260 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_VARIABLE);} -#line 3727 "sql.c" - yymsp[-1].minor.yy260 = yylhsminor.yy260; +{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_VARIABLE; yylhsminor.yy439 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_VARIABLE);} +#line 3733 "sql.c" + yymsp[-1].minor.yy439 = yylhsminor.yy439; break; case 245: /* expr ::= BOOL */ #line 718 "sql.y" -{ yylhsminor.yy260 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_BOOL);} -#line 3733 "sql.c" - yymsp[0].minor.yy260 = yylhsminor.yy260; +{ yylhsminor.yy439 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_BOOL);} +#line 3739 "sql.c" + yymsp[0].minor.yy439 = yylhsminor.yy439; break; case 246: /* expr ::= NULL */ #line 719 "sql.y" -{ yylhsminor.yy260 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_NULL);} -#line 3739 "sql.c" - yymsp[0].minor.yy260 = yylhsminor.yy260; +{ yylhsminor.yy439 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_NULL);} +#line 3745 "sql.c" + yymsp[0].minor.yy439 = yylhsminor.yy439; break; case 247: /* expr ::= ID LP exprlist RP */ #line 722 "sql.y" -{ tStrTokenAppend(pInfo->funcs, &yymsp[-3].minor.yy0); yylhsminor.yy260 = tSqlExprCreateFunction(yymsp[-1].minor.yy403, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } -#line 3745 "sql.c" - yymsp[-3].minor.yy260 = yylhsminor.yy260; +{ tStrTokenAppend(pInfo->funcs, &yymsp[-3].minor.yy0); yylhsminor.yy439 = tSqlExprCreateFunction(yymsp[-1].minor.yy421, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } +#line 3751 "sql.c" + yymsp[-3].minor.yy439 = yylhsminor.yy439; break; case 248: /* expr ::= ID LP STAR RP */ #line 725 "sql.y" -{ tStrTokenAppend(pInfo->funcs, &yymsp[-3].minor.yy0); yylhsminor.yy260 = tSqlExprCreateFunction(NULL, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } -#line 3751 "sql.c" - yymsp[-3].minor.yy260 = yylhsminor.yy260; +{ tStrTokenAppend(pInfo->funcs, &yymsp[-3].minor.yy0); yylhsminor.yy439 = tSqlExprCreateFunction(NULL, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } +#line 3757 "sql.c" + yymsp[-3].minor.yy439 = yylhsminor.yy439; break; case 249: /* expr ::= expr IS NULL */ #line 728 "sql.y" -{yylhsminor.yy260 = tSqlExprCreate(yymsp[-2].minor.yy260, NULL, TK_ISNULL);} -#line 3757 "sql.c" - yymsp[-2].minor.yy260 = yylhsminor.yy260; +{yylhsminor.yy439 = tSqlExprCreate(yymsp[-2].minor.yy439, NULL, TK_ISNULL);} +#line 3763 "sql.c" + yymsp[-2].minor.yy439 = yylhsminor.yy439; break; case 250: /* expr ::= expr IS NOT NULL */ #line 729 "sql.y" -{yylhsminor.yy260 = tSqlExprCreate(yymsp[-3].minor.yy260, NULL, TK_NOTNULL);} -#line 3763 "sql.c" - yymsp[-3].minor.yy260 = yylhsminor.yy260; +{yylhsminor.yy439 = tSqlExprCreate(yymsp[-3].minor.yy439, NULL, TK_NOTNULL);} +#line 3769 "sql.c" + yymsp[-3].minor.yy439 = yylhsminor.yy439; break; case 251: /* expr ::= expr LT expr */ #line 732 "sql.y" -{yylhsminor.yy260 = tSqlExprCreate(yymsp[-2].minor.yy260, yymsp[0].minor.yy260, TK_LT);} -#line 3769 "sql.c" - yymsp[-2].minor.yy260 = yylhsminor.yy260; +{yylhsminor.yy439 = tSqlExprCreate(yymsp[-2].minor.yy439, yymsp[0].minor.yy439, TK_LT);} +#line 3775 "sql.c" + yymsp[-2].minor.yy439 = yylhsminor.yy439; break; case 252: /* expr ::= expr GT expr */ #line 733 "sql.y" -{yylhsminor.yy260 = tSqlExprCreate(yymsp[-2].minor.yy260, yymsp[0].minor.yy260, TK_GT);} -#line 3775 "sql.c" - yymsp[-2].minor.yy260 = yylhsminor.yy260; +{yylhsminor.yy439 = tSqlExprCreate(yymsp[-2].minor.yy439, yymsp[0].minor.yy439, TK_GT);} +#line 3781 "sql.c" + yymsp[-2].minor.yy439 = yylhsminor.yy439; break; case 253: /* expr ::= expr LE expr */ #line 734 "sql.y" -{yylhsminor.yy260 = tSqlExprCreate(yymsp[-2].minor.yy260, yymsp[0].minor.yy260, TK_LE);} -#line 3781 "sql.c" - yymsp[-2].minor.yy260 = yylhsminor.yy260; +{yylhsminor.yy439 = tSqlExprCreate(yymsp[-2].minor.yy439, yymsp[0].minor.yy439, TK_LE);} +#line 3787 "sql.c" + yymsp[-2].minor.yy439 = yylhsminor.yy439; break; case 254: /* expr ::= expr GE expr */ #line 735 "sql.y" -{yylhsminor.yy260 = tSqlExprCreate(yymsp[-2].minor.yy260, yymsp[0].minor.yy260, TK_GE);} -#line 3787 "sql.c" - yymsp[-2].minor.yy260 = yylhsminor.yy260; +{yylhsminor.yy439 = tSqlExprCreate(yymsp[-2].minor.yy439, yymsp[0].minor.yy439, TK_GE);} +#line 3793 "sql.c" + yymsp[-2].minor.yy439 = yylhsminor.yy439; break; case 255: /* expr ::= expr NE expr */ #line 736 "sql.y" -{yylhsminor.yy260 = tSqlExprCreate(yymsp[-2].minor.yy260, yymsp[0].minor.yy260, TK_NE);} -#line 3793 "sql.c" - yymsp[-2].minor.yy260 = yylhsminor.yy260; +{yylhsminor.yy439 = tSqlExprCreate(yymsp[-2].minor.yy439, yymsp[0].minor.yy439, TK_NE);} +#line 3799 "sql.c" + yymsp[-2].minor.yy439 = yylhsminor.yy439; break; case 256: /* expr ::= expr EQ expr */ #line 737 "sql.y" -{yylhsminor.yy260 = tSqlExprCreate(yymsp[-2].minor.yy260, yymsp[0].minor.yy260, TK_EQ);} -#line 3799 "sql.c" - yymsp[-2].minor.yy260 = yylhsminor.yy260; +{yylhsminor.yy439 = tSqlExprCreate(yymsp[-2].minor.yy439, yymsp[0].minor.yy439, TK_EQ);} +#line 3805 "sql.c" + yymsp[-2].minor.yy439 = yylhsminor.yy439; break; case 257: /* expr ::= expr BETWEEN expr AND expr */ #line 739 "sql.y" -{ tSqlExpr* X2 = tSqlExprClone(yymsp[-4].minor.yy260); yylhsminor.yy260 = tSqlExprCreate(tSqlExprCreate(yymsp[-4].minor.yy260, yymsp[-2].minor.yy260, TK_GE), tSqlExprCreate(X2, yymsp[0].minor.yy260, TK_LE), TK_AND);} -#line 3805 "sql.c" - yymsp[-4].minor.yy260 = yylhsminor.yy260; +{ tSqlExpr* X2 = tSqlExprClone(yymsp[-4].minor.yy439); yylhsminor.yy439 = tSqlExprCreate(tSqlExprCreate(yymsp[-4].minor.yy439, yymsp[-2].minor.yy439, TK_GE), tSqlExprCreate(X2, yymsp[0].minor.yy439, TK_LE), TK_AND);} +#line 3811 "sql.c" + yymsp[-4].minor.yy439 = yylhsminor.yy439; break; case 258: /* expr ::= expr AND expr */ #line 741 "sql.y" -{yylhsminor.yy260 = tSqlExprCreate(yymsp[-2].minor.yy260, yymsp[0].minor.yy260, TK_AND);} -#line 3811 "sql.c" - yymsp[-2].minor.yy260 = yylhsminor.yy260; +{yylhsminor.yy439 = tSqlExprCreate(yymsp[-2].minor.yy439, yymsp[0].minor.yy439, TK_AND);} +#line 3817 "sql.c" + yymsp[-2].minor.yy439 = yylhsminor.yy439; break; case 259: /* expr ::= expr OR expr */ #line 742 "sql.y" -{yylhsminor.yy260 = tSqlExprCreate(yymsp[-2].minor.yy260, yymsp[0].minor.yy260, TK_OR); } -#line 3817 "sql.c" - yymsp[-2].minor.yy260 = yylhsminor.yy260; +{yylhsminor.yy439 = tSqlExprCreate(yymsp[-2].minor.yy439, yymsp[0].minor.yy439, TK_OR); } +#line 3823 "sql.c" + yymsp[-2].minor.yy439 = yylhsminor.yy439; break; case 260: /* expr ::= expr PLUS expr */ #line 745 "sql.y" -{yylhsminor.yy260 = tSqlExprCreate(yymsp[-2].minor.yy260, yymsp[0].minor.yy260, TK_PLUS); } -#line 3823 "sql.c" - yymsp[-2].minor.yy260 = yylhsminor.yy260; +{yylhsminor.yy439 = tSqlExprCreate(yymsp[-2].minor.yy439, yymsp[0].minor.yy439, TK_PLUS); } +#line 3829 "sql.c" + yymsp[-2].minor.yy439 = yylhsminor.yy439; break; case 261: /* expr ::= expr MINUS expr */ #line 746 "sql.y" -{yylhsminor.yy260 = tSqlExprCreate(yymsp[-2].minor.yy260, yymsp[0].minor.yy260, TK_MINUS); } -#line 3829 "sql.c" - yymsp[-2].minor.yy260 = yylhsminor.yy260; +{yylhsminor.yy439 = tSqlExprCreate(yymsp[-2].minor.yy439, yymsp[0].minor.yy439, TK_MINUS); } +#line 3835 "sql.c" + yymsp[-2].minor.yy439 = yylhsminor.yy439; break; case 262: /* expr ::= expr STAR expr */ #line 747 "sql.y" -{yylhsminor.yy260 = tSqlExprCreate(yymsp[-2].minor.yy260, yymsp[0].minor.yy260, TK_STAR); } -#line 3835 "sql.c" - yymsp[-2].minor.yy260 = yylhsminor.yy260; +{yylhsminor.yy439 = tSqlExprCreate(yymsp[-2].minor.yy439, yymsp[0].minor.yy439, TK_STAR); } +#line 3841 "sql.c" + yymsp[-2].minor.yy439 = yylhsminor.yy439; break; case 263: /* expr ::= expr SLASH expr */ #line 748 "sql.y" -{yylhsminor.yy260 = tSqlExprCreate(yymsp[-2].minor.yy260, yymsp[0].minor.yy260, TK_DIVIDE);} -#line 3841 "sql.c" - yymsp[-2].minor.yy260 = yylhsminor.yy260; +{yylhsminor.yy439 = tSqlExprCreate(yymsp[-2].minor.yy439, yymsp[0].minor.yy439, TK_DIVIDE);} +#line 3847 "sql.c" + yymsp[-2].minor.yy439 = yylhsminor.yy439; break; case 264: /* expr ::= expr REM expr */ #line 749 "sql.y" -{yylhsminor.yy260 = tSqlExprCreate(yymsp[-2].minor.yy260, yymsp[0].minor.yy260, TK_REM); } -#line 3847 "sql.c" - yymsp[-2].minor.yy260 = yylhsminor.yy260; +{yylhsminor.yy439 = tSqlExprCreate(yymsp[-2].minor.yy439, yymsp[0].minor.yy439, TK_REM); } +#line 3853 "sql.c" + yymsp[-2].minor.yy439 = yylhsminor.yy439; break; case 265: /* expr ::= expr LIKE expr */ #line 752 "sql.y" -{yylhsminor.yy260 = tSqlExprCreate(yymsp[-2].minor.yy260, yymsp[0].minor.yy260, TK_LIKE); } -#line 3853 "sql.c" - yymsp[-2].minor.yy260 = yylhsminor.yy260; +{yylhsminor.yy439 = tSqlExprCreate(yymsp[-2].minor.yy439, yymsp[0].minor.yy439, TK_LIKE); } +#line 3859 "sql.c" + yymsp[-2].minor.yy439 = yylhsminor.yy439; break; case 266: /* expr ::= expr MATCH expr */ #line 755 "sql.y" -{yylhsminor.yy260 = tSqlExprCreate(yymsp[-2].minor.yy260, yymsp[0].minor.yy260, TK_MATCH); } -#line 3859 "sql.c" - yymsp[-2].minor.yy260 = yylhsminor.yy260; - break; - case 267: /* expr ::= expr IN LP exprlist RP */ -#line 758 "sql.y" -{yylhsminor.yy260 = tSqlExprCreate(yymsp[-4].minor.yy260, (tSqlExpr*)yymsp[-1].minor.yy403, TK_IN); } +{yylhsminor.yy439 = tSqlExprCreate(yymsp[-2].minor.yy439, yymsp[0].minor.yy439, TK_MATCH); } #line 3865 "sql.c" - yymsp[-4].minor.yy260 = yylhsminor.yy260; + yymsp[-2].minor.yy439 = yylhsminor.yy439; break; - case 268: /* exprlist ::= exprlist COMMA expritem */ -#line 766 "sql.y" -{yylhsminor.yy403 = tSqlExprListAppend(yymsp[-2].minor.yy403,yymsp[0].minor.yy260,0, 0);} + case 267: /* expr ::= expr NMATCH expr */ +#line 756 "sql.y" +{yylhsminor.yy439 = tSqlExprCreate(yymsp[-2].minor.yy439, yymsp[0].minor.yy439, TK_NMATCH); } #line 3871 "sql.c" - yymsp[-2].minor.yy403 = yylhsminor.yy403; + yymsp[-2].minor.yy439 = yylhsminor.yy439; break; - case 269: /* exprlist ::= expritem */ -#line 767 "sql.y" -{yylhsminor.yy403 = tSqlExprListAppend(0,yymsp[0].minor.yy260,0, 0);} + case 268: /* expr ::= expr IN LP exprlist RP */ +#line 759 "sql.y" +{yylhsminor.yy439 = tSqlExprCreate(yymsp[-4].minor.yy439, (tSqlExpr*)yymsp[-1].minor.yy421, TK_IN); } #line 3877 "sql.c" - yymsp[0].minor.yy403 = yylhsminor.yy403; + yymsp[-4].minor.yy439 = yylhsminor.yy439; break; - case 270: /* expritem ::= expr */ -#line 768 "sql.y" -{yylhsminor.yy260 = yymsp[0].minor.yy260;} + case 269: /* exprlist ::= exprlist COMMA expritem */ +#line 767 "sql.y" +{yylhsminor.yy421 = tSqlExprListAppend(yymsp[-2].minor.yy421,yymsp[0].minor.yy439,0, 0);} #line 3883 "sql.c" - yymsp[0].minor.yy260 = yylhsminor.yy260; + yymsp[-2].minor.yy421 = yylhsminor.yy421; break; - case 272: /* cmd ::= RESET QUERY CACHE */ -#line 772 "sql.y" -{ setDCLSqlElems(pInfo, TSDB_SQL_RESET_CACHE, 0);} + case 270: /* exprlist ::= expritem */ +#line 768 "sql.y" +{yylhsminor.yy421 = tSqlExprListAppend(0,yymsp[0].minor.yy439,0, 0);} #line 3889 "sql.c" + yymsp[0].minor.yy421 = yylhsminor.yy421; + break; + case 271: /* expritem ::= expr */ +#line 769 "sql.y" +{yylhsminor.yy439 = yymsp[0].minor.yy439;} +#line 3895 "sql.c" + yymsp[0].minor.yy439 = yylhsminor.yy439; + break; + case 273: /* cmd ::= RESET QUERY CACHE */ +#line 773 "sql.y" +{ setDCLSqlElems(pInfo, TSDB_SQL_RESET_CACHE, 0);} +#line 3901 "sql.c" break; - case 273: /* cmd ::= SYNCDB ids REPLICA */ -#line 775 "sql.y" + case 274: /* cmd ::= SYNCDB ids REPLICA */ +#line 776 "sql.y" { setDCLSqlElems(pInfo, TSDB_SQL_SYNC_DB_REPLICA, 1, &yymsp[-1].minor.yy0);} -#line 3894 "sql.c" +#line 3906 "sql.c" break; - case 274: /* cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ -#line 778 "sql.y" + case 275: /* cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ +#line 779 "sql.y" { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy403, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, -1); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy421, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, -1); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } -#line 3903 "sql.c" +#line 3915 "sql.c" break; - case 275: /* cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ -#line 784 "sql.y" + case 276: /* cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ +#line 785 "sql.y" { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; @@ -3912,28 +3924,28 @@ static YYACTIONTYPE yy_reduce( SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, NULL, K, TSDB_ALTER_TABLE_DROP_COLUMN, -1); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } -#line 3916 "sql.c" +#line 3928 "sql.c" break; - case 276: /* cmd ::= ALTER TABLE ids cpxName MODIFY COLUMN columnlist */ -#line 794 "sql.y" + case 277: /* cmd ::= ALTER TABLE ids cpxName MODIFY COLUMN columnlist */ +#line 795 "sql.y" { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy403, NULL, TSDB_ALTER_TABLE_CHANGE_COLUMN, -1); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy421, NULL, TSDB_ALTER_TABLE_CHANGE_COLUMN, -1); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } -#line 3925 "sql.c" +#line 3937 "sql.c" break; - case 277: /* cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ -#line 801 "sql.y" + case 278: /* cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ +#line 802 "sql.y" { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy403, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, -1); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy421, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, -1); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } -#line 3934 "sql.c" +#line 3946 "sql.c" break; - case 278: /* cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ -#line 806 "sql.y" + case 279: /* cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ +#line 807 "sql.y" { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; @@ -3943,10 +3955,10 @@ static YYACTIONTYPE yy_reduce( SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, NULL, A, TSDB_ALTER_TABLE_DROP_TAG_COLUMN, -1); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } -#line 3947 "sql.c" +#line 3959 "sql.c" break; - case 279: /* cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ -#line 816 "sql.y" + case 280: /* cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ +#line 817 "sql.y" { yymsp[-5].minor.yy0.n += yymsp[-4].minor.yy0.n; @@ -3959,42 +3971,42 @@ static YYACTIONTYPE yy_reduce( SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-5].minor.yy0, NULL, A, TSDB_ALTER_TABLE_CHANGE_TAG_COLUMN, -1); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } -#line 3963 "sql.c" +#line 3975 "sql.c" break; - case 280: /* cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ -#line 829 "sql.y" + case 281: /* cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ +#line 830 "sql.y" { yymsp[-6].minor.yy0.n += yymsp[-5].minor.yy0.n; toTSDBType(yymsp[-2].minor.yy0.type); SArray* A = tVariantListAppendToken(NULL, &yymsp[-2].minor.yy0, -1); - A = tVariantListAppend(A, &yymsp[0].minor.yy488, -1); + A = tVariantListAppend(A, &yymsp[0].minor.yy430, -1); SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-6].minor.yy0, NULL, A, TSDB_ALTER_TABLE_UPDATE_TAG_VAL, -1); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } -#line 3977 "sql.c" +#line 3989 "sql.c" break; - case 281: /* cmd ::= ALTER TABLE ids cpxName MODIFY TAG columnlist */ -#line 840 "sql.y" + case 282: /* cmd ::= ALTER TABLE ids cpxName MODIFY TAG columnlist */ +#line 841 "sql.y" { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy403, NULL, TSDB_ALTER_TABLE_MODIFY_TAG_COLUMN, -1); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy421, NULL, TSDB_ALTER_TABLE_MODIFY_TAG_COLUMN, -1); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } -#line 3986 "sql.c" +#line 3998 "sql.c" break; - case 282: /* cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ -#line 847 "sql.y" + case 283: /* cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ +#line 848 "sql.y" { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy403, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, TSDB_SUPER_TABLE); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy421, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, TSDB_SUPER_TABLE); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } -#line 3995 "sql.c" +#line 4007 "sql.c" break; - case 283: /* cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ -#line 853 "sql.y" + case 284: /* cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ +#line 854 "sql.y" { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; @@ -4004,28 +4016,28 @@ static YYACTIONTYPE yy_reduce( SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, NULL, K, TSDB_ALTER_TABLE_DROP_COLUMN, TSDB_SUPER_TABLE); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } -#line 4008 "sql.c" +#line 4020 "sql.c" break; - case 284: /* cmd ::= ALTER STABLE ids cpxName MODIFY COLUMN columnlist */ -#line 863 "sql.y" + case 285: /* cmd ::= ALTER STABLE ids cpxName MODIFY COLUMN columnlist */ +#line 864 "sql.y" { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy403, NULL, TSDB_ALTER_TABLE_CHANGE_COLUMN, TSDB_SUPER_TABLE); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy421, NULL, TSDB_ALTER_TABLE_CHANGE_COLUMN, TSDB_SUPER_TABLE); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } -#line 4017 "sql.c" +#line 4029 "sql.c" break; - case 285: /* cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ -#line 870 "sql.y" + case 286: /* cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ +#line 871 "sql.y" { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy403, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, TSDB_SUPER_TABLE); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy421, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, TSDB_SUPER_TABLE); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } -#line 4026 "sql.c" +#line 4038 "sql.c" break; - case 286: /* cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ -#line 875 "sql.y" + case 287: /* cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ +#line 876 "sql.y" { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; @@ -4035,10 +4047,10 @@ static YYACTIONTYPE yy_reduce( SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, NULL, A, TSDB_ALTER_TABLE_DROP_TAG_COLUMN, TSDB_SUPER_TABLE); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } -#line 4039 "sql.c" +#line 4051 "sql.c" break; - case 287: /* cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ -#line 885 "sql.y" + case 288: /* cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ +#line 886 "sql.y" { yymsp[-5].minor.yy0.n += yymsp[-4].minor.yy0.n; @@ -4051,45 +4063,45 @@ static YYACTIONTYPE yy_reduce( SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-5].minor.yy0, NULL, A, TSDB_ALTER_TABLE_CHANGE_TAG_COLUMN, TSDB_SUPER_TABLE); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } -#line 4055 "sql.c" +#line 4067 "sql.c" break; - case 288: /* cmd ::= ALTER STABLE ids cpxName SET TAG ids EQ tagitem */ -#line 898 "sql.y" + case 289: /* cmd ::= ALTER STABLE ids cpxName SET TAG ids EQ tagitem */ +#line 899 "sql.y" { yymsp[-6].minor.yy0.n += yymsp[-5].minor.yy0.n; toTSDBType(yymsp[-2].minor.yy0.type); SArray* A = tVariantListAppendToken(NULL, &yymsp[-2].minor.yy0, -1); - A = tVariantListAppend(A, &yymsp[0].minor.yy488, -1); + A = tVariantListAppend(A, &yymsp[0].minor.yy430, -1); SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-6].minor.yy0, NULL, A, TSDB_ALTER_TABLE_UPDATE_TAG_VAL, TSDB_SUPER_TABLE); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } -#line 4069 "sql.c" +#line 4081 "sql.c" break; - case 289: /* cmd ::= ALTER STABLE ids cpxName MODIFY TAG columnlist */ -#line 909 "sql.y" + case 290: /* cmd ::= ALTER STABLE ids cpxName MODIFY TAG columnlist */ +#line 910 "sql.y" { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy403, NULL, TSDB_ALTER_TABLE_MODIFY_TAG_COLUMN, TSDB_SUPER_TABLE); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy421, NULL, TSDB_ALTER_TABLE_MODIFY_TAG_COLUMN, TSDB_SUPER_TABLE); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } -#line 4078 "sql.c" +#line 4090 "sql.c" break; - case 290: /* cmd ::= KILL CONNECTION INTEGER */ -#line 916 "sql.y" + case 291: /* cmd ::= KILL CONNECTION INTEGER */ +#line 917 "sql.y" {setKillSql(pInfo, TSDB_SQL_KILL_CONNECTION, &yymsp[0].minor.yy0);} -#line 4083 "sql.c" +#line 4095 "sql.c" break; - case 291: /* cmd ::= KILL STREAM INTEGER COLON INTEGER */ -#line 917 "sql.y" + case 292: /* cmd ::= KILL STREAM INTEGER COLON INTEGER */ +#line 918 "sql.y" {yymsp[-2].minor.yy0.n += (yymsp[-1].minor.yy0.n + yymsp[0].minor.yy0.n); setKillSql(pInfo, TSDB_SQL_KILL_STREAM, &yymsp[-2].minor.yy0);} -#line 4088 "sql.c" +#line 4100 "sql.c" break; - case 292: /* cmd ::= KILL QUERY INTEGER COLON INTEGER */ -#line 918 "sql.y" + case 293: /* cmd ::= KILL QUERY INTEGER COLON INTEGER */ +#line 919 "sql.y" {yymsp[-2].minor.yy0.n += (yymsp[-1].minor.yy0.n + yymsp[0].minor.yy0.n); setKillSql(pInfo, TSDB_SQL_KILL_QUERY, &yymsp[-2].minor.yy0);} -#line 4093 "sql.c" +#line 4105 "sql.c" break; default: break; @@ -4174,7 +4186,7 @@ static void yy_syntax_error( } assert(len <= outputBufLen); -#line 4178 "sql.c" +#line 4190 "sql.c" /************ End %syntax_error code ******************************************/ ParseARG_STORE /* Suppress warning about unused %extra_argument variable */ ParseCTX_STORE @@ -4201,7 +4213,7 @@ static void yy_accept( ** parser accepts */ /*********** Begin %parse_accept code *****************************************/ #line 61 "sql.y" -#line 4205 "sql.c" +#line 4217 "sql.c" /*********** End %parse_accept code *******************************************/ ParseARG_STORE /* Suppress warning about unused %extra_argument variable */ ParseCTX_STORE diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index e958a8e5ec5b6542d609028ee052d21a9a84d397..9ea5fd539244820f111a3fbb3c60aee088e727c5 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -407,7 +407,7 @@ void rpcSendRequest(void *shandle, const SRpcEpSet *pEpSet, SRpcMsg *pMsg, int64 if (type == TSDB_MSG_TYPE_QUERY || type == TSDB_MSG_TYPE_CM_RETRIEVE || type == TSDB_MSG_TYPE_FETCH || type == TSDB_MSG_TYPE_CM_STABLE_VGROUP || type == TSDB_MSG_TYPE_CM_TABLES_META || type == TSDB_MSG_TYPE_CM_TABLE_META - || type == TSDB_MSG_TYPE_CM_SHOW || type == TSDB_MSG_TYPE_DM_STATUS) + || type == TSDB_MSG_TYPE_CM_SHOW || type == TSDB_MSG_TYPE_DM_STATUS || type == TSDB_MSG_TYPE_CM_ALTER_TABLE) pContext->connType = RPC_CONN_TCPC; pContext->rid = taosAddRef(tsRpcRefId, pContext); diff --git a/src/tsdb/inc/tsdbBuffer.h b/src/tsdb/inc/tsdbBuffer.h index ec6b057aef142fb938993b3a27717c5e64937258..4b650d3993a54f6a98caf00a3605feb37e972ebd 100644 --- a/src/tsdb/inc/tsdbBuffer.h +++ b/src/tsdb/inc/tsdbBuffer.h @@ -29,6 +29,7 @@ typedef struct { int tBufBlocks; int nBufBlocks; int nRecycleBlocks; + int nElasticBlocks; int64_t index; SList* bufBlockList; } STsdbBufPool; @@ -41,6 +42,10 @@ int tsdbOpenBufPool(STsdbRepo* pRepo); void tsdbCloseBufPool(STsdbRepo* pRepo); SListNode* tsdbAllocBufBlockFromPool(STsdbRepo* pRepo); int tsdbExpandPool(STsdbRepo* pRepo, int32_t oldTotalBlocks); -void tsdbRecycleBufferBlock(STsdbBufPool* pPool, SListNode *pNode); +void tsdbRecycleBufferBlock(STsdbBufPool* pPool, SListNode *pNode, bool bELastic); + +// health cite +STsdbBufBlock *tsdbNewBufBlock(int bufBlockSize); +void tsdbFreeBufBlock(STsdbBufBlock *pBufBlock); #endif /* _TD_TSDB_BUFFER_H_ */ diff --git a/src/tsdb/inc/tsdbHealth.h b/src/tsdb/inc/tsdbHealth.h new file mode 100644 index 0000000000000000000000000000000000000000..324f4312e05fc0ca0200c319728bf692bf476bf6 --- /dev/null +++ b/src/tsdb/inc/tsdbHealth.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef _TD_TSDB_HEALTH_H_ +#define _TD_TSDB_HEALTH_H_ + +bool tsdbUrgeQueryFree(STsdbRepo* pRepo); +int32_t tsdbInsertNewBlock(STsdbRepo* pRepo); + +bool tsdbIdleMemEnough(); +bool tsdbAllowNewBlock(STsdbRepo* pRepo); + +#endif /* _TD_TSDB_BUFFER_H_ */ diff --git a/src/tsdb/inc/tsdbMeta.h b/src/tsdb/inc/tsdbMeta.h index 51801c843c279f10e9e0895a0f2dee2839a3f6a2..8ce5e7ade80b2006ac8c39fec178994073c5a26d 100644 --- a/src/tsdb/inc/tsdbMeta.h +++ b/src/tsdb/inc/tsdbMeta.h @@ -100,7 +100,7 @@ static FORCE_INLINE int tsdbCompareSchemaVersion(const void *key1, const void *k } static FORCE_INLINE STSchema* tsdbGetTableSchemaImpl(STable* pTable, bool lock, bool copy, int16_t _version) { - STable* pDTable = (TABLE_TYPE(pTable) == TSDB_CHILD_TABLE) ? pTable->pSuper : pTable; + STable* pDTable = (pTable->pSuper != NULL) ? pTable->pSuper : pTable; // for performance purpose STSchema* pSchema = NULL; STSchema* pTSchema = NULL; diff --git a/src/tsdb/inc/tsdbint.h b/src/tsdb/inc/tsdbint.h index 532907ae01be576e40feea2969761846f07170b3..80e92975799f47d68ff72ef80a52efb6fe901b5e 100644 --- a/src/tsdb/inc/tsdbint.h +++ b/src/tsdb/inc/tsdbint.h @@ -97,6 +97,7 @@ struct STsdbRepo { SMergeBuf mergeBuf; //used when update=2 int8_t compactState; // compact state: inCompact/noCompact/waitingCompact? + pthread_t* pthread; }; #define REPO_ID(r) (r)->config.tsdbId diff --git a/src/tsdb/src/tsdbBuffer.c b/src/tsdb/src/tsdbBuffer.c index e675bf6f9de04021112d43a1db70cf56cf430f08..70589031f6516a129a5a683b0e76edb23b814e15 100644 --- a/src/tsdb/src/tsdbBuffer.c +++ b/src/tsdb/src/tsdbBuffer.c @@ -14,12 +14,10 @@ */ #include "tsdbint.h" +#include "tsdbHealth.h" #define POOL_IS_EMPTY(b) (listNEles((b)->bufBlockList) == 0) -static STsdbBufBlock *tsdbNewBufBlock(int bufBlockSize); -static void tsdbFreeBufBlock(STsdbBufBlock *pBufBlock); - // ---------------- INTERNAL FUNCTIONS ---------------- STsdbBufPool *tsdbNewBufPool() { STsdbBufPool *pBufPool = (STsdbBufPool *)calloc(1, sizeof(*pBufPool)); @@ -65,10 +63,10 @@ int tsdbOpenBufPool(STsdbRepo *pRepo) { STsdbBufPool *pPool = pRepo->pPool; ASSERT(pPool != NULL); - pPool->bufBlockSize = pCfg->cacheBlockSize * 1024 * 1024; // MB pPool->tBufBlocks = pCfg->totalBlocks; pPool->nBufBlocks = 0; + pPool->nElasticBlocks = 0; pPool->index = 0; pPool->nRecycleBlocks = 0; @@ -120,6 +118,18 @@ SListNode *tsdbAllocBufBlockFromPool(STsdbRepo *pRepo) { STsdbBufPool *pBufPool = pRepo->pPool; while (POOL_IS_EMPTY(pBufPool)) { + if(tsDeadLockKillQuery) { + // supply new Block + if(tsdbInsertNewBlock(pRepo) > 0) { + tsdbWarn("vgId:%d add new elastic block . elasticBlocks=%d cur free Blocks=%d", REPO_ID(pRepo), pBufPool->nElasticBlocks, pBufPool->bufBlockList->numOfEles); + break; + } else { + // no newBlock, kill query free + if(!tsdbUrgeQueryFree(pRepo)) + tsdbWarn("vgId:%d Urge query free thread start failed.", REPO_ID(pRepo)); + } + } + pRepo->repoLocked = false; pthread_cond_wait(&(pBufPool->poolNotEmpty), &(pRepo->mutex)); pRepo->repoLocked = true; @@ -139,11 +149,11 @@ SListNode *tsdbAllocBufBlockFromPool(STsdbRepo *pRepo) { } // ---------------- LOCAL FUNCTIONS ---------------- -static STsdbBufBlock *tsdbNewBufBlock(int bufBlockSize) { +STsdbBufBlock *tsdbNewBufBlock(int bufBlockSize) { STsdbBufBlock *pBufBlock = (STsdbBufBlock *)malloc(sizeof(*pBufBlock) + bufBlockSize); if (pBufBlock == NULL) { terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - goto _err; + return NULL; } pBufBlock->blockId = 0; @@ -151,13 +161,9 @@ static STsdbBufBlock *tsdbNewBufBlock(int bufBlockSize) { pBufBlock->remain = bufBlockSize; return pBufBlock; - -_err: - tsdbFreeBufBlock(pBufBlock); - return NULL; } -static void tsdbFreeBufBlock(STsdbBufBlock *pBufBlock) { tfree(pBufBlock); } + void tsdbFreeBufBlock(STsdbBufBlock *pBufBlock) { tfree(pBufBlock); } int tsdbExpandPool(STsdbRepo* pRepo, int32_t oldTotalBlocks) { if (oldTotalBlocks == pRepo->config.totalBlocks) { @@ -193,10 +199,16 @@ err: return err; } -void tsdbRecycleBufferBlock(STsdbBufPool* pPool, SListNode *pNode) { +void tsdbRecycleBufferBlock(STsdbBufPool* pPool, SListNode *pNode, bool bELastic) { STsdbBufBlock *pBufBlock = NULL; tdListNodeGetData(pPool->bufBlockList, pNode, (void *)(&pBufBlock)); tsdbFreeBufBlock(pBufBlock); free(pNode); - pPool->nBufBlocks--; -} + if(bELastic) + { + pPool->nElasticBlocks--; + tsdbWarn("pPool=%p elastic block reduce one . nElasticBlocks=%d cur free Blocks=%d", pPool, pPool->nElasticBlocks, pPool->bufBlockList->numOfEles); + } + else + pPool->nBufBlocks--; +} \ No newline at end of file diff --git a/src/tsdb/src/tsdbHealth.c b/src/tsdb/src/tsdbHealth.c new file mode 100644 index 0000000000000000000000000000000000000000..8198c480334912b1ce373ceca7b82409f5a644f2 --- /dev/null +++ b/src/tsdb/src/tsdbHealth.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include "os.h" +#include "taosmsg.h" +#include "tarray.h" +#include "query.h" +#include "tglobal.h" +#include "tlist.h" +#include "tsdbint.h" +#include "tsdbBuffer.h" +#include "tsdbLog.h" +#include "tsdbHealth.h" +#include "ttimer.h" +#include "tthread.h" + + +// return malloc new block count +int32_t tsdbInsertNewBlock(STsdbRepo * pRepo) { + STsdbBufPool *pPool = pRepo->pPool; + int32_t cnt = 0; + + if(tsdbAllowNewBlock(pRepo)) { + STsdbBufBlock *pBufBlock = tsdbNewBufBlock(pPool->bufBlockSize); + if (pBufBlock) { + if (tdListAppend(pPool->bufBlockList, (void *)(&pBufBlock)) < 0) { + // append error + tsdbFreeBufBlock(pBufBlock); + } else { + pPool->nElasticBlocks ++; + cnt ++ ; + } + } + } + return cnt; +} + +// switch anther thread to run +void* cbKillQueryFree(void* param) { + STsdbRepo* pRepo = (STsdbRepo*)param; + // vnode + if(pRepo->appH.notifyStatus) { + pRepo->appH.notifyStatus(pRepo->appH.appH, TSDB_STATUS_COMMIT_NOBLOCK, TSDB_CODE_SUCCESS); + } + + // free + if(pRepo->pthread){ + void* p = pRepo->pthread; + pRepo->pthread = NULL; + free(p); + } + + return NULL; +} + +// return true do free , false do nothing +bool tsdbUrgeQueryFree(STsdbRepo * pRepo) { + // check previous running + if(pRepo->pthread && taosThreadRunning(pRepo->pthread)) { + tsdbWarn("vgId:%d pre urge thread is runing. nBlocks=%d nElasticBlocks=%d", REPO_ID(pRepo), pRepo->pPool->nBufBlocks, pRepo->pPool->nElasticBlocks); + return false; + } + // create new + pRepo->pthread = taosCreateThread(cbKillQueryFree, pRepo); + if(pRepo->pthread == NULL) { + tsdbError("vgId:%d create urge thread error.", REPO_ID(pRepo)); + return false; + } + return true; +} + +bool tsdbAllowNewBlock(STsdbRepo* pRepo) { + int32_t nMaxElastic = pRepo->config.totalBlocks/3; + STsdbBufPool* pPool = pRepo->pPool; + if(pPool->nElasticBlocks >= nMaxElastic) { + tsdbWarn("vgId:%d tsdbAllowNewBlock return fasle. nElasticBlock(%d) >= MaxElasticBlocks(%d)", REPO_ID(pRepo), pPool->nElasticBlocks, nMaxElastic); + return false; + } + return true; +} + +bool tsdbNoProblem(STsdbRepo* pRepo) { + if(listNEles(pRepo->pPool->bufBlockList) == 0) + return false; + return true; +} \ No newline at end of file diff --git a/src/tsdb/src/tsdbMain.c b/src/tsdb/src/tsdbMain.c index b2e6fe89161d0e9bceaf74a46807f51ec402fb2a..c2021963e0d0c8be4ed42588549153dcd20be63c 100644 --- a/src/tsdb/src/tsdbMain.c +++ b/src/tsdb/src/tsdbMain.c @@ -16,6 +16,8 @@ // no test file errors here #include "taosdef.h" #include "tsdbint.h" +#include "ttimer.h" +#include "tthread.h" #define IS_VALID_PRECISION(precision) \ (((precision) >= TSDB_TIME_PRECISION_MILLI) && ((precision) <= TSDB_TIME_PRECISION_NANO)) @@ -126,6 +128,10 @@ int tsdbCloseRepo(STsdbRepo *repo, int toCommit) { terrno = TSDB_CODE_SUCCESS; tsdbStopStream(pRepo); + if(pRepo->pthread){ + taosDestoryThread(pRepo->pthread); + pRepo->pthread = NULL; + } if (toCommit) { tsdbSyncCommit(repo); @@ -547,6 +553,7 @@ static STsdbRepo *tsdbNewRepo(STsdbCfg *pCfg, STsdbAppH *pAppH) { pRepo->appH = *pAppH; } pRepo->repoLocked = false; + pRepo->pthread = NULL; int code = pthread_mutex_init(&(pRepo->mutex), NULL); if (code != 0) { diff --git a/src/tsdb/src/tsdbMemTable.c b/src/tsdb/src/tsdbMemTable.c index e766d97a97a5905db87691426d282a219eef9d68..3890dca5b96c26009dcf3ca72205ca4b1725aa29 100644 --- a/src/tsdb/src/tsdbMemTable.c +++ b/src/tsdb/src/tsdbMemTable.c @@ -99,17 +99,22 @@ int tsdbUnRefMemTable(STsdbRepo *pRepo, SMemTable *pMemTable) { STsdbBufPool *pBufPool = pRepo->pPool; SListNode *pNode = NULL; - bool recycleBlocks = pBufPool->nRecycleBlocks > 0; + bool addNew = false; if (tsdbLockRepo(pRepo) < 0) return -1; while ((pNode = tdListPopHead(pMemTable->bufBlockList)) != NULL) { if (pBufPool->nRecycleBlocks > 0) { - tsdbRecycleBufferBlock(pBufPool, pNode); + tsdbRecycleBufferBlock(pBufPool, pNode, false); pBufPool->nRecycleBlocks -= 1; } else { - tdListAppendNode(pBufPool->bufBlockList, pNode); + if(pBufPool->nElasticBlocks > 0 && listNEles(pBufPool->bufBlockList) > 2) { + tsdbRecycleBufferBlock(pBufPool, pNode, true); + } else { + tdListAppendNode(pBufPool->bufBlockList, pNode); + addNew = true; + } } } - if (!recycleBlocks) { + if (addNew) { int code = pthread_cond_signal(&pBufPool->poolNotEmpty); if (code != 0) { if (tsdbUnlockRepo(pRepo) < 0) return -1; diff --git a/src/tsdb/src/tsdbRead.c b/src/tsdb/src/tsdbRead.c index af2d746ace05554760895f9d14491a15369ed7cf..4bf503e2110b418aa0059ec535d1245c761b9973 100644 --- a/src/tsdb/src/tsdbRead.c +++ b/src/tsdb/src/tsdbRead.c @@ -290,8 +290,6 @@ static SArray* createCheckInfoFromTableGroup(STsdbQueryHandle* pQueryHandle, STa STableKeyInfo* pKeyInfo = (STableKeyInfo*) taosArrayGet(group, j); STableCheckInfo info = { .lastKey = pKeyInfo->lastKey, .pTableObj = pKeyInfo->pTable }; - info.tableId = ((STable*)(pKeyInfo->pTable))->tableId; - assert(info.pTableObj != NULL && (info.pTableObj->type == TSDB_NORMAL_TABLE || info.pTableObj->type == TSDB_CHILD_TABLE || info.pTableObj->type == TSDB_STREAM_TABLE)); @@ -2220,7 +2218,7 @@ static int32_t createDataBlocksInfo(STsdbQueryHandle* pQueryHandle, int32_t numO SBlock* pBlock = pTableCheck->pCompInfo->blocks; sup.numOfBlocksPerTable[numOfQualTables] = pTableCheck->numOfBlocks; - char* buf = calloc(1, sizeof(STableBlockInfo) * pTableCheck->numOfBlocks); + char* buf = malloc(sizeof(STableBlockInfo) * pTableCheck->numOfBlocks); if (buf == NULL) { cleanBlockOrderSupporter(&sup, numOfQualTables); return TSDB_CODE_TDB_OUT_OF_MEMORY; @@ -3605,8 +3603,6 @@ SArray* createTableGroup(SArray* pTableList, STSchema* pTagSchema, SColIndex* pC for(int32_t i = 0; i < size; ++i) { STableKeyInfo *pKeyInfo = taosArrayGet(pTableList, i); - assert(((STable*)pKeyInfo->pTable)->type == TSDB_CHILD_TABLE); - tsdbRefTable(pKeyInfo->pTable); STableKeyInfo info = {.pTable = pKeyInfo->pTable, .lastKey = skey}; diff --git a/src/util/inc/tcache.h b/src/util/inc/tcache.h index e41b544d00e55f7eece904c5957ef9c06063e6c3..40069d7d273caa14ce3b80467b25d68ea476fb75 100644 --- a/src/util/inc/tcache.h +++ b/src/util/inc/tcache.h @@ -33,6 +33,7 @@ extern "C" { #endif typedef void (*__cache_free_fn_t)(void*); +typedef void (*__cache_trav_fn_t)(void*, void*); typedef struct SCacheStatis { int64_t missCount; @@ -176,7 +177,7 @@ void taosCacheCleanup(SCacheObj *pCacheObj); * @param fp * @return */ -void taosCacheRefresh(SCacheObj *pCacheObj, __cache_free_fn_t fp); +void taosCacheRefresh(SCacheObj *pCacheObj, __cache_trav_fn_t fp, void* param1); /** * stop background refresh worker thread diff --git a/src/util/inc/tcompare.h b/src/util/inc/tcompare.h index ef4c1096023bd670335603dee6ab274470de3ed7..1125516d34c65da1b5d0c47dadd126aa0b1959fa 100644 --- a/src/util/inc/tcompare.h +++ b/src/util/inc/tcompare.h @@ -84,6 +84,8 @@ int32_t compareLenPrefixedStr(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 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 compareWStrPatternComp(const void* pLeft, const void* pRight); diff --git a/src/util/inc/tconfig.h b/src/util/inc/tconfig.h index d03ce6e0f1f34478951a84b2ab18020f5cbec92b..cf8977ce06c898fcdee8d21eedf5ed8d0f47f263 100644 --- a/src/util/inc/tconfig.h +++ b/src/util/inc/tconfig.h @@ -20,7 +20,7 @@ extern "C" { #endif -#define TSDB_CFG_MAX_NUM 116 // 110 + 6 with lossy option +#define TSDB_CFG_MAX_NUM 123 #define TSDB_CFG_PRINT_LEN 23 #define TSDB_CFG_OPTION_LEN 24 #define TSDB_CFG_VALUE_LEN 41 diff --git a/src/util/inc/tlosertree.h b/src/util/inc/tlosertree.h index 4c731625dd5c7950c321b2180ca913e49362059b..58f2ca8c5c81408b35c2c9435357deeb2b0f13a4 100644 --- a/src/util/inc/tlosertree.h +++ b/src/util/inc/tlosertree.h @@ -26,7 +26,7 @@ typedef int (*__merge_compare_fn_t)(const void *, const void *, void *param); typedef struct SLoserTreeNode { int32_t index; - void * pData; + void *pData; } SLoserTreeNode; typedef struct SLoserTreeInfo { @@ -34,8 +34,7 @@ typedef struct SLoserTreeInfo { int32_t totalEntries; __merge_compare_fn_t comparFn; void * param; - - SLoserTreeNode *pNode; + SLoserTreeNode *pNode; } SLoserTreeInfo; uint32_t tLoserTreeCreate(SLoserTreeInfo **pTree, int32_t numOfEntries, void *param, __merge_compare_fn_t compareFn); diff --git a/src/util/inc/tthread.h b/src/util/inc/tthread.h new file mode 100644 index 0000000000000000000000000000000000000000..7443ad706dcbef529d857fe823cddd0cc1efbdd3 --- /dev/null +++ b/src/util/inc/tthread.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef TDENGINE_TTHREAD_H +#define TDENGINE_TTHREAD_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "os.h" +#include "taosdef.h" + +// create new thread +pthread_t* taosCreateThread( void *(*__start_routine) (void *), void* param); +// destory thread +bool taosDestoryThread(pthread_t* pthread); +// thread running return true +bool taosThreadRunning(pthread_t* pthread); + +#ifdef __cplusplus +} +#endif + +#endif // TDENGINE_TTHREAD_H diff --git a/src/util/src/hash.c b/src/util/src/hash.c index a22ce34a0e3030f409948cfcf3e739335d6417cb..6577a0a0f4710951cf240f792d68f1afb2d37569 100644 --- a/src/util/src/hash.c +++ b/src/util/src/hash.c @@ -741,17 +741,19 @@ void taosHashTableResize(SHashObj *pHashObj) { } SHashNode *doCreateHashNode(const void *key, size_t keyLen, const void *pData, size_t dsize, uint32_t hashVal) { - SHashNode *pNewNode = calloc(1, sizeof(SHashNode) + keyLen + dsize); + SHashNode *pNewNode = malloc(sizeof(SHashNode) + keyLen + dsize); if (pNewNode == NULL) { uError("failed to allocate memory, reason:%s", strerror(errno)); return NULL; } - pNewNode->keyLen = (uint32_t)keyLen; + pNewNode->keyLen = (uint32_t)keyLen; pNewNode->hashVal = hashVal; pNewNode->dataLen = (uint32_t) dsize; - pNewNode->count = 1; + pNewNode->count = 1; + pNewNode->removed = 0; + pNewNode->next = NULL; memcpy(GET_HASH_NODE_DATA(pNewNode), pData, dsize); memcpy(GET_HASH_NODE_KEY(pNewNode), key, keyLen); diff --git a/src/util/src/tarray.c b/src/util/src/tarray.c index 2d6c513cb57ce1d524a1fb69df68702e624ede7b..007ce0682974d06bf506a82d8bbbc809092eb9e4 100644 --- a/src/util/src/tarray.c +++ b/src/util/src/tarray.c @@ -24,11 +24,12 @@ void* taosArrayInit(size_t size, size_t elemSize) { size = TARRAY_MIN_SIZE; } - SArray* pArray = calloc(1, sizeof(SArray)); + SArray* pArray = malloc(sizeof(SArray)); if (pArray == NULL) { return NULL; } + pArray->size = 0; pArray->pData = calloc(size, elemSize); if (pArray->pData == NULL) { free(pArray); diff --git a/src/util/src/tcache.c b/src/util/src/tcache.c index 6665c25a90a7fcb0db83766b88c9c9c7fe047fbf..589d3d4fa57c42b472319673a72d2e7ab599689f 100644 --- a/src/util/src/tcache.c +++ b/src/util/src/tcache.c @@ -505,7 +505,8 @@ void taosCacheRelease(SCacheObj *pCacheObj, void **data, bool _remove) { typedef struct SHashTravSupp { SCacheObj* pCacheObj; int64_t time; - __cache_free_fn_t fp; + __cache_trav_fn_t fp; + void* param1; } SHashTravSupp; static bool travHashTableEmptyFn(void* param, void* data) { @@ -667,17 +668,17 @@ bool travHashTableFn(void* param, void* data) { } if (ps->fp) { - (ps->fp)(pNode->data); + (ps->fp)(pNode->data, ps->param1); } // do not remove element in hash table return true; } -static void doCacheRefresh(SCacheObj* pCacheObj, int64_t time, __cache_free_fn_t fp) { +static void doCacheRefresh(SCacheObj* pCacheObj, int64_t time, __cache_trav_fn_t fp, void* param1) { assert(pCacheObj != NULL); - SHashTravSupp sup = {.pCacheObj = pCacheObj, .fp = fp, .time = time}; + SHashTravSupp sup = {.pCacheObj = pCacheObj, .fp = fp, .time = time, .param1 = param1}; taosHashCondTraverse(pCacheObj->pHashTable, travHashTableFn, &sup); } @@ -748,7 +749,7 @@ void* taosCacheTimedRefresh(void *handle) { // refresh data in hash table if (elemInHash > 0) { int64_t now = taosGetTimestampMs(); - doCacheRefresh(pCacheObj, now, NULL); + doCacheRefresh(pCacheObj, now, NULL, NULL); } taosTrashcanEmpty(pCacheObj, false); @@ -766,13 +767,13 @@ void* taosCacheTimedRefresh(void *handle) { return NULL; } -void taosCacheRefresh(SCacheObj *pCacheObj, __cache_free_fn_t fp) { +void taosCacheRefresh(SCacheObj *pCacheObj, __cache_trav_fn_t fp, void* param1) { if (pCacheObj == NULL) { return; } int64_t now = taosGetTimestampMs(); - doCacheRefresh(pCacheObj, now, fp); + doCacheRefresh(pCacheObj, now, fp, param1); } void taosStopCacheRefreshWorker(void) { diff --git a/src/util/src/tcompare.c b/src/util/src/tcompare.c index ab65965eebaec4a6706d5cc5c5ed54fc263c2f8f..179fbd05a5a8f5ddfb28b68130f87e26ed4e522f 100644 --- a/src/util/src/tcompare.c +++ b/src/util/src/tcompare.c @@ -359,6 +359,14 @@ int32_t compareStrPatternComp(const void* pLeft, const void* pRight) { 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) { size_t sz = varDataLen(pRight); char *pattern = malloc(sz + 1); @@ -458,7 +466,9 @@ __compar_fn_t getComparFunc(int32_t type, int32_t optr) { case TSDB_DATA_TYPE_DOUBLE: comparFn = compareDoubleVal; break; case TSDB_DATA_TYPE_BINARY: { 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 */ comparFn = compareStrPatternComp; } else if (optr == TSDB_RELATION_IN) { @@ -472,7 +482,9 @@ __compar_fn_t getComparFunc(int32_t type, int32_t optr) { case TSDB_DATA_TYPE_NCHAR: { if (optr == TSDB_RELATION_MATCH) { - comparFn = compareStrRegexComp; + comparFn = compareStrRegexCompMatch; + } else if (optr == TSDB_RELATION_NMATCH) { + comparFn = compareStrRegexCompNMatch; } else if (optr == TSDB_RELATION_LIKE) { comparFn = compareWStrPatternComp; } else if (optr == TSDB_RELATION_IN) { diff --git a/src/util/src/terror.c b/src/util/src/terror.c index 8fb39cd1702fe670e44f2e0db1639a0f48ab5ab0..e3d022a6b0a4a929b6c06b2c305fb71b6980a865 100644 --- a/src/util/src/terror.c +++ b/src/util/src/terror.c @@ -116,6 +116,9 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TSC_DUP_COL_NAMES, "duplicated column nam TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_TAG_LENGTH, "Invalid tag length") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_COLUMN_LENGTH, "Invalid column length") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_DUP_TAG_NAMES, "duplicated tag names") +TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_JSON, "Invalid JSON format") +TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_JSON_TYPE, "Invalid JSON data type") +TAOS_DEFINE_ERROR(TSDB_CODE_TSC_VALUE_OUT_OF_RANGE, "Value out of range") // mnode TAOS_DEFINE_ERROR(TSDB_CODE_MND_MSG_NOT_PROCESSED, "Message not processed") diff --git a/src/util/src/tlosertree.c b/src/util/src/tlosertree.c index e793548407ad37e2021fdba7db106db3a48fcaf0..0f104c4b63a36880a79ad564a0f837f9b09e7819 100644 --- a/src/util/src/tlosertree.c +++ b/src/util/src/tlosertree.c @@ -90,12 +90,13 @@ void tLoserTreeAdjust(SLoserTreeInfo* pTree, int32_t idx) { SLoserTreeNode kLeaf = pTree->pNode[idx]; while (parentId > 0) { - if (pTree->pNode[parentId].index == -1) { + SLoserTreeNode* pCur = &pTree->pNode[parentId]; + if (pCur->index == -1) { pTree->pNode[parentId] = kLeaf; return; } - int32_t ret = pTree->comparFn(&pTree->pNode[parentId], &kLeaf, pTree->param); + int32_t ret = pTree->comparFn(pCur, &kLeaf, pTree->param); if (ret < 0) { SLoserTreeNode t = pTree->pNode[parentId]; pTree->pNode[parentId] = kLeaf; diff --git a/src/util/src/tthread.c b/src/util/src/tthread.c new file mode 100644 index 0000000000000000000000000000000000000000..043b2de2f241297d209041294428dde2c55e974e --- /dev/null +++ b/src/util/src/tthread.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include "os.h" +#include "tthread.h" +#include "tglobal.h" +#include "taosdef.h" +#include "tutil.h" +#include "tulog.h" +#include "taoserror.h" + +// create new thread +pthread_t* taosCreateThread( void *(*__start_routine) (void *), void* param) { + pthread_t* pthread = (pthread_t*)malloc(sizeof(pthread_t)); + pthread_attr_t thattr; + pthread_attr_init(&thattr); + pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE); + int32_t ret = pthread_create(pthread, &thattr, __start_routine, param); + pthread_attr_destroy(&thattr); + + if (ret != 0) { + free(pthread); + return NULL; + } + return pthread; +} + +// destory thread +bool taosDestoryThread(pthread_t* pthread) { + if(pthread == NULL) return false; + if(taosThreadRunning(pthread)) { + pthread_cancel(*pthread); + pthread_join(*pthread, NULL); + } + + free(pthread); + return true; +} + +// thread running return true +bool taosThreadRunning(pthread_t* pthread) { + if(pthread == NULL) return false; + int ret = pthread_kill(*pthread, 0); + if(ret == ESRCH) + return false; + if(ret == EINVAL) + return false; + // alive + return true; +} diff --git a/src/util/src/ttokenizer.c b/src/util/src/ttokenizer.c index 04f2d7fc04cafb5514e4f7df1e6063cad9c096da..289c4a6ef5d5db1a04fdb33985ed4de959375f8d 100644 --- a/src/util/src/ttokenizer.c +++ b/src/util/src/ttokenizer.c @@ -195,6 +195,7 @@ static SKeyword keywordTable[] = { {"INITIALLY", TK_INITIALLY}, {"INSTEAD", TK_INSTEAD}, {"MATCH", TK_MATCH}, + {"NMATCH", TK_NMATCH}, {"KEY", TK_KEY}, {"OF", TK_OF}, {"RAISE", TK_RAISE}, diff --git a/src/vnode/src/vnodeMain.c b/src/vnode/src/vnodeMain.c index f826c1aecd336a0eedeb3f02df0a7acc61895bb2..c823880ae2028c4bcfe26dbfc5cd60af62443722 100644 --- a/src/vnode/src/vnodeMain.c +++ b/src/vnode/src/vnodeMain.c @@ -560,5 +560,10 @@ static int32_t vnodeProcessTsdbStatus(void *arg, int32_t status, int32_t eno) { return vnodeSaveVersion(pVnode); } + // timer thread callback + if(status == TSDB_STATUS_COMMIT_NOBLOCK) { + qSolveCommitNoBlock(pVnode->tsdb, pVnode->qMgmt); + } + return 0; } diff --git a/tests/connectorTest/C#Test/nanosupport/TDengineDriver.cs b/tests/connectorTest/C#Test/nanosupport/TDengineDriver.cs new file mode 100644 index 0000000000000000000000000000000000000000..e6c3a598adc0bc4bcf5ea84953f649b418199555 --- /dev/null +++ b/tests/connectorTest/C#Test/nanosupport/TDengineDriver.cs @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +namespace TDengineDriver +{ + enum TDengineDataType + { + TSDB_DATA_TYPE_NULL = 0, // 1 bytes + TSDB_DATA_TYPE_BOOL = 1, // 1 bytes + TSDB_DATA_TYPE_TINYINT = 2, // 1 bytes + TSDB_DATA_TYPE_SMALLINT = 3, // 2 bytes + TSDB_DATA_TYPE_INT = 4, // 4 bytes + TSDB_DATA_TYPE_BIGINT = 5, // 8 bytes + TSDB_DATA_TYPE_FLOAT = 6, // 4 bytes + TSDB_DATA_TYPE_DOUBLE = 7, // 8 bytes + TSDB_DATA_TYPE_BINARY = 8, // string + TSDB_DATA_TYPE_TIMESTAMP = 9,// 8 bytes + TSDB_DATA_TYPE_NCHAR = 10, // unicode string + TSDB_DATA_TYPE_UTINYINT = 11,// 1 byte + TSDB_DATA_TYPE_USMALLINT= 12,// 2 bytes + TSDB_DATA_TYPE_UINT = 13, // 4 bytes + TSDB_DATA_TYPE_UBIGINT= 14 // 8 bytes + } + + enum TDengineInitOption + { + TSDB_OPTION_LOCALE = 0, + TSDB_OPTION_CHARSET = 1, + TSDB_OPTION_TIMEZONE = 2, + TDDB_OPTION_CONFIGDIR = 3, + TDDB_OPTION_SHELL_ACTIVITY_TIMER = 4 + } + + class TDengineMeta + { + public string name; + public short size; + public byte type; + public string TypeName() + { + switch ((TDengineDataType)type) + { + case TDengineDataType.TSDB_DATA_TYPE_BOOL: + return "BOOL"; + case TDengineDataType.TSDB_DATA_TYPE_TINYINT: + return "TINYINT"; + case TDengineDataType.TSDB_DATA_TYPE_SMALLINT: + return "SMALLINT"; + case TDengineDataType.TSDB_DATA_TYPE_INT: + return "INT"; + case TDengineDataType.TSDB_DATA_TYPE_BIGINT: + return "BIGINT"; + case TDengineDataType.TSDB_DATA_TYPE_UTINYINT: + return "TINYINT UNSIGNED"; + case TDengineDataType.TSDB_DATA_TYPE_USMALLINT: + return "SMALLINT UNSIGNED"; + case TDengineDataType.TSDB_DATA_TYPE_UINT: + return "INT UNSIGNED"; + case TDengineDataType.TSDB_DATA_TYPE_UBIGINT: + return "BIGINT UNSIGNED"; + case TDengineDataType.TSDB_DATA_TYPE_FLOAT: + return "FLOAT"; + case TDengineDataType.TSDB_DATA_TYPE_DOUBLE: + return "DOUBLE"; + case TDengineDataType.TSDB_DATA_TYPE_BINARY: + return "STRING"; + case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP: + return "TIMESTAMP"; + case TDengineDataType.TSDB_DATA_TYPE_NCHAR: + return "NCHAR"; + default: + return "undefine"; + } + } + } + + class TDengine + { + public const int TSDB_CODE_SUCCESS = 0; + + [DllImport("taos", EntryPoint = "taos_init", CallingConvention = CallingConvention.Cdecl)] + static extern public void Init(); + + [DllImport("taos", EntryPoint = "taos_cleanup", CallingConvention = CallingConvention.Cdecl)] + static extern public void Cleanup(); + + [DllImport("taos", EntryPoint = "taos_options", CallingConvention = CallingConvention.Cdecl)] + static extern public void Options(int option, string value); + + [DllImport("taos", EntryPoint = "taos_connect", CallingConvention = CallingConvention.Cdecl)] + static extern public IntPtr Connect(string ip, string user, string password, string db, short port); + + [DllImport("taos", EntryPoint = "taos_errstr", CallingConvention = CallingConvention.Cdecl)] + static extern private IntPtr taos_errstr(IntPtr res); + static public string Error(IntPtr res) + { + IntPtr errPtr = taos_errstr(res); + return Marshal.PtrToStringAnsi(errPtr); + } + + [DllImport("taos", EntryPoint = "taos_errno", CallingConvention = CallingConvention.Cdecl)] + static extern public int ErrorNo(IntPtr res); + + [DllImport("taos", EntryPoint = "taos_query", CallingConvention = CallingConvention.Cdecl)] + static extern public IntPtr Query(IntPtr conn, string sqlstr); + + [DllImport("taos", EntryPoint = "taos_affected_rows", CallingConvention = CallingConvention.Cdecl)] + static extern public int AffectRows(IntPtr res); + + [DllImport("taos", EntryPoint = "taos_field_count", CallingConvention = CallingConvention.Cdecl)] + static extern public int FieldCount(IntPtr res); + + [DllImport("taos", EntryPoint = "taos_fetch_fields", CallingConvention = CallingConvention.Cdecl)] + static extern private IntPtr taos_fetch_fields(IntPtr res); + static public List FetchFields(IntPtr res) + { + const int fieldSize = 68; + + List metas = new List(); + if (res == IntPtr.Zero) + { + return metas; + } + + int fieldCount = FieldCount(res); + IntPtr fieldsPtr = taos_fetch_fields(res); + + for (int i = 0; i < fieldCount; ++i) + { + int offset = i * fieldSize; + + TDengineMeta meta = new TDengineMeta(); + meta.name = Marshal.PtrToStringAnsi(fieldsPtr + offset); + meta.type = Marshal.ReadByte(fieldsPtr + offset + 65); + meta.size = Marshal.ReadInt16(fieldsPtr + offset + 66); + metas.Add(meta); + } + + return metas; + } + + [DllImport("taos", EntryPoint = "taos_fetch_row", CallingConvention = CallingConvention.Cdecl)] + static extern public IntPtr FetchRows(IntPtr res); + + [DllImport("taos", EntryPoint = "taos_free_result", CallingConvention = CallingConvention.Cdecl)] + static extern public IntPtr FreeResult(IntPtr res); + + [DllImport("taos", EntryPoint = "taos_close", CallingConvention = CallingConvention.Cdecl)] + static extern public int Close(IntPtr taos); + //get precisionin parameter restultset + [DllImport("taos", EntryPoint = "taos_result_precision", CallingConvention = CallingConvention.Cdecl)] + static extern public int ResultPrecision(IntPtr taos); + } +} diff --git a/tests/connectorTest/C#Test/nanosupport/nanotest.cs b/tests/connectorTest/C#Test/nanosupport/nanotest.cs new file mode 100644 index 0000000000000000000000000000000000000000..b9eaefef8c740f8196a715282c8c28ffd79bbdac --- /dev/null +++ b/tests/connectorTest/C#Test/nanosupport/nanotest.cs @@ -0,0 +1,502 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +using System; +using System.Text; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Collections; +namespace TDengineDriver +{ + class TDengineNanoTest + { + //connect parameters + private string host="localhost"; + private string configDir="/etc/taos"; + private string user="root"; + private string password="taosdata"; + private short port = 0; + + //sql parameters + private string dbName; + private string tbName; + private string precision; + + private bool isInsertData; + private bool isQueryData; + + private long tableCount; + private long totalRows; + private long batchRows; + private long beginTimestamp = 1551369600000L; + + private IntPtr conn = IntPtr.Zero; + private long rowsInserted = 0; + + static void Main(string[] args) + { + TDengineNanoTest tester = new TDengineNanoTest(); + //tester.ReadArgument(args); + + tester.InitTDengine(); + tester.ConnectTDengine(); + tester.execute("reset query cache"); + tester.execute("drop database if exists db"); + tester.execute("create database db precision 'ns'"); + tester.executeQuery("show databases;"); + //tester.checkData(0,16,"ns"); + tester.execute("use db"); + + Console.WriteLine("testing nanosecond support in 1st timestamp"); + tester.execute("create table tb (ts timestamp, speed int)"); + tester.execute("insert into tb values('2021-06-10 0:00:00.100000001', 1);"); + tester.execute("insert into tb values(1623254400150000000, 2);"); + tester.execute("import into tb values(1623254400300000000, 3);"); + tester.execute("import into tb values(1623254400299999999, 4);"); + tester.execute("insert into tb values(1623254400300000001, 5);"); + tester.execute("insert into tb values(1623254400999999999, 7);"); + tester.executeQuery("select * from tb;"); + + Console.WriteLine("expect data is "); + + tester.executeQuery("select * from tb;"); + + // Console.WriteLine("expected is : {0}", width); + // tdSql.checkData(0,0,"2021-06-10 0:00:00.100000001"); + // tdSql.checkData(1,0,"2021-06-10 0:00:00.150000000"); + // tdSql.checkData(2,0,"2021-06-10 0:00:00.299999999"); + // tdSql.checkData(3,1,3); + // tdSql.checkData(4,1,5); + // tdSql.checkData(5,1,7); + // tdSql.checkRows(6); + + tester.executeQuery("select count(*) from tb where ts > 1623254400100000000 and ts < 1623254400100000002;"); + Console.WriteLine("expected is : 1 " ); + tester.executeQuery("select count(*) from tb where ts > '2021-06-10 0:00:00.100000001' and ts < '2021-06-10 0:00:00.160000000';"); + Console.WriteLine("expected is : 1 " ); + + tester.executeQuery("select count(*) from tb where ts > 1623254400100000000 and ts < 1623254400150000000;"); + Console.WriteLine("expected is : 1 " ); + tester.executeQuery("select count(*) from tb where ts > '2021-06-10 0:00:00.100000000' and ts < '2021-06-10 0:00:00.150000000';"); + Console.WriteLine("expected is : 1 " ); + + tester.executeQuery("select count(*) from tb where ts > 1623254400400000000;"); + Console.WriteLine("expected is : 1 " ); + tester.executeQuery("select count(*) from tb where ts < '2021-06-10 00:00:00.400000000';"); + Console.WriteLine("expected is : 5 " ); + + tester.executeQuery("select count(*) from tb where ts > now + 400000000b;"); + Console.WriteLine("expected is : 0 " ); + + tester.executeQuery("select count(*) from tb where ts >= '2021-06-10 0:00:00.100000001';"); + Console.WriteLine("expected is : 6 " ); + + tester.executeQuery("select count(*) from tb where ts <= 1623254400300000000;"); + Console.WriteLine("expected is : 4 " ); + + tester.executeQuery("select count(*) from tb where ts = '2021-06-10 0:00:00.000000000';"); + Console.WriteLine("expected is : 0 " ); + + tester.executeQuery("select count(*) from tb where ts = 1623254400150000000;"); + Console.WriteLine("expected is : 1 " ); + + tester.executeQuery("select count(*) from tb where ts = '2021-06-10 0:00:00.100000001';"); + Console.WriteLine("expected is : 1 " ); + + tester.executeQuery("select count(*) from tb where ts between 1623254400000000000 and 1623254400400000000;"); + Console.WriteLine("expected is : 5 " ); + + tester.executeQuery("select count(*) from tb where ts between '2021-06-10 0:00:00.299999999' and '2021-06-10 0:00:00.300000001';"); + Console.WriteLine("expected is : 3 " ); + + tester.executeQuery("select avg(speed) from tb interval(5000000000b);"); + Console.WriteLine("expected is : 1 " ); + + tester.executeQuery("select avg(speed) from tb interval(100000000b)"); + Console.WriteLine("expected is : 4 " ); + + // tdSql.error("select avg(speed) from tb interval(1b);") + // tdSql.error("select avg(speed) from tb interval(999b);") + + tester.executeQuery("select avg(speed) from tb interval(1000b);"); + Console.WriteLine("expected is : 5 rows " ); + + tester.executeQuery("select avg(speed) from tb interval(1u);"); + Console.WriteLine("expected is : 5 rows " ); + + tester.executeQuery("select avg(speed) from tb interval(100000000b) sliding (100000000b);"); + Console.WriteLine("expected is : 4 rows " ); + + tester.executeQuery("select last(*) from tb"); + Console.WriteLine("expected is :1623254400999999999 " ); + + // tdSql.checkData(0,0, "2021-06-10 0:00:00.999999999") + // tdSql.checkData(0,0, 1623254400999999999) + + tester.executeQuery("select first(*) from tb"); + Console.WriteLine("expected is : 1623254400100000001" ); + // tdSql.checkData(0,0, 1623254400100000001); + // tdSql.checkData(0,0, "2021-06-10 0:00:00.100000001"); + + tester.execute("insert into tb values(now + 500000000b, 6);"); + tester.executeQuery("select * from tb;"); + // tdSql.checkRows(7); + + tester.execute("create table tb2 (ts timestamp, speed int, ts2 timestamp);"); + tester.execute("insert into tb2 values('2021-06-10 0:00:00.100000001', 1, '2021-06-11 0:00:00.100000001');"); + tester.execute("insert into tb2 values(1623254400150000000, 2, 1623340800150000000);"); + tester.execute("import into tb2 values(1623254400300000000, 3, 1623340800300000000);"); + tester.execute("import into tb2 values(1623254400299999999, 4, 1623340800299999999);"); + tester.execute("insert into tb2 values(1623254400300000001, 5, 1623340800300000001);"); + tester.execute("insert into tb2 values(1623254400999999999, 7, 1623513600999999999);"); + + tester.executeQuery("select * from tb2;"); + // tdSql.checkData(0,0,"2021-06-10 0:00:00.100000001"); + // tdSql.checkData(1,0,"2021-06-10 0:00:00.150000000"); + // tdSql.checkData(2,1,4); + // tdSql.checkData(3,1,3); + // tdSql.checkData(4,2,"2021-06-11 00:00:00.300000001"); + // tdSql.checkData(5,2,"2021-06-13 00:00:00.999999999"); + // tdSql.checkRows(6); + tester.executeQuery("select count(*) from tb2 where ts2 > 1623340800000000000 and ts2 < 1623340800150000000;"); + Console.WriteLine("expected is : 1 " ); + // tdSql.checkData(0,0,1); + + tester.executeQuery("select count(*) from tb2 where ts2 > '2021-06-11 0:00:00.100000000' and ts2 < '2021-06-11 0:00:00.100000002';"); + Console.WriteLine("expected is : 1 " ); + // tdSql.checkData(0,0,1); + + tester.executeQuery("select count(*) from tb2 where ts2 > 1623340800500000000;"); + Console.WriteLine("expected is : 1 " ); + // tdSql.checkData(0,0,1); + tester.executeQuery("select count(*) from tb2 where ts2 < '2021-06-11 0:00:00.400000000';"); + Console.WriteLine("expected is : 5 " ); + // tdSql.checkData(0,0,5); + + tester.executeQuery("select count(*) from tb2 where ts2 > now + 400000000b;"); + Console.WriteLine("expected is : 0 " ); + // tdSql.checkRows(0); + + tester.executeQuery("select count(*) from tb2 where ts2 >= '2021-06-11 0:00:00.100000001';"); + Console.WriteLine("expected is : 6 " ); + // tdSql.checkData(0,0,6); + + tester.executeQuery("select count(*) from tb2 where ts2 <= 1623340800400000000;"); + Console.WriteLine("expected is : 5 " ); + // tdSql.checkData(0,0,5); + + tester.executeQuery("select count(*) from tb2 where ts2 = '2021-06-11 0:00:00.000000000';"); + Console.WriteLine("expected is : 0 " ); + // tdSql.checkRows(0); + + tester.executeQuery("select count(*) from tb2 where ts2 = '2021-06-11 0:00:00.300000001';"); + Console.WriteLine("expected is : 1 " ); + // tdSql.checkData(0,0,1); + + tester.executeQuery("select count(*) from tb2 where ts2 = 1623340800300000001;"); + Console.WriteLine("expected is : 1 " ); + // tdSql.checkData(0,0,1); + + tester.executeQuery("select count(*) from tb2 where ts2 between 1623340800000000000 and 1623340800450000000;"); + Console.WriteLine("expected is : 5 " ); + // tdSql.checkData(0,0,5); + + tester.executeQuery("select count(*) from tb2 where ts2 between '2021-06-11 0:00:00.299999999' and '2021-06-11 0:00:00.300000001';"); + Console.WriteLine("expected is : 3 " ); + // tdSql.checkData(0,0,3); + + tester.executeQuery("select count(*) from tb2 where ts2 <> 1623513600999999999;"); + Console.WriteLine("expected is : 5 " ); + // tdSql.checkData(0,0,5); + + tester.executeQuery("select count(*) from tb2 where ts2 <> '2021-06-11 0:00:00.100000001';"); + Console.WriteLine("expected is : 5 " ); + // tdSql.checkData(0,0,5); + + tester.executeQuery("select count(*) from tb2 where ts2 <> '2021-06-11 0:00:00.100000000';"); + Console.WriteLine("expected is : 6 " ); + // tdSql.checkData(0,0,6); + + tester.executeQuery("select count(*) from tb2 where ts2 != 1623513600999999999;"); + Console.WriteLine("expected is : 5 " ); + // tdSql.checkData(0,0,5); + + tester.executeQuery("select count(*) from tb2 where ts2 != '2021-06-11 0:00:00.100000001';"); + Console.WriteLine("expected is : 5 " ); + // tdSql.checkData(0,0,5); + + tester.executeQuery("select count(*) from tb2 where ts2 != '2021-06-11 0:00:00.100000000';"); + Console.WriteLine("expected is : 6 " ); + // tdSql.checkData(0,0,6); + + tester.execute("insert into tb2 values(now + 500000000b, 6, now +2d);"); + tester.executeQuery("select * from tb2;"); + Console.WriteLine("expected is : 7 rows" ); + // tdSql.checkRows(7); + + // tdLog.debug("testing ill nanosecond format handling"); + tester.execute("create table tb3 (ts timestamp, speed int);"); + // tdSql.error("insert into tb3 values(16232544001500000, 2);"); + tester.execute("insert into tb3 values('2021-06-10 0:00:00.123456', 2);"); + tester.executeQuery("select * from tb3 where ts = '2021-06-10 0:00:00.123456000';"); + // tdSql.checkRows(1); + Console.WriteLine("expected is : 1 rows " ); + + tester.execute("insert into tb3 values('2021-06-10 0:00:00.123456789000', 2);"); + tester.executeQuery("select * from tb3 where ts = '2021-06-10 0:00:00.123456789';"); + // tdSql.checkRows(1); + Console.WriteLine("expected is : 1 rows " ); + + // check timezone support + Console.WriteLine("nsdb" ); + tester.execute("drop database if exists nsdb;"); + tester.execute("create database nsdb precision 'ns';"); + tester.execute("use nsdb;"); + tester.execute("create stable st (ts timestamp ,speed float ) tags(time timestamp ,id int);"); + tester.execute("insert into tb1 using st tags('2021-06-10 0:00:00.123456789' , 1 ) values('2021-06-10T0:00:00.123456789+07:00' , 1.0);" ); + tester.executeQuery("select first(*) from tb1;"); + Console.WriteLine("expected is : 1623258000123456789 " ); + // tdSql.checkData(0,0,1623258000123456789); + + + + Console.WriteLine("usdb" ); + tester.execute("create database usdb precision 'us';"); + tester.execute("use usdb;"); + tester.execute("create stable st (ts timestamp ,speed float ) tags(time timestamp ,id int);"); + tester.execute("insert into tb1 using st tags('2021-06-10 0:00:00.123456' , 1 ) values('2021-06-10T0:00:00.123456+07:00' , 1.0);" ); + tester.executeQuery("select first(*) from tb1;"); + + Console.WriteLine("expected is : 1623258000123456 " ); + + Console.WriteLine("msdb" ); + tester.execute("drop database if exists msdb;"); + tester.execute("create database msdb precision 'ms';"); + tester.execute("use msdb;"); + tester.execute("create stable st (ts timestamp ,speed float ) tags(time timestamp ,id int);"); + tester.execute("insert into tb1 using st tags('2021-06-10 0:00:00.123' , 1 ) values('2021-06-10T0:00:00.123+07:00' , 1.0);" ); + tester.executeQuery("select first(*) from tb1;"); + Console.WriteLine("expected is : 1623258000123 " ); + + + + tester.CloseConnection(); + tester.cleanup(); + + + } + + public void InitTDengine() + { + TDengine.Options((int)TDengineInitOption.TDDB_OPTION_CONFIGDIR, this.configDir); + TDengine.Options((int)TDengineInitOption.TDDB_OPTION_SHELL_ACTIVITY_TIMER, "60"); + Console.WriteLine("init..."); + TDengine.Init(); + Console.WriteLine("get connection starting..."); + } + + public void ConnectTDengine() + { + string db = ""; + this.conn = TDengine.Connect(this.host, this.user, this.password, db, this.port); + if (this.conn == IntPtr.Zero) + { + Console.WriteLine("connection failed: " + this.host); + ExitProgram(); + } + else + { + Console.WriteLine("[ OK ] Connection established."); + } + } + //EXECUTE SQL + public void execute(string sql) + { + DateTime dt1 = DateTime.Now; + IntPtr res = TDengine.Query(this.conn, sql.ToString()); + DateTime dt2 = DateTime.Now; + TimeSpan span = dt2 - dt1; + + if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0)) + { + Console.Write(sql.ToString() + " failure, "); + if (res != IntPtr.Zero) { + Console.Write("reason: " + TDengine.Error(res)); + } + Console.WriteLine(""); + ExitProgram(); + } + else + { + Console.WriteLine(sql.ToString() + " success"); + } + TDengine.FreeResult(res); + } + //EXECUTE QUERY + public void executeQuery(string sql) + { + + DateTime dt1 = DateTime.Now; + long queryRows = 0; + IntPtr res = TDengine.Query(conn, sql); + getPrecision(res); + if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0)) + { + Console.Write(sql.ToString() + " failure, "); + if (res != IntPtr.Zero) { + Console.Write("reason: " + TDengine.Error(res)); + } + Console.WriteLine(""); + ExitProgram(); + } + DateTime dt2 = DateTime.Now; + TimeSpan span = dt2 - dt1; + Console.WriteLine("[OK] time cost: " + span.ToString() + "ms, execute statement ====> " + sql.ToString()); + int fieldCount = TDengine.FieldCount(res); + + List metas = TDengine.FetchFields(res); + for (int j = 0; j < metas.Count; j++) + { + TDengineMeta meta = (TDengineMeta)metas[j]; + } + + IntPtr rowdata; + StringBuilder builder = new StringBuilder(); + while ((rowdata = TDengine.FetchRows(res)) != IntPtr.Zero) + { + queryRows++; + for (int fields = 0; fields < fieldCount; ++fields) + { + TDengineMeta meta = metas[fields]; + int offset = IntPtr.Size * fields; + IntPtr data = Marshal.ReadIntPtr(rowdata, offset); + + builder.Append("---"); + + if (data == IntPtr.Zero) + { + builder.Append("NULL"); + continue; + } + + switch ((TDengineDataType)meta.type) + { + case TDengineDataType.TSDB_DATA_TYPE_BOOL: + bool v1 = Marshal.ReadByte(data) == 0 ? false : true; + builder.Append(v1); + break; + case TDengineDataType.TSDB_DATA_TYPE_TINYINT: + byte v2 = Marshal.ReadByte(data); + builder.Append(v2); + break; + case TDengineDataType.TSDB_DATA_TYPE_SMALLINT: + short v3 = Marshal.ReadInt16(data); + builder.Append(v3); + break; + case TDengineDataType.TSDB_DATA_TYPE_INT: + int v4 = Marshal.ReadInt32(data); + builder.Append(v4); + break; + case TDengineDataType.TSDB_DATA_TYPE_BIGINT: + long v5 = Marshal.ReadInt64(data); + builder.Append(v5); + break; + case TDengineDataType.TSDB_DATA_TYPE_FLOAT: + float v6 = (float)Marshal.PtrToStructure(data, typeof(float)); + builder.Append(v6); + break; + case TDengineDataType.TSDB_DATA_TYPE_DOUBLE: + double v7 = (double)Marshal.PtrToStructure(data, typeof(double)); + builder.Append(v7); + break; + case TDengineDataType.TSDB_DATA_TYPE_BINARY: + string v8 = Marshal.PtrToStringAnsi(data); + builder.Append(v8); + break; + case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP: + long v9 = Marshal.ReadInt64(data); + builder.Append(v9); + break; + case TDengineDataType.TSDB_DATA_TYPE_NCHAR: + string v10 = Marshal.PtrToStringAnsi(data); + builder.Append(v10); + break; + } + } + builder.Append("---"); + + if (queryRows <= 10) + { + Console.WriteLine(builder.ToString()); + } + builder.Clear(); + } + + if (TDengine.ErrorNo(res) != 0) + { + Console.Write("Query is not complete, Error {0:G}", TDengine.ErrorNo(res), TDengine.Error(res)); + } + Console.WriteLine(""); + + TDengine.FreeResult(res); + + } + + public void CloseConnection() + { + if (this.conn != IntPtr.Zero) + { + TDengine.Close(this.conn); + Console.WriteLine("connection closed."); + } + } + + static void ExitProgram() + { + System.Environment.Exit(0); + } + + public void cleanup() + { + Console.WriteLine("clean up..."); + System.Environment.Exit(0); + } + + // method to get db precision + public void getPrecision(IntPtr res) + { + int psc=TDengine.ResultPrecision(res); + switch(psc) + { + case 0: + Console.WriteLine("db:[{0:G}]'s precision is {1:G}",this.dbName,"millisecond"); + break; + case 1: + Console.WriteLine("db:[{0:G}]'s precision is {1:G}",this.dbName,"microsecond"); + break; + case 2: + Console.WriteLine("db:[{0:G}]'s precision is {1:G}",this.dbName,"nanosecond"); + break; + } + + } + + // public void checkData(int x ,int y , long ts ){ + + // } + + } +} + diff --git a/tests/connectorTest/nodejsTest/nanosupport/nanosecondTest.js b/tests/connectorTest/nodejsTest/nanosupport/nanosecondTest.js new file mode 100644 index 0000000000000000000000000000000000000000..11812ac84b91d5c639a3b3bd73c8b81838c5cc23 --- /dev/null +++ b/tests/connectorTest/nodejsTest/nanosupport/nanosecondTest.js @@ -0,0 +1,290 @@ +const taos = require('td2.0-connector'); +var conn = taos.connect({host:"localhost", user:"root", password:"taosdata", config:"/etc/taos",port:6030}) +var c1 = conn.cursor(); + + +function checkData(sql,row,col,data){ + + + console.log(sql) + c1.execute(sql) + var d = c1.fetchall(); + let checkdata = d[row][col]; + if (checkdata == data) { + + console.log('check pass') + } + else{ + console.log('check failed') + console.log('checked is :',checkdata) + console.log("expected is :",data) + + + } +} + + +// nano basic case + +c1.execute('reset query cache') +c1.execute('drop database if exists db') +c1.execute('create database db precision "ns";') +c1.execute('use db'); +c1.execute('create table tb (ts timestamp, speed int)') +c1.execute('insert into tb values(\'2021-06-10 00:00:00.100000001\', 1);') +c1.execute('insert into tb values(1623254400150000000, 2);') +c1.execute('import into tb values(1623254400300000000, 3);') +c1.execute('import into tb values(1623254400299999999, 4);') +c1.execute('insert into tb values(1623254400300000001, 5);') +c1.execute('insert into tb values(1623254400999999999, 7);') +c1.execute('insert into tb values(1623254400123456789, 8);') +sql = 'select * from tb;' + +console.log('*******************************************') +console.log('this is area about checkdata result') +//check data about insert data +checkData(sql,0,0,'2021-06-10 00:00:00.100000001') +checkData(sql,1,0,'2021-06-10 00:00:00.123456789') +checkData(sql,2,0,'2021-06-10 00:00:00.150000000') +checkData(sql,3,0,'2021-06-10 00:00:00.299999999') +checkData(sql,4,0,'2021-06-10 00:00:00.300000000') +checkData(sql,5,0,'2021-06-10 00:00:00.300000001') +checkData(sql,6,0,'2021-06-10 00:00:00.999999999') +checkData(sql,0,1,1) +checkData(sql,1,1,8) +checkData(sql,2,1,2) +checkData(sql,5,1,5) + + + +// us basic case + +c1.execute('reset query cache') +c1.execute('drop database if exists usdb') +c1.execute('create database usdb precision "us";') +c1.execute('use usdb'); +c1.execute('create table tb (ts timestamp, speed int)') +c1.execute('insert into tb values(\'2021-06-10 00:00:00.100001\', 1);') +c1.execute('insert into tb values(1623254400150000, 2);') +c1.execute('import into tb values(1623254400300000, 3);') +c1.execute('import into tb values(1623254400299999, 4);') +c1.execute('insert into tb values(1623254400300001, 5);') +c1.execute('insert into tb values(1623254400999999, 7);') +c1.execute('insert into tb values(1623254400123789, 8);') +sql = 'select * from tb;' + +console.log('*******************************************') + +//check data about insert data +checkData(sql,0,0,'2021-06-10 00:00:00.100001') +checkData(sql,1,0,'2021-06-10 00:00:00.123789') +checkData(sql,2,0,'2021-06-10 00:00:00.150000') +checkData(sql,3,0,'2021-06-10 00:00:00.299999') +checkData(sql,4,0,'2021-06-10 00:00:00.300000') +checkData(sql,5,0,'2021-06-10 00:00:00.300001') +checkData(sql,6,0,'2021-06-10 00:00:00.999999') +checkData(sql,0,1,1) +checkData(sql,1,1,8) +checkData(sql,2,1,2) +checkData(sql,5,1,5) + +console.log('*******************************************') + +// ms basic case + +c1.execute('reset query cache') +c1.execute('drop database if exists msdb') +c1.execute('create database msdb precision "ms";') +c1.execute('use msdb'); +c1.execute('create table tb (ts timestamp, speed int)') +c1.execute('insert into tb values(\'2021-06-10 00:00:00.101\', 1);') +c1.execute('insert into tb values(1623254400150, 2);') +c1.execute('import into tb values(1623254400300, 3);') +c1.execute('import into tb values(1623254400299, 4);') +c1.execute('insert into tb values(1623254400301, 5);') +c1.execute('insert into tb values(1623254400789, 7);') +c1.execute('insert into tb values(1623254400999, 8);') +sql = 'select * from tb;' + +console.log('*******************************************') +console.log('this is area about checkdata result') +//check data about insert data +checkData(sql,0,0,'2021-06-10 00:00:00.101') +checkData(sql,1,0,'2021-06-10 00:00:00.150') +checkData(sql,2,0,'2021-06-10 00:00:00.299') +checkData(sql,3,0,'2021-06-10 00:00:00.300') +checkData(sql,4,0,'2021-06-10 00:00:00.301') +checkData(sql,5,0,'2021-06-10 00:00:00.789') +checkData(sql,6,0,'2021-06-10 00:00:00.999') +checkData(sql,0,1,1) +checkData(sql,1,1,2) +checkData(sql,2,1,4) +checkData(sql,5,1,7) + +console.log('*******************************************') + +// offfical query result to show +// console.log('this is area about fetch all data') +// var query = c1.query(sql) +// var promise = query.execute(); +// promise.then(function(result) { +// result.pretty(); +// }); + +console.log('*******************************************') +c1.execute('use db') + +sql2 = 'select count(*) from tb where ts > 1623254400100000000 and ts < 1623254400100000002;' +checkData(sql2,0,0,1) + +sql3 = 'select count(*) from tb where ts > \'2021-06-10 0:00:00.100000001\' and ts < \'2021-06-10 0:00:00.160000000\';' +checkData(sql3,0,0,2) + +sql4 = 'select count(*) from tb where ts > 1623254400100000000 and ts < 1623254400150000000;' +checkData(sql4,0,0,2) + +sql5 = 'select count(*) from tb where ts > \'2021-06-10 0:00:00.100000000\' and ts < \'2021-06-10 0:00:00.150000000\';' +checkData(sql5,0,0,2) + +sql6 = 'select count(*) from tb where ts > 1623254400400000000;' +checkData(sql6,0,0,1) + +sql7 = 'select count(*) from tb where ts < \'2021-06-10 00:00:00.400000000\';' +checkData(sql7,0,0,6) + +sql8 = 'select count(*) from tb where ts > now + 400000000b;' +c1.execute(sql8) + +sql9 = 'select count(*) from tb where ts >= \'2021-06-10 0:00:00.100000001\';' +checkData(sql9,0,0,7) + +sql10 = 'select count(*) from tb where ts <= 1623254400300000000;' +checkData(sql10,0,0,5) + +sql11 = 'select count(*) from tb where ts = \'2021-06-10 0:00:00.000000000\';' +c1.execute(sql11) + +sql12 = 'select count(*) from tb where ts = 1623254400150000000;' +checkData(sql12,0,0,1) + +sql13 = 'select count(*) from tb where ts = \'2021-06-10 0:00:00.100000001\';' +checkData(sql13,0,0,1) + +sql14 = 'select count(*) from tb where ts between 1623254400000000000 and 1623254400400000000;' +checkData(sql14,0,0,6) + +sql15 = 'select count(*) from tb where ts between \'2021-06-10 0:00:00.299999999\' and \'2021-06-10 0:00:00.300000001\';' +checkData(sql15,0,0,3) + +sql16 = 'select avg(speed) from tb interval(5000000000b);' +checkData(sql16,0,0,'2021-06-10 00:00:00.000000000') + +sql17 = 'select avg(speed) from tb interval(100000000b)' +checkData(sql17,0,1,3.6666666666666665) +checkData(sql17,1,1,4.000000000) + +checkData(sql17,2,0,'2021-06-10 00:00:00.300000000') +checkData(sql17,3,0,'2021-06-10 00:00:00.900000000') + +console.log("print break ") + +// sql18 = 'select avg(speed) from tb interval(999b)' +// c1.execute(sql18) + +console.log("print break2 ") +sql19 = 'select avg(speed) from tb interval(1u);' +checkData(sql19,2,1,2.000000000) +checkData(sql19,3,0,'2021-06-10 00:00:00.299999000') + +sql20 = 'select avg(speed) from tb interval(100000000b) sliding (100000000b);' +checkData(sql20,2,1,4.000000000) +checkData(sql20,3,0,'2021-06-10 00:00:00.900000000') + +sql21 = 'select last(*) from tb;' +checkData(sql21,0,0,'2021-06-10 00:00:00.999999999') + +sql22 = 'select first(*) from tb;' +checkData(sql22,0,0,'2021-06-10 00:00:00.100000001') + +// timezone support + +console.log('testing nanosecond support in other timestamps') + +c1.execute('create table tb2 (ts timestamp, speed int, ts2 timestamp);') +c1.execute('insert into tb2 values(\'2021-06-10 0:00:00.100000001\', 1, \'2021-06-11 0:00:00.100000001\');') +c1.execute('insert into tb2 values(1623254400150000000, 2, 1623340800150000000);') +c1.execute('import into tb2 values(1623254400300000000, 3, 1623340800300000000);') +c1.execute('import into tb2 values(1623254400299999999, 4, 1623340800299999999);') +c1.execute('insert into tb2 values(1623254400300000001, 5, 1623340800300000001);') +c1.execute('insert into tb2 values(1623254400999999999, 7, 1623513600999999999);') + +sql23 = 'select * from tb2;' +checkData(sql23,0,0,'2021-06-10 00:00:00.100000001') +checkData(sql23,1,0,'2021-06-10 00:00:00.150000000') +checkData(sql23,2,1,4) +checkData(sql23,3,1,3) +checkData(sql23,4,2,'2021-06-11 00:00:00.300000001') +checkData(sql23,5,2,'2021-06-13 00:00:00.999999999') + +sql24 = 'select count(*) from tb2 where ts2 >= \'2021-06-11 0:00:00.100000001\';' +checkData(sql24,0,0,6) + +sql25 = 'select count(*) from tb2 where ts2 <= 1623340800400000000;' +checkData(sql25,0,0,5) + +sql26 = 'select count(*) from tb2 where ts2 = \'2021-06-11 0:00:00.300000001\';' +checkData(sql26,0,0,1) + +sql27 = 'select count(*) from tb2 where ts2 = 1623340800300000001;' +checkData(sql27,0,0,1) + +sql28 = 'select count(*) from tb2 where ts2 between 1623340800000000000 and 1623340800450000000;' +checkData(sql28,0,0,5) + +sql29 = 'select count(*) from tb2 where ts2 between \'2021-06-11 0:00:00.299999999\' and \'2021-06-11 0:00:00.300000001\';' +checkData(sql29,0,0,3) + +sql30 = 'select count(*) from tb2 where ts2 <> 1623513600999999999;' +checkData(sql30,0,0,5) + +sql31 = 'select count(*) from tb2 where ts2 <> \'2021-06-11 0:00:00.100000001\';' +checkData(sql31,0,0,5) + +sql32 = 'select count(*) from tb2 where ts2 != 1623513600999999999;' +checkData(sql32,0,0,5) + +sql33 = 'select count(*) from tb2 where ts2 != \'2021-06-11 0:00:00.100000001\';' +checkData(sql33,0,0,5) + +c1.execute('insert into tb2 values(now + 500000000b, 6, now +2d);') + +sql34 = 'select count(*) from tb2;' +checkData(sql34,0,0,7) + + +// check timezone support + +c1.execute('use db;') +c1.execute('create stable st (ts timestamp ,speed float ) tags(time timestamp ,id int);') +c1.execute('insert into stb1 using st tags("2021-06-10 0:00:00.123456789" , 1 ) values("2021-06-10T0:00:00.123456789+07:00" , 1.0);' ) +sql35 = 'select first(*) from stb1;' +checkData(sql35,0,0,'2021-06-10 01:00:00.123456789') + +c1.execute('use usdb;') +c1.execute('create stable st (ts timestamp ,speed float ) tags(time timestamp ,id int);') +c1.execute('insert into stb1 using st tags("2021-06-10 0:00:00.123456" , 1 ) values("2021-06-10T0:00:00.123456+07:00" , 1.0);' ) +sql36 = 'select first(*) from stb1;' +checkData(sql36,0,0,'2021-06-10 01:00:00.123456') + +c1.execute('use msdb;') +c1.execute('create stable st (ts timestamp ,speed float ) tags(time timestamp ,id int);') +c1.execute('insert into stb1 using st tags("2021-06-10 0:00:00.123456" , 1 ) values("2021-06-10T0:00:00.123456+07:00" , 1.0);' ) +sql36 = 'select first(*) from stb1;' +checkData(sql36,0,0,'2021-06-10 01:00:00.123') + + + + + + + diff --git a/tests/connectorTest/nodejsTest/nodetaos/cinterface.js b/tests/connectorTest/nodejsTest/nodetaos/cinterface.js new file mode 100644 index 0000000000000000000000000000000000000000..03d27e5593ccb15d8ff47cd3c3dedba765d14fc1 --- /dev/null +++ b/tests/connectorTest/nodejsTest/nodetaos/cinterface.js @@ -0,0 +1,587 @@ +/** + * C Interface with TDengine Module + * @module CTaosInterface + */ + +const ref = require('ref-napi'); +const os = require('os'); +const ffi = require('ffi-napi'); +const ArrayType = require('ref-array-napi'); +const Struct = require('ref-struct-napi'); +const FieldTypes = require('./constants'); +const errors = require('./error'); +const TaosObjects = require('./taosobjects'); +const { NULL_POINTER } = require('ref-napi'); + +module.exports = CTaosInterface; + +function convertTimestamp(data, num_of_rows, nbytes = 0, offset = 0, precision = 0) { + data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset); + let res = []; + let currOffset = 0; + while (currOffset < data.length) { + let time = data.readInt64LE(currOffset); + currOffset += nbytes; + res.push(new TaosObjects.TaosTimestamp(time, precision)); + } + return res; +} +function convertBool(data, num_of_rows, nbytes = 0, offset = 0, precision = 0) { + data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset); + let res = new Array(data.length); + for (let i = 0; i < data.length; i++) { + if (data[i] == 0) { + res[i] = false; + } + else if (data[i] == 1) { + res[i] = true; + } + else if (data[i] == FieldTypes.C_BOOL_NULL) { + res[i] = null; + } + } + return res; +} +function convertTinyint(data, num_of_rows, nbytes = 0, offset = 0, precision = 0) { + data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset); + let res = []; + let currOffset = 0; + while (currOffset < data.length) { + let d = data.readIntLE(currOffset, 1); + res.push(d == FieldTypes.C_TINYINT_NULL ? null : d); + currOffset += nbytes; + } + return res; +} +function convertSmallint(data, num_of_rows, nbytes = 0, offset = 0, precision = 0) { + data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset); + let res = []; + let currOffset = 0; + while (currOffset < data.length) { + let d = data.readIntLE(currOffset, 2); + res.push(d == FieldTypes.C_SMALLINT_NULL ? null : d); + currOffset += nbytes; + } + return res; +} +function convertInt(data, num_of_rows, nbytes = 0, offset = 0, precision = 0) { + data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset); + let res = []; + let currOffset = 0; + while (currOffset < data.length) { + let d = data.readInt32LE(currOffset); + res.push(d == FieldTypes.C_INT_NULL ? null : d); + currOffset += nbytes; + } + return res; +} +function convertBigint(data, num_of_rows, nbytes = 0, offset = 0, precision = 0) { + data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset); + let res = []; + let currOffset = 0; + while (currOffset < data.length) { + let d = data.readInt64LE(currOffset); + res.push(d == FieldTypes.C_BIGINT_NULL ? null : BigInt(d)); + currOffset += nbytes; + } + return res; +} +function convertFloat(data, num_of_rows, nbytes = 0, offset = 0, precision = 0) { + data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset); + let res = []; + let currOffset = 0; + while (currOffset < data.length) { + let d = parseFloat(data.readFloatLE(currOffset).toFixed(5)); + res.push(isNaN(d) ? null : d); + currOffset += nbytes; + } + return res; +} +function convertDouble(data, num_of_rows, nbytes = 0, offset = 0, precision = 0) { + data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset); + let res = []; + let currOffset = 0; + while (currOffset < data.length) { + let d = parseFloat(data.readDoubleLE(currOffset).toFixed(16)); + res.push(isNaN(d) ? null : d); + currOffset += nbytes; + } + return res; +} + +function convertNchar(data, num_of_rows, nbytes = 0, offset = 0, precision = 0) { + data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset); + let res = []; + + let currOffset = 0; + while (currOffset < data.length) { + let len = data.readIntLE(currOffset, 2); + let dataEntry = data.slice(currOffset + 2, currOffset + len + 2); //one entry in a row under a column; + res.push(dataEntry.toString("utf-8")); + currOffset += nbytes; + } + return res; +} + +// Object with all the relevant converters from pblock data to javascript readable data +let convertFunctions = { + [FieldTypes.C_BOOL]: convertBool, + [FieldTypes.C_TINYINT]: convertTinyint, + [FieldTypes.C_SMALLINT]: convertSmallint, + [FieldTypes.C_INT]: convertInt, + [FieldTypes.C_BIGINT]: convertBigint, + [FieldTypes.C_FLOAT]: convertFloat, + [FieldTypes.C_DOUBLE]: convertDouble, + [FieldTypes.C_BINARY]: convertNchar, + [FieldTypes.C_TIMESTAMP]: convertTimestamp, + [FieldTypes.C_NCHAR]: convertNchar +} + +// Define TaosField structure +var char_arr = ArrayType(ref.types.char); +var TaosField = Struct({ + 'name': char_arr, +}); +TaosField.fields.name.type.size = 65; +TaosField.defineProperty('type', ref.types.char); +TaosField.defineProperty('bytes', ref.types.short); + + +/** + * + * @param {Object} config - Configuration options for the interface + * @return {CTaosInterface} + * @class CTaosInterface + * @classdesc The CTaosInterface is the interface through which Node.JS communicates data back and forth with TDengine. It is not advised to + * access this class directly and use it unless you understand what these functions do. + */ +function CTaosInterface(config = null, pass = false) { + ref.types.char_ptr = ref.refType(ref.types.char); + ref.types.void_ptr = ref.refType(ref.types.void); + ref.types.void_ptr2 = ref.refType(ref.types.void_ptr); + /*Declare a bunch of functions first*/ + /* Note, pointers to TAOS_RES, TAOS, are ref.types.void_ptr. The connection._conn buffer is supplied for pointers to TAOS * */ + + if ('win32' == os.platform()) { + taoslibname = 'taos'; + } else { + taoslibname = 'libtaos'; + } + this.libtaos = ffi.Library(taoslibname, { + 'taos_options': [ref.types.int, [ref.types.int, ref.types.void_ptr]], + 'taos_init': [ref.types.void, []], + //TAOS *taos_connect(char *ip, char *user, char *pass, char *db, int port) + 'taos_connect': [ref.types.void_ptr, [ref.types.char_ptr, ref.types.char_ptr, ref.types.char_ptr, ref.types.char_ptr, ref.types.int]], + //void taos_close(TAOS *taos) + 'taos_close': [ref.types.void, [ref.types.void_ptr]], + //int *taos_fetch_lengths(TAOS_RES *res); + 'taos_fetch_lengths': [ref.types.void_ptr, [ref.types.void_ptr]], + //int taos_query(TAOS *taos, char *sqlstr) + 'taos_query': [ref.types.void_ptr, [ref.types.void_ptr, ref.types.char_ptr]], + //int taos_affected_rows(TAOS_RES *res) + 'taos_affected_rows': [ref.types.int, [ref.types.void_ptr]], + //int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) + 'taos_fetch_block': [ref.types.int, [ref.types.void_ptr, ref.types.void_ptr]], + //int taos_num_fields(TAOS_RES *res); + 'taos_num_fields': [ref.types.int, [ref.types.void_ptr]], + //TAOS_ROW taos_fetch_row(TAOS_RES *res) + //TAOS_ROW is void **, but we set the return type as a reference instead to get the row + 'taos_fetch_row': [ref.refType(ref.types.void_ptr2), [ref.types.void_ptr]], + 'taos_print_row': [ref.types.int, [ref.types.char_ptr, ref.types.void_ptr, ref.types.void_ptr, ref.types.int]], + //int taos_result_precision(TAOS_RES *res) + 'taos_result_precision': [ref.types.int, [ref.types.void_ptr]], + //void taos_free_result(TAOS_RES *res) + 'taos_free_result': [ref.types.void, [ref.types.void_ptr]], + //int taos_field_count(TAOS *taos) + 'taos_field_count': [ref.types.int, [ref.types.void_ptr]], + //TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) + 'taos_fetch_fields': [ref.refType(TaosField), [ref.types.void_ptr]], + //int taos_errno(TAOS *taos) + 'taos_errno': [ref.types.int, [ref.types.void_ptr]], + //char *taos_errstr(TAOS *taos) + 'taos_errstr': [ref.types.char_ptr, [ref.types.void_ptr]], + //void taos_stop_query(TAOS_RES *res); + 'taos_stop_query': [ref.types.void, [ref.types.void_ptr]], + //char *taos_get_server_info(TAOS *taos); + 'taos_get_server_info': [ref.types.char_ptr, [ref.types.void_ptr]], + //char *taos_get_client_info(); + 'taos_get_client_info': [ref.types.char_ptr, []], + + // ASYNC + // void taos_query_a(TAOS *taos, char *sqlstr, void (*fp)(void *, TAOS_RES *, int), void *param) + 'taos_query_a': [ref.types.void, [ref.types.void_ptr, ref.types.char_ptr, ref.types.void_ptr, ref.types.void_ptr]], + // void taos_fetch_rows_a(TAOS_RES *res, void (*fp)(void *param, TAOS_RES *, int numOfRows), void *param); + 'taos_fetch_rows_a': [ref.types.void, [ref.types.void_ptr, ref.types.void_ptr, ref.types.void_ptr]], + + // Subscription + //TAOS_SUB *taos_subscribe(TAOS* taos, int restart, const char* topic, const char *sql, TAOS_SUBSCRIBE_CALLBACK fp, void *param, int interval) + 'taos_subscribe': [ref.types.void_ptr, [ref.types.void_ptr, ref.types.int, ref.types.char_ptr, ref.types.char_ptr, ref.types.void_ptr, ref.types.void_ptr, ref.types.int]], + // TAOS_RES *taos_consume(TAOS_SUB *tsub) + 'taos_consume': [ref.types.void_ptr, [ref.types.void_ptr]], + //void taos_unsubscribe(TAOS_SUB *tsub); + 'taos_unsubscribe': [ref.types.void, [ref.types.void_ptr]], + + // Continuous Query + //TAOS_STREAM *taos_open_stream(TAOS *taos, char *sqlstr, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row), + // int64_t stime, void *param, void (*callback)(void *)); + 'taos_open_stream': [ref.types.void_ptr, [ref.types.void_ptr, ref.types.char_ptr, ref.types.void_ptr, ref.types.int64, ref.types.void_ptr, ref.types.void_ptr]], + //void taos_close_stream(TAOS_STREAM *tstr); + 'taos_close_stream': [ref.types.void, [ref.types.void_ptr]] + + }); + if (pass == false) { + if (config == null) { + this._config = ref.alloc(ref.types.char_ptr, ref.NULL); + } + else { + try { + this._config = ref.allocCString(config); + } + catch (err) { + throw "Attribute Error: config is expected as a str"; + } + } + if (config != null) { + this.libtaos.taos_options(3, this._config); + } + this.libtaos.taos_init(); + } + return this; +} +CTaosInterface.prototype.config = function config() { + return this._config; +} +CTaosInterface.prototype.connect = function connect(host = null, user = "root", password = "taosdata", db = null, port = 0) { + let _host, _user, _password, _db, _port; + try { + _host = host != null ? ref.allocCString(host) : ref.NULL; + } + catch (err) { + throw "Attribute Error: host is expected as a str"; + } + try { + _user = ref.allocCString(user) + } + catch (err) { + throw "Attribute Error: user is expected as a str"; + } + try { + _password = ref.allocCString(password); + } + catch (err) { + throw "Attribute Error: password is expected as a str"; + } + try { + _db = db != null ? ref.allocCString(db) : ref.NULL; + } + catch (err) { + throw "Attribute Error: db is expected as a str"; + } + try { + _port = ref.alloc(ref.types.int, port); + } + catch (err) { + throw TypeError("port is expected as an int") + } + let connection = this.libtaos.taos_connect(_host, _user, _password, _db, _port); + if (ref.isNull(connection)) { + throw new errors.TDError('Failed to connect to TDengine'); + } + else { + console.log('Successfully connected to TDengine'); + } + return connection; +} +CTaosInterface.prototype.close = function close(connection) { + this.libtaos.taos_close(connection); + console.log("Connection is closed"); +} +CTaosInterface.prototype.query = function query(connection, sql) { + return this.libtaos.taos_query(connection, ref.allocCString(sql)); +} +CTaosInterface.prototype.affectedRows = function affectedRows(result) { + return this.libtaos.taos_affected_rows(result); +} +CTaosInterface.prototype.useResult = function useResult(result) { + + let fields = []; + let pfields = this.fetchFields(result); + if (ref.isNull(pfields) == false) { + pfields = ref.reinterpret(pfields, this.fieldsCount(result) * 68, 0); + for (let i = 0; i < pfields.length; i += 68) { + //0 - 63 = name //64 - 65 = bytes, 66 - 67 = type + fields.push({ + name: ref.readCString(ref.reinterpret(pfields, 65, i)), + type: pfields[i + 65], + bytes: pfields[i + 66] + }) + } + } + return fields; +} +CTaosInterface.prototype.fetchBlock = function fetchBlock(result, fields) { + let pblock = ref.NULL_POINTER; + let num_of_rows = this.libtaos.taos_fetch_block(result, pblock); + if (ref.isNull(pblock.deref()) == true) { + return { block: null, num_of_rows: 0 }; + } + + var fieldL = this.libtaos.taos_fetch_lengths(result); + let precision = this.libtaos.taos_result_precision(result); + + var fieldlens = []; + + if (ref.isNull(fieldL) == false) { + for (let i = 0; i < fields.length; i++) { + let plen = ref.reinterpret(fieldL, 4, i * 4); + let len = plen.readInt32LE(0); + fieldlens.push(len); + } + } + + let blocks = new Array(fields.length); + blocks.fill(null); + num_of_rows = Math.abs(num_of_rows); + let offset = 0; + let ptr = pblock.deref(); + + for (let i = 0; i < fields.length; i++) { + pdata = ref.reinterpret(ptr, 8, i * 8); + if (ref.isNull(pdata.readPointer())) { + blocks[i] = new Array(); + } else { + pdata = ref.ref(pdata.readPointer()); + if (!convertFunctions[fields[i]['type']]) { + throw new errors.DatabaseError("Invalid data type returned from database"); + } + blocks[i] = convertFunctions[fields[i]['type']](pdata, num_of_rows, fieldlens[i], offset, precision); + } + } + return { blocks: blocks, num_of_rows } +} +CTaosInterface.prototype.fetchRow = function fetchRow(result, fields) { + let row = this.libtaos.taos_fetch_row(result); + return row; +} +CTaosInterface.prototype.freeResult = function freeResult(result) { + this.libtaos.taos_free_result(result); + result = null; +} +/** Number of fields returned in this result handle, must use with async */ +CTaosInterface.prototype.numFields = function numFields(result) { + return this.libtaos.taos_num_fields(result); +} +// Fetch fields count by connection, the latest query +CTaosInterface.prototype.fieldsCount = function fieldsCount(result) { + return this.libtaos.taos_field_count(result); +} +CTaosInterface.prototype.fetchFields = function fetchFields(result) { + return this.libtaos.taos_fetch_fields(result); +} +CTaosInterface.prototype.errno = function errno(result) { + return this.libtaos.taos_errno(result); +} +CTaosInterface.prototype.errStr = function errStr(result) { + return ref.readCString(this.libtaos.taos_errstr(result)); +} +// Async +CTaosInterface.prototype.query_a = function query_a(connection, sql, callback, param = ref.ref(ref.NULL)) { + // void taos_query_a(TAOS *taos, char *sqlstr, void (*fp)(void *param, TAOS_RES *, int), void *param) + callback = ffi.Callback(ref.types.void, [ref.types.void_ptr, ref.types.void_ptr, ref.types.int], callback); + this.libtaos.taos_query_a(connection, ref.allocCString(sql), callback, param); + return param; +} +/** Asynchrnously fetches the next block of rows. Wraps callback and transfers a 4th argument to the cursor, the row data as blocks in javascript form + * Note: This isn't a recursive function, in order to fetch all data either use the TDengine cursor object, TaosQuery object, or implement a recrusive + * function yourself using the libtaos.taos_fetch_rows_a function + */ +CTaosInterface.prototype.fetch_rows_a = function fetch_rows_a(result, callback, param = ref.ref(ref.NULL)) { + // void taos_fetch_rows_a(TAOS_RES *res, void (*fp)(void *param, TAOS_RES *, int numOfRows), void *param); + var cti = this; + // wrap callback with a function so interface can access the numOfRows value, needed in order to properly process the binary data + let asyncCallbackWrapper = function (param2, result2, numOfRows2) { + // Data preparation to pass to cursor. Could be bottleneck in query execution callback times. + let row = cti.libtaos.taos_fetch_row(result2); + let fields = cti.fetchFields_a(result2); + + let precision = cti.libtaos.taos_result_precision(result2); + let blocks = new Array(fields.length); + blocks.fill(null); + numOfRows2 = Math.abs(numOfRows2); + let offset = 0; + var fieldL = cti.libtaos.taos_fetch_lengths(result); + var fieldlens = []; + if (ref.isNull(fieldL) == false) { + + for (let i = 0; i < fields.length; i++) { + let plen = ref.reinterpret(fieldL, 8, i * 8); + let len = ref.get(plen, 0, ref.types.int32); + fieldlens.push(len); + } + } + if (numOfRows2 > 0) { + for (let i = 0; i < fields.length; i++) { + if (ref.isNull(pdata.readPointer())) { + blocks[i] = new Array(); + } else { + if (!convertFunctions[fields[i]['type']]) { + throw new errors.DatabaseError("Invalid data type returned from database"); + } + let prow = ref.reinterpret(row, 8, i * 8); + prow = prow.readPointer(); + prow = ref.ref(prow); + blocks[i] = convertFunctions[fields[i]['type']](prow, 1, fieldlens[i], offset, precision); + //offset += fields[i]['bytes'] * numOfRows2; + } + } + } + callback(param2, result2, numOfRows2, blocks); + } + asyncCallbackWrapper = ffi.Callback(ref.types.void, [ref.types.void_ptr, ref.types.void_ptr, ref.types.int], asyncCallbackWrapper); + this.libtaos.taos_fetch_rows_a(result, asyncCallbackWrapper, param); + return param; +} +// Fetch field meta data by result handle +CTaosInterface.prototype.fetchFields_a = function fetchFields_a(result) { + let pfields = this.fetchFields(result); + let pfieldscount = this.numFields(result); + let fields = []; + if (ref.isNull(pfields) == false) { + pfields = ref.reinterpret(pfields, 68 * pfieldscount, 0); + for (let i = 0; i < pfields.length; i += 68) { + //0 - 64 = name //65 = type, 66 - 67 = bytes + fields.push({ + name: ref.readCString(ref.reinterpret(pfields, 65, i)), + type: pfields[i + 65], + bytes: pfields[i + 66] + }) + } + } + return fields; +} +// Stop a query by result handle +CTaosInterface.prototype.stopQuery = function stopQuery(result) { + if (result != null) { + this.libtaos.taos_stop_query(result); + } + else { + throw new errors.ProgrammingError("No result handle passed to stop query"); + } +} +CTaosInterface.prototype.getServerInfo = function getServerInfo(connection) { + return ref.readCString(this.libtaos.taos_get_server_info(connection)); +} +CTaosInterface.prototype.getClientInfo = function getClientInfo() { + return ref.readCString(this.libtaos.taos_get_client_info()); +} + +// Subscription +CTaosInterface.prototype.subscribe = function subscribe(connection, restart, topic, sql, interval) { + let topicOrig = topic; + let sqlOrig = sql; + try { + sql = sql != null ? ref.allocCString(sql) : ref.alloc(ref.types.char_ptr, ref.NULL); + } + catch (err) { + throw "Attribute Error: sql is expected as a str"; + } + try { + topic = topic != null ? ref.allocCString(topic) : ref.alloc(ref.types.char_ptr, ref.NULL); + } + catch (err) { + throw TypeError("topic is expected as a str"); + } + + restart = ref.alloc(ref.types.int, restart); + + let subscription = this.libtaos.taos_subscribe(connection, restart, topic, sql, null, null, interval); + if (ref.isNull(subscription)) { + throw new errors.TDError('Failed to subscribe to TDengine | Database: ' + dbOrig + ', Table: ' + tableOrig); + } + else { + console.log('Successfully subscribed to TDengine - Topic: ' + topicOrig); + } + return subscription; +} + +CTaosInterface.prototype.consume = function consume(subscription) { + let result = this.libtaos.taos_consume(subscription); + let fields = []; + let pfields = this.fetchFields(result); + if (ref.isNull(pfields) == false) { + pfields = ref.reinterpret(pfields, this.numFields(result) * 68, 0); + for (let i = 0; i < pfields.length; i += 68) { + //0 - 63 = name //64 - 65 = bytes, 66 - 67 = type + fields.push({ + name: ref.readCString(ref.reinterpret(pfields, 64, i)), + bytes: pfields[i + 64], + type: pfields[i + 66] + }) + } + } + + let data = []; + while (true) { + let { blocks, num_of_rows } = this.fetchBlock(result, fields); + if (num_of_rows == 0) { + break; + } + for (let i = 0; i < num_of_rows; i++) { + data.push([]); + let rowBlock = new Array(fields.length); + for (let j = 0; j < fields.length; j++) { + rowBlock[j] = blocks[j][i]; + } + data[data.length - 1] = (rowBlock); + } + } + return { data: data, fields: fields, result: result }; +} +CTaosInterface.prototype.unsubscribe = function unsubscribe(subscription) { + //void taos_unsubscribe(TAOS_SUB *tsub); + this.libtaos.taos_unsubscribe(subscription); +} + +// Continuous Query +CTaosInterface.prototype.openStream = function openStream(connection, sql, callback, stime, stoppingCallback, param = ref.ref(ref.NULL)) { + try { + sql = ref.allocCString(sql); + } + catch (err) { + throw "Attribute Error: sql string is expected as a str"; + } + var cti = this; + let asyncCallbackWrapper = function (param2, result2, row) { + let fields = cti.fetchFields_a(result2); + let precision = cti.libtaos.taos_result_precision(result2); + let blocks = new Array(fields.length); + blocks.fill(null); + let numOfRows2 = 1; + let offset = 0; + if (numOfRows2 > 0) { + for (let i = 0; i < fields.length; i++) { + if (!convertFunctions[fields[i]['type']]) { + throw new errors.DatabaseError("Invalid data type returned from database"); + } + blocks[i] = convertFunctions[fields[i]['type']](row, numOfRows2, fields[i]['bytes'], offset, precision); + offset += fields[i]['bytes'] * numOfRows2; + } + } + callback(param2, result2, blocks, fields); + } + asyncCallbackWrapper = ffi.Callback(ref.types.void, [ref.types.void_ptr, ref.types.void_ptr, ref.refType(ref.types.void_ptr2)], asyncCallbackWrapper); + asyncStoppingCallbackWrapper = ffi.Callback(ref.types.void, [ref.types.void_ptr], stoppingCallback); + let streamHandle = this.libtaos.taos_open_stream(connection, sql, asyncCallbackWrapper, stime, param, asyncStoppingCallbackWrapper); + if (ref.isNull(streamHandle)) { + throw new errors.TDError('Failed to open a stream with TDengine'); + return false; + } + else { + console.log("Succesfully opened stream"); + return streamHandle; + } +} +CTaosInterface.prototype.closeStream = function closeStream(stream) { + this.libtaos.taos_close_stream(stream); + console.log("Closed stream"); +} diff --git a/tests/connectorTest/nodejsTest/nodetaos/connection.js b/tests/connectorTest/nodejsTest/nodetaos/connection.js new file mode 100644 index 0000000000000000000000000000000000000000..08186f87053ad0ed0982ec8941f0cf38c4ad0467 --- /dev/null +++ b/tests/connectorTest/nodejsTest/nodetaos/connection.js @@ -0,0 +1,84 @@ +const TDengineCursor = require('./cursor') +const CTaosInterface = require('./cinterface') +module.exports = TDengineConnection; + +/** + * TDengine Connection Class + * @param {object} options - Options for configuring the connection with TDengine + * @return {TDengineConnection} + * @class TDengineConnection + * @constructor + * @example + * //Initialize a new connection + * var conn = new TDengineConnection({host:"127.0.0.1", user:"root", password:"taosdata", config:"/etc/taos",port:0}) + * + */ +function TDengineConnection(options) { + this._conn = null; + this._host = null; + this._user = "root"; //The default user + this._password = "taosdata"; //The default password + this._database = null; + this._port = 0; + this._config = null; + this._chandle = null; + this._configConn(options) + return this; +} +/** + * Configure the connection to TDengine + * @private + * @memberof TDengineConnection + */ +TDengineConnection.prototype._configConn = function _configConn(options) { + if (options['host']) { + this._host = options['host']; + } + if (options['user']) { + this._user = options['user']; + } + if (options['password']) { + this._password = options['password']; + } + if (options['database']) { + this._database = options['database']; + } + if (options['port']) { + this._port = options['port']; + } + if (options['config']) { + this._config = options['config']; + } + this._chandle = new CTaosInterface(this._config); + this._conn = this._chandle.connect(this._host, this._user, this._password, this._database, this._port); +} +/** Close the connection to TDengine */ +TDengineConnection.prototype.close = function close() { + this._chandle.close(this._conn); +} +/** + * Initialize a new cursor to interact with TDengine with + * @return {TDengineCursor} + */ +TDengineConnection.prototype.cursor = function cursor() { + //Pass the connection object to the cursor + return new TDengineCursor(this); +} +TDengineConnection.prototype.commit = function commit() { + return this; +} +TDengineConnection.prototype.rollback = function rollback() { + return this; +} +/** + * Clear the results from connector + * @private + */ +/* + TDengineConnection.prototype._clearResultSet = function _clearResultSet() { + var result = this._chandle.useResult(this._conn).result; + if (result) { + this._chandle.freeResult(result) + } +} +*/ diff --git a/tests/connectorTest/nodejsTest/nodetaos/constants.js b/tests/connectorTest/nodejsTest/nodetaos/constants.js new file mode 100644 index 0000000000000000000000000000000000000000..cd6a0c9fbaff51e7f0ecd3ab06907b7b1fb7dcb1 --- /dev/null +++ b/tests/connectorTest/nodejsTest/nodetaos/constants.js @@ -0,0 +1,76 @@ +/** + * Contains the the definitions/values assigned to various field types + * @module FieldTypes + */ +/** + * TDengine Field Types and their type codes + * @typedef {Object} FieldTypes + * @global + * @property {number} C_NULL - Null + * @property {number} C_BOOL - Boolean. Note, 0x02 is the C_BOOL_NULL value. + * @property {number} C_TINYINT - Tiny Int, values in the range [-2^7+1, 2^7-1]. Note, -2^7 has been used as the C_TINYINT_NULL value + * @property {number} C_SMALLINT - Small Int, values in the range [-2^15+1, 2^15-1]. Note, -2^15 has been used as the C_SMALLINT_NULL value + * @property {number} C_INT - Int, values in the range [-2^31+1, 2^31-1]. Note, -2^31 has been used as the C_INT_NULL value + * @property {number} C_BIGINT - Big Int, values in the range [-2^59, 2^59]. + * @property {number} C_FLOAT - Float, values in the range [-3.4E38, 3.4E38], accurate up to 6-7 decimal places. + * @property {number} C_DOUBLE - Double, values in the range [-1.7E308, 1.7E308], accurate up to 15-16 decimal places. + * @property {number} C_BINARY - Binary, encoded in utf-8. + * @property {number} C_TIMESTAMP - Timestamp in format "YYYY:MM:DD HH:MM:SS.MMM". Measured in number of milliseconds passed after + 1970-01-01 08:00:00.000 GMT. + * @property {number} C_NCHAR - NChar field type encoded in ASCII, a wide string. + * + * + * + * @property {number} C_TIMESTAMP_MILLI - The code for millisecond timestamps, as returned by libtaos.taos_result_precision(result). + * @property {number} C_TIMESTAMP_MICRO - The code for microsecond timestamps, as returned by libtaos.taos_result_precision(result). + */ +module.exports = { + C_NULL : 0, + C_BOOL : 1, + C_TINYINT : 2, + C_SMALLINT : 3, + C_INT : 4, + C_BIGINT : 5, + C_FLOAT : 6, + C_DOUBLE : 7, + C_BINARY : 8, + C_TIMESTAMP : 9, + C_NCHAR : 10, + // NULL value definition + // NOTE: These values should change according to C definition in tsdb.h + C_BOOL_NULL : 2, + C_TINYINT_NULL : -128, + C_SMALLINT_NULL : -32768, + C_INT_NULL : -2147483648, + C_BIGINT_NULL : -9223372036854775808, + C_FLOAT_NULL : 2146435072, + C_DOUBLE_NULL : -9223370937343148032, + C_NCHAR_NULL : 4294967295, + C_BINARY_NULL : 255, + C_TIMESTAMP_MILLI : 0, + C_TIMESTAMP_MICRO : 1, + getType, +} + +const typeCodesToName = { + 0 : 'Null', + 1 : 'Boolean', + 2 : 'Tiny Int', + 3 : 'Small Int', + 4 : 'Int', + 5 : 'Big Int', + 6 : 'Float', + 7 : 'Double', + 8 : 'Binary', + 9 : 'Timestamp', + 10 : 'Nchar', +} + +/** + * @function + * @param {number} typecode - The code to get the name of the type for + * @return {string} Name of the field type + */ +function getType(typecode) { + return typeCodesToName[typecode]; +} diff --git a/tests/connectorTest/nodejsTest/nodetaos/cursor.js b/tests/connectorTest/nodejsTest/nodetaos/cursor.js new file mode 100644 index 0000000000000000000000000000000000000000..f879d89d487eae9290fd9fc70259699f27937928 --- /dev/null +++ b/tests/connectorTest/nodejsTest/nodetaos/cursor.js @@ -0,0 +1,476 @@ +const ref = require('ref-napi'); +require('./globalfunc.js') +const CTaosInterface = require('./cinterface') +const errors = require('./error') +const TaosQuery = require('./taosquery') +const { PerformanceObserver, performance } = require('perf_hooks'); +module.exports = TDengineCursor; + +/** + * @typedef {Object} Buffer - A Node.js buffer. Please refer to {@link https://nodejs.org/api/buffer.html} for more details + * @global + */ + +/** + * @class TDengineCursor + * @classdesc The TDengine Cursor works directly with the C Interface which works with TDengine. It refrains from + * returning parsed data and majority of functions return the raw data such as cursor.fetchall() as compared to the TaosQuery class which + * has functions that "prettify" the data and add more functionality and can be used through cursor.query("your query"). Instead of + * promises, the class and its functions use callbacks. + * @param {TDengineConnection} - The TDengine Connection this cursor uses to interact with TDengine + * @property {data} - Latest retrieved data from query execution. It is an empty array by default + * @property {fields} - Array of the field objects in order from left to right of the latest data retrieved + * @since 1.0.0 + */ +function TDengineCursor(connection = null) { + //All parameters are store for sync queries only. + this._rowcount = -1; + this._connection = null; + this._result = null; + this._fields = null; + this.data = []; + this.fields = null; + if (connection != null) { + this._connection = connection + this._chandle = connection._chandle //pass through, just need library loaded. + } + else { + throw new errors.ProgrammingError("A TDengineConnection object is required to be passed to the TDengineCursor"); + } + +} +/** + * Get the row counts of the latest query + * @since 1.0.0 + * @return {number} Rowcount + */ +TDengineCursor.prototype.rowcount = function rowcount() { + return this._rowcount; +} +/** + * Close the cursor by setting its connection to null and freeing results from the connection and resetting the results it has stored + * @return {boolean} Whether or not the cursor was succesfully closed + * @since 1.0.0 + */ +TDengineCursor.prototype.close = function close() { + if (this._connection == null) { + return false; + } + this._connection._clearResultSet(); + this._reset_result(); + this._connection = null; + return true; +} +/** + * Create a TaosQuery object to perform a query to TDengine and retrieve data. + * @param {string} operation - The operation string to perform a query on + * @param {boolean} execute - Whether or not to immedietely perform the query. Default is false. + * @return {TaosQuery | Promise} A TaosQuery object + * @example + * var query = cursor.query("select count(*) from meterinfo.meters"); + * query.execute(); + * @since 1.0.6 + */ +TDengineCursor.prototype.query = function query(operation, execute = false) { + return new TaosQuery(operation, this, execute); +} + +/** + * Execute a query. Also stores all the field meta data returned from the query into cursor.fields. It is preferable to use cursor.query() to create + * queries and execute them instead of using the cursor object directly. + * @param {string} operation - The query operation to execute in the taos shell + * @param {Object} options - Execution options object. quiet : true turns off logging from queries + * @param {boolean} options.quiet - True if you want to surpress logging such as "Query OK, 1 row(s) ..." + * @param {function} callback - A callback function to execute after the query is made to TDengine + * @return {number | Buffer} Number of affected rows or a Buffer that points to the results of the query + * @since 1.0.0 + */ +TDengineCursor.prototype.execute = function execute(operation, options, callback) { + if (operation == undefined) { + throw new errors.ProgrammingError('No operation passed as argument'); + return null; + } + + if (typeof options == 'function') { + callback = options; + } + if (typeof options != 'object') options = {} + if (this._connection == null) { + throw new errors.ProgrammingError('Cursor is not connected'); + } + + this._reset_result(); + + let stmt = operation; + let time = 0; + let res; + if (options['quiet'] != true) { + const obs = new PerformanceObserver((items) => { + time = items.getEntries()[0].duration; + performance.clearMarks(); + }); + obs.observe({ entryTypes: ['measure'] }); + performance.mark('A'); + this._result = this._chandle.query(this._connection._conn, stmt); + performance.mark('B'); + performance.measure('query', 'A', 'B'); + } + else { + this._result = this._chandle.query(this._connection._conn, stmt); + } + res = this._chandle.errno(this._result); + if (res == 0) { + let fieldCount = this._chandle.fieldsCount(this._result); + if (fieldCount == 0) { + let affectedRowCount = this._chandle.affectedRows(this._result); + let response = this._createAffectedResponse(affectedRowCount, time) + if (options['quiet'] != true) { + console.log(response); + } + wrapCB(callback); + return affectedRowCount; //return num of affected rows, common with insert, use statements + } + else { + this._fields = this._chandle.useResult(this._result); + this.fields = this._fields; + wrapCB(callback); + + return this._result; //return a pointer to the result + } + } + else { + throw new errors.ProgrammingError(this._chandle.errStr(this._result)) + } + +} +TDengineCursor.prototype._createAffectedResponse = function (num, time) { + return "Query OK, " + num + " row(s) affected (" + (time * 0.001).toFixed(8) + "s)"; +} +TDengineCursor.prototype._createSetResponse = function (num, time) { + return "Query OK, " + num + " row(s) in set (" + (time * 0.001).toFixed(8) + "s)"; +} +TDengineCursor.prototype.executemany = function executemany() { + +} +TDengineCursor.prototype.fetchone = function fetchone() { + +} +TDengineCursor.prototype.fetchmany = function fetchmany() { + +} +/** + * Fetches all results from a query and also stores results into cursor.data. It is preferable to use cursor.query() to create + * queries and execute them instead of using the cursor object directly. + * @param {function} callback - callback function executing on the complete fetched data + * @return {Array} The resultant array, with entries corresponding to each retreived row from the query results, sorted in + * order by the field name ordering in the table. + * @since 1.0.0 + * @example + * cursor.execute('select * from db.table'); + * var data = cursor.fetchall(function(results) { + * results.forEach(row => console.log(row)); + * }) + */ +TDengineCursor.prototype.fetchall = function fetchall(options, callback) { + if (this._result == null || this._fields == null) { + throw new errors.OperationalError("Invalid use of fetchall, either result or fields from query are null. First execute a query first"); + } + + let num_of_rows = this._chandle.affectedRows(this._result); + let data = new Array(num_of_rows); + + this._rowcount = 0; + + let time = 0; + const obs = new PerformanceObserver((items) => { + time += items.getEntries()[0].duration; + performance.clearMarks(); + }); + obs.observe({ entryTypes: ['measure'] }); + performance.mark('A'); + while (true) { + let blockAndRows = this._chandle.fetchBlock(this._result, this._fields); + // console.log(blockAndRows); + // break; + let block = blockAndRows.blocks; + let num_of_rows = blockAndRows.num_of_rows; + if (num_of_rows == 0) { + break; + } + this._rowcount += num_of_rows; + let numoffields = this._fields.length; + for (let i = 0; i < num_of_rows; i++) { + // data.push([]); + + let rowBlock = new Array(numoffields); + for (let j = 0; j < numoffields; j++) { + rowBlock[j] = block[j][i]; + } + data[this._rowcount - num_of_rows + i] = (rowBlock); + // data.push(rowBlock); + } + + } + + performance.mark('B'); + performance.measure('query', 'A', 'B'); + let response = this._createSetResponse(this._rowcount, time) + console.log(response); + + // this._connection._clearResultSet(); + let fields = this.fields; + this._reset_result(); + this.data = data; + this.fields = fields; + + wrapCB(callback, data); + + return data; +} +/** + * Asynchrnously execute a query to TDengine. NOTE, insertion requests must be done in sync if on the same table. + * @param {string} operation - The query operation to execute in the taos shell + * @param {Object} options - Execution options object. quiet : true turns off logging from queries + * @param {boolean} options.quiet - True if you want to surpress logging such as "Query OK, 1 row(s) ..." + * @param {function} callback - A callback function to execute after the query is made to TDengine + * @return {number | Buffer} Number of affected rows or a Buffer that points to the results of the query + * @since 1.0.0 + */ +TDengineCursor.prototype.execute_a = function execute_a(operation, options, callback, param) { + if (operation == undefined) { + throw new errors.ProgrammingError('No operation passed as argument'); + return null; + } + if (typeof options == 'function') { + //we expect the parameter after callback to be param + param = callback; + callback = options; + } + if (typeof options != 'object') options = {} + if (this._connection == null) { + throw new errors.ProgrammingError('Cursor is not connected'); + } + if (typeof callback != 'function') { + throw new errors.ProgrammingError("No callback function passed to execute_a function"); + } + // Async wrapper for callback; + var cr = this; + + let asyncCallbackWrapper = function (param2, res2, resCode) { + if (typeof callback == 'function') { + callback(param2, res2, resCode); + } + + if (resCode >= 0) { + // let fieldCount = cr._chandle.numFields(res2); + // if (fieldCount == 0) { + // //cr._chandle.freeResult(res2); + // return res2; + // } + // else { + // return res2; + // } + return res2; + + } + else { + throw new errors.ProgrammingError("Error occuring with use of execute_a async function. Status code was returned with failure"); + } + } + + let stmt = operation; + let time = 0; + + // Use ref module to write to buffer in cursor.js instead of taosquery to maintain a difference in levels. Have taosquery stay high level + // through letting it pass an object as param + var buf = ref.alloc('Object'); + ref.writeObject(buf, 0, param); + const obs = new PerformanceObserver((items) => { + time = items.getEntries()[0].duration; + performance.clearMarks(); + }); + obs.observe({ entryTypes: ['measure'] }); + performance.mark('A'); + this._chandle.query_a(this._connection._conn, stmt, asyncCallbackWrapper, buf); + performance.mark('B'); + performance.measure('query', 'A', 'B'); + return param; + + +} +/** + * Fetches all results from an async query. It is preferable to use cursor.query_a() to create + * async queries and execute them instead of using the cursor object directly. + * @param {Object} options - An options object containing options for this function + * @param {function} callback - callback function that is callbacked on the COMPLETE fetched data (it is calledback only once!). + * Must be of form function (param, result, rowCount, rowData) + * @param {Object} param - A parameter that is also passed to the main callback function. Important! Param must be an object, and the key "data" cannot be used + * @return {{param:Object, result:Buffer}} An object with the passed parameters object and the buffer instance that is a pointer to the result handle. + * @since 1.2.0 + * @example + * cursor.execute('select * from db.table'); + * var data = cursor.fetchall(function(results) { + * results.forEach(row => console.log(row)); + * }) + */ +TDengineCursor.prototype.fetchall_a = function fetchall_a(result, options, callback, param = {}) { + if (typeof options == 'function') { + //we expect the parameter after callback to be param + param = callback; + callback = options; + } + if (typeof options != 'object') options = {} + if (this._connection == null) { + throw new errors.ProgrammingError('Cursor is not connected'); + } + if (typeof callback != 'function') { + throw new errors.ProgrammingError('No callback function passed to fetchall_a function') + } + if (param.data) { + throw new errors.ProgrammingError("You aren't allowed to set the key 'data' for the parameters object"); + } + let buf = ref.alloc('Object'); + param.data = []; + var cr = this; + + // This callback wrapper accumulates the data from the fetch_rows_a function from the cinterface. It is accumulated by passing the param2 + // object which holds accumulated data in the data key. + let asyncCallbackWrapper = function asyncCallbackWrapper(param2, result2, numOfRows2, rowData) { + param2 = ref.readObject(param2); //return the object back from the pointer + if (numOfRows2 > 0 && rowData.length != 0) { + // Keep fetching until now rows left. + let buf2 = ref.alloc('Object'); + param2.data.push(rowData); + ref.writeObject(buf2, 0, param2); + cr._chandle.fetch_rows_a(result2, asyncCallbackWrapper, buf2); + } + else { + let finalData = param2.data; + let fields = cr._chandle.fetchFields_a(result2); + let data = []; + for (let i = 0; i < finalData.length; i++) { + let num_of_rows = finalData[i][0].length; //fetched block number i; + let block = finalData[i]; + for (let j = 0; j < num_of_rows; j++) { + data.push([]); + let rowBlock = new Array(fields.length); + for (let k = 0; k < fields.length; k++) { + rowBlock[k] = block[k][j]; + } + data[data.length - 1] = rowBlock; + } + } + cr._chandle.freeResult(result2); // free result, avoid seg faults and mem leaks! + callback(param2, result2, numOfRows2, { data: data, fields: fields }); + + } + } + ref.writeObject(buf, 0, param); + param = this._chandle.fetch_rows_a(result, asyncCallbackWrapper, buf); //returned param + return { param: param, result: result }; +} +/** + * Stop a query given the result handle. + * @param {Buffer} result - The buffer that acts as the result handle + * @since 1.3.0 + */ +TDengineCursor.prototype.stopQuery = function stopQuery(result) { + this._chandle.stopQuery(result); +} +TDengineCursor.prototype._reset_result = function _reset_result() { + this._rowcount = -1; + if (this._result != null) { + this._chandle.freeResult(this._result); + } + this._result = null; + this._fields = null; + this.data = []; + this.fields = null; +} +/** + * Get server info such as version number + * @return {string} + * @since 1.3.0 + */ +TDengineCursor.prototype.getServerInfo = function getServerInfo() { + return this._chandle.getServerInfo(this._connection._conn); +} +/** + * Get client info such as version number + * @return {string} + * @since 1.3.0 + */ +TDengineCursor.prototype.getClientInfo = function getClientInfo() { + return this._chandle.getClientInfo(); +} +/** + * Subscribe to a table from a database in TDengine. + * @param {Object} config - A configuration object containing the configuration options for the subscription + * @param {string} config.restart - whether or not to continue a subscription if it already exits, otherwise start from beginning + * @param {string} config.topic - The unique identifier of a subscription + * @param {string} config.sql - A sql statement for data query + * @param {string} config.interval - The pulling interval + * @return {Buffer} A buffer pointing to the subscription session handle + * @since 1.3.0 + */ +TDengineCursor.prototype.subscribe = function subscribe(config) { + let restart = config.restart ? 1 : 0; + return this._chandle.subscribe(this._connection._conn, restart, config.topic, config.sql, config.interval); +}; +/** + * An infinite loop that consumes the latest data and calls a callback function that is provided. + * @param {Buffer} subscription - A buffer object pointing to the subscription session handle + * @param {function} callback - The callback function that takes the row data, field/column meta data, and the subscription session handle as input + * @since 1.3.0 + */ +TDengineCursor.prototype.consumeData = async function consumeData(subscription, callback) { + while (true) { + let { data, fields, result } = this._chandle.consume(subscription); + callback(data, fields, result); + } +} +/** + * Unsubscribe the provided buffer object pointing to the subscription session handle + * @param {Buffer} subscription - A buffer object pointing to the subscription session handle that is to be unsubscribed + * @since 1.3.0 + */ +TDengineCursor.prototype.unsubscribe = function unsubscribe(subscription) { + this._chandle.unsubscribe(subscription); +} +/** + * Open a stream with TDengine to run the sql query periodically in the background + * @param {string} sql - The query to run + * @param {function} callback - The callback function to run after each query, accepting inputs as param, result handle, data, fields meta data + * @param {number} stime - The time of the stream starts in the form of epoch milliseconds. If 0 is given, the start time is set as the current time. + * @param {function} stoppingCallback - The callback function to run when the continuous query stops. It takes no inputs + * @param {object} param - A parameter that is passed to the main callback function + * @return {Buffer} A buffer pointing to the stream handle + * @since 1.3.0 + */ +TDengineCursor.prototype.openStream = function openStream(sql, callback, stime = 0, stoppingCallback, param = {}) { + let buf = ref.alloc('Object'); + ref.writeObject(buf, 0, param); + + let asyncCallbackWrapper = function (param2, result2, blocks, fields) { + let data = []; + let num_of_rows = blocks[0].length; + for (let j = 0; j < num_of_rows; j++) { + data.push([]); + let rowBlock = new Array(fields.length); + for (let k = 0; k < fields.length; k++) { + rowBlock[k] = blocks[k][j]; + } + data[data.length - 1] = rowBlock; + } + callback(param2, result2, blocks, fields); + } + return this._chandle.openStream(this._connection._conn, sql, asyncCallbackWrapper, stime, stoppingCallback, buf); +} +/** + * Close a stream + * @param {Buffer} - A buffer pointing to the handle of the stream to be closed + * @since 1.3.0 + */ +TDengineCursor.prototype.closeStream = function closeStream(stream) { + this._chandle.closeStream(stream); +} diff --git a/tests/connectorTest/nodejsTest/nodetaos/error.js b/tests/connectorTest/nodejsTest/nodetaos/error.js new file mode 100644 index 0000000000000000000000000000000000000000..8ab91a50c7d81a4675246617e0969ee8c81c514e --- /dev/null +++ b/tests/connectorTest/nodejsTest/nodetaos/error.js @@ -0,0 +1,96 @@ + +/** + * TDengine Error Class + * @ignore + */ +class TDError extends Error { + constructor(args) { + super(args) + this.name = "TDError"; + } +} +/** Exception raised for important warnings like data truncations while inserting. + * @ignore + */ +class Warning extends Error { + constructor(args) { + super(args) + this.name = "Warning"; + } +} +/** Exception raised for errors that are related to the database interface rather than the database itself. + * @ignore + */ +class InterfaceError extends TDError { + constructor(args) { + super(args) + this.name = "TDError.InterfaceError"; + } +} +/** Exception raised for errors that are related to the database. + * @ignore + */ +class DatabaseError extends TDError { + constructor(args) { + super(args) + this.name = "TDError.DatabaseError"; + } +} +/** Exception raised for errors that are due to problems with the processed data like division by zero, numeric value out of range. + * @ignore + */ +class DataError extends DatabaseError { + constructor(args) { + super(args) + this.name = "TDError.DatabaseError.DataError"; + } +} +/** Exception raised for errors that are related to the database's operation and not necessarily under the control of the programmer + * @ignore + */ +class OperationalError extends DatabaseError { + constructor(args) { + super(args) + this.name = "TDError.DatabaseError.OperationalError"; + } +} +/** Exception raised when the relational integrity of the database is affected. + * @ignore + */ +class IntegrityError extends DatabaseError { + constructor(args) { + super(args) + this.name = "TDError.DatabaseError.IntegrityError"; + } +} +/** Exception raised when the database encounters an internal error. + * @ignore + */ +class InternalError extends DatabaseError { + constructor(args) { + super(args) + this.name = "TDError.DatabaseError.InternalError"; + } +} +/** Exception raised for programming errors. + * @ignore + */ +class ProgrammingError extends DatabaseError { + constructor(args) { + super(args) + this.name = "TDError.DatabaseError.ProgrammingError"; + } +} +/** Exception raised in case a method or database API was used which is not supported by the database. + * @ignore + */ +class NotSupportedError extends DatabaseError { + constructor(args) { + super(args) + this.name = "TDError.DatabaseError.NotSupportedError"; + } +} + +module.exports = { + TDError, Warning, InterfaceError, DatabaseError, DataError, OperationalError, IntegrityError, InternalError, ProgrammingError, NotSupportedError +}; diff --git a/tests/connectorTest/nodejsTest/nodetaos/globalfunc.js b/tests/connectorTest/nodejsTest/nodetaos/globalfunc.js new file mode 100644 index 0000000000000000000000000000000000000000..cf7344c868ee94831eba47ff55369a684e34b02f --- /dev/null +++ b/tests/connectorTest/nodejsTest/nodetaos/globalfunc.js @@ -0,0 +1,14 @@ +/* Wrap a callback, reduce code amount */ +function wrapCB(callback, input) { + if (typeof callback === 'function') { + callback(input); + } + return; +} +global.wrapCB = wrapCB; +function toTaosTSString(date) { + date = new Date(date); + let tsArr = date.toISOString().split("T") + return tsArr[0] + " " + tsArr[1].substring(0, tsArr[1].length-1); +} +global.toTaosTSString = toTaosTSString; diff --git a/tests/connectorTest/nodejsTest/nodetaos/taosobjects.js b/tests/connectorTest/nodejsTest/nodetaos/taosobjects.js new file mode 100644 index 0000000000000000000000000000000000000000..3bc0fe0aca060a32daa7a5cebd2dbfb99ac29a7c --- /dev/null +++ b/tests/connectorTest/nodejsTest/nodetaos/taosobjects.js @@ -0,0 +1,152 @@ +const FieldTypes = require('./constants'); +const util = require('util'); +/** + * Various objects such as TaosRow and TaosColumn that help make parsing data easier + * @module TaosObjects + * + */ + +/** + * The TaosRow object. Contains the data from a retrieved row from a database and functions that parse the data. + * @typedef {Object} TaosRow - A row of data retrieved from a table. + * @global + * @example + * var trow = new TaosRow(row); + * console.log(trow.data); + */ +function TaosRow(row) { + this.data = row; + this.length = row.length; + return this; +} + +/** + * @typedef {Object} TaosField - A field/column's metadata from a table. + * @global + * @example + * var tfield = new TaosField(field); + * console.log(tfield.name); + */ + +function TaosField(field) { + this._field = field; + this.name = field.name; + this.type = FieldTypes.getType(field.type); + return this; +} + +/** + * A TaosTimestamp object, which is the standard date object with added functionality + * @global + * @memberof TaosObjects + * @param {Date} date - A Javascript date time object or the time in milliseconds past 1970-1-1 00:00:00.000 + */ +class TaosTimestamp extends Date { + constructor(date, precision = 0) { + if (precision === 1) { + super(Math.floor(date / 1000)); + this.precisionExtras = date % 1000; + } else if (precision === 2) { + // use BigInt to fix: 1623254400999999999 / 1000000 = 1623254401000 which not expected + super(parseInt(BigInt(date) / 1000000n)); + // use BigInt to fix: 1625801548423914405 % 1000000 = 914496 which not expected (914405) + this.precisionExtras = parseInt(BigInt(date) % 1000000n); + } else { + super(parseInt(date)); + } + this.precision = precision; + } + + /** + * TDengine raw timestamp. + * @returns raw taos timestamp (int64) + */ + taosTimestamp() { + if (this.precision == 1) { + return (this * 1000 + this.precisionExtras); + } else if (this.precision == 2) { + return (this * 1000000 + this.precisionExtras); + } else { + return Math.floor(this); + } + } + + /** + * Gets the microseconds of a Date. + * @return {Int} A microseconds integer + */ + getMicroseconds() { + if (this.precision == 1) { + return this.getMilliseconds() * 1000 + this.precisionExtras; + } else if (this.precision == 2) { + return this.getMilliseconds() * 1000 + this.precisionExtras / 1000; + } else { + return 0; + } + } + /** + * Gets the nanoseconds of a TaosTimestamp. + * @return {Int} A nanoseconds integer + */ + getNanoseconds() { + if (this.precision == 1) { + return this.getMilliseconds() * 1000000 + this.precisionExtras * 1000; + } else if (this.precision == 2) { + return this.getMilliseconds() * 1000000 + this.precisionExtras; + } else { + return 0; + } + } + + /** + * @returns {String} a string for timestamp string format + */ + _precisionExtra() { + if (this.precision == 1) { + return String(this.precisionExtras).padStart(3, '0'); + } else if (this.precision == 2) { + return String(this.precisionExtras).padStart(6, '0'); + } else { + return ''; + } + } + /** + * @function Returns the date into a string usable by TDengine + * @return {string} A Taos Timestamp String + */ + toTaosString() { + var tzo = -this.getTimezoneOffset(), + dif = tzo >= 0 ? '+' : '-', + pad = function (num) { + var norm = Math.floor(Math.abs(num)); + return (norm < 10 ? '0' : '') + norm; + }, + pad2 = function (num) { + var norm = Math.floor(Math.abs(num)); + if (norm < 10) return '00' + norm; + if (norm < 100) return '0' + norm; + if (norm < 1000) return norm; + }; + return this.getFullYear() + + '-' + pad(this.getMonth() + 1) + + '-' + pad(this.getDate()) + + ' ' + pad(this.getHours()) + + ':' + pad(this.getMinutes()) + + ':' + pad(this.getSeconds()) + + '.' + pad2(this.getMilliseconds()) + + '' + this._precisionExtra(); + } + + /** + * Custom console.log + * @returns {String} string format for debug + */ + [util.inspect.custom](depth, opts) { + return this.toTaosString() + JSON.stringify({ precision: this.precision, precisionExtras: this.precisionExtras }, opts); + } + toString() { + return this.toTaosString(); + } +} + +module.exports = { TaosRow, TaosField, TaosTimestamp } diff --git a/tests/connectorTest/nodejsTest/nodetaos/taosquery.js b/tests/connectorTest/nodejsTest/nodetaos/taosquery.js new file mode 100644 index 0000000000000000000000000000000000000000..eeede3ff6885e27c1d1c569a7a410f88109c9acd --- /dev/null +++ b/tests/connectorTest/nodejsTest/nodetaos/taosquery.js @@ -0,0 +1,112 @@ +var TaosResult = require('./taosresult') +require('./globalfunc.js') +module.exports = TaosQuery; + + +/** + * @class TaosQuery + * @classdesc The TaosQuery class is one level above the TDengine Cursor in that it makes sure to generally return promises from functions, and wrap + * all data with objects such as wrapping a row of data with Taos Row. This is meant to enable an higher level API that allows additional + * functionality and save time whilst also making it easier to debug and enter less problems with the use of promises. + * @param {string} query - Query to construct object from + * @param {TDengineCursor} cursor - The cursor from which this query will execute from + * @param {boolean} execute - Whether or not to immedietely execute the query synchronously and fetch all results. Default is false. + * @property {string} query - The current query in string format the TaosQuery object represents + * @return {TaosQuery} + * @since 1.0.6 + */ +function TaosQuery(query = "", cursor = null, execute = false) { + this.query = query; + this._cursor = cursor; + if (execute == true) { + return this.execute(); + } + return this; +} + +/** + * Executes the query object and returns a Promise + * @memberof TaosQuery + * @return {Promise} A promise that resolves with a TaosResult object, or rejects with an error + * @since 1.0.6 + */ +TaosQuery.prototype.execute = async function execute() { + var taosQuery = this; //store the current instance of taosQuery to avoid async issues? + var executionPromise = new Promise(function(resolve, reject) { + let data = []; + let fields = []; + let result; + try { + taosQuery._cursor.execute(taosQuery.query); + if (taosQuery._cursor._fields) fields = taosQuery._cursor._fields; + if (taosQuery._cursor._result != null) data = taosQuery._cursor.fetchall(); + result = new TaosResult(data, fields) + } + catch(err) { + reject(err); + } + resolve(result) + + }); + return executionPromise; +} + +/** + * Executes the query object asynchronously and returns a Promise. Completes query to completion. + * @memberof TaosQuery + * @param {Object} options - Execution options + * @return {Promise} A promise that resolves with a TaosResult object, or rejects with an error + * @since 1.2.0 + */ +TaosQuery.prototype.execute_a = async function execute_a(options = {}) { + var executionPromise = new Promise( (resolve, reject) => { + + }); + var fres; + var frej; + var fetchPromise = new Promise( (resolve, reject) => { + fres = resolve; + frej = reject; + }); + let asyncCallbackFetchall = async function(param, res, numOfRows, blocks) { + if (numOfRows > 0) { + // Likely a query like insert + fres(); + } + else { + fres(new TaosResult(blocks.data, blocks.fields)); + } + } + let asyncCallback = async function(param, res, code) { + //upon success, we fetchall results + this._cursor.fetchall_a(res, options, asyncCallbackFetchall, {}); + } + this._cursor.execute_a(this.query, asyncCallback.bind(this), {}); + return fetchPromise; +} + +/** + * Bind arguments to the query and automatically parses them into the right format + * @param {array | ...args} args - A number of arguments to bind to each ? in the query + * @return {TaosQuery} + * @example + * // An example of binding a javascript date and a number to a query + * var query = cursor.query("select count(*) from meterinfo.meters where ts <= ? and areaid = ?").bind(new Date(), 3); + * var promise1 = query.execute(); + * promise1.then(function(result) { + * result.pretty(); // Log the prettified version of the results. + * }); + * @since 1.0.6 + */ +TaosQuery.prototype.bind = function bind(f, ...args) { + if (typeof f == 'object' && f.constructor.name != 'Array') args.unshift(f); //param is not an array object + else if (typeof f != 'object') args.unshift(f); + else { args = f; } + args.forEach(function(arg) { + if (arg.constructor.name == 'TaosTimestamp') arg = "\"" + arg.toTaosString() + "\""; + else if (arg.constructor.name == 'Date') arg = "\"" + toTaosTSString(arg) + "\""; + else if (typeof arg == 'string') arg = "\"" + arg + "\""; + this.query = this.query.replace(/\?/,arg); + }, this); + return this; +} diff --git a/tests/connectorTest/nodejsTest/nodetaos/taosresult.js b/tests/connectorTest/nodejsTest/nodetaos/taosresult.js new file mode 100644 index 0000000000000000000000000000000000000000..4138ebbec6e1b792691d17a25b7c18d35b6a922a --- /dev/null +++ b/tests/connectorTest/nodejsTest/nodetaos/taosresult.js @@ -0,0 +1,85 @@ +require('./globalfunc.js') +const TaosObjects = require('./taosobjects'); +const TaosRow = TaosObjects.TaosRow; +const TaosField = TaosObjects.TaosField; + +module.exports = TaosResult; +/** + * @class TaosResult + * @classdesc A TaosResult class consts of the row data and the fields metadata, all wrapped under various objects for higher functionality. + * @param {Array} data - Array of result rows + * @param {Array} fields - Array of field meta data + * @property {Array} data - Array of TaosRows forming the result data (this does not include field meta data) + * @property {Array} fields - Array of TaosFields forming the fields meta data array. + * @return {TaosResult} + * @since 1.0.6 + */ +function TaosResult(data, fields) { + this.data = data.map(row => new TaosRow(row)); + this.rowcount = this.data.length; + this.fields = fields.map(field => new TaosField(field)); +} +/** + * Pretty print data and the fields meta data as if you were using the taos shell + * @memberof TaosResult + * @function pretty + * @since 1.0.6 + */ + +TaosResult.prototype.pretty = function pretty() { + let fieldsStr = ""; + let sizing = []; + this.fields.forEach((field,i) => { + if (field._field.type == 8 || field._field.type == 10){ + sizing.push(Math.max(field.name.length, field._field.bytes)); + } + else { + sizing.push(Math.max(field.name.length, suggestedMinWidths[field._field.type])); + } + fieldsStr += fillEmpty(Math.floor(sizing[i]/2 - field.name.length / 2)) + field.name + fillEmpty(Math.ceil(sizing[i]/2 - field.name.length / 2)) + " | "; + }); + var sumLengths = sizing.reduce((a,b)=> a+=b,(0)) + sizing.length * 3; + + console.log("\n" + fieldsStr); + console.log(printN("=",sumLengths)); + this.data.forEach(row => { + let rowStr = ""; + row.data.forEach((entry, i) => { + if (this.fields[i]._field.type == 9) { + entry = entry.toTaosString(); + } else { + entry = entry == null ? 'null' : entry.toString(); + } + rowStr += entry + rowStr += fillEmpty(sizing[i] - entry.length) + " | "; + }); + console.log(rowStr); + }); +} +const suggestedMinWidths = { + 0: 4, + 1: 4, + 2: 4, + 3: 6, + 4: 11, + 5: 12, + 6: 24, + 7: 24, + 8: 10, + 9: 25, + 10: 10, +} +function printN(s, n) { + let f = ""; + for (let i = 0; i < n; i ++) { + f += s; + } + return f; +} +function fillEmpty(n) { + let str = ""; + for (let i = 0; i < n; i++) { + str += " "; + } + return str; +} diff --git a/tests/connectorTest/nodejsTest/readme.md b/tests/connectorTest/nodejsTest/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..26a28afbdd514ad97e969302e7d790f6240bb770 --- /dev/null +++ b/tests/connectorTest/nodejsTest/readme.md @@ -0,0 +1,161 @@ +# TDengine Node.js connector +[![minzip](https://img.shields.io/bundlephobia/minzip/td2.0-connector.svg)](https://github.com/taosdata/TDengine/tree/master/src/connector/nodejs) [![NPM](https://img.shields.io/npm/l/td2.0-connector.svg)](https://github.com/taosdata/TDengine/#what-is-tdengine) + +This is the Node.js library that lets you connect to [TDengine](https://www.github.com/taosdata/tdengine) 2.0 version. It is built so that you can use as much of it as you want or as little of it as you want through providing an extensive API. If you want the raw data in the form of an array of arrays for the row data retrieved from a table, you can do that. If you want to wrap that data with objects that allow you easily manipulate and display data such as using a prettifier function, you can do that! + +## Installation + +To get started, just type in the following to install the connector through [npm](https://www.npmjs.com/) + +```cmd +npm install td2.0-connector +``` + +To interact with TDengine, we make use of the [node-gyp](https://github.com/nodejs/node-gyp) library. To install, you will need to install the following depending on platform (the following instructions are quoted from node-gyp) + +### On Linux + +- `python` (`v2.7` recommended, `v3.x.x` is **not** supported) +- `make` +- A proper C/C++ compiler toolchain, like [GCC](https://gcc.gnu.org) +- `node` (between `v10.x` and `v11.x`, other version has some dependency compatibility problems) + +### On macOS + +- `python` (`v2.7` recommended, `v3.x.x` is **not** supported) (already installed on macOS) + +- Xcode + + - You also need to install the + + ``` + Command Line Tools + ``` + + via Xcode. You can find this under the menu + + ``` + Xcode -> Preferences -> Locations + ``` + + (or by running + + ``` + xcode-select --install + ``` + + in your Terminal) + + - This step will install `gcc` and the related toolchain containing `make` + +### On Windows + +#### Option 1 + +Install all the required tools and configurations using Microsoft's [windows-build-tools](https://github.com/felixrieseberg/windows-build-tools) using `npm install --global --production windows-build-tools` from an elevated PowerShell or CMD.exe (run as Administrator). + +#### Option 2 + +Install tools and configuration manually: + +- Install Visual C++ Build Environment: [Visual Studio Build Tools](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools) (using "Visual C++ build tools" workload) or [Visual Studio 2017 Community](https://visualstudio.microsoft.com/pl/thank-you-downloading-visual-studio/?sku=Community) (using the "Desktop development with C++" workload) +- Install [Python 2.7](https://www.python.org/downloads/) (`v3.x.x` is not supported), and run `npm config set python python2.7` (or see below for further instructions on specifying the proper Python version and path.) +- Launch cmd, `npm config set msvs_version 2017` + +If the above steps didn't work for you, please visit [Microsoft's Node.js Guidelines for Windows](https://github.com/Microsoft/nodejs-guidelines/blob/master/windows-environment.md#compiling-native-addon-modules) for additional tips. + +To target native ARM64 Node.js on Windows 10 on ARM, add the components "Visual C++ compilers and libraries for ARM64" and "Visual C++ ATL for ARM64". + +## Usage + +The following is a short summary of the basic usage of the connector, the full api and documentation can be found [here](http://docs.taosdata.com/node) + +### Connection + +To use the connector, first require the library ```td2.0-connector```. Running the function ```taos.connect``` with the connection options passed in as an object will return a TDengine connection object. The required connection option is ```host```, other options if not set, will be the default values as shown below. + +A cursor also needs to be initialized in order to interact with TDengine from Node.js. + +```javascript +const taos = require('td2.0-connector'); +var conn = taos.connect({host:"127.0.0.1", user:"root", password:"taosdata", config:"/etc/taos",port:0}) +var cursor = conn.cursor(); // Initializing a new cursor +``` + +Close a connection + +```javascript +conn.close(); +``` + +### Queries + +We can now start executing simple queries through the ```cursor.query``` function, which returns a TaosQuery object. + +```javascript +var query = cursor.query('show databases;') +``` + +We can get the results of the queries through the ```query.execute()``` function, which returns a promise that resolves with a TaosResult object, which contains the raw data and additional functionalities such as pretty printing the results. + +```javascript +var promise = query.execute(); +promise.then(function(result) { + result.pretty(); //logs the results to the console as if you were in the taos shell +}); +``` + +You can also query by binding parameters to a query by filling in the question marks in a string as so. The query will automatically parse what was binded and convert it to the proper format for use with TDengine +```javascript +var query = cursor.query('select * from meterinfo.meters where ts <= ? and areaid = ?;').bind(new Date(), 5); +query.execute().then(function(result) { + result.pretty(); +}) +``` + +The TaosQuery object can also be immediately executed upon creation by passing true as the second argument, returning a promise instead of a TaosQuery. +```javascript +var promise = cursor.query('select * from meterinfo.meters where v1 = 30;', true) +promise.then(function(result) { + result.pretty(); +}) +``` + +If you want to execute queries without objects being wrapped around the data, use ```cursor.execute()``` directly and ```cursor.fetchall()``` to retrieve data if there is any. +```javascript +cursor.execute('select count(*), avg(v1), min(v2) from meterinfo.meters where ts >= \"2019-07-20 00:00:00.000\";'); +var data = cursor.fetchall(); +console.log(cursor.fields); // Latest query's Field metadata is stored in cursor.fields +console.log(cursor.data); // Latest query's result data is stored in cursor.data, also returned by fetchall. +``` + +### Async functionality + +Async queries can be performed using the same functions such as `cursor.execute`, `TaosQuery.query`, but now with `_a` appended to them. + +Say you want to execute an two async query on two separate tables, using `cursor.query`, you can do that and get a TaosQuery object, which upon executing with the `execute_a` function, returns a promise that resolves with a TaosResult object. + +```javascript +var promise1 = cursor.query('select count(*), avg(v1), avg(v2) from meter1;').execute_a() +var promise2 = cursor.query('select count(*), avg(v1), avg(v2) from meter2;').execute_a(); +promise1.then(function(result) { + result.pretty(); +}) +promise2.then(function(result) { + result.pretty(); +}) +``` + +## Example + +An example of using the NodeJS connector to create a table with weather data and create and execute queries can be found [here](https://github.com/taosdata/TDengine/tree/master/tests/examples/nodejs/node-example.js) (The preferred method for using the connector) + +An example of using the NodeJS connector to achieve the same things but without all the object wrappers that wrap around the data returned to achieve higher functionality can be found [here](https://github.com/taosdata/TDengine/tree/master/tests/examples/nodejs/node-example-raw.js) + +## Contributing to TDengine + +Please follow the [contribution guidelines](https://github.com/taosdata/TDengine/blob/master/CONTRIBUTING.md) to contribute to the project. + +## License + +[GNU AGPL v3.0](http://www.gnu.org/licenses/agpl-3.0.html) diff --git a/tests/connectorTest/nodejsTest/tdengine.js b/tests/connectorTest/nodejsTest/tdengine.js new file mode 100644 index 0000000000000000000000000000000000000000..047c744a4fc90c6306e851eaa529a7f9f578fe12 --- /dev/null +++ b/tests/connectorTest/nodejsTest/tdengine.js @@ -0,0 +1,4 @@ +var TDengineConnection = require('./nodetaos/connection.js') +module.exports.connect = function (connection={}) { + return new TDengineConnection(connection); +} diff --git a/tests/connectorTest/nodejsTest/test/performance.js b/tests/connectorTest/nodejsTest/test/performance.js new file mode 100644 index 0000000000000000000000000000000000000000..ea197f034435e28edd67df8d5f4b141f410fed81 --- /dev/null +++ b/tests/connectorTest/nodejsTest/test/performance.js @@ -0,0 +1,89 @@ +function memoryUsageData() { + let s = process.memoryUsage() + for (key in s) { + s[key] = (s[key]/1000000).toFixed(3) + "MB"; + } + return s; +} +console.log("initial mem usage:", memoryUsageData()); + +const { PerformanceObserver, performance } = require('perf_hooks'); +const taos = require('../tdengine'); +var conn = taos.connect({host:"127.0.0.1", user:"root", password:"taosdata", config:"/etc/taos",port:0}); +var c1 = conn.cursor(); + +// Initialize env +c1.execute('create database if not exists td_connector_test;'); +c1.execute('use td_connector_test;') +c1.execute('create table if not exists all_types (ts timestamp, _int int, _bigint bigint, _float float, _double double, _binary binary(40), _smallint smallint, _tinyint tinyint, _bool bool, _nchar nchar(40));'); +c1.execute('create table if not exists stabletest (ts timestamp, v1 int, v2 int, v3 int, v4 double) tags (id int, location binary(20));') + + +// Insertion into single table Performance Test +var dataPrepTime = 0; +var insertTime = 0; +var insertTime5000 = 0; +var avgInsert5ktime = 0; +const obs = new PerformanceObserver((items) => { + let entry = items.getEntries()[0]; + + if (entry.name == 'Data Prep') { + dataPrepTime += entry.duration; + } + else if (entry.name == 'Insert'){ + insertTime += entry.duration + } + else { + console.log(entry.name + ': ' + (entry.duration/1000).toFixed(8) + 's'); + } + performance.clearMarks(); +}); +obs.observe({ entryTypes: ['measure'] }); + +function R(l,r) { + return Math.random() * (r - l) - r; +} +function randomBool() { + if (Math.random() < 0.5) { + return true; + } + return false; +} +function insertN(n) { + for (let i = 0; i < n; i++) { + performance.mark('A3'); + let insertData = ["now + " + i + "m", // Timestamp + parseInt( R(-Math.pow(2,31) + 1 , Math.pow(2,31) - 1) ), // Int + parseInt( R(-Math.pow(2,31) + 1 , Math.pow(2,31) - 1) ), // BigInt + parseFloat( R(-3.4E38, 3.4E38) ), // Float + parseFloat( R(-1.7E308, 1.7E308) ), // Double + "\"Long Binary\"", // Binary + parseInt( R(-32767, 32767) ), // Small Int + parseInt( R(-127, 127) ), // Tiny Int + randomBool(), + "\"Nchars 一些中文字幕\""]; // Bool + let query = 'insert into td_connector_test.all_types values(' + insertData.join(',') + ' );'; + performance.mark('B3'); + performance.measure('Data Prep', 'A3', 'B3'); + performance.mark('A2'); + c1.execute(query, {quiet:true}); + performance.mark('B2'); + performance.measure('Insert', 'A2', 'B2'); + if ( i % 5000 == 4999) { + console.log("Insert # " + (i+1)); + console.log('Insert 5k records: ' + ((insertTime - insertTime5000)/1000).toFixed(8) + 's'); + insertTime5000 = insertTime; + avgInsert5ktime = (avgInsert5ktime/1000 * Math.floor(i / 5000) + insertTime5000/1000) / Math.ceil( i / 5000); + console.log('DataPrepTime So Far: ' + (dataPrepTime/1000).toFixed(8) + 's | Inserting time So Far: ' + (insertTime/1000).toFixed(8) + 's | Avg. Insert 5k time: ' + avgInsert5ktime.toFixed(8)); + + + } + } +} +performance.mark('insert 1E5') +insertN(1E5); +performance.mark('insert 1E5 2') +performance.measure('Insert With Logs', 'insert 1E5', 'insert 1E5 2'); +console.log('DataPrepTime: ' + (dataPrepTime/1000).toFixed(8) + 's | Inserting time: ' + (insertTime/1000).toFixed(8) + 's'); +dataPrepTime = 0; insertTime = 0; +//'insert into td_connector_test.all_types values (now, null,null,null,null,null,null,null,null,null);' diff --git a/tests/connectorTest/nodejsTest/test/test.js b/tests/connectorTest/nodejsTest/test/test.js new file mode 100644 index 0000000000000000000000000000000000000000..caf05955da4c960ebedc872f400c17d18be767dd --- /dev/null +++ b/tests/connectorTest/nodejsTest/test/test.js @@ -0,0 +1,170 @@ +const taos = require('../tdengine'); +var conn = taos.connect(); +var c1 = conn.cursor(); +let stime = new Date(); +let interval = 1000; + +function convertDateToTS(date) { + let tsArr = date.toISOString().split("T") + return "\"" + tsArr[0] + " " + tsArr[1].substring(0, tsArr[1].length-1) + "\""; +} +function R(l,r) { + return Math.random() * (r - l) - r; +} +function randomBool() { + if (Math.random() < 0.5) { + return true; + } + return false; +} + +// Initialize +//c1.execute('drop database td_connector_test;'); +c1.execute('create database if not exists td_connector_test;'); +c1.execute('use td_connector_test;') +c1.execute('create table if not exists all_types (ts timestamp, _int int, _bigint bigint, _float float, _double double, _binary binary(40), _smallint smallint, _tinyint tinyint, _bool bool, _nchar nchar(40));'); +c1.execute('create table if not exists stabletest (ts timestamp, v1 int, v2 int, v3 int, v4 double) tags (id int, location binary(20));') + +// Shell Test : The following uses the cursor to imitate the taos shell + +// Insert +for (let i = 0; i < 10000; i++) { + let insertData = ["now+" + i + "s", // Timestamp + parseInt( R(-Math.pow(2,31) + 1 , Math.pow(2,31) - 1) ), // Int + parseInt( R(-Math.pow(2,31) + 1 , Math.pow(2,31) - 1) ), // BigInt + parseFloat( R(-3.4E38, 3.4E38) ), // Float + parseFloat( R(-1.7E30, 1.7E30) ), // Double + "\"Long Binary\"", // Binary + parseInt( R(-32767, 32767) ), // Small Int + parseInt( R(-127, 127) ), // Tiny Int + randomBool(), + "\"Nchars\""]; // Bool + c1.execute('insert into td_connector_test.all_types values(' + insertData.join(',') + ' );', {quiet:true}); + if (i % 1000 == 0) { + console.log("Insert # " , i); + } +} + +// Select +console.log('select * from td_connector_test.all_types limit 3 offset 100;'); +c1.execute('select * from td_connector_test.all_types limit 2 offset 100;'); + +var d = c1.fetchall(); +console.log(c1.fields); +console.log(d); + +// Functions +console.log('select count(*), avg(_int), sum(_float), max(_bigint), min(_double) from td_connector_test.all_types;') +c1.execute('select count(*), avg(_int), sum(_float), max(_bigint), min(_double) from td_connector_test.all_types;'); +var d = c1.fetchall(); +console.log(c1.fields); +console.log(d); + +// Immediate Execution like the Shell + +c1.query('select count(*), stddev(_double), min(_tinyint) from all_types where _tinyint > 50 and _int < 0;', true).then(function(result){ + result.pretty(); +}) + +c1.query('select _tinyint, _bool from all_types where _tinyint > 50 and _int < 0 limit 50;', true).then(function(result){ + result.pretty(); +}) + +c1.query('select stddev(_double), stddev(_bigint), stddev(_float) from all_types;', true).then(function(result){ + result.pretty(); +}) +c1.query('select stddev(_double), stddev(_bigint), stddev(_float) from all_types interval(1m) limit 100;', true).then(function(result){ + result.pretty(); +}) + +// Binding arguments, and then using promise +var q = c1.query('select _nchar from td_connector_test.all_types where ts >= ? and _int > ? limit 100 offset 40;').bind(new Date(1231), 100) +console.log(q.query); +q.execute().then(function(r) { + r.pretty(); +}); + + +// test query null value +c1.execute("create table if not exists td_connector_test.weather(ts timestamp, temperature float, humidity int) tags(location nchar(64))"); +c1.execute("insert into t1 using weather tags('北京') values(now, 11.11, 11)"); +c1.execute("insert into t1(ts, temperature) values(now, 22.22)"); +c1.execute("insert into t1(ts, humidity) values(now, 33)"); +c1.query('select * from test.t1', true).then(function (result) { + result.pretty(); +}); + +var q = c1.query('select * from td_connector_test.weather'); +console.log(q.query); +q.execute().then(function(r) { + r.pretty(); +}); + +function sleep(sleepTime) { + for(var start = +new Date; +new Date - start <= sleepTime; ) { } +} + +sleep(10000); + +// Raw Async Testing (Callbacks, not promises) +function cb2(param, result, rowCount, rd) { + console.log('CB2 Callbacked!'); + console.log("RES *", result); + console.log("Async fetched", rowCount, " rows"); + console.log("Passed Param: ", param); + console.log("Fields ", rd.fields); + console.log("Data ", rd.data); +} +function cb1(param,result,code) { + console.log('CB1 Callbacked!'); + console.log("RES * ", result); + console.log("Status: ", code); + console.log("Passed Param ", param); + c1.fetchall_a(result, cb2, param); +} + +c1.execute_a("describe td_connector_test.all_types;", cb1, {myparam:3.141}); + +function cb4(param, result, rowCount, rd) { + console.log('CB4 Callbacked!'); + console.log("RES *", result); + console.log("Async fetched", rowCount, "rows"); + console.log("Passed Param: ", param); + console.log("Fields", rd.fields); + console.log("Data", rd.data); +} +// Without directly calling fetchall_a +var thisRes; +function cb3(param,result,code) { + console.log('CB3 Callbacked!'); + console.log("RES *", result); + console.log("Status:", code); + console.log("Passed Param", param); + thisRes = result; +} +//Test calling execute and fetchall seperately and not through callbacks +var param = c1.execute_a("describe td_connector_test.all_types;", cb3, {e:2.718}); +console.log("Passed Param outside of callback: ", param); +console.log(param); +setTimeout(function(){ + c1.fetchall_a(thisRes, cb4, param); +},100); + + +// Async through promises +var aq = c1.query('select count(*) from td_connector_test.all_types;',false); +aq.execute_a().then(function(data) { + data.pretty(); +}); + +c1.query('describe td_connector_test.stabletest').execute_a().then(function(r){ + r.pretty() +}); + +setTimeout(function(){ + c1.query('drop database td_connector_test;'); +},200); + +setTimeout(function(){ + conn.close(); +},2000); diff --git a/tests/connectorTest/nodejsTest/test/testMicroseconds.js b/tests/connectorTest/nodejsTest/test/testMicroseconds.js new file mode 100644 index 0000000000000000000000000000000000000000..cc65b3d919f92b3b4d7e0e216c6c8ac64a294d7f --- /dev/null +++ b/tests/connectorTest/nodejsTest/test/testMicroseconds.js @@ -0,0 +1,49 @@ +const taos = require('../tdengine'); +var conn = taos.connect(); +var c1 = conn.cursor(); +let stime = new Date(); +let interval = 1000; + +function convertDateToTS(date) { + let tsArr = date.toISOString().split("T") + return "\"" + tsArr[0] + " " + tsArr[1].substring(0, tsArr[1].length - 1) + "\""; +} +function R(l, r) { + return Math.random() * (r - l) - r; +} +function randomBool() { + if (Math.random() < 0.5) { + return true; + } + return false; +} + +// Initialize +//c1.execute('drop database td_connector_test;'); +const dbname = 'nodejs_test_us'; +c1.execute('create database if not exists ' + dbname + ' precision "us"'); +c1.execute('use ' + dbname) +c1.execute('create table if not exists tstest (ts timestamp, _int int);'); +c1.execute('insert into tstest values(1625801548423914, 0)'); +// Select +console.log('select * from tstest'); +c1.execute('select * from tstest'); + +var d = c1.fetchall(); +console.log(c1.fields); +let ts = d[0][0]; +console.log(ts); + +if (ts.taosTimestamp() != 1625801548423914) { + throw "microseconds not match!"; +} +if (ts.getMicroseconds() % 1000 !== 914) { + throw "micronsecond precision error"; +} +setTimeout(function () { + c1.query('drop database nodejs_us_test;'); +}, 200); + +setTimeout(function () { + conn.close(); +}, 2000); diff --git a/tests/connectorTest/nodejsTest/test/testNanoseconds.js b/tests/connectorTest/nodejsTest/test/testNanoseconds.js new file mode 100644 index 0000000000000000000000000000000000000000..85a7600b01f2c908f22e621488f22678083149ea --- /dev/null +++ b/tests/connectorTest/nodejsTest/test/testNanoseconds.js @@ -0,0 +1,49 @@ +const taos = require('../tdengine'); +var conn = taos.connect(); +var c1 = conn.cursor(); +let stime = new Date(); +let interval = 1000; + +function convertDateToTS(date) { + let tsArr = date.toISOString().split("T") + return "\"" + tsArr[0] + " " + tsArr[1].substring(0, tsArr[1].length - 1) + "\""; +} +function R(l, r) { + return Math.random() * (r - l) - r; +} +function randomBool() { + if (Math.random() < 0.5) { + return true; + } + return false; +} + +// Initialize +//c1.execute('drop database td_connector_test;'); +const dbname = 'nodejs_test_ns'; +c1.execute('create database if not exists ' + dbname + ' precision "ns"'); +c1.execute('use ' + dbname) +c1.execute('create table if not exists tstest (ts timestamp, _int int);'); +c1.execute('insert into tstest values(1625801548423914405, 0)'); +// Select +console.log('select * from tstest'); +c1.execute('select * from tstest'); + +var d = c1.fetchall(); +console.log(c1.fields); +let ts = d[0][0]; +console.log(ts); + +if (ts.taosTimestamp() != 1625801548423914405) { + throw "nanosecond not match!"; +} +if (ts.getNanoseconds() % 1000000 !== 914405) { + throw "nanosecond precision error"; +} +setTimeout(function () { + c1.query('drop database nodejs_ns_test;'); +}, 200); + +setTimeout(function () { + conn.close(); +}, 2000); diff --git a/tests/connectorTest/nodejsTest/test/testSubscribe.js b/tests/connectorTest/nodejsTest/test/testSubscribe.js new file mode 100644 index 0000000000000000000000000000000000000000..30fb3f425683f0113873534f2b67255db811edcc --- /dev/null +++ b/tests/connectorTest/nodejsTest/test/testSubscribe.js @@ -0,0 +1,16 @@ +const taos = require('../tdengine'); +var conn = taos.connect({host:"127.0.0.1", user:"root", password:"taosdata", config:"/etc/taos",port:10}); +var c1 = conn.cursor(); +let stime = new Date(); +let interval = 1000; +c1.execute('use td_connector_test'); +let sub = c1.subscribe({ + restart: true, + sql: "select AVG(_int) from td_connector_test.all_Types;", + topic: 'all_Types', + interval: 1000 +}); + +c1.consumeData(sub, (data, fields) => { + console.log(data); +}); \ No newline at end of file diff --git a/tests/connectorTest/odbcTest/nanosupport/nanoTest_odbc.py b/tests/connectorTest/odbcTest/nanosupport/nanoTest_odbc.py new file mode 100644 index 0000000000000000000000000000000000000000..e6a4bc73aef3e19bc56e817325acd62d21156d67 --- /dev/null +++ b/tests/connectorTest/odbcTest/nanosupport/nanoTest_odbc.py @@ -0,0 +1,111 @@ +import pyodbc +import argparse +import sys + +parser = argparse.ArgumentParser(description='Access TDengine via ODBC.') +parser.add_argument('--DSN', help='DSN to use') +parser.add_argument('--UID', help='UID to use') +parser.add_argument('--PWD', help='PWD to use') +parser.add_argument('--Server', help='Server to use') +parser.add_argument('-C', metavar='CONNSTR', help='Connection string to use') + +args = parser.parse_args() + +a = 'DSN=%s'%args.DSN if args.DSN else None +b = 'UID=%s'%args.UID if args.UID else None +c = 'PWD=%s'%args.PWD if args.PWD else None +d = 'Server=%s'%args.Server if args.Server else None +conn_str = ';'.join(filter(None, [a,b,c,d])) if args.DSN else None +conn_str = conn_str if conn_str else args.C +if not conn_str: + parser.print_help(file=sys.stderr) + exit() + +print('connecting: [%s]' % conn_str) +cnxn = pyodbc.connect(conn_str, autocommit=True) +cnxn.setdecoding(pyodbc.SQL_CHAR, encoding='utf-8') + +cursor = cnxn.cursor() +cursor.execute("drop database if exists db"); +cursor.close() + +cursor = cnxn.cursor() +cursor.execute("create database db"); +cursor.close() + +cursor = cnxn.cursor() +cursor.execute("create table db.mt (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, bin binary(10), blob nchar(10))"); +cursor.close() + +cursor = cnxn.cursor() +cursor.execute("insert into db.mt values('2020-10-13 06:44:00.123', 1, 127, 32767, 2147483647, 32769, 123.456, 789.987, 'hello', 'helloworld')") +cursor.close() + +cursor = cnxn.cursor() +cursor.execute("insert into db.mt values(?,?,?,?,?,?,?,?,?,?)", "2020-10-13 07:06:00.234", 0, 127, 32767, 32768, 32769, 123.456, 789.987, "hel后lo".encode('utf-8'), "wo哈rlxd129") +##cursor.execute("insert into db.mt values(?,?,?,?,?,?,?,?,?,?)", 1502535178128, 9223372036854775807, 127, 32767, 32768, 32769, 123.456, 789.987, "hel后lo".encode('utf-8'), "wo哈rlxd123"); +cursor.close() + +cursor = cnxn.cursor() +cursor.execute(""" +INSERT INTO db.mt (ts,b,v1,v2,v4,v8,f4,f8,bin,blob) values (?,?,?,?,?,?,?,?,?,?) +""", +"2020-12-12 00:00:00", +'true', +'-127', +'-32767', +'-2147483647', +'-9223372036854775807', +'-1.23e10', +'-11.23e6', +'abcdefghij'.encode('utf-8'), +"人啊大发测试及abc") +cursor.close() + +cursor = cnxn.cursor() +cursor.execute("drop database if exists db"); +cursor.close() + +cursor = cnxn.cursor() +cursor.execute("create database db"); +cursor.close() + +cursor = cnxn.cursor() +cursor.execute("create table db.t (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, bin binary(4), blob nchar(4))"); +cursor.close() + +cursor = cnxn.cursor() +cursor.execute("insert into db.t values('2020-10-13 06:44:00', 1, 127, 32767, 32768, 32769, 123.456, 789.987, 'hell', 'w我你z')") +cursor.close() + +cursor = cnxn.cursor() +cursor.execute("create table db.v (ts timestamp, v1 tinyint, v2 smallint, name nchar(10), ts2 timestamp)") +cursor.close() + +params = [ ('2020-10-16 00:00:00.123', 19, '2111-01-02 01:02:03.123'), + ('2020-10-16 00:00:01', 41, '2111-01-02 01:02:03.423'), + ('2020-10-16 00:00:02', 57, '2111-01-02 01:02:03.153'), + ('2020-10-16 00:00:03.009', 26, '2111-01-02 01:02:03.623') ] +cursor = cnxn.cursor() +cursor.fast_executemany = True +print('py:...................') +cursor.executemany("insert into db.v (ts, v1, ts2) values (?, ?, ?)", params) +print('py:...................') +cursor.close() + +## cursor = cnxn.cursor() +## cursor.execute("SELECT * from db.v where v1 > ?", 4) +## row = cursor.fetchone() +## while row: +## print(row) +## row = cursor.fetchone() +## cursor.close() +## +## cursor = cnxn.cursor() +## cursor.execute("SELECT * from db.v where v1 > ?", '5') +## row = cursor.fetchone() +## while row: +## print(row) +## row = cursor.fetchone() +## cursor.close() + diff --git a/tests/connectorTest/odbcTest/nanosupport/odbc.go b/tests/connectorTest/odbcTest/nanosupport/odbc.go new file mode 100644 index 0000000000000000000000000000000000000000..4d9c760c4e87a4a899051edc74692ecca8a19d15 --- /dev/null +++ b/tests/connectorTest/odbcTest/nanosupport/odbc.go @@ -0,0 +1,84 @@ +package main + +import ( + "context" + "database/sql" + "flag" + "log" + "os" + "os/signal" + "time" + _ "github.com/alexbrainman/odbc" +) + +var pool *sql.DB // Database connection pool. + +func main() { + id := flag.Int64("id", 32768, "person ID to find") + dsn := flag.String("dsn", os.Getenv("DSN"), "connection data source name") + flag.Parse() + + if len(*dsn) == 0 { + log.Fatal("missing dsn flag") + } + if *id == 0 { + log.Fatal("missing person ID") + } + var err error + + // Opening a driver typically will not attempt to connect to the database. + pool, err = sql.Open("odbc", *dsn) + if err != nil { + // This will not be a connection error, but a DSN parse error or + // another initialization error. + log.Fatal("unable to use data source name", err) + } + defer pool.Close() + + pool.SetConnMaxLifetime(0) + pool.SetMaxIdleConns(3) + pool.SetMaxOpenConns(3) + + ctx, stop := context.WithCancel(context.Background()) + defer stop() + + appSignal := make(chan os.Signal, 3) + signal.Notify(appSignal, os.Interrupt) + + go func() { + select { + case <-appSignal: + stop() + } + }() + + Ping(ctx) + + Query(ctx, *id) +} + +// Ping the database to verify DSN provided by the user is valid and the +// server accessible. If the ping fails exit the program with an error. +func Ping(ctx context.Context) { + ctx, cancel := context.WithTimeout(ctx, 1*time.Second) + defer cancel() + + if err := pool.PingContext(ctx); err != nil { + log.Fatalf("unable to connect to database: %v", err) + } +} + +// Query the database for the information requested and prints the results. +// If the query fails exit the program with an error. +func Query(ctx context.Context, id int64) { + ctx, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() + + var name string + err := pool.QueryRowContext(ctx, "select name from m.t").Scan(&name) + if err != nil { + log.Fatal("unable to execute search query", err) + } + log.Println("name=", name) +} + diff --git a/tests/connectorTest/odbcTest/nanosupport/odbc.py b/tests/connectorTest/odbcTest/nanosupport/odbc.py new file mode 100644 index 0000000000000000000000000000000000000000..cee0cf1a13f6360790de368637e2b6a05de3564f --- /dev/null +++ b/tests/connectorTest/odbcTest/nanosupport/odbc.py @@ -0,0 +1,115 @@ +import pyodbc +import argparse +import sys + +parser = argparse.ArgumentParser(description='Access TDengine via ODBC.') +parser.add_argument('--DSN', help='DSN to use') +parser.add_argument('--UID', help='UID to use') +parser.add_argument('--PWD', help='PWD to use') +parser.add_argument('--Server', help='Server to use') +parser.add_argument('-C', metavar='CONNSTR', help='Connection string to use') + +args = parser.parse_args() + +a = 'DSN=%s'%args.DSN if args.DSN else None +b = 'UID=%s'%args.UID if args.UID else None +c = 'PWD=%s'%args.PWD if args.PWD else None +d = 'Server=%s'%args.Server if args.Server else None +conn_str = ';'.join(filter(None, [a,b,c,d])) if args.DSN else None +conn_str = conn_str if conn_str else args.C +if not conn_str: + parser.print_help(file=sys.stderr) + exit() + +print('connecting: [%s]' % conn_str) +cnxn = pyodbc.connect(conn_str, autocommit=True) +cnxn.setdecoding(pyodbc.SQL_CHAR, encoding='utf-8') + +cursor = cnxn.cursor() +cursor.execute("drop database if exists db"); +cursor.close() + +cursor = cnxn.cursor() +cursor.execute("create database db"); +cursor.close() + +cursor = cnxn.cursor() +cursor.execute("create table db.mt (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, bin binary(10), blob nchar(10))"); +cursor.close() + +cursor = cnxn.cursor() +cursor.execute("insert into db.mt values('2020-10-13 06:44:00.123', 1, 127, 32767, 2147483647, 32769, 123.456, 789.987, 'hello', 'helloworld')") +cursor.close() + +cursor = cnxn.cursor() +cursor.execute("insert into db.mt values(?,?,?,?,?,?,?,?,?,?)", "2020-10-13 07:06:00.234", 0, 127, 32767, 32768, 32769, 123.456, 789.987, "hel后lo".encode('utf-8'), "wo哈rlxd129") +##cursor.execute("insert into db.mt values(?,?,?,?,?,?,?,?,?,?)", 1502535178128, 9223372036854775807, 127, 32767, 32768, 32769, 123.456, 789.987, "hel后lo".encode('utf-8'), "wo哈rlxd123"); +cursor.close() + +cursor = cnxn.cursor() +cursor.execute(""" +INSERT INTO db.mt (ts,b,v1,v2,v4,v8,f4,f8,bin,blob) values (?,?,?,?,?,?,?,?,?,?) +""", +"2020-12-12 00:00:00", +'true', +'-127', +'-32767', +'-2147483647', +'-9223372036854775807', +'-1.23e10', +'-11.23e6', +'abcdefghij'.encode('utf-8'), +"人啊大发测试及abc") +cursor.close() + +cursor = cnxn.cursor() +cursor.execute("drop database if exists db"); +cursor.close() + +cursor = cnxn.cursor() +cursor.execute("create database db"); +cursor.close() + +cursor = cnxn.cursor() +cursor.execute("create table db.t (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, bin binary(4), blob nchar(4))"); +cursor.close() + +cursor = cnxn.cursor() +cursor.execute("insert into db.t values('2020-10-13 06:44:00', 1, 127, 32767, 32768, 32769, 123.456, 789.987, 'hell', 'w我你z')") +cursor.close() + +cursor = cnxn.cursor() +cursor.execute("create table db.v (ts timestamp, v1 tinyint, v2 smallint, name nchar(10), ts2 timestamp)") +cursor.close() + +cursor = cnxn.cursor() +cursor.execute("select * from db.v") +cursor.close() + +params = [ ('2020-10-16 00:00:00.123', 19, '2111-01-02 01:02:03.123'), + ('2020-10-16 00:00:01', 41, '2111-01-02 01:02:03.423'), + ('2020-10-16 00:00:02', 57, '2111-01-02 01:02:03.153'), + ('2020-10-16 00:00:03.009', 26, '2111-01-02 01:02:03.623') ] +cursor = cnxn.cursor() +cursor.fast_executemany = True +print('py:...................') +cursor.executemany("insert into db.v (ts, v1, ts2) values (?, ?, ?)", params) +print('py:...................') +cursor.close() + +## cursor = cnxn.cursor() +## cursor.execute("SELECT * from db.v where v1 > ?", 4) +## row = cursor.fetchone() +## while row: +## print(row) +## row = cursor.fetchone() +## cursor.close() +## +## cursor = cnxn.cursor() +## cursor.execute("SELECT * from db.v where v1 > ?", '5') +## row = cursor.fetchone() +## while row: +## print(row) +## row = cursor.fetchone() +## cursor.close() + diff --git a/tests/examples/JDBC/JDBCDemo/pom.xml b/tests/examples/JDBC/JDBCDemo/pom.xml index fed00c147b87621c70d60ea206b06f1b0f3e8d8f..8cf0356721f8ffd568e87fa4a77c86eb0f90a62b 100644 --- a/tests/examples/JDBC/JDBCDemo/pom.xml +++ b/tests/examples/JDBC/JDBCDemo/pom.xml @@ -17,7 +17,7 @@ com.taosdata.jdbc taos-jdbcdriver - 2.0.31 + 2.0.34 diff --git a/tests/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcDemo.java b/tests/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcDemo.java index d4ea5f919d2882e4f82b817380172eff20d7c611..5bc23403087578c0791b0a5e6fca74a47aad8184 100644 --- a/tests/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcDemo.java +++ b/tests/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcDemo.java @@ -7,6 +7,9 @@ public class JdbcDemo { private static String host; private static final String dbName = "test"; private static final String tbName = "weather"; + private static final String user = "root"; + private static final String password = "taosdata"; + private Connection connection; public static void main(String[] args) { @@ -30,10 +33,9 @@ public class JdbcDemo { } private void init() { - final String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"; + final String url = "jdbc:TAOS://" + host + ":6030/?user=" + user + "&password=" + password; // get connection try { - Class.forName("com.taosdata.jdbc.TSDBDriver"); Properties properties = new Properties(); properties.setProperty("charset", "UTF-8"); properties.setProperty("locale", "en_US.UTF-8"); @@ -42,8 +44,7 @@ public class JdbcDemo { connection = DriverManager.getConnection(url, properties); if (connection != null) System.out.println("[ OK ] Connection established."); - } catch (ClassNotFoundException | SQLException e) { - System.out.println("[ ERROR! ] Connection establish failed."); + } catch (SQLException e) { e.printStackTrace(); } } @@ -74,7 +75,7 @@ public class JdbcDemo { } private void select() { - final String sql = "select * from "+ dbName + "." + tbName; + final String sql = "select * from " + dbName + "." + tbName; executeQuery(sql); } @@ -89,8 +90,6 @@ public class JdbcDemo { } } - /************************************************************************/ - private void executeQuery(String sql) { long start = System.currentTimeMillis(); try (Statement statement = connection.createStatement()) { @@ -117,7 +116,6 @@ public class JdbcDemo { } } - private void printSql(String sql, boolean succeed, long cost) { System.out.println("[ " + (succeed ? "OK" : "ERROR!") + " ] time cost: " + cost + " ms, execute statement ====> " + sql); } @@ -132,7 +130,6 @@ public class JdbcDemo { long end = System.currentTimeMillis(); printSql(sql, false, (end - start)); e.printStackTrace(); - } } @@ -141,5 +138,4 @@ public class JdbcDemo { System.exit(0); } - -} \ No newline at end of file +} diff --git a/tests/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcRestfulDemo.java b/tests/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcRestfulDemo.java index 5bf980f6d84e53438573812aa9f07d8d463f08c3..d89476b8ca718dab24202e2320e842366533a763 100644 --- a/tests/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcRestfulDemo.java +++ b/tests/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcRestfulDemo.java @@ -4,14 +4,15 @@ import java.sql.*; import java.util.Properties; public class JdbcRestfulDemo { - private static final String host = "127.0.0.1"; + private static final String host = "localhost"; + private static final String dbname = "test"; + private static final String user = "root"; + private static final String password = "taosdata"; public static void main(String[] args) { try { - // load JDBC-restful driver - Class.forName("com.taosdata.jdbc.rs.RestfulDriver"); // use port 6041 in url when use JDBC-restful - String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata"; + String url = "jdbc:TAOS-RS://" + host + ":6041/?user=" + user + "&password=" + password; Properties properties = new Properties(); properties.setProperty("charset", "UTF-8"); @@ -21,12 +22,12 @@ public class JdbcRestfulDemo { Connection conn = DriverManager.getConnection(url, properties); Statement stmt = conn.createStatement(); - stmt.execute("drop database if exists restful_test"); - stmt.execute("create database if not exists restful_test"); - stmt.execute("use restful_test"); - stmt.execute("create table restful_test.weather(ts timestamp, temperature float) tags(location nchar(64))"); - stmt.executeUpdate("insert into t1 using restful_test.weather tags('北京') values(now, 18.2)"); - ResultSet rs = stmt.executeQuery("select * from restful_test.weather"); + stmt.execute("drop database if exists " + dbname); + stmt.execute("create database if not exists " + dbname); + stmt.execute("use " + dbname); + stmt.execute("create table " + dbname + ".weather(ts timestamp, temperature float) tags(location nchar(64))"); + stmt.executeUpdate("insert into t1 using " + dbname + ".weather tags('北京') values(now, 18.2)"); + ResultSet rs = stmt.executeQuery("select * from " + dbname + ".weather"); ResultSetMetaData meta = rs.getMetaData(); while (rs.next()) { for (int i = 1; i <= meta.getColumnCount(); i++) { @@ -38,8 +39,6 @@ public class JdbcRestfulDemo { rs.close(); stmt.close(); conn.close(); - } catch (ClassNotFoundException e) { - e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } diff --git a/tests/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/SubscribeDemo.java b/tests/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/SubscribeDemo.java index def4c649027034028d222bfedb71e37d82b99380..4c499b0b3abb518b48b222eca9bbbcb388bd2008 100644 --- a/tests/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/SubscribeDemo.java +++ b/tests/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/SubscribeDemo.java @@ -34,9 +34,8 @@ public class SubscribeDemo { System.out.println(usage); return; } - /*********************************************************************************************/ + try { - Class.forName("com.taosdata.jdbc.TSDBDriver"); Properties properties = new Properties(); properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); diff --git a/tests/examples/JDBC/springbootdemo/pom.xml b/tests/examples/JDBC/springbootdemo/pom.xml index 6c83718896cc2e5716f599ba08212d3dc8292133..9126813b67e71691692109920f891a6fb4cc5ab5 100644 --- a/tests/examples/JDBC/springbootdemo/pom.xml +++ b/tests/examples/JDBC/springbootdemo/pom.xml @@ -60,12 +60,15 @@ + + org.springframework.boot + spring-boot-starter-aop + + com.taosdata.jdbc taos-jdbcdriver - 2.0.28 - - + 2.0.34 diff --git a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/SpringbootdemoApplication.java b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/SpringbootdemoApplication.java index fa10f3b0929e4c25c1379f489f73fc12ad9c1917..53edaa5796cccc7e4a4f274048c83a9ca7bbc7bb 100644 --- a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/SpringbootdemoApplication.java +++ b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/SpringbootdemoApplication.java @@ -4,7 +4,7 @@ import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -@MapperScan(basePackages = {"com.taosdata.example.springbootdemo.dao"}) +@MapperScan(basePackages = {"com.taosdata.example.springbootdemo"}) @SpringBootApplication public class SpringbootdemoApplication { diff --git a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/controller/WeatherController.java b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/controller/WeatherController.java index cf14f5d84ace6348f38709ac3d3668ee8d2a0797..ed720fe6c02dd3a7eba6e645ea1e76d704c04d0c 100644 --- a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/controller/WeatherController.java +++ b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/controller/WeatherController.java @@ -15,35 +15,21 @@ public class WeatherController { @Autowired private WeatherService weatherService; - /** - * create database and table - * - * @return - */ + @GetMapping("/lastOne") + public Weather lastOne() { + return weatherService.lastOne(); + } + @GetMapping("/init") public int init() { return weatherService.init(); } - /** - * Pagination Query - * - * @param limit - * @param offset - * @return - */ @GetMapping("/{limit}/{offset}") public List queryWeather(@PathVariable Long limit, @PathVariable Long offset) { return weatherService.query(limit, offset); } - /** - * upload single weather info - * - * @param temperature - * @param humidity - * @return - */ @PostMapping("/{temperature}/{humidity}") public int saveWeather(@PathVariable float temperature, @PathVariable float humidity) { return weatherService.save(temperature, humidity); diff --git a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/dao/WeatherMapper.java b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/dao/WeatherMapper.java index ad6733558a9d548be196cf8c9c0c63dc96227b39..d9202b45b4cc3dddf8e5a082ac339c1f88d4ec01 100644 --- a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/dao/WeatherMapper.java +++ b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/dao/WeatherMapper.java @@ -8,6 +8,8 @@ import java.util.Map; public interface WeatherMapper { + Map lastOne(); + void dropDB(); void createDB(); diff --git a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/dao/WeatherMapper.xml b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/dao/WeatherMapper.xml index 2d3e0540650f35c1018992795ac33fb6cb7c4837..91938ca24e3cf9c3e0f2895cf40f214d484c55d5 100644 --- a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/dao/WeatherMapper.xml +++ b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/dao/WeatherMapper.xml @@ -9,20 +9,48 @@ + + - drop database if exists test + drop + database if exists test - create database if not exists test + create + database if not exists test - create table if not exists test.weather(ts timestamp, temperature float, humidity float) tags(location nchar(64), groupId int) + create table if not exists test.weather + ( + ts + timestamp, + temperature + float, + humidity + float, + note + binary + ( + 64 + )) tags + ( + location nchar + ( + 64 + ), groupId int) - create table if not exists test.t#{groupId} using test.weather tags(#{location}, #{groupId}) + create table if not exists test.t#{groupId} using test.weather tags + ( + #{location}, + #{groupId} + ) - insert into test.t#{groupId} (ts, temperature, humidity) values (#{ts}, ${temperature}, ${humidity}) + insert into test.t#{groupId} (ts, temperature, humidity, note) + values (#{ts}, ${temperature}, ${humidity}, #{note}) - - - + + + \ No newline at end of file diff --git a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/domain/Weather.java b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/domain/Weather.java index c11b9a6f50655788d1e35eb9607a101d2d06c872..e4238127bd32b0f6ad21a514f3a1f07f6069b6d5 100644 --- a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/domain/Weather.java +++ b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/domain/Weather.java @@ -11,6 +11,7 @@ public class Weather { private Float temperature; private Float humidity; private String location; + private String note; private int groupId; public Weather() { @@ -61,4 +62,12 @@ public class Weather { public void setGroupId(int groupId) { this.groupId = groupId; } + + public String getNote() { + return note; + } + + public void setNote(String note) { + this.note = note; + } } diff --git a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/service/WeatherService.java b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/service/WeatherService.java index 26d09c7d128015739cdb0a87956affa4910b4b4e..2264b200afc3e0c2b7dd8e496e607649f940581d 100644 --- a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/service/WeatherService.java +++ b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/service/WeatherService.java @@ -29,6 +29,7 @@ public class WeatherService { Weather weather = new Weather(new Timestamp(ts + (thirtySec * i)), 30 * random.nextFloat(), random.nextInt(100)); weather.setLocation(locations[random.nextInt(locations.length)]); weather.setGroupId(i % locations.length); + weather.setNote("note-" + i); weatherMapper.createTable(weather); count += weatherMapper.insert(weather); } @@ -58,4 +59,21 @@ public class WeatherService { public List avg() { return weatherMapper.avg(); } + + public Weather lastOne() { + Map result = weatherMapper.lastOne(); + + long ts = (long) result.get("ts"); + float temperature = (float) result.get("temperature"); + float humidity = (float) result.get("humidity"); + String note = (String) result.get("note"); + int groupId = (int) result.get("groupid"); + String location = (String) result.get("location"); + + Weather weather = new Weather(new Timestamp(ts), temperature, humidity); + weather.setNote(note); + weather.setGroupId(groupId); + weather.setLocation(location); + return weather; + } } diff --git a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/util/TaosAspect.java b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/util/TaosAspect.java new file mode 100644 index 0000000000000000000000000000000000000000..80dad1bd7d669ba6b912c7e5fa816c29b7e37c87 --- /dev/null +++ b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/util/TaosAspect.java @@ -0,0 +1,36 @@ +package com.taosdata.example.springbootdemo.util; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.stereotype.Component; + +import java.sql.Timestamp; +import java.util.Map; + +@Aspect +@Component +public class TaosAspect { + + @Around("execution(java.util.Map com.taosdata.example.springbootdemo.dao.*.*(..))") + public Object handleType(ProceedingJoinPoint joinPoint) { + Map result = null; + try { + result = (Map) joinPoint.proceed(); + for (String key : result.keySet()) { + Object obj = result.get(key); + if (obj instanceof byte[]) { + obj = new String((byte[]) obj); + result.put(key, obj); + } + if (obj instanceof Timestamp) { + obj = ((Timestamp) obj).getTime(); + result.put(key, obj); + } + } + } catch (Throwable e) { + e.printStackTrace(); + } + return result; + } +} diff --git a/tests/examples/JDBC/springbootdemo/src/main/resources/application.properties b/tests/examples/JDBC/springbootdemo/src/main/resources/application.properties index 4d7e64d10576388827502a459df9e68da2721dbb..06daa81bbb06450d99ab3f6e640c9795c0ad5d2e 100644 --- a/tests/examples/JDBC/springbootdemo/src/main/resources/application.properties +++ b/tests/examples/JDBC/springbootdemo/src/main/resources/application.properties @@ -1,22 +1,20 @@ # datasource config - JDBC-JNI #spring.datasource.driver-class-name=com.taosdata.jdbc.TSDBDriver -#spring.datasource.url=jdbc:TAOS://127.0.0.1:6030/test?timezone=UTC-8&charset=UTF-8&locale=en_US.UTF-8 +#spring.datasource.url=jdbc:TAOS://localhost:6030/?timezone=UTC-8&charset=UTF-8&locale=en_US.UTF-8 #spring.datasource.username=root #spring.datasource.password=taosdata - # datasource config - JDBC-RESTful spring.datasource.driver-class-name=com.taosdata.jdbc.rs.RestfulDriver -spring.datasource.url=jdbc:TAOS-RS://master:6041/test?timezone=UTC-8&charset=UTF-8&locale=en_US.UTF-8 +spring.datasource.url=jdbc:TAOS-RS://localhsot:6041/test?timezone=UTC-8&charset=UTF-8&locale=en_US.UTF-8 spring.datasource.username=root spring.datasource.password=taosdata - spring.datasource.druid.initial-size=5 spring.datasource.druid.min-idle=5 spring.datasource.druid.max-active=5 spring.datasource.druid.max-wait=30000 spring.datasource.druid.validation-query=select server_status(); - +spring.aop.auto=true +spring.aop.proxy-target-class=true #mybatis mybatis.mapper-locations=classpath:mapper/*.xml - logging.level.com.taosdata.jdbc.springbootdemo.dao=debug diff --git a/tests/examples/c/apitest.c b/tests/examples/c/apitest.c index 621950a834c515962f35e000279bc91e4c25b5e0..28e8d3f012dd4d6b4b12f2a01132b00a2ae7225c 100644 --- a/tests/examples/c/apitest.c +++ b/tests/examples/c/apitest.c @@ -2,6 +2,7 @@ // to compile: gcc -o apitest apitest.c -ltaos #include "taoserror.h" +#include "cJSON.h" #include #include @@ -1020,7 +1021,7 @@ int32_t verify_schema_less(TAOS* taos) { void verify_telnet_insert(TAOS* taos) { TAOS_RES *result; - result = taos_query(taos, "drop database if exists test;"); + result = taos_query(taos, "drop database if exists db;"); taos_free_result(result); usleep(100000); result = taos_query(taos, "create database db precision 'ms';"); @@ -1038,7 +1039,7 @@ void verify_telnet_insert(TAOS* taos) { }; code = taos_insert_telnet_lines(taos, lines0, 3); if (code) { - printf("code: %d, %s.\n", code, tstrerror(code)); + printf("lines0 code: %d, %s.\n", code, tstrerror(code)); } /* timestamp */ @@ -1052,7 +1053,7 @@ void verify_telnet_insert(TAOS* taos) { }; code = taos_insert_telnet_lines(taos, lines1, 6); if (code) { - printf("code: %d, %s.\n", code, tstrerror(code)); + printf("lines1 code: %d, %s.\n", code, tstrerror(code)); } /* metric value */ @@ -1063,7 +1064,7 @@ void verify_telnet_insert(TAOS* taos) { }; code = taos_insert_telnet_lines(taos, lines2_0, 2); if (code) { - printf("code: %d, %s.\n", code, tstrerror(code)); + printf("lines2_0 code: %d, %s.\n", code, tstrerror(code)); } //smallint @@ -1073,7 +1074,7 @@ void verify_telnet_insert(TAOS* taos) { }; code = taos_insert_telnet_lines(taos, lines2_1, 2); if (code) { - printf("code: %d, %s.\n", code, tstrerror(code)); + printf("lines2_1 code: %d, %s.\n", code, tstrerror(code)); } //int @@ -1083,7 +1084,7 @@ void verify_telnet_insert(TAOS* taos) { }; code = taos_insert_telnet_lines(taos, lines2_2, 2); if (code) { - printf("code: %d, %s.\n", code, tstrerror(code)); + printf("lines2_2 code: %d, %s.\n", code, tstrerror(code)); } //bigint @@ -1093,7 +1094,7 @@ void verify_telnet_insert(TAOS* taos) { }; code = taos_insert_telnet_lines(taos, lines2_3, 2); if (code) { - printf("code: %d, %s.\n", code, tstrerror(code)); + printf("lines2_3 code: %d, %s.\n", code, tstrerror(code)); } //float @@ -1112,7 +1113,7 @@ void verify_telnet_insert(TAOS* taos) { }; code = taos_insert_telnet_lines(taos, lines2_4, 11); if (code) { - printf("code: %d, %s.\n", code, tstrerror(code)); + printf("lines2_4 code: %d, %s.\n", code, tstrerror(code)); } //double @@ -1130,7 +1131,7 @@ void verify_telnet_insert(TAOS* taos) { }; code = taos_insert_telnet_lines(taos, lines2_5, 10); if (code) { - printf("code: %d, %s.\n", code, tstrerror(code)); + printf("lines2_5 code: %d, %s.\n", code, tstrerror(code)); } //bool @@ -1148,7 +1149,7 @@ void verify_telnet_insert(TAOS* taos) { }; code = taos_insert_telnet_lines(taos, lines2_6, 10); if (code) { - printf("code: %d, %s.\n", code, tstrerror(code)); + printf("lines2_6 code: %d, %s.\n", code, tstrerror(code)); } //binary @@ -1159,7 +1160,7 @@ void verify_telnet_insert(TAOS* taos) { }; code = taos_insert_telnet_lines(taos, lines2_7, 3); if (code) { - printf("code: %d, %s.\n", code, tstrerror(code)); + printf("lines2_7 code: %d, %s.\n", code, tstrerror(code)); } //nchar @@ -1169,7 +1170,7 @@ void verify_telnet_insert(TAOS* taos) { }; code = taos_insert_telnet_lines(taos, lines2_8, 2); if (code) { - printf("code: %d, %s.\n", code, tstrerror(code)); + printf("lines2_8 code: %d, %s.\n", code, tstrerror(code)); } /* tags */ @@ -1180,7 +1181,7 @@ void verify_telnet_insert(TAOS* taos) { }; code = taos_insert_telnet_lines(taos, lines3_0, 2); if (code) { - printf("code: %d, %s.\n", code, tstrerror(code)); + printf("lines3_0 code: %d, %s.\n", code, tstrerror(code)); } //tag ID as child table name @@ -1191,12 +1192,745 @@ void verify_telnet_insert(TAOS* taos) { }; code = taos_insert_telnet_lines(taos, lines3_1, 3); if (code) { - printf("code: %d, %s.\n", code, tstrerror(code)); + printf("lines3_1 code: %d, %s.\n", code, tstrerror(code)); } return; } +void verify_json_insert(TAOS* taos) { + TAOS_RES *result; + + result = taos_query(taos, "drop database if exists db;"); + taos_free_result(result); + usleep(100000); + result = taos_query(taos, "create database db precision 'ms';"); + taos_free_result(result); + usleep(100000); + + (void)taos_select_db(taos, "db"); + int32_t code = 0; + + char *message = + "{ \ + \"metric\":\"cpu_load_0\", \ + \"timestamp\": 1626006833610123, \ + \"value\": 55.5, \ + \"tags\": \ + { \ + \"host\": \"ubuntu\", \ + \"interface1\": \"eth0\", \ + \"Id\": \"tb0\" \ + } \ + }"; + + code = taos_insert_json_payload(taos, message); + if (code) { + printf("payload_0 code: %d, %s.\n", code, tstrerror(code)); + } + + char *message1 = + "[ \ + { \ + \"metric\":\"cpu_load_1\", \ + \"timestamp\": 1626006833610123, \ + \"value\": 55.5, \ + \"tags\": \ + { \ + \"host\": \"ubuntu\", \ + \"interface\": \"eth1\", \ + \"Id\": \"tb1\" \ + } \ + }, \ + { \ + \"metric\":\"cpu_load_2\", \ + \"timestamp\": 1626006833610123, \ + \"value\": 55.5, \ + \"tags\": \ + { \ + \"host\": \"ubuntu\", \ + \"interface\": \"eth2\", \ + \"Id\": \"tb2\" \ + } \ + } \ + ]"; + + code = taos_insert_json_payload(taos, message1); + if (code) { + printf("payload_1 code: %d, %s.\n", code, tstrerror(code)); + } + + char *message2 = + "[ \ + { \ + \"metric\":\"cpu_load_3\", \ + \"timestamp\": \ + { \ + \"value\": 1626006833610123, \ + \"type\": \"us\" \ + }, \ + \"value\": \ + { \ + \"value\": 55, \ + \"type\": \"int\" \ + }, \ + \"tags\": \ + { \ + \"host\": \ + { \ + \"value\": \"ubuntu\", \ + \"type\": \"binary\" \ + }, \ + \"interface\": \ + { \ + \"value\": \"eth3\", \ + \"type\": \"nchar\" \ + }, \ + \"ID\": \"tb3\", \ + \"port\": \ + { \ + \"value\": 4040, \ + \"type\": \"int\" \ + } \ + } \ + }, \ + { \ + \"metric\":\"cpu_load_4\", \ + \"timestamp\": 1626006833610123, \ + \"value\": 66.6, \ + \"tags\": \ + { \ + \"host\": \"ubuntu\", \ + \"interface\": \"eth4\", \ + \"Id\": \"tb4\" \ + } \ + } \ + ]"; + code = taos_insert_json_payload(taos, message2); + if (code) { + printf("payload_2 code: %d, %s.\n", code, tstrerror(code)); + } + + + cJSON *payload, *tags; + char *payload_str; + + /* Default format */ + //number + payload = cJSON_CreateObject(); + cJSON_AddStringToObject(payload, "metric", "stb0_0"); + cJSON_AddNumberToObject(payload, "timestamp", 1626006833610123); + cJSON_AddNumberToObject(payload, "value", 10); + tags = cJSON_CreateObject(); + cJSON_AddTrueToObject(tags, "t1"); + cJSON_AddFalseToObject(tags, "t2"); + cJSON_AddNumberToObject(tags, "t3", 10); + cJSON_AddStringToObject(tags, "t4", "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>"); + cJSON_AddItemToObject(payload, "tags", tags); + payload_str = cJSON_Print(payload); + //printf("%s\n", payload_str); + + code = taos_insert_json_payload(taos, payload_str); + if (code) { + printf("payload0_0 code: %d, %s.\n", code, tstrerror(code)); + } + free(payload_str); + cJSON_Delete(payload); + + //true + payload = cJSON_CreateObject(); + cJSON_AddStringToObject(payload, "metric", "stb0_1"); + cJSON_AddNumberToObject(payload, "timestamp", 1626006833610123); + cJSON_AddTrueToObject(payload, "value"); + tags = cJSON_CreateObject(); + cJSON_AddTrueToObject(tags, "t1"); + cJSON_AddFalseToObject(tags, "t2"); + cJSON_AddNumberToObject(tags, "t3", 10); + cJSON_AddStringToObject(tags, "t4", "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>"); + cJSON_AddItemToObject(payload, "tags", tags); + payload_str = cJSON_Print(payload); + //printf("%s\n", payload_str); + + code = taos_insert_json_payload(taos, payload_str); + if (code) { + printf("payload0_1 code: %d, %s.\n", code, tstrerror(code)); + } + free(payload_str); + cJSON_Delete(payload); + + //false + payload = cJSON_CreateObject(); + cJSON_AddStringToObject(payload, "metric", "stb0_2"); + cJSON_AddNumberToObject(payload, "timestamp", 1626006833610123); + cJSON_AddFalseToObject(payload, "value"); + tags = cJSON_CreateObject(); + cJSON_AddTrueToObject(tags, "t1"); + cJSON_AddFalseToObject(tags, "t2"); + cJSON_AddNumberToObject(tags, "t3", 10); + cJSON_AddStringToObject(tags, "t4", "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>"); + cJSON_AddItemToObject(payload, "tags", tags); + payload_str = cJSON_Print(payload); + //printf("%s\n", payload_str); + + code = taos_insert_json_payload(taos, payload_str); + if (code) { + printf("payload0_2 code: %d, %s.\n", code, tstrerror(code)); + } + free(payload_str); + cJSON_Delete(payload); + + //string + payload = cJSON_CreateObject(); + cJSON_AddStringToObject(payload, "metric", "stb0_3"); + cJSON_AddNumberToObject(payload, "timestamp", 1626006833610123); + cJSON_AddStringToObject(payload, "value", "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>"); + tags = cJSON_CreateObject(); + cJSON_AddTrueToObject(tags, "t1"); + cJSON_AddFalseToObject(tags, "t2"); + cJSON_AddNumberToObject(tags, "t3", 10); + cJSON_AddStringToObject(tags, "t4", "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>"); + cJSON_AddItemToObject(payload, "tags", tags); + payload_str = cJSON_Print(payload); + //printf("%s\n", payload_str); + + code = taos_insert_json_payload(taos, payload_str); + if (code) { + printf("payload0_3 code: %d, %s.\n", code, tstrerror(code)); + } + free(payload_str); + cJSON_Delete(payload); + + //timestamp 0 -> current time + payload = cJSON_CreateObject(); + cJSON_AddStringToObject(payload, "metric", "stb0_4"); + cJSON_AddNumberToObject(payload, "timestamp", 0); + cJSON_AddNumberToObject(payload, "value", 123); + tags = cJSON_CreateObject(); + cJSON_AddTrueToObject(tags, "t1"); + cJSON_AddFalseToObject(tags, "t2"); + cJSON_AddNumberToObject(tags, "t3", 10); + cJSON_AddStringToObject(tags, "t4", "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>"); + cJSON_AddItemToObject(payload, "tags", tags); + payload_str = cJSON_Print(payload); + //printf("%s\n", payload_str); + + code = taos_insert_json_payload(taos, payload_str); + if (code) { + printf("payload0_4 code: %d, %s.\n", code, tstrerror(code)); + } + free(payload_str); + cJSON_Delete(payload); + + //ID + payload = cJSON_CreateObject(); + cJSON_AddStringToObject(payload, "metric", "stb0_5"); + cJSON_AddNumberToObject(payload, "timestamp", 0); + cJSON_AddNumberToObject(payload, "value", 123); + tags = cJSON_CreateObject(); + cJSON_AddStringToObject(tags, "ID", "tb0_5"); + cJSON_AddTrueToObject(tags, "t1"); + cJSON_AddStringToObject(tags, "iD", "tb000"); + cJSON_AddFalseToObject(tags, "t2"); + cJSON_AddNumberToObject(tags, "t3", 10); + cJSON_AddStringToObject(tags, "t4", "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>"); + cJSON_AddStringToObject(tags, "id", "tb555"); + cJSON_AddItemToObject(payload, "tags", tags); + payload_str = cJSON_Print(payload); + //printf("%s\n", payload_str); + + code = taos_insert_json_payload(taos, payload_str); + if (code) { + printf("payload0_5 code: %d, %s.\n", code, tstrerror(code)); + } + free(payload_str); + cJSON_Delete(payload); + + /* Nested format */ + //timestamp + cJSON *timestamp; + //seconds + payload = cJSON_CreateObject(); + cJSON_AddStringToObject(payload, "metric", "stb1_0"); + + timestamp = cJSON_CreateObject(); + cJSON_AddNumberToObject(timestamp, "value", 1626006833); + cJSON_AddStringToObject(timestamp, "type", "s"); + cJSON_AddItemToObject(payload, "timestamp", timestamp); + + cJSON_AddNumberToObject(payload, "value", 10); + tags = cJSON_CreateObject(); + cJSON_AddTrueToObject(tags, "t1"); + cJSON_AddFalseToObject(tags, "t2"); + cJSON_AddNumberToObject(tags, "t3", 10); + cJSON_AddStringToObject(tags, "t4", "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>"); + cJSON_AddItemToObject(payload, "tags", tags); + payload_str = cJSON_Print(payload); + //printf("%s\n", payload_str); + + code = taos_insert_json_payload(taos, payload_str); + if (code) { + printf("payload1_0 code: %d, %s.\n", code, tstrerror(code)); + } + free(payload_str); + cJSON_Delete(payload); + + //milleseconds + payload = cJSON_CreateObject(); + cJSON_AddStringToObject(payload, "metric", "stb1_1"); + + timestamp = cJSON_CreateObject(); + cJSON_AddNumberToObject(timestamp, "value", 1626006833610); + cJSON_AddStringToObject(timestamp, "type", "ms"); + cJSON_AddItemToObject(payload, "timestamp", timestamp); + + cJSON_AddNumberToObject(payload, "value", 10); + tags = cJSON_CreateObject(); + cJSON_AddTrueToObject(tags, "t1"); + cJSON_AddFalseToObject(tags, "t2"); + cJSON_AddNumberToObject(tags, "t3", 10); + cJSON_AddStringToObject(tags, "t4", "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>"); + cJSON_AddItemToObject(payload, "tags", tags); + payload_str = cJSON_Print(payload); + //printf("%s\n", payload_str); + + code = taos_insert_json_payload(taos, payload_str); + if (code) { + printf("payload1_1 code: %d, %s.\n", code, tstrerror(code)); + } + free(payload_str); + cJSON_Delete(payload); + + //microseconds + payload = cJSON_CreateObject(); + cJSON_AddStringToObject(payload, "metric", "stb1_2"); + + timestamp = cJSON_CreateObject(); + cJSON_AddNumberToObject(timestamp, "value", 1626006833610123); + cJSON_AddStringToObject(timestamp, "type", "us"); + cJSON_AddItemToObject(payload, "timestamp", timestamp); + + cJSON_AddNumberToObject(payload, "value", 10); + tags = cJSON_CreateObject(); + cJSON_AddTrueToObject(tags, "t1"); + cJSON_AddFalseToObject(tags, "t2"); + cJSON_AddNumberToObject(tags, "t3", 10); + cJSON_AddStringToObject(tags, "t4", "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>"); + cJSON_AddItemToObject(payload, "tags", tags); + payload_str = cJSON_Print(payload); + //printf("%s\n", payload_str); + + code = taos_insert_json_payload(taos, payload_str); + if (code) { + printf("payload1_2 code: %d, %s.\n", code, tstrerror(code)); + } + free(payload_str); + cJSON_Delete(payload); + + //nanoseconds + payload = cJSON_CreateObject(); + cJSON_AddStringToObject(payload, "metric", "stb1_3"); + + timestamp = cJSON_CreateObject(); + cJSON_AddNumberToObject(timestamp, "value", 1626006833610123321); + cJSON_AddStringToObject(timestamp, "type", "ns"); + cJSON_AddItemToObject(payload, "timestamp", timestamp); + + cJSON_AddNumberToObject(payload, "value", 10); + tags = cJSON_CreateObject(); + cJSON_AddTrueToObject(tags, "t1"); + cJSON_AddFalseToObject(tags, "t2"); + cJSON_AddNumberToObject(tags, "t3", 10); + cJSON_AddStringToObject(tags, "t4", "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>"); + cJSON_AddItemToObject(payload, "tags", tags); + payload_str = cJSON_Print(payload); + //printf("%s\n", payload_str); + + code = taos_insert_json_payload(taos, payload_str); + if (code) { + printf("payload1_3 code: %d, %s.\n", code, tstrerror(code)); + } + free(payload_str); + cJSON_Delete(payload); + + //now + payload = cJSON_CreateObject(); + cJSON_AddStringToObject(payload, "metric", "stb1_4"); + + timestamp = cJSON_CreateObject(); + cJSON_AddNumberToObject(timestamp, "value", 0); + cJSON_AddStringToObject(timestamp, "type", "ns"); + cJSON_AddItemToObject(payload, "timestamp", timestamp); + + cJSON_AddNumberToObject(payload, "value", 10); + tags = cJSON_CreateObject(); + cJSON_AddTrueToObject(tags, "t1"); + cJSON_AddFalseToObject(tags, "t2"); + cJSON_AddNumberToObject(tags, "t3", 10); + cJSON_AddStringToObject(tags, "t4", "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>"); + cJSON_AddItemToObject(payload, "tags", tags); + payload_str = cJSON_Print(payload); + //printf("%s\n", payload_str); + + code = taos_insert_json_payload(taos, payload_str); + if (code) { + printf("payload1_4 code: %d, %s.\n", code, tstrerror(code)); + } + free(payload_str); + cJSON_Delete(payload); + + //metric value + cJSON *metric_val; + //bool + payload = cJSON_CreateObject(); + cJSON_AddStringToObject(payload, "metric", "stb2_0"); + + timestamp = cJSON_CreateObject(); + cJSON_AddNumberToObject(timestamp, "value", 1626006833); + cJSON_AddStringToObject(timestamp, "type", "s"); + cJSON_AddItemToObject(payload, "timestamp", timestamp); + + metric_val = cJSON_CreateObject(); + cJSON_AddTrueToObject(metric_val, "value"); + cJSON_AddStringToObject(metric_val, "type", "bool"); + cJSON_AddItemToObject(payload, "value", metric_val); + + tags = cJSON_CreateObject(); + cJSON_AddTrueToObject(tags, "t1"); + cJSON_AddFalseToObject(tags, "t2"); + cJSON_AddNumberToObject(tags, "t3", 10); + cJSON_AddStringToObject(tags, "t4", "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>"); + cJSON_AddItemToObject(payload, "tags", tags); + payload_str = cJSON_Print(payload); + //printf("%s\n", payload_str); + + code = taos_insert_json_payload(taos, payload_str); + if (code) { + printf("payload2_0 code: %d, %s.\n", code, tstrerror(code)); + } + free(payload_str); + cJSON_Delete(payload); + + //tinyint + payload = cJSON_CreateObject(); + cJSON_AddStringToObject(payload, "metric", "stb2_1"); + + timestamp = cJSON_CreateObject(); + cJSON_AddNumberToObject(timestamp, "value", 1626006833); + cJSON_AddStringToObject(timestamp, "type", "s"); + cJSON_AddItemToObject(payload, "timestamp", timestamp); + + metric_val = cJSON_CreateObject(); + cJSON_AddNumberToObject(metric_val, "value", 127); + cJSON_AddStringToObject(metric_val, "type", "tinyint"); + cJSON_AddItemToObject(payload, "value", metric_val); + + tags = cJSON_CreateObject(); + cJSON_AddTrueToObject(tags, "t1"); + cJSON_AddFalseToObject(tags, "t2"); + cJSON_AddNumberToObject(tags, "t3", 10); + cJSON_AddStringToObject(tags, "t4", "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>"); + cJSON_AddItemToObject(payload, "tags", tags); + payload_str = cJSON_Print(payload); + //printf("%s\n", payload_str); + + code = taos_insert_json_payload(taos, payload_str); + if (code) { + printf("payload2_1 code: %d, %s.\n", code, tstrerror(code)); + } + free(payload_str); + cJSON_Delete(payload); + + //smallint + payload = cJSON_CreateObject(); + cJSON_AddStringToObject(payload, "metric", "stb2_2"); + + timestamp = cJSON_CreateObject(); + cJSON_AddNumberToObject(timestamp, "value", 1626006833); + cJSON_AddStringToObject(timestamp, "type", "s"); + cJSON_AddItemToObject(payload, "timestamp", timestamp); + + metric_val = cJSON_CreateObject(); + cJSON_AddNumberToObject(metric_val, "value", 32767); + cJSON_AddStringToObject(metric_val, "type", "smallint"); + cJSON_AddItemToObject(payload, "value", metric_val); + + tags = cJSON_CreateObject(); + cJSON_AddTrueToObject(tags, "t1"); + cJSON_AddFalseToObject(tags, "t2"); + cJSON_AddNumberToObject(tags, "t3", 10); + cJSON_AddStringToObject(tags, "t4", "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>"); + cJSON_AddItemToObject(payload, "tags", tags); + payload_str = cJSON_Print(payload); + //printf("%s\n", payload_str); + + code = taos_insert_json_payload(taos, payload_str); + if (code) { + printf("payload2_2 code: %d, %s.\n", code, tstrerror(code)); + } + free(payload_str); + cJSON_Delete(payload); + + //int + payload = cJSON_CreateObject(); + cJSON_AddStringToObject(payload, "metric", "stb2_3"); + + timestamp = cJSON_CreateObject(); + cJSON_AddNumberToObject(timestamp, "value", 1626006833); + cJSON_AddStringToObject(timestamp, "type", "s"); + cJSON_AddItemToObject(payload, "timestamp", timestamp); + + metric_val = cJSON_CreateObject(); + cJSON_AddNumberToObject(metric_val, "value", 2147483647); + cJSON_AddStringToObject(metric_val, "type", "int"); + cJSON_AddItemToObject(payload, "value", metric_val); + + tags = cJSON_CreateObject(); + cJSON_AddTrueToObject(tags, "t1"); + cJSON_AddFalseToObject(tags, "t2"); + cJSON_AddNumberToObject(tags, "t3", 10); + cJSON_AddStringToObject(tags, "t4", "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>"); + cJSON_AddItemToObject(payload, "tags", tags); + payload_str = cJSON_Print(payload); + //printf("%s\n", payload_str); + + code = taos_insert_json_payload(taos, payload_str); + if (code) { + printf("payload2_3 code: %d, %s.\n", code, tstrerror(code)); + } + free(payload_str); + cJSON_Delete(payload); + + //bigint + payload = cJSON_CreateObject(); + cJSON_AddStringToObject(payload, "metric", "stb2_4"); + + timestamp = cJSON_CreateObject(); + cJSON_AddNumberToObject(timestamp, "value", 1626006833); + cJSON_AddStringToObject(timestamp, "type", "s"); + cJSON_AddItemToObject(payload, "timestamp", timestamp); + + metric_val = cJSON_CreateObject(); + cJSON_AddNumberToObject(metric_val, "value", 9223372036854775807); + cJSON_AddStringToObject(metric_val, "type", "bigint"); + cJSON_AddItemToObject(payload, "value", metric_val); + + tags = cJSON_CreateObject(); + cJSON_AddTrueToObject(tags, "t1"); + cJSON_AddFalseToObject(tags, "t2"); + cJSON_AddNumberToObject(tags, "t3", 10); + cJSON_AddStringToObject(tags, "t4", "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>"); + cJSON_AddItemToObject(payload, "tags", tags); + payload_str = cJSON_Print(payload); + //printf("%s\n", payload_str); + + code = taos_insert_json_payload(taos, payload_str); + if (code) { + printf("payload2_4 code: %d, %s.\n", code, tstrerror(code)); + } + free(payload_str); + cJSON_Delete(payload); + + //float + payload = cJSON_CreateObject(); + cJSON_AddStringToObject(payload, "metric", "stb2_5"); + + timestamp = cJSON_CreateObject(); + cJSON_AddNumberToObject(timestamp, "value", 1626006833); + cJSON_AddStringToObject(timestamp, "type", "s"); + cJSON_AddItemToObject(payload, "timestamp", timestamp); + + metric_val = cJSON_CreateObject(); + cJSON_AddNumberToObject(metric_val, "value", 11.12345); + cJSON_AddStringToObject(metric_val, "type", "float"); + cJSON_AddItemToObject(payload, "value", metric_val); + + tags = cJSON_CreateObject(); + cJSON_AddTrueToObject(tags, "t1"); + cJSON_AddFalseToObject(tags, "t2"); + cJSON_AddNumberToObject(tags, "t3", 10); + cJSON_AddStringToObject(tags, "t4", "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>"); + cJSON_AddItemToObject(payload, "tags", tags); + payload_str = cJSON_Print(payload); + //printf("%s\n", payload_str); + + code = taos_insert_json_payload(taos, payload_str); + if (code) { + printf("payload2_5 code: %d, %s.\n", code, tstrerror(code)); + } + free(payload_str); + cJSON_Delete(payload); + + //double + payload = cJSON_CreateObject(); + cJSON_AddStringToObject(payload, "metric", "stb2_6"); + + timestamp = cJSON_CreateObject(); + cJSON_AddNumberToObject(timestamp, "value", 1626006833); + cJSON_AddStringToObject(timestamp, "type", "s"); + cJSON_AddItemToObject(payload, "timestamp", timestamp); + + metric_val = cJSON_CreateObject(); + cJSON_AddNumberToObject(metric_val, "value", 22.123456789); + cJSON_AddStringToObject(metric_val, "type", "double"); + cJSON_AddItemToObject(payload, "value", metric_val); + + tags = cJSON_CreateObject(); + cJSON_AddTrueToObject(tags, "t1"); + cJSON_AddFalseToObject(tags, "t2"); + cJSON_AddNumberToObject(tags, "t3", 10); + cJSON_AddStringToObject(tags, "t4", "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>"); + cJSON_AddItemToObject(payload, "tags", tags); + payload_str = cJSON_Print(payload); + //printf("%s\n", payload_str); + + code = taos_insert_json_payload(taos, payload_str); + if (code) { + printf("payload2_6 code: %d, %s.\n", code, tstrerror(code)); + } + free(payload_str); + cJSON_Delete(payload); + + //binary + payload = cJSON_CreateObject(); + cJSON_AddStringToObject(payload, "metric", "stb2_7"); + + timestamp = cJSON_CreateObject(); + cJSON_AddNumberToObject(timestamp, "value", 1626006833); + cJSON_AddStringToObject(timestamp, "type", "s"); + cJSON_AddItemToObject(payload, "timestamp", timestamp); + + metric_val = cJSON_CreateObject(); + cJSON_AddStringToObject(metric_val, "value", "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>"); + cJSON_AddStringToObject(metric_val, "type", "binary"); + cJSON_AddItemToObject(payload, "value", metric_val); + + tags = cJSON_CreateObject(); + cJSON_AddTrueToObject(tags, "t1"); + cJSON_AddFalseToObject(tags, "t2"); + cJSON_AddNumberToObject(tags, "t3", 10); + cJSON_AddStringToObject(tags, "t4", "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>"); + cJSON_AddItemToObject(payload, "tags", tags); + payload_str = cJSON_Print(payload); + //printf("%s\n", payload_str); + + code = taos_insert_json_payload(taos, payload_str); + if (code) { + printf("payload2_7 code: %d, %s.\n", code, tstrerror(code)); + } + free(payload_str); + cJSON_Delete(payload); + + //nchar + payload = cJSON_CreateObject(); + cJSON_AddStringToObject(payload, "metric", "stb2_8"); + + timestamp = cJSON_CreateObject(); + cJSON_AddNumberToObject(timestamp, "value", 1626006833); + cJSON_AddStringToObject(timestamp, "type", "s"); + cJSON_AddItemToObject(payload, "timestamp", timestamp); + + metric_val = cJSON_CreateObject(); + cJSON_AddStringToObject(metric_val, "value", "你好"); + cJSON_AddStringToObject(metric_val, "type", "nchar"); + cJSON_AddItemToObject(payload, "value", metric_val); + + tags = cJSON_CreateObject(); + cJSON_AddTrueToObject(tags, "t1"); + cJSON_AddFalseToObject(tags, "t2"); + cJSON_AddNumberToObject(tags, "t3", 10); + cJSON_AddStringToObject(tags, "t4", "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>"); + cJSON_AddItemToObject(payload, "tags", tags); + payload_str = cJSON_Print(payload); + //printf("%s\n", payload_str); + + code = taos_insert_json_payload(taos, payload_str); + if (code) { + printf("payload2_8 code: %d, %s.\n", code, tstrerror(code)); + } + free(payload_str); + cJSON_Delete(payload); + + //tag value + cJSON *tag; + + payload = cJSON_CreateObject(); + cJSON_AddStringToObject(payload, "metric", "stb3_0"); + + timestamp = cJSON_CreateObject(); + cJSON_AddNumberToObject(timestamp, "value", 1626006833); + cJSON_AddStringToObject(timestamp, "type", "s"); + cJSON_AddItemToObject(payload, "timestamp", timestamp); + + metric_val = cJSON_CreateObject(); + cJSON_AddStringToObject(metric_val, "value", "hello"); + cJSON_AddStringToObject(metric_val, "type", "nchar"); + cJSON_AddItemToObject(payload, "value", metric_val); + + tags = cJSON_CreateObject(); + + tag = cJSON_CreateObject(); + cJSON_AddTrueToObject(tag, "value"); + cJSON_AddStringToObject(tag, "type", "bool"); + cJSON_AddItemToObject(tags, "t1", tag); + + tag = cJSON_CreateObject(); + cJSON_AddFalseToObject(tag, "value"); + cJSON_AddStringToObject(tag, "type", "bool"); + cJSON_AddItemToObject(tags, "t2", tag); + + tag = cJSON_CreateObject(); + cJSON_AddNumberToObject(tag, "value", 127); + cJSON_AddStringToObject(tag, "type", "tinyint"); + cJSON_AddItemToObject(tags, "t3", tag); + + tag = cJSON_CreateObject(); + cJSON_AddNumberToObject(tag, "value", 32767); + cJSON_AddStringToObject(tag, "type", "smallint"); + cJSON_AddItemToObject(tags, "t4", tag); + + tag = cJSON_CreateObject(); + cJSON_AddNumberToObject(tag, "value", 2147483647); + cJSON_AddStringToObject(tag, "type", "int"); + cJSON_AddItemToObject(tags, "t5", tag); + + tag = cJSON_CreateObject(); + cJSON_AddNumberToObject(tag, "value", 9223372036854775807); + cJSON_AddStringToObject(tag, "type", "bigint"); + cJSON_AddItemToObject(tags, "t6", tag); + + tag = cJSON_CreateObject(); + cJSON_AddNumberToObject(tag, "value", 11.12345); + cJSON_AddStringToObject(tag, "type", "float"); + cJSON_AddItemToObject(tags, "t7", tag); + + tag = cJSON_CreateObject(); + cJSON_AddNumberToObject(tag, "value", 22.1234567890); + cJSON_AddStringToObject(tag, "type", "double"); + cJSON_AddItemToObject(tags, "t8", tag); + + tag = cJSON_CreateObject(); + cJSON_AddStringToObject(tag, "value", "binary_val"); + cJSON_AddStringToObject(tag, "type", "binary"); + cJSON_AddItemToObject(tags, "t9", tag); + + tag = cJSON_CreateObject(); + cJSON_AddStringToObject(tag, "value", "你好"); + cJSON_AddStringToObject(tag, "type", "nchar"); + cJSON_AddItemToObject(tags, "t10", tag); + + cJSON_AddItemToObject(payload, "tags", tags); + + payload_str = cJSON_Print(payload); + //printf("%s\n", payload_str); + + code = taos_insert_json_payload(taos, payload_str); + if (code) { + printf("payload3_0 code: %d, %s.\n", code, tstrerror(code)); + } + free(payload_str); + cJSON_Delete(payload); +} + int main(int argc, char *argv[]) { const char* host = "127.0.0.1"; const char* user = "root"; @@ -1220,6 +1954,9 @@ int main(int argc, char *argv[]) { printf("************ verify telnet-insert *************\n"); verify_telnet_insert(taos); + printf("************ verify json-insert *************\n"); + verify_json_insert(taos); + printf("************ verify query *************\n"); verify_query(taos); diff --git a/tests/examples/c/makefile b/tests/examples/c/makefile index 304623c27af27cd23a301af134647fb3b9746d64..c85eb4adc515e5fb4e875b8e8e955222bc09190e 100644 --- a/tests/examples/c/makefile +++ b/tests/examples/c/makefile @@ -6,8 +6,8 @@ TARGET=exe LFLAGS = '-Wl,-rpath,/usr/local/taos/driver/' -ltaos -lpthread -lm -lrt CFLAGS = -O3 -g -Wall -Wno-deprecated -fPIC -Wno-unused-result -Wconversion \ -Wno-char-subscripts -D_REENTRANT -Wno-format -D_REENTRANT -DLINUX \ - -Wno-unused-function -D_M_X64 -I/usr/local/taos/include -std=gnu99 - + -Wno-unused-function -D_M_X64 -I/usr/local/taos/include -std=gnu99 \ + -I../../../deps/cJson/inc all: $(TARGET) exe: diff --git a/tests/gotest/batchtest.bat b/tests/gotest/batchtest.bat index efd8961bb0be2eb6f20e291114b92b00469b984f..2a96ee31eb6211dbc5f300fbb2f3d62c03df3061 100755 --- a/tests/gotest/batchtest.bat +++ b/tests/gotest/batchtest.bat @@ -1,3 +1,4 @@ + @echo off echo ==== start Go connector test cases test ==== cd /d %~dp0 @@ -18,3 +19,10 @@ rem case002.bat :: cd case002 :: case002.bat + + +rem cd nanosupport +rem nanoCase.bat + +:: cd nanosupport +:: nanoCase.bat \ No newline at end of file diff --git a/tests/gotest/batchtest.sh b/tests/gotest/batchtest.sh index 8f5a7fe8f032134e55c9d9675361590ed6d5b19b..503d77b226885b10e3874a3e0718789bed34b200 100755 --- a/tests/gotest/batchtest.sh +++ b/tests/gotest/batchtest.sh @@ -19,3 +19,4 @@ go env -w GOPROXY=https://goproxy.io,direct bash ./case001/case001.sh $severIp $serverPort bash ./case002/case002.sh $severIp $serverPort #bash ./case003/case003.sh $severIp $serverPort +bash ./nanosupport/nanoCase.sh $severIp $serverPort diff --git a/tests/gotest/case001/case001.go b/tests/gotest/case001/case001.go index 9d35888f313461a2ce90c7a6ed4ef2791229866c..29bc92f2a0668b3f576145d5bd6d08ed37c82f1b 100644 --- a/tests/gotest/case001/case001.go +++ b/tests/gotest/case001/case001.go @@ -12,7 +12,6 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ - package main import ( diff --git a/tests/gotest/case001/case001.sh b/tests/gotest/case001/case001.sh index 94e5bb44e03a1f7d2704752fcf9c080abcb4f23f..831e9f83ac482c0a2c668e2ad0d16c4bf59f19aa 100644 --- a/tests/gotest/case001/case001.sh +++ b/tests/gotest/case001/case001.sh @@ -15,8 +15,7 @@ script_dir="$(dirname $(readlink -f $0))" ###### step 3: start build cd $script_dir rm -f go.* -go mod init demotest > /dev/null 2>&1 -go mod tidy > /dev/null 2>&1 -go build > /dev/null 2>&1 +go mod init demotest +go build sleep 1s ./demotest -h $1 -p $2 diff --git a/tests/gotest/case002/case002.bat b/tests/gotest/case002/case002.bat index ebec576e724ccb14319dd380c9783a783ac0db62..385677acae826e248a410472bfc7a022ff3003ab 100644 --- a/tests/gotest/case002/case002.bat +++ b/tests/gotest/case002/case002.bat @@ -1,5 +1,5 @@ @echo off -echo ==== start run cases001.go +echo ==== start run cases002.go del go.* go mod init demotest diff --git a/tests/gotest/case002/case002.go b/tests/gotest/case002/case002.go index c69da04cb271c24e33953ca8fdfea71c67349b4f..e2ba5ea28ee4f92cfbdca27c78d47268a387c693 100644 --- a/tests/gotest/case002/case002.go +++ b/tests/gotest/case002/case002.go @@ -43,10 +43,9 @@ func main() { os.Exit(1) } defer db.Close() - db.Exec("drop if exists database test") - db.Exec("create if not exists database test") + db.Exec("drop database if exists test") + db.Exec("create database if not exists test ") db.Exec("use test") - db.Exec("drop if exists database test") db.Exec("create table test (ts timestamp ,level int)") for i := 0; i < 10; i++ { sqlcmd := fmt.Sprintf("insert into test values(%d,%d)", ts+i, i) diff --git a/tests/gotest/case002/case002.sh b/tests/gotest/case002/case002.sh index 94e5bb44e03a1f7d2704752fcf9c080abcb4f23f..d98337cce7cfeb51ec9305226b20abdd7b360a46 100644 --- a/tests/gotest/case002/case002.sh +++ b/tests/gotest/case002/case002.sh @@ -1,6 +1,6 @@ #!/bin/bash -echo "==== start run cases001.go" +echo "==== start run cases002.go" set +e #set -x diff --git a/tests/gotest/nanosupport/connector/executor.go b/tests/gotest/nanosupport/connector/executor.go new file mode 100644 index 0000000000000000000000000000000000000000..218ea29af3b34a8cfb5ab56585eeb07bc467d209 --- /dev/null +++ b/tests/gotest/nanosupport/connector/executor.go @@ -0,0 +1,208 @@ +package connector + +import ( + "context" + "fmt" + "reflect" + "time" + + "github.com/taosdata/go-utils/log" + "github.com/taosdata/go-utils/tdengine/config" + "github.com/taosdata/go-utils/tdengine/connector" + tdengineExecutor "github.com/taosdata/go-utils/tdengine/executor" +) + +type Executor struct { + executor *tdengineExecutor.Executor + ctx context.Context +} + +var Logger = log.NewLogger("taos test") + +func NewExecutor(conf *config.TDengineGo, db string, showSql bool) (*Executor, error) { + tdengineConnector, err := connector.NewTDengineConnector("go", conf) + if err != nil { + return nil, err + } + executor := tdengineExecutor.NewExecutor(tdengineConnector, db, showSql, Logger) + return &Executor{ + executor: executor, + ctx: context.Background(), + }, nil +} + +func (e *Executor) Execute(sql string) (int64, error) { + return e.executor.DoExec(e.ctx, sql) +} +func (e *Executor) Query(sql string) (*connector.Data, error) { + fmt.Println("query :", sql) + return e.executor.DoQuery(e.ctx, sql) +} +func (e *Executor) CheckData(row, col int, value interface{}, data *connector.Data) (bool, error) { + if data == nil { + return false, fmt.Errorf("data is nil") + } + if col >= len(data.Head) { + return false, fmt.Errorf("col out of data") + } + if row >= len(data.Data) { + return false, fmt.Errorf("row out of data") + } + dataValue := data.Data[row][col] + + if dataValue == nil && value != nil { + return false, fmt.Errorf("dataValue is nil but value is not nil") + } + if dataValue == nil && value == nil { + return true, nil + } + if reflect.TypeOf(dataValue) != reflect.TypeOf(value) { + return false, fmt.Errorf("type not match expect %s got %s", reflect.TypeOf(value), reflect.TypeOf(dataValue)) + } + switch value.(type) { + case time.Time: + t, _ := dataValue.(time.Time) + if value.(time.Time).Nanosecond() != t.Nanosecond() { + return false, fmt.Errorf("value not match expect %d got %d", value.(time.Time).Nanosecond(), t.Nanosecond()) + } + case string: + if value.(string) != dataValue.(string) { + return false, fmt.Errorf("value not match expect %s got %s", value.(string), dataValue.(string)) + } + case int8: + if value.(int8) != dataValue.(int8) { + return false, fmt.Errorf("value not match expect %d got %d", value.(int8), dataValue.(int8)) + } + case int16: + if value.(int16) != dataValue.(int16) { + return false, fmt.Errorf("value not match expect %d got %d", value.(int16), dataValue.(int16)) + } + case int32: + if value.(int32) != dataValue.(int32) { + return false, fmt.Errorf("value not match expect %d got %d", value.(int32), dataValue.(int32)) + } + case int64: + if value.(int64) != dataValue.(int64) { + return false, fmt.Errorf("value not match expect %d got %d", value.(int64), dataValue.(int64)) + } + case float32: + if value.(float32) != dataValue.(float32) { + return false, fmt.Errorf("value not match expect %f got %f", value.(float32), dataValue.(float32)) + } + case float64: + if value.(float64) != dataValue.(float64) { + return false, fmt.Errorf("value not match expect %f got %f", value.(float32), dataValue.(float32)) + } + case bool: + if value.(bool) != dataValue.(bool) { + return false, fmt.Errorf("value not match expect %t got %t", value.(bool), dataValue.(bool)) + } + default: + return false, fmt.Errorf("unsupport type %v", reflect.TypeOf(value)) + } + return true, nil +} + +func (e *Executor) CheckData2(row, col int, value interface{}, data *connector.Data) { + + match, err := e.CheckData(row, col, value, data) + fmt.Println("expect data is :", value) + fmt.Println("go got data is :", data.Data[row][col]) + if err != nil { + fmt.Println(err) + } + if !match { + fmt.Println(" data not match") + + } + + /* + fmt.Println(value) + if data == nil { + // return false, fmt.Errorf("data is nil") + // fmt.Println("check failed") + } + if col >= len(data.Head) { + // return false, fmt.Errorf("col out of data") + // fmt.Println("check failed") + } + if row >= len(data.Data) { + // return false, fmt.Errorf("row out of data") + // fmt.Println("check failed") + } + dataValue := data.Data[row][col] + + if dataValue == nil && value != nil { + // return false, fmt.Errorf("dataValue is nil but value is not nil") + // fmt.Println("check failed") + } + if dataValue == nil && value == nil { + // return true, nil + fmt.Println("check pass") + } + if reflect.TypeOf(dataValue) != reflect.TypeOf(value) { + // return false, fmt.Errorf("type not match expect %s got %s", reflect.TypeOf(value), reflect.TypeOf(dataValue)) + fmt.Println("check failed") + } + switch value.(type) { + case time.Time: + t, _ := dataValue.(time.Time) + if value.(time.Time).Nanosecond() != t.Nanosecond() { + // return false, fmt.Errorf("value not match expect %d got %d", value.(time.Time).Nanosecond(), t.Nanosecond()) + // fmt.Println("check failed") + } + case string: + if value.(string) != dataValue.(string) { + // return false, fmt.Errorf("value not match expect %s got %s", value.(string), dataValue.(string)) + // fmt.Println("check failed") + } + case int8: + if value.(int8) != dataValue.(int8) { + // return false, fmt.Errorf("value not match expect %d got %d", value.(int8), dataValue.(int8)) + // fmt.Println("check failed") + } + case int16: + if value.(int16) != dataValue.(int16) { + // return false, fmt.Errorf("value not match expect %d got %d", value.(int16), dataValue.(int16)) + // fmt.Println("check failed") + } + case int32: + if value.(int32) != dataValue.(int32) { + // return false, fmt.Errorf("value not match expect %d got %d", value.(int32), dataValue.(int32)) + // fmt.Println("check failed") + } + case int64: + if value.(int64) != dataValue.(int64) { + // return false, fmt.Errorf("value not match expect %d got %d", value.(int64), dataValue.(int64)) + // fmt.Println("check failed") + } + case float32: + if value.(float32) != dataValue.(float32) { + // return false, fmt.Errorf("value not match expect %f got %f", value.(float32), dataValue.(float32)) + // fmt.Println("check failed") + } + case float64: + if value.(float64) != dataValue.(float64) { + // return false, fmt.Errorf("value not match expect %f got %f", value.(float32), dataValue.(float32)) + // fmt.Println("check failed") + } + case bool: + if value.(bool) != dataValue.(bool) { + // return false, fmt.Errorf("value not match expect %t got %t", value.(bool), dataValue.(bool)) + // fmt.Println("check failed") + } + default: + // return false, fmt.Errorf("unsupport type %v", reflect.TypeOf(value)) + // fmt.Println("check failed") + } + // return true, nil + // fmt.Println("check pass") + */ +} + +func (e *Executor) CheckRow(count int, data *connector.Data) { + + if len(data.Data) != count { + fmt.Println("check failed !") + } +} diff --git a/tests/gotest/nanosupport/nanoCase.bat b/tests/gotest/nanosupport/nanoCase.bat new file mode 100644 index 0000000000000000000000000000000000000000..86bddd5b02c5399d5b8d70bd08020e96a7d1c0e5 --- /dev/null +++ b/tests/gotest/nanosupport/nanoCase.bat @@ -0,0 +1,9 @@ +@echo off +echo ==== start run nanosupport.go + +del go.* +go mod init nano +go mod tidy +go build +nano.exe -h %1 -p %2 +cd .. diff --git a/tests/gotest/nanosupport/nanoCase.sh b/tests/gotest/nanosupport/nanoCase.sh new file mode 100644 index 0000000000000000000000000000000000000000..bec8929f14c0a56e7c4074efa39d1e1e881fb12e --- /dev/null +++ b/tests/gotest/nanosupport/nanoCase.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +echo "==== start run nanosupport.go " + +set +e +#set -x + +script_dir="$(dirname $(readlink -f $0))" +#echo "pwd: $script_dir, para0: $0" + +#execName=$0 +#execName=`echo ${execName##*/}` +#goName=`echo ${execName%.*}` + +###### step 3: start build +cd $script_dir +rm -f go.* +go mod init nano +go mod tidy +go build +sleep 10s +./nano -h $1 -p $2 diff --git a/tests/gotest/nanosupport/nanosupport.go b/tests/gotest/nanosupport/nanosupport.go new file mode 100644 index 0000000000000000000000000000000000000000..e2f24a73c0a6db3c94b90879c73d0f05e2476307 --- /dev/null +++ b/tests/gotest/nanosupport/nanosupport.go @@ -0,0 +1,269 @@ +package main + +import ( + "fmt" + "log" + "nano/connector" + "time" + + "github.com/taosdata/go-utils/tdengine/config" +) + +func main() { + e, err := connector.NewExecutor(&config.TDengineGo{ + Address: "root:taosdata@/tcp(127.0.0.1:6030)/", + MaxIdle: 20, + MaxOpen: 30, + MaxLifetime: 30, + }, "db", false) + if err != nil { + panic(err) + } + prepareData(e) + data, err := e.Query("select * from tb") + if err != nil { + panic(err) + } + + layout := "2006-01-02 15:04:05.999999999" + t0, _ := time.Parse(layout, "2021-06-10 00:00:00.100000001") + t1, _ := time.Parse(layout, "2021-06-10 00:00:00.150000000") + t2, _ := time.Parse(layout, "2021-06-10 00:00:00.299999999") + t3, _ := time.Parse(layout, "2021-06-10 00:00:00.300000000") + t4, _ := time.Parse(layout, "2021-06-10 00:00:00.300000001") + t5, _ := time.Parse(layout, "2021-06-10 00:00:00.999999999") + + e.CheckData2(0, 0, t0, data) + e.CheckData2(1, 0, t1, data) + e.CheckData2(2, 0, t2, data) + e.CheckData2(3, 0, t3, data) + e.CheckData2(4, 0, t4, data) + e.CheckData2(5, 0, t5, data) + e.CheckData2(3, 1, int32(3), data) + e.CheckData2(4, 1, int32(5), data) + e.CheckData2(5, 1, int32(7), data) + + fmt.Println(" start check nano support!") + + data, _ = e.Query("select count(*) from tb where ts > 1623254400100000000 and ts < 1623254400100000002;") + e.CheckData2(0, 0, int64(1), data) + + data, _ = e.Query("select count(*) from tb where ts > \"2021-06-10 0:00:00.100000001\" and ts < \"2021-06-10 0:00:00.160000000\";") + e.CheckData2(0, 0, int64(1), data) + + data, _ = e.Query("select count(*) from tb where ts > 1623254400100000000 and ts < 1623254400150000000;") + e.CheckData2(0, 0, int64(1), data) + data, _ = e.Query("select count(*) from tb where ts > \"2021-06-10 0:00:00.100000000\" and ts < \"2021-06-10 0:00:00.150000000\";") + e.CheckData2(0, 0, int64(1), data) + + data, _ = e.Query("select count(*) from tb where ts > 1623254400400000000;") + e.CheckData2(0, 0, int64(1), data) + data, _ = e.Query("select count(*) from tb where ts < \"2021-06-10 00:00:00.400000000\";") + e.CheckData2(0, 0, int64(5), data) + + data, _ = e.Query("select count(*) from tb where ts < now + 400000000b;") + e.CheckData2(0, 0, int64(6), data) + + data, _ = e.Query("select count(*) from tb where ts >= \"2021-06-10 0:00:00.100000001\";") + e.CheckData2(0, 0, int64(6), data) + + data, _ = e.Query("select count(*) from tb where ts <= 1623254400300000000;") + e.CheckData2(0, 0, int64(4), data) + + data, _ = e.Query("select count(*) from tb where ts = \"2021-06-10 0:00:00.000000000\";") + + data, _ = e.Query("select count(*) from tb where ts = 1623254400150000000;") + e.CheckData2(0, 0, int64(1), data) + + data, _ = e.Query("select count(*) from tb where ts = \"2021-06-10 0:00:00.100000001\";") + e.CheckData2(0, 0, int64(1), data) + + data, _ = e.Query("select count(*) from tb where ts between 1623254400000000000 and 1623254400400000000;") + e.CheckData2(0, 0, int64(5), data) + + data, _ = e.Query("select count(*) from tb where ts between \"2021-06-10 0:00:00.299999999\" and \"2021-06-10 0:00:00.300000001\";") + e.CheckData2(0, 0, int64(3), data) + + data, _ = e.Query("select avg(speed) from tb interval(5000000000b);") + e.CheckRow(1, data) + + data, _ = e.Query("select avg(speed) from tb interval(100000000b)") + e.CheckRow(4, data) + + data, _ = e.Query("select avg(speed) from tb interval(1000b);") + e.CheckRow(5, data) + + data, _ = e.Query("select avg(speed) from tb interval(1u);") + e.CheckRow(5, data) + + data, _ = e.Query("select avg(speed) from tb interval(100000000b) sliding (100000000b);") + e.CheckRow(4, data) + + data, _ = e.Query("select last(*) from tb") + tt, _ := time.Parse(layout, "2021-06-10 0:00:00.999999999") + e.CheckData2(0, 0, tt, data) + + data, _ = e.Query("select first(*) from tb") + tt1, _ := time.Parse(layout, "2021-06-10 0:00:00.100000001") + e.CheckData2(0, 0, tt1, data) + + e.Execute("insert into tb values(now + 500000000b, 6);") + data, _ = e.Query("select * from tb;") + e.CheckRow(7, data) + + e.Execute("create table tb2 (ts timestamp, speed int, ts2 timestamp);") + e.Execute("insert into tb2 values(\"2021-06-10 0:00:00.100000001\", 1, \"2021-06-11 0:00:00.100000001\");") + e.Execute("insert into tb2 values(1623254400150000000, 2, 1623340800150000000);") + e.Execute("import into tb2 values(1623254400300000000, 3, 1623340800300000000);") + e.Execute("import into tb2 values(1623254400299999999, 4, 1623340800299999999);") + e.Execute("insert into tb2 values(1623254400300000001, 5, 1623340800300000001);") + e.Execute("insert into tb2 values(1623254400999999999, 7, 1623513600999999999);") + + data, _ = e.Query("select * from tb2;") + tt2, _ := time.Parse(layout, "2021-06-10 0:00:00.100000001") + tt3, _ := time.Parse(layout, "2021-06-10 0:00:00.150000000") + + e.CheckData2(0, 0, tt2, data) + e.CheckData2(1, 0, tt3, data) + e.CheckData2(2, 1, int32(4), data) + e.CheckData2(3, 1, int32(3), data) + tt4, _ := time.Parse(layout, "2021-06-11 00:00:00.300000001") + e.CheckData2(4, 2, tt4, data) + e.CheckRow(6, data) + + data, _ = e.Query("select count(*) from tb2 where ts2 > 1623340800000000000 and ts2 < 1623340800150000000;") + e.CheckData2(0, 0, int64(1), data) + + data, _ = e.Query("select count(*) from tb2 where ts2 > \"2021-06-11 0:00:00.100000000\" and ts2 < \"2021-06-11 0:00:00.100000002\";") + e.CheckData2(0, 0, int64(1), data) + + data, _ = e.Query("select count(*) from tb2 where ts2 > 1623340800500000000;") + e.CheckData2(0, 0, int64(1), data) + data, _ = e.Query("select count(*) from tb2 where ts2 < \"2021-06-11 0:00:00.400000000\";") + e.CheckData2(0, 0, int64(5), data) + + data, _ = e.Query("select count(*) from tb2 where ts2 < now + 400000000b;") + e.CheckData2(0, 0, int64(6), data) + + data, _ = e.Query("select count(*) from tb2 where ts2 >= \"2021-06-11 0:00:00.100000001\";") + e.CheckData2(0, 0, int64(6), data) + + data, _ = e.Query("select count(*) from tb2 where ts2 <= 1623340800400000000;") + e.CheckData2(0, 0, int64(5), data) + + data, _ = e.Query("select count(*) from tb2 where ts2 = \"2021-06-11 0:00:00.000000000\";") + + data, _ = e.Query("select count(*) from tb2 where ts2 = \"2021-06-11 0:00:00.300000001\";") + e.CheckData2(0, 0, int64(1), data) + + data, _ = e.Query("select count(*) from tb2 where ts2 = 1623340800300000001;") + e.CheckData2(0, 0, int64(1), data) + + data, _ = e.Query("select count(*) from tb2 where ts2 between 1623340800000000000 and 1623340800450000000;") + e.CheckData2(0, 0, int64(5), data) + + data, _ = e.Query("select count(*) from tb2 where ts2 between \"2021-06-11 0:00:00.299999999\" and \"2021-06-11 0:00:00.300000001\";") + e.CheckData2(0, 0, int64(3), data) + + data, _ = e.Query("select count(*) from tb2 where ts2 <> 1623513600999999999;") + e.CheckData2(0, 0, int64(5), data) + + data, _ = e.Query("select count(*) from tb2 where ts2 <> \"2021-06-11 0:00:00.100000001\";") + e.CheckData2(0, 0, int64(5), data) + + data, _ = e.Query("select count(*) from tb2 where ts2 <> \"2021-06-11 0:00:00.100000000\";") + e.CheckData2(0, 0, int64(6), data) + + data, _ = e.Query("select count(*) from tb2 where ts2 != 1623513600999999999;") + e.CheckData2(0, 0, int64(5), data) + + data, _ = e.Query("select count(*) from tb2 where ts2 != \"2021-06-11 0:00:00.100000001\";") + e.CheckData2(0, 0, int64(5), data) + + data, _ = e.Query("select count(*) from tb2 where ts2 != \"2021-06-11 0:00:00.100000000\";") + e.CheckData2(0, 0, int64(6), data) + + e.Execute("insert into tb2 values(now + 500000000b, 6, now +2d);") + data, _ = e.Query("select * from tb2;") + e.CheckRow(7, data) + + e.Execute("create table tb3 (ts timestamp, speed int);") + _, err = e.Execute("insert into tb3 values(16232544001500000, 2);") + if err != nil { + fmt.Println("check pass! ") + } + + e.Execute("insert into tb3 values(\"2021-06-10 0:00:00.123456\", 2);") + data, _ = e.Query("select * from tb3 where ts = \"2021-06-10 0:00:00.123456000\";") + e.CheckRow(1, data) + + e.Execute("insert into tb3 values(\"2021-06-10 0:00:00.123456789000\", 2);") + data, _ = e.Query("select * from tb3 where ts = \"2021-06-10 0:00:00.123456789\";") + e.CheckRow(1, data) + + // check timezone support + + e.Execute("drop database if exists nsdb;") + e.Execute("create database nsdb precision 'ns';") + e.Execute("use nsdb;") + e.Execute("create stable st (ts timestamp ,speed float ) tags(time timestamp ,id int);") + e.Execute("insert into tb1 using st tags('2021-06-10 0:00:00.123456789' , 1 ) values('2021-06-10T0:00:00.123456789+07:00' , 1.0);") + data, _ = e.Query("select first(*) from tb1;") + + ttt, _ := time.Parse(layout, "2021-06-10 01:00:00.123456789") + e.CheckData2(0, 0, ttt, data) + + e.Execute("create database usdb precision 'us';") + e.Execute("use usdb;") + e.Execute("create stable st (ts timestamp ,speed float ) tags(time timestamp ,id int);") + e.Execute("insert into tb1 using st tags('2021-06-10 0:00:00.123456' , 1 ) values('2021-06-10T0:00:00.123456+07:00' , 1.0);") + data, _ = e.Query("select first(*) from tb1;") + ttt2, _ := time.Parse(layout, "2021-06-10 01:00:00.123456") + e.CheckData2(0, 0, ttt2, data) + + e.Execute("drop database if exists msdb;") + e.Execute("create database msdb precision 'ms';") + e.Execute("use msdb;") + e.Execute("create stable st (ts timestamp ,speed float ) tags(time timestamp ,id int);") + e.Execute("insert into tb1 using st tags('2021-06-10 0:00:00.123' , 1 ) values('2021-06-10T0:00:00.123+07:00' , 1.0);") + data, _ = e.Query("select first(*) from tb1;") + ttt3, _ := time.Parse(layout, "2021-06-10 01:00:00.123") + e.CheckData2(0, 0, ttt3, data) + fmt.Println("all test done!") + +} + +func prepareData(e *connector.Executor) { + sqlList := []string{ + "reset query cache;", + "drop database if exists db;", + "create database db;", + "use db;", + "reset query cache;", + "drop database if exists db;", + "create database db precision 'ns';", + "show databases;", + "use db;", + "create table tb (ts timestamp, speed int);", + "insert into tb values('2021-06-10 0:00:00.100000001', 1);", + "insert into tb values(1623254400150000000, 2);", + "import into tb values(1623254400300000000, 3);", + "import into tb values(1623254400299999999, 4);", + "insert into tb values(1623254400300000001, 5);", + "insert into tb values(1623254400999999999, 7);", + } + for _, sql := range sqlList { + err := executeSql(e, sql) + if err != nil { + log.Fatalf("prepare data error:%v, sql:%s", err, sql) + } + } +} + +func executeSql(e *connector.Executor, sql string) error { + _, err := e.Execute(sql) + if err != nil { + return err + } + return nil +} diff --git a/tests/perftest-scripts/perftest-query.sh b/tests/perftest-scripts/perftest-query.sh index 68b64fd4e0c4f09ff0b8e96d7802b954b774fbc5..05b2d45ce434d0990d7c143863b9ca268a7d6a26 100755 --- a/tests/perftest-scripts/perftest-query.sh +++ b/tests/perftest-scripts/perftest-query.sh @@ -21,7 +21,8 @@ fi today=`date +"%Y%m%d"` WORK_DIR=/root/pxiao -PERFORMANCE_TEST_REPORT=$WORK_DIR/TDengine/tests/performance-report-$branch-$type-$today.log +name=`echo $branch | cut -d '/' -f2` +PERFORMANCE_TEST_REPORT=$WORK_DIR/TDinternal/community/tests/performance-report-$name-$type-$today.log # Coloured Echoes # function red_echo { echo -e "\033[31m$@\033[0m"; } # @@ -54,11 +55,12 @@ function stopTaosd { } function buildTDengine { - echoInfo "Build TDengine" - cd $WORK_DIR/TDengine + echoInfo "Build TDinternal" + cd $WORK_DIR/TDinternal git remote update > /dev/null git reset --hard HEAD + git fetch git checkout $branch REMOTE_COMMIT=`git rev-parse --short remotes/origin/$branch` LOCAL_COMMIT=`git rev-parse --short @` @@ -69,13 +71,22 @@ function buildTDengine { echo "repo up-to-date" fi + cd community + git reset --hard HEAD + cd .. + echo "git submodule update --init --recursive" + git submodule update --init --recursive + git pull > /dev/null 2>&1 - if [ $type = "jemalloc" ];then - echo "git submodule update --init --recursive" - git submodule update --init --recursive - fi + + cd community + git remote update > /dev/null + git reset --hard HEAD + git fetch + git checkout $branch + REMOTE_COMMIT=`git rev-parse --short remotes/origin/$branch` LOCAL_COMMIT=`git rev-parse --short @` - cd debug + cd ../debug rm -rf * if [ $type = "jemalloc" ];then echo "cmake .. -DJEMALLOC_ENABLED=true > /dev/null" @@ -83,6 +94,10 @@ function buildTDengine { else cmake .. > /dev/null fi + #cp $WORK_DIR/taosdemoPerformance.py $WORK_DIR/TDinternal/community/tests/pytest/tools/ + #cp $WORK_DIR/insertFromCSVPerformance.py $WORK_DIR/TDinternal/community/tests/pytest/insert/ + #cp $WORK_DIR/queryPerformance.py $WORK_DIR/TDinternal/community/tests/pytest/query/ + rm -rf $WORK_DIR/TDinternal/community/tests/pytest/query/operator.py make > /dev/null 2>&1 make install > /dev/null 2>&1 echo "Build TDengine on remote server" @@ -91,24 +106,24 @@ function buildTDengine { function runQueryPerfTest { [ -f $PERFORMANCE_TEST_REPORT ] && rm $PERFORMANCE_TEST_REPORT - nohup $WORK_DIR/TDengine/debug/build/bin/taosd -c /etc/perf/ > /dev/null 2>&1 & + nohup $WORK_DIR/TDinternal/debug/build/bin/taosd -c /etc/perf/ > /dev/null 2>&1 & echoInfo "Wait TDengine to start" sleep 60 echoInfo "Run Performance Test" - cd $WORK_DIR/TDengine/tests/pytest + cd $WORK_DIR/TDinternal/community/tests/pytest - python3 query/queryPerformance.py -c $LOCAL_COMMIT -b $branch -T $type | tee -a $PERFORMANCE_TEST_REPORT + python3 query/queryPerformance.py -c $LOCAL_COMMIT -b $branch -T $type -d perf2 | tee -a $PERFORMANCE_TEST_REPORT python3 insert/insertFromCSVPerformance.py -c $LOCAL_COMMIT -b $branch -T $type | tee -a $PERFORMANCE_TEST_REPORT echo "=========== taosdemo performance: 4 int columns, 10000 tables, 100000 recoreds per table ===========" | tee -a $PERFORMANCE_TEST_REPORT python3 tools/taosdemoPerformance.py -c $LOCAL_COMMIT -b $branch -T $type | tee -a $PERFORMANCE_TEST_REPORT - echo "=========== taosdemo performance: 400 int columns, 400 double columns, 200 binary(128) columns, 10000 tables, 1000 recoreds per table ===========" | tee -a $PERFORMANCE_TEST_REPORT - python3 tools/taosdemoPerformance.py -c $LOCAL_COMMIT -b $branch -T $type -i 400 -D 400 -B 200 -t 10000 -r 100 | tee -a $PERFORMANCE_TEST_REPORT + echo "=========== taosdemo performance: 400 int columns, 400 double columns, 200 binary(128) columns, 10000 tables, 10 recoreds per table ===========" | tee -a $PERFORMANCE_TEST_REPORT + python3 tools/taosdemoPerformance.py -c $LOCAL_COMMIT -b $branch -T $type -i 400 -D 400 -B 200 -t 10000 -r 10 | tee -a $PERFORMANCE_TEST_REPORT - echo "=========== taosdemo performance: 1900 int columns, 1900 double columns, 200 binary(128) columns, 10000 tables, 1000 recoreds per table ===========" | tee -a $PERFORMANCE_TEST_REPORT - python3 tools/taosdemoPerformance.py -c $LOCAL_COMMIT -b $branch -T $type -i 1900 -D 1900 -B 200 -t 10000 -r 100 | tee -a $PERFORMANCE_TEST_REPORT + echo "=========== taosdemo performance: 1900 int columns, 1900 double columns, 200 binary(128) columns, 10000 tables, 10 recoreds per table ===========" | tee -a $PERFORMANCE_TEST_REPORT + python3 tools/taosdemoPerformance.py -c $LOCAL_COMMIT -b $branch -T $type -i 1900 -D 1900 -B 200 -t 10000 -r 10 | tee -a $PERFORMANCE_TEST_REPORT } @@ -121,7 +136,7 @@ function sendReport { sed -i 's/\x1b\[[0-9;]*m//g' $PERFORMANCE_TEST_REPORT BODY_CONTENT=`cat $PERFORMANCE_TEST_REPORT` - echo -e "From: \nto: ${receiver}\nsubject: Query Performace Report ${branch} ${jemalloc} commit ID: ${LOCAL_COMMIT}\n\n${today}:\n${BODY_CONTENT}" | \ + echo -e "From: \nto: ${receiver}\nsubject: Query Performace Report ${branch} ${type} commit ID: ${LOCAL_COMMIT}\n\n${today}:\n${BODY_CONTENT}" | \ (cat - && uuencode $PERFORMANCE_TEST_REPORT performance-test-report-$today.log) | \ /usr/sbin/ssmtp "${receiver}" && echo "Report Sent!" } diff --git a/tests/pytest/fulltest.sh b/tests/pytest/fulltest.sh index 06ec3c6bfabfe4d9c378c9d17dda944990f624a8..3f7367354bd57ba0f8225107ada299584ef24b8a 100755 --- a/tests/pytest/fulltest.sh +++ b/tests/pytest/fulltest.sh @@ -267,7 +267,7 @@ python3 ./test.py -f query/queryStateWindow.py # python3 ./test.py -f query/nestedQuery/queryWithOrderLimit.py python3 ./test.py -f query/nestquery_last_row.py python3 ./test.py -f query/queryCnameDisplay.py -python3 ./test.py -f query/operator_cost.py +# python3 ./test.py -f query/operator_cost.py # python3 ./test.py -f query/long_where_query.py python3 test.py -f query/nestedQuery/queryWithSpread.py diff --git a/tests/pytest/functions/showOfflineThresholdIs864000.py b/tests/pytest/functions/showOfflineThresholdIs864000.py index 8ec25cef26b3c97bc55f2f4df3fe8cf55a19125c..7462d4cd72f600674fcb82aa1224019787d23fd5 100644 --- a/tests/pytest/functions/showOfflineThresholdIs864000.py +++ b/tests/pytest/functions/showOfflineThresholdIs864000.py @@ -12,6 +12,8 @@ # -*- coding: utf-8 -*- import sys +import numpy as np + from util.log import * from util.cases import * from util.sql import * @@ -24,8 +26,17 @@ class TDTestCase: tdSql.init(conn.cursor(), logSql) def run(self): + # tdSql.query("show variables") + # tdSql.checkData(54, 1, 864000) + tdSql.execute("show variables") + res = tdSql.cursor.fetchall() + resList = np.array(res) + index = np.where(resList == "offlineThreshold") + index_value = np.dstack((index[0])).squeeze() tdSql.query("show variables") - tdSql.checkData(55, 1, 864000) + tdSql.checkData(index_value, 1, 864000) + pass + def stop(self): tdSql.close() diff --git a/tests/pytest/insert/insertJSONPayload.py b/tests/pytest/insert/insertJSONPayload.py new file mode 100644 index 0000000000000000000000000000000000000000..30f34446a93237f9b7b610efc9b1b5507ba09f4a --- /dev/null +++ b/tests/pytest/insert/insertJSONPayload.py @@ -0,0 +1,568 @@ +################################################################### +# Copyright (c) 2021 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +import sys +from util.log import * +from util.cases import * +from util.sql import * + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), logSql) + self._conn = conn + + def run(self): + print("running {}".format(__file__)) + tdSql.execute("drop database if exists test") + tdSql.execute("create database if not exists test precision 'us'") + tdSql.execute('use test') + + + ### Default format ### + ### metric value ### + print("============= step1 : test metric value types ================") + payload = ''' + { + "metric": "stb0_0", + "timestamp": 1626006833610123, + "value": 10, + "tags": { + "t1": true, + "t2": false, + "t3": 10, + "t4": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + ''' + code = self._conn.insert_json_payload(payload) + print("insert_json_payload result {}".format(code)) + + tdSql.query("describe stb0_0") + tdSql.checkData(1, 1, "FLOAT") + + payload = ''' + { + "metric": "stb0_1", + "timestamp": 1626006833610123, + "value": true, + "tags": { + "t1": true, + "t2": false, + "t3": 10, + "t4": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + ''' + code = self._conn.insert_json_payload(payload) + print("insert_json_payload result {}".format(code)) + + tdSql.query("describe stb0_1") + tdSql.checkData(1, 1, "BOOL") + + payload = ''' + { + "metric": "stb0_2", + "timestamp": 1626006833610123, + "value": false, + "tags": { + "t1": true, + "t2": false, + "t3": 10, + "t4": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + ''' + code = self._conn.insert_json_payload(payload) + print("insert_json_payload result {}".format(code)) + + tdSql.query("describe stb0_2") + tdSql.checkData(1, 1, "BOOL") + + payload = ''' + { + "metric": "stb0_3", + "timestamp": 1626006833610123, + "value": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>", + "tags": { + "t1": true, + "t2": false, + "t3": 10, + "t4": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + ''' + code = self._conn.insert_json_payload(payload) + print("insert_json_payload result {}".format(code)) + + tdSql.query("describe stb0_3") + tdSql.checkData(1, 1, "NCHAR") + + ### timestamp 0 ### + payload = ''' + { + "metric": "stb0_4", + "timestamp": 0, + "value": 123, + "tags": { + "t1": true, + "t2": false, + "t3": 10, + "t4": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + ''' + code = self._conn.insert_json_payload(payload) + print("insert_json_payload result {}".format(code)) + + + ### ID ### + payload = ''' + { + "metric": "stb0_5", + "timestamp": 0, + "value": 123, + "tags": { + "ID": "tb0_5", + "t1": true, + "iD": "tb000", + "t2": false, + "t3": 10, + "t4": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>", + "id": "tb555" + } + } + ''' + code = self._conn.insert_json_payload(payload) + print("insert_json_payload result {}".format(code)) + + tdSql.query("select tbname from stb0_5") + tdSql.checkData(0, 0, "tb0_5") + + ### Nested format ### + ### timestamp ### + #seconds + payload = ''' + { + "metric": "stb1_0", + "timestamp": { + "value": 1626006833, + "type": "s" + }, + "value": 10, + "tags": { + "t1": true, + "t2": false, + "t3": 10, + "t4": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + ''' + code = self._conn.insert_json_payload(payload) + print("insert_json_payload result {}".format(code)) + + tdSql.query("select ts from stb1_0") + tdSql.checkData(0, 0, "2021-07-11 20:33:53.000000") + + #milliseconds + payload = ''' + { + "metric": "stb1_1", + "timestamp": { + "value": 1626006833610, + "type": "ms" + }, + "value": 10, + "tags": { + "t1": true, + "t2": false, + "t3": 10, + "t4": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + ''' + code = self._conn.insert_json_payload(payload) + print("insert_json_payload result {}".format(code)) + + tdSql.query("select ts from stb1_1") + tdSql.checkData(0, 0, "2021-07-11 20:33:53.610000") + + #microseconds + payload = ''' + { + "metric": "stb1_2", + "timestamp": { + "value": 1626006833610123, + "type": "us" + }, + "value": 10, + "tags": { + "t1": true, + "t2": false, + "t3": 10, + "t4": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + ''' + code = self._conn.insert_json_payload(payload) + print("insert_json_payload result {}".format(code)) + + tdSql.query("select ts from stb1_2") + tdSql.checkData(0, 0, "2021-07-11 20:33:53.610123") + + #nanoseconds + payload = ''' + { + "metric": "stb1_3", + "timestamp": { + "value": 1.6260068336101233e+18, + "type": "ns" + }, + "value": 10, + "tags": { + "t1": true, + "t2": false, + "t3": 10, + "t4": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + ''' + code = self._conn.insert_json_payload(payload) + print("insert_json_payload result {}".format(code)) + + tdSql.query("select ts from stb1_3") + tdSql.checkData(0, 0, "2021-07-11 20:33:53.610123") + + #now + tdSql.execute('use test') + payload = ''' + { + "metric": "stb1_4", + "timestamp": { + "value": 0, + "type": "ns" + }, + "value": 10, + "tags": { + "t1": true, + "t2": false, + "t3": 10, + "t4": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + ''' + code = self._conn.insert_json_payload(payload) + print("insert_json_payload result {}".format(code)) + + ### metric value ### + payload = ''' + { + "metric": "stb2_0", + "timestamp": { + "value": 1626006833, + "type": "s" + }, + "value": { + "value": true, + "type": "bool" + }, + "tags": { + "t1": true, + "t2": false, + "t3": 10, + "t4": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + ''' + code = self._conn.insert_json_payload(payload) + print("insert_json_payload result {}".format(code)) + + tdSql.query("describe stb2_0") + tdSql.checkData(1, 1, "BOOL") + + payload = ''' + { + "metric": "stb2_1", + "timestamp": { + "value": 1626006833, + "type": "s" + }, + "value": { + "value": 127, + "type": "tinyint" + }, + "tags": { + "t1": true, + "t2": false, + "t3": 10, + "t4": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + ''' + code = self._conn.insert_json_payload(payload) + print("insert_json_payload result {}".format(code)) + + tdSql.query("describe stb2_1") + tdSql.checkData(1, 1, "TINYINT") + + payload = ''' + { + "metric": "stb2_2", + "timestamp": { + "value": 1626006833, + "type": "s" + }, + "value": { + "value": 32767, + "type": "smallint" + }, + "tags": { + "t1": true, + "t2": false, + "t3": 10, + "t4": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + ''' + code = self._conn.insert_json_payload(payload) + print("insert_json_payload result {}".format(code)) + + tdSql.query("describe stb2_2") + tdSql.checkData(1, 1, "SMALLINT") + + payload = ''' + { + "metric": "stb2_3", + "timestamp": { + "value": 1626006833, + "type": "s" + }, + "value": { + "value": 2147483647, + "type": "int" + }, + "tags": { + "t1": true, + "t2": false, + "t3": 10, + "t4": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + ''' + code = self._conn.insert_json_payload(payload) + print("insert_json_payload result {}".format(code)) + + tdSql.query("describe stb2_3") + tdSql.checkData(1, 1, "INT") + + payload = ''' + { + "metric": "stb2_4", + "timestamp": { + "value": 1626006833, + "type": "s" + }, + "value": { + "value": 9.2233720368547758e+18, + "type": "bigint" + }, + "tags": { + "t1": true, + "t2": false, + "t3": 10, + "t4": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + ''' + code = self._conn.insert_json_payload(payload) + print("insert_json_payload result {}".format(code)) + + tdSql.query("describe stb2_4") + tdSql.checkData(1, 1, "BIGINT") + + payload = ''' + { + "metric": "stb2_5", + "timestamp": { + "value": 1626006833, + "type": "s" + }, + "value": { + "value": 11.12345, + "type": "float" + }, + "tags": { + "t1": true, + "t2": false, + "t3": 10, + "t4": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + ''' + code = self._conn.insert_json_payload(payload) + print("insert_json_payload result {}".format(code)) + + tdSql.query("describe stb2_5") + tdSql.checkData(1, 1, "FLOAT") + + payload = ''' + { + "metric": "stb2_6", + "timestamp": { + "value": 1626006833, + "type": "s" + }, + "value": { + "value": 22.123456789, + "type": "double" + }, + "tags": { + "t1": true, + "t2": false, + "t3": 10, + "t4": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + ''' + code = self._conn.insert_json_payload(payload) + print("insert_json_payload result {}".format(code)) + + tdSql.query("describe stb2_6") + tdSql.checkData(1, 1, "DOUBLE") + + payload = ''' + { + "metric": "stb2_7", + "timestamp": { + "value": 1626006833, + "type": "s" + }, + "value": { + "value": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>", + "type": "binary" + }, + "tags": { + "t1": true, + "t2": false, + "t3": 10, + "t4": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + ''' + code = self._conn.insert_json_payload(payload) + print("insert_json_payload result {}".format(code)) + + tdSql.query("describe stb2_7") + tdSql.checkData(1, 1, "BINARY") + + payload = ''' + { + "metric": "stb2_8", + "timestamp": { + "value": 1626006833, + "type": "s" + }, + "value": { + "value": "你好", + "type": "nchar" + }, + "tags": { + "t1": true, + "t2": false, + "t3": 10, + "t4": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + ''' + code = self._conn.insert_json_payload(payload) + print("insert_json_payload result {}".format(code)) + + tdSql.query("describe stb2_8") + tdSql.checkData(1, 1, "NCHAR") + + ### tag value ### + + payload = ''' + { + "metric": "stb3_0", + "timestamp": { + "value": 1626006833, + "type": "s" + }, + "value": { + "value": "hello", + "type": "nchar" + }, + "tags": { + "t1": { + "value": true, + "type": "bool" + }, + "t2": { + "value": 127, + "type": "tinyint" + }, + "t3": { + "value": 32767, + "type": "smallint" + }, + "t4": { + "value": 2147483647, + "type": "int" + }, + "t5": { + "value": 9.2233720368547758e+18, + "type": "bigint" + }, + "t6": { + "value": 11.12345, + "type": "float" + }, + "t7": { + "value": 22.123456789, + "type": "double" + }, + "t8": { + "value": "binary_val", + "type": "binary" + }, + "t9": { + "value": "你好", + "type": "nchar" + } + } + } + ''' + code = self._conn.insert_json_payload(payload) + print("insert_json_payload result {}".format(code)) + + tdSql.query("describe stb3_0") + tdSql.checkData(2, 1, "BOOL") + tdSql.checkData(3, 1, "TINYINT") + tdSql.checkData(4, 1, "SMALLINT") + tdSql.checkData(5, 1, "INT") + tdSql.checkData(6, 1, "BIGINT") + tdSql.checkData(7, 1, "FLOAT") + tdSql.checkData(8, 1, "DOUBLE") + tdSql.checkData(9, 1, "BINARY") + tdSql.checkData(10, 1, "NCHAR") + + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdumpTestNanoSupport.py b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdumpTestNanoSupport.py index ca8832170b7706621f5ef9d3225fe2cf16141c34..a2059ec924ad1e2239c2709bc99dd58fbafa1337 100644 --- a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdumpTestNanoSupport.py +++ b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdumpTestNanoSupport.py @@ -44,7 +44,7 @@ class TDTestCase: projPath = selfPath[:selfPath.find("tests")] for root, dirs, files in os.walk(projPath): - if ("taosdump" in files): + if ("taosd" in files): rootRealPath = os.path.dirname(os.path.realpath(root)) if ("packaging" not in rootRealPath): buildPath = root[:len(root) - len("/build/bin")] diff --git a/tests/pytest/tools/taosdemoAllTest/insertInterlaceRowsLarge1M.json b/tests/pytest/tools/taosdemoAllTest/insertInterlaceRowsLarge1M.json index 1b56830189623d344168918f239887c3359b2645..197f8a208e85ca4ce57c06518a433ec3a3acbac3 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertInterlaceRowsLarge1M.json +++ b/tests/pytest/tools/taosdemoAllTest/insertInterlaceRowsLarge1M.json @@ -41,7 +41,7 @@ "batch_create_tbl_num": 10, "data_source": "rand", "insert_mode": "taosc", - "insert_rows": 1000, + "insert_rows": 1001, "childtable_limit": 0, "childtable_offset":0, "multi_thread_write_one_tbl": "no", diff --git a/tests/pytest/tools/taosdemoPerformance.py b/tests/pytest/tools/taosdemoPerformance.py index 51b064a08e5cd55401f9cf803a8683653f722679..82c57a656dfea12f80fe4eb2b530742c5bfb0916 100644 --- a/tests/pytest/tools/taosdemoPerformance.py +++ b/tests/pytest/tools/taosdemoPerformance.py @@ -120,7 +120,7 @@ class taosdemoPerformace: projPath = selfPath[:selfPath.find("tests")] for root, dirs, files in os.walk(projPath): - if ("taosdemo" in files): + if ("taosd" in files): rootRealPath = os.path.dirname(os.path.realpath(root)) if ("packaging" not in rootRealPath): buildPath = root[:len(root) - len("/build/bin")] diff --git a/tests/pytest/tools/taosdemoTest.py b/tests/pytest/tools/taosdemoTest.py index 5662881031a01d19398cce223892eebbd8133c97..3cdcdcef5afcb14c04204d2489571bdfed937080 100644 --- a/tests/pytest/tools/taosdemoTest.py +++ b/tests/pytest/tools/taosdemoTest.py @@ -36,7 +36,7 @@ class TDTestCase: projPath = selfPath[:selfPath.find("tests")] for root, dirs, files in os.walk(projPath): - if ("taosdemo" in files): + if ("taosd" in files): rootRealPath = os.path.dirname(os.path.realpath(root)) if ("packaging" not in rootRealPath): buildPath = root[:len(root) - len("/build/bin")] diff --git a/tests/pytest/tools/taosdemoTestTblAlt.py b/tests/pytest/tools/taosdemoTestTblAlt.py index b70525ae4d87465a59ad524067d8b1e4a61d526a..70df535f59cbb97469b7a73e4e230d9a8671bfc7 100644 --- a/tests/pytest/tools/taosdemoTestTblAlt.py +++ b/tests/pytest/tools/taosdemoTestTblAlt.py @@ -26,7 +26,7 @@ class TDTestCase: tdLog.debug("start to execute %s" % __file__) tdSql.init(conn.cursor(), logSql) - self.numberOfTables = 10 + self.numberOfTables = 8 self.numberOfRecords = 1000000 def getBuildPath(self): @@ -86,7 +86,7 @@ class TDTestCase: while True: print("query started") try: - tdSql.query("select * from test.t9") + tdSql.query("select * from test.t7") except Exception as e: tdLog.info("select * test failed") time.sleep(2) @@ -100,8 +100,8 @@ class TDTestCase: print("alter table test.meters add column c10 int") tdSql.execute("alter table test.meters add column c10 int") - print("insert into test.t9 values (now, 1, 2, 3, 4, 0)") - tdSql.execute("insert into test.t9 values (now, 1, 2, 3, 4, 0)") + print("insert into test.t7 values (now, 1, 2, 3, 4, 0)") + tdSql.execute("insert into test.t7 values (now, 1, 2, 3, 4, 0)") def run(self): tdSql.prepare() diff --git a/tests/pytest/tools/taosdumpTest2.py b/tests/pytest/tools/taosdumpTest2.py index bed0564139e20fb6c562a7258af0cbd5b542069b..839988375b652b0cfad09d8a6de7697de19609ea 100644 --- a/tests/pytest/tools/taosdumpTest2.py +++ b/tests/pytest/tools/taosdumpTest2.py @@ -37,7 +37,7 @@ class TDTestCase: projPath = selfPath[:selfPath.find("tests")] for root, dirs, files in os.walk(projPath): - if ("taosdump" in files): + if ("taosd" in files): rootRealPath = os.path.dirname(os.path.realpath(root)) if ("packaging" not in rootRealPath): buildPath = root[:len(root) - len("/build/bin")] diff --git a/tests/script/general/parser/condition.sim b/tests/script/general/parser/condition.sim index 96cd1e80bd01ad6ffa197ccbe8c58ce6474f3339..dbdbddbbcb27ad0f618bb375199c017d2d9c0a5d 100644 --- a/tests/script/general/parser/condition.sim +++ b/tests/script/general/parser/condition.sim @@ -204,6 +204,7 @@ sleep 100 run general/parser/condition_query.sim run general/parser/condition_query2.sim + sql drop database if exists cdb diff --git a/tests/script/general/parser/condition_query.sim b/tests/script/general/parser/condition_query.sim index c4b8de2a4b32ab8c8f152cef52c202683cf4bbe1..bebcbe709f005337795fe1286b34fc264b287cb0 100644 --- a/tests/script/general/parser/condition_query.sim +++ b/tests/script/general/parser/condition_query.sim @@ -41,6 +41,15 @@ sql_error select * from stb1 where c6 match '.*'; sql_error select * from stb1 where c7 match '.*'; sql_error select * from stb1 where c9 match '.*'; sql_error select * from stb1 where ts match '.*'; +sql_error select * from stb1 where c1 nmatch '.*'; +sql_error select * from stb1 where c2 nmatch '.*'; +sql_error select * from stb1 where c3 nmatch '.*'; +sql_error select * from stb1 where c4 nmatch '.*'; +sql_error select * from stb1 where c5 nmatch '.*'; +sql_error select * from stb1 where c6 nmatch '.*'; +sql_error select * from stb1 where c7 nmatch '.*'; +sql_error select * from stb1 where c9 nmatch '.*'; +sql_error select * from stb1 where ts nmatch '.*'; sql_error select * from (select * from stb1 where c7=true) a, (select * from stb1 where c1 > 30) b; sql_error select a.ts,a.c1,a.c8 from (select * from stb1 where c7=true) a, (select * from stb1 where c1 > 30) b where a.ts=b.ts and a.c1 > 50 or b.c1 < 60; @@ -2314,4 +2323,22 @@ if $data30 != @21-05-05 18:19:07.000@ then return -1 endi +sql select * from stb1 where c8 nmatch '^1.*'; +if $rows != 23 then + return -1 +endi + +sql select ts,c8 from stb1 where c8 nmatch '[2345]+'; +if $rows != 3 then + return -1 +endi +if $data00 != @21-05-05 18:19:00.000@ then + return -1 +endi +if $data10 != @21-05-05 18:19:04.000@ then + return -1 +endi +if $data20 != @21-05-05 18:19:24.000@ then + return -1 +endi diff --git a/tests/script/general/parser/condition_query2.sim b/tests/script/general/parser/condition_query2.sim index e20c85540e6b0cab3bd0acf82d01068f24d467c6..fddd770ea53b0b147b9665434a5bc601e7aad38f 100644 --- a/tests/script/general/parser/condition_query2.sim +++ b/tests/script/general/parser/condition_query2.sim @@ -623,6 +623,38 @@ if $data70 != @21-05-05 18:19:19.000@ then return -1 endi +sql select ts,c1,t9,t10,tbname from stb5 where tbname nmatch '[123467]+'; +if $rows != 9 then + return -1 +endi +if $data00 != @21-05-05 18:19:20.000@ then + return -1 +endi +if $data10 != @21-05-05 18:19:21.000@ then + return -1 +endi +if $data20 != @21-05-05 18:19:22.000@ then + return -1 +endi +if $data30 != @21-05-05 18:19:23.000@ then + return -1 +endi +if $data40 != @21-05-05 18:19:34.000@ then + return -1 +endi +if $data50 != @21-05-05 18:19:35.000@ then + return -1 +endi +if $data60 != @21-05-05 18:19:36.000@ then + return -1 +endi +if $data70 != @21-05-05 18:19:37.000@ then + return -1 +endi +if $data80 != @21-05-05 18:19:38.000@ then + return -1 +endi + print "tag test" sql_error select * from stb5 where t1 match '.*'; sql_error select * from stb5 where t2 match '.*'; @@ -1275,7 +1307,40 @@ if $data40 != @21-05-05 18:19:38.000@ then return -1 endi - +sql select ts,c1,t9,t10 from stb5 where t9 nmatch '^[12345]*\$'; +if $rows != 10 then + return -1 +endi +if $data00 != @21-05-05 18:19:24.000@ then + return -1 +endi +if $data10 != @21-05-05 18:19:25.000@ then + return -1 +endi +if $data20 != @21-05-05 18:19:26.000@ then + return -1 +endi +if $data30 != @21-05-05 18:19:27.000@ then + return -1 +endi +if $data40 != @21-05-05 18:19:28.000@ then + return -1 +endi +if $data50 != @21-05-05 18:19:34.000@ then + return -1 +endi +if $data60 != @21-05-05 18:19:35.000@ then + return -1 +endi +if $data70 != @21-05-05 18:19:36.000@ then + return -1 +endi +if $data80 != @21-05-05 18:19:37.000@ then + return -1 +endi +if $data90 != @21-05-05 18:19:38.000@ then + return -1 +endi print "join test" sql_error select * from tb1, tb2_1 where tb1.ts=tb2_1.ts or tb1.ts =tb2_1.ts; diff --git a/tests/script/general/parser/condition_query3.sim b/tests/script/general/parser/condition_query3.sim index 2993d642e74231d387b85efd70f5488f5c338d98..a88d75f40d2d638e19d356b2f0ef76789c42b2db 100644 --- a/tests/script/general/parser/condition_query3.sim +++ b/tests/script/general/parser/condition_query3.sim @@ -43,7 +43,13 @@ if $rows != 4 then endi sql select tbname,t1 from stba where t1 is null; +if $rows != 0 then + return -1 +endi sql select tbname,t1 from stba where t1 is not null; +if $rows != 10 then + return -1 +endi sql_error select tbname,t1 from stbb where t1 > true; sql select tbname,t1 from stbb where t1 = true; @@ -57,8 +63,13 @@ if $rows != 5 then endi sql select tbname,t1 from stbb where t1 is null; +if $rows != 0 then + return -1 +endi sql select tbname,t1 from stbb where t1 is not null; - +if $rows != 10 then + return -1 +endi sql select tbname,t1 from stbc; if $rows != 10 then @@ -101,7 +112,13 @@ if $rows != 4 then endi sql select tbname,t1 from stbc where t1 is null; +if $rows != 0 then + return -1 +endi sql select tbname,t1 from stbc where t1 is not null; +if $rows != 10 then + return -1 +endi sql select tbname,t1 from stbd where t1 > '2222'; if $rows != 7 then @@ -139,8 +156,13 @@ if $rows != 4 then endi sql select tbname,t1 from stbd where t1 is null; +if $rows != 0 then + return -1 +endi sql select tbname,t1 from stbd where t1 is not null; - +if $rows != 10 then + return -1 +endi sql select tbname,t1 from stbe where t1 > '2222'; if $rows != 7 then return -1 @@ -177,6 +199,12 @@ if $rows != 4 then endi sql select tbname,t1 from stbe where t1 is null; +if $rows != 0 then + return -1 +endi sql select tbname,t1 from stbe where t1 is not null; +if $rows != 10 then + return -1 +endi #system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/general/parser/regex.sim b/tests/script/general/parser/regex.sim index 5351d914f34004b5bf198fb9e10792306f8ac32b..eed36018d4c04ec5752e64105d025347982bfcb0 100644 --- a/tests/script/general/parser/regex.sim +++ b/tests/script/general/parser/regex.sim @@ -29,13 +29,22 @@ endi sql select tbname from $st_name where tbname match '^ct[[:digit:]]' - if $rows != 2 then return -1 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 '.*' -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 endi @@ -44,6 +53,11 @@ if $rows != 2 then return -1 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 $ct2_name values(now, 'this is app egnine') @@ -56,6 +70,52 @@ if $rows != 1 then return -1 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