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

Merge branch 'develop' of github.com:taosdata/TDengine into develop

......@@ -8,6 +8,7 @@ def skipbuild = 0
def win_stop = 0
def scope = []
def mod = [0,1,2,3,4]
def sim_mod = [0,1,2,3]
def abortPreviousBuilds() {
def currentJobName = env.JOB_NAME
......@@ -45,6 +46,7 @@ def pre_test(){
killall -9 gdb || echo "no gdb running"
killall -9 python3.8 || echo "no python program running"
cd ${WKC}
[ -f src/connector/grafanaplugin/README.md ] && rm -f src/connector/grafanaplugin/README.md > /dev/null || echo "failed to remove grafanaplugin README.md"
git reset --hard HEAD~10 >/dev/null
'''
script {
......@@ -120,6 +122,7 @@ def pre_test_noinstall(){
sh'hostname'
sh'''
cd ${WKC}
[ -f src/connector/grafanaplugin/README.md ] && rm -f src/connector/grafanaplugin/README.md > /dev/null || echo "failed to remove grafanaplugin README.md"
git reset --hard HEAD~10 >/dev/null
'''
script {
......@@ -192,6 +195,7 @@ def pre_test_mac(){
sh'hostname'
sh'''
cd ${WKC}
[ -f src/connector/grafanaplugin/README.md ] && rm -f src/connector/grafanaplugin/README.md > /dev/null || echo "failed to remove grafanaplugin README.md"
git reset --hard HEAD~10 >/dev/null
'''
script {
......@@ -377,12 +381,14 @@ pipeline {
println gitlog
if (!(gitlog =~ /\((.*?)\)/)){
autoCancelled = true
error('Aborting the build.')
error('Please fill in the scope information correctly.\neg. [TD-xxxx]<fix>(query,insert):xxxxxxxxxxxxxxxxxx ')
}
temp = (gitlog =~ /\((.*?)\)/)
temp = temp[0].remove(1)
scope = temp.split(",")
scope = ['connector','query','insert','other','tools','taosAdapter']
Collections.shuffle mod
Collections.shuffle sim_mod
}
}
......@@ -400,7 +406,7 @@ pipeline {
}
parallel {
stage('python_1') {
agent{label " slave1 || slave6 || slave11 || slave16 "}
agent{label " slave1 || slave11 "}
steps {
pre_test()
timeout(time: 100, unit: 'MINUTES'){
......@@ -417,7 +423,7 @@ pipeline {
}
}
stage('python_2') {
agent{label " slave2 || slave7 || slave12 || slave17 "}
agent{label " slave2 || slave12 "}
steps {
pre_test()
timeout(time: 100, unit: 'MINUTES'){
......@@ -434,7 +440,7 @@ pipeline {
}
}
stage('python_3') {
agent{label " slave3 || slave8 || slave13 ||slave18 "}
agent{label " slave3 || slave13 "}
steps {
timeout(time: 105, unit: 'MINUTES'){
pre_test()
......@@ -451,7 +457,7 @@ pipeline {
}
}
stage('python_4') {
agent{label " slave4 || slave9 || slave14 || slave19 "}
agent{label " slave4 || slave14 "}
steps {
timeout(time: 100, unit: 'MINUTES'){
pre_test()
......@@ -469,7 +475,7 @@ pipeline {
}
}
stage('python_5') {
agent{label " slave5 || slave10 || slave15 || slave20 "}
agent{label " slave5 || slave15 "}
steps {
timeout(time: 100, unit: 'MINUTES'){
pre_test()
......@@ -486,35 +492,98 @@ pipeline {
}
}
}
stage('arm64centos7') {
agent{label " arm64centos7 "}
stage('sim_1') {
agent{label " slave6 || slave16 "}
steps {
pre_test_noinstall()
}
pre_test()
timeout(time: 100, unit: 'MINUTES'){
sh """
date
cd ${WKC}/tests
./test-CI.sh sim 4 ${sim_mod[0]}
date"""
}
}
}
stage('arm64centos8') {
agent{label " arm64centos8 "}
stage('sim_2') {
agent{label " slave7 || slave17 "}
steps {
pre_test_noinstall()
pre_test()
timeout(time: 100, unit: 'MINUTES'){
sh """
date
cd ${WKC}/tests
./test-CI.sh sim 4 ${sim_mod[1]}
date"""
}
}
}
stage('arm32bionic') {
agent{label " arm32bionic "}
stage('sim_3') {
agent{label " slave8 || slave18 "}
steps {
pre_test_noinstall()
timeout(time: 105, unit: 'MINUTES'){
pre_test()
sh """
date
cd ${WKC}/tests
./test-CI.sh sim 4 ${sim_mod[2]}
date"""
}
}
}
stage('arm64bionic') {
agent{label " arm64bionic "}
stage('sim_4') {
agent{label " slave9 || slave19 "}
steps {
pre_test_noinstall()
timeout(time: 100, unit: 'MINUTES'){
pre_test()
sh """
date
cd ${WKC}/tests
./test-CI.sh sim 4 ${sim_mod[3]}
date"""
}
}
}
stage('arm64focal') {
agent{label " arm64focal "}
stage('other') {
agent{label " slave10 || slave20 "}
steps {
pre_test_noinstall()
timeout(time: 100, unit: 'MINUTES'){
pre_test()
timeout(time: 60, unit: 'MINUTES'){
sh '''
cd ${WKC}/tests/pytest
./crash_gen.sh -a -p -t 4 -s 2000
'''
}
timeout(time: 60, unit: 'MINUTES'){
sh '''
cd ${WKC}/tests/pytest
rm -rf /var/lib/taos/*
rm -rf /var/log/taos/*
./handle_crash_gen_val_log.sh
'''
sh '''
cd ${WKC}/tests/pytest
rm -rf /var/lib/taos/*
rm -rf /var/log/taos/*
./handle_taosd_val_log.sh
'''
}
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
sh '''
cd ${WKC}/tests/pytest
./valgrind-test.sh 2>&1 > mem-error-out.log
./handle_val_log.sh
'''
}
sh '''
cd ${WKC}/tests
./test-all.sh full unit
date
'''
}
}
}
stage('centos7') {
agent{label " centos7 "}
......@@ -546,12 +615,41 @@ pipeline {
pre_test_mac()
}
}
stage('arm64centos7') {
agent{label " arm64centos7 "}
steps {
pre_test_noinstall()
}
}
stage('arm64centos8') {
agent{label " arm64centos8 "}
steps {
pre_test_noinstall()
}
}
stage('arm32bionic') {
agent{label " arm32bionic "}
steps {
pre_test_noinstall()
}
}
stage('arm64bionic') {
agent{label " arm64bionic "}
steps {
pre_test_noinstall()
}
}
stage('arm64focal') {
agent{label " arm64focal "}
steps {
pre_test_noinstall()
}
}
stage('build'){
agent{label " wintest "}
steps {
pre_test()
script{
script{
while(win_stop == 0){
sleep(1)
}
......@@ -561,6 +659,7 @@ pipeline {
stage('test'){
agent{label "win"}
steps{
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
pre_test_win()
timeout(time: 20, unit: 'MINUTES'){
......@@ -569,7 +668,7 @@ pipeline {
.\\test-all.bat wintest
'''
}
}
}
script{
win_stop=1
}
......
......@@ -46,7 +46,7 @@ ELSEIF (TD_WINDOWS)
#INSTALL(TARGETS taos RUNTIME DESTINATION driver)
#INSTALL(TARGETS shell RUNTIME DESTINATION .)
IF (TD_MVN_INSTALLED)
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.36-dist.jar DESTINATION connector/jdbc)
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.37-dist.jar DESTINATION connector/jdbc)
ENDIF ()
ELSEIF (TD_DARWIN)
SET(TD_MAKE_INSTALL_SH "${TD_COMMUNITY_DIR}/packaging/tools/make_install.sh")
......
......@@ -83,10 +83,11 @@ TDengine是一个高效的存储、查询、分析时序大数据的平台,专
* [Windows客户端](https://www.taosdata.com/blog/2019/07/26/514.html):自行编译windows客户端,Windows环境的各种连接器都需要它
* [Rust Connector](/connector/rust): Rust语言下通过libtaos客户端或RESTful接口,连接TDengine服务器。
## [TDengine 组件与工具](/cn/documentation/)
## TDengine 组件与工具
* [taosAdapter 用户手册](/tools/adapter)
* [TDinsight 用户手册](/tools/insight)
* [taoTools 用户手册](/tools/taos-tools)
## [与其他工具的连接](/connections)
......
......@@ -20,7 +20,7 @@ INSERT INTO d1001 VALUES (1538548685000, 10.3, 219, 0.31) (1538548695000, 12.6,
详细的SQL INSERT语法规则请见 [TAOS SQL 的数据写入](https://www.taosdata.com/cn/documentation/taos-sql#insert) 章节。
**Tips:**
**Tips:**
- 要提高写入效率,需要批量写入。一批写入的记录条数越多,插入效率就越高。但一条记录不能超过16K,一条SQL语句总长度不能超过1M 。
- TDengine支持多线程同时写入,要进一步提高写入速度,一个客户端需要打开20个以上的线程同时写。但线程数达到一定数量后,无法再提高,甚至还会下降,因为线程频繁切换,带来额外开销。
......@@ -56,7 +56,7 @@ tag_set 中的所有的数据自动转化为 nchar 数据类型,并不需要
* 对空格、等号(=)、逗号(,)、双引号("),前面需要使用反斜杠(\)进行转义。(都指的是英文半角符号)
* 数值类型将通过后缀来区分数据类型:
| **序号** | **后缀** | **映射类型** | **大小(字节)** |
| **序号** | **后缀** | **映射类型** | **大小(字节)** |
| -- | ------- | ---------| ------ |
| 1 | 无或f64 | double | 8 |
| 2 | f32 | float | 4 |
......@@ -231,16 +231,16 @@ prometheus产生的数据格式如下:
```json
{
Timestamp: 1576466279341,
Value: 37.000000,
Value: 37.000000,
apiserver_request_latencies_bucket {
component="apiserver",
instance="192.168.99.116:8443",
job="kubernetes-apiservers",
le="125000",
resource="persistentvolumes",
component="apiserver",
instance="192.168.99.116:8443",
job="kubernetes-apiservers",
le="125000",
resource="persistentvolumes",
scope="cluster",
verb="LIST",
version="v1"
verb="LIST",
version="v1"
}
}
```
......@@ -251,6 +251,7 @@ select * from apiserver_request_latencies_bucket;
```
## <a class="anchor" id="telegraf"></a> Telegraf 直接写入(通过 taosAdapter)
安装 Telegraf 请参考[官方文档](https://portal.influxdata.com/downloads/)
TDengine 新版本(2.3.0.0+)包含一个 taosAdapter 独立程序,负责接收包括 Telegraf 的多种应用的数据写入。
......@@ -276,6 +277,7 @@ sudo systemctl start telegraf
taosAdapter 相关配置参数请参考 taosadapter --help 命令输出以及相关文档。
## <a class="anchor" id="collectd"></a> collectd 直接写入(通过 taosAdapter)
安装 collectd,请参考[官方文档](https://collectd.org/download.shtml)
TDengine 新版本(2.3.0.0+)包含一个 taosAdapter 独立程序,负责接收包括 collectd 的多种应用的数据写入。
......@@ -294,6 +296,7 @@ sudo systemctl start collectd
taosAdapter 相关配置参数请参考 taosadapter --help 命令输出以及相关文档。
## <a class="anchor" id="statsd"></a> StatsD 直接写入(通过 taosAdapter)
安装 StatsD
请参考[官方文档](https://github.com/statsd/statsd)
......@@ -316,6 +319,30 @@ port: 8125
taosAdapter 相关配置参数请参考 taosadapter --help 命令输出以及相关文档。
icinga2 可以收集监控和性能数据并写入 OpenTSDB,taosAdapter 可以支持接收 icinga2 的数据并写入到 TDengine 中。
## <a class="anchor" id="icinga2"></a> icinga2 直接写入(通过 taosAdapter)
* 参考链接 https://icinga.com/docs/icinga-2/latest/doc/14-features/#opentsdb-writer 使能 opentsdb-writer
* 使能 taosAdapter 配置项 opentsdb_telnet.enable
* 修改配置文件 /etc/icinga2/features-enabled/opentsdb.conf
```
object OpenTsdbWriter "opentsdb" {
host = "host to taosAdapter"
port = 6048
}
```
taosAdapter 相关配置参数请参考 taosadapter --help 命令输出以及相关文档。
## <a class="anchor" id="tcollector"></a> TCollector 直接写入(通过 taosAdapter)
TCollector 是一个在客户侧收集本地收集器并发送数据到 OpenTSDB 的进程,taosAdaapter 可以支持接收 TCollector 的数据并写入到 TDengine 中。
使能 taosAdapter 配置项 opentsdb_telnet.enable
修改 TCollector 配置文件,修改 OpenTSDB 宿主机地址为 taosAdapter 被部署的地址,并修改端口号为 taosAdapter 使用的端口(默认6049)。
taosAdapter 相关配置参数请参考 taosadapter --help 命令输出以及相关文档。
## <a class="anchor" id="taosadapter2-telegraf"></a> 使用 Bailongma 2.0 接入 Telegraf 数据写入
......
......@@ -53,6 +53,7 @@ TDengine 提供 3 个 UDF 的源代码示例,分别为:
* numOfOutput:输出数据的个数,对聚合函数来说只能是0或者1。
* buf:用于在 UDF 与引擎间的状态控制信息传递块。
其他典型场景,如协方差的计算,即可通过定义聚合UDF的方式实现。
### 其他 UDF 函数
......
......@@ -1350,18 +1350,18 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
```mysql
SELECT LAST_ROW(field_name) FROM { tb_name | stb_name };
```
功能说明:返回表/超级表的最后一条记录。
返回结果数据类型:同应用的字段。
应用字段:所有字段。
适用于:**表、超级表**。
限制:LAST_ROW() 不能与 INTERVAL 一起使用。
说明:在用于超级表时,时间戳完全一样且同为最大的数据行可能有多个,那么会从中随机返回一条,而并不保证多次运行所挑选的数据行必然一致。<br/>
<br/>示例:
功能说明:返回表/超级表的最后一条记录。
返回结果数据类型:同应用的字段。
应用字段:所有字段。
适用于:**表、超级表**。
限制:LAST_ROW() 不能与 INTERVAL 一起使用。
说明:在用于超级表时,时间戳完全一样且同为最大的数据行可能有多个,那么会从中随机返回一条,而并不保证多次运行所挑选的数据行必然一致。<br/>
<br/>示例:
```mysql
taos> SELECT LAST_ROW(current) FROM meters;
......@@ -1383,51 +1383,51 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
SELECT INTERP(field_name) FROM { tb_name | stb_name } [WHERE where_condition] [ RANGE(timestamp1,timestamp2) ] [EVERY(interval)] [FILL ({ VALUE | PREV | NULL | LINEAR | NEXT})];
```
功能说明:返回表/超级表的指定时间截面指定列的记录值(插值)。
功能说明:返回表/超级表的指定时间截面指定列的记录值(插值)。
返回结果数据类型:同字段类型。
返回结果数据类型:同字段类型。
应用字段:数值型字段。
应用字段:数值型字段。
适用于:**表、超级表、嵌套查询**。
适用于:**表、超级表、嵌套查询**。
说明:
1)INTERP用于在指定时间断面获取指定列的记录值,如果该时间断面不存在符合条件的行数据,那么会根据 FILL 参数的设定进行插值。
说明:
1)INTERP用于在指定时间断面获取指定列的记录值,如果该时间断面不存在符合条件的行数据,那么会根据 FILL 参数的设定进行插值。
2)INTERP的输入数据为指定列的数据,可以通过条件语句(where子句)来对原始列数据进行过滤,如果没有指定过滤条件则输入为全部数据。
2)INTERP的输入数据为指定列的数据,可以通过条件语句(where子句)来对原始列数据进行过滤,如果没有指定过滤条件则输入为全部数据。
3)INTERP的输出时间范围根据RANGE(timestamp1,timestamp2)字段来指定,需满足timestamp1<=timestamp2。其中timestamp1(必选值)为输出时间范围的起始值,即如果timestamp1时刻符合插值条件则timestamp1为输出的第一条记录,timestamp2(必选值)为输出时间范围的结束值,即输出的最后一条记录的timestamp不能大于timestamp2。如果没有指定RANGE,那么满足过滤条件的输入数据中第一条记录的timestamp即为timestamp1,最后一条记录的timestamp即为timestamp2,同样也满足timestamp1 <= timestamp2。
3)INTERP的输出时间范围根据RANGE(timestamp1,timestamp2)字段来指定,需满足timestamp1<=timestamp2。其中timestamp1(必选值)为输出时间范围的起始值,即如果timestamp1时刻符合插值条件则timestamp1为输出的第一条记录,timestamp2(必选值)为输出时间范围的结束值,即输出的最后一条记录的timestamp不能大于timestamp2。如果没有指定RANGE,那么满足过滤条件的输入数据中第一条记录的timestamp即为timestamp1,最后一条记录的timestamp即为timestamp2,同样也满足timestamp1 <= timestamp2。
4)INTERP根据EVERY字段来确定输出时间范围内的结果条数,即从timestamp1开始每隔固定长度的时间(EVERY值)进行插值。如果没有指定EVERY,则默认窗口大小为无穷大,即从timestamp1开始只有一个窗口。
4)INTERP根据EVERY字段来确定输出时间范围内的结果条数,即从timestamp1开始每隔固定长度的时间(EVERY值)进行插值。如果没有指定EVERY,则默认窗口大小为无穷大,即从timestamp1开始只有一个窗口。
5)INTERP根据FILL字段来决定在每个符合输出条件的时刻如何进行插值,如果没有FILL字段则默认不插值,即输出为原始记录值或不输出(原始记录不存在)。
5)INTERP根据FILL字段来决定在每个符合输出条件的时刻如何进行插值,如果没有FILL字段则默认不插值,即输出为原始记录值或不输出(原始记录不存在)。
6)INTERP只能在一个时间序列内进行插值,因此当作用于超级表时必须跟group by tbname一起使用,当作用嵌套查询外层时内层子查询不能含GROUP BY信息。
6)INTERP只能在一个时间序列内进行插值,因此当作用于超级表时必须跟group by tbname一起使用,当作用嵌套查询外层时内层子查询不能含GROUP BY信息。
7)INTERP的插值结果不受ORDER BY timestamp的影响,ORDER BY timestamp只影响输出结果的排序。
7)INTERP的插值结果不受ORDER BY timestamp的影响,ORDER BY timestamp只影响输出结果的排序。
SQL示例:
SQL示例:
1) 单点线性插值
```mysql
taos> SELECT INTERP(*) FROM t1 RANGE('2017-7-14 18:40:00','2017-7-14 18:40:00') FILL(LINEAR);
```
2) 在2017-07-14 18:00:00到2017-07-14 19:00:00间每隔5秒钟进行取值(不插值)
```mysql
taos> SELECT INTERP(*) FROM t1 RANGE('2017-7-14 18:00:00','2017-7-14 19:00:00') EVERY(5s);
```
3) 在2017-07-14 18:00:00到2017-07-14 19:00:00间每隔5秒钟进行线性插值
```mysql
taos> SELECT INTERP(*) FROM t1 RANGE('2017-7-14 18:00:00','2017-7-14 19:00:00') EVERY(5s) FILL(LINEAR);
```
4.在所有时间范围内每隔5秒钟进行向后插值
```mysql
taos> SELECT INTERP(*) FROM t1 EVERY(5s) FILL(NEXT);
```
5.根据2017-07-14 17:00:00到2017-07-14 20:00:00间的数据进行从2017-07-14 18:00:00到2017-07-14 19:00:00间每隔5秒钟进行线性插值
```mysql
taos> SELECT INTERP(*) FROM t1 where ts >= '2017-07-14 17:00:00' and ts <= '2017-07-14 20:00:00' RANGE('2017-7-14 18:00:00','2017-7-14 19:00:00') EVERY(5s) FILL(LINEAR);
```
1) 单点线性插值
```mysql
taos> SELECT INTERP(*) FROM t1 RANGE('2017-7-14 18:40:00','2017-7-14 18:40:00') FILL(LINEAR);
```
2) 在2017-07-14 18:00:00到2017-07-14 19:00:00间每隔5秒钟进行取值(不插值)
```mysql
taos> SELECT INTERP(*) FROM t1 RANGE('2017-7-14 18:00:00','2017-7-14 19:00:00') EVERY(5s);
```
3) 在2017-07-14 18:00:00到2017-07-14 19:00:00间每隔5秒钟进行线性插值
```mysql
taos> SELECT INTERP(*) FROM t1 RANGE('2017-7-14 18:00:00','2017-7-14 19:00:00') EVERY(5s) FILL(LINEAR);
```
4.在所有时间范围内每隔5秒钟进行向后插值
```mysql
taos> SELECT INTERP(*) FROM t1 EVERY(5s) FILL(NEXT);
```
5.根据2017-07-14 17:00:00到2017-07-14 20:00:00间的数据进行从2017-07-14 18:00:00到2017-07-14 19:00:00间每隔5秒钟进行线性插值
```mysql
taos> SELECT INTERP(*) FROM t1 where ts >= '2017-07-14 17:00:00' and ts <= '2017-07-14 20:00:00' RANGE('2017-7-14 18:00:00','2017-7-14 19:00:00') EVERY(5s) FILL(LINEAR);
```
- **INTERP [2.3.1之前的版本]**
......@@ -1436,15 +1436,15 @@ SQL示例:
SELECT INTERP(field_name) FROM { tb_name | stb_name } WHERE ts='timestamp' [FILL ({ VALUE | PREV | NULL | LINEAR | NEXT})];
```
功能说明:返回表/超级表的指定时间截面、指定字段的记录。
功能说明:返回表/超级表的指定时间截面、指定字段的记录。
返回结果数据类型:同字段类型。
返回结果数据类型:同字段类型。
应用字段:数值型字段。
应用字段:数值型字段。
适用于:**表、超级表**。
适用于:**表、超级表**。
说明:(从 2.0.15.0 版本开始新增此函数) <br/>1)INTERP 必须指定时间断面,如果该时间断面不存在直接对应的数据,那么会根据 FILL 参数的设定进行插值。此外,条件语句里面可附带筛选条件,例如标签、tbname。<br/>2)INTERP 查询要求查询的时间区间必须位于数据集合(表)的所有记录的时间范围之内。如果给定的时间戳位于时间范围之外,即使有插值指令,仍然不返回结果。<br/>3)单个 INTERP 函数查询只能够针对一个时间点进行查询,如果需要返回等时间间隔的断面数据,可以通过 INTERP 配合 EVERY 的方式来进行查询处理(而不是使用 INTERVAL),其含义是每隔固定长度的时间进行插值。<br/>
说明:(从 2.0.15.0 版本开始新增此函数) <br/>1)INTERP 必须指定时间断面,如果该时间断面不存在直接对应的数据,那么会根据 FILL 参数的设定进行插值。此外,条件语句里面可附带筛选条件,例如标签、tbname。<br/>2)INTERP 查询要求查询的时间区间必须位于数据集合(表)的所有记录的时间范围之内。如果给定的时间戳位于时间范围之外,即使有插值指令,仍然不返回结果。<br/>3)单个 INTERP 函数查询只能够针对一个时间点进行查询,如果需要返回等时间间隔的断面数据,可以通过 INTERP 配合 EVERY 的方式来进行查询处理(而不是使用 INTERVAL),其含义是每隔固定长度的时间进行插值。<br/>
示例:
```mysql
......@@ -1455,7 +1455,7 @@ SQL示例:
Query OK, 1 row(s) in set (0.002652s)
```
如果给定的时间戳无对应的数据,在不指定插值生成策略的情况下,不会返回结果,如果指定了插值策略,会根据插值策略返回结果。
如果给定的时间戳无对应的数据,在不指定插值生成策略的情况下,不会返回结果,如果指定了插值策略,会根据插值策略返回结果。
```mysql
taos> SELECT INTERP(*) FROM meters WHERE tbname IN ('d636') AND ts='2017-7-14 18:40:00.005';
......@@ -1468,7 +1468,7 @@ SQL示例:
Query OK, 1 row(s) in set (0.003056s)
```
如下所示代码表示在时间区间 `['2017-7-14 18:40:00', '2017-7-14 18:40:00.014']` 中每隔 5 毫秒 进行一次断面计算。
如下所示代码表示在时间区间 `['2017-7-14 18:40:00', '2017-7-14 18:40:00.014']` 中每隔 5 毫秒 进行一次断面计算。
```mysql
taos> SELECT INTERP(current) FROM d636 WHERE ts>='2017-7-14 18:40:00' AND ts<='2017-7-14 18:40:00.014' EVERY(5a);
......@@ -1577,8 +1577,6 @@ SQL示例:
支持 +、-、*、/ 运算,如 ceil(col1) + ceil(col2)。
只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
该函数可以应用在普通表和超级表上。
支持版本:指定计算算法的功能从 2.2.0.x 版本开始,2.2.0.0 之前的版本不支持指定使用算法的功能。
- **FLOOR**
```mysql
......@@ -1671,7 +1669,7 @@ SELECT COUNT(*), FIRST(ts), status FROM temp_tb_1 STATE_WINDOW(status)
```mysql
SELECT COUNT(*), FIRST(ts) FROM temp_tb_1 SESSION_WINDOW(ts, tol_val)
SELECT COUNT(*), FIRST(ts) FROM temp_tb_1 SESSION(ts, tol_val)
```
这种类型的查询语法如下:
......@@ -1853,3 +1851,24 @@ TDengine 中的表(列)名命名规则如下:
```mysql
select jtag->'key' from (select jtag from stable) where jtag->'key'>0
```
## 转义字符说明
- 转义字符表
| 字符序列 | **代表的字符** |
| :--------: | ------- |
| `\'` | 单引号' |
| `\"` | 双引号" |
| \n | 换行符 |
| \r | 回车符 |
| \t | tab符 |
| `\\` | 斜杠\ |
| `\%` | % 规则见下 |
| `\%` | _ 规则见下 |
- 转义字符使用规则
1. 标识符里有转义字符(数据库名、表名、列名)
1. 普通标识符: 直接提示错误的标识符,因为标识符规定必须是数字、字母和下划线,并且不能以数字开头。
2. 反引号``标识符: 保持原样,不转义
2. 数据里有转义字符
1. 遇到上面定义的转义字符会转义(%和_见下面说明),如果没有匹配的转义字符会忽略掉转义符\。
2. 对于%和_,因为在like里这两个字符是通配符,所以在模式匹配like里用`\%`%和`\_`表示字符里本身的%和_,如果在like模式匹配上下文之外使用`\%`或`\_`,则它们的计算结果为字符串`\%`和`\_`,而不是%和_。
\ No newline at end of file
......@@ -83,6 +83,7 @@ TDengine is a highly efficient platform to store, query, and analyze time-series
* [taosAdapter User Manual](/tools/adapter)
* [TDinsight User Manual](/tools/insight)
* [taos-tools User Manual](/tools/taos-tools)
## [Connections with Other Tools](/connections)
......
......@@ -8,14 +8,14 @@ The following article explains how to quickly build a single-node TDengine runti
The Docker tools themselves can be downloaded from [Docker official site](https://docs.docker.com/get-docker/).
After installation, you can check the Docker version in the command line terminal. If the version number is output properly, the Docker environment has been installed successfully.
After installation, you can check the Docker version in the command-line terminal. If the version number is output properly, the Docker environment has been installed successfully.
```bash
$ docker -v
Docker version 20.10.3, build 48d30b5
```
## Using Docker to run TDengine
## How to use Docker to run TDengine
### running TDengine server inside Docker
......@@ -215,7 +215,7 @@ column[0]:FLOAT column[1]:INT column[2]:FLOAT
Press enter key to continue or Ctrl-C to stop
```
After enter, this command will automatically create a super table meters under the database test, there are 10,000 tables under this super table, the table name is "d0" to "d9999", each table has 10,000 records, each record has four fields (ts, current, voltage, phase), the time stamp is from "2017-07-14 10:40:00 000" to "2017-07-14 10:40:09 999", each table has a tag location and groupId, groupId is set from 1 to 10 and location is set to "beijing" or "shanghai".
After enter, this command will automatically create a super table `meters` under the database test, there are 10,000 tables under this super table, the table name is "d0" to "d9999", each table has 10,000 records, each record has four fields (ts, current, voltage, phase), the time stamp is from "2017-07-14 10:40:00 000" to "2017-07-14 10:40:09 999", each table has a tag location and groupId, groupId is set from 1 to 10 and location is set to "beijing" or "shanghai".
It takes about a few minutes to execute this command and ends up inserting a total of 100 million records.
......
......@@ -2,7 +2,7 @@
TDengine supports multiple ways to write data, including SQL, Prometheus, Telegraf, collectd, StatsD, EMQ MQTT Broker, HiveMQ Broker, CSV file, etc. Kafka, OPC and other interfaces will be provided in the future. Data can be inserted in one single record or in batches, data from one or multiple data collection points can be inserted at the same time. TDengine supports multi-thread insertion, out-of-order data insertion, and also historical data insertion.
## <a class="anchor" id="sql"></a> Data Writing via SQL
## <a class="anchor" id="sql"></a> Data Writing via SQL
Applications insert data by executing SQL insert statements through C/C++, Java, Go, C#, Python, Node.js Connectors, and users can manually enter SQL insert statements to insert data through TAOS Shell. For example, the following insert writes a record to table d1001:
......@@ -119,16 +119,16 @@ The format of generated data by Prometheus is as follows:
```json
{
Timestamp: 1576466279341,
Value: 37.000000,
Value: 37.000000,
apiserver_request_latencies_bucket {
component="apiserver",
instance="192.168.99.116:8443",
job="kubernetes-apiservers",
le="125000",
component="apiserver",
instance="192.168.99.116:8443",
job="kubernetes-apiservers",
le="125000",
resource="persistentvolumes", s
cope="cluster",
verb="LIST",
version=“v1"
verb="LIST",
version=“v1"
}
}
```
......@@ -167,13 +167,13 @@ Now you can query the metrics data of Telegraf from TDengine.
Please find taosAdapter configuration and usage from `taosadapter --help` output.
## <a class="anchor" id="collectd"></a> collectd 直接写入(通过 taosAdapter)
## <a class="anchor" id="collectd"></a> Data Writing via collectd and taosAdapter
Please refer to [official document](https://collectd.org/download.shtml) for collectd installation.
TDengine version 2.3.0.0+ includes a stand-alone application taosAdapter in charge of receive data insertion from collectd.
Configuration:
Please add following words in /etc/collectd/collectd.conf. Please fill the value 'host' and 'port' with what the TDengine and taosAdapter using.
Please add following words in /etc/collectd/collectd.conf. Please fill the value 'host' and 'port' with what the TDengine and taosAdapter using.
```
LoadPlugin network
<Plugin network>
......@@ -186,12 +186,12 @@ sudo systemctl start collectd
```
Please find taosAdapter configuration and usage from `taosadapter --help` output.
## <a class="anchor" id="statsd"></a> StatsD 直接写入(通过 taosAdapter)
## <a class="anchor" id="statsd"></a> Data Writting via StatsD and taosAdapter
Please refer to [official document](https://github.com/statsd/statsd) for StatsD installation.
TDengine version 2.3.0.0+ includes a stand-alone application taosAdapter in charge of receive data insertion from StatsD.
Please add following words in the config.js file. Please fill the value to 'host' and 'port' with what the TDengine and taosAdapter using.
Please add following words in the config.js file. Please fill the value to 'host' and 'port' with what the TDengine and taosAdapter using.
```
add "./backends/repeater" to backends section.
add { host:'<TDengine server/cluster host>', port: <port for StatsD>} to repeater section.
......@@ -206,8 +206,30 @@ port: 8125
}
```
## <a class="anchor" id="cinga2"></a> Data Writting via icinga2 and taosAdapter
Use icinga2 to collect check result metrics and performance data
* Follow the doc to enable opentsdb-writer https://icinga.com/docs/icinga-2/latest/doc/14-features/#opentsdb-writer
* Enable taosAdapter configuration opentsdb_telnet.enable
* Modify the configuration file /etc/icinga2/features-enabled/opentsdb.conf
```
object OpenTsdbWriter "opentsdb" {
host = "host to taosAdapter"
port = 6048
}
```
Please find taosAdapter configuration and usage from `taosadapter --help` output.
## <a class="anchor" id="tcollector"></a> Data Writting via TCollector and taosAdapter
TCollector is a client-side process that gathers data from local collectors and pushes the data to OpenTSDB. You run it on all your hosts, and it does the work of sending each host’s data to the TSD (OpenTSDB backend process).
* Enable taosAdapter configuration opentsdb_telnet.enable
* Modify the TCollector configuration file, modify the OpenTSDB host to the host where taosAdapter is deployed, and modify the port to 6049
Please find taosAdapter configuration and usage from `taosadapter --help` output.
## <a class="anchor" id="taosadapter2-telegraf"></a> Insert data via Bailongma 2.0 and Telegraf
......
......@@ -1335,3 +1335,24 @@ Is not null supports all types of columns. Non-null expression is < > "" and onl
select jtag->'key' from (select jtag from stable) where jtag->'key'>0
```
## Escape character description
- Special Character Escape Sequences
| Escape Sequence | **Character Represented by Sequence** |
| :--------: | ------------------- |
| `\'` | A single quote (') character |
| `\"` | A double quote (") character |
| \n | A newline (linefeed) character |
| \r | A carriage return character |
| \t | A tab character |
| `\\` | A backslash (\) character |
| `\%` | A % character; see note following the table |
| `\_` | A _ character; see note following the table |
- Escape character usage rules
- The escape characters that in a identifier (database name, table name, column name)
1. Normal identifier: The wrong identifier is prompted directly, because the identifier must be numbers, letters and underscores, and cannot start with a number.
2. Backquote`` identifier: Keep it as it is.
- The escape characters that in a data
3. The escape character defined above will be escaped (% and _ see the description below). If there is no matching escape character, the escape character will be ignored.
4. The `\%` and `\_` sequences are used to search for literal instances of % and _ in pattern-matching contexts where they would otherwise be interpreted as wildcard characters.If you use `\%` or `\_` outside of pattern-matching contexts, they evaluate to the strings `\%` and `\_`, not to % and _.
\ No newline at end of file
......@@ -36,11 +36,11 @@ install_home_path="/usr/local/taos"
mkdir -p ${pkg_dir}${install_home_path}
mkdir -p ${pkg_dir}${install_home_path}/bin
mkdir -p ${pkg_dir}${install_home_path}/cfg
mkdir -p ${pkg_dir}${install_home_path}/connector
#mkdir -p ${pkg_dir}${install_home_path}/connector
mkdir -p ${pkg_dir}${install_home_path}/driver
mkdir -p ${pkg_dir}${install_home_path}/examples
mkdir -p ${pkg_dir}${install_home_path}/include
mkdir -p ${pkg_dir}${install_home_path}/init.d
#mkdir -p ${pkg_dir}${install_home_path}/init.d
mkdir -p ${pkg_dir}${install_home_path}/script
cp ${compile_dir}/../packaging/cfg/taos.cfg ${pkg_dir}${install_home_path}/cfg
......@@ -51,7 +51,7 @@ if [ -f "${compile_dir}/test/cfg/taosadapter.service" ]; then
cp ${compile_dir}/test/cfg/taosadapter.service ${pkg_dir}${install_home_path}/cfg || :
fi
cp ${compile_dir}/../packaging/deb/taosd ${pkg_dir}${install_home_path}/init.d
#cp ${compile_dir}/../packaging/deb/taosd ${pkg_dir}${install_home_path}/init.d
cp ${compile_dir}/../packaging/tools/post.sh ${pkg_dir}${install_home_path}/script
cp ${compile_dir}/../packaging/tools/preun.sh ${pkg_dir}${install_home_path}/script
cp ${compile_dir}/../packaging/tools/startPre.sh ${pkg_dir}${install_home_path}/bin
......@@ -70,10 +70,10 @@ cp ${compile_dir}/../src/inc/taos.h ${pkg_dir}${install_home_pat
cp ${compile_dir}/../src/inc/taosdef.h ${pkg_dir}${install_home_path}/include
cp ${compile_dir}/../src/inc/taoserror.h ${pkg_dir}${install_home_path}/include
cp -r ${top_dir}/tests/examples/* ${pkg_dir}${install_home_path}/examples
cp -r ${top_dir}/src/connector/python ${pkg_dir}${install_home_path}/connector
cp -r ${top_dir}/src/connector/go ${pkg_dir}${install_home_path}/connector
cp -r ${top_dir}/src/connector/nodejs ${pkg_dir}${install_home_path}/connector
cp ${compile_dir}/build/lib/taos-jdbcdriver*.* ${pkg_dir}${install_home_path}/connector ||:
#cp -r ${top_dir}/src/connector/python ${pkg_dir}${install_home_path}/connector
#cp -r ${top_dir}/src/connector/go ${pkg_dir}${install_home_path}/connector
#cp -r ${top_dir}/src/connector/nodejs ${pkg_dir}${install_home_path}/connector
#cp ${compile_dir}/build/lib/taos-jdbcdriver*.* ${pkg_dir}${install_home_path}/connector ||:
install_user_local_path="/usr/local"
......
......@@ -46,11 +46,11 @@ libfile="libtaos.so.%{_version}"
# create install path, and cp file
mkdir -p %{buildroot}%{homepath}/bin
mkdir -p %{buildroot}%{homepath}/cfg
mkdir -p %{buildroot}%{homepath}/connector
#mkdir -p %{buildroot}%{homepath}/connector
mkdir -p %{buildroot}%{homepath}/driver
mkdir -p %{buildroot}%{homepath}/examples
mkdir -p %{buildroot}%{homepath}/include
mkdir -p %{buildroot}%{homepath}/init.d
#mkdir -p %{buildroot}%{homepath}/init.d
mkdir -p %{buildroot}%{homepath}/script
cp %{_compiledir}/../packaging/cfg/taos.cfg %{buildroot}%{homepath}/cfg
......@@ -60,7 +60,7 @@ fi
if [ -f %{_compiledir}/test/cfg/taosadapter.service ]; then
cp %{_compiledir}/test/cfg/taosadapter.service %{buildroot}%{homepath}/cfg
fi
cp %{_compiledir}/../packaging/rpm/taosd %{buildroot}%{homepath}/init.d
#cp %{_compiledir}/../packaging/rpm/taosd %{buildroot}%{homepath}/init.d
cp %{_compiledir}/../packaging/tools/post.sh %{buildroot}%{homepath}/script
cp %{_compiledir}/../packaging/tools/preun.sh %{buildroot}%{homepath}/script
cp %{_compiledir}/../packaging/tools/startPre.sh %{buildroot}%{homepath}/bin
......@@ -75,10 +75,10 @@ cp %{_compiledir}/build/lib/${libfile} %{buildroot}%{homepath}/driv
cp %{_compiledir}/../src/inc/taos.h %{buildroot}%{homepath}/include
cp %{_compiledir}/../src/inc/taosdef.h %{buildroot}%{homepath}/include
cp %{_compiledir}/../src/inc/taoserror.h %{buildroot}%{homepath}/include
cp -r %{_compiledir}/../src/connector/python %{buildroot}%{homepath}/connector
cp -r %{_compiledir}/../src/connector/go %{buildroot}%{homepath}/connector
cp -r %{_compiledir}/../src/connector/nodejs %{buildroot}%{homepath}/connector
cp %{_compiledir}/build/lib/taos-jdbcdriver*.* %{buildroot}%{homepath}/connector ||:
#cp -r %{_compiledir}/../src/connector/python %{buildroot}%{homepath}/connector
#cp -r %{_compiledir}/../src/connector/go %{buildroot}%{homepath}/connector
#cp -r %{_compiledir}/../src/connector/nodejs %{buildroot}%{homepath}/connector
#cp %{_compiledir}/build/lib/taos-jdbcdriver*.* %{buildroot}%{homepath}/connector ||:
cp -r %{_compiledir}/../tests/examples/* %{buildroot}%{homepath}/examples
if [ -f %{_compiledir}/build/bin/jemalloc-config ]; then
......
......@@ -167,11 +167,11 @@ function install_main_path() {
${csudo}mkdir -p ${install_main_dir}
${csudo}mkdir -p ${install_main_dir}/cfg
${csudo}mkdir -p ${install_main_dir}/bin
${csudo}mkdir -p ${install_main_dir}/connector
# ${csudo}mkdir -p ${install_main_dir}/connector
${csudo}mkdir -p ${install_main_dir}/driver
${csudo}mkdir -p ${install_main_dir}/examples
${csudo}mkdir -p ${install_main_dir}/include
${csudo}mkdir -p ${install_main_dir}/init.d
# ${csudo}mkdir -p ${install_main_dir}/init.d
if [ "$verMode" == "cluster" ]; then
${csudo}mkdir -p ${nginx_dir}
fi
......@@ -199,7 +199,7 @@ function install_bin() {
[ -x ${install_main_dir}/bin/taos ] && ${csudo}ln -s ${install_main_dir}/bin/taos ${bin_link_dir}/taos || :
[ -x ${install_main_dir}/bin/taosd ] && ${csudo}ln -s ${install_main_dir}/bin/taosd ${bin_link_dir}/taosd || :
[ -x ${install_main_dir}/bin/taosadapter ] && ${csudo}ln -s ${install_main_dir}/bin/taosadapter ${bin_link_dir}/taosadapter || :
[ -x ${install_main_dir}/bin/taosdemo ] && ${csudo}ln -s ${install_main_dir}/bin/taosdemo ${bin_link_dir}/taosdemo || :
[ -x ${install_main_dir}/bin/taosBenchmark ] && ${csudo}ln -s ${install_main_dir}/bin/taosBenchmark ${bin_link_dir}/taosdemo || :
[ -x ${install_main_dir}/bin/taosdump ] && ${csudo}ln -s ${install_main_dir}/bin/taosdump ${bin_link_dir}/taosdump || :
[ -x ${install_main_dir}/bin/remove.sh ] && ${csudo}ln -s ${install_main_dir}/bin/remove.sh ${bin_link_dir}/rmtaos || :
[ -x ${install_main_dir}/bin/set_core.sh ] && ${csudo}ln -s ${install_main_dir}/bin/set_core.sh ${bin_link_dir}/set_core || :
......@@ -639,14 +639,14 @@ function install_service_on_sysvinit() {
# Install taosd service
if ((${os_type}==1)); then
${csudo}cp -f ${script_dir}/init.d/taosd.deb ${install_main_dir}/init.d/taosd
# ${csudo}cp -f ${script_dir}/init.d/taosd.deb ${install_main_dir}/init.d/taosd
${csudo}cp ${script_dir}/init.d/taosd.deb ${service_config_dir}/taosd && ${csudo}chmod a+x ${service_config_dir}/taosd
${csudo}cp -f ${script_dir}/init.d/tarbitratord.deb ${install_main_dir}/init.d/tarbitratord
# ${csudo}cp -f ${script_dir}/init.d/tarbitratord.deb ${install_main_dir}/init.d/tarbitratord
${csudo}cp ${script_dir}/init.d/tarbitratord.deb ${service_config_dir}/tarbitratord && ${csudo}chmod a+x ${service_config_dir}/tarbitratord
elif ((${os_type}==2)); then
${csudo}cp -f ${script_dir}/init.d/taosd.rpm ${install_main_dir}/init.d/taosd
# ${csudo}cp -f ${script_dir}/init.d/taosd.rpm ${install_main_dir}/init.d/taosd
${csudo}cp ${script_dir}/init.d/taosd.rpm ${service_config_dir}/taosd && ${csudo}chmod a+x ${service_config_dir}/taosd
${csudo}cp -f ${script_dir}/init.d/tarbitratord.rpm ${install_main_dir}/init.d/tarbitratord
# ${csudo}cp -f ${script_dir}/init.d/tarbitratord.rpm ${install_main_dir}/init.d/tarbitratord
${csudo}cp ${script_dir}/init.d/tarbitratord.rpm ${service_config_dir}/tarbitratord && ${csudo}chmod a+x ${service_config_dir}/tarbitratord
fi
......@@ -706,7 +706,7 @@ function install_service_on_systemd() {
${csudo}cp ${script_dir}/cfg/taosd.service \
${service_config_dir}/ || :
${csudo}systemctl daemon-reload
#taosd_service_config="${service_config_dir}/taosd.service"
#${csudo}bash -c "echo '[Unit]' >> ${taosd_service_config}"
#${csudo}bash -c "echo 'Description=TDengine server service' >> ${taosd_service_config}"
......@@ -736,7 +736,7 @@ function install_service_on_systemd() {
${csudo}cp ${script_dir}/cfg/tarbitratord.service \
${service_config_dir}/ || :
${csudo}systemctl daemon-reload
#tarbitratord_service_config="${service_config_dir}/tarbitratord.service"
#${csudo}bash -c "echo '[Unit]' >> ${tarbitratord_service_config}"
#${csudo}bash -c "echo 'Description=TDengine arbitrator service' >> ${tarbitratord_service_config}"
......@@ -923,15 +923,14 @@ function update_TDengine() {
install_log
install_header
install_lib
if [ "$pagMode" != "lite" ]; then
install_connector
fi
# if [ "$pagMode" != "lite" ]; then
# install_connector
# fi
install_examples
if [ -z $1 ]; then
install_bin
install_service
install_taosadapter_service
install_config
install_taosadapter_config
openresty_work=false
......@@ -1008,9 +1007,9 @@ function install_TDengine() {
#install_avro lib
#install_avro lib64
if [ "$pagMode" != "lite" ]; then
install_connector
fi
# if [ "$pagMode" != "lite" ]; then
# install_connector
# fi
install_examples
if [ -z $1 ]; then # install service and client
......@@ -1018,6 +1017,7 @@ function install_TDengine() {
install_bin
install_service
install_taosadapter_service
install_taosadapter_config
openresty_work=false
if [ "$verMode" == "cluster" ]; then
......
......@@ -137,17 +137,17 @@ function install_main_path() {
${csudo}mkdir -p ${install_main_dir}
${csudo}mkdir -p ${install_main_dir}/cfg
${csudo}mkdir -p ${install_main_dir}/bin
${csudo}mkdir -p ${install_main_dir}/connector
# ${csudo}mkdir -p ${install_main_dir}/connector
${csudo}mkdir -p ${install_main_dir}/driver
${csudo}mkdir -p ${install_main_dir}/examples
${csudo}mkdir -p ${install_main_dir}/include
${csudo}mkdir -p ${install_main_dir}/init.d
# ${csudo}mkdir -p ${install_main_dir}/init.d
else
${csudo}rm -rf ${install_main_dir} || ${csudo}rm -rf ${install_main_2_dir} || :
${csudo}mkdir -p ${install_main_dir} || ${csudo}mkdir -p ${install_main_2_dir}
${csudo}mkdir -p ${install_main_dir}/cfg || ${csudo}mkdir -p ${install_main_2_dir}/cfg
${csudo}mkdir -p ${install_main_dir}/bin || ${csudo}mkdir -p ${install_main_2_dir}/bin
${csudo}mkdir -p ${install_main_dir}/connector || ${csudo}mkdir -p ${install_main_2_dir}/connector
# ${csudo}mkdir -p ${install_main_dir}/connector || ${csudo}mkdir -p ${install_main_2_dir}/connector
${csudo}mkdir -p ${install_main_dir}/driver || ${csudo}mkdir -p ${install_main_2_dir}/driver
${csudo}mkdir -p ${install_main_dir}/examples || ${csudo}mkdir -p ${install_main_2_dir}/examples
${csudo}mkdir -p ${install_main_dir}/include || ${csudo}mkdir -p ${install_main_2_dir}/include
......@@ -168,9 +168,15 @@ function install_bin() {
${csudo}rm -f ${bin_link_dir}/run_taosd.sh || :
${csudo}rm -f ${bin_link_dir}/rmtaos || :
${csudo}cp -r ${binary_dir}/build/bin/* ${install_main_dir}/bin
${csudo}cp -r ${script_dir}/taosd-dump-cfg.gdb ${install_main_dir}/bin
${csudo}cp -r ${binary_dir}/build/bin/taos ${install_main_dir}/bin || :
[ -f ${binary_dir}/build/bin/taosBenchmark ] && ${csudo}cp -r ${binary_dir}/build/bin/taosBenchmark ${install_main_dir}/bin || :
[ -f ${install_main_dir}/bin/taosBenchmark ] && ${csudo}ln -sf ${install_main_dir}/bin/taosBenchmark ${install_main_dir}/bin/taosdemo || :
[ -f ${binary_dir}/build/bin/taosdump ] && ${csudo}cp -r ${binary_dir}/build/bin/taosdump ${install_main_dir}/bin || :
[ -f ${binary_dir}/build/bin/taosadapter ] && ${csudo}cp -r ${binary_dir}/build/bin/taosadapter ${install_main_dir}/bin || :
${csudo}cp -r ${binary_dir}/build/bin/taosd ${install_main_dir}/bin || :
${csudo}cp -r ${binary_dir}/build/bin/tarbitrator ${install_main_dir}/bin || :
${csudo}cp -r ${script_dir}/taosd-dump-cfg.gdb ${install_main_dir}/bin
${csudo}cp -r ${script_dir}/remove.sh ${install_main_dir}/bin
${csudo}cp -r ${script_dir}/set_core.sh ${install_main_dir}/bin
${csudo}cp -r ${script_dir}/run_taosd.sh ${install_main_dir}/bin
......@@ -458,10 +464,10 @@ function install_service_on_sysvinit() {
# Install taosd service
if ((${os_type}==1)); then
${csudo}cp -f ${script_dir}/../deb/taosd ${install_main_dir}/init.d
# ${csudo}cp -f ${script_dir}/../deb/taosd ${install_main_dir}/init.d
${csudo}cp ${script_dir}/../deb/taosd ${service_config_dir} && ${csudo}chmod a+x ${service_config_dir}/taosd
elif ((${os_type}==2)); then
${csudo}cp -f ${script_dir}/../rpm/taosd ${install_main_dir}/init.d
# ${csudo}cp -f ${script_dir}/../rpm/taosd ${install_main_dir}/init.d
${csudo}cp ${script_dir}/../rpm/taosd ${service_config_dir} && ${csudo}chmod a+x ${service_config_dir}/taosd
fi
......@@ -563,7 +569,7 @@ function update_TDengine() {
install_log
install_header
install_lib
install_connector
# install_connector
install_examples
install_bin
......@@ -603,7 +609,7 @@ function install_TDengine() {
install_log
install_header
install_lib
install_connector
# install_connector
install_examples
install_bin
......
......@@ -123,9 +123,9 @@ if [ -n "${taostools_bin_files}" ]; then
mkdir -p ${taostools_install_dir}/bin \
&& cp ${taostools_bin_files} ${taostools_install_dir}/bin \
&& chmod a+x ${taostools_install_dir}/bin/* || :
[ -f ${taostools_install_dir}/bin/taosBenchmark ] && \
ln -sf ${taostools_install_dir}/bin/taosBenchmark \
${taostools_install_dir}/bin/taosdemo
# [ -f ${taostools_install_dir}/bin/taosBenchmark ] && \
# ln -sf ${taostools_install_dir}/bin/taosBenchmark \
# ${taostools_install_dir}/bin/taosdemo
if [ -f ${top_dir}/src/kit/taos-tools/packaging/tools/install-taostools.sh ]; then
cp ${top_dir}/src/kit/taos-tools/packaging/tools/install-taostools.sh \
......@@ -248,18 +248,18 @@ fi
mkdir -p ${install_dir}/driver && cp ${lib_files} ${install_dir}/driver && echo "${versionComp}" > ${install_dir}/driver/vercomp.txt
# Copy connector
connector_dir="${code_dir}/connector"
mkdir -p ${install_dir}/connector
if [[ "$pagMode" != "lite" ]] && [[ "$cpuType" != "aarch32" ]]; then
cp ${build_dir}/lib/*.jar ${install_dir}/connector ||:
if find ${connector_dir}/go -mindepth 1 -maxdepth 1 | read; then
cp -r ${connector_dir}/go ${install_dir}/connector
else
echo "WARNING: go connector not found, please check if want to use it!"
fi
cp -r ${connector_dir}/python ${install_dir}/connector
cp -r ${connector_dir}/nodejs ${install_dir}/connector
fi
#connector_dir="${code_dir}/connector"
#mkdir -p ${install_dir}/connector
#if [[ "$pagMode" != "lite" ]] && [[ "$cpuType" != "aarch32" ]]; then
# cp ${build_dir}/lib/*.jar ${install_dir}/connector ||:
# if find ${connector_dir}/go -mindepth 1 -maxdepth 1 | read; then
# cp -r ${connector_dir}/go ${install_dir}/connector
# else
# echo "WARNING: go connector not found, please check if want to use it!"
# fi
# cp -r ${connector_dir}/python ${install_dir}/connector
# cp -r ${connector_dir}/nodejs ${install_dir}/connector
#fi
# Copy release note
# cp ${script_dir}/release_note ${install_dir}
......
......@@ -207,7 +207,7 @@ TAOS_FIELD* tscFieldInfoGetField(SFieldInfo* pFieldInfo, int32_t index);
void tscFieldInfoUpdateOffset(SQueryInfo* pQueryInfo);
int16_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index);
int32_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index);
void tscFieldInfoClear(SFieldInfo* pFieldInfo);
void tscFieldInfoCopy(SFieldInfo* pFieldInfo, const SFieldInfo* pSrc, const SArray* pExprList);
......@@ -258,8 +258,6 @@ void tscColumnListCopyAll(SArray* dst, const SArray* src);
void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo, uint64_t objId, bool convertNchar, bool convertJson);
void tscDequoteAndTrimToken(SStrToken* pToken);
void tscRmEscapeAndTrimToken(SStrToken* pToken);
int32_t tscValidateName(SStrToken* pToken, bool escapeEnabled, bool *dbIncluded);
void tscIncStreamExecutionCount(void* pStream);
......
......@@ -209,6 +209,15 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_prepareStmtImp
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setBindTableNameImp
(JNIEnv *, jobject, jlong, jstring, jlong);
/**
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: setTableNameTagsImp
* Signature: (JLjava/lang/String;I[B[B[B[BJ)I
*/
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setTableNameTagsImp
(JNIEnv *, jobject, jlong, jstring, jint, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jlong);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: bindColDataImp
......@@ -217,6 +226,14 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setBindTableNameI
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp
(JNIEnv *, jobject, jlong, jbyteArray, jbyteArray, jbyteArray, jint, jint, jint, jint, jlong);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: stmt_add_batch
* Signature: (JJ)I
*/
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_addBatchImp(JNIEnv *env, jobject jobj, jlong stmt, jlong con);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: executeBatchImp
......@@ -231,13 +248,12 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_executeBatchImp(J
*/
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_closeStmt(JNIEnv *env, jobject jobj, jlong stmt, jlong con);
/**
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: setTableNameTagsImp
* Signature: (JLjava/lang/String;I[B[B[B[BJ)I
* Method: stmt_errstr
* Signature: (JJ)I
*/
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setTableNameTagsImp
(JNIEnv *, jobject, jlong, jstring, jint, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jlong);
JNIEXPORT jstring JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_stmtErrorMsgImp(JNIEnv *env, jobject jobj, jlong stmt, jlong con);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
......
......@@ -805,6 +805,78 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setBindTableNameI
return JNI_SUCCESS;
}
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setTableNameTagsImp(
JNIEnv *env, jobject jobj, jlong stmt, jstring tableName, jint numOfTags, jbyteArray tags, jbyteArray typeList,
jbyteArray lengthList, jbyteArray nullList, jlong conn) {
TAOS *tsconn = (TAOS *)conn;
if (tsconn == NULL) {
jniError("jobj:%p, connection already closed", jobj);
return JNI_CONNECTION_NULL;
}
TAOS_STMT *pStmt = (TAOS_STMT *)stmt;
if (pStmt == NULL) {
jniError("jobj:%p, conn:%p, invalid stmt handle", jobj, tsconn);
return JNI_SQL_NULL;
}
jsize len = (*env)->GetArrayLength(env, tags);
char *tagsData = (char *)calloc(1, len);
(*env)->GetByteArrayRegion(env, tags, 0, len, (jbyte *)tagsData);
if ((*env)->ExceptionCheck(env)) {
// todo handle error
}
len = (*env)->GetArrayLength(env, lengthList);
int64_t *lengthArray = (int64_t *)calloc(1, len);
(*env)->GetByteArrayRegion(env, lengthList, 0, len, (jbyte *)lengthArray);
if ((*env)->ExceptionCheck(env)) {
}
len = (*env)->GetArrayLength(env, typeList);
char *typeArray = (char *)calloc(1, len);
(*env)->GetByteArrayRegion(env, typeList, 0, len, (jbyte *)typeArray);
if ((*env)->ExceptionCheck(env)) {
}
len = (*env)->GetArrayLength(env, nullList);
int32_t *nullArray = (int32_t *)calloc(1, len);
(*env)->GetByteArrayRegion(env, nullList, 0, len, (jbyte *)nullArray);
if ((*env)->ExceptionCheck(env)) {
}
const char *name = (*env)->GetStringUTFChars(env, tableName, NULL);
char *curTags = tagsData;
TAOS_BIND *tagsBind = calloc(numOfTags, sizeof(TAOS_BIND));
for (int32_t i = 0; i < numOfTags; ++i) {
tagsBind[i].buffer_type = typeArray[i];
tagsBind[i].buffer = curTags;
tagsBind[i].is_null = &nullArray[i];
tagsBind[i].length = (uintptr_t *)&lengthArray[i];
curTags += lengthArray[i];
}
int32_t code = taos_stmt_set_tbname_tags((void *)stmt, name, tagsBind);
int32_t nTags = (int32_t)numOfTags;
jniDebug("jobj:%p, conn:%p, set table name:%s, numOfTags:%d", jobj, tsconn, name, nTags);
tfree(tagsData);
tfree(lengthArray);
tfree(typeArray);
tfree(nullArray);
tfree(tagsBind);
(*env)->ReleaseStringUTFChars(env, tableName, name);
if (code != TSDB_CODE_SUCCESS) {
jniError("jobj:%p, conn:%p, code:%s", jobj, tsconn, tstrerror(code));
return JNI_TDENGINE_ERROR;
}
return JNI_SUCCESS;
}
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(
JNIEnv *env, jobject jobj, jlong stmt, jbyteArray colDataList, jbyteArray lengthList, jbyteArray nullList,
jint dataType, jint dataBytes, jint numOfRows, jint colIndex, jlong con) {
......@@ -872,8 +944,8 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(
return JNI_SUCCESS;
}
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_executeBatchImp(JNIEnv *env, jobject jobj, jlong stmt,
jlong con) {
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_addBatchImp(JNIEnv *env, jobject jobj, jlong stmt,
jlong con) {
TAOS *tscon = (TAOS *)con;
if (tscon == NULL) {
jniError("jobj:%p, connection already closed", jobj);
......@@ -886,19 +958,18 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_executeBatchImp(J
return JNI_SQL_NULL;
}
taos_stmt_add_batch(pStmt);
int32_t code = taos_stmt_execute(pStmt);
int32_t code = taos_stmt_add_batch(pStmt);
if (code != TSDB_CODE_SUCCESS) {
jniError("jobj:%p, conn:%p, code:%s", jobj, tscon, tstrerror(code));
return JNI_TDENGINE_ERROR;
}
jniDebug("jobj:%p, conn:%p, batch execute", jobj, tscon);
jniDebug("jobj:%p, conn:%p, stmt closed", jobj, tscon);
return JNI_SUCCESS;
}
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_closeStmt(JNIEnv *env, jobject jobj, jlong stmt,
jlong con) {
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_executeBatchImp(JNIEnv *env, jobject jobj, jlong stmt,
jlong con) {
TAOS *tscon = (TAOS *)con;
if (tscon == NULL) {
jniError("jobj:%p, connection already closed", jobj);
......@@ -911,91 +982,63 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_closeStmt(JNIEnv
return JNI_SQL_NULL;
}
int32_t code = taos_stmt_close(pStmt);
int32_t code = taos_stmt_execute(pStmt);
if (code != TSDB_CODE_SUCCESS) {
jniError("jobj:%p, conn:%p, code:%s", jobj, tscon, tstrerror(code));
return JNI_TDENGINE_ERROR;
}
jniDebug("jobj:%p, conn:%p, stmt closed", jobj, tscon);
jniDebug("jobj:%p, conn:%p, batch execute", jobj, tscon);
return JNI_SUCCESS;
}
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setTableNameTagsImp(
JNIEnv *env, jobject jobj, jlong stmt, jstring tableName, jint numOfTags, jbyteArray tags, jbyteArray typeList,
jbyteArray lengthList, jbyteArray nullList, jlong conn) {
TAOS *tsconn = (TAOS *)conn;
if (tsconn == NULL) {
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_closeStmt(JNIEnv *env, jobject jobj, jlong stmt,
jlong con) {
TAOS *tscon = (TAOS *)con;
if (tscon == NULL) {
jniError("jobj:%p, connection already closed", jobj);
return JNI_CONNECTION_NULL;
}
TAOS_STMT *pStmt = (TAOS_STMT *)stmt;
if (pStmt == NULL) {
jniError("jobj:%p, conn:%p, invalid stmt handle", jobj, tsconn);
jniError("jobj:%p, conn:%p, invalid stmt", jobj, tscon);
return JNI_SQL_NULL;
}
jsize len = (*env)->GetArrayLength(env, tags);
char *tagsData = (char *)calloc(1, len);
(*env)->GetByteArrayRegion(env, tags, 0, len, (jbyte *)tagsData);
if ((*env)->ExceptionCheck(env)) {
// todo handle error
}
len = (*env)->GetArrayLength(env, lengthList);
int64_t *lengthArray = (int64_t *)calloc(1, len);
(*env)->GetByteArrayRegion(env, lengthList, 0, len, (jbyte *)lengthArray);
if ((*env)->ExceptionCheck(env)) {
int32_t code = taos_stmt_close(pStmt);
if (code != TSDB_CODE_SUCCESS) {
jniError("jobj:%p, conn:%p, code:%s", jobj, tscon, tstrerror(code));
return JNI_TDENGINE_ERROR;
}
len = (*env)->GetArrayLength(env, typeList);
char *typeArray = (char *)calloc(1, len);
(*env)->GetByteArrayRegion(env, typeList, 0, len, (jbyte *)typeArray);
if ((*env)->ExceptionCheck(env)) {
}
jniDebug("jobj:%p, conn:%p, stmt closed", jobj, tscon);
return JNI_SUCCESS;
}
len = (*env)->GetArrayLength(env, nullList);
int32_t *nullArray = (int32_t *)calloc(1, len);
(*env)->GetByteArrayRegion(env, nullList, 0, len, (jbyte *)nullArray);
if ((*env)->ExceptionCheck(env)) {
JNIEXPORT jstring JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_stmtErrorMsgImp(JNIEnv *env, jobject jobj, jlong stmt,
jlong con) {
char errMsg[128];
TAOS *tscon = (TAOS *)con;
if (tscon == NULL) {
jniError("jobj:%p, connection already closed", jobj);
sprintf(errMsg, "jobj:%p, connection already closed", jobj);
return (*env)->NewStringUTF(env, errMsg);
}
const char *name = (*env)->GetStringUTFChars(env, tableName, NULL);
char *curTags = tagsData;
TAOS_BIND *tagsBind = calloc(numOfTags, sizeof(TAOS_BIND));
for (int32_t i = 0; i < numOfTags; ++i) {
tagsBind[i].buffer_type = typeArray[i];
tagsBind[i].buffer = curTags;
tagsBind[i].is_null = &nullArray[i];
tagsBind[i].length = (uintptr_t *)&lengthArray[i];
curTags += lengthArray[i];
TAOS_STMT *pStmt = (TAOS_STMT *)stmt;
if (pStmt == NULL) {
jniError("jobj:%p, conn:%p, invalid stmt", jobj, tscon);
sprintf(errMsg, "jobj:%p, conn:%p, invalid stmt", jobj, tscon);
return (*env)->NewStringUTF(env, errMsg);
}
int32_t code = taos_stmt_set_tbname_tags((void *)stmt, name, tagsBind);
int32_t nTags = (int32_t)numOfTags;
jniDebug("jobj:%p, conn:%p, set table name:%s, numOfTags:%d", jobj, tsconn, name, nTags);
tfree(tagsData);
tfree(lengthArray);
tfree(typeArray);
tfree(nullArray);
tfree(tagsBind);
(*env)->ReleaseStringUTFChars(env, tableName, name);
if (code != TSDB_CODE_SUCCESS) {
jniError("jobj:%p, conn:%p, code:%s", jobj, tsconn, tstrerror(code));
return JNI_TDENGINE_ERROR;
}
return JNI_SUCCESS;
return (*env)->NewStringUTF(env, taos_stmt_errstr((TAOS_STMT *)stmt));
}
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_insertLinesImp(JNIEnv *env, jobject jobj,
jobjectArray lines, jlong conn,
jint protocol, jint precision) {
jobjectArray lines, jlong conn,
jint protocol, jint precision) {
TAOS *taos = (TAOS *)conn;
if (taos == NULL) {
jniError("jobj:%p, connection already closed", jobj);
......@@ -1013,8 +1056,8 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_insertLinesImp(JN
c_lines[i] = (char *)(*env)->GetStringUTFChars(env, line, 0);
}
SSqlObj* result = (SSqlObj*)taos_schemaless_insert(taos, c_lines, numLines, protocol, precision);
int code = taos_errno(result);
SSqlObj *result = (SSqlObj *)taos_schemaless_insert(taos, c_lines, numLines, protocol, precision);
int code = taos_errno(result);
for (int i = 0; i < numLines; ++i) {
jstring line = (jstring)((*env)->GetObjectArrayElement(env, lines, i));
......
......@@ -52,3 +52,4 @@ taos_stmt_bind_single_param_batch
taos_is_null
taos_insert_lines
taos_schemaless_insert
taos_result_block
......@@ -902,7 +902,7 @@ SSDataBlock* doGlobalAggregate(void* param, bool* newgroup) {
// not belongs to the same group, return the result of current group;
setInputDataBlock(pOperator, pAggInfo->binfo.pCtx, pAggInfo->pExistBlock, TSDB_ORDER_ASC);
updateOutputBuf(&pAggInfo->binfo, &pAggInfo->bufCapacity, pAggInfo->pExistBlock->info.rows);
updateOutputBuf(&pAggInfo->binfo, &pAggInfo->bufCapacity, pAggInfo->pExistBlock->info.rows, pOperator->pRuntimeEnv);
{ // reset output buffer
for(int32_t j = 0; j < pOperator->numOfOutput; ++j) {
......@@ -954,7 +954,7 @@ SSDataBlock* doGlobalAggregate(void* param, bool* newgroup) {
// not belongs to the same group, return the result of current group
setInputDataBlock(pOperator, pAggInfo->binfo.pCtx, pBlock, TSDB_ORDER_ASC);
updateOutputBuf(&pAggInfo->binfo, &pAggInfo->bufCapacity, pBlock->info.rows * pAggInfo->resultRowFactor);
updateOutputBuf(&pAggInfo->binfo, &pAggInfo->bufCapacity, pBlock->info.rows * pAggInfo->resultRowFactor, pOperator->pRuntimeEnv);
doExecuteFinalMerge(pOperator, pOperator->numOfOutput, pBlock);
savePrevOrderColumns(pAggInfo->currentGroupColData, pAggInfo->groupColumnList, pBlock, 0, &pAggInfo->hasGroupColData);
......
......@@ -481,32 +481,12 @@ int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, int16_t timePrec, i
// Remove quotation marks
if (TK_STRING == sToken.type) {
// delete escape character: \\, \', \"
char delim = sToken.z[0];
int32_t cnt = 0;
int32_t j = 0;
if (sToken.n >= TSDB_MAX_BYTES_PER_ROW) {
return tscSQLSyntaxErrMsg(pInsertParam->msg, "too long string", sToken.z);
}
for (uint32_t k = 1; k < sToken.n - 1; ++k) {
if (sToken.z[k] == '\\' || (sToken.z[k] == delim && sToken.z[k + 1] == delim)) {
tmpTokenBuf[j] = sToken.z[k + 1];
cnt++;
j++;
k++;
continue;
}
tmpTokenBuf[j] = sToken.z[k];
j++;
}
tmpTokenBuf[j] = 0;
strncpy(tmpTokenBuf, sToken.z, sToken.n);
sToken.n = stringProcess(tmpTokenBuf, sToken.n);
sToken.z = tmpTokenBuf;
sToken.n -= 2 + cnt;
}
bool isPrimaryKey = (colIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX);
......@@ -1057,10 +1037,12 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC
break;
}
char* tmp = NULL;
// Remove quotation marks
if (TK_STRING == sToken.type) {
sToken.z++;
sToken.n -= 2;
tmp = strndup(sToken.z, sToken.n);
sToken.n = stringProcess(tmp, sToken.n);
sToken.z = tmp;
}
char tagVal[TSDB_MAX_TAGS_LEN] = {0};
......@@ -1068,6 +1050,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC
if (code != TSDB_CODE_SUCCESS) {
tdDestroyKVRowBuilder(&kvRowBuilder);
tscDestroyBoundColumnInfo(&spd);
tfree(tmp);
return code;
}
......@@ -1078,18 +1061,18 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC
if(sToken.n > TSDB_MAX_JSON_TAGS_LEN/TSDB_NCHAR_SIZE){
tdDestroyKVRowBuilder(&kvRowBuilder);
tscDestroyBoundColumnInfo(&spd);
tfree(tmp);
return tscSQLSyntaxErrMsg(pInsertParam->msg, "json tag too long", NULL);
}
char* json = strndup(sToken.z, sToken.n);
code = parseJsontoTagData(json, &kvRowBuilder, pInsertParam->msg, pTagSchema[spd.boundedColumns[0]].colId);
code = parseJsontoTagData(sToken.z, &kvRowBuilder, pInsertParam->msg, pTagSchema[spd.boundedColumns[0]].colId);
if (code != TSDB_CODE_SUCCESS) {
tdDestroyKVRowBuilder(&kvRowBuilder);
tscDestroyBoundColumnInfo(&spd);
tfree(json);
tfree(tmp);
return code;
}
tfree(json);
}
tfree(tmp);
}
tscDestroyBoundColumnInfo(&spd);
......@@ -1246,12 +1229,8 @@ static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDat
strncpy(tmpTokenBuf, sToken.z, sToken.n);
sToken.z = tmpTokenBuf;
if (TK_STRING == sToken.type) {
tscDequoteAndTrimToken(&sToken);
}
if (TK_ID == sToken.type) {
tscRmEscapeAndTrimToken(&sToken);
if (TK_STRING == sToken.type || TK_ID == sToken.type) {
sToken.n = stringProcess(sToken.z, sToken.n);
}
if (sToken.type == TK_RP) {
......@@ -1371,7 +1350,7 @@ _clean:
static int32_t getFileFullPath(SStrToken* pToken, char* output) {
char path[PATH_MAX] = {0};
strncpy(path, pToken->z, pToken->n);
strdequote(path);
stringProcess(path, (int32_t)strlen(path));
wordexp_t full_path;
if (wordexp(path, &full_path, 0) != 0) {
......
......@@ -20,7 +20,7 @@
#include "tscParseLine.h"
typedef struct {
char sTableName[TSDB_TABLE_NAME_LEN + TS_ESCAPE_CHAR_SIZE];
char sTableName[TSDB_TABLE_NAME_LEN + TS_BACKQUOTE_CHAR_SIZE];
SHashObj* tagHash;
SHashObj* fieldHash;
SArray* tags; //SArray<SSchema>
......@@ -68,13 +68,13 @@ typedef enum {
} ESchemaAction;
typedef struct {
char sTableName[TSDB_TABLE_NAME_LEN + TS_ESCAPE_CHAR_SIZE];
char sTableName[TSDB_TABLE_NAME_LEN + TS_BACKQUOTE_CHAR_SIZE];
SArray* tags; //SArray<SSchema>
SArray* fields; //SArray<SSchema>
} SCreateSTableActionInfo;
typedef struct {
char sTableName[TSDB_TABLE_NAME_LEN + TS_ESCAPE_CHAR_SIZE];
char sTableName[TSDB_TABLE_NAME_LEN + TS_BACKQUOTE_CHAR_SIZE];
SSchema* field;
} SAlterSTableActionInfo;
......@@ -161,14 +161,14 @@ static int32_t getSmlMd5ChildTableName(TAOS_SML_DATA_POINT* point, char* tableNa
}
SStringBuilder sb; memset(&sb, 0, sizeof(sb));
char sTableName[TSDB_TABLE_NAME_LEN + TS_ESCAPE_CHAR_SIZE] = {0};
char sTableName[TSDB_TABLE_NAME_LEN + TS_BACKQUOTE_CHAR_SIZE] = {0};
strncpy(sTableName, point->stableName, strlen(point->stableName));
//strtolower(sTableName, point->stableName);
taosStringBuilderAppendString(&sb, sTableName);
for (int j = 0; j < point->tagNum; ++j) {
taosStringBuilderAppendChar(&sb, ',');
TAOS_SML_KV* tagKv = point->tags + j;
char tagName[TSDB_COL_NAME_LEN + TS_ESCAPE_CHAR_SIZE] = {0};
char tagName[TSDB_COL_NAME_LEN + TS_BACKQUOTE_CHAR_SIZE] = {0};
strncpy(tagName, tagKv->key, strlen(tagKv->key));
//strtolower(tagName, tagKv->key);
taosStringBuilderAppendString(&sb, tagName);
......@@ -192,8 +192,8 @@ static int32_t getSmlMd5ChildTableName(TAOS_SML_DATA_POINT* point, char* tableNa
static int32_t buildSmlChildTableName(TAOS_SML_DATA_POINT* point, SSmlLinesInfo* info) {
tscDebug("SML:0x%"PRIx64" taos_sml_insert build child table name", info->id);
char childTableName[TSDB_TABLE_NAME_LEN + TS_ESCAPE_CHAR_SIZE];
int32_t tableNameLen = TSDB_TABLE_NAME_LEN + TS_ESCAPE_CHAR_SIZE;
char childTableName[TSDB_TABLE_NAME_LEN + TS_BACKQUOTE_CHAR_SIZE];
int32_t tableNameLen = TSDB_TABLE_NAME_LEN + TS_BACKQUOTE_CHAR_SIZE;
getSmlMd5ChildTableName(point, childTableName, &tableNameLen, info);
point->childTableName = calloc(1, tableNameLen+1);
strncpy(point->childTableName, childTableName, tableNameLen);
......@@ -251,15 +251,15 @@ static int32_t buildDataPointSchemas(TAOS_SML_DATA_POINT* points, int numPoint,
size_t nameLen = strlen(tsSmlTagNullName);
strncpy(tagNullName, tsSmlTagNullName, nameLen);
addEscapeCharToString(tagNullName, (int32_t)nameLen);
size_t* pTagNullIdx = taosHashGet(pStableSchema->tagHash, tagNullName, nameLen + TS_ESCAPE_CHAR_SIZE);
size_t* pTagNullIdx = taosHashGet(pStableSchema->tagHash, tagNullName, nameLen + TS_BACKQUOTE_CHAR_SIZE);
if (!pTagNullIdx) {
SSchema tagNull = {0};
tagNull.type = TSDB_DATA_TYPE_NCHAR;
tagNull.bytes = TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE;
strncpy(tagNull.name, tagNullName, nameLen + TS_ESCAPE_CHAR_SIZE);
strncpy(tagNull.name, tagNullName, nameLen + TS_BACKQUOTE_CHAR_SIZE);
taosArrayPush(pStableSchema->tags, &tagNull);
size_t tagNullIdx = taosArrayGetSize(pStableSchema->tags) - 1;
taosHashPut(pStableSchema->tagHash, tagNull.name, nameLen + TS_ESCAPE_CHAR_SIZE, &tagNullIdx, sizeof(tagNullIdx));
taosHashPut(pStableSchema->tagHash, tagNull.name, nameLen + TS_BACKQUOTE_CHAR_SIZE, &tagNullIdx, sizeof(tagNullIdx));
}
}
......@@ -295,7 +295,7 @@ static int32_t buildDataPointSchemas(TAOS_SML_DATA_POINT* points, int numPoint,
static int32_t generateSchemaAction(SSchema* pointColField, SHashObj* dbAttrHash, SArray* dbAttrArray, bool isTag, char sTableName[],
SSchemaAction* action, bool* actionNeeded, SSmlLinesInfo* info) {
char fieldName[TSDB_COL_NAME_LEN + TS_ESCAPE_CHAR_SIZE] = {0};
char fieldName[TSDB_COL_NAME_LEN + TS_BACKQUOTE_CHAR_SIZE] = {0};
strcpy(fieldName, pointColField->name);
size_t* pDbIndex = taosHashGet(dbAttrHash, fieldName, strlen(fieldName));
......@@ -315,7 +315,7 @@ static int32_t generateSchemaAction(SSchema* pointColField, SHashObj* dbAttrHash
action->action = SCHEMA_ACTION_CHANGE_COLUMN_SIZE;
}
memset(&action->alterSTable, 0, sizeof(SAlterSTableActionInfo));
memcpy(action->alterSTable.sTableName, sTableName, TSDB_TABLE_NAME_LEN + TS_ESCAPE_CHAR_SIZE);
memcpy(action->alterSTable.sTableName, sTableName, TSDB_TABLE_NAME_LEN + TS_BACKQUOTE_CHAR_SIZE);
action->alterSTable.field = pointColField;
*actionNeeded = true;
}
......@@ -326,7 +326,7 @@ static int32_t generateSchemaAction(SSchema* pointColField, SHashObj* dbAttrHash
action->action = SCHEMA_ACTION_ADD_COLUMN;
}
memset(&action->alterSTable, 0, sizeof(SAlterSTableActionInfo));
memcpy(action->alterSTable.sTableName, sTableName, TSDB_TABLE_NAME_LEN + TS_ESCAPE_CHAR_SIZE);
memcpy(action->alterSTable.sTableName, sTableName, TSDB_TABLE_NAME_LEN + TS_BACKQUOTE_CHAR_SIZE);
action->alterSTable.field = pointColField;
*actionNeeded = true;
}
......@@ -572,7 +572,7 @@ static int32_t getSuperTableMetaFromLocalCache(TAOS* taos, char* tableName, STab
pSql->fp = NULL;
registerSqlObj(pSql);
char tableNameBuf[TSDB_TABLE_NAME_LEN + TS_ESCAPE_CHAR_SIZE] = {0};
char tableNameBuf[TSDB_TABLE_NAME_LEN + TS_BACKQUOTE_CHAR_SIZE] = {0};
memcpy(tableNameBuf, tableName, strlen(tableName));
SStrToken tableToken = {.z = tableNameBuf, .n = (uint32_t)strlen(tableName), .type = TK_ID};
tGetToken(tableNameBuf, &tableToken.type);
......@@ -689,7 +689,7 @@ static int32_t modifyDBSchemas(TAOS* taos, SArray* stableSchemas, SSmlLinesInfo*
SSchemaAction schemaAction = {0};
schemaAction.action = SCHEMA_ACTION_CREATE_STABLE;
memset(&schemaAction.createSTable, 0, sizeof(SCreateSTableActionInfo));
memcpy(schemaAction.createSTable.sTableName, pointSchema->sTableName, TSDB_TABLE_NAME_LEN + TS_ESCAPE_CHAR_SIZE);
memcpy(schemaAction.createSTable.sTableName, pointSchema->sTableName, TSDB_TABLE_NAME_LEN + TS_BACKQUOTE_CHAR_SIZE);
schemaAction.createSTable.tags = pointSchema->tags;
schemaAction.createSTable.fields = pointSchema->fields;
applySchemaAction(taos, &schemaAction, info);
......@@ -726,7 +726,7 @@ static int32_t modifyDBSchemas(TAOS* taos, SArray* stableSchemas, SSmlLinesInfo*
SSchema* pointColTs = taosArrayGet(pointSchema->fields, 0);
SSchema* dbColTs = taosArrayGet(dbSchema.fields, 0);
memcpy(pointColTs->name, dbColTs->name, TSDB_COL_NAME_LEN + TS_ESCAPE_CHAR_SIZE);
memcpy(pointColTs->name, dbColTs->name, TSDB_COL_NAME_LEN + TS_BACKQUOTE_CHAR_SIZE);
for (int j = 1; j < pointFieldSize; ++j) {
SSchema* pointCol = taosArrayGet(pointSchema->fields, j);
......@@ -1398,7 +1398,7 @@ char* addEscapeCharToString(char *str, int32_t len) {
return NULL;
}
memmove(str + 1, str, len);
str[0] = str[len + 1] = TS_ESCAPE_CHAR;
str[0] = str[len + 1] = TS_BACKQUOTE_CHAR;
str[len + 2] = '\0';
return str;
}
......@@ -2129,7 +2129,7 @@ static int32_t parseSmlKey(TAOS_SML_KV *pKV, const char **index, SHashObj *pHash
return TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
}
pKV->key = calloc(len + TS_ESCAPE_CHAR_SIZE + 1, 1);
pKV->key = calloc(len + TS_BACKQUOTE_CHAR_SIZE + 1, 1);
memcpy(pKV->key, key, len + 1);
addEscapeCharToString(pKV->key, len);
tscDebug("SML:0x%"PRIx64" Key:%s|len:%d", info->id, pKV->key, len);
......@@ -2227,7 +2227,7 @@ static int32_t parseSmlMeasurement(TAOS_SML_DATA_POINT *pSml, const char **index
const char *cur = *index;
int16_t len = 0;
pSml->stableName = calloc(TSDB_TABLE_NAME_LEN + TS_ESCAPE_CHAR_SIZE, 1);
pSml->stableName = calloc(TSDB_TABLE_NAME_LEN + TS_BACKQUOTE_CHAR_SIZE, 1);
if (pSml->stableName == NULL){
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
......@@ -2313,7 +2313,7 @@ static int32_t parseSmlKvPairs(TAOS_SML_KV **pKVs, int *num_kvs,
}
size_t childTableNameLen = strlen(tsSmlChildTableName);
char childTableName[TSDB_TABLE_NAME_LEN + TS_ESCAPE_CHAR_SIZE] = {0};
char childTableName[TSDB_TABLE_NAME_LEN + TS_BACKQUOTE_CHAR_SIZE] = {0};
if (childTableNameLen != 0) {
memcpy(childTableName, tsSmlChildTableName, childTableNameLen);
addEscapeCharToString(childTableName, (int32_t)(childTableNameLen));
......@@ -2332,7 +2332,7 @@ static int32_t parseSmlKvPairs(TAOS_SML_KV **pKVs, int *num_kvs,
}
if (!isField && childTableNameLen != 0 && strcasecmp(pkv->key, childTableName) == 0) {
smlData->childTableName = malloc(pkv->length + TS_ESCAPE_CHAR_SIZE + 1);
smlData->childTableName = malloc(pkv->length + TS_BACKQUOTE_CHAR_SIZE + 1);
memcpy(smlData->childTableName, pkv->value, pkv->length);
addEscapeCharToString(smlData->childTableName, (int32_t)pkv->length);
free(pkv->key);
......
......@@ -37,7 +37,7 @@ static int32_t parseTelnetMetric(TAOS_SML_DATA_POINT *pSml, const char **index,
const char *cur = *index;
uint16_t len = 0;
pSml->stableName = tcalloc(TSDB_TABLE_NAME_LEN + TS_ESCAPE_CHAR_SIZE, 1);
pSml->stableName = tcalloc(TSDB_TABLE_NAME_LEN + TS_BACKQUOTE_CHAR_SIZE, 1);
if (pSml->stableName == NULL) {
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
......@@ -125,7 +125,7 @@ static int32_t parseTelnetTimeStamp(TAOS_SML_KV **pTS, int *num_kvs, const char
}
tfree(value);
(*pTS)->key = tcalloc(sizeof(key) + TS_ESCAPE_CHAR_SIZE, 1);
(*pTS)->key = tcalloc(sizeof(key) + TS_BACKQUOTE_CHAR_SIZE, 1);
memcpy((*pTS)->key, key, sizeof(key));
addEscapeCharToString((*pTS)->key, (int32_t)strlen(key));
......@@ -196,7 +196,7 @@ static int32_t parseTelnetMetricValue(TAOS_SML_KV **pKVs, int *num_kvs, const ch
}
tfree(value);
pVal->key = tcalloc(sizeof(key) + TS_ESCAPE_CHAR_SIZE, 1);
pVal->key = tcalloc(sizeof(key) + TS_BACKQUOTE_CHAR_SIZE, 1);
memcpy(pVal->key, key, sizeof(key));
addEscapeCharToString(pVal->key, (int32_t)strlen(pVal->key));
*num_kvs += 1;
......@@ -240,7 +240,7 @@ static int32_t parseTelnetTagKey(TAOS_SML_KV *pKV, const char **index, SHashObj
return TSDB_CODE_TSC_DUP_TAG_NAMES;
}
pKV->key = tcalloc(len + TS_ESCAPE_CHAR_SIZE + 1, 1);
pKV->key = tcalloc(len + TS_BACKQUOTE_CHAR_SIZE + 1, 1);
memcpy(pKV->key, key, len + 1);
addEscapeCharToString(pKV->key, len);
//tscDebug("OTD:0x%"PRIx64" Key:%s|len:%d", info->id, pKV->key, len);
......@@ -307,7 +307,7 @@ static int32_t parseTelnetTagKvs(TAOS_SML_KV **pKVs, int *num_kvs,
pkv = *pKVs;
size_t childTableNameLen = strlen(tsSmlChildTableName);
char childTbName[TSDB_TABLE_NAME_LEN + TS_ESCAPE_CHAR_SIZE] = {0};
char childTbName[TSDB_TABLE_NAME_LEN + TS_BACKQUOTE_CHAR_SIZE] = {0};
if (childTableNameLen != 0) {
memcpy(childTbName, tsSmlChildTableName, childTableNameLen);
addEscapeCharToString(childTbName, (int32_t)(childTableNameLen));
......@@ -324,7 +324,7 @@ static int32_t parseTelnetTagKvs(TAOS_SML_KV **pKVs, int *num_kvs,
return ret;
}
if (childTableNameLen != 0 && strcasecmp(pkv->key, childTbName) == 0) {
*childTableName = tcalloc(pkv->length + TS_ESCAPE_CHAR_SIZE + 1, 1);
*childTableName = tcalloc(pkv->length + TS_BACKQUOTE_CHAR_SIZE + 1, 1);
memcpy(*childTableName, pkv->value, pkv->length);
(*childTableName)[pkv->length] = '\0';
addEscapeCharToString(*childTableName, pkv->length);
......@@ -500,7 +500,7 @@ static int32_t parseMetricFromJSON(cJSON *root, TAOS_SML_DATA_POINT* pSml, SSmlL
return TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH;
}
pSml->stableName = tcalloc(stableLen + TS_ESCAPE_CHAR_SIZE + 1, sizeof(char));
pSml->stableName = tcalloc(stableLen + TS_BACKQUOTE_CHAR_SIZE + 1, sizeof(char));
if (pSml->stableName == NULL){
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
......@@ -879,7 +879,7 @@ static int32_t parseMetricValueFromJSON(cJSON *root, TAOS_SML_KV **pKVs, int *nu
return ret;
}
pVal->key = tcalloc(sizeof(key) + TS_ESCAPE_CHAR_SIZE, 1);
pVal->key = tcalloc(sizeof(key) + TS_BACKQUOTE_CHAR_SIZE, 1);
memcpy(pVal->key, key, sizeof(key));
addEscapeCharToString(pVal->key, (int32_t)strlen(pVal->key));
......@@ -910,7 +910,7 @@ static int32_t parseTagsFromJSON(cJSON *root, TAOS_SML_KV **pKVs, int *num_kvs,
return TSDB_CODE_TSC_INVALID_JSON;
}
size_t idLen = strlen(id->valuestring);
*childTableName = tcalloc(idLen + TS_ESCAPE_CHAR_SIZE + 1, sizeof(char));
*childTableName = tcalloc(idLen + TS_BACKQUOTE_CHAR_SIZE + 1, sizeof(char));
memcpy(*childTableName, id->valuestring, idLen);
addEscapeCharToString(*childTableName, (int32_t)idLen);
......@@ -948,7 +948,7 @@ static int32_t parseTagsFromJSON(cJSON *root, TAOS_SML_KV **pKVs, int *num_kvs,
tscError("OTD:0x%"PRIx64" Tag key cannot exceeds %d characters in JSON", info->id, TSDB_COL_NAME_LEN - 1);
return TSDB_CODE_TSC_INVALID_COLUMN_LENGTH;
}
pkv->key = tcalloc(keyLen + TS_ESCAPE_CHAR_SIZE + 1, sizeof(char));
pkv->key = tcalloc(keyLen + TS_BACKQUOTE_CHAR_SIZE + 1, sizeof(char));
strncpy(pkv->key, tag->string, keyLen);
addEscapeCharToString(pkv->key, (int32_t)keyLen);
//value
......
......@@ -170,6 +170,16 @@ void tscAddIntoStreamList(SSqlStream *pStream) {
STscObj * pObj = pStream->pSql->pTscObj;
pthread_mutex_lock(&pObj->mutex);
//check if newly added stream node is present
//in the streamList to prevent loop in the list
SSqlStream *iter = pObj->streamList;
while (iter) {
if (pStream == iter) {
pthread_mutex_unlock(&pObj->mutex);
return;
}
iter = iter->next;
}
pStream->next = pObj->streamList;
if (pObj->streamList) pObj->streamList->prev = pStream;
......
......@@ -322,7 +322,7 @@ static int32_t invalidOperationMsg(char* dstBuffer, const char* errMsg) {
static int convertTimestampStrToInt64(tVariant *pVar, int32_t precision) {
int64_t time = 0;
strdequote(pVar->pz);
stringProcess(pVar->pz, pVar->nLen);
char* seg = strnchr(pVar->pz, '-', pVar->nLen, false);
if (seg != NULL) {
......@@ -359,7 +359,7 @@ static int32_t handlePassword(SSqlCmd* pCmd, SStrToken* pPwd) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3);
}
strdequote(pPwd->z);
stringProcess(pPwd->z, pPwd->n);
pPwd->n = (uint32_t)strtrim(pPwd->z); // trim space before and after passwords
if (pPwd->n <= 0) {
......@@ -477,7 +477,7 @@ int32_t handleUserDefinedFunc(SSqlObj* pSql, struct SSqlInfo* pInfo) {
if (validateColumnName(createInfo->name.z) != TSDB_CODE_SUCCESS) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
}
strdequote(createInfo->name.z);
stringProcess(createInfo->name.z, createInfo->name.n);
if (strlen(createInfo->name.z) >= TSDB_FUNC_NAME_LEN) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
......@@ -485,7 +485,7 @@ int32_t handleUserDefinedFunc(SSqlObj* pSql, struct SSqlInfo* pInfo) {
createInfo->path.z[createInfo->path.n] = 0;
strdequote(createInfo->path.z);
stringProcess(createInfo->path.z, createInfo->path.n);
if (strlen(createInfo->path.z) >= PATH_MAX) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
......@@ -543,7 +543,7 @@ int32_t handleUserDefinedFunc(SSqlObj* pSql, struct SSqlInfo* pInfo) {
t0->z[t0->n] = 0;
strdequote(t0->z);
stringProcess(t0->z, t0->n);
if (strlen(t0->z) >= TSDB_FUNC_NAME_LEN) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
......@@ -628,7 +628,7 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
}
} else if (pInfo->type == TSDB_SQL_DROP_DNODE) {
if (pzName->type == TK_STRING) {
pzName->n = strdequote(pzName->z);
pzName->n = stringProcess(pzName->z, pzName->n);
}
strncpy(pCmd->payload, pzName->z, pzName->n);
} else { // drop user/account
......@@ -718,7 +718,7 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
SStrToken* id = taosArrayGet(pInfo->pMiscInfo->a, 0);
if (id->type == TK_STRING) {
id->n = strdequote(id->z);
id->n = stringProcess(id->z, id->n);
}
break;
}
......@@ -834,7 +834,7 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
SStrToken* t0 = taosArrayGet(pMiscInfo->a, 0);
SStrToken* t1 = taosArrayGet(pMiscInfo->a, 1);
t0->n = strdequote(t0->z);
t0->n = stringProcess(t0->z, t0->n);
strncpy(pCfg->ep, t0->z, t0->n);
if (validateEp(pCfg->ep) != TSDB_CODE_SUCCESS) {
......@@ -1084,8 +1084,9 @@ static int32_t addPrimaryTsColumnForTimeWindowQuery(SQueryInfo* pQueryInfo, SSql
uint64_t uid = tscExprGet(pQueryInfo, 0)->base.uid;
int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL;
STableMetaInfo* pTableMetaInfo = NULL;
for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
if (pTableMetaInfo->pTableMeta->id.uid == uid) {
tableIndex = i;
break;
......@@ -1097,7 +1098,11 @@ static int32_t addPrimaryTsColumnForTimeWindowQuery(SQueryInfo* pQueryInfo, SSql
}
SSchema s = {.bytes = TSDB_KEYSIZE, .type = TSDB_DATA_TYPE_TIMESTAMP, .colId = PRIMARYKEY_TIMESTAMP_COL_INDEX};
tstrncpy(s.name, aAggs[TSDB_FUNC_TS].name, sizeof(s.name));
if (pTableMetaInfo) {
tstrncpy(s.name, pTableMetaInfo->pTableMeta->schema[PRIMARYKEY_TIMESTAMP_COL_INDEX].name, sizeof(s.name));
} else {
tstrncpy(s.name, aAggs[TSDB_FUNC_TS].name, sizeof(s.name));
}
SColumnIndex index = {tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX};
tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TS, &index, &s, TSDB_COL_NORMAL, 0);
......@@ -1392,7 +1397,7 @@ int32_t parseSlidingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* pSl
const char* msg1 = "sliding value no larger than the interval value";
const char* msg2 = "sliding value can not less than 1% of interval value";
const char* msg3 = "does not support sliding when interval is natural month/year";
const char* msg4 = "sliding not support for interp query";
const char* msg4 = "sliding not support for interp query";
const static int32_t INTERVAL_SLIDING_FACTOR = 100;
......@@ -1410,7 +1415,7 @@ int32_t parseSlidingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* pSl
if (interpQuery) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4);
}
if (pInterval->intervalUnit == 'n' || pInterval->intervalUnit == 'y') {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3);
}
......@@ -2668,6 +2673,8 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
const char* msg14 = "third parameter algorithm must be 'default' or 't-digest'";
const char* msg15 = "parameter is out of range [1, 1000]";
const char* msg16 = "elapsed duration should be greater than or equal to database precision";
const char* msg17 = "elapsed/twa should not be used in nested query if inner query has group by clause";
const char* msg18 = "the second parameter is not an integer";
switch (functionId) {
case TSDB_FUNC_COUNT: {
......@@ -2727,7 +2734,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
memset(pExpr->base.aliasName, 0, tListLen(pExpr->base.aliasName));
getColumnName(pItem, pExpr->base.aliasName, pExpr->base.token,sizeof(pExpr->base.aliasName) - 1);
SColumnList list = createColumnList(1, index.tableIndex, index.columnIndex);
if (finalResult) {
int32_t numOfOutput = tscNumOfFields(pQueryInfo);
......@@ -2792,6 +2799,17 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
}
}
//for timeline related aggregation function like elapsed and twa, groupby in subquery is not allowed
//as calculation result is meaningless by mixing different childtables(timelines) results.
if ((functionId == TSDB_FUNC_ELAPSED || functionId == TSDB_FUNC_TWA) && pQueryInfo->pUpstream != NULL) {
size_t numOfUpstreams = taosArrayGetSize(pQueryInfo->pUpstream);
for (int32_t i = 0; i < numOfUpstreams; ++i) {
SQueryInfo* pSub = taosArrayGetP(pQueryInfo->pUpstream, i);
if (pSub->groupbyExpr.numOfGroupCols > 0) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg17);
}
}
}
STableComInfo info = tscGetTableInfo(pTableMetaInfo->pTableMeta);
......@@ -2852,6 +2870,13 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
char val[8] = {0};
int64_t tickPerSec = 0;
char *exprToken = tcalloc(pParamElem[1].pNode->exprToken.n + 1, sizeof(char));
memcpy(exprToken, pParamElem[1].pNode->exprToken.z, pParamElem[1].pNode->exprToken.n);
if (pParamElem[1].pNode->exprToken.type == TK_NOW || strstr(exprToken, "now")) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
tfree(exprToken);
if ((TSDB_DATA_TYPE_NULL == pParamElem[1].pNode->value.nType) || tVariantDump(&pParamElem[1].pNode->value, (char*) &tickPerSec, TSDB_DATA_TYPE_BIGINT, true) < 0) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
......@@ -2866,7 +2891,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg10);
} else if (tickPerSec <= 0) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg16);
}
}
tscExprAddParams(&pExpr->base, (char*) &tickPerSec, TSDB_DATA_TYPE_BIGINT, LONG_BYTES);
if (functionId == TSDB_FUNC_DERIVATIVE) {
......@@ -3132,6 +3157,11 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
char* endptr = NULL;
strtoll(pParamElem[1].pNode->exprToken.z, &endptr, 10);
if ((endptr-pParamElem[1].pNode->exprToken.z != pParamElem[1].pNode->exprToken.n) || errno == ERANGE) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg18);
}
tVariantDump(pVariant, val, TSDB_DATA_TYPE_BIGINT, true);
int64_t numRowsSelected = GET_INT64_VAL(val);
......@@ -3411,7 +3441,7 @@ static int16_t doGetColumnIndex(SQueryInfo* pQueryInfo, int32_t index, SStrToken
pToken->z = tmpTokenBuf;
if (pToken->type == TK_ID) {
tscRmEscapeAndTrimToken(pToken);
pToken->n = stringProcess(pToken->z, pToken->n);
}
for (int16_t i = 0; i < numOfCols; ++i) {
......@@ -3572,11 +3602,11 @@ int32_t setShowInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
// show table/stable like 'xxxx', set the like pattern for show tables
SStrToken* pPattern = &pShowInfo->pattern;
if (pPattern->type != 0) {
if (pPattern->type == TK_ID && pPattern->z[0] == TS_ESCAPE_CHAR) {
if (pPattern->type == TK_ID && pPattern->z[0] == TS_BACKQUOTE_CHAR) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7);
}
pPattern->n = strdequote(pPattern->z);
pPattern->n = stringProcess(pPattern->z, pPattern->n);
if (pPattern->n <= 0) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6);
......@@ -3594,7 +3624,7 @@ int32_t setShowInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
}
if (pShowInfo->prefix.type == TK_STRING) {
pShowInfo->prefix.n = strdequote(pShowInfo->prefix.z);
pShowInfo->prefix.n = stringProcess(pShowInfo->prefix.z, pShowInfo->prefix.n);
}
}
return TSDB_CODE_SUCCESS;
......@@ -4906,14 +4936,14 @@ static int32_t validateNullExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t
if (IS_VAR_DATA_TYPE(pSchema[index].type) || pSchema[index].type == TSDB_DATA_TYPE_JSON) {
return TSDB_CODE_SUCCESS;
}
char *v = strndup(pRight->exprToken.z, pRight->exprToken.n);
int32_t len = strRmquote(v, pRight->exprToken.n);
int32_t len = stringProcess(v, pRight->exprToken.n);
if (len > 0) {
uint32_t type = 0;
tGetToken(v, &type);
if (type == TK_NULL) {
if (type == TK_NULL) {
free(v);
return invalidOperationMsg(msgBuf, msg);
}
......@@ -5022,20 +5052,10 @@ static int32_t validateMatchExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_
regex_t regex;
char regErrBuf[256] = {0};
//remove the quote at the begin end of original sql string.
uint32_t lenPattern = pRight->exprToken.n - 2;
char* pattern = malloc(lenPattern + 1);
strncpy(pattern, pRight->exprToken.z+1, lenPattern);
pattern[lenPattern] = '\0';
tfree(pRight->value.pz);
pRight->value.pz = pattern;
pRight->value.nLen = lenPattern;
int cflags = REG_EXTENDED;
if ((errCode = regcomp(&regex, pattern, cflags)) != 0) {
if ((errCode = regcomp(&regex, pRight->value.pz, cflags)) != 0) {
regerror(errCode, &regex, regErrBuf, sizeof(regErrBuf));
tscError("Failed to compile regex pattern %s. reason %s", pattern, regErrBuf);
tscError("Failed to compile regex pattern %s. reason %s", pRight->value.pz, regErrBuf);
return invalidOperationMsg(msgBuf, msg3);
}
regfree(&regex);
......@@ -5229,7 +5249,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql
}
}
if (pRight != NULL && (pRight->tokenId == TK_ID || pRight->tokenId == TK_ARROW)) { // join on tag columns for stable query
if (joinQuery && pRight != NULL && (pRight->tokenId == TK_ID || pRight->tokenId == TK_ARROW)) { // join on tag columns for stable query
if (!validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &index)) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
......@@ -6035,7 +6055,7 @@ int32_t getTimeRange(STimeWindow* win, tSqlExpr* pRight, int32_t optr, int16_t t
int64_t val = 0;
bool parsed = false;
if (pRight->value.nType == TSDB_DATA_TYPE_BINARY) {
pRight->value.nLen = strdequote(pRight->value.pz);
pRight->value.nLen = stringProcess(pRight->value.pz, pRight->value.nLen);
char* seg = strnchr(pRight->value.pz, '-', pRight->value.nLen, false);
if (seg != NULL) {
......@@ -6991,7 +7011,7 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
//handle Escape character backstick
bool inEscape = false;
if (name.z[0] == TS_ESCAPE_CHAR && name.z[name.n - 1] == TS_ESCAPE_CHAR) {
if (name.z[0] == TS_BACKQUOTE_CHAR && name.z[name.n - 1] == TS_BACKQUOTE_CHAR) {
inEscape = true;
name.type = TK_ID;
}
......@@ -7010,7 +7030,7 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
int32_t nameLen = pItem->pVar.nLen;
if (inEscape) {
memmove(name1, name1 + 1, nameLen);
name1[nameLen - TS_ESCAPE_CHAR_SIZE] = '\0';
name1[nameLen - TS_BACKQUOTE_CHAR_SIZE] = '\0';
}
TAOS_FIELD f = tscCreateField(TSDB_DATA_TYPE_INT, name1, tDataTypes[TSDB_DATA_TYPE_INT].bytes);
......@@ -7031,7 +7051,7 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
//handle Escape character backstick
bool inEscape = false;
if (name.z[0] == TS_ESCAPE_CHAR && name.z[name.n - 1] == TS_ESCAPE_CHAR) {
if (name.z[0] == TS_BACKQUOTE_CHAR && name.z[name.n - 1] == TS_BACKQUOTE_CHAR) {
inEscape = true;
name.type = TK_ID;
}
......@@ -7072,8 +7092,8 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
if (inEscape) {
memmove(name.z, name.z + 1, name.n);
name.z[name.n - TS_ESCAPE_CHAR_SIZE] = '\0';
name.n -= TS_ESCAPE_CHAR_SIZE;
name.z[name.n - TS_BACKQUOTE_CHAR_SIZE] = '\0';
name.n -= TS_BACKQUOTE_CHAR_SIZE;
}
TAOS_FIELD f = tscCreateField(pColSchema->type, name.z, pItem->bytes);
......@@ -7091,10 +7111,10 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER;
SStrToken name = {.type = TK_STRING, .z = pItem->name, .n = (uint32_t)strlen(pItem->name)};
//handle Escape character backstick
if (name.z[0] == TS_ESCAPE_CHAR && name.z[name.n - 1] == TS_ESCAPE_CHAR) {
if (name.z[0] == TS_BACKQUOTE_CHAR && name.z[name.n - 1] == TS_BACKQUOTE_CHAR) {
memmove(name.z, name.z + 1, name.n);
name.z[name.n - TS_ESCAPE_CHAR_SIZE] = '\0';
name.n -= TS_ESCAPE_CHAR_SIZE;
name.z[name.n - TS_BACKQUOTE_CHAR_SIZE] = '\0';
name.n -= TS_BACKQUOTE_CHAR_SIZE;
}
if (getColumnIndexByName(&name, pQueryInfo, &columnIndex, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) {
return invalidOperationMsg(pMsg, msg17);
......@@ -7291,7 +7311,7 @@ int32_t validateDNodeConfig(SMiscInfo* pOptions) {
SStrToken* pValToken = taosArrayGet(pOptions->a, 2);
int32_t vnodeId = 0;
int32_t dnodeId = 0;
strdequote(pValToken->z);
stringProcess(pValToken->z, pValToken->n);
bool parseOk = taosCheckBalanceCfgOptions(pValToken->z, &vnodeId, &dnodeId);
if (!parseOk) {
return TSDB_CODE_TSC_INVALID_OPERATION; // options value is invalid
......@@ -7393,7 +7413,7 @@ int32_t validateColumnName(char* name) {
}
if (token.type == TK_STRING) {
strdequote(token.z);
token.n = stringProcess(token.z, token.n);
strntolower(token.z, token.z, token.n);
token.n = (uint32_t)strtrim(token.z);
......@@ -7404,7 +7424,7 @@ int32_t validateColumnName(char* name) {
return validateColumnName(token.z);
} else if (token.type == TK_ID) {
strRmquoteEscape(name, token.n);
stringProcess(name, token.n);
return TSDB_CODE_SUCCESS;
} else {
if (isNumber(&token)) {
......@@ -7555,7 +7575,7 @@ static int32_t setTimePrecision(SSqlCmd* pCmd, SCreateDbMsg* pMsg, SCreateDbInfo
SStrToken* pToken = &pCreateDbInfo->precision;
if (pToken->n > 0) {
pToken->n = strdequote(pToken->z);
pToken->n = stringProcess(pToken->z, pToken->n);
if (strncmp(pToken->z, TSDB_TIME_PRECISION_MILLI_STR, pToken->n) == 0 &&
strlen(TSDB_TIME_PRECISION_MILLI_STR) == pToken->n) {
......@@ -8610,12 +8630,8 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) {
strncpy(tmpTokenBuf, sToken->z, sToken->n);
sToken->z = tmpTokenBuf;
if (TK_STRING == sToken->type) {
tscDequoteAndTrimToken(sToken);
}
if (TK_ID == sToken->type) {
tscRmEscapeAndTrimToken(sToken);
if (TK_STRING == sToken->type || TK_ID == sToken->type) {
sToken->n = stringProcess(sToken->z, sToken->n);
}
tVariantListItem* pItem = taosArrayGet(pValList, i);
......@@ -9554,8 +9570,6 @@ static int32_t doLoadAllTableMeta(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNod
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
}
tscDequoteAndTrimToken(oriName);
bool dbIncluded = false;
char buf[TSDB_TABLE_FNAME_LEN];
SStrToken sTblToken;
......@@ -9577,7 +9591,6 @@ static int32_t doLoadAllTableMeta(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNod
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
tscDequoteAndTrimToken(aliasName);
if (tscValidateName(aliasName, false, NULL) != TSDB_CODE_SUCCESS || aliasName->n >= TSDB_TABLE_NAME_LEN) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3);
}
......
......@@ -363,6 +363,41 @@ void tscSetFqdnErrorMsg(SSqlObj* pSql, SRpcEpSet* pEpSet) {
}
}
bool shouldRewTableMeta(SSqlObj* pSql, SRpcMsg* rpcMsg) {
SSqlCmd *pCmd = &pSql->cmd;
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
int32_t cmd = pCmd->command;
if ((cmd != TSDB_SQL_SELECT && cmd != TSDB_SQL_UPDATE_TAGS_VAL)) {
return false;
}
if (rpcMsg->code != TSDB_CODE_TDB_INVALID_TABLE_ID &&
rpcMsg->code != TSDB_CODE_VND_INVALID_VGROUP_ID &&
rpcMsg->code != TSDB_CODE_QRY_INVALID_SCHEMA_VERSION &&
rpcMsg->code != TSDB_CODE_RPC_NETWORK_UNAVAIL &&
rpcMsg->code != TSDB_CODE_APP_NOT_READY ) {
return false;
}
if (rpcMsg->code == TSDB_CODE_QRY_INVALID_SCHEMA_VERSION) {
return true;
}
// 1. super table subquery
// 2. nest queries are all not updated the tablemeta and retry parse the sql after cleanup local tablemeta/vgroup id buffer
if ((TSDB_QUERY_HAS_TYPE(pQueryInfo->type, (TSDB_QUERY_TYPE_STABLE_SUBQUERY | TSDB_QUERY_TYPE_SUBQUERY | TSDB_QUERY_TYPE_TAG_FILTER_QUERY)) &&
!TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_PROJECTION_QUERY)) ||
(TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_NEST_SUBQUERY)) ||
(TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_STABLE_SUBQUERY) && pQueryInfo->distinct)
|| (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_QUERY))) {
return false;
}
// single table query error need to renew table meta.
return true;
}
void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
TSDB_CACHE_PTR_TYPE handle = (TSDB_CACHE_PTR_TYPE) rpcMsg->ahandle;
SSqlObj* pSql = (SSqlObj*)taosAcquireRef(tscObjRef, handle);
......@@ -415,42 +450,29 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
pSql->cmd.insertParam.schemaAttached = 1;
}
// single table query error need to be handled here.
if ((cmd == TSDB_SQL_SELECT || cmd == TSDB_SQL_UPDATE_TAGS_VAL) &&
(((rpcMsg->code == TSDB_CODE_TDB_INVALID_TABLE_ID || rpcMsg->code == TSDB_CODE_VND_INVALID_VGROUP_ID)) ||
rpcMsg->code == TSDB_CODE_RPC_NETWORK_UNAVAIL || rpcMsg->code == TSDB_CODE_APP_NOT_READY)) {
// 1. super table subquery
// 2. nest queries are all not updated the tablemeta and retry parse the sql after cleanup local tablemeta/vgroup id buffer
if ((TSDB_QUERY_HAS_TYPE(pQueryInfo->type, (TSDB_QUERY_TYPE_STABLE_SUBQUERY | TSDB_QUERY_TYPE_SUBQUERY |
TSDB_QUERY_TYPE_TAG_FILTER_QUERY)) &&
!TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_PROJECTION_QUERY)) ||
(TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_NEST_SUBQUERY)) || (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_STABLE_SUBQUERY) && pQueryInfo->distinct)
|| (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_QUERY))) {
// do nothing in case of super table subquery
} else {
pSql->retry += 1;
tscWarn("0x%" PRIx64 " it shall renew table meta, code:%s, retry:%d", pSql->self, tstrerror(rpcMsg->code), pSql->retry);
pSql->res.code = rpcMsg->code; // keep the previous error code
if (pSql->retry > pSql->maxRetry) {
tscError("0x%" PRIx64 " max retry %d reached, give up", pSql->self, pSql->maxRetry);
} else {
// wait for a little bit moment and then retry
// todo do not sleep in rpc callback thread, add this process into queue to process
if (rpcMsg->code == TSDB_CODE_APP_NOT_READY || rpcMsg->code == TSDB_CODE_VND_INVALID_VGROUP_ID) {
int32_t duration = getWaitingTimeInterval(pSql->retry);
taosMsleep(duration);
}
pSql->retryReason = rpcMsg->code;
rpcMsg->code = tscRenewTableMeta(pSql);
// if there is an error occurring, proceed to the following error handling procedure.
if (rpcMsg->code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
taosReleaseRef(tscObjRef, handle);
rpcFreeCont(rpcMsg->pCont);
return;
}
bool renewTableMeta = shouldRewTableMeta(pSql, rpcMsg);
if (renewTableMeta) {
pSql->retry += 1;
tscWarn("0x%" PRIx64 " it shall renew table meta, code:%s, retry:%d", pSql->self, tstrerror(rpcMsg->code), pSql->retry);
pSql->res.code = rpcMsg->code; // keep the previous error code
if (pSql->retry > pSql->maxRetry) {
tscError("0x%" PRIx64 " max retry %d reached, give up", pSql->self, pSql->maxRetry);
} else {
// wait for a little bit moment and then retry
// todo do not sleep in rpc callback thread, add this process into queue to process
if (rpcMsg->code == TSDB_CODE_APP_NOT_READY || rpcMsg->code == TSDB_CODE_VND_INVALID_VGROUP_ID) {
int32_t duration = getWaitingTimeInterval(pSql->retry);
taosMsleep(duration);
}
pSql->retryReason = rpcMsg->code;
rpcMsg->code = tscRenewTableMeta(pSql);
// if there is an error occurring, proceed to the following error handling procedure.
if (rpcMsg->code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
taosReleaseRef(tscObjRef, handle);
rpcFreeCont(rpcMsg->pCont);
return;
}
}
}
......@@ -511,6 +533,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
}
bool shouldFree = tscShouldBeFreed(pSql);
if (rpcMsg->code != TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
if (rpcMsg->code != TSDB_CODE_SUCCESS) {
pRes->code = rpcMsg->code;
......@@ -962,7 +985,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
pQueryMsg->numOfGroupCols = htons(pQueryInfo->groupbyExpr.numOfGroupCols);
pQueryMsg->queryType = htonl(pQueryInfo->type);
pQueryMsg->prevResultLen = htonl(pQueryInfo->bufLen);
// set column list ids
size_t numOfCols = taosArrayGetSize(pQueryInfo->colList);
char *pMsg = (char *)(pQueryMsg->tableCols) + numOfCols * sizeof(SColumnInfo);
......@@ -1148,21 +1171,21 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
pMsg += sqlLen;
/*
//MSG EXTEND DEMO
pQueryMsg->extend = 1;
STLV *tlv = (STLV *)pMsg;
tlv->type = htons(TLV_TYPE_DUMMY);
tlv->len = htonl(sizeof(int16_t));
*(int16_t *)tlv->value = htons(12345);
tlv->type = htons(TLV_TYPE_META_VERSION);
tlv->len = htonl(sizeof(int16_t) * 2);
*(int16_t*)tlv->value = htons(pTableMeta->sversion);
*(int16_t*)(tlv->value+sizeof(int16_t)) = htons(pTableMeta->tversion);
pMsg += sizeof(*tlv) + ntohl(tlv->len);
tlv = (STLV *)pMsg;
tlv->type = htons(TLV_TYPE_END_MARK);
tlv->len = 0;
pMsg += sizeof(*tlv);
*/
int32_t msgLen = (int32_t)(pMsg - pCmd->payload);
......@@ -1859,6 +1882,13 @@ int tscProcessRetrieveGlobalMergeRsp(SSqlObj *pSql) {
tscDebug("0x%"PRIx64" create QInfo 0x%"PRIx64" to execute query processing", pSql->self, pSql->self);
pQueryInfo->pQInfo = createQInfoFromQueryNode(pQueryInfo, &tableGroupInfo, NULL, NULL, pRes->pMerger, MERGE_STAGE, pSql->self);
if (pQueryInfo->pQInfo == NULL) {
taosHashCleanup(tableGroupInfo.map);
taosArrayDestroy(&group);
tscAsyncResultOnError(pSql);
pRes->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
return pRes->code;
}
}
uint64_t localQueryId = pSql->self;
......@@ -1866,6 +1896,7 @@ int tscProcessRetrieveGlobalMergeRsp(SSqlObj *pSql) {
bool convertJson = true;
if (pQueryInfo->isStddev == true) convertJson = false;
convertQueryResult(pRes, pQueryInfo, pSql->self, true, convertJson);
pRes->code = pQueryInfo->pQInfo->code;
code = pRes->code;
if (pRes->code == TSDB_CODE_SUCCESS) {
......@@ -2690,7 +2721,9 @@ int tscProcessQueryRsp(SSqlObj *pSql) {
pRes->data = NULL;
tscResetForNextRetrieve(pRes);
tscDebug("0x%"PRIx64" query rsp received, qId:0x%"PRIx64, pSql->self, pRes->qId);
return 0;
}
......@@ -2702,7 +2735,7 @@ static void decompressQueryColData(SSqlObj *pSql, SSqlRes *pRes, SQueryInfo* pQu
compSizes = (int32_t *)(pData + compLen);
TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, numOfCols - 1);
int16_t offset = tscFieldInfoGetOffset(pQueryInfo, numOfCols - 1);
int32_t offset = tscFieldInfoGetOffset(pQueryInfo, numOfCols - 1);
char *outputBuf = tcalloc(pRes->numOfRows, (pField->bytes + offset));
char *p = outputBuf;
......@@ -2803,11 +2836,12 @@ int tscProcessRetrieveRspFromNode(SSqlObj *pSql) {
pRes->row = 0;
tscDebug("0x%"PRIx64" numOfRows:%d, offset:%" PRId64 ", complete:%d, qId:0x%"PRIx64, pSql->self, pRes->numOfRows, pRes->offset,
pRes->completed, pRes->qId);
pRes->completed, pRes->qId);
return 0;
}
void tscTableMetaCallBack(void *param, TAOS_RES *res, int code);
static int32_t getTableMetaFromMnode(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo, bool autocreate) {
......
......@@ -137,7 +137,7 @@ static SSqlObj *taosConnectImpl(const char *ip, const char *user, const char *pa
char tmp[TSDB_DB_NAME_LEN] = {0};
tstrncpy(tmp, db, sizeof(tmp));
strdequote(tmp);
stringProcess(tmp, (int32_t)strlen(tmp));
strtolower(pObj->db, tmp);
}
......@@ -547,6 +547,28 @@ int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) {
return pRes->numOfRows;
}
TAOS_ROW *taos_result_block(TAOS_RES *res) {
SSqlObj *pSql = (SSqlObj *)res;
if (pSql == NULL || pSql->signature != pSql) {
terrno = TSDB_CODE_TSC_DISCONNECTED;
return NULL;
}
SSqlCmd *pCmd = &pSql->cmd;
SSqlRes *pRes = &pSql->res;
if (pCmd == NULL ||
pRes == NULL ||
pRes->qId == 0 ||
pRes->code == TSDB_CODE_TSC_QUERY_CANCELLED ||
pCmd->command == TSDB_SQL_RETRIEVE_EMPTY_RESULT ||
pCmd->command == TSDB_SQL_INSERT) {
return NULL;
}
return &pRes->urow;
}
int taos_select_db(TAOS *taos, const char *db) {
char sql[256] = {0};
......
......@@ -211,6 +211,7 @@ static void tscProcessStreamQueryCallback(void *param, TAOS_RES *tres, int numOf
tfree(pSql->pSubs);
pSql->subState.numOfSub = 0;
pSql->parseRetry = 0;
int32_t code = tsParseSql(pSql, true);
if (code == TSDB_CODE_SUCCESS) {
cbParseSql(pStream, pSql, code);
......@@ -220,6 +221,7 @@ static void tscProcessStreamQueryCallback(void *param, TAOS_RES *tres, int numOf
tscError("0x%"PRIx64" open stream failed, code:%s", pSql->self, tstrerror(code));
taosReleaseRef(tscObjRef, pSql->self);
free(pStream);
return;
}
// tscSetRetryTimer(pStream, pStream->pSql, retryDelay);
......
......@@ -3902,8 +3902,11 @@ void* createQInfoFromQueryNode(SQueryInfo* pQueryInfo, STableGroupInfo* pTableGr
STsBufInfo bufInfo = {0};
SQueryParam param = {.pOperator = pa};
/*int32_t code = */initQInfo(&bufInfo, NULL, pSourceOperator, pQInfo, &param, NULL, 0, merger);
int32_t code = initQInfo(&bufInfo, NULL, pSourceOperator, pQInfo, &param, NULL, 0, merger);
taosArrayDestroy(&pa);
if (code != TSDB_CODE_SUCCESS) {
goto _cleanup;
}
return pQInfo;
......
......@@ -1479,6 +1479,18 @@ void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQue
break;
}
}
// set input data order to param[1]
if(pex->base.functionId == TSDB_FUNC_FIRST || pex->base.functionId == TSDB_FUNC_FIRST_DST ||
pex->base.functionId == TSDB_FUNC_LAST || pex->base.functionId == TSDB_FUNC_LAST_DST) {
// set input order
SQueryInfo* pInputQI = pSqlObjList[0]->cmd.pQueryInfo;
if(pInputQI) {
pex->base.numOfParams = 3;
pex->base.param[2].nType = TSDB_DATA_TYPE_INT;
pex->base.param[2].i64 = pInputQI->order.order;
}
}
}
tscDebug("0x%"PRIx64" create QInfo 0x%"PRIx64" to execute the main query while all nest queries are ready", pSql->self, pSql->self);
......@@ -2357,7 +2369,7 @@ TAOS_FIELD* tscFieldInfoGetField(SFieldInfo* pFieldInfo, int32_t index) {
return &((SInternalField*)TARRAY_GET_ELEM(pFieldInfo->internalField, index))->field;
}
int16_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index) {
int32_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index) {
SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, index);
assert(pInfo != NULL && pInfo->pExpr->pExpr == NULL);
......@@ -2906,7 +2918,7 @@ void tscColumnListDestroy(SArray* pColumnList) {
*
*/
static int32_t validateQuoteToken(SStrToken* pToken, bool escapeEnabled, bool *dbIncluded) {
tscDequoteAndTrimToken(pToken);
if(pToken->z[0] != TS_BACKQUOTE_CHAR) pToken->n = stringProcess(pToken->z, pToken->n);
int32_t k = tGetToken(pToken->z, &pToken->type);
......@@ -2920,94 +2932,6 @@ static int32_t validateQuoteToken(SStrToken* pToken, bool escapeEnabled, bool *d
return TSDB_CODE_SUCCESS;
}
void tscDequoteAndTrimToken(SStrToken* pToken) {
uint32_t first = 0, last = pToken->n;
// trim leading spaces
while (first < last) {
char c = pToken->z[first];
if (c != ' ' && c != '\t') {
break;
}
first++;
}
// trim ending spaces
while (first < last) {
char c = pToken->z[last - 1];
if (c != ' ' && c != '\t') {
break;
}
last--;
}
// there are still at least two characters
if (first < last - 1) {
char c = pToken->z[first];
// dequote
if ((c == '\'' || c == '"') && c == pToken->z[last - 1]) {
first++;
last--;
}
}
// left shift the string and pad spaces
for (uint32_t i = 0; i + first < last; i++) {
pToken->z[i] = pToken->z[first + i];
}
for (uint32_t i = last - first; i < pToken->n; i++) {
pToken->z[i] = ' ';
}
// adjust token length
pToken->n = last - first;
}
void tscRmEscapeAndTrimToken(SStrToken* pToken) {
uint32_t first = 0, last = pToken->n;
// trim leading spaces
while (first < last) {
char c = pToken->z[first];
if (c != ' ' && c != '\t') {
break;
}
first++;
}
// trim ending spaces
while (first < last) {
char c = pToken->z[last - 1];
if (c != ' ' && c != '\t') {
break;
}
last--;
}
// there are still at least two characters
if (first < last - 1) {
char c = pToken->z[first];
// dequote
if ((c == '`') && c == pToken->z[last - 1]) {
first++;
last--;
}
}
// left shift the string and pad spaces
for (uint32_t i = 0; i + first < last; i++) {
pToken->z[i] = pToken->z[first + i];
}
for (uint32_t i = last - first; i < pToken->n; i++) {
pToken->z[i] = ' ';
}
// adjust token length
pToken->n = last - first;
}
int32_t tscValidateName(SStrToken* pToken, bool escapeEnabled, bool *dbIncluded) {
if (pToken == NULL || pToken->z == NULL
|| (pToken->type != TK_STRING && pToken->type != TK_ID)) {
......@@ -3015,7 +2939,7 @@ int32_t tscValidateName(SStrToken* pToken, bool escapeEnabled, bool *dbIncluded)
}
if ((!escapeEnabled) && pToken->type == TK_ID) {
if (pToken->z[0] == TS_ESCAPE_CHAR) {
if (pToken->z[0] == TS_BACKQUOTE_CHAR) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
}
......@@ -3033,7 +2957,7 @@ int32_t tscValidateName(SStrToken* pToken, bool escapeEnabled, bool *dbIncluded)
if (pToken->type == TK_STRING) {
tscDequoteAndTrimToken(pToken);
if(pToken->z[0] != TS_BACKQUOTE_CHAR) pToken->n = stringProcess(pToken->z, pToken->n);
// tscStrToLower(pToken->z, pToken->n);
strntolower(pToken->z, pToken->z, pToken->n);
//pToken->n = (uint32_t)strtrim(pToken->z);
......@@ -3053,7 +2977,7 @@ int32_t tscValidateName(SStrToken* pToken, bool escapeEnabled, bool *dbIncluded)
return tscValidateName(pToken, escapeEnabled, NULL);
}
} else if (pToken->type == TK_ID) {
tscRmEscapeAndTrimToken(pToken);
if(pToken->z[0] == TS_BACKQUOTE_CHAR) pToken->n = stringProcess(pToken->z, pToken->n);
if (pToken->n == 0) {
return TSDB_CODE_TSC_INVALID_OPERATION;
......@@ -3114,7 +3038,7 @@ int32_t tscValidateName(SStrToken* pToken, bool escapeEnabled, bool *dbIncluded)
}
if (escapeEnabled && pToken->type == TK_ID) {
tscRmEscapeAndTrimToken(pToken);
if(pToken->z[0] == TS_BACKQUOTE_CHAR) pToken->n = stringProcess(pToken->z, pToken->n);
}
// re-build the whole name string
......@@ -4303,6 +4227,11 @@ void executeQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo) {
// create sub query to handle the sub query.
SQueryInfo* pq = tscGetQueryInfo(&psub->cmd);
STableMetaInfo* pSubMeta = tscGetMetaInfo(pq, 0);
if (UTIL_TABLE_IS_SUPER_TABLE(pSubMeta) &&
pq->command == TSDB_SQL_RETRIEVE_EMPTY_RESULT) {
psub->cmd.command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
}
executeQuery(psub, pq);
}
......
......@@ -289,7 +289,7 @@ char Compressor[32] = "ZSTD_COMPRESSOR"; // ZSTD_COMPRESSOR or GZIP_COMPRES
#endif
// long query death-lock
int8_t tsDeadLockKillQuery = 0;
int8_t tsDeadLockKillQuery = 1;
// default JSON string type
char tsDefaultJSONStrType[7] = "nchar";
......
......@@ -50,7 +50,7 @@ SSchema tGetUserSpecifiedColumnSchema(tVariant* pVal, SStrToken* exprStr, const
} else {
size_t tlen = MIN(sizeof(s.name), exprStr->n + 1);
tstrncpy(s.name, exprStr->z, tlen);
strdequote(s.name);
stringProcess(s.name, (int32_t)strlen(s.name));
}
return s;
......@@ -163,7 +163,7 @@ char *tableNameGetPosition(SStrToken* pToken, char target) {
return pToken->z + i;
}
if (*(pToken->z + i) == TS_ESCAPE_CHAR) {
if (*(pToken->z + i) == TS_BACKQUOTE_CHAR) {
if (!inQuote) {
inEscape = !inEscape;
}
......@@ -223,7 +223,7 @@ void extractTableNameFromToken(SStrToken* pToken, SStrToken* pTable) {
char* r = tableNameGetPosition(pToken, sep);
if (r != NULL) { // record the table name token
if (pToken->z[0] == TS_ESCAPE_CHAR && *(r - 1) == TS_ESCAPE_CHAR) {
if (pToken->z[0] == TS_BACKQUOTE_CHAR && *(r - 1) == TS_BACKQUOTE_CHAR) {
pTable->n = (uint32_t)(r - pToken->z - 2);
pTable->z = pToken->z + 1;
} else {
......
......@@ -87,7 +87,7 @@ void tVariantCreateExt(tVariant *pVar, SStrToken *token, int32_t optrType, bool
case TSDB_DATA_TYPE_BINARY: {
pVar->pz = strndup(token->z, token->n);
pVar->nLen = needRmquoteEscape ? strRmquoteEscape(pVar->pz, token->n) : token->n;
pVar->nLen = needRmquoteEscape ? stringProcess(pVar->pz, token->n) : token->n;
break;
}
case TSDB_DATA_TYPE_TIMESTAMP: {
......
src/TDengineDriver/bin/
src/TDengineDriver/obj/
src/test/Cases/bin/
src/test/Cases/obj/
src/test/FunctionTest/bin/
src/test/FunctionTest/obj/
src/test/XUnitTest/bin/
src/test/XUnitTest/obj/
src/test/doc/
......
......@@ -11,7 +11,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{CB8E6458-3
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XUnitTest", "src\test\XUnitTest\XUnitTest.csproj", "{64C0A478-2591-4459-9F8F-A70F37976A41}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cases", "src\test\Cases\Cases.csproj", "{19A69D26-66BF-4227-97BE-9B087BC76B2F}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FunctionTest", "src\test\FunctionTest\FunctionTest.csproj", "{E66B034B-4677-4BFB-8B87-84715D281E21}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
......@@ -50,23 +50,23 @@ Global
{64C0A478-2591-4459-9F8F-A70F37976A41}.Release|x64.Build.0 = Release|Any CPU
{64C0A478-2591-4459-9F8F-A70F37976A41}.Release|x86.ActiveCfg = Release|Any CPU
{64C0A478-2591-4459-9F8F-A70F37976A41}.Release|x86.Build.0 = Release|Any CPU
{19A69D26-66BF-4227-97BE-9B087BC76B2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19A69D26-66BF-4227-97BE-9B087BC76B2F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19A69D26-66BF-4227-97BE-9B087BC76B2F}.Debug|x64.ActiveCfg = Debug|Any CPU
{19A69D26-66BF-4227-97BE-9B087BC76B2F}.Debug|x64.Build.0 = Debug|Any CPU
{19A69D26-66BF-4227-97BE-9B087BC76B2F}.Debug|x86.ActiveCfg = Debug|Any CPU
{19A69D26-66BF-4227-97BE-9B087BC76B2F}.Debug|x86.Build.0 = Debug|Any CPU
{19A69D26-66BF-4227-97BE-9B087BC76B2F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19A69D26-66BF-4227-97BE-9B087BC76B2F}.Release|Any CPU.Build.0 = Release|Any CPU
{19A69D26-66BF-4227-97BE-9B087BC76B2F}.Release|x64.ActiveCfg = Release|Any CPU
{19A69D26-66BF-4227-97BE-9B087BC76B2F}.Release|x64.Build.0 = Release|Any CPU
{19A69D26-66BF-4227-97BE-9B087BC76B2F}.Release|x86.ActiveCfg = Release|Any CPU
{19A69D26-66BF-4227-97BE-9B087BC76B2F}.Release|x86.Build.0 = Release|Any CPU
{E66B034B-4677-4BFB-8B87-84715D281E21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E66B034B-4677-4BFB-8B87-84715D281E21}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E66B034B-4677-4BFB-8B87-84715D281E21}.Debug|x64.ActiveCfg = Debug|Any CPU
{E66B034B-4677-4BFB-8B87-84715D281E21}.Debug|x64.Build.0 = Debug|Any CPU
{E66B034B-4677-4BFB-8B87-84715D281E21}.Debug|x86.ActiveCfg = Debug|Any CPU
{E66B034B-4677-4BFB-8B87-84715D281E21}.Debug|x86.Build.0 = Debug|Any CPU
{E66B034B-4677-4BFB-8B87-84715D281E21}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E66B034B-4677-4BFB-8B87-84715D281E21}.Release|Any CPU.Build.0 = Release|Any CPU
{E66B034B-4677-4BFB-8B87-84715D281E21}.Release|x64.ActiveCfg = Release|Any CPU
{E66B034B-4677-4BFB-8B87-84715D281E21}.Release|x64.Build.0 = Release|Any CPU
{E66B034B-4677-4BFB-8B87-84715D281E21}.Release|x86.ActiveCfg = Release|Any CPU
{E66B034B-4677-4BFB-8B87-84715D281E21}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{5BED7402-0A65-4ED9-A491-C56BFB518045} = {A1FB5B66-E32F-4789-9BE9-042E5BD21087}
{CB8E6458-31E1-4351-B704-1B918E998654} = {A1FB5B66-E32F-4789-9BE9-042E5BD21087}
{64C0A478-2591-4459-9F8F-A70F37976A41} = {CB8E6458-31E1-4351-B704-1B918E998654}
{19A69D26-66BF-4227-97BE-9B087BC76B2F} = {CB8E6458-31E1-4351-B704-1B918E998654}
{E66B034B-4677-4BFB-8B87-84715D281E21} = {CB8E6458-31E1-4351-B704-1B918E998654}
EndGlobalSection
EndGlobal
......@@ -87,7 +87,7 @@ namespace TDengineDriver
case TDengineDataType.TSDB_DATA_TYPE_DOUBLE:
return "DOUBLE";
case TDengineDataType.TSDB_DATA_TYPE_BINARY:
return "STRING";
return "BINARY";
case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP:
return "TIMESTAMP";
case TDengineDataType.TSDB_DATA_TYPE_NCHAR:
......
......@@ -4,7 +4,7 @@
<TargetFrameworks>net5;netstandard2.0;net45</TargetFrameworks>
<PackageId>TDengine.Connector</PackageId>
<PackageIcon>logo.jpg</PackageIcon>
<Version>1.0.3</Version>
<Version>1.0.4</Version>
<Authors>taosdata</Authors>
<Company>www.taosdata.com</Company>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
......@@ -14,7 +14,7 @@
This C # connector supports: Linux 64/Windows x64/Windows x86.
more information please visit: https://www.taosdata.com
</Description>
<RepositoryUrl>https://github.com/taosdata/TDengine/tree/develop/src/connector/C%23</RepositoryUrl>
<RepositoryUrl>https://github.com/taosdata/TDengine/tree/develop/src/connector/C%2523/src/TDengineDriver</RepositoryUrl>
<NoWarn>CS1591</NoWarn>
</PropertyGroup>
<ItemGroup>
......
......@@ -436,49 +436,46 @@ namespace TDengineDriver
{
TAOS_MULTI_BIND multiBind = new TAOS_MULTI_BIND();
int elementCount = arr.Length;
//TypeSize represent the Max element length of the comming arr
//The size of the buffer is typeSize * elementCount
//This buffer is used to store TAOS_MULTI_BIND.buffer
int typeSize = MaxElementLength(arr);
//This intSize is used to calcuate buffer size of the struct TAOS_MULTI_BIND's
//length. The buffer is intSize * elementCount,which is used to store TAOS_MULTI_BIND.length
int intSize = sizeof(int);
//This byteSize is used to calculate the buffer size of the struct TAOS_MULTI_BIND.is_null
//This buffer size is byteSize * elementCount
int byteSize = sizeof(byte);
StringBuilder arrStrBuilder = new StringBuilder(); ;
StringBuilder arrStrBuilder = new StringBuilder(); ;
//TAOS_MULTI_BIND.length
IntPtr lengthArr = Marshal.AllocHGlobal(intSize * elementCount);
//TAOS_MULTI_BIND.is_null
IntPtr nullArr = Marshal.AllocHGlobal(byteSize * elementCount);
//TAOS_MULTI_BIND.buffer
IntPtr uNcharBuff = Marshal.AllocHGlobal(typeSize * elementCount);
for (int i = 0; i < elementCount; i++)
{
int itemLength = 0;
byte[] decodeByte = GetStringEncodeByte(arr[i]);
itemLength = decodeByte.Length;
// if element if not null and element length is less then typeSize
// fill the memory with default char.Since arr element memory need align.
if (!String.IsNullOrEmpty(arr[i]) && typeSize == itemLength)
{
arrStrBuilder.Append(arr[i]);
}
else if (!String.IsNullOrEmpty(arr[i]) && typeSize > itemLength)
{
arrStrBuilder.Append(arr[i]);
arrStrBuilder.Append(AlignCharArr(typeSize - itemLength));
}
else
if (!String.IsNullOrEmpty(arr[i]))
{
// if is null value,fill the memory with default values.
arrStrBuilder.Append(AlignCharArr(typeSize));
for (int j = 0; j < itemLength; j++)
{
//Read byte after byte
Marshal.WriteByte(uNcharBuff, i * typeSize + j, decodeByte[j]);
}
}
//set TAOS_MULTI_BIND.length
Marshal.WriteInt32(lengthArr, intSize * i, typeSize);
//set TAOS_MULTI_BIND.is_null
//Set TAOS_MULTI_BIND.length
Marshal.WriteInt32(lengthArr, intSize * i, itemLength);
//Set TAOS_MULTI_BIND.is_null
Marshal.WriteByte(nullArr, byteSize * i, Convert.ToByte(String.IsNullOrEmpty(arr[i]) ? 1 : 0));
}
//set TAOS_MULTI_BIND.buffer
IntPtr uBinaryBuff = (IntPtr)Marshal.StringToHGlobalAnsi(arrStrBuilder.ToString());
//config TAOS_MULTI_BIND
//Config TAOS_MULTI_BIND
multiBind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_BINARY;
multiBind.buffer = uBinaryBuff;
multiBind.buffer = uNcharBuff;
multiBind.buffer_length = (ulong)typeSize;
multiBind.length = lengthArr;
multiBind.is_null = nullArr;
......@@ -491,47 +488,43 @@ namespace TDengineDriver
{
TAOS_MULTI_BIND multiBind = new TAOS_MULTI_BIND();
int elementCount = arr.Length;
//TypeSize represent the Max element length of the comming arr
//The size of the buffer is typeSize * elementCount
//This buffer is used to store TAOS_MULTI_BIND.buffer
int typeSize = MaxElementLength(arr);
//This intSize is used to calcuate buffer size of the struct TAOS_MULTI_BIND's
//length. The buffer is intSize * elementCount,which is used to store TAOS_MULTI_BIND.length
int intSize = sizeof(int);
//This byteSize is used to calculate the buffer size of the struct TAOS_MULTI_BIND.is_null
//This buffer size is byteSize * elementCount
int byteSize = sizeof(byte);
StringBuilder arrStrBuilder = new StringBuilder(); ;
//TAOS_MULTI_BIND.length
IntPtr lengthArr = Marshal.AllocHGlobal(intSize * elementCount);
//TAOS_MULTI_BIND.is_null
IntPtr nullArr = Marshal.AllocHGlobal(byteSize * elementCount);
//TAOS_MULTI_BIND.buffer
IntPtr uNcharBuff = Marshal.AllocHGlobal(typeSize * elementCount);
for (int i = 0; i < elementCount; i++)
{
int itemLength = 0;
byte[] decodeByte = GetStringEncodeByte(arr[i]);
itemLength = decodeByte.Length;
// if element if not null and element length is less then typeSize
// fill the memory with default char.Since arr element memory need align.
if (!String.IsNullOrEmpty(arr[i]) && typeSize == itemLength)
{
arrStrBuilder.Append(arr[i]);
}
else if (!String.IsNullOrEmpty(arr[i]) && typeSize > itemLength)
if (!String.IsNullOrEmpty(arr[i]))
{
arrStrBuilder.Append(arr[i]);
arrStrBuilder.Append(AlignCharArr(typeSize - itemLength));
for (int j = 0; j < itemLength; j++)
{
//Read byte after byte
Marshal.WriteByte(uNcharBuff, i * typeSize + j, decodeByte[j]);
}
}
else
{
// if is null value,fill the memory with default values.
arrStrBuilder.Append(AlignCharArr(typeSize));
}
//set TAOS_MULTI_BIND.length
Marshal.WriteInt32(lengthArr, intSize * i, typeSize);
//set TAOS_MULTI_BIND.is_null
//Set TAOS_MULTI_BIND.length
Marshal.WriteInt32(lengthArr, intSize * i, itemLength);
//Set TAOS_MULTI_BIND.is_null
Marshal.WriteByte(nullArr, byteSize * i, Convert.ToByte(String.IsNullOrEmpty(arr[i]) ? 1 : 0));
}
//set TAOS_MULTI_BIND.buffer
IntPtr uNcharBuff = (IntPtr)Marshal.StringToHGlobalAnsi(arrStrBuilder.ToString());
//config TAOS_MULTI_BIND
//Config TAOS_MULTI_BIND
multiBind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_NCHAR;
multiBind.buffer = uNcharBuff;
multiBind.buffer_length = (ulong)typeSize;
......@@ -612,16 +605,16 @@ namespace TDengineDriver
}
private static Byte[] GetStringEncodeByte(string str)
{
{
Byte[] strToBytes = null;
if(String.IsNullOrEmpty(str))
if (String.IsNullOrEmpty(str))
{
strToBytes = System.Text.Encoding.Default.GetBytes(String.Empty);
}
else
{
strToBytes = System.Text.Encoding.Default.GetBytes(str);
}
}
return strToBytes;
}
}
......
using System;
using Test.UtilsTools;
using System.Collections.Generic;
namespace Cases
{
public class FetchLengthCase
{
/// <author>xiaolei</author>
/// <Name>TestRetrieveBinary</Name>
/// <describe>TD-12103 C# connector fetch_row with binary data retrieving error</describe>
/// <filename>FetchLength.cs</filename>
/// <result>pass or failed </result>
public void TestRetrieveBinary(IntPtr conn)
{
string sql1 = "create stable stb1 (ts timestamp, name binary(10)) tags(n int);";
string sql2 = "insert into tb1 using stb1 tags(1) values(now, 'log');";
string sql3 = "insert into tb2 using stb1 tags(2) values(now, 'test');";
string sql4 = "insert into tb3 using stb1 tags(3) values(now, 'db02');";
string sql5 = "insert into tb4 using stb1 tags(4) values(now, 'db3');";
string sql6 = "select distinct(name) from stb1;";//
UtilsTools.ExecuteQuery(conn, sql1);
UtilsTools.ExecuteQuery(conn, sql2);
UtilsTools.ExecuteQuery(conn, sql3);
UtilsTools.ExecuteQuery(conn, sql4);
UtilsTools.ExecuteQuery(conn, sql5);
IntPtr resPtr = IntPtr.Zero;
resPtr = UtilsTools.ExecuteQuery(conn, sql6);
List<List<string>> result = UtilsTools.GetResultSet(resPtr);
List<string> colname = result[0];
List<string> data = result[1];
UtilsTools.AssertEqual("db3", data[0]);
UtilsTools.AssertEqual("log", data[1]);
UtilsTools.AssertEqual("db02", data[2]);
UtilsTools.AssertEqual("test", data[3]);
}
}
}
using System;
using Test.UtilsTools;
using Cases;
namespace Cases.EntryPoint
{
class Program
{
static void Main(string[] args)
{
IntPtr conn = IntPtr.Zero;
IntPtr stmt = IntPtr.Zero;
IntPtr res = IntPtr.Zero;
conn = UtilsTools.TDConnection("127.0.0.1", "root", "taosdata", "", 0);
UtilsTools.ExecuteUpdate(conn, "drop database if exists csharp");
UtilsTools.ExecuteUpdate(conn, "create database if not exists csharp keep 3650");
UtilsTools.ExecuteUpdate(conn, "use csharp");
Console.WriteLine("====================StableColumnByColumn===================");
StableColumnByColumn columnByColumn = new StableColumnByColumn();
columnByColumn.Test(conn, "stablecolumnbycolumn");
Console.WriteLine("====================StmtStableQuery===================");
StmtStableQuery stmtStableQuery = new StmtStableQuery();
stmtStableQuery.Test(conn, "stablecolumnbycolumn");
Console.WriteLine("====================StableMutipleLine===================");
StableMutipleLine mutipleLine = new StableMutipleLine();
mutipleLine.Test(conn, "stablemutipleline");
//================================================================================
Console.WriteLine("====================NtableSingleLine===================");
NtableSingleLine ntableSingleLine = new NtableSingleLine();
ntableSingleLine.Test(conn, "stablesingleline");
IntPtr resPtr = UtilsTools.ExecuteQuery(conn, "select * from stablesingleline ");
UtilsTools.DisplayRes(resPtr);
Console.WriteLine("====================NtableMutipleLine===================");
NtableMutipleLine ntableMutipleLine = new NtableMutipleLine();
ntableMutipleLine.Test(conn, "ntablemutipleline");
Console.WriteLine("====================StmtNtableQuery===================");
StmtNtableQuery stmtNtableQuery = new StmtNtableQuery();
stmtNtableQuery.Test(conn, "ntablemutipleline");
Console.WriteLine("====================NtableColumnByColumn===================");
NtableColumnByColumn ntableColumnByColumn = new NtableColumnByColumn();
ntableColumnByColumn.Test(conn, "ntablecolumnbycolumn");
Console.WriteLine("====================fetchfeilds===================");
FetchFields fetchFields = new FetchFields();
fetchFields.Test(conn, "fetchfeilds");
StableStmtCases stableStmtCases = new StableStmtCases();
Console.WriteLine("====================stableStmtCases.TestBindSingleLineCn===================");
stableStmtCases.TestBindSingleLineCn(conn, "stablestmtcasestestbindsinglelinecn");
Console.WriteLine("====================stableStmtCases.TestBindColumnCn===================");
stableStmtCases.TestBindColumnCn(conn, " stablestmtcasestestbindcolumncn");
Console.WriteLine("====================stableStmtCases.TestBindMultiLineCn===================");
stableStmtCases.TestBindMultiLineCn(conn, "stablestmtcasestestbindmultilinecn");
NormalTableStmtCases normalTableStmtCases = new NormalTableStmtCases();
Console.WriteLine("====================normalTableStmtCases.TestBindSingleLineCn===================");
normalTableStmtCases.TestBindSingleLineCn(conn, "normaltablestmtcasestestbindsinglelinecn");
Console.WriteLine("====================normalTableStmtCases.TestBindColumnCn===================");
normalTableStmtCases.TestBindColumnCn(conn, "normaltablestmtcasestestbindcolumncn");
Console.WriteLine("====================normalTableStmtCases.TestBindMultiLineCn===================");
normalTableStmtCases.TestBindMultiLineCn(conn, "normaltablestmtcasestestbindmultilinecn");
Console.WriteLine("===================JsonTagTest====================");
JsonTagTest jsonTagTest = new JsonTagTest();
jsonTagTest.Test(conn);
Console.WriteLine("====================fetchLengthCase===================");
FetchLengthCase fetchLengthCase = new FetchLengthCase();
fetchLengthCase.TestRetrieveBinary(conn);
UtilsTools.ExecuteQuery(conn, "drop database if exists csharp");
UtilsTools.CloseConnection(conn);
UtilsTools.ExitProgram();
}
}
}
using System;
using Test.UtilsTools;
using TDengineDriver;
using Test.UtilsTools.DataSource;
namespace Cases
{
public class StableMutipleLine
{
TAOS_BIND[] tags = DataSource.getTags();
TAOS_MULTI_BIND[] mbind = DataSource.GetMultiBindArr();
public void Test(IntPtr conn, string tableName)
{
String createTb = "create stable " + tableName + " (ts timestamp ,b bool,v1 tinyint,v2 smallint,v4 int,v8 bigint,f4 float,f8 double,u1 tinyint unsigned,u2 smallint unsigned,u4 int unsigned,u8 bigint unsigned,bin binary(200),blob nchar(200))tags(bo bool,tt tinyint,si smallint,ii int,bi bigint,tu tinyint unsigned,su smallint unsigned,iu int unsigned,bu bigint unsigned,ff float ,dd double ,bb binary(200),nc nchar(200));";
String insertSql = "insert into ? using " + tableName + " tags(?,?,?,?,?,?,?,?,?,?,?,?,?) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
UtilsTools.ExecuteUpdate(conn, createTb);
IntPtr stmt = StmtUtilTools.StmtInit(conn);
StmtUtilTools.StmtPrepare(stmt, insertSql);
StmtUtilTools.SetTableNameTags(stmt, tableName + "_t1", tags);
StmtUtilTools.BindParamBatch(stmt, mbind);
StmtUtilTools.AddBatch(stmt);
StmtUtilTools.StmtExecute(stmt);
StmtUtilTools.StmtClose(stmt);
DataSource.FreeTaosBind(tags);
DataSource.FreeTaosMBind(mbind);
}
}
public class StableColumnByColumn
{
DataSource data = new DataSource();
TAOS_BIND[] tags = DataSource.getTags();
TAOS_MULTI_BIND[] mbind = DataSource.GetMultiBindArr();
public void Test(IntPtr conn, string tableName)
{
String createTb = "create stable " + tableName + " (ts timestamp ,b bool,v1 tinyint,v2 smallint,v4 int,v8 bigint,f4 float,f8 double,u1 tinyint unsigned,u2 smallint unsigned,u4 int unsigned,u8 bigint unsigned,bin binary(200),blob nchar(200))tags(bo bool,tt tinyint,si smallint,ii int,bi bigint,tu tinyint unsigned,su smallint unsigned,iu int unsigned,bu bigint unsigned,ff float ,dd double ,bb binary(200),nc nchar(200));";
String insertSql = "insert into ? using " + tableName + " tags(?,?,?,?,?,?,?,?,?,?,?,?,?) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
UtilsTools.ExecuteUpdate(conn, createTb);
IntPtr stmt = StmtUtilTools.StmtInit(conn);
StmtUtilTools.StmtPrepare(stmt, insertSql);
StmtUtilTools.SetTableNameTags(stmt, tableName + "_t1", tags);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[0], 0);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[1], 1);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[2], 2);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[3], 3);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[4], 4);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[5], 5);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[6], 6);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[7], 7);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[8], 8);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[9], 9);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[10], 10);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[11], 11);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[12], 12);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[13], 13);
StmtUtilTools.AddBatch(stmt);
StmtUtilTools.StmtExecute(stmt);
StmtUtilTools.StmtClose(stmt);
DataSource.FreeTaosBind(tags);
DataSource.FreeTaosMBind(mbind);
}
}
public class StableStmtCases
{
/// <author>xiaolei</author>
/// <Name>StableStmtCases.TestBindSingleLineCn</Name>
/// <describe>Test stmt insert single line of chinese character into stable by column after column </describe>
/// <filename>StmtSTable.cs</filename>
/// <result>pass or failed </result>
public void TestBindSingleLineCn(IntPtr conn, string tableName)
{
TAOS_BIND[] tags = DataSource.getCNTags();
TAOS_BIND[] binds = DataSource.getNtableCNRow();
String createTb = "create stable " + tableName + " (ts timestamp,v1 tinyint,v2 smallint,v4 int,v8 bigint,u1 tinyint unsigned,u2 smallint unsigned,u4 int unsigned,u8 bigint unsigned,f4 float,f8 double,bin binary(200),blob nchar(200),b bool,nilcol int)tags(bo bool,tt tinyint,si smallint,ii int,bi bigint,tu tinyint unsigned,su smallint unsigned,iu int unsigned,bu bigint unsigned,ff float ,dd double ,bb binary(200),nc nchar(200));";
String insertSql = "insert into ? using " + tableName + " tags(?,?,?,?,?,?,?,?,?,?,?,?,?) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
UtilsTools.ExecuteUpdate(conn, createTb);
IntPtr stmt = StmtUtilTools.StmtInit(conn);
StmtUtilTools.StmtPrepare(stmt, insertSql);
StmtUtilTools.SetTableNameTags(stmt, tableName + "_t1", tags);
StmtUtilTools.BindParam(stmt, binds);
StmtUtilTools.AddBatch(stmt);
StmtUtilTools.StmtExecute(stmt);
StmtUtilTools.StmtClose(stmt);
DataSource.FreeTaosBind(tags);
DataSource.FreeTaosBind(binds);
string querySql = "select * from " + tableName;
IntPtr res = UtilsTools.ExecuteQuery(conn, querySql);
UtilsTools.DisplayRes(res);
}
/// <author>xiaolei</author>
/// <Name>StableStmtCases.TestBindColumnCn</Name>
/// <describe>Test stmt insert single line of chinese character into stable by column after column </describe>
/// <filename>StmtSTable.cs</filename>
/// <result>pass or failed </result>
public void TestBindColumnCn(IntPtr conn, string tableName)
{
DataSource data = new DataSource();
TAOS_BIND[] tags = DataSource.getCNTags();
TAOS_MULTI_BIND[] mbind = DataSource.GetMultiBindCNArr();
String createTb = "create stable " + tableName + " (ts timestamp ,b bool,v1 tinyint,v2 smallint,v4 int,v8 bigint,f4 float,f8 double,u1 tinyint unsigned,u2 smallint unsigned,u4 int unsigned,u8 bigint unsigned,bin binary(200),blob nchar(200))tags(bo bool,tt tinyint,si smallint,ii int,bi bigint,tu tinyint unsigned,su smallint unsigned,iu int unsigned,bu bigint unsigned,ff float ,dd double ,bb binary(200),nc nchar(200));";
String insertSql = "insert into ? using " + tableName + " tags(?,?,?,?,?,?,?,?,?,?,?,?,?) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
UtilsTools.ExecuteUpdate(conn, createTb);
IntPtr stmt = StmtUtilTools.StmtInit(conn);
StmtUtilTools.StmtPrepare(stmt, insertSql);
StmtUtilTools.SetTableNameTags(stmt, tableName + "_t1", tags);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[0], 0);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[1], 1);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[2], 2);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[3], 3);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[4], 4);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[5], 5);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[6], 6);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[7], 7);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[8], 8);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[9], 9);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[10], 10);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[11], 11);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[12], 12);
StmtUtilTools.BindSingleParamBatch(stmt, mbind[13], 13);
StmtUtilTools.AddBatch(stmt);
StmtUtilTools.StmtExecute(stmt);
StmtUtilTools.StmtClose(stmt);
DataSource.FreeTaosBind(tags);
DataSource.FreeTaosMBind(mbind);
string querySql = "select * from " + tableName;
IntPtr res = UtilsTools.ExecuteQuery(conn, querySql);
UtilsTools.DisplayRes(res);
}
/// <author>xiaolei</author>
/// <Name>StableStmtCases.TestBindMultiLineCn</Name>
/// <describe>Test stmt insert single line of chinese character into stable by column after column </describe>
/// <filename>StmtSTable.cs</filename>
/// <result>pass or failed </result>
public void TestBindMultiLineCn(IntPtr conn, string tableName)
{
TAOS_BIND[] tags = DataSource.getCNTags();
TAOS_MULTI_BIND[] mbind = DataSource.GetMultiBindCNArr();
String createTb = "create stable " + tableName + " (ts timestamp ,b bool,v1 tinyint,v2 smallint,v4 int,v8 bigint,f4 float,f8 double,u1 tinyint unsigned,u2 smallint unsigned,u4 int unsigned,u8 bigint unsigned,bin binary(200),blob nchar(200))tags(bo bool,tt tinyint,si smallint,ii int,bi bigint,tu tinyint unsigned,su smallint unsigned,iu int unsigned,bu bigint unsigned,ff float ,dd double ,bb binary(200),nc nchar(200));";
String insertSql = "insert into ? using " + tableName + " tags(?,?,?,?,?,?,?,?,?,?,?,?,?) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
UtilsTools.ExecuteUpdate(conn, createTb);
IntPtr stmt = StmtUtilTools.StmtInit(conn);
StmtUtilTools.StmtPrepare(stmt, insertSql);
StmtUtilTools.SetTableNameTags(stmt, tableName + "_t1", tags);
StmtUtilTools.BindParamBatch(stmt, mbind);
StmtUtilTools.AddBatch(stmt);
StmtUtilTools.StmtExecute(stmt);
StmtUtilTools.StmtClose(stmt);
DataSource.FreeTaosBind(tags);
DataSource.FreeTaosMBind(mbind);
string querySql = "select * from " + tableName;
IntPtr res = UtilsTools.ExecuteQuery(conn, querySql);
UtilsTools.DisplayRes(res);
}
}
}
\ No newline at end of file
using System;
using Test.UtilsTools;
using TDengineDriver;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace Cases
{
public class FetchFields
{
public void Test(IntPtr conn, string tableName)
{
IntPtr res = IntPtr.Zero;
String createTb = "create stable " + tableName + " (ts timestamp ,b bool,v1 tinyint,v2 smallint,v4 int,v8 bigint,f4 float,f8 double,u1 tinyint unsigned,u2 smallint unsigned,u4 int unsigned,u8 bigint unsigned,bin binary(200),blob nchar(200))tags(jsontag json);";
String insertSql = "insert into " + tableName + "_t1 using " + tableName + " tags('{\"k1\": \"v1\"}') values(1637064040000,true,1,2,3,4,5,6,7,8,9,10,'XI','XII')";
String selectSql = "select * from " + tableName;
String dropSql = "drop table " + tableName;
UtilsTools.ExecuteQuery(conn, createTb);
UtilsTools.ExecuteQuery(conn, insertSql);
res = UtilsTools.ExecuteQuery(conn, selectSql);
UtilsTools.ExecuteQuery(conn, dropSql);
List<TDengineMeta> metas = new List<TDengineMeta>();
metas = TDengine.FetchFields(res);
if (metas.Capacity == 0)
{
Console.WriteLine("empty result");
}
else
{
foreach(TDengineMeta meta in metas){
Console.WriteLine("col_name:{0},col_type_code:{1},col_type:{2}({3})",meta.name,meta.type,meta.TypeName(),meta.size);
}
}
}
}
}
using System;
using Test.UtilsTools;
using TDengineDriver;
using System.Collections.Generic;
namespace Test.UtilsTools.DataSource
{
public class DataSource
......@@ -23,7 +23,10 @@ namespace Test.UtilsTools.DataSource
public static string[] binaryArrCn = new string[5] { "涛思数据", String.Empty, null, "taosdata涛思数据", "涛思数据TDengine" };
public static string[] NcharArrCn = new string[5] { "涛思数据", null, "taosdata涛思数据", "涛思数据TDengine", String.Empty };
public static TAOS_BIND[] getTags()
// Construct a TAOS_BIND array which contains normal character.
// For stmt bind tags,this will be used as tag info
public static TAOS_BIND[] GetTags()
{
TAOS_BIND[] binds = new TAOS_BIND[13];
binds[0] = TaosBind.BindBool(true);
......@@ -41,8 +44,59 @@ namespace Test.UtilsTools.DataSource
binds[12] = TaosBind.BindNchar("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKZXCVBNM`1234567890-=+_)(*&^%$#@!~[];,./<>?:{}");
return binds;
}
// Get the tag data within and string list
// Which will be retrieved as a string List
private static List<String> GetTagData()
{
List<String> tagData = new List<String>();
tagData.Add(true.ToString());
tagData.Add((-2).ToString());
tagData.Add((short.MaxValue).ToString());
tagData.Add((int.MaxValue).ToString());
tagData.Add((Int64.MaxValue).ToString());
tagData.Add((byte.MaxValue - 1).ToString());
tagData.Add((UInt16.MaxValue - 1).ToString());
tagData.Add((uint.MinValue + 1).ToString());
tagData.Add((UInt64.MinValue + 1).ToString());
tagData.Add((11.11F).ToString());
tagData.Add((22.22D).ToString());
tagData.Add("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKZXCVBNM`1234567890-=+_)(*&^%$#@!~[];,./<>?:{}");
tagData.Add("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKZXCVBNM`1234567890-=+_)(*&^%$#@!~[];,./<>?:{}");
return tagData;
}
public static TAOS_BIND[] getCNTags()
public static List<string> GetMultiBindStableRowData()
{
List<string> rowData = new List<String>();
List<string> tagData = GetTagData();
for (int i = 0; i < tsArr.Length; i++)
{
rowData.Add(tsArr[i].ToString());
rowData.Add(boolArr[i].Equals(null) ? "NULL" : boolArr[i].ToString());
rowData.Add(tinyIntArr[i].Equals(null) ? "NULL" : tinyIntArr[i].ToString());
rowData.Add(shortArr[i].Equals(null) ? "NULL" : shortArr[i].ToString());
rowData.Add(intArr[i].Equals(null) ? "NULL" : intArr[i].ToString());
rowData.Add(longArr[i].Equals(null) ? "NULL" : longArr[i].ToString());
rowData.Add(floatArr[i].Equals(null) ? "NULL" : floatArr[i].ToString());
rowData.Add(doubleArr[i].Equals(null) ? "NULL" : doubleArr[i].ToString());
rowData.Add(uTinyIntArr[i].Equals(null) ? "NULL" : uTinyIntArr[i].ToString());
rowData.Add(uShortArr[i].Equals(null) ? "NULL" : uShortArr[i].ToString());
rowData.Add(uIntArr[i].Equals(null) ? "NULL" : uIntArr[i].ToString());
rowData.Add(uLongArr[i].Equals(null) ? "NULL" : uLongArr[i].ToString());
rowData.Add(String.IsNullOrEmpty(binaryArr[i]) ? "NULL" : binaryArr[i]);
rowData.Add(String.IsNullOrEmpty(ncharArr[i]) ? "NULL" : ncharArr[i]);
rowData.AddRange(tagData);
// Console.WriteLine("binaryArrCn[{0}]:{1},ncharArr[{0}]:{2}",i,String.IsNullOrEmpty(binaryArrCn[i]) ? "NULL" : binaryArrCn[i],String.IsNullOrEmpty(ncharArr[i]) ? "NULL" : NcharArrCn[i]);
// Console.WriteLine("binaryArrCn[{0}]:{1},ncharArr[{0}]:{2}",i,String.IsNullOrEmpty(binaryArrCn[i]) ? 0 :binaryArrCn[i].Length, String.IsNullOrEmpty(ncharArr[i]) ? 0 : NcharArrCn[i].Length);
// Console.WriteLine("========");
}
return rowData;
}
// Construct a TAOS_BIND array which contains chinese character.
// For stmt bind tags,this will be used as tag info
public static TAOS_BIND[] GetCNTags()
{
TAOS_BIND[] binds = new TAOS_BIND[13];
binds[0] = TaosBind.BindBool(true);
......@@ -57,11 +111,32 @@ namespace Test.UtilsTools.DataSource
binds[9] = TaosBind.BindFloat(11.11F);
binds[10] = TaosBind.BindDouble(22.22D);
binds[11] = TaosBind.BindBinary("TDengine涛思数据");
binds[12] = TaosBind.BindNchar("涛思");
binds[12] = TaosBind.BindNchar("涛思数据taos");
return binds;
}
public static TAOS_BIND[] getNtableCNRow()
// Get the tag data within and string list
// Which will be retrieved as a string List
private static List<String> GetTagCnData()
{
List<String> tagData = new List<String>();
tagData.Add(true.ToString());
tagData.Add((-2).ToString());
tagData.Add((short.MaxValue - 1).ToString());
tagData.Add((int.MaxValue - 1).ToString());
tagData.Add((Int64.MaxValue - 1).ToString());
tagData.Add((byte.MaxValue - 1).ToString());
tagData.Add((UInt16.MaxValue - 1).ToString());
tagData.Add((uint.MinValue + 1).ToString());
tagData.Add((UInt64.MinValue + 1).ToString());
tagData.Add((11.11F).ToString());
tagData.Add((22.22D).ToString());
tagData.Add("TDengine涛思数据");
tagData.Add("涛思数据taos");
return tagData;
}
// A line of data that's without CN character.
// Which is construct as an TAOS_BIND array
public static TAOS_BIND[] GetNtableCNRow()
{
TAOS_BIND[] binds = new TAOS_BIND[15];
binds[0] = TaosBind.BindTimestamp(1637064040000);
......@@ -81,8 +156,40 @@ namespace Test.UtilsTools.DataSource
binds[14] = TaosBind.BindNil();
return binds;
}
//Get and list data that will be insert into table
public static List<String> GetNtableCNRowData()
{
var data = new List<string>{
"1637064040000",
"-2",
short.MaxValue.ToString(),
int.MaxValue.ToString(),
Int64.MaxValue.ToString(),
(byte.MaxValue - 1).ToString(),
(UInt16.MaxValue - 1).ToString(),
(uint.MinValue + 1).ToString(),
(UInt64.MinValue + 1).ToString(),
(11.11F).ToString(),
(22.22D).ToString(),
"TDengine数据",
"taosdata涛思数据",
"True",
"NULL"
};
return data;
}
// Get the data value and tag values which have chinese characters
// And retrieved as a string list.This is single Line.
public static List<String> GetStableCNRowData()
{
List<String> columnData = GetNtableCNRowData();
List<String> tagData = GetTagCnData();
columnData.AddRange(tagData);
return columnData;
}
public static TAOS_BIND[] getNtableRow()
// A line of data that's without CN character
public static TAOS_BIND[] GetNtableRow()
{
TAOS_BIND[] binds = new TAOS_BIND[15];
binds[0] = TaosBind.BindTimestamp(1637064040000);
......@@ -102,6 +209,31 @@ namespace Test.UtilsTools.DataSource
binds[14] = TaosBind.BindNil();
return binds;
}
// A List of data ,use as expectResData. The value is equal to getNtableRow()
public static List<String> GetNtableRowData()
{
var data = new List<string>{
"1637064040000",
"-2",
short.MaxValue.ToString(),
int.MaxValue.ToString(),
(Int64.MaxValue).ToString(),
(byte.MaxValue - 1).ToString(),
(UInt16.MaxValue - 1).ToString(),
(uint.MinValue + 1).ToString(),
(UInt64.MinValue + 1).ToString(),
(11.11F).ToString(),
(22.22D).ToString(),
"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKZXCVBNM`1234567890-=+_)(*&^%$#@!~[];,./<>?:{}",
"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKZXCVBNM`1234567890-=+_)(*&^%$#@!~[];,./<>?:{}",
true.ToString(),
"NULL"
};
return data;
}
// Five lines of data, that is construct as taos_mutli_bind array.
// There aren't any CN character
public static TAOS_MULTI_BIND[] GetMultiBindArr()
{
TAOS_MULTI_BIND[] mBinds = new TAOS_MULTI_BIND[14];
......@@ -121,6 +253,35 @@ namespace Test.UtilsTools.DataSource
mBinds[13] = TaosMultiBind.MultiBindNchar(ncharArr);
return mBinds;
}
// A List of data ,use as expectResData. The value is equal to GetMultiBindCNArr()
public static List<string> GetMultiBindResData()
{
var rowData = new List<string>();
for (int i = 0; i < tsArr.Length; i++)
{
rowData.Add(tsArr[i].ToString());
rowData.Add(boolArr[i].Equals(null) ? "NULL" : boolArr[i].ToString());
rowData.Add(tinyIntArr[i].Equals(null) ? "NULL" : tinyIntArr[i].ToString());
rowData.Add(shortArr[i].Equals(null) ? "NULL" : shortArr[i].ToString());
rowData.Add(intArr[i].Equals(null) ? "NULL" : intArr[i].ToString());
rowData.Add(longArr[i].Equals(null) ? "NULL" : longArr[i].ToString());
rowData.Add(floatArr[i].Equals(null) ? "NULL" : floatArr[i].ToString());
rowData.Add(doubleArr[i].Equals(null) ? "NULL" : doubleArr[i].ToString());
rowData.Add(uTinyIntArr[i].Equals(null) ? "NULL" : uTinyIntArr[i].ToString());
rowData.Add(uShortArr[i].Equals(null) ? "NULL" : uShortArr[i].ToString());
rowData.Add(uIntArr[i].Equals(null) ? "NULL" : uIntArr[i].ToString());
rowData.Add(uLongArr[i].Equals(null) ? "NULL" : uLongArr[i].ToString());
rowData.Add(String.IsNullOrEmpty(binaryArr[i]) ? "NULL" : binaryArr[i]);
rowData.Add(String.IsNullOrEmpty(ncharArr[i]) ? "NULL" : ncharArr[i]);
// Console.WriteLine("binaryArrCn[{0}]:{1},NcharArrCn[{0}]:{2}",i,String.IsNullOrEmpty(binaryArrCn[i]) ? "NULL" : binaryArrCn[i],String.IsNullOrEmpty(NcharArrCn[i]) ? "NULL" : NcharArrCn[i]);
// Console.WriteLine("binaryArrCn[{0}]:{1},NcharArrCn[{0}]:{2}",i,String.IsNullOrEmpty(binaryArrCn[i]) ? 0 :binaryArrCn[i].Length, String.IsNullOrEmpty(NcharArrCn[i]) ? 0 : NcharArrCn[i].Length);
// Console.WriteLine("========");
}
return rowData;
}
// Five lines of data, that is construct as taos_mutli_bind array.
// There aren some CN characters and letters.
public static TAOS_MULTI_BIND[] GetMultiBindCNArr()
{
TAOS_MULTI_BIND[] mBinds = new TAOS_MULTI_BIND[14];
......@@ -140,6 +301,62 @@ namespace Test.UtilsTools.DataSource
mBinds[13] = TaosMultiBind.MultiBindNchar(NcharArrCn);
return mBinds;
}
// A List of data ,use as expectResData. The value is equal to GetMultiBindCNArr()
public static List<string> GetMultiBindCNRowData()
{
var rowData = new List<string>();
for (int i = 0; i < tsArr.Length; i++)
{
rowData.Add(tsArr[i].ToString());
rowData.Add(boolArr[i].Equals(null) ? "NULL" : boolArr[i].ToString());
rowData.Add(tinyIntArr[i].Equals(null) ? "NULL" : tinyIntArr[i].ToString());
rowData.Add(shortArr[i].Equals(null) ? "NULL" : shortArr[i].ToString());
rowData.Add(intArr[i].Equals(null) ? "NULL" : intArr[i].ToString());
rowData.Add(longArr[i].Equals(null) ? "NULL" : longArr[i].ToString());
rowData.Add(floatArr[i].Equals(null) ? "NULL" : floatArr[i].ToString());
rowData.Add(doubleArr[i].Equals(null) ? "NULL" : doubleArr[i].ToString());
rowData.Add(uTinyIntArr[i].Equals(null) ? "NULL" : uTinyIntArr[i].ToString());
rowData.Add(uShortArr[i].Equals(null) ? "NULL" : uShortArr[i].ToString());
rowData.Add(uIntArr[i].Equals(null) ? "NULL" : uIntArr[i].ToString());
rowData.Add(uLongArr[i].Equals(null) ? "NULL" : uLongArr[i].ToString());
rowData.Add(String.IsNullOrEmpty(binaryArrCn[i]) ? "NULL" : binaryArrCn[i]);
rowData.Add(String.IsNullOrEmpty(NcharArrCn[i]) ? "NULL" : NcharArrCn[i]);
// Console.WriteLine("binaryArrCn[{0}]:{1},NcharArrCn[{0}]:{2}",i,String.IsNullOrEmpty(binaryArrCn[i]) ? "NULL" : binaryArrCn[i],String.IsNullOrEmpty(NcharArrCn[i]) ? "NULL" : NcharArrCn[i]);
// Console.WriteLine("binaryArrCn[{0}]:{1},NcharArrCn[{0}]:{2}",i,String.IsNullOrEmpty(binaryArrCn[i]) ? 0 :binaryArrCn[i].Length, String.IsNullOrEmpty(NcharArrCn[i]) ? 0 : NcharArrCn[i].Length);
// Console.WriteLine("========");
}
return rowData;
}
public static List<String> GetMultiBindStableCNRowData()
{
List<String> columnData = new List<string>();
List<String> tagData = GetTagCnData();
for (int i = 0; i < tsArr.Length; i++)
{
columnData.Add(tsArr[i].ToString());
columnData.Add(boolArr[i].Equals(null) ? "NULL" : boolArr[i].ToString());
columnData.Add(tinyIntArr[i].Equals(null) ? "NULL" : tinyIntArr[i].ToString());
columnData.Add(shortArr[i].Equals(null) ? "NULL" : shortArr[i].ToString());
columnData.Add(intArr[i].Equals(null) ? "NULL" : intArr[i].ToString());
columnData.Add(longArr[i].Equals(null) ? "NULL" : longArr[i].ToString());
columnData.Add(floatArr[i].Equals(null) ? "NULL" : floatArr[i].ToString());
columnData.Add(doubleArr[i].Equals(null) ? "NULL" : doubleArr[i].ToString());
columnData.Add(uTinyIntArr[i].Equals(null) ? "NULL" : uTinyIntArr[i].ToString());
columnData.Add(uShortArr[i].Equals(null) ? "NULL" : uShortArr[i].ToString());
columnData.Add(uIntArr[i].Equals(null) ? "NULL" : uIntArr[i].ToString());
columnData.Add(uLongArr[i].Equals(null) ? "NULL" : uLongArr[i].ToString());
columnData.Add(String.IsNullOrEmpty(binaryArrCn[i]) ? "NULL" : binaryArrCn[i]);
columnData.Add(String.IsNullOrEmpty(NcharArrCn[i]) ? "NULL" : NcharArrCn[i]);
columnData.AddRange(tagData);
// Console.WriteLine("binaryArrCn[{0}]:{1},NcharArrCn[{0}]:{2}",i,String.IsNullOrEmpty(binaryArrCn[i]) ? "NULL" : binaryArrCn[i],String.IsNullOrEmpty(NcharArrCn[i]) ? "NULL" : NcharArrCn[i]);
// Console.WriteLine("binaryArrCn[{0}]:{1},NcharArrCn[{0}]:{2}",i,String.IsNullOrEmpty(binaryArrCn[i]) ? 0 :binaryArrCn[i].Length, String.IsNullOrEmpty(NcharArrCn[i]) ? 0 : NcharArrCn[i].Length);
// Console.WriteLine("========");
}
return columnData;
}
public static TAOS_BIND[] GetQueryCondition()
{
......@@ -158,7 +375,47 @@ namespace Test.UtilsTools.DataSource
{
TaosMultiBind.FreeTaosBind(mbinds);
}
//Get the TDengineMeta list from the ddl either normal table or stable
public static List<TDengineMeta> GetMetaFromDLL(string dllStr)
{
var expectResMeta = new List<TDengineMeta>();
//"CREATE TABLE meters(ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS(location BINARY(30), groupId INT);";
int bracetInd = dllStr.IndexOf("(");
//(ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS(location BINARY(30), groupId INT);
string subDllStr = dllStr.Substring(bracetInd);
String[] stableSeparators = new String[] { "tags", "TAGS" };
//(ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT)
//(location BINARY(30), groupId INT)
String[] dllStrElements = subDllStr.Split(stableSeparators, StringSplitOptions.RemoveEmptyEntries);
//(ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT)
dllStrElements[0] = dllStrElements[0].Substring(1, dllStrElements[0].Length - 2);
String[] finalStr1 = dllStrElements[0].Split(',', StringSplitOptions.RemoveEmptyEntries);
foreach (string item in finalStr1)
{
//ts TIMESTAMP
string[] itemArr = item.Split(' ', 2, StringSplitOptions.RemoveEmptyEntries);
// Console.WriteLine("GetMetaFromDLL():{0},{1}",itemArr[0],itemArr[1]);
expectResMeta.Add(UtilsTools.ConstructTDengineMeta(itemArr[0], itemArr[1]));
}
if (dllStr.Contains("TAGS") || dllStr.Contains("tags"))
{
//location BINARY(30), groupId INT
dllStrElements[1] = dllStrElements[1].Substring(1, dllStrElements[1].Length - 2);
//location BINARY(30) groupId INT
String[] finalStr2 = dllStrElements[1].Split(',', StringSplitOptions.RemoveEmptyEntries);
Console.WriteLine("========");
foreach (string item in finalStr2)
{
//location BINARY(30)
string[] itemArr = item.Split(' ', 2, StringSplitOptions.RemoveEmptyEntries);
// Console.WriteLine("GetMetaFromDLL():{0},{1}",itemArr[0],itemArr[1]);
expectResMeta.Add(UtilsTools.ConstructTDengineMeta(itemArr[0], itemArr[1]));
}
}
return expectResMeta;
}
}
}
\ No newline at end of file
using System;
using Test.UtilsTools;
using System.Collections.Generic;
using Xunit;
using TDengineDriver;
using Test.UtilsTools.ResultSet;
namespace Cases
{
public class FetchLengthCase
{
/// <author>xiaolei</author>
/// <Name>TestRetrieveBinary</Name>
/// <describe>TD-12103 C# connector fetch_row with binary data retrieving error</describe>
/// <filename>FetchLength.cs</filename>
/// <result>pass or failed </result>
[Fact(DisplayName = "Skip FetchLengthCase.TestRetrieveBinary()")]
public void TestRetrieveBinary()
{
IntPtr conn = UtilsTools.TDConnection();
var expectData = new List<string> { "log", "test", "db02", "db3" };
var expectMeta = new List<TDengineMeta>{
UtilsTools.ConstructTDengineMeta("ts","timestamp"),
UtilsTools.ConstructTDengineMeta("name","binary(10)"),
UtilsTools.ConstructTDengineMeta("n","int")
};
string sql0 = "drop table if exists stb1;";
string sql1 = "create stable if not exists stb1 (ts timestamp, name binary(10)) tags(n int);";
string sql2 = $"insert into tb1 using stb1 tags(1) values(now, '{expectData[0]}');";
string sql3 = $"insert into tb2 using stb1 tags(2) values(now, '{expectData[1]}');";
string sql4 = $"insert into tb3 using stb1 tags(3) values(now, '{expectData[2]}');";
string sql5 = $"insert into tb4 using stb1 tags(4) values(now, '{expectData[3]}');";
string sql6 = "select distinct(name) from stb1;";
UtilsTools.ExecuteQuery(conn, sql0);
UtilsTools.ExecuteQuery(conn, sql1);
UtilsTools.ExecuteQuery(conn, sql2);
UtilsTools.ExecuteQuery(conn, sql3);
UtilsTools.ExecuteQuery(conn, sql4);
UtilsTools.ExecuteQuery(conn, sql5);
IntPtr resPtr = IntPtr.Zero;
resPtr = UtilsTools.ExecuteQuery(conn, sql6);
ResultSet actualResult = new ResultSet(resPtr);
List<string> actualData = actualResult.GetResultData();
List<TDengineMeta> actualMeta = actualResult.GetResultMeta();
expectData.Reverse();
Assert.Equal(expectData[0], actualData[0]);
Assert.Equal(expectMeta[1].name, actualMeta[0].name);
Assert.Equal(expectMeta[1].size, actualMeta[0].size);
Assert.Equal(expectMeta[1].type, actualMeta[0].type);
}
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<IsPackable>false</IsPackable>
<NoWarn>CS1591;CS0168</NoWarn>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<DocumentationFile>..\doc\FunctionTest.XML</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.0.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\TDengineDriver\TDengineDriver.csproj" />
</ItemGroup>
</Project>
using System;
using TDengineDriver;
using System.Runtime.InteropServices;
using System.Text;
using System.Collections.Generic;
namespace Test.UtilsTools.ResultSet
{
public class ResultSet
{
private List<TDengineMeta> resultMeta;
private List<String> resultData;
// private bool isValidResult = false;
public ResultSet(IntPtr res)
{
resultMeta = UtilsTools.GetResField(res);
resultData = UtilsTools.GetResData(res);
}
public ResultSet(List<TDengineMeta> metas, List<String> datas)
{
resultMeta = metas;
resultData = datas;
}
public List<String> GetResultData()
{
return resultData;
}
public List<TDengineMeta> GetResultMeta()
{
return resultMeta;
}
}
}
\ No newline at end of file
此差异已折叠。
using System;
using Test.UtilsTools;
using TDengineDriver;
using System.Collections.Generic;
using Xunit;
using Test.UtilsTools.ResultSet;
namespace Cases
{
public class FetchFieldCases
{
/// <author>xiaolei</author>
/// <Name>FetchFieldCases.TestFetchFieldJsonTag</Name>
/// <describe>test taos_fetch_fields(), check the meta data</describe>
/// <filename>TaosFeild.cs</filename>
/// <result>pass or failed </result>
[Fact(DisplayName = "FetchFieldCases.TestFetchFieldJsonTag()")]
public void TestFetchFieldJsonTag()
{
IntPtr conn = UtilsTools.TDConnection();
IntPtr _res = IntPtr.Zero;
string tableName = "fetchfeilds";
var expectResMeta = new List<TDengineMeta> {
UtilsTools.ConstructTDengineMeta("ts", "timestamp"),
UtilsTools.ConstructTDengineMeta("b", "bool"),
UtilsTools.ConstructTDengineMeta("v1", "tinyint"),
UtilsTools.ConstructTDengineMeta("v2", "smallint"),
UtilsTools.ConstructTDengineMeta("v4", "int"),
UtilsTools.ConstructTDengineMeta("v8", "bigint"),
UtilsTools.ConstructTDengineMeta("f4", "float"),
UtilsTools.ConstructTDengineMeta("f8", "double"),
UtilsTools.ConstructTDengineMeta("u1", "tinyint unsigned"),
UtilsTools.ConstructTDengineMeta("u2", "smallint unsigned"),
UtilsTools.ConstructTDengineMeta("u4", "int unsigned"),
UtilsTools.ConstructTDengineMeta("u8", "bigint unsigned"),
UtilsTools.ConstructTDengineMeta("bin", "binary(200)"),
UtilsTools.ConstructTDengineMeta("blob", "nchar(200)"),
UtilsTools.ConstructTDengineMeta("jsontag", "json"),
};
var expectResData = new List<String> { "1637064040000", "true", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "XI", "XII", "{\"k1\": \"v1\"}" };
String dropTb = "drop table if exists " + tableName;
String createTb = "create stable " + tableName
+ " (ts timestamp" +
",b bool" +
",v1 tinyint" +
",v2 smallint" +
",v4 int" +
",v8 bigint" +
",f4 float" +
",f8 double" +
",u1 tinyint unsigned" +
",u2 smallint unsigned" +
",u4 int unsigned" +
",u8 bigint unsigned" +
",bin binary(200)" +
",blob nchar(200)" +
")" +
"tags" +
"(jsontag json);";
String insertSql = "insert into " + tableName + "_t1 using " + tableName +
" tags('{\"k1\": \"v1\"}') " +
"values(1637064040000,true,1,2,3,4,5,6,7,8,9,10,'XI','XII')";
String selectSql = "select * from " + tableName;
String dropSql = "drop table " + tableName;
UtilsTools.ExecuteUpdate(conn, dropTb);
UtilsTools.ExecuteUpdate(conn, createTb);
UtilsTools.ExecuteUpdate(conn, insertSql);
_res = UtilsTools.ExecuteQuery(conn, selectSql);
ResultSet actualResult = new ResultSet(_res);
List<TDengineMeta> actualMeta = actualResult.GetResultMeta();
for (int i = 0; i < actualMeta.Count; i++)
{
Assert.Equal(expectResMeta[i].name, actualMeta[i].name);
Assert.Equal(expectResMeta[i].type, actualMeta[i].type);
Assert.Equal(expectResMeta[i].size, actualMeta[i].size);
}
}
}
}
using System;
using TDengineDriver;
using System.Runtime.InteropServices;
using System.Text;
using System.Collections.Generic;
namespace Test.UtilsTools
{
public class UtilsTools
{
static string ip = "127.0.0.1";
static string user = "root";
static string password = "taosdata";
static string db = "";
static short port = 0;
public static IntPtr TDConnection()
{
TDengine.Options((int)TDengineInitOption.TDDB_OPTION_CONFIGDIR, GetConfigPath());
TDengine.Options((int)TDengineInitOption.TDDB_OPTION_SHELL_ACTIVITY_TIMER, "60");
TDengine.Init();
IntPtr conn = TDengine.Connect(ip, user, password, db, port);
// UtilsTools.ExecuteUpdate(conn, "drop database if exists csharp");
UtilsTools.ExecuteUpdate(conn, "create database if not exists csharp keep 3650");
UtilsTools.ExecuteUpdate(conn, "use csharp");
return conn;
}
public static string GetConfigPath()
{
string configDir = "" ;
if(OperatingSystem.IsOSPlatform("Windows"))
{
configDir = "C:/TDengine/cfg";
}
else if(OperatingSystem.IsOSPlatform("Linux"))
{
configDir = "/etc/taos";
}
else if(OperatingSystem.IsOSPlatform("macOS"))
{
configDir = "/etc/taos";
}
return configDir;
}
public static IntPtr ExecuteQuery(IntPtr conn, String sql)
{
IntPtr res = TDengine.Query(conn, sql);
if (!IsValidResult(res))
{
Console.Write(sql.ToString() + " failure, ");
ExitProgram();
}
else
{
Console.WriteLine(sql.ToString() + " success");
}
return res;
}
public static IntPtr ExecuteErrorQuery(IntPtr conn, String sql)
{
IntPtr res = TDengine.Query(conn, sql);
if (!IsValidResult(res))
{
Console.Write(sql.ToString() + " failure, ");
ExitProgram();
}
else
{
Console.WriteLine(sql.ToString() + " success");
}
return res;
}
public static void ExecuteUpdate(IntPtr conn, String sql)
{
IntPtr res = TDengine.Query(conn, sql);
if (!IsValidResult(res))
{
Console.Write(sql.ToString() + " failure, ");
ExitProgram();
}
else
{
Console.WriteLine(sql.ToString() + " success");
}
TDengine.FreeResult(res);
}
public static void DisplayRes(IntPtr res)
{
if (!IsValidResult(res))
{
ExitProgram();
}
List<TDengineMeta> metas = GetResField(res);
int fieldCount = metas.Count;
IntPtr rowdata;
// StringBuilder builder = new StringBuilder();
List<string> datas = QueryRes(res, metas);
Console.Write(" DisplayRes ---");
for (int i = 0; i < metas.Count; i++)
{
for (int j = 0; j < datas.Count; j++)
{
Console.Write(" {0} ---", datas[i * j + i]);
}
Console.WriteLine("");
}
// if (TDengine.ErrorNo(res) != 0)
// {
// Console.Write("Query is not complete, Error {0:G}", TDengine.ErrorNo(res), TDengine.Error(res));
// }
// TDengine.FreeResult(res); Console.WriteLine("");
}
public static List<List<string>> GetResultSet(IntPtr res)
{
List<List<string>> result = new List<List<string>>();
List<string> colName = new List<string>();
List<string> dataRaw = new List<string>();
if (!IsValidResult(res))
{
ExitProgram();
}
List<TDengineMeta> metas = GetResField(res);
result.Add(colName);
dataRaw = QueryRes(res, metas);
result.Add(dataRaw);
if (TDengine.ErrorNo(res) != 0)
{
Console.Write("Query is not complete, Error {0:G}", TDengine.ErrorNo(res), TDengine.Error(res));
}
return result;
}
public static bool IsValidResult(IntPtr res)
{
if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0))
{
if (res != IntPtr.Zero)
{
Console.Write("reason: " + TDengine.Error(res));
return false;
}
Console.WriteLine("");
return false;
}
return true;
}
public static void CloseConnection(IntPtr conn)
{
ExecuteUpdate(conn, "drop database if exists csharp");
if (conn != IntPtr.Zero)
{
if (TDengine.Close(conn) == 0)
{
Console.WriteLine("close connection sucess");
}
else
{
Console.WriteLine("close Connection failed");
}
}
}
public static List<TDengineMeta> GetResField(IntPtr res)
{
List<TDengineMeta> metas = TDengine.FetchFields(res);
return metas;
}
public static void AssertEqual(string expectVal, string actualVal)
{
if (expectVal == actualVal)
{
Console.WriteLine("{0}=={1} pass", expectVal, actualVal);
}
else
{
Console.WriteLine("{0}=={1} failed", expectVal, actualVal);
ExitProgram();
}
}
public static void ExitProgram()
{
TDengine.Cleanup();
System.Environment.Exit(0);
}
public static List<String> GetResData(IntPtr res)
{
List<string> colName = new List<string>();
List<string> dataRaw = new List<string>();
if (!IsValidResult(res))
{
ExitProgram();
}
List<TDengineMeta> metas = GetResField(res);
dataRaw = QueryRes(res, metas);
return dataRaw;
}
public static TDengineMeta ConstructTDengineMeta(string name, string type)
{
TDengineMeta _meta = new TDengineMeta();
_meta.name = name;
char[] separators = new char[] { '(', ')' };
string[] subs = type.Split(separators, StringSplitOptions.RemoveEmptyEntries);
switch (subs[0].ToUpper())
{
case "BOOL":
_meta.type = 1;
_meta.size = 1;
break;
case "TINYINT":
_meta.type = 2;
_meta.size = 1;
break;
case "SMALLINT":
_meta.type = 3;
_meta.size = 2;
break;
case "INT":
_meta.type = 4;
_meta.size = 4;
break;
case "BIGINT":
_meta.type = 5;
_meta.size = 8;
break;
case "TINYINT UNSIGNED":
_meta.type = 11;
_meta.size = 1;
break;
case "SMALLINT UNSIGNED":
_meta.type = 12;
_meta.size = 2;
break;
case "INT UNSIGNED":
_meta.type = 13;
_meta.size = 4;
break;
case "BIGINT UNSIGNED":
_meta.type = 14;
_meta.size = 8;
break;
case "FLOAT":
_meta.type = 6;
_meta.size = 4;
break;
case "DOUBLE":
_meta.type = 7;
_meta.size = 8;
break;
case "BINARY":
_meta.type = 8;
_meta.size = short.Parse(subs[1]);
break;
case "TIMESTAMP":
_meta.type = 9;
_meta.size = 8;
break;
case "NCHAR":
_meta.type = 10;
_meta.size = short.Parse(subs[1]);
break;
case "JSON":
_meta.type = 15;
_meta.size = 4096;
break;
default:
_meta.type = byte.MaxValue;
_meta.size = 0;
break;
}
return _meta;
}
private static List<string> QueryRes(IntPtr res, List<TDengineMeta> metas)
{
IntPtr rowdata;
long queryRows = 0;
List<string> dataRaw = new List<string>();
int fieldCount = metas.Count;
while ((rowdata = TDengine.FetchRows(res)) != IntPtr.Zero)
{
queryRows++;
IntPtr colLengthPtr = TDengine.FetchLengths(res);
int[] colLengthArr = new int[fieldCount];
Marshal.Copy(colLengthPtr, colLengthArr, 0, fieldCount);
for (int fields = 0; fields < fieldCount; ++fields)
{
TDengineMeta meta = metas[fields];
int offset = IntPtr.Size * fields;
IntPtr data = Marshal.ReadIntPtr(rowdata, offset);
if (data == IntPtr.Zero)
{
dataRaw.Add("NULL");
continue;
}
switch ((TDengineDataType)meta.type)
{
case TDengineDataType.TSDB_DATA_TYPE_BOOL:
bool v1 = Marshal.ReadByte(data) == 0 ? false : true;
dataRaw.Add(v1.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_TINYINT:
sbyte v2 = (sbyte)Marshal.ReadByte(data);
dataRaw.Add(v2.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_SMALLINT:
short v3 = Marshal.ReadInt16(data);
dataRaw.Add(v3.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_INT:
int v4 = Marshal.ReadInt32(data);
dataRaw.Add(v4.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_BIGINT:
long v5 = Marshal.ReadInt64(data);
dataRaw.Add(v5.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_FLOAT:
float v6 = (float)Marshal.PtrToStructure(data, typeof(float));
dataRaw.Add(v6.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_DOUBLE:
double v7 = (double)Marshal.PtrToStructure(data, typeof(double));
dataRaw.Add(v7.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_BINARY:
string v8 = Marshal.PtrToStringAnsi(data, colLengthArr[fields]);
dataRaw.Add(v8);
break;
case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP:
long v9 = Marshal.ReadInt64(data);
dataRaw.Add(v9.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_NCHAR:
string v10 = Marshal.PtrToStringAnsi(data, colLengthArr[fields]);
dataRaw.Add(v10);
break;
case TDengineDataType.TSDB_DATA_TYPE_UTINYINT:
byte v12 = Marshal.ReadByte(data);
dataRaw.Add(v12.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_USMALLINT:
ushort v13 = (ushort)Marshal.ReadInt16(data);
dataRaw.Add(v13.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_UINT:
uint v14 = (uint)Marshal.ReadInt32(data);
dataRaw.Add(v14.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_UBIGINT:
ulong v15 = (ulong)Marshal.ReadInt64(data);
dataRaw.Add(v15.ToString());
break;
default:
dataRaw.Add("unknown value");
break;
}
}
}
if (TDengine.ErrorNo(res) != 0)
{
Console.Write("Query is not complete, Error {0:G}", TDengine.ErrorNo(res), TDengine.Error(res));
}
TDengine.FreeResult(res);
Console.WriteLine("");
return dataRaw;
}
}
}
......@@ -8,7 +8,7 @@ IF (TD_MVN_INSTALLED)
ADD_CUSTOM_COMMAND(OUTPUT ${JDBC_CMD_NAME}
POST_BUILD
COMMAND mvn -Dmaven.test.skip=true install -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.36-dist.jar ${LIBRARY_OUTPUT_PATH}
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.37-dist.jar ${LIBRARY_OUTPUT_PATH}
COMMAND mvn -Dmaven.test.skip=true clean -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml
COMMENT "build jdbc driver")
ADD_CUSTOM_TARGET(${JDBC_TARGET_NAME} ALL WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} DEPENDS ${JDBC_CMD_NAME})
......
......@@ -5,7 +5,7 @@
<groupId>com.taosdata.jdbc</groupId>
<artifactId>taos-jdbcdriver</artifactId>
<version>2.0.36</version>
<version>2.0.37</version>
<packaging>jar</packaging>
<name>JDBCDriver</name>
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Subproject commit 59f00a69f36b08cea86a70a22c29b2c27ef506ae
Subproject commit da842b77f438e5b4c496918e51f8ea02ba0f2c99
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Subproject commit fd84b35d3a30c9bcf3939d565f717b7f98ff9eb7
Subproject commit 8f9501a30b1893c6616d644a924c995aa21ad957
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册