Merge pull request #29187 from taosdata/merge/mainto3.0

merge: main to 3.0 branch
This commit is contained in:
Shengliang Guan 2024-12-18 08:59:32 +08:00 committed by GitHub
commit 8d0ca8d24e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
43 changed files with 709 additions and 140 deletions

View File

@ -2,7 +2,7 @@
IF (DEFINED VERNUMBER)
SET(TD_VER_NUMBER ${VERNUMBER})
ELSE ()
SET(TD_VER_NUMBER "3.3.4.8.alpha")
SET(TD_VER_NUMBER "3.3.5.0.alpha")
ENDIF ()
IF (DEFINED VERCOMPATIBLE)

View File

@ -190,6 +190,7 @@ ROUND(expr[, digits])
- `digits` less than zero means discarding the decimal places and rounding the number to the left of the decimal point by `digits` places. If the number of places to the left of the decimal point is less than `digits`, returns 0.
- Since the DECIMAL type is not yet supported, this function will use DOUBLE and FLOAT to represent results containing decimals, but DOUBLE and FLOAT have precision limits, and using this function may be meaningless when there are too many digits.
- Can only be used with regular columns, selection (Selection), projection (Projection) functions, and cannot be used with aggregation (Aggregation) functions.
- `digits` is supported from version 3.3.3.0.
**Example**:
@ -249,6 +250,8 @@ TAN(expr)
**Function Description**: Obtains the tangent result of the specified field.
**Version**: ver-3.3.3.0
**Return Result Type**: DOUBLE.
**Applicable Data Types**: Numeric types.
@ -297,6 +300,8 @@ TRUNCATE(expr, digits)
**Function Description**: Gets the truncated value of the specified field to the specified number of digits.
**Version**: ver-3.3.3.0
**Return Type**: Consistent with the original data type of the `expr` field.
**Applicable Data Types**:
@ -340,6 +345,8 @@ EXP(expr)
**Function Description**: Returns the value of e (the base of natural logarithms) raised to the specified power.
**Version**: ver-3.3.3.0
**Return Type**: DOUBLE.
**Applicable Data Types**: Numeric type.
@ -370,6 +377,8 @@ LN(expr)
**Function Description**: Returns the natural logarithm of the specified parameter.
**Version**: ver-3.3.3.0
**Return Type**: DOUBLE.
**Applicable Data Types**: Numeric type.
@ -401,6 +410,8 @@ MOD(expr1, expr2)
**Function Description**: Calculates the result of expr1 % expr2.
**Version**: ver-3.3.3.0
**Return Type**: DOUBLE.
**Applicable Data Types**: Numeric type.
@ -437,6 +448,8 @@ RAND([seed])
**Function Description**: Returns a uniformly distributed random number from 0 to 1.
**Version**: ver-3.3.3.0
**Return Result Type**: DOUBLE.
**Applicable Data Types**:
@ -484,6 +497,8 @@ SIGN(expr)
**Function Description**: Returns the sign of the specified parameter.
**Version**: ver-3.3.3.0
**Return Result Type**: Consistent with the original data type of the specified field.
**Applicable Data Types**: Numeric types.
@ -527,6 +542,8 @@ DEGREES(expr)
**Function Description**: Calculates the value of the specified parameter converted from radians to degrees.
**Version**: ver-3.3.3.0
**Return Result Type**: DOUBLE.
**Applicable Data Types**: Numeric types.
@ -558,6 +575,8 @@ RADIANS(expr)
**Function Description**: Calculates the value of the specified parameter converted from degrees to radians.
**Version**: ver-3.3.3.0
**Return Type**: DOUBLE.
**Applicable Data Types**: Numeric types.
@ -729,6 +748,8 @@ TRIM([remstr FROM] expr)
**Function Description**: Returns the string expr with all prefixes or suffixes of remstr removed.
**Version**: ver-3.3.3.0
**Return Result Type**: Same as the original type of the input field expr.
**Applicable Data Types**:
@ -807,6 +828,8 @@ SUBSTRING/SUBSTR(expr FROM pos [FOR len])
- If `len` is less than 1, returns an empty string.
- `pos` is 1-based; if `pos` is 0, returns an empty string.
- If `pos` + `len` exceeds `len(expr)`, returns the substring from `pos` to the end of the string, equivalent to executing `substring(expr, pos)`.
- Function `SUBSTRING` is equal to `SUBSTR`, supported from ver-3.3.3.0.
- Syntax `SUBSTRING/SUBSTR(expr FROM pos [FOR len])` is supported from ver-3.3.3.0.
**Examples**:
@ -845,6 +868,8 @@ SUBSTRING_INDEX(expr, delim, count)
**Function Description**: Returns a substring of `expr` cut at the position where the delimiter appears the specified number of times.
**Version**: ver-3.3.3.0
**Return Result Type**: Same as the original type of the input field `expr`.
**Applicable Data Types**:
@ -902,6 +927,8 @@ CHAR(expr1 [, expr2] [, expr3] ...)
**Function Description**: Treats the input parameters as integers and returns the characters corresponding to these integers in ASCII encoding.
**Version**: ver-3.3.3.0
**Return Result Type**: VARCHAR.
**Applicable Data Types**: Integer types, VARCHAR, NCHAR.
@ -949,6 +976,8 @@ ASCII(expr)
**Function Description**: Returns the ASCII code of the first character of the string.
**Version**: ver-3.3.3.0
**Return Result Data Type**: BIGINT.
**Applicable Data Types**: VARCHAR, NCHAR.
@ -979,6 +1008,8 @@ POSITION(expr1 IN expr2)
**Function Description**: Calculates the position of string `expr1` in string `expr2`.
**Version**: ver-3.3.3.0
**Return Result Type**: BIGINT.
**Applicable Data Types**:
@ -1026,6 +1057,8 @@ REPLACE(expr, from_str, to_str)
**Function Description**: Replaces all occurrences of `from_str` in the string with `to_str`.
**Version**: ver-3.3.3.0
**Return Type**: Same as the original type of the input field `expr`.
**Applicable Data Types**:
@ -1061,6 +1094,8 @@ REPEAT(expr, count)
**Function Description**: Returns a string that repeats the string `expr` a specified number of times.
**Version**: ver-3.3.3.0
**Return Type**: Same as the original type of the input field `expr`.
**Applicable Data Types**:
@ -1319,6 +1354,7 @@ TIMEDIFF(expr1, expr2 [, time_unit])
- `expr1`: BIGINT, TIMESTAMP types representing timestamps, or VARCHAR, NCHAR types in ISO8601/RFC3339 standard date-time format.
- `expr2`: BIGINT, TIMESTAMP types representing timestamps, or VARCHAR, NCHAR types in ISO8601/RFC3339 standard date-time format.
- `time_unit`: See usage instructions.
- `timediff` return the absolute value of the difference between timestamp `expr1` and `expr2` before ver-3.3.3.0.
**Nested Subquery Support**: Applicable to both inner and outer queries.
@ -1423,6 +1459,8 @@ WEEK(expr [, mode])
**Function Description**: Returns the week number of the input date.
**Version**: ver-3.3.3.0
**Return Result Type**: BIGINT.
**Applicable Data Types**:
@ -1490,6 +1528,8 @@ WEEKOFYEAR(expr)
**Function Description**: Returns the week number of the input date.
**Version**: ver-3.3.3.0
**Return Type**: BIGINT.
**Applicable Data Types**: BIGINT, TIMESTAMP types representing timestamps, or VARCHAR, NCHAR types in ISO8601/RFC3339 date-time format.
@ -1521,6 +1561,8 @@ WEEKDAY(expr)
**Function Description**: Returns the weekday of the input date.
**Version**: ver-3.3.3.0
**Return Type**: BIGINT.
**Applicable Data Types**: BIGINT, TIMESTAMP types representing timestamps, or VARCHAR, NCHAR types in ISO8601/RFC3339 date-time format.
@ -1552,6 +1594,8 @@ DAYOFWEEK(expr)
**Function Description**: Returns the weekday of the input date.
**Version**: ver-3.3.3.0
**Return Type**: BIGINT.
**Applicable Data Types**: BIGINT, TIMESTAMP types representing timestamps, or VARCHAR, NCHAR types in ISO8601/RFC3339 date-time format.
@ -1707,6 +1751,9 @@ STDDEV/STDDEV_POP(expr)
**Applicable to**: Tables and supertables.
**Description**:
- Function `STDDEV_POP` equals `STDDEV` and is supported from ver-3.3.3.0.
**Example**:
```sql
@ -1733,6 +1780,8 @@ VAR_POP(expr)
**Function Description**: Calculates the population variance of a column in a table.
**Version**: ver-3.3.3.0
**Return Data Type**: DOUBLE.
**Applicable Data Types**: Numeric types.
@ -1975,7 +2024,8 @@ MAX(expr)
**Applicable to**: Tables and supertables.
**Usage Instructions**: The max function can accept strings as input parameters, and when the input parameter is a string type, it returns the largest string value.
**Usage Instructions**:
- The max function can accept strings as input parameters, and when the input parameter is a string type, it returns the largest string value(supported from ver-3.3.3.0, function `max` only accept numeric parameter before ver-3.3.3.0).
### MIN
@ -1991,7 +2041,8 @@ MIN(expr)
**Applicable to**: Tables and supertables.
**Usage Instructions**: The min function can accept strings as input parameters, and when the input parameter is a string type, it returns the largest string value.
**Usage Instructions**:
- The min function can accept strings as input parameters, and when the input parameter is a string type, it returns the largest string value(supported from ver-3.3.3.0, function `min` only accept numeric parameter before ver-3.3.3.0).
### MODE

View File

@ -47,7 +47,7 @@ taosws://用户名:密码@主机名:端口号
```bash
taosws://root:taosdata@localhost:6041
```
第5步配置好连接串点击 “TEST CONNECTION” 测试连接是否成功,测试通过后点击 “CONNECT” 按钮,完成连接。
** 5 **,配置好连接串,点击 “TEST CONNECTION” 测试连接是否成功,测试通过后点击 “CONNECT” 按钮,完成连接。
## 开始使用

View File

@ -282,9 +282,6 @@ d4,2017-07-14T10:40:00.006+08:00,-2.740636,10,-0.893545,7,California.LosAngles
# listen to ip:port address
#listen = "0.0.0.0:6050"
# database url
#database_url = "sqlite:taosx.db"
# default global request timeout which unit is second. This parameter takes effect for certain interfaces that require a timeout setting
#request_timeout = 30
@ -384,6 +381,16 @@ Linux 下 `journalctl` 查看日志的命令如下:
journalctl -u taosx [-f]
```
### 从旧版本升级
从 3.3.5.0/3.3.4.11 版本开始,不再在 systemd 服务文件预置 `DATABASE_URL=` 环境变量。如果在配置文件中使用了自定义 `data_dir` 参数,从旧版本升级后,必须将数据库文件从旧版本移动到自定义目录中。以 `data_dir = "/path/to/data"` 为例,执行以下命令:
```shell
mv /var/lib/taos/taosx/taosx.db* /path/to/data/
```
之后再重启服务(此行为仅影响 Linux 系统)。
## taosX 监控指标
taosX 会将监控指标上报给 taosKeeper这些监控指标会被 taosKeeper 写入监控数据库,默认是 `log` 库,可以在 taoskeeper 配置文件中修改。以下是这些监控指标的详细介绍。

View File

@ -193,6 +193,7 @@ ROUND(expr[, digits])
- `digits` 小于零表示丢掉小数位,并将数字四舍五入到小数点左侧 `digits` 位。若小数点左侧的位数小于 `digits`位,返回 0。
- 由于暂未支持 DECIMAL 类型,所以该函数会用 DOUBLE 和 FLOAT 来表示包含小数的结果,但是 DOUBLE 和 FLOAT 是有精度上限的,当位数太多时使用该函数可能没有意义。
- 只能与普通列选择Selection、投影Projection函数一起使用不能与聚合Aggregation函数一起使用。
- `digits` 从 ver-3.3.3.0 开始支持。
**举例**
```sql
@ -268,6 +269,8 @@ PI()
**功能说明**:返回圆周率 π 的值。
**版本**: ver-3.3.3.0
**返回结果类型**DOUBLE。
**适用数据类型**:无。
@ -295,6 +298,8 @@ TRUNCATE(expr, digits)
**功能说明**:获得指定字段按照指定位数截断的值。
**版本**: ver-3.3.3.0
**返回结果类型**:与 `expr` 字段的原始数据类型一致。
**适用数据类型**
@ -333,6 +338,8 @@ EXP(expr)
```
**功能说明**:返回 e自然对数的底的指定乘方后的值。
**版本**: ver-3.3.3.0
**返回结果类型**DOUBLE。
**适用数据类型**:数值类型。
@ -360,6 +367,8 @@ LN(expr)
**功能说明**:返回指定参数的自然对数。
**版本**: ver-3.3.3.0
**返回结果类型**DOUBLE。
**适用数据类型**:数值类型。
@ -388,6 +397,8 @@ MOD(expr1, expr2)
**功能说明**:计算 expr1 % expr2 的结果。
**版本**: ver-3.3.3.0
**返回结果类型**DOUBLE。
**适用数据类型**:数值类型。
@ -421,6 +432,8 @@ RAND([seed])
**功能说明**返回一个从0到1均匀分布的随机数。
**版本**: ver-3.3.3.0
**返回结果类型**DOUBLE。
**适用数据类型**
@ -464,6 +477,8 @@ SIGN(expr)
**功能说明**:返回指定参数的符号。
**版本**: ver-3.3.3.0
**返回结果类型**:与指定字段的原始数据类型一致。
**适用数据类型**:数值类型。
@ -504,6 +519,8 @@ DEGREES(expr)
**功能说明**:计算指定参数由弧度值转为角度后的值。
**版本**: ver-3.3.3.0
**返回结果类型**DOUBLE。
**适用数据类型**:数值类型。
@ -532,6 +549,8 @@ RADIANS(expr)
**功能说明**:计算指定参数由角度值转为弧度后的值。
**版本**: ver-3.3.3.0
**返回结果类型**DOUBLE。
**适用数据类型**:数值类型。
@ -702,6 +721,8 @@ TRIM([remstr FROM] expr)
**功能说明**:返回去掉了所有 remstr 前缀或后缀的字符串 epxr 。
**版本**: ver-3.3.3.0
**返回结果类型**:与输入字段 epxr 的原始类型相同。
**适用数据类型**
@ -773,6 +794,8 @@ SUBSTRING/SUBSTR(expr FROM pos [FOR len])
- 若 `len` 小于 1返回空串。
- `pos` 是 1-base 的,若 `pos` 为 0返回空串。
- 若 `pos` + `len` 大于 `len(expr)`,返回从 `pos` 开始到字符串结尾的子串,等同于执行 `substring(expr, pos)`
- `SUBSTRING` 函数等价于 `SUBSTR`, 从 ver-3.3.3.0 开始支持。
- `SUBSTRING/SUBSTR(expr FROM pos [FOR len])` 语法从 ver-3.3.3.0 开始支持。
**举例**
```sql
@ -809,6 +832,8 @@ SUBSTRING_INDEX(expr, delim, count)
**功能说明**:返回字符串 `expr` 在出现指定次数分隔符的位置截取的子串。
**版本**: ver-3.3.3.0
**返回结果类型**:与输入字段 `expr` 的原始类型相同。
**适用数据类型**
@ -862,6 +887,8 @@ CHAR(expr1 [, expr2] [, epxr3] ...)
**功能说明**:将输入参数当作整数,并返回这些整数在 ASCII 编码中对应的字符。
**版本**: ver-3.3.3.0
**返回结果类型**VARCHAR。
**适用数据类型**:整数类型,VARCHAR,NCHAR。
@ -906,6 +933,8 @@ ASCII(expr)
**功能说明**:返回字符串第一个字符的 ASCII 码。
**版本**: ver-3.3.3.0
**返回结果数据类型**BIGINT。
**适用数据类型**VARCHAR, NCHAR。
@ -933,6 +962,8 @@ POSITION(expr1 IN expr2)
**功能说明**:计算字符串 `expr1` 在字符串 `expr2` 中的位置。
**版本**: ver-3.3.3.0
**返回结果类型**BIGINT。
**适用数据类型**
@ -975,6 +1006,8 @@ REPLACE(expr, from_str, to_str)
```
**功能说明**:将字符串中的 `from_str` 全部替换为 `to_str`
**版本**: ver-3.3.3.0
**返回结果类型**:与输入字段 `expr` 的原始类型相同。
**适用数据类型**
@ -1005,6 +1038,8 @@ REPEAT(expr, count)
```
**功能说明**:返回将字符串重复指定次数得到的字符串。
**版本**: ver-3.3.3.0
**返回结果类型**:与输入字段 `expr` 的原始类型相同。
**适用数据类型**
@ -1260,6 +1295,7 @@ TIMEDIFF(expr1, expr2 [, time_unit])
- `expr1`:表示时间戳的 BIGINT, TIMESTAMP 类型,或符合 ISO8601/RFC3339 标准的日期时间格式的 VARCHAR, NCHAR 类型。
- `expr2`:表示时间戳的 BIGINT, TIMESTAMP 类型,或符合 ISO8601/RFC3339 标准的日期时间格式的 VARCHAR, NCHAR 类型。
- `time_unit`:见使用说明。
- ver-3.3.3.0 之前该函数结果为时间戳 `expr1``expr2` 的差值的绝对值,结果为正数。
**嵌套子查询支持**:适用于内层查询和外层查询。
@ -1361,6 +1397,8 @@ WEEK(expr [, mode])
```
**功能说明**:返回输入日期的周数。
**版本**: ver-3.3.3.0
**返回结果类型**BIGINT。
**适用数据类型**
@ -1422,6 +1460,8 @@ WEEKOFYEAR(expr)
```
**功能说明**:返回输入日期的周数。
**版本**: ver-3.3.3.0
**返回结果类型**BIGINT。
**适用数据类型**:表示时间戳的 BIGINT, TIMESTAMP 类型,或符合 ISO8601/RFC3339 标准的日期时间格式的 VARCHAR, NCHAR 类型。
@ -1449,6 +1489,8 @@ WEEKDAY(expr)
```
**功能说明**:返回输入日期是周几。
**版本**: ver-3.3.3.0
**返回结果类型**BIGINT。
**适用数据类型**:表示 表示时间戳的 BIGINT, TIMESTAMP 类型,或符合 ISO8601/RFC3339 标准的日期时间格式的 VARCHAR, NCHAR 类型。
@ -1476,6 +1518,8 @@ DAYOFWEEK(expr)
```
**功能说明**:返回输入日期是周几。
**版本**: ver-3.3.3.0
**返回结果类型**BIGINT。
**适用数据类型**:表示时间戳的 BIGINT, TIMESTAMP 类型,或符合 ISO8601/RFC3339 标准的日期时间格式的 VARCHAR, NCHAR 类型。
@ -1633,6 +1677,9 @@ STDDEV/STDDEV_POP(expr)
**适用于**:表和超级表。
**说明**
- `STDDEV_POP` 函数等价于 `STDDEV` 函数,从 ver-3.3.3.0 开始支持。
**举例**
```sql
taos> select id from test_stddev;
@ -1656,6 +1703,8 @@ VAR_POP(expr)
**功能说明**:统计表中某列的总体方差。
**版本**: ver-3.3.3.0
**返回数据类型**DOUBLE。
**适用数据类型**:数值类型。
@ -1898,7 +1947,8 @@ MAX(expr)
**适用于**:表和超级表。
**使用说明**max 函数可以接受字符串作为输入参数,当输入参数为字符串类型时,返回最大的字符串值。
**使用说明**
- max 函数可以接受字符串作为输入参数,当输入参数为字符串类型时,返回最大的字符串值,从 ver-3.3.3.0 开始支持,之前的版本不支持字符串参数。
### MIN
@ -1914,7 +1964,8 @@ MIN(expr)
**适用于**:表和超级表。
**使用说明**min 函数可以接受字符串作为输入参数,当输入参数为字符串类型时,返回最大的字符串值。
**使用说明**
- min 函数可以接受字符串作为输入参数,当输入参数为字符串类型时,返回最大的字符串值,从 ver-3.3.3.0 开始支持,之前的版本不支持字符串参数。
### MODE

View File

@ -26,7 +26,7 @@ typedef struct SCryptOpts {
char* source;
char* result;
int32_t unitLen;
char key[17];
char key[ENCRYPT_KEY_LEN + 1];
} SCryptOpts;
int32_t CBC_Decrypt(SCryptOpts* opts);

View File

@ -207,7 +207,6 @@ typedef struct {
typedef struct {
int32_t nodeId;
SEpSet epset;
} SDownstreamTaskEpset;
typedef enum {

View File

@ -77,7 +77,7 @@ static int32_t stmtCreateRequest(STscStmt2* pStmt) {
}
if (pStmt->db != NULL) {
taosMemoryFreeClear(pStmt->exec.pRequest->pDb);
pStmt->exec.pRequest->pDb = strdup(pStmt->db);
pStmt->exec.pRequest->pDb = taosStrdup(pStmt->db);
}
if (TSDB_CODE_SUCCESS == code) {
pStmt->exec.pRequest->syncQuery = true;

View File

@ -788,6 +788,8 @@ TEST(clientCase, insert_test) {
}
TEST(clientCase, projection_query_tables) {
taos_options(TSDB_OPTION_CONFIGDIR, "/home/lisa/first/cfg");
TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
ASSERT_NE(pConn, nullptr);
@ -796,6 +798,12 @@ TEST(clientCase, projection_query_tables) {
pRes= taos_query(pConn, "use abc1");
taos_free_result(pRes);
pRes = taos_query(pConn, "select forecast(k,'algo=arima,wncheck=0') from t1 where ts<='2024-11-15 1:7:44'");
if (taos_errno(pRes) != 0) {
(void)printf("failed to create table tu, reason:%s\n", taos_errstr(pRes));
}
taos_free_result(pRes);
pRes = taos_query(pConn, "create table tu using st2 tags(2)");
if (taos_errno(pRes) != 0) {
(void)printf("failed to create table tu, reason:%s\n", taos_errstr(pRes));

View File

@ -18,7 +18,7 @@
#include "tcompression.h"
const int32_t TYPE_BYTES[21] = {
-1, // TSDB_DATA_TYPE_NULL
2, // TSDB_DATA_TYPE_NULL
CHAR_BYTES, // TSDB_DATA_TYPE_BOOL
CHAR_BYTES, // TSDB_DATA_TYPE_TINYINT
SHORT_BYTES, // TSDB_DATA_TYPE_SMALLINT
@ -42,7 +42,7 @@ const int32_t TYPE_BYTES[21] = {
};
tDataTypeDescriptor tDataTypes[TSDB_DATA_TYPE_MAX] = {
{TSDB_DATA_TYPE_NULL, 6, 1, "NOTYPE", 0, 0, NULL, NULL},
{TSDB_DATA_TYPE_NULL, 6, 2, "NOTYPE", 0, 0, NULL, NULL},
{TSDB_DATA_TYPE_BOOL, 4, CHAR_BYTES, "BOOL", false, true, tsCompressBool, tsDecompressBool},
{TSDB_DATA_TYPE_TINYINT, 7, CHAR_BYTES, "TINYINT", INT8_MIN, INT8_MAX, tsCompressTinyint, tsDecompressTinyint},
{TSDB_DATA_TYPE_SMALLINT, 8, SHORT_BYTES, "SMALLINT", INT16_MIN, INT16_MAX, tsCompressSmallint,

View File

@ -211,7 +211,7 @@ static void vmGenerateVnodeCfg(SCreateVnodeReq *pCreate, SVnodeCfg *pCfg) {
#if defined(TD_ENTERPRISE)
pCfg->tdbEncryptAlgorithm = pCreate->encryptAlgorithm;
if (pCfg->tdbEncryptAlgorithm == DND_CA_SM4) {
tstrncpy(pCfg->tdbEncryptKey, tsEncryptKey, ENCRYPT_KEY_LEN);
tstrncpy(pCfg->tdbEncryptKey, tsEncryptKey, ENCRYPT_KEY_LEN + 1);
}
#else
pCfg->tdbEncryptAlgorithm = 0;

View File

@ -29,7 +29,7 @@ static int32_t mndCfgActionInsert(SSdb *pSdb, SConfigObj *obj);
static int32_t mndCfgActionDelete(SSdb *pSdb, SConfigObj *obj);
static int32_t mndCfgActionUpdate(SSdb *pSdb, SConfigObj *oldItem, SConfigObj *newObj);
static int32_t mndCfgActionDeploy(SMnode *pMnode);
static int32_t mndCfgActionPrepare(SMnode *pMnode);
static int32_t mndCfgActionAfterRestored(SMnode *pMnode);
static int32_t mndProcessConfigReq(SRpcMsg *pReq);
#ifdef __cplusplus

View File

@ -18,6 +18,7 @@
#include "mndConfig.h"
#include "mndDnode.h"
#include "mndPrivilege.h"
#include "mndSync.h"
#include "mndTrans.h"
#include "mndUser.h"
#include "tutil.h"
@ -52,7 +53,7 @@ int32_t mndInitConfig(SMnode *pMnode) {
.updateFp = (SdbUpdateFp)mndCfgActionUpdate,
.deleteFp = (SdbDeleteFp)mndCfgActionDelete,
.deployFp = (SdbDeployFp)mndCfgActionDeploy,
.prepareFp = (SdbPrepareFp)mndCfgActionPrepare};
.afterRestoredFp = (SdbAfterRestoredFp)mndCfgActionAfterRestored};
mndSetMsgHandle(pMnode, TDMT_MND_CONFIG, mndProcessConfigReq);
mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_DNODE, mndProcessConfigDnodeReq);
@ -213,7 +214,7 @@ static int32_t mndCfgActionUpdate(SSdb *pSdb, SConfigObj *pOld, SConfigObj *pNew
static int32_t mndCfgActionDeploy(SMnode *pMnode) { return mndInitWriteCfg(pMnode); }
static int32_t mndCfgActionPrepare(SMnode *pMnode) { return mndTryRebuildCfg(pMnode); }
static int32_t mndCfgActionAfterRestored(SMnode *pMnode) { return mndTryRebuildCfg(pMnode); }
static int32_t mndProcessConfigReq(SRpcMsg *pReq) {
SMnode *pMnode = pReq->info.node;
@ -340,11 +341,15 @@ _OVER:
}
int32_t mndTryRebuildCfg(SMnode *pMnode) {
if (!mndIsLeader(pMnode)) {
return TSDB_CODE_SUCCESS;
}
int32_t code = 0;
int32_t sz = -1;
STrans *pTrans = NULL;
SAcctObj *vObj = NULL, *obj = NULL;
SArray *addArray = NULL;
vObj = sdbAcquire(pMnode->pSdb, SDB_CFG, "tsmmConfigVersion");
if (vObj == NULL) {
if ((code = mndInitWriteCfg(pMnode)) < 0) goto _exit;

View File

@ -797,14 +797,7 @@ int32_t mndStart(SMnode *pMnode) {
return -1;
}
mndSetRestored(pMnode, true);
} else {
if (sdbPrepare(pMnode->pSdb) != 0) {
mError("failed to prepare sdb while start mnode");
return -1;
}
mndSetRestored(pMnode, true);
}
grantReset(pMnode, TSDB_GRANT_ALL, 0);
return mndInitTimer(pMnode);

View File

@ -1430,7 +1430,7 @@ int32_t mndFindChangedNodeInfo(SMnode *pMnode, const SArray *pPrevNodeList, cons
return TSDB_CODE_INVALID_PARA;
}
pInfo->pUpdateNodeList = taosArrayInit(4, sizeof(SNodeUpdateInfo)),
pInfo->pUpdateNodeList = taosArrayInit(4, sizeof(SNodeUpdateInfo));
pInfo->pDBMap = taosHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), true, HASH_NO_LOCK);
if (pInfo->pUpdateNodeList == NULL || pInfo->pDBMap == NULL) {

View File

@ -14,11 +14,11 @@
*/
#define _DEFAULT_SOURCE
#include "mndSync.h"
#include "mndCluster.h"
#include "mndStream.h"
#include "mndSync.h"
#include "mndTrans.h"
#include "mndUser.h"
#include "mndStream.h"
static int32_t mndSyncEqCtrlMsg(const SMsgCb *msgcb, SRpcMsg *pMsg) {
if (pMsg == NULL || pMsg->pCont == NULL) {
@ -309,6 +309,9 @@ void mndRestoreFinish(const SSyncFSM *pFsm, const SyncIndex commitIdx) {
} else {
mInfo("vgId:1, sync restore finished, repeat call");
}
if (sdbAfterRestored(pMnode->pSdb) != 0) {
mError("failed to prepare sdb while start mnode");
}
} else {
mInfo("vgId:1, sync restore finished");
}
@ -507,7 +510,7 @@ int32_t mndInitSync(SMnode *pMnode) {
mError("failed to open sync, tsem_init, since %s", tstrerror(code));
TAOS_RETURN(code);
}
pMgmt->sync = syncOpen(&syncInfo, 1); // always check
pMgmt->sync = syncOpen(&syncInfo, 1); // always check
if (pMgmt->sync <= 0) {
if (terrno != 0) code = terrno;
mError("failed to open sync since %s", tstrerror(code));
@ -546,7 +549,7 @@ void mndSyncCheckTimeout(SMnode *pMnode) {
// pMgmt->transSeq = 0;
// terrno = TSDB_CODE_SYN_TIMEOUT;
// pMgmt->errCode = TSDB_CODE_SYN_TIMEOUT;
//if (tsem_post(&pMgmt->syncSem) < 0) {
// if (tsem_post(&pMgmt->syncSem) < 0) {
// mError("failed to post sem");
//}
} else {

View File

@ -117,7 +117,7 @@ typedef int32_t (*SdbInsertFp)(SSdb *pSdb, void *pObj);
typedef int32_t (*SdbUpdateFp)(SSdb *pSdb, void *pSrcObj, void *pDstObj);
typedef int32_t (*SdbDeleteFp)(SSdb *pSdb, void *pObj, bool callFunc);
typedef int32_t (*SdbDeployFp)(SMnode *pMnode);
typedef int32_t (*SdbPrepareFp)(SMnode *pMnode);
typedef int32_t (*SdbAfterRestoredFp)(SMnode *pMnode);
typedef int32_t (*SdbValidateFp)(SMnode *pMnode, void *pTrans, SSdbRaw *pRaw);
typedef SSdbRow *(*SdbDecodeFp)(SSdbRaw *pRaw);
typedef SSdbRaw *(*SdbEncodeFp)(void *pObj);
@ -188,31 +188,31 @@ typedef struct SSdbRow {
} SSdbRow;
typedef struct SSdb {
SMnode *pMnode;
SWal *pWal;
int64_t sync;
char *currDir;
char *tmpDir;
int64_t commitIndex;
int64_t commitTerm;
int64_t commitConfig;
int64_t applyIndex;
int64_t applyTerm;
int64_t applyConfig;
int64_t tableVer[SDB_MAX];
int64_t maxId[SDB_MAX];
EKeyType keyTypes[SDB_MAX];
SHashObj *hashObjs[SDB_MAX];
TdThreadRwlock locks[SDB_MAX];
SdbInsertFp insertFps[SDB_MAX];
SdbUpdateFp updateFps[SDB_MAX];
SdbDeleteFp deleteFps[SDB_MAX];
SdbDeployFp deployFps[SDB_MAX];
SdbPrepareFp prepareFps[SDB_MAX];
SdbEncodeFp encodeFps[SDB_MAX];
SdbDecodeFp decodeFps[SDB_MAX];
SdbValidateFp validateFps[SDB_MAX];
TdThreadMutex filelock;
SMnode *pMnode;
SWal *pWal;
int64_t sync;
char *currDir;
char *tmpDir;
int64_t commitIndex;
int64_t commitTerm;
int64_t commitConfig;
int64_t applyIndex;
int64_t applyTerm;
int64_t applyConfig;
int64_t tableVer[SDB_MAX];
int64_t maxId[SDB_MAX];
EKeyType keyTypes[SDB_MAX];
SHashObj *hashObjs[SDB_MAX];
TdThreadRwlock locks[SDB_MAX];
SdbInsertFp insertFps[SDB_MAX];
SdbUpdateFp updateFps[SDB_MAX];
SdbDeleteFp deleteFps[SDB_MAX];
SdbDeployFp deployFps[SDB_MAX];
SdbAfterRestoredFp afterRestoredFps[SDB_MAX];
SdbEncodeFp encodeFps[SDB_MAX];
SdbDecodeFp decodeFps[SDB_MAX];
SdbValidateFp validateFps[SDB_MAX];
TdThreadMutex filelock;
} SSdb;
typedef struct SSdbIter {
@ -222,16 +222,16 @@ typedef struct SSdbIter {
} SSdbIter;
typedef struct {
ESdbType sdbType;
EKeyType keyType;
SdbDeployFp deployFp;
SdbPrepareFp prepareFp;
SdbEncodeFp encodeFp;
SdbDecodeFp decodeFp;
SdbInsertFp insertFp;
SdbUpdateFp updateFp;
SdbDeleteFp deleteFp;
SdbValidateFp validateFp;
ESdbType sdbType;
EKeyType keyType;
SdbDeployFp deployFp;
SdbAfterRestoredFp afterRestoredFp;
SdbEncodeFp encodeFp;
SdbDecodeFp decodeFp;
SdbInsertFp insertFp;
SdbUpdateFp updateFp;
SdbDeleteFp deleteFp;
SdbValidateFp validateFp;
} SSdbTable;
typedef struct SSdbOpt {
@ -279,7 +279,7 @@ int32_t sdbDeploy(SSdb *pSdb);
* @param pSdb The sdb object.
* @return int32_t 0 for success, -1 for failure.
*/
int32_t sdbPrepare(SSdb *pSdb);
int32_t sdbAfterRestored(SSdb *pSdb);
/**
* @brief Load sdb from file.

View File

@ -127,7 +127,7 @@ int32_t sdbSetTable(SSdb *pSdb, SSdbTable table) {
pSdb->deployFps[sdbType] = table.deployFp;
pSdb->encodeFps[sdbType] = table.encodeFp;
pSdb->decodeFps[sdbType] = table.decodeFp;
pSdb->prepareFps[sdbType] = table.prepareFp;
pSdb->afterRestoredFps[sdbType] = table.afterRestoredFp;
pSdb->validateFps[sdbType] = table.validateFp;
int32_t hashType = 0;

View File

@ -48,12 +48,12 @@ static int32_t sdbDeployData(SSdb *pSdb) {
return 0;
}
static int32_t sdbPrepareData(SSdb *pSdb) {
static int32_t sdbAfterRestoredData(SSdb *pSdb) {
int32_t code = 0;
mInfo("start to prepare sdb");
for (int32_t i = SDB_MAX - 1; i >= 0; --i) {
SdbPrepareFp fp = pSdb->prepareFps[i];
SdbAfterRestoredFp fp = pSdb->afterRestoredFps[i];
if (fp == NULL) continue;
mInfo("start to prepare sdb:%s", sdbTableName(i));
@ -666,9 +666,9 @@ int32_t sdbDeploy(SSdb *pSdb) {
return 0;
}
int32_t sdbPrepare(SSdb *pSdb) {
int32_t sdbAfterRestored(SSdb *pSdb) {
int32_t code = 0;
code = sdbPrepareData(pSdb);
code = sdbAfterRestoredData(pSdb);
if (code != 0) {
TAOS_RETURN(code);
}

View File

@ -327,7 +327,7 @@ struct SVnodeCfg {
int16_t hashSuffix;
int32_t tsdbPageSize;
int32_t tdbEncryptAlgorithm;
char tdbEncryptKey[ENCRYPT_KEY_LEN];
char tdbEncryptKey[ENCRYPT_KEY_LEN + 1];
int32_t s3ChunkSize;
int32_t s3KeepLocal;
int8_t s3Compact;

View File

@ -104,7 +104,7 @@ int32_t tsdbOpenFile(const char *path, STsdb *pTsdb, int32_t flag, STsdbFD **ppF
}
pFD->path = (char *)&pFD[1];
tstrncpy(pFD->path, path, strlen(path) + 1);
memcpy(pFD->path, path, strlen(path) + 1);
pFD->szPage = szPage;
pFD->flag = flag;
pFD->szPage = szPage;

View File

@ -330,7 +330,7 @@ static int32_t vnodeAsyncInit(SVAsync **async, const char *label) {
return terrno;
}
tstrncpy((char *)((*async) + 1), label, strlen(label) + 1);
memcpy((char *)((*async) + 1), label, strlen(label) + 1);
(*async)->label = (const char *)((*async) + 1);
(void)taosThreadMutexInit(&(*async)->mutex, NULL);

View File

@ -303,7 +303,7 @@ int vnodeDecodeConfig(const SJson *pJson, void *pObj) {
if (tsEncryptKey[0] == 0) {
return terrno = TSDB_CODE_DNODE_INVALID_ENCRYPTKEY;
} else {
tstrncpy(pCfg->tdbEncryptKey, tsEncryptKey, ENCRYPT_KEY_LEN);
tstrncpy(pCfg->tdbEncryptKey, tsEncryptKey, ENCRYPT_KEY_LEN + 1);
}
}
#endif

View File

@ -417,7 +417,7 @@ SVnode *vnodeOpen(const char *path, int32_t diskPrimary, STfs *pTfs, SMsgCb msgC
}
pVnode->path = (char *)&pVnode[1];
tstrncpy(pVnode->path, path, strlen(path) + 1);
memcpy(pVnode->path, path, strlen(path) + 1);
pVnode->config = info.config;
pVnode->state.committed = info.state.committed;
pVnode->state.commitTerm = info.state.commitTerm;

View File

@ -497,6 +497,8 @@ typedef struct SCtgAsyncFps {
ctgDumpTaskResFp dumpResFp;
ctgCompTaskFp compFp;
ctgCloneTaskResFp cloneFp;
int32_t subTaskFactor; // to indicate how many sub tasks this task will generate by ctgLaunchSubTask
// default to 1, means no sub task, 2 means 1 sub task, 3 means 2 sub tasks...
} SCtgAsyncFps;
typedef struct SCtgApiStat {

View File

@ -861,6 +861,16 @@ int32_t ctgInitJob(SCatalog* pCtg, SRequestConnInfo* pConn, SCtgJob** job, const
int32_t taskNum = tbMetaNum + dbVgNum + udfNum + tbHashNum + qnodeNum + dnodeNum + svrVerNum + dbCfgNum + indexNum +
userNum + dbInfoNum + tbIndexNum + tbCfgNum + tbTagNum + viewNum + tbTsmaNum + tbNameNum;
int32_t taskNumWithSubTasks = tbMetaNum * gCtgAsyncFps[CTG_TASK_GET_TB_META].subTaskFactor + dbVgNum * gCtgAsyncFps[CTG_TASK_GET_DB_VGROUP].subTaskFactor +
udfNum * gCtgAsyncFps[CTG_TASK_GET_UDF].subTaskFactor + tbHashNum * gCtgAsyncFps[CTG_TASK_GET_TB_HASH].subTaskFactor +
qnodeNum * gCtgAsyncFps[CTG_TASK_GET_QNODE].subTaskFactor + dnodeNum * gCtgAsyncFps[CTG_TASK_GET_DNODE].subTaskFactor +
svrVerNum * gCtgAsyncFps[CTG_TASK_GET_SVR_VER].subTaskFactor + dbCfgNum * gCtgAsyncFps[CTG_TASK_GET_DB_CFG].subTaskFactor +
indexNum * gCtgAsyncFps[CTG_TASK_GET_INDEX_INFO].subTaskFactor + userNum * gCtgAsyncFps[CTG_TASK_GET_USER].subTaskFactor +
dbInfoNum * gCtgAsyncFps[CTG_TASK_GET_DB_INFO].subTaskFactor + tbIndexNum * gCtgAsyncFps[CTG_TASK_GET_TB_SMA_INDEX].subTaskFactor +
tbCfgNum * gCtgAsyncFps[CTG_TASK_GET_TB_CFG].subTaskFactor + tbTagNum * gCtgAsyncFps[CTG_TASK_GET_TB_TAG].subTaskFactor +
viewNum * gCtgAsyncFps[CTG_TASK_GET_VIEW].subTaskFactor + tbTsmaNum * gCtgAsyncFps[CTG_TASK_GET_TB_TSMA].subTaskFactor +
tsmaNum * gCtgAsyncFps[CTG_TASK_GET_TSMA].subTaskFactor + tbNameNum * gCtgAsyncFps[CTG_TASK_GET_TB_NAME].subTaskFactor;
*job = taosMemoryCalloc(1, sizeof(SCtgJob));
if (NULL == *job) {
ctgError("failed to calloc, size:%d,QID:0x%" PRIx64, (int32_t)sizeof(SCtgJob), pConn->requestId);
@ -905,7 +915,7 @@ int32_t ctgInitJob(SCatalog* pCtg, SRequestConnInfo* pConn, SCtgJob** job, const
}
#endif
pJob->pTasks = taosArrayInit(taskNum, sizeof(SCtgTask));
pJob->pTasks = taosArrayInit(taskNumWithSubTasks, sizeof(SCtgTask));
if (NULL == pJob->pTasks) {
ctgError("taosArrayInit %d tasks failed", taskNum);
CTG_ERR_JRET(terrno);
@ -4178,27 +4188,27 @@ int32_t ctgCloneDbVg(SCtgTask* pTask, void** pRes) {
}
SCtgAsyncFps gCtgAsyncFps[] = {
{ctgInitGetQnodeTask, ctgLaunchGetQnodeTask, ctgHandleGetQnodeRsp, ctgDumpQnodeRes, NULL, NULL},
{ctgInitGetDnodeTask, ctgLaunchGetDnodeTask, ctgHandleGetDnodeRsp, ctgDumpDnodeRes, NULL, NULL},
{ctgInitGetDbVgTask, ctgLaunchGetDbVgTask, ctgHandleGetDbVgRsp, ctgDumpDbVgRes, ctgCompDbVgTasks, ctgCloneDbVg},
{ctgInitGetDbCfgTask, ctgLaunchGetDbCfgTask, ctgHandleGetDbCfgRsp, ctgDumpDbCfgRes, NULL, NULL},
{ctgInitGetDbInfoTask, ctgLaunchGetDbInfoTask, ctgHandleGetDbInfoRsp, ctgDumpDbInfoRes, NULL, NULL},
{ctgInitGetQnodeTask, ctgLaunchGetQnodeTask, ctgHandleGetQnodeRsp, ctgDumpQnodeRes, NULL, NULL, 1},
{ctgInitGetDnodeTask, ctgLaunchGetDnodeTask, ctgHandleGetDnodeRsp, ctgDumpDnodeRes, NULL, NULL, 1},
{ctgInitGetDbVgTask, ctgLaunchGetDbVgTask, ctgHandleGetDbVgRsp, ctgDumpDbVgRes, ctgCompDbVgTasks, ctgCloneDbVg, 1},
{ctgInitGetDbCfgTask, ctgLaunchGetDbCfgTask, ctgHandleGetDbCfgRsp, ctgDumpDbCfgRes, NULL, NULL, 1},
{ctgInitGetDbInfoTask, ctgLaunchGetDbInfoTask, ctgHandleGetDbInfoRsp, ctgDumpDbInfoRes, NULL, NULL, 1},
{ctgInitGetTbMetaTask, ctgLaunchGetTbMetaTask, ctgHandleGetTbMetaRsp, ctgDumpTbMetaRes, ctgCompTbMetaTasks,
ctgCloneTbMeta},
{ctgInitGetTbHashTask, ctgLaunchGetTbHashTask, ctgHandleGetTbHashRsp, ctgDumpTbHashRes, NULL, NULL},
{ctgInitGetTbIndexTask, ctgLaunchGetTbIndexTask, ctgHandleGetTbIndexRsp, ctgDumpTbIndexRes, NULL, NULL},
{ctgInitGetTbCfgTask, ctgLaunchGetTbCfgTask, ctgHandleGetTbCfgRsp, ctgDumpTbCfgRes, NULL, NULL},
{ctgInitGetIndexTask, ctgLaunchGetIndexTask, ctgHandleGetIndexRsp, ctgDumpIndexRes, NULL, NULL},
{ctgInitGetUdfTask, ctgLaunchGetUdfTask, ctgHandleGetUdfRsp, ctgDumpUdfRes, NULL, NULL},
{ctgInitGetUserTask, ctgLaunchGetUserTask, ctgHandleGetUserRsp, ctgDumpUserRes, NULL, NULL},
{ctgInitGetSvrVerTask, ctgLaunchGetSvrVerTask, ctgHandleGetSvrVerRsp, ctgDumpSvrVer, NULL, NULL},
{ctgInitGetTbMetasTask, ctgLaunchGetTbMetasTask, ctgHandleGetTbMetasRsp, ctgDumpTbMetasRes, NULL, NULL},
{ctgInitGetTbHashsTask, ctgLaunchGetTbHashsTask, ctgHandleGetTbHashsRsp, ctgDumpTbHashsRes, NULL, NULL},
{ctgInitGetTbTagTask, ctgLaunchGetTbTagTask, ctgHandleGetTbTagRsp, ctgDumpTbTagRes, NULL, NULL},
{ctgInitGetViewsTask, ctgLaunchGetViewsTask, ctgHandleGetViewsRsp, ctgDumpViewsRes, NULL, NULL},
{ctgInitGetTbTSMATask, ctgLaunchGetTbTSMATask, ctgHandleGetTbTSMARsp, ctgDumpTbTSMARes, NULL, NULL},
{ctgInitGetTSMATask, ctgLaunchGetTSMATask, ctgHandleGetTSMARsp, ctgDumpTSMARes, NULL, NULL},
{ctgInitGetTbNamesTask, ctgLaunchGetTbNamesTask, ctgHandleGetTbNamesRsp, ctgDumpTbNamesRes, NULL, NULL},
ctgCloneTbMeta, 1},
{ctgInitGetTbHashTask, ctgLaunchGetTbHashTask, ctgHandleGetTbHashRsp, ctgDumpTbHashRes, NULL, NULL, 1},
{ctgInitGetTbIndexTask, ctgLaunchGetTbIndexTask, ctgHandleGetTbIndexRsp, ctgDumpTbIndexRes, NULL, NULL, 1},
{ctgInitGetTbCfgTask, ctgLaunchGetTbCfgTask, ctgHandleGetTbCfgRsp, ctgDumpTbCfgRes, NULL, NULL, 2},
{ctgInitGetIndexTask, ctgLaunchGetIndexTask, ctgHandleGetIndexRsp, ctgDumpIndexRes, NULL, NULL, 1},
{ctgInitGetUdfTask, ctgLaunchGetUdfTask, ctgHandleGetUdfRsp, ctgDumpUdfRes, NULL, NULL, 1},
{ctgInitGetUserTask, ctgLaunchGetUserTask, ctgHandleGetUserRsp, ctgDumpUserRes, NULL, NULL, 2},
{ctgInitGetSvrVerTask, ctgLaunchGetSvrVerTask, ctgHandleGetSvrVerRsp, ctgDumpSvrVer, NULL, NULL, 1},
{ctgInitGetTbMetasTask, ctgLaunchGetTbMetasTask, ctgHandleGetTbMetasRsp, ctgDumpTbMetasRes, NULL, NULL, 1},
{ctgInitGetTbHashsTask, ctgLaunchGetTbHashsTask, ctgHandleGetTbHashsRsp, ctgDumpTbHashsRes, NULL, NULL, 1},
{ctgInitGetTbTagTask, ctgLaunchGetTbTagTask, ctgHandleGetTbTagRsp, ctgDumpTbTagRes, NULL, NULL, 2},
{ctgInitGetViewsTask, ctgLaunchGetViewsTask, ctgHandleGetViewsRsp, ctgDumpViewsRes, NULL, NULL, 1},
{ctgInitGetTbTSMATask, ctgLaunchGetTbTSMATask, ctgHandleGetTbTSMARsp, ctgDumpTbTSMARes, NULL, NULL, 1},
{ctgInitGetTSMATask, ctgLaunchGetTSMATask, ctgHandleGetTSMARsp, ctgDumpTSMARes, NULL, NULL, 1},
{ctgInitGetTbNamesTask, ctgLaunchGetTbNamesTask, ctgHandleGetTbNamesRsp, ctgDumpTbNamesRes, NULL, NULL, 1},
};
int32_t ctgMakeAsyncRes(SCtgJob* pJob) {

View File

@ -611,7 +611,12 @@ static void resetProjectNullType(SNode* pStmt) {
resetProjectNullTypeImpl(((SSelectStmt*)pStmt)->pProjectionList);
break;
case QUERY_NODE_SET_OPERATOR: {
resetProjectNullTypeImpl(((SSetOperator*)pStmt)->pProjectionList);
SSetOperator* pSetOp = (SSetOperator*)pStmt;
resetProjectNullTypeImpl(pSetOp->pProjectionList);
if (pSetOp->pLeft)
resetProjectNullType(pSetOp->pLeft);
if (pSetOp->pRight)
resetProjectNullType(pSetOp->pRight);
break;
}
default:

View File

@ -2270,6 +2270,7 @@ static bool dataTypeEqual(const SDataType* l, const SDataType* r) {
// 0 means equal, 1 means the left shall prevail, -1 means the right shall prevail
static int32_t dataTypeComp(const SDataType* l, const SDataType* r) {
if (l->type == TSDB_DATA_TYPE_NULL) return -1;
if (l->type != r->type) {
return 1;
}

View File

@ -236,6 +236,7 @@ typedef struct SFltBuildGroupCtx {
SFilterInfo *info;
SArray *group;
int32_t code;
bool ignore;
} SFltBuildGroupCtx;
typedef struct {
@ -266,6 +267,7 @@ struct SFilterInfo {
int8_t *blkUnitRes;
void *pTable;
SArray *blkList;
bool isStrict;
SFilterPCtx pctx;
};

View File

@ -21,6 +21,8 @@ extern "C" {
#include "query.h"
#include "tcommon.h"
#include "thash.h"
#include "querynodes.h"
#include "function.h"
typedef struct SOperatorValueType {
int32_t opResType;
@ -147,6 +149,8 @@ int32_t vectorCompareImpl(SScalarParam* pLeft, SScalarParam* pRight, SScalarPara
int32_t _ord, int32_t optr);
int32_t vectorCompare(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *pOut, int32_t _ord, int32_t optr);
bool checkOperatorRestypeIsTimestamp(EOperatorType opType, int32_t ldt, int32_t rdt);
#ifdef __cplusplus
}
#endif

View File

@ -13,6 +13,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <tlog.h>
#include "nodes.h"
#include "os.h"
#include "tglobal.h"
#include "thash.h"
@ -1284,7 +1285,8 @@ static void filterFreeGroup(void *pItem) {
taosMemoryFreeClear(p->unitFlags);
}
int32_t fltAddGroupUnitFromNode(SFilterInfo *info, SNode *tree, SArray *group) {
int32_t fltAddGroupUnitFromNode(void *pContext, SFilterInfo *info, SNode *tree, SArray *group) {
SFltBuildGroupCtx *ctx = (SFltBuildGroupCtx *)pContext;
SOperatorNode *node = (SOperatorNode *)tree;
int32_t ret = TSDB_CODE_SUCCESS;
SFilterFieldId left = {0}, right = {0};
@ -1305,6 +1307,7 @@ int32_t fltAddGroupUnitFromNode(SFilterInfo *info, SNode *tree, SArray *group) {
out.columnData->info.type = type;
out.columnData->info.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes; // reserved space for simple_copy
int32_t overflowCount = 0;
for (int32_t i = 0; i < listNode->pNodeList->length; ++i) {
SValueNode *valueNode = (SValueNode *)cell->pNode;
if (valueNode->node.resType.type != type) {
@ -1317,6 +1320,7 @@ int32_t fltAddGroupUnitFromNode(SFilterInfo *info, SNode *tree, SArray *group) {
if (overflow) {
cell = cell->pNext;
++overflowCount;
continue;
}
@ -1357,6 +1361,9 @@ int32_t fltAddGroupUnitFromNode(SFilterInfo *info, SNode *tree, SArray *group) {
cell = cell->pNext;
}
if(overflowCount == listNode->pNodeList->length) {
ctx->ignore = true;
}
colDataDestroy(out.columnData);
taosMemoryFree(out.columnData);
FLT_ERR_RET(code);
@ -1692,10 +1699,17 @@ EDealRes fltTreeToGroup(SNode *pNode, void *pContext) {
FLT_ERR_RET(terrno);
}
SFltBuildGroupCtx tctx = {.info = ctx->info, .group = newGroup};
SFltBuildGroupCtx tctx = {.info = ctx->info, .group = newGroup, .ignore = false};
nodesWalkExpr(cell->pNode, fltTreeToGroup, (void *)&tctx);
FLT_ERR_JRET(tctx.code);
if(tctx.ignore) {
ctx->ignore = true;
taosArrayDestroyEx(newGroup, filterFreeGroup);
newGroup = NULL;
taosArrayDestroyEx(resGroup, filterFreeGroup);
resGroup = NULL;
break;
}
FLT_ERR_JRET(filterDetachCnfGroups(resGroup, preGroup, newGroup));
taosArrayDestroyEx(newGroup, filterFreeGroup);
@ -1707,9 +1721,10 @@ EDealRes fltTreeToGroup(SNode *pNode, void *pContext) {
cell = cell->pNext;
}
if (NULL == taosArrayAddAll(ctx->group, preGroup)) {
FLT_ERR_JRET(terrno);
if (!ctx->ignore) {
if (NULL == taosArrayAddAll(ctx->group, preGroup)) {
FLT_ERR_JRET(terrno);
}
}
taosArrayDestroy(preGroup);
@ -1721,6 +1736,9 @@ EDealRes fltTreeToGroup(SNode *pNode, void *pContext) {
SListCell *cell = node->pParameterList->pHead;
for (int32_t i = 0; i < node->pParameterList->length; ++i) {
nodesWalkExpr(cell->pNode, fltTreeToGroup, (void *)pContext);
if(ctx->ignore) {
ctx->ignore = false;
}
FLT_ERR_JRET(ctx->code);
cell = cell->pNext;
@ -1735,7 +1753,7 @@ EDealRes fltTreeToGroup(SNode *pNode, void *pContext) {
}
if (QUERY_NODE_OPERATOR == nType) {
FLT_ERR_JRET(fltAddGroupUnitFromNode(ctx->info, pNode, ctx->group));
FLT_ERR_JRET(fltAddGroupUnitFromNode(ctx, ctx->info, pNode, ctx->group));
return DEAL_RES_IGNORE_CHILD;
}
@ -3831,13 +3849,21 @@ int32_t fltInitFromNode(SNode *tree, SFilterInfo *info, uint32_t options) {
goto _return;
}
SFltBuildGroupCtx tctx = {.info = info, .group = group};
SFltBuildGroupCtx tctx = {.info = info, .group = group, .ignore = false};
nodesWalkExpr(tree, fltTreeToGroup, (void *)&tctx);
if (TSDB_CODE_SUCCESS != tctx.code) {
taosArrayDestroyEx(group, filterFreeGroup);
code = tctx.code;
goto _return;
}
if (tctx.ignore) {
FILTER_SET_FLAG(info->status, FI_STATUS_EMPTY);
}
if (FILTER_EMPTY_RES(info)) {
info->func = filterExecuteImplEmpty;
taosArrayDestroyEx(group, filterFreeGroup);
return TSDB_CODE_SUCCESS;
}
code = filterConvertGroupFromArray(info, group);
if (TSDB_CODE_SUCCESS != code) {
taosArrayDestroyEx(group, filterFreeGroup);
@ -3871,7 +3897,7 @@ int32_t fltInitFromNode(SNode *tree, SFilterInfo *info, uint32_t options) {
_return:
if (code) {
qInfo("init from node failed, code:%d", code);
qInfo("init from node failed, code:%d, %s", code, tstrerror(code));
}
return code;
}
@ -4561,8 +4587,7 @@ int32_t filterGetTimeRange(SNode *pNode, STimeWindow *win, bool *isStrict) {
FLT_ERR_JRET(fltSclGetTimeStampDatum(endPt, &end));
win->skey = start.i;
win->ekey = end.i;
if(optNode->opType == OP_TYPE_IN) *isStrict = false;
else *isStrict = true;
*isStrict = info->isStrict;
goto _return;
} else if (taosArrayGetSize(points) == 0) {
*win = TSWINDOW_DESC_INITIALIZER;
@ -5026,7 +5051,8 @@ int32_t fltSclBuildRangePoints(SFltSclOperator *oper, SArray *points) {
}
// TODO: process DNF composed of CNF
int32_t fltSclProcessCNF(SArray *sclOpListCNF, SArray *colRangeList) {
static int32_t fltSclProcessCNF(SFilterInfo *pInfo, SArray *sclOpListCNF, SArray *colRangeList) {
pInfo->isStrict = true;
size_t sz = taosArrayGetSize(sclOpListCNF);
for (int32_t i = 0; i < sz; ++i) {
SFltSclOperator *sclOper = taosArrayGet(sclOpListCNF, i);
@ -5049,10 +5075,16 @@ int32_t fltSclProcessCNF(SArray *sclOpListCNF, SArray *colRangeList) {
taosArrayDestroy(colRange->points);
taosArrayDestroy(points);
colRange->points = merged;
if(merged->size == 0) {
return TSDB_CODE_SUCCESS;
}
} else {
taosArrayDestroy(colRange->points);
colRange->points = points;
}
if (sclOper->type == OP_TYPE_IN) {
pInfo->isStrict = false;
}
}
return TSDB_CODE_SUCCESS;
}
@ -5154,7 +5186,7 @@ int32_t fltOptimizeNodes(SFilterInfo *pInfo, SNode **pNode, SFltTreeStat *pStat)
if (NULL == colRangeList) {
FLT_ERR_JRET(terrno);
}
FLT_ERR_JRET(fltSclProcessCNF(sclOpList, colRangeList));
FLT_ERR_JRET(fltSclProcessCNF(pInfo, sclOpList, colRangeList));
pInfo->sclCtx.fltSclRange = colRangeList;
for (int32_t i = 0; i < taosArrayGetSize(sclOpList); ++i) {

View File

@ -1695,15 +1695,12 @@ static int32_t sclGetMathOperatorResType(SOperatorNode *pOp) {
if ((TSDB_DATA_TYPE_TIMESTAMP == ldt.type && TSDB_DATA_TYPE_TIMESTAMP == rdt.type) ||
TSDB_DATA_TYPE_VARBINARY == ldt.type || TSDB_DATA_TYPE_VARBINARY == rdt.type ||
(TSDB_DATA_TYPE_TIMESTAMP == ldt.type && (IS_VAR_DATA_TYPE(rdt.type) || IS_FLOAT_TYPE(rdt.type))) ||
(TSDB_DATA_TYPE_TIMESTAMP == rdt.type && (IS_VAR_DATA_TYPE(ldt.type) || IS_FLOAT_TYPE(ldt.type)))) {
(TSDB_DATA_TYPE_TIMESTAMP == ldt.type && (IS_VAR_DATA_TYPE(rdt.type))) ||
(TSDB_DATA_TYPE_TIMESTAMP == rdt.type && (IS_VAR_DATA_TYPE(ldt.type)))) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
if ((TSDB_DATA_TYPE_TIMESTAMP == ldt.type && IS_INTEGER_TYPE(rdt.type)) ||
(TSDB_DATA_TYPE_TIMESTAMP == rdt.type && IS_INTEGER_TYPE(ldt.type)) ||
(TSDB_DATA_TYPE_TIMESTAMP == ldt.type && TSDB_DATA_TYPE_BOOL == rdt.type) ||
(TSDB_DATA_TYPE_TIMESTAMP == rdt.type && TSDB_DATA_TYPE_BOOL == ldt.type)) {
if (checkOperatorRestypeIsTimestamp(pOp->opType, ldt.type, rdt.type)) {
pOp->node.resType.type = TSDB_DATA_TYPE_TIMESTAMP;
pOp->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_TIMESTAMP].bytes;
} else {

View File

@ -24,6 +24,7 @@
#include "tcompare.h"
#include "tdatablock.h"
#include "tdataformat.h"
#include "tdef.h"
#include "ttime.h"
#include "ttypes.h"
#include "geosWrapper.h"
@ -1262,12 +1263,7 @@ int32_t vectorMathAdd(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *p
SColumnInfoData *pRightCol = NULL;
SCL_ERR_JRET(vectorConvertVarToDouble(pLeft, &leftConvert, &pLeftCol));
SCL_ERR_JRET(vectorConvertVarToDouble(pRight, &rightConvert, &pRightCol));
if ((GET_PARAM_TYPE(pLeft) == TSDB_DATA_TYPE_TIMESTAMP && IS_INTEGER_TYPE(GET_PARAM_TYPE(pRight))) ||
(GET_PARAM_TYPE(pRight) == TSDB_DATA_TYPE_TIMESTAMP && IS_INTEGER_TYPE(GET_PARAM_TYPE(pLeft))) ||
(GET_PARAM_TYPE(pLeft) == TSDB_DATA_TYPE_TIMESTAMP && GET_PARAM_TYPE(pRight) == TSDB_DATA_TYPE_BOOL) ||
(GET_PARAM_TYPE(pRight) == TSDB_DATA_TYPE_TIMESTAMP &&
GET_PARAM_TYPE(pLeft) == TSDB_DATA_TYPE_BOOL)) { // timestamp plus duration
if(checkOperatorRestypeIsTimestamp(OP_TYPE_ADD, GET_PARAM_TYPE(pLeft), GET_PARAM_TYPE(pRight))) { // timestamp plus duration
int64_t *output = (int64_t *)pOutputCol->pData;
_getBigintValue_fn_t getVectorBigintValueFnLeft;
_getBigintValue_fn_t getVectorBigintValueFnRight;
@ -1399,9 +1395,7 @@ int32_t vectorMathSub(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *p
SCL_ERR_JRET(vectorConvertVarToDouble(pLeft, &leftConvert, &pLeftCol));
SCL_ERR_JRET(vectorConvertVarToDouble(pRight, &rightConvert, &pRightCol));
if ((GET_PARAM_TYPE(pLeft) == TSDB_DATA_TYPE_TIMESTAMP && GET_PARAM_TYPE(pRight) == TSDB_DATA_TYPE_BIGINT) ||
(GET_PARAM_TYPE(pRight) == TSDB_DATA_TYPE_TIMESTAMP &&
GET_PARAM_TYPE(pLeft) == TSDB_DATA_TYPE_BIGINT)) { // timestamp minus duration
if (checkOperatorRestypeIsTimestamp(OP_TYPE_SUB, GET_PARAM_TYPE(pLeft), GET_PARAM_TYPE(pRight))) { // timestamp minus duration
int64_t *output = (int64_t *)pOutputCol->pData;
_getBigintValue_fn_t getVectorBigintValueFnLeft;
_getBigintValue_fn_t getVectorBigintValueFnRight;
@ -2306,3 +2300,16 @@ _bin_scalar_fn_t getBinScalarOperatorFn(int32_t binFunctionId) {
return NULL;
}
}
bool checkOperatorRestypeIsTimestamp(EOperatorType opType, int32_t lType, int32_t rType) {
if (opType != OP_TYPE_ADD && opType != OP_TYPE_SUB && opType != OP_TYPE_MINUS) {
return false;
}
if ((TSDB_DATA_TYPE_TIMESTAMP == lType && IS_INTEGER_TYPE(rType) && rType != TSDB_DATA_TYPE_UBIGINT) ||
(TSDB_DATA_TYPE_TIMESTAMP == rType && IS_INTEGER_TYPE(lType) && lType != TSDB_DATA_TYPE_UBIGINT) ||
(TSDB_DATA_TYPE_TIMESTAMP == lType && TSDB_DATA_TYPE_BOOL == rType) ||
(TSDB_DATA_TYPE_TIMESTAMP == rType && TSDB_DATA_TYPE_BOOL == lType)) {
return true;
}
return false;
}

View File

@ -200,6 +200,7 @@ void streamTaskInitForLaunchHTask(SHistoryTaskInfo* pInfo);
void streamTaskSetRetryInfoForLaunch(SHistoryTaskInfo* pInfo);
int32_t streamTaskResetTimewindowFilter(SStreamTask* pTask);
void streamTaskClearActiveInfo(SActiveCheckpointInfo* pInfo);
int32_t streamTaskAddIntoNodeUpdateList(SStreamTask* pTask, int32_t nodeId);
void streamClearChkptReadyMsg(SActiveCheckpointInfo* pActiveInfo);
EExtractDataCode streamTaskGetDataFromInputQ(SStreamTask* pTask, SStreamQueueItem** pInput, int32_t* numOfBlocks,
@ -243,6 +244,8 @@ int32_t flushStateDataInExecutor(SStreamTask* pTask, SStreamQueueItem* pCheckpoi
int32_t streamCreateSinkResTrigger(SStreamTrigger** pTrigger);
int32_t streamCreateForcewindowTrigger(SStreamTrigger** pTrigger, int32_t trigger, SInterval* pInterval,
STimeWindow* pLatestWindow, const char* id);
// inject stream errors
void chkptFailedByRetrieveReqToSource(SStreamTask* pTask, int64_t checkpointId);
// inject stream errors
void chkptFailedByRetrieveReqToSource(SStreamTask* pTask, int64_t checkpointId);

View File

@ -21,7 +21,6 @@
#define CHECK_NOT_RSP_DURATION 10 * 1000 // 10 sec
static void processDownstreamReadyRsp(SStreamTask* pTask);
static int32_t addIntoNodeUpdateList(SStreamTask* pTask, int32_t nodeId);
static void rspMonitorFn(void* param, void* tmrId);
static void streamTaskInitTaskCheckInfo(STaskCheckInfo* pInfo, STaskOutputInfo* pOutputInfo, int64_t startTs);
static int32_t streamTaskStartCheckDownstream(STaskCheckInfo* pInfo, const char* id);
@ -226,13 +225,13 @@ int32_t streamTaskProcessCheckRsp(SStreamTask* pTask, const SStreamTaskCheckRsp*
stError("s-task:%s vgId:%d self vnode-transfer/leader-change/restart detected, old stage:%" PRId64
", current stage:%" PRId64 ", not check wait for downstream task nodeUpdate, and all tasks restart",
id, pRsp->upstreamNodeId, pRsp->oldStage, pTask->pMeta->stage);
code = addIntoNodeUpdateList(pTask, pRsp->upstreamNodeId);
code = streamTaskAddIntoNodeUpdateList(pTask, pRsp->upstreamNodeId);
} else {
stError(
"s-task:%s downstream taskId:0x%x (vgId:%d) not leader, self dispatch epset needs to be updated, not check "
"downstream again, nodeUpdate needed",
id, pRsp->downstreamTaskId, pRsp->downstreamNodeId);
code = addIntoNodeUpdateList(pTask, pRsp->downstreamNodeId);
code = streamTaskAddIntoNodeUpdateList(pTask, pRsp->downstreamNodeId);
}
streamMetaAddFailedTaskSelf(pTask, now);
@ -373,11 +372,10 @@ void processDownstreamReadyRsp(SStreamTask* pTask) {
}
}
int32_t addIntoNodeUpdateList(SStreamTask* pTask, int32_t nodeId) {
int32_t streamTaskAddIntoNodeUpdateList(SStreamTask* pTask, int32_t nodeId) {
int32_t vgId = pTask->pMeta->vgId;
int32_t code = 0;
;
bool existed = false;
bool existed = false;
streamMutexLock(&pTask->lock);
@ -675,8 +673,8 @@ void handleTimeoutDownstreamTasks(SStreamTask* pTask, SArray* pTimeoutList) {
SDownstreamStatusInfo* p = NULL;
findCheckRspStatus(pInfo, *pTaskId, &p);
if (p != NULL) {
code = addIntoNodeUpdateList(pTask, p->vgId);
stDebug("s-task:%s vgId:%d downstream task:0x%x (vgId:%d) timeout more than 100sec, add into nodeUpate list",
code = streamTaskAddIntoNodeUpdateList(pTask, p->vgId);
stDebug("s-task:%s vgId:%d downstream task:0x%x (vgId:%d) timeout more than 100sec, add into nodeUpdate list",
id, vgId, p->taskId, p->vgId);
}
}
@ -717,7 +715,7 @@ void handleNotReadyDownstreamTask(SStreamTask* pTask, SArray* pNotReadyList) {
// the action of add status may incur the restart procedure, which should NEVER be executed in the timer thread.
// The restart of all tasks requires that all tasks should not have active timer for now. Therefore, the execution
// of restart in timer thread will result in a dead lock.
// of restart in timer thread will result in a deadlock.
int32_t addDownstreamFailedStatusResultAsync(SMsgCb* pMsgCb, int32_t vgId, int64_t streamId, int32_t taskId) {
return streamTaskSchedTask(pMsgCb, vgId, streamId, taskId, STREAM_EXEC_T_ADD_FAILED_TASK);
}

View File

@ -1552,7 +1552,6 @@ static bool setDispatchRspInfo(SDispatchMsgInfo* pMsgInfo, int32_t vgId, int32_t
int32_t* pFailed, const char* id) {
int32_t numOfRsp = 0;
int32_t numOfFailed = 0;
bool allRsp = false;
int32_t numOfDispatchBranch = taosArrayGetSize(pMsgInfo->pSendInfo);
@ -1639,6 +1638,7 @@ int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, i
int32_t notRsp = 0;
int32_t numOfFailed = 0;
bool triggerDispatchRsp = false;
bool addFailure = false;
SActiveCheckpointInfo* pInfo = pTask->chkInfo.pActiveInfo;
int64_t tmpCheckpointId = -1;
int32_t tmpTranId = -1;
@ -1698,6 +1698,7 @@ int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, i
} else {
if (pRsp->inputStatus == TASK_INPUT_STATUS__REFUSED) {
// todo handle the role-changed during checkpoint generation, add test case
addFailure = true;
stError(
"s-task:%s downstream task:0x%x(vgId:%d) refused the dispatch msg, downstream may become follower or "
"restart already, treat it as success",
@ -1745,6 +1746,11 @@ int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, i
msgId, pRsp->downstreamTaskId, pRsp->downstreamNodeId, pRsp->inputStatus, tstrerror(code));
}
if (addFailure) { // add failure downstream node id, and start the nodeEp update procedure
// ignore the return error and continue
int32_t unused = streamTaskAddIntoNodeUpdateList(pTask, pRsp->downstreamNodeId);
}
// all msg rsp already, continue
// we need to re-try send dispatch msg to downstream tasks
if (allRsp && (numOfFailed == 0)) {
@ -1866,6 +1872,11 @@ int32_t streamProcessDispatchMsg(SStreamTask* pTask, SStreamDispatchReq* pReq, S
}
}
#if 0
// inject errors, and always refuse the upstream dispatch msg and trigger the task nodeEpset update trans.
status = TASK_INPUT_STATUS__REFUSED;
#endif
{
// do send response with the input status
int32_t code = buildDispatchRsp(pTask, pReq, status, &pRsp->pCont);

View File

@ -1089,6 +1089,10 @@
,,n,system-test,python3 ./test.py -f 5-taos-tools/taosbenchmark/insertMix.py -N 3
,,n,system-test,python3 ./test.py -f 5-taos-tools/taosbenchmark/stt.py -N 3
,,n,system-test,python3 ./test.py -f eco-system/meta/database/keep_time_offset.py
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/operator.py
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/operator.py -Q 2
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/operator.py -Q 3
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/operator.py -Q 4
,,y,system-test,./pytest.sh python3 ./test.py -f eco-system/manager/schema_change.py -N 3 -M 3
#tsim test

View File

@ -254,5 +254,7 @@ if $rows <= 0 then
return -1
endi
system taos -P7100 -d db -s " show create table db.t0"
system sh/exec.sh -n dnode1 -s stop -x SIGINT
system sh/exec.sh -n dnode2 -s stop -x SIGINT

View File

@ -41,8 +41,9 @@ class TDTestCase:
]
self.time_unit = ['b','u','a','s','m','h','d','w']
self.symbol = ['+','-','*','/']
self.error_values = [1.5,'abc','"abc"','!@','today()']
self.error_values = ['abc','"abc"','!@','today()']
self.db_percision = ['ms','us','ns']
self.test_values = [1.5, 10]
def tbtype_check(self,tb_type):
if tb_type == 'normal table' or tb_type == 'child table':
tdSql.checkRows(len(self.values_list))
@ -71,6 +72,9 @@ class TDTestCase:
self.tbtype_check(tb_type)
for i in range(len(self.values_list)):
tdSql.checkData(i,0,None)
for param in self.test_values:
tdSql.query(f'select now() {symbol}{param} from {tbname}')
tdSql.query(f'select 1 {symbol}{param} from {tbname}')
def now_check_ntb(self):
for time_unit in self.db_percision:

View File

@ -18,7 +18,7 @@ class TDTestCase:
self.today_ts = datetime.datetime.strptime(datetime.datetime.now().strftime("%Y-%m-%d"), "%Y-%m-%d").timestamp()
self.today_ts_ns = 0
self.time_unit = ['b','u','a','s','m','h','d','w']
self.error_param = ['1.5','abc','!@#','"abc"','today()']
self.error_param = ['abc','!@#','"abc"','today()']
self.arithmetic_operators = ['+','-','*','/']
self.relational_operator = ['<','<=','=','>=','>']
# prepare data

View File

@ -0,0 +1,347 @@
from wsgiref.headers import tspecials
from util.log import *
from util.cases import *
from util.sql import *
from util.common import tdCom
import numpy as np
class TDTestCase:
def init(self, conn, logSql, replicaVar=1):
self.replicaVar = int(replicaVar)
tdLog.debug("start to execute %s" % __file__)
tdSql.init(conn.cursor())
self.dbname = "db"
self.rowNum = 10
self.ts = 1537146000000
# test in/not in contidion with invalid value
def ts5757(self):
tdSql.execute(f"create database if not exists {self.dbname}")
tdSql.execute(f"DROP STABLE IF EXISTS {self.dbname}.super_t1;")
tdSql.execute(f"DROP TABLE IF EXISTS {self.dbname}.t1;")
tdSql.execute(f"CREATE STABLE IF NOT EXISTS {self.dbname}.super_t1(time TIMESTAMP, c0 BIGINT UNSIGNED) TAGS (location BINARY(64))")
tdSql.execute(f"CREATE TABLE {self.dbname}.t1 USING {self.dbname}.super_t1 TAGS ('ek')")
tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c0) VALUES (1641024000000, 1);")
tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c0) VALUES (1641024005000, 2);")
tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c0) VALUES (1641024010000, NULL);")
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NOT NULL AND c0 IN (-1);")
tdSql.checkRows(0)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NULL AND c0 IN (-1);")
tdSql.checkRows(0)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NOT NULL AND c0 IN (-1, 1);")
tdSql.checkRows(1)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NULL AND c0 IN (2, -1, 1);")
tdSql.checkRows(0)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NOT NULL AND c0 NOT IN (-1);")
tdSql.checkRows(2)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NULL AND c0 NOT IN (-1);")
tdSql.checkRows(0)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NULL AND c0 NOT IN (3);")
tdSql.checkRows(0)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NOT NULL AND c0 NOT IN (-1, 1);")
tdSql.checkRows(1)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NULL AND c0 NOT IN (2, -1, 1);")
tdSql.checkRows(0)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE (c0 IS NULL AND c0 IN (-1)) or c0 in(1)")
tdSql.checkRows(1)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NOT NULL OR c0 IN (-1);")
tdSql.checkRows(2)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NULL OR c0 IN (-1);")
tdSql.checkRows(1)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NOT NULL OR c0 IN (-1, 1);")
tdSql.checkRows(2)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NULL OR c0 IN (2, -1, 1);")
tdSql.checkRows(3)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NOT NULL OR c0 NOT IN (-1);")
tdSql.checkRows(2)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NULL OR c0 NOT IN (-1);")
tdSql.checkRows(3)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NULL OR c0 NOT IN (3);")
tdSql.checkRows(3)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NOT NULL OR c0 NOT IN (-1, 1);")
tdSql.checkRows(2)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NOT NULL OR c0 NOT IN (-1);")
tdSql.checkRows(2)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NULL OR c0 NOT IN (2, -1, 1);")
tdSql.checkRows(1)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE ((c0 is NULL) AND (c0 in (-1)) )")
tdSql.checkRows(0)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE ((c0 in (-1)) AND (c0 is NULL) )")
tdSql.checkRows(0)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE ((c0 in (-1)) AND (c0 is NULL) ) OR c0 in(1)")
tdSql.checkRows(1)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IN (-1);")
tdSql.checkRows(0)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NOT NULL;")
tdSql.checkRows(2)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IN (-1) or c0 in(1);")
tdSql.checkRows(1)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IN (1) or c0 in(-1);")
tdSql.checkRows(1)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IN (-1) or c0 in(-1);")
tdSql.checkRows(0)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IN (-1) and c0 in(1);")
tdSql.checkRows(0)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IN (1) and c0 in(-1);")
tdSql.checkRows(0)
tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IN (-1) and c0 in(-1);")
tdSql.checkRows(0)
def ts5760(self):
tdSql.execute(f"create database if not exists {self.dbname}")
tdSql.execute(f"DROP TABLE IF EXISTS {self.dbname}.t1;")
tdSql.execute(f"CREATE TABLE {self.dbname}.t1( time TIMESTAMP, c0 INT);")
tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c0) VALUES (1641024000000, 1);")
tdSql.query(f"SELECT time, c0 FROM {self.dbname}.t1 WHERE (time - c0) > 0;")
tdSql.checkRows(1)
tdSql.query(f"SELECT time, c0 FROM {self.dbname}.t1 WHERE (time + c0) > 0;")
tdSql.checkRows(1)
tdSql.query(f"SELECT time, c0 FROM {self.dbname}.t1 WHERE (-(- c0)) > 0;")
tdSql.checkRows(1)
tdSql.query(f"SELECT time, c0 FROM {self.dbname}.t1 WHERE -(- c0) > 0;")
tdSql.checkRows(1)
tdSql.query(f"SELECT time, c0 FROM {self.dbname}.t1 WHERE -(- c0) < 0;")
tdSql.checkRows(0)
tdSql.query(f"SELECT time, c0 FROM {self.dbname}.t1 WHERE -(- c0) = 0;")
tdSql.checkRows(0)
tdSql.query(f"SELECT time, c0 FROM {self.dbname}.t1 WHERE (- c0) > 0;")
tdSql.checkRows(0)
tdSql.query(f"SELECT time, c0 FROM {self.dbname}.t1 WHERE (- c0) < 0;")
tdSql.checkRows(1)
tdSql.query(f"SELECT time, c0 FROM {self.dbname}.t1 WHERE (time + (- c0)) > 0;")
tdSql.checkRows(1)
tdSql.query(f"SELECT time, c0 FROM {self.dbname}.t1 WHERE (time + (- c0)) > 0;")
tdSql.checkRows(1)
tdSql.query(f"SELECT time, c0 FROM {self.dbname}.t1 WHERE (time - (- (- c0)) ) > 0;")
tdSql.checkRows(1)
tdSql.query(f"SELECT time, c0 FROM {self.dbname}.t1 WHERE (time + (-(- c0))) > 0;")
tdSql.checkRows(1)
def ts5758(self):
tdSql.execute(f"create database if not exists {self.dbname}")
tdSql.execute(f"DROP TABLE IF EXISTS {self.dbname}.t1;")
tdSql.execute(f"CREATE TABLE {self.dbname}.t1( time TIMESTAMP, c1 BIGINT);")
tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c1) VALUES (1641024000000, 0);")
tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c1) VALUES (1641024000001, 1);")
tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c1) VALUES (1641024000002, 2);")
tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c1) VALUES (1641024000003, 3);")
tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c1) VALUES (1641024000004, 4);")
tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c1) VALUES (1641024000005, 5);")
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time IN (1) AND time BETWEEN (1741024000000) AND (1741024000000);")
tdSql.checkRows(0)
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time BETWEEN (1741024000000) AND (1741024000000) AND time IN (1);")
tdSql.checkRows(0)
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time IN (1) and time BETWEEN (1741024000000) AND (1741024000000) AND time IN (1);")
tdSql.checkRows(0)
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time IN (1641024000000) and time BETWEEN (1741024000000) AND (1741024000000) AND time IN (1);")
tdSql.checkRows(0)
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time IN (1) AND time BETWEEN (1641024000000) AND (1741024000000);")
tdSql.checkRows(0)
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time IN (1641024000001) AND time BETWEEN (1641024000000) AND (1741024000000);")
tdSql.checkRows(1)
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time IN (1641024000001, 1641024000002, 1641024000003) AND time BETWEEN (1641024000000) AND (1741024000000);")
tdSql.checkRows(3)
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time IN (1641024000001, 1641024000002, 1641024000005) AND time BETWEEN (1641024000000) AND (1641024000004);")
tdSql.checkRows(2)
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time IN (1) OR time = 1741024000000;")
tdSql.checkRows(0)
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time = 1741024000000 OR time IN (1);")
tdSql.checkRows(0)
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time IN (1, 2, 3) OR time BETWEEN (1641024000000) and (1741024000000);")
tdSql.checkRows(6)
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time IN (1, 2, 3) OR time = 1641024000000;")
tdSql.checkRows(1)
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time = 1641024000001 OR time BETWEEN (1641024000000) and (1641024000002);")
tdSql.checkRows(3)
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time = 1641024000004 OR time BETWEEN (1641024000000) and (1641024000002);")
tdSql.checkRows(4)
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time = 1641024000001 OR time = 1741024000000;")
tdSql.checkRows(1)
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time IN (1641024000001, 1641024000002) OR time = 1741024000000;")
tdSql.checkRows(2)
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time IN (1641024000001, 1641024000002) OR time BETWEEN (1641024000000) and (1741024000000);")
tdSql.checkRows(6)
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE (time = 1641024000004 OR time BETWEEN (1641024000000) and (1641024000002)) and time in(1);")
tdSql.checkRows(0)
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE (time = 1641024000004 OR time BETWEEN (1641024000000) and (1641024000002)) and time in(1641024000004, 1641024000002);")
tdSql.checkRows(2)
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE (time = 1641024000004 OR time BETWEEN (1641024000000) and (1641024000002)) or time in(1);")
tdSql.checkRows(4)
def ts5759(self):
tdSql.execute(f"create database if not exists {self.dbname}")
tdSql.execute(f"DROP TABLE IF EXISTS {self.dbname}.t1;")
tdSql.execute(f"CREATE TABLE {self.dbname}.t1( time TIMESTAMP, c1 BIGINT);")
tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c1) VALUES (1641024000000, 0);")
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001)")
tdSql.checkRows(1)
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) OR (1 < 2)")
tdSql.checkRows(1)
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) OR (3 < 2)")
tdSql.checkRows(1)
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) and (1 < 2)")
tdSql.checkRows(1)
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) OR (1 > 2)")
tdSql.checkRows(1)
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) and (1 > 2)")
tdSql.checkRows(0)
tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c1) VALUES (1641024000001, 1);")
tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c1) VALUES (1641024000002, 2);")
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) OR (1 < 2)")
tdSql.checkRows(3)
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) OR (1 > 2)")
tdSql.checkRows(2)
tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) and (1 < 2)")
tdSql.checkRows(2)
def operOnTime(self):
tdSql.execute(f"create database if not exists {self.dbname}")
tdSql.execute(f"DROP TABLE IF EXISTS {self.dbname}.t1;")
tdSql.execute(f"CREATE TABLE {self.dbname}.t1( ts TIMESTAMP, c0 INT, c1 INT UNSIGNED, \
c2 BIGINT, c3 BIGINT UNSIGNED, c4 SMALLINT, c5 SMALLINT UNSIGNED, c6 TINYINT, c7 TINYINT UNSIGNED);")
tdSql.execute(f"INSERT INTO {self.dbname}.t1 VALUES (1641024000001, 1, 1, 1, 1, 1, 1, 1, 1);")
columns = ["c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7"]
for col in columns:
tdLog.debug(f"oper on time test, {col} start ...")
tdSql.query(f"SELECT ts, ts+1, ts+{col}, ts+(-{col}) FROM {self.dbname}.t1")
tdSql.checkRows(1)
tdSql.checkData(0, 0, 1641024000001)
tdSql.checkData(0, 1, 1641024000002)
tdSql.checkData(0, 2, 1641024000002)
tdSql.checkData(0, 3, 1641024000000)
tdSql.query(f"SELECT ts, ts+1, ts+{col}, ts+(-{col}) FROM {self.dbname}.t1 where (ts-(-{col})) > 0")
tdSql.checkRows(1)
tdSql.checkData(0, 0, 1641024000001)
tdSql.checkData(0, 1, 1641024000002)
tdSql.checkData(0, 2, 1641024000002)
tdSql.checkData(0, 3, 1641024000000)
tdSql.query(f"SELECT ts, ts-1, ts-{col}, ts-(-{col}) FROM {self.dbname}.t1")
tdSql.checkRows(1)
tdSql.checkData(0, 0, 1641024000001)
tdSql.checkData(0, 1, 1641024000000)
tdSql.checkData(0, 2, 1641024000000)
tdSql.checkData(0, 3, 1641024000002)
tdSql.query(f"SELECT ts, ts+true, ts-true, ts-false, ts+false FROM {self.dbname}.t1")
tdSql.checkRows(1)
tdSql.checkData(0, 0, 1641024000001)
tdSql.checkData(0, 1, 1641024000002)
tdSql.checkData(0, 2, 1641024000000)
tdSql.checkData(0, 3, 1641024000001)
tdSql.checkData(0, 4, 1641024000001)
tdSql.execute(f"DROP TABLE IF EXISTS {self.dbname}.t2;")
tdSql.execute(f"CREATE TABLE {self.dbname}.t2( ts TIMESTAMP, c1 float, c2 double);")
tdSql.execute(f"INSERT INTO {self.dbname}.t2(ts, c1, c2) VALUES (1641024000001, 1.0, 1.0);")
columns = ["c1", "c2"]
for col in columns:
tdSql.query(f"SELECT ts, ts+{col}, ts+(-{col}), ts-{col}, ts-(-{col}) FROM {self.dbname}.t2")
tdSql.checkRows(1)
tdSql.checkData(0, 0, 1641024000001)
tdSql.checkData(0, 1, 1641024000002)
tdSql.checkData(0, 2, 1641024000000)
tdSql.checkData(0, 3, 1641024000000)
tdSql.checkData(0, 4, 1641024000002)
tdSql.query(f"SELECT ts, ts+{col}, ts+(-{col}), ts-{col}, ts-(-{col}) FROM {self.dbname}.t2 where (ts-(-{col})) > 0")
tdSql.checkRows(1)
tdSql.checkData(0, 0, 1641024000001)
tdSql.checkData(0, 1, 1641024000002)
tdSql.checkData(0, 2, 1641024000000)
tdSql.checkData(0, 3, 1641024000000)
tdSql.checkData(0, 4, 1641024000002)
tdSql.query(f"SELECT ts, cast(ts+{col} as bigint), cast(ts+(-{col}) as bigint), cast(ts-{col} as bigint),\
cast(ts-(-{col}) as bigint) FROM {self.dbname}.t2")
tdSql.checkRows(1)
tdSql.checkData(0, 0, 1641024000001)
tdSql.checkData(0, 1, 1641024000002)
tdSql.checkData(0, 2, 1641024000000)
tdSql.checkData(0, 3, 1641024000000)
tdSql.checkData(0, 4, 1641024000002)
tdSql.query(f"SELECT sum(ts + c1), sum(ts+c2) from {self.dbname}.t2")
tdSql.checkData(0, 0, 1641024000002)
tdSql.checkData(0, 1, 1641024000002)
tdSql.query(f"SELECT sum(ts * c1), sum(ts*c2) from {self.dbname}.t2")
tdSql.checkData(0, 0, 1641024000001)
tdSql.checkData(0, 1, 1641024000001)
tdSql.query(f"SELECT sum(ts / c1), sum(ts/c2) from {self.dbname}.t2")
tdSql.checkData(0, 0, 1641024000001)
tdSql.checkData(0, 1, 1641024000001)
tdSql.execute(f"INSERT INTO {self.dbname}.t2(ts, c1, c2) VALUES (1641024000002, 2.0, 2.0);")
tdSql.query(f"SELECT sum(ts + c1), sum(ts+c2) from {self.dbname}.t2")
tdSql.checkData(0, 0, 3282048000006)
tdSql.checkData(0, 1, 3282048000006)
tdSql.query(f"SELECT sum(ts - c1), sum(ts-c2) from {self.dbname}.t2")
tdSql.checkData(0, 0, 3282048000000)
tdSql.checkData(0, 1, 3282048000000)
tdSql.query(f"SELECT sum(ts * c1), sum(ts*c2) from {self.dbname}.t2")
tdSql.checkData(0, 0, 4923072000005)
tdSql.checkData(0, 1, 4923072000005)
tdSql.query(f"SELECT ts / c1, ts/c2 from {self.dbname}.t2 order by ts")
tdSql.checkData(0, 0, 1641024000001)
tdSql.checkData(0, 1, 1641024000001)
tdSql.checkData(1, 0, 820512000001)
tdSql.checkData(1, 1, 820512000001)
tdSql.query(f"SELECT sum(ts / c1), sum(ts/c2) from {self.dbname}.t2")
tdSql.checkData(0, 0, 2461536000002)
tdSql.checkData(0, 1, 2461536000002)
# data overflow
tdSql.query(f"SELECT ts + 9223372036854775807 from {self.dbname}.t2 order by ts")
tdSql.query(f"SELECT ts - 9223372036854775808 from {self.dbname}.t2 order by ts")
tdSql.query(f"SELECT ts + 8223372036854775807 from {self.dbname}.t2 order by ts")
tdSql.query(f"SELECT ts - 8223372036854775808 from {self.dbname}.t2 order by ts")
def run(self):
dbname = "db"
tdSql.prepare()
tdSql.execute(f"create database if not exists {self.dbname}")
self.ts5757()
self.ts5760()
self.ts5758()
self.ts5759()
self.operOnTime()
def stop(self):
tdSql.close()
tdLog.success("%s successfully executed" % __file__)
tdCases.addWindows(__file__, TDTestCase())
tdCases.addLinux(__file__, TDTestCase())

View File

@ -78,7 +78,7 @@ class TDTestCase:
)
# sqls.extend( f"select sum( {un_num_col} + {un_num_col_2} ) from {tbanme} " for un_num_col_2 in UN_NUM_COL )
sqls.extend( f"select sum( {num_col} + {ts_col} ) from {DBNAME}.{tbanme} " for num_col in NUM_COL for ts_col in TS_TYPE_COL)
#sqls.extend( f"select sum( {num_col} + {ts_col} ) from {DBNAME}.{tbanme} " for num_col in NUM_COL for ts_col in TS_TYPE_COL)
sqls.extend(
(
f"select sum() from {DBNAME}.{tbanme} ",

View File

@ -436,6 +436,29 @@ class TDTestCase:
tdSql.query(sql, queryTimes=1)
tdSql.checkRows(49)
sql = "select null union select null"
tdSql.query(sql, queryTimes=1)
tdSql.checkRows(1)
tdSql.checkData(0, 0, None)
sql = "select null union all select null"
tdSql.query(sql, queryTimes=1)
tdSql.checkRows(2)
tdSql.checkData(0, 0, None)
tdSql.checkData(1, 0, None)
sql = "select null union select 1"
tdSql.query(sql, queryTimes=1)
tdSql.checkRows(2)
tdSql.checkData(0, 0, None)
tdSql.checkData(1, 0, 1)
sql = "select null union select 'asd'"
tdSql.query(sql, queryTimes=1)
tdSql.checkRows(2)
tdSql.checkData(0, 0, None)
tdSql.checkData(1, 0, 'asd')
def stop(self):
tdSql.close()
tdLog.success(f"{__file__} successfully executed")