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

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

......@@ -3,7 +3,7 @@
## <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 等
......
......@@ -1166,7 +1166,7 @@ var affectRows = cursor.execute('insert into test.weather values(now, 22.3, 34);
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
| 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 以前的版本中,此参数的单位是字节) |
| 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 文件中不支持此参数。 |
| 103 | numOfCommitThreads | YES | **S** | | 设置写入线程的最大数量 | | | |
| 104 | maxWildCardsLength | | **C** | bytes | 设定 LIKE 算子的通配符字符串允许的最大长度 | 0-16384 | 100 | 2.1.6.1 版本新增。 |
......@@ -239,7 +239,7 @@ taosd -C
| 10 | fsync | 毫秒 | 当wal设置为2时,执行fsync的周期。设置为0,表示每次写入,立即执行fsync。 | | 3000 |
| 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 |
| 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 |
对于一个应用场景,可能有多种数据特征的数据并存,最佳的设计是将具有相同数据特征的表放在一个库里,这样一个应用有多个库,而每个库可以配置不同的存储参数,从而保证系统有最优的性能。TDengine允许应用在创建库时指定上述存储参数,如果指定,该参数就将覆盖对应的系统配置参数。举例,有下述SQL:
......
......@@ -99,7 +99,7 @@ gcc -g -O0 -fPIC -shared add_one.c -o add_one.so
在创建 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(Y):包含 UDF 函数实现的动态链接库的库文件路径(指的是库文件在当前客户端所在主机上的保存路径,通常是指向一个 .so 文件),这个路径需要用英文单引号或英文双引号括起来;
* typename(Z):此函数计算结果的数据类型,与上文中 udfNormalFunc 的 itype 参数不同,这里不是使用数字表示法,而是直接写类型名称即可;
......@@ -107,10 +107,10 @@ gcc -g -O0 -fPIC -shared add_one.c -o add_one.so
例如,如下语句可以把 add_one.so 创建为系统中可用的 UDF:
```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(Y):包含 UDF 函数实现的动态链接库的库文件路径(指的是库文件在当前客户端所在主机上的保存路径,通常是指向一个 .so 文件),这个路径需要用英文单引号或英文双引号括起来;
* typename(Z):此函数计算结果的数据类型,与上文中 udfNormalFunc 的 itype 参数不同,这里不是使用数字表示法,而是直接写类型名称即可;
......@@ -118,7 +118,7 @@ gcc -g -O0 -fPIC -shared add_one.c -o add_one.so
例如,如下语句可以把 add_one.so 创建为系统中可用的 UDF:
```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
......
......@@ -70,7 +70,7 @@ TDengine 缺省的时间戳是毫秒精度,但通过在 CREATE DATABASE 时传
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;
......@@ -573,16 +573,24 @@ Query OK, 2 row(s) in set (0.003112s)
注意:普通表的通配符 * 中并不包含 _标签列_。
##### 获取标签列的去重取值
#### 获取标签列或普通列的去重取值
从 2.0.15 版本开始,支持在超级表查询标签列时,指定 DISTINCT 关键字,这样将返回指定标签列的所有不重复取值
```mysql
SELECT DISTINCT tag_name FROM stb_name;
从 2.0.15.0 版本开始,支持在超级表查询标签列时,指定 DISTINCT 关键字,这样将返回指定标签列的所有不重复取值。注意,在 2.1.6.0 版本之前,DISTINCT 只支持处理单个标签列,而从 2.1.6.0 版本开始,DISTINCT 可以对多个标签列进行处理,输出这些标签列取值不重复的组合
```sql
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 目前尚不支持删除功能,未来根据用户需求可能会支
另需注意,在 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列的表?
使用 2.0 及其以上版本,默认支持 1024 列;2.0 之前的版本,TDengine 最大允许创建 250 列的表。但是如果确实超过限值,建议按照数据特性,逻辑地将这个宽表分解成几个小表。(从 2.1.7.0 版本开始,表的最大列数增加到了 4096 列。)
......
......@@ -2,7 +2,7 @@
## <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
- Multiple filters for tags and numeric values: >, <, =, < >, like, etc
......@@ -96,4 +96,4 @@ Query OK, 5 row(s) in set (0.001521s)
In IoT scenario, it is difficult to synchronize the time stamp of collected data at each point, but many analysis algorithms (such as FFT) need to align the collected data strictly at equal intervals of time. In many systems, it’s required to write their own programs to process, but the down sampling operation of TDengine can be used to solve the problem easily. If there is no collected data in an interval, TDengine also provides interpolation calculation function.
For details of syntax rules, please refer to the [Time-dimension Aggregation section of TAOS SQL](https://www.taosdata.com/en/documentation/taos-sql#aggregation).
\ No newline at end of file
For details of syntax rules, please refer to the [Time-dimension Aggregation section of TAOS SQL](https://www.taosdata.com/en/documentation/taos-sql#aggregation).
......@@ -2551,6 +2551,9 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
case TSDB_FUNC_MAX:
case TSDB_FUNC_DIFF:
case TSDB_FUNC_DERIVATIVE:
case TSDB_FUNC_CEIL:
case TSDB_FUNC_FLOOR:
case TSDB_FUNC_ROUND:
case TSDB_FUNC_STDDEV:
case TSDB_FUNC_LEASTSQR: {
// 1. valid the number of parameters
......@@ -2741,6 +2744,10 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
if (pParamElem->pNode->columnName.z == NULL) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
// functions can not be applied to tags
if ((index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) || (index.columnIndex < 0)) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6);
......@@ -3474,6 +3481,7 @@ static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool
int32_t scalarUdf = 0;
int32_t prjNum = 0;
int32_t aggNum = 0;
int32_t scalNum = 0;
size_t numOfExpr = tscNumOfExprs(pQueryInfo);
assert(numOfExpr > 0);
......@@ -3505,6 +3513,10 @@ static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool
++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))) {
continue;
}
......@@ -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);
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;
}
if (scalarUdf > 0 && aggNum > 0) {
if (aggNum > 0 && scalNum > 0) {
return false;
}
......@@ -6536,7 +6552,9 @@ int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQu
}
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;
break;
}
......@@ -7138,6 +7156,7 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) {
const char* msg2 = "aggregation function should not be mixed up with projection";
bool tagTsColExists = false;
int16_t numOfScalar = 0;
int16_t numOfSelectivity = 0;
int16_t numOfAggregation = 0;
......@@ -7171,6 +7190,8 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) {
if ((aAggs[functionId].status & TSDB_FUNCSTATE_SELECTIVITY) != 0) {
numOfSelectivity++;
} else if ((aAggs[functionId].status & TSDB_FUNCSTATE_SCALAR) != 0) {
numOfScalar++;
} else {
numOfAggregation++;
}
......
......@@ -269,7 +269,10 @@ bool tscIsProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex) {
functionId != TSDB_FUNC_DIFF &&
functionId != TSDB_FUNC_DERIVATIVE &&
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;
}
}
......@@ -1465,7 +1468,12 @@ void tscFreeSubobj(SSqlObj* pSql) {
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) {
tscDebug("0x%"PRIx64" free sub SqlObj:0x%"PRIx64", index:%d", pSql->self, pSql->pSubs[i]->self, i);
if (pSql->pSubs[i] != NULL) {
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]);
pSql->pSubs[i] = NULL;
}
......
......@@ -104,6 +104,7 @@ extern char configDir[];
#define DATATYPE_BUFF_LEN (SMALL_BUFF_LEN*3)
#define NOTE_BUFF_LEN (SMALL_BUFF_LEN*16)
#define DEFAULT_NTHREADS 8
#define DEFAULT_TIMESTAMP_STEP 1
#define DEFAULT_INTERLACE_ROWS 0
#define DEFAULT_DATATYPE_NUM 1
......@@ -227,7 +228,7 @@ typedef struct SArguments_S {
char * sqlFile;
bool use_metric;
bool drop_database;
bool insert_only;
bool aggr_func;
bool answer_yes;
bool debug_print;
bool verbose_print;
......@@ -375,8 +376,7 @@ typedef struct SDbs_S {
char password[SHELL_MAX_PASSWORD_LEN];
char resultFile[MAX_FILE_NAME_LEN];
bool use_metric;
bool insert_only;
bool do_aggreFunc;
bool aggr_func;
bool asyncMode;
uint32_t threadCount;
......@@ -605,6 +605,9 @@ char *g_rand_current_buff = NULL;
char *g_rand_phase_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)",
"max(C0)", "min(C0)", "first(C0)", "last(C0)"};
......@@ -628,7 +631,7 @@ SArguments g_args = {
NULL, // sqlFile
true, // use_metric
true, // drop_database
true, // insert_only
false, // aggr_func
false, // debug_print
false, // verbose_print
false, // performance statistic print
......@@ -646,7 +649,7 @@ SArguments g_args = {
64, // binwidth
4, // columnCount, timestamp + float + int + float
20 + FLOAT_BUFF_LEN + INT_BUFF_LEN + FLOAT_BUFF_LEN, // lenOfOneRow
8, // num_of_connections/thread
DEFAULT_NTHREADS,// nthreads
0, // insert_interval
DEFAULT_TIMESTAMP_STEP, // timestamp_step
1, // query_times
......@@ -748,19 +751,19 @@ static void printHelp() {
char indent[10] = " ";
printf("%s\n\n", "Usage: taosdemo [OPTION...]");
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",
"The user name to use when connecting to the server.");
#ifdef _TD_POWER_
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",
"Configuration directory. Default is '/etc/power/'.");
"Configuration directory. By default is '/etc/power/'.");
#elif (_TD_TQ_ == true)
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",
"Configuration directory. Default is '/etc/tq/'.");
"Configuration directory. By default is '/etc/tq/'.");
#else
printf("%s%s%s%s\n", indent, "-p, --password", "\t\t",
"The password to use when connecting to the server.");
......@@ -772,24 +775,24 @@ static void printHelp() {
printf("%s%s%s%s\n", indent, "-P, --port=PORT", "\t\t",
"The TCP/IP port number to use for the connection.");
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",
"Destination database. Default is 'test'.");
"Destination database. By default is 'test'.");
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",
"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",
"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, "-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",
"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",
"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",
"The width of data_type 'BINARY' or 'NCHAR'. Default is ",
"The width of data_type 'BINARY' or 'NCHAR'. By default use ",
g_args.binwidth);
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 ",
......@@ -798,32 +801,32 @@ static void printHelp() {
MAX_NUM_COLUMNS);
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.");
printf("%s%s%s%s\n", indent, "-T, --threads=NUMBER", "\t\t",
"The number of threads. Default is 10.");
printf("%s%s%s%s%d.\n", indent, "-T, --threads=NUMBER", "\t\t",
"The number of threads. By default use ", DEFAULT_NTHREADS);
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",
"The timestamp step between insertion. Default is ",
"The timestamp step between insertion. By default is ",
DEFAULT_TIMESTAMP_STEP);
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);
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",
"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",
"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",
"The value of records generated are totally random.");
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.");
printf("%s\n", "\t\t\t\tBy default to simulate power equipment scenario.");
printf("%s%s%s%s\n", indent, "-x, --aggr-func", "\t\t",
"Test aggregation functions after insertion.");
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",
"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",
"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",
"Print debug info.");
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) {
}
} else if ((strcmp(argv[i], "-N") == 0)
|| (0 == strcmp(argv[i], "--normal-table"))) {
arguments->demo_mode = false;
arguments->use_metric = false;
} else if ((strcmp(argv[i], "-M") == 0)
|| (0 == strcmp(argv[i], "--random"))) {
arguments->demo_mode = false;
} else if ((strcmp(argv[i], "-x") == 0)
|| (0 == strcmp(argv[i], "--no-insert"))) {
arguments->insert_only = false;
|| (0 == strcmp(argv[i], "--aggr-func"))) {
arguments->aggr_func = true;
} else if ((strcmp(argv[i], "-y") == 0)
|| (0 == strcmp(argv[i], "--answer-yes"))) {
arguments->answer_yes = true;
......@@ -2429,10 +2433,11 @@ static void init_rand_data() {
static int printfInsertMeta() {
SHOW_PARSE_RESULT_START();
if (g_args.demo_mode)
printf("\ntaosdemo is simulating data generated by power equipments monitoring...\n\n");
else
if (g_args.demo_mode) {
printf("\ntaosdemo is simulating data generated by power equipment monitoring...\n\n");
} else {
printf("\ntaosdemo is simulating random data as you request..\n\n");
}
if (g_args.iface != INTERFACE_BUT) {
// first time if no iface specified
......@@ -10065,11 +10070,10 @@ static void startMultiThreadInsertData(int threads, char* db_name,
free(infos);
}
static void *readTable(void *sarg) {
#if 1
static void *queryNtableAggrFunc(void *sarg) {
threadInfo *pThreadInfo = (threadInfo *)sarg;
TAOS *taos = pThreadInfo->taos;
setThreadName("readTable");
setThreadName("queryNtableAggrFunc");
char *command = calloc(1, BUFFER_SIZE);
assert(command);
......@@ -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 totalData = insertRows * ntables;
bool do_aggreFunc = g_Dbs.do_aggreFunc;
bool aggr_func = g_Dbs.aggr_func;
char **aggreFunc;
int n;
int n = do_aggreFunc ? (sizeof(g_aggreFunc) / sizeof(g_aggreFunc[0])) : 2;
if (!do_aggreFunc) {
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("%"PRId64" records:\n", totalData);
......@@ -10106,9 +10120,11 @@ static void *readTable(void *sarg) {
uint64_t count = 0;
for (int64_t i = 0; i < ntables; i++) {
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);
int32_t code = taos_errno(pSql);
......@@ -10125,29 +10141,27 @@ static void *readTable(void *sarg) {
count++;
}
t = taosGetTimestampMs() - t;
t = taosGetTimestampUs() - t;
totalT += t;
taos_free_result(pSql);
}
fprintf(fp, "|%10s | %"PRId64" | %12.2f | %10.2f |\n",
g_aggreFunc[j][0] == '*' ? " * " : g_aggreFunc[j], totalData,
(double)(ntables * insertRows) / totalT, totalT * 1000);
printf("select %10s took %.6f second(s)\n", g_aggreFunc[j], totalT * 1000);
aggreFunc[j][0] == '*' ? " * " : aggreFunc[j], totalData,
(double)(ntables * insertRows) / totalT, totalT / 1000000);
printf("select %10s took %.6f second(s)\n", aggreFunc[j], totalT / 1000000);
}
fprintf(fp, "\n");
fclose(fp);
free(command);
#endif
return NULL;
}
static void *readMetric(void *sarg) {
#if 1
static void *queryStableAggrFunc(void *sarg) {
threadInfo *pThreadInfo = (threadInfo *)sarg;
TAOS *taos = pThreadInfo->taos;
setThreadName("readMetric");
setThreadName("queryStableAggrFunc");
char *command = calloc(1, BUFFER_SIZE);
assert(command);
......@@ -10161,12 +10175,23 @@ static void *readMetric(void *sarg) {
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;
bool aggr_func = g_Dbs.aggr_func;
char **aggreFunc;
int n;
int n = do_aggreFunc ? (sizeof(g_aggreFunc) / sizeof(g_aggreFunc[0])) : 2;
if (!do_aggreFunc) {
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("%"PRId64" records:\n", totalData);
fprintf(fp, "Querying On %"PRId64" records:\n", totalData);
......@@ -10178,18 +10203,29 @@ static void *readMetric(void *sarg) {
for (int64_t i = 1; i <= m; i++) {
if (i == 1) {
sprintf(tempS, "t1 = %"PRId64"", i);
if (g_args.demo_mode) {
sprintf(tempS, "groupid = %"PRId64"", i);
} else {
sprintf(tempS, "t0 = %"PRId64"", i);
}
} else {
sprintf(tempS, " or t1 = %"PRId64" ", i);
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);
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);
debugPrint("%s() LN%d, sql command: %s\n",
__func__, __LINE__, command);
fprintf(fp, "%s\n", command);
double t = taosGetTimestampMs();
double t = taosGetTimestampUs();
TAOS_RES *pSql = taos_query(taos, command);
int32_t code = taos_errno(pSql);
......@@ -10206,11 +10242,11 @@ static void *readMetric(void *sarg) {
while(taos_fetch_row(pSql) != NULL) {
count++;
}
t = taosGetTimestampMs() - t;
t = taosGetTimestampUs() - t;
fprintf(fp, "| Speed: %12.2f(per s) | Latency: %.4f(ms) |\n",
ntables * insertRows / (t * 1000.0), t);
printf("select %10s took %.6f second(s)\n\n", g_aggreFunc[j], t * 1000.0);
ntables * insertRows / (t / 1000), t);
printf("select %10s took %.6f second(s)\n\n", aggreFunc[j], t / 1000000);
taos_free_result(pSql);
}
......@@ -10218,7 +10254,7 @@ static void *readMetric(void *sarg) {
}
fclose(fp);
free(command);
#endif
return NULL;
}
......@@ -11225,9 +11261,8 @@ static void setParaFromArg() {
tstrncpy(g_Dbs.resultFile, g_args.output_file, MAX_FILE_NAME_LEN);
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 *data_type = g_args.data_type;
......@@ -11238,7 +11273,7 @@ static void setParaFromArg() {
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;
g_Dbs.aggr_func = false;
}
if (g_args.use_metric) {
......@@ -11420,7 +11455,7 @@ static void testMetaFile() {
}
}
static void queryResult() {
static void queryAggrFunc() {
// query data
pthread_t read_id;
......@@ -11429,7 +11464,6 @@ static void queryResult() {
pThreadInfo->start_time = DEFAULT_START_TIME; // 2017-07-14 10:40:00.000
pThreadInfo->start_table_from = 0;
//pThreadInfo->do_aggreFunc = g_Dbs.do_aggreFunc;
if (g_args.use_metric) {
pThreadInfo->ntables = g_Dbs.db[0].superTbls[0].childTblCount;
pThreadInfo->end_table_to = g_Dbs.db[0].superTbls[0].childTblCount - 1;
......@@ -11458,9 +11492,9 @@ static void queryResult() {
tstrncpy(pThreadInfo->filePath, g_Dbs.resultFile, MAX_FILE_NAME_LEN);
if (!g_Dbs.use_metric) {
pthread_create(&read_id, NULL, readTable, pThreadInfo);
pthread_create(&read_id, NULL, queryNtableAggrFunc, pThreadInfo);
} else {
pthread_create(&read_id, NULL, readMetric, pThreadInfo);
pthread_create(&read_id, NULL, queryStableAggrFunc, pThreadInfo);
}
pthread_join(read_id, NULL);
taos_close(pThreadInfo->taos);
......@@ -11482,8 +11516,9 @@ static void testCmdLine() {
g_args.test_mode = INSERT_TEST;
insertTestProcess();
if (false == g_Dbs.insert_only)
queryResult();
if (g_Dbs.aggr_func) {
queryAggrFunc();
}
}
int main(int argc, char *argv[]) {
......
......@@ -70,14 +70,14 @@ extern "C" {
#define TSDB_FUNC_DERIVATIVE 32
#define TSDB_FUNC_BLKINFO 33
#define TSDB_FUNC_HISTOGRAM 34
#define TSDB_FUNC_HLL 35
#define TSDB_FUNC_MODE 36
#define TSDB_FUNC_SAMPLE 37
#define TSDB_FUNC_CEIL 38
#define TSDB_FUNC_FLOOR 39
#define TSDB_FUNC_ROUND 40
#define TSDB_FUNC_CEIL 34
#define TSDB_FUNC_FLOOR 35
#define TSDB_FUNC_ROUND 36
#define TSDB_FUNC_HISTOGRAM 37
#define TSDB_FUNC_HLL 38
#define TSDB_FUNC_MODE 39
#define TSDB_FUNC_SAMPLE 40
#define TSDB_FUNC_MAVG 41
#define TSDB_FUNC_CSUM 42
......@@ -88,6 +88,7 @@ extern "C" {
#define TSDB_FUNCSTATE_OF 0x10u // outer forward
#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_SCALAR 0x80u
#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
......
......@@ -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 ||
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;
*bytes = (int16_t)dataBytes;
......@@ -405,7 +407,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
// TODO use hash table
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);
if (len != nameLen) {
continue;
......@@ -4256,6 +4258,231 @@ void blockinfo_func_finalizer(SQLFunctionCtx* 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.
......@@ -4274,8 +4501,8 @@ int32_t functionCompatList[] = {
4, -1, -1, 1, 1, 1, 1, 1, 1, -1,
// 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,
// tid_tag, derivative, blk_info
6, 8, 7,
// tid_tag, derivative, blk_info,ceil, floor, round
6, 8, 7, 1, 1, 1
};
SAggFunctionInfo aAggs[] = {{
......@@ -4678,7 +4905,7 @@ SAggFunctionInfo aAggs[] = {{
dataBlockRequired,
},
{
// 33
// 33
"_block_dist", // return table id and the corresponding tags for join match and subscribe
TSDB_FUNC_BLKINFO,
TSDB_FUNC_BLKINFO,
......@@ -4688,4 +4915,40 @@ SAggFunctionInfo aAggs[] = {{
blockinfo_func_finalizer,
block_func_merge,
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
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) {
for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) {
int32_t functId = pQueryAttr->pExpr1[i].base.functionId;
......@@ -1939,7 +1958,7 @@ void setBlockStatisInfo(SQLFunctionCtx *pCtx, SSDataBlock* pSDataBlock, SColInde
// set the output buffer for the selectivity + tag query
static int32_t setCtxTagColumnInfo(SQLFunctionCtx *pCtx, int32_t numOfOutput) {
if (!isSelectivityWithTagsQuery(pCtx, numOfOutput)) {
if (!isSelectivityWithTagsQuery(pCtx, numOfOutput) && !isScalarWithTagsQuery(pCtx, numOfOutput)) {
return TSDB_CODE_SUCCESS;
}
......@@ -1958,7 +1977,7 @@ static int32_t setCtxTagColumnInfo(SQLFunctionCtx *pCtx, int32_t numOfOutput) {
if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) {
tagLen += pCtx[i].outputBytes;
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];
} else if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TAG) {
// tag function may be the group by tag column
......
......@@ -645,6 +645,12 @@ SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr) {
} else {
op = OP_Project;
taosArrayPush(plan, &op);
if (pQueryAttr->pExpr2 != NULL) {
op = OP_Project;
taosArrayPush(plan, &op);
}
if (pQueryAttr->distinct) {
op = OP_Distinct;
taosArrayPush(plan, &op);
......
......@@ -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_derivative.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/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.
先完成此消息的编辑!
想要评论请 注册