提交 7026709d 编写于 作者: C Cary Xu

Merge branch 'develop' into feature/TS-463

import hudson.model.Result import hudson.model.Result
import hudson.model.*; import hudson.model.*;
import jenkins.model.CauseOfInterruption import jenkins.model.CauseOfInterruption
properties([pipelineTriggers([githubPush()])])
node { node {
git url: 'https://github.com/taosdata/TDengine.git'
} }
def skipbuild=0 def skipbuild=0
...@@ -194,6 +192,7 @@ def pre_test_win(){ ...@@ -194,6 +192,7 @@ def pre_test_win(){
} }
pipeline { pipeline {
agent none agent none
options { skipDefaultCheckout() }
environment{ environment{
WK = '/var/lib/jenkins/workspace/TDinternal' WK = '/var/lib/jenkins/workspace/TDinternal'
WKC= '/var/lib/jenkins/workspace/TDinternal/community' WKC= '/var/lib/jenkins/workspace/TDinternal/community'
...@@ -201,6 +200,7 @@ pipeline { ...@@ -201,6 +200,7 @@ pipeline {
stages { stages {
stage('pre_build'){ stage('pre_build'){
agent{label 'master'} agent{label 'master'}
options { skipDefaultCheckout() }
when{ when{
changeRequest() changeRequest()
} }
...@@ -209,52 +209,51 @@ pipeline { ...@@ -209,52 +209,51 @@ pipeline {
abort_previous() abort_previous()
abortPreviousBuilds() abortPreviousBuilds()
} }
sh''' // sh'''
rm -rf ${WORKSPACE}.tes // rm -rf ${WORKSPACE}.tes
cp -r ${WORKSPACE} ${WORKSPACE}.tes // cp -r ${WORKSPACE} ${WORKSPACE}.tes
cd ${WORKSPACE}.tes // cd ${WORKSPACE}.tes
git fetch // git fetch
''' // '''
script { // script {
if (env.CHANGE_TARGET == 'master') { // if (env.CHANGE_TARGET == 'master') {
sh ''' // sh '''
git checkout master // git checkout master
''' // '''
} // }
else if(env.CHANGE_TARGET == '2.0'){ // else if(env.CHANGE_TARGET == '2.0'){
sh ''' // sh '''
git checkout 2.0 // git checkout 2.0
''' // '''
} // }
else{ // else{
sh ''' // sh '''
git checkout develop // git checkout develop
''' // '''
} // }
} // }
sh''' // sh'''
git fetch origin +refs/pull/${CHANGE_ID}/merge // git fetch origin +refs/pull/${CHANGE_ID}/merge
git checkout -qf FETCH_HEAD // git checkout -qf FETCH_HEAD
''' // '''
script{ // script{
skipbuild='2' // skipbuild='2'
skipbuild=sh(script: "git log -2 --pretty=%B | fgrep -ie '[skip ci]' -e '[ci skip]' && echo 1 || echo 2", returnStdout:true) // skipbuild=sh(script: "git log -2 --pretty=%B | fgrep -ie '[skip ci]' -e '[ci skip]' && echo 1 || echo 2", returnStdout:true)
println skipbuild // println skipbuild
} // }
sh''' // sh'''
rm -rf ${WORKSPACE}.tes // rm -rf ${WORKSPACE}.tes
''' // '''
// }
} }
} }
stage('Parallel test stage') { stage('Parallel test stage') {
//only build pr //only build pr
options { skipDefaultCheckout() }
when { when {
allOf{ allOf{
changeRequest() changeRequest()
expression{
return skipbuild.trim() == '2'
}
not{ expression { env.CHANGE_BRANCH =~ /docs\// }} not{ expression { env.CHANGE_BRANCH =~ /docs\// }}
} }
} }
...@@ -262,7 +261,6 @@ pipeline { ...@@ -262,7 +261,6 @@ pipeline {
stage('python_1_s1') { stage('python_1_s1') {
agent{label " slave1 || slave11 "} agent{label " slave1 || slave11 "}
steps { steps {
pre_test() pre_test()
timeout(time: 55, unit: 'MINUTES'){ timeout(time: 55, unit: 'MINUTES'){
sh ''' sh '''
...@@ -415,7 +413,7 @@ pipeline { ...@@ -415,7 +413,7 @@ pipeline {
stage('test_b4_s7') { stage('test_b4_s7') {
agent{label " slave7 || slave17 "} agent{label " slave7 || slave17 "}
steps { steps {
timeout(time: 55, unit: 'MINUTES'){ timeout(time: 105, unit: 'MINUTES'){
pre_test() pre_test()
sh ''' sh '''
date date
......
...@@ -128,17 +128,25 @@ IF (TD_APLHINE) ...@@ -128,17 +128,25 @@ IF (TD_APLHINE)
MESSAGE(STATUS "aplhine is defined") MESSAGE(STATUS "aplhine is defined")
ENDIF () ENDIF ()
IF (TD_LINUX) MESSAGE("before BUILD_HTTP: " ${BUILD_HTTP})
IF (TD_ARM_32) IF ("${BUILD_HTTP}" STREQUAL "")
SET(TD_BUILD_HTTP TRUE) IF (TD_LINUX)
ADD_DEFINITIONS(-DHTTP_EMBEDDED) IF (TD_ARM_32)
ELSE () SET(BUILD_HTTP "true")
IF (TD_BUILD_HTTP) ELSE ()
ADD_DEFINITIONS(-DHTTP_EMBEDDED) SET(BUILD_HTTP "false")
ENDIF () ENDIF ()
ELSE ()
SET(BUILD_HTTP "true")
ENDIF () ENDIF ()
ELSE () ENDIF ()
MESSAGE("after BUILD_HTTP: " ${BUILD_HTTP})
IF (${BUILD_HTTP} MATCHES "true")
SET(TD_BUILD_HTTP TRUE) SET(TD_BUILD_HTTP TRUE)
ENDIF ()
IF (TD_BUILD_HTTP)
ADD_DEFINITIONS(-DHTTP_EMBEDDED) ADD_DEFINITIONS(-DHTTP_EMBEDDED)
ENDIF () ENDIF ()
......
...@@ -92,10 +92,6 @@ ENDIF () ...@@ -92,10 +92,6 @@ ENDIF ()
SET(TD_BUILD_HTTP FALSE) SET(TD_BUILD_HTTP FALSE)
IF (${BUILD_HTTP} MATCHES "true")
SET(TD_BUILD_HTTP TRUE)
ENDIF ()
SET(TD_MEMORY_SANITIZER FALSE) SET(TD_MEMORY_SANITIZER FALSE)
IF (${MEMORY_SANITIZER} MATCHES "true") IF (${MEMORY_SANITIZER} MATCHES "true")
SET(TD_MEMORY_SANITIZER TRUE) SET(TD_MEMORY_SANITIZER TRUE)
......
...@@ -131,7 +131,7 @@ TDengine是一个高效的存储、查询、分析时序大数据的平台,专 ...@@ -131,7 +131,7 @@ TDengine是一个高效的存储、查询、分析时序大数据的平台,专
* [TDengine写入性能测试工具](https://www.taosdata.com/blog/2020/01/18/1166.html) * [TDengine写入性能测试工具](https://www.taosdata.com/blog/2020/01/18/1166.html)
* [IDEA数据库管理工具可视化使用TDengine](https://www.taosdata.com/blog/2020/08/27/1767.html) * [IDEA数据库管理工具可视化使用TDengine](https://www.taosdata.com/blog/2020/08/27/1767.html)
* [基于Electron开发的跨平台TDengine图形化管理工具](https://github.com/skye0207/TDengineGUI) * [基于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与其他数据库的对比测试 ## TDengine与其他数据库的对比测试
......
...@@ -382,17 +382,17 @@ dataDir [path] <level> <primary> ...@@ -382,17 +382,17 @@ dataDir [path] <level> <primary>
各级存储之间的数据流向:0 级存储 -> 1 级存储 -> 2 级存储。 各级存储之间的数据流向: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/data1 0 1
dataDir /mnt/data2 0 1 dataDir /mnt/data2 0 0
dataDir /mnt/data3 1 1 dataDir /mnt/data3 1 0
dataDir /mnt/data4 1 1 dataDir /mnt/data4 1 0
dataDir /mnt/data5 2 1 dataDir /mnt/data5 2 0
dataDir /mnt/data6 2 1 dataDir /mnt/data6 2 0
``` ```
注意: 注意:
......
...@@ -405,45 +405,45 @@ typedef struct TAOS_MULTI_BIND { ...@@ -405,45 +405,45 @@ typedef struct TAOS_MULTI_BIND {
<a class="anchor" id="schemaless"></a> <a class="anchor" id="schemaless"></a>
### Schemaless 方式写入接口 ### Schemaless 方式写入接口
除了使用 SQL 方式或者使用参数绑定 API 写入数据外,还可以使用 Schemaless 的方式完成写入。Schemaless 可以免于预先创建超级表/数据子表的数据结构,而是可以直接写入数据,TDengine 系统会根据写入的数据内容自动创建和维护所需要的表结构。Schemaless 的使用方式详见 [Schemaless 写入](https://www.taosdata.com/cn/documentation/insert#schemaless) 章节,这里介绍与之配套使用的 C/C++ API。 除了使用 SQL 方式或者使用参数绑定 API 写入数据外,还可以使用 Schemaless 的方式完成写入。Schemaless 可以免于预先创建超级表/数据子表的数据结构,而是可以直接写入数据,TDengine 系统会根据写入的数据内容自动创建和维护所需要的表结构。Schemaless 的使用方式详见 [Schemaless 写入](https://www.taosdata.com/cn/documentation/insert#schemaless) 章节,这里介绍与之配套使用的 C/C++ API。
2.2.0.0版本接口: - `TAOS_RES* taos_schemaless_insert(TAOS* taos, const char* lines[], int numLines, int protocol, int precision)`
- `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文件中的错误码定义。
**说明** **功能说明**
协议类型是枚举类型,包含以下三种格式: 该接口将行协议的文本数据写入到TDengine中。
SML_LINE_PROTOCOL:InfluxDB行协议(Line Protocol)
SML_TELNET_PROTOCOL: OpenTSDB文本行协议 **参数说明**
SML_JSON_PROTOCOL: OpenTSDB Json协议格式 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 ```c
#include <stdlib.h> #include <stdlib.h>
...@@ -454,10 +454,7 @@ int main() { ...@@ -454,10 +454,7 @@ int main() {
const char* host = "127.0.0.1"; const char* host = "127.0.0.1";
const char* user = "root"; const char* user = "root";
const char* passwd = "taosdata"; const char* passwd = "taosdata";
// error message buffer
char msg[512] = {0};
// connect to server // connect to server
TAOS* taos = taos_connect(host, user, passwd, "test", 0); TAOS* taos = taos_connect(host, user, passwd, "test", 0);
...@@ -468,17 +465,18 @@ int main() { ...@@ -468,17 +465,18 @@ int main() {
}; };
// schema-less insert // schema-less insert
int code = taos_schemaless_insert(taos, lines1, 2, SML_LINE_PROTOCOL, "ns", msg, sizeof(msg)/sizeof(msg[0])); TAOS_RES* res = taos_schemaless_insert(taos, lines1, 2, TSDB_SML_LINE_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS);
if (code != 0) { if (taos_errno(res) != 0) {
printf("failed to insert schema-less data, reason: %s\n", msg); printf("failed to insert schema-less data, reason: %s\n", taos_errstr(res));
} }
taos_free_result(res);
// close the connection // close the connection
taos_close(taos); taos_close(taos);
return (code); return (code);
} }
``` ```
**注**:后续2.2.0.0版本也更新成2.3.0.0版本的接口。
### 连续查询接口 ### 连续查询接口
...@@ -575,6 +573,14 @@ cd C:\TDengine\connector\python ...@@ -575,6 +573,14 @@ cd C:\TDengine\connector\python
python -m pip install . python -m pip install .
``` ```
**PyPI**
从2.1.1版本开始,用户可以从[PyPI](https://pypi.org/project/taospy/)安装:
```sh
pip install taospy
```
* 如果机器上没有pip命令,用户可将src/connector/python下的taos文件夹拷贝到应用程序的目录使用。 * 如果机器上没有pip命令,用户可将src/connector/python下的taos文件夹拷贝到应用程序的目录使用。
对于windows 客户端,安装TDengine windows 客户端后,将C:\TDengine\driver\taos.dll拷贝到C:\windows\system32目录下即可。 对于windows 客户端,安装TDengine windows 客户端后,将C:\TDengine\driver\taos.dll拷贝到C:\windows\system32目录下即可。
...@@ -610,6 +616,22 @@ python3 PythonChecker.py -host <fqdn> ...@@ -610,6 +616,22 @@ python3 PythonChecker.py -host <fqdn>
### Python连接器的使用 ### 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客户端模块 * 导入TDengine客户端模块
...@@ -665,6 +687,44 @@ for data in c1: ...@@ -665,6 +687,44 @@ for data in c1:
print("ts=%s, temperature=%d, humidity=%f" %(data[0], data[1],data[2])) 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 ```python
......
# UDF(用户定义函数) # UDF(用户定义函数)
在有些应用场景中,应用逻辑需要的查询无法直接使用系统内置的函数来表示。利用 UDF 功能,TDengine 可以插入用户编写的处理代码并在查询中使用它们,就能够很方便地解决特殊应用场景中的使用需求。 在有些应用场景中,应用逻辑需要的查询无法直接使用系统内置的函数来表示。利用 UDF 功能,TDengine 可以插入用户编写的处理代码并在查询中使用它们,就能够很方便地解决特殊应用场景中的使用需求。 UDF 通常以数据表中的一列数据做为输入,同时支持以嵌套子查询的结果作为输入。
从 2.2.0.0 版本开始,TDengine 支持通过 C/C++ 语言进行 UDF 定义。接下来结合示例讲解 UDF 的使用方法。 从 2.2.0.0 版本开始,TDengine 支持通过 C/C++ 语言进行 UDF 定义。接下来结合示例讲解 UDF 的使用方法。
...@@ -9,76 +9,70 @@ ...@@ -9,76 +9,70 @@
TDengine 提供 3 个 UDF 的源代码示例,分别为: TDengine 提供 3 个 UDF 的源代码示例,分别为:
* [add_one.c](https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/add_one.c) * [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) * [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 中各参数的具体含义是: - udfNormalFunc 中各参数的具体含义是:
* data:存有输入的数据。 * data:输入数据。
* itype:输入数据的类型。这里采用的是短整型表示法,与各种数据类型对应的值可以参见 [column_meta 中的列类型说明](https://www.taosdata.com/cn/documentation/connector#column_meta)。例如 4 用于表示 INT 型。 * itype:输入数据的类型。这里采用的是短整型表示法,与各种数据类型对应的值可以参见 [column_meta 中的列类型说明](https://www.taosdata.com/cn/documentation/connector#column_meta)。例如 4 用于表示 INT 型。
* iBytes:输入数据中每个值会占用的字节数。 * iBytes:输入数据中每个值会占用的字节数。
* numOfRows:输入数据的总行数。 * numOfRows:输入数据的总行数。
* ts:主键时间戳在输入中的列数据。 * ts:主键时间戳在输入中的列数据(只读)
* dataOutput:输出数据的缓冲区。 * dataOutput:输出数据的缓冲区,缓冲区大小为用户指定的输出类型大小 * numOfRows
* interBuf:系统使用的中间临时缓冲区,通常用户逻辑无需对 interBuf 进行处理 * interBuf:中间计算结果的缓冲区,大小为用户在创建 UDF 时指定的BUFSIZE大小。通常用于计算中间结果与最终结果不一致时使用,由引擎负责分配与释放
* tsOutput:主键时间戳在输出时的列数据。 * tsOutput:主键时间戳在输出时的列数据,如果非空可用于输出结果对应的时间戳
* numOfOutput:输出数据的个数 * numOfOutput:输出结果的个数(行数)
* oType:输出数据的类型。取值含义与 itype 参数一致。 * oType:输出数据的类型。取值含义与 itype 参数一致。
* oBytes:输出数据中每个值占用的字节数。 * oBytes:输出数据中每个值占用的字节数。
* buf:计算过程的中间变量缓冲区 * buf:用于在 UDF 与引擎间的状态控制信息传递块
其中 buf 参数需要用到一个自定义结构体 SUdfInit。在这个例子中,因为 add_one 的计算过程无需用到中间变量缓存,所以可以把 SUdfInit 定义成一个空结构体。
### 无需中间变量的聚合函数 ### 聚合函数
[abs_max.c](https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/abs_max.c) 实现的是一个聚合函数,功能是对一组数据按绝对值取最大值。 [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 实现规则的一部分,系统会按照这些函数名后缀来调用相应功能。 值得注意的是,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)`,其中各参数的具体含义是: - udfMergeFunc 用于对计算中间结果进行聚合,只有针对超级表的聚合查询才需要调用该函数。本例中 udfMergeFunc 对应的实现函数为 `void abs_max_merge(char* data, int32_t numOfRows, char* dataOutput, int32_t* numOfOutput, SUdfInit* buf)`,其中各参数的具体含义是:
* data:udfNormalFunc 的输出组合在一起的数据,也就成为了 udfMergeFunc 的输入 * data:udfNormalFunc 的输出数据数组,如果使用了 interBuf 那么 data 就是 interBuf 的数组
* numOfRows:data 中数据的行数。 * numOfRows:data 中数据的行数。
* dataOutput:输出数据的缓冲区。 * dataOutput:输出数据的缓冲区,大小等于一条最终结果的大小。如果此时输出还不是最终结果,可以选择输出到 interBuf 中即data中。
* numOfOutput:输出数据的个数。 * numOfOutput:输出结果的个数(行数)。
* buf:计算过程的中间变量缓冲区。 * buf:用于在 UDF 与引擎间的状态控制信息传递块。
- udfFinalizeFunc 用于对计算结果进行最终聚合。本例中 udfFinalizeFunc 对应的实现函数为 `void abs_max_finalize(char* dataOutput, char* interBuf, int* numOfOutput, SUdfInit* buf)`,其中各参数的具体含义是:
* dataOutput:输出数据的缓冲区。对 udfFinalizeFunc 来说,其输入数据也来自于这里。
* interBuf:系统使用的中间临时缓冲区,与 udfNormalFunc 中的同名参数含义一致。
* numOfOutput:输出数据的个数。
* buf:计算过程的中间变量缓冲区。
同样因为 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)`,其中各参数的具体含义是: - udfInitFunc 用于初始化状态控制信息传递块。上例中 udfInitFunc 对应的实现函数为 `int abs_max_init(SUdfInit* buf)`,其中各参数的具体含义是:
* buf:计算过程的中间变量缓冲区 * buf:用于在 UDF 与引擎间的状态控制信息传递块
- udfDestroyFunc 用于释放中间变量缓冲区中的变量和内容。本例中 udfDestroyFunc 对应的实现函数为 `void sum_double_destroy(SUdfInit* buf)`,其中各参数的具体含义是: - udfDestroyFunc 用于释放状态控制信息传递块。上例中 udfDestroyFunc 对应的实现函数为 `void abs_max_destroy(SUdfInit* buf)`,其中各参数的具体含义是:
* buf:计算过程的中间变量缓冲区 * buf:用于在 UDF 与引擎间的状态控制信息传递块
注意,UDF 的实现过程中需要小心处理对中间变量缓冲区的使用,如果使用不当则有可能导致内存泄露或对资源的过度占用,甚至导致系统服务进程崩溃等 目前该功能暂时没有实际意义,待后续扩展使用
### UDF 实现方式的规则总结 ### UDF 实现方式的规则总结
根据所要实现的 UDF 类型不同,用户所要实现的功能函数内容也会有所区别 根据 UDF 函数类型的不同,用户所要实现的功能函数也不同
* 无需中间变量的标量函数:结构体 SUdfInit 可以为空,需实现 udfNormalFunc。 * 标量函数:UDF 中需实现 udfNormalFunc。
* 无需中间变量的聚合函数:结构体 SUdfInit 可以为空,需实现 udfNormalFunc、udfMergeFunc、udfFinalizeFunc。 * 聚合函数:UDF 中需实现 udfNormalFunc、udfMergeFunc(对超级表查询)、udfFinalizeFunc。
* 使用中间变量的标量函数:结构体 SUdfInit 需要具体定义,并需实现 udfNormalFunc、udfInitFunc、udfDestroyFunc。
* 使用中间变量的聚合函数:结构体 SUdfInit 需要具体定义,并需实现 udfNormalFunc、udfInitFunc、udfDestroyFunc、udfMergeFunc、udfFinalizeFunc 需要注意的是,如果对应的函数不需要具体的功能,也需要实现一个空函数
## 编译 UDF ## 编译 UDF
...@@ -97,28 +91,30 @@ gcc -g -O0 -fPIC -shared add_one.c -o add_one.so ...@@ -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 也仍然可用。 用户可以通过 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(X):标量函数未来在 SQL 指令中被调用时的函数名,必须与函数实现中 udfNormalFunc 的实际名称一致;
* ids(Y):包含 UDF 函数实现的动态链接库的库文件路径(指的是库文件在当前客户端所在主机上的保存路径,通常是指向一个 .so 文件),这个路径需要用英文单引号或英文双引号括起来; * ids(Y):包含 UDF 函数实现的动态链接库的库文件绝对路径(指的是库文件在当前客户端所在主机上的保存路径,通常是指向一个 .so 文件),这个路径需要用英文单引号或英文双引号括起来;
* typename(Z):此函数计算结果的数据类型,与上文中 udfNormalFunc 的 itype 参数不同,这里不是使用数字表示法,而是直接写类型名称即可; * typename(Z):此函数计算结果的数据类型,与上文中 udfNormalFunc 的 itype 参数不同,这里不是使用数字表示法,而是直接写类型名称即可;
* B:系统使用的中间临时缓冲区大小,单位是字节,最小 0,最大 512,通常可以设置为 128 * B:中间计算结果的缓冲区大小,单位是字节,最小 0,最大 512,如果不使用可以不设置
例如,如下语句可以把 add_one.so 创建为系统中可用的 UDF: 例如,如下语句可以把 add_one.so 创建为系统中可用的 UDF:
```sql ```sql
CREATE FUNCTION add_one AS "/home/taos/udf_example/add_one.so" OUTPUTTYPE INT; 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(X):聚合函数未来在 SQL 指令中被调用时的函数名,必须与函数实现中 udfNormalFunc 的实际名称一致;
* ids(Y):包含 UDF 函数实现的动态链接库的库文件路径(指的是库文件在当前客户端所在主机上的保存路径,通常是指向一个 .so 文件),这个路径需要用英文单引号或英文双引号括起来; * ids(Y):包含 UDF 函数实现的动态链接库的库文件绝对路径(指的是库文件在当前客户端所在主机上的保存路径,通常是指向一个 .so 文件),这个路径需要用英文单引号或英文双引号括起来;
* typename(Z):此函数计算结果的数据类型,与上文中 udfNormalFunc 的 itype 参数不同,这里不是使用数字表示法,而是直接写类型名称即可; * 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 ```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 ### 管理 UDF
...@@ -140,7 +136,7 @@ SELECT X(c) FROM table/stable; ...@@ -140,7 +136,7 @@ SELECT X(c) FROM table/stable;
在当前版本下,使用 UDF 存在如下这些限制: 在当前版本下,使用 UDF 存在如下这些限制:
1. 在创建和调用 UDF 时,服务端和客户端都只支持 Linux 操作系统; 1. 在创建和调用 UDF 时,服务端和客户端都只支持 Linux 操作系统;
2. UDF 不能与系统内建的 SQL 函数混合使用; 2. UDF 不能与系统内建的 SQL 函数混合使用,暂不支持在一条 SQL 语句中使用多个不同名的 UDF
3. UDF 只支持以单个数据列作为输入; 3. UDF 只支持以单个数据列作为输入;
4. UDF 只要创建成功,就会被持久化存储到 MNode 节点中; 4. UDF 只要创建成功,就会被持久化存储到 MNode 节点中;
5. 无法通过 RESTful 接口来创建 UDF; 5. 无法通过 RESTful 接口来创建 UDF;
......
...@@ -1579,11 +1579,11 @@ SELECT function_list FROM stb_name ...@@ -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); CREATE TABLE meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT);
``` ```
针对智能电表采集的数据,以 10 分钟为一个阶段,计算过去 24 小时的电流数据的平均值、最大值、电流的中位数、以及随着时间变化的电流走势拟合直线。如果没有计算值,用前一个非 NULL 值填充。使用的查询语句如下: 针对智能电表采集的数据,以 10 分钟为一个阶段,计算过去 24 小时的电流数据的平均值、最大值、电流的中位数。如果没有计算值,用前一个非 NULL 值填充。使用的查询语句如下:
```mysql ```mysql
SELECT AVG(current), MAX(current), LEASTSQUARES(current, start_val, step_val), PERCENTILE(current, 50) FROM meters SELECT AVG(current), MAX(current), APERCENTILE(current, 50) FROM meters
WHERE ts>=NOW-1d WHERE ts>=NOW-1d and ts<=now
INTERVAL(10m) INTERVAL(10m)
FILL(PREV); FILL(PREV);
``` ```
......
...@@ -183,9 +183,10 @@ TDengine 中时间戳的时区总是由客户端进行处理,而与服务端 ...@@ -183,9 +183,10 @@ TDengine 中时间戳的时区总是由客户端进行处理,而与服务端
| TCP | 6035 | 多节点集群的节点间通讯。 | 随 serverPort 端口变化。 | | TCP | 6035 | 多节点集群的节点间通讯。 | 随 serverPort 端口变化。 |
| TCP | 6040 | 多节点集群的节点间数据同步。 | 随 serverPort 端口变化。 | | TCP | 6040 | 多节点集群的节点间数据同步。 | 随 serverPort 端口变化。 |
| TCP | 6041 | 客户端与服务端之间的 RESTful 通讯。 | 随 serverPort 端口变化。 | | TCP | 6041 | 客户端与服务端之间的 RESTful 通讯。 | 随 serverPort 端口变化。 |
| TCP | 6042 | Arbitrator 的服务端口。 | 随 Arbitrator 启动参数设置变化。 | | TCP | 6042 | Arbitrator 的服务端口。 | 随 Arbitrator 启动参数设置变化。 |
| TCP | 6043 | 支持 collectd 数据接入端口。 | 随 BLM3 启动参数设置变化(2.3.0.1+以上版本)。 | | TCP | 6043 | TaosKeeper 监控服务端口。 | 随 TaosKeeper 启动参数设置变化。 |
| TCP | 6044 | 支持 StatsD 的数据接入端口。 | 随 BLM3 启动参数设置变化(2.3.0.1+以上版本)。 | | TCP | 6044 | 支持 StatsD 的数据接入端口。 | 随 BLM3 启动参数设置变化(2.3.0.1+以上版本)。 |
| TCP | 6045 | 支持 collectd 数据接入端口。 | 随 BLM3 启动参数设置变化(2.3.0.1+以上版本)。 |
| TCP | 6060 | 企业版内 Monitor 服务的网络端口。 | | | TCP | 6060 | 企业版内 Monitor 服务的网络端口。 | |
| UDP | 6030-6034 | 客户端与服务端之间通讯。 | 随 serverPort 端口变化。 | | UDP | 6030-6034 | 客户端与服务端之间通讯。 | 随 serverPort 端口变化。 |
| UDP | 6035-6039 | 多节点集群的节点间通讯。 | 随 serverPort 端口变化。 | | UDP | 6035-6039 | 多节点集群的节点间通讯。 | 随 serverPort 端口变化。 |
...@@ -193,12 +194,14 @@ TDengine 中时间戳的时区总是由客户端进行处理,而与服务端 ...@@ -193,12 +194,14 @@ TDengine 中时间戳的时区总是由客户端进行处理,而与服务端
## 20. go 语言编写组件编译失败怎样解决? ## 20. go 语言编写组件编译失败怎样解决?
新版本 TDengine 2.3.0.0 包含一个使用 go 语言开发的 BLM3 组件,取代之前内置的 httpd ,提供包含原 httpd 功能以及支持多种其他软件(Prometheus、Telegraf、collectd、StatsD等)的数据接入功能。 新版本 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 环境变量来解决: 目前编译方式默认自动编译 blm3。go 语言版本要求 1.14 以上,如果发生 go 编译错误,往往是国内访问 go mod 问题,可以通过设置 go 环境变量来解决:
```sh
go env -w GO111MODULE=on go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct go env -w GOPROXY=https://goproxy.cn,direct
```
如果希望继续使用之前的内置 httpd,可以关闭 blm3 编译,使用 如果希望继续使用之前的内置 httpd,可以关闭 blm3 编译,使用
cmake .. -DBUILD_HTTP=true 使用原来内置的 httpd。 `cmake .. -DBUILD_HTTP=true` 使用原来内置的 httpd。
...@@ -419,19 +419,47 @@ or ...@@ -419,19 +419,47 @@ or
`pip3 install src/connector/python/` `pip3 install src/connector/python/`
You can install the `taospy` connector from [PyPI](https://pypi.org/project/taospy/):
```sh
pip install taospy
```
#### Windows #### Windows
With Windows TDengine client installed, copy the file "C:\TDengine\driver\taos.dll" to the "C:\ windows\ system32" directory and enter the Windows <em>cmd</em> 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 ```cmd
cd C:\TDengine\connector\python cd C:\TDengine\connector\python
python -m pip install . 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. - 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 ### 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 #### Code sample
- Import the TDengine client module - Import the TDengine client module
...@@ -488,6 +516,44 @@ for data in c1: ...@@ -488,6 +516,44 @@ for data in c1:
print("ts=%s, temperature=%d, humidity=%f" %(data[0], data[1],data[2])) 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 - Create subscription
```python ```python
...@@ -510,6 +576,7 @@ for d in data: ...@@ -510,6 +576,7 @@ for d in data:
sub.close() sub.close()
``` ```
- Close connection - Close connection
```python ```python
......
...@@ -4,21 +4,19 @@ WORKDIR /root ...@@ -4,21 +4,19 @@ WORKDIR /root
ARG pkgFile ARG pkgFile
ARG dirName ARG dirName
RUN echo ${pkgFile} RUN echo ${pkgFile} && echo ${dirName}
RUN echo ${dirName}
COPY ${pkgFile} /root/ COPY ${pkgFile} /root/
RUN tar -zxf ${pkgFile} RUN tar -zxf ${pkgFile}
WORKDIR /root/${dirName}/ WORKDIR /root/${dirName}/
RUN /bin/bash install.sh -e no RUN /bin/bash install.sh -e no
RUN apt-get clean && apt-get update && apt-get install -y locales RUN apt-get clean && apt-get update && apt-get install -y locales && locale-gen en_US.UTF-8
RUN locale-gen en_US.UTF-8 ENV LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/lib" \
ENV LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/lib" LC_CTYPE=en_US.UTF-8 \
ENV LC_CTYPE=en_US.UTF-8 LANG=en_US.UTF-8 \
ENV LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8
ENV LC_ALL=en_US.UTF-8
EXPOSE 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 EXPOSE 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042
CMD ["taosd"] 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
...@@ -213,7 +213,7 @@ else ...@@ -213,7 +213,7 @@ else
exit 1 exit 1
fi fi
make -j8 make
cd ${curr_dir} cd ${curr_dir}
......
...@@ -395,8 +395,9 @@ function install_connector() { ...@@ -395,8 +395,9 @@ function install_connector() {
${csudo} cp -rf ${source_dir}/src/connector/python ${install_main_dir}/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 ${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 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 -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 ${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 fi
} }
......
name: tdengine name: tdengine
base: core18 base: core20
version: '2.3.0.0' version: '2.3.0.0'
icon: snap/gui/t-dengine.svg icon: snap/gui/t-dengine.svg
summary: an open-source big data platform designed and optimized for IoT. summary: an open-source big data platform designed and optimized for IoT.
...@@ -39,14 +39,17 @@ parts: ...@@ -39,14 +39,17 @@ parts:
- taoswrapper.sh - taoswrapper.sh
tdengine: tdengine:
plugin: cmake
source: . source: .
source-type: local source-type: local
plugin: cmake
build-packages: build-packages:
- gcc - gcc
- g++ - g++
- make - make
- cmake - cmake
cmake-parameters:
- -DCMAKE_BUILD_TYPE=Release
- -DBUILD_HTTP=true
override-build: | override-build: |
snapcraftctl build snapcraftctl build
if [ ! -d $SNAPCRAFT_STAGE/usr ]; then if [ ! -d $SNAPCRAFT_STAGE/usr ]; then
......
...@@ -23,6 +23,8 @@ extern "C" { ...@@ -23,6 +23,8 @@ extern "C" {
#define SML_TIMESTAMP_SECOND_DIGITS 10 #define SML_TIMESTAMP_SECOND_DIGITS 10
#define SML_TIMESTAMP_MILLI_SECOND_DIGITS 13 #define SML_TIMESTAMP_MILLI_SECOND_DIGITS 13
typedef TSDB_SML_PROTOCOL_TYPE SMLProtocolType;
typedef struct { typedef struct {
char* key; char* key;
uint8_t type; uint8_t type;
...@@ -46,22 +48,16 @@ typedef struct { ...@@ -46,22 +48,16 @@ typedef struct {
} TAOS_SML_DATA_POINT; } TAOS_SML_DATA_POINT;
typedef enum { typedef enum {
SML_TIME_STAMP_NOW, SML_TIME_STAMP_NOT_CONFIGURED,
SML_TIME_STAMP_HOURS, SML_TIME_STAMP_HOURS,
SML_TIME_STAMP_MINUTES, SML_TIME_STAMP_MINUTES,
SML_TIME_STAMP_SECONDS, SML_TIME_STAMP_SECONDS,
SML_TIME_STAMP_MILLI_SECONDS, SML_TIME_STAMP_MILLI_SECONDS,
SML_TIME_STAMP_MICRO_SECONDS, SML_TIME_STAMP_MICRO_SECONDS,
SML_TIME_STAMP_NANO_SECONDS, SML_TIME_STAMP_NANO_SECONDS,
SML_TIME_STAMP_NOT_CONFIGURED SML_TIME_STAMP_NOW
} SMLTimeStampType; } SMLTimeStampType;
typedef enum {
SML_LINE_PROTOCOL = 0,
SML_TELNET_PROTOCOL = 1,
SML_JSON_PROTOCOL = 2,
} SMLProtocolType;
typedef struct { typedef struct {
uint64_t id; uint64_t id;
SMLProtocolType protocol; SMLProtocolType protocol;
...@@ -71,6 +67,7 @@ typedef struct { ...@@ -71,6 +67,7 @@ typedef struct {
int64_t affectedRows; int64_t affectedRows;
} SSmlLinesInfo; } SSmlLinesInfo;
void addEscapeCharToString(char *str, int32_t len);
int tscSmlInsert(TAOS* taos, TAOS_SML_DATA_POINT* points, int numPoint, SSmlLinesInfo* info); int tscSmlInsert(TAOS* taos, TAOS_SML_DATA_POINT* points, int numPoint, SSmlLinesInfo* info);
bool checkDuplicateKey(char *key, SHashObj *pHash, SSmlLinesInfo* info); bool checkDuplicateKey(char *key, SHashObj *pHash, SSmlLinesInfo* info);
bool isValidInteger(char *str); bool isValidInteger(char *str);
...@@ -85,12 +82,12 @@ int32_t convertSmlTimeStamp(TAOS_SML_KV *pVal, char *value, ...@@ -85,12 +82,12 @@ int32_t convertSmlTimeStamp(TAOS_SML_KV *pVal, char *value,
void destroySmlDataPoint(TAOS_SML_DATA_POINT* point); void destroySmlDataPoint(TAOS_SML_DATA_POINT* point);
int taos_insert_sml_lines(TAOS* taos, char* lines[], int numLines, int taos_insert_lines(TAOS* taos, char* lines[], int numLines, SMLProtocolType protocol,
SMLProtocolType protocol, SMLTimeStampType tsType); SMLTimeStampType tsType, int* affectedRows);
int taos_insert_telnet_lines(TAOS* taos, char* lines[], int numLines, int taos_insert_telnet_lines(TAOS* taos, char* lines[], int numLines, SMLProtocolType protocol,
SMLProtocolType protocol, SMLTimeStampType tsType); SMLTimeStampType tsType, int* affectedRows);
int taos_insert_json_payload(TAOS* taos, char* payload, int taos_insert_json_payload(TAOS* taos, char* payload, SMLProtocolType protocol,
SMLProtocolType protocol, SMLTimeStampType tsType); SMLTimeStampType tsType, int* affectedRows);
#ifdef __cplusplus #ifdef __cplusplus
......
...@@ -251,6 +251,7 @@ void tscColumnListCopyAll(SArray* dst, const SArray* src); ...@@ -251,6 +251,7 @@ void tscColumnListCopyAll(SArray* dst, const SArray* src);
void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo, uint64_t objId, bool convertNchar); void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo, uint64_t objId, bool convertNchar);
void tscDequoteAndTrimToken(SStrToken* pToken); void tscDequoteAndTrimToken(SStrToken* pToken);
void tscRmEscapeAndTrimToken(SStrToken* pToken);
int32_t tscValidateName(SStrToken* pToken, bool escapeEnabled, bool *dbIncluded); int32_t tscValidateName(SStrToken* pToken, bool escapeEnabled, bool *dbIncluded);
void tscIncStreamExecutionCount(void* pStream); void tscIncStreamExecutionCount(void* pStream);
......
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* 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
#include <jni.h>
#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
...@@ -17,46 +17,9 @@ ...@@ -17,46 +17,9 @@
#include "taos.h" #include "taos.h"
#include "tlog.h" #include "tlog.h"
#include "tscUtil.h" #include "tscUtil.h"
#include "tscParseLine.h"
#include "com_taosdata_jdbc_TSDBJNIConnector.h" #include "com_taosdata_jdbc_TSDBJNIConnector.h"
#include "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__); \
} \
}
int __init = 0; int __init = 0;
...@@ -91,16 +54,7 @@ jmethodID g_blockdataSetByteArrayFp; ...@@ -91,16 +54,7 @@ jmethodID g_blockdataSetByteArrayFp;
jmethodID g_blockdataSetNumOfRowsFp; jmethodID g_blockdataSetNumOfRowsFp;
jmethodID g_blockdataSetNumOfColsFp; jmethodID g_blockdataSetNumOfColsFp;
#define JNI_SUCCESS 0 void jniGetGlobalMethod(JNIEnv *env) {
#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) {
// make sure init function executed once // make sure init function executed once
switch (atomic_val_compare_exchange_32(&__init, 0, 1)) { switch (atomic_val_compare_exchange_32(&__init, 0, 1)) {
case 0: case 0:
...@@ -159,7 +113,7 @@ static void jniGetGlobalMethod(JNIEnv *env) { ...@@ -159,7 +113,7 @@ static void jniGetGlobalMethod(JNIEnv *env) {
jniDebug("native method register finished"); 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) { if ((TAOS *)conn == NULL) {
jniError("jobj:%p, connection is closed", jobj); jniError("jobj:%p, connection is closed", jobj);
return JNI_CONNECTION_NULL; return JNI_CONNECTION_NULL;
...@@ -219,26 +173,8 @@ JNIEXPORT jobject createTSDBException(JNIEnv *env, int code, char *msg) { ...@@ -219,26 +173,8 @@ JNIEXPORT jobject createTSDBException(JNIEnv *env, int code, char *msg) {
return exception_obj; 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, JNIEXPORT jobject JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setConfigImp(JNIEnv *env, jclass jobj,
jstring config) { 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) { if (config == NULL) {
char *msg = "config value is null"; char *msg = "config value is null";
jniDebug("config value is null"); jniDebug("config value is null");
...@@ -254,7 +190,7 @@ JNIEXPORT jobject JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setConfigImp(J ...@@ -254,7 +190,7 @@ JNIEXPORT jobject JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setConfigImp(J
setConfRet result = taos_set_config(cfg); setConfRet result = taos_set_config(cfg);
int code = result.retCode; int code = result.retCode;
char * msg = result.retMsg; char *msg = result.retMsg;
return createTSDBException(env, code, msg); return createTSDBException(env, code, msg);
} }
...@@ -424,7 +360,7 @@ JNIEXPORT jstring JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getErrMsgImp(J ...@@ -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, JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getResultSetImp(JNIEnv *env, jobject jobj, jlong con,
jlong tres) { jlong tres) {
TAOS * tscon = (TAOS *)con; TAOS *tscon = (TAOS *)con;
int32_t code = check_for_params(jobj, con, tres); int32_t code = check_for_params(jobj, con, tres);
if (code != JNI_SUCCESS) { if (code != JNI_SUCCESS) {
return code; return code;
...@@ -467,7 +403,7 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_freeResultSetImp( ...@@ -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, JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getAffectedRowsImp(JNIEnv *env, jobject jobj, jlong con,
jlong res) { jlong res) {
TAOS * tscon = (TAOS *)con; TAOS *tscon = (TAOS *)con;
int32_t code = check_for_params(jobj, con, res); int32_t code = check_for_params(jobj, con, res);
if (code != JNI_SUCCESS) { if (code != JNI_SUCCESS) {
return code; return code;
...@@ -483,13 +419,13 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getAffectedRowsIm ...@@ -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, JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getSchemaMetaDataImp(JNIEnv *env, jobject jobj,
jlong con, jlong res, jlong con, jlong res,
jobject arrayListObj) { jobject arrayListObj) {
TAOS * tscon = (TAOS *)con; TAOS *tscon = (TAOS *)con;
int32_t code = check_for_params(jobj, con, res); int32_t code = check_for_params(jobj, con, res);
if (code != JNI_SUCCESS) { if (code != JNI_SUCCESS) {
return code; return code;
} }
TAOS_RES * tres = (TAOS_RES *)res; TAOS_RES *tres = (TAOS_RES *)res;
TAOS_FIELD *fields = taos_fetch_fields(tres); TAOS_FIELD *fields = taos_fetch_fields(tres);
int32_t num_fields = taos_num_fields(tres); int32_t num_fields = taos_num_fields(tres);
...@@ -626,13 +562,13 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchRowImp(JNIEn ...@@ -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, JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchBlockImp(JNIEnv *env, jobject jobj, jlong con,
jlong res, jobject rowobj) { jlong res, jobject rowobj) {
TAOS * tscon = (TAOS *)con; TAOS *tscon = (TAOS *)con;
int32_t code = check_for_params(jobj, con, res); int32_t code = check_for_params(jobj, con, res);
if (code != JNI_SUCCESS) { if (code != JNI_SUCCESS) {
return code; return code;
} }
TAOS_RES * tres = (TAOS_RES *)res; TAOS_RES *tres = (TAOS_RES *)res;
TAOS_FIELD *fields = taos_fetch_fields(tres); TAOS_FIELD *fields = taos_fetch_fields(tres);
int32_t numOfFields = taos_num_fields(tres); int32_t numOfFields = taos_num_fields(tres);
...@@ -1021,7 +957,7 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setTableNameTagsI ...@@ -1021,7 +957,7 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setTableNameTagsI
} }
const char *name = (*env)->GetStringUTFChars(env, tableName, NULL); const char *name = (*env)->GetStringUTFChars(env, tableName, NULL);
char * curTags = tagsData; char *curTags = tagsData;
TAOS_BIND *tagsBind = calloc(numOfTags, sizeof(TAOS_BIND)); TAOS_BIND *tagsBind = calloc(numOfTags, sizeof(TAOS_BIND));
for (int32_t i = 0; i < numOfTags; ++i) { for (int32_t i = 0; i < numOfTags; ++i) {
...@@ -1053,7 +989,8 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setTableNameTagsI ...@@ -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, 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; TAOS *taos = (TAOS *)conn;
if (taos == NULL) { if (taos == NULL) {
jniError("jobj:%p, connection already closed", jobj); jniError("jobj:%p, connection already closed", jobj);
...@@ -1071,7 +1008,8 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_insertLinesImp(J ...@@ -1071,7 +1008,8 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_insertLinesImp(J
c_lines[i] = (char *)(*env)->GetStringUTFChars(env, line, 0); 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) { for (int i = 0; i < numLines; ++i) {
jstring line = (jstring)((*env)->GetObjectArrayElement(env, lines, i)); jstring line = (jstring)((*env)->GetObjectArrayElement(env, lines, i));
...@@ -1080,9 +1018,10 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_insertLinesImp(J ...@@ -1080,9 +1018,10 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_insertLinesImp(J
tfree(c_lines); tfree(c_lines);
if (code != TSDB_CODE_SUCCESS) { 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 JNI_TDENGINE_ERROR;
} }
return code;
return (jlong)result;
} }
#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
...@@ -51,3 +51,4 @@ taos_stmt_bind_param_batch ...@@ -51,3 +51,4 @@ taos_stmt_bind_param_batch
taos_stmt_bind_single_param_batch taos_stmt_bind_single_param_batch
taos_is_null taos_is_null
taos_insert_lines taos_insert_lines
taos_schemaless_insert
...@@ -1251,10 +1251,18 @@ static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDat ...@@ -1251,10 +1251,18 @@ static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDat
sToken = tStrGetToken(str, &index, false); sToken = tStrGetToken(str, &index, false);
str += index; 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) { if (TK_STRING == sToken.type) {
tscDequoteAndTrimToken(&sToken); tscDequoteAndTrimToken(&sToken);
} }
if (TK_ID == sToken.type) {
tscRmEscapeAndTrimToken(&sToken);
}
if (sToken.type == TK_RP) { if (sToken.type == TK_RP) {
if (end != NULL) { // set the end position if (end != NULL) { // set the end position
*end = str; *end = str;
......
...@@ -499,6 +499,7 @@ static int32_t fillDbSchema(STableMeta* tableMeta, char* tableName, SSmlSTableSc ...@@ -499,6 +499,7 @@ static int32_t fillDbSchema(STableMeta* tableMeta, char* tableName, SSmlSTableSc
for (int i=0; i<tableMeta->tableInfo.numOfColumns; ++i) { for (int i=0; i<tableMeta->tableInfo.numOfColumns; ++i) {
SSchema field; SSchema field;
tstrncpy(field.name, tableMeta->schema[i].name, strlen(tableMeta->schema[i].name)+1); 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.type = tableMeta->schema[i].type;
field.bytes = tableMeta->schema[i].bytes; field.bytes = tableMeta->schema[i].bytes;
taosArrayPush(schema->fields, &field); taosArrayPush(schema->fields, &field);
...@@ -510,6 +511,7 @@ static int32_t fillDbSchema(STableMeta* tableMeta, char* tableName, SSmlSTableSc ...@@ -510,6 +511,7 @@ static int32_t fillDbSchema(STableMeta* tableMeta, char* tableName, SSmlSTableSc
int j = i + tableMeta->tableInfo.numOfColumns; int j = i + tableMeta->tableInfo.numOfColumns;
SSchema field; SSchema field;
tstrncpy(field.name, tableMeta->schema[j].name, strlen(tableMeta->schema[j].name)+1); 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.type = tableMeta->schema[j].type;
field.bytes = tableMeta->schema[j].bytes; field.bytes = tableMeta->schema[j].bytes;
taosArrayPush(schema->tags, &field); taosArrayPush(schema->tags, &field);
...@@ -1175,6 +1177,15 @@ static void escapeSpecialCharacter(uint8_t field, const char **pos) { ...@@ -1175,6 +1177,15 @@ static void escapeSpecialCharacter(uint8_t field, const char **pos) {
*pos = cur; *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) { bool isValidInteger(char *str) {
char *c = str; char *c = str;
if (*c != '+' && *c != '-' && !isdigit(*c)) { if (*c != '+' && *c != '-' && !isdigit(*c)) {
...@@ -1435,58 +1446,65 @@ static bool isNchar(char *pVal, uint16_t len) { ...@@ -1435,58 +1446,65 @@ static bool isNchar(char *pVal, uint16_t len) {
return false; 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) { if (len == 0) {
return true; return TSDB_CODE_SUCCESS;
} }
if ((len == 1) && pVal[0] == '0') { if ((len == 1) && pVal[0] == '0') {
*tsType = SML_TIME_STAMP_NOW; *tsType = SML_TIME_STAMP_NOW;
return true; return TSDB_CODE_SUCCESS;
} }
//Default no appendix for (int i = 0; i < len; ++i) {
if (isdigit(pVal[len - 1]) && isdigit(pVal[len - 2])) { if(!isdigit(pVal[i])) {
if (info->protocol == SML_LINE_PROTOCOL) { return TSDB_CODE_TSC_INVALID_TIME_STAMP;
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;
}
} }
return true;
} }
if (pVal[len - 1] == 's') { /* For InfluxDB line protocol use user passed timestamp precision
switch (pVal[len - 2]) { * For OpenTSDB protocols only 10 digit(seconds) or 13 digits(milliseconds)
case 'm': * precision allowed
*tsType = SML_TIME_STAMP_MILLI_SECONDS; */
break; if (info->protocol == TSDB_SML_LINE_PROTOCOL) {
case 'u': if (info->tsType != SML_TIME_STAMP_NOT_CONFIGURED) {
*tsType = SML_TIME_STAMP_MICRO_SECONDS; *tsType = info->tsType;
break; } else {
case 'n': *tsType = SML_TIME_STAMP_NANO_SECONDS;
*tsType = SML_TIME_STAMP_NANO_SECONDS; }
break; } else if (info->protocol == TSDB_SML_TELNET_PROTOCOL) {
default: if (len == SML_TIMESTAMP_SECOND_DIGITS) {
if (isdigit(pVal[len - 2])) { *tsType = SML_TIME_STAMP_SECONDS;
*tsType = SML_TIME_STAMP_SECONDS; } else if (len == SML_TIMESTAMP_MILLI_SECOND_DIGITS) {
break; *tsType = SML_TIME_STAMP_MILLI_SECONDS;
} else { } else {
return false; 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) { static bool convertStrToNumber(TAOS_SML_KV *pVal, char *str, SSmlLinesInfo* info) {
...@@ -1750,14 +1768,6 @@ bool convertSmlValueType(TAOS_SML_KV *pVal, char *value, ...@@ -1750,14 +1768,6 @@ bool convertSmlValueType(TAOS_SML_KV *pVal, char *value,
static int32_t getTimeStampValue(char *value, uint16_t len, static int32_t getTimeStampValue(char *value, uint16_t len,
SMLTimeStampType type, int64_t *ts, SSmlLinesInfo* info) { 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) //No appendix or no timestamp given (len = 0)
if (len != 0 && type != SML_TIME_STAMP_NOW) { if (len != 0 && type != SML_TIME_STAMP_NOW) {
*ts = (int64_t)strtoll(value, NULL, 10); *ts = (int64_t)strtoll(value, NULL, 10);
...@@ -1806,13 +1816,13 @@ int32_t convertSmlTimeStamp(TAOS_SML_KV *pVal, char *value, ...@@ -1806,13 +1816,13 @@ int32_t convertSmlTimeStamp(TAOS_SML_KV *pVal, char *value,
SMLTimeStampType type; SMLTimeStampType type;
int64_t tsVal; int64_t tsVal;
strntolower_s(value, value, len); ret = isTimeStamp(value, len, &type, info);
if (!isTimeStamp(value, len, &type, info)) { if (ret != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_TIME_STAMP; return ret;
} }
ret = getTimeStampValue(value, len, type, &tsVal, info); ret = getTimeStampValue(value, len, type, &tsVal, info);
if (ret) { if (ret != TSDB_CODE_SUCCESS) {
return ret; return ret;
} }
tscDebug("SML:0x%"PRIx64"Timestamp after conversion:%"PRId64, info->id, tsVal); tscDebug("SML:0x%"PRIx64"Timestamp after conversion:%"PRId64, info->id, tsVal);
...@@ -1884,15 +1894,10 @@ bool checkDuplicateKey(char *key, SHashObj *pHash, SSmlLinesInfo* info) { ...@@ -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) { static int32_t parseSmlKey(TAOS_SML_KV *pKV, const char **index, SHashObj *pHash, SSmlLinesInfo* info) {
const char *cur = *index; const char *cur = *index;
char key[TSDB_COL_NAME_LEN + 1]; // +1 to avoid key[len] over write 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') { 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); tscError("SML:0x%"PRIx64" Key field cannot exceeds %d characters", info->id, TSDB_COL_NAME_LEN - 1);
return TSDB_CODE_TSC_INVALID_COLUMN_LENGTH; return TSDB_CODE_TSC_INVALID_COLUMN_LENGTH;
} }
...@@ -1919,9 +1924,11 @@ static int32_t parseSmlKey(TAOS_SML_KV *pKV, const char **index, SHashObj *pHash ...@@ -1919,9 +1924,11 @@ static int32_t parseSmlKey(TAOS_SML_KV *pKV, const char **index, SHashObj *pHash
return TSDB_CODE_TSC_LINE_SYNTAX_ERROR; 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); 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; *index = cur + 1;
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
...@@ -1932,7 +1939,7 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **index, ...@@ -1932,7 +1939,7 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **index,
const char *start, *cur; const char *start, *cur;
int32_t ret = TSDB_CODE_SUCCESS; int32_t ret = TSDB_CODE_SUCCESS;
char *value = NULL; char *value = NULL;
uint16_t len = 0; int16_t len = 0;
bool searchQuote = false; bool searchQuote = false;
start = cur = *index; start = cur = *index;
...@@ -2013,21 +2020,15 @@ error: ...@@ -2013,21 +2020,15 @@ error:
static int32_t parseSmlMeasurement(TAOS_SML_DATA_POINT *pSml, const char **index, static int32_t parseSmlMeasurement(TAOS_SML_DATA_POINT *pSml, const char **index,
uint8_t *has_tags, SSmlLinesInfo* info) { uint8_t *has_tags, SSmlLinesInfo* info) {
const char *cur = *index; 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){ if (pSml->stableName == NULL){
return TSDB_CODE_TSC_OUT_OF_MEMORY; 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') { 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); tscError("SML:0x%"PRIx64" Measurement field cannot exceeds %d characters", info->id, TSDB_TABLE_NAME_LEN - 1);
free(pSml->stableName); free(pSml->stableName);
pSml->stableName = NULL; pSml->stableName = NULL;
...@@ -2061,7 +2062,7 @@ static int32_t parseSmlMeasurement(TAOS_SML_DATA_POINT *pSml, const char **index ...@@ -2061,7 +2062,7 @@ static int32_t parseSmlMeasurement(TAOS_SML_DATA_POINT *pSml, const char **index
pSml->stableName = NULL; pSml->stableName = NULL;
return TSDB_CODE_TSC_LINE_SYNTAX_ERROR; return TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
} }
pSml->stableName[len] = '\0'; addEscapeCharToString(pSml->stableName, len);
*index = cur + 1; *index = cur + 1;
tscDebug("SML:0x%"PRIx64" Stable name in measurement:%s|len:%d", info->id, pSml->stableName, len); 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, ...@@ -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); tscError("SML:0x%"PRIx64" Unable to parse value", info->id);
goto error; goto error;
} }
if (!isField && (strcasecmp(pkv->key, "ID") == 0)) { if (!isField && (strcasecmp(pkv->key, "`ID`") == 0)) {
ret = isValidChildTableName(pkv->value, pkv->length, info); smlData->childTableName = malloc(pkv->length + TS_ESCAPE_CHAR_SIZE + 1);
if (ret) {
free(pkv->key);
free(pkv->value);
goto error;
}
smlData->childTableName = malloc( pkv->length + 1);
memcpy(smlData->childTableName, pkv->value, pkv->length); memcpy(smlData->childTableName, pkv->value, pkv->length);
strntolower_s(smlData->childTableName, smlData->childTableName, (int32_t)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->key);
free(pkv->value); free(pkv->value);
} else { } else {
...@@ -2273,7 +2268,7 @@ int32_t tscParseLines(char* lines[], int numLines, SArray* points, SArray* faile ...@@ -2273,7 +2268,7 @@ int32_t tscParseLines(char* lines[], int numLines, SArray* points, SArray* faile
return TSDB_CODE_SUCCESS; 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; int32_t code = 0;
SSmlLinesInfo* info = tcalloc(1, sizeof(SSmlLinesInfo)); SSmlLinesInfo* info = tcalloc(1, sizeof(SSmlLinesInfo));
...@@ -2317,6 +2312,9 @@ int taos_insert_lines(TAOS* taos, char* lines[], int numLines, SMLProtocolType p ...@@ -2317,6 +2312,9 @@ int taos_insert_lines(TAOS* taos, char* lines[], int numLines, SMLProtocolType p
if (code != 0) { if (code != 0) {
tscError("SML:0x%"PRIx64" taos_sml_insert error: %s", info->id, tstrerror((code))); tscError("SML:0x%"PRIx64" taos_sml_insert error: %s", info->id, tstrerror((code)));
} }
if (affectedRows != NULL) {
*affectedRows = info->affectedRows;
}
cleanup: cleanup:
tscDebug("SML:0x%"PRIx64" taos_insert_lines finish inserting %d lines. code: %d", info->id, numLines, code); tscDebug("SML:0x%"PRIx64" taos_insert_lines finish inserting %d lines. code: %d", info->id, numLines, code);
...@@ -2332,52 +2330,57 @@ cleanup: ...@@ -2332,52 +2330,57 @@ cleanup:
return code; return code;
} }
int32_t convertPrecisionStrType(char* precision, SMLTimeStampType *tsType) { static int32_t convertPrecisionType(int precision, SMLTimeStampType *tsType) {
if (precision == NULL) { switch (precision) {
*tsType = SML_TIME_STAMP_NOT_CONFIGURED; case TSDB_SML_TIMESTAMP_NOT_CONFIGURED:
return TSDB_CODE_SUCCESS; *tsType = SML_TIME_STAMP_NOT_CONFIGURED;
} break;
if (strcmp(precision, "μ") == 0) { case TSDB_SML_TIMESTAMP_HOURS:
*tsType = SML_TIME_STAMP_MICRO_SECONDS; *tsType = SML_TIME_STAMP_HOURS;
return TSDB_CODE_SUCCESS; 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); return TSDB_CODE_SUCCESS;
if (len == 1) { }
switch (precision[0]) {
case 'u': //make a dummy SSqlObj
*tsType = SML_TIME_STAMP_MICRO_SECONDS; static SSqlObj* createSmlQueryObj(TAOS* taos, int32_t affected_rows, int32_t code) {
break; SSqlObj *pNew = (SSqlObj*)calloc(1, sizeof(SSqlObj));
case 's': if (pNew == NULL) {
*tsType = SML_TIME_STAMP_SECONDS; return NULL;
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;
} }
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 * taos_schemaless_insert() parse and insert data points into database according to
* different protocol. * different protocol.
...@@ -2399,31 +2402,35 @@ int32_t convertPrecisionStrType(char* precision, SMLTimeStampType *tsType) { ...@@ -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) { TAOS_RES* taos_schemaless_insert(TAOS* taos, char* lines[], int numLines, int protocol, int precision) {
int code; int code = TSDB_CODE_SUCCESS;
int affected_rows = 0;
SMLTimeStampType tsType; SMLTimeStampType tsType;
if (protocol == SML_LINE_PROTOCOL) { if (protocol == TSDB_SML_LINE_PROTOCOL) {
code = convertPrecisionStrType(timePrecision, &tsType); code = convertPrecisionType(precision, &tsType);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
return code; return NULL;
} }
} }
switch (protocol) { switch (protocol) {
case SML_LINE_PROTOCOL: case TSDB_SML_LINE_PROTOCOL:
code = taos_insert_lines(taos, lines, numLines, protocol, tsType); code = taos_insert_lines(taos, lines, numLines, protocol, tsType, &affected_rows);
break; break;
case SML_TELNET_PROTOCOL: case TSDB_SML_TELNET_PROTOCOL:
code = taos_insert_telnet_lines(taos, lines, numLines, protocol, tsType); code = taos_insert_telnet_lines(taos, lines, numLines, protocol, tsType, &affected_rows);
break; break;
case SML_JSON_PROTOCOL: case TSDB_SML_JSON_PROTOCOL:
code = taos_insert_json_payload(taos, *lines, protocol, tsType); code = taos_insert_json_payload(taos, *lines, protocol, tsType, &affected_rows);
break; break;
default: default:
code = TSDB_CODE_TSC_INVALID_PROTOCOL_TYPE; code = TSDB_CODE_TSC_INVALID_PROTOCOL_TYPE;
break; break;
} }
return code;
SSqlObj *pSql = createSmlQueryObj(taos, affected_rows, code);
return (TAOS_RES*)pSql;
} }
...@@ -37,18 +37,20 @@ static int32_t parseTelnetMetric(TAOS_SML_DATA_POINT *pSml, const char **index, ...@@ -37,18 +37,20 @@ static int32_t parseTelnetMetric(TAOS_SML_DATA_POINT *pSml, const char **index,
const char *cur = *index; const char *cur = *index;
uint16_t len = 0; 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) { if (pSml->stableName == NULL) {
return TSDB_CODE_TSC_OUT_OF_MEMORY; return TSDB_CODE_TSC_OUT_OF_MEMORY;
} }
/*
if (isdigit(*cur)) { if (isdigit(*cur)) {
tscError("OTD:0x%"PRIx64" Metric cannot start with digit", info->id); tscError("OTD:0x%"PRIx64" Metric cannot start with digit", info->id);
tfree(pSml->stableName); tfree(pSml->stableName);
return TSDB_CODE_TSC_LINE_SYNTAX_ERROR; return TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
} }
*/
while (*cur != '\0') { 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); tscError("OTD:0x%"PRIx64" Metric cannot exceeds %d characters", info->id, TSDB_TABLE_NAME_LEN - 1);
tfree(pSml->stableName); tfree(pSml->stableName);
return TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH; return TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH;
...@@ -63,7 +65,7 @@ static int32_t parseTelnetMetric(TAOS_SML_DATA_POINT *pSml, const char **index, ...@@ -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++; cur++;
len++; len++;
...@@ -73,7 +75,7 @@ static int32_t parseTelnetMetric(TAOS_SML_DATA_POINT *pSml, const char **index, ...@@ -73,7 +75,7 @@ static int32_t parseTelnetMetric(TAOS_SML_DATA_POINT *pSml, const char **index,
return TSDB_CODE_TSC_LINE_SYNTAX_ERROR; return TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
} }
pSml->stableName[len] = '\0'; addEscapeCharToString(pSml->stableName, len);
*index = cur + 1; *index = cur + 1;
tscDebug("OTD:0x%"PRIx64" Stable name in metric:%s|len:%d", info->id, pSml->stableName, len); 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 ...@@ -207,12 +209,12 @@ static int32_t parseTelnetTagKey(TAOS_SML_KV *pKV, const char **index, SHashObj
uint16_t len = 0; uint16_t len = 0;
//key field cannot start with digit //key field cannot start with digit
if (isdigit(*cur)) { //if (isdigit(*cur)) {
tscError("OTD:0x%"PRIx64" Tag key cannot start with digit", info->id); // tscError("OTD:0x%"PRIx64" Tag key cannot start with digit", info->id);
return TSDB_CODE_TSC_LINE_SYNTAX_ERROR; // return TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
} //}
while (*cur != '\0') { 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); tscError("OTD:0x%"PRIx64" Tag key cannot exceeds %d characters", info->id, TSDB_COL_NAME_LEN - 1);
return TSDB_CODE_TSC_INVALID_COLUMN_LENGTH; return TSDB_CODE_TSC_INVALID_COLUMN_LENGTH;
} }
...@@ -236,8 +238,10 @@ static int32_t parseTelnetTagKey(TAOS_SML_KV *pKV, const char **index, SHashObj ...@@ -236,8 +238,10 @@ static int32_t parseTelnetTagKey(TAOS_SML_KV *pKV, const char **index, SHashObj
return TSDB_CODE_TSC_DUP_TAG_NAMES; 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); 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); //tscDebug("OTD:0x%"PRIx64" Key:%s|len:%d", info->id, pKV->key, len);
*index = cur + 1; *index = cur + 1;
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
...@@ -312,15 +316,12 @@ static int32_t parseTelnetTagKvs(TAOS_SML_KV **pKVs, int *num_kvs, ...@@ -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); tscError("OTD:0x%"PRIx64" Unable to parse value", info->id);
return ret; return ret;
} }
if ((strcasecmp(pkv->key, "ID") == 0)) { if ((strcasecmp(pkv->key, "`ID`") == 0)) {
ret = isValidChildTableName(pkv->value, pkv->length, info); *childTableName = tcalloc(pkv->length + TS_ESCAPE_CHAR_SIZE + 1, 1);
if (ret) {
return ret;
}
*childTableName = malloc(pkv->length + 1);
memcpy(*childTableName, pkv->value, pkv->length); memcpy(*childTableName, pkv->value, pkv->length);
(*childTableName)[pkv->length] = '\0'; (*childTableName)[pkv->length] = '\0';
strntolower_s(*childTableName, *childTableName, (int32_t)pkv->length); strntolower_s(*childTableName, *childTableName, (int32_t)pkv->length);
addEscapeCharToString(*childTableName, pkv->length);
tfree(pkv->key); tfree(pkv->key);
tfree(pkv->value); tfree(pkv->value);
} else { } else {
...@@ -409,7 +410,7 @@ static int32_t tscParseTelnetLines(char* lines[], int numLines, SArray* points, ...@@ -409,7 +410,7 @@ static int32_t tscParseTelnetLines(char* lines[], int numLines, SArray* points,
return TSDB_CODE_SUCCESS; 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; int32_t code = 0;
SSmlLinesInfo* info = tcalloc(1, sizeof(SSmlLinesInfo)); SSmlLinesInfo* info = tcalloc(1, sizeof(SSmlLinesInfo));
...@@ -453,6 +454,9 @@ int taos_insert_telnet_lines(TAOS* taos, char* lines[], int numLines, SMLProtoco ...@@ -453,6 +454,9 @@ int taos_insert_telnet_lines(TAOS* taos, char* lines[], int numLines, SMLProtoco
if (code != 0) { if (code != 0) {
tscError("OTD:0x%"PRIx64" taos_insert_telnet_lines error: %s", info->id, tstrerror((code))); tscError("OTD:0x%"PRIx64" taos_insert_telnet_lines error: %s", info->id, tstrerror((code)));
} }
if (affectedRows != NULL) {
*affectedRows = info->affectedRows;
}
cleanup: cleanup:
tscDebug("OTD:0x%"PRIx64" taos_insert_telnet_lines finish inserting %d lines. code: %d", info->id, numLines, code); 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 ...@@ -490,19 +494,22 @@ static int32_t parseMetricFromJSON(cJSON *root, TAOS_SML_DATA_POINT* pSml, SSmlL
return TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH; 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){ if (pSml->stableName == NULL){
return TSDB_CODE_TSC_OUT_OF_MEMORY; return TSDB_CODE_TSC_OUT_OF_MEMORY;
} }
/*
if (isdigit(metric->valuestring[0])) { if (isdigit(metric->valuestring[0])) {
tscError("OTD:0x%"PRIx64" Metric cannot start with digit in JSON", info->id); tscError("OTD:0x%"PRIx64" Metric cannot start with digit in JSON", info->id);
tfree(pSml->stableName); tfree(pSml->stableName);
return TSDB_CODE_TSC_INVALID_JSON; return TSDB_CODE_TSC_INVALID_JSON;
} }
*/
tstrncpy(pSml->stableName, metric->valuestring, stableLen + 1); tstrncpy(pSml->stableName, metric->valuestring, stableLen + 1);
strntolower_s(pSml->stableName, pSml->stableName, (int32_t)stableLen); strntolower_s(pSml->stableName, pSml->stableName, (int32_t)stableLen);
addEscapeCharToString(pSml->stableName, stableLen);
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
...@@ -885,7 +892,6 @@ static int32_t parseTagsFromJSON(cJSON *root, TAOS_SML_KV **pKVs, int *num_kvs, ...@@ -885,7 +892,6 @@ static int32_t parseTagsFromJSON(cJSON *root, TAOS_SML_KV **pKVs, int *num_kvs,
if (tags == NULL || tags->type != cJSON_Object) { if (tags == NULL || tags->type != cJSON_Object) {
return TSDB_CODE_TSC_INVALID_JSON; return TSDB_CODE_TSC_INVALID_JSON;
} }
//only pick up the first ID value as child table name //only pick up the first ID value as child table name
cJSON *id = cJSON_GetObjectItem(tags, "ID"); cJSON *id = cJSON_GetObjectItem(tags, "ID");
if (id != NULL) { if (id != NULL) {
...@@ -894,13 +900,10 @@ static int32_t parseTagsFromJSON(cJSON *root, TAOS_SML_KV **pKVs, int *num_kvs, ...@@ -894,13 +900,10 @@ static int32_t parseTagsFromJSON(cJSON *root, TAOS_SML_KV **pKVs, int *num_kvs,
return TSDB_CODE_TSC_INVALID_JSON; return TSDB_CODE_TSC_INVALID_JSON;
} }
size_t idLen = strlen(id->valuestring); size_t idLen = strlen(id->valuestring);
ret = isValidChildTableName(id->valuestring, (int16_t)idLen, info); *childTableName = tcalloc(idLen + TS_ESCAPE_CHAR_SIZE + 1, sizeof(char));
if (ret != TSDB_CODE_SUCCESS) {
return ret;
}
*childTableName = tcalloc(idLen + 1, sizeof(char));
memcpy(*childTableName, id->valuestring, idLen); memcpy(*childTableName, id->valuestring, idLen);
strntolower_s(*childTableName, *childTableName, (int32_t)idLen); strntolower_s(*childTableName, *childTableName, (int32_t)idLen);
addEscapeCharToString(*childTableName, idLen);
//check duplicate IDs //check duplicate IDs
cJSON_DeleteItemFromObject(tags, "ID"); cJSON_DeleteItemFromObject(tags, "ID");
...@@ -909,7 +912,6 @@ static int32_t parseTagsFromJSON(cJSON *root, TAOS_SML_KV **pKVs, int *num_kvs, ...@@ -909,7 +912,6 @@ static int32_t parseTagsFromJSON(cJSON *root, TAOS_SML_KV **pKVs, int *num_kvs,
return TSDB_CODE_TSC_DUP_TAG_NAMES; return TSDB_CODE_TSC_DUP_TAG_NAMES;
} }
} }
int32_t tagNum = cJSON_GetArraySize(tags); int32_t tagNum = cJSON_GetArraySize(tags);
//at least one tag pair required //at least one tag pair required
if (tagNum <= 0) { if (tagNum <= 0) {
...@@ -935,8 +937,10 @@ static int32_t parseTagsFromJSON(cJSON *root, TAOS_SML_KV **pKVs, int *num_kvs, ...@@ -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); 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; 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); strncpy(pkv->key, tag->string, keyLen);
strntolower_s(pkv->key, pkv->key, (int32_t)keyLen);
addEscapeCharToString(pkv->key, keyLen);
//value //value
ret = parseValueFromJSON(tag, pkv, info); ret = parseValueFromJSON(tag, pkv, info);
if (ret != TSDB_CODE_SUCCESS) { if (ret != TSDB_CODE_SUCCESS) {
...@@ -1045,7 +1049,7 @@ PARSE_JSON_OVER: ...@@ -1045,7 +1049,7 @@ PARSE_JSON_OVER:
return ret; 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; int32_t code = 0;
SSmlLinesInfo* info = tcalloc(1, sizeof(SSmlLinesInfo)); SSmlLinesInfo* info = tcalloc(1, sizeof(SSmlLinesInfo));
...@@ -1080,6 +1084,9 @@ int taos_insert_json_payload(TAOS* taos, char* payload, SMLProtocolType protocol ...@@ -1080,6 +1084,9 @@ int taos_insert_json_payload(TAOS* taos, char* payload, SMLProtocolType protocol
if (code != 0) { if (code != 0) {
tscError("OTD:0x%"PRIx64" taos_insert_json_payload error: %s", info->id, tstrerror((code))); tscError("OTD:0x%"PRIx64" taos_insert_json_payload error: %s", info->id, tstrerror((code)));
} }
if (affectedRows != NULL) {
*affectedRows = info->affectedRows;
}
cleanup: cleanup:
tscDebug("OTD:0x%"PRIx64" taos_insert_json_payload finish inserting 1 Point. code: %d", info->id, code); tscDebug("OTD:0x%"PRIx64" taos_insert_json_payload finish inserting 1 Point. code: %d", info->id, code);
......
...@@ -3112,10 +3112,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col ...@@ -3112,10 +3112,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
memset(pExpr->base.aliasName, 0, tListLen(pExpr->base.aliasName)); memset(pExpr->base.aliasName, 0, tListLen(pExpr->base.aliasName));
getColumnName(pItem, pExpr->base.aliasName, pExpr->base.token, sizeof(pExpr->base.aliasName) - 1); getColumnName(pItem, pExpr->base.aliasName, pExpr->base.token, sizeof(pExpr->base.aliasName) - 1);
SSchema s = {0}; SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
s.type = (uint8_t)resType;
s.bytes = bytes;
s.colId = pExpr->base.colInfo.colId;
uint64_t uid = pTableMetaInfo->pTableMeta->id.uid; uint64_t uid = pTableMetaInfo->pTableMeta->id.uid;
SColumnList ids = createColumnList(1, index.tableIndex, index.columnIndex); SColumnList ids = createColumnList(1, index.tableIndex, index.columnIndex);
...@@ -3123,7 +3120,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col ...@@ -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); insertResultField(pQueryInfo, colIndex, &ids, pUdfInfo->resBytes, pUdfInfo->resType, pExpr->base.aliasName, pExpr);
} else { } else {
for (int32_t i = 0; i < ids.num; ++i) { 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); tscInsertPrimaryTsSourceColumn(pQueryInfo, pTableMetaInfo->pTableMeta->id.uid);
...@@ -3177,6 +3174,14 @@ static int16_t doGetColumnIndex(SQueryInfo* pQueryInfo, int32_t index, SStrToken ...@@ -3177,6 +3174,14 @@ static int16_t doGetColumnIndex(SQueryInfo* pQueryInfo, int32_t index, SStrToken
int16_t columnIndex = COLUMN_INDEX_INITIAL_VAL; 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) { for (int16_t i = 0; i < numOfCols; ++i) {
if (pToken->n != strlen(pSchema[i].name)) { if (pToken->n != strlen(pSchema[i].name)) {
continue; continue;
...@@ -4227,7 +4232,11 @@ static int32_t validateSQLExpr(SSqlCmd* pCmd, tSqlExpr* pExpr, SQueryInfo* pQuer ...@@ -4227,7 +4232,11 @@ static int32_t validateSQLExpr(SSqlCmd* pCmd, tSqlExpr* pExpr, SQueryInfo* pQuer
// Append the sqlExpr into exprList of pQueryInfo structure sequentially // Append the sqlExpr into exprList of pQueryInfo structure sequentially
pExpr->functionId = isValidFunction(pExpr->Expr.operand.z, pExpr->Expr.operand.n); pExpr->functionId = isValidFunction(pExpr->Expr.operand.z, pExpr->Expr.operand.n);
if (pExpr->functionId < 0) { 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) { if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, &item, false, NULL) != TSDB_CODE_SUCCESS) {
...@@ -5738,6 +5747,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq ...@@ -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* msg8 = "only column in groupby clause allowed as order column";
const char* msg9 = "orderby column must projected in subquery"; const char* msg9 = "orderby column must projected in subquery";
const char* msg10 = "not support distinct mixed with order by"; const char* msg10 = "not support distinct mixed with order by";
const char* msg11 = "not support order with udf";
setDefaultOrderInfo(pQueryInfo); setDefaultOrderInfo(pQueryInfo);
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
...@@ -5777,6 +5787,19 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq ...@@ -5777,6 +5787,19 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq
SStrToken columnName = {pVar->nLen, pVar->nType, pVar->pz}; SStrToken columnName = {pVar->nLen, pVar->nType, pVar->pz};
SColumnIndex index = COLUMN_INDEX_INITIALIZER; 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 (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { // super table query
if (getColumnIndexByName(&columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { if (getColumnIndexByName(&columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) {
...@@ -5832,6 +5855,9 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq ...@@ -5832,6 +5855,9 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq
pQueryInfo->groupbyExpr.orderType = p1->sortOrder; pQueryInfo->groupbyExpr.orderType = p1->sortOrder;
pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId; pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
if (udf) {
return invalidOperationMsg(pMsgBuf, msg11);
}
} else if (isTopBottomQuery(pQueryInfo)) { } else if (isTopBottomQuery(pQueryInfo)) {
/* order of top/bottom query in interval is not valid */ /* order of top/bottom query in interval is not valid */
...@@ -5853,6 +5879,10 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq ...@@ -5853,6 +5879,10 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq
} else { } else {
tVariantListItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0); tVariantListItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0);
if (udf) {
return invalidOperationMsg(pMsgBuf, msg11);
}
pQueryInfo->order.order = p1->sortOrder; pQueryInfo->order.order = p1->sortOrder;
pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX; pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
...@@ -5880,9 +5910,15 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq ...@@ -5880,9 +5910,15 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq
} else if (orderByGroupbyCol){ } else if (orderByGroupbyCol){
pQueryInfo->order.order = pItem->sortOrder; pQueryInfo->order.order = pItem->sortOrder;
pQueryInfo->order.orderColId = index.columnIndex; pQueryInfo->order.orderColId = index.columnIndex;
if (udf) {
return invalidOperationMsg(pMsgBuf, msg11);
}
} else { } else {
pQueryInfo->order.order = pItem->sortOrder; pQueryInfo->order.order = pItem->sortOrder;
pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX; pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
if (udf) {
return invalidOperationMsg(pMsgBuf, msg11);
}
} }
pItem = taosArrayGet(pSqlNode->pSortOrder, 1); pItem = taosArrayGet(pSqlNode->pSortOrder, 1);
...@@ -5918,6 +5954,10 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq ...@@ -5918,6 +5954,10 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq
return invalidOperationMsg(pMsgBuf, msg7); return invalidOperationMsg(pMsgBuf, msg7);
} }
if (udf) {
return invalidOperationMsg(pMsgBuf, msg11);
}
tVariantListItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0); tVariantListItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0);
pQueryInfo->groupbyExpr.orderIndex = pSchema[index.columnIndex].colId; pQueryInfo->groupbyExpr.orderIndex = pSchema[index.columnIndex].colId;
pQueryInfo->groupbyExpr.orderType = p1->sortOrder; pQueryInfo->groupbyExpr.orderType = p1->sortOrder;
...@@ -5951,6 +5991,10 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq ...@@ -5951,6 +5991,10 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
if (udf) {
return invalidOperationMsg(pMsgBuf, msg11);
}
tVariantListItem* pItem = taosArrayGet(pSqlNode->pSortOrder, 0); tVariantListItem* pItem = taosArrayGet(pSqlNode->pSortOrder, 0);
pQueryInfo->order.order = pItem->sortOrder; pQueryInfo->order.order = pItem->sortOrder;
pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId; pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
...@@ -5963,6 +6007,10 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq ...@@ -5963,6 +6007,10 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq
return invalidOperationMsg(pMsgBuf, msg1); return invalidOperationMsg(pMsgBuf, msg1);
} }
if (udf) {
return invalidOperationMsg(pMsgBuf, msg11);
}
tVariantListItem* pItem = taosArrayGet(pSqlNode->pSortOrder, 0); tVariantListItem* pItem = taosArrayGet(pSqlNode->pSortOrder, 0);
pQueryInfo->order.order = pItem->sortOrder; pQueryInfo->order.order = pItem->sortOrder;
pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId; pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
...@@ -6273,6 +6321,13 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { ...@@ -6273,6 +6321,13 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER; SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER;
SStrToken name = {.type = TK_STRING, .z = pItem->name, .n = (uint32_t)strlen(pItem->name)}; 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) { if (getColumnIndexByName(&name, pQueryInfo, &columnIndex, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) {
return invalidOperationMsg(pMsg, msg17); return invalidOperationMsg(pMsg, msg17);
} }
...@@ -6606,6 +6661,9 @@ int32_t validateColumnName(char* name) { ...@@ -6606,6 +6661,9 @@ int32_t validateColumnName(char* name) {
} }
return validateColumnName(token.z); return validateColumnName(token.z);
} else if (token.type == TK_ID) {
strRmquoteEscape(name, token.n);
return TSDB_CODE_SUCCESS;
} else { } else {
if (isNumber(&token)) { if (isNumber(&token)) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
...@@ -7245,7 +7303,7 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, char* ...@@ -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* 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* msg4 = "retrieve tags not compatible with group by or interval query";
const char* msg5 = "functions can not be mixed up"; 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 // only retrieve tags, group by is not supportted
if (tscQueryTags(pQueryInfo)) { if (tscQueryTags(pQueryInfo)) {
...@@ -7298,10 +7356,16 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, char* ...@@ -7298,10 +7356,16 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, char*
} }
if (f < 0) { if (f < 0) {
SUdfInfo* pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, -1 * f - 1);
if (pUdfInfo->funcType == TSDB_UDF_TYPE_SCALAR) {
return invalidOperationMsg(msg, msg1);
}
continue; 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) { for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) {
SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j); SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j);
if (j == 0) { if (j == 0) {
...@@ -7320,6 +7384,10 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, char* ...@@ -7320,6 +7384,10 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, char*
return invalidOperationMsg(msg, msg1); 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) { if (f == TSDB_FUNC_COUNT && pExpr->base.colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) {
return invalidOperationMsg(msg, msg1); return invalidOperationMsg(msg, msg1);
} }
...@@ -7661,7 +7729,7 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { ...@@ -7661,7 +7729,7 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) {
SCreatedTableInfo* pCreateTableInfo = taosArrayGet(pCreateTable->childTableInfo, j); SCreatedTableInfo* pCreateTableInfo = taosArrayGet(pCreateTable->childTableInfo, j);
SStrToken* pToken = &pCreateTableInfo->stableName; SStrToken* pToken = &pCreateTableInfo->stableName;
bool dbIncluded = false; bool dbIncluded = false;
char buf[TSDB_TABLE_FNAME_LEN]; char buf[TSDB_TABLE_FNAME_LEN];
SStrToken sTblToken; SStrToken sTblToken;
...@@ -7721,10 +7789,19 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { ...@@ -7721,10 +7789,19 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) {
for (int32_t i = 0; i < nameSize; ++i) { for (int32_t i = 0; i < nameSize; ++i) {
SStrToken* sToken = taosArrayGet(pNameList, 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) { if (TK_STRING == sToken->type) {
tscDequoteAndTrimToken(sToken); tscDequoteAndTrimToken(sToken);
} }
if (TK_ID == sToken->type) {
tscRmEscapeAndTrimToken(sToken);
}
tVariantListItem* pItem = taosArrayGet(pValList, i); tVariantListItem* pItem = taosArrayGet(pValList, i);
findColumnIndex = false; findColumnIndex = false;
...@@ -8558,12 +8635,33 @@ int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo) { ...@@ -8558,12 +8635,33 @@ int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo) {
if (functionId < 0) { if (functionId < 0) {
struct SUdfInfo info = {0}; struct SUdfInfo info = {0};
info.name = strndup(t->z, t->n); info.name = strndup(t->z, t->n);
info.keep = true;
if (pQueryInfo->pUdfInfo == NULL) { if (pQueryInfo->pUdfInfo == NULL) {
pQueryInfo->pUdfInfo = taosArrayInit(4, sizeof(struct SUdfInfo)); 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;; info.functionId = (int32_t)taosArrayGetSize(pQueryInfo->pUdfInfo) * (-1) - 1;;
taosArrayPush(pQueryInfo->pUdfInfo, &info); taosArrayPush(pQueryInfo->pUdfInfo, &info);
if (taosArrayGetSize(pQueryInfo->pUdfInfo) > 1) {
code = tscInvalidOperationMsg(pCmd->payload, "only one udf allowed", NULL);
goto _end;
}
} }
} }
} }
......
...@@ -1102,6 +1102,11 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { ...@@ -1102,6 +1102,11 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
// support only one udf // support only one udf
if (pQueryInfo->pUdfInfo != NULL && taosArrayGetSize(pQueryInfo->pUdfInfo) > 0) { 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)); pQueryMsg->udfContentOffset = htonl((int32_t) (pMsg - pCmd->payload));
for(int32_t i = 0; i < taosArrayGetSize(pQueryInfo->pUdfInfo); ++i) { for(int32_t i = 0; i < taosArrayGetSize(pQueryInfo->pUdfInfo); ++i) {
SUdfInfo* pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, i); SUdfInfo* pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, i);
......
...@@ -629,6 +629,10 @@ static bool hasAdditionalErrorInfo(int32_t code, SSqlCmd *pCmd) { ...@@ -629,6 +629,10 @@ static bool hasAdditionalErrorInfo(int32_t code, SSqlCmd *pCmd) {
return false; return false;
} }
if (pCmd->payload == NULL) {
return false;
}
size_t len = strlen(pCmd->payload); size_t len = strlen(pCmd->payload);
char *z = NULL; char *z = NULL;
......
...@@ -1271,6 +1271,28 @@ void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQue ...@@ -1271,6 +1271,28 @@ void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQue
.pGroupList = taosArrayInit(1, POINTER_BYTES), .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); tableGroupInfo.map = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK);
STableKeyInfo tableKeyInfo = {.pTable = NULL, .lastKey = INT64_MIN}; STableKeyInfo tableKeyInfo = {.pTable = NULL, .lastKey = INT64_MIN};
...@@ -1352,6 +1374,9 @@ void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQue ...@@ -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); 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 = createQInfoFromQueryNode(px, &tableGroupInfo, pSourceOperator, NULL, NULL, MASTER_SCAN, pSql->self);
px->pQInfo->runtimeEnv.udfIsCopy = true;
px->pQInfo->runtimeEnv.pUdfInfo = pUdfInfo;
tfree(pColumnInfo); tfree(pColumnInfo);
tfree(schema); tfree(schema);
...@@ -4800,9 +4825,14 @@ int32_t createProjectionExpr(SQueryInfo* pQueryInfo, STableMetaInfo* pTableMetaI ...@@ -4800,9 +4825,14 @@ int32_t createProjectionExpr(SQueryInfo* pQueryInfo, STableMetaInfo* pTableMetaI
functionId = TSDB_FUNC_STDDEV; functionId = TSDB_FUNC_STDDEV;
} }
SUdfInfo* pUdfInfo = NULL;
if (functionId < 0) {
pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, -1 * functionId - 1);
}
int32_t inter = 0; int32_t inter = 0;
getResultDataInfo(pSource->base.colType, pSource->base.colBytes, functionId, 0, &pse->resType, 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->colType = pse->resType;
pse->colBytes = pse->resBytes; pse->colBytes = pse->resBytes;
......
...@@ -49,7 +49,7 @@ public class TSDBResultSetRowData { ...@@ -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) { public void setBooleanValue(int col, boolean value) {
setBoolean(col - 1, value); setBoolean(col - 1, value);
...@@ -86,7 +86,7 @@ public class TSDBResultSetRowData { ...@@ -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) { public void setByteValue(int colIndex, byte value) {
setByte(colIndex - 1, value); setByte(colIndex - 1, value);
...@@ -100,7 +100,7 @@ public class TSDBResultSetRowData { ...@@ -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) { public void setShortValue(int colIndex, short value) {
setShort(colIndex - 1, value); setShort(colIndex - 1, value);
...@@ -114,7 +114,7 @@ public class TSDBResultSetRowData { ...@@ -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) { public void setIntValue(int colIndex, int value) {
setInt(colIndex - 1, value); setInt(colIndex - 1, value);
...@@ -194,7 +194,7 @@ public class TSDBResultSetRowData { ...@@ -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) { public void setLongValue(int colIndex, long value) {
setLong(colIndex - 1, value); setLong(colIndex - 1, value);
...@@ -262,7 +262,7 @@ public class TSDBResultSetRowData { ...@@ -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) { public void setFloatValue(int colIndex, float value) {
setFloat(colIndex - 1, value); setFloat(colIndex - 1, value);
...@@ -302,7 +302,7 @@ public class TSDBResultSetRowData { ...@@ -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) { public void setDoubleValue(int colIndex, double value) {
setDouble(colIndex - 1, value); setDouble(colIndex - 1, value);
...@@ -342,7 +342,7 @@ public class TSDBResultSetRowData { ...@@ -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) { public void setStringValue(int colIndex, String value) {
data.set(colIndex - 1, value); data.set(colIndex - 1, value);
...@@ -361,7 +361,7 @@ public class TSDBResultSetRowData { ...@@ -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) { public void setByteArrayValue(int colIndex, byte[] value) {
setByteArray(colIndex - 1, value); setByteArray(colIndex - 1, value);
...@@ -424,7 +424,7 @@ public class TSDBResultSetRowData { ...@@ -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) { public void setTimestampValue(int colIndex, long value) {
setTimestamp(colIndex - 1, value, 0); setTimestamp(colIndex - 1, value, 0);
......
...@@ -23,7 +23,7 @@ import java.util.Calendar; ...@@ -23,7 +23,7 @@ import java.util.Calendar;
import java.util.Map; 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 * standard JDBC API contains more or less some adjustments customized for certain
* compatibility needs. * compatibility needs.
*/ */
......
import taos import taos
from taos import SmlProtocol, SmlPrecision
conn = taos.connect() conn = taos.connect()
dbname = "pytest_line" dbname = "pytest_line"
...@@ -9,10 +10,10 @@ conn.select_db(dbname) ...@@ -9,10 +10,10 @@ conn.select_db(dbname)
lines = [ lines = [
'st,t1=3i64,t2=4f64,t3="t3" c1=3i64,c3=L"pass",c2=false,c4=4f64 1626006833639000000', '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") 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") result = conn.query("show tables")
for row in result: for row in result:
......
[tool.poetry] [tool.poetry]
name = "taos" name = "taos"
version = "2.1.0" version = "2.1.1"
description = "TDengine connector for python" description = "TDengine connector for python"
authors = ["Taosdata Inc. <support@taosdata.com>"] authors = ["Taosdata Inc. <support@taosdata.com>"]
license = "AGPL-3.0" license = "AGPL-3.0"
......
...@@ -5,7 +5,7 @@ with open("README.md", "r") as fh: ...@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
setuptools.setup( setuptools.setup(
name="taos", name="taos",
version="2.1.0", version="2.1.1",
author="Taosdata Inc.", author="Taosdata Inc.",
author_email="support@taosdata.com", author_email="support@taosdata.com",
description="TDengine python client package", description="TDengine python client package",
......
...@@ -440,6 +440,7 @@ from .cursor import * ...@@ -440,6 +440,7 @@ from .cursor import *
from .result import * from .result import *
from .statement import * from .statement import *
from .subscription import * from .subscription import *
from .schemaless import *
try: try:
import importlib.metadata import importlib.metadata
...@@ -468,6 +469,8 @@ __all__ = [ ...@@ -468,6 +469,8 @@ __all__ = [
"TaosRow", "TaosRow",
"TaosStmt", "TaosStmt",
"PrecisionEnum", "PrecisionEnum",
"SmlPrecision",
"SmlProtocol"
] ]
def connect(*args, **kwargs): def connect(*args, **kwargs):
......
...@@ -12,6 +12,7 @@ except: ...@@ -12,6 +12,7 @@ except:
from .error import * from .error import *
from .bind import * from .bind import *
from .field import * from .field import *
from .schemaless import *
# stream callback # stream callback
...@@ -64,6 +65,8 @@ _libtaos.taos_consume.restype = ctypes.c_void_p ...@@ -64,6 +65,8 @@ _libtaos.taos_consume.restype = ctypes.c_void_p
_libtaos.taos_fetch_lengths.restype = ctypes.POINTER(ctypes.c_int) _libtaos.taos_fetch_lengths.restype = ctypes.POINTER(ctypes.c_int)
_libtaos.taos_free_result.restype = None _libtaos.taos_free_result.restype = None
_libtaos.taos_query.restype = ctypes.POINTER(ctypes.c_void_p) _libtaos.taos_query.restype = ctypes.POINTER(ctypes.c_void_p)
_libtaos.taos_schemaless_insert.restype = ctypes.c_void_p
try: try:
_libtaos.taos_stmt_errstr.restype = c_char_p _libtaos.taos_stmt_errstr.restype = c_char_p
except AttributeError: except AttributeError:
...@@ -808,25 +811,27 @@ def taos_stmt_use_result(stmt): ...@@ -808,25 +811,27 @@ def taos_stmt_use_result(stmt):
return result return result
try: try:
_libtaos.taos_insert_lines.restype = c_int _libtaos.taos_schemaless_insert.restype = c_void_p
_libtaos.taos_insert_lines.argstype = c_void_p, c_void_p, c_int _libtaos.taos_schemaless_insert.argstype = c_void_p, c_void_p, c_int, c_int, c_int
except AttributeError: 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): 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) num_of_lines = len(lines)
lines = (c_char_p(line.encode("utf-8")) for line in lines) lines = (c_char_p(line.encode("utf-8")) for line in lines)
lines_type = ctypes.c_char_p * num_of_lines lines_type = ctypes.c_char_p * num_of_lines
p_lines = lines_type(*lines) p_lines = lines_type(*lines)
if precision != None: res = c_void_p(_libtaos.taos_schemaless_insert(connection, p_lines, num_of_lines, protocol, precision))
precision = c_char_p(precision.encode("utf-8")) errno = taos_errno(res)
errno = _libtaos.taos_schemaless_insert(connection, p_lines, num_of_lines, protocol, precision) affected_rows = taos_affected_rows(res)
if errno != 0: 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): class CTaosInterface(object):
def __init__(self, config=None): def __init__(self, config=None):
......
...@@ -72,10 +72,9 @@ class TaosConnection(object): ...@@ -72,10 +72,9 @@ class TaosConnection(object):
taos_select_db(self._conn, database) taos_select_db(self._conn, database)
def execute(self, sql): def execute(self, sql):
# type: (str) -> None # type: (str) -> int
"""Simplely execute sql ignoring the results""" """Simplely execute sql ignoring the results"""
res = taos_query(self._conn, sql) return self.query(sql).affected_rows
taos_free_result(res)
def query(self, sql): def query(self, sql):
# type: (str) -> TaosResult # type: (str) -> TaosResult
...@@ -118,7 +117,7 @@ class TaosConnection(object): ...@@ -118,7 +117,7 @@ class TaosConnection(object):
return TaosStream(stream) return TaosStream(stream)
def schemaless_insert(self, lines, protocol, precision): def schemaless_insert(self, lines, protocol, precision):
# type: (list[str]) -> None # type: (list[str], SmlProtocol, SmlPrecision) -> int
""" """
1.Line protocol and schemaless support 1.Line protocol and schemaless support
...@@ -171,6 +170,7 @@ class TaosConnection(object): ...@@ -171,6 +170,7 @@ class TaosConnection(object):
conn.schemaless_insert(lines, 2, None) conn.schemaless_insert(lines, 2, None)
""" """
print(lines, protocol, precision)
return taos_schemaless_insert(self._conn, lines, protocol, precision) return taos_schemaless_insert(self._conn, lines, protocol, precision)
......
...@@ -83,7 +83,16 @@ class ResultError(DatabaseError): ...@@ -83,7 +83,16 @@ class ResultError(DatabaseError):
class SchemalessError(DatabaseError): class SchemalessError(DatabaseError):
"""taos_schemaless_insert errors.""" """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): class StatementError(DatabaseError):
......
...@@ -123,6 +123,12 @@ class TaosResult(object): ...@@ -123,6 +123,12 @@ class TaosResult(object):
for i in range(len(self._fields)): for i in range(len(self._fields)):
buffer[i].extend(block[i]) buffer[i].extend(block[i])
return list(map(tuple, zip(*buffer))) 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): def fetch_rows_a(self, callback, param):
taos_fetch_rows_a(self._result, callback, param) taos_fetch_rows_a(self._result, callback, param)
...@@ -228,6 +234,12 @@ class TaosRow: ...@@ -228,6 +234,12 @@ class TaosRow:
blocks[i] = CONVERT_FUNC[fields[i].type](data, 1, field_lens[i], precision)[0] blocks[i] = CONVERT_FUNC[fields[i].type](data, 1, field_lens[i], precision)[0]
return tuple(blocks) return tuple(blocks)
def as_dict(self):
values = self.as_tuple()
names = self._result.fields
dict(zip(names, values))
class TaosBlocks: class TaosBlocks:
"""TDengine result blocks iterator""" """TDengine result blocks iterator"""
......
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
from taos.error import OperationalError from taos.error import OperationalError, SchemalessError
from taos import connect, new_bind_params, PrecisionEnum from taos import connect, new_bind_params, PrecisionEnum
from taos import * from taos import *
...@@ -13,35 +13,95 @@ def conn(): ...@@ -13,35 +13,95 @@ def conn():
return connect() 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): def test_schemaless_insert(conn):
# type: (TaosConnection) -> None # type: (TaosConnection) -> None
dbname = "pytest_taos_schemaless_insert" dbname = "pytest_taos_schemaless_insert"
try: try:
conn.execute("drop database if exists %s" % dbname) 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) conn.select_db(dbname)
lines = [ lines = [
'st,t1=3i64,t2=4f64,t3="t3" c1=3i64,c3=L"passit",c2=false,c4=4f64 1626006833639000000', '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', '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") res = conn.schemaless_insert(lines, 1, 0)
print("inserted") print("affected rows: ", res)
assert(res == 3)
lines = [ lines = [
'stf,t1=5i64,t3="t4",t2=5f64,t4=5f64 c1=3i64,c3=L"passitagin_stf",c2=false,c5=5f64,c6=7u64 1626006933641000000', '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") res = conn.schemaless_insert(lines, 1, 0)
print("inserted") 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") result = conn.query("select * from st")
print(*result.fields) result.row_count
all = result.rows_iter() all = result.rows_iter()
for row in all: for row in all:
print(row) print(row)
result.close() result.close()
print(result.row_count)
conn.execute("drop database if exists %s" % dbname) conn.execute("drop database if exists %s" % dbname)
conn.close() conn.close()
...@@ -55,3 +115,4 @@ def test_schemaless_insert(conn): ...@@ -55,3 +115,4 @@ def test_schemaless_insert(conn):
if __name__ == "__main__": if __name__ == "__main__":
test_schemaless_insert(connect()) test_schemaless_insert(connect())
test_schemaless_insert_update_2(connect())
# encoding:UTF-8
from taos import * from taos import *
from ctypes import * from ctypes import *
......
...@@ -72,6 +72,23 @@ typedef enum { ...@@ -72,6 +72,23 @@ typedef enum {
SET_CONF_RET_ERR_TOO_LONG = -6 SET_CONF_RET_ERR_TOO_LONG = -6
} SET_CONF_RET_CODE; } 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 #define RET_MSG_LENGTH 1024
typedef struct setConfRet { typedef struct setConfRet {
SET_CONF_RET_CODE retCode; SET_CONF_RET_CODE retCode;
...@@ -188,7 +205,7 @@ DLL_EXPORT void taos_close_stream(TAOS_STREAM *tstr); ...@@ -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_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 #ifdef __cplusplus
} }
......
...@@ -99,6 +99,7 @@ extern const int32_t TYPE_BYTES[15]; ...@@ -99,6 +99,7 @@ extern const int32_t TYPE_BYTES[15];
#define TS_PATH_DELIMITER "." #define TS_PATH_DELIMITER "."
#define TS_ESCAPE_CHAR '`' #define TS_ESCAPE_CHAR '`'
#define TS_ESCAPE_CHAR_SIZE 2
#define TSDB_TIME_PRECISION_MILLI 0 #define TSDB_TIME_PRECISION_MILLI 0
#define TSDB_TIME_PRECISION_MICRO 1 #define TSDB_TIME_PRECISION_MICRO 1
......
...@@ -421,9 +421,6 @@ bool tsdbNoProblem(STsdbRepo* pRepo); ...@@ -421,9 +421,6 @@ bool tsdbNoProblem(STsdbRepo* pRepo);
// unit of walSize: MB // unit of walSize: MB
int tsdbCheckWal(STsdbRepo *pRepo, uint32_t walSize); 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 #ifdef __cplusplus
} }
#endif #endif
......
...@@ -77,6 +77,7 @@ extern char configDir[]; ...@@ -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 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 OPT_ABORT 1 /* –abort */
#define MAX_FILE_NAME_LEN 256 // max file name length on linux is 255. #define MAX_FILE_NAME_LEN 256 // max file name length on linux is 255.
#define MAX_PATH_LEN 4096
#define DEFAULT_START_TIME 1500000000000 #define DEFAULT_START_TIME 1500000000000
...@@ -511,7 +512,7 @@ typedef struct SThreadInfo_S { ...@@ -511,7 +512,7 @@ typedef struct SThreadInfo_S {
int threadID; int threadID;
char db_name[TSDB_DB_NAME_LEN]; char db_name[TSDB_DB_NAME_LEN];
uint32_t time_precision; uint32_t time_precision;
char filePath[TSDB_FILENAME_LEN]; char filePath[MAX_PATH_LEN];
FILE *fp; FILE *fp;
char tb_prefix[TSDB_TABLE_NAME_LEN]; char tb_prefix[TSDB_TABLE_NAME_LEN];
uint64_t start_table_from; uint64_t start_table_from;
...@@ -3481,8 +3482,14 @@ static int postProceSql(char *host, uint16_t port, ...@@ -3481,8 +3482,14 @@ static int postProceSql(char *host, uint16_t port,
'w', 'x', 'y', 'z', '0', '1', '2', '3', 'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'}; '4', '5', '6', '7', '8', '9', '+', '/'};
snprintf(userpass_buf, INPUT_BUF_LEN, "%s:%s", if (g_args.test_mode == INSERT_TEST) {
g_Dbs.user, g_Dbs.password); 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 userpass_buf_len = strlen(userpass_buf);
size_t encoded_len = 4 * ((userpass_buf_len +2) / 3); size_t encoded_len = 4 * ((userpass_buf_len +2) / 3);
...@@ -3560,18 +3567,22 @@ static int postProceSql(char *host, uint16_t port, ...@@ -3560,18 +3567,22 @@ static int postProceSql(char *host, uint16_t port,
break; break;
received += bytes; received += bytes;
verbosePrint("%s() LN%d: received:%d resp_len:%d, response_buf:\n%s\n", response_buf[RESP_BUF_LEN - 1] = '\0';
__func__, __LINE__, received, resp_len, response_buf);
if (((NULL != strstr(response_buf, resEncodingChunk)) if (strlen(response_buf)) {
&& (NULL != strstr(response_buf, resHttp))) verbosePrint("%s() LN%d: received:%d resp_len:%d, response_buf:\n%s\n",
|| ((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); __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); } while(received < resp_len);
if (received == resp_len) { if (received == resp_len) {
...@@ -3579,8 +3590,6 @@ static int postProceSql(char *host, uint16_t port, ...@@ -3579,8 +3590,6 @@ static int postProceSql(char *host, uint16_t port,
ERROR_EXIT("storing complete response from socket"); ERROR_EXIT("storing complete response from socket");
} }
response_buf[RESP_BUF_LEN - 1] = '\0';
if (strlen(pThreadInfo->filePath) > 0) { if (strlen(pThreadInfo->filePath) > 0) {
appendResultBufToFile(response_buf, pThreadInfo); appendResultBufToFile(response_buf, pThreadInfo);
} }
...@@ -4378,7 +4387,7 @@ static int createSuperTable( ...@@ -4378,7 +4387,7 @@ static int createSuperTable(
superTbl->lenOfTagOfOneRow = lenOfTagOfOneRow; superTbl->lenOfTagOfOneRow = lenOfTagOfOneRow;
snprintf(command, BUFFER_SIZE, snprintf(command, BUFFER_SIZE,
superTbl->escapeChar ? superTbl->escapeChar ?
"CREATE TABLE IF NOT EXISTS %s.`%s` (ts TIMESTAMP%s) TAGS %s": "CREATE TABLE IF NOT EXISTS %s.`%s` (ts TIMESTAMP%s) TAGS %s":
...@@ -4513,7 +4522,7 @@ int createDatabasesAndStables(char *command) { ...@@ -4513,7 +4522,7 @@ int createDatabasesAndStables(char *command) {
if (g_Dbs.db[i].superTbls[j].iface == SML_IFACE) { if (g_Dbs.db[i].superTbls[j].iface == SML_IFACE) {
goto skip; goto skip;
} }
sprintf(command, "describe %s.%s;", g_Dbs.db[i].dbName, sprintf(command, "describe %s.%s;", g_Dbs.db[i].dbName,
g_Dbs.db[i].superTbls[j].stbName); g_Dbs.db[i].superTbls[j].stbName);
ret = queryDbExec(taos, command, NO_INSERT_TYPE, true); ret = queryDbExec(taos, command, NO_INSERT_TYPE, true);
...@@ -4573,7 +4582,7 @@ static void* createTable(void *sarg) ...@@ -4573,7 +4582,7 @@ static void* createTable(void *sarg)
i <= pThreadInfo->end_table_to; i++) { i <= pThreadInfo->end_table_to; i++) {
if (0 == g_Dbs.use_metric) { if (0 == g_Dbs.use_metric) {
snprintf(pThreadInfo->buffer, buff_len, 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;" :
"CREATE TABLE IF NOT EXISTS %s.%s%"PRIu64" %s;", "CREATE TABLE IF NOT EXISTS %s.%s%"PRIu64" %s;",
pThreadInfo->db_name, pThreadInfo->db_name,
...@@ -6602,7 +6611,7 @@ static int getRowDataFromSample( ...@@ -6602,7 +6611,7 @@ static int getRowDataFromSample(
stbInfo->sampleDataBuf stbInfo->sampleDataBuf
+ stbInfo->lenOfOneRow * (*sampleUsePos)); + stbInfo->lenOfOneRow * (*sampleUsePos));
} }
dataLen += snprintf(dataBuf + dataLen, maxLen - dataLen, ")"); dataLen += snprintf(dataBuf + dataLen, maxLen - dataLen, ")");
(*sampleUsePos)++; (*sampleUsePos)++;
...@@ -7058,6 +7067,7 @@ static int32_t execInsert(threadInfo *pThreadInfo, uint32_t k) ...@@ -7058,6 +7067,7 @@ static int32_t execInsert(threadInfo *pThreadInfo, uint32_t k)
{ {
int32_t affectedRows; int32_t affectedRows;
SSuperTable* stbInfo = pThreadInfo->stbInfo; SSuperTable* stbInfo = pThreadInfo->stbInfo;
TAOS_RES* res;
int32_t code; int32_t code;
uint16_t iface; uint16_t iface;
if (stbInfo) if (stbInfo)
...@@ -7111,17 +7121,14 @@ static int32_t execInsert(threadInfo *pThreadInfo, uint32_t k) ...@@ -7111,17 +7121,14 @@ static int32_t execInsert(threadInfo *pThreadInfo, uint32_t k)
affectedRows = k; affectedRows = k;
break; break;
case SML_IFACE: case SML_IFACE:
code = taos_schemaless_insert(pThreadInfo->taos, pThreadInfo->lines, k, 0, pThreadInfo->time_precision == TSDB_TIME_PRECISION_MILLI res = taos_schemaless_insert(pThreadInfo->taos, pThreadInfo->lines, k, 0, pThreadInfo->time_precision);
? "ms" code = taos_errno(res);
: (pThreadInfo->time_precision == TSDB_TIME_PRECISION_MICRO affectedRows = taos_affected_rows(res);
? "us" if (code != TSDB_CODE_SUCCESS) {
: "ns"));
if (code) {
errorPrint2("%s() LN%d, failed to execute schemaless insert. reason: %s\n", errorPrint2("%s() LN%d, failed to execute schemaless insert. reason: %s\n",
__func__, __LINE__, tstrerror(code)); __func__, __LINE__, taos_errstr(res));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
affectedRows = k;
break; break;
default: default:
errorPrint2("%s() LN%d: unknown insert mode: %d\n", errorPrint2("%s() LN%d: unknown insert mode: %d\n",
...@@ -7139,7 +7146,7 @@ static void getTableName(char *pTblName, ...@@ -7139,7 +7146,7 @@ static void getTableName(char *pTblName,
if (stbInfo) { if (stbInfo) {
if (AUTO_CREATE_SUBTBL != stbInfo->autoCreateTable) { if (AUTO_CREATE_SUBTBL != stbInfo->autoCreateTable) {
if (stbInfo->childTblLimit > 0) { if (stbInfo->childTblLimit > 0) {
snprintf(pTblName, TSDB_TABLE_NAME_LEN, snprintf(pTblName, TSDB_TABLE_NAME_LEN,
stbInfo->escapeChar ? "`%s`" : "%s", stbInfo->escapeChar ? "`%s`" : "%s",
stbInfo->childTblName + stbInfo->childTblName +
(tableSeq - stbInfo->childTblOffset) * TSDB_TABLE_NAME_LEN); (tableSeq - stbInfo->childTblOffset) * TSDB_TABLE_NAME_LEN);
...@@ -7152,12 +7159,12 @@ static void getTableName(char *pTblName, ...@@ -7152,12 +7159,12 @@ static void getTableName(char *pTblName,
stbInfo->childTblName + tableSeq * TSDB_TABLE_NAME_LEN); stbInfo->childTblName + tableSeq * TSDB_TABLE_NAME_LEN);
} }
} else { } else {
snprintf(pTblName, TSDB_TABLE_NAME_LEN, snprintf(pTblName, TSDB_TABLE_NAME_LEN,
stbInfo->escapeChar ? "`%s%"PRIu64"`" : "%s%"PRIu64"", stbInfo->escapeChar ? "`%s%"PRIu64"`" : "%s%"PRIu64"",
stbInfo->childTblPrefix, tableSeq); stbInfo->childTblPrefix, tableSeq);
} }
} else { } else {
snprintf(pTblName, TSDB_TABLE_NAME_LEN, snprintf(pTblName, TSDB_TABLE_NAME_LEN,
g_args.escapeChar ? "`%s%"PRIu64"`" : "%s%"PRIu64"", g_args.escapeChar ? "`%s%"PRIu64"`" : "%s%"PRIu64"",
g_args.tb_prefix, tableSeq); g_args.tb_prefix, tableSeq);
} }
...@@ -9713,7 +9720,7 @@ static void generateSmlHead(char* smlHead, SSuperTable* stbInfo, threadInfo* pTh ...@@ -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) { threadInfo* pThreadInfo, int64_t timestamp) {
int dataLen = 0; int dataLen = 0;
dataLen = snprintf(line, BUFFER_SIZE, "%s ", smlHead); dataLen = snprintf(line, BUFFER_SIZE, "%s ", smlHead);
...@@ -9860,7 +9867,7 @@ static void* syncWriteInterlaceSml(threadInfo *pThreadInfo, uint32_t interlaceRo ...@@ -9860,7 +9867,7 @@ static void* syncWriteInterlaceSml(threadInfo *pThreadInfo, uint32_t interlaceRo
} else { } else {
batchPerTblTimes = 1; batchPerTblTimes = 1;
} }
char *smlHead[pThreadInfo->ntables]; char *smlHead[pThreadInfo->ntables];
for (int t = 0; t < pThreadInfo->ntables; t++) { for (int t = 0; t < pThreadInfo->ntables; t++) {
smlHead[t] = (char *)calloc(HEAD_BUFF_LEN, 1); smlHead[t] = (char *)calloc(HEAD_BUFF_LEN, 1);
...@@ -9869,7 +9876,7 @@ static void* syncWriteInterlaceSml(threadInfo *pThreadInfo, uint32_t interlaceRo ...@@ -9869,7 +9876,7 @@ static void* syncWriteInterlaceSml(threadInfo *pThreadInfo, uint32_t interlaceRo
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
generateSmlHead(smlHead[t], stbInfo, pThreadInfo, t); generateSmlHead(smlHead[t], stbInfo, pThreadInfo, t);
} }
pThreadInfo->totalInsertRows = 0; pThreadInfo->totalInsertRows = 0;
...@@ -9895,11 +9902,11 @@ static void* syncWriteInterlaceSml(threadInfo *pThreadInfo, uint32_t interlaceRo ...@@ -9895,11 +9902,11 @@ static void* syncWriteInterlaceSml(threadInfo *pThreadInfo, uint32_t interlaceRo
pThreadInfo->lines = calloc(g_args.reqPerReq, sizeof(char *)); pThreadInfo->lines = calloc(g_args.reqPerReq, sizeof(char *));
if (NULL == pThreadInfo->lines) { if (NULL == pThreadInfo->lines) {
errorPrint2("Failed to alloc %"PRIu64" bytes, reason:%s\n", errorPrint2("Failed to alloc %"PRIu64" bytes, reason:%s\n",
g_args.reqPerReq * sizeof(char *), g_args.reqPerReq * (uint64_t)sizeof(char *),
strerror(errno)); strerror(errno));
return NULL; return NULL;
} }
while(pThreadInfo->totalInsertRows < pThreadInfo->ntables * insertRows) { while(pThreadInfo->totalInsertRows < pThreadInfo->ntables * insertRows) {
if ((flagSleep) && (insert_interval)) { if ((flagSleep) && (insert_interval)) {
st = taosGetTimestampMs(); st = taosGetTimestampMs();
...@@ -10450,10 +10457,8 @@ static void* syncWriteProgressiveSml(threadInfo *pThreadInfo) { ...@@ -10450,10 +10457,8 @@ static void* syncWriteProgressiveSml(threadInfo *pThreadInfo) {
debugPrint("%s() LN%d: ### sml progressive write\n", __func__, __LINE__); debugPrint("%s() LN%d: ### sml progressive write\n", __func__, __LINE__);
SSuperTable* stbInfo = pThreadInfo->stbInfo; SSuperTable* stbInfo = pThreadInfo->stbInfo;
int64_t timeStampStep = int64_t timeStampStep = stbInfo->timeStampStep;
stbInfo?stbInfo->timeStampStep:g_args.timestamp_step; int64_t insertRows = stbInfo->insertRows;
int64_t insertRows =
(stbInfo)?stbInfo->insertRows:g_args.insertRows;
verbosePrint("%s() LN%d insertRows=%"PRId64"\n", verbosePrint("%s() LN%d insertRows=%"PRId64"\n",
__func__, __LINE__, insertRows); __func__, __LINE__, insertRows);
...@@ -10472,7 +10477,7 @@ static void* syncWriteProgressiveSml(threadInfo *pThreadInfo) { ...@@ -10472,7 +10477,7 @@ static void* syncWriteProgressiveSml(threadInfo *pThreadInfo) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
generateSmlHead(smlHead[t], stbInfo, pThreadInfo, t); generateSmlHead(smlHead[t], stbInfo, pThreadInfo, t);
} }
int currentPercent = 0; int currentPercent = 0;
int percentComplete = 0; int percentComplete = 0;
...@@ -10483,14 +10488,14 @@ static void* syncWriteProgressiveSml(threadInfo *pThreadInfo) { ...@@ -10483,14 +10488,14 @@ static void* syncWriteProgressiveSml(threadInfo *pThreadInfo) {
pThreadInfo->lines = calloc(g_args.reqPerReq, sizeof(char *)); pThreadInfo->lines = calloc(g_args.reqPerReq, sizeof(char *));
if (NULL == pThreadInfo->lines) { if (NULL == pThreadInfo->lines) {
errorPrint2("Failed to alloc %"PRIu64" bytes, reason:%s\n", errorPrint2("Failed to alloc %"PRIu64" bytes, reason:%s\n",
g_args.reqPerReq * sizeof(char *), g_args.reqPerReq * (uint64_t)sizeof(char *),
strerror(errno)); strerror(errno));
return NULL; return NULL;
} }
for (uint64_t i = 0; i < pThreadInfo->ntables; i++) { for (uint64_t i = 0; i < pThreadInfo->ntables; i++) {
int64_t timestamp = pThreadInfo->start_time; int64_t timestamp = pThreadInfo->start_time;
for (uint64_t j = 0; j < insertRows;) { for (uint64_t j = 0; j < insertRows;) {
for (int k = 0; k < g_args.reqPerReq; k++) { for (int k = 0; k < g_args.reqPerReq; k++) {
pThreadInfo->lines[k] = calloc(BUFFER_SIZE, 1); pThreadInfo->lines[k] = calloc(BUFFER_SIZE, 1);
...@@ -10958,7 +10963,7 @@ static void startMultiThreadInsertData(int threads, char* db_name, ...@@ -10958,7 +10963,7 @@ static void startMultiThreadInsertData(int threads, char* db_name,
int64_t ntables = 0; int64_t ntables = 0;
uint64_t tableFrom; uint64_t tableFrom;
if (stbInfo) { if (stbInfo) {
if (stbInfo->iface != SML_IFACE) { if (stbInfo->iface != SML_IFACE) {
int64_t limit; int64_t limit;
...@@ -11200,7 +11205,7 @@ static void startMultiThreadInsertData(int threads, char* db_name, ...@@ -11200,7 +11205,7 @@ static void startMultiThreadInsertData(int threads, char* db_name,
pThreadInfo->start_time = pThreadInfo->start_time + rand_int() % 10000 - rand_tinyint(); pThreadInfo->start_time = pThreadInfo->start_time + rand_int() % 10000 - rand_tinyint();
} }
*/ */
if (g_args.iface == REST_IFACE || ((stbInfo) && (stbInfo->iface == REST_IFACE))) { if (g_args.iface == REST_IFACE || ((stbInfo) && (stbInfo->iface == REST_IFACE))) {
#ifdef WINDOWS #ifdef WINDOWS
WSADATA wsaData; WSADATA wsaData;
...@@ -11225,7 +11230,7 @@ static void startMultiThreadInsertData(int threads, char* db_name, ...@@ -11225,7 +11230,7 @@ static void startMultiThreadInsertData(int threads, char* db_name,
} }
pThreadInfo->sockfd = sockfd; pThreadInfo->sockfd = sockfd;
} }
tsem_init(&(pThreadInfo->lock_sem), 0, 0); tsem_init(&(pThreadInfo->lock_sem), 0, 0);
if (ASYNC_MODE == g_Dbs.asyncMode) { if (ASYNC_MODE == g_Dbs.asyncMode) {
...@@ -11658,11 +11663,16 @@ static int insertTestProcess() { ...@@ -11658,11 +11663,16 @@ static int insertTestProcess() {
} }
} }
} else { } 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.threadCount,
g_Dbs.db[i].dbName, g_Dbs.db[i].dbName,
g_Dbs.db[i].dbCfg.precision, g_Dbs.db[i].dbCfg.precision,
NULL); NULL);
}
} }
} }
//end = taosGetTimestampMs(); //end = taosGetTimestampMs();
......
...@@ -2091,7 +2091,7 @@ static int getTableDes( ...@@ -2091,7 +2091,7 @@ static int getTableDes(
memset(tableDes->cols[i].value, 0, sizeof(tableDes->cols[i].note)); memset(tableDes->cols[i].value, 0, sizeof(tableDes->cols[i].note));
char tbuf[COL_NOTE_LEN-2]; // need reserve 2 bytes for ' ' 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); 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; break;
} }
case TSDB_DATA_TYPE_TIMESTAMP: case TSDB_DATA_TYPE_TIMESTAMP:
......
...@@ -32,7 +32,7 @@ ELSE () ...@@ -32,7 +32,7 @@ ELSE ()
MESSAGE("") MESSAGE("")
MESSAGE("${Green} use blm3 as httpd ${ColourReset}") MESSAGE("${Green} use blm3 as httpd ${ColourReset}")
EXECUTE_PROCESS( EXECUTE_PROCESS(
COMMAND cd blm3 COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR}/blm3
) )
EXECUTE_PROCESS( EXECUTE_PROCESS(
COMMAND git rev-parse --short HEAD COMMAND git rev-parse --short HEAD
......
Subproject commit c67fcc11bc5e82e3d7aea8db855a8cbf8b109239 Subproject commit f56aa0f485d7bb6aebbcefc2007eeecdccb767c8
...@@ -204,7 +204,6 @@ static void monBuildMonitorSql(char *sql, int32_t cmd) { ...@@ -204,7 +204,6 @@ static void monBuildMonitorSql(char *sql, int32_t cmd) {
", disk_used float, disk_total int" ", disk_used float, disk_total int"
", band_speed float" ", band_speed float"
", io_read float, io_write float" ", io_read float, io_write float"
", io_read_rate float, io_write_rate float"
", req_http int, req_select int, req_insert int" ", req_http int, req_select int, req_insert int"
") tags (dnodeid int, fqdn binary(%d))", ") tags (dnodeid int, fqdn binary(%d))",
tsMonitorDbName, TSDB_FQDN_LEN); tsMonitorDbName, TSDB_FQDN_LEN);
...@@ -326,10 +325,7 @@ static int32_t monBuildIoSql(char *sql) { ...@@ -326,10 +325,7 @@ static int32_t monBuildIoSql(char *sql) {
monDebug("failed to get io info"); monDebug("failed to get io info");
} }
float readRate = readKB/tsMonitorInterval; return sprintf(sql, ", %f, %f", readKB, writeKB);
float writeRate = writeKB/tsMonitorInterval;
return sprintf(sql, ", %f, %f, %f, %f", readKB, writeKB, readRate, writeRate);
} }
static void monSaveSystemInfo() { static void monSaveSystemInfo() {
......
...@@ -233,6 +233,7 @@ int32_t isValidFunction(const char* name, int32_t len); ...@@ -233,6 +233,7 @@ int32_t isValidFunction(const char* name, int32_t len);
#define IS_MULTIOUTPUT(x) (((x)&TSDB_FUNCSTATE_MO) != 0) #define IS_MULTIOUTPUT(x) (((x)&TSDB_FUNCSTATE_MO) != 0)
#define IS_SINGLEOUTPUT(x) (((x)&TSDB_FUNCSTATE_SO) != 0) #define IS_SINGLEOUTPUT(x) (((x)&TSDB_FUNCSTATE_SO) != 0)
#define IS_OUTER_FORWARD(x) (((x)&TSDB_FUNCSTATE_OF) != 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 // determine the real data need to calculated the result
enum { enum {
......
...@@ -312,7 +312,8 @@ typedef struct SQueryRuntimeEnv { ...@@ -312,7 +312,8 @@ typedef struct SQueryRuntimeEnv {
STableQueryInfo *current; STableQueryInfo *current;
SRspResultInfo resultInfo; SRspResultInfo resultInfo;
SHashObj *pTableRetrieveTsMap; SHashObj *pTableRetrieveTsMap;
SUdfInfo *pUdfInfo; SUdfInfo *pUdfInfo;
bool udfIsCopy;
} SQueryRuntimeEnv; } SQueryRuntimeEnv;
enum { enum {
......
...@@ -51,6 +51,7 @@ typedef struct SUdfInfo { ...@@ -51,6 +51,7 @@ typedef struct SUdfInfo {
SUdfInit init; SUdfInit init;
char *content; char *content;
char *path; char *path;
bool keep;
} SUdfInfo; } SUdfInfo;
//script //script
......
...@@ -988,13 +988,12 @@ void doInvokeUdf(SUdfInfo* pUdfInfo, SQLFunctionCtx *pCtx, int32_t idx, int32_t ...@@ -988,13 +988,12 @@ void doInvokeUdf(SUdfInfo* pUdfInfo, SQLFunctionCtx *pCtx, int32_t idx, int32_t
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
void *interBuf = (void *)GET_ROWCELL_INTERBUF(pResInfo); void *interBuf = (void *)GET_ROWCELL_INTERBUF(pResInfo);
if (pUdfInfo->isScript) { 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 { } 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 (pCtx->resultInfo->numOfRes > 0) {
if (output > 0) {
pCtx->resultInfo->hasResult = DATA_SET_FLAG; pCtx->resultInfo->hasResult = DATA_SET_FLAG;
} }
...@@ -2409,8 +2408,10 @@ static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) { ...@@ -2409,8 +2408,10 @@ static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) {
tfree(pRuntimeEnv->sasArray); tfree(pRuntimeEnv->sasArray);
} }
destroyUdfInfo(pRuntimeEnv->pUdfInfo); if (!pRuntimeEnv->udfIsCopy) {
destroyUdfInfo(pRuntimeEnv->pUdfInfo);
}
destroyResultBuf(pRuntimeEnv->pResultBuf); destroyResultBuf(pRuntimeEnv->pResultBuf);
doFreeQueryHandle(pRuntimeEnv); doFreeQueryHandle(pRuntimeEnv);
...@@ -8039,7 +8040,7 @@ static char* getUdfFuncName(char* funcname, char* name, int type) { ...@@ -8039,7 +8040,7 @@ static char* getUdfFuncName(char* funcname, char* name, int type) {
} }
int32_t initUdfInfo(SUdfInfo* pUdfInfo) { int32_t initUdfInfo(SUdfInfo* pUdfInfo) {
if (pUdfInfo == NULL) { if (pUdfInfo == NULL || pUdfInfo->handle) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
//qError("script len: %d", pUdfInfo->contLen); //qError("script len: %d", pUdfInfo->contLen);
...@@ -8074,10 +8075,21 @@ int32_t initUdfInfo(SUdfInfo* pUdfInfo) { ...@@ -8074,10 +8075,21 @@ int32_t initUdfInfo(SUdfInfo* pUdfInfo) {
// TODO check for failure of flush to disk // TODO check for failure of flush to disk
/*size_t t = */ fwrite(pUdfInfo->content, pUdfInfo->contLen, 1, file); /*size_t t = */ fwrite(pUdfInfo->content, pUdfInfo->contLen, 1, file);
fclose(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); pUdfInfo->path = strdup(path);
if (pUdfInfo->handle) {
taosCloseDll(pUdfInfo->handle);
}
pUdfInfo->handle = taosLoadDll(path); pUdfInfo->handle = taosLoadDll(path);
if (NULL == pUdfInfo->handle) { if (NULL == pUdfInfo->handle) {
...@@ -8092,9 +8104,17 @@ int32_t initUdfInfo(SUdfInfo* pUdfInfo) { ...@@ -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_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) { if (pUdfInfo->funcType == TSDB_UDF_TYPE_AGGREGATE) {
pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(funcname, pUdfInfo->name, TSDB_UDF_FUNC_FINALIZE)); if (NULL == pUdfInfo->funcs[TSDB_UDF_FUNC_MERGE] || NULL == pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE]) {
pUdfInfo->funcs[TSDB_UDF_FUNC_MERGE] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(funcname, pUdfInfo->name, TSDB_UDF_FUNC_MERGE)); 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)); 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 ...@@ -8201,7 +8221,7 @@ int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExp
} }
int32_t param = (int32_t)pExprs[i].base.param[0].i64; 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)) { (type != pExprs[i].base.colType || bytes != pExprs[i].base.colBytes)) {
tfree(pExprs); tfree(pExprs);
return TSDB_CODE_QRY_INVALID_MSG; return TSDB_CODE_QRY_INVALID_MSG;
......
...@@ -185,19 +185,10 @@ int tsdbUnlockRepo(STsdbRepo *pRepo) { ...@@ -185,19 +185,10 @@ int tsdbUnlockRepo(STsdbRepo *pRepo) {
return 0; 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 int tsdbCheckWal(STsdbRepo *pRepo, uint32_t walSize) { // MB
STsdbCfg *pCfg = &(pRepo->config); STsdbCfg *pCfg = &(pRepo->config);
if ((walSize > tsdbWalFlushSize) && (walSize > (pCfg->totalBlocks / 2 * pCfg->cacheBlockSize))) { 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; return 0;
} }
...@@ -211,7 +202,7 @@ int tsdbCheckCommit(STsdbRepo *pRepo) { ...@@ -211,7 +202,7 @@ int tsdbCheckCommit(STsdbRepo *pRepo) {
if ((pRepo->mem->extraBuffList != NULL) || if ((pRepo->mem->extraBuffList != NULL) ||
((listNEles(pRepo->mem->bufBlockList) >= pCfg->totalBlocks / 3) && (pBufBlock->remain < TSDB_BUFFER_RESERVE))) { ((listNEles(pRepo->mem->bufBlockList) >= pCfg->totalBlocks / 3) && (pBufBlock->remain < TSDB_BUFFER_RESERVE))) {
// trigger commit // trigger commit
if (tsdbIsNeedCommit(pRepo) && (tsdbAsyncCommit(pRepo) < 0)) return -1; if (tsdbAsyncCommit(pRepo) < 0) return -1;
} }
return 0; return 0;
} }
......
...@@ -628,7 +628,7 @@ SStrToken tStrGetToken(char* str, int32_t* i, bool isPrevOptr) { ...@@ -628,7 +628,7 @@ SStrToken tStrGetToken(char* str, int32_t* i, bool isPrevOptr) {
t0.n = 0; t0.n = 0;
return t0; return t0;
} }
t = str[++(*i)]; t = str[++(*i)];
} }
......
...@@ -53,13 +53,13 @@ int32_t strdequote(char *z) { ...@@ -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: \\, \', \" // delete escape character: \\, \', \"
char delim = z[0]; char delim = z[0];
if (delim != '\'' && delim != '\"') { if (delim != '\'' && delim != '\"') {
return len; return len;
} }
int32_t cnt = 0; int32_t cnt = 0;
int32_t j = 0; int32_t j = 0;
for (uint32_t k = 1; k < len - 1; ++k) { for (uint32_t k = 1; k < len - 1; ++k) {
...@@ -74,23 +74,24 @@ int32_t strRmquote(char *z, int32_t len){ ...@@ -74,23 +74,24 @@ int32_t strRmquote(char *z, int32_t len){
continue; continue;
} }
} }
z[j] = z[k]; z[j] = z[k];
j++; j++;
} }
z[j] = 0; z[j] = 0;
return len - 2 - cnt; return len - 2 - cnt;
} }
int32_t strRmquoteEscape(char *z, int32_t len) { int32_t strRmquoteEscape(char *z, int32_t len) {
if (len <= 0) return len; if (len <= 0) return len;
if (z[0] == '\'' || z[0] == '\"') { if (z[0] == '\'' || z[0] == '\"') {
return strRmquote(z, len); return strRmquote(z, len);
} else if (len > 1 && z[0] == TS_ESCAPE_CHAR && z[len - 1] == TS_ESCAPE_CHAR) { } else if (len > 1 && z[0] == TS_ESCAPE_CHAR && z[len - 1] == TS_ESCAPE_CHAR) {
memmove(z, z + 1, len - 2); memmove(z, z + 1, len - 2);
z[len - 2] = '\0';
return len - 2; return len - 2;
} }
......
...@@ -169,7 +169,7 @@ static int32_t vnodeProcessSubmitMsg(SVnodeObj *pVnode, void *pCont, SRspRet *pR ...@@ -169,7 +169,7 @@ static int32_t vnodeProcessSubmitMsg(SVnodeObj *pVnode, void *pCont, SRspRet *pR
} }
static int32_t vnodeCheckWal(SVnodeObj *pVnode) { static int32_t vnodeCheckWal(SVnodeObj *pVnode) {
if (tsdbIsNeedCommit(pVnode->tsdb)) { if (pVnode->isCommiting == 0) {
return tsdbCheckWal(pVnode->tsdb, walGetFSize(pVnode->wal) >> 20); return tsdbCheckWal(pVnode->tsdb, walGetFSize(pVnode->wal) >> 20);
} }
return 0; return 0;
...@@ -189,7 +189,7 @@ static int32_t vnodeProcessCreateTableMsg(SVnodeObj *pVnode, void *pCont, SRspRe ...@@ -189,7 +189,7 @@ static int32_t vnodeProcessCreateTableMsg(SVnodeObj *pVnode, void *pCont, SRspRe
ASSERT(code != 0); ASSERT(code != 0);
} }
if (((++pVnode->tblMsgVer) & 16383) == 0) { // lazy check if (((++pVnode->tblMsgVer) & 32767) == 0) { // lazy check
vnodeCheckWal(pVnode); vnodeCheckWal(pVnode);
} }
......
...@@ -15,7 +15,7 @@ static void prepare_data(TAOS* taos) { ...@@ -15,7 +15,7 @@ static void prepare_data(TAOS* taos) {
result = taos_query(taos, "drop database if exists test;"); result = taos_query(taos, "drop database if exists test;");
taos_free_result(result); taos_free_result(result);
usleep(100000); usleep(100000);
result = taos_query(taos, "create database test precision 'us';"); result = taos_query(taos, "create database test precision 'ns';");
taos_free_result(result); taos_free_result(result);
usleep(100000); usleep(100000);
taos_select_db(taos, "test"); taos_select_db(taos, "test");
...@@ -288,12 +288,12 @@ void verify_stream(TAOS* taos) { ...@@ -288,12 +288,12 @@ void verify_stream(TAOS* taos) {
taos_close_stream(strm); taos_close_stream(strm);
} }
int32_t verify_schema_less(TAOS* taos) { void verify_schema_less(TAOS* taos) {
TAOS_RES* result; TAOS_RES* result;
result = taos_query(taos, "drop database if exists test;"); result = taos_query(taos, "drop database if exists test;");
taos_free_result(result); taos_free_result(result);
usleep(100000); 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); taos_free_result(result);
usleep(100000); usleep(100000);
...@@ -302,7 +302,7 @@ int32_t verify_schema_less(TAOS* taos) { ...@@ -302,7 +302,7 @@ int32_t verify_schema_less(TAOS* taos) {
taos_free_result(result); taos_free_result(result);
usleep(100000); usleep(100000);
int code = 0; int code = 0, affected_rows = 0;
char* lines[] = { char* lines[] = {
"st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000", "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) { ...@@ -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" "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[] = { char* lines2[] = {
"stg,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000", "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" "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"); result = taos_schemaless_insert(taos, &lines2[0], 1, TSDB_SML_LINE_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS);
code = taos_schemaless_insert(taos, &lines2[1], 1, 0, "ns"); 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[] = { 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,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" "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[] = { char* lines4[] = {
"st123456,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000", "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" "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[] = { 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,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" "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"); result = taos_schemaless_insert(taos, &lines5[0], 1, TSDB_SML_LINE_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS);
code = taos_schemaless_insert(taos, &lines5[1], 1, 0, "ns"); 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[] = { char* lines6[] = {
"st123456,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000", "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" "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[]) { int main(int argc, char* argv[]) {
......
...@@ -33,6 +33,8 @@ typedef struct { ...@@ -33,6 +33,8 @@ typedef struct {
int numBatches; int numBatches;
SThreadLinesBatch batches[MAX_THREAD_LINE_BATCHES]; SThreadLinesBatch batches[MAX_THREAD_LINE_BATCHES];
int64_t costTime; int64_t costTime;
int tsPrecision;
int lineProtocol;
} SThreadInsertArgs; } SThreadInsertArgs;
static void* insertLines(void* args) { static void* insertLines(void* args) {
...@@ -43,10 +45,12 @@ static void* insertLines(void* args) { ...@@ -43,10 +45,12 @@ static void* insertLines(void* args) {
SThreadLinesBatch* batch = insertArgs->batches + i; SThreadLinesBatch* batch = insertArgs->batches + i;
printf("%s, thread: 0x%s\n", "begin taos_insert_lines", tidBuf); printf("%s, thread: 0x%s\n", "begin taos_insert_lines", tidBuf);
int64_t begin = getTimeInUs(); 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(); int64_t end = getTimeInUs();
insertArgs->costTime += end - begin; 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; return NULL;
} }
...@@ -95,9 +99,11 @@ int main(int argc, char* argv[]) { ...@@ -95,9 +99,11 @@ int main(int argc, char* argv[]) {
int numFields = 13; int numFields = 13;
int maxLinesPerBatch = 16384; int maxLinesPerBatch = 16384;
int tsPrecision = TSDB_SML_TIMESTAMP_NOT_CONFIGURED;
int lineProtocol = TSDB_SML_UNKNOWN_PROTOCOL;
int opt; 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) { switch (opt) {
case 's': case 's':
numSuperTables = atoi(optarg); numSuperTables = atoi(optarg);
...@@ -117,6 +123,12 @@ int main(int argc, char* argv[]) { ...@@ -117,6 +123,12 @@ int main(int argc, char* argv[]) {
case 'm': case 'm':
maxLinesPerBatch = atoi(optarg); maxLinesPerBatch = atoi(optarg);
break; break;
case 'p':
tsPrecision = atoi(optarg);
break;
case 'P':
lineProtocol = atoi(optarg);
break;
case 'h': case 'h':
fprintf(stderr, "Usage: %s -s supertable -c childtable -r rows -f fields -t threads -m maxlines_per_batch\n", fprintf(stderr, "Usage: %s -s supertable -c childtable -r rows -f fields -t threads -m maxlines_per_batch\n",
argv[0]); argv[0]);
...@@ -178,6 +190,8 @@ int main(int argc, char* argv[]) { ...@@ -178,6 +190,8 @@ int main(int argc, char* argv[]) {
args.taos = taos; args.taos = taos;
args.batches[0].lines = linesStb; args.batches[0].lines = linesStb;
args.batches[0].numLines = numSuperTables; args.batches[0].numLines = numSuperTables;
args.tsPrecision = tsPrecision;
args.lineProtocol = lineProtocol;
insertLines(&args); insertLines(&args);
for (int i = 0; i < numSuperTables; ++i) { for (int i = 0; i < numSuperTables; ++i) {
free(linesStb[i]); free(linesStb[i]);
......
...@@ -21,78 +21,91 @@ import json ...@@ -21,78 +21,91 @@ import json
import random import random
import time import time
import datetime import datetime
import multiprocessing
from multiprocessing import Manager, Pool, Lock from multiprocessing import Manager, Pool, Lock
from multipledispatch import dispatch from multipledispatch import dispatch
from concurrent.futures import ThreadPoolExecutor, wait, ALL_COMPLETED from concurrent.futures import ThreadPoolExecutor, wait, ALL_COMPLETED
@dispatch(str, str) @dispatch(str, str)
def v_print(msg: str, arg: str): def v_print(msg, arg):
# type: (str, str) -> None
if verbose: if verbose:
print(msg % arg) print(msg % arg)
@dispatch(str, str, str) @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: if verbose:
print(msg % (arg1, arg2)) print(msg % (arg1, arg2))
@dispatch(str, str, str, str) @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: if verbose:
print(msg % (arg1, arg2, arg3)) print(msg % (arg1, arg2, arg3))
@dispatch(str, str, str, str, str) @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: if verbose:
print(msg % (arg1, arg2, arg3, arg4)) print(msg % (arg1, arg2, arg3, arg4))
@dispatch(str, int) @dispatch(str, int)
def v_print(msg: str, arg: int): def v_print(msg, arg):
# type: (str, int) -> None
if verbose: if verbose:
print(msg % int(arg)) print(msg % int(arg))
@dispatch(str, int, str) @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: if verbose:
print(msg % (int(arg1), str(arg2))) print(msg % (int(arg1), str(arg2)))
@dispatch(str, str, int) @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: if verbose:
print(msg % (arg1, int(arg2))) print(msg % (arg1, int(arg2)))
@dispatch(str, int, int) @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: if verbose:
print(msg % (int(arg1), int(arg2))) print(msg % (int(arg1), int(arg2)))
@dispatch(str, int, int, str) @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: if verbose:
print(msg % (int(arg1), int(arg2), str(arg3))) print(msg % (int(arg1), int(arg2), str(arg3)))
@dispatch(str, int, int, int) @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: if verbose:
print(msg % (int(arg1), int(arg2), int(arg3))) print(msg % (int(arg1), int(arg2), int(arg3)))
@dispatch(str, int, int, int, int) @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: if verbose:
print(msg % (int(arg1), int(arg2), int(arg3), int(arg4))) 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) url = "http://%s:%d/rest/sql" % (host, restPort)
v_print("restful_execute - cmd: %s", cmd) v_print("restful_execute - cmd: %s", cmd)
...@@ -112,7 +125,8 @@ def restful_execute(host: str, port: int, user: str, password: str, cmd: str): ...@@ -112,7 +125,8 @@ def restful_execute(host: str, port: int, user: str, password: str, cmd: str):
print("resp: %s" % json.dumps(resp.json())) 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) v_print("%d process %d thread cmd: %s", process, thread, cmd)
if oneMoreHost != "NotSupported" and random.randint( if oneMoreHost != "NotSupported" and random.randint(
...@@ -133,7 +147,8 @@ def query_func(process: int, thread: int, cmd: str): ...@@ -133,7 +147,8 @@ def query_func(process: int, thread: int, cmd: str):
host, port, user, password, cmd) host, port, user, password, cmd)
def query_data_process(cmd: str): def query_data_process(cmd):
# type: (str) -> None
# establish connection if native # establish connection if native
if native: if native:
v_print("host:%s, user:%s passwd:%s configDir:%s ", host, user, password, configDir) v_print("host:%s, user:%s passwd:%s configDir:%s ", host, user, password, configDir)
...@@ -256,7 +271,8 @@ def drop_databases(): ...@@ -256,7 +271,8 @@ def drop_databases():
(dbName, i)) (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) v_print("%d process %d thread, insert_func ", process, thread)
# generate uuid # generate uuid
...@@ -374,7 +390,8 @@ def create_tb(): ...@@ -374,7 +390,8 @@ def create_tb():
(tbName, j)) (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() lock.acquire()
tasks = end - begin tasks = end - begin
v_print("insert_data_process:%d table from %d to %d, tasks %d", i, begin, end, tasks) v_print("insert_data_process:%d table from %d to %d, tasks %d", i, begin, end, tasks)
...@@ -675,7 +692,10 @@ if __name__ == "__main__": ...@@ -675,7 +692,10 @@ if __name__ == "__main__":
printConfig() printConfig()
if not skipPrompt: if not skipPrompt:
input("Press any key to continue..") try:
input("Press any key to continue..")
except SyntaxError:
pass
# establish connection first if native # establish connection first if native
if native: if native:
......
...@@ -36,7 +36,8 @@ class TwoClients: ...@@ -36,7 +36,8 @@ class TwoClients:
tdDnodes.deploy(1) tdDnodes.deploy(1)
tdDnodes.start(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()) conn1 = taos.connect(host=self.host, user=self.user, password=self.password, config=tdDnodes.getSimCfgPath())
cursor1 = conn1.cursor() cursor1 = conn1.cursor()
cursor1.execute("drop database if exists db") cursor1.execute("drop database if exists db")
...@@ -90,6 +91,8 @@ class TwoClients: ...@@ -90,6 +91,8 @@ class TwoClients:
cursor2.close() cursor2.close()
conn1.close() conn1.close()
conn2.close() conn2.close()
tdLog.success("%s successfully executed" % __file__)
clients = TwoClients() clients = TwoClients()
clients.initConnection() clients.initConnection()
......
...@@ -313,7 +313,7 @@ python3 testNoCompress.py ...@@ -313,7 +313,7 @@ python3 testNoCompress.py
python3 testMinTablesPerVnode.py python3 testMinTablesPerVnode.py
python3 queryCount.py python3 queryCount.py
python3 ./test.py -f query/queryGroupbyWithInterval.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/queryInterval.py
python3 test.py -f query/queryFillTest.py python3 test.py -f query/queryFillTest.py
# subscribe # subscribe
......
...@@ -15,6 +15,7 @@ import sys ...@@ -15,6 +15,7 @@ import sys
from util.log import * from util.log import *
from util.cases import * from util.cases import *
from util.sql import * from util.sql import *
from util.types import TDSmlProtocolType, TDSmlTimestampType
class TDTestCase: class TDTestCase:
...@@ -35,7 +36,7 @@ class TDTestCase: ...@@ -35,7 +36,7 @@ class TDTestCase:
print("============= step0 : test metric ================") print("============= step0 : test metric ================")
payload = [''' payload = ['''
{ {
"metric": "`.stb.0.`", "metric": ".stb.0.",
"timestamp": 1626006833610, "timestamp": 1626006833610,
"value": 10, "value": 10,
"tags": { "tags": {
...@@ -46,7 +47,7 @@ class TDTestCase: ...@@ -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)) print("schemaless_insert result {}".format(code))
tdSql.query("describe `.stb.0.`") tdSql.query("describe `.stb.0.`")
...@@ -67,7 +68,7 @@ class TDTestCase: ...@@ -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)) print("schemaless_insert result {}".format(code))
tdSql.query("describe stb0_0") tdSql.query("describe stb0_0")
...@@ -86,7 +87,7 @@ class TDTestCase: ...@@ -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)) print("schemaless_insert result {}".format(code))
tdSql.query("describe stb0_1") tdSql.query("describe stb0_1")
...@@ -105,7 +106,7 @@ class TDTestCase: ...@@ -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)) print("schemaless_insert result {}".format(code))
tdSql.query("describe stb0_2") tdSql.query("describe stb0_2")
...@@ -124,7 +125,7 @@ class TDTestCase: ...@@ -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)) print("schemaless_insert result {}".format(code))
tdSql.query("describe stb0_3") tdSql.query("describe stb0_3")
...@@ -143,7 +144,7 @@ class TDTestCase: ...@@ -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)) print("schemaless_insert result {}".format(code))
tdSql.query("describe stb0_4") tdSql.query("describe stb0_4")
...@@ -162,7 +163,7 @@ class TDTestCase: ...@@ -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)) print("schemaless_insert result {}".format(code))
tdSql.query("describe stb0_5") tdSql.query("describe stb0_5")
...@@ -184,7 +185,7 @@ class TDTestCase: ...@@ -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)) print("schemaless_insert result {}".format(code))
### timestamp 10 digits second ### ### timestamp 10 digits second ###
...@@ -201,7 +202,7 @@ class TDTestCase: ...@@ -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("schemaless_insert result {}".format(code))
print("============= step3 : test tags ================") print("============= step3 : test tags ================")
...@@ -216,7 +217,7 @@ class TDTestCase: ...@@ -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)) print("schemaless_insert result {}".format(code))
tdSql.query("describe stb0_8") tdSql.query("describe stb0_8")
...@@ -232,7 +233,7 @@ class TDTestCase: ...@@ -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)) print("schemaless_insert result {}".format(code))
tdSql.query("describe stb0_9") tdSql.query("describe stb0_9")
...@@ -248,7 +249,7 @@ class TDTestCase: ...@@ -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)) print("schemaless_insert result {}".format(code))
tdSql.query("describe stb0_10") tdSql.query("describe stb0_10")
...@@ -274,7 +275,7 @@ class TDTestCase: ...@@ -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)) print("schemaless_insert result {}".format(code))
tdSql.query("select ts from stb1_0") tdSql.query("select ts from stb1_0")
...@@ -297,7 +298,7 @@ class TDTestCase: ...@@ -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)) print("schemaless_insert result {}".format(code))
tdSql.query("select ts from stb1_1") tdSql.query("select ts from stb1_1")
...@@ -320,7 +321,7 @@ class TDTestCase: ...@@ -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)) print("schemaless_insert result {}".format(code))
tdSql.query("select ts from stb1_2") tdSql.query("select ts from stb1_2")
...@@ -343,7 +344,7 @@ class TDTestCase: ...@@ -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)) print("schemaless_insert result {}".format(code))
tdSql.query("select ts from stb1_3") tdSql.query("select ts from stb1_3")
...@@ -367,7 +368,7 @@ class TDTestCase: ...@@ -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)) print("schemaless_insert result {}".format(code))
### metric value ### ### metric value ###
...@@ -390,7 +391,7 @@ class TDTestCase: ...@@ -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)) print("schemaless_insert result {}".format(code))
tdSql.query("describe stb2_0") tdSql.query("describe stb2_0")
...@@ -415,7 +416,7 @@ class TDTestCase: ...@@ -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)) print("schemaless_insert result {}".format(code))
tdSql.query("describe stb2_1") tdSql.query("describe stb2_1")
...@@ -440,7 +441,7 @@ class TDTestCase: ...@@ -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)) print("schemaless_insert result {}".format(code))
tdSql.query("describe stb2_2") tdSql.query("describe stb2_2")
...@@ -465,7 +466,7 @@ class TDTestCase: ...@@ -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)) print("schemaless_insert result {}".format(code))
tdSql.query("describe stb2_3") tdSql.query("describe stb2_3")
...@@ -490,7 +491,7 @@ class TDTestCase: ...@@ -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)) print("schemaless_insert result {}".format(code))
tdSql.query("describe stb2_4") tdSql.query("describe stb2_4")
...@@ -515,7 +516,7 @@ class TDTestCase: ...@@ -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)) print("schemaless_insert result {}".format(code))
tdSql.query("describe stb2_5") tdSql.query("describe stb2_5")
...@@ -540,7 +541,7 @@ class TDTestCase: ...@@ -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)) print("schemaless_insert result {}".format(code))
tdSql.query("describe stb2_6") tdSql.query("describe stb2_6")
...@@ -565,7 +566,7 @@ class TDTestCase: ...@@ -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)) print("schemaless_insert result {}".format(code))
tdSql.query("describe stb2_7") tdSql.query("describe stb2_7")
...@@ -590,7 +591,7 @@ class TDTestCase: ...@@ -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)) print("schemaless_insert result {}".format(code))
tdSql.query("describe stb2_8") tdSql.query("describe stb2_8")
...@@ -649,7 +650,7 @@ class TDTestCase: ...@@ -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)) print("schemaless_insert result {}".format(code))
tdSql.query("describe stb3_0") tdSql.query("describe stb3_0")
...@@ -663,6 +664,183 @@ class TDTestCase: ...@@ -663,6 +664,183 @@ class TDTestCase:
tdSql.checkData(9, 1, "BINARY") tdSql.checkData(9, 1, "BINARY")
tdSql.checkData(10, 1, "NCHAR") 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): def stop(self):
tdSql.close() tdSql.close()
......
...@@ -15,7 +15,7 @@ import sys ...@@ -15,7 +15,7 @@ import sys
from util.log import * from util.log import *
from util.cases import * from util.cases import *
from util.sql import * from util.sql import *
from util.types import TDSmlProtocolType, TDSmlTimestampType
class TDTestCase: class TDTestCase:
def init(self, conn, logSql): def init(self, conn, logSql):
...@@ -35,10 +35,10 @@ class TDTestCase: ...@@ -35,10 +35,10 @@ class TDTestCase:
"stb0_0 1626006833639000000ns 4i8 host=\"host0\" interface=\"eth0\"", "stb0_0 1626006833639000000ns 4i8 host=\"host0\" interface=\"eth0\"",
"stb0_1 1626006833639000000ns 4i8 host=\"host0\" interface=\"eth0\"", "stb0_1 1626006833639000000ns 4i8 host=\"host0\" interface=\"eth0\"",
"stb0_2 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)) print("schemaless_insert result {}".format(code))
tdSql.query("show stables") tdSql.query("show stables")
...@@ -59,30 +59,26 @@ class TDTestCase: ...@@ -59,30 +59,26 @@ class TDTestCase:
### timestamp ### ### timestamp ###
print("============= step2 : test timestamp ================") print("============= step2 : test timestamp ================")
lines1 = [ lines1 = [
"stb1 1626006833s 1i8 host=\"host0\"", "stb1 1626006833641 1i8 host=\"host0\"",
"stb1 1626006833639000000ns 2i8 host=\"host0\"", "stb1 1626006834 2i8 host=\"host0\"",
"stb1 1626006833640000us 3i8 host=\"host0\"", "stb1 0 3i8 host=\"host0\"",
"stb1 1626006833641 4i8 host=\"host0\"",
"stb1 1626006834 5i8 host=\"host0\"",
"stb1 1626006833651ms 6i8 host=\"host0\"",
"stb1 0 7i8 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)) print("schemaless_insert result {}".format(code))
tdSql.query("select * from stb1") tdSql.query("select * from stb1")
tdSql.checkRows(7) tdSql.checkRows(3)
### metric value ### ### metric value ###
print("============= step3 : test metric value ================") print("============= step3 : test metric value ================")
#tinyint #tinyint
lines2_0 = [ lines2_0 = [
"stb2_0 1626006833651ms -127i8 host=\"host0\"", "stb2_0 1626006833651 -127i8 host=\"host0\"",
"stb2_0 1626006833652ms 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)) print("schemaless_insert result {}".format(code))
tdSql.query("select * from stb2_0") tdSql.query("select * from stb2_0")
...@@ -94,10 +90,10 @@ class TDTestCase: ...@@ -94,10 +90,10 @@ class TDTestCase:
#smallint #smallint
lines2_1 = [ lines2_1 = [
"stb2_1 1626006833651ms -32767i16 host=\"host0\"", "stb2_1 1626006833651 -32767i16 host=\"host0\"",
"stb2_1 1626006833652ms 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)) print("schemaless_insert result {}".format(code))
tdSql.query("select * from stb2_1") tdSql.query("select * from stb2_1")
...@@ -109,11 +105,11 @@ class TDTestCase: ...@@ -109,11 +105,11 @@ class TDTestCase:
#int #int
lines2_2 = [ lines2_2 = [
"stb2_2 1626006833651ms -2147483647i32 host=\"host0\"", "stb2_2 1626006833651 -2147483647i32 host=\"host0\"",
"stb2_2 1626006833652ms 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)) print("schemaless_insert result {}".format(code))
tdSql.query("select * from stb2_2") tdSql.query("select * from stb2_2")
...@@ -125,11 +121,11 @@ class TDTestCase: ...@@ -125,11 +121,11 @@ class TDTestCase:
#bigint #bigint
lines2_3 = [ lines2_3 = [
"stb2_3 1626006833651ms -9223372036854775807i64 host=\"host0\"", "stb2_3 1626006833651 -9223372036854775807i64 host=\"host0\"",
"stb2_3 1626006833652ms 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)) print("schemaless_insert result {}".format(code))
tdSql.query("select * from stb2_3") tdSql.query("select * from stb2_3")
...@@ -141,19 +137,19 @@ class TDTestCase: ...@@ -141,19 +137,19 @@ class TDTestCase:
#float #float
lines2_4 = [ lines2_4 = [
"stb2_4 1626006833610ms 3f32 host=\"host0\"", "stb2_4 1626006833610 3f32 host=\"host0\"",
"stb2_4 1626006833620ms -3f32 host=\"host0\"", "stb2_4 1626006833620 -3f32 host=\"host0\"",
"stb2_4 1626006833630ms 3.4f32 host=\"host0\"", "stb2_4 1626006833630 3.4f32 host=\"host0\"",
"stb2_4 1626006833640ms -3.4f32 host=\"host0\"", "stb2_4 1626006833640 -3.4f32 host=\"host0\"",
"stb2_4 1626006833650ms 3.4E10f32 host=\"host0\"", "stb2_4 1626006833650 3.4E10f32 host=\"host0\"",
"stb2_4 1626006833660ms -3.4e10f32 host=\"host0\"", "stb2_4 1626006833660 -3.4e10f32 host=\"host0\"",
"stb2_4 1626006833670ms 3.4E+2f32 host=\"host0\"", "stb2_4 1626006833670 3.4E+2f32 host=\"host0\"",
"stb2_4 1626006833680ms -3.4e-2f32 host=\"host0\"", "stb2_4 1626006833680 -3.4e-2f32 host=\"host0\"",
"stb2_4 1626006833700ms 3.4E38f32 host=\"host0\"", "stb2_4 1626006833700 3.4E38f32 host=\"host0\"",
"stb2_4 1626006833710ms -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)) print("schemaless_insert result {}".format(code))
tdSql.query("select * from stb2_4") tdSql.query("select * from stb2_4")
...@@ -165,20 +161,20 @@ class TDTestCase: ...@@ -165,20 +161,20 @@ class TDTestCase:
#double #double
lines2_5 = [ lines2_5 = [
"stb2_5 1626006833610ms 3f64 host=\"host0\"", "stb2_5 1626006833610 3f64 host=\"host0\"",
"stb2_5 1626006833620ms -3f64 host=\"host0\"", "stb2_5 1626006833620 -3f64 host=\"host0\"",
"stb2_5 1626006833630ms 3.4f64 host=\"host0\"", "stb2_5 1626006833630 3.4f64 host=\"host0\"",
"stb2_5 1626006833640ms -3.4f64 host=\"host0\"", "stb2_5 1626006833640 -3.4f64 host=\"host0\"",
"stb2_5 1626006833650ms 3.4E10f64 host=\"host0\"", "stb2_5 1626006833650 3.4E10f64 host=\"host0\"",
"stb2_5 1626006833660ms -3.4e10f64 host=\"host0\"", "stb2_5 1626006833660 -3.4e10f64 host=\"host0\"",
"stb2_5 1626006833670ms 3.4E+2f64 host=\"host0\"", "stb2_5 1626006833670 3.4E+2f64 host=\"host0\"",
"stb2_5 1626006833680ms -3.4e-2f64 host=\"host0\"", "stb2_5 1626006833680 -3.4e-2f64 host=\"host0\"",
"stb2_5 1626006833690ms 1.7E308f64 host=\"host0\"", "stb2_5 1626006833690 1.7E308f64 host=\"host0\"",
"stb2_5 1626006833700ms -1.7E308f64 host=\"host0\"", "stb2_5 1626006833700 -1.7E308f64 host=\"host0\"",
"stb2_5 1626006833710ms 3 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)) print("schemaless_insert result {}".format(code))
tdSql.query("select * from stb2_5") tdSql.query("select * from stb2_5")
...@@ -190,19 +186,19 @@ class TDTestCase: ...@@ -190,19 +186,19 @@ class TDTestCase:
#bool #bool
lines2_6 = [ lines2_6 = [
"stb2_6 1626006833610ms t host=\"host0\"", "stb2_6 1626006833610 t host=\"host0\"",
"stb2_6 1626006833620ms T host=\"host0\"", "stb2_6 1626006833620 T host=\"host0\"",
"stb2_6 1626006833630ms true host=\"host0\"", "stb2_6 1626006833630 true host=\"host0\"",
"stb2_6 1626006833640ms True host=\"host0\"", "stb2_6 1626006833640 True host=\"host0\"",
"stb2_6 1626006833650ms TRUE host=\"host0\"", "stb2_6 1626006833650 TRUE host=\"host0\"",
"stb2_6 1626006833660ms f host=\"host0\"", "stb2_6 1626006833660 f host=\"host0\"",
"stb2_6 1626006833670ms F host=\"host0\"", "stb2_6 1626006833670 F host=\"host0\"",
"stb2_6 1626006833680ms false host=\"host0\"", "stb2_6 1626006833680 false host=\"host0\"",
"stb2_6 1626006833690ms False host=\"host0\"", "stb2_6 1626006833690 False host=\"host0\"",
"stb2_6 1626006833700ms 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)) print("schemaless_insert result {}".format(code))
tdSql.query("select * from stb2_6") tdSql.query("select * from stb2_6")
...@@ -214,12 +210,12 @@ class TDTestCase: ...@@ -214,12 +210,12 @@ class TDTestCase:
#binary #binary
lines2_7 = [ lines2_7 = [
"stb2_7 1626006833610ms \" binary_val .!@#$%^&* \" host=\"host0\"", "stb2_7 1626006833610 \" binary_val .!@#$%^&* \" host=\"host0\"",
"stb2_7 1626006833620ms \"binary_val.:;,./?|+-=\" host=\"host0\"", "stb2_7 1626006833620 \"binary_val.:;,./?|+-=\" host=\"host0\"",
"stb2_7 1626006833630ms \"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)) print("schemaless_insert result {}".format(code))
tdSql.query("select * from stb2_7") tdSql.query("select * from stb2_7")
...@@ -231,11 +227,11 @@ class TDTestCase: ...@@ -231,11 +227,11 @@ class TDTestCase:
#nchar #nchar
lines2_8 = [ lines2_8 = [
"stb2_8 1626006833610ms L\" nchar_val 数值一 \" host=\"host0\"", "stb2_8 1626006833610 L\" nchar_val 数值一 \" host=\"host0\"",
"stb2_8 1626006833620ms 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)) print("schemaless_insert result {}".format(code))
tdSql.query("select * from stb2_8") tdSql.query("select * from stb2_8")
...@@ -249,11 +245,11 @@ class TDTestCase: ...@@ -249,11 +245,11 @@ class TDTestCase:
print("============= step3 : test tags ================") print("============= step3 : test tags ================")
#tag value types #tag value types
lines3_0 = [ 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 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 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 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)) print("schemaless_insert result {}".format(code))
tdSql.query("select * from stb3_0") tdSql.query("select * from stb3_0")
...@@ -292,12 +288,12 @@ class TDTestCase: ...@@ -292,12 +288,12 @@ class TDTestCase:
#tag ID as child table name #tag ID as child table name
lines3_1 = [ lines3_1 = [
"stb3_1 1626006833610ms 1 id=child_table1 host=host1", "stb3_1 1626006833610 1 id=child_table1 host=host1",
"stb3_1 1626006833610ms 2 host=host2 iD=child_table2", "stb3_1 1626006833610 2 host=host2 iD=child_table2",
"stb3_1 1626006833610ms 3 ID=child_table3 host=host3" "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)) print("schemaless_insert result {}".format(code))
tdSql.query("select * from stb3_1") tdSql.query("select * from stb3_1")
...@@ -308,6 +304,56 @@ class TDTestCase: ...@@ -308,6 +304,56 @@ class TDTestCase:
tdSql.checkData(0, 0, "child_table1") 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): def stop(self):
tdSql.close() tdSql.close()
tdLog.success("%s successfully executed" % __file__) tdLog.success("%s successfully executed" % __file__)
......
...@@ -15,13 +15,14 @@ import sys ...@@ -15,13 +15,14 @@ import sys
from util.log import * from util.log import *
from util.cases import * from util.cases import *
from util.sql import * from util.sql import *
from util.types import TDSmlProtocolType, TDSmlTimestampType
class TDTestCase: class TDTestCase:
def init(self, conn, logSql): def init(self, conn, logSql):
tdLog.debug("start to execute %s" % __file__) tdLog.debug("start to execute %s" % __file__)
tdSql.init(conn.cursor(), logSql) tdSql.init(conn.cursor(), logSql)
self._conn = conn self._conn = conn
def run(self): def run(self):
print("running {}".format(__file__)) print("running {}".format(__file__))
...@@ -42,17 +43,17 @@ class TDTestCase: ...@@ -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" "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)) print("schemaless_insert result {}".format(code))
lines2 = [ "stg,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000", 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" "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)) 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)) print("schemaless_insert result {}".format(code))
tdSql.query("select * from st") tdSql.query("select * from st")
...@@ -76,7 +77,7 @@ class TDTestCase: ...@@ -76,7 +77,7 @@ class TDTestCase:
self._conn.schemaless_insert([ 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,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" "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.execute('reset query cache')
tdSql.query('select tbname, * from sth') tdSql.query('select tbname, * from sth')
...@@ -84,6 +85,53 @@ class TDTestCase: ...@@ -84,6 +85,53 @@ class TDTestCase:
tdSql.query('select tbname, * from childtable') tdSql.query('select tbname, * from childtable')
tdSql.checkRows(1) 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): def stop(self):
tdSql.close() tdSql.close()
tdLog.success("%s successfully executed" % __file__) tdLog.success("%s successfully executed" % __file__)
......
...@@ -210,10 +210,10 @@ class TDTestCase: ...@@ -210,10 +210,10 @@ class TDTestCase:
tdSql.query("select max(id) + 5 from tb1") 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 st")
tdSql.query("select max(id) + avg(val) from tb1") tdSql.query("select max(id) + avg(val) from tb1")
tdSql.error("select abs_max(number) + 5 from st") tdSql.query("select abs_max(number) + 5 from st")
tdSql.error("select abs_max(number) + 5 from tb1") 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) + 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 =======") tdLog.info("======= UDF Nested query test =======")
tdSql.query("select sum(id) from (select id from st)") tdSql.query("select sum(id) from (select id from st)")
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
"cache": 50, "cache": 50,
"blocks": 8, "blocks": 8,
"precision": "ms", "precision": "ms",
"keep": 365, "keep": 36500,
"minRows": 100, "minRows": 100,
"maxRows": 4096, "maxRows": 4096,
"comp":2, "comp":2,
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
"name": "stb0", "name": "stb0",
"child_table_exists":"no", "child_table_exists":"no",
"childtable_count": 60, "childtable_count": 60,
"childtable_prefix": "stb00_", "childtable_prefix": "stb00_",
"auto_create_table": "no", "auto_create_table": "no",
"batch_create_tbl_num": 20, "batch_create_tbl_num": 20,
"data_source": "rand", "data_source": "rand",
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
"cache": 50, "cache": 50,
"blocks": 8, "blocks": 8,
"precision": "ms", "precision": "ms",
"keep": 36, "keep": 36500,
"minRows": 100, "minRows": 100,
"maxRows": 4096, "maxRows": 4096,
"comp":2, "comp":2,
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
"cache": 50, "cache": 50,
"blocks": 8, "blocks": 8,
"precision": "ns", "precision": "ns",
"keep": 36, "keep": 36500,
"minRows": 100, "minRows": 100,
"maxRows": 4096, "maxRows": 4096,
"comp":2, "comp":2,
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
"cache": 50, "cache": 50,
"blocks": 8, "blocks": 8,
"precision": "us", "precision": "us",
"keep": 36, "keep": 36500,
"minRows": 100, "minRows": 100,
"maxRows": 4096, "maxRows": 4096,
"comp":2, "comp":2,
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
"cache": 50, "cache": 50,
"blocks": 8, "blocks": 8,
"precision": "ns", "precision": "ns",
"keep": 36, "keep": 36500,
"minRows": 100, "minRows": 100,
"maxRows": 4096, "maxRows": 4096,
"comp":2, "comp":2,
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
"cache": 50, "cache": 50,
"blocks": 8, "blocks": 8,
"precision": "ns", "precision": "ns",
"keep": 36, "keep": 36500,
"minRows": 100, "minRows": 100,
"maxRows": 4096, "maxRows": 4096,
"comp":2, "comp":2,
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册