提交 2069de9f 编写于 作者: W wenzhouwww

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

...@@ -57,7 +57,7 @@ def pre_test(){ ...@@ -57,7 +57,7 @@ def pre_test(){
cd ${WKC} cd ${WKC}
git checkout 2.0 git checkout 2.0
''' '''
} }
else{ else{
sh ''' sh '''
cd ${WKC} cd ${WKC}
...@@ -67,6 +67,7 @@ def pre_test(){ ...@@ -67,6 +67,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
...@@ -88,28 +89,28 @@ def pre_test(){ ...@@ -88,28 +89,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
} }
...@@ -131,7 +132,7 @@ def pre_test_noinstall(){ ...@@ -131,7 +132,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}
...@@ -141,6 +142,7 @@ def pre_test_noinstall(){ ...@@ -141,6 +142,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
...@@ -162,24 +164,24 @@ def pre_test_noinstall(){ ...@@ -162,24 +164,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
...@@ -202,7 +204,7 @@ def pre_test_mac(){ ...@@ -202,7 +204,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}
...@@ -212,6 +214,7 @@ def pre_test_mac(){ ...@@ -212,6 +214,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
...@@ -233,24 +236,24 @@ def pre_test_mac(){ ...@@ -233,24 +236,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 .
...@@ -265,7 +268,7 @@ def pre_test_win(){ ...@@ -265,7 +268,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') {
...@@ -279,7 +282,7 @@ def pre_test_win(){ ...@@ -279,7 +282,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
...@@ -289,7 +292,8 @@ def pre_test_win(){ ...@@ -289,7 +292,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
...@@ -309,36 +313,36 @@ def pre_test_win(){ ...@@ -309,36 +313,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'
...@@ -346,7 +350,7 @@ pipeline { ...@@ -346,7 +350,7 @@ pipeline {
stages { stages {
stage('pre_build'){ stage('pre_build'){
agent{label 'master'} agent{label 'master'}
options { skipDefaultCheckout() } options { skipDefaultCheckout() }
when { when {
changeRequest() changeRequest()
} }
...@@ -371,32 +375,32 @@ pipeline { ...@@ -371,32 +375,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()
...@@ -415,13 +419,11 @@ pipeline { ...@@ -415,13 +419,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 '''
...@@ -434,8 +436,8 @@ pipeline { ...@@ -434,8 +436,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
...@@ -447,8 +449,8 @@ pipeline { ...@@ -447,8 +449,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/*
...@@ -492,11 +494,11 @@ pipeline { ...@@ -492,11 +494,11 @@ pipeline {
cd ${WKC}/src/connector/C# cd ${WKC}/src/connector/C#
dotnet test dotnet test
dotnet run --project src/test/Cases/Cases.csproj dotnet run --project src/test/Cases/Cases.csproj
cd ${WKC}/tests/examples/C# cd ${WKC}/tests/examples/C#
dotnet run --project C#checker/C#checker.csproj dotnet run --project C#checker/C#checker.csproj
dotnet run --project TDengineTest/TDengineTest.csproj dotnet run --project TDengineTest/TDengineTest.csproj
dotnet run --project schemaless/schemaless.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
...@@ -517,7 +519,7 @@ pipeline { ...@@ -517,7 +519,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'){
...@@ -547,7 +549,7 @@ pipeline { ...@@ -547,7 +549,7 @@ pipeline {
./test-all.sh b2fq ./test-all.sh b2fq
date date
''' '''
} }
} }
} }
stage('test_valgrind_s4') { stage('test_valgrind_s4') {
...@@ -561,8 +563,8 @@ pipeline { ...@@ -561,8 +563,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
...@@ -578,8 +580,8 @@ pipeline { ...@@ -578,8 +580,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
...@@ -592,14 +594,13 @@ pipeline { ...@@ -592,14 +594,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
...@@ -611,8 +612,8 @@ pipeline { ...@@ -611,8 +612,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
...@@ -623,14 +624,13 @@ pipeline { ...@@ -623,14 +624,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
...@@ -640,68 +640,68 @@ pipeline { ...@@ -640,68 +640,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()
} }
} }
...@@ -709,7 +709,7 @@ pipeline { ...@@ -709,7 +709,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)
} }
...@@ -719,7 +719,6 @@ pipeline { ...@@ -719,7 +719,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'){
...@@ -728,18 +727,16 @@ pipeline { ...@@ -728,18 +727,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",
...@@ -766,7 +763,6 @@ pipeline { ...@@ -766,7 +763,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>
...@@ -804,7 +800,6 @@ pipeline { ...@@ -804,7 +800,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>
...@@ -816,5 +811,5 @@ pipeline { ...@@ -816,5 +811,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")
......
...@@ -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 直接写入
......
# 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
...@@ -2759,7 +2759,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col ...@@ -2759,7 +2759,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);
} }
...@@ -6277,7 +6277,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq ...@@ -6277,7 +6277,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";
......
...@@ -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:
......
...@@ -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);
......
...@@ -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;
} }
Subproject commit 25f8683ece07897fea12c347d369602b2235665f Subproject commit 7da3cc9e4ad1030c2eec250b869a8fa215b4a4b4
...@@ -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" +
......
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 "";
}
...@@ -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 0b4a16e96b5cc9cb6e4f8cacf6a1f3028c91adb0
...@@ -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}
......
...@@ -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);
......
此差异已折叠。
...@@ -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
......
...@@ -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__)
......
...@@ -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();
} }
} }
......
#!/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
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -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.
先完成此消息的编辑!
想要评论请 注册