提交 45800340 编写于 作者: L liuyq-617

Merge branch 'develop' of github.com:taosdata/TDengine into CI/TD-12111

...@@ -58,7 +58,7 @@ def pre_test(){ ...@@ -58,7 +58,7 @@ def pre_test(){
cd ${WKC} cd ${WKC}
git checkout 2.0 git checkout 2.0
''' '''
} }
else{ else{
sh ''' sh '''
cd ${WKC} cd ${WKC}
...@@ -68,6 +68,7 @@ def pre_test(){ ...@@ -68,6 +68,7 @@ def pre_test(){
} }
sh''' sh'''
cd ${WKC} cd ${WKC}
git remote prune origin
[ -f src/connector/grafanaplugin/README.md ] && rm -f src/connector/grafanaplugin/README.md > /dev/null || echo "failed to remove grafanaplugin README.md" [ -f src/connector/grafanaplugin/README.md ] && rm -f src/connector/grafanaplugin/README.md > /dev/null || echo "failed to remove grafanaplugin README.md"
git pull >/dev/null git pull >/dev/null
git fetch origin +refs/pull/${CHANGE_ID}/merge git fetch origin +refs/pull/${CHANGE_ID}/merge
...@@ -89,28 +90,28 @@ def pre_test(){ ...@@ -89,28 +90,28 @@ def pre_test(){
cd ${WK} cd ${WK}
git checkout 2.0 git checkout 2.0
''' '''
} }
else{ else{
sh ''' sh '''
cd ${WK} cd ${WK}
git checkout develop git checkout develop
''' '''
} }
} }
sh ''' sh '''
cd ${WK} cd ${WK}
git pull >/dev/null git pull >/dev/null
export TZ=Asia/Harbin export TZ=Asia/Harbin
date date
git clean -dfx git clean -dfx
mkdir debug mkdir debug
cd debug cd debug
cmake .. -DBUILD_HTTP=false > /dev/null cmake .. -DBUILD_HTTP=false -DBUILD_TOOLS=true > /dev/null
make > /dev/null make > /dev/null
make install > /dev/null make install > /dev/null
cd ${WKC}/tests cd ${WKC}/tests
pip3 install ${WKC}/src/connector/python/ pip3 install ${WKC}/src/connector/python/
''' '''
return 1 return 1
} }
...@@ -132,7 +133,7 @@ def pre_test_noinstall(){ ...@@ -132,7 +133,7 @@ def pre_test_noinstall(){
cd ${WKC} cd ${WKC}
git checkout 2.0 git checkout 2.0
''' '''
} }
else{ else{
sh ''' sh '''
cd ${WKC} cd ${WKC}
...@@ -142,6 +143,7 @@ def pre_test_noinstall(){ ...@@ -142,6 +143,7 @@ def pre_test_noinstall(){
} }
sh''' sh'''
cd ${WKC} cd ${WKC}
git remote prune origin
[ -f src/connector/grafanaplugin/README.md ] && rm -f src/connector/grafanaplugin/README.md > /dev/null || echo "failed to remove grafanaplugin README.md" [ -f src/connector/grafanaplugin/README.md ] && rm -f src/connector/grafanaplugin/README.md > /dev/null || echo "failed to remove grafanaplugin README.md"
git pull >/dev/null git pull >/dev/null
git fetch origin +refs/pull/${CHANGE_ID}/merge git fetch origin +refs/pull/${CHANGE_ID}/merge
...@@ -163,24 +165,24 @@ def pre_test_noinstall(){ ...@@ -163,24 +165,24 @@ def pre_test_noinstall(){
cd ${WK} cd ${WK}
git checkout 2.0 git checkout 2.0
''' '''
} }
else{ else{
sh ''' sh '''
cd ${WK} cd ${WK}
git checkout develop git checkout develop
''' '''
} }
} }
sh ''' sh '''
cd ${WK} cd ${WK}
git pull >/dev/null git pull >/dev/null
export TZ=Asia/Harbin export TZ=Asia/Harbin
date date
git clean -dfx git clean -dfx
mkdir debug mkdir debug
cd debug cd debug
cmake .. -DBUILD_HTTP=false > /dev/null cmake .. -DBUILD_HTTP=false -DBUILD_TOOLS=false > /dev/null
make make
''' '''
return 1 return 1
...@@ -203,7 +205,7 @@ def pre_test_mac(){ ...@@ -203,7 +205,7 @@ def pre_test_mac(){
cd ${WKC} cd ${WKC}
git checkout 2.0 git checkout 2.0
''' '''
} }
else{ else{
sh ''' sh '''
cd ${WKC} cd ${WKC}
...@@ -213,6 +215,7 @@ def pre_test_mac(){ ...@@ -213,6 +215,7 @@ def pre_test_mac(){
} }
sh''' sh'''
cd ${WKC} cd ${WKC}
git remote prune origin
[ -f src/connector/grafanaplugin/README.md ] && rm -f src/connector/grafanaplugin/README.md > /dev/null || echo "failed to remove grafanaplugin README.md" [ -f src/connector/grafanaplugin/README.md ] && rm -f src/connector/grafanaplugin/README.md > /dev/null || echo "failed to remove grafanaplugin README.md"
git pull >/dev/null git pull >/dev/null
git fetch origin +refs/pull/${CHANGE_ID}/merge git fetch origin +refs/pull/${CHANGE_ID}/merge
...@@ -234,24 +237,24 @@ def pre_test_mac(){ ...@@ -234,24 +237,24 @@ def pre_test_mac(){
cd ${WK} cd ${WK}
git checkout 2.0 git checkout 2.0
''' '''
} }
else{ else{
sh ''' sh '''
cd ${WK} cd ${WK}
git checkout develop git checkout develop
''' '''
} }
} }
sh ''' sh '''
cd ${WK} cd ${WK}
git pull >/dev/null git pull >/dev/null
export TZ=Asia/Harbin export TZ=Asia/Harbin
date date
git clean -dfx git clean -dfx
mkdir debug mkdir debug
cd debug cd debug
cmake .. > /dev/null cmake .. -DBUILD_TOOLS=false > /dev/null
go env -w GOPROXY=https://goproxy.cn,direct go env -w GOPROXY=https://goproxy.cn,direct
go env -w GO111MODULE=on go env -w GO111MODULE=on
cmake --build . cmake --build .
...@@ -266,7 +269,7 @@ def pre_test_win(){ ...@@ -266,7 +269,7 @@ def pre_test_win(){
cd C:\\workspace\\TDinternal cd C:\\workspace\\TDinternal
rd /s /Q C:\\workspace\\TDinternal\\debug rd /s /Q C:\\workspace\\TDinternal\\debug
cd C:\\workspace\\TDinternal\\community cd C:\\workspace\\TDinternal\\community
git reset --hard HEAD~10 git reset --hard HEAD~10
''' '''
script { script {
if (env.CHANGE_TARGET == 'master') { if (env.CHANGE_TARGET == 'master') {
...@@ -280,7 +283,7 @@ def pre_test_win(){ ...@@ -280,7 +283,7 @@ def pre_test_win(){
cd C:\\workspace\\TDinternal\\community cd C:\\workspace\\TDinternal\\community
git checkout 2.0 git checkout 2.0
''' '''
} }
else{ else{
bat ''' bat '''
cd C:\\workspace\\TDinternal\\community cd C:\\workspace\\TDinternal\\community
...@@ -290,7 +293,8 @@ def pre_test_win(){ ...@@ -290,7 +293,8 @@ def pre_test_win(){
} }
bat''' bat'''
cd C:\\workspace\\TDinternal\\community cd C:\\workspace\\TDinternal\\community
git pull git remote prune origin
git pull
git fetch origin +refs/pull/%CHANGE_ID%/merge git fetch origin +refs/pull/%CHANGE_ID%/merge
git checkout -qf FETCH_HEAD git checkout -qf FETCH_HEAD
git clean -dfx git clean -dfx
...@@ -310,36 +314,36 @@ def pre_test_win(){ ...@@ -310,36 +314,36 @@ def pre_test_win(){
cd C:\\workspace\\TDinternal cd C:\\workspace\\TDinternal
git checkout 2.0 git checkout 2.0
''' '''
} }
else{ else{
bat ''' bat '''
cd C:\\workspace\\TDinternal cd C:\\workspace\\TDinternal
git checkout develop git checkout develop
''' '''
} }
} }
bat ''' bat '''
cd C:\\workspace\\TDinternal cd C:\\workspace\\TDinternal
git pull git pull
date date
git clean -dfx git clean -dfx
mkdir debug mkdir debug
cd debug cd debug
call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Auxiliary\\Build\\vcvarsall.bat" amd64 call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Auxiliary\\Build\\vcvarsall.bat" amd64
cmake ../ -G "NMake Makefiles" cmake ../ -G "NMake Makefiles"
set CL=/MP nmake nmake || exit 8 set CL=/MP nmake nmake || exit 8
nmake install || exit 8 nmake install || exit 8
xcopy /e/y/i/f C:\\workspace\\TDinternal\\debug\\build\\lib\\taos.dll C:\\Windows\\System32 || exit 8 xcopy /e/y/i/f C:\\workspace\\TDinternal\\debug\\build\\lib\\taos.dll C:\\Windows\\System32 || exit 8
cd C:\\workspace\\TDinternal\\community\\src\\connector\\python cd C:\\workspace\\TDinternal\\community\\src\\connector\\python
python -m pip install . python -m pip install .
''' '''
return 1 return 1
} }
pipeline { pipeline {
agent none agent none
options { skipDefaultCheckout() } options { skipDefaultCheckout() }
environment{ environment{
WK = '/var/lib/jenkins/workspace/TDinternal' WK = '/var/lib/jenkins/workspace/TDinternal'
WKC= '/var/lib/jenkins/workspace/TDinternal/community' WKC= '/var/lib/jenkins/workspace/TDinternal/community'
...@@ -347,7 +351,7 @@ pipeline { ...@@ -347,7 +351,7 @@ pipeline {
stages { stages {
stage('pre_build'){ stage('pre_build'){
agent{label 'master'} agent{label 'master'}
options { skipDefaultCheckout() } options { skipDefaultCheckout() }
when { when {
changeRequest() changeRequest()
} }
...@@ -388,32 +392,32 @@ pipeline { ...@@ -388,32 +392,32 @@ pipeline {
// sh ''' // sh '''
// git checkout 2.0 // git checkout 2.0
// ''' // '''
// } // }
// else{ // else{
// sh ''' // sh '''
// git checkout develop // git checkout develop
// ''' // '''
// } // }
// } // }
// sh''' // sh'''
// git fetch origin +refs/pull/${CHANGE_ID}/merge // git fetch origin +refs/pull/${CHANGE_ID}/merge
// git checkout -qf FETCH_HEAD // git checkout -qf FETCH_HEAD
// ''' // '''
// script{ // script{
// skipbuild='2' // skipbuild='2'
// skipbuild=sh(script: "git log -2 --pretty=%B | fgrep -ie '[skip ci]' -e '[ci skip]' && echo 1 || echo 2", returnStdout:true) // skipbuild=sh(script: "git log -2 --pretty=%B | fgrep -ie '[skip ci]' -e '[ci skip]' && echo 1 || echo 2", returnStdout:true)
// println skipbuild // println skipbuild
// } // }
// sh''' // sh'''
// rm -rf ${WORKSPACE}.tes // rm -rf ${WORKSPACE}.tes
// ''' // '''
// } // }
} }
} }
stage('Parallel test stage') { stage('Parallel test stage') {
//only build pr //only build pr
options { skipDefaultCheckout() } options { skipDefaultCheckout() }
when { when {
allOf{ allOf{
changeRequest() changeRequest()
...@@ -432,13 +436,11 @@ pipeline { ...@@ -432,13 +436,11 @@ pipeline {
./test-all.sh p1 ./test-all.sh p1
date''' date'''
} }
} }
} }
stage('python_2_s5') { stage('python_2_s5') {
agent{label " slave5 || slave15 "} agent{label " slave5 || slave15 "}
steps { steps {
pre_test() pre_test()
timeout(time: 55, unit: 'MINUTES'){ timeout(time: 55, unit: 'MINUTES'){
sh ''' sh '''
...@@ -451,8 +453,8 @@ pipeline { ...@@ -451,8 +453,8 @@ pipeline {
} }
stage('python_3_s6') { stage('python_3_s6') {
agent{label " slave6 || slave16 "} agent{label " slave6 || slave16 "}
steps { steps {
timeout(time: 55, unit: 'MINUTES'){ timeout(time: 55, unit: 'MINUTES'){
pre_test() pre_test()
sh ''' sh '''
date date
...@@ -464,8 +466,8 @@ pipeline { ...@@ -464,8 +466,8 @@ pipeline {
} }
stage('test_b1_s2') { stage('test_b1_s2') {
agent{label " slave2 || slave12 "} agent{label " slave2 || slave12 "}
steps { steps {
timeout(time: 55, unit: 'MINUTES'){ timeout(time: 55, unit: 'MINUTES'){
pre_test() pre_test()
sh ''' sh '''
rm -rf /var/lib/taos/* rm -rf /var/lib/taos/*
...@@ -493,6 +495,9 @@ pipeline { ...@@ -493,6 +495,9 @@ pipeline {
''' '''
sh ''' sh '''
cd ${WKC}/src/connector/nodejs
npm install
npm run test
cd ${WKC}/tests/examples/nodejs cd ${WKC}/tests/examples/nodejs
npm install td2.0-connector > /dev/null 2>&1 npm install td2.0-connector > /dev/null 2>&1
node nodejsChecker.js host=localhost node nodejsChecker.js host=localhost
...@@ -503,6 +508,15 @@ pipeline { ...@@ -503,6 +508,15 @@ pipeline {
''' '''
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
sh ''' sh '''
cd ${WKC}/src/connector/C#
dotnet test
dotnet run --project src/test/Cases/Cases.csproj
cd ${WKC}/tests/examples/C#
dotnet run --project C#checker/C#checker.csproj
dotnet run --project TDengineTest/TDengineTest.csproj
dotnet run --project schemaless/schemaless.csproj
cd ${WKC}/tests/examples/C#/taosdemo cd ${WKC}/tests/examples/C#/taosdemo
dotnet build -c Release dotnet build -c Release
tree | true tree | true
...@@ -522,7 +536,7 @@ pipeline { ...@@ -522,7 +536,7 @@ pipeline {
} }
stage('test_crash_gen_s3') { stage('test_crash_gen_s3') {
agent{label " slave3 || slave13 "} agent{label " slave3 || slave13 "}
steps { steps {
pre_test() pre_test()
timeout(time: 60, unit: 'MINUTES'){ timeout(time: 60, unit: 'MINUTES'){
...@@ -552,7 +566,7 @@ pipeline { ...@@ -552,7 +566,7 @@ pipeline {
./test-all.sh b2fq ./test-all.sh b2fq
date date
''' '''
} }
} }
} }
stage('test_valgrind_s4') { stage('test_valgrind_s4') {
...@@ -566,8 +580,8 @@ pipeline { ...@@ -566,8 +580,8 @@ pipeline {
./valgrind-test.sh 2>&1 > mem-error-out.log ./valgrind-test.sh 2>&1 > mem-error-out.log
./handle_val_log.sh ./handle_val_log.sh
''' '''
} }
timeout(time: 55, unit: 'MINUTES'){ timeout(time: 55, unit: 'MINUTES'){
sh ''' sh '''
date date
cd ${WKC}/tests cd ${WKC}/tests
...@@ -583,8 +597,8 @@ pipeline { ...@@ -583,8 +597,8 @@ pipeline {
} }
stage('test_b4_s7') { stage('test_b4_s7') {
agent{label " slave7 || slave17 "} agent{label " slave7 || slave17 "}
steps { steps {
timeout(time: 105, unit: 'MINUTES'){ timeout(time: 105, unit: 'MINUTES'){
pre_test() pre_test()
sh ''' sh '''
date date
...@@ -597,14 +611,13 @@ pipeline { ...@@ -597,14 +611,13 @@ pipeline {
// ./test-all.sh full jdbc // ./test-all.sh full jdbc
// cd ${WKC}/tests // cd ${WKC}/tests
// ./test-all.sh full unit // ./test-all.sh full unit
} }
} }
} }
stage('test_b5_s8') { stage('test_b5_s8') {
agent{label " slave8 || slave18 "} agent{label " slave8 || slave18 "}
steps { steps {
timeout(time: 55, unit: 'MINUTES'){ timeout(time: 55, unit: 'MINUTES'){
pre_test() pre_test()
sh ''' sh '''
date date
...@@ -616,8 +629,8 @@ pipeline { ...@@ -616,8 +629,8 @@ pipeline {
} }
stage('test_b6_s9') { stage('test_b6_s9') {
agent{label " slave9 || slave19 "} agent{label " slave9 || slave19 "}
steps { steps {
timeout(time: 55, unit: 'MINUTES'){ timeout(time: 55, unit: 'MINUTES'){
pre_test() pre_test()
sh ''' sh '''
cd ${WKC}/tests cd ${WKC}/tests
...@@ -628,14 +641,13 @@ pipeline { ...@@ -628,14 +641,13 @@ pipeline {
cd ${WKC}/tests cd ${WKC}/tests
./test-all.sh b6fq ./test-all.sh b6fq
date''' date'''
} }
} }
} }
stage('test_b7_s10') { stage('test_b7_s10') {
agent{label " slave10 || slave20 "} agent{label " slave10 || slave20 "}
steps { steps {
timeout(time: 55, unit: 'MINUTES'){ timeout(time: 55, unit: 'MINUTES'){
pre_test() pre_test()
sh ''' sh '''
cd ${WKC}/tests cd ${WKC}/tests
...@@ -645,68 +657,68 @@ pipeline { ...@@ -645,68 +657,68 @@ pipeline {
date date
cd ${WKC}/tests cd ${WKC}/tests
./test-all.sh b7fq ./test-all.sh b7fq
date''' date'''
} }
} }
} }
stage('arm64centos7') { stage('arm64centos7') {
agent{label " arm64centos7 "} agent{label " arm64centos7 "}
steps { steps {
pre_test_noinstall() pre_test_noinstall()
} }
} }
stage('arm64centos8') { stage('arm64centos8') {
agent{label " arm64centos8 "} agent{label " arm64centos8 "}
steps { steps {
pre_test_noinstall() pre_test_noinstall()
} }
} }
stage('arm32bionic') { stage('arm32bionic') {
agent{label " arm32bionic "} agent{label " arm32bionic "}
steps { steps {
pre_test_noinstall() pre_test_noinstall()
} }
} }
stage('arm64bionic') { stage('arm64bionic') {
agent{label " arm64bionic "} agent{label " arm64bionic "}
steps { steps {
pre_test_noinstall() pre_test_noinstall()
} }
} }
stage('arm64focal') { stage('arm64focal') {
agent{label " arm64focal "} agent{label " arm64focal "}
steps { steps {
pre_test_noinstall() pre_test_noinstall()
} }
} }
stage('centos7') { stage('centos7') {
agent{label " centos7 "} agent{label " centos7 "}
steps { steps {
pre_test_noinstall() pre_test_noinstall()
} }
} }
stage('ubuntu:trusty') { stage('ubuntu:trusty') {
agent{label " trusty "} agent{label " trusty "}
steps { steps {
pre_test_noinstall() pre_test_noinstall()
} }
} }
stage('ubuntu:xenial') { stage('ubuntu:xenial') {
agent{label " xenial "} agent{label " xenial "}
steps { steps {
pre_test_noinstall() pre_test_noinstall()
} }
} }
stage('ubuntu:bionic') { stage('ubuntu:bionic') {
agent{label " bionic "} agent{label " bionic "}
steps { steps {
pre_test_noinstall() pre_test_noinstall()
} }
} }
stage('Mac_build') { stage('Mac_build') {
agent{label " catalina "} agent{label " catalina "}
steps { steps {
pre_test_mac() pre_test_mac()
} }
} }
...@@ -714,7 +726,7 @@ pipeline { ...@@ -714,7 +726,7 @@ pipeline {
agent{label " wintest "} agent{label " wintest "}
steps { steps {
pre_test() pre_test()
script{ script{
while(win_stop == 0){ while(win_stop == 0){
sleep(1) sleep(1)
} }
...@@ -724,7 +736,6 @@ pipeline { ...@@ -724,7 +736,6 @@ pipeline {
stage('test'){ stage('test'){
agent{label "win"} agent{label "win"}
steps{ steps{
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') { catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
pre_test_win() pre_test_win()
timeout(time: 20, unit: 'MINUTES'){ timeout(time: 20, unit: 'MINUTES'){
...@@ -733,18 +744,16 @@ pipeline { ...@@ -733,18 +744,16 @@ pipeline {
.\\test-all.bat wintest .\\test-all.bat wintest
''' '''
} }
} }
script{ script{
win_stop=1 win_stop=1
} }
} }
} }
} }
} }
} }
post { post {
success { success {
emailext ( emailext (
subject: "PR-result: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' SUCCESS", subject: "PR-result: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' SUCCESS",
...@@ -771,7 +780,6 @@ pipeline { ...@@ -771,7 +780,6 @@ pipeline {
<li>提交信息:${env.CHANGE_TITLE}</li> <li>提交信息:${env.CHANGE_TITLE}</li>
<li>构建地址:<a href=${BUILD_URL}>${BUILD_URL}</a></li> <li>构建地址:<a href=${BUILD_URL}>${BUILD_URL}</a></li>
<li>构建日志:<a href=${BUILD_URL}console>${BUILD_URL}console</a></li> <li>构建日志:<a href=${BUILD_URL}console>${BUILD_URL}console</a></li>
</div> </div>
</ul> </ul>
</td> </td>
...@@ -809,7 +817,6 @@ pipeline { ...@@ -809,7 +817,6 @@ pipeline {
<li>提交信息:${env.CHANGE_TITLE}</li> <li>提交信息:${env.CHANGE_TITLE}</li>
<li>构建地址:<a href=${BUILD_URL}>${BUILD_URL}</a></li> <li>构建地址:<a href=${BUILD_URL}>${BUILD_URL}</a></li>
<li>构建日志:<a href=${BUILD_URL}console>${BUILD_URL}console</a></li> <li>构建日志:<a href=${BUILD_URL}console>${BUILD_URL}console</a></li>
</div> </div>
</ul> </ul>
</td> </td>
...@@ -821,5 +828,5 @@ pipeline { ...@@ -821,5 +828,5 @@ pipeline {
from: "support@taosdata.com" from: "support@taosdata.com"
) )
} }
} }
} }
...@@ -59,6 +59,9 @@ sudo apt-get install -y maven ...@@ -59,6 +59,9 @@ sudo apt-get install -y maven
``` ```
#### Install build dependencies for taos-tools #### Install build dependencies for taos-tools
We provide a few useful tools such as taosBenchmark (was named taosdemo) and taosdump. They were part of TDengine. From TDengine 2.4.0.0, taosBenchmark and taosdump were not released together with TDengine.
By default, TDengine compiling does not include taos-tools. You can use 'cmake .. -DBUILD_TOOLS=true' to make them be compiled with TDengine.
To build the [taos-tools](https://github.com/taosdata/taos-tools) on Ubuntu/Debian, the following packages need to be installed. To build the [taos-tools](https://github.com/taosdata/taos-tools) on Ubuntu/Debian, the following packages need to be installed.
```bash ```bash
sudo apt install libjansson-dev libsnappy-dev liblzma-dev libz-dev pkg-config sudo apt install libjansson-dev libsnappy-dev liblzma-dev libz-dev pkg-config
...@@ -142,7 +145,7 @@ mkdir debug && cd debug ...@@ -142,7 +145,7 @@ mkdir debug && cd debug
cmake .. && cmake --build . cmake .. && cmake --build .
``` ```
Note TDengine 2.3.x.0 and later use a component named 'taosAdapter' to play http daemon role by default instead of the http daemon embedded in the early version of TDengine. The taosAdapter is programmed by go language. If you pull TDengine source code to the latest from an existing codebase, please execute 'git submodule update --init --recursive' to pull taosAdapter source code. Please install go language 1.14 or above for compiling taosAdapter. If you meet difficulties regarding 'go mod', especially you are from China, you can use a proxy to solve the problem. Note TDengine 2.3.x.0 and later use a component named 'taosAdapter' to play http daemon role by default instead of the http daemon embedded in the early version of TDengine. The taosAdapter is programmed by go language. If you pull TDengine source code to the latest from an existing codebase, please execute 'git submodule update --init --recursive' to pull taosAdapter source code. Please install go language version 1.14 or above for compiling taosAdapter. If you meet difficulties regarding 'go mod', especially you are from China, you can use a proxy to solve the problem.
``` ```
go env -w GO111MODULE=on go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct go env -w GOPROXY=https://goproxy.cn,direct
......
...@@ -168,7 +168,7 @@ IF ("${BUILD_TOOLS}" STREQUAL "") ...@@ -168,7 +168,7 @@ IF ("${BUILD_TOOLS}" STREQUAL "")
ELSEIF (TD_ARM_64) ELSEIF (TD_ARM_64)
SET(BUILD_TOOLS "false") SET(BUILD_TOOLS "false")
ELSE () ELSE ()
SET(BUILD_TOOLS "true") SET(BUILD_TOOLS "false")
ENDIF () ENDIF ()
ELSEIF (TD_DARWIN) ELSEIF (TD_DARWIN)
SET(BUILD_TOOLS "false") SET(BUILD_TOOLS "false")
......
...@@ -364,7 +364,7 @@ taosdemo 不仅仅可以进行数据写入,也可以执行查询和订阅功 ...@@ -364,7 +364,7 @@ taosdemo 不仅仅可以进行数据写入,也可以执行查询和订阅功
} }
``` ```
以下为 JSON 文件中和查询相关的特有参数含义: 以下为 JSON 文件中和查询相关的特有参数含义:
```
"query_times": 每种查询类型的查询次数 "query_times": 每种查询类型的查询次数
"query_mode": 查询数据接口,"taosc":调用TDengine的c接口;“resetful”:使用restfule接口。可选项。缺省是“taosc”。 "query_mode": 查询数据接口,"taosc":调用TDengine的c接口;“resetful”:使用restfule接口。可选项。缺省是“taosc”。
"specified_table_query": { 指定表的查询 "specified_table_query": { 指定表的查询
...@@ -379,7 +379,7 @@ taosdemo 不仅仅可以进行数据写入,也可以执行查询和订阅功 ...@@ -379,7 +379,7 @@ taosdemo 不仅仅可以进行数据写入,也可以执行查询和订阅功
"threads": 并发执行sqls的线程数,可选项,缺省是1。每个线程负责一部分子表,执行所有的sqls。 "threads": 并发执行sqls的线程数,可选项,缺省是1。每个线程负责一部分子表,执行所有的sqls。
"sql": "select count(*) from xxxx"。查询超级表内所有子表的查询语句,其中表名必须写成 “xxxx”,实例会自动替换成子表名。 "sql": "select count(*) from xxxx"。查询超级表内所有子表的查询语句,其中表名必须写成 “xxxx”,实例会自动替换成子表名。
"result": 查询结果写入的文件名。可选项,缺省是空,表示查询结果不写入文件。 "result": 查询结果写入的文件名。可选项,缺省是空,表示查询结果不写入文件。
```
以下为一个典型订阅 JSON 示例文件内容: 以下为一个典型订阅 JSON 示例文件内容:
``` ```
...@@ -422,13 +422,13 @@ taosdemo 不仅仅可以进行数据写入,也可以执行查询和订阅功 ...@@ -422,13 +422,13 @@ taosdemo 不仅仅可以进行数据写入,也可以执行查询和订阅功
} }
``` ```
以下为订阅功能相关的特有参数含义: 以下为订阅功能相关的特有参数含义:
```
"interval": 执行订阅的间隔,单位是秒。可选项,缺省是0。 "interval": 执行订阅的间隔,单位是秒。可选项,缺省是0。
"restart": 订阅重启。"yes":如果订阅已经存在,重新开始,"no": 继续之前的订阅。(请注意执行用户需要对 dataDir 目录有读写权限) "restart": 订阅重启。"yes":如果订阅已经存在,重新开始,"no": 继续之前的订阅。(请注意执行用户需要对 dataDir 目录有读写权限)
"keepProgress": 保留订阅信息进度。yes表示保留订阅信息,no表示不保留。该值为yes,restart为no时,才能继续之前的订阅。 "keepProgress": 保留订阅信息进度。yes表示保留订阅信息,no表示不保留。该值为yes,restart为no时,才能继续之前的订阅。
"resubAfterConsume": 配合 keepProgress 使用,在订阅消费了相应次数后调用 unsubscribe 取消订阅并再次订阅。 "resubAfterConsume": 配合 keepProgress 使用,在订阅消费了相应次数后调用 unsubscribe 取消订阅并再次订阅。
"result": 查询结果写入的文件名。可选项,缺省是空,表示查询结果不写入文件。 注意:每条sql语句后的保存结果的文件不能重名,且生成结果文件时,文件名会附加线程号。 "result": 查询结果写入的文件名。可选项,缺省是空,表示查询结果不写入文件。 注意:每条sql语句后的保存结果的文件不能重名,且生成结果文件时,文件名会附加线程号。
```
结语 结语
-- --
TDengine是涛思数据专为物联网、车联网、工业互联网、IT运维等设计和优化的大数据平台。TDengine 由于数据库内核中创新的数据存储和查询引擎设计,展现出远超同类产品的高效性能。并且由于支持 SQL 语法和多种编程语言的连接器(目前支持 Java, Python, Go, C#, NodeJS, Rust 等),易用性极强,学习成本为零。为了便于运维需求,我们还提供数据迁移和监控功能等相关生态工具软件。 TDengine是涛思数据专为物联网、车联网、工业互联网、IT运维等设计和优化的大数据平台。TDengine 由于数据库内核中创新的数据存储和查询引擎设计,展现出远超同类产品的高效性能。并且由于支持 SQL 语法和多种编程语言的连接器(目前支持 Java, Python, Go, C#, NodeJS, Rust 等),易用性极强,学习成本为零。为了便于运维需求,我们还提供数据迁移和监控功能等相关生态工具软件。
...@@ -440,6 +440,7 @@ TDengine是涛思数据专为物联网、车联网、工业互联网、IT运维 ...@@ -440,6 +440,7 @@ TDengine是涛思数据专为物联网、车联网、工业互联网、IT运维
附录 - 完整 taosdemo 参数介绍 附录 - 完整 taosdemo 参数介绍
-- --
taosdemo支持两种配置参数的模式,一种是命令行参数,一种是使用 JSON 格式的配置文件。 taosdemo支持两种配置参数的模式,一种是命令行参数,一种是使用 JSON 格式的配置文件。
一、命令行参数 一、命令行参数
-f:指定taosdemo所需参数的meta文件。当使用该参数时,其他所有命令行参数都失效。可选项,缺省是NULL。目前仅支持不含 BOM(byte-order mark)的标准 UTF-8 编码文件。 -f:指定taosdemo所需参数的meta文件。当使用该参数时,其他所有命令行参数都失效。可选项,缺省是NULL。目前仅支持不含 BOM(byte-order mark)的标准 UTF-8 编码文件。
...@@ -508,8 +509,9 @@ taosdemo支持两种配置参数的模式,一种是命令行参数,一种是 ...@@ -508,8 +509,9 @@ taosdemo支持两种配置参数的模式,一种是命令行参数,一种是
二、JSON 格式的配置文件中所有参数说明 二、JSON 格式的配置文件中所有参数说明
taosdemo支持3种功能的测试,包括插入、查询、订阅。但一个taosdemo实例不能同时支持三种功能,一个 taosdemo 实例只能支持其中的一种功能,通过配置文件来指定进行哪种功能的测试。 taosdemo支持3种功能的测试,包括插入、查询、订阅。但一个taosdemo实例不能同时支持三种功能,一个 taosdemo 实例只能支持其中的一种功能,通过配置文件来指定进行哪种功能的测试。
1、插入功能测试的 JSON 配置文件
1、插入功能测试的 JSON 配置文件
```
{ {
"filetype": "insert", "filetype": "insert",
"cfgdir": "/etc/taos", "cfgdir": "/etc/taos",
...@@ -571,6 +573,7 @@ taosdemo支持3种功能的测试,包括插入、查询、订阅。但一个ta ...@@ -571,6 +573,7 @@ taosdemo支持3种功能的测试,包括插入、查询、订阅。但一个ta
}] }]
}] }]
} }
```
"filetype": 本taosdemo实例进行哪种功能测试。"insert"表示数据插入功能。必选项。 "filetype": 本taosdemo实例进行哪种功能测试。"insert"表示数据插入功能。必选项。
...@@ -600,7 +603,7 @@ taosdemo支持3种功能的测试,包括插入、查询、订阅。但一个ta ...@@ -600,7 +603,7 @@ taosdemo支持3种功能的测试,包括插入、查询、订阅。但一个ta
"databases": [{ "databases": [{
"dbinfo": {"name": 数据库名称。必选项。 "dbinfo": {"name": 数据库名称。必选项。
"drop": 如果数据库已经存在,”yes“:删除后重建;”no“:不删除,直接使用。可选项,缺省是”no“。drop = yes 会使其他子表创建相关条目无效。 "drop": 如果数据库已经存在,”yes“:删除后重建;”no“:不删除,直接使用。可选项,缺省是”no“。drop = yes 会使其他子表创建相关条目无效。
...@@ -695,8 +698,9 @@ taosdemo支持3种功能的测试,包括插入、查询、订阅。但一个ta ...@@ -695,8 +698,9 @@ taosdemo支持3种功能的测试,包括插入、查询、订阅。但一个ta
"count":该类型的连续列个数,可选项,缺省是1。 "count":该类型的连续列个数,可选项,缺省是1。
}] }]
2、查询功能测试的 JSON 配置文件
2、查询功能测试的 JSON 配置文件
```
{ {
"filetype": "query", "filetype": "query",
"cfgdir": "/etc/taos", "cfgdir": "/etc/taos",
...@@ -734,7 +738,7 @@ taosdemo支持3种功能的测试,包括插入、查询、订阅。但一个ta ...@@ -734,7 +738,7 @@ taosdemo支持3种功能的测试,包括插入、查询、订阅。但一个ta
] ]
} }
} }
```
"filetype": 本taosdemo实例进行哪种功能测试。"query"表示数据查询功能。必选项。 "filetype": 本taosdemo实例进行哪种功能测试。"query"表示数据查询功能。必选项。
...@@ -784,8 +788,9 @@ taosdemo支持3种功能的测试,包括插入、查询、订阅。但一个ta ...@@ -784,8 +788,9 @@ taosdemo支持3种功能的测试,包括插入、查询、订阅。但一个ta
注意:每条sql语句后的保存结果的文件不能重名,且生成结果文件时,文件名会附加线程号。 注意:每条sql语句后的保存结果的文件不能重名,且生成结果文件时,文件名会附加线程号。
查询结果显示:如果查询线程结束一次查询距开始执行时间超过30秒打印一次查询次数、用时和QPS。所有查询结束时,汇总打印总的查询次数和QPS。 查询结果显示:如果查询线程结束一次查询距开始执行时间超过30秒打印一次查询次数、用时和QPS。所有查询结束时,汇总打印总的查询次数和QPS。
3、订阅功能测试的 JSON 配置文件
3、订阅功能测试的 JSON 配置文件
```
{ {
"filetype":"subscribe", "filetype":"subscribe",
"cfgdir": "/etc/taos", "cfgdir": "/etc/taos",
...@@ -822,7 +827,8 @@ taosdemo支持3种功能的测试,包括插入、查询、订阅。但一个ta ...@@ -822,7 +827,8 @@ taosdemo支持3种功能的测试,包括插入、查询、订阅。但一个ta
"result": "./subscribe_res1.txt" "result": "./subscribe_res1.txt"
}] }]
} }
} }
```
"filetype": 本taosdemo实例进行哪种功能测试。"subscribe"表示数据查询功能。必选项。** "filetype": 本taosdemo实例进行哪种功能测试。"subscribe"表示数据查询功能。必选项。**
...@@ -878,4 +884,4 @@ taosdemo支持3种功能的测试,包括插入、查询、订阅。但一个ta ...@@ -878,4 +884,4 @@ taosdemo支持3种功能的测试,包括插入、查询、订阅。但一个ta
"sql": " select count(*) from xxxx "。查询语句,其中表名必须写成 “xxxx”,实例会自动替换成子表名。 "sql": " select count(*) from xxxx "。查询语句,其中表名必须写成 “xxxx”,实例会自动替换成子表名。
"result": 查询结果写入的文件名。可选项,缺省是空,表示查询结果不写入文件。 注意:每条sql语句后的保存结果的文件不能重名,且生成结果文件时,文件名会附加线程号。 "result": 查询结果写入的文件名。可选项,缺省是空,表示查询结果不写入文件。 注意:每条sql语句后的保存结果的文件不能重名,且生成结果文件时,文件名会附加线程号。
...@@ -30,7 +30,7 @@ wget -qO - http://repos.taosdata.com/tdengine.key | sudo apt-key add - ...@@ -30,7 +30,7 @@ wget -qO - http://repos.taosdata.com/tdengine.key | sudo apt-key add -
echo "deb [arch=amd64] http://repos.taosdata.com/tdengine-stable stable main" | sudo tee /etc/apt/sources.list.d/tdengine-stable.list echo "deb [arch=amd64] http://repos.taosdata.com/tdengine-stable stable main" | sudo tee /etc/apt/sources.list.d/tdengine-stable.list
[ beta 版安装包仓库为可选安装项 ] echo "deb [arch=amd64] http://repos.taosdata.com/tdengine-beta beta main" | sudo tee /etc/apt/sources.list.d/tdengine-beta.list [ beta 版安装包仓库为可选安装项 ] echo "deb [arch=amd64] http://repos.taosdata.com/tdengine-beta beta main" | sudo tee /etc/apt/sources.list.d/tdengine-beta.list
sudo apt-get update sudo apt-get update
apt-get policy tdengine apt-cache policy tdengine
sudo apt-get install tdengine sudo apt-get install tdengine
``` ```
......
...@@ -319,118 +319,9 @@ taosAdapter 相关配置参数请参考 taosadapter --help 命令输出以及相 ...@@ -319,118 +319,9 @@ taosAdapter 相关配置参数请参考 taosadapter --help 命令输出以及相
## <a class="anchor" id="taosadapter2-telegraf"></a> 使用 Bailongma 2.0 接入 Telegraf 数据写入 ## <a class="anchor" id="taosadapter2-telegraf"></a> 使用 Bailongma 2.0 接入 Telegraf 数据写入
*注意:TDengine 新版本(2.3.0.0+)提供新版本 Bailongma ,命名为 taosAdapter ,提供更简便的 Telegraf 数据写入以及其他更强大的功能,Bailongma v2 即之前版本将逐步不再维护。 **注意:**
TDengine 新版本(2.3.0.0+)提供新版本 Bailongma ,命名为 taosAdapter ,提供更简便的 Telegraf 数据写入以及其他更强大的功能,Bailongma v2 及之前版本将逐步不再维护。
[Telegraf](https://www.influxdata.com/time-series-platform/telegraf/)是一流行的IT运维数据采集开源工具,TDengine提供一个小工具[Bailongma](https://github.com/taosdata/Bailongma),只需在Telegraf做简单配置,无需任何代码,就可将Telegraf采集的数据直接写入TDengine,并按规则在TDengine自动创建库和相关表项。博文[用Docker容器快速搭建一个Devops监控Demo](https://www.taosdata.com/blog/2020/02/03/1189.html)即是采用bailongma将Prometheus和Telegraf的数据写入TDengine中的示例,可以参考。
### 从源代码编译 blm_telegraf
用户需要从github下载[Bailongma](https://github.com/taosdata/Bailongma)的源码,使用Golang语言编译器编译生成可执行文件。在开始编译前,需要准备好以下条件:
- Linux操作系统的服务器
- 安装好Golang,1.10版本以上
- 对应的TDengine版本。因为用到了TDengine的客户端动态链接库,因此需要安装好和服务端相同版本的TDengine程序;比如服务端版本是TDengine 2.0.0, 则在Bailongma所在的Linux服务器(可以与TDengine在同一台服务器,或者不同服务器)
Bailongma项目中有一个文件夹blm_telegraf,存放了Telegraf的写入API程序。编译过程如下:
```bash
cd blm_telegraf
go build
```
一切正常的情况下,就会在对应的目录下生成一个blm_telegraf的可执行程序。
### 安装 Telegraf
目前TDengine支持Telegraf 1.7.4以上的版本。用户可以根据当前的操作系统,到Telegraf官网下载安装包,并执行安装。下载地址如下:https://portal.influxdata.com/downloads 。
### 配置 Telegraf
修改Telegraf配置文件/etc/telegraf/telegraf.conf中与TDengine有关的配置项。
在output plugins部分,增加[[outputs.http]]配置项:
- url:Bailongma API服务提供的URL,参考下面的启动示例章节
- data_format:"json"
- json_timestamp_units:"1ms"
在agent部分:
- hostname: 区分不同采集设备的机器名称,需确保其唯一性。
- metric_batch_size: 100,允许Telegraf每批次写入记录最大数量,增大其数量可以降低Telegraf的请求发送频率。
关于如何使用Telegraf采集数据以及更多有关使用Telegraf的信息,请参考Telegraf官方的[文档](https://docs.influxdata.com/telegraf/v1.11/)
### 启动 blm_telegraf 程序
blm_telegraf程序有以下选项,在启动blm_telegraf程序时可以通过设定这些选项来设定blm_telegraf的配置。
```bash
--host
TDengine服务端的IP地址,缺省值为空。
--batch-size
blm_telegraf会将收到的telegraf的数据拼装成TDengine的写入请求,这个参数控制一次发给TDengine的写入请求中携带的数据条数。
--dbname
设置在TDengine中创建的数据库名称,blm_telegraf会自动在TDengine中创建一个以dbname为名称的数据库,缺省值是prometheus。
--dbuser
设置访问TDengine的用户名,缺省值是'root'
--dbpassword
设置访问TDengine的密码,缺省值是'taosdata'
--port
blm_telegraf对telegraf提供服务的端口号。
```
### 启动示例
通过以下命令启动一个blm_telegraf的API服务:
```bash
./blm_telegraf -host 127.0.0.1 -port 8089
```
假设blm_telegraf所在服务器的IP地址为"10.1.2.3",则在telegraf的配置文件中, 在output plugins部分,增加[[outputs.http]]配置项:
```yaml
url = "http://10.1.2.3:8089/telegraf"
```
### 查询 telegraf 写入数据
telegraf产生的数据格式如下:
```json
{
"fields": {
"usage_guest": 0,
"usage_guest_nice": 0,
"usage_idle": 89.7897897897898,
"usage_iowait": 0,
"usage_irq": 0,
"usage_nice": 0,
"usage_softirq": 0,
"usage_steal": 0,
"usage_system": 5.405405405405405,
"usage_user": 4.804804804804805
},
"name": "cpu",
"tags": {
"cpu": "cpu2",
"host": "bogon"
},
"timestamp": 1576464360
}
```
其中,name字段为telegraf采集的时序数据的名称,tags字段为该时序数据的标签。blm_telegraf会以时序数据的名称在TDengine中自动创建一个超级表,并将tags字段中的标签转换成TDengine的tag值,timestamp作为时间戳,fields字段中的值作为该时序数据的值。因此在TDengine的客户端中,可以通过以下指令查到这个数据是否成功写入。
```mysql
use telegraf;
select * from cpu;
```
## <a class="anchor" id="emq"></a>EMQ Broker 直接写入 ## <a class="anchor" id="emq"></a>EMQ Broker 直接写入
......
...@@ -208,6 +208,8 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine ...@@ -208,6 +208,8 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine
返回值为空表示失败。应用程序需要保存返回的参数,以便后续API调用。 返回值为空表示失败。应用程序需要保存返回的参数,以便后续API调用。
**提示:** 同一进程可以根据不同的host/port 连接多个taosd 集群
- `char *taos_get_server_info(TAOS *taos)` - `char *taos_get_server_info(TAOS *taos)`
获取服务端版本信息。 获取服务端版本信息。
......
...@@ -223,7 +223,6 @@ taosd -C ...@@ -223,7 +223,6 @@ taosd -C
| 105 | compressColData | | **S** | bytes | 客户端与服务器之间进行消息通讯过程中,对服务器端查询结果进行列压缩的阈值。 | 0: 对所有查询结果均进行压缩 >0: 查询结果中任意列大小超过该值的消息才进行压缩 -1: 不压缩 | -1 | 2.3.0.0 版本新增。 | | 105 | compressColData | | **S** | bytes | 客户端与服务器之间进行消息通讯过程中,对服务器端查询结果进行列压缩的阈值。 | 0: 对所有查询结果均进行压缩 >0: 查询结果中任意列大小超过该值的消息才进行压缩 -1: 不压缩 | -1 | 2.3.0.0 版本新增。 |
| 106 | tsdbMetaCompactRatio | | **C** | | tsdb meta文件中冗余数据超过多少阈值,开启meta文件的压缩功能 | 0:不开启,[1-100]:冗余数据比例 | 0 | | | 106 | tsdbMetaCompactRatio | | **C** | | tsdb meta文件中冗余数据超过多少阈值,开启meta文件的压缩功能 | 0:不开启,[1-100]:冗余数据比例 | 0 | |
| 107 | rpcForceTcp | | **SC**| | 强制使用TCP传输 | 0: 不开启 1: 开启 | 0 | 在网络比较差的环境中,建议开启。2.0版本新增。| | 107 | rpcForceTcp | | **SC**| | 强制使用TCP传输 | 0: 不开启 1: 开启 | 0 | 在网络比较差的环境中,建议开启。2.0版本新增。|
| 107 | rpcForceTcp | | **SC** | | 强制使用TCP传输。 | 0: 不开启 1: 开启 | 0 | 在网络比较差的环境中,建议开启。2.0 版本新增。 |
**注意:**对于端口,TDengine会使用从serverPort起13个连续的TCP和UDP端口号,请务必在防火墙打开。因此如果是缺省配置,需要打开从6030到6042共13个端口,而且必须TCP和UDP都打开。(详细的端口情况请参见 [TDengine 2.0 端口说明](https://www.taosdata.com/cn/documentation/faq#port) **注意:**对于端口,TDengine会使用从serverPort起13个连续的TCP和UDP端口号,请务必在防火墙打开。因此如果是缺省配置,需要打开从6030到6042共13个端口,而且必须TCP和UDP都打开。(详细的端口情况请参见 [TDengine 2.0 端口说明](https://www.taosdata.com/cn/documentation/faq#port)
......
...@@ -374,7 +374,7 @@ The following is the content of a typical query JSON example file. ...@@ -374,7 +374,7 @@ The following is the content of a typical query JSON example file.
} }
``` ```
The following parameters are specific to the query in the JSON file. The following parameters are specific to the query in the JSON file.
```
"query_times": the number of queries per query type "query_times": the number of queries per query type
"query_mode": query data interface, "tosc": call TDengine's c interface; "resetful": use restfule interface. Options are available. Default is "taosc". "query_mode": query data interface, "tosc": call TDengine's c interface; "resetful": use restfule interface. Options are available. Default is "taosc".
"specified_table_query": { query for the specified table "specified_table_query": { query for the specified table
...@@ -389,7 +389,7 @@ The following parameters are specific to the query in the JSON file. ...@@ -389,7 +389,7 @@ The following parameters are specific to the query in the JSON file.
"threads": the number of threads to execute sqls concurrently, optional, default is 1. Each thread is responsible for a part of sub-tables and executes all sqls. "threads": the number of threads to execute sqls concurrently, optional, default is 1. Each thread is responsible for a part of sub-tables and executes all sqls.
"sql": "select count(*) from xxxx". Query statement for all sub-tables in the super table, where the table name must be written as "xxxx" and the instance will be replaced with the sub-table name automatically. "sql": "select count(*) from xxxx". Query statement for all sub-tables in the super table, where the table name must be written as "xxxx" and the instance will be replaced with the sub-table name automatically.
"result": the name of the file to which the query result is written. Optional, the default is null, which means the query results are not written to a file. "result": the name of the file to which the query result is written. Optional, the default is null, which means the query results are not written to a file.
```
The following is a typical subscription JSON example file content. The following is a typical subscription JSON example file content.
``` ```
...@@ -432,13 +432,13 @@ The following is a typical subscription JSON example file content. ...@@ -432,13 +432,13 @@ The following is a typical subscription JSON example file content.
} }
``` ```
The following are the meanings of the parameters specific to the subscription function. The following are the meanings of the parameters specific to the subscription function.
```
"interval": interval for executing subscriptions, in seconds. Optional, default is 0. "interval": interval for executing subscriptions, in seconds. Optional, default is 0.
"restart": subscription restart." yes": restart the subscription if it already exists, "no": continue the previous subscription. (Please note that the executing user needs to have read/write access to the dataDir directory) "restart": subscription restart." yes": restart the subscription if it already exists, "no": continue the previous subscription. (Please note that the executing user needs to have read/write access to the dataDir directory)
"keepProgress": keep the progress of the subscription information. yes means keep the subscription information, no means don't keep it. The value is yes and restart is no to continue the previous subscriptions. "keepProgress": keep the progress of the subscription information. yes means keep the subscription information, no means don't keep it. The value is yes and restart is no to continue the previous subscriptions.
"resubAfterConsume": Used in conjunction with keepProgress to call unsubscribe after the subscription has been consumed the appropriate number of times and to subscribe again. "resubAfterConsume": Used in conjunction with keepProgress to call unsubscribe after the subscription has been consumed the appropriate number of times and to subscribe again.
"result": the name of the file to which the query result is written. Optional, default is null, means the query result will not be written to the file. Note: The file to save the result after each sql statement cannot be renamed, and the file name will be appended with the thread number when generating the result file. "result": the name of the file to which the query result is written. Optional, default is null, means the query result will not be written to the file. Note: The file to save the result after each sql statement cannot be renamed, and the file name will be appended with the thread number when generating the result file.
```
Conclusion Conclusion
-- --
TDengine is a big data platform designed and optimized for IoT, Telematics, Industrial Internet, DevOps, etc. TDengine shows a high performance that far exceeds similar products due to the innovative data storage and query engine design in the database kernel. And withSQL syntax support and connectors for multiple programming languages (currently Java, Python, Go, C#, NodeJS, Rust, etc. are supported), it is extremely easy to use and has zero learning cost. To facilitate the operation and maintenance needs, we also provide data migration and monitoring functions and other related ecological tools and software. TDengine is a big data platform designed and optimized for IoT, Telematics, Industrial Internet, DevOps, etc. TDengine shows a high performance that far exceeds similar products due to the innovative data storage and query engine design in the database kernel. And withSQL syntax support and connectors for multiple programming languages (currently Java, Python, Go, C#, NodeJS, Rust, etc. are supported), it is extremely easy to use and has zero learning cost. To facilitate the operation and maintenance needs, we also provide data migration and monitoring functions and other related ecological tools and software.
......
# Efficient Data Writing # Efficient Data Writing
TDengine supports multiple ways to write data, including SQL, Prometheus, Telegraf, 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. 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
...@@ -141,141 +141,84 @@ use prometheus; ...@@ -141,141 +141,84 @@ use prometheus;
select * from apiserver_request_latencies_bucket; select * from apiserver_request_latencies_bucket;
``` ```
## <a class="anchor" id="telegraf"></a> Data Writing via Telegraf and taosAdapter
Please refer to [Official document](https://portal.influxdata.com/downloads/) for Telegraf installation.
TDengine version 2.3.0.0+ includes a stand-alone application taosAdapter in charge of receive data insertion from Telegraf.
## <a class="anchor" id="telegraf"></a> Data Writing via Telegraf Configuration:
Please add following words in /etc/telegraf/telegraf.conf. Fill 'database name' with the database name you want to store in the TDengine for Telegraf data. Please fill the values in TDengine server/cluster host, username and password fields.
[Telegraf](https://www.influxdata.com/time-series-platform/telegraf/) is a popular open source tool for IT operation data collection. TDengine provides a simple tool [Bailongma](https://github.com/taosdata/Bailongma), which only needs to be simply configured in Telegraf without any code, and can directly write the data collected by Telegraf into TDengine, then automatically create databases and related table entries in TDengine according to rules. Blog post [Use Docker Container to Quickly Build a Devops Monitoring Demo](https://www.taosdata.com/blog/2020/02/03/1189.html), which is an example of using bailongma to write Prometheus and Telegraf data into TDengine. ```
[[outputs.http]]
### Compile blm_telegraf From Source Code url = "http://<TDengine server/cluster host>:6041/influxdb/v1/write?db=<database name>"
method = "POST"
Users need to download the source code of [Bailongma](https://github.com/taosdata/Bailongma) from github, then compile and generate an executable file using Golang language compiler. Before you start compiling, you need to complete following prepares: timeout = "5s"
username = "<TDengine's username>"
- A server running Linux OS password = "<TDengine's password>"
- Golang version 1.10 and higher installed data_format = "influx"
- An appropriated TDengine version. Because the client dynamic link library of TDengine is used, it is necessary to install the same version of TDengine as the server-side; for example, if the server version is TDengine 2.0. 0, ensure install the same version on the linux server where bailongma is located (can be on the same server as TDengine, or on a different server) influx_max_line_bytes = 250
Bailongma project has a folder, blm_telegraf, which holds the Telegraf writing API. The compiling process is as follows:
```bash
cd blm_telegraf
go build
``` ```
If everything goes well, an executable of blm_telegraf will be generated in the corresponding directory. Then restart telegraf:
```
### Install Telegraf sudo systemctl start telegraf
```
At the moment, TDengine supports Telegraf version 1.7. 4 and above. Users can download the installation package on Telegraf's website according to your current operating system. The download address is as follows: https://portal.influxdata.com/downloads Now you can query the metrics data of Telegraf from TDengine.
### Configure Telegraf
Modify the TDengine-related configurations in the Telegraf configuration file /etc/telegraf/telegraf.conf.
In the output plugins section, add the [[outputs.http]] configuration:
- url: The URL provided by bailongma API service, please refer to the example section below
- data_format: "json"
- json_timestamp_units: "1ms"
In agent section:
- hostname: The machine name that distinguishes different collection devices, and it is necessary to ensure its uniqueness
- metric_batch_size: 100, which is the max number of records per batch written by Telegraf allowed. Increasing the number can reduce the request sending frequency of Telegraf.
For information on how to use Telegraf to collect data and more about using Telegraf, please refer to the official [document](https://docs.influxdata.com/telegraf/v1.11/) of Telegraf.
### Launch blm_telegraf
blm_telegraf has following options, which can be set to tune configurations of blm_telegraf when launching.
```sh
--host
The ip address of TDengine server, default is null
--batch-size
blm_prometheus assembles the received telegraf data into a TDengine writing request. This parameter controls the number of data pieces carried in a writing request sent to TDengine at a time.
--dbname
Set a name for the database created in TDengine, blm_telegraf will automatically create a database named dbname in TDengine, and the default value is prometheus.
--dbuser
Set the user name to access TDengine, the default value is 'root ' Please find taosAdapter configuration and usage from `taosadapter --help` output.
--dbpassword ## <a class="anchor" id="collectd"></a> collectd 直接写入(通过 taosAdapter)
Please refer to [official document](https://collectd.org/download.shtml) for collectd installation.
Set the password to access TDengine, the default value is'taosdata ' TDengine version 2.3.0.0+ includes a stand-alone application taosAdapter in charge of receive data insertion from collectd.
--port Configuration:
Please add following words in /etc/collectd/collectd.conf. Please fill the value 'host' and 'port' with what the TDengine and taosAdapter using.
The port number blm_telegraf used to serve Telegraf.
``` ```
LoadPlugin network
<Plugin network>
Server "<TDengine cluster/server host>" "<port for collectd>"
</Plugin>
```
Then restart collectd
```
sudo systemctl start collectd
```
Please find taosAdapter configuration and usage from `taosadapter --help` output.
## <a class="anchor" id="statsd"></a> StatsD 直接写入(通过 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.
### Example Please add following words in the config.js file. Please fill the value to 'host' and 'port' with what the TDengine and taosAdapter using.
Launch an API service for blm_telegraf with the following command
```bash
./blm_telegraf -host 127.0.0.1 -port 8089
``` ```
add "./backends/repeater" to backends section.
Assuming that the IP address of the server where blm_telegraf located is "10.1.2. 3", the URL shall be added to the configuration file of telegraf as: add { host:'<TDengine server/cluster host>', port: <port for StatsD>} to repeater section.
```yaml
url = "http://10.1.2.3:8089/telegraf"
``` ```
### Query written data of telegraf Example file:
```
The format of generated data by telegraf is as follows:
```json
{ {
"fields": { port: 8125
"usage_guest": 0, , backends: ["./backends/repeater"]
"usage_guest_nice": 0, , repeater: [{ host: '127.0.0.1', port: 6044}]
"usage_idle": 89.7897897897898,
"usage_iowait": 0,
"usage_irq": 0,
"usage_nice": 0,
"usage_softirq": 0,
"usage_steal": 0,
"usage_system": 5.405405405405405,
"usage_user": 4.804804804804805
},
"name": "cpu",
"tags": {
"cpu": "cpu2",
"host": "bogon"
},
"timestamp": 1576464360
} }
``` ```
Where the name field is the name of the time-series data collected by telegraf, and the tag field is the tag of the time-series data. blm_telegraf automatically creates a STable in TDengine with the name of the time series data, and converts the tag field into the tag value of TDengine, with Timestamp as the timestamp and fields values as the value of the time-series data. Therefore, in the client of TDEngine, you can check whether this data was successfully written through the following instruction. Please find taosAdapter configuration and usage from `taosadapter --help` output.
```mysql
use telegraf;
select * from cpu; ## <a class="anchor" id="taosadapter2-telegraf"></a> Insert data via Bailongma 2.0 and Telegraf
```
**Notice:**
TDengine 2.3.0.0+ provides taosAdapter to support Telegraf data writing. Bailongma v2 will be abandoned and no more maintained.
MQTT is a popular data transmission protocol in the IoT. TDengine can easily access the data received by MQTT Broker and write it to TDengine.
## <a class="anchor" id="emq"></a> Data Writing via EMQ Broker ## <a class="anchor" id="emq"></a> Data Writing via EMQ Broker
[EMQ](https://github.com/emqx/emqx) is an open source MQTT Broker software, with no need of coding, only to use "rules" in EMQ Dashboard for simple configuration, and MQTT data can be directly written into TDengine. EMQ X supports storing data to the TDengine by sending it to a Web service, and also provides a native TDengine driver on Enterprise Edition for direct data store. Please refer to [EMQ official documents](https://docs.emqx.io/broker/latest/cn/rule/rule-example.html#%E4%BF%9D%E5%AD%98%E6%95%B0%E6%8D%AE%E5%88%B0-tdengine) for more details. [EMQ](https://github.com/emqx/emqx) is an open source MQTT Broker software, with no need of coding, only to use "rules" in EMQ Dashboard for simple configuration, and MQTT data can be directly written into TDengine. EMQ X supports storing data to the TDengine by sending it to a Web service, and also provides a native TDengine driver on Enterprise Edition for direct data store. Please refer to [EMQ official documents](https://docs.emqx.io/broker/latest/cn/rule/rule-example.html#%E4%BF%9D%E5%AD%98%E6%95%B0%E6%8D%AE%E5%88%B0-tdengine) for more details.
## <a class="anchor" id="hivemq"></a> Data Writing via HiveMQ Broker ## <a class="anchor" id="hivemq"></a> Data Writing via HiveMQ Broker
[HiveMQ](https://www.hivemq.com/) is an MQTT agent that provides Free Personal and Enterprise Edition versions. It is mainly used for enterprises, emerging machine-to-machine(M2M) communication and internal transmission to meet scalability, easy management and security features. HiveMQ provides an open source plug-in development kit. You can store data to TDengine via HiveMQ extension-TDengine. Refer to the [HiveMQ extension-TDengine documentation](https://github.com/huskar-t/hivemq-tdengine-extension/blob/b62a26ecc164a310104df57691691b237e091c89/README.md) for more details. [HiveMQ](https://www.hivemq.com/) is an MQTT agent that provides Free Personal and Enterprise Edition versions. It is mainly used for enterprises, emerging machine-to-machine(M2M) communication and internal transmission to meet scalability, easy management and security features. HiveMQ provides an open source plug-in development kit. You can store data to TDengine via HiveMQ extension-TDengine. Refer to the [HiveMQ extension-TDengine documentation](https://github.com/huskar-t/hivemq-tdengine-extension/blob/b62a26ecc164a310104df57691691b237e091c89/README.md) for more details.
\ No newline at end of file
...@@ -200,6 +200,8 @@ Create a database connection and initialize the connection context. The paramete ...@@ -200,6 +200,8 @@ Create a database connection and initialize the connection context. The paramete
* port: Port number * port: Port number
A null return value indicates a failure. The application needs to save the returned parameters for subsequent API calls. A null return value indicates a failure. The application needs to save the returned parameters for subsequent API calls.
Note: The same process can connect to multiple taosd processes based on ip/port
- `char *taos_get_server_info(TAOS *taos)` - `char *taos_get_server_info(TAOS *taos)`
......
...@@ -100,7 +100,7 @@ static int32_t validateStateWindowNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS ...@@ -100,7 +100,7 @@ static int32_t validateStateWindowNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS
static int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExprItem* pItem, bool outerQuery); static int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExprItem* pItem, bool outerQuery);
static int32_t validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql); static int32_t validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql, bool joinQuery);
static int32_t validateFillNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode); static int32_t validateFillNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode);
static int32_t validateRangeNode(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode); static int32_t validateRangeNode(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode);
static int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode, SSchema* pSchema); static int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode, SSchema* pSchema);
...@@ -191,7 +191,7 @@ bool serializeExprListToVariant(SArray* pList, tVariant **dst, int16_t colType, ...@@ -191,7 +191,7 @@ bool serializeExprListToVariant(SArray* pList, tVariant **dst, int16_t colType,
} }
if (colType == TSDB_DATA_TYPE_BOOL && (var->i64 > 1 ||var->i64 < 0)) { if (colType == TSDB_DATA_TYPE_BOOL && (var->i64 > 1 ||var->i64 < 0)) {
break; break;
} }
tbufWriteInt64(&bw, var->i64); tbufWriteInt64(&bw, var->i64);
} else if (IS_UNSIGNED_NUMERIC_TYPE(colType)) { } else if (IS_UNSIGNED_NUMERIC_TYPE(colType)) {
if (IS_SIGNED_NUMERIC_TYPE(var->nType) || IS_UNSIGNED_NUMERIC_TYPE(var->nType)) { if (IS_SIGNED_NUMERIC_TYPE(var->nType) || IS_UNSIGNED_NUMERIC_TYPE(var->nType)) {
...@@ -472,7 +472,7 @@ int32_t handleUserDefinedFunc(SSqlObj* pSql, struct SSqlInfo* pInfo) { ...@@ -472,7 +472,7 @@ int32_t handleUserDefinedFunc(SSqlObj* pSql, struct SSqlInfo* pInfo) {
} }
createInfo->name.z[createInfo->name.n] = 0; createInfo->name.z[createInfo->name.n] = 0;
// funcname's naming rule is same to column // funcname's naming rule is same to column
if (validateColumnName(createInfo->name.z) != TSDB_CODE_SUCCESS) { if (validateColumnName(createInfo->name.z) != TSDB_CODE_SUCCESS) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
} }
...@@ -603,11 +603,11 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { ...@@ -603,11 +603,11 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
char buf[TSDB_TABLE_FNAME_LEN]; char buf[TSDB_TABLE_FNAME_LEN];
SStrToken sTblToken; SStrToken sTblToken;
sTblToken.z = buf; sTblToken.z = buf;
if (pInfo->type != TSDB_SQL_DROP_DNODE) { if (pInfo->type != TSDB_SQL_DROP_DNODE) {
if ((escapeEnabled && (validateTableName(pzName->z, pzName->n, &sTblToken, &dbIncluded) != TSDB_CODE_SUCCESS)) || if ((escapeEnabled && (validateTableName(pzName->z, pzName->n, &sTblToken, &dbIncluded) != TSDB_CODE_SUCCESS)) ||
((!escapeEnabled) && (tscValidateName(pzName, escapeEnabled, &dbIncluded) != TSDB_CODE_SUCCESS))){ ((!escapeEnabled) && (tscValidateName(pzName, escapeEnabled, &dbIncluded) != TSDB_CODE_SUCCESS))){
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
} }
} }
...@@ -623,7 +623,7 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { ...@@ -623,7 +623,7 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
code = tscSetTableFullName(&pTableMetaInfo->name, &sTblToken, pSql, dbIncluded); code = tscSetTableFullName(&pTableMetaInfo->name, &sTblToken, pSql, dbIncluded);
if(code != TSDB_CODE_SUCCESS) { if(code != TSDB_CODE_SUCCESS) {
return code; return code;
} }
} else if (pInfo->type == TSDB_SQL_DROP_DNODE) { } else if (pInfo->type == TSDB_SQL_DROP_DNODE) {
if (pzName->type == TK_STRING) { if (pzName->type == TK_STRING) {
...@@ -765,7 +765,7 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { ...@@ -765,7 +765,7 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
char buf[TSDB_TABLE_FNAME_LEN]; char buf[TSDB_TABLE_FNAME_LEN];
SStrToken sTblToken; SStrToken sTblToken;
sTblToken.z = buf; sTblToken.z = buf;
if (validateTableName(pToken->z, pToken->n, &sTblToken, &dbIncluded) != TSDB_CODE_SUCCESS) { if (validateTableName(pToken->z, pToken->n, &sTblToken, &dbIncluded) != TSDB_CODE_SUCCESS) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
} }
...@@ -788,7 +788,7 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { ...@@ -788,7 +788,7 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
char buf[TSDB_TABLE_FNAME_LEN]; char buf[TSDB_TABLE_FNAME_LEN];
SStrToken sTblToken; SStrToken sTblToken;
sTblToken.z = buf; sTblToken.z = buf;
if (validateTableName(pToken->z, pToken->n, &sTblToken, &dbIncluded) != TSDB_CODE_SUCCESS) { if (validateTableName(pToken->z, pToken->n, &sTblToken, &dbIncluded) != TSDB_CODE_SUCCESS) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
} }
...@@ -804,7 +804,7 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { ...@@ -804,7 +804,7 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
const char* msg1 = "invalid database name"; const char* msg1 = "invalid database name";
SStrToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0); SStrToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0);
if (tscValidateName(pToken, false, NULL) != TSDB_CODE_SUCCESS) { if (tscValidateName(pToken, false, NULL) != TSDB_CODE_SUCCESS) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
} }
...@@ -2175,16 +2175,16 @@ int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pS ...@@ -2175,16 +2175,16 @@ int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pS
pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES); pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
} }
bool hasDistinct = false; bool hasDistinct = false;
bool hasAgg = false; bool hasAgg = false;
size_t numOfExpr = taosArrayGetSize(pSelNodeList); size_t numOfExpr = taosArrayGetSize(pSelNodeList);
int32_t distIdx = -1; int32_t distIdx = -1;
for (int32_t i = 0; i < numOfExpr; ++i) { for (int32_t i = 0; i < numOfExpr; ++i) {
int32_t outputIndex = (int32_t)tscNumOfExprs(pQueryInfo); int32_t outputIndex = (int32_t)tscNumOfExprs(pQueryInfo);
tSqlExprItem* pItem = taosArrayGet(pSelNodeList, i); tSqlExprItem* pItem = taosArrayGet(pSelNodeList, i);
if (hasDistinct == false) { if (hasDistinct == false) {
hasDistinct = (pItem->distinct == true); hasDistinct = (pItem->distinct == true);
distIdx = hasDistinct ? i : -1; distIdx = hasDistinct ? i : -1;
} }
if(pItem->aliasName != NULL && validateColumnName(pItem->aliasName) != TSDB_CODE_SUCCESS){ if(pItem->aliasName != NULL && validateColumnName(pItem->aliasName) != TSDB_CODE_SUCCESS){
...@@ -2202,7 +2202,7 @@ int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pS ...@@ -2202,7 +2202,7 @@ int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pS
return code; return code;
} }
} else if (type == SQL_NODE_SQLFUNCTION) { } else if (type == SQL_NODE_SQLFUNCTION) {
hasAgg = true; hasAgg = true;
if (hasDistinct) break; if (hasDistinct) break;
pItem->pNode->functionId = isValidFunction(pItem->pNode->Expr.operand.z, pItem->pNode->Expr.operand.n); pItem->pNode->functionId = isValidFunction(pItem->pNode->Expr.operand.z, pItem->pNode->Expr.operand.n);
...@@ -2252,12 +2252,12 @@ int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pS ...@@ -2252,12 +2252,12 @@ int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pS
} }
} }
//TODO(dengyihao), refactor as function //TODO(dengyihao), refactor as function
//handle distinct func mixed with other func //handle distinct func mixed with other func
if (hasDistinct == true) { if (hasDistinct == true) {
if (distIdx != 0 || hasAgg) { if (distIdx != 0 || hasAgg) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4);
} }
if (joinQuery) { if (joinQuery) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6);
} }
...@@ -2267,11 +2267,11 @@ int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pS ...@@ -2267,11 +2267,11 @@ int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pS
if (pQueryInfo->pDownstream != NULL) { if (pQueryInfo->pDownstream != NULL) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg8); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg8);
} }
pQueryInfo->distinct = true; pQueryInfo->distinct = true;
} }
// there is only one user-defined column in the final result field, add the timestamp column. // there is only one user-defined column in the final result field, add the timestamp column.
size_t numOfSrcCols = taosArrayGetSize(pQueryInfo->colList); size_t numOfSrcCols = taosArrayGetSize(pQueryInfo->colList);
if ((numOfSrcCols <= 0 || !hasNoneUserDefineExpr(pQueryInfo)) && !tscQueryTags(pQueryInfo) && !tscQueryBlockInfo(pQueryInfo)) { if ((numOfSrcCols <= 0 || !hasNoneUserDefineExpr(pQueryInfo)) && !tscQueryTags(pQueryInfo) && !tscQueryBlockInfo(pQueryInfo)) {
...@@ -2490,6 +2490,7 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t ...@@ -2490,6 +2490,7 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t
/*SExprInfo* pExpr = */ tscAddFuncInSelectClause(pQueryInfo, startPos, TSDB_FUNC_TAGPRJ, &index, &colSchema, /*SExprInfo* pExpr = */ tscAddFuncInSelectClause(pQueryInfo, startPos, TSDB_FUNC_TAGPRJ, &index, &colSchema,
TSDB_COL_TAG, getNewResColId(pCmd)); TSDB_COL_TAG, getNewResColId(pCmd));
} }
pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
} else { } else {
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
...@@ -2759,7 +2760,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col ...@@ -2759,7 +2760,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
if (pItem->pNode->Expr.paramList == NULL || if (pItem->pNode->Expr.paramList == NULL ||
(functionId != TSDB_FUNC_LEASTSQR && functionId != TSDB_FUNC_DERIVATIVE && functionId != TSDB_FUNC_ELAPSED && numOfParams != 1) || (functionId != TSDB_FUNC_LEASTSQR && functionId != TSDB_FUNC_DERIVATIVE && functionId != TSDB_FUNC_ELAPSED && numOfParams != 1) ||
((functionId == TSDB_FUNC_LEASTSQR || functionId == TSDB_FUNC_DERIVATIVE) && numOfParams != 3) || ((functionId == TSDB_FUNC_LEASTSQR || functionId == TSDB_FUNC_DERIVATIVE) && numOfParams != 3) ||
(functionId == TSDB_FUNC_ELAPSED && numOfParams > 2)) { (functionId == TSDB_FUNC_ELAPSED && numOfParams != 1 && numOfParams != 2)) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
} }
...@@ -4693,7 +4694,12 @@ static int32_t validateSQLExprItem(SSqlCmd* pCmd, tSqlExpr* pExpr, ...@@ -4693,7 +4694,12 @@ static int32_t validateSQLExprItem(SSqlCmd* pCmd, tSqlExpr* pExpr,
if (pExpr->value.nType == (uint32_t)-1) { if (pExpr->value.nType == (uint32_t)-1) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3);
} }
//now allowing now +/- value in select expr
if (pExpr->tokenId == TK_TIMESTAMP) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3);
}
if (pExpr->type == SQL_NODE_VALUE) { if (pExpr->type == SQL_NODE_VALUE) {
*type = SQLEXPR_TYPE_VALUE; *type = SQLEXPR_TYPE_VALUE;
} }
...@@ -5036,11 +5042,13 @@ int32_t handleNeOptr(tSqlExpr** rexpr, tSqlExpr* expr) { ...@@ -5036,11 +5042,13 @@ int32_t handleNeOptr(tSqlExpr** rexpr, tSqlExpr* expr) {
static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SCondExpr* pCondExpr, static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SCondExpr* pCondExpr,
int32_t* type, int32_t* tbIdx, int32_t parentOptr, tSqlExpr** columnExpr, tSqlExpr** tsExpr) { int32_t* type, int32_t* tbIdx, int32_t parentOptr, tSqlExpr** columnExpr,
tSqlExpr** tsExpr, bool joinQuery) {
const char* msg1 = "table query cannot use tags filter"; const char* msg1 = "table query cannot use tags filter";
const char* msg2 = "illegal column name"; const char* msg2 = "illegal column name";
const char* msg4 = "too many join tables"; const char* msg4 = "too many join tables";
const char* msg5 = "not support ordinary column join"; const char* msg5 = "not support ordinary column join";
const char* msg6 = "illegal condition expression";
tSqlExpr* pLeft = (*pExpr)->pLeft; tSqlExpr* pLeft = (*pExpr)->pLeft;
tSqlExpr* pRight = (*pExpr)->pRight; tSqlExpr* pRight = (*pExpr)->pRight;
...@@ -5157,7 +5165,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql ...@@ -5157,7 +5165,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql
} else { } else {
rexpr = *pExpr; rexpr = *pExpr;
} }
ret = setNormalExprToCond(tsExpr, rexpr, parentOptr); ret = setNormalExprToCond(tsExpr, rexpr, parentOptr);
if (type) { if (type) {
*type |= TSQL_EXPR_TS; *type |= TSQL_EXPR_TS;
...@@ -5189,7 +5197,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql ...@@ -5189,7 +5197,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql
*pExpr = NULL; *pExpr = NULL;
if (type) { if (type) {
*type |= TSQL_EXPR_JOIN; *type |= TSQL_EXPR_JOIN;
} }
} else { } else {
// do nothing // do nothing
// ret = setExprToCond(pCmd, &pCondExpr->pTagCond, // ret = setExprToCond(pCmd, &pCondExpr->pTagCond,
...@@ -5202,7 +5210,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql ...@@ -5202,7 +5210,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql
handleNeOptr(&rexpr, *pExpr); handleNeOptr(&rexpr, *pExpr);
*pExpr = rexpr; *pExpr = rexpr;
} }
if (type) { if (type) {
*type |= TSQL_EXPR_TAG; *type |= TSQL_EXPR_TAG;
} }
...@@ -5211,9 +5219,13 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql ...@@ -5211,9 +5219,13 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql
if (type) { if (type) {
*type |= TSQL_EXPR_COLUMN; *type |= TSQL_EXPR_COLUMN;
} }
if (pRight->tokenId == TK_ID) { // other column cannot be served as the join column if (pRight->tokenId == TK_ID) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); if (joinQuery) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); // other column cannot be served as the join column
} else {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6);
}
} }
tSqlExpr *rexpr = NULL; tSqlExpr *rexpr = NULL;
...@@ -5231,7 +5243,8 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql ...@@ -5231,7 +5243,8 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql
} }
int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SCondExpr* pCondExpr, int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SCondExpr* pCondExpr,
int32_t* type, int32_t* tbIdx, int32_t parentOptr, tSqlExpr** columnExpr, tSqlExpr** tsExpr) { int32_t* type, int32_t* tbIdx, int32_t parentOptr, tSqlExpr** columnExpr,
tSqlExpr** tsExpr, bool joinQuery) {
if (pExpr == NULL) { if (pExpr == NULL) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
...@@ -5263,12 +5276,12 @@ int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr ...@@ -5263,12 +5276,12 @@ int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr
int32_t rightTbIdx = 0; int32_t rightTbIdx = 0;
if (!tSqlExprIsParentOfLeaf(*pExpr)) { if (!tSqlExprIsParentOfLeaf(*pExpr)) {
ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pLeft, pCondExpr, type ? &leftType : NULL, &leftTbIdx, (*pExpr)->tokenId, &columnLeft, &tsLeft); ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pLeft, pCondExpr, type ? &leftType : NULL, &leftTbIdx, (*pExpr)->tokenId, &columnLeft, &tsLeft, joinQuery);
if (ret != TSDB_CODE_SUCCESS) { if (ret != TSDB_CODE_SUCCESS) {
goto err_ret; goto err_ret;
} }
ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pRight, pCondExpr, type ? &rightType : NULL, &rightTbIdx, (*pExpr)->tokenId, &columnRight, &tsRight); ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pRight, pCondExpr, type ? &rightType : NULL, &rightTbIdx, (*pExpr)->tokenId, &columnRight, &tsRight, joinQuery);
if (ret != TSDB_CODE_SUCCESS) { if (ret != TSDB_CODE_SUCCESS) {
goto err_ret; goto err_ret;
} }
...@@ -5323,7 +5336,7 @@ int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr ...@@ -5323,7 +5336,7 @@ int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr
goto err_ret; goto err_ret;
} }
ret = handleExprInQueryCond(pCmd, pQueryInfo, pExpr, pCondExpr, type, tbIdx, parentOptr, columnExpr, tsExpr); ret = handleExprInQueryCond(pCmd, pQueryInfo, pExpr, pCondExpr, type, tbIdx, parentOptr, columnExpr, tsExpr, joinQuery);
if (ret) { if (ret) {
goto err_ret; goto err_ret;
} }
...@@ -5863,12 +5876,11 @@ _ret: ...@@ -5863,12 +5876,11 @@ _ret:
int32_t int32_t validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql, bool joinQuery) {
validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql) {
if (pExpr == NULL) { if (pExpr == NULL) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
const char* msg1 = "invalid expression"; const char* msg1 = "invalid expression";
// const char* msg2 = "invalid filter expression"; // const char* msg2 = "invalid filter expression";
...@@ -5892,7 +5904,7 @@ validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql) { ...@@ -5892,7 +5904,7 @@ validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql) {
} }
#endif #endif
if ((ret = getQueryCondExpr(&pSql->cmd, pQueryInfo, pExpr, &condExpr, etype, &tbIdx, (*pExpr)->tokenId, &condExpr.pColumnCond, &condExpr.pTimewindow)) != TSDB_CODE_SUCCESS) { if ((ret = getQueryCondExpr(&pSql->cmd, pQueryInfo, pExpr, &condExpr, etype, &tbIdx, (*pExpr)->tokenId, &condExpr.pColumnCond, &condExpr.pTimewindow, joinQuery)) != TSDB_CODE_SUCCESS) {
goto PARSE_WHERE_EXIT; goto PARSE_WHERE_EXIT;
} }
...@@ -6271,7 +6283,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq ...@@ -6271,7 +6283,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq
const char* msg0 = "only one column allowed in orderby"; const char* msg0 = "only one column allowed in orderby";
const char* msg1 = "invalid column name in orderby clause"; const char* msg1 = "invalid column name in orderby clause";
const char* msg2 = "too many order by columns"; const char* msg2 = "too many order by columns";
const char* msg3 = "only primary timestamp/column in groupby clause allowed as order column"; const char* msg3 = "only primary timestamp, first tag/tbname in groupby clause allowed as order column";
const char* msg4 = "only tag in groupby clause allowed in order clause"; const char* msg4 = "only tag in groupby clause allowed in order clause";
const char* msg5 = "only primary timestamp/column in top/bottom function allowed as order column"; const char* msg5 = "only primary timestamp/column in top/bottom function allowed as order column";
const char* msg6 = "only primary timestamp allowed as the second order column"; const char* msg6 = "only primary timestamp allowed as the second order column";
...@@ -8742,7 +8754,7 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { ...@@ -8742,7 +8754,7 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
if (tscValidateName(pName, true, &dbIncluded1) != TSDB_CODE_SUCCESS) { if (tscValidateName(pName, true, &dbIncluded1) != TSDB_CODE_SUCCESS) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
} }
SRelationInfo* pFromInfo = pInfo->pCreateTableInfo->pSelect->from; SRelationInfo* pFromInfo = pInfo->pCreateTableInfo->pSelect->from;
if (pFromInfo == NULL || taosArrayGetSize(pFromInfo->list) == 0) { if (pFromInfo == NULL || taosArrayGetSize(pFromInfo->list) == 0) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6);
...@@ -8759,7 +8771,7 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { ...@@ -8759,7 +8771,7 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
char buf[TSDB_TABLE_FNAME_LEN]; char buf[TSDB_TABLE_FNAME_LEN];
SStrToken sTblToken; SStrToken sTblToken;
sTblToken.z = buf; sTblToken.z = buf;
int32_t code = validateTableName(srcToken.z, srcToken.n, &sTblToken, &dbIncluded2); int32_t code = validateTableName(srcToken.z, srcToken.n, &sTblToken, &dbIncluded2);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
...@@ -8779,8 +8791,10 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { ...@@ -8779,8 +8791,10 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
int32_t joinQuery = (pSqlNode->from != NULL && taosArrayGetSize(pSqlNode->from->list) > 1);
if (pSqlNode->pWhere != NULL) { // query condition in stream computing if (pSqlNode->pWhere != NULL) { // query condition in stream computing
if (validateWhereNode(pQueryInfo, &pSqlNode->pWhere, pSql) != TSDB_CODE_SUCCESS) { if (validateWhereNode(pQueryInfo, &pSqlNode->pWhere, pSql, joinQuery) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
} }
...@@ -9721,11 +9735,13 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf ...@@ -9721,11 +9735,13 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
(TPARSER_HAS_TOKEN(pSqlNode->interval.interval) || TPARSER_HAS_TOKEN(pSqlNode->sessionVal.gap)); (TPARSER_HAS_TOKEN(pSqlNode->interval.interval) || TPARSER_HAS_TOKEN(pSqlNode->sessionVal.gap));
TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TABLE_QUERY); TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TABLE_QUERY);
int32_t joinQuery = (pSqlNode->from != NULL && taosArrayGetSize(pSqlNode->from->list) > 1);
// parse the group by clause in the first place // parse the group by clause in the first place
if (validateGroupbyNode(pQueryInfo, pSqlNode->pGroupby, pCmd) != TSDB_CODE_SUCCESS) { if (validateGroupbyNode(pQueryInfo, pSqlNode->pGroupby, pCmd) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
if (validateSelectNodeList(pCmd, pQueryInfo, pSqlNode->pSelNodeList, false, timeWindowQuery, true) != if (validateSelectNodeList(pCmd, pQueryInfo, pSqlNode->pSelNodeList, false, timeWindowQuery, true) !=
TSDB_CODE_SUCCESS) { TSDB_CODE_SUCCESS) {
...@@ -9757,7 +9773,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf ...@@ -9757,7 +9773,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
SExprInfo* pExpr = tscExprGet(pQueryInfo, i); SExprInfo* pExpr = tscExprGet(pQueryInfo, i);
int32_t f = pExpr->base.functionId; int32_t f = pExpr->base.functionId;
if (f == TSDB_FUNC_DERIVATIVE || f == TSDB_FUNC_TWA || f == TSDB_FUNC_IRATE || if (f == TSDB_FUNC_DERIVATIVE || f == TSDB_FUNC_TWA || f == TSDB_FUNC_IRATE ||
f == TSDB_FUNC_RATE || f == TSDB_FUNC_DIFF) { f == TSDB_FUNC_RATE || f == TSDB_FUNC_DIFF) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7);
} }
...@@ -9766,7 +9782,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf ...@@ -9766,7 +9782,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
// validate the query filter condition info // validate the query filter condition info
if (pSqlNode->pWhere != NULL) { if (pSqlNode->pWhere != NULL) {
if (validateWhereNode(pQueryInfo, &pSqlNode->pWhere, pSql) != TSDB_CODE_SUCCESS) { if (validateWhereNode(pQueryInfo, &pSqlNode->pWhere, pSql, joinQuery) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
} else { } else {
...@@ -9811,7 +9827,6 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf ...@@ -9811,7 +9827,6 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
} }
// parse the having clause in the first place // parse the having clause in the first place
int32_t joinQuery = (pSqlNode->from != NULL && taosArrayGetSize(pSqlNode->from->list) > 1);
if (validateHavingClause(pQueryInfo, pSqlNode->pHaving, pCmd, pSqlNode->pSelNodeList, joinQuery, timeWindowQuery) != if (validateHavingClause(pQueryInfo, pSqlNode->pHaving, pCmd, pSqlNode->pSelNodeList, joinQuery, timeWindowQuery) !=
TSDB_CODE_SUCCESS) { TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
...@@ -9863,6 +9878,8 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf ...@@ -9863,6 +9878,8 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
int32_t type = isSTable? TSDB_QUERY_TYPE_STABLE_QUERY:TSDB_QUERY_TYPE_TABLE_QUERY; int32_t type = isSTable? TSDB_QUERY_TYPE_STABLE_QUERY:TSDB_QUERY_TYPE_TABLE_QUERY;
TSDB_QUERY_SET_TYPE(pQueryInfo->type, type); TSDB_QUERY_SET_TYPE(pQueryInfo->type, type);
int32_t joinQuery = (pSqlNode->from != NULL && taosArrayGetSize(pSqlNode->from->list) > 1);
// parse the group by clause in the first place // parse the group by clause in the first place
if (validateGroupbyNode(pQueryInfo, pSqlNode->pGroupby, pCmd) != TSDB_CODE_SUCCESS) { if (validateGroupbyNode(pQueryInfo, pSqlNode->pGroupby, pCmd) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
...@@ -9870,7 +9887,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf ...@@ -9870,7 +9887,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
pQueryInfo->onlyHasTagCond = true; pQueryInfo->onlyHasTagCond = true;
// set where info // set where info
if (pSqlNode->pWhere != NULL) { if (pSqlNode->pWhere != NULL) {
if (validateWhereNode(pQueryInfo, &pSqlNode->pWhere, pSql) != TSDB_CODE_SUCCESS) { if (validateWhereNode(pQueryInfo, &pSqlNode->pWhere, pSql, joinQuery) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
...@@ -9881,7 +9898,6 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf ...@@ -9881,7 +9898,6 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
} }
} }
int32_t joinQuery = (pSqlNode->from != NULL && taosArrayGetSize(pSqlNode->from->list) > 1);
int32_t timeWindowQuery = int32_t timeWindowQuery =
(TPARSER_HAS_TOKEN(pSqlNode->interval.interval) || TPARSER_HAS_TOKEN(pSqlNode->sessionVal.gap)); (TPARSER_HAS_TOKEN(pSqlNode->interval.interval) || TPARSER_HAS_TOKEN(pSqlNode->sessionVal.gap));
...@@ -9891,7 +9907,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf ...@@ -9891,7 +9907,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
} }
if (isSTable && tscQueryTags(pQueryInfo) && pQueryInfo->distinct && !pQueryInfo->onlyHasTagCond) { if (isSTable && tscQueryTags(pQueryInfo) && pQueryInfo->distinct && !pQueryInfo->onlyHasTagCond) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
// parse the window_state // parse the window_state
......
...@@ -3783,7 +3783,7 @@ void tscSetQuerySort(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAttr) { ...@@ -3783,7 +3783,7 @@ void tscSetQuerySort(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAttr) {
size_t size = taosArrayGetSize(pQueryInfo->pUpstream); size_t size = taosArrayGetSize(pQueryInfo->pUpstream);
for(int32_t i = 0; i < size; ++i) { for(int32_t i = 0; i < size; ++i) {
SQueryInfo* pq = taosArrayGetP(pQueryInfo->pUpstream, i); SQueryInfo* pq = taosArrayGetP(pQueryInfo->pUpstream, i);
if (pq->groupbyTag && pq->interval.interval > 0) { if (pq->groupbyTag) {
pQueryAttr->needSort = true; pQueryAttr->needSort = true;
return; return;
} }
......
...@@ -113,7 +113,7 @@ int32_t tscAcquireRpc(const char *key, const char *user, const char *secretEncry ...@@ -113,7 +113,7 @@ int32_t tscAcquireRpc(const char *key, const char *user, const char *secretEncry
SRpcObj rpcObj; SRpcObj rpcObj;
memset(&rpcObj, 0, sizeof(rpcObj)); memset(&rpcObj, 0, sizeof(rpcObj));
strncpy(rpcObj.key, key, strlen(key)); tstrncpy(rpcObj.key, key, sizeof(rpcObj.key));
rpcObj.pDnodeConn = rpcOpen(&rpcInit); rpcObj.pDnodeConn = rpcOpen(&rpcInit);
if (rpcObj.pDnodeConn == NULL) { if (rpcObj.pDnodeConn == NULL) {
pthread_mutex_unlock(&rpcObjMutex); pthread_mutex_unlock(&rpcObjMutex);
......
...@@ -4928,7 +4928,11 @@ int32_t createProjectionExpr(SQueryInfo* pQueryInfo, STableMetaInfo* pTableMetaI ...@@ -4928,7 +4928,11 @@ int32_t createProjectionExpr(SQueryInfo* pQueryInfo, STableMetaInfo* pTableMetaI
} }
} }
pse->colInfo.flag = pSource->base.colInfo.flag; //TSDB_COL_NORMAL; if (!pQueryInfo->stableQuery && TSDB_COL_IS_TAG(pSource->base.colInfo.flag)) {
pse->colInfo.flag = (pSource->base.colInfo.flag) & (~TSDB_COL_TAG);
} else {
pse->colInfo.flag = pSource->base.colInfo.flag;
}
pse->resType = pSource->base.resType; pse->resType = pSource->base.resType;
pse->resBytes = pSource->base.resBytes; pse->resBytes = pSource->base.resBytes;
strncpy(pse->colInfo.name, pSource->base.aliasName, tListLen(pse->colInfo.name)); strncpy(pse->colInfo.name, pSource->base.aliasName, tListLen(pse->colInfo.name));
...@@ -5558,7 +5562,7 @@ end: ...@@ -5558,7 +5562,7 @@ end:
int8_t jsonType2DbType(double data, int jsonType){ int8_t jsonType2DbType(double data, int jsonType){
switch(jsonType){ switch(jsonType){
case cJSON_Number: case cJSON_Number:
if (data - (int64_t)data > 0) return TSDB_DATA_TYPE_DOUBLE; else return TSDB_DATA_TYPE_BIGINT; if (data - (int64_t)data == 0) return TSDB_DATA_TYPE_BIGINT; else return TSDB_DATA_TYPE_DOUBLE;
case cJSON_String: case cJSON_String:
return TSDB_DATA_TYPE_NCHAR; return TSDB_DATA_TYPE_NCHAR;
case cJSON_NULL: case cJSON_NULL:
......
...@@ -42,6 +42,7 @@ extern int8_t tsArbOnline; ...@@ -42,6 +42,7 @@ extern int8_t tsArbOnline;
extern int64_t tsArbOnlineTimestamp; extern int64_t tsArbOnlineTimestamp;
extern int32_t tsDnodeId; extern int32_t tsDnodeId;
extern int64_t tsDnodeStartTime; extern int64_t tsDnodeStartTime;
extern int8_t tsDnodeNopLoop;
// common // common
extern int tsRpcTimer; extern int tsRpcTimer;
......
...@@ -39,7 +39,9 @@ typedef struct tVariant { ...@@ -39,7 +39,9 @@ typedef struct tVariant {
bool tVariantIsValid(tVariant *pVar); bool tVariantIsValid(tVariant *pVar);
void tVariantCreate(tVariant *pVar, SStrToken *token, bool needRmquoteEscape); void tVariantCreate(tVariant *pVar, SStrToken *token);
void tVariantCreateExt(tVariant *pVar, SStrToken *token, int32_t optrType, bool needRmquoteEscape);
void tVariantCreateFromBinary(tVariant *pVar, const char *pz, size_t len, uint32_t type); void tVariantCreateFromBinary(tVariant *pVar, const char *pz, size_t len, uint32_t type);
......
...@@ -47,6 +47,7 @@ int64_t tsArbOnlineTimestamp = TSDB_ARB_DUMMY_TIME; ...@@ -47,6 +47,7 @@ int64_t tsArbOnlineTimestamp = TSDB_ARB_DUMMY_TIME;
char tsEmail[TSDB_FQDN_LEN] = {0}; char tsEmail[TSDB_FQDN_LEN] = {0};
int32_t tsDnodeId = 0; int32_t tsDnodeId = 0;
int64_t tsDnodeStartTime = 0; int64_t tsDnodeStartTime = 0;
int8_t tsDnodeNopLoop = 0;
// common // common
int32_t tsRpcTimer = 300; int32_t tsRpcTimer = 300;
...@@ -622,6 +623,16 @@ static void doInitGlobalConfig(void) { ...@@ -622,6 +623,16 @@ static void doInitGlobalConfig(void) {
cfg.unitType = TAOS_CFG_UTYPE_NONE; cfg.unitType = TAOS_CFG_UTYPE_NONE;
taosInitConfigOption(cfg); taosInitConfigOption(cfg);
cfg.option = "dnodeNopLoop";
cfg.ptr = &tsDnodeNopLoop;
cfg.valType = TAOS_CFG_VTYPE_INT8;
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG;
cfg.minValue = 0;
cfg.maxValue = 1;
cfg.ptrLength = 0;
cfg.unitType = TAOS_CFG_UTYPE_NONE;
taosInitConfigOption(cfg);
cfg.option = "balance"; cfg.option = "balance";
cfg.ptr = &tsEnableBalance; cfg.ptr = &tsEnableBalance;
cfg.valType = TAOS_CFG_VTYPE_INT8; cfg.valType = TAOS_CFG_VTYPE_INT8;
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "hash.h" #include "hash.h"
#include "taos.h" #include "taos.h"
#include "taoserror.h"
#include "taosdef.h" #include "taosdef.h"
#include "ttoken.h" #include "ttoken.h"
#include "ttokendef.h" #include "ttokendef.h"
...@@ -30,7 +31,11 @@ ...@@ -30,7 +31,11 @@
assert(0); \ assert(0); \
} while (0) } while (0)
void tVariantCreate(tVariant *pVar, SStrToken *token, bool needRmquoteEscape) { void tVariantCreate(tVariant *pVar, SStrToken *token) {
tVariantCreateExt(pVar, token, TK_ID, true);
}
void tVariantCreateExt(tVariant *pVar, SStrToken *token, int32_t optrType, bool needRmquoteEscape) {
int32_t ret = 0; int32_t ret = 0;
int32_t type = token->type; int32_t type = token->type;
...@@ -54,7 +59,7 @@ void tVariantCreate(tVariant *pVar, SStrToken *token, bool needRmquoteEscape) { ...@@ -54,7 +59,7 @@ void tVariantCreate(tVariant *pVar, SStrToken *token, bool needRmquoteEscape) {
case TSDB_DATA_TYPE_BIGINT: case TSDB_DATA_TYPE_BIGINT:
case TSDB_DATA_TYPE_INT:{ case TSDB_DATA_TYPE_INT:{
ret = tStrToInteger(token->z, token->type, token->n, &pVar->i64, true); ret = tStrToInteger(token->z, token->type, token->n, &pVar->i64, true);
if (ret != 0) { if (ret != TSDB_CODE_SUCCESS) {
SStrToken t = {0}; SStrToken t = {0};
tGetToken(token->z, &t.type); tGetToken(token->z, &t.type);
if (t.type == TK_MINUS) { // it is a signed number which is greater than INT64_MAX or less than INT64_MIN if (t.type == TK_MINUS) { // it is a signed number which is greater than INT64_MAX or less than INT64_MIN
...@@ -64,7 +69,7 @@ void tVariantCreate(tVariant *pVar, SStrToken *token, bool needRmquoteEscape) { ...@@ -64,7 +69,7 @@ void tVariantCreate(tVariant *pVar, SStrToken *token, bool needRmquoteEscape) {
// data overflow, try unsigned parse the input number // data overflow, try unsigned parse the input number
ret = tStrToInteger(token->z, token->type, token->n, &pVar->i64, false); ret = tStrToInteger(token->z, token->type, token->n, &pVar->i64, false);
if (ret != 0) { if (ret != TSDB_CODE_SUCCESS) {
pVar->nType = -1; // -1 means error type pVar->nType = -1; // -1 means error type
return; return;
} }
...@@ -85,15 +90,29 @@ void tVariantCreate(tVariant *pVar, SStrToken *token, bool needRmquoteEscape) { ...@@ -85,15 +90,29 @@ void tVariantCreate(tVariant *pVar, SStrToken *token, bool needRmquoteEscape) {
break; break;
} }
case TSDB_DATA_TYPE_TIMESTAMP: { case TSDB_DATA_TYPE_TIMESTAMP: {
pVar->i64 = taosGetTimestamp(TSDB_TIME_PRECISION_NANO); if (optrType == TK_NOW) {
break; pVar->i64 = taosGetTimestamp(TSDB_TIME_PRECISION_NANO);
} } else if (optrType == TK_PLUS || optrType == TK_MINUS) {
char unit = 0;
ret = parseAbsoluteDuration(token->z, token->n, &pVar->i64, &unit, TSDB_TIME_PRECISION_NANO);
if (ret != TSDB_CODE_SUCCESS) {
pVar->nType = -1; // -1 means error type
return;
}
if (optrType == TK_PLUS) {
pVar->i64 += taosGetTimestamp(TSDB_TIME_PRECISION_NANO);
} else {
pVar->i64 = taosGetTimestamp(TSDB_TIME_PRECISION_NANO) - pVar->i64;
}
}
break;
}
default: { // nType == 0 means the null value default: { // nType == 0 means the null value
type = TSDB_DATA_TYPE_NULL; type = TSDB_DATA_TYPE_NULL;
} }
} }
pVar->nType = type; pVar->nType = type;
} }
...@@ -164,7 +183,7 @@ void tVariantCreateFromBinary(tVariant *pVar, const char *pz, size_t len, uint32 ...@@ -164,7 +183,7 @@ void tVariantCreateFromBinary(tVariant *pVar, const char *pz, size_t len, uint32
pVar->wpz = calloc(1, (lenInwchar + 1) * TSDB_NCHAR_SIZE); pVar->wpz = calloc(1, (lenInwchar + 1) * TSDB_NCHAR_SIZE);
memcpy(pVar->wpz, pz, lenInwchar * TSDB_NCHAR_SIZE); memcpy(pVar->wpz, pz, lenInwchar * TSDB_NCHAR_SIZE);
pVar->nLen = (int32_t)len; pVar->nLen = (int32_t)len;
break; break;
} }
case TSDB_DATA_TYPE_JSON:{ case TSDB_DATA_TYPE_JSON:{
...@@ -179,18 +198,18 @@ void tVariantCreateFromBinary(tVariant *pVar, const char *pz, size_t len, uint32 ...@@ -179,18 +198,18 @@ void tVariantCreateFromBinary(tVariant *pVar, const char *pz, size_t len, uint32
pVar->nLen = (int32_t)len; pVar->nLen = (int32_t)len;
break; break;
} }
default: default:
pVar->i64 = GET_INT32_VAL(pz); pVar->i64 = GET_INT32_VAL(pz);
pVar->nLen = tDataTypes[TSDB_DATA_TYPE_INT].bytes; pVar->nLen = tDataTypes[TSDB_DATA_TYPE_INT].bytes;
} }
pVar->nType = type; pVar->nType = type;
} }
void tVariantDestroy(tVariant *pVar) { void tVariantDestroy(tVariant *pVar) {
if (pVar == NULL) return; if (pVar == NULL) return;
if (pVar->nType == TSDB_DATA_TYPE_BINARY || pVar->nType == TSDB_DATA_TYPE_NCHAR || pVar->nType == TSDB_DATA_TYPE_JSON) { if (pVar->nType == TSDB_DATA_TYPE_BINARY || pVar->nType == TSDB_DATA_TYPE_NCHAR || pVar->nType == TSDB_DATA_TYPE_JSON) {
tfree(pVar->pz); tfree(pVar->pz);
pVar->nLen = 0; pVar->nLen = 0;
...@@ -248,7 +267,7 @@ bool tVariantTypeMatch(tVariant *pVar, int8_t dbType){ ...@@ -248,7 +267,7 @@ bool tVariantTypeMatch(tVariant *pVar, int8_t dbType){
void tVariantAssign(tVariant *pDst, const tVariant *pSrc) { void tVariantAssign(tVariant *pDst, const tVariant *pSrc) {
if (pSrc == NULL || pDst == NULL) return; if (pSrc == NULL || pDst == NULL) return;
pDst->nType = pSrc->nType; pDst->nType = pSrc->nType;
if (pSrc->nType == TSDB_DATA_TYPE_BINARY || pSrc->nType == TSDB_DATA_TYPE_NCHAR || pSrc->nType == TSDB_DATA_TYPE_JSON) { if (pSrc->nType == TSDB_DATA_TYPE_BINARY || pSrc->nType == TSDB_DATA_TYPE_NCHAR || pSrc->nType == TSDB_DATA_TYPE_JSON) {
int32_t len = pSrc->nLen + TSDB_NCHAR_SIZE; int32_t len = pSrc->nLen + TSDB_NCHAR_SIZE;
...@@ -332,14 +351,14 @@ int32_t tVariantCompare(const tVariant* p1, const tVariant* p2) { ...@@ -332,14 +351,14 @@ int32_t tVariantCompare(const tVariant* p1, const tVariant* p2) {
int32_t tVariantToString(tVariant *pVar, char *dst) { int32_t tVariantToString(tVariant *pVar, char *dst) {
if (pVar == NULL || dst == NULL) return 0; if (pVar == NULL || dst == NULL) return 0;
switch (pVar->nType) { switch (pVar->nType) {
case TSDB_DATA_TYPE_BINARY: { case TSDB_DATA_TYPE_BINARY: {
int32_t len = sprintf(dst, "\'%s\'", pVar->pz); int32_t len = sprintf(dst, "\'%s\'", pVar->pz);
assert(len <= pVar->nLen + sizeof("\'") * 2); // two more chars assert(len <= pVar->nLen + sizeof("\'") * 2); // two more chars
return len; return len;
} }
case TSDB_DATA_TYPE_NCHAR: { case TSDB_DATA_TYPE_NCHAR: {
dst[0] = '\''; dst[0] = '\'';
taosUcs4ToMbs(pVar->wpz, (twcslen(pVar->wpz) + 1) * TSDB_NCHAR_SIZE, dst + 1); taosUcs4ToMbs(pVar->wpz, (twcslen(pVar->wpz) + 1) * TSDB_NCHAR_SIZE, dst + 1);
...@@ -348,7 +367,7 @@ int32_t tVariantToString(tVariant *pVar, char *dst) { ...@@ -348,7 +367,7 @@ int32_t tVariantToString(tVariant *pVar, char *dst) {
dst[len + 1] = 0; dst[len + 1] = 0;
return len + 1; return len + 1;
} }
case TSDB_DATA_TYPE_BOOL: case TSDB_DATA_TYPE_BOOL:
case TSDB_DATA_TYPE_TINYINT: case TSDB_DATA_TYPE_TINYINT:
case TSDB_DATA_TYPE_SMALLINT: case TSDB_DATA_TYPE_SMALLINT:
...@@ -357,7 +376,7 @@ int32_t tVariantToString(tVariant *pVar, char *dst) { ...@@ -357,7 +376,7 @@ int32_t tVariantToString(tVariant *pVar, char *dst) {
case TSDB_DATA_TYPE_USMALLINT: case TSDB_DATA_TYPE_USMALLINT:
case TSDB_DATA_TYPE_UINT: case TSDB_DATA_TYPE_UINT:
return sprintf(dst, "%d", (int32_t)pVar->i64); return sprintf(dst, "%d", (int32_t)pVar->i64);
case TSDB_DATA_TYPE_BIGINT: case TSDB_DATA_TYPE_BIGINT:
return sprintf(dst, "%" PRId64, pVar->i64); return sprintf(dst, "%" PRId64, pVar->i64);
case TSDB_DATA_TYPE_UBIGINT: case TSDB_DATA_TYPE_UBIGINT:
...@@ -365,7 +384,7 @@ int32_t tVariantToString(tVariant *pVar, char *dst) { ...@@ -365,7 +384,7 @@ int32_t tVariantToString(tVariant *pVar, char *dst) {
case TSDB_DATA_TYPE_FLOAT: case TSDB_DATA_TYPE_FLOAT:
case TSDB_DATA_TYPE_DOUBLE: case TSDB_DATA_TYPE_DOUBLE:
return sprintf(dst, "%.9lf", pVar->dKey); return sprintf(dst, "%.9lf", pVar->dKey);
default: default:
return 0; return 0;
} }
...@@ -403,21 +422,21 @@ static int32_t toBinary(tVariant *pVariant, char **pDest, int32_t *pDestSize) { ...@@ -403,21 +422,21 @@ static int32_t toBinary(tVariant *pVariant, char **pDest, int32_t *pDestSize) {
if (*pDest == pVariant->pz) { if (*pDest == pVariant->pz) {
pBuf = calloc(1, INITIAL_ALLOC_SIZE); pBuf = calloc(1, INITIAL_ALLOC_SIZE);
} }
if (pVariant->nType == TSDB_DATA_TYPE_NCHAR) { if (pVariant->nType == TSDB_DATA_TYPE_NCHAR) {
size_t newSize = pVariant->nLen * TSDB_NCHAR_SIZE; size_t newSize = pVariant->nLen * TSDB_NCHAR_SIZE;
if (pBuf != NULL) { if (pBuf != NULL) {
if (newSize >= INITIAL_ALLOC_SIZE) { if (newSize >= INITIAL_ALLOC_SIZE) {
pBuf = realloc(pBuf, newSize + 1); pBuf = realloc(pBuf, newSize + 1);
} }
taosUcs4ToMbs(pVariant->wpz, (int32_t)newSize, pBuf); taosUcs4ToMbs(pVariant->wpz, (int32_t)newSize, pBuf);
free(pVariant->wpz); free(pVariant->wpz);
pBuf[newSize] = 0; pBuf[newSize] = 0;
} else { } else {
taosUcs4ToMbs(pVariant->wpz, (int32_t)newSize, *pDest); taosUcs4ToMbs(pVariant->wpz, (int32_t)newSize, *pDest);
} }
} else { } else {
if (IS_SIGNED_NUMERIC_TYPE(pVariant->nType)) { if (IS_SIGNED_NUMERIC_TYPE(pVariant->nType)) {
sprintf(pBuf == NULL ? *pDest : pBuf, "%" PRId64, pVariant->i64); sprintf(pBuf == NULL ? *pDest : pBuf, "%" PRId64, pVariant->i64);
...@@ -429,18 +448,18 @@ static int32_t toBinary(tVariant *pVariant, char **pDest, int32_t *pDestSize) { ...@@ -429,18 +448,18 @@ static int32_t toBinary(tVariant *pVariant, char **pDest, int32_t *pDestSize) {
setNull(pBuf == NULL ? *pDest : pBuf, TSDB_DATA_TYPE_BINARY, 0); setNull(pBuf == NULL ? *pDest : pBuf, TSDB_DATA_TYPE_BINARY, 0);
} }
} }
if (pBuf != NULL) { if (pBuf != NULL) {
*pDest = pBuf; *pDest = pBuf;
} }
*pDestSize = (int32_t)strlen(*pDest); *pDestSize = (int32_t)strlen(*pDest);
return 0; return 0;
} }
static int32_t toNchar(tVariant *pVariant, char **pDest, int32_t *pDestSize) { static int32_t toNchar(tVariant *pVariant, char **pDest, int32_t *pDestSize) {
char tmpBuf[40] = {0}; char tmpBuf[40] = {0};
char * pDst = tmpBuf; char * pDst = tmpBuf;
int32_t nLen = 0; int32_t nLen = 0;
...@@ -778,7 +797,7 @@ int32_t tVariantDumpEx(tVariant *pVariant, char *payload, int16_t type, bool inc ...@@ -778,7 +797,7 @@ int32_t tVariantDumpEx(tVariant *pVariant, char *payload, int16_t type, bool inc
if (converted) { if (converted) {
*converted = true; *converted = true;
} }
if (value > FLT_MAX || value < -FLT_MAX) { if (value > FLT_MAX || value < -FLT_MAX) {
SET_EXT_INFO(converted, value, -FLT_MAX, FLT_MAX, extInfo); SET_EXT_INFO(converted, value, -FLT_MAX, FLT_MAX, extInfo);
return -1; return -1;
...@@ -789,8 +808,8 @@ int32_t tVariantDumpEx(tVariant *pVariant, char *payload, int16_t type, bool inc ...@@ -789,8 +808,8 @@ int32_t tVariantDumpEx(tVariant *pVariant, char *payload, int16_t type, bool inc
if (converted) { if (converted) {
*converted = true; *converted = true;
} }
if (pVariant->i64 > FLT_MAX || pVariant->i64 < -FLT_MAX) { if (pVariant->i64 > FLT_MAX || pVariant->i64 < -FLT_MAX) {
SET_EXT_INFO(converted, pVariant->i64, -FLT_MAX, FLT_MAX, extInfo); SET_EXT_INFO(converted, pVariant->i64, -FLT_MAX, FLT_MAX, extInfo);
return -1; return -1;
} }
...@@ -800,12 +819,12 @@ int32_t tVariantDumpEx(tVariant *pVariant, char *payload, int16_t type, bool inc ...@@ -800,12 +819,12 @@ int32_t tVariantDumpEx(tVariant *pVariant, char *payload, int16_t type, bool inc
if (converted) { if (converted) {
*converted = true; *converted = true;
} }
if (pVariant->dKey > FLT_MAX || pVariant->dKey < -FLT_MAX) { if (pVariant->dKey > FLT_MAX || pVariant->dKey < -FLT_MAX) {
SET_EXT_INFO(converted, pVariant->dKey, -FLT_MAX, FLT_MAX, extInfo); SET_EXT_INFO(converted, pVariant->dKey, -FLT_MAX, FLT_MAX, extInfo);
return -1; return -1;
} }
SET_FLOAT_VAL(payload, pVariant->dKey); SET_FLOAT_VAL(payload, pVariant->dKey);
} else if (pVariant->nType == TSDB_DATA_TYPE_NULL) { } else if (pVariant->nType == TSDB_DATA_TYPE_NULL) {
*((uint32_t *)payload) = TSDB_DATA_FLOAT_NULL; *((uint32_t *)payload) = TSDB_DATA_FLOAT_NULL;
...@@ -850,7 +869,7 @@ int32_t tVariantDumpEx(tVariant *pVariant, char *payload, int16_t type, bool inc ...@@ -850,7 +869,7 @@ int32_t tVariantDumpEx(tVariant *pVariant, char *payload, int16_t type, bool inc
break; break;
} }
case TSDB_DATA_TYPE_BINARY:{ case TSDB_DATA_TYPE_BINARY:{
if (!includeLengthPrefix) { if (!includeLengthPrefix) {
if (pVariant->nType == TSDB_DATA_TYPE_NULL) { if (pVariant->nType == TSDB_DATA_TYPE_NULL) {
...@@ -921,7 +940,7 @@ int32_t tVariantDumpEx(tVariant *pVariant, char *payload, int16_t type, bool inc ...@@ -921,7 +940,7 @@ int32_t tVariantDumpEx(tVariant *pVariant, char *payload, int16_t type, bool inc
assert(p == varDataVal(payload)); assert(p == varDataVal(payload));
} }
} }
break; break;
} }
case TSDB_DATA_TYPE_JSON:{ case TSDB_DATA_TYPE_JSON:{
...@@ -935,7 +954,7 @@ int32_t tVariantDumpEx(tVariant *pVariant, char *payload, int16_t type, bool inc ...@@ -935,7 +954,7 @@ int32_t tVariantDumpEx(tVariant *pVariant, char *payload, int16_t type, bool inc
break; break;
} }
} }
return 0; return 0;
} }
...@@ -950,13 +969,13 @@ int32_t tVariantTypeSetType(tVariant *pVariant, char type) { ...@@ -950,13 +969,13 @@ int32_t tVariantTypeSetType(tVariant *pVariant, char type) {
if (pVariant == NULL || pVariant->nType == 0) { // value is not set if (pVariant == NULL || pVariant->nType == 0) { // value is not set
return 0; return 0;
} }
switch (type) { switch (type) {
case TSDB_DATA_TYPE_BOOL: { // bool case TSDB_DATA_TYPE_BOOL: { // bool
if (convertToBool(pVariant, &pVariant->i64) < 0) { if (convertToBool(pVariant, &pVariant->i64) < 0) {
return -1; return -1;
} }
pVariant->nType = type; pVariant->nType = type;
break; break;
} }
...@@ -977,7 +996,7 @@ int32_t tVariantTypeSetType(tVariant *pVariant, char type) { ...@@ -977,7 +996,7 @@ int32_t tVariantTypeSetType(tVariant *pVariant, char type) {
free(pVariant->pz); free(pVariant->pz);
return -1; return -1;
} }
free(pVariant->pz); free(pVariant->pz);
pVariant->dKey = v; pVariant->dKey = v;
} else if (pVariant->nType == TSDB_DATA_TYPE_NCHAR) { } else if (pVariant->nType == TSDB_DATA_TYPE_NCHAR) {
...@@ -987,14 +1006,14 @@ int32_t tVariantTypeSetType(tVariant *pVariant, char type) { ...@@ -987,14 +1006,14 @@ int32_t tVariantTypeSetType(tVariant *pVariant, char type) {
free(pVariant->pz); free(pVariant->pz);
return -1; return -1;
} }
free(pVariant->pz); free(pVariant->pz);
pVariant->dKey = v; pVariant->dKey = v;
} else if (pVariant->nType >= TSDB_DATA_TYPE_BOOL && pVariant->nType <= TSDB_DATA_TYPE_BIGINT) { } else if (pVariant->nType >= TSDB_DATA_TYPE_BOOL && pVariant->nType <= TSDB_DATA_TYPE_BIGINT) {
double tmp = (double) pVariant->i64; double tmp = (double) pVariant->i64;
pVariant->dKey = tmp; pVariant->dKey = tmp;
} }
pVariant->nType = TSDB_DATA_TYPE_DOUBLE; pVariant->nType = TSDB_DATA_TYPE_DOUBLE;
break; break;
} }
...@@ -1015,6 +1034,6 @@ int32_t tVariantTypeSetType(tVariant *pVariant, char type) { ...@@ -1015,6 +1034,6 @@ int32_t tVariantTypeSetType(tVariant *pVariant, char type) {
break; break;
} }
} }
return 0; return 0;
} }
...@@ -3,6 +3,7 @@ using TDengineDriver; ...@@ -3,6 +3,7 @@ using TDengineDriver;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Collections.Generic; using System.Collections.Generic;
namespace Test.UtilsTools namespace Test.UtilsTools
{ {
public class UtilsTools public class UtilsTools
...@@ -163,4 +164,4 @@ namespace Test.UtilsTools ...@@ -163,4 +164,4 @@ namespace Test.UtilsTools
System.Environment.Exit(0); System.Environment.Exit(0);
} }
} }
} }
\ No newline at end of file
Subproject commit 25f8683ece07897fea12c347d369602b2235665f Subproject commit 7da3cc9e4ad1030c2eec250b869a8fa215b4a4b4
...@@ -14,13 +14,43 @@ import java.math.BigDecimal; ...@@ -14,13 +14,43 @@ import java.math.BigDecimal;
import java.sql.*; import java.sql.*;
import java.time.Instant; import java.time.Instant;
import java.time.ZoneOffset; import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.chrono.IsoChronology;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException; import java.time.format.DateTimeParseException;
import java.time.format.ResolverStyle;
import java.time.temporal.ChronoField;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.List; import java.util.List;
public class RestfulResultSet extends AbstractResultSet implements ResultSet { public class RestfulResultSet extends AbstractResultSet implements ResultSet {
public static DateTimeFormatter rfc3339Parser = null;
{
rfc3339Parser = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendValue(ChronoField.YEAR, 4)
.appendLiteral('-')
.appendValue(ChronoField.MONTH_OF_YEAR, 2)
.appendLiteral('-')
.appendValue(ChronoField.DAY_OF_MONTH, 2)
.appendLiteral('T')
.appendValue(ChronoField.HOUR_OF_DAY, 2)
.appendLiteral(':')
.appendValue(ChronoField.MINUTE_OF_HOUR, 2)
.appendLiteral(':')
.appendValue(ChronoField.SECOND_OF_MINUTE, 2)
.optionalStart()
.appendFraction(ChronoField.NANO_OF_SECOND, 2, 9, true)
.optionalEnd()
.appendOffset("+HH:MM", "Z").toFormatter()
.withResolverStyle(ResolverStyle.STRICT)
.withChronology(IsoChronology.INSTANCE);
}
private final Statement statement; private final Statement statement;
// data // data
private final List<List<Object>> resultSet = new ArrayList<>(); private final List<List<Object>> resultSet = new ArrayList<>();
...@@ -187,25 +217,41 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { ...@@ -187,25 +217,41 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
} }
case UTC: { case UTC: {
String value = row.getString(colIndex); String value = row.getString(colIndex);
long epochSec = Timestamp.valueOf(value.substring(0, 19).replace("T", " ")).getTime() / 1000; if (value.lastIndexOf(":") > 19) {
int fractionalSec = Integer.parseInt(value.substring(20, value.length() - 5)); ZonedDateTime parse = ZonedDateTime.parse(value, rfc3339Parser);
long nanoAdjustment; long nanoAdjustment;
if (value.length() > 31) { if (value.length() > 32) {
// ns timestamp: yyyy-MM-ddTHH:mm:ss.SSSSSSSSS+0x00 // ns timestamp: yyyy-MM-ddTHH:mm:ss.SSSSSSSSS+0x:00
nanoAdjustment = fractionalSec; this.timestampPrecision = TimestampPrecision.NS;
this.timestampPrecision = TimestampPrecision.NS; } else if (value.length() > 29) {
} else if (value.length() > 28) { // ms timestamp: yyyy-MM-ddTHH:mm:ss.SSSSSS+0x:00
// ms timestamp: yyyy-MM-ddTHH:mm:ss.SSSSSS+0x00 this.timestampPrecision = TimestampPrecision.US;
nanoAdjustment = fractionalSec * 1000L; } else {
this.timestampPrecision = TimestampPrecision.US; // ms timestamp: yyyy-MM-ddTHH:mm:ss.SSS+0x:00
this.timestampPrecision = TimestampPrecision.MS;
}
return Timestamp.from(parse.toInstant());
} else { } else {
// ms timestamp: yyyy-MM-ddTHH:mm:ss.SSS+0x00 long epochSec = Timestamp.valueOf(value.substring(0, 19).replace("T", " ")).getTime() / 1000;
nanoAdjustment = fractionalSec * 1000_000L; int fractionalSec = Integer.parseInt(value.substring(20, value.length() - 5));
this.timestampPrecision = TimestampPrecision.MS; long nanoAdjustment;
if (value.length() > 32) {
// ns timestamp: yyyy-MM-ddTHH:mm:ss.SSSSSSSSS+0x00
nanoAdjustment = fractionalSec;
this.timestampPrecision = TimestampPrecision.NS;
} else if (value.length() > 29) {
// ms timestamp: yyyy-MM-ddTHH:mm:ss.SSSSSS+0x00
nanoAdjustment = fractionalSec * 1000L;
this.timestampPrecision = TimestampPrecision.US;
} else {
// ms timestamp: yyyy-MM-ddTHH:mm:ss.SSS+0x00
nanoAdjustment = fractionalSec * 1000_000L;
this.timestampPrecision = TimestampPrecision.MS;
}
ZoneOffset zoneOffset = ZoneOffset.of(value.substring(value.length() - 5));
Instant instant = Instant.ofEpochSecond(epochSec, nanoAdjustment).atOffset(zoneOffset).toInstant();
return Timestamp.from(instant);
} }
ZoneOffset zoneOffset = ZoneOffset.of(value.substring(value.length() - 5));
Instant instant = Instant.ofEpochSecond(epochSec, nanoAdjustment).atOffset(zoneOffset).toInstant();
return Timestamp.from(instant);
} }
case STRING: case STRING:
default: { default: {
......
...@@ -72,6 +72,7 @@ public class RestfulStatement extends AbstractStatement { ...@@ -72,6 +72,7 @@ public class RestfulStatement extends AbstractStatement {
} }
this.database = sql.trim().replace("use", "").trim(); this.database = sql.trim().replace("use", "").trim();
this.conn.setCatalog(this.database); this.conn.setCatalog(this.database);
this.conn.setClientInfo(TSDBDriver.PROPERTY_KEY_DBNAME, this.database);
result = false; result = false;
} else if (SqlSyntaxValidator.isDatabaseUnspecifiedQuery(sql)) { } else if (SqlSyntaxValidator.isDatabaseUnspecifiedQuery(sql)) {
executeOneQuery(sql); executeOneQuery(sql);
......
...@@ -128,8 +128,8 @@ public class ParameterBindTest { ...@@ -128,8 +128,8 @@ public class ParameterBindTest {
@After @After
public void after() { public void after() {
try { try {
// Statement stmt = conn.createStatement(); Statement stmt = conn.createStatement();
// stmt.execute("drop database if exists test_pd"); stmt.execute("drop database if exists test_pd");
if (conn != null) if (conn != null)
conn.close(); conn.close();
} catch (SQLException e) { } catch (SQLException e) {
......
...@@ -2,17 +2,23 @@ package com.taosdata.jdbc; ...@@ -2,17 +2,23 @@ package com.taosdata.jdbc;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.taosdata.jdbc.annotation.CatalogRunner;
import com.taosdata.jdbc.annotation.Description;
import com.taosdata.jdbc.annotation.TestTarget;
import com.taosdata.jdbc.enums.SchemalessProtocolType; import com.taosdata.jdbc.enums.SchemalessProtocolType;
import com.taosdata.jdbc.enums.SchemalessTimestampType; import com.taosdata.jdbc.enums.SchemalessTimestampType;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith;
import java.sql.*; import java.sql.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@RunWith(CatalogRunner.class)
@TestTarget(alias = "Schemaless",author = "huolibo", version = "2.0.36")
public class SchemalessInsertTest { public class SchemalessInsertTest {
private final String dbname = "test_schemaless_insert"; private final String dbname = "test_schemaless_insert";
private Connection conn; private Connection conn;
...@@ -23,6 +29,7 @@ public class SchemalessInsertTest { ...@@ -23,6 +29,7 @@ public class SchemalessInsertTest {
* @throws SQLException execute error * @throws SQLException execute error
*/ */
@Test @Test
@Description("line insert")
public void schemalessInsert() throws SQLException { public void schemalessInsert() throws SQLException {
// given // given
String[] lines = new String[]{ String[] lines = new String[]{
...@@ -53,6 +60,7 @@ public class SchemalessInsertTest { ...@@ -53,6 +60,7 @@ public class SchemalessInsertTest {
* @throws SQLException execute error * @throws SQLException execute error
*/ */
@Test @Test
@Description("telnet insert")
public void telnetInsert() throws SQLException { public void telnetInsert() throws SQLException {
// given // given
String[] lines = new String[]{ String[] lines = new String[]{
...@@ -87,6 +95,7 @@ public class SchemalessInsertTest { ...@@ -87,6 +95,7 @@ public class SchemalessInsertTest {
* @throws SQLException execute error * @throws SQLException execute error
*/ */
@Test @Test
@Description("json insert")
public void jsonInsert() throws SQLException { public void jsonInsert() throws SQLException {
// given // given
String json = "[\n" + String json = "[\n" +
...@@ -178,7 +187,6 @@ public class SchemalessInsertTest { ...@@ -178,7 +187,6 @@ public class SchemalessInsertTest {
public void after() { public void after() {
try (Statement stmt = conn.createStatement()) { try (Statement stmt = conn.createStatement()) {
stmt.execute("drop database if exists " + dbname); stmt.execute("drop database if exists " + dbname);
stmt.close();
conn.close(); conn.close();
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
......
...@@ -380,8 +380,12 @@ public class TSDBConnectionTest { ...@@ -380,8 +380,12 @@ public class TSDBConnectionTest {
@AfterClass @AfterClass
public static void afterClass() throws SQLException { public static void afterClass() throws SQLException {
if (conn != null) if (conn != null) {
Statement statement = conn.createStatement();
statement.execute("drop database if exists test");
statement.close();
conn.close(); conn.close();
}
} }
} }
\ No newline at end of file
package com.taosdata.jdbc; package com.taosdata.jdbc;
import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import java.sql.*; import java.sql.*;
......
...@@ -7,6 +7,7 @@ import org.junit.Test; ...@@ -7,6 +7,7 @@ import org.junit.Test;
import java.lang.management.ManagementFactory; import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean; import java.lang.management.RuntimeMXBean;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.SQLWarning;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Properties; import java.util.Properties;
...@@ -19,115 +20,111 @@ public class TSDBJNIConnectorTest { ...@@ -19,115 +20,111 @@ public class TSDBJNIConnectorTest {
private static TSDBResultSetRowData rowData; private static TSDBResultSetRowData rowData;
@Test @Test
public void test() { public void test() throws SQLException {
try { try {
try { //change sleepSeconds when debugging with attach to process to find PID
//change sleepSeconds when debugging with attach to process to find PID int sleepSeconds = -1;
int sleepSeconds = -1; if (sleepSeconds > 0) {
if (sleepSeconds > 0) { RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean();
RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean(); String jvmName = runtimeBean.getName();
String jvmName = runtimeBean.getName(); long pid = Long.valueOf(jvmName.split("@")[0]);
long pid = Long.valueOf(jvmName.split("@")[0]); System.out.println("JVM PID = " + pid);
System.out.println("JVM PID = " + pid);
Thread.sleep(sleepSeconds * 1000);
Thread.sleep(sleepSeconds * 1000);
}
} catch (Exception e) {
e.printStackTrace();
} }
} catch (Exception e) {
e.printStackTrace();
}
// init // init
Properties properties = new Properties(); Properties properties = new Properties();
properties.setProperty(TSDBDriver.PROPERTY_KEY_CONFIG_DIR, "/etc/taos"); properties.setProperty(TSDBDriver.PROPERTY_KEY_CONFIG_DIR, "/etc/taos");
TSDBJNIConnector.init(properties); TSDBJNIConnector.init(properties);
// connect // connect
TSDBJNIConnector connector = new TSDBJNIConnector(); TSDBJNIConnector connector = new TSDBJNIConnector();
connector.connect("127.0.0.1", 6030, null, "root", "taosdata"); connector.connect("127.0.0.1", 6030, null, "root", "taosdata");
// setup // setup
String setupSqlStrs[] = {"create database if not exists d precision \"us\"", String setupSqlStrs[] = {"create database if not exists d precision \"us\"",
"create table if not exists d.t(ts timestamp, f int)", "create table if not exists d.t(ts timestamp, f int)",
"create database if not exists d2", "create database if not exists d2",
"create table if not exists d2.t2(ts timestamp, f int)", "create table if not exists d2.t2(ts timestamp, f int)",
"insert into d.t values(now+100s, 100)", "insert into d.t values(now+100s, 100)",
"insert into d2.t2 values(now+200s, 200)" "insert into d2.t2 values(now+200s, 200)"
}; };
for (String setupSqlStr : setupSqlStrs) { for (String setupSqlStr : setupSqlStrs) {
long setupSql = connector.executeQuery(setupSqlStr); long setupSql = connector.executeQuery(setupSqlStr);
assertEquals(0, connector.getResultTimePrecision(setupSql)); assertEquals(0, connector.getResultTimePrecision(setupSql));
if (connector.isUpdateQuery(setupSql)) { if (connector.isUpdateQuery(setupSql)) {
connector.freeResultSet(setupSql); connector.freeResultSet(setupSql);
}
} }
}
{ {
long sqlObj1 = connector.executeQuery("select * from d2.t2"); long sqlObj1 = connector.executeQuery("select * from d2.t2");
assertEquals(0, connector.getResultTimePrecision(sqlObj1)); assertEquals(0, connector.getResultTimePrecision(sqlObj1));
List<ColumnMetaData> columnMetaDataList = new ArrayList<>(); List<ColumnMetaData> columnMetaDataList = new ArrayList<>();
int code = connector.getSchemaMetaData(sqlObj1, columnMetaDataList); int code = connector.getSchemaMetaData(sqlObj1, columnMetaDataList);
rowData = new TSDBResultSetRowData(columnMetaDataList.size()); rowData = new TSDBResultSetRowData(columnMetaDataList.size());
assertTrue(next(connector, sqlObj1)); assertTrue(next(connector, sqlObj1));
assertEquals(0, connector.getResultTimePrecision(sqlObj1)); assertEquals(0, connector.getResultTimePrecision(sqlObj1));
connector.freeResultSet(sqlObj1); connector.freeResultSet(sqlObj1);
} }
// executeQuery // executeQuery
long pSql = connector.executeQuery("select * from d.t"); long pSql = connector.executeQuery("select * from d.t");
if (connector.isUpdateQuery(pSql)) { if (connector.isUpdateQuery(pSql)) {
connector.freeResultSet(pSql); connector.freeResultSet(pSql);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY);
} }
assertEquals(1, connector.getResultTimePrecision(pSql)); assertEquals(1, connector.getResultTimePrecision(pSql));
// get schema // get schema
List<ColumnMetaData> columnMetaDataList = new ArrayList<>(); List<ColumnMetaData> columnMetaDataList = new ArrayList<>();
int code = connector.getSchemaMetaData(pSql, columnMetaDataList); int code = connector.getSchemaMetaData(pSql, columnMetaDataList);
if (code == TSDBConstants.JNI_CONNECTION_NULL) { if (code == TSDBConstants.JNI_CONNECTION_NULL) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
} }
if (code == TSDBConstants.JNI_RESULT_SET_NULL) { if (code == TSDBConstants.JNI_RESULT_SET_NULL) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_RESULT_SET_NULL); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_RESULT_SET_NULL);
} }
if (code == TSDBConstants.JNI_NUM_OF_FIELDS_0) { if (code == TSDBConstants.JNI_NUM_OF_FIELDS_0) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_NUM_OF_FIELDS_0); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_NUM_OF_FIELDS_0);
} }
assertEquals(1, connector.getResultTimePrecision(pSql));
int columnSize = columnMetaDataList.size();
// print metadata
for (int i = 0; i < columnSize; i++) {
// System.out.println(columnMetaDataList.get(i));
}
rowData = new TSDBResultSetRowData(columnSize);
// iterate resultSet
for (int i = 0; next(connector, pSql); i++) {
assertEquals(1, connector.getResultTimePrecision(pSql)); assertEquals(1, connector.getResultTimePrecision(pSql));
int columnSize = columnMetaDataList.size();
// print metadata
for (int i = 0; i < columnSize; i++) {
System.out.println(columnMetaDataList.get(i));
}
rowData = new TSDBResultSetRowData(columnSize);
// iterate resultSet
for (int i = 0; next(connector, pSql); i++) {
assertEquals(1, connector.getResultTimePrecision(pSql));
System.out.println();
}
// close resultSet
code = connector.freeResultSet(pSql);
if (code == TSDBConstants.JNI_CONNECTION_NULL) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
} else if (code == TSDBConstants.JNI_RESULT_SET_NULL) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_RESULT_SET_NULL);
}
// close statement
connector.executeQuery("use d");
String[] lines = new String[]{
"st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000",
"st,t1=4i64,t3=\"t4\",t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin\",c2=true,c4=5f64,c5=5f64 1626006833640000000"};
connector.insertLines(lines, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO_SECONDS);
// close connection
connector.closeConnection();
} catch (SQLException e) {
e.printStackTrace();
} }
// close resultSet
code = connector.freeResultSet(pSql);
if (code == TSDBConstants.JNI_CONNECTION_NULL) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
} else if (code == TSDBConstants.JNI_RESULT_SET_NULL) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_RESULT_SET_NULL);
}
// close statement
connector.executeQuery("use d");
String[] lines = new String[]{
"st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000",
"st,t1=4i64,t3=\"t4\",t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin\",c2=true,c4=5f64,c5=5f64 1626006833640000000"};
connector.insertLines(lines, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO_SECONDS);
// close connection
connector.executeQuery("drop database if exists d");
connector.executeQuery("drop database if exists d2");
connector.closeConnection();
} }
private static boolean next(TSDBJNIConnector connector, long pSql) throws SQLException { private static boolean next(TSDBJNIConnector connector, long pSql) throws SQLException {
......
...@@ -17,6 +17,7 @@ public class TSDBParameterMetaDataTest { ...@@ -17,6 +17,7 @@ public class TSDBParameterMetaDataTest {
private static PreparedStatement pstmt_select; private static PreparedStatement pstmt_select;
private static ParameterMetaData parameterMetaData_insert; private static ParameterMetaData parameterMetaData_insert;
private static ParameterMetaData parameterMetaData_select; private static ParameterMetaData parameterMetaData_select;
private static final String dbname = "test_pstmt";
@Test @Test
public void getParameterCount() throws SQLException { public void getParameterCount() throws SQLException {
...@@ -152,9 +153,9 @@ public class TSDBParameterMetaDataTest { ...@@ -152,9 +153,9 @@ public class TSDBParameterMetaDataTest {
try { try {
conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"); conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata");
try (Statement stmt = conn.createStatement()) { try (Statement stmt = conn.createStatement()) {
stmt.execute("drop database if exists test_pstmt"); stmt.execute("drop database if exists " + dbname);
stmt.execute("create database if not exists test_pstmt"); stmt.execute("create database if not exists " + dbname);
stmt.execute("use test_pstmt"); stmt.execute("use " + dbname);
stmt.execute("create table weather(ts timestamp, f1 int, f2 bigint, f3 float, f4 double, f5 smallint, f6 tinyint, f7 bool, f8 binary(64), f9 nchar(64)) tags(loc nchar(64))"); stmt.execute("create table weather(ts timestamp, f1 int, f2 bigint, f3 float, f4 double, f5 smallint, f6 tinyint, f7 bool, f8 binary(64), f9 nchar(64)) tags(loc nchar(64))");
stmt.execute("create table t1 using weather tags('beijing')"); stmt.execute("create table t1 using weather tags('beijing')");
} }
...@@ -190,8 +191,12 @@ public class TSDBParameterMetaDataTest { ...@@ -190,8 +191,12 @@ public class TSDBParameterMetaDataTest {
pstmt_insert.close(); pstmt_insert.close();
if (pstmt_select != null) if (pstmt_select != null)
pstmt_select.close(); pstmt_select.close();
if (conn != null) if (conn != null) {
Statement statement = conn.createStatement();
statement.execute("drop database if exists " + dbname);
statement.close();
conn.close(); conn.close();
}
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
......
...@@ -1233,6 +1233,7 @@ public class TSDBPreparedStatementTest { ...@@ -1233,6 +1233,7 @@ public class TSDBPreparedStatementTest {
try { try {
Statement statement = conn.createStatement(); Statement statement = conn.createStatement();
statement.execute("drop database if exists " + dbname); statement.execute("drop database if exists " + dbname);
statement.execute("drop database if exists dbtest");
statement.close(); statement.close();
if (conn != null) if (conn != null)
conn.close(); conn.close();
......
...@@ -668,8 +668,12 @@ public class TSDBResultSetTest { ...@@ -668,8 +668,12 @@ public class TSDBResultSetTest {
rs.close(); rs.close();
if (stmt != null) if (stmt != null)
stmt.close(); stmt.close();
if (conn != null) if (conn != null) {
Statement statement = conn.createStatement();
statement.execute("drop database if exists restful_test");
statement.close();
conn.close(); conn.close();
}
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
......
package com.taosdata.jdbc.annotation;
import java.util.ArrayList;
import java.util.List;
/**
* Test class
*/
public class CatalogClass {
private String name;
private String alias;
private String author;
private String version;
private List<CatalogMethod> methods = new ArrayList<>();
private int total;
private int failure;
public void setTotal(int total) {
this.total = total;
}
public void setFailure(int failure) {
this.failure = failure;
}
public void setAuthor(String author) {
this.author = author;
}
public void setVersion(String version) {
this.version = version;
}
public void setName(String name) {
this.name = name;
}
public void setAlias(String alias) {
this.alias = alias;
}
public void setMethods(List<CatalogMethod> methods) {
this.methods = methods;
}
@Override
public String toString() {
if (methods.size() < 1)
return null;
StringBuilder sb = new StringBuilder();
sb.append("ClassName: ").append(name);
String msg = trim(alias);
if (null != msg)
sb.append("\tAlias:").append(alias);
sb.append("\tTotal:").append(total)
.append("\tFailure:").append(failure).append("\n");
for (CatalogMethod method : methods) {
sb.append("\t").append(method.getName());
sb.append("\t").append(method.isSuccess());
sb.append("\t").append(method.getMessage());
String mAuthor = trim(method.getAuthor());
if (null == mAuthor) {
sb.append("\t").append(author);
} else {
sb.append("\t").append(method.getAuthor());
}
String mVersion = trim(method.getVersion());
if (null == mVersion) {
sb.append("\t").append(version);
} else {
sb.append("\t").append(mVersion);
}
sb.append("\n");
}
return sb.toString();
}
private String trim(String s) {
if (null == s || s.trim().equals("")) {
return null;
} else {
return s.trim();
}
}
}
package com.taosdata.jdbc.annotation;
import org.junit.runner.Description;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;
import java.io.File;
import java.io.FileWriter;
import java.util.LinkedList;
public class CatalogListener extends RunListener {
public static final String CATALOG_FILE = "target/TestCaseCatalog.txt";
CatalogClass catalogClass = null;
private final LinkedList<CatalogMethod> methods = new LinkedList<>();
@Override
public void testRunStarted(Description description) throws Exception {
catalogClass = new CatalogClass();
TestTarget target = description.getAnnotation(TestTarget.class);
if (target != null) {
catalogClass.setAlias(target.alias());
catalogClass.setAuthor(target.author());
catalogClass.setVersion(target.version());
}
catalogClass.setName(getClassName(description.getClassName()));
}
private String getClassName(String name) {
if (null == name || name.trim().equals("")) {
return null;
}
name = name.trim();
int pos = name.lastIndexOf(".");
if (-1 == pos) {
return name;
}
return name.substring(pos + 1);
}
@Override
public void testRunFinished(Result result) throws Exception {
catalogClass.setMethods(methods);
catalogClass.setTotal(result.getRunCount());
catalogClass.setFailure(result.getFailureCount());
File file = new File(CATALOG_FILE);
if (!file.exists()) {
synchronized (CatalogListener.class) {
if (!file.exists()) {
file.createNewFile();
try (FileWriter writer = new FileWriter(file, true)) {
writer.write("\tName\tPass\tMessage\tAuthor\tVersion\n");
writer.write(catalogClass.toString());
}
}
}
} else {
try (FileWriter writer = new FileWriter(file, true)) {
writer.write(catalogClass.toString());
}
}
}
@Override
public void testStarted(Description description) throws Exception {
}
@Override
public void testFinished(Description description) throws Exception {
com.taosdata.jdbc.annotation.Description annotation
= description.getAnnotation(com.taosdata.jdbc.annotation.Description.class);
if (annotation != null) {
CatalogMethod method = new CatalogMethod();
method.setMessage(annotation.value());
method.setAuthor(annotation.author());
method.setVersion(annotation.version());
method.setSuccess(true);
method.setName(description.getMethodName());
methods.addLast(method);
}
}
@Override
public void testFailure(Failure failure) throws Exception {
com.taosdata.jdbc.annotation.Description annotation
= failure.getDescription().getAnnotation(com.taosdata.jdbc.annotation.Description.class);
CatalogMethod method = new CatalogMethod();
method.setMessage(annotation.value());
method.setAuthor(annotation.author());
method.setVersion(annotation.version());
method.setSuccess(false);
method.setName(failure.getDescription().getMethodName());
methods.addFirst(method);
}
@Override
public void testAssumptionFailure(Failure failure) {
}
@Override
public void testIgnored(Description description) throws Exception {
super.testIgnored(description);
}
}
\ No newline at end of file
package com.taosdata.jdbc.annotation;
/**
* Test method
*/
public class CatalogMethod {
private String name;
private boolean success;
private String message;
private String author;
private String version;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
}
package com.taosdata.jdbc.annotation;
import org.junit.internal.AssumptionViolatedException;
import org.junit.internal.runners.model.EachTestNotifier;
import org.junit.runner.notification.RunNotifier;
import org.junit.runner.notification.StoppedByUserException;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement;
public class CatalogRunner extends BlockJUnit4ClassRunner {
public CatalogRunner(Class<?> testClass) throws InitializationError {
super(testClass);
}
@Override
public void run(RunNotifier notifier) {
//add user-defined listener
notifier.addListener(new CatalogListener());
EachTestNotifier testNotifier = new EachTestNotifier(notifier, getDescription());
notifier.fireTestRunStarted(getDescription());
try {
Statement statement = classBlock(notifier);
statement.evaluate();
} catch (AssumptionViolatedException av) {
testNotifier.addFailedAssumption(av);
} catch (StoppedByUserException exception) {
throw exception;
} catch (Throwable e) {
testNotifier.addFailure(e);
}
}
}
\ No newline at end of file
package com.taosdata.jdbc.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Description {
String value();
// git blame author
String author() default "";
// since which version;
String version() default "";
}
package com.taosdata.jdbc.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface TestTarget {
String alias() default "";
String author();
String version() default "";
}
package com.taosdata.jdbc.cases; package com.taosdata.jdbc.cases;
import org.junit.Assert; import org.junit.*;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters; import org.junit.runners.MethodSorters;
import java.sql.*; import java.sql.*;
...@@ -16,36 +13,32 @@ public class InsertDbwithoutUseDbTest { ...@@ -16,36 +13,32 @@ public class InsertDbwithoutUseDbTest {
private static final String host = "127.0.0.1"; private static final String host = "127.0.0.1";
private static Properties properties; private static Properties properties;
private static final Random random = new Random(System.currentTimeMillis()); private static final Random random = new Random(System.currentTimeMillis());
private static final String dbname = "inWithoutDb";
@Test @Test
public void case001() throws SQLException { public void case001() throws SQLException {
// prepare schema // prepare schema
String url = "jdbc:TAOS://127.0.0.1:6030/?user=root&password=taosdata"; String url = "jdbc:TAOS://127.0.0.1:6030/?user=root&password=taosdata";
Connection conn = DriverManager.getConnection(url, properties); Connection conn = DriverManager.getConnection(url, properties);
try (Statement stmt = conn.createStatement()) { Statement stmt = conn.createStatement();
stmt.execute("drop database if exists inWithoutDb"); stmt.execute("drop database if exists " + dbname);
stmt.execute("create database if not exists inWithoutDb"); stmt.execute("create database if not exists " + dbname);
stmt.execute("create table inWithoutDb.weather(ts timestamp, f1 int)"); stmt.execute("create table " + dbname + ".weather(ts timestamp, f1 int)");
}
conn.close(); conn.close();
// execute insert // execute insert
url = "jdbc:TAOS://127.0.0.1:6030/inWithoutDb?user=root&password=taosdata"; url = "jdbc:TAOS://127.0.0.1:6030/" + dbname + "?user=root&password=taosdata";
conn = DriverManager.getConnection(url, properties); conn = DriverManager.getConnection(url, properties);
try (Statement stmt = conn.createStatement()) { stmt = conn.createStatement();
int affectedRow = stmt.executeUpdate("insert into weather(ts, f1) values(now," + random.nextInt(100) + ")"); int affectedRow = stmt.executeUpdate("insert into weather(ts, f1) values(now," + random.nextInt(100) + ")");
Assert.assertEquals(1, affectedRow); Assert.assertEquals(1, affectedRow);
boolean flag = stmt.execute("insert into weather(ts, f1) values(now + 10s," + random.nextInt(100) + ")"); boolean flag = stmt.execute("insert into weather(ts, f1) values(now + 10s," + random.nextInt(100) + ")");
Assert.assertEquals(false, flag); Assert.assertEquals(false, flag);
ResultSet rs = stmt.executeQuery("select count(*) from weather"); ResultSet rs = stmt.executeQuery("select count(*) from weather");
rs.next(); rs.next();
int count = rs.getInt("count(*)"); int count = rs.getInt("count(*)");
Assert.assertEquals(2, count); Assert.assertEquals(2, count);
} catch (SQLException e) {
e.printStackTrace();
}
conn.close(); conn.close();
} }
...@@ -54,28 +47,25 @@ public class InsertDbwithoutUseDbTest { ...@@ -54,28 +47,25 @@ public class InsertDbwithoutUseDbTest {
// prepare the schema // prepare the schema
final String url = "jdbc:TAOS-RS://" + host + ":6041/inWithoutDb?user=root&password=taosdata"; final String url = "jdbc:TAOS-RS://" + host + ":6041/inWithoutDb?user=root&password=taosdata";
Connection conn = DriverManager.getConnection(url, properties); Connection conn = DriverManager.getConnection(url, properties);
try (Statement stmt = conn.createStatement()) { Statement stmt = conn.createStatement();
stmt.execute("drop database if exists inWithoutDb"); stmt.execute("drop database if exists " + dbname);
stmt.execute("create database if not exists inWithoutDb"); stmt.execute("create database if not exists " + dbname);
stmt.execute("create table inWithoutDb.weather(ts timestamp, f1 int)"); stmt.execute("create table " + dbname + ".weather(ts timestamp, f1 int)");
} stmt.close();
conn.close();
// execute // execute
conn = DriverManager.getConnection(url, properties); stmt = conn.createStatement();
try (Statement stmt = conn.createStatement()) { int affectedRow = stmt.executeUpdate("insert into weather(ts, f1) values(now," + random.nextInt(100) + ")");
int affectedRow = stmt.executeUpdate("insert into weather(ts, f1) values(now," + random.nextInt(100) + ")"); Assert.assertEquals(1, affectedRow);
Assert.assertEquals(1, affectedRow); boolean flag = stmt.execute("insert into weather(ts, f1) values(now + 10s," + random.nextInt(100) + ")");
boolean flag = stmt.execute("insert into weather(ts, f1) values(now + 10s," + random.nextInt(100) + ")"); Assert.assertEquals(false, flag);
Assert.assertEquals(false, flag); ResultSet rs = stmt.executeQuery("select count(*) from weather");
ResultSet rs = stmt.executeQuery("select count(*) from weather"); rs.next();
rs.next(); int count = rs.getInt("count(*)");
int count = rs.getInt("count(*)"); Assert.assertEquals(2, count);
Assert.assertEquals(2, count); stmt.execute("drop database if exists " + dbname);
stmt.close();
} catch (SQLException e) { conn.close();
e.printStackTrace();
}
} }
@BeforeClass @BeforeClass
......
...@@ -427,8 +427,12 @@ public class InsertSpecialCharacterJniTest { ...@@ -427,8 +427,12 @@ public class InsertSpecialCharacterJniTest {
@AfterClass @AfterClass
public static void afterClass() throws SQLException { public static void afterClass() throws SQLException {
if (conn != null) if (conn != null) {
Statement statement = conn.createStatement();
statement.execute("drop database if exists " + dbName);
statement.close();
conn.close(); conn.close();
}
} }
} }
...@@ -391,8 +391,12 @@ public class InsertSpecialCharacterRestfulTest { ...@@ -391,8 +391,12 @@ public class InsertSpecialCharacterRestfulTest {
@AfterClass @AfterClass
public static void afterClass() throws SQLException { public static void afterClass() throws SQLException {
if (conn != null) if (conn != null) {
Statement statement = conn.createStatement();
statement.execute("drop database if exists "+ dbName);
statement.close();
conn.close(); conn.close();
}
} }
} }
package com.taosdata.jdbc.cases; package com.taosdata.jdbc.cases;
import org.junit.AfterClass;
import org.junit.Test; import org.junit.Test;
import java.sql.*; import java.sql.*;
public class JDBCTypeAndTypeCompareTest { public class JDBCTypeAndTypeCompareTest {
private static Connection conn;
private static final String dbname = "test";
@Test @Test
public void test() throws SQLException { public void test() throws SQLException {
Connection conn = DriverManager.getConnection("jdbc:TAOS://192.168.17.156:6030/", "root", "taosdata"); conn = DriverManager.getConnection("jdbc:TAOS://127.0.0.1:6030/", "root", "taosdata");
Statement stmt = conn.createStatement(); Statement stmt = conn.createStatement();
stmt.execute("drop database if exists test"); stmt.execute("drop database if exists " + dbname);
stmt.execute("create database if not exists test"); stmt.execute("create database if not exists " + dbname);
stmt.execute("use test"); stmt.execute("use " + dbname);
stmt.execute("create table weather(ts timestamp, f1 int, f2 bigint, f3 float, f4 double, f5 smallint, f6 tinyint, f7 bool, f8 binary(10), f9 nchar(10) )"); stmt.execute("create table weather(ts timestamp, f1 int, f2 bigint, f3 float, f4 double, f5 smallint, f6 tinyint, f7 bool, f8 binary(10), f9 nchar(10) )");
stmt.execute("insert into weather values(now, 1, 2, 3.0, 4.0, 5, 6, true, 'test','test')"); stmt.execute("insert into weather values(now, 1, 2, 3.0, 4.0, 5, 6, true, 'test','test')");
...@@ -29,6 +32,19 @@ public class JDBCTypeAndTypeCompareTest { ...@@ -29,6 +32,19 @@ public class JDBCTypeAndTypeCompareTest {
} }
stmt.close(); stmt.close();
conn.close(); }
@AfterClass
public static void afterClass() {
try {
if (null != conn) {
Statement statement = conn.createStatement();
statement.execute("drop database if exists " + dbname);
statement.close();
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
} }
} }
...@@ -47,7 +47,7 @@ public class MicroSecondPrecisionJNITest { ...@@ -47,7 +47,7 @@ public class MicroSecondPrecisionJNITest {
Assert.assertEquals(timestamp2 % 1000_000l * 1000, nanos); Assert.assertEquals(timestamp2 % 1000_000l * 1000, nanos);
ts = rs.getLong(1); ts = rs.getLong(1);
Assert.assertEquals(timestamp1, ts); Assert.assertEquals(timestamp2, ts);
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
...@@ -79,8 +79,13 @@ public class MicroSecondPrecisionJNITest { ...@@ -79,8 +79,13 @@ public class MicroSecondPrecisionJNITest {
@AfterClass @AfterClass
public static void afterClass() { public static void afterClass() {
try { try {
if (conn != null) if (conn != null) {
Statement statement = conn.createStatement();
statement.execute("drop database " + ms_timestamp_db);
statement.execute("drop database " + us_timestamp_db);
statement.close();
conn.close(); conn.close();
}
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
......
...@@ -47,7 +47,7 @@ public class MicroSecondPrecisionRestfulTest { ...@@ -47,7 +47,7 @@ public class MicroSecondPrecisionRestfulTest {
Assert.assertEquals(timestamp2 % 1000_000l * 1000, nanos); Assert.assertEquals(timestamp2 % 1000_000l * 1000, nanos);
ts = rs.getLong(1); ts = rs.getLong(1);
Assert.assertEquals(timestamp1, ts); Assert.assertEquals(timestamp2, ts);
} }
} }
...@@ -77,7 +77,7 @@ public class MicroSecondPrecisionRestfulTest { ...@@ -77,7 +77,7 @@ public class MicroSecondPrecisionRestfulTest {
Assert.assertEquals(timestamp2 % 1000_000l * 1000, nanos); Assert.assertEquals(timestamp2 % 1000_000l * 1000, nanos);
ts = rs.getLong(1); ts = rs.getLong(1);
Assert.assertEquals(timestamp1, ts); Assert.assertEquals(timestamp2, ts);
} }
} }
...@@ -107,7 +107,7 @@ public class MicroSecondPrecisionRestfulTest { ...@@ -107,7 +107,7 @@ public class MicroSecondPrecisionRestfulTest {
Assert.assertEquals(timestamp2 % 1000_000l * 1000, nanos); Assert.assertEquals(timestamp2 % 1000_000l * 1000, nanos);
ts = rs.getLong(1); ts = rs.getLong(1);
Assert.assertEquals(timestamp1, ts); Assert.assertEquals(timestamp2, ts);
} }
} }
...@@ -142,12 +142,21 @@ public class MicroSecondPrecisionRestfulTest { ...@@ -142,12 +142,21 @@ public class MicroSecondPrecisionRestfulTest {
} }
@AfterClass @AfterClass
public static void afterClass() throws SQLException { public static void afterClass() {
if (conn1 != null) try {
conn1.close(); if (conn1 != null) {
if (conn2 != null) Statement statement = conn1.createStatement();
conn2.close(); statement.execute("drop database if exists " + ms_timestamp_db);
if (conn3 != null) statement.execute("drop database if exists " + us_timestamp_db);
conn3.close(); statement.close();
conn1.close();
}
if (conn2 != null)
conn2.close();
if (conn3 != null)
conn3.close();
}catch (SQLException e){
e.printStackTrace();
}
} }
} }
package com.taosdata.jdbc.cases; package com.taosdata.jdbc.cases;
import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
...@@ -90,4 +91,16 @@ public class MultiConnectionWithDifferentDbTest { ...@@ -90,4 +91,16 @@ public class MultiConnectionWithDifferentDbTest {
} }
} }
@After
public void after() {
String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata";
try (Connection connection = DriverManager.getConnection(url);
Statement statement = connection.createStatement()) {
statement.execute("drop database if exists " + db1);
statement.execute("drop database if exists " + db2);
} catch (SQLException e) {
e.printStackTrace();
}
}
} }
package com.taosdata.jdbc.cases; package com.taosdata.jdbc.cases;
import org.junit.Assert; import org.junit.*;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import java.sql.*; import java.sql.*;
import java.time.Instant; import java.time.Instant;
...@@ -83,9 +80,9 @@ public class NanoSecondTimestampJNITest { ...@@ -83,9 +80,9 @@ public class NanoSecondTimestampJNITest {
// then // then
long actual = rs.getLong(1); long actual = rs.getLong(1);
Assert.assertEquals(ms, actual); Assert.assertEquals(ns, actual);
actual = rs.getLong("ts"); actual = rs.getLong("ts");
Assert.assertEquals(ms, actual); Assert.assertEquals(ns, actual);
} }
@Test @Test
...@@ -160,4 +157,18 @@ public class NanoSecondTimestampJNITest { ...@@ -160,4 +157,18 @@ public class NanoSecondTimestampJNITest {
} }
} }
@AfterClass
public static void afterClass(){
try {
if (null != conn){
Statement statement = conn.createStatement();
statement.execute("drop database if exists " + dbname);
statement.close();
conn.close();
}
}catch (SQLException e){
e.printStackTrace();
}
}
} }
package com.taosdata.jdbc.cases; package com.taosdata.jdbc.cases;
import org.junit.Assert; import org.junit.*;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import java.sql.*; import java.sql.*;
import java.time.Instant; import java.time.Instant;
...@@ -83,9 +80,9 @@ public class NanoSecondTimestampRestfulTest { ...@@ -83,9 +80,9 @@ public class NanoSecondTimestampRestfulTest {
// then // then
long actual = rs.getLong(1); long actual = rs.getLong(1);
Assert.assertEquals(ms, actual); Assert.assertEquals(ns, actual);
actual = rs.getLong("ts"); actual = rs.getLong("ts");
Assert.assertEquals(ms, actual); Assert.assertEquals(ns, actual);
} }
@Test @Test
...@@ -160,4 +157,14 @@ public class NanoSecondTimestampRestfulTest { ...@@ -160,4 +157,14 @@ public class NanoSecondTimestampRestfulTest {
} }
} }
@AfterClass
public static void afterClass() throws SQLException {
if (conn != null){
try (Statement stmt = conn.createStatement()) {
stmt.execute("drop database if exists " + dbname);
}
conn.close();
}
}
} }
...@@ -45,7 +45,11 @@ public class NullValueInResultSetJNITest { ...@@ -45,7 +45,11 @@ public class NullValueInResultSetJNITest {
@After @After
public void after() throws SQLException { public void after() throws SQLException {
if (conn != null) if (conn != null) {
Statement statement = conn.createStatement();
statement.execute("drop database if exists test_null");
statement.close();
conn.close(); conn.close();
}
} }
} }
...@@ -47,7 +47,11 @@ public class NullValueInResultSetRestfulTest { ...@@ -47,7 +47,11 @@ public class NullValueInResultSetRestfulTest {
@After @After
public void after() throws SQLException { public void after() throws SQLException {
if (conn != null) if (conn != null) {
Statement statement = conn.createStatement();
statement.execute("drop database if exists test_null");
statement.close();
conn.close(); conn.close();
}
} }
} }
...@@ -85,7 +85,11 @@ public class NullValueInResultSetTest { ...@@ -85,7 +85,11 @@ public class NullValueInResultSetTest {
public static void afterClass() throws SQLException { public static void afterClass() throws SQLException {
if (conn_restful != null) if (conn_restful != null)
conn_restful.close(); conn_restful.close();
if (conn_jni != null) if (conn_jni != null) {
Statement statement = conn_jni.createStatement();
statement.execute("drop database if exists test_null");
statement.close();
conn_jni.close(); conn_jni.close();
}
} }
} }
...@@ -62,8 +62,12 @@ public class TimestampPrecisionInNanoInJniTest { ...@@ -62,8 +62,12 @@ public class TimestampPrecisionInNanoInJniTest {
@AfterClass @AfterClass
public static void afterClass() { public static void afterClass() {
try { try {
if (conn != null) if (conn != null) {
Statement statement = conn.createStatement();
statement.execute("drop database if exists " + ns_timestamp_db);
statement.close();
conn.close(); conn.close();
}
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
...@@ -83,7 +87,7 @@ public class TimestampPrecisionInNanoInJniTest { ...@@ -83,7 +87,7 @@ public class TimestampPrecisionInNanoInJniTest {
int nanos = rs.getTimestamp(1).getNanos(); int nanos = rs.getTimestamp(1).getNanos();
Assert.assertEquals(ts % 1000_000_000l, nanos); Assert.assertEquals(ts % 1000_000_000l, nanos);
long test_ts = rs.getLong(1); long test_ts = rs.getLong(1);
Assert.assertEquals(ts / 1000_000l, test_ts); Assert.assertEquals(ts, test_ts);
} }
@Test @Test
......
...@@ -62,8 +62,12 @@ public class TimestampPrecisonInNanoRestTest { ...@@ -62,8 +62,12 @@ public class TimestampPrecisonInNanoRestTest {
@AfterClass @AfterClass
public static void afterClass() { public static void afterClass() {
try { try {
if (conn != null) if (conn != null) {
Statement statement = conn.createStatement();
statement.execute("drop database if exists " + ns_timestamp_db);
statement.close();
conn.close(); conn.close();
}
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
...@@ -83,7 +87,7 @@ public class TimestampPrecisonInNanoRestTest { ...@@ -83,7 +87,7 @@ public class TimestampPrecisonInNanoRestTest {
int nanos = rs.getTimestamp(1).getNanos(); int nanos = rs.getTimestamp(1).getNanos();
Assert.assertEquals(ts % 1000_000_000l, nanos); Assert.assertEquals(ts % 1000_000_000l, nanos);
long test_ts = rs.getLong(1); long test_ts = rs.getLong(1);
Assert.assertEquals(ts / 1000_000l, test_ts); Assert.assertEquals(ts, test_ts);
} }
@Test @Test
......
...@@ -156,8 +156,12 @@ public class UnsignedNumberJniTest { ...@@ -156,8 +156,12 @@ public class UnsignedNumberJniTest {
@AfterClass @AfterClass
public static void afterClass() throws SQLException { public static void afterClass() throws SQLException {
if (conn != null) if (conn != null) {
Statement statement = conn.createStatement();
statement.execute("drop database if exists unsign_jni");
statement.close();
conn.close(); conn.close();
}
} }
} }
...@@ -14,6 +14,7 @@ public class UnsignedNumberRestfulTest { ...@@ -14,6 +14,7 @@ public class UnsignedNumberRestfulTest {
private static final String host = "127.0.0.1"; private static final String host = "127.0.0.1";
private static Connection conn; private static Connection conn;
private static long ts; private static long ts;
private static final String dbname = "unsign_restful";
@Test @Test
public void testCase001() throws SQLException { public void testCase001() throws SQLException {
...@@ -148,9 +149,9 @@ public class UnsignedNumberRestfulTest { ...@@ -148,9 +149,9 @@ public class UnsignedNumberRestfulTest {
final String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata"; final String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata";
conn = DriverManager.getConnection(url, properties); conn = DriverManager.getConnection(url, properties);
Statement stmt = conn.createStatement(); Statement stmt = conn.createStatement();
stmt.execute("drop database if exists unsign_restful"); stmt.execute("drop database if exists " + dbname);
stmt.execute("create database if not exists unsign_restful"); stmt.execute("create database if not exists " + dbname);
stmt.execute("use unsign_restful"); stmt.execute("use " + dbname);
stmt.execute("create table us_table(ts timestamp, f1 tinyint unsigned, f2 smallint unsigned, f3 int unsigned, f4 bigint unsigned)"); stmt.execute("create table us_table(ts timestamp, f1 tinyint unsigned, f2 smallint unsigned, f3 int unsigned, f4 bigint unsigned)");
stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + ts + ", 127, 32767,2147483647, 9223372036854775807)"); stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + ts + ", 127, 32767,2147483647, 9223372036854775807)");
stmt.close(); stmt.close();
...@@ -162,8 +163,12 @@ public class UnsignedNumberRestfulTest { ...@@ -162,8 +163,12 @@ public class UnsignedNumberRestfulTest {
@AfterClass @AfterClass
public static void afterClass() { public static void afterClass() {
try { try {
if (conn != null) if (conn != null) {
Statement statement = conn.createStatement();
statement.execute("drop database if exists " + dbname);
statement.close();
conn.close(); conn.close();
}
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
......
package com.taosdata.jdbc.cases; package com.taosdata.jdbc.cases;
import org.junit.AfterClass;
import org.junit.Test; import org.junit.Test;
import java.sql.*; import java.sql.*;
...@@ -8,7 +9,7 @@ import static org.junit.Assert.assertEquals; ...@@ -8,7 +9,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
public class UseNowInsertTimestampTest { public class UseNowInsertTimestampTest {
String url = "jdbc:TAOS://127.0.0.1:6030/?user=root&password=taosdata"; private static String url = "jdbc:TAOS://127.0.0.1:6030/?user=root&password=taosdata";
@Test @Test
public void millisec() throws SQLException { public void millisec() throws SQLException {
...@@ -55,13 +56,14 @@ public class UseNowInsertTimestampTest { ...@@ -55,13 +56,14 @@ public class UseNowInsertTimestampTest {
@Test @Test
public void nanosec() throws SQLException { public void nanosec() throws SQLException {
long now_time = System.currentTimeMillis() * 1000_000L + System.nanoTime() % 1000_000L;
try (Connection conn = DriverManager.getConnection(url)) { try (Connection conn = DriverManager.getConnection(url)) {
Statement stmt = conn.createStatement(); Statement stmt = conn.createStatement();
stmt.execute("drop database if exists test"); stmt.execute("drop database if exists test");
stmt.execute("create database if not exists test precision 'ns'"); stmt.execute("create database if not exists test precision 'ns'");
stmt.execute("use test"); stmt.execute("use test");
stmt.execute("create table weather(ts timestamp, f1 int)"); stmt.execute("create table weather(ts timestamp, f1 int)");
stmt.execute("insert into weather values(now, 1)"); stmt.execute("insert into weather values(" + now_time + ", 1)");
ResultSet rs = stmt.executeQuery("select * from weather"); ResultSet rs = stmt.executeQuery("select * from weather");
rs.next(); rs.next();
...@@ -74,4 +76,15 @@ public class UseNowInsertTimestampTest { ...@@ -74,4 +76,15 @@ public class UseNowInsertTimestampTest {
stmt.execute("drop database if exists test"); stmt.execute("drop database if exists test");
} }
} }
@AfterClass
public static void afterClass() {
try (Connection conn = DriverManager.getConnection(url);
Statement stmt = conn.createStatement()) {
stmt.execute("drop database if exists test");
} catch (SQLException e) {
e.printStackTrace();
}
}
} }
...@@ -45,7 +45,11 @@ public class BadLocaleSettingTest { ...@@ -45,7 +45,11 @@ public class BadLocaleSettingTest {
@AfterClass @AfterClass
public static void afterClass() throws SQLException { public static void afterClass() throws SQLException {
if (conn != null) if (conn != null) {
Statement statement = conn.createStatement();
statement.execute("drop database " + dbName);
statement.close();
conn.close(); conn.close();
}
} }
} }
\ No newline at end of file
...@@ -79,4 +79,15 @@ public class BatchFetchTest { ...@@ -79,4 +79,15 @@ public class BatchFetchTest {
} }
return builder.toString(); return builder.toString();
} }
@AfterClass
public static void afterClass(){
String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata";
try (Connection conn = DriverManager.getConnection(url);
Statement stmt = conn.createStatement()) {
stmt.execute("drop database if exists test");
} catch (SQLException e) {
e.printStackTrace();
}
}
} }
package com.taosdata.jdbc.confprops; package com.taosdata.jdbc.confprops;
import com.taosdata.jdbc.TSDBDriver; import com.taosdata.jdbc.TSDBDriver;
import org.junit.AfterClass;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
...@@ -37,4 +38,18 @@ public class CharsetTest { ...@@ -37,4 +38,18 @@ public class CharsetTest {
} }
} }
@AfterClass
public static void afterClass(){
String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata";
Properties props = new Properties();
props.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
try (Connection conn = DriverManager.getConnection(url, props);
Statement stmt = conn.createStatement()) {
stmt.execute("drop database if exists test");
} catch (SQLException e) {
e.printStackTrace();
}
}
} }
...@@ -29,7 +29,7 @@ public class TimeZoneTest { ...@@ -29,7 +29,7 @@ public class TimeZoneTest {
} }
@Test @Test
public void taosTimeZone() { public void taosTimeZone() throws SQLException {
// given // given
Properties props = new Properties(); Properties props = new Properties();
props.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); props.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
...@@ -39,7 +39,7 @@ public class TimeZoneTest { ...@@ -39,7 +39,7 @@ public class TimeZoneTest {
Statement stmt = connection.createStatement(); Statement stmt = connection.createStatement();
stmt.execute("drop database if exists timezone_test"); stmt.execute("drop database if exists timezone_test");
stmt.execute("create database if not exists timezone_test keep 365000"); stmt.execute("create database if not exists timezone_test keep 36500");
stmt.execute("use timezone_test"); stmt.execute("use timezone_test");
stmt.execute("create table weather(ts timestamp, temperature float)"); stmt.execute("create table weather(ts timestamp, temperature float)");
...@@ -51,7 +51,7 @@ public class TimeZoneTest { ...@@ -51,7 +51,7 @@ public class TimeZoneTest {
System.out.println("ts: " + ts.getTime() + "," + ts); System.out.println("ts: " + ts.getTime() + "," + ts);
} }
stmt.execute("insert into timezone_test.weather(ts, temperature, humidity) values('1970-01-02 00:00:00', 1.0, 2.0)"); stmt.execute("insert into timezone_test.weather(ts, temperature) values('1970-01-02 00:00:00', 1.0)");
rs = stmt.executeQuery("select * from timezone_test.weather"); rs = stmt.executeQuery("select * from timezone_test.weather");
while (rs.next()) { while (rs.next()) {
...@@ -63,8 +63,6 @@ public class TimeZoneTest { ...@@ -63,8 +63,6 @@ public class TimeZoneTest {
stmt.execute("drop database if exists timezone_test"); stmt.execute("drop database if exists timezone_test");
stmt.close(); stmt.close();
} catch (SQLException e) {
e.printStackTrace();
} }
} }
......
package com.taosdata.jdbc.confprops; package com.taosdata.jdbc.confprops;
import com.taosdata.jdbc.TSDBDriver; import com.taosdata.jdbc.TSDBDriver;
import org.junit.Assert; import org.junit.*;
import org.junit.Before;
import org.junit.Test;
import java.sql.*; import java.sql.*;
import java.time.Instant; import java.time.Instant;
import java.util.Calendar;
import java.util.Properties; import java.util.Properties;
public class TimestampFormatTest { public class TimestampFormatTest {
private static final String host = "127.0.0.1"; private static final String host = "127.0.0.1";
private long ts = Instant.now().toEpochMilli(); private long ts = Instant.now().toEpochMilli();
private Connection conn;
@Test @Test
public void string() throws SQLException { public void string() throws SQLException {
...@@ -154,13 +154,27 @@ public class TimestampFormatTest { ...@@ -154,13 +154,27 @@ public class TimestampFormatTest {
@Before @Before
public void before() throws SQLException { public void before() throws SQLException {
String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata"; String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata";
try (Connection conn = DriverManager.getConnection(url); conn = DriverManager.getConnection(url);
Statement stmt = conn.createStatement()) { Statement stmt = conn.createStatement();
stmt.execute("drop database if exists test"); stmt.execute("drop database if exists test");
stmt.execute("create database if not exists test"); stmt.execute("create database if not exists test");
stmt.execute("use test"); stmt.execute("use test");
stmt.execute("create table weather(ts timestamp, temperature nchar(10))"); stmt.execute("create table weather(ts timestamp, temperature nchar(10))");
stmt.execute("insert into weather values(" + ts + ", '北京')"); stmt.execute("insert into weather values(" + ts + ", '北京')");
stmt.close();
}
@After
public void after() {
try {
if (null != conn) {
Statement stmt = conn.createStatement();
stmt.execute("drop database if exists test");
stmt.close();
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
} }
} }
......
...@@ -33,7 +33,6 @@ public class DatabaseSpecifiedTest { ...@@ -33,7 +33,6 @@ public class DatabaseSpecifiedTest {
String loc = rs.getString("loc"); String loc = rs.getString("loc");
assertEquals("beijing", loc); assertEquals("beijing", loc);
} }
connection.close();
} }
@Before @Before
...@@ -59,8 +58,12 @@ public class DatabaseSpecifiedTest { ...@@ -59,8 +58,12 @@ public class DatabaseSpecifiedTest {
@After @After
public void after() { public void after() {
try { try {
if (connection != null) if (connection != null) {
Statement statement = connection.createStatement();
statement.execute("drop database if exists " + dbname);
statement.close();
connection.close(); connection.close();
}
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
......
...@@ -383,8 +383,12 @@ public class RestfulConnectionTest { ...@@ -383,8 +383,12 @@ public class RestfulConnectionTest {
@AfterClass @AfterClass
public static void afterClass() throws SQLException { public static void afterClass() throws SQLException {
if (conn != null) if (conn != null) {
Statement statement = conn.createStatement();
statement.execute("drop database if exists test");
statement.close();
conn.close(); conn.close();
}
} }
} }
\ No newline at end of file
...@@ -18,6 +18,7 @@ public class RestfulParameterMetaDataTest { ...@@ -18,6 +18,7 @@ public class RestfulParameterMetaDataTest {
private static PreparedStatement pstmt_select; private static PreparedStatement pstmt_select;
private static ParameterMetaData parameterMetaData_insert; private static ParameterMetaData parameterMetaData_insert;
private static ParameterMetaData parameterMetaData_select; private static ParameterMetaData parameterMetaData_select;
private static final String dbname = "test_pstmt";
@Test @Test
public void getParameterCount() throws SQLException { public void getParameterCount() throws SQLException {
...@@ -148,9 +149,9 @@ public class RestfulParameterMetaDataTest { ...@@ -148,9 +149,9 @@ public class RestfulParameterMetaDataTest {
Class.forName("com.taosdata.jdbc.rs.RestfulDriver"); Class.forName("com.taosdata.jdbc.rs.RestfulDriver");
conn = DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata"); conn = DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata");
try (Statement stmt = conn.createStatement()) { try (Statement stmt = conn.createStatement()) {
stmt.execute("drop database if exists test_pstmt"); stmt.execute("drop database if exists " + dbname);
stmt.execute("create database if not exists test_pstmt"); stmt.execute("create database if not exists " + dbname);
stmt.execute("use test_pstmt"); stmt.execute("use " + dbname);
stmt.execute("create table weather(ts timestamp, f1 int, f2 bigint, f3 float, f4 double, f5 smallint, f6 tinyint, f7 bool, f8 binary(64), f9 nchar(64)) tags(loc nchar(64))"); stmt.execute("create table weather(ts timestamp, f1 int, f2 bigint, f3 float, f4 double, f5 smallint, f6 tinyint, f7 bool, f8 binary(64), f9 nchar(64)) tags(loc nchar(64))");
stmt.execute("create table t1 using weather tags('beijing')"); stmt.execute("create table t1 using weather tags('beijing')");
} }
...@@ -186,8 +187,12 @@ public class RestfulParameterMetaDataTest { ...@@ -186,8 +187,12 @@ public class RestfulParameterMetaDataTest {
pstmt_insert.close(); pstmt_insert.close();
if (pstmt_select != null) if (pstmt_select != null)
pstmt_select.close(); pstmt_select.close();
if (conn != null) if (conn != null) {
Statement statement = conn.createStatement();
statement.execute("drop database if exists " + dbname);
statement.close();
conn.close(); conn.close();
}
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
......
...@@ -400,8 +400,12 @@ public class RestfulPreparedStatementTest { ...@@ -400,8 +400,12 @@ public class RestfulPreparedStatementTest {
pstmt_select.close(); pstmt_select.close();
if (pstmt_without_parameters != null) if (pstmt_without_parameters != null)
pstmt_without_parameters.close(); pstmt_without_parameters.close();
if (conn != null) if (conn != null) {
Statement statement = conn.createStatement();
statement.execute("drop database if exists test_pstmt");
statement.close();
conn.close(); conn.close();
}
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
......
...@@ -15,6 +15,7 @@ public class RestfulResultSetMetaDataTest { ...@@ -15,6 +15,7 @@ public class RestfulResultSetMetaDataTest {
private static Statement stmt; private static Statement stmt;
private static ResultSet rs; private static ResultSet rs;
private static ResultSetMetaData meta; private static ResultSetMetaData meta;
private static final String dbname = "restful_test";
@Test @Test
public void getColumnCount() throws SQLException { public void getColumnCount() throws SQLException {
...@@ -206,8 +207,12 @@ public class RestfulResultSetMetaDataTest { ...@@ -206,8 +207,12 @@ public class RestfulResultSetMetaDataTest {
rs.close(); rs.close();
if (stmt != null) if (stmt != null)
stmt.close(); stmt.close();
if (conn != null) if (conn != null) {
Statement statement = conn.createStatement();
statement.execute("drop database if exists " + dbname);
statement.close();
conn.close(); conn.close();
}
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
......
...@@ -3,7 +3,6 @@ var conn = taos.connect(); ...@@ -3,7 +3,6 @@ var conn = taos.connect();
var c1 = conn.cursor(); var c1 = conn.cursor();
let stime = new Date(); let stime = new Date();
let interval = 1000; let interval = 1000;
function convertDateToTS(date) { function convertDateToTS(date) {
let tsArr = date.toISOString().split("T") let tsArr = date.toISOString().split("T")
return "\"" + tsArr[0] + " " + tsArr[1].substring(0, tsArr[1].length - 1) + "\""; return "\"" + tsArr[0] + " " + tsArr[1].substring(0, tsArr[1].length - 1) + "\"";
......
const taos = require('../tdengine'); const taos = require('../tdengine');
var conn = taos.connect({ host: "127.0.0.1", user: "root", password: "taosdata", config: "/etc/taos", port: 10 }); var conn = taos.connect({ host: "127.0.0.1", user: "root", password: "taosdata", config: "/etc/taos", port: 10 });
var c1 = conn.cursor(); var c1 = conn.cursor();
executeUpdate("create database nodedb;"); executeUpdate("create database if not exists nodedb;");
executeUpdate("use nodedb;"); executeUpdate("use nodedb;");
executeUpdate("create table unsigntest(ts timestamp,ut tinyint unsigned,us smallint unsigned,ui int unsigned,ub bigint unsigned,bi bigint);"); executeUpdate("create table if not exists unsigntest(ts timestamp,ut tinyint unsigned,us smallint unsigned,ui int unsigned,ub bigint unsigned,bi bigint);");
executeUpdate("insert into unsigntest values (now, 254,65534,4294967294,18446744073709551614,9223372036854775807);"); executeUpdate("insert into unsigntest values (now, 254,65534,4294967294,18446744073709551614,9223372036854775807);");
executeUpdate("insert into unsigntest values (now, 0,0,0,0,-9223372036854775807);"); executeUpdate("insert into unsigntest values (now, 0,0,0,0,-9223372036854775807);");
executeQuery("select * from unsigntest;"); executeQuery("select * from unsigntest;");
executeUpdate("drop database nodedb;"); executeUpdate("drop database if exists nodedb;");
function executeUpdate(sql) { function executeUpdate(sql) {
console.log(sql); console.log(sql);
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "tconfig.h" #include "tconfig.h"
#include "dnodeMain.h" #include "dnodeMain.h"
bool dnodeExit = false;
static tsem_t exitSem; static tsem_t exitSem;
static void siguser1Handler(int32_t signum, void *sigInfo, void *context); static void siguser1Handler(int32_t signum, void *sigInfo, void *context);
static void siguser2Handler(int32_t signum, void *sigInfo, void *context); static void siguser2Handler(int32_t signum, void *sigInfo, void *context);
...@@ -182,6 +183,8 @@ static void sigintHandler(int32_t signum, void *sigInfo, void *context) { ...@@ -182,6 +183,8 @@ static void sigintHandler(int32_t signum, void *sigInfo, void *context) {
syslog(LOG_INFO, "Shut down signal is %d", signum); syslog(LOG_INFO, "Shut down signal is %d", signum);
syslog(LOG_INFO, "Shutting down TDengine service..."); syslog(LOG_INFO, "Shutting down TDengine service...");
dnodeExit = true;
// inform main thread to exit // inform main thread to exit
tsem_post(&exitSem); tsem_post(&exitSem);
#ifdef WINDOWS #ifdef WINDOWS
......
...@@ -30,6 +30,7 @@ typedef struct { ...@@ -30,6 +30,7 @@ typedef struct {
int32_t * vnodeList; int32_t * vnodeList;
} SOpenVnodeThread; } SOpenVnodeThread;
extern bool dnodeExit;
extern void * tsDnodeTmr; extern void * tsDnodeTmr;
static void * tsStatusTimer = NULL; static void * tsStatusTimer = NULL;
static uint32_t tsRebootTime = 0; static uint32_t tsRebootTime = 0;
...@@ -222,6 +223,22 @@ static void dnodeProcessStatusRsp(SRpcMsg *pMsg) { ...@@ -222,6 +223,22 @@ static void dnodeProcessStatusRsp(SRpcMsg *pMsg) {
if (clusterId[0] != '\0') { if (clusterId[0] != '\0') {
dnodeSetDropped(); dnodeSetDropped();
dError("exit zombie dropped dnode"); dError("exit zombie dropped dnode");
// warning: only for k8s!
while (tsDnodeNopLoop) {
if (dnodeExit) {
dInfo("Break loop");
return;
}
dInfo("Nop loop");
#ifdef WINDOWS
Sleep(100);
#else
usleep(100000);
#endif
}
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#ifndef TDENGINE_TTOKENDEF_H #ifndef TDENGINE_TTOKENDEF_H
#define TDENGINE_TTOKENDEF_H #define TDENGINE_TTOKENDEF_H
#define TK_ID 1 #define TK_ID 1
#define TK_BOOL 2 #define TK_BOOL 2
#define TK_TINYINT 3 #define TK_TINYINT 3
...@@ -139,12 +138,12 @@ ...@@ -139,12 +138,12 @@
#define TK_USING 120 #define TK_USING 120
#define TK_NULL 121 #define TK_NULL 121
#define TK_NOW 122 #define TK_NOW 122
#define TK_SELECT 123 #define TK_VARIABLE 123
#define TK_UNION 124 #define TK_SELECT 124
#define TK_ALL 125 #define TK_UNION 125
#define TK_DISTINCT 126 #define TK_ALL 126
#define TK_FROM 127 #define TK_DISTINCT 127
#define TK_VARIABLE 128 #define TK_FROM 128
#define TK_RANGE 129 #define TK_RANGE 129
#define TK_INTERVAL 130 #define TK_INTERVAL 130
#define TK_EVERY 131 #define TK_EVERY 131
...@@ -219,7 +218,6 @@ ...@@ -219,7 +218,6 @@
#define TK_FILE 200 #define TK_FILE 200
#define TK_SPACE 300 #define TK_SPACE 300
#define TK_COMMENT 301 #define TK_COMMENT 301
#define TK_ILLEGAL 302 #define TK_ILLEGAL 302
......
Subproject commit 78519c0c90a261b6a559c6bbe7f3d3b5a7b630b4 Subproject commit 7eae58a0fbf7c7321dd1bdc96e375d4c832cf373
...@@ -1003,6 +1003,7 @@ static SDbCfg mnodeGetAlterDbOption(SDbObj *pDb, SAlterDbMsg *pAlter) { ...@@ -1003,6 +1003,7 @@ static SDbCfg mnodeGetAlterDbOption(SDbObj *pDb, SAlterDbMsg *pAlter) {
newCfg.daysToKeep0 = daysToKeep0; newCfg.daysToKeep0 = daysToKeep0;
} }
#ifdef _STORAGE
if (daysToKeep1 > 0 && (daysToKeep1 != pDb->cfg.daysToKeep1 || newCfg.daysToKeep1 != pDb->cfg.daysToKeep1)) { if (daysToKeep1 > 0 && (daysToKeep1 != pDb->cfg.daysToKeep1 || newCfg.daysToKeep1 != pDb->cfg.daysToKeep1)) {
mDebug("db:%s, daysToKeep1:%d change to %d", pDb->name, pDb->cfg.daysToKeep1, daysToKeep1); mDebug("db:%s, daysToKeep1:%d change to %d", pDb->name, pDb->cfg.daysToKeep1, daysToKeep1);
newCfg.daysToKeep1 = daysToKeep1; newCfg.daysToKeep1 = daysToKeep1;
...@@ -1012,6 +1013,7 @@ static SDbCfg mnodeGetAlterDbOption(SDbObj *pDb, SAlterDbMsg *pAlter) { ...@@ -1012,6 +1013,7 @@ static SDbCfg mnodeGetAlterDbOption(SDbObj *pDb, SAlterDbMsg *pAlter) {
mDebug("db:%s, daysToKeep2:%d change to %d", pDb->name, pDb->cfg.daysToKeep2, daysToKeep2); mDebug("db:%s, daysToKeep2:%d change to %d", pDb->name, pDb->cfg.daysToKeep2, daysToKeep2);
newCfg.daysToKeep2 = daysToKeep2; newCfg.daysToKeep2 = daysToKeep2;
} }
#endif
if (minRows > 0 && minRows != pDb->cfg.minRowsPerFileBlock) { if (minRows > 0 && minRows != pDb->cfg.minRowsPerFileBlock) {
mError("db:%s, can't alter minRows option", pDb->name); mError("db:%s, can't alter minRows option", pDb->name);
...@@ -1100,6 +1102,7 @@ static SDbCfg mnodeGetAlterDbOption(SDbObj *pDb, SAlterDbMsg *pAlter) { ...@@ -1100,6 +1102,7 @@ static SDbCfg mnodeGetAlterDbOption(SDbObj *pDb, SAlterDbMsg *pAlter) {
// community version can only change daysToKeep // community version can only change daysToKeep
// but enterprise version can change all daysToKeep options // but enterprise version can change all daysToKeep options
#ifndef _STORAGE #ifndef _STORAGE
newCfg.daysToKeep1 = newCfg.daysToKeep0; newCfg.daysToKeep1 = newCfg.daysToKeep0;
newCfg.daysToKeep2 = newCfg.daysToKeep0; newCfg.daysToKeep2 = newCfg.daysToKeep0;
......
...@@ -253,7 +253,7 @@ acct_optr(Y) ::= pps(C) tseries(D) storage(P) streams(F) qtime(Q) dbs(E) users(K ...@@ -253,7 +253,7 @@ acct_optr(Y) ::= pps(C) tseries(D) storage(P) streams(F) qtime(Q) dbs(E) users(K
intitemlist(A) ::= intitemlist(X) COMMA intitem(Y). { A = tVariantListAppend(X, &Y, -1); } intitemlist(A) ::= intitemlist(X) COMMA intitem(Y). { A = tVariantListAppend(X, &Y, -1); }
intitemlist(A) ::= intitem(X). { A = tVariantListAppend(NULL, &X, -1); } intitemlist(A) ::= intitem(X). { A = tVariantListAppend(NULL, &X, -1); }
intitem(A) ::= INTEGER(X). { toTSDBType(X.type); tVariantCreate(&A, &X, true); } intitem(A) ::= INTEGER(X). { toTSDBType(X.type); tVariantCreate(&A, &X); }
%type keep {SArray*} %type keep {SArray*}
%destructor keep {taosArrayDestroy($$);} %destructor keep {taosArrayDestroy($$);}
...@@ -438,39 +438,49 @@ column(A) ::= ids(X) typename(Y). { ...@@ -438,39 +438,49 @@ column(A) ::= ids(X) typename(Y). {
tagitemlist(A) ::= tagitemlist(X) COMMA tagitem(Y). { A = tVariantListAppend(X, &Y, -1); } tagitemlist(A) ::= tagitemlist(X) COMMA tagitem(Y). { A = tVariantListAppend(X, &Y, -1); }
tagitemlist(A) ::= tagitem(X). { A = tVariantListAppend(NULL, &X, -1); } tagitemlist(A) ::= tagitem(X). { A = tVariantListAppend(NULL, &X, -1); }
tagitem(A) ::= INTEGER(X). { toTSDBType(X.type); tVariantCreate(&A, &X, true); } tagitem(A) ::= INTEGER(X). { toTSDBType(X.type); tVariantCreate(&A, &X); }
tagitem(A) ::= FLOAT(X). { toTSDBType(X.type); tVariantCreate(&A, &X, true); } tagitem(A) ::= FLOAT(X). { toTSDBType(X.type); tVariantCreate(&A, &X); }
tagitem(A) ::= STRING(X). { toTSDBType(X.type); tVariantCreate(&A, &X, true); } tagitem(A) ::= STRING(X). { toTSDBType(X.type); tVariantCreate(&A, &X); }
tagitem(A) ::= BOOL(X). { toTSDBType(X.type); tVariantCreate(&A, &X, true); } tagitem(A) ::= BOOL(X). { toTSDBType(X.type); tVariantCreate(&A, &X); }
tagitem(A) ::= NULL(X). { X.type = 0; tVariantCreate(&A, &X, true); } tagitem(A) ::= NULL(X). { X.type = 0; tVariantCreate(&A, &X); }
tagitem(A) ::= NOW(X). { X.type = TSDB_DATA_TYPE_TIMESTAMP; tVariantCreate(&A, &X, true);} tagitem(A) ::= NOW(X). { X.type = TSDB_DATA_TYPE_TIMESTAMP; tVariantCreateExt(&A, &X, TK_NOW, true);}
tagitem(A) ::= NOW PLUS VARIABLE(X).{
X.type = TSDB_DATA_TYPE_TIMESTAMP;
tVariantCreateExt(&A, &X, TK_PLUS, true);
}
tagitem(A) ::= NOW MINUS VARIABLE(X).{
X.type = TSDB_DATA_TYPE_TIMESTAMP;
tVariantCreateExt(&A, &X, TK_MINUS, true);
}
tagitem(A) ::= MINUS(X) INTEGER(Y).{ tagitem(A) ::= MINUS(X) INTEGER(Y).{
X.n += Y.n; X.n += Y.n;
X.type = Y.type; X.type = Y.type;
toTSDBType(X.type); toTSDBType(X.type);
tVariantCreate(&A, &X, true); tVariantCreate(&A, &X);
} }
tagitem(A) ::= MINUS(X) FLOAT(Y). { tagitem(A) ::= MINUS(X) FLOAT(Y). {
X.n += Y.n; X.n += Y.n;
X.type = Y.type; X.type = Y.type;
toTSDBType(X.type); toTSDBType(X.type);
tVariantCreate(&A, &X, true); tVariantCreate(&A, &X);
} }
tagitem(A) ::= PLUS(X) INTEGER(Y). { tagitem(A) ::= PLUS(X) INTEGER(Y). {
X.n += Y.n; X.n += Y.n;
X.type = Y.type; X.type = Y.type;
toTSDBType(X.type); toTSDBType(X.type);
tVariantCreate(&A, &X, true); tVariantCreate(&A, &X);
} }
tagitem(A) ::= PLUS(X) FLOAT(Y). { tagitem(A) ::= PLUS(X) FLOAT(Y). {
X.n += Y.n; X.n += Y.n;
X.type = Y.type; X.type = Y.type;
toTSDBType(X.type); toTSDBType(X.type);
tVariantCreate(&A, &X, true); tVariantCreate(&A, &X);
} }
//////////////////////// The SELECT statement ///////////////////////////////// //////////////////////// The SELECT statement /////////////////////////////////
...@@ -609,7 +619,7 @@ fill_opt(N) ::= . { N = 0; } ...@@ -609,7 +619,7 @@ fill_opt(N) ::= . { N = 0; }
fill_opt(N) ::= FILL LP ID(Y) COMMA tagitemlist(X) RP. { fill_opt(N) ::= FILL LP ID(Y) COMMA tagitemlist(X) RP. {
tVariant A = {0}; tVariant A = {0};
toTSDBType(Y.type); toTSDBType(Y.type);
tVariantCreate(&A, &Y, true); tVariantCreate(&A, &Y);
tVariantListInsert(X, &A, -1, 0); tVariantListInsert(X, &A, -1, 0);
N = X; N = X;
...@@ -652,12 +662,12 @@ sortlist(A) ::= arrow(Y) sortorder(Z). { ...@@ -652,12 +662,12 @@ sortlist(A) ::= arrow(Y) sortorder(Z). {
%type item {tVariant} %type item {tVariant}
item(A) ::= ID(X). { item(A) ::= ID(X). {
toTSDBType(X.type); toTSDBType(X.type);
tVariantCreate(&A, &X, true); tVariantCreate(&A, &X);
} }
item(A) ::= ID(X) DOT ID(Y). { item(A) ::= ID(X) DOT ID(Y). {
toTSDBType(X.type); toTSDBType(X.type);
X.n += (1+Y.n); X.n += (1+Y.n);
tVariantCreate(&A, &X, true); tVariantCreate(&A, &X);
} }
%type sortorder {int} %type sortorder {int}
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#define DOUBLE_MAX 1.79e+308 #define DOUBLE_MAX 1.79e+308
#define ADDITION_CENTROID_NUM 2 #define ADDITION_CENTROID_NUM 2
#define COMPRESSION 400 #define COMPRESSION 300
#define GET_CENTROID(compression) (ceil(compression * M_PI / 2) + 1 + ADDITION_CENTROID_NUM) #define GET_CENTROID(compression) (ceil(compression * M_PI / 2) + 1 + ADDITION_CENTROID_NUM)
#define GET_THRESHOLD(compression) (7.5 + 0.37 * compression - 2e-4 * pow(compression, 2)) #define GET_THRESHOLD(compression) (7.5 + 0.37 * compression - 2e-4 * pow(compression, 2))
#define TDIGEST_SIZE(compression) (sizeof(TDigest) + sizeof(SCentroid)*GET_CENTROID(compression) + sizeof(SPt)*GET_THRESHOLD(compression)) #define TDIGEST_SIZE(compression) (sizeof(TDigest) + sizeof(SCentroid)*GET_CENTROID(compression) + sizeof(SPt)*GET_THRESHOLD(compression))
......
...@@ -588,6 +588,12 @@ SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr) { ...@@ -588,6 +588,12 @@ SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr) {
op = OP_Fill; op = OP_Fill;
taosArrayPush(plan, &op); taosArrayPush(plan, &op);
} }
// outer query order by support
int32_t orderColId = pQueryAttr->order.orderColId;
if (pQueryAttr->vgId == 0 && orderColId != PRIMARYKEY_TIMESTAMP_COL_INDEX && orderColId != INT32_MIN) {
op = OP_Order;
taosArrayPush(plan, &op);
}
} }
} else if (pQueryAttr->groupbyColumn) { } else if (pQueryAttr->groupbyColumn) {
......
...@@ -143,14 +143,14 @@ tSqlExpr *tSqlExprCreateIdValue(SSqlInfo* pInfo, SStrToken *pToken, int32_t optr ...@@ -143,14 +143,14 @@ tSqlExpr *tSqlExprCreateIdValue(SSqlInfo* pInfo, SStrToken *pToken, int32_t optr
if (optrType == TK_NULL) { if (optrType == TK_NULL) {
if (pToken){ if (pToken){
pToken->type = TSDB_DATA_TYPE_NULL; pToken->type = TSDB_DATA_TYPE_NULL;
tVariantCreate(&pSqlExpr->value, pToken, true); tVariantCreate(&pSqlExpr->value, pToken);
} }
pSqlExpr->tokenId = optrType; pSqlExpr->tokenId = optrType;
pSqlExpr->type = SQL_NODE_VALUE; pSqlExpr->type = SQL_NODE_VALUE;
} else if (optrType == TK_INTEGER || optrType == TK_STRING || optrType == TK_FLOAT || optrType == TK_BOOL) { } else if (optrType == TK_INTEGER || optrType == TK_STRING || optrType == TK_FLOAT || optrType == TK_BOOL) {
if (pToken) { if (pToken) {
toTSDBType(pToken->type); toTSDBType(pToken->type);
tVariantCreate(&pSqlExpr->value, pToken, true); tVariantCreate(&pSqlExpr->value, pToken);
} }
pSqlExpr->tokenId = optrType; pSqlExpr->tokenId = optrType;
pSqlExpr->type = SQL_NODE_VALUE; pSqlExpr->type = SQL_NODE_VALUE;
...@@ -211,7 +211,7 @@ tSqlExpr *tSqlExprCreateTimestamp(SStrToken *pToken, int32_t optrType) { ...@@ -211,7 +211,7 @@ tSqlExpr *tSqlExprCreateTimestamp(SStrToken *pToken, int32_t optrType) {
if (optrType == TK_INTEGER || optrType == TK_STRING) { if (optrType == TK_INTEGER || optrType == TK_STRING) {
if (pToken) { if (pToken) {
toTSDBType(pToken->type); toTSDBType(pToken->type);
tVariantCreate(&pSqlExpr->value, pToken, true); tVariantCreate(&pSqlExpr->value, pToken);
} }
pSqlExpr->tokenId = optrType; pSqlExpr->tokenId = optrType;
pSqlExpr->type = SQL_NODE_VALUE; pSqlExpr->type = SQL_NODE_VALUE;
...@@ -599,7 +599,7 @@ SArray *tVariantListAppendToken(SArray *pList, SStrToken *pToken, uint8_t order, ...@@ -599,7 +599,7 @@ SArray *tVariantListAppendToken(SArray *pList, SStrToken *pToken, uint8_t order,
if (pToken) { if (pToken) {
tVariantListItem item; tVariantListItem item;
tVariantCreate(&item.pVar, pToken, needRmquoteEscape); tVariantCreateExt(&item.pVar, pToken, TK_ID, needRmquoteEscape);
item.sortOrder = order; item.sortOrder = order;
taosArrayPush(pList, &item); taosArrayPush(pList, &item);
......
...@@ -279,6 +279,7 @@ bool qTableQuery(qinfo_t qinfo, uint64_t *qId) { ...@@ -279,6 +279,7 @@ bool qTableQuery(qinfo_t qinfo, uint64_t *qId) {
if (isQueryKilled(pQInfo)) { if (isQueryKilled(pQInfo)) {
qDebug("QInfo:0x%"PRIx64" it is already killed, abort", pQInfo->qId); qDebug("QInfo:0x%"PRIx64" it is already killed, abort", pQInfo->qId);
setQueryKilled(pQInfo);
pQInfo->runtimeEnv.outputBuf = NULL; pQInfo->runtimeEnv.outputBuf = NULL;
return doBuildResCheck(pQInfo); return doBuildResCheck(pQInfo);
} }
......
此差异已折叠。
...@@ -131,7 +131,7 @@ void taosCloseLog() { ...@@ -131,7 +131,7 @@ void taosCloseLog() {
taosStopLog(); taosStopLog();
//tsem_post(&(tsLogObj.logHandle->buffNotEmpty)); //tsem_post(&(tsLogObj.logHandle->buffNotEmpty));
taosMsleep(MAX_LOG_INTERVAL/1000); taosMsleep(MAX_LOG_INTERVAL/1000);
if (taosCheckPthreadValid(tsLogObj.logHandle->asyncThread)) { if (tsLogObj.logHandle && taosCheckPthreadValid(tsLogObj.logHandle->asyncThread)) {
pthread_join(tsLogObj.logHandle->asyncThread, NULL); pthread_join(tsLogObj.logHandle->asyncThread, NULL);
} }
// In case that other threads still use log resources causing invalid write in valgrind // In case that other threads still use log resources causing invalid write in valgrind
......
...@@ -356,7 +356,7 @@ static int32_t taosNetCheckRpc(const char* serverFqdn, uint16_t port, uint16_t p ...@@ -356,7 +356,7 @@ static int32_t taosNetCheckRpc(const char* serverFqdn, uint16_t port, uint16_t p
epSet.inUse = 0; epSet.inUse = 0;
epSet.numOfEps = 1; epSet.numOfEps = 1;
epSet.port[0] = port; epSet.port[0] = port;
strcpy(epSet.fqdn[0], serverFqdn); tstrncpy(epSet.fqdn[0], serverFqdn, sizeof(epSet.fqdn[0]));
reqMsg.msgType = TSDB_MSG_TYPE_NETWORK_TEST; reqMsg.msgType = TSDB_MSG_TYPE_NETWORK_TEST;
reqMsg.pCont = rpcMallocCont(pktLen); reqMsg.pCont = rpcMallocCont(pktLen);
...@@ -364,7 +364,7 @@ static int32_t taosNetCheckRpc(const char* serverFqdn, uint16_t port, uint16_t p ...@@ -364,7 +364,7 @@ static int32_t taosNetCheckRpc(const char* serverFqdn, uint16_t port, uint16_t p
reqMsg.code = 0; reqMsg.code = 0;
reqMsg.handle = NULL; // rpc handle returned to app reqMsg.handle = NULL; // rpc handle returned to app
reqMsg.ahandle = NULL; // app handle set by client reqMsg.ahandle = NULL; // app handle set by client
strcpy(reqMsg.pCont, "nettest"); tstrncpy((char*)reqMsg.pCont, "nettest", pktLen);
rpcSendRecv(pRpcConn, &epSet, &reqMsg, &rspMsg); rpcSendRecv(pRpcConn, &epSet, &reqMsg, &rspMsg);
...@@ -606,7 +606,7 @@ static void taosNetCheckSpeed(char *host, int32_t port, int32_t pkgLen, ...@@ -606,7 +606,7 @@ static void taosNetCheckSpeed(char *host, int32_t port, int32_t pkgLen,
epSet.inUse = 0; epSet.inUse = 0;
epSet.numOfEps = 1; epSet.numOfEps = 1;
epSet.port[0] = port; epSet.port[0] = port;
strcpy(epSet.fqdn[0], host); tstrncpy(epSet.fqdn[0], host, sizeof(epSet.fqdn[0]));
reqMsg.msgType = TSDB_MSG_TYPE_NETWORK_TEST; reqMsg.msgType = TSDB_MSG_TYPE_NETWORK_TEST;
reqMsg.pCont = rpcMallocCont(pkgLen); reqMsg.pCont = rpcMallocCont(pkgLen);
...@@ -614,8 +614,8 @@ static void taosNetCheckSpeed(char *host, int32_t port, int32_t pkgLen, ...@@ -614,8 +614,8 @@ static void taosNetCheckSpeed(char *host, int32_t port, int32_t pkgLen,
reqMsg.code = 0; reqMsg.code = 0;
reqMsg.handle = NULL; // rpc handle returned to app reqMsg.handle = NULL; // rpc handle returned to app
reqMsg.ahandle = NULL; // app handle set by client reqMsg.ahandle = NULL; // app handle set by client
strcpy(reqMsg.pCont, "nettest speed"); tstrncpy((char*)reqMsg.pCont, "nettest speed", pkgLen);
rpcSendRecv(pRpcConn, &epSet, &reqMsg, &rspMsg); rpcSendRecv(pRpcConn, &epSet, &reqMsg, &rspMsg);
int code = 0; int code = 0;
......
...@@ -16,6 +16,7 @@ import taos ...@@ -16,6 +16,7 @@ import taos
from util.log import tdLog from util.log import tdLog
from util.cases import tdCases from util.cases import tdCases
from util.sql import tdSql from util.sql import tdSql
import json
class TDTestCase: class TDTestCase:
...@@ -505,6 +506,11 @@ class TDTestCase: ...@@ -505,6 +506,11 @@ class TDTestCase:
tdSql.query("select round(dataint) from jsons1 where jtag->'tag1'>1") tdSql.query("select round(dataint) from jsons1 where jtag->'tag1'>1")
tdSql.checkRows(3) tdSql.checkRows(3)
#test TD-12077
tdSql.execute("insert into jsons1_16 using jsons1 tags('{\"tag1\":\"收到货\",\"tag2\":\"\",\"tag3\":-2.111}') values(1591062628000, 2, NULL, '你就会', 'dws')")
tdSql.query("select jtag->'tag3' from jsons1_16")
tdSql.checkData(0, 0, '-2.111000000')
def stop(self): def stop(self):
tdSql.close() tdSql.close()
tdLog.success("%s successfully executed" % __file__) tdLog.success("%s successfully executed" % __file__)
......
###################################################################
# Copyright (c) 2016 by TAOS Technologies, Inc.
# All rights reserved.
#
# This file is proprietary and confidential to TAOS Technologies.
# No part of this file may be reproduced, stored, transmitted,
# disclosed or used in any form or by any means other than as
# expressly provided by the written permission from Jianhui Tao
#
###################################################################
# -*- coding: utf-8 -*-
import sys
from util.log import *
from util.cases import *
from util.sql import *
from util.dnodes import *
class TDTestCase:
def caseDescription(self):
'''
case1<pxiao>: [TS-854] normal table batch insert with binding same table, different number of columns and timestamp in ascending order
case2<pxiao>: [TS-854] normal table batch insert with binding same table, different number of columns and timestamp in descending order
case3<pxiao>: [TS-854] normal table batch insert with binding same table, different number of columns and timestamp out of order
case4<pxiao>: [TS-854] normal table batch insert with binding same table, different number of columns and same timestamp
case5<pxiao>: [TS-854] normal table batch insert with binding different tables, different number of columns and timestamp in ascending order
case6<pxiao>: [TS-854] normal table batch insert with binding different tables, different number of columns and timestamp in descending order
case7<pxiao>: [TS-854] normal table batch insert with binding different tables, different number of columns and timestamp out of order
case8<pxiao>: [TS-854] normal table batch insert with binding different tables, different number of columns and same timestamp
case9<pxiao>: [TS-854] sub table batch insert with binding same table, different number of columns and timestamp in ascending order
case10<pxiao>: [TS-854] sub table batch insert with binding same table, different number of columns and timestamp in descending order
case11<pxiao>: [TS-854] sub table batch insert with binding same table, different number of columns and timestamp out of order
case12<pxiao>: [TS-854] sub table batch insert with binding same table, different number of columns and same timestamp
case13<pxiao>: [TS-854] sub table batch insert with binding different tables, different number of columns and timestamp in ascending order
case14<pxiao>: [TS-854] sub table batch insert with binding different tables, different number of columns and timestamp in descending order
case15<pxiao>: [TS-854] sub table batch insert with binding different tables, different number of columns and timestamp out of order
case16<pxiao>: [TS-854] sub table batch insert with binding different tables, different number of columns and same timestamp
case17<pxiao>: [TS-854] sub table batch insert with binding same table, different number of columns, different number of tags and timestamp in ascending order
case18<pxiao>: [TS-854] sub table batch insert with binding same table, different number of columns, different number of tags and timestamp in descending order
case19<pxiao>: [TS-854] sub table batch insert with binding same table, different number of columns, different number of tags and timestamp out of order
case20<pxiao>: [TS-854] sub table batch insert with binding same table, different number of columns, different number of tags and same timestamp
case21<pxiao>: [TS-854] sub table batch insert with binding different tables, different number of columns, different number of tags and timestamp in ascending order
case22<pxiao>: [TS-854] sub table batch insert with binding different tables, different number of columns, different number of tags and timestamp in descending order
case23<pxiao>: [TS-854] sub table batch insert with binding different tables, different number of columns, different number of tags and timestamp out of order
case24<pxiao>: [TS-854] sub table batch insert with binding different tables, different number of columns, different number of tags and same timestamp
'''
return
def init(self, conn, logSql):
tdLog.debug("start to execute %s" % __file__)
tdSql.init(conn.cursor(), logSql)
self.ts = 1607817000000
def run(self):
tdSql.prepare()
tdSql.execute("create table tb1(ts timestamp, c1 double, c2 double, c3 double, c4 double)")
args = [(self.ts + 1000, self.ts + 3000, self.ts + 5000, self.ts + 7000),
(self.ts + 8000, self.ts + 6000, self.ts + 4000, self.ts + 2000),
(self.ts - 1000 , self.ts - 5000, self.ts - 3000, self.ts - 8000),
(self.ts, self.ts, self.ts, self.ts)]
# case 1, 2, 3, 4
tdLog.info("test case for case 1, 2, 3, 4")
sql = "insert into tb1(ts, c1) values(%d, 0.0) tb1(ts, c1) values(%d, 0.0) tb1(ts, c1) values(%d, 0.0) tb1(ts, c1, c2, c3, c4) values(%d, 0.0, 0.0, 0.0, 0.0)"
i = 1
rows = 0
for arg in args:
tdLog.info("test case for case %d" % i)
tdLog.info(sql % arg)
tdSql.execute(sql % arg)
if i == 4:
rows = rows + 1
else:
rows = rows + 4
tdSql.query("select * from tb1")
tdSql.checkRows(rows)
i = i + 1
# restart taosd and check again
tdDnodes.stop(1)
tdDnodes.start(1)
tdSql.query("select * from tb1")
tdSql.checkRows(rows)
# case 5, 6, 7, 8
tdSql.execute("create table tb2(ts timestamp, c1 int, c2 int, c3 int, c4 int)")
tdSql.execute("create table tb3(ts timestamp, c1 double, c2 double, c3 double, c4 double)")
tdLog.info("test case for case 5, 6, 7, 8")
sql = "insert into tb2(ts, c1) values(%d, 0) tb2(ts, c1, c2, c3, c4) values(%d, 0, 0, 0, 0) tb3(ts, c2) values(%d, 0.0) tb3(ts, c1, c2, c3, c4) values(%d, 0.0, 0.0, 0.0, 0.0)"
rows = 0
for arg in args:
tdLog.info("test case for case %d" % i)
tdLog.info(sql % arg)
tdSql.execute(sql % arg)
tdSql.query("select * from tb2")
if i == 8:
rows = rows + 1
else:
rows = rows + 2
tdSql.query("select * from tb2")
tdSql.checkRows(rows)
tdSql.query("select * from tb3")
tdSql.checkRows(rows)
i = i + 1
# restart taosd and check again
tdDnodes.stop(1)
tdDnodes.start(1)
tdSql.query("select * from tb2")
tdSql.checkRows(rows)
tdSql.query("select * from tb3")
tdSql.checkRows(rows)
# case 9, 10, 11, 12
tdSql.execute("create table stb(ts timestamp, c1 double, c2 double, c3 double, c4 double) tags(t1 nchar(20))")
tdLog.info("test case for case 9, 10, 11, 12")
sql = "insert into t1(ts, c1) using stb tags('tag1') values(%d, 0.0) t1(ts, c1) using stb tags('tag1') values(%d, 0.0) t1(ts, c1) using stb tags('tag1') values(%d, 0.0) t1(ts, c1, c2, c3, c4) using stb tags('tag1') values(%d, 0.0, 0.0, 0.0, 0.0)"
rows = 0
for arg in args:
tdLog.info("test case for case %d" % i)
tdLog.info(sql % arg)
tdSql.execute(sql % arg)
if i == 12:
rows = rows + 1
else:
rows = rows + 4
tdSql.query("select * from stb")
tdSql.checkRows(rows)
i = i + 1
# restart taosd and check again
tdDnodes.stop(1)
tdDnodes.start(1)
tdSql.query("select * from stb")
tdSql.checkRows(rows)
# case 13, 14, 15, 16
tdSql.execute("create table stb2(ts timestamp, c1 int, c2 int, c3 int, c4 int) tags(t1 nchar(20))")
tdSql.execute("create table stb3(ts timestamp, c1 double, c2 double, c3 double, c4 double) tags(t1 binary(20))")
tdLog.info("test case for case 13, 14, 15, 16")
sql = "insert into t2(ts, c1) using stb2 tags('tag2') values(%d, 0) t2(ts, c1, c2, c3, c4) using stb2 tags('tag2') values(%d, 0, 0, 0, 0) t3(ts, c2) using stb3 tags('tag3') values(%d, 0.0) t3(ts, c1, c2, c3, c4) using stb3 tags('tag3') values(%d, 0.0, 0.0, 0.0, 0.0)"
rows = 0
for arg in args:
tdLog.info("test case for case %d" % i)
tdLog.info(sql % arg)
tdSql.execute(sql % arg)
if i == 16:
rows = rows + 1
else:
rows = rows + 2
tdSql.query("select * from stb2")
tdSql.checkRows(rows)
tdSql.query("select * from stb3")
tdSql.checkRows(rows)
i = i + 1
# restart taosd and check again
tdDnodes.stop(1)
tdDnodes.start(1)
tdSql.query("select * from stb2")
tdSql.checkRows(rows)
tdSql.query("select * from stb3")
tdSql.checkRows(rows)
# case 17, 18, 19, 20
tdSql.execute("drop table if exists stb")
tdSql.execute("create table stb(ts timestamp, c1 double, c2 double, c3 double, c4 double) tags(t1 nchar(20), t2 int, t3 binary(20))")
tdLog.info("test case for case 17, 18, 19, 20")
sql = "insert into t1(ts, c1) using stb(t1) tags('tag1') values(%d, 0.0) t1(ts, c1) using stb(t2) tags(1) values(%d, 0.0) t1(ts, c1) using stb(t1, t2) tags('tag1', 1) values(%d, 0.0) t1(ts, c1, c2, c3, c4) using stb(t1, t2, t3) tags('tag1', 1, 'tag3') values(%d, 0.0, 0.0, 0.0, 0.0)"
rows = 0
for arg in args:
tdLog.info("test case for case %d" % i)
tdLog.info(sql % arg)
tdSql.execute(sql % arg)
if i == 20:
rows = rows + 1
else:
rows = rows + 4
tdSql.query("select * from stb")
tdSql.checkRows(rows)
i = i + 1
# restart taosd and check again
tdDnodes.stop(1)
tdDnodes.start(1)
tdSql.query("select * from stb")
tdSql.checkRows(rows)
# case 21, 22, 23, 24
tdSql.execute("drop table if exists stb2")
tdSql.execute("drop table if exists stb3")
tdSql.execute("create table stb2(ts timestamp, c1 int, c2 int, c3 int, c4 int) tags(t1 nchar(20), t2 int)")
tdSql.execute("create table stb3(ts timestamp, c1 double, c2 double, c3 double, c4 double) tags(t1 binary(20), t2 double)")
tdLog.info("test case for case 21, 22, 23, 24")
sql = "insert into t2(ts, c1) using stb2(t1) tags('tag2') values(%d, 0) t2(ts, c1, c2, c3, c4) using stb2(t1, t2) tags('tag2', 1) values(%d, 0, 0, 0, 0) t3(ts, c2) using stb3(t1) tags('tag3') values(%d, 0.0) t3(ts, c1, c2, c3, c4) using stb3(t1, t2) tags('tag3', 0.0) values(%d, 0.0, 0.0, 0.0, 0.0)"
rows = 0
for arg in args:
tdLog.info("test case for case %d" % i)
tdLog.info(sql % arg)
tdSql.execute(sql % arg)
if i == 24:
rows = rows + 1
else:
rows = rows + 2
tdSql.query("select * from stb2")
tdSql.checkRows(rows)
tdSql.query("select * from stb3")
tdSql.checkRows(rows)
i = i + 1
# restart taosd and check again
tdDnodes.stop(1)
tdDnodes.start(1)
tdSql.query("select * from stb2")
tdSql.checkRows(rows)
tdSql.query("select * from stb3")
tdSql.checkRows(rows)
def stop(self):
tdSql.close()
tdLog.success("%s successfully executed" % __file__)
tdCases.addWindows(__file__, TDTestCase())
tdCases.addLinux(__file__, TDTestCase())
python3 test.py -f 0-management/3-tag/json_tag.py python3 test.py -f 0-management/3-tag/json_tag.py
python3 test.py -f 1-insert/0-sql/basic.py python3 test.py -f 1-insert/0-sql/basic.py
python3 test.py -f 1-insert/0-sql/batchInsert.py
\ No newline at end of file
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace TDengineDriver
{
enum TDengineDataType
{
TSDB_DATA_TYPE_NULL = 0, // 1 bytes
TSDB_DATA_TYPE_BOOL = 1, // 1 bytes
TSDB_DATA_TYPE_TINYINT = 2, // 1 bytes
TSDB_DATA_TYPE_SMALLINT = 3, // 2 bytes
TSDB_DATA_TYPE_INT = 4, // 4 bytes
TSDB_DATA_TYPE_BIGINT = 5, // 8 bytes
TSDB_DATA_TYPE_FLOAT = 6, // 4 bytes
TSDB_DATA_TYPE_DOUBLE = 7, // 8 bytes
TSDB_DATA_TYPE_BINARY = 8, // string
TSDB_DATA_TYPE_TIMESTAMP = 9,// 8 bytes
TSDB_DATA_TYPE_NCHAR = 10, // unicode string
TSDB_DATA_TYPE_UTINYINT = 11,// 1 byte
TSDB_DATA_TYPE_USMALLINT= 12,// 2 bytes
TSDB_DATA_TYPE_UINT = 13, // 4 bytes
TSDB_DATA_TYPE_UBIGINT= 14 // 8 bytes
}
enum TDengineInitOption
{
TSDB_OPTION_LOCALE = 0,
TSDB_OPTION_CHARSET = 1,
TSDB_OPTION_TIMEZONE = 2,
TDDB_OPTION_CONFIGDIR = 3,
TDDB_OPTION_SHELL_ACTIVITY_TIMER = 4
}
class TDengineMeta
{
public string name;
public short size;
public byte type;
public string TypeName()
{
switch ((TDengineDataType)type)
{
case TDengineDataType.TSDB_DATA_TYPE_BOOL:
return "BOOL";
case TDengineDataType.TSDB_DATA_TYPE_TINYINT:
return "TINYINT";
case TDengineDataType.TSDB_DATA_TYPE_SMALLINT:
return "SMALLINT";
case TDengineDataType.TSDB_DATA_TYPE_INT:
return "INT";
case TDengineDataType.TSDB_DATA_TYPE_BIGINT:
return "BIGINT";
case TDengineDataType.TSDB_DATA_TYPE_UTINYINT:
return "TINYINT UNSIGNED";
case TDengineDataType.TSDB_DATA_TYPE_USMALLINT:
return "SMALLINT UNSIGNED";
case TDengineDataType.TSDB_DATA_TYPE_UINT:
return "INT UNSIGNED";
case TDengineDataType.TSDB_DATA_TYPE_UBIGINT:
return "BIGINT UNSIGNED";
case TDengineDataType.TSDB_DATA_TYPE_FLOAT:
return "FLOAT";
case TDengineDataType.TSDB_DATA_TYPE_DOUBLE:
return "DOUBLE";
case TDengineDataType.TSDB_DATA_TYPE_BINARY:
return "STRING";
case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP:
return "TIMESTAMP";
case TDengineDataType.TSDB_DATA_TYPE_NCHAR:
return "NCHAR";
default:
return "undefine";
}
}
}
class TDengine
{
public const int TSDB_CODE_SUCCESS = 0;
[DllImport("taos", EntryPoint = "taos_init", CallingConvention = CallingConvention.Cdecl)]
static extern public void Init();
[DllImport("taos", EntryPoint = "taos_cleanup", CallingConvention = CallingConvention.Cdecl)]
static extern public void Cleanup();
[DllImport("taos", EntryPoint = "taos_options", CallingConvention = CallingConvention.Cdecl)]
static extern public void Options(int option, string value);
[DllImport("taos", EntryPoint = "taos_connect", CallingConvention = CallingConvention.Cdecl)]
static extern public IntPtr Connect(string ip, string user, string password, string db, short port);
[DllImport("taos", EntryPoint = "taos_errstr", CallingConvention = CallingConvention.Cdecl)]
static extern private IntPtr taos_errstr(IntPtr res);
static public string Error(IntPtr res)
{
IntPtr errPtr = taos_errstr(res);
return Marshal.PtrToStringAnsi(errPtr);
}
[DllImport("taos", EntryPoint = "taos_errno", CallingConvention = CallingConvention.Cdecl)]
static extern public int ErrorNo(IntPtr res);
[DllImport("taos", EntryPoint = "taos_query", CallingConvention = CallingConvention.Cdecl)]
static extern public IntPtr Query(IntPtr conn, string sqlstr);
[DllImport("taos", EntryPoint = "taos_affected_rows", CallingConvention = CallingConvention.Cdecl)]
static extern public int AffectRows(IntPtr res);
[DllImport("taos", EntryPoint = "taos_field_count", CallingConvention = CallingConvention.Cdecl)]
static extern public int FieldCount(IntPtr res);
[DllImport("taos", EntryPoint = "taos_fetch_fields", CallingConvention = CallingConvention.Cdecl)]
static extern private IntPtr taos_fetch_fields(IntPtr res);
static public List<TDengineMeta> FetchFields(IntPtr res)
{
const int fieldSize = 68;
List<TDengineMeta> metas = new List<TDengineMeta>();
if (res == IntPtr.Zero)
{
return metas;
}
int fieldCount = FieldCount(res);
IntPtr fieldsPtr = taos_fetch_fields(res);
for (int i = 0; i < fieldCount; ++i)
{
int offset = i * fieldSize;
TDengineMeta meta = new TDengineMeta();
meta.name = Marshal.PtrToStringAnsi(fieldsPtr + offset);
meta.type = Marshal.ReadByte(fieldsPtr + offset + 65);
meta.size = Marshal.ReadInt16(fieldsPtr + offset + 66);
metas.Add(meta);
}
return metas;
}
[DllImport("taos", EntryPoint = "taos_fetch_row", CallingConvention = CallingConvention.Cdecl)]
static extern public IntPtr FetchRows(IntPtr res);
[DllImport("taos", EntryPoint = "taos_free_result", CallingConvention = CallingConvention.Cdecl)]
static extern public IntPtr FreeResult(IntPtr res);
[DllImport("taos", EntryPoint = "taos_close", CallingConvention = CallingConvention.Cdecl)]
static extern public int Close(IntPtr taos);
//get precision in restultset
[DllImport("taos", EntryPoint = "taos_result_precision", CallingConvention = CallingConvention.Cdecl)]
static extern public int ResultPrecision(IntPtr taos);
//schemaless API
[DllImport("taos",SetLastError = true, EntryPoint = "taos_schemaless_insert", CallingConvention = CallingConvention.Cdecl)]
static extern public IntPtr SchemalessInsert(IntPtr taos, string[] lines, int numLines, int protocol, int precision);
}
}
...@@ -168,7 +168,7 @@ namespace TDengineDriver ...@@ -168,7 +168,7 @@ namespace TDengineDriver
host = this.GetArgumentAsString(argv, "-h", "127.0.0.1"); host = this.GetArgumentAsString(argv, "-h", "127.0.0.1");
user = this.GetArgumentAsString(argv, "-u", "root"); user = this.GetArgumentAsString(argv, "-u", "root");
password = this.GetArgumentAsString(argv, "-p", "taosdata"); password = this.GetArgumentAsString(argv, "-p", "taosdata");
dbName = this.GetArgumentAsString(argv, "-d", "db"); dbName = this.GetArgumentAsString(argv, "-d", "tdengint_test_cs");
stableName = this.GetArgumentAsString(argv, "-s", "st"); stableName = this.GetArgumentAsString(argv, "-s", "st");
tablePrefix = this.GetArgumentAsString(argv, "-t", "t"); tablePrefix = this.GetArgumentAsString(argv, "-t", "t");
isInsertData = this.GetArgumentAsLong(argv, "-w", 0, 1, 1) != 0; isInsertData = this.GetArgumentAsLong(argv, "-w", 0, 1, 1) != 0;
......
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="TDengine.Connector" Version="1.0.2" />
</ItemGroup>
</Project>
...@@ -118,7 +118,7 @@ namespace TDengineDriver ...@@ -118,7 +118,7 @@ namespace TDengineDriver
port = (short)this.GetArgumentAsLong(argv, "-p", 0, 65535, 6030); port = (short)this.GetArgumentAsLong(argv, "-p", 0, 65535, 6030);
user = this.GetArgumentAsString(argv, "-u", "root"); user = this.GetArgumentAsString(argv, "-u", "root");
password = this.GetArgumentAsString(argv, "-P", "taosdata"); password = this.GetArgumentAsString(argv, "-P", "taosdata");
dbName = this.GetArgumentAsString(argv, "-d", "db"); dbName = this.GetArgumentAsString(argv, "-d", "taosdemo_cs");
stablePrefix = this.GetArgumentAsString(argv, "-s", "st"); stablePrefix = this.GetArgumentAsString(argv, "-s", "st");
tablePrefix = this.GetArgumentAsString(argv, "-m", "t"); tablePrefix = this.GetArgumentAsString(argv, "-m", "t");
isInsertOnly = this.GetArgumentAsFlag(argv, "-x", true); isInsertOnly = this.GetArgumentAsFlag(argv, "-x", true);
...@@ -361,7 +361,10 @@ namespace TDengineDriver ...@@ -361,7 +361,10 @@ namespace TDengineDriver
threadArr[i] = new Thread(createTableThread.ThreadMain); threadArr[i] = new Thread(createTableThread.ThreadMain);
threadArr[i].Start(); threadArr[i].Start();
threadArr[i].Join(); }
for (int j = 0; j < numOfThreads; j++)
{
threadArr[j].Join();
} }
} }
...@@ -482,7 +485,10 @@ namespace TDengineDriver ...@@ -482,7 +485,10 @@ namespace TDengineDriver
threadArr[i] = new Thread(insertThread.ThreadMain); threadArr[i] = new Thread(insertThread.ThreadMain);
threadArr[i].Start(); threadArr[i].Start();
threadArr[i].Join(); }
for (int j = 0; j < numOfThreads; j++)
{
threadArr[j].Join();
} }
} }
......
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
<dependency> <dependency>
<groupId>org.apache.logging.log4j</groupId> <groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId> <artifactId>log4j-core</artifactId>
<version>2.14.1</version> <version>2.15.0</version>
</dependency> </dependency>
<!-- proxool --> <!-- proxool -->
<dependency> <dependency>
......
...@@ -88,7 +88,7 @@ ...@@ -88,7 +88,7 @@
<dependency> <dependency>
<groupId>org.apache.logging.log4j</groupId> <groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId> <artifactId>log4j-core</artifactId>
<version>2.14.1</version> <version>2.16.0</version>
</dependency> </dependency>
<!-- junit --> <!-- junit -->
<dependency> <dependency>
......
此差异已折叠。
#!/bin/bash
ulimit -c unlimited
#======================p1-start===============
#======================p1-end===============
# restful test for python
# python3 test.py -f restful/restful_bind_db1.py
# python3 test.py -f restful/restful_bind_db2.py
python3 ./test.py -f client/nettest.py
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -52,6 +52,8 @@ python3 ./test.py -f table/create_db_from_normal_db.py ...@@ -52,6 +52,8 @@ python3 ./test.py -f table/create_db_from_normal_db.py
#stable #stable
python3 ./test.py -f stable/insert.py python3 ./test.py -f stable/insert.py
python3 test.py -f tools/taosdemoAllTest/taosdemoTestInsertWithJsonStmt.py python3 test.py -f tools/taosdemoAllTest/taosdemoTestInsertWithJsonStmt.py
python3 test.py -f tools/taosdemoAllTest/taosdemoTestInsertWithJsonSml.py
python3 test.py -f tag_lite/json_tag_extra.py
# tag # tag
python3 ./test.py -f tag_lite/filter.py python3 ./test.py -f tag_lite/filter.py
...@@ -223,6 +225,7 @@ python3 ./test.py -f perfbenchmark/bug3433.py ...@@ -223,6 +225,7 @@ python3 ./test.py -f perfbenchmark/bug3433.py
python3 test.py -f tools/taosdemoAllTest/taosdemoTestInsertWithJson.py python3 test.py -f tools/taosdemoAllTest/taosdemoTestInsertWithJson.py
python3 test.py -f tools/taosdemoAllTest/taosdemoTestQueryWithJson.py python3 test.py -f tools/taosdemoAllTest/taosdemoTestQueryWithJson.py
python3 test.py -f tools/taosdemoAllTest/taosdemoTestInsertAllType.py python3 test.py -f tools/taosdemoAllTest/taosdemoTestInsertAllType.py
python3 test.py -f tools/taosdemoAllTest/taosdemoTestInsertShell.py
#query #query
python3 test.py -f query/distinctOneColTb.py python3 test.py -f query/distinctOneColTb.py
......
...@@ -320,6 +320,8 @@ class ElapsedCase: ...@@ -320,6 +320,8 @@ class ElapsedCase:
def selectIllegalTest(self): def selectIllegalTest(self):
tdSql.execute("use wxy_db") tdSql.execute("use wxy_db")
tdSql.error("select elapsed() from t1")
tdSql.error("select elapsed(,) from t1")
tdSql.error("select elapsed(1) from t1 where ts > '2021-11-22 00:00:00' and ts < '2021-11-23 00:00:00'") tdSql.error("select elapsed(1) from t1 where ts > '2021-11-22 00:00:00' and ts < '2021-11-23 00:00:00'")
tdSql.error("select elapsed('2021-11-18 00:00:10') from t1 where ts > '2021-11-22 00:00:00' and ts < '2021-11-23 00:00:00'") tdSql.error("select elapsed('2021-11-18 00:00:10') from t1 where ts > '2021-11-22 00:00:00' and ts < '2021-11-23 00:00:00'")
tdSql.error("select elapsed(now) from t1 where ts > '2021-11-22 00:00:00' and ts < '2021-11-23 00:00:00'") tdSql.error("select elapsed(now) from t1 where ts > '2021-11-22 00:00:00' and ts < '2021-11-23 00:00:00'")
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册