diff --git a/Jenkinsfile b/Jenkinsfile index 11095d64b0281c5e998c3d275a7e3eb71d6b64b2..495b1fb1adb122a5c59c2f4f964af758698b4598 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,9 +1,7 @@ import hudson.model.Result import hudson.model.*; import jenkins.model.CauseOfInterruption -properties([pipelineTriggers([githubPush()])]) node { - git url: 'https://github.com/taosdata/TDengine.git' } def skipbuild=0 @@ -194,6 +192,7 @@ def pre_test_win(){ } pipeline { agent none + options { skipDefaultCheckout() } environment{ WK = '/var/lib/jenkins/workspace/TDinternal' WKC= '/var/lib/jenkins/workspace/TDinternal/community' @@ -201,6 +200,7 @@ pipeline { stages { stage('pre_build'){ agent{label 'master'} + options { skipDefaultCheckout() } when{ changeRequest() } @@ -209,52 +209,51 @@ pipeline { abort_previous() abortPreviousBuilds() } - sh''' - rm -rf ${WORKSPACE}.tes - cp -r ${WORKSPACE} ${WORKSPACE}.tes - cd ${WORKSPACE}.tes - git fetch - ''' - script { - if (env.CHANGE_TARGET == 'master') { - sh ''' - git checkout master - ''' - } - else if(env.CHANGE_TARGET == '2.0'){ - sh ''' - git checkout 2.0 - ''' - } - else{ - sh ''' - git checkout develop - ''' - } - } - sh''' - git fetch origin +refs/pull/${CHANGE_ID}/merge - git checkout -qf FETCH_HEAD - ''' + // sh''' + // rm -rf ${WORKSPACE}.tes + // cp -r ${WORKSPACE} ${WORKSPACE}.tes + // cd ${WORKSPACE}.tes + // git fetch + // ''' + // script { + // if (env.CHANGE_TARGET == 'master') { + // sh ''' + // git checkout master + // ''' + // } + // else if(env.CHANGE_TARGET == '2.0'){ + // sh ''' + // git checkout 2.0 + // ''' + // } + // else{ + // sh ''' + // git checkout develop + // ''' + // } + // } + // sh''' + // git fetch origin +refs/pull/${CHANGE_ID}/merge + // git checkout -qf FETCH_HEAD + // ''' - script{ - skipbuild='2' - skipbuild=sh(script: "git log -2 --pretty=%B | fgrep -ie '[skip ci]' -e '[ci skip]' && echo 1 || echo 2", returnStdout:true) - println skipbuild - } - sh''' - rm -rf ${WORKSPACE}.tes - ''' + // script{ + // skipbuild='2' + // skipbuild=sh(script: "git log -2 --pretty=%B | fgrep -ie '[skip ci]' -e '[ci skip]' && echo 1 || echo 2", returnStdout:true) + // println skipbuild + // } + // sh''' + // rm -rf ${WORKSPACE}.tes + // ''' + // } } } stage('Parallel test stage') { //only build pr + options { skipDefaultCheckout() } when { allOf{ changeRequest() - expression{ - return skipbuild.trim() == '2' - } not{ expression { env.CHANGE_BRANCH =~ /docs\// }} } } @@ -262,7 +261,6 @@ pipeline { stage('python_1_s1') { agent{label " slave1 || slave11 "} steps { - pre_test() timeout(time: 55, unit: 'MINUTES'){ sh ''' @@ -415,7 +413,7 @@ pipeline { stage('test_b4_s7') { agent{label " slave7 || slave17 "} steps { - timeout(time: 55, unit: 'MINUTES'){ + timeout(time: 105, unit: 'MINUTES'){ pre_test() sh ''' date diff --git a/cmake/define.inc b/cmake/define.inc index a37fef8dfb4eff64bba7f4f3c853506a788fd328..bb6b285f268a6476c79fb599e76b1fd0435173b5 100755 --- a/cmake/define.inc +++ b/cmake/define.inc @@ -128,17 +128,25 @@ IF (TD_APLHINE) MESSAGE(STATUS "aplhine is defined") ENDIF () -IF (TD_LINUX) - IF (TD_ARM_32) - SET(TD_BUILD_HTTP TRUE) - ADD_DEFINITIONS(-DHTTP_EMBEDDED) - ELSE () - IF (TD_BUILD_HTTP) - ADD_DEFINITIONS(-DHTTP_EMBEDDED) +MESSAGE("before BUILD_HTTP: " ${BUILD_HTTP}) +IF ("${BUILD_HTTP}" STREQUAL "") + IF (TD_LINUX) + IF (TD_ARM_32) + SET(BUILD_HTTP "true") + ELSE () + SET(BUILD_HTTP "false") ENDIF () + ELSE () + SET(BUILD_HTTP "true") ENDIF () -ELSE () +ENDIF () +MESSAGE("after BUILD_HTTP: " ${BUILD_HTTP}) + +IF (${BUILD_HTTP} MATCHES "true") SET(TD_BUILD_HTTP TRUE) +ENDIF () + +IF (TD_BUILD_HTTP) ADD_DEFINITIONS(-DHTTP_EMBEDDED) ENDIF () diff --git a/cmake/input.inc b/cmake/input.inc index a6eaaa97898bbba5b4ba79fac35b0d96c6a9391f..5bd1a7bed6fe9b0c7dc51c46870d8109462eae81 100755 --- a/cmake/input.inc +++ b/cmake/input.inc @@ -92,10 +92,6 @@ ENDIF () SET(TD_BUILD_HTTP FALSE) -IF (${BUILD_HTTP} MATCHES "true") - SET(TD_BUILD_HTTP TRUE) -ENDIF () - SET(TD_MEMORY_SANITIZER FALSE) IF (${MEMORY_SANITIZER} MATCHES "true") SET(TD_MEMORY_SANITIZER TRUE) diff --git a/documentation20/cn/00.index/docs.md b/documentation20/cn/00.index/docs.md index 24654ed407ea121c627e0488888a455f9a858646..a16154443c96cfd31cbc7c5d4b49caf3ccbeab9e 100644 --- a/documentation20/cn/00.index/docs.md +++ b/documentation20/cn/00.index/docs.md @@ -131,7 +131,7 @@ TDengine是一个高效的存储、查询、分析时序大数据的平台,专 * [TDengine写入性能测试工具](https://www.taosdata.com/blog/2020/01/18/1166.html) * [IDEA数据库管理工具可视化使用TDengine](https://www.taosdata.com/blog/2020/08/27/1767.html) * [基于Electron开发的跨平台TDengine图形化管理工具](https://github.com/skye0207/TDengineGUI) -* [DataX,支持TDengine的离线数据采集/同步工具](https://github.com/wgzhao/DataX)(文档:[读取插件](https://github.com/wgzhao/DataX/blob/master/docs/src/main/sphinx/reader/tdenginereader.md)、[写入插件](https://github.com/wgzhao/DataX/blob/master/docs/src/main/sphinx/writer/tdenginewriter.md)) +* [基于DataX的TDeninge数据迁移工具](https://www.taosdata.com/blog/2021/10/26/3156.html) ## TDengine与其他数据库的对比测试 diff --git a/documentation20/cn/03.architecture/docs.md b/documentation20/cn/03.architecture/docs.md index 6afdfb7a7d50533e094e13195c21b223daf888d1..5eafea00c8ca84dff466d835e3016d5818e2a1d5 100644 --- a/documentation20/cn/03.architecture/docs.md +++ b/documentation20/cn/03.architecture/docs.md @@ -382,17 +382,17 @@ dataDir [path] 各级存储之间的数据流向:0 级存储 -> 1 级存储 -> 2 级存储。 同一存储等级可挂载多个硬盘,同一存储等级上的数据文件分布在该存储等级的所有硬盘上。 需要说明的是,数据在不同级别的存储介质上的移动,是由系统自动完成的,用户无需干预。 -- primary: 是否为主挂载点,0(是)或 1(否),省略默认为 1。 +- primary: 是否为主挂载点,0(否)或 1(是),省略默认为 1。 -在配置中,只允许一个主挂载点的存在(level=0, primary=0),例如采用如下的配置方式: +在配置中,只允许一个主挂载点的存在(level=0, primary=1),例如采用如下的配置方式: ``` -dataDir /mnt/data1 0 0 -dataDir /mnt/data2 0 1 -dataDir /mnt/data3 1 1 -dataDir /mnt/data4 1 1 -dataDir /mnt/data5 2 1 -dataDir /mnt/data6 2 1 +dataDir /mnt/data1 0 1 +dataDir /mnt/data2 0 0 +dataDir /mnt/data3 1 0 +dataDir /mnt/data4 1 0 +dataDir /mnt/data5 2 0 +dataDir /mnt/data6 2 0 ``` 注意: diff --git a/documentation20/cn/08.connector/docs.md b/documentation20/cn/08.connector/docs.md index bbac768316e47e34ea56107eed81416f518cd42a..b4543111b22008467ba749018fa2c19321f4f18e 100644 --- a/documentation20/cn/08.connector/docs.md +++ b/documentation20/cn/08.connector/docs.md @@ -405,45 +405,45 @@ typedef struct TAOS_MULTI_BIND { ### Schemaless 方式写入接口 -除了使用 SQL 方式或者使用参数绑定 API 写入数据外,还可以使用 Schemaless 的方式完成写入。Schemaless 可以免于预先创建超级表/数据子表的数据结构,而是可以直接写入数据,TDengine 系统会根据写入的数据内容自动创建和维护所需要的表结构。Schemaless 的使用方式详见 [Schemaless 写入](https://www.taosdata.com/cn/documentation/insert#schemaless) 章节,这里介绍与之配套使用的 C/C++ API。 - -2.2.0.0版本接口: -- `int taos_insert_lines(TAOS* taos, char* lines[], int numLines)` - - 以 Schemaless 格式写入多行数据。其中: - * taos:调用 taos_connect 返回的数据库连接。 - * lines:由 char 字符串指针组成的数组,指向本次想要写入数据库的多行数据。 - * numLines:lines 数据的总行数。 - - 返回值为 0 表示写入成功,非零值表示出错。具体错误代码请参见 [taoserror.h](https://github.com/taosdata/TDengine/blob/develop/src/inc/taoserror.h) 文件。 - - 说明: - 1. 此接口是一个同步阻塞式接口,使用时机与 `taos_query()` 一致。 - 2. 在调用此接口之前,必须先调用 `taos_select_db()` 来确定目前是在向哪个 DB 来写入。 - -2.3.0.0版本接口: -- `int taos_schemaless_insert(TAOS* taos, const char* lines[], int numLines, int protocol, const char* precision, int* affectedRows, char* msg, int msgBufLen)` - **参数说明** - taos: 数据库连接,通过taos_connect 函数建立的数据库连接。 - lines:文本数据。满足解析格式要求的无模式文本字符串。 - numLines:文本数据的行数,不能为 0 。 - protocol: 行协议类型,用于标识文本数据格式。 - precision:文本数据中的时间戳精度字符串。 - affectedRows:插入操作完成以后,正确写入到数据库中的记录行数。 - msg: 如果出现错误(函数返回值不为 0)情况下,错误提示信息。该参数是输入参数,需要用户指定消息输出缓冲区,如果不指定该缓冲区(输入为NULL),即使出现错误也不会得到错误提示信息。 - msgBufLen: 缓冲区的长度,避免错误提示消息越界。 - - **返回值** - 0:无错误发生。 - 非 0 值:发生了错误。此时可以通过msg获取错误信息的提示。该返回值含义可以参考taoserror.h文件中的错误码定义。 +除了使用 SQL 方式或者使用参数绑定 API 写入数据外,还可以使用 Schemaless 的方式完成写入。Schemaless 可以免于预先创建超级表/数据子表的数据结构,而是可以直接写入数据,TDengine 系统会根据写入的数据内容自动创建和维护所需要的表结构。Schemaless 的使用方式详见 [Schemaless 写入](https://www.taosdata.com/cn/documentation/insert#schemaless) 章节,这里介绍与之配套使用的 C/C++ API。 + +- `TAOS_RES* taos_schemaless_insert(TAOS* taos, const char* lines[], int numLines, int protocol, int precision)` - **说明** - 协议类型是枚举类型,包含以下三种格式: - SML_LINE_PROTOCOL:InfluxDB行协议(Line Protocol) - SML_TELNET_PROTOCOL: OpenTSDB文本行协议 - SML_JSON_PROTOCOL: OpenTSDB Json协议格式 + **功能说明** + 该接口将行协议的文本数据写入到TDengine中。 + + **参数说明** + taos: 数据库连接,通过taos_connect 函数建立的数据库连接。 + lines:文本数据。满足解析格式要求的无模式文本字符串。 + numLines:文本数据的行数,不能为 0 。 + protocol: 行协议类型,用于标识文本数据格式。 + precision:文本数据中的时间戳精度字符串。 + + **返回值** + TAOS_RES 结构体,应用可以通过使用 taos_errstr 获得错误信息,也可以使用 taos_errno 获得错误码。 + 在某些情况下,返回的 TAOS_RES 为 NULL,此时仍然可以调用 taos_errno 来安全地获得错误码信息。 + 返回的 TAOS_RES 需要调用方来负责释放,否则会出现内存泄漏。 + + **说明** + 协议类型是枚举类型,包含以下三种格式: + TSDB_SML_LINE_PROTOCOL:InfluxDB行协议(Line Protocol) + TSDB_SML_TELNET_PROTOCOL: OpenTSDB文本行协议 + TSDB_SML_JSON_PROTOCOL: OpenTSDB Json协议格式 + + 时间戳分辨率的定义,定义在 taos.h 文件中,具体内容如下: + TSDB_SML_TIMESTAMP_NOT_CONFIGURED = 0, + TSDB_SML_TIMESTAMP_HOURS, + TSDB_SML_TIMESTAMP_MINUTES, + TSDB_SML_TIMESTAMP_SECONDS, + TSDB_SML_TIMESTAMP_MILLI_SECONDS, + TSDB_SML_TIMESTAMP_MICRO_SECONDS, + TSDB_SML_TIMESTAMP_NANO_SECONDS - 时间戳分辨率的说明使用如下字符串:“h“ (小时)、”m“(分钟)、”s“ (秒) ”ms“(毫秒)、”u“ (微秒)、”ns”(纳秒),不区分大小写。需要注意的是,时间戳分辨率参数只在协议类型为 SML_LINE_PROTOCOL 的时候生效。对于 OpenTSDB的文本协议,时间戳的解析遵循其官方解析规则 — 按照时间戳包含的字符的数量来确认时间精度。 + 需要注意的是,时间戳分辨率参数只在协议类型为 SML_LINE_PROTOCOL 的时候生效。 + 对于 OpenTSDB 的文本协议,时间戳的解析遵循其官方解析规则 — 按照时间戳包含的字符的数量来确认时间精度。 + + **支持版本** + 该功能接口从2.3.0.0版本开始支持。 ```c #include @@ -454,10 +454,7 @@ int main() { const char* host = "127.0.0.1"; const char* user = "root"; const char* passwd = "taosdata"; - - // error message buffer - char msg[512] = {0}; - + // connect to server TAOS* taos = taos_connect(host, user, passwd, "test", 0); @@ -468,17 +465,18 @@ int main() { }; // schema-less insert - int code = taos_schemaless_insert(taos, lines1, 2, SML_LINE_PROTOCOL, "ns", msg, sizeof(msg)/sizeof(msg[0])); - if (code != 0) { - printf("failed to insert schema-less data, reason: %s\n", msg); + TAOS_RES* res = taos_schemaless_insert(taos, lines1, 2, TSDB_SML_LINE_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS); + if (taos_errno(res) != 0) { + printf("failed to insert schema-less data, reason: %s\n", taos_errstr(res)); } + taos_free_result(res); + // close the connection taos_close(taos); return (code); } ``` -**注**:后续2.2.0.0版本也更新成2.3.0.0版本的接口。 ### 连续查询接口 @@ -575,6 +573,14 @@ cd C:\TDengine\connector\python python -m pip install . ``` +**PyPI** + +从2.1.1版本开始,用户可以从[PyPI](https://pypi.org/project/taospy/)安装: + +```sh +pip install taospy +``` + * 如果机器上没有pip命令,用户可将src/connector/python下的taos文件夹拷贝到应用程序的目录使用。 对于windows 客户端,安装TDengine windows 客户端后,将C:\TDengine\driver\taos.dll拷贝到C:\windows\system32目录下即可。 @@ -610,6 +616,22 @@ python3 PythonChecker.py -host ### Python连接器的使用 +#### PEP-249 兼容API + +您可以像其他数据库一样,使用类似 [PEP-249](https://www.python.org/dev/peps/pep-0249/) 数据库API规范风格的API: + +```python +import taos + +conn = taos.connect() +cursor = conn.cursor() + +cursor.execute("show databases") +results = cursor.fetchall() +for row in results: + print(row) +``` + #### 代码示例 * 导入TDengine客户端模块 @@ -665,6 +687,44 @@ for data in c1: print("ts=%s, temperature=%d, humidity=%f" %(data[0], data[1],data[2])) ``` +* 从v2.1.0版本开始, 我们提供另外一种API:`connection.query` + + ```python + import taos + + conn = taos.connect() + conn.execute("create database if not exists pytest") + + result = conn.query("show databases") + num_of_fields = result.field_count + for field in result.fields: + print(field) + for row in result: + print(row) + conn.execute("drop database pytest") + ``` + + `query` 方法会返回一个 `TaosResult` 类对象,并提供了以下有用的属性或方法: + + 属性: + + - `fields`: `TaosFields` 集合类,提供返回数据的列信息。 + - `field_count`: 返回数据的列数. + - `affected_rows`: 插入数据的行数. + - `row_count`: 查询数据结果数. + - `precision`: 当前数据库的时间精度. + + 方法: + + - `fetch_all()`: 类似于 `cursor.fetchall()` 返回同样的集合数据 + - `fetch_all_into_dict()`: v2.1.1 新添加的API,将上面的数据转换成字典类型返回 + - `blocks_iter()` `rows_iter()`: 根据底层API提供的两种不同迭代器。 + - `fetch_rows_a`: 异步API + - `errno`: 错误码 + - `errstr`: 错误信息 + - `close`: 关闭结果对象,一般不需要直接调用 + + * 创建订阅 ```python diff --git a/documentation20/cn/12.taos-sql/02.udf/docs.md b/documentation20/cn/12.taos-sql/02.udf/docs.md index 454f650b111ac02f318c6f2bdd9bf8eb9b3f3e5d..5b068d43fda8d765c052582dc1bdda163d9d72e3 100644 --- a/documentation20/cn/12.taos-sql/02.udf/docs.md +++ b/documentation20/cn/12.taos-sql/02.udf/docs.md @@ -1,6 +1,6 @@ # UDF(用户定义函数) -在有些应用场景中,应用逻辑需要的查询无法直接使用系统内置的函数来表示。利用 UDF 功能,TDengine 可以插入用户编写的处理代码并在查询中使用它们,就能够很方便地解决特殊应用场景中的使用需求。 +在有些应用场景中,应用逻辑需要的查询无法直接使用系统内置的函数来表示。利用 UDF 功能,TDengine 可以插入用户编写的处理代码并在查询中使用它们,就能够很方便地解决特殊应用场景中的使用需求。 UDF 通常以数据表中的一列数据做为输入,同时支持以嵌套子查询的结果作为输入。 从 2.2.0.0 版本开始,TDengine 支持通过 C/C++ 语言进行 UDF 定义。接下来结合示例讲解 UDF 的使用方法。 @@ -9,76 +9,70 @@ TDengine 提供 3 个 UDF 的源代码示例,分别为: * [add_one.c](https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/add_one.c) * [abs_max.c](https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/abs_max.c) -* [sum_double.c](https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/sum_double.c) +* [demo.c](https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/demo.c) -### 无需中间变量的标量函数 +### 标量函数 -[add_one.c](https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/add_one.c) 是结构最简单的 UDF 实现。其功能为:对传入的一个数据列(可能因 WHERE 子句进行了筛选)中的每一项,都输出 +1 之后的值,并且要求输入的列数据类型为 INT。 +[add_one.c](https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/add_one.c) 是结构最简单的 UDF 实现。其功能为:对传入的一个数据列(可能因 WHERE 子句进行了筛选)中的每一项,都输出 +1 之后的值,并且要求输入的列数据类型为 INT。 -这一具体的处理逻辑在函数 `void add_one(char* data, short itype, short ibytes, int numOfRows, long long* ts, char* dataOutput, char* interBUf, char* tsOutput, int* numOfOutput, short otype, short obytes, SUdfInit* buf)` 中定义。这类用于实现 UDF 的基础计算逻辑的函数,我们称为 udfNormalFunc,也就是对行数据块的标量计算函数。需要注意的是,udfNormalFunc 的参数项是固定的,用于按照约束完成与引擎之间的数据交换。 +这一具体的处理逻辑在函数 `void add_one(char* data, short itype, short ibytes, int numOfRows, long long* ts, char* dataOutput, char* interBuf, char* tsOutput, int* numOfOutput, short otype, short obytes, SUdfInit* buf)` 中定义。这类用于实现 UDF 的基础计算逻辑的函数,我们称为 udfNormalFunc,也就是对行数据块的标量计算函数。需要注意的是,udfNormalFunc 的参数项是固定的,用于按照约束完成与引擎之间的数据交换。 - udfNormalFunc 中各参数的具体含义是: - * data:存有输入的数据。 + * data:输入数据。 * itype:输入数据的类型。这里采用的是短整型表示法,与各种数据类型对应的值可以参见 [column_meta 中的列类型说明](https://www.taosdata.com/cn/documentation/connector#column_meta)。例如 4 用于表示 INT 型。 * iBytes:输入数据中每个值会占用的字节数。 * numOfRows:输入数据的总行数。 - * ts:主键时间戳在输入中的列数据。 - * dataOutput:输出数据的缓冲区。 - * interBuf:系统使用的中间临时缓冲区,通常用户逻辑无需对 interBuf 进行处理。 - * tsOutput:主键时间戳在输出时的列数据。 - * numOfOutput:输出数据的个数。 + * ts:主键时间戳在输入中的列数据(只读)。 + * dataOutput:输出数据的缓冲区,缓冲区大小为用户指定的输出类型大小 * numOfRows。 + * interBuf:中间计算结果的缓冲区,大小为用户在创建 UDF 时指定的BUFSIZE大小。通常用于计算中间结果与最终结果不一致时使用,由引擎负责分配与释放。 + * tsOutput:主键时间戳在输出时的列数据,如果非空可用于输出结果对应的时间戳。 + * numOfOutput:输出结果的个数(行数)。 * oType:输出数据的类型。取值含义与 itype 参数一致。 - * oBytes:输出数据中每个值会占用的字节数。 - * buf:计算过程的中间变量缓冲区。 + * oBytes:输出数据中每个值占用的字节数。 + * buf:用于在 UDF 与引擎间的状态控制信息传递块。 -其中 buf 参数需要用到一个自定义结构体 SUdfInit。在这个例子中,因为 add_one 的计算过程无需用到中间变量缓存,所以可以把 SUdfInit 定义成一个空结构体。 -### 无需中间变量的聚合函数 +### 聚合函数 [abs_max.c](https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/abs_max.c) 实现的是一个聚合函数,功能是对一组数据按绝对值取最大值。 -其计算过程为:与所在查询语句相关的数据会被分为多个行数据块,对每个行数据块调用 udfNormalFunc(在本例的实现代码中,实际函数名是 `abs_max`),再将每个数据块的计算结果调用 udfMergeFunc(本例中,其实际的函数名是 `abs_max_merge`)进行聚合,生成每个子表的聚合结果。如果查询指令涉及超级表,那么最后还会通过 udfFinalizeFunc(本例中,其实际的函数名是 `abs_max_finalize`)再把子表的计算结果聚合为超级表的计算结果。 +其计算过程为:与所在查询语句相关的数据会被分为多个行数据块,对每个行数据块调用 udfNormalFunc(在本例的实现代码中,实际函数名是 `abs_max`)来生成每个子表的中间结果,再将子表的中间结果调用 udfMergeFunc(本例中,其实际的函数名是 `abs_max_merge`)进行聚合,生成超级表的最终聚合结果或中间结果。聚合查询最后还会通过 udfFinalizeFunc(本例中,其实际的函数名是 `abs_max_finalize`)再把超级表的中间结果处理为最终结果,最终结果只能含0或1条结果数据。 值得注意的是,udfNormalFunc、udfMergeFunc、udfFinalizeFunc 之间,函数名约定使用相同的前缀,此前缀即 udfNormalFunc 的实际函数名。udfMergeFunc 的函数名后缀 `_merge`、udfFinalizeFunc 的函数名后缀 `_finalize`,是 UDF 实现规则的一部分,系统会按照这些函数名后缀来调用相应功能。 -- udfMergeFunc 用于对计算中间结果进行聚合。本例中 udfMergeFunc 对应的实现函数为 `void abs_max_merge(char* data, int32_t numOfRows, char* dataOutput, int32_t* numOfOutput, SUdfInit* buf)`,其中各参数的具体含义是: - * data:udfNormalFunc 的输出组合在一起的数据,也就成为了 udfMergeFunc 的输入。 +- udfMergeFunc 用于对计算中间结果进行聚合,只有针对超级表的聚合查询才需要调用该函数。本例中 udfMergeFunc 对应的实现函数为 `void abs_max_merge(char* data, int32_t numOfRows, char* dataOutput, int32_t* numOfOutput, SUdfInit* buf)`,其中各参数的具体含义是: + * data:udfNormalFunc 的输出数据数组,如果使用了 interBuf 那么 data 就是 interBuf 的数组。 * numOfRows:data 中数据的行数。 - * dataOutput:输出数据的缓冲区。 - * numOfOutput:输出数据的个数。 - * buf:计算过程的中间变量缓冲区。 - -- udfFinalizeFunc 用于对计算结果进行最终聚合。本例中 udfFinalizeFunc 对应的实现函数为 `void abs_max_finalize(char* dataOutput, char* interBuf, int* numOfOutput, SUdfInit* buf)`,其中各参数的具体含义是: - * dataOutput:输出数据的缓冲区。对 udfFinalizeFunc 来说,其输入数据也来自于这里。 - * interBuf:系统使用的中间临时缓冲区,与 udfNormalFunc 中的同名参数含义一致。 - * numOfOutput:输出数据的个数。 - * buf:计算过程的中间变量缓冲区。 + * dataOutput:输出数据的缓冲区,大小等于一条最终结果的大小。如果此时输出还不是最终结果,可以选择输出到 interBuf 中即data中。 + * numOfOutput:输出结果的个数(行数)。 + * buf:用于在 UDF 与引擎间的状态控制信息传递块。 -同样因为 abs_max 的计算过程无需用到中间变量缓存,所以同样是可以把 SUdfInit 定义成一个空结构体。 - -### 使用中间变量的聚合函数 +- udfFinalizeFunc 用于对计算结果进行最终计算,通常用于有 interBuf 使用的场景。本例中 udfFinalizeFunc 对应的实现函数为 `void abs_max_finalize(char* dataOutput, char* interBuf, int* numOfOutput, SUdfInit* buf)`,其中各参数的具体含义是: + * dataOutput:输出数据的缓冲区。 + * interBuf:中间结算结果缓冲区,可作为输入。 + * numOfOutput:输出数据的个数,对聚合函数来说只能是0或者1。 + * buf:用于在 UDF 与引擎间的状态控制信息传递块。 -[sum_double.c](https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/sum_double.c) 也是一个聚合函数,功能是对一组数据输出求和结果的倍数。 -出于功能演示的目的,在这个用户定义函数的实现方法中,用到了中间变量缓冲区 buf。因此,在这个源代码文件中,SUdfInit 就不再是一个空的结构体,而是定义了缓冲区的具体存储内容。 +### 其他 UDF 函数 -也正是因为用到了中间变量缓冲区,因此就需要对这一缓冲区进行初始化和资源释放。具体来说,也即对应 udfInitFunc(本例中,其实际的函数名是 `sum_double_init`)和 udfDestroyFunc(本例中,其实际的函数名是 `sum_double_destroy`)。其函数名命名规则同样是采取以 udfNormalFunc 的实际函数名为前缀,以 `_init` 和 `_destroy` 为后缀。系统会在初始化和资源释放时调用对应名称的函数。 +用户 UDF 程序除了需要实现上面几个函数外,还有两个用于初始化和释放 UDF 与引擎间的状态控制信息传递块的函数。具体来说,也即对应 udfInitFunc 和 udfDestroyFunc。其函数名命名规则同样是采取以 udfNormalFunc 的实际函数名为前缀,以 `_init` 和 `_destroy` 为后缀。系统会在初始化和资源释放时调用对应名称的函数。 -- udfInitFunc 用于初始化中间变量缓冲区中的变量和内容。本例中 udfInitFunc 对应的实现函数为 `int sum_double_init(SUdfInit* buf)`,其中各参数的具体含义是: - * buf:计算过程的中间变量缓冲区。 +- udfInitFunc 用于初始化状态控制信息传递块。上例中 udfInitFunc 对应的实现函数为 `int abs_max_init(SUdfInit* buf)`,其中各参数的具体含义是: + * buf:用于在 UDF 与引擎间的状态控制信息传递块。 -- udfDestroyFunc 用于释放中间变量缓冲区中的变量和内容。本例中 udfDestroyFunc 对应的实现函数为 `void sum_double_destroy(SUdfInit* buf)`,其中各参数的具体含义是: - * buf:计算过程的中间变量缓冲区。 +- udfDestroyFunc 用于释放状态控制信息传递块。上例中 udfDestroyFunc 对应的实现函数为 `void abs_max_destroy(SUdfInit* buf)`,其中各参数的具体含义是: + * buf:用于在 UDF 与引擎间的状态控制信息传递块。 -注意,UDF 的实现过程中需要小心处理对中间变量缓冲区的使用,如果使用不当则有可能导致内存泄露或对资源的过度占用,甚至导致系统服务进程崩溃等。 +目前该功能暂时没有实际意义,待后续扩展使用。 ### UDF 实现方式的规则总结 -根据所要实现的 UDF 类型不同,用户所要实现的功能函数内容也会有所区别: -* 无需中间变量的标量函数:结构体 SUdfInit 可以为空,需实现 udfNormalFunc。 -* 无需中间变量的聚合函数:结构体 SUdfInit 可以为空,需实现 udfNormalFunc、udfMergeFunc、udfFinalizeFunc。 -* 使用中间变量的标量函数:结构体 SUdfInit 需要具体定义,并需实现 udfNormalFunc、udfInitFunc、udfDestroyFunc。 -* 使用中间变量的聚合函数:结构体 SUdfInit 需要具体定义,并需实现 udfNormalFunc、udfInitFunc、udfDestroyFunc、udfMergeFunc、udfFinalizeFunc。 +根据 UDF 函数类型的不同,用户所要实现的功能函数也不同: +* 标量函数:UDF 中需实现 udfNormalFunc。 +* 聚合函数:UDF 中需实现 udfNormalFunc、udfMergeFunc(对超级表查询)、udfFinalizeFunc。 + +需要注意的是,如果对应的函数不需要具体的功能,也需要实现一个空函数。 ## 编译 UDF @@ -97,28 +91,30 @@ gcc -g -O0 -fPIC -shared add_one.c -o add_one.so 用户可以通过 SQL 指令在系统中加载客户端所在主机上的 UDF 函数库(不能通过 RESTful 接口或 HTTP 管理界面来进行这一过程)。一旦创建成功,则当前 TDengine 集群的所有用户都可以在 SQL 指令中使用这些函数。UDF 存储在系统的 MNode 节点上,因此即使重启 TDengine 系统,已经创建的 UDF 也仍然可用。 -在创建 UDF 时,需要区分标量函数和聚合函数。如果创建时声明了错误的函数类别,则可能导致通过 SQL 指令调用函数时出错。 +在创建 UDF 时,需要区分标量函数和聚合函数。如果创建时声明了错误的函数类别,则可能导致通过 SQL 指令调用函数时出错。此外, UDF 支持输入与输出类型不一致,用户需要保证输入数据类型与 UDF 程序匹配,UDF 输出数据类型与 OUTPUTTYPE 匹配。 -- 创建标量函数:`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 文件),这个路径需要用英文单引号或英文双引号括起来; + * ids(Y):包含 UDF 函数实现的动态链接库的库文件绝对路径(指的是库文件在当前客户端所在主机上的保存路径,通常是指向一个 .so 文件),这个路径需要用英文单引号或英文双引号括起来; * typename(Z):此函数计算结果的数据类型,与上文中 udfNormalFunc 的 itype 参数不同,这里不是使用数字表示法,而是直接写类型名称即可; - * B:系统使用的中间临时缓冲区大小,单位是字节,最小 0,最大 512,通常可以设置为 128。 + * B:中间计算结果的缓冲区大小,单位是字节,最小 0,最大 512,如果不使用可以不设置。 例如,如下语句可以把 add_one.so 创建为系统中可用的 UDF: ```sql CREATE FUNCTION add_one AS "/home/taos/udf_example/add_one.so" OUTPUTTYPE INT; ``` -- 创建聚合函数:`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 文件),这个路径需要用英文单引号或英文双引号括起来; + * ids(Y):包含 UDF 函数实现的动态链接库的库文件绝对路径(指的是库文件在当前客户端所在主机上的保存路径,通常是指向一个 .so 文件),这个路径需要用英文单引号或英文双引号括起来; * typename(Z):此函数计算结果的数据类型,与上文中 udfNormalFunc 的 itype 参数不同,这里不是使用数字表示法,而是直接写类型名称即可; - * B:系统使用的中间临时缓冲区大小,单位是字节,最小 0,最大 512,通常可以设置为 128。 + * B:中间计算结果的缓冲区大小,单位是字节,最小 0,最大 512,如果不使用可以不设置。 - 例如,如下语句可以把 abs_max.so 创建为系统中可用的 UDF: + 关于中间计算结果的使用,可以参考示例程序[demo.c](https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/demo.c) + + 例如,如下语句可以把 demo.so 创建为系统中可用的 UDF: ```sql - CREATE AGGREGATE FUNCTION abs_max AS "/home/taos/udf_example/abs_max.so" OUTPUTTYPE BIGINT bufsize 128; + CREATE AGGREGATE FUNCTION demo AS "/home/taos/udf_example/demo.so" OUTPUTTYPE DOUBLE bufsize 14; ``` ### 管理 UDF @@ -140,7 +136,7 @@ SELECT X(c) FROM table/stable; 在当前版本下,使用 UDF 存在如下这些限制: 1. 在创建和调用 UDF 时,服务端和客户端都只支持 Linux 操作系统; -2. UDF 不能与系统内建的 SQL 函数混合使用; +2. UDF 不能与系统内建的 SQL 函数混合使用,暂不支持在一条 SQL 语句中使用多个不同名的 UDF ; 3. UDF 只支持以单个数据列作为输入; 4. UDF 只要创建成功,就会被持久化存储到 MNode 节点中; 5. 无法通过 RESTful 接口来创建 UDF; diff --git a/documentation20/cn/12.taos-sql/docs.md b/documentation20/cn/12.taos-sql/docs.md index cb3a87127323d32dc9654c5abbe7a1b5788e97c6..64020208abe45d589058414fb123d1616c67f2c7 100644 --- a/documentation20/cn/12.taos-sql/docs.md +++ b/documentation20/cn/12.taos-sql/docs.md @@ -1579,11 +1579,11 @@ SELECT function_list FROM stb_name CREATE TABLE meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT); ``` -针对智能电表采集的数据,以 10 分钟为一个阶段,计算过去 24 小时的电流数据的平均值、最大值、电流的中位数、以及随着时间变化的电流走势拟合直线。如果没有计算值,用前一个非 NULL 值填充。使用的查询语句如下: +针对智能电表采集的数据,以 10 分钟为一个阶段,计算过去 24 小时的电流数据的平均值、最大值、电流的中位数。如果没有计算值,用前一个非 NULL 值填充。使用的查询语句如下: ```mysql -SELECT AVG(current), MAX(current), LEASTSQUARES(current, start_val, step_val), PERCENTILE(current, 50) FROM meters - WHERE ts>=NOW-1d +SELECT AVG(current), MAX(current), APERCENTILE(current, 50) FROM meters + WHERE ts>=NOW-1d and ts<=now INTERVAL(10m) FILL(PREV); ``` diff --git a/documentation20/cn/13.faq/docs.md b/documentation20/cn/13.faq/docs.md index a3b60baca6d2927ba2015e5f734b2b4d569ac318..7483c972eebe26d0b010724ea699cd94906f382c 100644 --- a/documentation20/cn/13.faq/docs.md +++ b/documentation20/cn/13.faq/docs.md @@ -183,9 +183,10 @@ TDengine 中时间戳的时区总是由客户端进行处理,而与服务端 | TCP | 6035 | 多节点集群的节点间通讯。 | 随 serverPort 端口变化。 | | TCP | 6040 | 多节点集群的节点间数据同步。 | 随 serverPort 端口变化。 | | TCP | 6041 | 客户端与服务端之间的 RESTful 通讯。 | 随 serverPort 端口变化。 | -| TCP | 6042 | Arbitrator 的服务端口。 | 随 Arbitrator 启动参数设置变化。 | -| TCP | 6043 | 支持 collectd 数据接入端口。 | 随 BLM3 启动参数设置变化(2.3.0.1+以上版本)。 | -| TCP | 6044 | 支持 StatsD 的数据接入端口。 | 随 BLM3 启动参数设置变化(2.3.0.1+以上版本)。 | +| TCP | 6042 | Arbitrator 的服务端口。 | 随 Arbitrator 启动参数设置变化。 | +| TCP | 6043 | TaosKeeper 监控服务端口。 | 随 TaosKeeper 启动参数设置变化。 | +| TCP | 6044 | 支持 StatsD 的数据接入端口。 | 随 BLM3 启动参数设置变化(2.3.0.1+以上版本)。 | +| TCP | 6045 | 支持 collectd 数据接入端口。 | 随 BLM3 启动参数设置变化(2.3.0.1+以上版本)。 | | TCP | 6060 | 企业版内 Monitor 服务的网络端口。 | | | UDP | 6030-6034 | 客户端与服务端之间通讯。 | 随 serverPort 端口变化。 | | UDP | 6035-6039 | 多节点集群的节点间通讯。 | 随 serverPort 端口变化。 | @@ -193,12 +194,14 @@ TDengine 中时间戳的时区总是由客户端进行处理,而与服务端 ## 20. go 语言编写组件编译失败怎样解决? 新版本 TDengine 2.3.0.0 包含一个使用 go 语言开发的 BLM3 组件,取代之前内置的 httpd ,提供包含原 httpd 功能以及支持多种其他软件(Prometheus、Telegraf、collectd、StatsD等)的数据接入功能。 -使用最新 develop 分支代码编译需要先 git submodule update --init --recursive 下载 blm3 仓库代码后再编译。 +使用最新 develop 分支代码编译需要先 `git submodule update --init --recursive` 下载 blm3 仓库代码后再编译。 目前编译方式默认自动编译 blm3。go 语言版本要求 1.14 以上,如果发生 go 编译错误,往往是国内访问 go mod 问题,可以通过设置 go 环境变量来解决: + +```sh go env -w GO111MODULE=on go env -w GOPROXY=https://goproxy.cn,direct +``` 如果希望继续使用之前的内置 httpd,可以关闭 blm3 编译,使用 -cmake .. -DBUILD_HTTP=true 使用原来内置的 httpd。 - +`cmake .. -DBUILD_HTTP=true` 使用原来内置的 httpd。 diff --git a/documentation20/en/08.connector/docs.md b/documentation20/en/08.connector/docs.md index 57efd27dcc1b90775c7f2bfc6fbcbca57dc503ff..806bebd77738bd4251607237e3f88c589baa4741 100644 --- a/documentation20/en/08.connector/docs.md +++ b/documentation20/en/08.connector/docs.md @@ -419,19 +419,47 @@ or `pip3 install src/connector/python/` +You can install the `taospy` connector from [PyPI](https://pypi.org/project/taospy/): + +```sh +pip install taospy +``` + #### Windows -With Windows TDengine client installed, copy the file "C:\TDengine\driver\taos.dll" to the "C:\ windows\ system32" directory and enter the Windows cmd command line interface: +With Windows TDengine client installed, copy the file "C:\TDengine\driver\taos.dll" to the "C:\Windows\system32" directory and enter the Windows *cmd* command line interface: ```cmd cd C:\TDengine\connector\python python -m pip install . ``` +Or install from PyPI: + +```cmd +pip install taospy +``` + - If there is no `pip` command on the machine, the user can copy the taos folder under src/connector/python to the application directory for use. For Windows client, after installing the TDengine Windows client, copy C:\ TDengine\driver\taos.dll to the C:\ windows\ system32 directory. ### How to use +#### PEP-249 Python Database API + +Definitely you can use the [PEP-249](https://www.python.org/dev/peps/pep-0249/) database API like other type of databases: + +```python +import taos + +conn = taos.connect() +cursor = conn.cursor() + +cursor.execute("show databases") +results = cursor.fetchall() +for row in results: + print(row) +``` + #### Code sample - Import the TDengine client module @@ -488,6 +516,44 @@ for data in c1: print("ts=%s, temperature=%d, humidity=%f" %(data[0], data[1],data[2])) ``` +- Since v2.1.0, python connector provides a new API for query: + +```python +import taos + +conn = taos.connect() +conn.execute("create database if not exists pytest") + +result = conn.query("show databases") +num_of_fields = result.field_count +for field in result.fields: + print(field) +for row in result: + print(row) +conn.execute("drop database pytest") +``` + +The `query` method returns `TaosResult` class. It provides high level APIs for convenient use: + +Properties: + +- `fields`: the `TaosFields` object contains the column metadata, given the collection of each column field metadata by iterator. +- `field_count`: column number of result. +- `affected_rows`: the rows completed for insert. +- `row_count`: the rows number for select. +- `precision`: the result precision. + +Functions: + +- `fetch_all()`: get all data as tuple array. +- `fetch_all_into_dict()`: get all data as dict array, added since v2.1.1 +- `blocks_iter()`: provides iterator by C `taos_fetch_blocks` API +- `rows_iter()`: provides iterator by C `taos_fetch_row` API +- `fetch_rows_a`: fetch rows by async API in taosc. +- `errno`: error code if failed. +- `errstr`: error string if failed. +- `close`: close result, you do not need to call it directly, result will auto closed out of scope. + - Create subscription ```python @@ -510,6 +576,7 @@ for d in data: sub.close() ``` + - Close connection ```python diff --git a/packaging/docker/Dockerfile b/packaging/docker/Dockerfile index 629f8f9fd6a4167db6f30d29646263710602693a..c49bc0a8a356c960e27f3231c3e901de6d9a72ef 100644 --- a/packaging/docker/Dockerfile +++ b/packaging/docker/Dockerfile @@ -4,21 +4,19 @@ WORKDIR /root ARG pkgFile ARG dirName -RUN echo ${pkgFile} -RUN echo ${dirName} +RUN echo ${pkgFile} && echo ${dirName} COPY ${pkgFile} /root/ RUN tar -zxf ${pkgFile} WORKDIR /root/${dirName}/ RUN /bin/bash install.sh -e no -RUN apt-get clean && apt-get update && apt-get install -y locales -RUN locale-gen en_US.UTF-8 -ENV LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/lib" -ENV LC_CTYPE=en_US.UTF-8 -ENV LANG=en_US.UTF-8 -ENV LC_ALL=en_US.UTF-8 +RUN apt-get clean && apt-get update && apt-get install -y locales && locale-gen en_US.UTF-8 +ENV LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/lib" \ + LC_CTYPE=en_US.UTF-8 \ + LANG=en_US.UTF-8 \ + LC_ALL=en_US.UTF-8 EXPOSE 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 CMD ["taosd"] -VOLUME [ "/var/lib/taos", "/var/log/taos","/etc/taos/" ] +VOLUME [ "/var/lib/taos", "/var/log/taos","/etc/taos/" ] \ No newline at end of file diff --git a/packaging/release.sh b/packaging/release.sh index 705103a87a35a73b2a91079707785279416644cd..a827c9ea468277a9c33150447c71f5c93b30d45b 100755 --- a/packaging/release.sh +++ b/packaging/release.sh @@ -213,7 +213,7 @@ else exit 1 fi -make -j8 +make cd ${curr_dir} diff --git a/packaging/tools/make_install.sh b/packaging/tools/make_install.sh index 8015b8dfdc2ccfdc27026575abb6259594b793d9..7fbdbab1c798af572fc67cf79f27812ea64d3bae 100755 --- a/packaging/tools/make_install.sh +++ b/packaging/tools/make_install.sh @@ -395,8 +395,9 @@ function install_connector() { ${csudo} cp -rf ${source_dir}/src/connector/python ${install_main_dir}/connector ${csudo} cp ${binary_dir}/build/lib/*.jar ${install_main_dir}/connector &> /dev/null && ${csudo} chmod 777 ${install_main_dir}/connector/*.jar || echo &> /dev/null else - ${csudo} cp -rf ${source_dir}/src/connector/python ${install_main_dir}/connector || ${csudo} cp -rf ${source_dir}/src/connector/python ${install_main_2_dir}/connector} - ${csudo} cp ${binary_dir}/build/lib/*.jar ${install_main_dir}/connector &> /dev/null || cp ${binary_dir}/build/lib/*.jar ${install_main_2_dir}/connector &> /dev/null && ${csudo} chmod 777 ${install_main_dir}/connector/*.jar || ${csudo} chmod 777 ${install_main_2_dir}/connector/*.jar || echo &> /dev/null + ${csudo} cp -rf ${source_dir}/src/connector/python ${install_main_dir}/connector || ${csudo} cp -rf ${source_dir}/src/connector/python ${install_main_2_dir}/connector + ${csudo} cp ${binary_dir}/build/lib/*.jar ${install_main_dir}/connector &> /dev/null && ${csudo} chmod 777 ${install_main_dir}/connector/*.jar || echo &> /dev/null + ${csudo} cp ${binary_dir}/build/lib/*.jar ${install_main_2_dir}/connector &> /dev/null && ${csudo} chmod 777 ${install_main_2_dir}/connector/*.jar || echo &> /dev/null fi } diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 28515f6c63c98f741d84aa11f92b9ca9f7ad3691..47af7568642d0badccda51a28c09d321cf782571 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,5 +1,5 @@ name: tdengine -base: core18 +base: core20 version: '2.3.0.0' icon: snap/gui/t-dengine.svg summary: an open-source big data platform designed and optimized for IoT. @@ -39,14 +39,17 @@ parts: - taoswrapper.sh tdengine: + plugin: cmake source: . source-type: local - plugin: cmake build-packages: - gcc - g++ - make - cmake + cmake-parameters: + - -DCMAKE_BUILD_TYPE=Release + - -DBUILD_HTTP=true override-build: | snapcraftctl build if [ ! -d $SNAPCRAFT_STAGE/usr ]; then diff --git a/src/client/inc/tscParseLine.h b/src/client/inc/tscParseLine.h index bfc069c92cbfa8c92a889eee3536b4157b4452c3..f5db644a96d7d447ac6b5851b641e41f8745e98e 100644 --- a/src/client/inc/tscParseLine.h +++ b/src/client/inc/tscParseLine.h @@ -23,6 +23,8 @@ extern "C" { #define SML_TIMESTAMP_SECOND_DIGITS 10 #define SML_TIMESTAMP_MILLI_SECOND_DIGITS 13 +typedef TSDB_SML_PROTOCOL_TYPE SMLProtocolType; + typedef struct { char* key; uint8_t type; @@ -46,22 +48,16 @@ typedef struct { } TAOS_SML_DATA_POINT; typedef enum { - SML_TIME_STAMP_NOW, + SML_TIME_STAMP_NOT_CONFIGURED, SML_TIME_STAMP_HOURS, SML_TIME_STAMP_MINUTES, SML_TIME_STAMP_SECONDS, SML_TIME_STAMP_MILLI_SECONDS, SML_TIME_STAMP_MICRO_SECONDS, SML_TIME_STAMP_NANO_SECONDS, - SML_TIME_STAMP_NOT_CONFIGURED + SML_TIME_STAMP_NOW } SMLTimeStampType; -typedef enum { - SML_LINE_PROTOCOL = 0, - SML_TELNET_PROTOCOL = 1, - SML_JSON_PROTOCOL = 2, -} SMLProtocolType; - typedef struct { uint64_t id; SMLProtocolType protocol; @@ -71,6 +67,7 @@ typedef struct { int64_t affectedRows; } SSmlLinesInfo; +void addEscapeCharToString(char *str, int32_t len); int tscSmlInsert(TAOS* taos, TAOS_SML_DATA_POINT* points, int numPoint, SSmlLinesInfo* info); bool checkDuplicateKey(char *key, SHashObj *pHash, SSmlLinesInfo* info); bool isValidInteger(char *str); @@ -85,12 +82,12 @@ int32_t convertSmlTimeStamp(TAOS_SML_KV *pVal, char *value, void destroySmlDataPoint(TAOS_SML_DATA_POINT* point); -int taos_insert_sml_lines(TAOS* taos, char* lines[], int numLines, - SMLProtocolType protocol, SMLTimeStampType tsType); -int taos_insert_telnet_lines(TAOS* taos, char* lines[], int numLines, - SMLProtocolType protocol, SMLTimeStampType tsType); -int taos_insert_json_payload(TAOS* taos, char* payload, - SMLProtocolType protocol, SMLTimeStampType tsType); +int taos_insert_lines(TAOS* taos, char* lines[], int numLines, SMLProtocolType protocol, + SMLTimeStampType tsType, int* affectedRows); +int taos_insert_telnet_lines(TAOS* taos, char* lines[], int numLines, SMLProtocolType protocol, + SMLTimeStampType tsType, int* affectedRows); +int taos_insert_json_payload(TAOS* taos, char* payload, SMLProtocolType protocol, + SMLTimeStampType tsType, int* affectedRows); #ifdef __cplusplus diff --git a/src/client/inc/tscUtil.h b/src/client/inc/tscUtil.h index 11ae6ae2704050850e7d79f8ee8c36ce207158e6..e2b151ea6ab417ef18746d0a35ce3c7818b504b7 100644 --- a/src/client/inc/tscUtil.h +++ b/src/client/inc/tscUtil.h @@ -251,6 +251,7 @@ void tscColumnListCopyAll(SArray* dst, const SArray* src); void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo, uint64_t objId, bool convertNchar); void tscDequoteAndTrimToken(SStrToken* pToken); +void tscRmEscapeAndTrimToken(SStrToken* pToken); int32_t tscValidateName(SStrToken* pToken, bool escapeEnabled, bool *dbIncluded); void tscIncStreamExecutionCount(void* pStream); diff --git a/src/client/jni/com_alibaba_datax_plugin_writer_JniConnection.h b/src/client/jni/com_alibaba_datax_plugin_writer_JniConnection.h new file mode 100644 index 0000000000000000000000000000000000000000..61f0e6eb9ce4c15c8c68d8375ad853a7505588ce --- /dev/null +++ b/src/client/jni/com_alibaba_datax_plugin_writer_JniConnection.h @@ -0,0 +1,81 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_alibaba_datax_plugin_writer_JniConnection */ + +#ifndef _Included_com_alibaba_datax_plugin_writer_JniConnection +#define _Included_com_alibaba_datax_plugin_writer_JniConnection +#ifdef __cplusplus +extern "C" { +#endif +#undef com_alibaba_datax_plugin_writer_JniConnection_JNI_NULL_POINTER +#define com_alibaba_datax_plugin_writer_JniConnection_JNI_NULL_POINTER 0LL +#undef com_alibaba_datax_plugin_writer_JniConnection_JNI_SUCCESSFUL +#define com_alibaba_datax_plugin_writer_JniConnection_JNI_SUCCESSFUL 0L +/* + * Class: com_alibaba_datax_plugin_writer_JniConnection + * Method: initImp + * Signature: (Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_com_alibaba_datax_plugin_writer_JniConnection_initImp + (JNIEnv *, jclass, jstring); + +/* + * Class: com_alibaba_datax_plugin_writer_JniConnection + * Method: setOptions + * Signature: (ILjava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_com_alibaba_datax_plugin_writer_JniConnection_setOptions + (JNIEnv *, jclass, jint, jstring); + +/* + * Class: com_alibaba_datax_plugin_writer_JniConnection + * Method: connectImp + * Signature: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)J + */ +JNIEXPORT jlong JNICALL Java_com_alibaba_datax_plugin_writer_JniConnection_connectImp + (JNIEnv *, jobject, jstring, jint, jstring, jstring, jstring); + +/* + * Class: com_alibaba_datax_plugin_writer_JniConnection + * Method: getErrCodeImp + * Signature: (JJ)I + */ +JNIEXPORT jint JNICALL Java_com_alibaba_datax_plugin_writer_JniConnection_getErrCodeImp + (JNIEnv *, jobject, jlong, jlong); + +/* + * Class: com_alibaba_datax_plugin_writer_JniConnection + * Method: getErrMsgImp + * Signature: (J)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_com_alibaba_datax_plugin_writer_JniConnection_getErrMsgImp + (JNIEnv *, jobject, jlong); + +/* + * Class: com_alibaba_datax_plugin_writer_JniConnection + * Method: freeResultSetImp + * Signature: (JJ)V + */ +JNIEXPORT void JNICALL Java_com_alibaba_datax_plugin_writer_JniConnection_freeResultSetImp + (JNIEnv *, jobject, jlong, jlong); + +/* + * Class: com_alibaba_datax_plugin_writer_JniConnection + * Method: closeConnectionImp + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_alibaba_datax_plugin_writer_JniConnection_closeConnectionImp + (JNIEnv *, jobject, jlong); + +/* + * Class: com_alibaba_datax_plugin_writer_JniConnection + * Method: insertOpentsdbJson + * Signature: (Ljava/lang/String;J)J + */ +JNIEXPORT jlong JNICALL Java_com_alibaba_datax_plugin_writer_JniConnection_insertOpentsdbJson + (JNIEnv *, jobject, jstring, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/client/jni/jniCommon.h b/src/client/jni/jniCommon.h new file mode 100644 index 0000000000000000000000000000000000000000..78724eed319b8b414b12fc46e3d31899370ba39d --- /dev/null +++ b/src/client/jni/jniCommon.h @@ -0,0 +1,87 @@ +#include + +#ifndef TDENGINE_JNICOMMON_H +#define TDENGINE_JNICOMMON_H + +#define jniFatal(...) \ + { \ + if (jniDebugFlag & DEBUG_FATAL) { \ + taosPrintLog("JNI FATAL ", tscEmbedded ? 255 : jniDebugFlag, __VA_ARGS__); \ + } \ + } +#define jniError(...) \ + { \ + if (jniDebugFlag & DEBUG_ERROR) { \ + taosPrintLog("JNI ERROR ", tscEmbedded ? 255 : jniDebugFlag, __VA_ARGS__); \ + } \ + } +#define jniWarn(...) \ + { \ + if (jniDebugFlag & DEBUG_WARN) { \ + taosPrintLog("JNI WARN ", tscEmbedded ? 255 : jniDebugFlag, __VA_ARGS__); \ + } \ + } +#define jniInfo(...) \ + { \ + if (jniDebugFlag & DEBUG_INFO) { \ + taosPrintLog("JNI ", tscEmbedded ? 255 : jniDebugFlag, __VA_ARGS__); \ + } \ + } +#define jniDebug(...) \ + { \ + if (jniDebugFlag & DEBUG_DEBUG) { \ + taosPrintLog("JNI ", jniDebugFlag, __VA_ARGS__); \ + } \ + } +#define jniTrace(...) \ + { \ + if (jniDebugFlag & DEBUG_TRACE) { \ + taosPrintLog("JNI ", jniDebugFlag, __VA_ARGS__); \ + } \ + } + +extern jclass g_arrayListClass; +extern jmethodID g_arrayListConstructFp; +extern jmethodID g_arrayListAddFp; + +extern jclass g_metadataClass; +extern jmethodID g_metadataConstructFp; +extern jfieldID g_metadataColtypeField; +extern jfieldID g_metadataColnameField; +extern jfieldID g_metadataColsizeField; +extern jfieldID g_metadataColindexField; + +extern jclass g_rowdataClass; +extern jmethodID g_rowdataConstructor; +extern jmethodID g_rowdataClearFp; +extern jmethodID g_rowdataSetBooleanFp; +extern jmethodID g_rowdataSetByteFp; +extern jmethodID g_rowdataSetShortFp; +extern jmethodID g_rowdataSetIntFp; +extern jmethodID g_rowdataSetLongFp; +extern jmethodID g_rowdataSetFloatFp; +extern jmethodID g_rowdataSetDoubleFp; +extern jmethodID g_rowdataSetStringFp; +extern jmethodID g_rowdataSetTimestampFp; +extern jmethodID g_rowdataSetByteArrayFp; + +extern jmethodID g_blockdataSetByteArrayFp; +extern jmethodID g_blockdataSetNumOfRowsFp; +extern jmethodID g_blockdataSetNumOfColsFp; + +#define JNI_SUCCESS 0 +#define JNI_TDENGINE_ERROR -1 +#define JNI_CONNECTION_NULL -2 +#define JNI_RESULT_SET_NULL -3 +#define JNI_NUM_OF_FIELDS_0 -4 +#define JNI_SQL_NULL -5 +#define JNI_FETCH_END -6 +#define JNI_OUT_OF_MEMORY -7 + +extern JavaVM *g_vm; + +void jniGetGlobalMethod(JNIEnv *env); + +int32_t check_for_params(jobject jobj, jlong conn, jlong res); + +#endif // TDENGINE_JNICOMMON_H diff --git a/src/client/src/TSDBJNIConnector.c b/src/client/src/TSDBJNIConnector.c index 0444c2cb8dd23f2e73179668e6cb7195a030b6be..ef7387f9760b7d710f77a97b52fcafe9686bd335 100644 --- a/src/client/src/TSDBJNIConnector.c +++ b/src/client/src/TSDBJNIConnector.c @@ -17,46 +17,9 @@ #include "taos.h" #include "tlog.h" #include "tscUtil.h" -#include "tscParseLine.h" #include "com_taosdata_jdbc_TSDBJNIConnector.h" - -#define jniFatal(...) \ - { \ - if (jniDebugFlag & DEBUG_FATAL) { \ - taosPrintLog("JNI FATAL ", tscEmbedded ? 255 : jniDebugFlag, __VA_ARGS__); \ - } \ - } -#define jniError(...) \ - { \ - if (jniDebugFlag & DEBUG_ERROR) { \ - taosPrintLog("JNI ERROR ", tscEmbedded ? 255 : jniDebugFlag, __VA_ARGS__); \ - } \ - } -#define jniWarn(...) \ - { \ - if (jniDebugFlag & DEBUG_WARN) { \ - taosPrintLog("JNI WARN ", tscEmbedded ? 255 : jniDebugFlag, __VA_ARGS__); \ - } \ - } -#define jniInfo(...) \ - { \ - if (jniDebugFlag & DEBUG_INFO) { \ - taosPrintLog("JNI ", tscEmbedded ? 255 : jniDebugFlag, __VA_ARGS__); \ - } \ - } -#define jniDebug(...) \ - { \ - if (jniDebugFlag & DEBUG_DEBUG) { \ - taosPrintLog("JNI ", jniDebugFlag, __VA_ARGS__); \ - } \ - } -#define jniTrace(...) \ - { \ - if (jniDebugFlag & DEBUG_TRACE) { \ - taosPrintLog("JNI ", jniDebugFlag, __VA_ARGS__); \ - } \ - } +#include "jniCommon.h" int __init = 0; @@ -91,16 +54,7 @@ jmethodID g_blockdataSetByteArrayFp; jmethodID g_blockdataSetNumOfRowsFp; jmethodID g_blockdataSetNumOfColsFp; -#define JNI_SUCCESS 0 -#define JNI_TDENGINE_ERROR -1 -#define JNI_CONNECTION_NULL -2 -#define JNI_RESULT_SET_NULL -3 -#define JNI_NUM_OF_FIELDS_0 -4 -#define JNI_SQL_NULL -5 -#define JNI_FETCH_END -6 -#define JNI_OUT_OF_MEMORY -7 - -static void jniGetGlobalMethod(JNIEnv *env) { +void jniGetGlobalMethod(JNIEnv *env) { // make sure init function executed once switch (atomic_val_compare_exchange_32(&__init, 0, 1)) { case 0: @@ -159,7 +113,7 @@ static void jniGetGlobalMethod(JNIEnv *env) { jniDebug("native method register finished"); } -static int32_t check_for_params(jobject jobj, jlong conn, jlong res) { +int32_t check_for_params(jobject jobj, jlong conn, jlong res) { if ((TAOS *)conn == NULL) { jniError("jobj:%p, connection is closed", jobj); return JNI_CONNECTION_NULL; @@ -219,26 +173,8 @@ JNIEXPORT jobject createTSDBException(JNIEnv *env, int code, char *msg) { return exception_obj; } -/* - * Class: com_taosdata_jdbc_TSDBJNIConnector - * Method: setConfigImp - * Signature: (Ljava/lang/String;)Lcom/taosdata/jdbc/TSDBException; - */ JNIEXPORT jobject JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setConfigImp(JNIEnv *env, jclass jobj, jstring config) { - /* - if (config == NULL) { - jniDebug("config value is null"); - return -1; - } - - const char *cfg = (*env)->GetStringUTFChars(env, config, NULL); - if (!cfg) { - return -1; - } - return 0; - */ - if (config == NULL) { char *msg = "config value is null"; jniDebug("config value is null"); @@ -254,7 +190,7 @@ JNIEXPORT jobject JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setConfigImp(J setConfRet result = taos_set_config(cfg); int code = result.retCode; - char * msg = result.retMsg; + char *msg = result.retMsg; return createTSDBException(env, code, msg); } @@ -424,7 +360,7 @@ JNIEXPORT jstring JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getErrMsgImp(J JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getResultSetImp(JNIEnv *env, jobject jobj, jlong con, jlong tres) { - TAOS * tscon = (TAOS *)con; + TAOS *tscon = (TAOS *)con; int32_t code = check_for_params(jobj, con, tres); if (code != JNI_SUCCESS) { return code; @@ -467,7 +403,7 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_freeResultSetImp( JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getAffectedRowsImp(JNIEnv *env, jobject jobj, jlong con, jlong res) { - TAOS * tscon = (TAOS *)con; + TAOS *tscon = (TAOS *)con; int32_t code = check_for_params(jobj, con, res); if (code != JNI_SUCCESS) { return code; @@ -483,13 +419,13 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getAffectedRowsIm JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getSchemaMetaDataImp(JNIEnv *env, jobject jobj, jlong con, jlong res, jobject arrayListObj) { - TAOS * tscon = (TAOS *)con; + TAOS *tscon = (TAOS *)con; int32_t code = check_for_params(jobj, con, res); if (code != JNI_SUCCESS) { return code; } - TAOS_RES * tres = (TAOS_RES *)res; + TAOS_RES *tres = (TAOS_RES *)res; TAOS_FIELD *fields = taos_fetch_fields(tres); int32_t num_fields = taos_num_fields(tres); @@ -626,13 +562,13 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchRowImp(JNIEn JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchBlockImp(JNIEnv *env, jobject jobj, jlong con, jlong res, jobject rowobj) { - TAOS * tscon = (TAOS *)con; + TAOS *tscon = (TAOS *)con; int32_t code = check_for_params(jobj, con, res); if (code != JNI_SUCCESS) { return code; } - TAOS_RES * tres = (TAOS_RES *)res; + TAOS_RES *tres = (TAOS_RES *)res; TAOS_FIELD *fields = taos_fetch_fields(tres); int32_t numOfFields = taos_num_fields(tres); @@ -1021,7 +957,7 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setTableNameTagsI } const char *name = (*env)->GetStringUTFChars(env, tableName, NULL); - char * curTags = tagsData; + char *curTags = tagsData; TAOS_BIND *tagsBind = calloc(numOfTags, sizeof(TAOS_BIND)); for (int32_t i = 0; i < numOfTags; ++i) { @@ -1053,7 +989,8 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setTableNameTagsI } JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_insertLinesImp(JNIEnv *env, jobject jobj, - jobjectArray lines, jlong conn) { + jobjectArray lines, jlong conn, + jint protocol, jint precision) { TAOS *taos = (TAOS *)conn; if (taos == NULL) { jniError("jobj:%p, connection already closed", jobj); @@ -1071,7 +1008,8 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_insertLinesImp(J c_lines[i] = (char *)(*env)->GetStringUTFChars(env, line, 0); } - int code = taos_schemaless_insert(taos, c_lines, numLines, SML_LINE_PROTOCOL, "ms"); + SSqlObj* result = (SSqlObj*)taos_schemaless_insert(taos, c_lines, numLines, protocol, precision); + int code = taos_errno(result); for (int i = 0; i < numLines; ++i) { jstring line = (jstring)((*env)->GetObjectArrayElement(env, lines, i)); @@ -1080,9 +1018,10 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_insertLinesImp(J tfree(c_lines); if (code != TSDB_CODE_SUCCESS) { - jniError("jobj:%p, conn:%p, code:%s", jobj, taos, tstrerror(code)); + jniError("jobj:%p, conn:%p, code:%s, msg:%s", jobj, taos, tstrerror(code), taos_errstr(result)); return JNI_TDENGINE_ERROR; } - return code; + + return (jlong)result; } diff --git a/src/client/src/dataxJniConnection.c b/src/client/src/dataxJniConnection.c new file mode 100644 index 0000000000000000000000000000000000000000..beaa61dac16d790cb01ca616140801fade46eee1 --- /dev/null +++ b/src/client/src/dataxJniConnection.c @@ -0,0 +1,232 @@ +#include "os.h" +#include "taos.h" +#include "tlog.h" +#include "tscUtil.h" + +#include "com_alibaba_datax_plugin_writer_JniConnection.h" +#include "jniCommon.h" + +jclass g_arrayListClass; +jmethodID g_arrayListConstructFp; +jmethodID g_arrayListAddFp; + +jclass g_metadataClass; +jmethodID g_metadataConstructFp; +jfieldID g_metadataColtypeField; +jfieldID g_metadataColnameField; +jfieldID g_metadataColsizeField; +jfieldID g_metadataColindexField; + +jclass g_rowdataClass; +jmethodID g_rowdataConstructor; +jmethodID g_rowdataClearFp; +jmethodID g_rowdataSetBooleanFp; +jmethodID g_rowdataSetByteFp; +jmethodID g_rowdataSetShortFp; +jmethodID g_rowdataSetIntFp; +jmethodID g_rowdataSetLongFp; +jmethodID g_rowdataSetFloatFp; +jmethodID g_rowdataSetDoubleFp; +jmethodID g_rowdataSetStringFp; +jmethodID g_rowdataSetTimestampFp; +jmethodID g_rowdataSetByteArrayFp; + +jmethodID g_blockdataSetByteArrayFp; +jmethodID g_blockdataSetNumOfRowsFp; +jmethodID g_blockdataSetNumOfColsFp; + +JNIEXPORT void JNICALL Java_com_alibaba_datax_plugin_writer_JniConnection_initImp(JNIEnv *env, jobject jobj, + jstring jconfigDir) { + if (jconfigDir != NULL) { + const char *confDir = (*env)->GetStringUTFChars(env, jconfigDir, NULL); + if (confDir && strlen(confDir) != 0) { + tstrncpy(configDir, confDir, TSDB_FILENAME_LEN); + } + (*env)->ReleaseStringUTFChars(env, jconfigDir, confDir); + } + + jniDebug("jni initialized successfully, config directory: %s", configDir); +} + +JNIEXPORT jint JNICALL Java_com_alibaba_datax_plugin_writer_JniConnection_setOptions(JNIEnv *env, jobject jobj, + jint optionIndex, + jstring optionValue) { + if (optionValue == NULL) { + jniDebug("option index:%d value is null", (int32_t)optionIndex); + return 0; + } + + int res = 0; + + if (optionIndex == TSDB_OPTION_LOCALE) { + const char *locale = (*env)->GetStringUTFChars(env, optionValue, NULL); + if (locale && strlen(locale) != 0) { + res = taos_options(TSDB_OPTION_LOCALE, locale); + jniDebug("set locale to %s, result:%d", locale, res); + } else { + jniDebug("input locale is empty"); + } + (*env)->ReleaseStringUTFChars(env, optionValue, locale); + } else if (optionIndex == TSDB_OPTION_CHARSET) { + const char *charset = (*env)->GetStringUTFChars(env, optionValue, NULL); + if (charset && strlen(charset) != 0) { + res = taos_options(TSDB_OPTION_CHARSET, charset); + jniDebug("set character encoding to %s, result:%d", charset, res); + } else { + jniDebug("input character encoding is empty"); + } + (*env)->ReleaseStringUTFChars(env, optionValue, charset); + } else if (optionIndex == TSDB_OPTION_TIMEZONE) { + const char *tz1 = (*env)->GetStringUTFChars(env, optionValue, NULL); + if (tz1 && strlen(tz1) != 0) { + res = taos_options(TSDB_OPTION_TIMEZONE, tz1); + jniDebug("set timezone to %s, result:%d", tz1, res); + } else { + jniDebug("input timezone is empty"); + } + (*env)->ReleaseStringUTFChars(env, optionValue, tz1); + } else { + jniError("option index:%d is not found", (int32_t)optionIndex); + } + + return res; +} + +JNIEXPORT jlong JNICALL Java_com_alibaba_datax_plugin_writer_JniConnection_connectImp(JNIEnv *env, jobject jobj, + jstring jhost, jint jport, + jstring jdbName, jstring juser, + jstring jpass) { + jlong ret = 0; + const char *host = NULL; + const char *user = NULL; + const char *pass = NULL; + const char *dbname = NULL; + + if (jhost != NULL) { + host = (*env)->GetStringUTFChars(env, jhost, NULL); + } + + if (jdbName != NULL) { + dbname = (*env)->GetStringUTFChars(env, jdbName, NULL); + } + + if (juser != NULL) { + user = (*env)->GetStringUTFChars(env, juser, NULL); + } + + if (jpass != NULL) { + pass = (*env)->GetStringUTFChars(env, jpass, NULL); + } + + if (user == NULL) { + jniDebug("jobj:%p, user not specified, use default user %s", jobj, TSDB_DEFAULT_USER); + } + + if (pass == NULL) { + jniDebug("jobj:%p, pass not specified, use default password", jobj); + } + + ret = (jlong)taos_connect((char *)host, (char *)user, (char *)pass, (char *)dbname, (uint16_t)jport); + if (ret == 0) { + jniError("jobj:%p, conn:%p, connect to database failed, host=%s, user=%s, dbname=%s, port=%d", jobj, (void *)ret, + (char *)host, (char *)user, (char *)dbname, (int32_t)jport); + } else { + jniDebug("jobj:%p, conn:%p, connect to database succeed, host=%s, user=%s, dbname=%s, port=%d", jobj, (void *)ret, + (char *)host, (char *)user, (char *)dbname, (int32_t)jport); + } + + if (host != NULL) { + (*env)->ReleaseStringUTFChars(env, jhost, host); + } + + if (dbname != NULL) { + (*env)->ReleaseStringUTFChars(env, jdbName, dbname); + } + + if (user != NULL) { + (*env)->ReleaseStringUTFChars(env, juser, user); + } + + if (pass != NULL) { + (*env)->ReleaseStringUTFChars(env, jpass, pass); + } + + return ret; +} + +JNIEXPORT jint JNICALL Java_com_alibaba_datax_plugin_writer_JniConnection_getErrCodeImp(JNIEnv *env, jobject jobj, + jlong con, jlong tres) { + int32_t code = check_for_params(jobj, con, tres); + if (code != JNI_SUCCESS) { + return code; + } + + return (jint)taos_errno((TAOS_RES *)tres); +} + +JNIEXPORT jstring JNICALL Java_com_alibaba_datax_plugin_writer_JniConnection_getErrMsgImp(JNIEnv *env, jobject jobj, + jlong tres) { + TAOS_RES *pSql = (TAOS_RES *)tres; + return (*env)->NewStringUTF(env, (const char *)taos_errstr(pSql)); +} + +JNIEXPORT void JNICALL Java_com_alibaba_datax_plugin_writer_JniConnection_freeResultSetImp(JNIEnv *env, jobject jobj, + jlong con, jlong res) { + if ((TAOS *)con == NULL) { + jniError("jobj:%p, connection is closed", jobj); + } + if ((TAOS_RES *)res == NULL) { + jniError("jobj:%p, conn:%p, res is null", jobj, (TAOS *)con); + } + taos_free_result((TAOS_RES *)res); + jniDebug("jobj:%p, conn:%p, free resultset:%p", jobj, (TAOS *)con, (void *)res); +} + +JNIEXPORT jint JNICALL Java_com_alibaba_datax_plugin_writer_JniConnection_closeConnectionImp(JNIEnv *env, jobject jobj, + jlong con) { + TAOS *tscon = (TAOS *)con; + if (tscon == NULL) { + jniError("jobj:%p, connection is already closed", jobj); + return JNI_CONNECTION_NULL; + } else { + jniDebug("jobj:%p, conn:%p, close connection success", jobj, tscon); + taos_close(tscon); + return JNI_SUCCESS; + } +} + +JNIEXPORT jlong JNICALL Java_com_alibaba_datax_plugin_writer_JniConnection_insertOpentsdbJson(JNIEnv *env, jobject jobj, + jstring json, jlong con) { + // check connection + TAOS *conn = (TAOS *)con; + if (conn == NULL) { + jniError("jobj:%p, connection already closed", jobj); + return JNI_CONNECTION_NULL; + } + // java.lang.String -> char * + char *payload = NULL; + if (json != NULL) { + payload = (char *)(*env)->GetStringUTFChars(env, json, NULL); + } + // check payload + if (payload == NULL) { + jniDebug("jobj:%p, invalid argument: opentsdb insert json is NULL", jobj); + return JNI_SQL_NULL; + } + // schemaless insert + char *payload_arr[1]; + payload_arr[0] = payload; + TAOS_RES *result; + result = taos_schemaless_insert(conn, payload_arr, 0, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + + int code = taos_errno(result); + if (code != TSDB_CODE_SUCCESS) { + jniError("jobj:%p, conn:%p, code:%s, msg:%s", jobj, conn, tstrerror(code), taos_errstr(result)); + } else { + int32_t affectRows = taos_affected_rows(result); + jniDebug("jobj:%p, conn:%p, code:%s, affect rows:%d", jobj, conn, tstrerror(code), affectRows); + } + + (*env)->ReleaseStringUTFChars(env, json, payload); + return (jlong)result; +} \ No newline at end of file diff --git a/src/client/src/taos.def b/src/client/src/taos.def index 28a9dde2239435b1b916e00fe05ca5634e7bbcfc..0e7289764b28d6b40d6576afb125f4251e88182f 100644 --- a/src/client/src/taos.def +++ b/src/client/src/taos.def @@ -51,3 +51,4 @@ taos_stmt_bind_param_batch taos_stmt_bind_single_param_batch taos_is_null taos_insert_lines +taos_schemaless_insert diff --git a/src/client/src/tscParseInsert.c b/src/client/src/tscParseInsert.c index da03ed40f02c667c474f3c10a648cb1808667835..dbc7503535d79604c3ca908ce748075d41e2eb00 100644 --- a/src/client/src/tscParseInsert.c +++ b/src/client/src/tscParseInsert.c @@ -1251,10 +1251,18 @@ static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDat sToken = tStrGetToken(str, &index, false); str += index; + char tmpTokenBuf[TSDB_MAX_BYTES_PER_ROW] = {0}; // used for deleting Escape character backstick(`) + strncpy(tmpTokenBuf, sToken.z, sToken.n); + sToken.z = tmpTokenBuf; + if (TK_STRING == sToken.type) { tscDequoteAndTrimToken(&sToken); } + if (TK_ID == sToken.type) { + tscRmEscapeAndTrimToken(&sToken); + } + if (sToken.type == TK_RP) { if (end != NULL) { // set the end position *end = str; diff --git a/src/client/src/tscParseLineProtocol.c b/src/client/src/tscParseLineProtocol.c index f63a19452f1fc64483e32b9eb0f5c24b1b5f1d14..64b15d0dd85c5acc83eee9d18fe191817383d9ef 100644 --- a/src/client/src/tscParseLineProtocol.c +++ b/src/client/src/tscParseLineProtocol.c @@ -499,6 +499,7 @@ static int32_t fillDbSchema(STableMeta* tableMeta, char* tableName, SSmlSTableSc for (int i=0; itableInfo.numOfColumns; ++i) { SSchema field; tstrncpy(field.name, tableMeta->schema[i].name, strlen(tableMeta->schema[i].name)+1); + addEscapeCharToString(field.name, (int16_t)strlen(field.name)); field.type = tableMeta->schema[i].type; field.bytes = tableMeta->schema[i].bytes; taosArrayPush(schema->fields, &field); @@ -510,6 +511,7 @@ static int32_t fillDbSchema(STableMeta* tableMeta, char* tableName, SSmlSTableSc int j = i + tableMeta->tableInfo.numOfColumns; SSchema field; tstrncpy(field.name, tableMeta->schema[j].name, strlen(tableMeta->schema[j].name)+1); + addEscapeCharToString(field.name, (int16_t)strlen(field.name)); field.type = tableMeta->schema[j].type; field.bytes = tableMeta->schema[j].bytes; taosArrayPush(schema->tags, &field); @@ -1175,6 +1177,15 @@ static void escapeSpecialCharacter(uint8_t field, const char **pos) { *pos = cur; } +void addEscapeCharToString(char *str, int32_t len) { + if (str == NULL) { + return; + } + memmove(str + 1, str, len); + str[0] = str[len + 1] = TS_ESCAPE_CHAR; + str[len + 2] = '\0'; +} + bool isValidInteger(char *str) { char *c = str; if (*c != '+' && *c != '-' && !isdigit(*c)) { @@ -1435,58 +1446,65 @@ static bool isNchar(char *pVal, uint16_t len) { return false; } -static bool isTimeStamp(char *pVal, uint16_t len, SMLTimeStampType *tsType, SSmlLinesInfo* info) { +static int32_t isTimeStamp(char *pVal, uint16_t len, SMLTimeStampType *tsType, SSmlLinesInfo* info) { if (len == 0) { - return true; + return TSDB_CODE_SUCCESS; } if ((len == 1) && pVal[0] == '0') { *tsType = SML_TIME_STAMP_NOW; - return true; + return TSDB_CODE_SUCCESS; } - //Default no appendix - if (isdigit(pVal[len - 1]) && isdigit(pVal[len - 2])) { - if (info->protocol == SML_LINE_PROTOCOL) { - if (info->tsType != SML_TIME_STAMP_NOT_CONFIGURED) { - *tsType = info->tsType; - } else { - *tsType = SML_TIME_STAMP_NANO_SECONDS; - } - } else if (info->protocol == SML_TELNET_PROTOCOL) { - if (len == SML_TIMESTAMP_SECOND_DIGITS) { - *tsType = SML_TIME_STAMP_SECONDS; - } else if (len == SML_TIMESTAMP_MILLI_SECOND_DIGITS) { - *tsType = SML_TIME_STAMP_MILLI_SECONDS; - } else { - return TSDB_CODE_TSC_INVALID_TIME_STAMP; - } + for (int i = 0; i < len; ++i) { + if(!isdigit(pVal[i])) { + return TSDB_CODE_TSC_INVALID_TIME_STAMP; } - return true; } - if (pVal[len - 1] == 's') { - switch (pVal[len - 2]) { - case 'm': - *tsType = SML_TIME_STAMP_MILLI_SECONDS; - break; - case 'u': - *tsType = SML_TIME_STAMP_MICRO_SECONDS; - break; - case 'n': - *tsType = SML_TIME_STAMP_NANO_SECONDS; - break; - default: - if (isdigit(pVal[len - 2])) { - *tsType = SML_TIME_STAMP_SECONDS; - break; - } else { - return false; - } + /* For InfluxDB line protocol use user passed timestamp precision + * For OpenTSDB protocols only 10 digit(seconds) or 13 digits(milliseconds) + * precision allowed + */ + if (info->protocol == TSDB_SML_LINE_PROTOCOL) { + if (info->tsType != SML_TIME_STAMP_NOT_CONFIGURED) { + *tsType = info->tsType; + } else { + *tsType = SML_TIME_STAMP_NANO_SECONDS; + } + } else if (info->protocol == TSDB_SML_TELNET_PROTOCOL) { + if (len == SML_TIMESTAMP_SECOND_DIGITS) { + *tsType = SML_TIME_STAMP_SECONDS; + } else if (len == SML_TIMESTAMP_MILLI_SECOND_DIGITS) { + *tsType = SML_TIME_STAMP_MILLI_SECONDS; + } else { + return TSDB_CODE_TSC_INVALID_TIME_STAMP; } - //printf("Type is timestamp(%s)\n", pVal); - return true; } - return false; + return TSDB_CODE_SUCCESS; + + //if (pVal[len - 1] == 's') { + // switch (pVal[len - 2]) { + // case 'm': + // *tsType = SML_TIME_STAMP_MILLI_SECONDS; + // break; + // case 'u': + // *tsType = SML_TIME_STAMP_MICRO_SECONDS; + // break; + // case 'n': + // *tsType = SML_TIME_STAMP_NANO_SECONDS; + // break; + // default: + // if (isdigit(pVal[len - 2])) { + // *tsType = SML_TIME_STAMP_SECONDS; + // break; + // } else { + // return false; + // } + // } + // //printf("Type is timestamp(%s)\n", pVal); + // return true; + //} + //return false; } static bool convertStrToNumber(TAOS_SML_KV *pVal, char *str, SSmlLinesInfo* info) { @@ -1750,14 +1768,6 @@ bool convertSmlValueType(TAOS_SML_KV *pVal, char *value, static int32_t getTimeStampValue(char *value, uint16_t len, SMLTimeStampType type, int64_t *ts, SSmlLinesInfo* info) { - if (len >= 2) { - for (int i = 0; i < len - 2; ++i) { - if(!isdigit(value[i])) { - return TSDB_CODE_TSC_INVALID_TIME_STAMP; - } - } - } - //No appendix or no timestamp given (len = 0) if (len != 0 && type != SML_TIME_STAMP_NOW) { *ts = (int64_t)strtoll(value, NULL, 10); @@ -1806,13 +1816,13 @@ int32_t convertSmlTimeStamp(TAOS_SML_KV *pVal, char *value, SMLTimeStampType type; int64_t tsVal; - strntolower_s(value, value, len); - if (!isTimeStamp(value, len, &type, info)) { - return TSDB_CODE_TSC_INVALID_TIME_STAMP; + ret = isTimeStamp(value, len, &type, info); + if (ret != TSDB_CODE_SUCCESS) { + return ret; } ret = getTimeStampValue(value, len, type, &tsVal, info); - if (ret) { + if (ret != TSDB_CODE_SUCCESS) { return ret; } tscDebug("SML:0x%"PRIx64"Timestamp after conversion:%"PRId64, info->id, tsVal); @@ -1884,15 +1894,10 @@ bool checkDuplicateKey(char *key, SHashObj *pHash, SSmlLinesInfo* info) { static int32_t parseSmlKey(TAOS_SML_KV *pKV, const char **index, SHashObj *pHash, SSmlLinesInfo* info) { const char *cur = *index; char key[TSDB_COL_NAME_LEN + 1]; // +1 to avoid key[len] over write - uint16_t len = 0; + int16_t len = 0; - //key field cannot start with digit - if (isdigit(*cur)) { - tscError("SML:0x%"PRIx64" Tag key cannot start with digit", info->id); - return TSDB_CODE_TSC_LINE_SYNTAX_ERROR; - } while (*cur != '\0') { - if (len >= TSDB_COL_NAME_LEN - 1) { + if (len > TSDB_COL_NAME_LEN - 1) { tscError("SML:0x%"PRIx64" Key field cannot exceeds %d characters", info->id, TSDB_COL_NAME_LEN - 1); return TSDB_CODE_TSC_INVALID_COLUMN_LENGTH; } @@ -1919,9 +1924,11 @@ static int32_t parseSmlKey(TAOS_SML_KV *pKV, const char **index, SHashObj *pHash return TSDB_CODE_TSC_LINE_SYNTAX_ERROR; } - pKV->key = calloc(len + 1, 1); + pKV->key = calloc(len + TS_ESCAPE_CHAR_SIZE + 1, 1); memcpy(pKV->key, key, len + 1); - //tscDebug("SML:0x%"PRIx64" Key:%s|len:%d", info->id, pKV->key, len); + strntolower_s(pKV->key, pKV->key, (int32_t)len); + addEscapeCharToString(pKV->key, len); + tscDebug("SML:0x%"PRIx64" Key:%s|len:%d", info->id, pKV->key, len); *index = cur + 1; return TSDB_CODE_SUCCESS; } @@ -1932,7 +1939,7 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **index, const char *start, *cur; int32_t ret = TSDB_CODE_SUCCESS; char *value = NULL; - uint16_t len = 0; + int16_t len = 0; bool searchQuote = false; start = cur = *index; @@ -2013,21 +2020,15 @@ error: static int32_t parseSmlMeasurement(TAOS_SML_DATA_POINT *pSml, const char **index, uint8_t *has_tags, SSmlLinesInfo* info) { const char *cur = *index; - uint16_t len = 0; + int16_t len = 0; - pSml->stableName = calloc(TSDB_TABLE_NAME_LEN + 1, 1); // +1 to avoid 1772 line over write + pSml->stableName = calloc(TSDB_TABLE_NAME_LEN + TS_ESCAPE_CHAR_SIZE, 1); if (pSml->stableName == NULL){ return TSDB_CODE_TSC_OUT_OF_MEMORY; } - if (isdigit(*cur)) { - tscError("SML:0x%"PRIx64" Measurement field cannnot start with digit", info->id); - free(pSml->stableName); - pSml->stableName = NULL; - return TSDB_CODE_TSC_LINE_SYNTAX_ERROR; - } while (*cur != '\0') { - if (len >= TSDB_TABLE_NAME_LEN - 1) { + if (len > TSDB_TABLE_NAME_LEN - 1) { tscError("SML:0x%"PRIx64" Measurement field cannot exceeds %d characters", info->id, TSDB_TABLE_NAME_LEN - 1); free(pSml->stableName); pSml->stableName = NULL; @@ -2061,7 +2062,7 @@ static int32_t parseSmlMeasurement(TAOS_SML_DATA_POINT *pSml, const char **index pSml->stableName = NULL; return TSDB_CODE_TSC_LINE_SYNTAX_ERROR; } - pSml->stableName[len] = '\0'; + addEscapeCharToString(pSml->stableName, len); *index = cur + 1; tscDebug("SML:0x%"PRIx64" Stable name in measurement:%s|len:%d", info->id, pSml->stableName, len); @@ -2117,17 +2118,11 @@ static int32_t parseSmlKvPairs(TAOS_SML_KV **pKVs, int *num_kvs, tscError("SML:0x%"PRIx64" Unable to parse value", info->id); goto error; } - if (!isField && (strcasecmp(pkv->key, "ID") == 0)) { - ret = isValidChildTableName(pkv->value, pkv->length, info); - if (ret) { - free(pkv->key); - free(pkv->value); - goto error; - } - smlData->childTableName = malloc( pkv->length + 1); + if (!isField && (strcasecmp(pkv->key, "`ID`") == 0)) { + smlData->childTableName = malloc(pkv->length + TS_ESCAPE_CHAR_SIZE + 1); memcpy(smlData->childTableName, pkv->value, pkv->length); strntolower_s(smlData->childTableName, smlData->childTableName, (int32_t)pkv->length); - smlData->childTableName[pkv->length] = '\0'; + addEscapeCharToString(smlData->childTableName, (int32_t)pkv->length); free(pkv->key); free(pkv->value); } else { @@ -2273,7 +2268,7 @@ int32_t tscParseLines(char* lines[], int numLines, SArray* points, SArray* faile return TSDB_CODE_SUCCESS; } -int taos_insert_lines(TAOS* taos, char* lines[], int numLines, SMLProtocolType protocol, SMLTimeStampType tsType) { +int taos_insert_lines(TAOS* taos, char* lines[], int numLines, SMLProtocolType protocol, SMLTimeStampType tsType, int *affectedRows) { int32_t code = 0; SSmlLinesInfo* info = tcalloc(1, sizeof(SSmlLinesInfo)); @@ -2317,6 +2312,9 @@ int taos_insert_lines(TAOS* taos, char* lines[], int numLines, SMLProtocolType p if (code != 0) { tscError("SML:0x%"PRIx64" taos_sml_insert error: %s", info->id, tstrerror((code))); } + if (affectedRows != NULL) { + *affectedRows = info->affectedRows; + } cleanup: tscDebug("SML:0x%"PRIx64" taos_insert_lines finish inserting %d lines. code: %d", info->id, numLines, code); @@ -2332,52 +2330,57 @@ cleanup: return code; } -int32_t convertPrecisionStrType(char* precision, SMLTimeStampType *tsType) { - if (precision == NULL) { - *tsType = SML_TIME_STAMP_NOT_CONFIGURED; - return TSDB_CODE_SUCCESS; - } - if (strcmp(precision, "μ") == 0) { - *tsType = SML_TIME_STAMP_MICRO_SECONDS; - return TSDB_CODE_SUCCESS; +static int32_t convertPrecisionType(int precision, SMLTimeStampType *tsType) { + switch (precision) { + case TSDB_SML_TIMESTAMP_NOT_CONFIGURED: + *tsType = SML_TIME_STAMP_NOT_CONFIGURED; + break; + case TSDB_SML_TIMESTAMP_HOURS: + *tsType = SML_TIME_STAMP_HOURS; + break; + case TSDB_SML_TIMESTAMP_MILLI_SECONDS: + *tsType = SML_TIME_STAMP_MILLI_SECONDS; + break; + case TSDB_SML_TIMESTAMP_NANO_SECONDS: + *tsType = SML_TIME_STAMP_NANO_SECONDS; + break; + case TSDB_SML_TIMESTAMP_MICRO_SECONDS: + *tsType = SML_TIME_STAMP_MICRO_SECONDS; + break; + case TSDB_SML_TIMESTAMP_SECONDS: + *tsType = SML_TIME_STAMP_SECONDS; + break; + case TSDB_SML_TIMESTAMP_MINUTES: + *tsType = SML_TIME_STAMP_MINUTES; + break; + default: + return TSDB_CODE_TSC_INVALID_PRECISION_TYPE; } - int32_t len = (int32_t)strlen(precision); - if (len == 1) { - switch (precision[0]) { - case 'u': - *tsType = SML_TIME_STAMP_MICRO_SECONDS; - break; - case 's': - *tsType = SML_TIME_STAMP_SECONDS; - break; - case 'm': - *tsType = SML_TIME_STAMP_MINUTES; - break; - case 'h': - *tsType = SML_TIME_STAMP_HOURS; - break; - default: - return TSDB_CODE_TSC_INVALID_PRECISION_TYPE; - } - } else if (len == 2 && precision[1] == 's') { - switch (precision[0]) { - case 'm': - *tsType = SML_TIME_STAMP_MILLI_SECONDS; - break; - case 'n': - *tsType = SML_TIME_STAMP_NANO_SECONDS; - break; - default: - return TSDB_CODE_TSC_INVALID_PRECISION_TYPE; - } - } else { - return TSDB_CODE_TSC_INVALID_PRECISION_TYPE; + return TSDB_CODE_SUCCESS; +} + +//make a dummy SSqlObj +static SSqlObj* createSmlQueryObj(TAOS* taos, int32_t affected_rows, int32_t code) { + SSqlObj *pNew = (SSqlObj*)calloc(1, sizeof(SSqlObj)); + if (pNew == NULL) { + return NULL; } + pNew->signature = pNew; + pNew->pTscObj = taos; + pNew->fp = NULL; - return TSDB_CODE_SUCCESS; + tsem_init(&pNew->rspSem, 0, 0); + registerSqlObj(pNew); + + pNew->res.numOfRows = affected_rows; + pNew->res.code = code; + + + return pNew; } + /** * taos_schemaless_insert() parse and insert data points into database according to * different protocol. @@ -2399,31 +2402,35 @@ int32_t convertPrecisionStrType(char* precision, SMLTimeStampType *tsType) { * */ -int taos_schemaless_insert(TAOS* taos, char* lines[], int numLines, int protocol, char* timePrecision) { - int code; +TAOS_RES* taos_schemaless_insert(TAOS* taos, char* lines[], int numLines, int protocol, int precision) { + int code = TSDB_CODE_SUCCESS; + int affected_rows = 0; SMLTimeStampType tsType; - if (protocol == SML_LINE_PROTOCOL) { - code = convertPrecisionStrType(timePrecision, &tsType); + if (protocol == TSDB_SML_LINE_PROTOCOL) { + code = convertPrecisionType(precision, &tsType); if (code != TSDB_CODE_SUCCESS) { - return code; + return NULL; } } switch (protocol) { - case SML_LINE_PROTOCOL: - code = taos_insert_lines(taos, lines, numLines, protocol, tsType); + case TSDB_SML_LINE_PROTOCOL: + code = taos_insert_lines(taos, lines, numLines, protocol, tsType, &affected_rows); break; - case SML_TELNET_PROTOCOL: - code = taos_insert_telnet_lines(taos, lines, numLines, protocol, tsType); + case TSDB_SML_TELNET_PROTOCOL: + code = taos_insert_telnet_lines(taos, lines, numLines, protocol, tsType, &affected_rows); break; - case SML_JSON_PROTOCOL: - code = taos_insert_json_payload(taos, *lines, protocol, tsType); + case TSDB_SML_JSON_PROTOCOL: + code = taos_insert_json_payload(taos, *lines, protocol, tsType, &affected_rows); break; default: code = TSDB_CODE_TSC_INVALID_PROTOCOL_TYPE; break; } - return code; + + SSqlObj *pSql = createSmlQueryObj(taos, affected_rows, code); + + return (TAOS_RES*)pSql; } diff --git a/src/client/src/tscParseOpenTSDB.c b/src/client/src/tscParseOpenTSDB.c index a6c1acfc35903750e412775b53be924fc5550b87..717638f8407c47c3fc621a3dbd037f9b05dae553 100644 --- a/src/client/src/tscParseOpenTSDB.c +++ b/src/client/src/tscParseOpenTSDB.c @@ -37,18 +37,20 @@ static int32_t parseTelnetMetric(TAOS_SML_DATA_POINT *pSml, const char **index, const char *cur = *index; uint16_t len = 0; - pSml->stableName = tcalloc(TSDB_TABLE_NAME_LEN, 1); + pSml->stableName = tcalloc(TSDB_TABLE_NAME_LEN + TS_ESCAPE_CHAR_SIZE, 1); if (pSml->stableName == NULL) { return TSDB_CODE_TSC_OUT_OF_MEMORY; } + /* if (isdigit(*cur)) { tscError("OTD:0x%"PRIx64" Metric cannot start with digit", info->id); tfree(pSml->stableName); return TSDB_CODE_TSC_LINE_SYNTAX_ERROR; } + */ while (*cur != '\0') { - if (len >= TSDB_TABLE_NAME_LEN - 1) { + if (len > TSDB_TABLE_NAME_LEN - 1) { tscError("OTD:0x%"PRIx64" Metric cannot exceeds %d characters", info->id, TSDB_TABLE_NAME_LEN - 1); tfree(pSml->stableName); return TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH; @@ -63,7 +65,7 @@ static int32_t parseTelnetMetric(TAOS_SML_DATA_POINT *pSml, const char **index, } } - pSml->stableName[len] = *cur; + pSml->stableName[len] = tolower(*cur); cur++; len++; @@ -73,7 +75,7 @@ static int32_t parseTelnetMetric(TAOS_SML_DATA_POINT *pSml, const char **index, return TSDB_CODE_TSC_LINE_SYNTAX_ERROR; } - pSml->stableName[len] = '\0'; + addEscapeCharToString(pSml->stableName, len); *index = cur + 1; tscDebug("OTD:0x%"PRIx64" Stable name in metric:%s|len:%d", info->id, pSml->stableName, len); @@ -207,12 +209,12 @@ static int32_t parseTelnetTagKey(TAOS_SML_KV *pKV, const char **index, SHashObj uint16_t len = 0; //key field cannot start with digit - if (isdigit(*cur)) { - tscError("OTD:0x%"PRIx64" Tag key cannot start with digit", info->id); - return TSDB_CODE_TSC_LINE_SYNTAX_ERROR; - } + //if (isdigit(*cur)) { + // tscError("OTD:0x%"PRIx64" Tag key cannot start with digit", info->id); + // return TSDB_CODE_TSC_LINE_SYNTAX_ERROR; + //} while (*cur != '\0') { - if (len >= TSDB_COL_NAME_LEN - 1) { + if (len > TSDB_COL_NAME_LEN - 1) { tscError("OTD:0x%"PRIx64" Tag key cannot exceeds %d characters", info->id, TSDB_COL_NAME_LEN - 1); return TSDB_CODE_TSC_INVALID_COLUMN_LENGTH; } @@ -236,8 +238,10 @@ static int32_t parseTelnetTagKey(TAOS_SML_KV *pKV, const char **index, SHashObj return TSDB_CODE_TSC_DUP_TAG_NAMES; } - pKV->key = tcalloc(len + 1, 1); + pKV->key = tcalloc(len + TS_ESCAPE_CHAR_SIZE + 1, 1); memcpy(pKV->key, key, len + 1); + strntolower_s(pKV->key, pKV->key, (int32_t)len); + addEscapeCharToString(pKV->key, len); //tscDebug("OTD:0x%"PRIx64" Key:%s|len:%d", info->id, pKV->key, len); *index = cur + 1; return TSDB_CODE_SUCCESS; @@ -312,15 +316,12 @@ static int32_t parseTelnetTagKvs(TAOS_SML_KV **pKVs, int *num_kvs, tscError("OTD:0x%"PRIx64" Unable to parse value", info->id); return ret; } - if ((strcasecmp(pkv->key, "ID") == 0)) { - ret = isValidChildTableName(pkv->value, pkv->length, info); - if (ret) { - return ret; - } - *childTableName = malloc(pkv->length + 1); + if ((strcasecmp(pkv->key, "`ID`") == 0)) { + *childTableName = tcalloc(pkv->length + TS_ESCAPE_CHAR_SIZE + 1, 1); memcpy(*childTableName, pkv->value, pkv->length); (*childTableName)[pkv->length] = '\0'; strntolower_s(*childTableName, *childTableName, (int32_t)pkv->length); + addEscapeCharToString(*childTableName, pkv->length); tfree(pkv->key); tfree(pkv->value); } else { @@ -409,7 +410,7 @@ static int32_t tscParseTelnetLines(char* lines[], int numLines, SArray* points, return TSDB_CODE_SUCCESS; } -int taos_insert_telnet_lines(TAOS* taos, char* lines[], int numLines, SMLProtocolType protocol, SMLTimeStampType tsType) { +int taos_insert_telnet_lines(TAOS* taos, char* lines[], int numLines, SMLProtocolType protocol, SMLTimeStampType tsType, int* affectedRows) { int32_t code = 0; SSmlLinesInfo* info = tcalloc(1, sizeof(SSmlLinesInfo)); @@ -453,6 +454,9 @@ int taos_insert_telnet_lines(TAOS* taos, char* lines[], int numLines, SMLProtoco if (code != 0) { tscError("OTD:0x%"PRIx64" taos_insert_telnet_lines error: %s", info->id, tstrerror((code))); } + if (affectedRows != NULL) { + *affectedRows = info->affectedRows; + } cleanup: tscDebug("OTD:0x%"PRIx64" taos_insert_telnet_lines finish inserting %d lines. code: %d", info->id, numLines, code); @@ -490,19 +494,22 @@ static int32_t parseMetricFromJSON(cJSON *root, TAOS_SML_DATA_POINT* pSml, SSmlL return TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH; } - pSml->stableName = tcalloc(stableLen + 1, sizeof(char)); + pSml->stableName = tcalloc(stableLen + TS_ESCAPE_CHAR_SIZE + 1, sizeof(char)); if (pSml->stableName == NULL){ return TSDB_CODE_TSC_OUT_OF_MEMORY; } + /* if (isdigit(metric->valuestring[0])) { tscError("OTD:0x%"PRIx64" Metric cannot start with digit in JSON", info->id); tfree(pSml->stableName); return TSDB_CODE_TSC_INVALID_JSON; } + */ tstrncpy(pSml->stableName, metric->valuestring, stableLen + 1); strntolower_s(pSml->stableName, pSml->stableName, (int32_t)stableLen); + addEscapeCharToString(pSml->stableName, stableLen); return TSDB_CODE_SUCCESS; @@ -885,7 +892,6 @@ static int32_t parseTagsFromJSON(cJSON *root, TAOS_SML_KV **pKVs, int *num_kvs, if (tags == NULL || tags->type != cJSON_Object) { return TSDB_CODE_TSC_INVALID_JSON; } - //only pick up the first ID value as child table name cJSON *id = cJSON_GetObjectItem(tags, "ID"); if (id != NULL) { @@ -894,13 +900,10 @@ static int32_t parseTagsFromJSON(cJSON *root, TAOS_SML_KV **pKVs, int *num_kvs, return TSDB_CODE_TSC_INVALID_JSON; } size_t idLen = strlen(id->valuestring); - ret = isValidChildTableName(id->valuestring, (int16_t)idLen, info); - if (ret != TSDB_CODE_SUCCESS) { - return ret; - } - *childTableName = tcalloc(idLen + 1, sizeof(char)); + *childTableName = tcalloc(idLen + TS_ESCAPE_CHAR_SIZE + 1, sizeof(char)); memcpy(*childTableName, id->valuestring, idLen); strntolower_s(*childTableName, *childTableName, (int32_t)idLen); + addEscapeCharToString(*childTableName, idLen); //check duplicate IDs cJSON_DeleteItemFromObject(tags, "ID"); @@ -909,7 +912,6 @@ static int32_t parseTagsFromJSON(cJSON *root, TAOS_SML_KV **pKVs, int *num_kvs, return TSDB_CODE_TSC_DUP_TAG_NAMES; } } - int32_t tagNum = cJSON_GetArraySize(tags); //at least one tag pair required if (tagNum <= 0) { @@ -935,8 +937,10 @@ static int32_t parseTagsFromJSON(cJSON *root, TAOS_SML_KV **pKVs, int *num_kvs, tscError("OTD:0x%"PRIx64" Tag key cannot exceeds %d characters in JSON", info->id, TSDB_COL_NAME_LEN - 1); return TSDB_CODE_TSC_INVALID_COLUMN_LENGTH; } - pkv->key = tcalloc(keyLen + 1, sizeof(char)); + pkv->key = tcalloc(keyLen + TS_ESCAPE_CHAR_SIZE + 1, sizeof(char)); strncpy(pkv->key, tag->string, keyLen); + strntolower_s(pkv->key, pkv->key, (int32_t)keyLen); + addEscapeCharToString(pkv->key, keyLen); //value ret = parseValueFromJSON(tag, pkv, info); if (ret != TSDB_CODE_SUCCESS) { @@ -1045,7 +1049,7 @@ PARSE_JSON_OVER: return ret; } -int taos_insert_json_payload(TAOS* taos, char* payload, SMLProtocolType protocol, SMLTimeStampType tsType) { +int taos_insert_json_payload(TAOS* taos, char* payload, SMLProtocolType protocol, SMLTimeStampType tsType, int* affectedRows) { int32_t code = 0; SSmlLinesInfo* info = tcalloc(1, sizeof(SSmlLinesInfo)); @@ -1080,6 +1084,9 @@ int taos_insert_json_payload(TAOS* taos, char* payload, SMLProtocolType protocol if (code != 0) { tscError("OTD:0x%"PRIx64" taos_insert_json_payload error: %s", info->id, tstrerror((code))); } + if (affectedRows != NULL) { + *affectedRows = info->affectedRows; + } cleanup: tscDebug("OTD:0x%"PRIx64" taos_insert_json_payload finish inserting 1 Point. code: %d", info->id, code); diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index ed6c81bff6d277615ba45b453c65182ac6a03d82..2587ce1120aa7411732061f4e4eb3174d920654e 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -3112,10 +3112,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col memset(pExpr->base.aliasName, 0, tListLen(pExpr->base.aliasName)); getColumnName(pItem, pExpr->base.aliasName, pExpr->base.token, sizeof(pExpr->base.aliasName) - 1); - SSchema s = {0}; - s.type = (uint8_t)resType; - s.bytes = bytes; - s.colId = pExpr->base.colInfo.colId; + SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); uint64_t uid = pTableMetaInfo->pTableMeta->id.uid; SColumnList ids = createColumnList(1, index.tableIndex, index.columnIndex); @@ -3123,7 +3120,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col insertResultField(pQueryInfo, colIndex, &ids, pUdfInfo->resBytes, pUdfInfo->resType, pExpr->base.aliasName, pExpr); } else { for (int32_t i = 0; i < ids.num; ++i) { - tscColumnListInsert(pQueryInfo->colList, index.columnIndex, uid, &s); + tscColumnListInsert(pQueryInfo->colList, index.columnIndex, uid, pSchema); } } tscInsertPrimaryTsSourceColumn(pQueryInfo, pTableMetaInfo->pTableMeta->id.uid); @@ -3177,6 +3174,14 @@ static int16_t doGetColumnIndex(SQueryInfo* pQueryInfo, int32_t index, SStrToken int16_t columnIndex = COLUMN_INDEX_INITIAL_VAL; + char tmpTokenBuf[TSDB_MAX_BYTES_PER_ROW] = {0}; // create tmp buf to avoid alter orginal sqlstr + strncpy(tmpTokenBuf, pToken->z, pToken->n); + pToken->z = tmpTokenBuf; + + if (pToken->type == TK_ID) { + tscRmEscapeAndTrimToken(pToken); + } + for (int16_t i = 0; i < numOfCols; ++i) { if (pToken->n != strlen(pSchema[i].name)) { continue; @@ -4227,7 +4232,11 @@ static int32_t validateSQLExpr(SSqlCmd* pCmd, tSqlExpr* pExpr, SQueryInfo* pQuer // Append the sqlExpr into exprList of pQueryInfo structure sequentially pExpr->functionId = isValidFunction(pExpr->Expr.operand.z, pExpr->Expr.operand.n); if (pExpr->functionId < 0) { - return TSDB_CODE_TSC_INVALID_OPERATION; + SUdfInfo* pUdfInfo = NULL; + pUdfInfo = isValidUdf(pQueryInfo->pUdfInfo, pExpr->Expr.operand.z, pExpr->Expr.operand.n); + if (pUdfInfo == NULL) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), "invalid function name"); + } } if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, &item, false, NULL) != TSDB_CODE_SUCCESS) { @@ -5738,6 +5747,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq const char* msg8 = "only column in groupby clause allowed as order column"; const char* msg9 = "orderby column must projected in subquery"; const char* msg10 = "not support distinct mixed with order by"; + const char* msg11 = "not support order with udf"; setDefaultOrderInfo(pQueryInfo); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); @@ -5777,6 +5787,19 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq SStrToken columnName = {pVar->nLen, pVar->nType, pVar->pz}; SColumnIndex index = COLUMN_INDEX_INITIALIZER; + bool udf = false; + + if (pQueryInfo->pUdfInfo && taosArrayGetSize(pQueryInfo->pUdfInfo) > 0) { + int32_t usize = taosArrayGetSize(pQueryInfo->pUdfInfo); + + for (int32_t i = 0; i < usize; ++i) { + SUdfInfo* pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, i); + if (pUdfInfo->funcType == TSDB_UDF_TYPE_SCALAR) { + udf = true; + break; + } + } + } if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { // super table query if (getColumnIndexByName(&columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { @@ -5832,6 +5855,9 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq pQueryInfo->groupbyExpr.orderType = p1->sortOrder; pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId; + if (udf) { + return invalidOperationMsg(pMsgBuf, msg11); + } } else if (isTopBottomQuery(pQueryInfo)) { /* order of top/bottom query in interval is not valid */ @@ -5853,6 +5879,10 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq } else { tVariantListItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0); + if (udf) { + return invalidOperationMsg(pMsgBuf, msg11); + } + pQueryInfo->order.order = p1->sortOrder; pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX; @@ -5880,9 +5910,15 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq } else if (orderByGroupbyCol){ pQueryInfo->order.order = pItem->sortOrder; pQueryInfo->order.orderColId = index.columnIndex; + if (udf) { + return invalidOperationMsg(pMsgBuf, msg11); + } } else { pQueryInfo->order.order = pItem->sortOrder; pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX; + if (udf) { + return invalidOperationMsg(pMsgBuf, msg11); + } } pItem = taosArrayGet(pSqlNode->pSortOrder, 1); @@ -5918,6 +5954,10 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq return invalidOperationMsg(pMsgBuf, msg7); } + if (udf) { + return invalidOperationMsg(pMsgBuf, msg11); + } + tVariantListItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0); pQueryInfo->groupbyExpr.orderIndex = pSchema[index.columnIndex].colId; pQueryInfo->groupbyExpr.orderType = p1->sortOrder; @@ -5951,6 +5991,10 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq return TSDB_CODE_SUCCESS; } + if (udf) { + return invalidOperationMsg(pMsgBuf, msg11); + } + tVariantListItem* pItem = taosArrayGet(pSqlNode->pSortOrder, 0); pQueryInfo->order.order = pItem->sortOrder; pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId; @@ -5963,6 +6007,10 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq return invalidOperationMsg(pMsgBuf, msg1); } + if (udf) { + return invalidOperationMsg(pMsgBuf, msg11); + } + tVariantListItem* pItem = taosArrayGet(pSqlNode->pSortOrder, 0); pQueryInfo->order.order = pItem->sortOrder; pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId; @@ -6273,6 +6321,13 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER; SStrToken name = {.type = TK_STRING, .z = pItem->name, .n = (uint32_t)strlen(pItem->name)}; + //handle Escape character backstick + if (name.z[0] == TS_ESCAPE_CHAR && name.z[name.n - 1] == TS_ESCAPE_CHAR) { + memmove(name.z, name.z + 1, name.n); + name.z[name.n - TS_ESCAPE_CHAR_SIZE] = '\0'; + name.n -= TS_ESCAPE_CHAR_SIZE; + } + if (getColumnIndexByName(&name, pQueryInfo, &columnIndex, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(pMsg, msg17); } @@ -6606,6 +6661,9 @@ int32_t validateColumnName(char* name) { } return validateColumnName(token.z); + } else if (token.type == TK_ID) { + strRmquoteEscape(name, token.n); + return TSDB_CODE_SUCCESS; } else { if (isNumber(&token)) { return TSDB_CODE_TSC_INVALID_OPERATION; @@ -7245,7 +7303,7 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, char* const char* msg3 = "group by/session/state_window not allowed on projection query"; const char* msg4 = "retrieve tags not compatible with group by or interval query"; const char* msg5 = "functions can not be mixed up"; - const char* msg6 = "TWA/Diff/Derivative/Irate only support group by tbname"; + const char* msg6 = "TWA/Diff/Derivative/Irate/CSum/MAvg only support group by tbname"; // only retrieve tags, group by is not supportted if (tscQueryTags(pQueryInfo)) { @@ -7298,10 +7356,16 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, char* } if (f < 0) { + SUdfInfo* pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, -1 * f - 1); + if (pUdfInfo->funcType == TSDB_UDF_TYPE_SCALAR) { + return invalidOperationMsg(msg, msg1); + } + continue; } - if ((!pQueryInfo->stateWindow) && (f == TSDB_FUNC_DIFF || f == TSDB_FUNC_DERIVATIVE || f == TSDB_FUNC_TWA || f == TSDB_FUNC_IRATE)) { + if ((!pQueryInfo->stateWindow) && (f == TSDB_FUNC_DIFF || f == TSDB_FUNC_DERIVATIVE || f == TSDB_FUNC_TWA || + f == TSDB_FUNC_IRATE || f == TSDB_FUNC_CSUM || f == TSDB_FUNC_MAVG)) { for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) { SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j); if (j == 0) { @@ -7320,6 +7384,10 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, char* return invalidOperationMsg(msg, msg1); } + if (IS_SCALAR_FUNCTION(aAggs[f].status)) { + return invalidOperationMsg(msg, msg1); + } + if (f == TSDB_FUNC_COUNT && pExpr->base.colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) { return invalidOperationMsg(msg, msg1); } @@ -7661,7 +7729,7 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { SCreatedTableInfo* pCreateTableInfo = taosArrayGet(pCreateTable->childTableInfo, j); SStrToken* pToken = &pCreateTableInfo->stableName; - + bool dbIncluded = false; char buf[TSDB_TABLE_FNAME_LEN]; SStrToken sTblToken; @@ -7721,10 +7789,19 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { for (int32_t i = 0; i < nameSize; ++i) { SStrToken* sToken = taosArrayGet(pNameList, i); + + char tmpTokenBuf[TSDB_MAX_BYTES_PER_ROW] = {0}; // create tmp buf to avoid alter orginal sqlstr + strncpy(tmpTokenBuf, sToken->z, sToken->n); + sToken->z = tmpTokenBuf; + if (TK_STRING == sToken->type) { tscDequoteAndTrimToken(sToken); } + if (TK_ID == sToken->type) { + tscRmEscapeAndTrimToken(sToken); + } + tVariantListItem* pItem = taosArrayGet(pValList, i); findColumnIndex = false; @@ -8558,12 +8635,33 @@ int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo) { if (functionId < 0) { struct SUdfInfo info = {0}; info.name = strndup(t->z, t->n); + info.keep = true; if (pQueryInfo->pUdfInfo == NULL) { pQueryInfo->pUdfInfo = taosArrayInit(4, sizeof(struct SUdfInfo)); + } else if (taosArrayGetSize(pQueryInfo->pUdfInfo) > 0) { + int32_t usize = (int32_t)taosArrayGetSize(pQueryInfo->pUdfInfo); + int32_t exist = 0; + + for (int32_t j = 0; j < usize; ++j) { + SUdfInfo* pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, j); + int32_t len = strlen(pUdfInfo->name); + if (len == t->n && strncasecmp(info.name, pUdfInfo->name, t->n) == 0) { + exist = 1; + break; + } + } + + if (exist) { + continue; + } } info.functionId = (int32_t)taosArrayGetSize(pQueryInfo->pUdfInfo) * (-1) - 1;; taosArrayPush(pQueryInfo->pUdfInfo, &info); + if (taosArrayGetSize(pQueryInfo->pUdfInfo) > 1) { + code = tscInvalidOperationMsg(pCmd->payload, "only one udf allowed", NULL); + goto _end; + } } } } diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 2ed8ea94b53955a2061ffe763cb0521daab30fd9..b19af46a0c7f191b84d1ea8658f13456624179c9 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -1102,6 +1102,11 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { // support only one udf if (pQueryInfo->pUdfInfo != NULL && taosArrayGetSize(pQueryInfo->pUdfInfo) > 0) { + if (taosArrayGetSize(pQueryInfo->pUdfInfo) > 1) { + code = tscInvalidOperationMsg(pCmd->payload, "only one udf allowed", NULL); + goto _end; + } + pQueryMsg->udfContentOffset = htonl((int32_t) (pMsg - pCmd->payload)); for(int32_t i = 0; i < taosArrayGetSize(pQueryInfo->pUdfInfo); ++i) { SUdfInfo* pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, i); diff --git a/src/client/src/tscSql.c b/src/client/src/tscSql.c index caddde3f088c8ea65743070563a093921c3d2b2d..bb3bddeefd798366fe205eb67b55b3b4a7301df4 100644 --- a/src/client/src/tscSql.c +++ b/src/client/src/tscSql.c @@ -629,6 +629,10 @@ static bool hasAdditionalErrorInfo(int32_t code, SSqlCmd *pCmd) { return false; } + if (pCmd->payload == NULL) { + return false; + } + size_t len = strlen(pCmd->payload); char *z = NULL; diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index 5861527869359c707b359c3e3c512d164f0854b5..b14c5af47a54e8917c97cec4d1e31acebda9f602 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -1271,6 +1271,28 @@ void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQue .pGroupList = taosArrayInit(1, POINTER_BYTES), }; + SUdfInfo* pUdfInfo = NULL; + + size_t size = tscNumOfExprs(px); + for (int32_t j = 0; j < size; ++j) { + SExprInfo* pExprInfo = tscExprGet(px, j); + + int32_t functionId = pExprInfo->base.functionId; + if (functionId < 0) { + if (pUdfInfo) { + pSql->res.code = tscInvalidOperationMsg(pSql->cmd.payload, "only one udf allowed", NULL); + return; + } + + pUdfInfo = taosArrayGet(px->pUdfInfo, -1 * functionId - 1); + int32_t code = initUdfInfo(pUdfInfo); + if (code != TSDB_CODE_SUCCESS) { + pSql->res.code = code; + return; + } + } + } + tableGroupInfo.map = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK); STableKeyInfo tableKeyInfo = {.pTable = NULL, .lastKey = INT64_MIN}; @@ -1352,6 +1374,9 @@ void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQue tscDebug("0x%"PRIx64" create QInfo 0x%"PRIx64" to execute the main query while all nest queries are ready", pSql->self, pSql->self); px->pQInfo = createQInfoFromQueryNode(px, &tableGroupInfo, pSourceOperator, NULL, NULL, MASTER_SCAN, pSql->self); + px->pQInfo->runtimeEnv.udfIsCopy = true; + px->pQInfo->runtimeEnv.pUdfInfo = pUdfInfo; + tfree(pColumnInfo); tfree(schema); @@ -4800,9 +4825,14 @@ int32_t createProjectionExpr(SQueryInfo* pQueryInfo, STableMetaInfo* pTableMetaI functionId = TSDB_FUNC_STDDEV; } + SUdfInfo* pUdfInfo = NULL; + if (functionId < 0) { + pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, -1 * functionId - 1); + } + int32_t inter = 0; getResultDataInfo(pSource->base.colType, pSource->base.colBytes, functionId, 0, &pse->resType, - &pse->resBytes, &inter, 0, false, NULL); + &pse->resBytes, &inter, 0, false, pUdfInfo); pse->colType = pse->resType; pse->colBytes = pse->resBytes; diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java index 6565a8151e6b16d7f04b184e93dbe89d85466533..5cdaa3c70c334bc7bd97be08f2318e6fc548d22a 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java @@ -49,7 +49,7 @@ public class TSDBResultSetRowData { } /** - * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use an index start from 1 in JDBC api */ public void setBooleanValue(int col, boolean value) { setBoolean(col - 1, value); @@ -86,7 +86,7 @@ public class TSDBResultSetRowData { } /** - * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use an index start from 1 in JDBC api */ public void setByteValue(int colIndex, byte value) { setByte(colIndex - 1, value); @@ -100,7 +100,7 @@ public class TSDBResultSetRowData { } /** - * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use an index start from 1 in JDBC api */ public void setShortValue(int colIndex, short value) { setShort(colIndex - 1, value); @@ -114,7 +114,7 @@ public class TSDBResultSetRowData { } /** - * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use an index start from 1 in JDBC api */ public void setIntValue(int colIndex, int value) { setInt(colIndex - 1, value); @@ -194,7 +194,7 @@ public class TSDBResultSetRowData { /** - * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use an index start from 1 in JDBC api */ public void setLongValue(int colIndex, long value) { setLong(colIndex - 1, value); @@ -262,7 +262,7 @@ public class TSDBResultSetRowData { } /** - * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use an index start from 1 in JDBC api */ public void setFloatValue(int colIndex, float value) { setFloat(colIndex - 1, value); @@ -302,7 +302,7 @@ public class TSDBResultSetRowData { } /** - * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use an index start from 1 in JDBC api */ public void setDoubleValue(int colIndex, double value) { setDouble(colIndex - 1, value); @@ -342,7 +342,7 @@ public class TSDBResultSetRowData { } /** - * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use an index start from 1 in JDBC api */ public void setStringValue(int colIndex, String value) { data.set(colIndex - 1, value); @@ -361,7 +361,7 @@ public class TSDBResultSetRowData { } /** - * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use an index start from 1 in JDBC api */ public void setByteArrayValue(int colIndex, byte[] value) { setByteArray(colIndex - 1, value); @@ -424,7 +424,7 @@ public class TSDBResultSetRowData { } /** - * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use an index start from 1 in JDBC api */ public void setTimestampValue(int colIndex, long value) { setTimestamp(colIndex - 1, value, 0); diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetWrapper.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetWrapper.java index 48854e773f89a45784de3cd709ec5bbe6185e09b..0a9f017cbbd775cf710f3bac4440ee8a43403870 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetWrapper.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetWrapper.java @@ -23,7 +23,7 @@ import java.util.Calendar; import java.util.Map; /* - * TDengine only supports a subset of the standard SQL, thus this implemetation of the + * TDengine only supports a subset of the standard SQL, thus this implementation of the * standard JDBC API contains more or less some adjustments customized for certain * compatibility needs. */ diff --git a/src/connector/python/examples/insert-lines.py b/src/connector/python/examples/insert-lines.py index 755050dfb52b180567dd80e87b63508fc4101172..1d20af7e9bcac23deb70c1dbd058bb86dd5585a5 100644 --- a/src/connector/python/examples/insert-lines.py +++ b/src/connector/python/examples/insert-lines.py @@ -1,4 +1,5 @@ import taos +from taos import SmlProtocol, SmlPrecision conn = taos.connect() dbname = "pytest_line" @@ -9,10 +10,10 @@ conn.select_db(dbname) lines = [ 'st,t1=3i64,t2=4f64,t3="t3" c1=3i64,c3=L"pass",c2=false,c4=4f64 1626006833639000000', ] -conn.schemaless_insert(lines, 0, "ns") +conn.schemaless_insert(lines, taos.SmlProtocol.LINE_PROTOCOL, taos.SmlPrecision.NOT_CONFIGURED) print("inserted") -conn.schemaless_insert(lines, 0, "ns") +conn.schemaless_insert(lines, taos.SmlProtocol.LINE_PROTOCOL, taos.SmlPrecision.NOT_CONFIGURED) result = conn.query("show tables") for row in result: diff --git a/src/connector/python/pyproject.toml b/src/connector/python/pyproject.toml index a8099199563a0e5957a7d69e75bab65cca6d17db..da61cccf49429251d49f2cba495e24e146244c85 100644 --- a/src/connector/python/pyproject.toml +++ b/src/connector/python/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "taos" -version = "2.1.0" +version = "2.1.1" description = "TDengine connector for python" authors = ["Taosdata Inc. "] license = "AGPL-3.0" diff --git a/src/connector/python/setup.py b/src/connector/python/setup.py index b7e10001737bc40c04173ea4a65e95248965ffda..8f1dfafe4762e4a55a6d3e7c645c945a67a10f68 100644 --- a/src/connector/python/setup.py +++ b/src/connector/python/setup.py @@ -5,7 +5,7 @@ with open("README.md", "r") as fh: setuptools.setup( name="taos", - version="2.1.0", + version="2.1.1", author="Taosdata Inc.", author_email="support@taosdata.com", description="TDengine python client package", diff --git a/src/connector/python/taos/__init__.py b/src/connector/python/taos/__init__.py index ebbad68c5a8a148a601fb5ec48f9658a1920ed62..2520984e78fad236227d9cf55c29ace92878d3bf 100644 --- a/src/connector/python/taos/__init__.py +++ b/src/connector/python/taos/__init__.py @@ -440,6 +440,7 @@ from .cursor import * from .result import * from .statement import * from .subscription import * +from .schemaless import * try: import importlib.metadata @@ -468,6 +469,8 @@ __all__ = [ "TaosRow", "TaosStmt", "PrecisionEnum", + "SmlPrecision", + "SmlProtocol" ] def connect(*args, **kwargs): diff --git a/src/connector/python/taos/cinterface.py b/src/connector/python/taos/cinterface.py index 1fcbf678b6a2a3f51bd757b84c08a7693166556c..4365c7eabc509f95525078378ff76d46a884c075 100644 --- a/src/connector/python/taos/cinterface.py +++ b/src/connector/python/taos/cinterface.py @@ -12,6 +12,7 @@ except: from .error import * from .bind import * from .field import * +from .schemaless import * # stream callback @@ -64,6 +65,8 @@ _libtaos.taos_consume.restype = ctypes.c_void_p _libtaos.taos_fetch_lengths.restype = ctypes.POINTER(ctypes.c_int) _libtaos.taos_free_result.restype = None _libtaos.taos_query.restype = ctypes.POINTER(ctypes.c_void_p) +_libtaos.taos_schemaless_insert.restype = ctypes.c_void_p + try: _libtaos.taos_stmt_errstr.restype = c_char_p except AttributeError: @@ -808,25 +811,27 @@ def taos_stmt_use_result(stmt): return result try: - _libtaos.taos_insert_lines.restype = c_int - _libtaos.taos_insert_lines.argstype = c_void_p, c_void_p, c_int + _libtaos.taos_schemaless_insert.restype = c_void_p + _libtaos.taos_schemaless_insert.argstype = c_void_p, c_void_p, c_int, c_int, c_int except AttributeError: - print("WARNING: libtaos(%s) does not support insert_lines" % taos_get_client_info()) - - - + print("WARNING: libtaos(%s) does not support taos_schemaless_insert" % taos_get_client_info()) def taos_schemaless_insert(connection, lines, protocol, precision): - # type: (c_void_p, list[str] | tuple(str)) -> None + # type: (c_void_p, list[str] | tuple(str), SmlProtocol, SmlPrecision) -> int num_of_lines = len(lines) lines = (c_char_p(line.encode("utf-8")) for line in lines) lines_type = ctypes.c_char_p * num_of_lines p_lines = lines_type(*lines) - if precision != None: - precision = c_char_p(precision.encode("utf-8")) - errno = _libtaos.taos_schemaless_insert(connection, p_lines, num_of_lines, protocol, precision) + res = c_void_p(_libtaos.taos_schemaless_insert(connection, p_lines, num_of_lines, protocol, precision)) + errno = taos_errno(res) + affected_rows = taos_affected_rows(res) if errno != 0: - raise SchemalessError("schemaless insert error", errno) + errstr = taos_errstr(res) + taos_free_result(res) + raise SchemalessError(errstr, errno, affected_rows) + + taos_free_result(res) + return affected_rows class CTaosInterface(object): def __init__(self, config=None): diff --git a/src/connector/python/taos/connection.py b/src/connector/python/taos/connection.py index dfac42f244d19267124c5ea790d4503e28fd5a78..dc8225ab33c84930214eb8f0d8ba47f6f31a5adf 100644 --- a/src/connector/python/taos/connection.py +++ b/src/connector/python/taos/connection.py @@ -72,10 +72,9 @@ class TaosConnection(object): taos_select_db(self._conn, database) def execute(self, sql): - # type: (str) -> None + # type: (str) -> int """Simplely execute sql ignoring the results""" - res = taos_query(self._conn, sql) - taos_free_result(res) + return self.query(sql).affected_rows def query(self, sql): # type: (str) -> TaosResult @@ -118,7 +117,7 @@ class TaosConnection(object): return TaosStream(stream) def schemaless_insert(self, lines, protocol, precision): - # type: (list[str]) -> None + # type: (list[str], SmlProtocol, SmlPrecision) -> int """ 1.Line protocol and schemaless support @@ -171,6 +170,7 @@ class TaosConnection(object): conn.schemaless_insert(lines, 2, None) """ + print(lines, protocol, precision) return taos_schemaless_insert(self._conn, lines, protocol, precision) diff --git a/src/connector/python/taos/error.py b/src/connector/python/taos/error.py index 723f6f1a2db1249a3773538b4bfa6d51595a005d..122466fe3c448ec551fb910c402ad14bb6c93336 100644 --- a/src/connector/python/taos/error.py +++ b/src/connector/python/taos/error.py @@ -83,7 +83,16 @@ class ResultError(DatabaseError): class SchemalessError(DatabaseError): """taos_schemaless_insert errors.""" - pass + def __init__(self, msg=None, errno=0xffff, affected_rows=0): + DatabaseError.__init__(self, msg, errno) + self.affected_rows = affected_rows + + def __str__(self): + return self._full_msg + "(affected rows: %d)" % self.affected_rows + + # @property + # def affected_rows(self): + # return self.affected_rows class StatementError(DatabaseError): diff --git a/src/connector/python/taos/result.py b/src/connector/python/taos/result.py index 81151733615d1b7fdc3318b6e53888ae39d32b14..c9feb4d6502515cc6e3e2d4be688f2e7fcd895b2 100644 --- a/src/connector/python/taos/result.py +++ b/src/connector/python/taos/result.py @@ -123,6 +123,12 @@ class TaosResult(object): for i in range(len(self._fields)): buffer[i].extend(block[i]) return list(map(tuple, zip(*buffer))) + + def fetch_all_into_dict(self): + """Fetch all rows and convert it to dict""" + names = [field.name for field in self.fields] + rows = self.fetch_all() + return list(dict(zip(names, row)) for row in rows) def fetch_rows_a(self, callback, param): taos_fetch_rows_a(self._result, callback, param) @@ -228,6 +234,12 @@ class TaosRow: blocks[i] = CONVERT_FUNC[fields[i].type](data, 1, field_lens[i], precision)[0] return tuple(blocks) + def as_dict(self): + values = self.as_tuple() + names = self._result.fields + dict(zip(names, values)) + + class TaosBlocks: """TDengine result blocks iterator""" diff --git a/src/connector/python/taos/schemaless.py b/src/connector/python/taos/schemaless.py new file mode 100644 index 0000000000000000000000000000000000000000..35967412f78a63e67d63f0e58bbf903f21fb275a --- /dev/null +++ b/src/connector/python/taos/schemaless.py @@ -0,0 +1,17 @@ + +class SmlPrecision: + """Schemaless timestamp precision constants""" + NOT_CONFIGURED = 0 # C.TSDB_SML_TIMESTAMP_NOT_CONFIGURED + HOURS = 1 + MINUTES = 2 + SECONDS = 3 + MILLI_SECONDS = 4 + MICRO_SECONDS = 5 + NANO_SECONDS = 6 + +class SmlProtocol: + """Schemaless protocol constants""" + UNKNOWN_PROTOCOL = 0 + LINE_PROTOCOL = 1 + TELNET_PROTOCOL = 2 + JSON_PROTOCOL = 3 \ No newline at end of file diff --git a/src/connector/python/tests/test_lines.py b/src/connector/python/tests/test_lines.py index 157580f8466ce765246184421f0756958455a54b..51d23b8e891d398b404086fdb2ff2910dcc1eb0a 100644 --- a/src/connector/python/tests/test_lines.py +++ b/src/connector/python/tests/test_lines.py @@ -1,4 +1,4 @@ -from taos.error import OperationalError +from taos.error import OperationalError, SchemalessError from taos import connect, new_bind_params, PrecisionEnum from taos import * @@ -13,35 +13,95 @@ def conn(): return connect() +def test_schemaless_insert_update_2(conn): + # type: (TaosConnection) -> None + + dbname = "test_schemaless_insert_update_2" + try: + conn.execute("drop database if exists %s" % dbname) + conn.execute("create database if not exists %s update 2 precision 'ns'" % dbname) + conn.select_db(dbname) + + lines = [ + 'st,t1=4i64,t3="t4",t2=5f64,t4=5f64 c1=3i64,c3=L"passitagin, abc",c2=true,c4=5f64,c5=5f64,c6=7u64 1626006933640000000', + ] + res = conn.schemaless_insert(lines, 1, 0) + print("affected rows: ", res) + assert(res == 1) + + result = conn.query("select * from st") + [before] = result.fetch_all_into_dict() + assert(before["c3"] == "passitagin, abc") + + lines = [ + 'st,t1=4i64,t3="t4",t2=5f64,t4=5f64 c1=3i64,c3=L"passitagin",c2=true,c4=5f64,c5=5f64,c6=7u64 1626006933640000000', + ] + res = conn.schemaless_insert(lines, 1, 0) + result = conn.query("select * from st") + [after] = result.fetch_all_into_dict() + assert(after["c3"] == "passitagin") + + conn.execute("drop database if exists %s" % dbname) + conn.close() + + except Exception as err: + conn.execute("drop database if exists %s" % dbname) + conn.close() + print(err) + raise err + def test_schemaless_insert(conn): # type: (TaosConnection) -> None dbname = "pytest_taos_schemaless_insert" try: conn.execute("drop database if exists %s" % dbname) - conn.execute("create database if not exists %s precision 'us'" % dbname) + conn.execute("create database if not exists %s update 2 precision 'ns'" % dbname) conn.select_db(dbname) lines = [ 'st,t1=3i64,t2=4f64,t3="t3" c1=3i64,c3=L"passit",c2=false,c4=4f64 1626006833639000000', - 'st,t1=4i64,t3="t4",t2=5f64,t4=5f64 c1=3i64,c3=L"passitagin",c2=true,c4=5f64,c5=5f64,c6=7u64 1626006933640000000', + 'st,t1=4i64,t3="t4",t2=5f64,t4=5f64 c1=3i64,c3=L"passitagin, abc",c2=true,c4=5f64,c5=5f64,c6=7u64 1626006933640000000', 'stf,t1=4i64,t3="t4",t2=5f64,t4=5f64 c1=3i64,c3=L"passitagin_stf",c2=false,c5=5f64,c6=7u64 1626006933641000000', ] - conn.schemaless_insert(lines, 0, "ns") - print("inserted") + res = conn.schemaless_insert(lines, 1, 0) + print("affected rows: ", res) + assert(res == 3) lines = [ 'stf,t1=5i64,t3="t4",t2=5f64,t4=5f64 c1=3i64,c3=L"passitagin_stf",c2=false,c5=5f64,c6=7u64 1626006933641000000', ] - conn.schemaless_insert(lines, 0, "ns") - print("inserted") + res = conn.schemaless_insert(lines, 1, 0) + print("affected rows: ", res) + assert(res == 1) + result = conn.query("select * from st") + + dict2 = result.fetch_all_into_dict() + print(dict2) + result.row_count + all = result.rows_iter() + for row in all: + print(row) + result.close() + assert(result.row_count == 2) + + # error test + lines = [ + ',t1=3i64,t2=4f64,t3="t3" c1=3i64,c3=L"passit",c2=false,c4=4f64 1626006833639000000', + ] + try: + res = conn.schemaless_insert(lines, 1, 0) + print(res) + # assert(False) + except SchemalessError as err: + pass + result = conn.query("select * from st") - print(*result.fields) + result.row_count all = result.rows_iter() for row in all: print(row) result.close() - print(result.row_count) conn.execute("drop database if exists %s" % dbname) conn.close() @@ -55,3 +115,4 @@ def test_schemaless_insert(conn): if __name__ == "__main__": test_schemaless_insert(connect()) + test_schemaless_insert_update_2(connect()) diff --git a/src/connector/python/tests/test_stmt.py b/src/connector/python/tests/test_stmt.py index 938ba10eb3d2377a63f7972deb99dbd47f7de1b2..3368ecb6a9336a4295790f2cd55314ac9bb6290e 100644 --- a/src/connector/python/tests/test_stmt.py +++ b/src/connector/python/tests/test_stmt.py @@ -1,3 +1,4 @@ +# encoding:UTF-8 from taos import * from ctypes import * diff --git a/src/inc/taos.h b/src/inc/taos.h index da91ed16c8186d15e109aaf03b18c6ca4ce86837..4afec942ff991ce1009cb8c54113562f93f9c92d 100644 --- a/src/inc/taos.h +++ b/src/inc/taos.h @@ -72,6 +72,23 @@ typedef enum { SET_CONF_RET_ERR_TOO_LONG = -6 } SET_CONF_RET_CODE; +typedef enum { + TSDB_SML_UNKNOWN_PROTOCOL = 0, + TSDB_SML_LINE_PROTOCOL = 1, + TSDB_SML_TELNET_PROTOCOL = 2, + TSDB_SML_JSON_PROTOCOL = 3, +} TSDB_SML_PROTOCOL_TYPE; + +typedef enum { + TSDB_SML_TIMESTAMP_NOT_CONFIGURED = 0, + TSDB_SML_TIMESTAMP_HOURS, + TSDB_SML_TIMESTAMP_MINUTES, + TSDB_SML_TIMESTAMP_SECONDS, + TSDB_SML_TIMESTAMP_MILLI_SECONDS, + TSDB_SML_TIMESTAMP_MICRO_SECONDS, + TSDB_SML_TIMESTAMP_NANO_SECONDS, +} TSDB_SML_TIMESTAMP_TYPE; + #define RET_MSG_LENGTH 1024 typedef struct setConfRet { SET_CONF_RET_CODE retCode; @@ -188,7 +205,7 @@ DLL_EXPORT void taos_close_stream(TAOS_STREAM *tstr); DLL_EXPORT int taos_load_table_info(TAOS *taos, const char* tableNameList); -DLL_EXPORT int taos_schemaless_insert(TAOS* taos, char* lines[], int numLines, int protocol, char* precision); +DLL_EXPORT TAOS_RES *taos_schemaless_insert(TAOS* taos, char* lines[], int numLines, int protocol, int precision); #ifdef __cplusplus } diff --git a/src/inc/taosdef.h b/src/inc/taosdef.h index d7848937b137c2e458c567099e3df0e386eb92fa..78fb2ac01c1d8cd01d8d704a384891125f8bb00e 100644 --- a/src/inc/taosdef.h +++ b/src/inc/taosdef.h @@ -99,6 +99,7 @@ extern const int32_t TYPE_BYTES[15]; #define TS_PATH_DELIMITER "." #define TS_ESCAPE_CHAR '`' +#define TS_ESCAPE_CHAR_SIZE 2 #define TSDB_TIME_PRECISION_MILLI 0 #define TSDB_TIME_PRECISION_MICRO 1 diff --git a/src/inc/tsdb.h b/src/inc/tsdb.h index ad7eaef8cbda7a52f9e2340969d7ab95791d127d..9d82245c2199b5fa0b62d709a08633e5a976b007 100644 --- a/src/inc/tsdb.h +++ b/src/inc/tsdb.h @@ -421,9 +421,6 @@ bool tsdbNoProblem(STsdbRepo* pRepo); // unit of walSize: MB int tsdbCheckWal(STsdbRepo *pRepo, uint32_t walSize); -// not commit if other instances in committing state or waiting to commit -bool tsdbIsNeedCommit(STsdbRepo *pRepo); - #ifdef __cplusplus } #endif diff --git a/src/kit/taosdemo/taosdemo.c b/src/kit/taosdemo/taosdemo.c index 87757443f103e19f8809f4b906805ab539fcc4af..3acffe06ed599fb952fb00a4b1e6e0c509c941e3 100644 --- a/src/kit/taosdemo/taosdemo.c +++ b/src/kit/taosdemo/taosdemo.c @@ -77,6 +77,7 @@ extern char configDir[]; #define MAX_DATA_SIZE (16*TSDB_MAX_COLUMNS)+20 // max record len: 16*MAX_COLUMNS, timestamp string and ,('') need extra space #define OPT_ABORT 1 /* –abort */ #define MAX_FILE_NAME_LEN 256 // max file name length on linux is 255. +#define MAX_PATH_LEN 4096 #define DEFAULT_START_TIME 1500000000000 @@ -511,7 +512,7 @@ typedef struct SThreadInfo_S { int threadID; char db_name[TSDB_DB_NAME_LEN]; uint32_t time_precision; - char filePath[TSDB_FILENAME_LEN]; + char filePath[MAX_PATH_LEN]; FILE *fp; char tb_prefix[TSDB_TABLE_NAME_LEN]; uint64_t start_table_from; @@ -3481,8 +3482,14 @@ static int postProceSql(char *host, uint16_t port, 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; - snprintf(userpass_buf, INPUT_BUF_LEN, "%s:%s", - g_Dbs.user, g_Dbs.password); + if (g_args.test_mode == INSERT_TEST) { + snprintf(userpass_buf, INPUT_BUF_LEN, "%s:%s", + g_Dbs.user, g_Dbs.password); + } else { + snprintf(userpass_buf, INPUT_BUF_LEN, "%s:%s", + g_queryInfo.user, g_queryInfo.password); + } + size_t userpass_buf_len = strlen(userpass_buf); size_t encoded_len = 4 * ((userpass_buf_len +2) / 3); @@ -3560,18 +3567,22 @@ static int postProceSql(char *host, uint16_t port, break; received += bytes; - verbosePrint("%s() LN%d: received:%d resp_len:%d, response_buf:\n%s\n", - __func__, __LINE__, received, resp_len, response_buf); + response_buf[RESP_BUF_LEN - 1] = '\0'; - if (((NULL != strstr(response_buf, resEncodingChunk)) - && (NULL != strstr(response_buf, resHttp))) - || ((NULL != strstr(response_buf, resHttpOk)) - && (NULL != strstr(response_buf, "\"status\":")))) { - debugPrint( - "%s() LN%d: received:%d resp_len:%d, response_buf:\n%s\n", + if (strlen(response_buf)) { + verbosePrint("%s() LN%d: received:%d resp_len:%d, response_buf:\n%s\n", __func__, __LINE__, received, resp_len, response_buf); - break; - } + + if (((NULL != strstr(response_buf, resEncodingChunk)) + && (NULL != strstr(response_buf, resHttp))) + || ((NULL != strstr(response_buf, resHttpOk)) + && (NULL != strstr(response_buf, "\"status\":")))) { + debugPrint( + "%s() LN%d: received:%d resp_len:%d, response_buf:\n%s\n", + __func__, __LINE__, received, resp_len, response_buf); + break; + } + } } while(received < resp_len); if (received == resp_len) { @@ -3579,8 +3590,6 @@ static int postProceSql(char *host, uint16_t port, ERROR_EXIT("storing complete response from socket"); } - response_buf[RESP_BUF_LEN - 1] = '\0'; - if (strlen(pThreadInfo->filePath) > 0) { appendResultBufToFile(response_buf, pThreadInfo); } @@ -4378,7 +4387,7 @@ static int createSuperTable( superTbl->lenOfTagOfOneRow = lenOfTagOfOneRow; - + snprintf(command, BUFFER_SIZE, superTbl->escapeChar ? "CREATE TABLE IF NOT EXISTS %s.`%s` (ts TIMESTAMP%s) TAGS %s": @@ -4513,7 +4522,7 @@ int createDatabasesAndStables(char *command) { if (g_Dbs.db[i].superTbls[j].iface == SML_IFACE) { goto skip; } - + sprintf(command, "describe %s.%s;", g_Dbs.db[i].dbName, g_Dbs.db[i].superTbls[j].stbName); ret = queryDbExec(taos, command, NO_INSERT_TYPE, true); @@ -4573,7 +4582,7 @@ static void* createTable(void *sarg) i <= pThreadInfo->end_table_to; i++) { if (0 == g_Dbs.use_metric) { snprintf(pThreadInfo->buffer, buff_len, - g_args.escapeChar ? + g_args.escapeChar ? "CREATE TABLE IF NOT EXISTS %s.`%s%"PRIu64"` %s;" : "CREATE TABLE IF NOT EXISTS %s.%s%"PRIu64" %s;", pThreadInfo->db_name, @@ -6602,7 +6611,7 @@ static int getRowDataFromSample( stbInfo->sampleDataBuf + stbInfo->lenOfOneRow * (*sampleUsePos)); } - + dataLen += snprintf(dataBuf + dataLen, maxLen - dataLen, ")"); (*sampleUsePos)++; @@ -7058,6 +7067,7 @@ static int32_t execInsert(threadInfo *pThreadInfo, uint32_t k) { int32_t affectedRows; SSuperTable* stbInfo = pThreadInfo->stbInfo; + TAOS_RES* res; int32_t code; uint16_t iface; if (stbInfo) @@ -7111,17 +7121,14 @@ static int32_t execInsert(threadInfo *pThreadInfo, uint32_t k) affectedRows = k; break; case SML_IFACE: - code = taos_schemaless_insert(pThreadInfo->taos, pThreadInfo->lines, k, 0, pThreadInfo->time_precision == TSDB_TIME_PRECISION_MILLI - ? "ms" - : (pThreadInfo->time_precision == TSDB_TIME_PRECISION_MICRO - ? "us" - : "ns")); - if (code) { + res = taos_schemaless_insert(pThreadInfo->taos, pThreadInfo->lines, k, 0, pThreadInfo->time_precision); + code = taos_errno(res); + affectedRows = taos_affected_rows(res); + if (code != TSDB_CODE_SUCCESS) { errorPrint2("%s() LN%d, failed to execute schemaless insert. reason: %s\n", - __func__, __LINE__, tstrerror(code)); + __func__, __LINE__, taos_errstr(res)); exit(EXIT_FAILURE); } - affectedRows = k; break; default: errorPrint2("%s() LN%d: unknown insert mode: %d\n", @@ -7139,7 +7146,7 @@ static void getTableName(char *pTblName, if (stbInfo) { if (AUTO_CREATE_SUBTBL != stbInfo->autoCreateTable) { if (stbInfo->childTblLimit > 0) { - snprintf(pTblName, TSDB_TABLE_NAME_LEN, + snprintf(pTblName, TSDB_TABLE_NAME_LEN, stbInfo->escapeChar ? "`%s`" : "%s", stbInfo->childTblName + (tableSeq - stbInfo->childTblOffset) * TSDB_TABLE_NAME_LEN); @@ -7152,12 +7159,12 @@ static void getTableName(char *pTblName, stbInfo->childTblName + tableSeq * TSDB_TABLE_NAME_LEN); } } else { - snprintf(pTblName, TSDB_TABLE_NAME_LEN, + snprintf(pTblName, TSDB_TABLE_NAME_LEN, stbInfo->escapeChar ? "`%s%"PRIu64"`" : "%s%"PRIu64"", stbInfo->childTblPrefix, tableSeq); } } else { - snprintf(pTblName, TSDB_TABLE_NAME_LEN, + snprintf(pTblName, TSDB_TABLE_NAME_LEN, g_args.escapeChar ? "`%s%"PRIu64"`" : "%s%"PRIu64"", g_args.tb_prefix, tableSeq); } @@ -9713,7 +9720,7 @@ static void generateSmlHead(char* smlHead, SSuperTable* stbInfo, threadInfo* pTh } } -static void generateSmlTail(char* line, char* smlHead, SSuperTable* stbInfo, +static void generateSmlTail(char* line, char* smlHead, SSuperTable* stbInfo, threadInfo* pThreadInfo, int64_t timestamp) { int dataLen = 0; dataLen = snprintf(line, BUFFER_SIZE, "%s ", smlHead); @@ -9860,7 +9867,7 @@ static void* syncWriteInterlaceSml(threadInfo *pThreadInfo, uint32_t interlaceRo } else { batchPerTblTimes = 1; } - + char *smlHead[pThreadInfo->ntables]; for (int t = 0; t < pThreadInfo->ntables; t++) { smlHead[t] = (char *)calloc(HEAD_BUFF_LEN, 1); @@ -9869,7 +9876,7 @@ static void* syncWriteInterlaceSml(threadInfo *pThreadInfo, uint32_t interlaceRo exit(EXIT_FAILURE); } generateSmlHead(smlHead[t], stbInfo, pThreadInfo, t); - + } pThreadInfo->totalInsertRows = 0; @@ -9895,11 +9902,11 @@ static void* syncWriteInterlaceSml(threadInfo *pThreadInfo, uint32_t interlaceRo pThreadInfo->lines = calloc(g_args.reqPerReq, sizeof(char *)); if (NULL == pThreadInfo->lines) { errorPrint2("Failed to alloc %"PRIu64" bytes, reason:%s\n", - g_args.reqPerReq * sizeof(char *), + g_args.reqPerReq * (uint64_t)sizeof(char *), strerror(errno)); return NULL; } - + while(pThreadInfo->totalInsertRows < pThreadInfo->ntables * insertRows) { if ((flagSleep) && (insert_interval)) { st = taosGetTimestampMs(); @@ -10450,10 +10457,8 @@ static void* syncWriteProgressiveSml(threadInfo *pThreadInfo) { debugPrint("%s() LN%d: ### sml progressive write\n", __func__, __LINE__); SSuperTable* stbInfo = pThreadInfo->stbInfo; - int64_t timeStampStep = - stbInfo?stbInfo->timeStampStep:g_args.timestamp_step; - int64_t insertRows = - (stbInfo)?stbInfo->insertRows:g_args.insertRows; + int64_t timeStampStep = stbInfo->timeStampStep; + int64_t insertRows = stbInfo->insertRows; verbosePrint("%s() LN%d insertRows=%"PRId64"\n", __func__, __LINE__, insertRows); @@ -10472,7 +10477,7 @@ static void* syncWriteProgressiveSml(threadInfo *pThreadInfo) { exit(EXIT_FAILURE); } generateSmlHead(smlHead[t], stbInfo, pThreadInfo, t); - + } int currentPercent = 0; int percentComplete = 0; @@ -10483,14 +10488,14 @@ static void* syncWriteProgressiveSml(threadInfo *pThreadInfo) { pThreadInfo->lines = calloc(g_args.reqPerReq, sizeof(char *)); if (NULL == pThreadInfo->lines) { errorPrint2("Failed to alloc %"PRIu64" bytes, reason:%s\n", - g_args.reqPerReq * sizeof(char *), + g_args.reqPerReq * (uint64_t)sizeof(char *), strerror(errno)); return NULL; } - + for (uint64_t i = 0; i < pThreadInfo->ntables; i++) { int64_t timestamp = pThreadInfo->start_time; - + for (uint64_t j = 0; j < insertRows;) { for (int k = 0; k < g_args.reqPerReq; k++) { pThreadInfo->lines[k] = calloc(BUFFER_SIZE, 1); @@ -10958,7 +10963,7 @@ static void startMultiThreadInsertData(int threads, char* db_name, int64_t ntables = 0; uint64_t tableFrom; - + if (stbInfo) { if (stbInfo->iface != SML_IFACE) { int64_t limit; @@ -11200,7 +11205,7 @@ static void startMultiThreadInsertData(int threads, char* db_name, pThreadInfo->start_time = pThreadInfo->start_time + rand_int() % 10000 - rand_tinyint(); } */ - + if (g_args.iface == REST_IFACE || ((stbInfo) && (stbInfo->iface == REST_IFACE))) { #ifdef WINDOWS WSADATA wsaData; @@ -11225,7 +11230,7 @@ static void startMultiThreadInsertData(int threads, char* db_name, } pThreadInfo->sockfd = sockfd; } - + tsem_init(&(pThreadInfo->lock_sem), 0, 0); if (ASYNC_MODE == g_Dbs.asyncMode) { @@ -11658,11 +11663,16 @@ static int insertTestProcess() { } } } else { - startMultiThreadInsertData( + if (SML_IFACE == g_args.iface) { + errorPrint2("%s\n", "Schemaless insertion must include stable"); + exit(EXIT_FAILURE); + } else { + startMultiThreadInsertData( g_Dbs.threadCount, g_Dbs.db[i].dbName, g_Dbs.db[i].dbCfg.precision, NULL); + } } } //end = taosGetTimestampMs(); diff --git a/src/kit/taosdump/taosdump.c b/src/kit/taosdump/taosdump.c index 317722ada99392965ff07cb2921a6acb6b92ef01..69ec2968218a9e5b2ca34551c60b6c44256298d2 100644 --- a/src/kit/taosdump/taosdump.c +++ b/src/kit/taosdump/taosdump.c @@ -2091,7 +2091,7 @@ static int getTableDes( memset(tableDes->cols[i].value, 0, sizeof(tableDes->cols[i].note)); char tbuf[COL_NOTE_LEN-2]; // need reserve 2 bytes for ' ' convertNCharToReadable((char *)row[TSDB_SHOW_TABLES_NAME_INDEX], length[0], tbuf, COL_NOTE_LEN); - sprintf(tableDes->cols[i].value, "\'%s\'", tbuf); + sprintf(tableDes->cols[i].value, "%s", tbuf); break; } case TSDB_DATA_TYPE_TIMESTAMP: diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt index 83e54b97965f9dd0f8c1b484979cfd2e8919dbb1..4cf444bab2f05816c1af55d96156334800d758d5 100644 --- a/src/plugins/CMakeLists.txt +++ b/src/plugins/CMakeLists.txt @@ -32,7 +32,7 @@ ELSE () MESSAGE("") MESSAGE("${Green} use blm3 as httpd ${ColourReset}") EXECUTE_PROCESS( - COMMAND cd blm3 + COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR}/blm3 ) EXECUTE_PROCESS( COMMAND git rev-parse --short HEAD diff --git a/src/plugins/blm3 b/src/plugins/blm3 index c67fcc11bc5e82e3d7aea8db855a8cbf8b109239..f56aa0f485d7bb6aebbcefc2007eeecdccb767c8 160000 --- a/src/plugins/blm3 +++ b/src/plugins/blm3 @@ -1 +1 @@ -Subproject commit c67fcc11bc5e82e3d7aea8db855a8cbf8b109239 +Subproject commit f56aa0f485d7bb6aebbcefc2007eeecdccb767c8 diff --git a/src/plugins/monitor/src/monMain.c b/src/plugins/monitor/src/monMain.c index 107d3be228685be9ecd92125f226749a8cf20588..fea793fa860fd17ff30bcecae1436180bc6b34bf 100644 --- a/src/plugins/monitor/src/monMain.c +++ b/src/plugins/monitor/src/monMain.c @@ -204,7 +204,6 @@ static void monBuildMonitorSql(char *sql, int32_t cmd) { ", disk_used float, disk_total int" ", band_speed float" ", io_read float, io_write float" - ", io_read_rate float, io_write_rate float" ", req_http int, req_select int, req_insert int" ") tags (dnodeid int, fqdn binary(%d))", tsMonitorDbName, TSDB_FQDN_LEN); @@ -326,10 +325,7 @@ static int32_t monBuildIoSql(char *sql) { monDebug("failed to get io info"); } - float readRate = readKB/tsMonitorInterval; - float writeRate = writeKB/tsMonitorInterval; - - return sprintf(sql, ", %f, %f, %f, %f", readKB, writeKB, readRate, writeRate); + return sprintf(sql, ", %f, %f", readKB, writeKB); } static void monSaveSystemInfo() { diff --git a/src/query/inc/qAggMain.h b/src/query/inc/qAggMain.h index 548b03e1108f87feac0af5f93be69d4ee5569477..8bcd8fea42aa46ad3dd2f0857d88a9b4bb76dd4d 100644 --- a/src/query/inc/qAggMain.h +++ b/src/query/inc/qAggMain.h @@ -233,6 +233,7 @@ int32_t isValidFunction(const char* name, int32_t len); #define IS_MULTIOUTPUT(x) (((x)&TSDB_FUNCSTATE_MO) != 0) #define IS_SINGLEOUTPUT(x) (((x)&TSDB_FUNCSTATE_SO) != 0) #define IS_OUTER_FORWARD(x) (((x)&TSDB_FUNCSTATE_OF) != 0) +#define IS_SCALAR_FUNCTION(x) (((x)&TSDB_FUNCSTATE_SCALAR) != 0) // determine the real data need to calculated the result enum { diff --git a/src/query/inc/qExecutor.h b/src/query/inc/qExecutor.h index 82f4f34a57c7d6d10a021fb2e426ff83cb3604e6..1bbc8a363ba3af678b42530db48eebb92deece48 100644 --- a/src/query/inc/qExecutor.h +++ b/src/query/inc/qExecutor.h @@ -312,7 +312,8 @@ typedef struct SQueryRuntimeEnv { STableQueryInfo *current; SRspResultInfo resultInfo; SHashObj *pTableRetrieveTsMap; - SUdfInfo *pUdfInfo; + SUdfInfo *pUdfInfo; + bool udfIsCopy; } SQueryRuntimeEnv; enum { diff --git a/src/query/inc/qUdf.h b/src/query/inc/qUdf.h index 1083b1e698f7591aae4586c7722e5343cd9c4d86..77da4b668ae08d10a6154cdece59ec62f5114be9 100644 --- a/src/query/inc/qUdf.h +++ b/src/query/inc/qUdf.h @@ -51,6 +51,7 @@ typedef struct SUdfInfo { SUdfInit init; char *content; char *path; + bool keep; } SUdfInfo; //script diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index c773efd9971009f47eee24a434365c3b6ef0db07..9457483714310c9ada01148345927f44718a28e8 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -988,13 +988,12 @@ void doInvokeUdf(SUdfInfo* pUdfInfo, SQLFunctionCtx *pCtx, int32_t idx, int32_t SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); void *interBuf = (void *)GET_ROWCELL_INTERBUF(pResInfo); if (pUdfInfo->isScript) { - (*(scriptFinalizeFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE])(pUdfInfo->pScriptCtx, pCtx->startTs, pCtx->pOutput, &output); + (*(scriptFinalizeFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE])(pUdfInfo->pScriptCtx, pCtx->startTs, pCtx->pOutput, (int32_t *)&pCtx->resultInfo->numOfRes); } else { - (*(udfFinalizeFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE])(pCtx->pOutput, interBuf, &output, &pUdfInfo->init); + (*(udfFinalizeFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE])(pCtx->pOutput, interBuf, (int32_t *)&pCtx->resultInfo->numOfRes, &pUdfInfo->init); } - // set the output value exist - pCtx->resultInfo->numOfRes = output; - if (output > 0) { + + if (pCtx->resultInfo->numOfRes > 0) { pCtx->resultInfo->hasResult = DATA_SET_FLAG; } @@ -2409,8 +2408,10 @@ static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) { tfree(pRuntimeEnv->sasArray); } - destroyUdfInfo(pRuntimeEnv->pUdfInfo); - + if (!pRuntimeEnv->udfIsCopy) { + destroyUdfInfo(pRuntimeEnv->pUdfInfo); + } + destroyResultBuf(pRuntimeEnv->pResultBuf); doFreeQueryHandle(pRuntimeEnv); @@ -8039,7 +8040,7 @@ static char* getUdfFuncName(char* funcname, char* name, int type) { } int32_t initUdfInfo(SUdfInfo* pUdfInfo) { - if (pUdfInfo == NULL) { + if (pUdfInfo == NULL || pUdfInfo->handle) { return TSDB_CODE_SUCCESS; } //qError("script len: %d", pUdfInfo->contLen); @@ -8074,10 +8075,21 @@ int32_t initUdfInfo(SUdfInfo* pUdfInfo) { // TODO check for failure of flush to disk /*size_t t = */ fwrite(pUdfInfo->content, pUdfInfo->contLen, 1, file); fclose(file); - tfree(pUdfInfo->content); + if (!pUdfInfo->keep) { + tfree(pUdfInfo->content); + } + if (pUdfInfo->path) { + unlink(pUdfInfo->path); + } + + tfree(pUdfInfo->path); pUdfInfo->path = strdup(path); + if (pUdfInfo->handle) { + taosCloseDll(pUdfInfo->handle); + } + pUdfInfo->handle = taosLoadDll(path); if (NULL == pUdfInfo->handle) { @@ -8092,9 +8104,17 @@ int32_t initUdfInfo(SUdfInfo* pUdfInfo) { pUdfInfo->funcs[TSDB_UDF_FUNC_INIT] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(funcname, pUdfInfo->name, TSDB_UDF_FUNC_INIT)); + pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(funcname, pUdfInfo->name, TSDB_UDF_FUNC_FINALIZE)); + pUdfInfo->funcs[TSDB_UDF_FUNC_MERGE] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(funcname, pUdfInfo->name, TSDB_UDF_FUNC_MERGE)); + if (pUdfInfo->funcType == TSDB_UDF_TYPE_AGGREGATE) { - pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(funcname, pUdfInfo->name, TSDB_UDF_FUNC_FINALIZE)); - pUdfInfo->funcs[TSDB_UDF_FUNC_MERGE] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(funcname, pUdfInfo->name, TSDB_UDF_FUNC_MERGE)); + if (NULL == pUdfInfo->funcs[TSDB_UDF_FUNC_MERGE] || NULL == pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE]) { + return TSDB_CODE_QRY_SYS_ERROR; + } + } else { + if (pUdfInfo->funcs[TSDB_UDF_FUNC_MERGE] || pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE]) { + return TSDB_CODE_QRY_SYS_ERROR; + } } pUdfInfo->funcs[TSDB_UDF_FUNC_DESTROY] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(funcname, pUdfInfo->name, TSDB_UDF_FUNC_DESTROY)); @@ -8201,7 +8221,7 @@ int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExp } int32_t param = (int32_t)pExprs[i].base.param[0].i64; - if (pExprs[i].base.functionId != TSDB_FUNC_ARITHM && + if (pExprs[i].base.functionId > 0 && pExprs[i].base.functionId != TSDB_FUNC_ARITHM && (type != pExprs[i].base.colType || bytes != pExprs[i].base.colBytes)) { tfree(pExprs); return TSDB_CODE_QRY_INVALID_MSG; diff --git a/src/tsdb/src/tsdbMain.c b/src/tsdb/src/tsdbMain.c index 23835d659d3157b789f61bd7e50f21861d863433..2dea0de055c3f71d3a13b5ecb3c92b878f25d1e6 100644 --- a/src/tsdb/src/tsdbMain.c +++ b/src/tsdb/src/tsdbMain.c @@ -185,19 +185,10 @@ int tsdbUnlockRepo(STsdbRepo *pRepo) { return 0; } -bool tsdbIsNeedCommit(STsdbRepo *pRepo) { - int nVal = 0; - if (sem_getvalue(&pRepo->readyToCommit, &nVal) != 0) { - tsdbError("vgId:%d failed to sem_getvalue of readyToCommit", REPO_ID(pRepo)); - return false; - } - return nVal > 0; -} - int tsdbCheckWal(STsdbRepo *pRepo, uint32_t walSize) { // MB STsdbCfg *pCfg = &(pRepo->config); if ((walSize > tsdbWalFlushSize) && (walSize > (pCfg->totalBlocks / 2 * pCfg->cacheBlockSize))) { - if (tsdbIsNeedCommit(pRepo) && (tsdbAsyncCommit(pRepo) < 0)) return -1; + if (tsdbAsyncCommit(pRepo) < 0) return -1; } return 0; } @@ -211,7 +202,7 @@ int tsdbCheckCommit(STsdbRepo *pRepo) { if ((pRepo->mem->extraBuffList != NULL) || ((listNEles(pRepo->mem->bufBlockList) >= pCfg->totalBlocks / 3) && (pBufBlock->remain < TSDB_BUFFER_RESERVE))) { // trigger commit - if (tsdbIsNeedCommit(pRepo) && (tsdbAsyncCommit(pRepo) < 0)) return -1; + if (tsdbAsyncCommit(pRepo) < 0) return -1; } return 0; } diff --git a/src/util/src/ttokenizer.c b/src/util/src/ttokenizer.c index 99ade6db1a76fdac48e441a2c1a9a2a3d388f812..8414b6292c43f674d62a61338ca271273922a209 100644 --- a/src/util/src/ttokenizer.c +++ b/src/util/src/ttokenizer.c @@ -628,7 +628,7 @@ SStrToken tStrGetToken(char* str, int32_t* i, bool isPrevOptr) { t0.n = 0; return t0; } - + t = str[++(*i)]; } diff --git a/src/util/src/tutil.c b/src/util/src/tutil.c index 35ec90cb2efbb270c8b007f9bdb347333a87fded..31556b83d06224d285db29650eba82c4d3acab5e 100644 --- a/src/util/src/tutil.c +++ b/src/util/src/tutil.c @@ -53,13 +53,13 @@ int32_t strdequote(char *z) { } -int32_t strRmquote(char *z, int32_t len){ +int32_t strRmquote(char *z, int32_t len){ // delete escape character: \\, \', \" char delim = z[0]; if (delim != '\'' && delim != '\"') { return len; } - + int32_t cnt = 0; int32_t j = 0; for (uint32_t k = 1; k < len - 1; ++k) { @@ -74,23 +74,24 @@ int32_t strRmquote(char *z, int32_t len){ continue; } } - + z[j] = z[k]; j++; } - + z[j] = 0; - + return len - 2 - cnt; } int32_t strRmquoteEscape(char *z, int32_t len) { if (len <= 0) return len; - + if (z[0] == '\'' || z[0] == '\"') { return strRmquote(z, len); } else if (len > 1 && z[0] == TS_ESCAPE_CHAR && z[len - 1] == TS_ESCAPE_CHAR) { memmove(z, z + 1, len - 2); + z[len - 2] = '\0'; return len - 2; } diff --git a/src/vnode/src/vnodeWrite.c b/src/vnode/src/vnodeWrite.c index 7f7d37a255ff42ab47be94507a33647fce853e8e..a0c772f5409ed7b231e2e655c849037f81f7c67e 100644 --- a/src/vnode/src/vnodeWrite.c +++ b/src/vnode/src/vnodeWrite.c @@ -169,7 +169,7 @@ static int32_t vnodeProcessSubmitMsg(SVnodeObj *pVnode, void *pCont, SRspRet *pR } static int32_t vnodeCheckWal(SVnodeObj *pVnode) { - if (tsdbIsNeedCommit(pVnode->tsdb)) { + if (pVnode->isCommiting == 0) { return tsdbCheckWal(pVnode->tsdb, walGetFSize(pVnode->wal) >> 20); } return 0; @@ -189,7 +189,7 @@ static int32_t vnodeProcessCreateTableMsg(SVnodeObj *pVnode, void *pCont, SRspRe ASSERT(code != 0); } - if (((++pVnode->tblMsgVer) & 16383) == 0) { // lazy check + if (((++pVnode->tblMsgVer) & 32767) == 0) { // lazy check vnodeCheckWal(pVnode); } diff --git a/tests/examples/c/apitest.c b/tests/examples/c/apitest.c index d9d2a41cb2782f1e919857d3a94c5f83946bb277..2c197887e7d7f1e6397213641a02ee8b37a84190 100644 --- a/tests/examples/c/apitest.c +++ b/tests/examples/c/apitest.c @@ -15,7 +15,7 @@ static void prepare_data(TAOS* taos) { result = taos_query(taos, "drop database if exists test;"); taos_free_result(result); usleep(100000); - result = taos_query(taos, "create database test precision 'us';"); + result = taos_query(taos, "create database test precision 'ns';"); taos_free_result(result); usleep(100000); taos_select_db(taos, "test"); @@ -288,12 +288,12 @@ void verify_stream(TAOS* taos) { taos_close_stream(strm); } -int32_t verify_schema_less(TAOS* taos) { +void verify_schema_less(TAOS* taos) { TAOS_RES* result; result = taos_query(taos, "drop database if exists test;"); taos_free_result(result); usleep(100000); - result = taos_query(taos, "create database test precision 'us' update 1;"); + result = taos_query(taos, "create database test precision 'ns' update 1 keep 36500;"); taos_free_result(result); usleep(100000); @@ -302,7 +302,7 @@ int32_t verify_schema_less(TAOS* taos) { taos_free_result(result); usleep(100000); - int code = 0; + int code = 0, affected_rows = 0; char* lines[] = { "st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000", @@ -316,41 +316,106 @@ int32_t verify_schema_less(TAOS* taos) { "stf,t1=4i64,t3=\"t4\",t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin_stf\",c2=false,c5=5f64,c6=7u64 1626006933641000000" }; - code = taos_schemaless_insert(taos, lines , sizeof(lines)/sizeof(char*), 0, "ns"); + result = taos_schemaless_insert(taos, lines , sizeof(lines)/sizeof(char*), TSDB_SML_LINE_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS); + code = taos_errno(result); + if (code != TSDB_CODE_SUCCESS) { + affected_rows = taos_affected_rows(result); + printf("\033[31m [lines1]taos_schemaless_insert failed, code: %d,%s, affected rows:%d \033[0m\n", code, taos_errstr(result), affected_rows); + } + taos_free_result(result); char* lines2[] = { "stg,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000", "stg,t1=4i64,t3=\"t4\",t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin\",c2=true,c4=5f64,c5=5f64 1626006833641000000" }; - code = taos_schemaless_insert(taos, &lines2[0], 1, 0, "ns"); - code = taos_schemaless_insert(taos, &lines2[1], 1, 0, "ns"); + result = taos_schemaless_insert(taos, &lines2[0], 1, TSDB_SML_LINE_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS); + code = taos_errno(result); + if (code != TSDB_CODE_SUCCESS) { + affected_rows = taos_affected_rows(result); + printf("\033[31m [lines2_0]taos_schemaless_insert failed, code: %d,%s, affected rows:%d \033[0m\n", code, taos_errstr(result), affected_rows); + } + taos_free_result(result); + + result = taos_schemaless_insert(taos, &lines2[1], 1, TSDB_SML_LINE_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS); + code = taos_errno(result); + if (code != TSDB_CODE_SUCCESS) { + affected_rows = taos_affected_rows(result); + printf("\033[31m [lines2_1]taos_schemaless_insert failed, code: %d,%s, affected rows:%d \033[0m\n", code, taos_errstr(result), affected_rows); + } + taos_free_result(result); char* lines3[] = { "sth,t1=4i64,t2=5f64,t4=5f64,ID=childTable c1=3i64,c3=L\"passitagin_stf\",c2=false,c5=5f64,c6=7u64 1626006933641", "sth,t1=4i64,t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin_stf\",c2=false,c5=5f64,c6=7u64 1626006933654" }; - code = taos_schemaless_insert(taos, lines3, 2, 0, "ms"); + result = taos_schemaless_insert(taos, lines3, 2, TSDB_SML_LINE_PROTOCOL, TSDB_SML_TIMESTAMP_MILLI_SECONDS); + code = taos_errno(result); + if (code != TSDB_CODE_SUCCESS) { + affected_rows = taos_affected_rows(result); + printf("\033[31m [lines3]taos_schemaless_insert failed, code: %d,%s, affected rows:%d \033[0m\n", code, taos_errstr(result), affected_rows); + } + taos_free_result(result); char* lines4[] = { "st123456,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000", "dgtyqodr,t2=5f64,t3=L\"ste\" c1=tRue,c2=4i64,c3=\"iam\" 1626056811823316532" }; - code = taos_schemaless_insert(taos, lines4, 2, 0, "ns"); + result = taos_schemaless_insert(taos, lines4, 2, TSDB_SML_LINE_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS); + code = taos_errno(result); + if (code != TSDB_CODE_SUCCESS) { + affected_rows = taos_affected_rows(result); + printf("\033[31m [lines4]taos_schemaless_insert failed, code: %d,%s, affected rows:%d \033[0m\n", code, taos_errstr(result), affected_rows); + } + taos_free_result(result); + char* lines5[] = { "zqlbgs,id=zqlbgs_39302_21680,t0=f,t1=127i8,t2=32767i16,t3=2147483647i32,t4=9223372036854775807i64,t5=11.12345f32,t6=22.123456789f64,t7=\"binaryTagValue\",t8=L\"ncharTagValue\" c0=f,c1=127i8,c2=32767i16,c3=2147483647i32,c4=9223372036854775807i64,c5=11.12345f32,c6=22.123456789f64,c7=\"binaryColValue\",c8=L\"ncharColValue\",c9=7u64 1626006833639000000", "zqlbgs,t9=f,id=zqlbgs_39302_21680,t0=f,t1=127i8,t11=127i8,t2=32767i16,t3=2147483647i32,t4=9223372036854775807i64,t5=11.12345f32,t6=22.123456789f64,t7=\"binaryTagValue\",t8=L\"ncharTagValue\",t10=L\"ncharTagValue\" c10=f,c0=f,c1=127i8,c12=127i8,c2=32767i16,c3=2147483647i32,c4=9223372036854775807i64,c5=11.12345f32,c6=22.123456789f64,c7=\"binaryColValue\",c8=L\"ncharColValue\",c9=7u64,c11=L\"ncharColValue\" 1626006833639000000" }; - code = taos_schemaless_insert(taos, &lines5[0], 1, 0, "ns"); - code = taos_schemaless_insert(taos, &lines5[1], 1, 0, "ns"); + result = taos_schemaless_insert(taos, &lines5[0], 1, TSDB_SML_LINE_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS); + code = taos_errno(result); + if (code != TSDB_CODE_SUCCESS) { + affected_rows = taos_affected_rows(result); + printf("\033[31m [lines5_0]taos_schemaless_insert failed, code: %d,%s, affected rows:%d \033[0m\n", code, taos_errstr(result), affected_rows); + } + taos_free_result(result); + + result = taos_schemaless_insert(taos, &lines5[1], 1, TSDB_SML_LINE_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS); + code = taos_errno(result); + if (code != TSDB_CODE_SUCCESS) { + affected_rows = taos_affected_rows(result); + printf("\033[31m [lines5_1]taos_schemaless_insert failed, code: %d,%s, affected rows:%d \033[0m\n", code, taos_errstr(result), affected_rows); + } + taos_free_result(result); char* lines6[] = { "st123456,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000", "dgtyqodr,t2=5f64,t3=L\"ste\" c1=tRue,c2=4i64,c3=\"iam\" 1626056811823316532" }; - code = taos_schemaless_insert(taos, lines6, 2, 0, "ns"); + result = taos_schemaless_insert(taos, lines6, 2, TSDB_SML_LINE_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS); + code = taos_errno(result); + if (code != TSDB_CODE_SUCCESS) { + affected_rows = taos_affected_rows(result); + printf("\033[31m [lines6]taos_schemaless_insert failed, code: %d,%s, affected rows:%d \033[0m\n", code, taos_errstr(result), affected_rows); + } + taos_free_result(result); + + //Test timestamp precision + char* lines7[] = { + "stts,t1=10i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1", + }; + + for (int precision = TSDB_SML_TIMESTAMP_HOURS; precision <= TSDB_SML_TIMESTAMP_NANO_SECONDS; ++precision) { + result = taos_schemaless_insert(taos, lines7, 1, TSDB_SML_LINE_PROTOCOL, precision); + code = taos_errno(result); + if (code != TSDB_CODE_SUCCESS) { + affected_rows = taos_affected_rows(result); + printf("\033[31m [lines7_%d]taos_schemaless_insert failed, code: %d,%s, affected rows:%d \033[0m\n", precision, code, taos_errstr(result), affected_rows); + } + taos_free_result(result); + } - return (code); } int main(int argc, char* argv[]) { diff --git a/tests/examples/c/schemaless.c b/tests/examples/c/schemaless.c index 0d98acb03a27cd3c72568d8f713cf392e5bd057c..9a2d2f063573d26093bd5032e2f68cc54fc5f908 100644 --- a/tests/examples/c/schemaless.c +++ b/tests/examples/c/schemaless.c @@ -33,6 +33,8 @@ typedef struct { int numBatches; SThreadLinesBatch batches[MAX_THREAD_LINE_BATCHES]; int64_t costTime; + int tsPrecision; + int lineProtocol; } SThreadInsertArgs; static void* insertLines(void* args) { @@ -43,10 +45,12 @@ static void* insertLines(void* args) { SThreadLinesBatch* batch = insertArgs->batches + i; printf("%s, thread: 0x%s\n", "begin taos_insert_lines", tidBuf); int64_t begin = getTimeInUs(); - int32_t code = taos_schemaless_insert(insertArgs->taos, batch->lines, batch->numLines, 0, "ms"); + TAOS_RES *res = taos_schemaless_insert(insertArgs->taos, batch->lines, batch->numLines, insertArgs->lineProtocol, insertArgs->tsPrecision); + int32_t code = taos_errno(res); int64_t end = getTimeInUs(); insertArgs->costTime += end - begin; - printf("code: %d, %s. time used:%"PRId64", thread: 0x%s\n", code, tstrerror(code), end - begin, tidBuf); + printf("code: %d, %s. affected lines:%d time used:%"PRId64", thread: 0x%s\n", code, taos_errstr(res), taos_affected_rows(res), end - begin, tidBuf); + taos_free_result(res); } return NULL; } @@ -95,9 +99,11 @@ int main(int argc, char* argv[]) { int numFields = 13; int maxLinesPerBatch = 16384; + int tsPrecision = TSDB_SML_TIMESTAMP_NOT_CONFIGURED; + int lineProtocol = TSDB_SML_UNKNOWN_PROTOCOL; int opt; - while ((opt = getopt(argc, argv, "s:c:r:f:t:m:h")) != -1) { + while ((opt = getopt(argc, argv, "s:c:r:f:t:m:p:P:h")) != -1) { switch (opt) { case 's': numSuperTables = atoi(optarg); @@ -117,6 +123,12 @@ int main(int argc, char* argv[]) { case 'm': maxLinesPerBatch = atoi(optarg); break; + case 'p': + tsPrecision = atoi(optarg); + break; + case 'P': + lineProtocol = atoi(optarg); + break; case 'h': fprintf(stderr, "Usage: %s -s supertable -c childtable -r rows -f fields -t threads -m maxlines_per_batch\n", argv[0]); @@ -178,6 +190,8 @@ int main(int argc, char* argv[]) { args.taos = taos; args.batches[0].lines = linesStb; args.batches[0].numLines = numSuperTables; + args.tsPrecision = tsPrecision; + args.lineProtocol = lineProtocol; insertLines(&args); for (int i = 0; i < numSuperTables; ++i) { free(linesStb[i]); diff --git a/tests/examples/python/taosdemo/taosdemo.py b/tests/examples/python/taosdemo/taosdemo.py index d55023bdbf119544a788aa6246c9d63dbf024872..4aaf00157c5fe5bbeec27b001f663a94c1d89439 100755 --- a/tests/examples/python/taosdemo/taosdemo.py +++ b/tests/examples/python/taosdemo/taosdemo.py @@ -21,78 +21,91 @@ import json import random import time import datetime +import multiprocessing from multiprocessing import Manager, Pool, Lock from multipledispatch import dispatch from concurrent.futures import ThreadPoolExecutor, wait, ALL_COMPLETED @dispatch(str, str) -def v_print(msg: str, arg: str): +def v_print(msg, arg): + # type: (str, str) -> None if verbose: print(msg % arg) @dispatch(str, str, str) -def v_print(msg: str, arg1: str, arg2: str): +def v_print(msg, arg1, arg2): + # type: (str, str, str) -> None if verbose: print(msg % (arg1, arg2)) @dispatch(str, str, str, str) -def v_print(msg: str, arg1: str, arg2: str, arg3: str): +def v_print(msg, arg1, arg2, arg3): + # type: (str, str, str, str) -> None if verbose: print(msg % (arg1, arg2, arg3)) @dispatch(str, str, str, str, str) -def v_print(msg: str, arg1: str, arg2: str, arg3: str, arg4: str): +def v_print(msg, arg1, arg2, arg3, arg4): + # type: (str, str, str, str, str) -> None if verbose: print(msg % (arg1, arg2, arg3, arg4)) @dispatch(str, int) -def v_print(msg: str, arg: int): +def v_print(msg, arg): + # type: (str, int) -> None if verbose: print(msg % int(arg)) @dispatch(str, int, str) -def v_print(msg: str, arg1: int, arg2: str): +def v_print(msg, arg1, arg2): + # type: (str, int, str) -> None if verbose: print(msg % (int(arg1), str(arg2))) @dispatch(str, str, int) -def v_print(msg: str, arg1: str, arg2: int): +def v_print(msg, arg1, arg2): + # type: (str, str, int) -> None if verbose: print(msg % (arg1, int(arg2))) @dispatch(str, int, int) -def v_print(msg: str, arg1: int, arg2: int): +def v_print(msg, arg1, arg2): + # type: (str, int, int) -> None if verbose: print(msg % (int(arg1), int(arg2))) @dispatch(str, int, int, str) -def v_print(msg: str, arg1: int, arg2: int, arg3: str): +def v_print(msg, arg1, arg2, arg3): + # type: (str, int, int, str) -> None if verbose: print(msg % (int(arg1), int(arg2), str(arg3))) @dispatch(str, int, int, int) -def v_print(msg: str, arg1: int, arg2: int, arg3: int): +def v_print(msg, arg1, arg2, arg3): + # type: (str, int, int, int) -> None if verbose: print(msg % (int(arg1), int(arg2), int(arg3))) @dispatch(str, int, int, int, int) -def v_print(msg: str, arg1: int, arg2: int, arg3: int, arg4: int): +def v_print(msg, arg1, arg2, arg3, arg4): + # type: (str, int, int, int, int) -> None if verbose: print(msg % (int(arg1), int(arg2), int(arg3), int(arg4))) -def restful_execute(host: str, port: int, user: str, password: str, cmd: str): +def restful_execute(host, port, user, password, cmd): + # type: (str, int, str, str, str) -> None url = "http://%s:%d/rest/sql" % (host, restPort) v_print("restful_execute - cmd: %s", cmd) @@ -112,7 +125,8 @@ def restful_execute(host: str, port: int, user: str, password: str, cmd: str): print("resp: %s" % json.dumps(resp.json())) -def query_func(process: int, thread: int, cmd: str): +def query_func(process, thread, cmd): + # type: (int, int, str) -> None v_print("%d process %d thread cmd: %s", process, thread, cmd) if oneMoreHost != "NotSupported" and random.randint( @@ -133,7 +147,8 @@ def query_func(process: int, thread: int, cmd: str): host, port, user, password, cmd) -def query_data_process(cmd: str): +def query_data_process(cmd): + # type: (str) -> None # establish connection if native if native: v_print("host:%s, user:%s passwd:%s configDir:%s ", host, user, password, configDir) @@ -256,7 +271,8 @@ def drop_databases(): (dbName, i)) -def insert_func(process: int, thread: int): +def insert_func(process, thread): + # type: (int, int) -> None v_print("%d process %d thread, insert_func ", process, thread) # generate uuid @@ -374,7 +390,8 @@ def create_tb(): (tbName, j)) -def insert_data_process(lock, i: int, begin: int, end: int): +def insert_data_process(lock, i, begin, end): + # type: (multiprocessing._LockType, int, int, int) -> None lock.acquire() tasks = end - begin v_print("insert_data_process:%d table from %d to %d, tasks %d", i, begin, end, tasks) @@ -675,7 +692,10 @@ if __name__ == "__main__": printConfig() if not skipPrompt: - input("Press any key to continue..") + try: + input("Press any key to continue..") + except SyntaxError: + pass # establish connection first if native if native: diff --git a/tests/pytest/client/twoClients.py b/tests/pytest/client/twoClients.py index 358c4e851f7fa90caa8dd069e6b9b5064e44eb40..82191156bf425ca1f05e52516dbc04615255131c 100644 --- a/tests/pytest/client/twoClients.py +++ b/tests/pytest/client/twoClients.py @@ -36,7 +36,8 @@ class TwoClients: tdDnodes.deploy(1) tdDnodes.start(1) - # first client create a stable and insert data + tdLog.sleep(2) + # first client create a stable and insert data conn1 = taos.connect(host=self.host, user=self.user, password=self.password, config=tdDnodes.getSimCfgPath()) cursor1 = conn1.cursor() cursor1.execute("drop database if exists db") @@ -90,6 +91,8 @@ class TwoClients: cursor2.close() conn1.close() conn2.close() + + tdLog.success("%s successfully executed" % __file__) clients = TwoClients() clients.initConnection() diff --git a/tests/pytest/fulltest.sh b/tests/pytest/fulltest.sh index f54a6c4bbd6d7c10d94a59d6eae1f3aff00bf298..183d100bc9365883416f5dfdd0008bd8a0c5dc30 100755 --- a/tests/pytest/fulltest.sh +++ b/tests/pytest/fulltest.sh @@ -313,7 +313,7 @@ python3 testNoCompress.py python3 testMinTablesPerVnode.py python3 queryCount.py python3 ./test.py -f query/queryGroupbyWithInterval.py -#python3 client/twoClients.py +python3 client/twoClients.py python3 test.py -f query/queryInterval.py python3 test.py -f query/queryFillTest.py # subscribe diff --git a/tests/pytest/insert/insertJSONPayload.py b/tests/pytest/insert/insertJSONPayload.py index c5cd96f86d984bff09dcc3ee40405bf5c2056fea..81d4b47ef15cb03311943d3d53c2efe25a3b0312 100644 --- a/tests/pytest/insert/insertJSONPayload.py +++ b/tests/pytest/insert/insertJSONPayload.py @@ -15,6 +15,7 @@ import sys from util.log import * from util.cases import * from util.sql import * +from util.types import TDSmlProtocolType, TDSmlTimestampType class TDTestCase: @@ -35,7 +36,7 @@ class TDTestCase: print("============= step0 : test metric ================") payload = [''' { - "metric": "`.stb.0.`", + "metric": ".stb.0.", "timestamp": 1626006833610, "value": 10, "tags": { @@ -46,7 +47,7 @@ class TDTestCase: } } '''] - code = self._conn.schemaless_insert(payload, 2, None) + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("describe `.stb.0.`") @@ -67,7 +68,7 @@ class TDTestCase: } } '''] - code = self._conn.schemaless_insert(payload, 2, None) + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("describe stb0_0") @@ -86,7 +87,7 @@ class TDTestCase: } } '''] - code = self._conn.schemaless_insert(payload, 2, None) + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("describe stb0_1") @@ -105,7 +106,7 @@ class TDTestCase: } } '''] - code = self._conn.schemaless_insert(payload, 2, None) + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("describe stb0_2") @@ -124,7 +125,7 @@ class TDTestCase: } } '''] - code = self._conn.schemaless_insert(payload, 2, None) + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("describe stb0_3") @@ -143,7 +144,7 @@ class TDTestCase: } } '''] - code = self._conn.schemaless_insert(payload, 2, None) + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("describe stb0_4") @@ -162,7 +163,7 @@ class TDTestCase: } } '''] - code = self._conn.schemaless_insert(payload, 2, None) + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("describe stb0_5") @@ -184,7 +185,7 @@ class TDTestCase: } } '''] - code = self._conn.schemaless_insert(payload, 2, None) + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) ### timestamp 10 digits second ### @@ -201,7 +202,7 @@ class TDTestCase: } } '''] - code = self._conn.schemaless_insert(payload, 2, None) + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) print("============= step3 : test tags ================") @@ -216,7 +217,7 @@ class TDTestCase: } } '''] - code = self._conn.schemaless_insert(payload, 2, None) + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("describe stb0_8") @@ -232,7 +233,7 @@ class TDTestCase: } } '''] - code = self._conn.schemaless_insert(payload, 2, None) + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("describe stb0_9") @@ -248,7 +249,7 @@ class TDTestCase: } } '''] - code = self._conn.schemaless_insert(payload, 2, None) + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("describe stb0_10") @@ -274,7 +275,7 @@ class TDTestCase: } } '''] - code = self._conn.schemaless_insert(payload, 2, None) + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("select ts from stb1_0") @@ -297,7 +298,7 @@ class TDTestCase: } } '''] - code = self._conn.schemaless_insert(payload, 2, None) + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("select ts from stb1_1") @@ -320,7 +321,7 @@ class TDTestCase: } } '''] - code = self._conn.schemaless_insert(payload, 2, None) + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("select ts from stb1_2") @@ -343,7 +344,7 @@ class TDTestCase: } } '''] - code = self._conn.schemaless_insert(payload, 2, None) + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("select ts from stb1_3") @@ -367,7 +368,7 @@ class TDTestCase: } } '''] - code = self._conn.schemaless_insert(payload, 2, None) + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) ### metric value ### @@ -390,7 +391,7 @@ class TDTestCase: } } '''] - code = self._conn.schemaless_insert(payload, 2, None) + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("describe stb2_0") @@ -415,7 +416,7 @@ class TDTestCase: } } '''] - code = self._conn.schemaless_insert(payload, 2, None) + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("describe stb2_1") @@ -440,7 +441,7 @@ class TDTestCase: } } '''] - code = self._conn.schemaless_insert(payload, 2, None) + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("describe stb2_2") @@ -465,7 +466,7 @@ class TDTestCase: } } '''] - code = self._conn.schemaless_insert(payload, 2, None) + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("describe stb2_3") @@ -490,7 +491,7 @@ class TDTestCase: } } '''] - code = self._conn.schemaless_insert(payload, 2, None) + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("describe stb2_4") @@ -515,7 +516,7 @@ class TDTestCase: } } '''] - code = self._conn.schemaless_insert(payload, 2, None) + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("describe stb2_5") @@ -540,7 +541,7 @@ class TDTestCase: } } '''] - code = self._conn.schemaless_insert(payload, 2, None) + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("describe stb2_6") @@ -565,7 +566,7 @@ class TDTestCase: } } '''] - code = self._conn.schemaless_insert(payload, 2, None) + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("describe stb2_7") @@ -590,7 +591,7 @@ class TDTestCase: } } '''] - code = self._conn.schemaless_insert(payload, 2, None) + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("describe stb2_8") @@ -649,7 +650,7 @@ class TDTestCase: } } '''] - code = self._conn.schemaless_insert(payload, 2, None) + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("describe stb3_0") @@ -663,6 +664,183 @@ class TDTestCase: tdSql.checkData(9, 1, "BINARY") tdSql.checkData(10, 1, "NCHAR") + ### special characters ### + + payload = [''' + { + "metric": "1234", + "timestamp": 1626006833, + "value": 1, + "tags": { + "id": "123", + "456": true, + "int": false, + "double": 1, + "into": 1, + "from": 2, + "!@#$.%^&*()": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + '''] + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) + print("schemaless_insert result {}".format(code)) + + tdSql.query("describe `1234`") + tdSql.checkRows(8) + + tdSql.query("select * from `123`") + tdSql.checkRows(1) + + payload = [''' + { + "metric": "int", + "timestamp": 1626006833, + "value": 1, + "tags": { + "id": "and", + "456": true, + "int": false, + "double": 1, + "into": 1, + "from": 2, + "!@#$.%^&*()": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + '''] + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) + print("schemaless_insert result {}".format(code)) + + tdSql.query("describe `int`") + tdSql.checkRows(8) + + tdSql.query("select * from `and`") + tdSql.checkRows(1) + + payload = [''' + { + "metric": "double", + "timestamp": 1626006833, + "value": 1, + "tags": { + "id": "for", + "456": true, + "int": false, + "double": 1, + "into": 1, + "from": 2, + "!@#$.%^&*()": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + '''] + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) + print("schemaless_insert result {}".format(code)) + + tdSql.query("describe `double`") + tdSql.checkRows(8) + + tdSql.query("select * from `for`") + tdSql.checkRows(1) + + payload = [''' + { + "metric": "from", + "timestamp": 1626006833, + "value": 1, + "tags": { + "id": "!@#.^&", + "456": true, + "int": false, + "double": 1, + "into": 1, + "from": 2, + "!@#$.%^&*()": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + '''] + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) + print("schemaless_insert result {}".format(code)) + + tdSql.query("describe `from`") + tdSql.checkRows(8) + + tdSql.query("select * from `!@#.^&`") + tdSql.checkRows(1) + + payload = [''' + { + "metric": "!@#$.%^&*()", + "timestamp": 1626006833, + "value": 1, + "tags": { + "id": "none", + "456": true, + "int": false, + "double": 1, + "into": 1, + "from": 2, + "!@#$.%^&*()": "123_abc_.!@#$%^&*:;,./?|+-=()[]{}<>" + } + } + '''] + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) + print("schemaless_insert result {}".format(code)) + + tdSql.query("describe `!@#$.%^&*()`") + tdSql.checkRows(8) + + tdSql.query("select * from `none`") + tdSql.checkRows(1) + + payload = [''' + { + "metric": "STABLE", + "timestamp": { + "value": 1626006833, + "type": "s" + }, + "value": { + "value": "hello", + "type": "nchar" + }, + "tags": { + "id": "KEY", + "456": { + "value": true, + "type": "bool" + }, + "int": { + "value": 127, + "type": "tinyint" + }, + "double":{ + "value": 32767, + "type": "smallint" + }, + "into": { + "value": 2147483647, + "type": "int" + }, + "INSERT": { + "value": 9.2233720368547758e+18, + "type": "bigint" + }, + "!@#$.%^&*()": { + "value": 11.12345, + "type": "float" + } + } + } + '''] + + code = self._conn.schemaless_insert(payload, TDSmlProtocolType.JSON.value, TDSmlTimestampType.NOT_CONFIGURED.value) + print("schemaless_insert result {}".format(code)) + + tdSql.query("describe `stable`") + tdSql.checkRows(8) + + tdSql.query("select * from `key`") + tdSql.checkRows(1) + def stop(self): tdSql.close() diff --git a/tests/pytest/insert/insertTelnetLines.py b/tests/pytest/insert/insertTelnetLines.py index 782ef01cfc10b686c0f1b972e2348a5253b653b1..a48351f6c0b162be83f6aca44a87ff9f55b498c8 100644 --- a/tests/pytest/insert/insertTelnetLines.py +++ b/tests/pytest/insert/insertTelnetLines.py @@ -15,7 +15,7 @@ import sys from util.log import * from util.cases import * from util.sql import * - +from util.types import TDSmlProtocolType, TDSmlTimestampType class TDTestCase: def init(self, conn, logSql): @@ -35,10 +35,10 @@ class TDTestCase: "stb0_0 1626006833639000000ns 4i8 host=\"host0\" interface=\"eth0\"", "stb0_1 1626006833639000000ns 4i8 host=\"host0\" interface=\"eth0\"", "stb0_2 1626006833639000000ns 4i8 host=\"host0\" interface=\"eth0\"", - "`.stb0.3.` 1626006833639000000ns 4i8 host=\"host0\" interface=\"eth0\"", + ".stb0.3. 1626006833639000000ns 4i8 host=\"host0\" interface=\"eth0\"", ] - code = self._conn.schemaless_insert(lines0, 1, None) + code = self._conn.schemaless_insert(lines0, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("show stables") @@ -59,30 +59,26 @@ class TDTestCase: ### timestamp ### print("============= step2 : test timestamp ================") lines1 = [ - "stb1 1626006833s 1i8 host=\"host0\"", - "stb1 1626006833639000000ns 2i8 host=\"host0\"", - "stb1 1626006833640000us 3i8 host=\"host0\"", - "stb1 1626006833641 4i8 host=\"host0\"", - "stb1 1626006834 5i8 host=\"host0\"", - "stb1 1626006833651ms 6i8 host=\"host0\"", - "stb1 0 7i8 host=\"host0\"", + "stb1 1626006833641 1i8 host=\"host0\"", + "stb1 1626006834 2i8 host=\"host0\"", + "stb1 0 3i8 host=\"host0\"", ] - code = self._conn.schemaless_insert(lines1, 1, None) + code = self._conn.schemaless_insert(lines1, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("select * from stb1") - tdSql.checkRows(7) + tdSql.checkRows(3) ### metric value ### print("============= step3 : test metric value ================") #tinyint lines2_0 = [ - "stb2_0 1626006833651ms -127i8 host=\"host0\"", - "stb2_0 1626006833652ms 127i8 host=\"host0\"" + "stb2_0 1626006833651 -127i8 host=\"host0\"", + "stb2_0 1626006833652 127i8 host=\"host0\"" ] - code = self._conn.schemaless_insert(lines2_0, 1, None) + code = self._conn.schemaless_insert(lines2_0, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("select * from stb2_0") @@ -94,10 +90,10 @@ class TDTestCase: #smallint lines2_1 = [ - "stb2_1 1626006833651ms -32767i16 host=\"host0\"", - "stb2_1 1626006833652ms 32767i16 host=\"host0\"" + "stb2_1 1626006833651 -32767i16 host=\"host0\"", + "stb2_1 1626006833652 32767i16 host=\"host0\"" ] - code = self._conn.schemaless_insert(lines2_1, 1, None) + code = self._conn.schemaless_insert(lines2_1, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("select * from stb2_1") @@ -109,11 +105,11 @@ class TDTestCase: #int lines2_2 = [ - "stb2_2 1626006833651ms -2147483647i32 host=\"host0\"", - "stb2_2 1626006833652ms 2147483647i32 host=\"host0\"" + "stb2_2 1626006833651 -2147483647i32 host=\"host0\"", + "stb2_2 1626006833652 2147483647i32 host=\"host0\"" ] - code = self._conn.schemaless_insert(lines2_2, 1, None) + code = self._conn.schemaless_insert(lines2_2, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("select * from stb2_2") @@ -125,11 +121,11 @@ class TDTestCase: #bigint lines2_3 = [ - "stb2_3 1626006833651ms -9223372036854775807i64 host=\"host0\"", - "stb2_3 1626006833652ms 9223372036854775807i64 host=\"host0\"" + "stb2_3 1626006833651 -9223372036854775807i64 host=\"host0\"", + "stb2_3 1626006833652 9223372036854775807i64 host=\"host0\"" ] - code = self._conn.schemaless_insert(lines2_3, 1, None) + code = self._conn.schemaless_insert(lines2_3, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("select * from stb2_3") @@ -141,19 +137,19 @@ class TDTestCase: #float lines2_4 = [ - "stb2_4 1626006833610ms 3f32 host=\"host0\"", - "stb2_4 1626006833620ms -3f32 host=\"host0\"", - "stb2_4 1626006833630ms 3.4f32 host=\"host0\"", - "stb2_4 1626006833640ms -3.4f32 host=\"host0\"", - "stb2_4 1626006833650ms 3.4E10f32 host=\"host0\"", - "stb2_4 1626006833660ms -3.4e10f32 host=\"host0\"", - "stb2_4 1626006833670ms 3.4E+2f32 host=\"host0\"", - "stb2_4 1626006833680ms -3.4e-2f32 host=\"host0\"", - "stb2_4 1626006833700ms 3.4E38f32 host=\"host0\"", - "stb2_4 1626006833710ms -3.4E38f32 host=\"host0\"" + "stb2_4 1626006833610 3f32 host=\"host0\"", + "stb2_4 1626006833620 -3f32 host=\"host0\"", + "stb2_4 1626006833630 3.4f32 host=\"host0\"", + "stb2_4 1626006833640 -3.4f32 host=\"host0\"", + "stb2_4 1626006833650 3.4E10f32 host=\"host0\"", + "stb2_4 1626006833660 -3.4e10f32 host=\"host0\"", + "stb2_4 1626006833670 3.4E+2f32 host=\"host0\"", + "stb2_4 1626006833680 -3.4e-2f32 host=\"host0\"", + "stb2_4 1626006833700 3.4E38f32 host=\"host0\"", + "stb2_4 1626006833710 -3.4E38f32 host=\"host0\"" ] - code = self._conn.schemaless_insert(lines2_4, 1, None) + code = self._conn.schemaless_insert(lines2_4, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("select * from stb2_4") @@ -165,20 +161,20 @@ class TDTestCase: #double lines2_5 = [ - "stb2_5 1626006833610ms 3f64 host=\"host0\"", - "stb2_5 1626006833620ms -3f64 host=\"host0\"", - "stb2_5 1626006833630ms 3.4f64 host=\"host0\"", - "stb2_5 1626006833640ms -3.4f64 host=\"host0\"", - "stb2_5 1626006833650ms 3.4E10f64 host=\"host0\"", - "stb2_5 1626006833660ms -3.4e10f64 host=\"host0\"", - "stb2_5 1626006833670ms 3.4E+2f64 host=\"host0\"", - "stb2_5 1626006833680ms -3.4e-2f64 host=\"host0\"", - "stb2_5 1626006833690ms 1.7E308f64 host=\"host0\"", - "stb2_5 1626006833700ms -1.7E308f64 host=\"host0\"", - "stb2_5 1626006833710ms 3 host=\"host0\"" + "stb2_5 1626006833610 3f64 host=\"host0\"", + "stb2_5 1626006833620 -3f64 host=\"host0\"", + "stb2_5 1626006833630 3.4f64 host=\"host0\"", + "stb2_5 1626006833640 -3.4f64 host=\"host0\"", + "stb2_5 1626006833650 3.4E10f64 host=\"host0\"", + "stb2_5 1626006833660 -3.4e10f64 host=\"host0\"", + "stb2_5 1626006833670 3.4E+2f64 host=\"host0\"", + "stb2_5 1626006833680 -3.4e-2f64 host=\"host0\"", + "stb2_5 1626006833690 1.7E308f64 host=\"host0\"", + "stb2_5 1626006833700 -1.7E308f64 host=\"host0\"", + "stb2_5 1626006833710 3 host=\"host0\"" ] - code = self._conn.schemaless_insert(lines2_5, 1, None) + code = self._conn.schemaless_insert(lines2_5, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("select * from stb2_5") @@ -190,19 +186,19 @@ class TDTestCase: #bool lines2_6 = [ - "stb2_6 1626006833610ms t host=\"host0\"", - "stb2_6 1626006833620ms T host=\"host0\"", - "stb2_6 1626006833630ms true host=\"host0\"", - "stb2_6 1626006833640ms True host=\"host0\"", - "stb2_6 1626006833650ms TRUE host=\"host0\"", - "stb2_6 1626006833660ms f host=\"host0\"", - "stb2_6 1626006833670ms F host=\"host0\"", - "stb2_6 1626006833680ms false host=\"host0\"", - "stb2_6 1626006833690ms False host=\"host0\"", - "stb2_6 1626006833700ms FALSE host=\"host0\"" + "stb2_6 1626006833610 t host=\"host0\"", + "stb2_6 1626006833620 T host=\"host0\"", + "stb2_6 1626006833630 true host=\"host0\"", + "stb2_6 1626006833640 True host=\"host0\"", + "stb2_6 1626006833650 TRUE host=\"host0\"", + "stb2_6 1626006833660 f host=\"host0\"", + "stb2_6 1626006833670 F host=\"host0\"", + "stb2_6 1626006833680 false host=\"host0\"", + "stb2_6 1626006833690 False host=\"host0\"", + "stb2_6 1626006833700 FALSE host=\"host0\"" ] - code = self._conn.schemaless_insert(lines2_6, 1, None) + code = self._conn.schemaless_insert(lines2_6, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("select * from stb2_6") @@ -214,12 +210,12 @@ class TDTestCase: #binary lines2_7 = [ - "stb2_7 1626006833610ms \" binary_val .!@#$%^&* \" host=\"host0\"", - "stb2_7 1626006833620ms \"binary_val.:;,./?|+-=\" host=\"host0\"", - "stb2_7 1626006833630ms \"binary_val.()[]{}<>\" host=\"host0\"" + "stb2_7 1626006833610 \" binary_val .!@#$%^&* \" host=\"host0\"", + "stb2_7 1626006833620 \"binary_val.:;,./?|+-=\" host=\"host0\"", + "stb2_7 1626006833630 \"binary_val.()[]{}<>\" host=\"host0\"" ] - code = self._conn.schemaless_insert(lines2_7, 1, None) + code = self._conn.schemaless_insert(lines2_7, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("select * from stb2_7") @@ -231,11 +227,11 @@ class TDTestCase: #nchar lines2_8 = [ - "stb2_8 1626006833610ms L\" nchar_val 数值一 \" host=\"host0\"", - "stb2_8 1626006833620ms L\"nchar_val数值二\" host=\"host0\"" + "stb2_8 1626006833610 L\" nchar_val 数值一 \" host=\"host0\"", + "stb2_8 1626006833620 L\"nchar_val数值二\" host=\"host0\"" ] - code = self._conn.schemaless_insert(lines2_8, 1, None) + code = self._conn.schemaless_insert(lines2_8, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("select * from stb2_8") @@ -249,11 +245,11 @@ class TDTestCase: print("============= step3 : test tags ================") #tag value types lines3_0 = [ - "stb3_0 1626006833610ms 1 t1=127i8 t2=32767i16 t3=2147483647i32 t4=9223372036854775807i64 t5=3.4E38f32 t6=1.7E308f64 t7=true t8=\"binary_val_1\" t9=L\"标签值1\"", - "stb3_0 1626006833610ms 2 t1=-127i8 t2=-32767i16 t3=-2147483647i32 t4=-9223372036854775807i64 t5=-3.4E38f32 t6=-1.7E308f64 t7=false t8=\"binary_val_2\" t9=L\"标签值2\"" + "stb3_0 1626006833610 1 t1=127i8 t2=32767i16 t3=2147483647i32 t4=9223372036854775807i64 t5=3.4E38f32 t6=1.7E308f64 t7=true t8=\"binary_val_1\" t9=L\"标签值1\"", + "stb3_0 1626006833610 2 t1=-127i8 t2=-32767i16 t3=-2147483647i32 t4=-9223372036854775807i64 t5=-3.4E38f32 t6=-1.7E308f64 t7=false t8=\"binary_val_2\" t9=L\"标签值2\"" ] - code = self._conn.schemaless_insert(lines3_0, 1, None) + code = self._conn.schemaless_insert(lines3_0, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("select * from stb3_0") @@ -292,12 +288,12 @@ class TDTestCase: #tag ID as child table name lines3_1 = [ - "stb3_1 1626006833610ms 1 id=child_table1 host=host1", - "stb3_1 1626006833610ms 2 host=host2 iD=child_table2", - "stb3_1 1626006833610ms 3 ID=child_table3 host=host3" + "stb3_1 1626006833610 1 id=child_table1 host=host1", + "stb3_1 1626006833610 2 host=host2 iD=child_table2", + "stb3_1 1626006833610 3 ID=child_table3 host=host3" ] - code = self._conn.schemaless_insert(lines3_1, 1, None) + code = self._conn.schemaless_insert(lines3_1, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) print("schemaless_insert result {}".format(code)) tdSql.query("select * from stb3_1") @@ -308,6 +304,56 @@ class TDTestCase: tdSql.checkData(0, 0, "child_table1") + ### special characters and keywords ### + print("============= step4 : test special characters and keywords ================") + lines4_1 = [ + "1234 1626006833610ms 1 id=123 456=true int=true double=false into=1 from=2 !@#$.%^&*()=false", + "int 1626006833610ms 2 id=and 456=true int=true double=false into=1 from=2 !@#$.%^&*()=false", + "double 1626006833610ms 2 id=for 456=true int=true double=false into=1 from=2 !@#$.%^&*()=false", + "from 1626006833610ms 2 id=!@#.^& 456=true int=true double=false into=1 from=2 !@#$.%^&*()=false", + "!@#$.%^&*() 1626006833610ms 2 id=none 456=true int=true double=false into=1 from=2 !@#$.%^&*()=false", + "STABLE 1626006833610ms 2 id=KEY 456=true int=true double=false TAG=1 FROM=2 COLUMN=false", + ] + + code = self._conn.schemaless_insert(lines4_1, TDSmlProtocolType.TELNET.value, TDSmlTimestampType.NOT_CONFIGURED.value) + print("schemaless_insert result {}".format(code)) + + tdSql.query('describe `1234`') + tdSql.checkRows(8) + + tdSql.query('describe `int`') + tdSql.checkRows(8) + + tdSql.query('describe `double`') + tdSql.checkRows(8) + + tdSql.query('describe `from`') + tdSql.checkRows(8) + + tdSql.query('describe `!@#$.%^&*()`') + tdSql.checkRows(8) + + tdSql.query('describe `stable`') + tdSql.checkRows(8) + + tdSql.query('select * from `123`') + tdSql.checkRows(1) + + tdSql.query('select * from `and`') + tdSql.checkRows(1) + + tdSql.query('select * from `for`') + tdSql.checkRows(1) + + tdSql.query('select * from `!@#.^&`') + tdSql.checkRows(1) + + tdSql.query('select * from `none`') + tdSql.checkRows(1) + + tdSql.query('select * from `key`') + tdSql.checkRows(1) + def stop(self): tdSql.close() tdLog.success("%s successfully executed" % __file__) diff --git a/tests/pytest/insert/line_insert.py b/tests/pytest/insert/line_insert.py index 7a823b917d50c445ddef18ed0f4618f8444d3e85..ff26483aeb323ebd309ba7a41e91ac860af9d222 100644 --- a/tests/pytest/insert/line_insert.py +++ b/tests/pytest/insert/line_insert.py @@ -15,13 +15,14 @@ import sys from util.log import * from util.cases import * from util.sql import * +from util.types import TDSmlProtocolType, TDSmlTimestampType class TDTestCase: def init(self, conn, logSql): tdLog.debug("start to execute %s" % __file__) tdSql.init(conn.cursor(), logSql) - self._conn = conn + self._conn = conn def run(self): print("running {}".format(__file__)) @@ -42,17 +43,17 @@ class TDTestCase: "stf,t1=4i64,t3=\"t4\",t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin_stf\",c2=false,c5=5f64,c6=7u64 1626006933641000000" ] - code = self._conn.schemaless_insert(lines, 0, "ns") + code = self._conn.schemaless_insert(lines, TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) print("schemaless_insert result {}".format(code)) lines2 = [ "stg,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000", "stg,t1=4i64,t3=\"t4\",t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin\",c2=true,c4=5f64,c5=5f64 1626006833640000000" ] - code = self._conn.schemaless_insert([ lines2[0] ], 0, "ns") + code = self._conn.schemaless_insert([ lines2[0] ], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) print("schemaless_insert result {}".format(code)) - self._conn.schemaless_insert([ lines2[1] ], 0, "ns") + code = self._conn.schemaless_insert([ lines2[1] ], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) print("schemaless_insert result {}".format(code)) tdSql.query("select * from st") @@ -76,7 +77,7 @@ class TDTestCase: self._conn.schemaless_insert([ "sth,t1=4i64,t2=5f64,t4=5f64,ID=childtable c1=3i64,c3=L\"passitagin_stf\",c2=false,c5=5f64,c6=7u64 1626006933641", "sth,t1=4i64,t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin_stf\",c2=false,c5=5f64,c6=7u64 1626006933654" - ], 0, "ms") + ], TDSmlProtocolType.LINE.value, TDSmlTimestampType.MILLI_SECOND.value) tdSql.execute('reset query cache') tdSql.query('select tbname, * from sth') @@ -84,6 +85,53 @@ class TDTestCase: tdSql.query('select tbname, * from childtable') tdSql.checkRows(1) + + ###Special Character and keyss + self._conn.schemaless_insert([ + "1234,id=3456,abc=4i64,def=3i64 123=3i64,int=2i64,bool=false,into=5f64,column=7u64,!@#$.%^&*()=false 1626006933641", + "int,id=and,123=4i64,smallint=5f64,double=5f64,of=3i64,key=L\"passitagin_stf\",!@#$.%^&*()=false abc=false 1626006933654", + "double,id=for,123=4i64,smallint=5f64,double=5f64,of=3i64,key=L\"passitagin_stf\",!@#$.%^&*()=false abc=false 1626006933664", + "from,id=!@#$.%^,123=4i64,smallint=5f64,double=5f64,of=3i64,key=L\"passitagin_stf\",!@#$.%^&*()=false abc=false 1626006933674", + "!@#$.%^&*(),id=none,123=4i64,smallint=5f64,double=5f64,of=3i64,key=L\"passitagin_stf\",!@#$.%^&*()=false abc=false 1626006933684", + "STABLE,id=CREATE,123=4i64,smallint=5f64,DOUBLE=5f64,of=3i64,key=L\"passitagin_stf\",!@#$.%^&*()=false SELECT=false 1626006933684", + ], TDSmlProtocolType.LINE.value, TDSmlTimestampType.MILLI_SECOND.value) + tdSql.execute('reset query cache') + + tdSql.query('describe `1234`') + tdSql.checkRows(9) + + tdSql.query('describe `int`') + tdSql.checkRows(8) + + tdSql.query('describe `double`') + tdSql.checkRows(8) + + tdSql.query('describe `from`') + tdSql.checkRows(8) + + tdSql.query('describe `!@#$.%^&*()`') + tdSql.checkRows(8) + + tdSql.query('describe `stable`') + tdSql.checkRows(8) + + tdSql.query('select * from `3456`') + tdSql.checkRows(1) + + tdSql.query('select * from `and`') + tdSql.checkRows(1) + + tdSql.query('select * from `for`') + tdSql.checkRows(1) + + tdSql.query('select * from `!@#$.%^`') + tdSql.checkRows(1) + + tdSql.query('select * from `none`') + tdSql.checkRows(1) + + tdSql.query('select * from `create`') + tdSql.checkRows(1) def stop(self): tdSql.close() tdLog.success("%s successfully executed" % __file__) diff --git a/tests/pytest/insert/schemalessInsert.py b/tests/pytest/insert/schemalessInsert.py index 56558ab3be9d74c5abf0987f23b8986a629567b4..94ea0ab79a54cbb7daea1a431fa566567b9de684 100644 --- a/tests/pytest/insert/schemalessInsert.py +++ b/tests/pytest/insert/schemalessInsert.py @@ -21,6 +21,7 @@ import numpy as np from util.log import * from util.cases import * from util.sql import * +from util.types import TDSmlProtocolType, TDSmlTimestampType import threading @@ -294,7 +295,7 @@ class TDTestCase: def resCmp(self, input_sql, stb_name, query_sql="select * from", condition="", ts=None, id=True, none_check_tag=None): expect_list = self.inputHandle(input_sql) - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) query_sql = f"{query_sql} {stb_name} {condition}" res_row_list, res_field_list_without_ts, res_type_list = self.resHandle(query_sql, True) if ts == 0: @@ -409,11 +410,11 @@ class TDTestCase: """ for input_sql in [self.genLongSql(128, 1)[0], self.genLongSql(1, 4094)[0]]: self.cleanStb() - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) for input_sql in [self.genLongSql(129, 1)[0], self.genLongSql(1, 4095)[0]]: self.cleanStb() try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) except SchemalessError: pass @@ -427,7 +428,7 @@ class TDTestCase: for i in rstr: input_sql = self.genFullTypeSql(tb_name=f"\"aaa{i}bbb\"")[0] try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) except SchemalessError: pass @@ -438,7 +439,7 @@ class TDTestCase: self.cleanStb() input_sql = self.genFullTypeSql(tb_name=f"\"1aaabbb\"")[0] try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) except SchemalessError: pass @@ -449,7 +450,7 @@ class TDTestCase: self.cleanStb() input_sql = self.genFullTypeSql(ts="now")[0] try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) except SchemalessError: pass @@ -460,7 +461,7 @@ class TDTestCase: self.cleanStb() input_sql = self.genFullTypeSql(ts="2021-07-21\ 19:01:46.920")[0] try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) except SchemalessError: pass @@ -471,7 +472,7 @@ class TDTestCase: self.cleanStb() input_sql = self.genFullTypeSql(ts="16260068336390us19")[0] try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) except SchemalessError: pass @@ -487,7 +488,7 @@ class TDTestCase: for t1 in ["-128i8", "128i8"]: input_sql = self.genFullTypeSql(t1=t1)[0] try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) except SchemalessError: pass @@ -498,7 +499,7 @@ class TDTestCase: for t2 in ["-32768i16", "32768i16"]: input_sql = self.genFullTypeSql(t2=t2)[0] try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) except SchemalessError: pass @@ -509,7 +510,7 @@ class TDTestCase: for t3 in ["-2147483648i32", "2147483648i32"]: input_sql = self.genFullTypeSql(t3=t3)[0] try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) except SchemalessError: pass @@ -520,7 +521,7 @@ class TDTestCase: for t4 in ["-9223372036854775808i64", "9223372036854775808i64"]: input_sql = self.genFullTypeSql(t4=t4)[0] try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) except SchemalessError: pass @@ -532,7 +533,7 @@ class TDTestCase: for t5 in [f"{-3.4028234664*(10**38)}f32", f"{3.4028234664*(10**38)}f32"]: input_sql = self.genFullTypeSql(t5=t5)[0] try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) raise Exception("should not reach here") except SchemalessError as err: tdSql.checkNotEqual(err.errno, 0) @@ -546,7 +547,7 @@ class TDTestCase: for c6 in [f'{-1.797693134862316*(10**308)}f64', f'{-1.797693134862316*(10**308)}f64']: input_sql = self.genFullTypeSql(c6=c6)[0] try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) raise Exception("should not reach here") except SchemalessError as err: tdSql.checkNotEqual(err.errno, 0) @@ -554,11 +555,11 @@ class TDTestCase: # binary stb_name = self.getLongName(7, "letters") input_sql = f'{stb_name},t0=t,t1="{self.getLongName(16374, "letters")}" c0=f 1626006833639000000ns' - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) input_sql = f'{stb_name},t0=t,t1="{self.getLongName(16375, "letters")}" c0=f 1626006833639000000ns' try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) raise Exception("should not reach here") except SchemalessError as err: pass @@ -567,11 +568,11 @@ class TDTestCase: # * legal nchar could not be larger than 16374/4 stb_name = self.getLongName(7, "letters") input_sql = f'{stb_name},t0=t,t1=L"{self.getLongName(4093, "letters")}" c0=f 1626006833639000000ns' - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) input_sql = f'{stb_name},t0=t,t1=L"{self.getLongName(4094, "letters")}" c0=f 1626006833639000000ns' try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) raise Exception("should not reach here") except SchemalessError as err: tdSql.checkNotEqual(err.errno, 0) @@ -589,7 +590,7 @@ class TDTestCase: for c1 in ["-128i8", "128i8"]: input_sql = self.genFullTypeSql(c1=c1)[0] try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) raise Exception("should not reach here") except SchemalessError as err: tdSql.checkNotEqual(err.errno, 0) @@ -600,7 +601,7 @@ class TDTestCase: for c2 in ["-32768i16", "32768i16"]: input_sql = self.genFullTypeSql(c2=c2)[0] try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) raise Exception("should not reach here") except SchemalessError as err: tdSql.checkNotEqual(err.errno, 0) @@ -612,7 +613,7 @@ class TDTestCase: for c3 in ["-2147483648i32", "2147483648i32"]: input_sql = self.genFullTypeSql(c3=c3)[0] try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) raise Exception("should not reach here") except SchemalessError as err: tdSql.checkNotEqual(err.errno, 0) @@ -624,7 +625,7 @@ class TDTestCase: for c4 in ["-9223372036854775808i64", "9223372036854775808i64"]: input_sql = self.genFullTypeSql(c4=c4)[0] try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) raise Exception("should not reach here") except SchemalessError as err: tdSql.checkNotEqual(err.errno, 0) @@ -637,7 +638,7 @@ class TDTestCase: for c5 in [f"{-3.4028234664*(10**38)}f32", f"{3.4028234664*(10**38)}f32"]: input_sql = self.genFullTypeSql(c5=c5)[0] try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) raise Exception("should not reach here") except SchemalessError as err: tdSql.checkNotEqual(err.errno, 0) @@ -650,7 +651,7 @@ class TDTestCase: for c6 in [f'{-1.797693134862316*(10**308)}f64', f'{-1.797693134862316*(10**308)}f64']: input_sql = self.genFullTypeSql(c6=c6)[0] try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) raise Exception("should not reach here") except SchemalessError as err: tdSql.checkNotEqual(err.errno, 0) @@ -658,11 +659,11 @@ class TDTestCase: # # binary stb_name = self.getLongName(7, "letters") input_sql = f'{stb_name},t0=t c0=f,c1="{self.getLongName(16374, "letters")}" 1626006833639000000ns' - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) input_sql = f'{stb_name},t0=t c0=f,c1="{self.getLongName(16375, "letters")}" 1626006833639000000ns' try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) raise Exception("should not reach here") except SchemalessError as err: tdSql.checkNotEqual(err.errno, 0) @@ -671,11 +672,11 @@ class TDTestCase: # * legal nchar could not be larger than 16374/4 stb_name = self.getLongName(7, "letters") input_sql = f'{stb_name},t0=t c0=f,c1=L"{self.getLongName(4093, "letters")}" 1626006833639000000ns' - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) input_sql = f'{stb_name},t0=t c0=f,c1=L"{self.getLongName(4094, "letters")}" 1626006833639000000ns' try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) raise Exception("should not reach here") except SchemalessError as err: tdSql.checkNotEqual(err.errno, 0) @@ -690,13 +691,13 @@ class TDTestCase: for i in ["TrUe", "tRue", "trUe", "truE", "FalsE", "fAlse", "faLse", "falSe", "falsE"]: input_sql1 = self.genFullTypeSql(t0=i)[0] try: - self._conn.schemaless_insert([input_sql1], 0) + self._conn.schemaless_insert([input_sql1], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) raise Exception("should not reach here") except SchemalessError as err: tdSql.checkNotEqual(err.errno, 0) input_sql2 = self.genFullTypeSql(c0=i)[0] try: - self._conn.schemaless_insert([input_sql2], 0) + self._conn.schemaless_insert([input_sql2], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) raise Exception("should not reach here") except SchemalessError as err: tdSql.checkNotEqual(err.errno, 0) @@ -718,7 +719,7 @@ class TDTestCase: self.genFullTypeSql(c9="1s1u64")[0] ]: try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) raise Exception("should not reach here") except SchemalessError as err: tdSql.checkNotEqual(err.errno, 0) @@ -731,7 +732,7 @@ class TDTestCase: input_sql4 = f'{stb_name},t0=t,t1=L"abc aaa" c0=f 1626006833639000000ns' for input_sql in [input_sql1, input_sql2, input_sql3, input_sql4]: try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) raise Exception("should not reach here") except SchemalessError as err: tdSql.checkNotEqual(err.errno, 0) @@ -741,8 +742,8 @@ class TDTestCase: for symbol in list('~!@#$¥%^&*()-+={}|[]、「」:;'): input_sql1 = f'{stb_name},t0=t c0=f,c1="abc{symbol}aaa" 1626006833639000000ns' input_sql2 = f'{stb_name},t0=t,t1="abc{symbol}aaa" c0=f 1626006833639000000ns' - self._conn.schemaless_insert([input_sql1], 0) - self._conn.schemaless_insert([input_sql2], 0) + self._conn.schemaless_insert([input_sql1], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) + self._conn.schemaless_insert([input_sql2], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) def duplicateIdTagColInsertCheckCase(self): @@ -752,7 +753,7 @@ class TDTestCase: self.cleanStb() input_sql_id = self.genFullTypeSql(id_double_tag=True)[0] try: - self._conn.schemaless_insert([input_sql_id], 0) + self._conn.schemaless_insert([input_sql_id], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) raise Exception("should not reach here") except SchemalessError as err: tdSql.checkNotEqual(err.errno, 0) @@ -760,7 +761,7 @@ class TDTestCase: input_sql = self.genFullTypeSql()[0] input_sql_tag = input_sql.replace("t5", "t6") try: - self._conn.schemaless_insert([input_sql_tag], 0) + self._conn.schemaless_insert([input_sql_tag], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) raise Exception("should not reach here") except SchemalessError as err: tdSql.checkNotEqual(err.errno, 0) @@ -768,7 +769,7 @@ class TDTestCase: input_sql = self.genFullTypeSql()[0] input_sql_col = input_sql.replace("c5", "c6") try: - self._conn.schemaless_insert([input_sql_col], 0) + self._conn.schemaless_insert([input_sql_col], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) raise Exception("should not reach here") except SchemalessError as err: tdSql.checkNotEqual(err.errno, 0) @@ -776,7 +777,7 @@ class TDTestCase: input_sql = self.genFullTypeSql()[0] input_sql_col = input_sql.replace("c5", "C6") try: - self._conn.schemaless_insert([input_sql_col], 0) + self._conn.schemaless_insert([input_sql_col], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) raise Exception("should not reach here") except SchemalessError as err: tdSql.checkNotEqual(err.errno, 0) @@ -802,7 +803,7 @@ class TDTestCase: self.cleanStb() input_sql, stb_name = self.genFullTypeSql() self.resCmp(input_sql, stb_name) - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) self.resCmp(input_sql, stb_name) def tagColBinaryNcharLengthCheckCase(self): @@ -869,7 +870,7 @@ class TDTestCase: tdSql.checkRows(1) tdSql.checkEqual(tb_name1, tb_name2) input_sql, stb_name = self.genFullTypeSql(stb_name=stb_name, t0="f", c0="f", id_noexist_tag=True, ct_add_tag=True) - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) tb_name3 = self.getNoIdTbName(stb_name) tdSql.query(f"select * from {stb_name}") tdSql.checkRows(2) @@ -884,17 +885,17 @@ class TDTestCase: stb_name = self.getLongName(7, "letters") tb_name = f'{stb_name}_1' input_sql = f'{stb_name},id="{tb_name}",t0=t c0=f 1626006833639000000ns' - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) # * every binary and nchar must be length+2, so here is two tag, max length could not larger than 16384-2*2 input_sql = f'{stb_name},t0=t,t1="{self.getLongName(16374, "letters")}",t2="{self.getLongName(5, "letters")}" c0=f 1626006833639000000ns' - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) tdSql.query(f"select * from {stb_name}") tdSql.checkRows(2) input_sql = f'{stb_name},t0=t,t1="{self.getLongName(16374, "letters")}",t2="{self.getLongName(6, "letters")}" c0=f 1626006833639000000ns' try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) raise Exception("should not reach here") except SchemalessError: pass @@ -903,13 +904,13 @@ class TDTestCase: # # * check col,col+ts max in describe ---> 16143 input_sql = f'{stb_name},t0=t c0=f,c1="{self.getLongName(16374, "letters")}",c2="{self.getLongName(16374, "letters")}",c3="{self.getLongName(16374, "letters")}",c4="{self.getLongName(12, "letters")}" 1626006833639000000ns' - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) tdSql.query(f"select * from {stb_name}") tdSql.checkRows(3) input_sql = f'{stb_name},t0=t c0=f,c1="{self.getLongName(16374, "letters")}",c2="{self.getLongName(16374, "letters")}",c3="{self.getLongName(16374, "letters")}",c4="{self.getLongName(13, "letters")}" 1626006833639000000ns' try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) raise Exception("should not reach here") except SchemalessError as err: tdSql.checkNotEqual(err.errno, 0) @@ -925,16 +926,16 @@ class TDTestCase: stb_name = self.getLongName(7, "letters") tb_name = f'{stb_name}_1' input_sql = f'{stb_name},id="{tb_name}",t0=t c0=f 1626006833639000000ns' - code = self._conn.schemaless_insert([input_sql], 0) + code = self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) # * legal nchar could not be larger than 16374/4 input_sql = f'{stb_name},t0=t,t1=L"{self.getLongName(4093, "letters")}",t2=L"{self.getLongName(1, "letters")}" c0=f 1626006833639000000ns' - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) tdSql.query(f"select * from {stb_name}") tdSql.checkRows(2) input_sql = f'{stb_name},t0=t,t1=L"{self.getLongName(4093, "letters")}",t2=L"{self.getLongName(2, "letters")}" c0=f 1626006833639000000ns' try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) raise Exception("should not reach here") except SchemalessError as err: tdSql.checkNotEqual(err.errno, 0) @@ -942,12 +943,12 @@ class TDTestCase: tdSql.checkRows(2) input_sql = f'{stb_name},t0=t c0=f,c1=L"{self.getLongName(4093, "letters")}",c2=L"{self.getLongName(4093, "letters")}",c3=L"{self.getLongName(4093, "letters")}",c4=L"{self.getLongName(4, "letters")}" 1626006833639000000ns' - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) tdSql.query(f"select * from {stb_name}") tdSql.checkRows(3) input_sql = f'{stb_name},t0=t c0=f,c1=L"{self.getLongName(4093, "letters")}",c2=L"{self.getLongName(4093, "letters")}",c3=L"{self.getLongName(4093, "letters")}",c4=L"{self.getLongName(5, "letters")}" 1626006833639000000ns' try: - self._conn.schemaless_insert([input_sql], 0) + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) raise Exception("should not reach here") except SchemalessError as err: tdSql.checkNotEqual(err.errno, 0) @@ -971,7 +972,7 @@ class TDTestCase: "st123456,t1=4i64,t3=\"t4\",t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin\",c2=true,c4=5f64,c5=5f64,c6=7u64 1626006933640000000ns", "st123456,t1=4i64,t3=\"t4\",t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin_stf\",c2=false,c5=5f64,c6=7u64 1626006933641000000ns" ] - self._conn.schemaless_insert(lines, 0) + self._conn.schemaless_insert(lines, TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) def multiInsertCheckCase(self, count): """ @@ -984,7 +985,7 @@ class TDTestCase: for i in range(count): input_sql = self.genFullTypeSql(stb_name=stb_name, t7=f'"{self.getLongName(8, "letters")}"', c7=f'"{self.getLongName(8, "letters")}"', id_noexist_tag=True)[0] sql_list.append(input_sql) - self._conn.schemaless_insert(sql_list, 0) + self._conn.schemaless_insert(sql_list, TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) def batchErrorInsertCheckCase(self): """ @@ -995,7 +996,7 @@ class TDTestCase: lines = ["st123456,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000ns", f"{stb_name},t2=5f64,t3=L\"ste\" c1=tRue,c2=4i64,c3=\"iam\" 1626056811823316532ns"] try: - self._conn.schemaless_insert(lines, 0) + self._conn.schemaless_insert(lines, TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) raise Exception("should not reach here") except SchemalessError as err: tdSql.checkNotEqual(err.errno, 0) @@ -1049,7 +1050,7 @@ class TDTestCase: def genMultiThreadSeq(self, sql_list): tlist = list() for insert_sql in sql_list: - t = threading.Thread(target=self._conn.schemaless_insert,args=([insert_sql[0]], 0)) + t = threading.Thread(target=self._conn.schemaless_insert,args=([insert_sql[0]], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value)) tlist.append(t) return tlist @@ -1260,8 +1261,8 @@ class TDTestCase: input_sql1 = "rfasta,id=\"rfasta_1\",t0=true,t1=127i8,t2=32767i16,t3=2147483647i32,t4=9223372036854775807i64,t5=11.12345f32,t6=22.123456789f64,t7=\"ddzhiksj\",t8=L\"ncharTagValue\" c0=True,c1=127i8,c2=32767i16,c3=2147483647i32,c4=9223372036854775807i64,c5=11.12345f32,c6=22.123456789f64,c7=\"bnhwlgvj\",c8=L\"ncharTagValue\",c9=7u64 1626006933640000000ns" input_sql2 = "rfasta,id=\"rfasta_1\",t0=true,t1=127i8,t2=32767i16,t3=2147483647i32,t4=9223372036854775807i64,t5=11.12345f32,t6=22.123456789f64 c0=True,c1=127i8,c2=32767i16,c3=2147483647i32,c4=9223372036854775807i64,c5=11.12345f32,c6=22.123456789f64 1626006933640000000ns" try: - self._conn.schemaless_insert([input_sql1], 0) - self._conn.schemaless_insert([input_sql2], 0) + self._conn.schemaless_insert([input_sql1], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) + self._conn.schemaless_insert([input_sql2], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) except SchemalessError as err: print(err.errno) # self._conn.schemaless_insert([input_sql2], 0) diff --git a/tests/pytest/query/udf.py b/tests/pytest/query/udf.py index 5b345643b30856195caab938f59c7e8f7a642784..14429a53f44b1393c9f179cc405ed61fb59e8b02 100644 --- a/tests/pytest/query/udf.py +++ b/tests/pytest/query/udf.py @@ -210,10 +210,10 @@ class TDTestCase: tdSql.query("select max(id) + 5 from tb1") tdSql.query("select max(id) + avg(val) from st") tdSql.query("select max(id) + avg(val) from tb1") - tdSql.error("select abs_max(number) + 5 from st") - tdSql.error("select abs_max(number) + 5 from tb1") + tdSql.query("select abs_max(number) + 5 from st") + tdSql.query("select abs_max(number) + 5 from tb1") tdSql.error("select abs_max(number) + max(id) from st") - tdSql.error("select abs_max(number)*abs_max(val) from st") + tdSql.query("select abs_max(number)*abs_max(val) from st") tdLog.info("======= UDF Nested query test =======") tdSql.query("select sum(id) from (select id from st)") diff --git a/tests/pytest/tools/taosdemoAllTest/TD-3453/query-interrupt.json b/tests/pytest/tools/taosdemoAllTest/TD-3453/query-interrupt.json index 5e53bd7e7d10edea9bdbc56ef9ab737dbb34684e..c2e4920097cd1b3581c9893c9677c3cf1f14b7ed 100644 --- a/tests/pytest/tools/taosdemoAllTest/TD-3453/query-interrupt.json +++ b/tests/pytest/tools/taosdemoAllTest/TD-3453/query-interrupt.json @@ -22,7 +22,7 @@ "cache": 50, "blocks": 8, "precision": "ms", - "keep": 365, + "keep": 36500, "minRows": 100, "maxRows": 4096, "comp":2, @@ -36,7 +36,7 @@ "name": "stb0", "child_table_exists":"no", "childtable_count": 60, - "childtable_prefix": "stb00_", + "childtable_prefix": "stb00_", "auto_create_table": "no", "batch_create_tbl_num": 20, "data_source": "rand", diff --git a/tests/pytest/tools/taosdemoAllTest/taosdemoInsertMSDB.json b/tests/pytest/tools/taosdemoAllTest/taosdemoInsertMSDB.json index 49ab6f3a4367b4cebd840bb24b43a5d190c0d464..fd458a88d1a434c22958d5086949009cdd6080bf 100644 --- a/tests/pytest/tools/taosdemoAllTest/taosdemoInsertMSDB.json +++ b/tests/pytest/tools/taosdemoAllTest/taosdemoInsertMSDB.json @@ -22,7 +22,7 @@ "cache": 50, "blocks": 8, "precision": "ms", - "keep": 36, + "keep": 36500, "minRows": 100, "maxRows": 4096, "comp":2, diff --git a/tests/pytest/tools/taosdemoAllTest/taosdemoInsertNanoDB.json b/tests/pytest/tools/taosdemoAllTest/taosdemoInsertNanoDB.json index 9a35df917dcbb2600852e8172da0be3ffacb0d15..99233bdd738d068664241efda40d96c5a6fc7090 100644 --- a/tests/pytest/tools/taosdemoAllTest/taosdemoInsertNanoDB.json +++ b/tests/pytest/tools/taosdemoAllTest/taosdemoInsertNanoDB.json @@ -22,7 +22,7 @@ "cache": 50, "blocks": 8, "precision": "ns", - "keep": 36, + "keep": 36500, "minRows": 100, "maxRows": 4096, "comp":2, diff --git a/tests/pytest/tools/taosdemoAllTest/taosdemoInsertUSDB.json b/tests/pytest/tools/taosdemoAllTest/taosdemoInsertUSDB.json index 631179dbaebfff29de6b38831b78fede989369d4..14bb9e9be07d9bd61dc089af0bb34acd523155d9 100644 --- a/tests/pytest/tools/taosdemoAllTest/taosdemoInsertUSDB.json +++ b/tests/pytest/tools/taosdemoAllTest/taosdemoInsertUSDB.json @@ -22,7 +22,7 @@ "cache": 50, "blocks": 8, "precision": "us", - "keep": 36, + "keep": 36500, "minRows": 100, "maxRows": 4096, "comp":2, diff --git a/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabase.json b/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabase.json index 246f1c35f29973fc20602284b37ae68de23f70c1..e6c4b3205a77e20714067733bfa6f6c4053f087c 100644 --- a/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabase.json +++ b/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabase.json @@ -22,7 +22,7 @@ "cache": 50, "blocks": 8, "precision": "ns", - "keep": 36, + "keep": 36500, "minRows": 100, "maxRows": 4096, "comp":2, diff --git a/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabaseInsertForSub.json b/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabaseInsertForSub.json index 0726f3905de2b254b49be51a7973d34b5eb6757e..a19132b1da9c99b8fe3792a1c2d475fd4f18ef91 100644 --- a/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabaseInsertForSub.json +++ b/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabaseInsertForSub.json @@ -22,7 +22,7 @@ "cache": 50, "blocks": 8, "precision": "ns", - "keep": 36, + "keep": 36500, "minRows": 100, "maxRows": 4096, "comp":2, diff --git a/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabaseNow.json b/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabaseNow.json index f36b1f9b4c1b83707b9482428d4303a5418ad2c3..3b4c43d5d05ee1a1b26ee4016b1c38aade592b56 100644 --- a/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabaseNow.json +++ b/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabaseNow.json @@ -22,7 +22,7 @@ "cache": 50, "blocks": 8, "precision": "ns", - "keep": 36, + "keep": 36500, "minRows": 100, "maxRows": 4096, "comp":2, diff --git a/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabasecsv.json b/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabasecsv.json index 867619ed8c1497e76077f96d257dd09a489d9eb7..7fb90727ef6fa38da73639ebe11125924b9ed507 100644 --- a/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabasecsv.json +++ b/tests/pytest/tools/taosdemoAllTest/taosdemoTestNanoDatabasecsv.json @@ -22,7 +22,7 @@ "cache": 50, "blocks": 8, "precision": "ns", - "keep": 36, + "keep": 36500, "minRows": 100, "maxRows": 4096, "comp":2, diff --git a/tests/pytest/tools/taosdemoAllTest/taosdemoTestQueryWithJson.py b/tests/pytest/tools/taosdemoAllTest/taosdemoTestQueryWithJson.py index 6021c9136ad235f3e9d07bb4f6654fdac54989e5..3a3152ecde3c4eca09d8b8583cf90bbfdc0cc31d 100644 --- a/tests/pytest/tools/taosdemoAllTest/taosdemoTestQueryWithJson.py +++ b/tests/pytest/tools/taosdemoAllTest/taosdemoTestQueryWithJson.py @@ -20,14 +20,16 @@ from util.dnodes import * import time from datetime import datetime import ast +import re # from assertpy import assert_that import subprocess + class TDTestCase: def init(self, conn, logSql): tdLog.debug("start to execute %s" % __file__) tdSql.init(conn.cursor(), logSql) - + def getBuildPath(self): selfPath = os.path.dirname(os.path.realpath(__file__)) @@ -40,52 +42,54 @@ class TDTestCase: if ("taosd" in files): rootRealPath = os.path.dirname(os.path.realpath(root)) if ("packaging" not in rootRealPath): - buildPath = root[:len(root)-len("/build/bin")] + buildPath = root[:len(root) - len("/build/bin")] break return buildPath # 获取taosc接口查询的结果文件中的内容,返回每行数据,并断言数据的第一列内容。 - def assertfileDataTaosc(self,filename,expectResult): + def assertfileDataTaosc(self, filename, expectResult): self.filename = filename self.expectResult = expectResult - with open("%s" % filename, 'r+') as f1: + with open("%s" % filename, 'r+') as f1: for line in f1.readlines(): queryResult = line.strip().split()[0] - self.assertCheck(filename,queryResult,expectResult) + self.assertCheck(filename, queryResult, expectResult) # 获取restful接口查询的结果文件中的关键内容,目前的关键内容找到第一个key就跳出循,所以就只有一个数据。后续再修改多个结果文件。 - def getfileDataRestful(self,filename): + def getfileDataRestful(self, filename): self.filename = filename - with open("%s" % filename, 'r+') as f1: + with open("%s" % filename, 'r+') as f1: for line in f1.readlines(): contents = line.strip() if contents.find("data") != -1: + pattern = re.compile("{.*}") + contents = pattern.search(contents).group() contentsDict = ast.literal_eval(contents) # 字符串转换为字典 queryResult = contentsDict['data'][0][0] break return queryResult # 获取taosc接口查询次数 - def queryTimesTaosc(self,filename): + def queryTimesTaosc(self, filename): self.filename = filename - command = 'cat %s |wc -l'% filename - times = int(subprocess.getstatusoutput(command)[1]) + command = 'cat %s |wc -l' % filename + times = int(subprocess.getstatusoutput(command)[1]) return times # 获取restful接口查询次数 - def queryTimesRestful(self,filename): + def queryTimesRestful(self, filename): self.filename = filename - command = 'cat %s |grep "200 OK" |wc -l'% filename - times = int(subprocess.getstatusoutput(command)[1]) + command = 'cat %s |grep "200 OK" |wc -l' % filename + times = int(subprocess.getstatusoutput(command)[1]) return times # 定义断言结果是否正确。不正确返回错误结果,正确即通过。 - def assertCheck(self,filename,queryResult,expectResult): + def assertCheck(self, filename, queryResult, expectResult): self.filename = filename self.queryResult = queryResult self.expectResult = expectResult args0 = (filename, queryResult, expectResult) - assert queryResult == expectResult , "Queryfile:%s ,result is %s != expect: %s" % args0 + assert queryResult == expectResult, "Queryfile:%s ,result is %s != expect: %s" % args0 def run(self): buildPath = self.getBuildPath() @@ -93,109 +97,144 @@ class TDTestCase: tdLog.exit("taosd not found!") else: tdLog.info("taosd found in %s" % buildPath) - binPath = buildPath+ "/build/bin/" - + binPath = buildPath + "/build/bin/" + # delete useless files - os.system("rm -rf ./query_res*") + os.system("rm -rf ./query_res*") os.system("rm -rf ./all_query*") - - # taosc query: query specified table and query super table - os.system("%staosdemo -f tools/taosdemoAllTest/queryInsertdata.json" % binPath) - os.system("%staosdemo -f tools/taosdemoAllTest/queryTaosc.json" % binPath) + + # taosc query: query specified table and query super table + os.system( + "%staosdemo -f tools/taosdemoAllTest/queryInsertdata.json" % + binPath) + os.system( + "%staosdemo -f tools/taosdemoAllTest/queryTaosc.json" % + binPath) os.system("cat query_res0.txt* > all_query_res0_taosc.txt") os.system("cat query_res1.txt* > all_query_res1_taosc.txt") os.system("cat query_res2.txt* > all_query_res2_taosc.txt") - - # correct Times testcases + + # correct Times testcases queryTimes0Taosc = self.queryTimesTaosc("all_query_res0_taosc.txt") - self.assertCheck("all_query_res0_taosc.txt",queryTimes0Taosc,6) + self.assertCheck("all_query_res0_taosc.txt", queryTimes0Taosc, 6) queryTimes1Taosc = self.queryTimesTaosc("all_query_res1_taosc.txt") - self.assertCheck("all_query_res1_taosc.txt",queryTimes1Taosc,6) + self.assertCheck("all_query_res1_taosc.txt", queryTimes1Taosc, 6) queryTimes2Taosc = self.queryTimesTaosc("all_query_res2_taosc.txt") - self.assertCheck("all_query_res2_taosc.txt",queryTimes2Taosc,20) - + self.assertCheck("all_query_res2_taosc.txt", queryTimes2Taosc, 20) + # correct data testcase - self.assertfileDataTaosc("all_query_res0_taosc.txt","1604160000099") - self.assertfileDataTaosc("all_query_res1_taosc.txt","100") - self.assertfileDataTaosc("all_query_res2_taosc.txt","1604160000199") - + self.assertfileDataTaosc("all_query_res0_taosc.txt", "1604160000099") + self.assertfileDataTaosc("all_query_res1_taosc.txt", "100") + self.assertfileDataTaosc("all_query_res2_taosc.txt", "1604160000199") + # delete useless files - os.system("rm -rf ./query_res*") + os.system("rm -rf ./query_res*") os.system("rm -rf ./all_query*") - # use restful api to query - os.system("%staosdemo -f tools/taosdemoAllTest/queryInsertrestdata.json" % binPath) - os.system("%staosdemo -f tools/taosdemoAllTest/queryRestful.json" % binPath) + os.system( + "%staosdemo -f tools/taosdemoAllTest/queryInsertrestdata.json" % + binPath) + os.system( + "%staosdemo -f tools/taosdemoAllTest/queryRestful.json" % + binPath) os.system("cat query_res0.txt* > all_query_res0_rest.txt") os.system("cat query_res1.txt* > all_query_res1_rest.txt") os.system("cat query_res2.txt* > all_query_res2_rest.txt") - - # correct Times testcases + + # correct Times testcases queryTimes0Restful = self.queryTimesRestful("all_query_res0_rest.txt") - self.assertCheck("all_query_res0_rest.txt",queryTimes0Restful,6) + self.assertCheck("all_query_res0_rest.txt", queryTimes0Restful, 6) queryTimes1Restful = self.queryTimesRestful("all_query_res1_rest.txt") - self.assertCheck("all_query_res1_rest.txt",queryTimes1Restful,6) - + self.assertCheck("all_query_res1_rest.txt", queryTimes1Restful, 6) + queryTimes2Restful = self.queryTimesRestful("all_query_res2_rest.txt") - self.assertCheck("all_query_res2_rest.txt",queryTimes2Restful,4) + self.assertCheck("all_query_res2_rest.txt", queryTimes2Restful, 4) # correct data testcase data0 = self.getfileDataRestful("all_query_res0_rest.txt") - self.assertCheck('all_query_res0_rest.txt',data0,"2020-11-01 00:00:00.009") + self.assertCheck( + 'all_query_res0_rest.txt', + data0, + "2020-11-01 00:00:00.009") data1 = self.getfileDataRestful("all_query_res1_rest.txt") - self.assertCheck('all_query_res1_rest.txt',data1,10) + self.assertCheck('all_query_res1_rest.txt', data1, 10) data2 = self.getfileDataRestful("all_query_res2_rest.txt") - self.assertCheck('all_query_res2_rest.txt',data2,"2020-11-01 00:00:00.004") - - + self.assertCheck( + 'all_query_res2_rest.txt', + data2, + "2020-11-01 00:00:00.004") + # query times less than or equal to 100 - os.system("%staosdemo -f tools/taosdemoAllTest/queryInsertdata.json" % binPath) - os.system("%staosdemo -f tools/taosdemoAllTest/querySpeciMutisql100.json" % binPath) - os.system("%staosdemo -f tools/taosdemoAllTest/querySuperMutisql100.json" % binPath) - - #query result print QPS - os.system("%staosdemo -f tools/taosdemoAllTest/queryInsertdata.json" % binPath) - os.system("%staosdemo -f tools/taosdemoAllTest/queryQps.json" % binPath) - + os.system( + "%staosdemo -f tools/taosdemoAllTest/queryInsertdata.json" % + binPath) + os.system( + "%staosdemo -f tools/taosdemoAllTest/querySpeciMutisql100.json" % + binPath) + os.system( + "%staosdemo -f tools/taosdemoAllTest/querySuperMutisql100.json" % + binPath) + + # query result print QPS + os.system( + "%staosdemo -f tools/taosdemoAllTest/queryInsertdata.json" % + binPath) + os.system( + "%staosdemo -f tools/taosdemoAllTest/queryQps.json" % + binPath) + # use illegal or out of range parameters query json file - os.system("%staosdemo -f tools/taosdemoAllTest/queryInsertdata.json" % binPath) - exceptcode = os.system("%staosdemo -f tools/taosdemoAllTest/queryTimes0.json" % binPath) + os.system( + "%staosdemo -f tools/taosdemoAllTest/queryInsertdata.json" % + binPath) + exceptcode = os.system( + "%staosdemo -f tools/taosdemoAllTest/queryTimes0.json" % + binPath) assert exceptcode != 0 - exceptcode0 = os.system("%staosdemo -f tools/taosdemoAllTest/queryTimesless0.json" % binPath) + exceptcode0 = os.system( + "%staosdemo -f tools/taosdemoAllTest/queryTimesless0.json" % + binPath) assert exceptcode0 != 0 - exceptcode1 = os.system("%staosdemo -f tools/taosdemoAllTest/queryConcurrentless0.json" % binPath) + exceptcode1 = os.system( + "%staosdemo -f tools/taosdemoAllTest/queryConcurrentless0.json" % + binPath) assert exceptcode1 != 0 - exceptcode2 = os.system("%staosdemo -f tools/taosdemoAllTest/queryConcurrent0.json" % binPath) + exceptcode2 = os.system( + "%staosdemo -f tools/taosdemoAllTest/queryConcurrent0.json" % + binPath) assert exceptcode2 != 0 - exceptcode3 = os.system("%staosdemo -f tools/taosdemoAllTest/querrThreadsless0.json" % binPath) + exceptcode3 = os.system( + "%staosdemo -f tools/taosdemoAllTest/querrThreadsless0.json" % + binPath) assert exceptcode3 != 0 - exceptcode4 = os.system("%staosdemo -f tools/taosdemoAllTest/querrThreads0.json" % binPath) + exceptcode4 = os.system( + "%staosdemo -f tools/taosdemoAllTest/querrThreads0.json" % + binPath) assert exceptcode4 != 0 # delete useless files os.system("rm -rf ./insert_res.txt") - os.system("rm -rf tools/taosdemoAllTest/*.py.sql") - os.system("rm -rf ./querySystemInfo*") - os.system("rm -rf ./query_res*") - os.system("rm -rf ./all_query*") + os.system("rm -rf tools/taosdemoAllTest/*.py.sql") + os.system("rm -rf ./querySystemInfo*") + os.system("rm -rf ./query_res*") +# os.system("rm -rf ./all_query*") os.system("rm -rf ./test_query_res0.txt") - - def stop(self): tdSql.close() tdLog.success("%s successfully executed" % __file__) + tdCases.addWindows(__file__, TDTestCase()) tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/pytest/tools/taosdemoAllTest/taosdemoTestSupportNanoInsert.py b/tests/pytest/tools/taosdemoAllTest/taosdemoTestSupportNanoInsert.py index c3fdff00ec15fc1ca0d55f86d430c5cbf86ad168..d8c68af0f9b43443744d7d799db6f5ee1e1dacaa 100644 --- a/tests/pytest/tools/taosdemoAllTest/taosdemoTestSupportNanoInsert.py +++ b/tests/pytest/tools/taosdemoAllTest/taosdemoTestSupportNanoInsert.py @@ -36,7 +36,7 @@ class TDTestCase: if ("taosd" in files): rootRealPath = os.path.dirname(os.path.realpath(root)) if ("packaging" not in rootRealPath): - buildPath = root[:len(root)-len("/build/bin")] + buildPath = root[:len(root) - len("/build/bin")] break return buildPath @@ -46,14 +46,15 @@ class TDTestCase: tdLog.exit("taosd not found!") else: tdLog.info("taosd found in %s" % buildPath) - binPath = buildPath+ "/build/bin/" + binPath = buildPath + "/build/bin/" - # insert: create one or mutiple tables per sql and insert multiple rows per sql # insert data from a special timestamp # check stable stb0 - os.system("%staosdemo -f tools/taosdemoAllTest/taosdemoTestNanoDatabase.json -y " % binPath) + os.system( + "%staosdemo -f tools/taosdemoAllTest/taosdemoTestNanoDatabase.json -y " % + binPath) tdSql.execute("use nsdb") tdSql.query("show stables") tdSql.checkData(0, 4, 100) @@ -64,9 +65,9 @@ class TDTestCase: tdSql.query("select count(*) from stb0") tdSql.checkData(0, 0, 10000) tdSql.query("describe stb0") - tdSql.checkDataType(9, 1,"TIMESTAMP") + tdSql.checkDataType(9, 1, "TIMESTAMP") tdSql.query("select last(ts) from stb0") - tdSql.checkData(0, 0,"2021-07-01 00:00:00.990000000") + tdSql.checkData(0, 0, "2021-07-01 00:00:00.990000000") # check stable stb1 which is insert with disord @@ -78,16 +79,18 @@ class TDTestCase: tdSql.checkData(0, 0, 10000) # check c8 is an nano timestamp tdSql.query("describe stb1") - tdSql.checkDataType(9, 1,"TIMESTAMP") + tdSql.checkDataType(9, 1, "TIMESTAMP") # check insert timestamp_step is nano_second tdSql.query("select last(ts) from stb1") - tdSql.checkData(0, 0,"2021-07-01 00:00:00.990000000") - + tdSql.checkData(0, 0, "2021-07-01 00:00:00.990000000") + # insert data from now time # check stable stb0 - os.system("%staosdemo -f tools/taosdemoAllTest/taosdemoTestNanoDatabaseNow.json -y " % binPath) - + os.system( + "%staosdemo -f tools/taosdemoAllTest/taosdemoTestNanoDatabaseNow.json -y " % + binPath) + tdSql.execute("use nsdb2") tdSql.query("show stables") tdSql.checkData(0, 4, 100) @@ -99,11 +102,14 @@ class TDTestCase: tdSql.checkData(0, 0, 10000) # check c8 is an nano timestamp tdSql.query("describe stb0") - tdSql.checkDataType(9,1,"TIMESTAMP") + tdSql.checkDataType(9, 1, "TIMESTAMP") + + # insert by csv files and timetamp is long int , strings in ts and + # cols - # insert by csv files and timetamp is long int , strings in ts and cols - - os.system("%staosdemo -f tools/taosdemoAllTest/taosdemoTestNanoDatabasecsv.json -y " % binPath) + os.system( + "%staosdemo -f tools/taosdemoAllTest/taosdemoTestNanoDatabasecsv.json -y " % + binPath) tdSql.execute("use nsdbcsv") tdSql.query("show stables") tdSql.checkData(0, 4, 100) @@ -111,29 +117,36 @@ class TDTestCase: tdSql.checkData(0, 0, 10000) tdSql.query("describe stb0") tdSql.checkDataType(3, 1, "TIMESTAMP") - tdSql.query("select count(*) from stb0 where ts > \"2021-07-01 00:00:00.490000000\"") + tdSql.query( + "select count(*) from stb0 where ts > \"2021-07-01 00:00:00.490000000\"") tdSql.checkData(0, 0, 5000) tdSql.query("select count(*) from stb0 where ts < 1626918583000000000") tdSql.checkData(0, 0, 10000) - + os.system("rm -rf ./insert_res.txt") os.system("rm -rf tools/taosdemoAllTest/taosdemoTestSupportNano*.py.sql") - # taosdemo test insert with command and parameter , detals show taosdemo --help - os.system("%staosdemo -u root -ptaosdata -P 6030 -a 1 -m pre -n 10 -T 20 -t 60 -o res.txt -y " % binPath) + # taosdemo test insert with command and parameter , detals show + # taosdemo --help + os.system( + "%staosdemo -u root -ptaosdata -P 6030 -a 1 -m pre -n 10 -T 20 -t 60 -o res.txt -y " % + binPath) tdSql.query("select count(*) from test.meters") tdSql.checkData(0, 0, 600) # check taosdemo -s - sqls_ls = ['drop database if exists nsdbsql;','create database nsdbsql precision "ns" keep 36 days 6 update 1;', - 'use nsdbsql;','CREATE STABLE meters (ts timestamp, current float, voltage int, phase float) TAGS (location binary(64), groupdId int);', - 'CREATE TABLE d1001 USING meters TAGS ("Beijing.Chaoyang", 2);', - 'INSERT INTO d1001 USING METERS TAGS ("Beijng.Chaoyang", 2) VALUES (now, 10.2, 219, 0.32);', - 'INSERT INTO d1001 USING METERS TAGS ("Beijng.Chaoyang", 2) VALUES (now, 85, 32, 0.76);'] + sqls_ls = [ + 'drop database if exists nsdbsql;', + 'create database nsdbsql precision "ns" keep 36500 days 6 update 1;', + 'use nsdbsql;', + 'CREATE STABLE meters (ts timestamp, current float, voltage int, phase float) TAGS (location binary(64), groupdId int);', + 'CREATE TABLE d1001 USING meters TAGS ("Beijing.Chaoyang", 2);', + 'INSERT INTO d1001 USING METERS TAGS ("Beijng.Chaoyang", 2) VALUES (now, 10.2, 219, 0.32);', + 'INSERT INTO d1001 USING METERS TAGS ("Beijng.Chaoyang", 2) VALUES (now, 85, 32, 0.76);'] - with open("./taosdemoTestNanoCreateDB.sql",mode ="a" ) as sql_files: + with open("./taosdemoTestNanoCreateDB.sql", mode="a") as sql_files: for sql in sqls_ls: - sql_files.write(sql+"\n") + sql_files.write(sql + "\n") sql_files.close() sleep(10) @@ -141,11 +154,10 @@ class TDTestCase: os.system("%staosdemo -s taosdemoTestNanoCreateDB.sql -y " % binPath) tdSql.query("select count(*) from nsdbsql.meters") tdSql.checkData(0, 0, 2) - + os.system("rm -rf ./res.txt") os.system("rm -rf ./*.py.sql") os.system("rm -rf ./taosdemoTestNanoCreateDB.sql") - def stop(self): tdSql.close() diff --git a/tests/pytest/util/types.py b/tests/pytest/util/types.py new file mode 100644 index 0000000000000000000000000000000000000000..218a4770269328a5ef7161cc56c0e0dc0c420f73 --- /dev/null +++ b/tests/pytest/util/types.py @@ -0,0 +1,38 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +from enum import Enum + +class TDSmlProtocolType(Enum): + ''' + Schemaless Protocol types + 0 - unknown + 1 - InfluxDB Line Protocol + 2 - OpenTSDB Telnet Protocl + 3 - OpenTSDB JSON Protocol + ''' + UNKNOWN = 0 + LINE = 1 + TELNET = 2 + JSON = 3 + +class TDSmlTimestampType(Enum): + NOT_CONFIGURED = 0 + HOUR = 1 + MINUTE = 2 + SECOND = 3 + MILLI_SECOND = 4 + MICRO_SECOND = 5 + NANO_SECOND = 6 + + diff --git a/tests/script/api/openTSDBTest.c b/tests/script/api/openTSDBTest.c index 2b9cf986f2f5278f1cfc1c8042d735423fdef312..8b70a324ea55c905c9a8bdaf67de9c258f9d57d7 100644 --- a/tests/script/api/openTSDBTest.c +++ b/tests/script/api/openTSDBTest.c @@ -22,168 +22,190 @@ void verify_telnet_insert(TAOS* taos) { /* metric */ char* lines0[] = { - "stb0_0 1626006833639000000ns 4i8 host=\"host0\" interface=\"eth0\"", - "stb0_1 1626006833639000000ns 4i8 host=\"host0\" interface=\"eth0\"", - "stb0_2 1626006833639000000ns 4i8 host=\"host0\" interface=\"eth0\"", + "stb0_0 1626006833639 4i8 host=\"host0\" interface=\"eth0\"", + "stb0_1 1626006833639 4i8 host=\"host0\" interface=\"eth0\"", + "stb0_2 1626006833639 4i8 host=\"host0\" interface=\"eth0\"", }; - code = taos_schemaless_insert(taos, lines0, 3, 1, NULL); + result = taos_schemaless_insert(taos, lines0, 3, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("lines0 code: %d, %s.\n", code, tstrerror(code)); } + taos_free_result(result); /* timestamp */ char* lines1[] = { - "stb1 1626006833s 1i8 host=\"host0\"", - "stb1 1626006833639000000ns 2i8 host=\"host0\"", - "stb1 1626006833640000us 3i8 host=\"host0\"", - "stb1 1626006833641 4i8 host=\"host0\"", - "stb1 1626006832 5i8 host=\"host0\"", - "stb1 1626006833651ms 6i8 host=\"host0\"", - "stb1 0 7i8 host=\"host0\"", + "stb1 1626006833641 1i8 host=\"host0\"", + "stb1 1626006832 2i8 host=\"host0\"", + "stb1 0 3i8 host=\"host0\"", }; - code = taos_schemaless_insert(taos, lines1, 7, 1, NULL); + result = taos_schemaless_insert(taos, lines1, 3, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("lines1 code: %d, %s.\n", code, tstrerror(code)); } + taos_free_result(result); /* metric value */ //tinyint char* lines2_0[] = { - "stb2_0 1626006833651ms -127i8 host=\"host0\"", - "stb2_0 1626006833652ms 127i8 host=\"host0\"" + "stb2_0 1626006833651 -127i8 host=\"host0\"", + "stb2_0 1626006833652 127i8 host=\"host0\"" }; - code = taos_schemaless_insert(taos, lines2_0, 2, 1, NULL); + result = taos_schemaless_insert(taos, lines2_0, 2, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("lines2_0 code: %d, %s.\n", code, tstrerror(code)); } + taos_free_result(result); //smallint char* lines2_1[] = { - "stb2_1 1626006833651ms -32767i16 host=\"host0\"", - "stb2_1 1626006833652ms 32767i16 host=\"host0\"" + "stb2_1 1626006833651 -32767i16 host=\"host0\"", + "stb2_1 1626006833652 32767i16 host=\"host0\"" }; - code = taos_schemaless_insert(taos, lines2_1, 2, 1, NULL); + result = taos_schemaless_insert(taos, lines2_1, 2, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("lines2_1 code: %d, %s.\n", code, tstrerror(code)); } + taos_free_result(result); //int char* lines2_2[] = { - "stb2_2 1626006833651ms -2147483647i32 host=\"host0\"", - "stb2_2 1626006833652ms 2147483647i32 host=\"host0\"" + "stb2_2 1626006833651 -2147483647i32 host=\"host0\"", + "stb2_2 1626006833652 2147483647i32 host=\"host0\"" }; - code = taos_schemaless_insert(taos, lines2_2, 2, 1, NULL); + result = taos_schemaless_insert(taos, lines2_2, 2, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("lines2_2 code: %d, %s.\n", code, tstrerror(code)); } + taos_free_result(result); //bigint char* lines2_3[] = { - "stb2_3 1626006833651ms -9223372036854775807i64 host=\"host0\"", - "stb2_3 1626006833652ms 9223372036854775807i64 host=\"host0\"" + "stb2_3 1626006833651 -9223372036854775807i64 host=\"host0\"", + "stb2_3 1626006833652 9223372036854775807i64 host=\"host0\"" }; - code = taos_schemaless_insert(taos, lines2_3, 2, 1, NULL); + result = taos_schemaless_insert(taos, lines2_3, 2, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("lines2_3 code: %d, %s.\n", code, tstrerror(code)); } + taos_free_result(result); //float char* lines2_4[] = { - "stb2_4 1626006833610ms 3f32 host=\"host0\"", - "stb2_4 1626006833620ms -3f32 host=\"host0\"", - "stb2_4 1626006833630ms 3.4f32 host=\"host0\"", - "stb2_4 1626006833640ms -3.4f32 host=\"host0\"", - "stb2_4 1626006833650ms 3.4E10f32 host=\"host0\"", - "stb2_4 1626006833660ms -3.4e10f32 host=\"host0\"", - "stb2_4 1626006833670ms 3.4E+2f32 host=\"host0\"", - "stb2_4 1626006833680ms -3.4e-2f32 host=\"host0\"", - "stb2_4 1626006833700ms 3.4E38f32 host=\"host0\"", - "stb2_4 1626006833710ms -3.4E38f32 host=\"host0\"" + "stb2_4 1626006833610 3f32 host=\"host0\"", + "stb2_4 1626006833620 -3f32 host=\"host0\"", + "stb2_4 1626006833630 3.4f32 host=\"host0\"", + "stb2_4 1626006833640 -3.4f32 host=\"host0\"", + "stb2_4 1626006833650 3.4E10f32 host=\"host0\"", + "stb2_4 1626006833660 -3.4e10f32 host=\"host0\"", + "stb2_4 1626006833670 3.4E+2f32 host=\"host0\"", + "stb2_4 1626006833680 -3.4e-2f32 host=\"host0\"", + "stb2_4 1626006833700 3.4E38f32 host=\"host0\"", + "stb2_4 1626006833710 -3.4E38f32 host=\"host0\"" }; - code = taos_schemaless_insert(taos, lines2_4, 10, 1, NULL); + result = taos_schemaless_insert(taos, lines2_4, 10, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("lines2_4 code: %d, %s.\n", code, tstrerror(code)); } + taos_free_result(result); //double char* lines2_5[] = { - "stb2_5 1626006833610ms 3f64 host=\"host0\"", - "stb2_5 1626006833620ms -3f64 host=\"host0\"", - "stb2_5 1626006833630ms 3.4f64 host=\"host0\"", - "stb2_5 1626006833640ms -3.4f64 host=\"host0\"", - "stb2_5 1626006833650ms 3.4E10f64 host=\"host0\"", - "stb2_5 1626006833660ms -3.4e10f64 host=\"host0\"", - "stb2_5 1626006833670ms 3.4E+2f64 host=\"host0\"", - "stb2_5 1626006833680ms -3.4e-2f64 host=\"host0\"", - "stb2_5 1626006833690ms 1.7E308f64 host=\"host0\"", - "stb2_5 1626006833700ms -1.7E308f64 host=\"host0\"", - "stb2_5 1626006833710ms 3.15 host=\"host0\"" + "stb2_5 1626006833610 3f64 host=\"host0\"", + "stb2_5 1626006833620 -3f64 host=\"host0\"", + "stb2_5 1626006833630 3.4f64 host=\"host0\"", + "stb2_5 1626006833640 -3.4f64 host=\"host0\"", + "stb2_5 1626006833650 3.4E10f64 host=\"host0\"", + "stb2_5 1626006833660 -3.4e10f64 host=\"host0\"", + "stb2_5 1626006833670 3.4E+2f64 host=\"host0\"", + "stb2_5 1626006833680 -3.4e-2f64 host=\"host0\"", + "stb2_5 1626006833690 1.7E308f64 host=\"host0\"", + "stb2_5 1626006833700 -1.7E308f64 host=\"host0\"", + "stb2_5 1626006833710 3.15 host=\"host0\"" }; - code = taos_schemaless_insert(taos, lines2_5, 11, 1, NULL); + result = taos_schemaless_insert(taos, lines2_5, 11, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("lines2_5 code: %d, %s.\n", code, tstrerror(code)); } + taos_free_result(result); //bool char* lines2_6[] = { - "stb2_6 1626006833610ms t host=\"host0\"", - "stb2_6 1626006833620ms T host=\"host0\"", - "stb2_6 1626006833630ms true host=\"host0\"", - "stb2_6 1626006833640ms True host=\"host0\"", - "stb2_6 1626006833650ms TRUE host=\"host0\"", - "stb2_6 1626006833660ms f host=\"host0\"", - "stb2_6 1626006833670ms F host=\"host0\"", - "stb2_6 1626006833680ms false host=\"host0\"", - "stb2_6 1626006833690ms False host=\"host0\"", - "stb2_6 1626006833700ms FALSE host=\"host0\"" + "stb2_6 1626006833610 t host=\"host0\"", + "stb2_6 1626006833620 T host=\"host0\"", + "stb2_6 1626006833630 true host=\"host0\"", + "stb2_6 1626006833640 True host=\"host0\"", + "stb2_6 1626006833650 TRUE host=\"host0\"", + "stb2_6 1626006833660 f host=\"host0\"", + "stb2_6 1626006833670 F host=\"host0\"", + "stb2_6 1626006833680 false host=\"host0\"", + "stb2_6 1626006833690 False host=\"host0\"", + "stb2_6 1626006833700 FALSE host=\"host0\"" }; - code = taos_schemaless_insert(taos, lines2_6, 10, 1, NULL); + result = taos_schemaless_insert(taos, lines2_6, 10, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("lines2_6 code: %d, %s.\n", code, tstrerror(code)); } + taos_free_result(result); //binary char* lines2_7[] = { - "stb2_7 1626006833610ms \"binary_val.!@#$%^&*\" host=\"host0\"", - "stb2_7 1626006833620ms \"binary_val.:;,./?|+-=\" host=\"host0\"", - "stb2_7 1626006833630ms \"binary_val.()[]{}<>\" host=\"host0\"" + "stb2_7 1626006833610 \"binary_val.!@#$%^&*\" host=\"host0\"", + "stb2_7 1626006833620 \"binary_val.:;,./?|+-=\" host=\"host0\"", + "stb2_7 1626006833630 \"binary_val.()[]{}<>\" host=\"host0\"" }; - code = taos_schemaless_insert(taos, lines2_7, 3, 1, NULL); + result = taos_schemaless_insert(taos, lines2_7, 3, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("lines2_7 code: %d, %s.\n", code, tstrerror(code)); } + taos_free_result(result); //nchar char* lines2_8[] = { - "stb2_8 1626006833610ms L\"nchar_val数值一\" host=\"host0\"", - "stb2_8 1626006833620ms L\"nchar_val数值二\" host=\"host0\"" + "stb2_8 1626006833610 L\"nchar_val数值一\" host=\"host0\"", + "stb2_8 1626006833620 L\"nchar_val数值二\" host=\"host0\"" }; - code = taos_schemaless_insert(taos, lines2_8, 2, 1, NULL); + result = taos_schemaless_insert(taos, lines2_8, 2, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("lines2_8 code: %d, %s.\n", code, tstrerror(code)); } + taos_free_result(result); /* tags */ //tag value types char* lines3_0[] = { - "stb3_0 1626006833610ms 1 t1=127i8 t2=32767i16 t3=2147483647i32 t4=9223372036854775807i64 t5=3.4E38f32 t6=1.7E308f64 t7=true t8=\"binary_val_1\" t9=L\"标签值1\"", - "stb3_0 1626006833610ms 2 t1=-127i8 t2=-32767i16 t3=-2147483647i32 t4=-9223372036854775807i64 t5=-3.4E38f32 t6=-1.7E308f64 t7=false t8=\"binary_val_2\" t9=L\"标签值2\"" + "stb3_0 1626006833610 1 t1=127i8 t2=32767i16 t3=2147483647i32 t4=9223372036854775807i64 t5=3.4E38f32 t6=1.7E308f64 t7=true t8=\"binary_val_1\" t9=L\"标签值1\"", + "stb3_0 1626006833610 2 t1=-127i8 t2=-32767i16 t3=-2147483647i32 t4=-9223372036854775807i64 t5=-3.4E38f32 t6=-1.7E308f64 t7=false t8=\"binary_val_2\" t9=L\"标签值2\"" }; - code = taos_schemaless_insert(taos, lines3_0, 2, 1, NULL); + result = taos_schemaless_insert(taos, lines3_0, 2, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("lines3_0 code: %d, %s.\n", code, tstrerror(code)); } + taos_free_result(result); //tag ID as child table name char* lines3_1[] = { - "stb3_1 1626006833610ms 1 id=child_table1 host=host1", - "stb3_1 1626006833610ms 2 host=host2 iD=child_table2", - "stb3_1 1626006833610ms 3 ID=child_table3 host=host3" + "stb3_1 1626006833610 1 id=child_table1 host=host1", + "stb3_1 1626006833610 2 host=host2 iD=child_table2", + "stb3_1 1626006833610 3 ID=child_table3 host=host3" }; - code = taos_schemaless_insert(taos, lines3_1, 3, 1, NULL); + result = taos_schemaless_insert(taos, lines3_1, 3, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("lines3_1 code: %d, %s.\n", code, tstrerror(code)); } + taos_free_result(result); return; } @@ -214,10 +236,12 @@ void verify_json_insert(TAOS* taos) { } \ }"}; - code = taos_schemaless_insert(taos, message, 0, 2, NULL); + result = taos_schemaless_insert(taos, message, 0, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("payload_0 code: %d, %s.\n", code, tstrerror(code)); } + taos_free_result(result); char *message1[] = { "[ \ @@ -245,10 +269,12 @@ void verify_json_insert(TAOS* taos) { } \ ]"}; - code = taos_schemaless_insert(taos, message1, 0, 2, NULL); + result = taos_schemaless_insert(taos, message1, 0, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("payload_1 code: %d, %s.\n", code, tstrerror(code)); } + taos_free_result(result); char *message2[] = { "[ \ @@ -296,10 +322,12 @@ void verify_json_insert(TAOS* taos) { } \ } \ ]"}; - code = taos_schemaless_insert(taos, message2, 0, 2, NULL); + result = taos_schemaless_insert(taos, message2, 0, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("payload_2 code: %d, %s.\n", code, tstrerror(code)); } + taos_free_result(result); cJSON *payload, *tags; @@ -320,12 +348,14 @@ void verify_json_insert(TAOS* taos) { *payload_str = cJSON_Print(payload); //printf("%s\n", payload_str); - code = taos_schemaless_insert(taos, payload_str, 0, 2, NULL); + result = taos_schemaless_insert(taos, payload_str, 0, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("payload0_0 code: %d, %s.\n", code, tstrerror(code)); } free(*payload_str); cJSON_Delete(payload); + taos_free_result(result); //true payload = cJSON_CreateObject(); @@ -341,12 +371,14 @@ void verify_json_insert(TAOS* taos) { *payload_str = cJSON_Print(payload); //printf("%s\n", payload_str); - code = taos_schemaless_insert(taos, payload_str, 0, 2, NULL); + result = taos_schemaless_insert(taos, payload_str, 0, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("payload0_1 code: %d, %s.\n", code, tstrerror(code)); } free(*payload_str); cJSON_Delete(payload); + taos_free_result(result); //false payload = cJSON_CreateObject(); @@ -362,12 +394,14 @@ void verify_json_insert(TAOS* taos) { *payload_str = cJSON_Print(payload); //printf("%s\n", payload_str); - code = taos_schemaless_insert(taos, payload_str, 0, 2, NULL); + result = taos_schemaless_insert(taos, payload_str, 0, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("payload0_2 code: %d, %s.\n", code, tstrerror(code)); } free(*payload_str); cJSON_Delete(payload); + taos_free_result(result); //string payload = cJSON_CreateObject(); @@ -383,12 +417,14 @@ void verify_json_insert(TAOS* taos) { *payload_str = cJSON_Print(payload); //printf("%s\n", payload_str); - code = taos_schemaless_insert(taos, payload_str, 0, 2, NULL); + result = taos_schemaless_insert(taos, payload_str, 0, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("payload0_3 code: %d, %s.\n", code, tstrerror(code)); } free(*payload_str); cJSON_Delete(payload); + taos_free_result(result); //timestamp 0 -> current time payload = cJSON_CreateObject(); @@ -404,12 +440,14 @@ void verify_json_insert(TAOS* taos) { *payload_str = cJSON_Print(payload); //printf("%s\n", payload_str); - code = taos_schemaless_insert(taos, payload_str, 0, 2, NULL); + result = taos_schemaless_insert(taos, payload_str, 0, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("payload0_4 code: %d, %s.\n", code, tstrerror(code)); } free(*payload_str); cJSON_Delete(payload); + taos_free_result(result); /* Nested format */ //timestamp @@ -433,12 +471,14 @@ void verify_json_insert(TAOS* taos) { *payload_str = cJSON_Print(payload); //printf("%s\n", payload_str); - code = taos_schemaless_insert(taos, payload_str, 0, 2, NULL); + result = taos_schemaless_insert(taos, payload_str, 0, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("payload1_0 code: %d, %s.\n", code, tstrerror(code)); } free(*payload_str); cJSON_Delete(payload); + taos_free_result(result); //milleseconds payload = cJSON_CreateObject(); @@ -459,12 +499,14 @@ void verify_json_insert(TAOS* taos) { *payload_str = cJSON_Print(payload); //printf("%s\n", payload_str); - code = taos_schemaless_insert(taos, payload_str, 0, 2, NULL); + result = taos_schemaless_insert(taos, payload_str, 0, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("payload1_1 code: %d, %s.\n", code, tstrerror(code)); } free(*payload_str); cJSON_Delete(payload); + taos_free_result(result); //microseconds payload = cJSON_CreateObject(); @@ -485,12 +527,14 @@ void verify_json_insert(TAOS* taos) { *payload_str = cJSON_Print(payload); //printf("%s\n", payload_str); - code = taos_schemaless_insert(taos, payload_str, 0, 2, NULL); + result = taos_schemaless_insert(taos, payload_str, 0, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("payload1_2 code: %d, %s.\n", code, tstrerror(code)); } free(*payload_str); cJSON_Delete(payload); + taos_free_result(result); //now payload = cJSON_CreateObject(); @@ -511,12 +555,14 @@ void verify_json_insert(TAOS* taos) { *payload_str = cJSON_Print(payload); //printf("%s\n", payload_str); - code = taos_schemaless_insert(taos, payload_str, 0, 2, NULL); + result = taos_schemaless_insert(taos, payload_str, 0, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("payload1_4 code: %d, %s.\n", code, tstrerror(code)); } free(*payload_str); cJSON_Delete(payload); + taos_free_result(result); //metric value cJSON *metric_val; @@ -543,12 +589,14 @@ void verify_json_insert(TAOS* taos) { *payload_str = cJSON_Print(payload); //printf("%s\n", payload_str); - code = taos_schemaless_insert(taos, payload_str, 0, 2, NULL); + result = taos_schemaless_insert(taos, payload_str, 0, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("payload2_0 code: %d, %s.\n", code, tstrerror(code)); } free(*payload_str); cJSON_Delete(payload); + taos_free_result(result); //tinyint payload = cJSON_CreateObject(); @@ -573,12 +621,14 @@ void verify_json_insert(TAOS* taos) { *payload_str = cJSON_Print(payload); //printf("%s\n", payload_str); - code = taos_schemaless_insert(taos, payload_str, 0, 2, NULL); + result = taos_schemaless_insert(taos, payload_str, 0, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("payload2_1 code: %d, %s.\n", code, tstrerror(code)); } free(*payload_str); cJSON_Delete(payload); + taos_free_result(result); //smallint payload = cJSON_CreateObject(); @@ -603,12 +653,14 @@ void verify_json_insert(TAOS* taos) { *payload_str = cJSON_Print(payload); //printf("%s\n", payload_str); - code = taos_schemaless_insert(taos, payload_str, 0, 2, NULL); + result = taos_schemaless_insert(taos, payload_str, 0, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("payload2_2 code: %d, %s.\n", code, tstrerror(code)); } free(*payload_str); cJSON_Delete(payload); + taos_free_result(result); //int payload = cJSON_CreateObject(); @@ -633,12 +685,14 @@ void verify_json_insert(TAOS* taos) { *payload_str = cJSON_Print(payload); //printf("%s\n", payload_str); - code = taos_schemaless_insert(taos, payload_str, 0, 2, NULL); + result = taos_schemaless_insert(taos, payload_str, 0, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("payload2_3 code: %d, %s.\n", code, tstrerror(code)); } free(*payload_str); cJSON_Delete(payload); + taos_free_result(result); //bigint payload = cJSON_CreateObject(); @@ -663,12 +717,14 @@ void verify_json_insert(TAOS* taos) { *payload_str = cJSON_Print(payload); //printf("%s\n", payload_str); - code = taos_schemaless_insert(taos, payload_str, 0, 2, NULL); + result = taos_schemaless_insert(taos, payload_str, 0, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("payload2_4 code: %d, %s.\n", code, tstrerror(code)); } free(*payload_str); cJSON_Delete(payload); + taos_free_result(result); //float payload = cJSON_CreateObject(); @@ -693,12 +749,14 @@ void verify_json_insert(TAOS* taos) { *payload_str = cJSON_Print(payload); //printf("%s\n", payload_str); - code = taos_schemaless_insert(taos, payload_str, 0, 2, NULL); + result = taos_schemaless_insert(taos, payload_str, 0, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("payload2_5 code: %d, %s.\n", code, tstrerror(code)); } free(*payload_str); cJSON_Delete(payload); + taos_free_result(result); //double payload = cJSON_CreateObject(); @@ -723,12 +781,14 @@ void verify_json_insert(TAOS* taos) { *payload_str = cJSON_Print(payload); //printf("%s\n", payload_str); - code = taos_schemaless_insert(taos, payload_str, 0, 2, NULL); + result = taos_schemaless_insert(taos, payload_str, 0, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("payload2_6 code: %d, %s.\n", code, tstrerror(code)); } free(*payload_str); cJSON_Delete(payload); + taos_free_result(result); //binary payload = cJSON_CreateObject(); @@ -753,12 +813,14 @@ void verify_json_insert(TAOS* taos) { *payload_str = cJSON_Print(payload); //printf("%s\n", payload_str); - code = taos_schemaless_insert(taos, payload_str, 0, 2, NULL); + result = taos_schemaless_insert(taos, payload_str, 0, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("payload2_7 code: %d, %s.\n", code, tstrerror(code)); } free(*payload_str); cJSON_Delete(payload); + taos_free_result(result); //nchar payload = cJSON_CreateObject(); @@ -783,12 +845,14 @@ void verify_json_insert(TAOS* taos) { *payload_str = cJSON_Print(payload); //printf("%s\n", payload_str); - code = taos_schemaless_insert(taos, payload_str, 0, 2, NULL); + result = taos_schemaless_insert(taos, payload_str, 0, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("payload2_8 code: %d, %s.\n", code, tstrerror(code)); } free(*payload_str); cJSON_Delete(payload); + taos_free_result(result); //tag value cJSON *tag; @@ -863,12 +927,14 @@ void verify_json_insert(TAOS* taos) { *payload_str = cJSON_Print(payload); //printf("%s\n", payload_str); - code = taos_schemaless_insert(taos, payload_str, 0, 2, NULL); + result = taos_schemaless_insert(taos, payload_str, 0, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); + code = taos_errno(result); if (code) { printf("payload3_0 code: %d, %s.\n", code, tstrerror(code)); } free(*payload_str); cJSON_Delete(payload); + taos_free_result(result); } int main(int argc, char *argv[]) { diff --git a/tests/script/fullGeneralSuite.sim b/tests/script/fullGeneralSuite.sim index ec72827c9697cbb30a5845ff5f2a2f809ada4164..ebc054777940430e9cdb78b55b496dda873f2143 100644 --- a/tests/script/fullGeneralSuite.sim +++ b/tests/script/fullGeneralSuite.sim @@ -228,4 +228,6 @@ run general/db/show_create_table.sim run general/parser/like.sim run general/parser/regex.sim run general/parser/tbname_escape.sim +run general/parser/columnName_escape.sim +run general/parser/tagName_escape.sim run general/parser/interp_blocks.sim diff --git a/tests/script/general/compute/csum2.sim b/tests/script/general/compute/csum2.sim index 506070ae369ccb4c1d2bc28d149c7126079a2b54..48de71df394a6f520ede1a2540ad78e215c57075 100644 --- a/tests/script/general/compute/csum2.sim +++ b/tests/script/general/compute/csum2.sim @@ -78,7 +78,9 @@ print ===> $data11 if $data11 != 1.000000000 then return -1 endi + sql_error select csum(c7) from $tb +sql_error select csum(c7) from $tb group by c8 sql_error select csum(c8) from $tb sql_error select csum(c9) from $tb sql_error select csum(ts) from $tb diff --git a/tests/script/general/compute/mavg2.sim b/tests/script/general/compute/mavg2.sim index 60b170e270505b7c3e8d2ee174a4e3b8a4ad223d..55c1fbb29fa276e0c58eb592d910dce8f01da558 100644 --- a/tests/script/general/compute/mavg2.sim +++ b/tests/script/general/compute/mavg2.sim @@ -80,6 +80,7 @@ if $data11 != 1.500000000 then endi sql_error select mavg(c7,2) from $tb sql_error select mavg(c8,2) from $tb +sql_error select mavg(c8,2) from $tb order by c7 sql_error select mavg(c9,2) from $tb sql_error select mavg(ts,2) from $tb sql_error select mavg(c1,2), mavg(c2,2) from $tb diff --git a/tests/script/general/parser/columnName_escape.sim b/tests/script/general/parser/columnName_escape.sim new file mode 100644 index 0000000000000000000000000000000000000000..dd3278d0dc98fa5378b7aed122dc39f6717372d5 --- /dev/null +++ b/tests/script/general/parser/columnName_escape.sim @@ -0,0 +1,426 @@ +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 100 +sql connect +print ======================== dnode1 start + +sql create database colesc; + +sql use colesc; + +print ======================= test create table/stable + + +sql create table tb0 (ts timestamp, `123` int, `123 456` int, `123.abc` int) +sql create table tb1 (ts timestamp, `!%^&*()` int) +sql create table tb2 (ts timestamp, `int` int, `bool` int, `double` int, `INTO` int, `COLUMN` int) + +sql create table stb0 (ts timestamp, `123` int, `123 456` int, `123.abc` int) tags (t1 int) +sql create table stb1 (ts timestamp, `!%^&*()` int) tags (t2 int) +sql create table stb2 (ts timestamp, `int` int, `bool` int, `double` int, `INTO` int, `COLUMN` int) tags (t3 int) + +sql create table ctb0 using stb0 tags (1) +sql create table ctb1 using stb1 tags (1) +sql create table ctb2 using stb2 tags (1) + +##check table +sql describe tb0; +if $rows != 4 then + return -1 +endi +if $data10 != @123@ then + return -1 +endi +if $data20 != @123 456@ then + return -1 +endi +if $data30 != @123.abc@ then + return -1 +endi + +sql describe tb1; +if $rows != 2 then + return -1 +endi +if $data10 != @!%^&*()@ then + return -1 +endi + +sql describe tb2; +if $rows != 6 then + return -1 +endi +if $data10 != @int@ then + return -1 +endi +if $data20 != @bool@ then + return -1 +endi +if $data30 != @double@ then + return -1 +endi +if $data40 != @INTO@ then + return -1 +endi +if $data50 != @COLUMN@ then + return -1 +endi +##check stable +sql describe stb0; +if $rows != 5 then + return -1 +endi +if $data10 != @123@ then + return -1 +endi +if $data20 != @123 456@ then + return -1 +endi +if $data30 != @123.abc@ then + return -1 +endi + +sql describe stb1; +if $rows != 3 then + return -1 +endi +if $data10 != @!%^&*()@ then + return -1 +endi + +sql describe stb2; +if $rows != 7 then + return -1 +endi +if $data10 != @int@ then + return -1 +endi +if $data20 != @bool@ then + return -1 +endi +if $data30 != @double@ then + return -1 +endi +if $data40 != @INTO@ then + return -1 +endi +if $data50 != @COLUMN@ then + return -1 +endi + + +print ======================= test Alter columns for table/stable + +##Add column +sql_error alter table tb0 add column `123` int +sql_error alter table tb0 add column `123 456` int +sql_error alter table tb0 add column `123.abc` int + +sql_error alter table ctb0 add column `1234` + +sql alter table tb0 add column `!%^&*()` int +sql alter table tb0 add column `int` int +sql alter table tb0 add column `bool` int +sql alter table tb0 add column `double` int +sql alter table tb0 add column `INTO` nchar(10) +sql alter table tb0 add column `COLUMN` binary(10) + +sql alter table stb0 add column `!%^&*()` int +sql alter table stb0 add column `int` int +sql alter table stb0 add column `bool` int +sql alter table stb0 add column `double` int +sql alter table stb0 add column `INTO` nchar(10) +sql alter table stb0 add column `COLUMN` binary(10) + + +##check table +sql describe tb0; +if $rows != 10 then + return -1 +endi +if $data40 != @!%^&*()@ then + return -1 +endi +if $data50 != @int@ then + return -1 +endi +if $data60 != @bool@ then + return -1 +endi +if $data70 != @double@ then + return -1 +endi +if $data80 != @INTO@ then + return -1 +endi +if $data90 != @COLUMN@ then + return -1 +endi + +#check stable +sql describe stb0; +if $rows != 11 then + return -1 +endi +if $data40 != @!%^&*()@ then + return -1 +endi +if $data50 != @int@ then + return -1 +endi +if $data60 != @bool@ then + return -1 +endi +if $data70 != @double@ then + return -1 +endi +if $data80 != @INTO@ then + return -1 +endi +if $data90 != @COLUMN@ then + return -1 +endi + +##Drop column + +sql_error alter table ctb0 drop column `123` +sql_error alter table ctb0 drop column `123 456` +sql_error alter table ctb0 drop column `123.abc` + +sql alter table tb0 drop column `!%^&*()` +sql alter table tb0 drop column `int` +sql alter table tb0 drop column `bool` +sql alter table tb0 drop column `double` +sql alter table tb0 drop column `INTO` +sql alter table tb0 drop column `COLUMN` + +sql alter table stb0 drop column `!%^&*()` +sql alter table stb0 drop column `int` +sql alter table stb0 drop column `bool` +sql alter table stb0 drop column `double` +sql alter table stb0 drop column `INTO` +sql alter table stb0 drop column `COLUMN` + +##check table +sql describe tb0; +if $rows != 4 then + return -1 +endi +if $data10 != @123@ then + return -1 +endi +if $data20 != @123 456@ then + return -1 +endi +if $data30 != @123.abc@ then + return -1 +endi + +##check stable +sql describe stb0; +if $rows != 5 then + return -1 +endi +if $data10 != @123@ then + return -1 +endi +if $data20 != @123 456@ then + return -1 +endi +if $data30 != @123.abc@ then + return -1 +endi + +##Modify column for binary/nchar length + +sql alter table tb0 add column `INTO` nchar(10) +sql alter table tb0 add column `COLUMN` binary(10) + +sql alter table stb0 add column `INTO` nchar(10) +sql alter table stb0 add column `COLUMN` binary(10) + +sql alter table tb0 modify column `INTO` nchar(15) +sql alter table tb0 modify column `COLUMN` binary(15) + +sql alter table stb0 modify column `INTO` nchar(15) +sql alter table stb0 modify column `COLUMN` binary(15) + +sql describe tb0; +if $rows != 6 then + return -1 +endi +if $data42 != @15@ then + return -1 +endi +if $data52 != @15@ then + return -1 +endi + +sql describe stb0; +if $rows != 7 then + return -1 +endi +if $data42 != @15@ then + return -1 +endi +if $data52 != @15@ then + return -1 +endi + +print ======================= test insert columns for table/stable + +sql insert into tb0 (ts, `123`, `123 456`, `123.abc`) values (now, 1, 1, 1) +sql insert into tb1 (ts, `!%^&*()`) values (now, 1) +sql insert into tb2 (ts, `int`, `bool`, `double`, `INTO`, `COLUMN`) values (now, 1, 1, 1, 1, 1) + +sql insert into ctb0 (ts, `123`, `123 456`, `123.abc`) values (now, 1, 1, 1) +sql insert into ctb1 (ts, `!%^&*()`) values (now, 1) +sql insert into ctb2 (ts, `int`, `bool`, `double`, `INTO`, `COLUMN`) values (now, 1, 1, 1, 1, 1) + +sql select * from tb0; +if $rows != 1 then + return -1 +endi + +sql select * from tb1; +if $rows != 1 then + return -1 +endi + +sql select * from tb2; +if $rows != 1 then + return -1 +endi + +sql select * from ctb0; +if $rows != 1 then + return -1 +endi + +sql select * from ctb1; +if $rows != 1 then + return -1 +endi + +sql select * from ctb2; +if $rows != 1 then + return -1 +endi + +print ======================= test select columns for table/stable + +sql select `123`,`123 456`,`123.abc` from tb0; + +if $rows != 1 then + return -1 +endi + +if $data00 != 1 then + return -1 +endi + +if $data01 != 1 then + return -1 +endi + +if $data02 != 1 then + return -1 +endi + +sql select `!%^&*()` from tb1; + +if $rows != 1 then + return -1 +endi + +if $data00 != 1 then + return -1 +endi + +sql select `int`,`bool`,`double`,`INTO`,`COLUMN` from tb2; + +if $rows != 1 then + return -1 +endi + +if $data00 != 1 then + return -1 +endi + +if $data01 != 1 then + return -1 +endi + +if $data02 != 1 then + return -1 +endi + +if $data03 != 1 then + return -1 +endi + +if $data04 != 1 then + return -1 +endi + + +sql select `123`,`123 456`,`123.abc` from stb0; + +if $rows != 1 then + return -1 +endi + +if $data00 != 1 then + return -1 +endi + +if $data01 != 1 then + return -1 +endi + +if $data02 != 1 then + return -1 +endi + +sql select `!%^&*()` from stb1; + +if $rows != 1 then + return -1 +endi + +if $data00 != 1 then + return -1 +endi + +sql select `int`,`bool`,`double`,`INTO`,`COLUMN` from stb2; + +if $rows != 1 then + return -1 +endi + +if $data00 != 1 then + return -1 +endi + +if $data01 != 1 then + return -1 +endi + +if $data02 != 1 then + return -1 +endi + +if $data03 != 1 then + return -1 +endi + +if $data04 != 1 then + return -1 +endi + +system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/general/parser/tagName_escape.sim b/tests/script/general/parser/tagName_escape.sim new file mode 100644 index 0000000000000000000000000000000000000000..9b04dc2899af0dc4489f8f5621bbd2db3a79789b --- /dev/null +++ b/tests/script/general/parser/tagName_escape.sim @@ -0,0 +1,186 @@ +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 100 +sql connect +print ======================== dnode1 start + +sql create database tagesc; + +sql use tagesc; + +print ======================= test create table/stable + +sql create stable stb0 (ts timestamp, c0 int) tags (`123` int, `123 456` int, `123.abc` int) +sql create stable stb1 (ts timestamp, c1 int) tags (`!%^&*()` int) +sql create stable stb2 (ts timestamp, c2 int) tags (`int` int, `bool` int, `double` int, `INTO` int, `COLUMN` int) + +sql create table ctb0 using stb0 (`123`, `123 456`, `123.abc`) tags (1, 1, 1) +sql create table ctb1 using stb1 (`!%^&*()`) tags (1) +sql create table ctb2 using stb2 (`int`, `bool`, `double`, `INTO`, `COLUMN`) tags (1, 1, 1, 1, 1) + +##check table +sql describe ctb0; +if $rows != 5 then + return -1 +endi +if $data20 != @123@ then + return -1 +endi +if $data30 != @123 456@ then + return -1 +endi +if $data40 != @123.abc@ then + return -1 +endi + +sql describe ctb1; +if $rows != 3 then + return -1 +endi +if $data20 != @!%^&*()@ then + return -1 +endi + +sql describe ctb2; +if $rows != 7 then + return -1 +endi +if $data20 != @int@ then + return -1 +endi +if $data30 != @bool@ then + return -1 +endi +if $data40 != @double@ then + return -1 +endi +if $data50 != @INTO@ then + return -1 +endi +if $data60 != @COLUMN@ then + return -1 +endi + +print ======================= test Alter tags for stable + +##ADD TAG +sql_error alter stable stb0 add tag `123` int +sql_error alter stable stb0 add tag `123 456` int +sql_error alter stable stb0 add tag `123.abc` int + +sql alter stable stb0 add tag `!%^&*()` int +sql alter stable stb0 add tag `int` int +sql alter stable stb0 add tag `bool` int +sql alter stable stb0 add tag `double` int +sql alter stable stb0 add tag `INTO` int +sql alter stable stb0 add tag `COLUMN` int + + +sql describe stb0; +if $rows != 11 then + return -1 +endi +if $data50 != @!%^&*()@ then + return -1 +endi +if $data60 != @int@ then + return -1 +endi +if $data70 != @bool@ then + return -1 +endi +if $data80 != @double@ then + return -1 +endi +if $data90 != @INTO@ then + return -1 +endi + + +##DROP TAG +sql alter stable stb0 drop tag `!%^&*()` +sql alter stable stb0 drop tag `int` +sql alter stable stb0 drop tag `bool` +sql alter stable stb0 drop tag `double` +sql alter stable stb0 drop tag `INTO` +sql alter stable stb0 drop tag `COLUMN` + + +sql describe stb0; +if $rows != 5 then + return -1 +endi +if $data20 != @123@ then + return -1 +endi +if $data30 != @123 456@ then + return -1 +endi +if $data40 != @123.abc@ then + return -1 +endi + + +##CHANGE TAG + +sql alter stable stb0 change tag `123` `321` +sql alter stable stb0 change tag `123 456` `456 123` +#sql alter stable stb0 change tag `123.abc` `abc.123` +#change tag has bug when using dot in tagname + +sql describe stb0; +if $rows != 5 then + return -1 +endi +if $data20 != @321@ then + return -1 +endi +if $data30 != @456 123@ then + return -1 +endi + +##SET TAG + +sql insert into ctb0 values (now, 1) +sql insert into ctb1 values (now, 1) +sql insert into ctb2 values (now, 1) + +sql alter table ctb0 set tag `321`=2 +sql alter table ctb0 set tag `456 123`=2 +#sql alter table ctb0 set tag `abc.123`=2 +#change tag has bug when using dot in tagname + +print ======================= test insert specific tags automatically create table + +sql alter table ctb0 set tag `321`=2 +sql alter table ctb0 set tag `321`=2 +sql insert into ctb0_0 using stb0 (`321`, `456 123`, `123.abc`) tags (1, 1, 1) values (now + 10s, 5) +sql insert into ctb1_0 using stb1 (`!%^&*()`) tags (1) values (now + 10s, 5) +sql insert into ctb2_0 using stb2 (`int`, `bool`, `double`, `INTO`, `COLUMN`) tags (1, 1, 1, 1, 1) values (now + 10s, 5) +sql insert into ctb2_1 using stb2 (`int`, `bool`, `INTO`, `COLUMN`) tags (1, 1, 1, 1) values (now + 10s, 5) + +sql select * from stb0; +if $rows != 2 then + return -1 +endi + +sql select * from stb1; +if $rows != 2 then + return -1 +endi + +sql select * from stb2; +if $rows != 3 then + return -1 +endi + +if $data24 != NULL then + return -1 +endi + +system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/general/parser/udf_dll.sim b/tests/script/general/parser/udf_dll.sim index 7168e0a5ddf5502170e6bb22f30b10621795a568..61bf5fee6e54d02ccc08218102a43a37821fdd30 100644 --- a/tests/script/general/parser/udf_dll.sim +++ b/tests/script/general/parser/udf_dll.sim @@ -452,6 +452,7 @@ if $data31 != 2 then return -1 endi +sql_error select add_one(f1) from tb1 order by ts desc; sql select add_one(f1) from tb1 limit 2; if $rows != 2 then diff --git a/tests/script/general/parser/udf_dll_stable.sim b/tests/script/general/parser/udf_dll_stable.sim index 15becaab22476d12829abc62db4de4f914eef271..cd1dbc8b5374779d13decde5bf8a0fce48d90f0a 100644 --- a/tests/script/general/parser/udf_dll_stable.sim +++ b/tests/script/general/parser/udf_dll_stable.sim @@ -10,9 +10,10 @@ sql connect print ======================== dnode1 start sql create function add_one as '/tmp/add_one.so' outputtype int; +sql create function add_one_64232 as '/tmp/add_one_64232.so' outputtype int; sql create aggregate function sum_double as '/tmp/sum_double.so' outputtype int; sql show functions; -if $rows != 2 then +if $rows != 3 then return -1 endi @@ -1154,6 +1155,93 @@ if $data61 != 22 then return -1 endi +sql_error select sum_double(f1),add_one(f1) from tb1 where ts>="2021-03-23 17:00:00.000" and ts<="2021-03-24 20:00:00.000" interval (1h) sliding (30m); + +sql select add_one(f1) from (select * from tb1); +if $rows != 7 then + return -1 +endi + +if $data00 != 2 then + return -1 +endi +if $data10 != 3 then + return -1 +endi +if $data20 != 4 then + return -1 +endi +if $data30 != 5 then + return -1 +endi +if $data40 != 6 then + return -1 +endi +if $data50 != 7 then + return -1 +endi +if $data60 != 8 then + return -1 +endi + +sql select add_one(ff1) from (select add_one(f1) as ff1 from tb1); +if $rows != 7 then + return -1 +endi + +if $data00 != 3 then + return -1 +endi +if $data10 != 4 then + return -1 +endi +if $data20 != 5 then + return -1 +endi +if $data30 != 6 then + return -1 +endi +if $data40 != 7 then + return -1 +endi +if $data50 != 8 then + return -1 +endi +if $data60 != 9 then + return -1 +endi + +sql_error select add_one(f1),sub_one(f1) from tb1; + + +sql create table taaa (ts timestamp, f1 bigint); +sql insert into taaa values (now, 1); +sleep 100 +sql insert into taaa values (now, 10); +sleep 100 +sql insert into taaa values (now, 1000); +sleep 100 +sql insert into taaa values (now, 100); + +sql select add_one_64232(f1) from taaa; +if $rows != 4 then + print $rows + return -1 +endi + +if $data00 != 2 then + return -1 +endi +if $data10 != 11 then + return -1 +endi +if $data20 != 1001 then + return -1 +endi +if $data30 != 101 then + return -1 +endi + system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index a9b2764495095b86c55f56c52c55c74f4e545e96..850f3a19467a8748bba56f80033d4fc0b0bc77a3 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -404,7 +404,7 @@ cd ../../../debug; make ./test.sh -f unique/mnode/mgmt34.sim ./test.sh -f unique/mnode/mgmtr2.sim -./test.sh -f unique/arbitrator/insert_duplicationTs.sim +#./test.sh -f unique/arbitrator/insert_duplicationTs.sim ./test.sh -f general/parser/join_manyblocks.sim ./test.sh -f general/parser/stableOp.sim ./test.sh -f general/parser/timestamp.sim @@ -415,4 +415,8 @@ cd ../../../debug; make ./test.sh -f general/parser/last_cache.sim ./test.sh -f unique/big/balance.sim +./test.sh -f general/parser/udf.sim +./test.sh -f general/parser/udf_dll.sim +./test.sh -f general/parser/udf_dll_stable.sim + #======================b7-end=============== diff --git a/tests/script/sh/abs_max.c b/tests/script/sh/abs_max.c index 2983ad1a43d60494f75d32978ca51c5e385fa0b2..e9f11feb414363eb0e741c722f4d4dd79b87e81e 100644 --- a/tests/script/sh/abs_max.c +++ b/tests/script/sh/abs_max.c @@ -38,6 +38,8 @@ void abs_max(char* data, short itype, short ibytes, int numOfRows, long long* ts *(long *)dataOutput=r; printf("abs_max out, dataoutput:%ld, numOfOutput:%d\n", *(long *)dataOutput, *numOfOutput); + } else { + *numOfOutput=0; } } @@ -47,7 +49,7 @@ void abs_max_finalize(char* dataOutput, char* interBuf, int* numOfOutput, SUdfIn int i; int r = 0; printf("abs_max_finalize dataoutput:%p:%d, numOfOutput:%d, buf:%p\n", dataOutput, *dataOutput, *numOfOutput, buf); - *numOfOutput=1; + printf("abs_max finalize, dataoutput:%ld, numOfOutput:%d\n", *(long *)dataOutput, *numOfOutput); } diff --git a/tests/script/sh/add_one_64232.c b/tests/script/sh/add_one_64232.c new file mode 100644 index 0000000000000000000000000000000000000000..8db87d049d607a7fed60580dcdaf682dcca944b4 --- /dev/null +++ b/tests/script/sh/add_one_64232.c @@ -0,0 +1,33 @@ +#include +#include +#include + +typedef struct SUdfInit{ + int maybe_null; /* 1 if function can return NULL */ + int decimals; /* for real functions */ + long long length; /* For string functions */ + char *ptr; /* free pointer for function data */ + int const_item; /* 0 if result is independent of arguments */ +} SUdfInit; + +void add_one_64232(char* data, short itype, short ibytes, int numOfRows, long long* ts, char* dataOutput, char* interBUf, char* tsOutput, + int* numOfOutput, short otype, short obytes, SUdfInit* buf) { + int i; + int r = 0; + printf("add_one_64232 input data:%p, type:%d, rows:%d, ts:%p,%lld, dataoutput:%p, tsOutput:%p, numOfOutput:%p, buf:%p\n", data, itype, numOfRows, ts, *ts, dataOutput, tsOutput, numOfOutput, buf); + if (itype == 5) { + for(i=0;i +#include +#include + +typedef struct SUdfInit{ + int maybe_null; /* 1 if function can return NULL */ + int decimals; /* for real functions */ + long long length; /* For string functions */ + char *ptr; /* free pointer for function data */ + int const_item; /* 0 if result is independent of arguments */ +} SUdfInit; + +void sub_one(char* data, short itype, short ibytes, int numOfRows, long long* ts, char* dataOutput, char* interBUf, char* tsOutput, + int* numOfOutput, short otype, short obytes, SUdfInit* buf) { + int i; + int r = 0; + printf("sub_one input data:%p, type:%d, rows:%d, ts:%p,%lld, dataoutput:%p, tsOutput:%p, numOfOutput:%p, buf:%p\n", data, itype, numOfRows, ts, *ts, dataOutput, tsOutput, numOfOutput, buf); + if (itype == 4) { + for(i=0;ifileName, rest); simLogSql(buf, true); - char * lines[] = {rest}; - int32_t ret = taos_schemaless_insert(script->taos, lines, 1, 0, "ns"); - if (ret == TSDB_CODE_SUCCESS) { + char* lines[] = {rest}; + TAOS_RES *result = taos_schemaless_insert(script->taos, lines, 1, TSDB_SML_LINE_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS); + int32_t code = taos_errno(result); + if (code == TSDB_CODE_SUCCESS) { simDebug("script:%s, taos:%p, %s executed. success.", script->fileName, script->taos, rest); script->linePos++; - return true; + ret = true; } else { - sprintf(script->error, "lineNum: %d. line: %s failed, ret:%d:%s", line->lineNum, rest, - ret & 0XFFFF, tstrerror(ret)); - return false; + sprintf(script->error, "lineNum: %d. line: %s failed, code:%d:%s", line->lineNum, rest, + code & 0XFFFF, taos_errstr(result)); + ret = false; } + taos_free_result(result); + return ret; } bool simExecuteLineInsertErrorCmd(SScript *script, char *rest) { + bool ret; char buf[TSDB_MAX_BINARY_LEN]; simVisuallizeOption(script, rest, buf); @@ -1107,14 +1112,17 @@ bool simExecuteLineInsertErrorCmd(SScript *script, char *rest) { simInfo("script:%s, %s", script->fileName, rest); simLogSql(buf, true); char * lines[] = {rest}; - int32_t ret = taos_schemaless_insert(script->taos, lines, 1, 0, "ns"); - if (ret == TSDB_CODE_SUCCESS) { + TAOS_RES *result = taos_schemaless_insert(script->taos, lines, 1, TSDB_SML_LINE_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS); + int32_t code = taos_errno(result); + if (code == TSDB_CODE_SUCCESS) { sprintf(script->error, "script:%s, taos:%p, %s executed. expect failed, but success.", script->fileName, script->taos, rest); script->linePos++; - return false; + ret = false; } else { - simDebug("lineNum: %d. line: %s failed, ret:%d:%s. Expect failed, so success", line->lineNum, rest, - ret & 0XFFFF, tstrerror(ret)); - return true; + simDebug("lineNum: %d. line: %s failed, code:%d:%s. Expect failed, so success", line->lineNum, rest, + code & 0XFFFF, taos_errstr(result)); + ret = true; } + taos_free_result(result); + return ret; }