提交 bf673b4f 编写于 作者: C Cary Xu

Merge branch 'develop' into hotfix/TD-6636-D

...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
## <a class="anchor" id="queries"></a>主要查询功能 ## <a class="anchor" id="queries"></a>主要查询功能
TDengine 采用 SQL 作为查询语言。应用程序可以通过 C/C++, Java, Go, Python 连接器发送 SQL 语句,用户可以通过 TDengine 提供的命令行(Command Line Interface, CLI)工具 TAOS Shell 手动执行 SQL 即席查询(Ad-Hoc Query)。TDengine 支持如下查询功能: TDengine 采用 SQL 作为查询语言。应用程序可以通过 C/C++, Java, Go, C#, Python, Node.js 连接器发送 SQL 语句,用户可以通过 TDengine 提供的命令行(Command Line Interface, CLI)工具 TAOS Shell 手动执行 SQL 即席查询(Ad-Hoc Query)。TDengine 支持如下查询功能:
- 单列、多列数据查询 - 单列、多列数据查询
- 标签和数值的多种过滤条件:>, <, =, <>, like 等 - 标签和数值的多种过滤条件:>, <, =, <>, like 等
......
...@@ -1166,7 +1166,7 @@ var affectRows = cursor.execute('insert into test.weather values(now, 22.3, 34); ...@@ -1166,7 +1166,7 @@ var affectRows = cursor.execute('insert into test.weather values(now, 22.3, 34);
execute方法的返回值为该语句影响的行数,上面的sql向test库的weather表中,插入了一条数据,则返回值affectRows为1。 execute方法的返回值为该语句影响的行数,上面的sql向test库的weather表中,插入了一条数据,则返回值affectRows为1。
TDengine目前还不支持update和delete语句 TDengine 目前还不支持 delete 语句。但从 2.0.8.0 版本开始,可以通过 `CREATE DATABASE` 时指定的 UPDATE 参数来启用对数据行的 update
#### 查询 #### 查询
......
...@@ -216,7 +216,7 @@ taosd -C ...@@ -216,7 +216,7 @@ taosd -C
| 98 | maxBinaryDisplayWidth | | **C** | | Taos shell中binary 和 nchar字段的显示宽度上限,超过此限制的部分将被隐藏 | 5 - | 30 | 实际上限按以下规则计算:如果字段值的长度大于 maxBinaryDisplayWidth,则显示上限为 **字段名长度****maxBinaryDisplayWidth** 的较大者。否则,上限为 **字段名长度****字段值长度** 的较大者。可在 shell 中通过命令 set max_binary_display_width nn动态修改此选项 | | 98 | maxBinaryDisplayWidth | | **C** | | Taos shell中binary 和 nchar字段的显示宽度上限,超过此限制的部分将被隐藏 | 5 - | 30 | 实际上限按以下规则计算:如果字段值的长度大于 maxBinaryDisplayWidth,则显示上限为 **字段名长度****maxBinaryDisplayWidth** 的较大者。否则,上限为 **字段名长度****字段值长度** 的较大者。可在 shell 中通过命令 set max_binary_display_width nn动态修改此选项 |
| 99 | queryBufferSize | | **S** | MB | 为所有并发查询占用保留的内存大小。 | | | 计算规则可以根据实际应用可能的最大并发数和表的数字相乘,再乘 170 。(2.0.15 以前的版本中,此参数的单位是字节) | | 99 | queryBufferSize | | **S** | MB | 为所有并发查询占用保留的内存大小。 | | | 计算规则可以根据实际应用可能的最大并发数和表的数字相乘,再乘 170 。(2.0.15 以前的版本中,此参数的单位是字节) |
| 100 | ratioOfQueryCores | | **S** | | 设置查询线程的最大数量。 | | | 最小值0 表示只有1个查询线程;最大值2表示最大建立2倍CPU核数的查询线程。默认为1,表示最大和CPU核数相等的查询线程。该值可以为小数,即0.5表示最大建立CPU核数一半的查询线程。 | | 100 | ratioOfQueryCores | | **S** | | 设置查询线程的最大数量。 | | | 最小值0 表示只有1个查询线程;最大值2表示最大建立2倍CPU核数的查询线程。默认为1,表示最大和CPU核数相等的查询线程。该值可以为小数,即0.5表示最大建立CPU核数一半的查询线程。 |
| 101 | update | | **S** | | 允许更新已存在的数据行 | 0 \| 1 | 0 | 从 2.0.8.0 版本开始 | | 101 | update | | **S** | | 允许更新已存在的数据行 | 0:不允许更新;1:允许整行更新;2:允许部分列更新。(2.1.7.0 版本开始此参数支持设为 2,在此之前取值只能是 [0, 1]) | 0 | 2.0.8.0 版本之前,不支持此参数。 |
| 102 | cacheLast | | **S** | | 是否在内存中缓存子表的最近数据 | 0:关闭;1:缓存子表最近一行数据;2:缓存子表每一列的最近的非NULL值;3:同时打开缓存最近行和列功能。(2.1.2.0 版本开始此参数支持 0~3 的取值范围,在此之前取值只能是 [0, 1]) | 0 | 2.1.2.0 版本之前、2.0.20.7 版本之前在 taos.cfg 文件中不支持此参数。 | | 102 | cacheLast | | **S** | | 是否在内存中缓存子表的最近数据 | 0:关闭;1:缓存子表最近一行数据;2:缓存子表每一列的最近的非NULL值;3:同时打开缓存最近行和列功能。(2.1.2.0 版本开始此参数支持 0~3 的取值范围,在此之前取值只能是 [0, 1]) | 0 | 2.1.2.0 版本之前、2.0.20.7 版本之前在 taos.cfg 文件中不支持此参数。 |
| 103 | numOfCommitThreads | YES | **S** | | 设置写入线程的最大数量 | | | | | 103 | numOfCommitThreads | YES | **S** | | 设置写入线程的最大数量 | | | |
| 104 | maxWildCardsLength | | **C** | bytes | 设定 LIKE 算子的通配符字符串允许的最大长度 | 0-16384 | 100 | 2.1.6.1 版本新增。 | | 104 | maxWildCardsLength | | **C** | bytes | 设定 LIKE 算子的通配符字符串允许的最大长度 | 0-16384 | 100 | 2.1.6.1 版本新增。 |
...@@ -239,7 +239,7 @@ taosd -C ...@@ -239,7 +239,7 @@ taosd -C
| 10 | fsync | 毫秒 | 当wal设置为2时,执行fsync的周期。设置为0,表示每次写入,立即执行fsync。 | | 3000 | | 10 | fsync | 毫秒 | 当wal设置为2时,执行fsync的周期。设置为0,表示每次写入,立即执行fsync。 | | 3000 |
| 11 | replica | | (可通过 alter database 修改)副本个数 | 1-3 | 1 | | 11 | replica | | (可通过 alter database 修改)副本个数 | 1-3 | 1 |
| 12 | precision | | 时间戳精度标识(2.1.2.0 版本之前、2.0.20.7 版本之前在 taos.cfg 文件中不支持此参数。)(从 2.1.5.0 版本开始,新增对纳秒时间精度的支持) | ms 表示毫秒,us 表示微秒,ns 表示纳秒 | ms | | 12 | precision | | 时间戳精度标识(2.1.2.0 版本之前、2.0.20.7 版本之前在 taos.cfg 文件中不支持此参数。)(从 2.1.5.0 版本开始,新增对纳秒时间精度的支持) | ms 表示毫秒,us 表示微秒,ns 表示纳秒 | ms |
| 13 | update | | 是否允许更新 | 0:不允许;1:允许 | 0 | | 13 | update | | 是否允许数据更新(从 2.1.7.0 版本开始此参数支持 0~2 的取值范围,在此之前取值只能是 [0, 1];而 2.0.8.0 之前的版本在 SQL 指令中不支持此参数。) | 0:不允许;1:允许更新整行;2:允许部分列更新。 | 0 |
| 14 | cacheLast | | (可通过 alter database 修改)是否在内存中缓存子表的最近数据(从 2.1.2.0 版本开始此参数支持 0~3 的取值范围,在此之前取值只能是 [0, 1];而 2.0.11.0 之前的版本在 SQL 指令中不支持此参数。)(2.1.2.0 版本之前、2.0.20.7 版本之前在 taos.cfg 文件中不支持此参数。) | 0:关闭;1:缓存子表最近一行数据;2:缓存子表每一列的最近的非NULL值;3:同时打开缓存最近行和列功能 | 0 | | 14 | cacheLast | | (可通过 alter database 修改)是否在内存中缓存子表的最近数据(从 2.1.2.0 版本开始此参数支持 0~3 的取值范围,在此之前取值只能是 [0, 1];而 2.0.11.0 之前的版本在 SQL 指令中不支持此参数。)(2.1.2.0 版本之前、2.0.20.7 版本之前在 taos.cfg 文件中不支持此参数。) | 0:关闭;1:缓存子表最近一行数据;2:缓存子表每一列的最近的非NULL值;3:同时打开缓存最近行和列功能 | 0 |
对于一个应用场景,可能有多种数据特征的数据并存,最佳的设计是将具有相同数据特征的表放在一个库里,这样一个应用有多个库,而每个库可以配置不同的存储参数,从而保证系统有最优的性能。TDengine允许应用在创建库时指定上述存储参数,如果指定,该参数就将覆盖对应的系统配置参数。举例,有下述SQL: 对于一个应用场景,可能有多种数据特征的数据并存,最佳的设计是将具有相同数据特征的表放在一个库里,这样一个应用有多个库,而每个库可以配置不同的存储参数,从而保证系统有最优的性能。TDengine允许应用在创建库时指定上述存储参数,如果指定,该参数就将覆盖对应的系统配置参数。举例,有下述SQL:
......
...@@ -99,7 +99,7 @@ gcc -g -O0 -fPIC -shared add_one.c -o add_one.so ...@@ -99,7 +99,7 @@ gcc -g -O0 -fPIC -shared add_one.c -o add_one.so
在创建 UDF 时,需要区分标量函数和聚合函数。如果创建时声明了错误的函数类别,则可能导致通过 SQL 指令调用函数时出错。 在创建 UDF 时,需要区分标量函数和聚合函数。如果创建时声明了错误的函数类别,则可能导致通过 SQL 指令调用函数时出错。
- 创建标量函数:`CREATE FUNCTION ids(X) AS ids(Y) OUTPUTTYPE typename(Z) bufsize(B);` - 创建标量函数:`CREATE FUNCTION ids(X) AS ids(Y) OUTPUTTYPE typename(Z) bufsize B;`
* ids(X):标量函数未来在 SQL 指令中被调用时的函数名,必须与函数实现中 udfNormalFunc 的实际名称一致; * ids(X):标量函数未来在 SQL 指令中被调用时的函数名,必须与函数实现中 udfNormalFunc 的实际名称一致;
* ids(Y):包含 UDF 函数实现的动态链接库的库文件路径(指的是库文件在当前客户端所在主机上的保存路径,通常是指向一个 .so 文件),这个路径需要用英文单引号或英文双引号括起来; * ids(Y):包含 UDF 函数实现的动态链接库的库文件路径(指的是库文件在当前客户端所在主机上的保存路径,通常是指向一个 .so 文件),这个路径需要用英文单引号或英文双引号括起来;
* typename(Z):此函数计算结果的数据类型,与上文中 udfNormalFunc 的 itype 参数不同,这里不是使用数字表示法,而是直接写类型名称即可; * typename(Z):此函数计算结果的数据类型,与上文中 udfNormalFunc 的 itype 参数不同,这里不是使用数字表示法,而是直接写类型名称即可;
...@@ -107,10 +107,10 @@ gcc -g -O0 -fPIC -shared add_one.c -o add_one.so ...@@ -107,10 +107,10 @@ gcc -g -O0 -fPIC -shared add_one.c -o add_one.so
例如,如下语句可以把 add_one.so 创建为系统中可用的 UDF: 例如,如下语句可以把 add_one.so 创建为系统中可用的 UDF:
```sql ```sql
CREATE FUNCTION add_one AS "/home/taos/udf_example/add_one.so" OUTPUTTYPE INT bufsize(128); CREATE FUNCTION add_one AS "/home/taos/udf_example/add_one.so" OUTPUTTYPE INT bufsize 128;
``` ```
- 创建聚合函数:`CREATE AGGREGATE FUNCTION ids(X) AS ids(Y) OUTPUTTYPE typename(Z) bufsize(B);` - 创建聚合函数:`CREATE AGGREGATE FUNCTION ids(X) AS ids(Y) OUTPUTTYPE typename(Z) bufsize B;`
* ids(X):聚合函数未来在 SQL 指令中被调用时的函数名,必须与函数实现中 udfNormalFunc 的实际名称一致; * ids(X):聚合函数未来在 SQL 指令中被调用时的函数名,必须与函数实现中 udfNormalFunc 的实际名称一致;
* ids(Y):包含 UDF 函数实现的动态链接库的库文件路径(指的是库文件在当前客户端所在主机上的保存路径,通常是指向一个 .so 文件),这个路径需要用英文单引号或英文双引号括起来; * ids(Y):包含 UDF 函数实现的动态链接库的库文件路径(指的是库文件在当前客户端所在主机上的保存路径,通常是指向一个 .so 文件),这个路径需要用英文单引号或英文双引号括起来;
* typename(Z):此函数计算结果的数据类型,与上文中 udfNormalFunc 的 itype 参数不同,这里不是使用数字表示法,而是直接写类型名称即可; * typename(Z):此函数计算结果的数据类型,与上文中 udfNormalFunc 的 itype 参数不同,这里不是使用数字表示法,而是直接写类型名称即可;
...@@ -118,7 +118,7 @@ gcc -g -O0 -fPIC -shared add_one.c -o add_one.so ...@@ -118,7 +118,7 @@ gcc -g -O0 -fPIC -shared add_one.c -o add_one.so
例如,如下语句可以把 add_one.so 创建为系统中可用的 UDF: 例如,如下语句可以把 add_one.so 创建为系统中可用的 UDF:
```sql ```sql
CREATE FUNCTION abs_max AS "/home/taos/udf_example/abs_max.so" OUTPUTTYPE BIGINT bufsize(128); CREATE FUNCTION abs_max AS "/home/taos/udf_example/abs_max.so" OUTPUTTYPE BIGINT bufsize 128;
``` ```
### 管理 UDF ### 管理 UDF
......
...@@ -70,7 +70,7 @@ TDengine 缺省的时间戳是毫秒精度,但通过在 CREATE DATABASE 时传 ...@@ -70,7 +70,7 @@ TDengine 缺省的时间戳是毫秒精度,但通过在 CREATE DATABASE 时传
1) KEEP是该数据库的数据保留多长天数,缺省是3650天(10年),数据库会自动删除超过时限的数据;<!-- REPLACE_OPEN_TO_ENTERPRISE__KEEP_PARAM_DESCRIPTION --> 1) KEEP是该数据库的数据保留多长天数,缺省是3650天(10年),数据库会自动删除超过时限的数据;<!-- REPLACE_OPEN_TO_ENTERPRISE__KEEP_PARAM_DESCRIPTION -->
2) UPDATE 标志数据库支持更新相同时间戳数据; 2) UPDATE 标志数据库支持更新相同时间戳数据;(从 2.1.7.0 版本开始此参数支持设为 2,表示允许部分列更新,也即更新数据行时未被设置的列会保留原值。)(从 2.0.8.0 版本开始支持此参数。注意此参数不能通过 `ALTER DATABASE` 指令进行修改。)
3) 数据库名最大长度为33; 3) 数据库名最大长度为33;
...@@ -573,16 +573,24 @@ Query OK, 2 row(s) in set (0.003112s) ...@@ -573,16 +573,24 @@ Query OK, 2 row(s) in set (0.003112s)
注意:普通表的通配符 * 中并不包含 _标签列_。 注意:普通表的通配符 * 中并不包含 _标签列_。
##### 获取标签列的去重取值 #### 获取标签列或普通列的去重取值
从 2.0.15 版本开始,支持在超级表查询标签列时,指定 DISTINCT 关键字,这样将返回指定标签列的所有不重复取值 从 2.0.15.0 版本开始,支持在超级表查询标签列时,指定 DISTINCT 关键字,这样将返回指定标签列的所有不重复取值。注意,在 2.1.6.0 版本之前,DISTINCT 只支持处理单个标签列,而从 2.1.6.0 版本开始,DISTINCT 可以对多个标签列进行处理,输出这些标签列取值不重复的组合
```mysql ```sql
SELECT DISTINCT tag_name FROM stb_name; SELECT DISTINCT tag_name [, tag_name ...] FROM stb_name;
``` ```
注意:目前 DISTINCT 关键字只支持对超级表的标签列进行去重,而不能用于普通列。 从 2.1.7.0 版本开始,DISTINCT 也支持对数据子表或普通表进行处理,也即支持获取单个普通列的不重复取值,或多个普通列取值的不重复组合。
```sql
SELECT DISTINCT col_name [, col_name ...] FROM tb_name;
```
需要注意的是,DISTINCT 目前不支持对超级表中的普通列进行处理。如果需要进行此类操作,那么需要把超级表放在子查询中,再对子查询的计算结果执行 DISTINCT。
说明:
1. cfg 文件中的配置参数 maxNumOfDistinctRes 将对 DISTINCT 能够输出的数据行数进行限制。其最小值是 100000,最大值是 100000000,默认值是 10000000。如果实际计算结果超出了这个限制,那么会仅输出这个数量范围内的部分。
2. 由于浮点数天然的精度机制原因,在特定情况下,对 FLOAT 和 DOUBLE 列使用 DISTINCT 并不能保证输出值的完全唯一性。
3. 在当前版本下,DISTINCT 不能在嵌套查询的子查询中使用,也不能与聚合函数、GROUP BY、或 JOIN 在同一条语句中混用。
#### 结果集列名 #### 结果集列名
......
...@@ -96,6 +96,8 @@ TDengine 目前尚不支持删除功能,未来根据用户需求可能会支 ...@@ -96,6 +96,8 @@ TDengine 目前尚不支持删除功能,未来根据用户需求可能会支
另需注意,在 UPDATE 设置为 0 时,后发送的相同时间戳的数据会被直接丢弃,但并不会报错,而且仍然会被计入 affected rows (所以不能利用 INSERT 指令的返回信息进行时间戳查重)。这样设计的主要原因是,TDengine 把写入的数据看做一个数据流,无论时间戳是否出现冲突,TDengine 都认为产生数据的原始设备真实地产生了这样的数据。UPDATE 参数只是控制这样的流数据在进行持久化时要怎样处理——UPDATE 为 0 时,表示先写入的数据覆盖后写入的数据;而 UPDATE 为 1 时,表示后写入的数据覆盖先写入的数据。这种覆盖关系如何选择,取决于对数据的后续使用和统计中,希望以先还是后生成的数据为准。 另需注意,在 UPDATE 设置为 0 时,后发送的相同时间戳的数据会被直接丢弃,但并不会报错,而且仍然会被计入 affected rows (所以不能利用 INSERT 指令的返回信息进行时间戳查重)。这样设计的主要原因是,TDengine 把写入的数据看做一个数据流,无论时间戳是否出现冲突,TDengine 都认为产生数据的原始设备真实地产生了这样的数据。UPDATE 参数只是控制这样的流数据在进行持久化时要怎样处理——UPDATE 为 0 时,表示先写入的数据覆盖后写入的数据;而 UPDATE 为 1 时,表示后写入的数据覆盖先写入的数据。这种覆盖关系如何选择,取决于对数据的后续使用和统计中,希望以先还是后生成的数据为准。
此外,从 2.1.7.0 版本开始,支持将 UPDATE 参数设为 2,表示“支持部分列更新”。也即,当 UPDATE 设为 1 时,如果更新一个数据行,其中某些列没有提供取值,那么这些列会被设为 NULL;而当 UPDATE 设为 2 时,如果更新一个数据行,其中某些列没有提供取值,那么这些列会保持原有数据行中的对应值。
## 10. 我怎么创建超过1024列的表? ## 10. 我怎么创建超过1024列的表?
使用 2.0 及其以上版本,默认支持 1024 列;2.0 之前的版本,TDengine 最大允许创建 250 列的表。但是如果确实超过限值,建议按照数据特性,逻辑地将这个宽表分解成几个小表。(从 2.1.7.0 版本开始,表的最大列数增加到了 4096 列。) 使用 2.0 及其以上版本,默认支持 1024 列;2.0 之前的版本,TDengine 最大允许创建 250 列的表。但是如果确实超过限值,建议按照数据特性,逻辑地将这个宽表分解成几个小表。(从 2.1.7.0 版本开始,表的最大列数增加到了 4096 列。)
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
## <a class="anchor" id="queries"></a> Main Query Features ## <a class="anchor" id="queries"></a> Main Query Features
TDengine uses SQL as the query language. Applications can send SQL statements through C/C++, Java, Go, Python connectors, and users can manually execute SQL Ad-Hoc Query through the Command Line Interface (CLI) tool TAOS Shell provided by TDengine. TDengine supports the following query functions: TDengine uses SQL as the query language. Applications can send SQL statements through C/C++, Java, Go, C#, Python, Node.js connectors, and users can manually execute SQL Ad-Hoc Query through the Command Line Interface (CLI) tool TAOS Shell provided by TDengine. TDengine supports the following query functions:
- Single-column and multi-column data query - Single-column and multi-column data query
- Multiple filters for tags and numeric values: >, <, =, < >, like, etc - Multiple filters for tags and numeric values: >, <, =, < >, like, etc
......
...@@ -2551,6 +2551,9 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col ...@@ -2551,6 +2551,9 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
case TSDB_FUNC_MAX: case TSDB_FUNC_MAX:
case TSDB_FUNC_DIFF: case TSDB_FUNC_DIFF:
case TSDB_FUNC_DERIVATIVE: case TSDB_FUNC_DERIVATIVE:
case TSDB_FUNC_CEIL:
case TSDB_FUNC_FLOOR:
case TSDB_FUNC_ROUND:
case TSDB_FUNC_STDDEV: case TSDB_FUNC_STDDEV:
case TSDB_FUNC_LEASTSQR: { case TSDB_FUNC_LEASTSQR: {
// 1. valid the number of parameters // 1. valid the number of parameters
...@@ -2741,6 +2744,10 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col ...@@ -2741,6 +2744,10 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
if (pParamElem->pNode->columnName.z == NULL) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
// functions can not be applied to tags // functions can not be applied to tags
if ((index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) || (index.columnIndex < 0)) { if ((index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) || (index.columnIndex < 0)) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6);
...@@ -3474,6 +3481,7 @@ static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool ...@@ -3474,6 +3481,7 @@ static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool
int32_t scalarUdf = 0; int32_t scalarUdf = 0;
int32_t prjNum = 0; int32_t prjNum = 0;
int32_t aggNum = 0; int32_t aggNum = 0;
int32_t scalNum = 0;
size_t numOfExpr = tscNumOfExprs(pQueryInfo); size_t numOfExpr = tscNumOfExprs(pQueryInfo);
assert(numOfExpr > 0); assert(numOfExpr > 0);
...@@ -3505,6 +3513,10 @@ static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool ...@@ -3505,6 +3513,10 @@ static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool
++prjNum; ++prjNum;
} }
if (functionId == TSDB_FUNC_CEIL || functionId == TSDB_FUNC_FLOOR || functionId == TSDB_FUNC_ROUND) {
++scalNum;
}
if (functionId == TSDB_FUNC_PRJ && (pExpr1->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX || TSDB_COL_IS_UD_COL(pExpr1->base.colInfo.flag))) { if (functionId == TSDB_FUNC_PRJ && (pExpr1->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX || TSDB_COL_IS_UD_COL(pExpr1->base.colInfo.flag))) {
continue; continue;
} }
...@@ -3526,15 +3538,19 @@ static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool ...@@ -3526,15 +3538,19 @@ static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool
} }
} }
aggNum = (int32_t)size - prjNum - aggUdf - scalarUdf; aggNum = (int32_t)size - prjNum - scalNum - aggUdf - scalarUdf;
assert(aggNum >= 0); assert(aggNum >= 0);
if (aggUdf > 0 && (prjNum > 0 || aggNum > 0 || scalarUdf > 0)) { if (aggUdf > 0 && (prjNum > 0 || aggNum > 0 || scalNum > 0 || scalarUdf > 0)) {
return false;
}
if (scalarUdf > 0 && (aggNum > 0 || scalNum > 0)) {
return false; return false;
} }
if (scalarUdf > 0 && aggNum > 0) { if (aggNum > 0 && scalNum > 0) {
return false; return false;
} }
...@@ -6536,7 +6552,9 @@ int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQu ...@@ -6536,7 +6552,9 @@ int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQu
} }
int32_t f = pExpr->base.functionId; int32_t f = pExpr->base.functionId;
if ((f == TSDB_FUNC_PRJ && pExpr->base.numOfParams == 0) || f == TSDB_FUNC_DIFF || f == TSDB_FUNC_ARITHM || f == TSDB_FUNC_DERIVATIVE) { if ((f == TSDB_FUNC_PRJ && pExpr->base.numOfParams == 0) || f == TSDB_FUNC_DIFF || f == TSDB_FUNC_ARITHM || f == TSDB_FUNC_DERIVATIVE ||
f == TSDB_FUNC_CEIL || f == TSDB_FUNC_FLOOR || f == TSDB_FUNC_ROUND)
{
isProjectionFunction = true; isProjectionFunction = true;
break; break;
} }
...@@ -7138,6 +7156,7 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) { ...@@ -7138,6 +7156,7 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) {
const char* msg2 = "aggregation function should not be mixed up with projection"; const char* msg2 = "aggregation function should not be mixed up with projection";
bool tagTsColExists = false; bool tagTsColExists = false;
int16_t numOfScalar = 0;
int16_t numOfSelectivity = 0; int16_t numOfSelectivity = 0;
int16_t numOfAggregation = 0; int16_t numOfAggregation = 0;
...@@ -7171,6 +7190,8 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) { ...@@ -7171,6 +7190,8 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) {
if ((aAggs[functionId].status & TSDB_FUNCSTATE_SELECTIVITY) != 0) { if ((aAggs[functionId].status & TSDB_FUNCSTATE_SELECTIVITY) != 0) {
numOfSelectivity++; numOfSelectivity++;
} else if ((aAggs[functionId].status & TSDB_FUNCSTATE_SCALAR) != 0) {
numOfScalar++;
} else { } else {
numOfAggregation++; numOfAggregation++;
} }
......
...@@ -269,7 +269,10 @@ bool tscIsProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex) { ...@@ -269,7 +269,10 @@ bool tscIsProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex) {
functionId != TSDB_FUNC_DIFF && functionId != TSDB_FUNC_DIFF &&
functionId != TSDB_FUNC_DERIVATIVE && functionId != TSDB_FUNC_DERIVATIVE &&
functionId != TSDB_FUNC_TS_DUMMY && functionId != TSDB_FUNC_TS_DUMMY &&
functionId != TSDB_FUNC_TID_TAG) { functionId != TSDB_FUNC_TID_TAG &&
functionId != TSDB_FUNC_CEIL &&
functionId != TSDB_FUNC_FLOOR &&
functionId != TSDB_FUNC_ROUND) {
return false; return false;
} }
} }
...@@ -1465,7 +1468,12 @@ void tscFreeSubobj(SSqlObj* pSql) { ...@@ -1465,7 +1468,12 @@ void tscFreeSubobj(SSqlObj* pSql) {
tscDebug("0x%"PRIx64" start to free sub SqlObj, numOfSub:%d", pSql->self, pSql->subState.numOfSub); tscDebug("0x%"PRIx64" start to free sub SqlObj, numOfSub:%d", pSql->self, pSql->subState.numOfSub);
for(int32_t i = 0; i < pSql->subState.numOfSub; ++i) { for(int32_t i = 0; i < pSql->subState.numOfSub; ++i) {
if (pSql->pSubs[i] != NULL) {
tscDebug("0x%"PRIx64" free sub SqlObj:0x%"PRIx64", index:%d", pSql->self, pSql->pSubs[i]->self, i); tscDebug("0x%"PRIx64" free sub SqlObj:0x%"PRIx64", index:%d", pSql->self, pSql->pSubs[i]->self, i);
} else {
/* just for python error test case */
tscDebug("0x%"PRIx64" free sub SqlObj:0x0, index:%d", pSql->self, i);
}
taos_free_result(pSql->pSubs[i]); taos_free_result(pSql->pSubs[i]);
pSql->pSubs[i] = NULL; pSql->pSubs[i] = NULL;
} }
......
...@@ -104,6 +104,7 @@ extern char configDir[]; ...@@ -104,6 +104,7 @@ extern char configDir[];
#define DATATYPE_BUFF_LEN (SMALL_BUFF_LEN*3) #define DATATYPE_BUFF_LEN (SMALL_BUFF_LEN*3)
#define NOTE_BUFF_LEN (SMALL_BUFF_LEN*16) #define NOTE_BUFF_LEN (SMALL_BUFF_LEN*16)
#define DEFAULT_NTHREADS 8
#define DEFAULT_TIMESTAMP_STEP 1 #define DEFAULT_TIMESTAMP_STEP 1
#define DEFAULT_INTERLACE_ROWS 0 #define DEFAULT_INTERLACE_ROWS 0
#define DEFAULT_DATATYPE_NUM 1 #define DEFAULT_DATATYPE_NUM 1
...@@ -227,7 +228,7 @@ typedef struct SArguments_S { ...@@ -227,7 +228,7 @@ typedef struct SArguments_S {
char * sqlFile; char * sqlFile;
bool use_metric; bool use_metric;
bool drop_database; bool drop_database;
bool insert_only; bool aggr_func;
bool answer_yes; bool answer_yes;
bool debug_print; bool debug_print;
bool verbose_print; bool verbose_print;
...@@ -375,8 +376,7 @@ typedef struct SDbs_S { ...@@ -375,8 +376,7 @@ typedef struct SDbs_S {
char password[SHELL_MAX_PASSWORD_LEN]; char password[SHELL_MAX_PASSWORD_LEN];
char resultFile[MAX_FILE_NAME_LEN]; char resultFile[MAX_FILE_NAME_LEN];
bool use_metric; bool use_metric;
bool insert_only; bool aggr_func;
bool do_aggreFunc;
bool asyncMode; bool asyncMode;
uint32_t threadCount; uint32_t threadCount;
...@@ -605,6 +605,9 @@ char *g_rand_current_buff = NULL; ...@@ -605,6 +605,9 @@ char *g_rand_current_buff = NULL;
char *g_rand_phase_buff = NULL; char *g_rand_phase_buff = NULL;
char *g_randdouble_buff = NULL; char *g_randdouble_buff = NULL;
char *g_aggreFuncDemo[] = {"*", "count(*)", "avg(current)", "sum(current)",
"max(current)", "min(current)", "first(current)", "last(current)"};
char *g_aggreFunc[] = {"*", "count(*)", "avg(C0)", "sum(C0)", char *g_aggreFunc[] = {"*", "count(*)", "avg(C0)", "sum(C0)",
"max(C0)", "min(C0)", "first(C0)", "last(C0)"}; "max(C0)", "min(C0)", "first(C0)", "last(C0)"};
...@@ -628,7 +631,7 @@ SArguments g_args = { ...@@ -628,7 +631,7 @@ SArguments g_args = {
NULL, // sqlFile NULL, // sqlFile
true, // use_metric true, // use_metric
true, // drop_database true, // drop_database
true, // insert_only false, // aggr_func
false, // debug_print false, // debug_print
false, // verbose_print false, // verbose_print
false, // performance statistic print false, // performance statistic print
...@@ -646,7 +649,7 @@ SArguments g_args = { ...@@ -646,7 +649,7 @@ SArguments g_args = {
64, // binwidth 64, // binwidth
4, // columnCount, timestamp + float + int + float 4, // columnCount, timestamp + float + int + float
20 + FLOAT_BUFF_LEN + INT_BUFF_LEN + FLOAT_BUFF_LEN, // lenOfOneRow 20 + FLOAT_BUFF_LEN + INT_BUFF_LEN + FLOAT_BUFF_LEN, // lenOfOneRow
8, // num_of_connections/thread DEFAULT_NTHREADS,// nthreads
0, // insert_interval 0, // insert_interval
DEFAULT_TIMESTAMP_STEP, // timestamp_step DEFAULT_TIMESTAMP_STEP, // timestamp_step
1, // query_times 1, // query_times
...@@ -748,19 +751,19 @@ static void printHelp() { ...@@ -748,19 +751,19 @@ static void printHelp() {
char indent[10] = " "; char indent[10] = " ";
printf("%s\n\n", "Usage: taosdemo [OPTION...]"); printf("%s\n\n", "Usage: taosdemo [OPTION...]");
printf("%s%s%s%s\n", indent, "-f, --file=FILE", "\t\t", printf("%s%s%s%s\n", indent, "-f, --file=FILE", "\t\t",
"The meta file to the execution procedure. Default is './meta.json'."); "The meta file to the execution procedure.");
printf("%s%s%s%s\n", indent, "-u, --user=USER", "\t\t", printf("%s%s%s%s\n", indent, "-u, --user=USER", "\t\t",
"The user name to use when connecting to the server."); "The user name to use when connecting to the server.");
#ifdef _TD_POWER_ #ifdef _TD_POWER_
printf("%s%s%s%s\n", indent, "-p, --password", "\t\t", printf("%s%s%s%s\n", indent, "-p, --password", "\t\t",
"The password to use when connecting to the server. Default is 'powerdb'"); "The password to use when connecting to the server. By default is 'powerdb'");
printf("%s%s%s%s\n", indent, "-c, --config-dir=CONFIG_DIR", "\t", printf("%s%s%s%s\n", indent, "-c, --config-dir=CONFIG_DIR", "\t",
"Configuration directory. Default is '/etc/power/'."); "Configuration directory. By default is '/etc/power/'.");
#elif (_TD_TQ_ == true) #elif (_TD_TQ_ == true)
printf("%s%s%s%s\n", indent, "-p, --password", "\t\t", printf("%s%s%s%s\n", indent, "-p, --password", "\t\t",
"The password to use when connecting to the server. Default is 'tqueue'"); "The password to use when connecting to the server. By default is 'tqueue'");
printf("%s%s%s%s\n", indent, "-c, --config-dir=CONFIG_DIR", "\t", printf("%s%s%s%s\n", indent, "-c, --config-dir=CONFIG_DIR", "\t",
"Configuration directory. Default is '/etc/tq/'."); "Configuration directory. By default is '/etc/tq/'.");
#else #else
printf("%s%s%s%s\n", indent, "-p, --password", "\t\t", printf("%s%s%s%s\n", indent, "-p, --password", "\t\t",
"The password to use when connecting to the server."); "The password to use when connecting to the server.");
...@@ -772,24 +775,24 @@ static void printHelp() { ...@@ -772,24 +775,24 @@ static void printHelp() {
printf("%s%s%s%s\n", indent, "-P, --port=PORT", "\t\t", printf("%s%s%s%s\n", indent, "-P, --port=PORT", "\t\t",
"The TCP/IP port number to use for the connection."); "The TCP/IP port number to use for the connection.");
printf("%s%s%s%s\n", indent, "-I, --interface=INTERFACE", "\t", printf("%s%s%s%s\n", indent, "-I, --interface=INTERFACE", "\t",
"The interface (taosc, rest, and stmt) taosdemo uses. Default is 'taosc'."); "The interface (taosc, rest, and stmt) taosdemo uses. By default use 'taosc'.");
printf("%s%s%s%s\n", indent, "-d, --database=DATABASE", "\t", printf("%s%s%s%s\n", indent, "-d, --database=DATABASE", "\t",
"Destination database. Default is 'test'."); "Destination database. By default is 'test'.");
printf("%s%s%s%s\n", indent, "-a, --replica=REPLICA", "\t\t", printf("%s%s%s%s\n", indent, "-a, --replica=REPLICA", "\t\t",
"Set the replica parameters of the database, Default 1, min: 1, max: 3."); "Set the replica parameters of the database, By default use 1, min: 1, max: 3.");
printf("%s%s%s%s\n", indent, "-m, --table-prefix=TABLEPREFIX", "\t", printf("%s%s%s%s\n", indent, "-m, --table-prefix=TABLEPREFIX", "\t",
"Table prefix name. Default is 'd'."); "Table prefix name. By default use 'd'.");
printf("%s%s%s%s\n", indent, "-s, --sql-file=FILE", "\t\t", printf("%s%s%s%s\n", indent, "-s, --sql-file=FILE", "\t\t",
"The select sql file."); "The select sql file.");
printf("%s%s%s%s\n", indent, "-N, --normal-table", "\t\t", "Use normal table flag."); printf("%s%s%s%s\n", indent, "-N, --normal-table", "\t\t", "Use normal table flag.");
printf("%s%s%s%s\n", indent, "-o, --output=FILE", "\t\t", printf("%s%s%s%s\n", indent, "-o, --output=FILE", "\t\t",
"Direct output to the named file. Default is './output.txt'."); "Direct output to the named file. By default use './output.txt'.");
printf("%s%s%s%s\n", indent, "-q, --query-mode=MODE", "\t\t", printf("%s%s%s%s\n", indent, "-q, --query-mode=MODE", "\t\t",
"Query mode -- 0: SYNC, 1: ASYNC. Default is SYNC."); "Query mode -- 0: SYNC, 1: ASYNC. By default use SYNC.");
printf("%s%s%s%s\n", indent, "-b, --data-type=DATATYPE", "\t", printf("%s%s%s%s\n", indent, "-b, --data-type=DATATYPE", "\t",
"The data_type of columns, default: FLOAT, INT, FLOAT."); "The data_type of columns, By default use: FLOAT, INT, FLOAT.");
printf("%s%s%s%s%d\n", indent, "-w, --binwidth=WIDTH", "\t\t", printf("%s%s%s%s%d\n", indent, "-w, --binwidth=WIDTH", "\t\t",
"The width of data_type 'BINARY' or 'NCHAR'. Default is ", "The width of data_type 'BINARY' or 'NCHAR'. By default use ",
g_args.binwidth); g_args.binwidth);
printf("%s%s%s%s%d%s%d\n", indent, "-l, --columns=COLUMNS", "\t\t", printf("%s%s%s%s%d%s%d\n", indent, "-l, --columns=COLUMNS", "\t\t",
"The number of columns per record. Demo mode by default is ", "The number of columns per record. Demo mode by default is ",
...@@ -798,32 +801,32 @@ static void printHelp() { ...@@ -798,32 +801,32 @@ static void printHelp() {
MAX_NUM_COLUMNS); MAX_NUM_COLUMNS);
printf("%s%s%s%s\n", indent, indent, indent, printf("%s%s%s%s\n", indent, indent, indent,
"\t\t\t\tAll of the new column(s) type is INT. If use -b to specify column type, -l will be ignored."); "\t\t\t\tAll of the new column(s) type is INT. If use -b to specify column type, -l will be ignored.");
printf("%s%s%s%s\n", indent, "-T, --threads=NUMBER", "\t\t", printf("%s%s%s%s%d.\n", indent, "-T, --threads=NUMBER", "\t\t",
"The number of threads. Default is 10."); "The number of threads. By default use ", DEFAULT_NTHREADS);
printf("%s%s%s%s\n", indent, "-i, --insert-interval=NUMBER", "\t", printf("%s%s%s%s\n", indent, "-i, --insert-interval=NUMBER", "\t",
"The sleep time (ms) between insertion. Default is 0."); "The sleep time (ms) between insertion. By default is 0.");
printf("%s%s%s%s%d.\n", indent, "-S, --time-step=TIME_STEP", "\t", printf("%s%s%s%s%d.\n", indent, "-S, --time-step=TIME_STEP", "\t",
"The timestamp step between insertion. Default is ", "The timestamp step between insertion. By default is ",
DEFAULT_TIMESTAMP_STEP); DEFAULT_TIMESTAMP_STEP);
printf("%s%s%s%s%d.\n", indent, "-B, --interlace-rows=NUMBER", "\t", printf("%s%s%s%s%d.\n", indent, "-B, --interlace-rows=NUMBER", "\t",
"The interlace rows of insertion. Default is ", "The interlace rows of insertion. By default is ",
DEFAULT_INTERLACE_ROWS); DEFAULT_INTERLACE_ROWS);
printf("%s%s%s%s\n", indent, "-r, --rec-per-req=NUMBER", "\t", printf("%s%s%s%s\n", indent, "-r, --rec-per-req=NUMBER", "\t",
"The number of records per request. Default is 30000."); "The number of records per request. By default is 30000.");
printf("%s%s%s%s\n", indent, "-t, --tables=NUMBER", "\t\t", printf("%s%s%s%s\n", indent, "-t, --tables=NUMBER", "\t\t",
"The number of tables. Default is 10000."); "The number of tables. By default is 10000.");
printf("%s%s%s%s\n", indent, "-n, --records=NUMBER", "\t\t", printf("%s%s%s%s\n", indent, "-n, --records=NUMBER", "\t\t",
"The number of records per table. Default is 10000."); "The number of records per table. By default is 10000.");
printf("%s%s%s%s\n", indent, "-M, --random", "\t\t\t", printf("%s%s%s%s\n", indent, "-M, --random", "\t\t\t",
"The value of records generated are totally random."); "The value of records generated are totally random.");
printf("%s\n", "\t\t\t\tThe default is to simulate power equipment scenario."); printf("%s\n", "\t\t\t\tBy default to simulate power equipment scenario.");
printf("%s%s%s%s\n", indent, "-x, --no-insert", "\t\t", printf("%s%s%s%s\n", indent, "-x, --aggr-func", "\t\t",
"No-insert flag."); "Test aggregation functions after insertion.");
printf("%s%s%s%s\n", indent, "-y, --answer-yes", "\t\t", "Default input yes for prompt."); printf("%s%s%s%s\n", indent, "-y, --answer-yes", "\t\t", "Input yes for prompt.");
printf("%s%s%s%s\n", indent, "-O, --disorder=NUMBER", "\t\t", printf("%s%s%s%s\n", indent, "-O, --disorder=NUMBER", "\t\t",
"Insert order mode--0: In order, 1 ~ 50: disorder ratio. Default is in order."); "Insert order mode--0: In order, 1 ~ 50: disorder ratio. By default is in order.");
printf("%s%s%s%s\n", indent, "-R, --disorder-range=NUMBER", "\t", printf("%s%s%s%s\n", indent, "-R, --disorder-range=NUMBER", "\t",
"Out of order data's range, ms, default is 1000."); "Out of order data's range. Unit is ms. By default is 1000.");
printf("%s%s%s%s\n", indent, "-g, --debug", "\t\t\t", printf("%s%s%s%s\n", indent, "-g, --debug", "\t\t\t",
"Print debug info."); "Print debug info.");
printf("%s%s%s%s\n", indent, "-?, --help\t", "\t\t", printf("%s%s%s%s\n", indent, "-?, --help\t", "\t\t",
...@@ -1712,13 +1715,14 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { ...@@ -1712,13 +1715,14 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) {
} }
} else if ((strcmp(argv[i], "-N") == 0) } else if ((strcmp(argv[i], "-N") == 0)
|| (0 == strcmp(argv[i], "--normal-table"))) { || (0 == strcmp(argv[i], "--normal-table"))) {
arguments->demo_mode = false;
arguments->use_metric = false; arguments->use_metric = false;
} else if ((strcmp(argv[i], "-M") == 0) } else if ((strcmp(argv[i], "-M") == 0)
|| (0 == strcmp(argv[i], "--random"))) { || (0 == strcmp(argv[i], "--random"))) {
arguments->demo_mode = false; arguments->demo_mode = false;
} else if ((strcmp(argv[i], "-x") == 0) } else if ((strcmp(argv[i], "-x") == 0)
|| (0 == strcmp(argv[i], "--no-insert"))) { || (0 == strcmp(argv[i], "--aggr-func"))) {
arguments->insert_only = false; arguments->aggr_func = true;
} else if ((strcmp(argv[i], "-y") == 0) } else if ((strcmp(argv[i], "-y") == 0)
|| (0 == strcmp(argv[i], "--answer-yes"))) { || (0 == strcmp(argv[i], "--answer-yes"))) {
arguments->answer_yes = true; arguments->answer_yes = true;
...@@ -2429,10 +2433,11 @@ static void init_rand_data() { ...@@ -2429,10 +2433,11 @@ static void init_rand_data() {
static int printfInsertMeta() { static int printfInsertMeta() {
SHOW_PARSE_RESULT_START(); SHOW_PARSE_RESULT_START();
if (g_args.demo_mode) if (g_args.demo_mode) {
printf("\ntaosdemo is simulating data generated by power equipments monitoring...\n\n"); printf("\ntaosdemo is simulating data generated by power equipment monitoring...\n\n");
else } else {
printf("\ntaosdemo is simulating random data as you request..\n\n"); printf("\ntaosdemo is simulating random data as you request..\n\n");
}
if (g_args.iface != INTERFACE_BUT) { if (g_args.iface != INTERFACE_BUT) {
// first time if no iface specified // first time if no iface specified
...@@ -10065,11 +10070,10 @@ static void startMultiThreadInsertData(int threads, char* db_name, ...@@ -10065,11 +10070,10 @@ static void startMultiThreadInsertData(int threads, char* db_name,
free(infos); free(infos);
} }
static void *readTable(void *sarg) { static void *queryNtableAggrFunc(void *sarg) {
#if 1
threadInfo *pThreadInfo = (threadInfo *)sarg; threadInfo *pThreadInfo = (threadInfo *)sarg;
TAOS *taos = pThreadInfo->taos; TAOS *taos = pThreadInfo->taos;
setThreadName("readTable"); setThreadName("queryNtableAggrFunc");
char *command = calloc(1, BUFFER_SIZE); char *command = calloc(1, BUFFER_SIZE);
assert(command); assert(command);
...@@ -10092,10 +10096,20 @@ static void *readTable(void *sarg) { ...@@ -10092,10 +10096,20 @@ static void *readTable(void *sarg) {
int64_t ntables = pThreadInfo->ntables; // pThreadInfo->end_table_to - pThreadInfo->start_table_from + 1; int64_t ntables = pThreadInfo->ntables; // pThreadInfo->end_table_to - pThreadInfo->start_table_from + 1;
int64_t totalData = insertRows * ntables; int64_t totalData = insertRows * ntables;
bool do_aggreFunc = g_Dbs.do_aggreFunc; bool aggr_func = g_Dbs.aggr_func;
int n = do_aggreFunc ? (sizeof(g_aggreFunc) / sizeof(g_aggreFunc[0])) : 2; char **aggreFunc;
if (!do_aggreFunc) { int n;
if (g_args.demo_mode) {
aggreFunc = g_aggreFuncDemo;
n = aggr_func?(sizeof(g_aggreFuncDemo) / sizeof(g_aggreFuncDemo[0])) : 2;
} else {
aggreFunc = g_aggreFunc;
n = aggr_func?(sizeof(g_aggreFunc) / sizeof(g_aggreFunc[0])) : 2;
}
if (!aggr_func) {
printf("\nThe first field is either Binary or Bool. Aggregation functions are not supported.\n"); printf("\nThe first field is either Binary or Bool. Aggregation functions are not supported.\n");
} }
printf("%"PRId64" records:\n", totalData); printf("%"PRId64" records:\n", totalData);
...@@ -10106,9 +10120,11 @@ static void *readTable(void *sarg) { ...@@ -10106,9 +10120,11 @@ static void *readTable(void *sarg) {
uint64_t count = 0; uint64_t count = 0;
for (int64_t i = 0; i < ntables; i++) { for (int64_t i = 0; i < ntables; i++) {
sprintf(command, "SELECT %s FROM %s%"PRId64" WHERE ts>= %" PRIu64, sprintf(command, "SELECT %s FROM %s%"PRId64" WHERE ts>= %" PRIu64,
g_aggreFunc[j], tb_prefix, i, startTime); aggreFunc[j], tb_prefix, i, startTime);
double t = taosGetTimestampMs(); double t = taosGetTimestampUs();
debugPrint("%s() LN%d, sql command: %s\n",
__func__, __LINE__, command);
TAOS_RES *pSql = taos_query(taos, command); TAOS_RES *pSql = taos_query(taos, command);
int32_t code = taos_errno(pSql); int32_t code = taos_errno(pSql);
...@@ -10125,29 +10141,27 @@ static void *readTable(void *sarg) { ...@@ -10125,29 +10141,27 @@ static void *readTable(void *sarg) {
count++; count++;
} }
t = taosGetTimestampMs() - t; t = taosGetTimestampUs() - t;
totalT += t; totalT += t;
taos_free_result(pSql); taos_free_result(pSql);
} }
fprintf(fp, "|%10s | %"PRId64" | %12.2f | %10.2f |\n", fprintf(fp, "|%10s | %"PRId64" | %12.2f | %10.2f |\n",
g_aggreFunc[j][0] == '*' ? " * " : g_aggreFunc[j], totalData, aggreFunc[j][0] == '*' ? " * " : aggreFunc[j], totalData,
(double)(ntables * insertRows) / totalT, totalT * 1000); (double)(ntables * insertRows) / totalT, totalT / 1000000);
printf("select %10s took %.6f second(s)\n", g_aggreFunc[j], totalT * 1000); printf("select %10s took %.6f second(s)\n", aggreFunc[j], totalT / 1000000);
} }
fprintf(fp, "\n"); fprintf(fp, "\n");
fclose(fp); fclose(fp);
free(command); free(command);
#endif
return NULL; return NULL;
} }
static void *readMetric(void *sarg) { static void *queryStableAggrFunc(void *sarg) {
#if 1
threadInfo *pThreadInfo = (threadInfo *)sarg; threadInfo *pThreadInfo = (threadInfo *)sarg;
TAOS *taos = pThreadInfo->taos; TAOS *taos = pThreadInfo->taos;
setThreadName("readMetric"); setThreadName("queryStableAggrFunc");
char *command = calloc(1, BUFFER_SIZE); char *command = calloc(1, BUFFER_SIZE);
assert(command); assert(command);
...@@ -10161,12 +10175,23 @@ static void *readMetric(void *sarg) { ...@@ -10161,12 +10175,23 @@ static void *readMetric(void *sarg) {
int64_t insertRows = pThreadInfo->stbInfo->insertRows; int64_t insertRows = pThreadInfo->stbInfo->insertRows;
int64_t ntables = pThreadInfo->ntables; // pThreadInfo->end_table_to - pThreadInfo->start_table_from + 1; int64_t ntables = pThreadInfo->ntables; // pThreadInfo->end_table_to - pThreadInfo->start_table_from + 1;
int64_t totalData = insertRows * ntables; int64_t totalData = insertRows * ntables;
bool do_aggreFunc = g_Dbs.do_aggreFunc; bool aggr_func = g_Dbs.aggr_func;
char **aggreFunc;
int n;
if (g_args.demo_mode) {
aggreFunc = g_aggreFuncDemo;
n = aggr_func?(sizeof(g_aggreFuncDemo) / sizeof(g_aggreFuncDemo[0])) : 2;
} else {
aggreFunc = g_aggreFunc;
n = aggr_func?(sizeof(g_aggreFunc) / sizeof(g_aggreFunc[0])) : 2;
}
int n = do_aggreFunc ? (sizeof(g_aggreFunc) / sizeof(g_aggreFunc[0])) : 2; if (!aggr_func) {
if (!do_aggreFunc) {
printf("\nThe first field is either Binary or Bool. Aggregation functions are not supported.\n"); printf("\nThe first field is either Binary or Bool. Aggregation functions are not supported.\n");
} }
printf("%"PRId64" records:\n", totalData); printf("%"PRId64" records:\n", totalData);
fprintf(fp, "Querying On %"PRId64" records:\n", totalData); fprintf(fp, "Querying On %"PRId64" records:\n", totalData);
...@@ -10178,18 +10203,29 @@ static void *readMetric(void *sarg) { ...@@ -10178,18 +10203,29 @@ static void *readMetric(void *sarg) {
for (int64_t i = 1; i <= m; i++) { for (int64_t i = 1; i <= m; i++) {
if (i == 1) { if (i == 1) {
sprintf(tempS, "t1 = %"PRId64"", i); if (g_args.demo_mode) {
sprintf(tempS, "groupid = %"PRId64"", i);
} else { } else {
sprintf(tempS, " or t1 = %"PRId64" ", i); sprintf(tempS, "t0 = %"PRId64"", i);
}
} else {
if (g_args.demo_mode) {
sprintf(tempS, " or groupid = %"PRId64" ", i);
} else {
sprintf(tempS, " or t0 = %"PRId64" ", i);
}
} }
strncat(condition, tempS, COND_BUF_LEN - 1); 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", aggreFunc[j], condition);
printf("Where condition: %s\n", condition); printf("Where condition: %s\n", condition);
debugPrint("%s() LN%d, sql command: %s\n",
__func__, __LINE__, command);
fprintf(fp, "%s\n", command); fprintf(fp, "%s\n", command);
double t = taosGetTimestampMs(); double t = taosGetTimestampUs();
TAOS_RES *pSql = taos_query(taos, command); TAOS_RES *pSql = taos_query(taos, command);
int32_t code = taos_errno(pSql); int32_t code = taos_errno(pSql);
...@@ -10206,11 +10242,11 @@ static void *readMetric(void *sarg) { ...@@ -10206,11 +10242,11 @@ static void *readMetric(void *sarg) {
while(taos_fetch_row(pSql) != NULL) { while(taos_fetch_row(pSql) != NULL) {
count++; count++;
} }
t = taosGetTimestampMs() - t; t = taosGetTimestampUs() - t;
fprintf(fp, "| Speed: %12.2f(per s) | Latency: %.4f(ms) |\n", fprintf(fp, "| Speed: %12.2f(per s) | Latency: %.4f(ms) |\n",
ntables * insertRows / (t * 1000.0), t); ntables * insertRows / (t / 1000), t);
printf("select %10s took %.6f second(s)\n\n", g_aggreFunc[j], t * 1000.0); printf("select %10s took %.6f second(s)\n\n", aggreFunc[j], t / 1000000);
taos_free_result(pSql); taos_free_result(pSql);
} }
...@@ -10218,7 +10254,7 @@ static void *readMetric(void *sarg) { ...@@ -10218,7 +10254,7 @@ static void *readMetric(void *sarg) {
} }
fclose(fp); fclose(fp);
free(command); free(command);
#endif
return NULL; return NULL;
} }
...@@ -11225,9 +11261,8 @@ static void setParaFromArg() { ...@@ -11225,9 +11261,8 @@ static void setParaFromArg() {
tstrncpy(g_Dbs.resultFile, g_args.output_file, MAX_FILE_NAME_LEN); tstrncpy(g_Dbs.resultFile, g_args.output_file, MAX_FILE_NAME_LEN);
g_Dbs.use_metric = g_args.use_metric; g_Dbs.use_metric = g_args.use_metric;
g_Dbs.insert_only = g_args.insert_only;
g_Dbs.do_aggreFunc = true; g_Dbs.aggr_func = g_args.aggr_func;
char dataString[TSDB_MAX_BYTES_PER_ROW]; char dataString[TSDB_MAX_BYTES_PER_ROW];
char *data_type = g_args.data_type; char *data_type = g_args.data_type;
...@@ -11238,7 +11273,7 @@ static void setParaFromArg() { ...@@ -11238,7 +11273,7 @@ static void setParaFromArg() {
if ((data_type[0] == TSDB_DATA_TYPE_BINARY) if ((data_type[0] == TSDB_DATA_TYPE_BINARY)
|| (data_type[0] == TSDB_DATA_TYPE_BOOL) || (data_type[0] == TSDB_DATA_TYPE_BOOL)
|| (data_type[0] == TSDB_DATA_TYPE_NCHAR)) { || (data_type[0] == TSDB_DATA_TYPE_NCHAR)) {
g_Dbs.do_aggreFunc = false; g_Dbs.aggr_func = false;
} }
if (g_args.use_metric) { if (g_args.use_metric) {
...@@ -11420,7 +11455,7 @@ static void testMetaFile() { ...@@ -11420,7 +11455,7 @@ static void testMetaFile() {
} }
} }
static void queryResult() { static void queryAggrFunc() {
// query data // query data
pthread_t read_id; pthread_t read_id;
...@@ -11429,7 +11464,6 @@ static void queryResult() { ...@@ -11429,7 +11464,6 @@ static void queryResult() {
pThreadInfo->start_time = DEFAULT_START_TIME; // 2017-07-14 10:40:00.000 pThreadInfo->start_time = DEFAULT_START_TIME; // 2017-07-14 10:40:00.000
pThreadInfo->start_table_from = 0; pThreadInfo->start_table_from = 0;
//pThreadInfo->do_aggreFunc = g_Dbs.do_aggreFunc;
if (g_args.use_metric) { if (g_args.use_metric) {
pThreadInfo->ntables = g_Dbs.db[0].superTbls[0].childTblCount; pThreadInfo->ntables = g_Dbs.db[0].superTbls[0].childTblCount;
pThreadInfo->end_table_to = g_Dbs.db[0].superTbls[0].childTblCount - 1; pThreadInfo->end_table_to = g_Dbs.db[0].superTbls[0].childTblCount - 1;
...@@ -11458,9 +11492,9 @@ static void queryResult() { ...@@ -11458,9 +11492,9 @@ static void queryResult() {
tstrncpy(pThreadInfo->filePath, g_Dbs.resultFile, MAX_FILE_NAME_LEN); tstrncpy(pThreadInfo->filePath, g_Dbs.resultFile, MAX_FILE_NAME_LEN);
if (!g_Dbs.use_metric) { if (!g_Dbs.use_metric) {
pthread_create(&read_id, NULL, readTable, pThreadInfo); pthread_create(&read_id, NULL, queryNtableAggrFunc, pThreadInfo);
} else { } else {
pthread_create(&read_id, NULL, readMetric, pThreadInfo); pthread_create(&read_id, NULL, queryStableAggrFunc, pThreadInfo);
} }
pthread_join(read_id, NULL); pthread_join(read_id, NULL);
taos_close(pThreadInfo->taos); taos_close(pThreadInfo->taos);
...@@ -11482,8 +11516,9 @@ static void testCmdLine() { ...@@ -11482,8 +11516,9 @@ static void testCmdLine() {
g_args.test_mode = INSERT_TEST; g_args.test_mode = INSERT_TEST;
insertTestProcess(); insertTestProcess();
if (false == g_Dbs.insert_only) if (g_Dbs.aggr_func) {
queryResult(); queryAggrFunc();
}
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
......
...@@ -70,14 +70,14 @@ extern "C" { ...@@ -70,14 +70,14 @@ extern "C" {
#define TSDB_FUNC_DERIVATIVE 32 #define TSDB_FUNC_DERIVATIVE 32
#define TSDB_FUNC_BLKINFO 33 #define TSDB_FUNC_BLKINFO 33
#define TSDB_FUNC_CEIL 34
#define TSDB_FUNC_HISTOGRAM 34 #define TSDB_FUNC_FLOOR 35
#define TSDB_FUNC_HLL 35 #define TSDB_FUNC_ROUND 36
#define TSDB_FUNC_MODE 36
#define TSDB_FUNC_SAMPLE 37 #define TSDB_FUNC_HISTOGRAM 37
#define TSDB_FUNC_CEIL 38 #define TSDB_FUNC_HLL 38
#define TSDB_FUNC_FLOOR 39 #define TSDB_FUNC_MODE 39
#define TSDB_FUNC_ROUND 40 #define TSDB_FUNC_SAMPLE 40
#define TSDB_FUNC_MAVG 41 #define TSDB_FUNC_MAVG 41
#define TSDB_FUNC_CSUM 42 #define TSDB_FUNC_CSUM 42
...@@ -88,6 +88,7 @@ extern "C" { ...@@ -88,6 +88,7 @@ extern "C" {
#define TSDB_FUNCSTATE_OF 0x10u // outer forward #define TSDB_FUNCSTATE_OF 0x10u // outer forward
#define TSDB_FUNCSTATE_NEED_TS 0x20u // timestamp is required during query processing #define TSDB_FUNCSTATE_NEED_TS 0x20u // timestamp is required during query processing
#define TSDB_FUNCSTATE_SELECTIVITY 0x40u // selectivity functions, can exists along with tag columns #define TSDB_FUNCSTATE_SELECTIVITY 0x40u // selectivity functions, can exists along with tag columns
#define TSDB_FUNCSTATE_SCALAR 0x80u
#define TSDB_BASE_FUNC_SO TSDB_FUNCSTATE_SO | TSDB_FUNCSTATE_STREAM | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_OF #define TSDB_BASE_FUNC_SO TSDB_FUNCSTATE_SO | TSDB_FUNCSTATE_STREAM | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_OF
#define TSDB_BASE_FUNC_MO TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STREAM | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_OF #define TSDB_BASE_FUNC_MO TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STREAM | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_OF
......
...@@ -179,7 +179,9 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI ...@@ -179,7 +179,9 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TS_DUMMY || functionId == TSDB_FUNC_TAG_DUMMY || if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TS_DUMMY || functionId == TSDB_FUNC_TAG_DUMMY ||
functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TAGPRJ ||
functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_INTERP) { functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_INTERP || functionId == TSDB_FUNC_CEIL ||
functionId == TSDB_FUNC_FLOOR || functionId == TSDB_FUNC_ROUND)
{
*type = (int16_t)dataType; *type = (int16_t)dataType;
*bytes = (int16_t)dataBytes; *bytes = (int16_t)dataBytes;
...@@ -405,7 +407,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI ...@@ -405,7 +407,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
// TODO use hash table // TODO use hash table
int32_t isValidFunction(const char* name, int32_t len) { int32_t isValidFunction(const char* name, int32_t len) {
for(int32_t i = 0; i <= TSDB_FUNC_BLKINFO; ++i) { for(int32_t i = 0; i <= TSDB_FUNC_ROUND; ++i) {
int32_t nameLen = (int32_t) strlen(aAggs[i].name); int32_t nameLen = (int32_t) strlen(aAggs[i].name);
if (len != nameLen) { if (len != nameLen) {
continue; continue;
...@@ -4256,6 +4258,231 @@ void blockinfo_func_finalizer(SQLFunctionCtx* pCtx) { ...@@ -4256,6 +4258,231 @@ void blockinfo_func_finalizer(SQLFunctionCtx* pCtx) {
doFinalizer(pCtx); doFinalizer(pCtx);
} }
#define CFR_SET_VAL(type, data, pCtx, func, i, step, notNullElems) \
do { \
type *pData = (type *) data; \
type *pOutput = (type *) pCtx->pOutput; \
\
for (; i < pCtx->size && i >= 0; i += step) { \
if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) { \
continue; \
} \
\
*pOutput++ = (type) func((double) pData[i]); \
\
notNullElems++; \
} \
} while (0)
#define CFR_SET_VAL_DOUBLE(data, pCtx, func, i, step, notNullElems) \
do { \
double *pData = (double *) data; \
double *pOutput = (double *) pCtx->pOutput; \
\
for (; i < pCtx->size && i >= 0; i += step) { \
if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) { \
continue; \
} \
\
SET_DOUBLE_VAL(pOutput, func(pData[i])); \
pOutput++; \
\
notNullElems++; \
} \
} while (0)
static void ceil_function(SQLFunctionCtx *pCtx) {
void *data = GET_INPUT_DATA_LIST(pCtx);
int32_t notNullElems = 0;
int32_t step = GET_FORWARD_DIRECTION_FACTOR(pCtx->order);
int32_t i = (pCtx->order == TSDB_ORDER_ASC) ? 0 : pCtx->size - 1;
switch (pCtx->inputType) {
case TSDB_DATA_TYPE_INT: {
CFR_SET_VAL(int32_t, data, pCtx, ceil, i, step, notNullElems);
break;
};
case TSDB_DATA_TYPE_UINT: {
CFR_SET_VAL(uint32_t, data, pCtx, ceil, i, step, notNullElems);
break;
};
case TSDB_DATA_TYPE_BIGINT: {
CFR_SET_VAL(int64_t, data, pCtx, ceil, i, step, notNullElems);
break;
}
case TSDB_DATA_TYPE_UBIGINT: {
CFR_SET_VAL(uint64_t, data, pCtx, ceil, i, step, notNullElems);
break;
}
case TSDB_DATA_TYPE_DOUBLE: {
CFR_SET_VAL_DOUBLE(data, pCtx, ceil, i, step, notNullElems);
break;
}
case TSDB_DATA_TYPE_FLOAT: {
CFR_SET_VAL(float, data, pCtx, ceil, i, step, notNullElems);
break;
}
case TSDB_DATA_TYPE_SMALLINT: {
CFR_SET_VAL(int16_t, data, pCtx, ceil, i, step, notNullElems);
break;
}
case TSDB_DATA_TYPE_USMALLINT: {
CFR_SET_VAL(uint16_t, data, pCtx, ceil, i, step, notNullElems);
break;
}
case TSDB_DATA_TYPE_TINYINT: {
CFR_SET_VAL(int8_t, data, pCtx, ceil, i, step, notNullElems);
break;
}
case TSDB_DATA_TYPE_UTINYINT: {
CFR_SET_VAL(uint8_t, data, pCtx, ceil, i, step, notNullElems);
break;
}
default:
qError("error input type");
}
if (notNullElems <= 0) {
/*
* current block may be null value
*/
assert(pCtx->hasNull);
} else {
GET_RES_INFO(pCtx)->numOfRes += notNullElems;
}
}
static void floor_function(SQLFunctionCtx *pCtx) {
void *data = GET_INPUT_DATA_LIST(pCtx);
int32_t notNullElems = 0;
int32_t step = GET_FORWARD_DIRECTION_FACTOR(pCtx->order);
int32_t i = (pCtx->order == TSDB_ORDER_ASC) ? 0 : pCtx->size - 1;
switch (pCtx->inputType) {
case TSDB_DATA_TYPE_INT: {
CFR_SET_VAL(int32_t, data, pCtx, floor, i, step, notNullElems);
break;
};
case TSDB_DATA_TYPE_UINT: {
CFR_SET_VAL(uint32_t, data, pCtx, floor, i, step, notNullElems);
break;
};
case TSDB_DATA_TYPE_BIGINT: {
CFR_SET_VAL(int64_t, data, pCtx, floor, i, step, notNullElems);
break;
}
case TSDB_DATA_TYPE_UBIGINT: {
CFR_SET_VAL(uint64_t, data, pCtx, floor, i, step, notNullElems);
break;
}
case TSDB_DATA_TYPE_DOUBLE: {
CFR_SET_VAL_DOUBLE(data, pCtx, floor, i, step, notNullElems);
break;
}
case TSDB_DATA_TYPE_FLOAT: {
CFR_SET_VAL(float, data, pCtx, floor, i, step, notNullElems);
break;
}
case TSDB_DATA_TYPE_SMALLINT: {
CFR_SET_VAL(int16_t, data, pCtx, floor, i, step, notNullElems);
break;
}
case TSDB_DATA_TYPE_USMALLINT: {
CFR_SET_VAL(uint16_t, data, pCtx, floor, i, step, notNullElems);
break;
}
case TSDB_DATA_TYPE_TINYINT: {
CFR_SET_VAL(int8_t, data, pCtx, floor, i, step, notNullElems);
break;
}
case TSDB_DATA_TYPE_UTINYINT: {
CFR_SET_VAL(uint8_t, data, pCtx, floor, i, step, notNullElems);
break;
}
default:
qError("error input type");
}
if (notNullElems <= 0) {
/*
* current block may be null value
*/
assert(pCtx->hasNull);
} else {
GET_RES_INFO(pCtx)->numOfRes += notNullElems;
}
}
static void round_function(SQLFunctionCtx *pCtx) {
void *data = GET_INPUT_DATA_LIST(pCtx);
int32_t notNullElems = 0;
int32_t step = GET_FORWARD_DIRECTION_FACTOR(pCtx->order);
int32_t i = (pCtx->order == TSDB_ORDER_ASC) ? 0 : pCtx->size - 1;
switch (pCtx->inputType) {
case TSDB_DATA_TYPE_INT: {
CFR_SET_VAL(int32_t, data, pCtx, round, i, step, notNullElems);
break;
};
case TSDB_DATA_TYPE_UINT: {
CFR_SET_VAL(uint32_t, data, pCtx, round, i, step, notNullElems);
break;
};
case TSDB_DATA_TYPE_BIGINT: {
CFR_SET_VAL(int64_t, data, pCtx, round, i, step, notNullElems);
break;
}
case TSDB_DATA_TYPE_UBIGINT: {
CFR_SET_VAL(uint64_t, data, pCtx, round, i, step, notNullElems);
break;
}
case TSDB_DATA_TYPE_DOUBLE: {
CFR_SET_VAL_DOUBLE(data, pCtx, round, i, step, notNullElems);
break;
}
case TSDB_DATA_TYPE_FLOAT: {
CFR_SET_VAL(float, data, pCtx, round, i, step, notNullElems);
break;
}
case TSDB_DATA_TYPE_SMALLINT: {
CFR_SET_VAL(int16_t, data, pCtx, round, i, step, notNullElems);
break;
}
case TSDB_DATA_TYPE_USMALLINT: {
CFR_SET_VAL(uint16_t, data, pCtx, round, i, step, notNullElems);
break;
}
case TSDB_DATA_TYPE_TINYINT: {
CFR_SET_VAL(int8_t, data, pCtx, round, i, step, notNullElems);
break;
}
case TSDB_DATA_TYPE_UTINYINT: {
CFR_SET_VAL(uint8_t, data, pCtx, round, i, step, notNullElems);
break;
}
default:
qError("error input type");
}
if (notNullElems <= 0) {
/*
* current block may be null value
*/
assert(pCtx->hasNull);
} else {
GET_RES_INFO(pCtx)->numOfRes += notNullElems;
}
}
#undef CFR_SET_VAL
#undef CFR_SET_VAL_DOUBLE
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
/* /*
* function compatible list. * function compatible list.
...@@ -4274,8 +4501,8 @@ int32_t functionCompatList[] = { ...@@ -4274,8 +4501,8 @@ int32_t functionCompatList[] = {
4, -1, -1, 1, 1, 1, 1, 1, 1, -1, 4, -1, -1, 1, 1, 1, 1, 1, 1, -1,
// tag, colprj, tagprj, arithmetic, diff, first_dist, last_dist, stddev_dst, interp rate irate // tag, colprj, tagprj, arithmetic, diff, first_dist, last_dist, stddev_dst, interp rate irate
1, 1, 1, 1, -1, 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 5, 1, 1,
// tid_tag, derivative, blk_info // tid_tag, derivative, blk_info,ceil, floor, round
6, 8, 7, 6, 8, 7, 1, 1, 1
}; };
SAggFunctionInfo aAggs[] = {{ SAggFunctionInfo aAggs[] = {{
...@@ -4688,4 +4915,40 @@ SAggFunctionInfo aAggs[] = {{ ...@@ -4688,4 +4915,40 @@ SAggFunctionInfo aAggs[] = {{
blockinfo_func_finalizer, blockinfo_func_finalizer,
block_func_merge, block_func_merge,
dataBlockRequired, dataBlockRequired,
},
{
// 34
"ceil",
TSDB_FUNC_CEIL,
TSDB_FUNC_CEIL,
TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_NEED_TS | TSDB_FUNCSTATE_SCALAR,
function_setup,
ceil_function,
doFinalizer,
noop1,
dataBlockRequired
},
{
// 35
"floor",
TSDB_FUNC_FLOOR,
TSDB_FUNC_FLOOR,
TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_NEED_TS | TSDB_FUNCSTATE_SCALAR,
function_setup,
floor_function,
doFinalizer,
noop1,
dataBlockRequired
},
{
// 36
"round",
TSDB_FUNC_ROUND,
TSDB_FUNC_ROUND,
TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_NEED_TS | TSDB_FUNCSTATE_SCALAR,
function_setup,
round_function,
doFinalizer,
noop1,
dataBlockRequired
}}; }};
...@@ -405,6 +405,25 @@ static bool isSelectivityWithTagsQuery(SQLFunctionCtx *pCtx, int32_t numOfOutput ...@@ -405,6 +405,25 @@ static bool isSelectivityWithTagsQuery(SQLFunctionCtx *pCtx, int32_t numOfOutput
return (numOfSelectivity > 0 && hasTags); return (numOfSelectivity > 0 && hasTags);
} }
static bool isScalarWithTagsQuery(SQLFunctionCtx *pCtx, int32_t numOfOutput) {
bool hasTags = false;
int32_t numOfScalar = 0;
for (int32_t i = 0; i < numOfOutput; ++i) {
int32_t functId = pCtx[i].functionId;
if (functId == TSDB_FUNC_TAG_DUMMY || functId == TSDB_FUNC_TS_DUMMY) {
hasTags = true;
continue;
}
if ((aAggs[functId].status & TSDB_FUNCSTATE_SCALAR) != 0) {
numOfScalar++;
}
}
return (numOfScalar > 0 && hasTags);
}
static bool isProjQuery(SQueryAttr *pQueryAttr) { static bool isProjQuery(SQueryAttr *pQueryAttr) {
for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) {
int32_t functId = pQueryAttr->pExpr1[i].base.functionId; int32_t functId = pQueryAttr->pExpr1[i].base.functionId;
...@@ -1939,7 +1958,7 @@ void setBlockStatisInfo(SQLFunctionCtx *pCtx, SSDataBlock* pSDataBlock, SColInde ...@@ -1939,7 +1958,7 @@ void setBlockStatisInfo(SQLFunctionCtx *pCtx, SSDataBlock* pSDataBlock, SColInde
// set the output buffer for the selectivity + tag query // set the output buffer for the selectivity + tag query
static int32_t setCtxTagColumnInfo(SQLFunctionCtx *pCtx, int32_t numOfOutput) { static int32_t setCtxTagColumnInfo(SQLFunctionCtx *pCtx, int32_t numOfOutput) {
if (!isSelectivityWithTagsQuery(pCtx, numOfOutput)) { if (!isSelectivityWithTagsQuery(pCtx, numOfOutput) && !isScalarWithTagsQuery(pCtx, numOfOutput)) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
...@@ -1958,7 +1977,7 @@ static int32_t setCtxTagColumnInfo(SQLFunctionCtx *pCtx, int32_t numOfOutput) { ...@@ -1958,7 +1977,7 @@ static int32_t setCtxTagColumnInfo(SQLFunctionCtx *pCtx, int32_t numOfOutput) {
if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) { if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) {
tagLen += pCtx[i].outputBytes; tagLen += pCtx[i].outputBytes;
pTagCtx[num++] = &pCtx[i]; pTagCtx[num++] = &pCtx[i];
} else if ((aAggs[functionId].status & TSDB_FUNCSTATE_SELECTIVITY) != 0) { } else if ((aAggs[functionId].status & TSDB_FUNCSTATE_SELECTIVITY) != 0 || (aAggs[functionId].status & TSDB_FUNCSTATE_SCALAR) != 0) {
p = &pCtx[i]; p = &pCtx[i];
} else if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TAG) { } else if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TAG) {
// tag function may be the group by tag column // tag function may be the group by tag column
......
...@@ -645,6 +645,12 @@ SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr) { ...@@ -645,6 +645,12 @@ SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr) {
} else { } else {
op = OP_Project; op = OP_Project;
taosArrayPush(plan, &op); taosArrayPush(plan, &op);
if (pQueryAttr->pExpr2 != NULL) {
op = OP_Project;
taosArrayPush(plan, &op);
}
if (pQueryAttr->distinct) { if (pQueryAttr->distinct) {
op = OP_Distinct; op = OP_Distinct;
taosArrayPush(plan, &op); taosArrayPush(plan, &op);
......
...@@ -359,6 +359,9 @@ python3 ./test.py -f functions/queryTestCases.py ...@@ -359,6 +359,9 @@ python3 ./test.py -f functions/queryTestCases.py
python3 ./test.py -f functions/function_stateWindow.py python3 ./test.py -f functions/function_stateWindow.py
python3 ./test.py -f functions/function_derivative.py python3 ./test.py -f functions/function_derivative.py
python3 ./test.py -f functions/function_irate.py python3 ./test.py -f functions/function_irate.py
python3 ./test.py -f functions/function_ceil.py
python3 ./test.py -f functions/function_floor.py
python3 ./test.py -f functions/function_round.py
python3 ./test.py -f insert/unsignedInt.py python3 ./test.py -f insert/unsignedInt.py
python3 ./test.py -f insert/unsignedBigint.py python3 ./test.py -f insert/unsignedBigint.py
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
system sh/stop_dnodes.sh
system sh/deploy.sh -n dnode1 -i 1
system sh/cfg.sh -n dnode1 -c walLevel -v 1
system sh/exec.sh -n dnode1 -s start
sleep 2000
sql connect
$dbPrefix = m_di_db
$tbPrefix = m_di_tb
$mtPrefix = m_di_mt
$tbNum = 2
$rowNum = 5000
print =============== step1
$i = 0
$db = $dbPrefix . $i
$mt = $mtPrefix . $i
sql drop database $db -x step1
step1:
sql create database $db
sql use $db
sql create table $mt (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 nchar(5), c9 binary(10)) TAGS (tgcol int)
$i = 0
while $i < $tbNum
$tb = $tbPrefix . $i
sql create table $tb using $mt tags( $i )
$x = 0
$y = 0
$v0 = 5000.0
$v1 = -5000.1
$v2 = 5000.2
$v3 = -5000.3
$v4 = 5000.4
$v5 = -5000.5
$v6 = 5000.6
$v7 = -5000.7
$v8 = 5000.8
$v9 = -5000.9
while $x < $rowNum
$cc = $x * 60000
$ms = 1601481600000 + $cc
$val = $v0
if $y == 0 then
$val = $v0
endi
if $y == 1 then
$val = $v1
endi
if $y == 2 then
$val = $v2
endi
if $y == 3 then
$val = $v3
endi
if $y == 4 then
$val = $v4
endi
if $y == 5 then
$val = $v5
endi
if $y == 6 then
$val = $v6
endi
if $y == 7 then
$val = $v7
endi
if $y == 8 then
$val = $v8
endi
if $y == 9 then
$val = $v9
endi
$tinyint = $x / 128
sql insert into $tb values ($ms , $x , $val , $x , $x , $tinyint , $x , $x , $x , $x )
$x = $x + 1
$y = $y + 1
if $y == 10 then
$y = 0
endi
endw
$i = $i + 1
endw
sleep 100
print =============== step2
$i = 1
$tb = $tbPrefix . $i
sql select ceil(c2) from $tb
print ===> $data00
if $data00 != 5000.00000 then
return -1
endi
sql select ceil(c2) from $tb
print ===> $data10
if $data10 != -5000.00000 then
return -1
endi
sql select ceil(c2) from $tb
print ===> $data20
if $data20 != 5001.00000 then
return -1
endi
sql select ceil(c2) from $tb
print ===> $data30
if $data30 != -5000.00000 then
return -1
endi
sql select ceil(c2) from $tb
print ===> $data40
if $data40 != 5001.00000 then
return -1
endi
sql select ceil(c2) from $tb
print ===> $data50
if $data50 != -5000.00000 then
return -1
endi
sql select ceil(c2) from $tb
print ===> $data60
if $data60 != 5001.00000 then
return -1
endi
sql select ceil(c2) from $tb
print ===> $data70
if $data70 != -5000.00000 then
return -1
endi
sql select ceil(c2) from $tb
print ===> $data80
if $data80 != 5001.00000 then
return -1
endi
sql select ceil(c2) from $tb
print ===> $data90
if $data90 != -5000.00000 then
return -1
endi
sql select ceil(c5) from $tb
print ===> $data10
if $data10 != 0 then
return -1
endi
sql select ts, ceil(c2) from $tb
sql select c2, ceil(c2) from $tb
sql select c2, c3, ceil(c2) from $tb
sql select ts, c2, c3, ceil(c2) from $tb
sql select ceil(c2), ceil(c6) from $tb
sql select ts, ceil(c2), ceil(c6) from $tb
sql select c2, ceil(c2), ceil(c6) from $tb
sql select c2, c3, ceil(c2), ceil(c6) from $tb
sql select ts, c2, c3, ceil(c2), ceil(c6) from $tb
sql select ceil(c2), floor(c2), round(c2) from $tb
sql select ts, ceil(c2), floor(c2), round(c2) from $tb
sql select c2, ceil(c2), floor(c2), round(c2) from $tb
sql select c2, c3, ceil(c2), floor(c2), round(c2) from $tb
sql select ts, c2, c3, ceil(c2), floor(c2), round(c2) from $tb
sql select ts, ceil(c2) from $mt
sql select c2, ceil(c2) from $mt
sql select c2, c3, ceil(c2) from $mt
sql select ts, c2, c3, ceil(c2) from $mt
sql select ceil(c2), ceil(c6) from $mt
sql select ts, ceil(c2), ceil(c6) from $mt
sql select c2, ceil(c2), ceil(c6) from $mt
sql select c2, c3, ceil(c2), ceil(c6) from $mt
sql select ts, c2, c3, ceil(c2), ceil(c6) from $mt
sql select ceil(c2), ceil(c2), round(c2) from $mt
sql select ts, ceil(c2), floor(c2), round(c2) from $mt
sql select c2, ceil(c2), floor(c2), round(c2) from $mt
sql select c2, c3, ceil(c2), floor(c2), round(c2) from $mt
sql select ts, c2, c3, ceil(c2), floor(c2), round(c2) from $mt
sql_error select ceil(c7) from $tb
sql_error select ceil(c8) from $tb
sql_error select ceil(c9) from $tb
sql_error select ceil(ts) from $tb
sql_error select ceil(c2+2) from $tb
sql_error select ceil(c2) from $tb where ts > 0 and ts < now + 100m interval(10m)
sql_error select ceil(ceil(c2)) from $tb
sql_error select ceil(c2) from m_di_tb1 where c2 like '2%'
print =============== step3
sql select ceil(c2) from $tb where c2 <= 5001.00000
print ===> $data00
if $data00 != 5000.00000 then
return -1
endi
sql select ceil(c2) from $tb where c2 <= 5001.00000
print ===> $data10
if $data10 != -5000.00000 then
return -1
endi
sql select ceil(c2) from $tb where c2 <= 5001.00000
print ===> $data20
if $data20 != 5001.00000 then
return -1
endi
sql select ceil(c2) from $tb where c2 <= 5001.00000
print ===> $data70
if $data70 != -5000.00000 then
return -1
endi
sql select ceil(c2) from $tb where c2 <= 5001.00000
print ===> $data80
if $data80 != 5001.00000 then
return -1
endi
sql select ceil(c2) from $tb where c2 <= 5001.00000
print ===> $data90
if $data90 != -5000.00000 then
return -1
endi
print =============== step4
sql select ceil(c2) from $tb where c2 >= -5001.00000
print ===> $data00
if $data00 != 5000.00000 then
return -1
endi
sql select ceil(c2) from $tb where c2 >= -5001.00000
print ===> $data10
if $data10 != -5000.00000 then
return -1
endi
sql select ceil(c2) from $tb where c2 >= -5001.00000
print ===> $data20
if $data20 != 5001.00000 then
return -1
endi
sql select ceil(c2) from $tb where c2 >= -5001.00000
print ===> $data70
if $data70 != -5000.00000 then
return -1
endi
sql select ceil(c2) from $tb where c2 >= -5001.00000
print ===> $data80
if $data80 != 5001.00000 then
return -1
endi
sql select ceil(c2) from $tb where c2 >= -5001.00000
print ===> $data90
if $data90 != -5000.00000 then
return -1
endi
print =============== step5
sql select ceil(c1) as b from $tb interval(1m) -x step5
return -1
step5:
print =============== step6
sql select ceil(c1) as b from $tb where ts < now + 4m interval(1m) -x step6
return -1
step6:
print =============== clear
system sh/exec.sh -n dnode1 -s stop -x SIGINT
system sh/stop_dnodes.sh
system sh/deploy.sh -n dnode1 -i 1
system sh/cfg.sh -n dnode1 -c walLevel -v 1
system sh/exec.sh -n dnode1 -s start
sleep 2000
sql connect
$dbPrefix = m_di_db
$tbPrefix = m_di_tb
$mtPrefix = m_di_mt
$tbNum = 2
$rowNum = 10000
print =============== step1
$i = 0
$db = $dbPrefix . $i
$mt = $mtPrefix . $i
sql drop database $db -x step1
step1:
sql create database $db
sql use $db
sql create table $mt (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 nchar(5), c9 binary(10)) TAGS (tgcol int)
$i = 0
while $i < $tbNum
$tb = $tbPrefix . $i
sql create table $tb using $mt tags( $i )
$x = 0
$y = 0
$v0 = 5000.0
$v1 = -5000.1
$v2 = 5000.2
$v3 = -5000.3
$v4 = 5000.4
$v5 = -5000.5
$v6 = 5000.6
$v7 = -5000.7
$v8 = 5000.8
$v9 = -5000.9
while $x < $rowNum
$cc = $x * 60000
$ms = 1601481600000 + $cc
$val = $v0
if $y == 0 then
$val = $v0
endi
if $y == 1 then
$val = $v1
endi
if $y == 2 then
$val = $v2
endi
if $y == 3 then
$val = $v3
endi
if $y == 4 then
$val = $v4
endi
if $y == 5 then
$val = $v5
endi
if $y == 6 then
$val = $v6
endi
if $y == 7 then
$val = $v7
endi
if $y == 8 then
$val = $v8
endi
if $y == 9 then
$val = $v9
endi
$tinyint = $x / 128
sql insert into $tb values ($ms , $x , $val , $x , $x , $tinyint , $x , $x , $x , $x )
$x = $x + 1
$y = $y + 1
if $y == 10 then
$y = 0
endi
endw
$i = $i + 1
endw
sleep 100
print =============== step2
$i = 1
$tb = $tbPrefix . $i
sql select floor(c2) from $tb
print ===> $data00
if $data00 != 5000.00000 then
return -1
endi
sql select floor(c2) from $tb
print ===> $data10
if $data10 != -5001.00000 then
return -1
endi
sql select floor(c2) from $tb
print ===> $data20
if $data20 != 5000.00000 then
return -1
endi
sql select floor(c2) from $tb
print ===> $data30
if $data30 != -5001.00000 then
return -1
endi
sql select floor(c2) from $tb
print ===> $data40
if $data40 != 5000.00000 then
return -1
endi
sql select floor(c2) from $tb
print ===> $data50
if $data50 != -5001.00000 then
return -1
endi
sql select floor(c2) from $tb
print ===> $data60
if $data60 != 5000.00000 then
return -1
endi
sql select floor(c2) from $tb
print ===> $data70
if $data70 != -5001.00000 then
return -1
endi
sql select floor(c2) from $tb
print ===> $data80
if $data80 != 5000.00000 then
return -1
endi
sql select floor(c2) from $tb
print ===> $data90
if $data90 != -5001.00000 then
return -1
endi
sql select floor(c5) from $tb
print ===> $data10
if $data10 != 0 then
return -1
endi
sql select ts, floor(c2) from $tb
sql select c2, floor(c2) from $tb
sql select c2, c3, floor(c2) from $tb
sql select ts, c2, c3, floor(c2) from $tb
sql select floor(c2), floor(c6) from $tb
sql select ts, floor(c2), floor(c6) from $tb
sql select c2, floor(c2), floor(c6) from $tb
sql select c2, c3, floor(c2), floor(c6) from $tb
sql select ts, c2, c3, floor(c2), floor(c6) from $tb
sql select ceil(c2), floor(c2), round(c2) from $tb
sql select ts, ceil(c2), floor(c2), round(c2) from $tb
sql select c2, ceil(c2), floor(c2), round(c2) from $tb
sql select c2, c3, ceil(c2), floor(c2), round(c2) from $tb
sql select ts, c2, c3, ceil(c2), floor(c2), round(c2) from $tb
sql select ts, floor(c2) from $mt
sql select c2, floor(c2) from $mt
sql select c2, c3, floor(c2) from $mt
sql select ts, c2, c3, floor(c2) from $mt
sql select floor(c2), floor(c6) from $mt
sql select ts, floor(c2), floor(c6) from $mt
sql select c2, floor(c2), floor(c6) from $mt
sql select c2, c3, floor(c2), floor(c6) from $mt
sql select ts, c2, c3, floor(c2), floor(c6) from $mt
sql select ceil(c2), floor(c2), round(c2) from $mt
sql select ts, ceil(c2), floor(c2), round(c2) from $mt
sql select c2, ceil(c2), floor(c2), round(c2) from $mt
sql select c2, c3, ceil(c2), floor(c2), round(c2) from $mt
sql select ts, c2, c3, ceil(c2), floor(c2), round(c2) from $mt
sql_error select floor(c7) from $tb
sql_error select floor(c8) from $tb
sql_error select floor(c9) from $tb
sql_error select floor(ts) from $tb
sql_error select floor(c2+2) from $tb
sql_error select floor(c2) from $tb where ts > 0 and ts < now + 100m interval(10m)
sql_error select floor(floor(c2)) from $tb
sql_error select floor(c2) from m_di_tb1 where c2 like '2%'
print =============== step3
sql select floor(c2) from $tb where c2 <= 5001.00000
print ===> $data00
if $data00 != 5000.00000 then
return -1
endi
sql select floor(c2) from $tb where c2 <= 5001.00000
print ===> $data10
if $data10 != -5001.00000 then
return -1
endi
sql select floor(c2) from $tb where c2 <= 5001.00000
print ===> $data20
if $data20 != 5000.00000 then
return -1
endi
sql select floor(c2) from $tb where c2 <= 5001.00000
print ===> $data70
if $data70 != -5001.00000 then
return -1
endi
sql select floor(c2) from $tb where c2 <= 5001.00000
print ===> $data80
if $data80 != 5000.00000 then
return -1
endi
sql select floor(c2) from $tb where c2 <= 5001.00000
print ===> $data90
if $data90 != -5001.00000 then
return -1
endi
print =============== step4
sql select floor(c2) from $tb where c2 >= -5001.00000
print ===> $data00
if $data00 != 5000.00000 then
return -1
endi
sql select floor(c2) from $tb where c2 >= -5001.00000
print ===> $data10
if $data10 != -5001.00000 then
return -1
endi
sql select floor(c2) from $tb where c2 >= -5001.00000
print ===> $data20
if $data20 != 5000.00000 then
return -1
endi
sql select floor(c2) from $tb where c2 >= -5001.00000
print ===> $data70
if $data70 != -5001.00000 then
return -1
endi
sql select floor(c2) from $tb where c2 >= -5001.00000
print ===> $data80
if $data80 != 5000.00000 then
return -1
endi
sql select floor(c2) from $tb where c2 >= -5001.00000
print ===> $data90
if $data90 != -5001.00000 then
return -1
endi
print =============== step5
sql select floor(c1) as b from $tb interval(1m) -x step5
return -1
step5:
print =============== step6
sql select floor(c1) as b from $tb where ts < now + 4m interval(1m) -x step6
return -1
step6:
print =============== clear
system sh/exec.sh -n dnode1 -s stop -x SIGINT
system sh/stop_dnodes.sh
system sh/deploy.sh -n dnode1 -i 1
system sh/cfg.sh -n dnode1 -c walLevel -v 1
system sh/exec.sh -n dnode1 -s start
sleep 2000
sql connect
$dbPrefix = m_di_db
$tbPrefix = m_di_tb
$mtPrefix = m_di_mt
$tbNum = 2
$rowNum = 10000
print =============== step1
$i = 0
$db = $dbPrefix . $i
$mt = $mtPrefix . $i
sql drop database $db -x step1
step1:
sql create database $db
sql use $db
sql create table $mt (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 nchar(5), c9 binary(10)) TAGS (tgcol int)
$i = 0
while $i < $tbNum
$tb = $tbPrefix . $i
sql create table $tb using $mt tags( $i )
$x = 0
$y = 0
$v0 = 5000.0
$v1 = -5000.1
$v2 = 5000.2
$v3 = -5000.3
$v4 = 5000.4
$v5 = -5000.5
$v6 = 5000.6
$v7 = -5000.7
$v8 = 5000.8
$v9 = -5000.9
while $x < $rowNum
$cc = $x * 60000
$ms = 1601481600000 + $cc
$val = $v0
if $y == 0 then
$val = $v0
endi
if $y == 1 then
$val = $v1
endi
if $y == 2 then
$val = $v2
endi
if $y == 3 then
$val = $v3
endi
if $y == 4 then
$val = $v4
endi
if $y == 5 then
$val = $v5
endi
if $y == 6 then
$val = $v6
endi
if $y == 7 then
$val = $v7
endi
if $y == 8 then
$val = $v8
endi
if $y == 9 then
$val = $v9
endi
$tinyint = $x / 128
sql insert into $tb values ($ms , $x , $val , $x , $x , $tinyint , $x , $x , $x , $x )
$x = $x + 1
$y = $y + 1
if $y == 10 then
$y = 0
endi
endw
$i = $i + 1
endw
sleep 100
print =============== step2
$i = 1
$tb = $tbPrefix . $i
sql select round(c2) from $tb
print ===> $data00
if $data00 != 5000.00000 then
return -1
endi
sql select round(c2) from $tb
print ===> $data10
if $data10 != -5000.00000 then
return -1
endi
sql select round(c2) from $tb
print ===> $data20
if $data20 != 5000.00000 then
return -1
endi
sql select round(c2) from $tb
print ===> $data30
if $data30 != -5000.00000 then
return -1
endi
sql select round(c2) from $tb
print ===> $data40
if $data40 != 5000.00000 then
return -1
endi
sql select round(c2) from $tb
print ===> $data50
if $data50 != -5001.00000 then
return -1
endi
sql select round(c2) from $tb
print ===> $data60
if $data60 != 5001.00000 then
return -1
endi
sql select round(c2) from $tb
print ===> $data70
if $data70 != -5001.00000 then
return -1
endi
sql select round(c2) from $tb
print ===> $data80
if $data80 != 5001.00000 then
return -1
endi
sql select round(c2) from $tb
print ===> $data90
if $data90 != -5001.00000 then
return -1
endi
sql select round(c5) from $tb
print ===> $data10
if $data10 != 0 then
return -1
endi
sql select ts, round(c2) from $tb
sql select c2, round(c2) from $tb
sql select c2, c3, round(c2) from $tb
sql select ts, c2, c3, round(c2) from $tb
sql select round(c2), round(c6) from $tb
sql select ts, round(c2), round(c6) from $tb
sql select c2, round(c2), round(c6) from $tb
sql select c2, c3, round(c2), round(c6) from $tb
sql select ts, c2, c3, round(c2), round(c6) from $tb
sql select ceil(c2), floor(c2), round(c2) from $tb
sql select ts, ceil(c2), floor(c2), round(c2) from $tb
sql select c2, ceil(c2), floor(c2), round(c2) from $tb
sql select c2, c3, ceil(c2), floor(c2), round(c2) from $tb
sql select ts, c2, c3, ceil(c2), floor(c2), round(c2) from $tb
sql select ts, round(c2) from $mt
sql select c2, round(c2) from $mt
sql select c2, c3, round(c2) from $mt
sql select ts, c2, c3, round(c2) from $mt
sql select round(c2), round(c6) from $mt
sql select ts, round(c2), round(c6) from $mt
sql select c2, round(c2), round(c6) from $mt
sql select c2, c3, round(c2), round(c6) from $mt
sql select ts, c2, c3, round(c2), round(c6) from $mt
sql select ceil(c2), floor(c2), round(c2) from $mt
sql select ts, ceil(c2), floor(c2), round(c2) from $mt
sql select c2, ceil(c2), floor(c2), round(c2) from $mt
sql select c2, c3, ceil(c2), floor(c2), round(c2) from $mt
sql select ts, c2, c3, ceil(c2), floor(c2), round(c2) from $mt
sql_error select round(c7) from $tb
sql_error select round(c8) from $tb
sql_error select round(c9) from $tb
sql_error select round(ts) from $tb
sql_error select round(c2+2) from $tb
sql_error select round(c2) from $tb where ts > 0 and ts < now + 100m interval(10m)
sql_error select round(round(c2)) from $tb
sql_error select round(c2) from m_di_tb1 where c2 like '2%'
print =============== step3
sql select round(c2) from $tb where c2 <= 5001.00000
print ===> $data00
if $data00 != 5000.00000 then
return -1
endi
sql select round(c2) from $tb where c2 <= 5001.00000
print ===> $data10
if $data10 != -5000.00000 then
return -1
endi
sql select round(c2) from $tb where c2 <= 5001.00000
print ===> $data20
if $data20 != 5000.00000 then
return -1
endi
sql select round(c2) from $tb where c2 <= 5001.00000
print ===> $data70
if $data70 != -5001.00000 then
return -1
endi
sql select round(c2) from $tb where c2 <= 5001.00000
print ===> $data80
if $data80 != 5001.00000 then
return -1
endi
sql select round(c2) from $tb where c2 <= 5001.00000
print ===> $data90
if $data90 != -5001.00000 then
return -1
endi
print =============== step4
sql select round(c2) from $tb where c2 >= -5001.00000
print ===> $data00
if $data00 != 5000.00000 then
return -1
endi
sql select round(c2) from $tb where c2 >= -5001.00000
print ===> $data10
if $data10 != -5000.00000 then
return -1
endi
sql select round(c2) from $tb where c2 >= -5001.00000
print ===> $data20
if $data20 != 5000.00000 then
return -1
endi
sql select round(c2) from $tb where c2 >= -5001.00000
print ===> $data70
if $data70 != -5001.00000 then
return -1
endi
sql select round(c2) from $tb where c2 >= -5001.00000
print ===> $data80
if $data80 != 5001.00000 then
return -1
endi
sql select round(c2) from $tb where c2 >= -5001.00000
print ===> $data90
if $data90 != -5001.00000 then
return -1
endi
print =============== step5
sql select round(c1) as b from $tb interval(1m) -x step5
return -1
step5:
print =============== step6
sql select round(c1) as b from $tb where ts < now + 4m interval(1m) -x step6
return -1
step6:
print =============== clear
system sh/exec.sh -n dnode1 -s stop -x SIGINT
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册