[td-225]merge develop
This commit is contained in:
commit
e655a68f69
|
@ -1,10 +1,20 @@
|
||||||
version: 1.0.{build}
|
version: 1.0.{build}
|
||||||
os: Visual Studio 2015
|
image:
|
||||||
|
- Visual Studio 2015
|
||||||
|
- macos
|
||||||
environment:
|
environment:
|
||||||
matrix:
|
matrix:
|
||||||
- ARCH: amd64
|
- ARCH: amd64
|
||||||
- ARCH: x86
|
- ARCH: x86
|
||||||
|
matrix:
|
||||||
|
exclude:
|
||||||
|
- image: macos
|
||||||
|
ARCH: x86
|
||||||
|
for:
|
||||||
|
-
|
||||||
|
matrix:
|
||||||
|
only:
|
||||||
|
- image: Visual Studio 2015
|
||||||
clone_folder: c:\dev\TDengine
|
clone_folder: c:\dev\TDengine
|
||||||
clone_depth: 1
|
clone_depth: 1
|
||||||
|
|
||||||
|
@ -19,12 +29,21 @@ build_script:
|
||||||
- cd build
|
- cd build
|
||||||
- cmake -G "NMake Makefiles" ..
|
- cmake -G "NMake Makefiles" ..
|
||||||
- nmake install
|
- nmake install
|
||||||
|
-
|
||||||
|
matrix:
|
||||||
|
only:
|
||||||
|
- image: macos
|
||||||
|
clone_depth: 1
|
||||||
|
|
||||||
|
build_script:
|
||||||
|
- mkdir debug
|
||||||
|
- cd debug
|
||||||
|
- cmake .. > /dev/null
|
||||||
|
- make > /dev/null
|
||||||
notifications:
|
notifications:
|
||||||
- provider: Email
|
- provider: Email
|
||||||
to:
|
to:
|
||||||
- sangshuduo@gmail.com
|
- sangshuduo@gmail.com
|
||||||
|
|
||||||
on_build_success: true
|
on_build_success: true
|
||||||
on_build_failure: true
|
on_build_failure: true
|
||||||
on_build_status_changed: true
|
on_build_status_changed: true
|
||||||
|
|
|
@ -0,0 +1,198 @@
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
name: test_amd64
|
||||||
|
|
||||||
|
platform:
|
||||||
|
os: linux
|
||||||
|
arch: amd64
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: build
|
||||||
|
image: gcc
|
||||||
|
commands:
|
||||||
|
- apt-get update
|
||||||
|
- apt-get install -y cmake build-essential
|
||||||
|
- mkdir debug
|
||||||
|
- cd debug
|
||||||
|
- cmake ..
|
||||||
|
- make
|
||||||
|
trigger:
|
||||||
|
event:
|
||||||
|
- pull_request
|
||||||
|
when:
|
||||||
|
branch:
|
||||||
|
- develop
|
||||||
|
- master
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
name: test_arm64
|
||||||
|
|
||||||
|
platform:
|
||||||
|
os: linux
|
||||||
|
arch: arm64
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: build
|
||||||
|
image: gcc
|
||||||
|
commands:
|
||||||
|
- apt-get update
|
||||||
|
- apt-get install -y cmake build-essential
|
||||||
|
- mkdir debug
|
||||||
|
- cd debug
|
||||||
|
- cmake .. -DCPUTYPE=aarch64 > /dev/null
|
||||||
|
- make
|
||||||
|
trigger:
|
||||||
|
event:
|
||||||
|
- pull_request
|
||||||
|
when:
|
||||||
|
branch:
|
||||||
|
- develop
|
||||||
|
- master
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
name: test_arm
|
||||||
|
|
||||||
|
platform:
|
||||||
|
os: linux
|
||||||
|
arch: arm
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: build
|
||||||
|
image: arm32v7/ubuntu:bionic
|
||||||
|
commands:
|
||||||
|
- apt-get update
|
||||||
|
- apt-get install -y cmake build-essential
|
||||||
|
- mkdir debug
|
||||||
|
- cd debug
|
||||||
|
- cmake .. -DCPUTYPE=aarch32 > /dev/null
|
||||||
|
- make
|
||||||
|
trigger:
|
||||||
|
event:
|
||||||
|
- pull_request
|
||||||
|
when:
|
||||||
|
branch:
|
||||||
|
- develop
|
||||||
|
- master
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
name: build_trusty
|
||||||
|
|
||||||
|
platform:
|
||||||
|
os: linux
|
||||||
|
arch: amd64
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: build
|
||||||
|
image: ubuntu:trusty
|
||||||
|
commands:
|
||||||
|
- apt-get update
|
||||||
|
- apt-get install -y gcc cmake3 build-essential git binutils-2.26
|
||||||
|
|
||||||
|
- mkdir debug
|
||||||
|
- cd debug
|
||||||
|
- cmake ..
|
||||||
|
- make
|
||||||
|
trigger:
|
||||||
|
event:
|
||||||
|
- pull_request
|
||||||
|
when:
|
||||||
|
branch:
|
||||||
|
- develop
|
||||||
|
- master
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
name: build_xenial
|
||||||
|
|
||||||
|
platform:
|
||||||
|
os: linux
|
||||||
|
arch: amd64
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: build
|
||||||
|
image: ubuntu:xenial
|
||||||
|
commands:
|
||||||
|
- apt-get update
|
||||||
|
- apt-get install -y gcc cmake build-essential
|
||||||
|
- mkdir debug
|
||||||
|
- cd debug
|
||||||
|
- cmake ..
|
||||||
|
- make
|
||||||
|
trigger:
|
||||||
|
event:
|
||||||
|
- pull_request
|
||||||
|
when:
|
||||||
|
branch:
|
||||||
|
- develop
|
||||||
|
- master
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
name: build_bionic
|
||||||
|
platform:
|
||||||
|
os: linux
|
||||||
|
arch: amd64
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: build
|
||||||
|
image: ubuntu:bionic
|
||||||
|
commands:
|
||||||
|
- apt-get update
|
||||||
|
- apt-get install -y gcc cmake build-essential
|
||||||
|
- mkdir debug
|
||||||
|
- cd debug
|
||||||
|
- cmake ..
|
||||||
|
- make
|
||||||
|
trigger:
|
||||||
|
event:
|
||||||
|
- pull_request
|
||||||
|
when:
|
||||||
|
branch:
|
||||||
|
- develop
|
||||||
|
- master
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
name: build_centos7
|
||||||
|
platform:
|
||||||
|
os: linux
|
||||||
|
arch: amd64
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: build
|
||||||
|
image: ansible/centos7-ansible
|
||||||
|
commands:
|
||||||
|
- yum install -y gcc gcc-c++ make cmake
|
||||||
|
- mkdir debug
|
||||||
|
- cd debug
|
||||||
|
- cmake ..
|
||||||
|
- make
|
||||||
|
trigger:
|
||||||
|
event:
|
||||||
|
- pull_request
|
||||||
|
when:
|
||||||
|
branch:
|
||||||
|
- develop
|
||||||
|
- master
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
name: goodbye
|
||||||
|
|
||||||
|
platform:
|
||||||
|
os: linux
|
||||||
|
arch: amd64
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: 64-bit
|
||||||
|
image: alpine
|
||||||
|
commands:
|
||||||
|
- echo 64-bit is good.
|
||||||
|
when:
|
||||||
|
branch:
|
||||||
|
- develop
|
||||||
|
- master
|
||||||
|
|
||||||
|
|
||||||
|
depends_on:
|
||||||
|
- test_arm64
|
||||||
|
- test_amd64
|
|
@ -2,6 +2,7 @@ build/
|
||||||
.vscode/
|
.vscode/
|
||||||
.idea/
|
.idea/
|
||||||
cmake-build-debug/
|
cmake-build-debug/
|
||||||
|
cmake-build-release/
|
||||||
cscope.out
|
cscope.out
|
||||||
.DS_Store
|
.DS_Store
|
||||||
debug/
|
debug/
|
||||||
|
|
296
.travis.yml
296
.travis.yml
|
@ -1,296 +0,0 @@
|
||||||
#
|
|
||||||
# Configuration
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# Build Matrix
|
|
||||||
#
|
|
||||||
branches:
|
|
||||||
only:
|
|
||||||
- master
|
|
||||||
- develop
|
|
||||||
- coverity_scan
|
|
||||||
- /^.*ci-.*$/
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
- os: linux
|
|
||||||
dist: focal
|
|
||||||
language: c
|
|
||||||
|
|
||||||
git:
|
|
||||||
- depth: 1
|
|
||||||
|
|
||||||
compiler: gcc
|
|
||||||
env: DESC="linux/gcc build and test"
|
|
||||||
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
packages:
|
|
||||||
- build-essential
|
|
||||||
- cmake
|
|
||||||
- net-tools
|
|
||||||
- python3-pip
|
|
||||||
- python3-setuptools
|
|
||||||
- valgrind
|
|
||||||
- psmisc
|
|
||||||
- unixodbc
|
|
||||||
- unixodbc-dev
|
|
||||||
- mono-complete
|
|
||||||
|
|
||||||
before_script:
|
|
||||||
- export TZ=Asia/Harbin
|
|
||||||
- date
|
|
||||||
- cd ${TRAVIS_BUILD_DIR}
|
|
||||||
- mkdir debug
|
|
||||||
- cd debug
|
|
||||||
|
|
||||||
script:
|
|
||||||
- cmake .. > /dev/null
|
|
||||||
- make > /dev/null
|
|
||||||
|
|
||||||
after_success:
|
|
||||||
- travis_wait 20
|
|
||||||
- |-
|
|
||||||
case $TRAVIS_OS_NAME in
|
|
||||||
linux)
|
|
||||||
cd ${TRAVIS_BUILD_DIR}/debug
|
|
||||||
make install > /dev/null || travis_terminate $?
|
|
||||||
|
|
||||||
py3ver=`python3 --version|awk '{print $2}'|cut -d "." -f 1,2` && apt install python$py3ver-dev
|
|
||||||
pip3 install psutil
|
|
||||||
pip3 install guppy3
|
|
||||||
pip3 install --user ${TRAVIS_BUILD_DIR}/src/connector/python/linux/python3/
|
|
||||||
|
|
||||||
cd ${TRAVIS_BUILD_DIR}/tests/examples/C#/taosdemo
|
|
||||||
mcs -out:taosdemo *.cs || travis_terminate $?
|
|
||||||
pkill -TERM -x taosd
|
|
||||||
fuser -k -n tcp 6030
|
|
||||||
sleep 1
|
|
||||||
${TRAVIS_BUILD_DIR}/debug/build/bin/taosd -c ${TRAVIS_BUILD_DIR}/debug/test/cfg > /dev/null &
|
|
||||||
sleep 5
|
|
||||||
mono taosdemo -Q DEFAULT -y || travis_terminate $?
|
|
||||||
pkill -KILL -x taosd
|
|
||||||
fuser -k -n tcp 6030
|
|
||||||
sleep 1
|
|
||||||
|
|
||||||
cd ${TRAVIS_BUILD_DIR}/tests
|
|
||||||
./test-all.sh smoke || travis_terminate $?
|
|
||||||
sleep 1
|
|
||||||
|
|
||||||
cd ${TRAVIS_BUILD_DIR}/tests/pytest
|
|
||||||
pkill -TERM -x taosd
|
|
||||||
fuser -k -n tcp 6030
|
|
||||||
sleep 1
|
|
||||||
./crash_gen.sh -a -p -t 4 -s 2000|| travis_terminate $?
|
|
||||||
sleep 1
|
|
||||||
|
|
||||||
cd ${TRAVIS_BUILD_DIR}/tests/pytest
|
|
||||||
./valgrind-test.sh 2>&1 > mem-error-out.log
|
|
||||||
sleep 1
|
|
||||||
|
|
||||||
|
|
||||||
# Color setting
|
|
||||||
RED='\033[0;31m'
|
|
||||||
GREEN='\033[1;32m'
|
|
||||||
GREEN_DARK='\033[0;32m'
|
|
||||||
GREEN_UNDERLINE='\033[4;32m'
|
|
||||||
NC='\033[0m'
|
|
||||||
|
|
||||||
grep 'start to execute\|ERROR SUMMARY' mem-error-out.log|grep -v 'grep'|uniq|tee uniq-mem-error-out.log
|
|
||||||
|
|
||||||
for memError in `grep 'ERROR SUMMARY' uniq-mem-error-out.log | awk '{print $4}'`
|
|
||||||
do
|
|
||||||
if [ -n "$memError" ]; then
|
|
||||||
if [ "$memError" -gt 12 ]; then
|
|
||||||
echo -e "${RED} ## Memory errors number valgrind reports is $memError.\
|
|
||||||
More than our threshold! ## ${NC}"
|
|
||||||
travis_terminate $memError
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
grep 'start to execute\|definitely lost:' mem-error-out.log|grep -v 'grep'|uniq|tee uniq-definitely-lost-out.log
|
|
||||||
for defiMemError in `grep 'definitely lost:' uniq-definitely-lost-out.log | awk '{print $7}'`
|
|
||||||
do
|
|
||||||
if [ -n "$defiMemError" ]; then
|
|
||||||
if [ "$defiMemError" -gt 13 ]; then
|
|
||||||
echo -e "${RED} ## Memory errors number valgrind reports \
|
|
||||||
Definitely lost is $defiMemError. More than our threshold! ## ${NC}"
|
|
||||||
travis_terminate $defiMemError
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
- os: linux
|
|
||||||
dist: bionic
|
|
||||||
language: c
|
|
||||||
compiler: gcc
|
|
||||||
env: COVERITY_SCAN=true
|
|
||||||
git:
|
|
||||||
- depth: 1
|
|
||||||
|
|
||||||
script:
|
|
||||||
- echo "this job is for coverity scan"
|
|
||||||
|
|
||||||
addons:
|
|
||||||
coverity_scan:
|
|
||||||
# GitHub project metadata
|
|
||||||
# ** specific to your project **
|
|
||||||
project:
|
|
||||||
name: TDengine
|
|
||||||
version: 2.x
|
|
||||||
description: TDengine
|
|
||||||
|
|
||||||
# Where email notification of build analysis results will be sent
|
|
||||||
notification_email: sdsang@taosdata.com, slguan@taosdata.com
|
|
||||||
|
|
||||||
# Commands to prepare for build_command
|
|
||||||
# ** likely specific to your build **
|
|
||||||
build_command_prepend: cmake . > /dev/null
|
|
||||||
|
|
||||||
# The command that will be added as an argument to "cov-build" to compile your project for analysis,
|
|
||||||
# ** likely specific to your build **
|
|
||||||
build_command: make
|
|
||||||
|
|
||||||
# Pattern to match selecting branches that will run analysis. We recommend leaving this set to 'coverity_scan'.
|
|
||||||
# Take care in resource usage, and consider the build frequency allowances per
|
|
||||||
# https://scan.coverity.com/faq#frequency
|
|
||||||
branch_pattern: coverity_scan
|
|
||||||
|
|
||||||
- os: linux
|
|
||||||
dist: trusty
|
|
||||||
language: c
|
|
||||||
git:
|
|
||||||
- depth: 1
|
|
||||||
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
packages:
|
|
||||||
- build-essential
|
|
||||||
- cmake
|
|
||||||
- binutils-2.26
|
|
||||||
- unixodbc
|
|
||||||
- unixodbc-dev
|
|
||||||
env:
|
|
||||||
- DESC="trusty/gcc-4.8/bintuils-2.26 build"
|
|
||||||
|
|
||||||
before_script:
|
|
||||||
- export TZ=Asia/Harbin
|
|
||||||
- date
|
|
||||||
- cd ${TRAVIS_BUILD_DIR}
|
|
||||||
- mkdir debug
|
|
||||||
- cd debug
|
|
||||||
|
|
||||||
script:
|
|
||||||
- cmake .. > /dev/null
|
|
||||||
- export PATH=/usr/lib/binutils-2.26/bin:$PATH && make
|
|
||||||
|
|
||||||
- os: linux
|
|
||||||
dist: bionic
|
|
||||||
language: c
|
|
||||||
compiler: clang
|
|
||||||
env: DESC="linux/clang build"
|
|
||||||
git:
|
|
||||||
- depth: 1
|
|
||||||
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
packages:
|
|
||||||
- build-essential
|
|
||||||
- cmake
|
|
||||||
- unixodbc
|
|
||||||
- unixodbc-dev
|
|
||||||
|
|
||||||
before_script:
|
|
||||||
- export TZ=Asia/Harbin
|
|
||||||
- date
|
|
||||||
- cd ${TRAVIS_BUILD_DIR}
|
|
||||||
- mkdir debug
|
|
||||||
- cd debug
|
|
||||||
|
|
||||||
script:
|
|
||||||
- cmake .. > /dev/null
|
|
||||||
- make > /dev/null
|
|
||||||
|
|
||||||
- os: linux
|
|
||||||
arch: arm64
|
|
||||||
dist: bionic
|
|
||||||
language: c
|
|
||||||
compiler: clang
|
|
||||||
env: DESC="arm64 linux/clang build"
|
|
||||||
git:
|
|
||||||
- depth: 1
|
|
||||||
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
packages:
|
|
||||||
- build-essential
|
|
||||||
- cmake
|
|
||||||
|
|
||||||
before_script:
|
|
||||||
- export TZ=Asia/Harbin
|
|
||||||
- date
|
|
||||||
- cd ${TRAVIS_BUILD_DIR}
|
|
||||||
- mkdir debug
|
|
||||||
- cd debug
|
|
||||||
|
|
||||||
script:
|
|
||||||
- if [ "${TRAVIS_CPU_ARCH}" == "arm64" ]; then
|
|
||||||
cmake .. -DCPUTYPE=aarch64 > /dev/null;
|
|
||||||
else
|
|
||||||
cmake .. > /dev/null;
|
|
||||||
fi
|
|
||||||
- make > /dev/null
|
|
||||||
|
|
||||||
- os: linux
|
|
||||||
arch: arm64
|
|
||||||
dist: xenial
|
|
||||||
language: c
|
|
||||||
git:
|
|
||||||
- depth: 1
|
|
||||||
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
packages:
|
|
||||||
- build-essential
|
|
||||||
- cmake
|
|
||||||
- unixodbc
|
|
||||||
- unixodbc-dev
|
|
||||||
env:
|
|
||||||
- DESC="arm64 xenial build"
|
|
||||||
|
|
||||||
before_script:
|
|
||||||
- export TZ=Asia/Harbin
|
|
||||||
- date
|
|
||||||
- cd ${TRAVIS_BUILD_DIR}
|
|
||||||
- mkdir debug
|
|
||||||
- cd debug
|
|
||||||
|
|
||||||
script:
|
|
||||||
- if [ "${TRAVIS_CPU_ARCH}" == "arm64" ]; then
|
|
||||||
cmake .. -DCPUTYPE=aarch64 > /dev/null;
|
|
||||||
else
|
|
||||||
cmake .. > /dev/null;
|
|
||||||
fi
|
|
||||||
- make > /dev/null
|
|
||||||
|
|
||||||
- os: osx
|
|
||||||
osx_image: xcode11.4
|
|
||||||
language: c
|
|
||||||
compiler: clang
|
|
||||||
env: DESC="mac/clang build"
|
|
||||||
git:
|
|
||||||
- depth: 1
|
|
||||||
addons:
|
|
||||||
homebrew:
|
|
||||||
- cmake
|
|
||||||
- unixodbc
|
|
||||||
|
|
||||||
script:
|
|
||||||
- cd ${TRAVIS_BUILD_DIR}
|
|
||||||
- mkdir debug
|
|
||||||
- cd debug
|
|
||||||
- cmake .. > /dev/null
|
|
||||||
- make > /dev/null
|
|
|
@ -42,6 +42,13 @@ INCLUDE(cmake/env.inc)
|
||||||
INCLUDE(cmake/version.inc)
|
INCLUDE(cmake/version.inc)
|
||||||
INCLUDE(cmake/install.inc)
|
INCLUDE(cmake/install.inc)
|
||||||
|
|
||||||
|
IF (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||||
|
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pipe -Wall -Wshadow -Werror")
|
||||||
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pipe -Wall -Wshadow -Werror")
|
||||||
|
ENDIF ()
|
||||||
|
MESSAGE(STATUS "CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}")
|
||||||
|
MESSAGE(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
|
||||||
|
|
||||||
ADD_SUBDIRECTORY(deps)
|
ADD_SUBDIRECTORY(deps)
|
||||||
ADD_SUBDIRECTORY(src)
|
ADD_SUBDIRECTORY(src)
|
||||||
ADD_SUBDIRECTORY(tests)
|
ADD_SUBDIRECTORY(tests)
|
||||||
|
|
|
@ -94,6 +94,7 @@ def pre_test(){
|
||||||
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
|
||||||
'''
|
'''
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
[](https://travis-ci.org/taosdata/TDengine)
|
[](https://cloud.drone.io/taosdata/TDengine)
|
||||||
[](https://ci.appveyor.com/project/sangshuduo/tdengine-2n8ge/branch/master)
|
[](https://ci.appveyor.com/project/sangshuduo/tdengine-2n8ge/branch/master)
|
||||||
[](https://coveralls.io/github/taosdata/TDengine?branch=develop)
|
[](https://coveralls.io/github/taosdata/TDengine?branch=develop)
|
||||||
[](https://bestpractices.coreinfrastructure.org/projects/4201)
|
[](https://bestpractices.coreinfrastructure.org/projects/4201)
|
||||||
|
|
|
@ -157,7 +157,7 @@ IF (TD_WINDOWS)
|
||||||
IF (MSVC AND (MSVC_VERSION GREATER_EQUAL 1900))
|
IF (MSVC AND (MSVC_VERSION GREATER_EQUAL 1900))
|
||||||
SET(COMMON_FLAGS "${COMMON_FLAGS} /Wv:18")
|
SET(COMMON_FLAGS "${COMMON_FLAGS} /Wv:18")
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
SET(DEBUG_FLAGS "/Zi /W3 /GL")
|
SET(DEBUG_FLAGS "/fsanitize=thread /fsanitize=leak /fsanitize=memory /fsanitize=undefined /fsanitize=hwaddress /Zi /W3 /GL")
|
||||||
SET(RELEASE_FLAGS "/W0 /O3 /GL")
|
SET(RELEASE_FLAGS "/W0 /O3 /GL")
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ ENDIF ()
|
||||||
#
|
#
|
||||||
|
|
||||||
# Set compiler options
|
# Set compiler options
|
||||||
|
SET(COMMON_C_FLAGS "${COMMON_FLAGS} -std=gnu99")
|
||||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${COMMON_FLAGS} ${DEBUG_FLAGS}")
|
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${COMMON_FLAGS} ${DEBUG_FLAGS}")
|
||||||
SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${COMMON_FLAGS} ${RELEASE_FLAGS}")
|
SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${COMMON_FLAGS} ${RELEASE_FLAGS}")
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ ELSEIF (TD_WINDOWS)
|
||||||
#INSTALL(TARGETS taos RUNTIME DESTINATION driver)
|
#INSTALL(TARGETS taos RUNTIME DESTINATION driver)
|
||||||
#INSTALL(TARGETS shell RUNTIME DESTINATION .)
|
#INSTALL(TARGETS shell RUNTIME DESTINATION .)
|
||||||
IF (TD_MVN_INSTALLED)
|
IF (TD_MVN_INSTALLED)
|
||||||
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.28-dist.jar DESTINATION connector/jdbc)
|
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.29.jar DESTINATION connector/jdbc)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
ELSEIF (TD_DARWIN)
|
ELSEIF (TD_DARWIN)
|
||||||
SET(TD_MAKE_INSTALL_SH "${TD_COMMUNITY_DIR}/packaging/tools/make_install.sh")
|
SET(TD_MAKE_INSTALL_SH "${TD_COMMUNITY_DIR}/packaging/tools/make_install.sh")
|
||||||
|
|
|
@ -4,7 +4,7 @@ PROJECT(TDengine)
|
||||||
IF (DEFINED VERNUMBER)
|
IF (DEFINED VERNUMBER)
|
||||||
SET(TD_VER_NUMBER ${VERNUMBER})
|
SET(TD_VER_NUMBER ${VERNUMBER})
|
||||||
ELSE ()
|
ELSE ()
|
||||||
SET(TD_VER_NUMBER "2.0.20.0")
|
SET(TD_VER_NUMBER "2.1.0.0")
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
IF (DEFINED VERCOMPATIBLE)
|
IF (DEFINED VERCOMPATIBLE)
|
||||||
|
|
|
@ -36,6 +36,15 @@ static char monotonic_info_string[32];
|
||||||
|
|
||||||
static long mono_ticksPerMicrosecond = 0;
|
static long mono_ticksPerMicrosecond = 0;
|
||||||
|
|
||||||
|
#ifdef _TD_NINGSI_60
|
||||||
|
// implement __rdtsc in ningsi60
|
||||||
|
uint64_t __rdtsc(){
|
||||||
|
unsigned int lo,hi;
|
||||||
|
__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
|
||||||
|
return ((uint64_t)hi << 32) | lo;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static monotime getMonotonicUs_x86() {
|
static monotime getMonotonicUs_x86() {
|
||||||
return __rdtsc() / mono_ticksPerMicrosecond;
|
return __rdtsc() / mono_ticksPerMicrosecond;
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,9 +117,9 @@ TDengine是一个高效的存储、查询、分析时序大数据的平台,专
|
||||||
## 常用工具
|
## 常用工具
|
||||||
|
|
||||||
* [TDengine样例导入工具](https://www.taosdata.com/blog/2020/01/18/1166.html)
|
* [TDengine样例导入工具](https://www.taosdata.com/blog/2020/01/18/1166.html)
|
||||||
* [TDengine性能对比测试工具](https://www.taosdata.com/blog/2020/01/18/1166.html)
|
* [TDengine写入性能测试工具](https://www.taosdata.com/blog/2020/01/18/1166.html)
|
||||||
* [IDEA数据库管理工具可视化使用TDengine](https://www.taosdata.com/blog/2020/08/27/1767.html)
|
* [IDEA数据库管理工具可视化使用TDengine](https://www.taosdata.com/blog/2020/08/27/1767.html)
|
||||||
* [基于eletron开发的跨平台TDengine图形化管理工具](https://github.com/skye0207/TDengineGUI)
|
* [基于Electron开发的跨平台TDengine图形化管理工具](https://github.com/skye0207/TDengineGUI)
|
||||||
* [DataX,支持TDengine的离线数据采集/同步工具](https://github.com/wgzhao/DataX)(文档:[读取插件](https://github.com/wgzhao/DataX/blob/master/docs/src/main/sphinx/reader/tdenginereader.md)、[写入插件](https://github.com/wgzhao/DataX/blob/master/docs/src/main/sphinx/writer/tdenginewriter.md))
|
* [DataX,支持TDengine的离线数据采集/同步工具](https://github.com/wgzhao/DataX)(文档:[读取插件](https://github.com/wgzhao/DataX/blob/master/docs/src/main/sphinx/reader/tdenginereader.md)、[写入插件](https://github.com/wgzhao/DataX/blob/master/docs/src/main/sphinx/writer/tdenginewriter.md))
|
||||||
|
|
||||||
## TDengine与其他数据库的对比测试
|
## TDengine与其他数据库的对比测试
|
||||||
|
|
|
@ -12,7 +12,7 @@ TDengine 采用 SQL 作为查询语言。应用程序可以通过 C/C++, Java, G
|
||||||
- 时间戳对齐的连接查询(Join Query: 隐式连接)操作
|
- 时间戳对齐的连接查询(Join Query: 隐式连接)操作
|
||||||
- 多种聚合/计算函数: count, max, min, avg, sum, twa, stddev, leastsquares, top, bottom, first, last, percentile, apercentile, last_row, spread, diff等
|
- 多种聚合/计算函数: count, max, min, avg, sum, twa, stddev, leastsquares, top, bottom, first, last, percentile, apercentile, last_row, spread, diff等
|
||||||
|
|
||||||
例如:在TAOS Shell中,从表d1001中查询出vlotage > 215的记录,按时间降序排列,仅仅输出2条。
|
例如:在TAOS Shell中,从表d1001中查询出voltage > 215的记录,按时间降序排列,仅仅输出2条。
|
||||||
```mysql
|
```mysql
|
||||||
taos> select * from d1001 where voltage > 215 order by ts desc limit 2;
|
taos> select * from d1001 where voltage > 215 order by ts desc limit 2;
|
||||||
ts | current | voltage | phase |
|
ts | current | voltage | phase |
|
||||||
|
|
|
@ -16,7 +16,6 @@ TDengine 的 JDBC 驱动实现尽可能与关系型数据库驱动保持一致
|
||||||
|
|
||||||
* TDengine 目前不支持针对单条数据记录的删除操作。
|
* TDengine 目前不支持针对单条数据记录的删除操作。
|
||||||
* 目前不支持事务操作。
|
* 目前不支持事务操作。
|
||||||
* 目前不支持表间的 union 操作。
|
|
||||||
* 目前不支持嵌套查询(nested query)。
|
* 目前不支持嵌套查询(nested query)。
|
||||||
* 对每个 Connection 的实例,至多只能有一个打开的 ResultSet 实例;如果在 ResultSet 还没关闭的情况下执行了新的查询,taos-jdbcdriver 会自动关闭上一个 ResultSet。
|
* 对每个 Connection 的实例,至多只能有一个打开的 ResultSet 实例;如果在 ResultSet 还没关闭的情况下执行了新的查询,taos-jdbcdriver 会自动关闭上一个 ResultSet。
|
||||||
|
|
||||||
|
@ -447,7 +446,7 @@ Query OK, 1 row(s) in set (0.000141s)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## TAOS-JDBCDriver 版本以及支持的 TDengine 版本和 JDK 版本
|
## <a class="anchor" id="version"></a>TAOS-JDBCDriver 版本以及支持的 TDengine 版本和 JDK 版本
|
||||||
|
|
||||||
| taos-jdbcdriver 版本 | TDengine 版本 | JDK 版本 |
|
| taos-jdbcdriver 版本 | TDengine 版本 | JDK 版本 |
|
||||||
| -------------------- | ----------------- | -------- |
|
| -------------------- | ----------------- | -------- |
|
||||||
|
|
|
@ -32,7 +32,7 @@ TDengine提供了丰富的应用程序开发接口,其中包括C/C++、Java、
|
||||||
|
|
||||||
**Linux**
|
**Linux**
|
||||||
|
|
||||||
**1. 从涛思官网(https://www.taosdata.com/cn/all-downloads/)下载**
|
**1. 从[涛思官网](https://www.taosdata.com/cn/all-downloads/)下载**
|
||||||
|
|
||||||
* X64硬件环境:TDengine-client-2.x.x.x-Linux-x64.tar.gz
|
* X64硬件环境:TDengine-client-2.x.x.x-Linux-x64.tar.gz
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ TDengine提供了丰富的应用程序开发接口,其中包括C/C++、Java、
|
||||||
|
|
||||||
**Windows x64/x86**
|
**Windows x64/x86**
|
||||||
|
|
||||||
**1. 从涛思官网(https://www.taosdata.com/cn/all-downloads/)下载 :**
|
**1. 从[涛思官网](https://www.taosdata.com/cn/all-downloads/)下载 :**
|
||||||
|
|
||||||
* X64硬件环境:TDengine-client-2.X.X.X-Windows-x64.exe
|
* X64硬件环境:TDengine-client-2.X.X.X-Windows-x64.exe
|
||||||
|
|
||||||
|
@ -345,11 +345,11 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时
|
||||||
* taos:已经建立好的数据库连接
|
* taos:已经建立好的数据库连接
|
||||||
* sql:SQL查询语句(仅能使用查询语句)
|
* sql:SQL查询语句(仅能使用查询语句)
|
||||||
* fp:用户定义的回调函数指针,每次流式计算完成后,TDengine将查询的结果(TAOS_ROW)、查询状态(TAOS_RES)、用户定义参数(PARAM)传递给回调函数,在回调函数内,用户可以使用taos_num_fields获取结果集列数,taos_fetch_fields获取结果集每列数据的类型。
|
* fp:用户定义的回调函数指针,每次流式计算完成后,TDengine将查询的结果(TAOS_ROW)、查询状态(TAOS_RES)、用户定义参数(PARAM)传递给回调函数,在回调函数内,用户可以使用taos_num_fields获取结果集列数,taos_fetch_fields获取结果集每列数据的类型。
|
||||||
* stime:是流式计算开始的时间,如果是0,表示从现在开始,如果不为零,表示从指定的时间开始计算(UTC时间从1970/1/1算起的毫秒数)
|
* stime:是流式计算开始的时间。如果是“64位整数最小值”,表示从现在开始;如果不为“64位整数最小值”,表示从指定的时间开始计算(UTC时间从1970/1/1算起的毫秒数)。
|
||||||
* param:是应用提供的用于回调的一个参数,回调时,提供给应用
|
* param:是应用提供的用于回调的一个参数,回调时,提供给应用
|
||||||
* callback: 第二个回调函数,会在连续查询自动停止时被调用。
|
* callback: 第二个回调函数,会在连续查询自动停止时被调用。
|
||||||
|
|
||||||
返回值为NULL,表示创建成功,返回值不为空,表示成功。
|
返回值为NULL,表示创建失败;返回值不为空,表示成功。
|
||||||
|
|
||||||
- `void taos_close_stream (TAOS_STREAM *tstr)`
|
- `void taos_close_stream (TAOS_STREAM *tstr)`
|
||||||
|
|
||||||
|
@ -400,27 +400,22 @@ Python连接器的使用参见[视频教程](https://www.taosdata.com/blog/2020/
|
||||||
|
|
||||||
#### Linux
|
#### Linux
|
||||||
|
|
||||||
用户可以在源代码的src/connector/python(或者tar.gz的/connector/python)文件夹下找到python2和python3的connector安装包。用户可以通过pip命令安装:
|
用户可以在源代码的src/connector/python(或者tar.gz的/connector/python)文件夹下找到connector安装包。用户可以通过pip命令安装:
|
||||||
|
|
||||||
`pip install src/connector/python/linux/python2/`
|
`pip install src/connector/python/`
|
||||||
|
|
||||||
或
|
或
|
||||||
|
|
||||||
`pip3 install src/connector/python/linux/python3/`
|
`pip3 install src/connector/python/`
|
||||||
|
|
||||||
#### Windows
|
#### Windows
|
||||||
在已安装Windows TDengine 客户端的情况下, 将文件"C:\TDengine\driver\taos.dll" 拷贝到 "C:\windows\system32" 目录下, 然后进入Windwos <em>cmd</em> 命令行界面
|
在已安装Windows TDengine 客户端的情况下, 将文件"C:\TDengine\driver\taos.dll" 拷贝到 "C:\windows\system32" 目录下, 然后进入Windwos <em>cmd</em> 命令行界面
|
||||||
```cmd
|
```cmd
|
||||||
cd C:\TDengine\connector\python\windows
|
cd C:\TDengine\connector\python
|
||||||
python -m pip install python2\
|
python -m pip install .
|
||||||
```
|
|
||||||
或
|
|
||||||
```cmd
|
|
||||||
cd C:\TDengine\connector\python\windows
|
|
||||||
python -m pip install python3\
|
|
||||||
```
|
```
|
||||||
|
|
||||||
* 如果机器上没有pip命令,用户可将src/connector/python/python3或src/connector/python/python2下的taos文件夹拷贝到应用程序的目录使用。
|
* 如果机器上没有pip命令,用户可将src/connector/python下的taos文件夹拷贝到应用程序的目录使用。
|
||||||
对于windows 客户端,安装TDengine windows 客户端后,将C:\TDengine\driver\taos.dll拷贝到C:\windows\system32目录下即可。
|
对于windows 客户端,安装TDengine windows 客户端后,将C:\TDengine\driver\taos.dll拷贝到C:\windows\system32目录下即可。
|
||||||
|
|
||||||
### 使用
|
### 使用
|
||||||
|
|
|
@ -16,7 +16,7 @@ TDengine的Grafana插件在安装包的/usr/local/taos/connector/grafanaplugin
|
||||||
以CentOS 7.2操作系统为例,将grafanaplugin目录拷贝到/var/lib/grafana/plugins目录下,重新启动grafana即可。
|
以CentOS 7.2操作系统为例,将grafanaplugin目录拷贝到/var/lib/grafana/plugins目录下,重新启动grafana即可。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo cp -rf /usr/local/taos/connector/grafanaplugin /var/lib/grafana/tdengine
|
sudo cp -rf /usr/local/taos/connector/grafanaplugin /var/lib/grafana/plugins/tdengine
|
||||||
```
|
```
|
||||||
|
|
||||||
### 使用 Grafana
|
### 使用 Grafana
|
||||||
|
|
|
@ -144,7 +144,7 @@ TDengine集群中加入一个新的dnode时,涉及集群相关的一些参数
|
||||||
- numOfMnodes:系统中管理节点个数。默认值:3。
|
- numOfMnodes:系统中管理节点个数。默认值:3。
|
||||||
- balance:是否启动负载均衡。0:否,1:是。默认值:1。
|
- balance:是否启动负载均衡。0:否,1:是。默认值:1。
|
||||||
- mnodeEqualVnodeNum: 一个mnode等同于vnode消耗的个数。默认值:4。
|
- mnodeEqualVnodeNum: 一个mnode等同于vnode消耗的个数。默认值:4。
|
||||||
- offlineThreshold: dnode离线阈值,超过该时间将导致该dnode从集群中删除。单位为秒,默认值:86400*100(即100天)。
|
- offlineThreshold: dnode离线阈值,超过该时间将导致该dnode从集群中删除。单位为秒,默认值:86400*10(即10天)。
|
||||||
- statusInterval: dnode向mnode报告状态时长。单位为秒,默认值:1。
|
- statusInterval: dnode向mnode报告状态时长。单位为秒,默认值:1。
|
||||||
- maxTablesPerVnode: 每个vnode中能够创建的最大表个数。默认值:1000000。
|
- maxTablesPerVnode: 每个vnode中能够创建的最大表个数。默认值:1000000。
|
||||||
- maxVgroupsPerDb: 每个数据库中能够使用的最大vgroup个数。
|
- maxVgroupsPerDb: 每个数据库中能够使用的最大vgroup个数。
|
||||||
|
@ -462,31 +462,31 @@ TDengine的所有可执行文件默认存放在 _/usr/local/taos/bin_ 目录下
|
||||||
|
|
||||||
| 关键字列表 | | | | |
|
| 关键字列表 | | | | |
|
||||||
| ---------- | ----------- | ------------ | ---------- | --------- |
|
| ---------- | ----------- | ------------ | ---------- | --------- |
|
||||||
| ABLOCKS | CONNECTIONS | HAVING | MODULES | SLIMIT |
|
| ABLOCKS | CONNECTIONS | HAVING | MODULES | SMALLINT |
|
||||||
| ABORT | COPY | ID | NCHAR | SMALLINT |
|
| ABORT | COPY | ID | NCHAR | SPREAD |
|
||||||
| ACCOUNT | COUNT | IF | NE | SPREAD |
|
| ACCOUNT | COUNT | IF | NE | STABLE |
|
||||||
| ACCOUNTS | CREATE | IGNORE | NONE | STABLE |
|
| ACCOUNTS | CREATE | IGNORE | NONE | STABLES |
|
||||||
| ADD | CTIME | IMMEDIATE | NOT | STABLES |
|
| ADD | CTIME | IMMEDIATE | NOT | STAR |
|
||||||
| AFTER | DATABASE | IMPORT | NOTNULL | STAR |
|
| AFTER | DATABASE | IMPORT | NOTNULL | STATEMENT |
|
||||||
| ALL | DATABASES | IN | NOW | STATEMENT |
|
| ALL | DATABASES | IN | NOW | STDDEV |
|
||||||
| ALTER | DAYS | INITIALLY | OF | STDDEV |
|
| ALTER | DAYS | INITIALLY | OF | STREAM |
|
||||||
| AND | DEFERRED | INSERT | OFFSET | STREAM |
|
| AND | DEFERRED | INSERT | OFFSET | STREAMS |
|
||||||
| AS | DELIMITERS | INSTEAD | OR | STREAMS |
|
| AS | DELIMITERS | INSTEAD | OR | STRING |
|
||||||
| ASC | DESC | INTEGER | ORDER | STRING |
|
| ASC | DESC | INTEGER | ORDER | SUM |
|
||||||
| ATTACH | DESCRIBE | INTERVAL | PASS | SUM |
|
| ATTACH | DESCRIBE | INTERVAL | PASS | TABLE |
|
||||||
| AVG | DETACH | INTO | PERCENTILE | TABLE |
|
| AVG | DETACH | INTO | PERCENTILE | TABLES |
|
||||||
| BEFORE | DIFF | IP | PLUS | TABLES |
|
| BEFORE | DIFF | IP | PLUS | TAG |
|
||||||
| BEGIN | DISTINCT | IS | PRAGMA | TAG |
|
| BEGIN | DISTINCT | IS | PRAGMA | TAGS |
|
||||||
| BETWEEN | DIVIDE | ISNULL | PREV | TAGS |
|
| BETWEEN | DIVIDE | ISNULL | PREV | TBLOCKS |
|
||||||
| BIGINT | DNODE | JOIN | PRIVILEGE | TBLOCKS |
|
| BIGINT | DNODE | JOIN | PRIVILEGE | TBNAME |
|
||||||
| BINARY | DNODES | KEEP | QUERIES | TBNAME |
|
| BINARY | DNODES | KEEP | QUERIES | TIMES |
|
||||||
| BITAND | DOT | KEY | QUERY | TIMES |
|
| BITAND | DOT | KEY | QUERY | TIMESTAMP |
|
||||||
| BITNOT | DOUBLE | KILL | RAISE | TIMESTAMP |
|
| BITNOT | DOUBLE | KILL | RAISE | TINYINT |
|
||||||
| BITOR | DROP | LAST | REM | TINYINT |
|
| BITOR | DROP | LAST | REM | TOP |
|
||||||
| BOOL | EACH | LE | REPLACE | TOP |
|
| BOOL | EACH | LE | REPLACE | TOPIC |
|
||||||
| BOTTOM | END | LEASTSQUARES | REPLICA | TOPIC |
|
| BOTTOM | END | LEASTSQUARES | REPLICA | TRIGGER |
|
||||||
| BY | EQ | LIKE | RESET | TRIGGER |
|
| BY | EQ | LIKE | RESET | UMINUS |
|
||||||
| CACHE | EXISTS | LIMIT | RESTRICT | UMINUS |
|
| CACHE | EXISTS | LIMIT | RESTRICT | UNION |
|
||||||
| CASCADE | EXPLAIN | LINEAR | ROW | UPLUS |
|
| CASCADE | EXPLAIN | LINEAR | ROW | UPLUS |
|
||||||
| CHANGE | FAIL | LOCAL | ROWS | USE |
|
| CHANGE | FAIL | LOCAL | ROWS | USE |
|
||||||
| CLOG | FILL | LP | RP | USER |
|
| CLOG | FILL | LP | RP | USER |
|
||||||
|
@ -498,5 +498,5 @@ TDengine的所有可执行文件默认存放在 _/usr/local/taos/bin_ 目录下
|
||||||
| CONCAT | GLOB | METRICS | SHOW | VIEW |
|
| CONCAT | GLOB | METRICS | SHOW | VIEW |
|
||||||
| CONFIGS | GRANTS | MIN | SLASH | WAVG |
|
| CONFIGS | GRANTS | MIN | SLASH | WAVG |
|
||||||
| CONFLICT | GROUP | MINUS | SLIDING | WHERE |
|
| CONFLICT | GROUP | MINUS | SLIDING | WHERE |
|
||||||
| CONNECTION | GT | MNODES | | |
|
| CONNECTION | GT | MNODES | SLIMIT | |
|
||||||
|
|
||||||
|
|
|
@ -135,6 +135,14 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM
|
||||||
SHOW DATABASES;
|
SHOW DATABASES;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- **显示一个数据库的创建语句**
|
||||||
|
|
||||||
|
```mysql
|
||||||
|
SHOW CREATE DATABASE db_name;
|
||||||
|
```
|
||||||
|
常用于数据库迁移。对一个已经存在的数据库,返回其创建语句;在另一个集群中执行该语句,就能得到一个设置完全相同的 Database。
|
||||||
|
|
||||||
|
|
||||||
## <a class="anchor" id="table"></a>表管理
|
## <a class="anchor" id="table"></a>表管理
|
||||||
|
|
||||||
- **创建数据表**
|
- **创建数据表**
|
||||||
|
@ -200,6 +208,13 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM
|
||||||
|
|
||||||
通配符匹配:1)’%’ (百分号)匹配0到任意个字符;2)’\_’下划线匹配一个字符。
|
通配符匹配:1)’%’ (百分号)匹配0到任意个字符;2)’\_’下划线匹配一个字符。
|
||||||
|
|
||||||
|
- **显示一个数据表的创建语句**
|
||||||
|
|
||||||
|
```mysql
|
||||||
|
SHOW CREATE TABLE tb_name;
|
||||||
|
```
|
||||||
|
常用于数据库迁移。对一个已经存在的数据表,返回其创建语句;在另一个集群中执行该语句,就能得到一个结构完全相同的数据表。
|
||||||
|
|
||||||
- **在线修改显示字符宽度**
|
- **在线修改显示字符宽度**
|
||||||
|
|
||||||
```mysql
|
```mysql
|
||||||
|
@ -265,6 +280,13 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM
|
||||||
```
|
```
|
||||||
查看数据库内全部 STable,及其相关信息,包括 STable 的名称、创建时间、列数量、标签(TAG)数量、通过该 STable 建表的数量。
|
查看数据库内全部 STable,及其相关信息,包括 STable 的名称、创建时间、列数量、标签(TAG)数量、通过该 STable 建表的数量。
|
||||||
|
|
||||||
|
- **显示一个超级表的创建语句**
|
||||||
|
|
||||||
|
```mysql
|
||||||
|
SHOW CREATE STABLE stb_name;
|
||||||
|
```
|
||||||
|
常用于数据库迁移。对一个已经存在的超级表,返回其创建语句;在另一个集群中执行该语句,就能得到一个结构完全相同的超级表。
|
||||||
|
|
||||||
- **获取超级表的结构信息**
|
- **获取超级表的结构信息**
|
||||||
|
|
||||||
```mysql
|
```mysql
|
||||||
|
@ -407,7 +429,7 @@ SELECT select_expr [, select_expr ...]
|
||||||
[INTERVAL (interval_val [, interval_offset])]
|
[INTERVAL (interval_val [, interval_offset])]
|
||||||
[SLIDING sliding_val]
|
[SLIDING sliding_val]
|
||||||
[FILL fill_val]
|
[FILL fill_val]
|
||||||
[GROUP BY col_list <!-- [HAVING having_condition] -->]
|
[GROUP BY col_list]
|
||||||
[ORDER BY col_list { DESC | ASC }]
|
[ORDER BY col_list { DESC | ASC }]
|
||||||
[SLIMIT limit_val [SOFFSET offset_val]]
|
[SLIMIT limit_val [SOFFSET offset_val]]
|
||||||
[LIMIT limit_val [OFFSET offset_val]]
|
[LIMIT limit_val [OFFSET offset_val]]
|
||||||
|
@ -647,7 +669,7 @@ Query OK, 1 row(s) in set (0.001091s)
|
||||||
3. 从 2.0.17 版本开始,条件过滤开始支持 BETWEEN AND 语法,例如 `WHERE col2 BETWEEN 1.5 AND 3.25` 表示查询条件为“1.5 ≤ col2 ≤ 3.25”。
|
3. 从 2.0.17 版本开始,条件过滤开始支持 BETWEEN AND 语法,例如 `WHERE col2 BETWEEN 1.5 AND 3.25` 表示查询条件为“1.5 ≤ col2 ≤ 3.25”。
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
### GROUP BY 之后的 HAVING 过滤
|
### <a class="anchor" id="having"></a>GROUP BY 之后的 HAVING 过滤
|
||||||
|
|
||||||
从 2.0.20 版本开始,GROUP BY 之后允许再跟一个 HAVING 子句,对成组后的各组数据再做筛选。HAVING 子句可以使用聚合函数和选择函数作为过滤条件(但暂时不支持 LEASTSQUARES、TOP、BOTTOM、LAST_ROW)。
|
从 2.0.20 版本开始,GROUP BY 之后允许再跟一个 HAVING 子句,对成组后的各组数据再做筛选。HAVING 子句可以使用聚合函数和选择函数作为过滤条件(但暂时不支持 LEASTSQUARES、TOP、BOTTOM、LAST_ROW)。
|
||||||
|
|
||||||
|
@ -657,6 +679,16 @@ SELECT AVG(f1), SPREAD(f1, f2, st2.f1) FROM st2 WHERE f1 > 0 GROUP BY f1 HAVING
|
||||||
```
|
```
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
### <a class="anchor" id="union"></a>UNION ALL 操作符
|
||||||
|
|
||||||
|
```mysql
|
||||||
|
SELECT ...
|
||||||
|
UNION ALL SELECT ...
|
||||||
|
[UNION ALL SELECT ...]
|
||||||
|
```
|
||||||
|
|
||||||
|
TDengine 支持 UNION ALL 操作符。也就是说,如果多个 SELECT 子句返回结果集的结构完全相同(列名、列类型、列数、顺序),那么可以通过 UNION ALL 把这些结果集合并到一起。目前只支持 UNION ALL 模式,也即在结果集的合并过程中是不去重的。
|
||||||
|
|
||||||
### SQL 示例
|
### SQL 示例
|
||||||
|
|
||||||
- 对于下面的例子,表tb1用以下语句创建
|
- 对于下面的例子,表tb1用以下语句创建
|
||||||
|
|
|
@ -58,7 +58,12 @@ cp ${compile_dir}/build/lib/${libfile} ${pkg_dir}${install_home_pat
|
||||||
cp ${compile_dir}/../src/inc/taos.h ${pkg_dir}${install_home_path}/include
|
cp ${compile_dir}/../src/inc/taos.h ${pkg_dir}${install_home_path}/include
|
||||||
cp ${compile_dir}/../src/inc/taoserror.h ${pkg_dir}${install_home_path}/include
|
cp ${compile_dir}/../src/inc/taoserror.h ${pkg_dir}${install_home_path}/include
|
||||||
cp -r ${top_dir}/tests/examples/* ${pkg_dir}${install_home_path}/examples
|
cp -r ${top_dir}/tests/examples/* ${pkg_dir}${install_home_path}/examples
|
||||||
cp -r ${top_dir}/src/connector/grafanaplugin ${pkg_dir}${install_home_path}/connector
|
if [ -d "${top_dir}/src/connector/grafanaplugin/dist" ]; then
|
||||||
|
cp -r ${top_dir}/src/connector/grafanaplugin/dist ${pkg_dir}${install_home_path}/connector/grafanaplugin
|
||||||
|
else
|
||||||
|
echo "grafanaplugin bundled directory not found!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
cp -r ${top_dir}/src/connector/python ${pkg_dir}${install_home_path}/connector
|
cp -r ${top_dir}/src/connector/python ${pkg_dir}${install_home_path}/connector
|
||||||
cp -r ${top_dir}/src/connector/go ${pkg_dir}${install_home_path}/connector
|
cp -r ${top_dir}/src/connector/go ${pkg_dir}${install_home_path}/connector
|
||||||
cp -r ${top_dir}/src/connector/nodejs ${pkg_dir}${install_home_path}/connector
|
cp -r ${top_dir}/src/connector/nodejs ${pkg_dir}${install_home_path}/connector
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
#
|
#
|
||||||
# Generate the deb package for ubunt, or rpm package for centos, or tar.gz package for other linux os
|
# Generate the deb package for ubuntu, or rpm package for centos, or tar.gz package for other linux os
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
#set -x
|
#set -x
|
||||||
|
|
||||||
# releash.sh -v [cluster | edge]
|
# release.sh -v [cluster | edge]
|
||||||
# -c [aarch32 | aarch64 | x64 | x86 | mips64 ...]
|
# -c [aarch32 | aarch64 | x64 | x86 | mips64 ...]
|
||||||
# -o [Linux | Kylin | Alpine | Raspberrypi | Darwin | Windows | Ningsi60 | Ningsi80 |...]
|
# -o [Linux | Kylin | Alpine | Raspberrypi | Darwin | Windows | Ningsi60 | Ningsi80 |...]
|
||||||
# -V [stable | beta]
|
# -V [stable | beta]
|
||||||
|
|
|
@ -66,7 +66,12 @@ cp %{_compiledir}/build/bin/taosdump %{buildroot}%{homepath}/bin
|
||||||
cp %{_compiledir}/build/lib/${libfile} %{buildroot}%{homepath}/driver
|
cp %{_compiledir}/build/lib/${libfile} %{buildroot}%{homepath}/driver
|
||||||
cp %{_compiledir}/../src/inc/taos.h %{buildroot}%{homepath}/include
|
cp %{_compiledir}/../src/inc/taos.h %{buildroot}%{homepath}/include
|
||||||
cp %{_compiledir}/../src/inc/taoserror.h %{buildroot}%{homepath}/include
|
cp %{_compiledir}/../src/inc/taoserror.h %{buildroot}%{homepath}/include
|
||||||
cp -r %{_compiledir}/../src/connector/grafanaplugin %{buildroot}%{homepath}/connector
|
if [ -d %{_compiledir}/../src/connector/grafanaplugin/dist ]; then
|
||||||
|
cp -r %{_compiledir}/../src/connector/grafanaplugin/dist %{buildroot}%{homepath}/connector/grafanaplugin
|
||||||
|
else
|
||||||
|
echo grafanaplugin bundled directory not found!
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
cp -r %{_compiledir}/../src/connector/python %{buildroot}%{homepath}/connector
|
cp -r %{_compiledir}/../src/connector/python %{buildroot}%{homepath}/connector
|
||||||
cp -r %{_compiledir}/../src/connector/go %{buildroot}%{homepath}/connector
|
cp -r %{_compiledir}/../src/connector/go %{buildroot}%{homepath}/connector
|
||||||
cp -r %{_compiledir}/../src/connector/nodejs %{buildroot}%{homepath}/connector
|
cp -r %{_compiledir}/../src/connector/nodejs %{buildroot}%{homepath}/connector
|
||||||
|
|
|
@ -607,6 +607,7 @@ function install_service_on_systemd() {
|
||||||
${csudo} bash -c "echo 'Type=simple' >> ${taosd_service_config}"
|
${csudo} bash -c "echo 'Type=simple' >> ${taosd_service_config}"
|
||||||
${csudo} bash -c "echo 'ExecStart=/usr/bin/taosd' >> ${taosd_service_config}"
|
${csudo} bash -c "echo 'ExecStart=/usr/bin/taosd' >> ${taosd_service_config}"
|
||||||
${csudo} bash -c "echo 'ExecStartPre=/usr/local/taos/bin/startPre.sh' >> ${taosd_service_config}"
|
${csudo} bash -c "echo 'ExecStartPre=/usr/local/taos/bin/startPre.sh' >> ${taosd_service_config}"
|
||||||
|
${csudo} bash -c "echo 'TimeoutStopSec=1000000s' >> ${taosd_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${taosd_service_config}"
|
${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${taosd_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${taosd_service_config}"
|
${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${taosd_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitCORE=infinity' >> ${taosd_service_config}"
|
${csudo} bash -c "echo 'LimitCORE=infinity' >> ${taosd_service_config}"
|
||||||
|
@ -630,6 +631,7 @@ function install_service_on_systemd() {
|
||||||
${csudo} bash -c "echo '[Service]' >> ${tarbitratord_service_config}"
|
${csudo} bash -c "echo '[Service]' >> ${tarbitratord_service_config}"
|
||||||
${csudo} bash -c "echo 'Type=simple' >> ${tarbitratord_service_config}"
|
${csudo} bash -c "echo 'Type=simple' >> ${tarbitratord_service_config}"
|
||||||
${csudo} bash -c "echo 'ExecStart=/usr/bin/tarbitrator' >> ${tarbitratord_service_config}"
|
${csudo} bash -c "echo 'ExecStart=/usr/bin/tarbitrator' >> ${tarbitratord_service_config}"
|
||||||
|
${csudo} bash -c "echo 'TimeoutStopSec=1000000s' >> ${tarbitratord_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${tarbitratord_service_config}"
|
${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${tarbitratord_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${tarbitratord_service_config}"
|
${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${tarbitratord_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitCORE=infinity' >> ${tarbitratord_service_config}"
|
${csudo} bash -c "echo 'LimitCORE=infinity' >> ${tarbitratord_service_config}"
|
||||||
|
@ -655,6 +657,7 @@ function install_service_on_systemd() {
|
||||||
${csudo} bash -c "echo 'PIDFile=/usr/local/nginxd/logs/nginx.pid' >> ${nginx_service_config}"
|
${csudo} bash -c "echo 'PIDFile=/usr/local/nginxd/logs/nginx.pid' >> ${nginx_service_config}"
|
||||||
${csudo} bash -c "echo 'ExecStart=/usr/local/nginxd/sbin/nginx' >> ${nginx_service_config}"
|
${csudo} bash -c "echo 'ExecStart=/usr/local/nginxd/sbin/nginx' >> ${nginx_service_config}"
|
||||||
${csudo} bash -c "echo 'ExecStop=/usr/local/nginxd/sbin/nginx -s stop' >> ${nginx_service_config}"
|
${csudo} bash -c "echo 'ExecStop=/usr/local/nginxd/sbin/nginx -s stop' >> ${nginx_service_config}"
|
||||||
|
${csudo} bash -c "echo 'TimeoutStopSec=1000000s' >> ${nginx_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${nginx_service_config}"
|
${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${nginx_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${nginx_service_config}"
|
${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${nginx_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitCORE=infinity' >> ${nginx_service_config}"
|
${csudo} bash -c "echo 'LimitCORE=infinity' >> ${nginx_service_config}"
|
||||||
|
|
|
@ -205,6 +205,7 @@ function install_service_on_systemd() {
|
||||||
${csudo} bash -c "echo '[Service]' >> ${tarbitratord_service_config}"
|
${csudo} bash -c "echo '[Service]' >> ${tarbitratord_service_config}"
|
||||||
${csudo} bash -c "echo 'Type=simple' >> ${tarbitratord_service_config}"
|
${csudo} bash -c "echo 'Type=simple' >> ${tarbitratord_service_config}"
|
||||||
${csudo} bash -c "echo 'ExecStart=/usr/bin/tarbitrator' >> ${tarbitratord_service_config}"
|
${csudo} bash -c "echo 'ExecStart=/usr/bin/tarbitrator' >> ${tarbitratord_service_config}"
|
||||||
|
${csudo} bash -c "echo 'TimeoutStopSec=1000000s' >> ${tarbitratord_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${tarbitratord_service_config}"
|
${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${tarbitratord_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${tarbitratord_service_config}"
|
${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${tarbitratord_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitCORE=infinity' >> ${tarbitratord_service_config}"
|
${csudo} bash -c "echo 'LimitCORE=infinity' >> ${tarbitratord_service_config}"
|
||||||
|
|
|
@ -205,6 +205,7 @@ function install_service_on_systemd() {
|
||||||
${csudo} bash -c "echo '[Service]' >> ${tarbitratord_service_config}"
|
${csudo} bash -c "echo '[Service]' >> ${tarbitratord_service_config}"
|
||||||
${csudo} bash -c "echo 'Type=simple' >> ${tarbitratord_service_config}"
|
${csudo} bash -c "echo 'Type=simple' >> ${tarbitratord_service_config}"
|
||||||
${csudo} bash -c "echo 'ExecStart=/usr/bin/tarbitrator' >> ${tarbitratord_service_config}"
|
${csudo} bash -c "echo 'ExecStart=/usr/bin/tarbitrator' >> ${tarbitratord_service_config}"
|
||||||
|
${csudo} bash -c "echo 'TimeoutStopSec=1000000s' >> ${tarbitratord_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${tarbitratord_service_config}"
|
${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${tarbitratord_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${tarbitratord_service_config}"
|
${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${tarbitratord_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitCORE=infinity' >> ${tarbitratord_service_config}"
|
${csudo} bash -c "echo 'LimitCORE=infinity' >> ${tarbitratord_service_config}"
|
||||||
|
|
|
@ -577,6 +577,7 @@ function install_service_on_systemd() {
|
||||||
${csudo} bash -c "echo 'Type=simple' >> ${powerd_service_config}"
|
${csudo} bash -c "echo 'Type=simple' >> ${powerd_service_config}"
|
||||||
${csudo} bash -c "echo 'ExecStart=/usr/bin/powerd' >> ${powerd_service_config}"
|
${csudo} bash -c "echo 'ExecStart=/usr/bin/powerd' >> ${powerd_service_config}"
|
||||||
${csudo} bash -c "echo 'ExecStartPre=/usr/local/power/bin/startPre.sh' >> ${powerd_service_config}"
|
${csudo} bash -c "echo 'ExecStartPre=/usr/local/power/bin/startPre.sh' >> ${powerd_service_config}"
|
||||||
|
${csudo} bash -c "echo 'TimeoutStopSec=1000000s' >> ${powerd_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${powerd_service_config}"
|
${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${powerd_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${powerd_service_config}"
|
${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${powerd_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitCORE=infinity' >> ${powerd_service_config}"
|
${csudo} bash -c "echo 'LimitCORE=infinity' >> ${powerd_service_config}"
|
||||||
|
@ -599,6 +600,7 @@ function install_service_on_systemd() {
|
||||||
${csudo} bash -c "echo '[Service]' >> ${tarbitratord_service_config}"
|
${csudo} bash -c "echo '[Service]' >> ${tarbitratord_service_config}"
|
||||||
${csudo} bash -c "echo 'Type=simple' >> ${tarbitratord_service_config}"
|
${csudo} bash -c "echo 'Type=simple' >> ${tarbitratord_service_config}"
|
||||||
${csudo} bash -c "echo 'ExecStart=/usr/bin/tarbitrator' >> ${tarbitratord_service_config}"
|
${csudo} bash -c "echo 'ExecStart=/usr/bin/tarbitrator' >> ${tarbitratord_service_config}"
|
||||||
|
${csudo} bash -c "echo 'TimeoutStopSec=1000000s' >> ${tarbitratord_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${tarbitratord_service_config}"
|
${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${tarbitratord_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${tarbitratord_service_config}"
|
${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${tarbitratord_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitCORE=infinity' >> ${tarbitratord_service_config}"
|
${csudo} bash -c "echo 'LimitCORE=infinity' >> ${tarbitratord_service_config}"
|
||||||
|
@ -624,6 +626,7 @@ function install_service_on_systemd() {
|
||||||
${csudo} bash -c "echo 'PIDFile=/usr/local/nginxd/logs/nginx.pid' >> ${nginx_service_config}"
|
${csudo} bash -c "echo 'PIDFile=/usr/local/nginxd/logs/nginx.pid' >> ${nginx_service_config}"
|
||||||
${csudo} bash -c "echo 'ExecStart=/usr/local/nginxd/sbin/nginx' >> ${nginx_service_config}"
|
${csudo} bash -c "echo 'ExecStart=/usr/local/nginxd/sbin/nginx' >> ${nginx_service_config}"
|
||||||
${csudo} bash -c "echo 'ExecStop=/usr/local/nginxd/sbin/nginx -s stop' >> ${nginx_service_config}"
|
${csudo} bash -c "echo 'ExecStop=/usr/local/nginxd/sbin/nginx -s stop' >> ${nginx_service_config}"
|
||||||
|
${csudo} bash -c "echo 'TimeoutStopSec=1000000s' >> ${nginx_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${nginx_service_config}"
|
${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${nginx_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${nginx_service_config}"
|
${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${nginx_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitCORE=infinity' >> ${nginx_service_config}"
|
${csudo} bash -c "echo 'LimitCORE=infinity' >> ${nginx_service_config}"
|
||||||
|
|
|
@ -243,9 +243,17 @@ function install_data() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function install_connector() {
|
function install_connector() {
|
||||||
${csudo} cp -rf ${source_dir}/src/connector/grafanaplugin ${install_main_dir}/connector
|
if [ -d "${source_dir}/src/connector/grafanaplugin/dist" ]; then
|
||||||
|
${csudo} cp -rf ${source_dir}/src/connector/grafanaplugin/dist ${install_main_dir}/connector/grafanaplugin
|
||||||
|
else
|
||||||
|
echo "WARNING: grafanaplugin bundled dir not found, please check if want to use it!"
|
||||||
|
fi
|
||||||
|
if find ${source_dir}/src/connector/go -mindepth 1 -maxdepth 1 | read; then
|
||||||
|
${csudo} cp -r ${source_dir}/src/connector/go ${install_main_dir}/connector
|
||||||
|
else
|
||||||
|
echo "WARNING: go connector not found, please check if want to use it!"
|
||||||
|
fi
|
||||||
${csudo} cp -rf ${source_dir}/src/connector/python ${install_main_dir}/connector
|
${csudo} cp -rf ${source_dir}/src/connector/python ${install_main_dir}/connector
|
||||||
${csudo} cp -rf ${source_dir}/src/connector/go ${install_main_dir}/connector
|
|
||||||
|
|
||||||
${csudo} cp ${binary_dir}/build/lib/*.jar ${install_main_dir}/connector &> /dev/null && ${csudo} chmod 777 ${install_main_dir}/connector/*.jar || echo &> /dev/null
|
${csudo} cp ${binary_dir}/build/lib/*.jar ${install_main_dir}/connector &> /dev/null && ${csudo} chmod 777 ${install_main_dir}/connector/*.jar || echo &> /dev/null
|
||||||
}
|
}
|
||||||
|
@ -333,6 +341,7 @@ function install_service_on_systemd() {
|
||||||
${csudo} bash -c "echo 'Type=simple' >> ${taosd_service_config}"
|
${csudo} bash -c "echo 'Type=simple' >> ${taosd_service_config}"
|
||||||
${csudo} bash -c "echo 'ExecStart=/usr/bin/taosd' >> ${taosd_service_config}"
|
${csudo} bash -c "echo 'ExecStart=/usr/bin/taosd' >> ${taosd_service_config}"
|
||||||
${csudo} bash -c "echo 'ExecStartPre=/usr/local/taos/bin/startPre.sh' >> ${taosd_service_config}"
|
${csudo} bash -c "echo 'ExecStartPre=/usr/local/taos/bin/startPre.sh' >> ${taosd_service_config}"
|
||||||
|
${csudo} bash -c "echo 'TimeoutStopSec=1000000s' >> ${taosd_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${taosd_service_config}"
|
${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${taosd_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${taosd_service_config}"
|
${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${taosd_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitCORE=infinity' >> ${taosd_service_config}"
|
${csudo} bash -c "echo 'LimitCORE=infinity' >> ${taosd_service_config}"
|
||||||
|
|
|
@ -117,9 +117,17 @@ if [[ "$pagMode" != "lite" ]] && [[ "$cpuType" != "aarch32" ]]; then
|
||||||
if [ "$osType" != "Darwin" ]; then
|
if [ "$osType" != "Darwin" ]; then
|
||||||
cp ${build_dir}/lib/*.jar ${install_dir}/connector ||:
|
cp ${build_dir}/lib/*.jar ${install_dir}/connector ||:
|
||||||
fi
|
fi
|
||||||
cp -r ${connector_dir}/grafanaplugin ${install_dir}/connector/
|
if [ -d "${connector_dir}/grafanaplugin/dist" ]; then
|
||||||
cp -r ${connector_dir}/python ${install_dir}/connector/
|
cp -r ${connector_dir}/grafanaplugin/dist ${install_dir}/connector/grafanaplugin
|
||||||
|
else
|
||||||
|
echo "WARNING: grafanaplugin bundled dir not found, please check if want to use it!"
|
||||||
|
fi
|
||||||
|
if find ${connector_dir}/go -mindepth 1 -maxdepth 1 | read; then
|
||||||
cp -r ${connector_dir}/go ${install_dir}/connector
|
cp -r ${connector_dir}/go ${install_dir}/connector
|
||||||
|
else
|
||||||
|
echo "WARNING: go connector not found, please check if want to use it!"
|
||||||
|
fi
|
||||||
|
cp -r ${connector_dir}/python ${install_dir}/connector
|
||||||
cp -r ${connector_dir}/nodejs ${install_dir}/connector
|
cp -r ${connector_dir}/nodejs ${install_dir}/connector
|
||||||
fi
|
fi
|
||||||
# Copy release note
|
# Copy release note
|
||||||
|
|
|
@ -144,24 +144,23 @@ if [[ "$pagMode" != "lite" ]] && [[ "$cpuType" != "aarch32" ]]; then
|
||||||
if [ "$osType" != "Darwin" ]; then
|
if [ "$osType" != "Darwin" ]; then
|
||||||
cp ${build_dir}/lib/*.jar ${install_dir}/connector ||:
|
cp ${build_dir}/lib/*.jar ${install_dir}/connector ||:
|
||||||
fi
|
fi
|
||||||
cp -r ${connector_dir}/grafanaplugin ${install_dir}/connector/
|
if [ -d "${connector_dir}/grafanaplugin/dist" ]; then
|
||||||
cp -r ${connector_dir}/python ${install_dir}/connector/
|
cp -r ${connector_dir}/grafanaplugin/dist ${install_dir}/connector/grafanaplugin
|
||||||
|
else
|
||||||
|
echo "WARNING: grafanaplugin bunlded dir not found, please check if want to use it!"
|
||||||
|
fi
|
||||||
|
if find ${connector_dir}/go -mindepth 1 -maxdepth 1 | read; then
|
||||||
cp -r ${connector_dir}/go ${install_dir}/connector
|
cp -r ${connector_dir}/go ${install_dir}/connector
|
||||||
|
else
|
||||||
|
echo "WARNING: go connector not found, please check if want to use it!"
|
||||||
|
fi
|
||||||
|
cp -r ${connector_dir}/python ${install_dir}/connector
|
||||||
|
|
||||||
sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/linux/python2/taos/cinterface.py
|
sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/taos/cinterface.py
|
||||||
sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/linux/python3/taos/cinterface.py
|
|
||||||
sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/windows/python2/taos/cinterface.py
|
|
||||||
sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/windows/python3/taos/cinterface.py
|
|
||||||
|
|
||||||
sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/linux/python2/taos/subscription.py
|
sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/taos/subscription.py
|
||||||
sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/linux/python3/taos/subscription.py
|
|
||||||
sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/windows/python2/taos/subscription.py
|
|
||||||
sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/windows/python3/taos/subscription.py
|
|
||||||
|
|
||||||
sed -i '/self._password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/linux/python2/taos/connection.py
|
sed -i '/self._password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/taos/connection.py
|
||||||
sed -i '/self._password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/linux/python3/taos/connection.py
|
|
||||||
sed -i '/self._password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/windows/python2/taos/connection.py
|
|
||||||
sed -i '/self._password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/windows/python3/taos/connection.py
|
|
||||||
fi
|
fi
|
||||||
# Copy release note
|
# Copy release note
|
||||||
# cp ${script_dir}/release_note ${install_dir}
|
# cp ${script_dir}/release_note ${install_dir}
|
||||||
|
|
|
@ -131,9 +131,17 @@ connector_dir="${code_dir}/connector"
|
||||||
mkdir -p ${install_dir}/connector
|
mkdir -p ${install_dir}/connector
|
||||||
if [[ "$pagMode" != "lite" ]] && [[ "$cpuType" != "aarch32" ]]; then
|
if [[ "$pagMode" != "lite" ]] && [[ "$cpuType" != "aarch32" ]]; then
|
||||||
cp ${build_dir}/lib/*.jar ${install_dir}/connector ||:
|
cp ${build_dir}/lib/*.jar ${install_dir}/connector ||:
|
||||||
cp -r ${connector_dir}/grafanaplugin ${install_dir}/connector/
|
if [ -d "${connector_dir}/grafanaplugin/dist" ]; then
|
||||||
cp -r ${connector_dir}/python ${install_dir}/connector/
|
cp -r ${connector_dir}/grafanaplugin/dist ${install_dir}/connector/grafanaplugin
|
||||||
|
else
|
||||||
|
echo "WARNING: grafanaplugin bundled dir not found, please check if you want to use it!"
|
||||||
|
fi
|
||||||
|
if find ${connector_dir}/go -mindepth 1 -maxdepth 1 | read; then
|
||||||
cp -r ${connector_dir}/go ${install_dir}/connector
|
cp -r ${connector_dir}/go ${install_dir}/connector
|
||||||
|
else
|
||||||
|
echo "WARNING: go connector not found, please check if want to use it!"
|
||||||
|
fi
|
||||||
|
cp -r ${connector_dir}/python ${install_dir}/connector
|
||||||
cp -r ${connector_dir}/nodejs ${install_dir}/connector
|
cp -r ${connector_dir}/nodejs ${install_dir}/connector
|
||||||
fi
|
fi
|
||||||
# Copy release note
|
# Copy release note
|
||||||
|
|
|
@ -166,24 +166,24 @@ connector_dir="${code_dir}/connector"
|
||||||
mkdir -p ${install_dir}/connector
|
mkdir -p ${install_dir}/connector
|
||||||
if [[ "$pagMode" != "lite" ]] && [[ "$cpuType" != "aarch32" ]]; then
|
if [[ "$pagMode" != "lite" ]] && [[ "$cpuType" != "aarch32" ]]; then
|
||||||
cp ${build_dir}/lib/*.jar ${install_dir}/connector ||:
|
cp ${build_dir}/lib/*.jar ${install_dir}/connector ||:
|
||||||
cp -r ${connector_dir}/grafanaplugin ${install_dir}/connector/
|
|
||||||
cp -r ${connector_dir}/python ${install_dir}/connector/
|
if [ -d "${connector_dir}/grafanaplugin/dist" ]; then
|
||||||
|
cp -r ${connector_dir}/grafanaplugin/dist ${install_dir}/connector/grafanaplugin
|
||||||
|
else
|
||||||
|
echo "WARNING: grafanaplugin bundled dir not found, please check if want to use it!"
|
||||||
|
fi
|
||||||
|
if find ${connector_dir}/go -mindepth 1 -maxdepth 1 | read; then
|
||||||
cp -r ${connector_dir}/go ${install_dir}/connector
|
cp -r ${connector_dir}/go ${install_dir}/connector
|
||||||
|
else
|
||||||
|
echo "WARNING: go connector not found, please check if want to use it!"
|
||||||
|
fi
|
||||||
|
cp -r ${connector_dir}/python ${install_dir}/connector/
|
||||||
|
|
||||||
sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/linux/python2/taos/cinterface.py
|
sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/taos/cinterface.py
|
||||||
sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/linux/python3/taos/cinterface.py
|
|
||||||
sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/windows/python2/taos/cinterface.py
|
|
||||||
sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/windows/python3/taos/cinterface.py
|
|
||||||
|
|
||||||
sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/linux/python2/taos/subscription.py
|
sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/taos/subscription.py
|
||||||
sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/linux/python3/taos/subscription.py
|
|
||||||
sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/windows/python2/taos/subscription.py
|
|
||||||
sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/windows/python3/taos/subscription.py
|
|
||||||
|
|
||||||
sed -i '/self._password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/linux/python2/taos/connection.py
|
sed -i '/self._password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/taos/connection.py
|
||||||
sed -i '/self._password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/linux/python3/taos/connection.py
|
|
||||||
sed -i '/self._password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/windows/python2/taos/connection.py
|
|
||||||
sed -i '/self._password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/windows/python3/taos/connection.py
|
|
||||||
fi
|
fi
|
||||||
# Copy release note
|
# Copy release note
|
||||||
# cp ${script_dir}/release_note ${install_dir}
|
# cp ${script_dir}/release_note ${install_dir}
|
||||||
|
|
|
@ -405,6 +405,7 @@ function install_service_on_systemd() {
|
||||||
${csudo} bash -c "echo 'Type=simple' >> ${taosd_service_config}"
|
${csudo} bash -c "echo 'Type=simple' >> ${taosd_service_config}"
|
||||||
${csudo} bash -c "echo 'ExecStart=/usr/bin/taosd' >> ${taosd_service_config}"
|
${csudo} bash -c "echo 'ExecStart=/usr/bin/taosd' >> ${taosd_service_config}"
|
||||||
${csudo} bash -c "echo 'ExecStartPre=/usr/local/taos/bin/startPre.sh' >> ${taosd_service_config}"
|
${csudo} bash -c "echo 'ExecStartPre=/usr/local/taos/bin/startPre.sh' >> ${taosd_service_config}"
|
||||||
|
${csudo} bash -c "echo 'TimeoutStopSec=1000000s' >> ${taosd_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${taosd_service_config}"
|
${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${taosd_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${taosd_service_config}"
|
${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${taosd_service_config}"
|
||||||
${csudo} bash -c "echo 'LimitCORE=infinity' >> ${taosd_service_config}"
|
${csudo} bash -c "echo 'LimitCORE=infinity' >> ${taosd_service_config}"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
name: tdengine
|
name: tdengine
|
||||||
base: core18
|
base: core18
|
||||||
version: '2.0.20.0'
|
|
||||||
|
version: '2.1.0.0'
|
||||||
icon: snap/gui/t-dengine.svg
|
icon: snap/gui/t-dengine.svg
|
||||||
summary: an open-source big data platform designed and optimized for IoT.
|
summary: an open-source big data platform designed and optimized for IoT.
|
||||||
description: |
|
description: |
|
||||||
|
@ -72,7 +73,7 @@ parts:
|
||||||
- usr/bin/taosd
|
- usr/bin/taosd
|
||||||
- usr/bin/taos
|
- usr/bin/taos
|
||||||
- usr/bin/taosdemo
|
- usr/bin/taosdemo
|
||||||
- usr/lib/libtaos.so.2.0.20.0
|
- usr/lib/libtaos.so.2.1.0.0
|
||||||
- usr/lib/libtaos.so.1
|
- usr/lib/libtaos.so.1
|
||||||
- usr/lib/libtaos.so
|
- usr/lib/libtaos.so
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,8 @@ void tscLockByThread(int64_t *lockedBy);
|
||||||
|
|
||||||
void tscUnlockByThread(int64_t *lockedBy);
|
void tscUnlockByThread(int64_t *lockedBy);
|
||||||
|
|
||||||
|
int tsInsertInitialCheck(SSqlObj *pSql);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <tsched.h>
|
#include "tsched.h"
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "qExtbuffer.h"
|
#include "qExtbuffer.h"
|
||||||
|
@ -170,9 +170,12 @@ void tscFieldInfoCopy(SFieldInfo* pFieldInfo, const SFieldInfo* pSrc, const SArr
|
||||||
|
|
||||||
static FORCE_INLINE int32_t tscNumOfFields(SQueryInfo* pQueryInfo) { return pQueryInfo->fieldsInfo.numOfOutput; }
|
static FORCE_INLINE int32_t tscNumOfFields(SQueryInfo* pQueryInfo) { return pQueryInfo->fieldsInfo.numOfOutput; }
|
||||||
|
|
||||||
int32_t tscFieldInfoCompare(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2);
|
int32_t tscFieldInfoCompare(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2, int32_t *diffSize);
|
||||||
void tscInsertPrimaryTsSourceColumn(SQueryInfo* pQueryInfo, uint64_t uid);
|
void tscInsertPrimaryTsSourceColumn(SQueryInfo* pQueryInfo, uint64_t uid);
|
||||||
|
|
||||||
|
int32_t tscFieldInfoSetSize(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2);
|
||||||
|
void addExprParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes);
|
||||||
|
|
||||||
int32_t tscGetResRowLength(SArray* pExprList);
|
int32_t tscGetResRowLength(SArray* pExprList);
|
||||||
|
|
||||||
SExprInfo* tscExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, SColumnIndex* pColIndex, int16_t type,
|
SExprInfo* tscExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, SColumnIndex* pColIndex, int16_t type,
|
||||||
|
@ -316,7 +319,7 @@ STableMeta* createSuperTableMeta(STableMetaMsg* pChild);
|
||||||
uint32_t tscGetTableMetaSize(STableMeta* pTableMeta);
|
uint32_t tscGetTableMetaSize(STableMeta* pTableMeta);
|
||||||
CChildTableMeta* tscCreateChildMeta(STableMeta* pTableMeta);
|
CChildTableMeta* tscCreateChildMeta(STableMeta* pTableMeta);
|
||||||
uint32_t tscGetTableMetaMaxSize();
|
uint32_t tscGetTableMetaMaxSize();
|
||||||
int32_t tscCreateTableMetaFromCChildMeta(STableMeta* pChild, const char* name);
|
int32_t tscCreateTableMetaFromCChildMeta(STableMeta* pChild, const char* name, void* buf);
|
||||||
STableMeta* tscTableMetaDup(STableMeta* pTableMeta);
|
STableMeta* tscTableMetaDup(STableMeta* pTableMeta);
|
||||||
int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAttr, void* addr);
|
int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAttr, void* addr);
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,8 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
#include "tstoken.h"
|
|
||||||
#include "tsclient.h"
|
#include "tsclient.h"
|
||||||
|
#include "ttoken.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get the number of tags of this table
|
* get the number of tags of this table
|
||||||
|
|
|
@ -84,6 +84,7 @@ typedef struct STableMeta {
|
||||||
|
|
||||||
typedef struct STableMetaInfo {
|
typedef struct STableMetaInfo {
|
||||||
STableMeta *pTableMeta; // table meta, cached in client side and acquired by name
|
STableMeta *pTableMeta; // table meta, cached in client side and acquired by name
|
||||||
|
uint32_t tableMetaSize;
|
||||||
SVgroupsInfo *vgroupList;
|
SVgroupsInfo *vgroupList;
|
||||||
SArray *pVgroupTables; // SArray<SVgroupTableInfo>
|
SArray *pVgroupTables; // SArray<SVgroupTableInfo>
|
||||||
|
|
||||||
|
@ -154,13 +155,12 @@ typedef struct STagCond {
|
||||||
|
|
||||||
typedef struct SParamInfo {
|
typedef struct SParamInfo {
|
||||||
int32_t idx;
|
int32_t idx;
|
||||||
char type;
|
uint8_t type;
|
||||||
uint8_t timePrec;
|
uint8_t timePrec;
|
||||||
int16_t bytes;
|
int16_t bytes;
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
} SParamInfo;
|
} SParamInfo;
|
||||||
|
|
||||||
|
|
||||||
typedef struct SBoundColumn {
|
typedef struct SBoundColumn {
|
||||||
bool hasVal; // denote if current column has bound or not
|
bool hasVal; // denote if current column has bound or not
|
||||||
int32_t offset; // all column offset value
|
int32_t offset; // all column offset value
|
||||||
|
@ -386,6 +386,7 @@ typedef struct SSqlObj {
|
||||||
tsem_t rspSem;
|
tsem_t rspSem;
|
||||||
SSqlCmd cmd;
|
SSqlCmd cmd;
|
||||||
SSqlRes res;
|
SSqlRes res;
|
||||||
|
bool isBind;
|
||||||
|
|
||||||
SSubqueryState subState;
|
SSubqueryState subState;
|
||||||
struct SSqlObj **pSubs;
|
struct SSqlObj **pSubs;
|
||||||
|
|
|
@ -100,7 +100,7 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getResultSetImp
|
||||||
/*
|
/*
|
||||||
* Class: com_taosdata_jdbc_TSDBJNIConnector
|
* Class: com_taosdata_jdbc_TSDBJNIConnector
|
||||||
* Method: isUpdateQueryImp
|
* Method: isUpdateQueryImp
|
||||||
* Signature: (J)J
|
* Signature: (JJ)I
|
||||||
*/
|
*/
|
||||||
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_isUpdateQueryImp
|
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_isUpdateQueryImp
|
||||||
(JNIEnv *env, jobject jobj, jlong con, jlong tres);
|
(JNIEnv *env, jobject jobj, jlong con, jlong tres);
|
||||||
|
@ -185,6 +185,44 @@ JNIEXPORT void JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_unsubscribeImp
|
||||||
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_validateCreateTableSqlImp
|
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_validateCreateTableSqlImp
|
||||||
(JNIEnv *, jobject, jlong, jbyteArray);
|
(JNIEnv *, jobject, jlong, jbyteArray);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: com_taosdata_jdbc_TSDBJNIConnector
|
||||||
|
* Method: prepareStmtImp
|
||||||
|
* Signature: ([BJ)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_prepareStmtImp
|
||||||
|
(JNIEnv *, jobject, jbyteArray, jlong);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: com_taosdata_jdbc_TSDBJNIConnector
|
||||||
|
* Method: setBindTableNameImp
|
||||||
|
* Signature: (JLjava/lang/String;J)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setBindTableNameImp
|
||||||
|
(JNIEnv *, jobject, jlong, jstring, jlong);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: com_taosdata_jdbc_TSDBJNIConnector
|
||||||
|
* Method: bindColDataImp
|
||||||
|
* Signature: (J[B[B[BIIIIJ)J
|
||||||
|
*/
|
||||||
|
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp
|
||||||
|
(JNIEnv *, jobject, jlong, jbyteArray, jbyteArray, jbyteArray, jint, jint, jint, jint, jlong);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: com_taosdata_jdbc_TSDBJNIConnector
|
||||||
|
* Method: executeBatchImp
|
||||||
|
* Signature: (JJ)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_executeBatchImp(JNIEnv *env, jobject jobj, jlong stmt, jlong con);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: com_taosdata_jdbc_TSDBJNIConnector
|
||||||
|
* Method: executeBatchImp
|
||||||
|
* Signature: (JJ)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_closeStmt(JNIEnv *env, jobject jobj, jlong stmt, jlong con);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -688,3 +688,193 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TDDBJNIConnector_getResultTimePrec
|
||||||
|
|
||||||
return taos_result_precision(result);
|
return taos_result_precision(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_prepareStmtImp(JNIEnv *env, jobject jobj, jbyteArray jsql, jlong con) {
|
||||||
|
TAOS *tscon = (TAOS *)con;
|
||||||
|
if (tscon == NULL) {
|
||||||
|
jniError("jobj:%p, connection already closed", jobj);
|
||||||
|
return JNI_CONNECTION_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jsql == NULL) {
|
||||||
|
jniError("jobj:%p, conn:%p, empty sql string", jobj, tscon);
|
||||||
|
return JNI_SQL_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
jsize len = (*env)->GetArrayLength(env, jsql);
|
||||||
|
|
||||||
|
char *str = (char *) calloc(1, sizeof(char) * (len + 1));
|
||||||
|
if (str == NULL) {
|
||||||
|
jniError("jobj:%p, conn:%p, alloc memory failed", jobj, tscon);
|
||||||
|
return JNI_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*env)->GetByteArrayRegion(env, jsql, 0, len, (jbyte *)str);
|
||||||
|
if ((*env)->ExceptionCheck(env)) {
|
||||||
|
// todo handle error
|
||||||
|
}
|
||||||
|
|
||||||
|
TAOS_STMT* pStmt = taos_stmt_init(tscon);
|
||||||
|
int32_t code = taos_stmt_prepare(pStmt, str, len);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
jniError("jobj:%p, conn:%p, code:%s", jobj, tscon, tstrerror(code));
|
||||||
|
return JNI_TDENGINE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(str);
|
||||||
|
return (jlong) pStmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setBindTableNameImp(JNIEnv *env, jobject jobj, jlong stmt, jstring jname, jlong conn) {
|
||||||
|
TAOS *tsconn = (TAOS *)conn;
|
||||||
|
if (tsconn == NULL) {
|
||||||
|
jniError("jobj:%p, connection already closed", jobj);
|
||||||
|
return JNI_CONNECTION_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
TAOS_STMT* pStmt = (TAOS_STMT*) stmt;
|
||||||
|
if (pStmt == NULL) {
|
||||||
|
jniError("jobj:%p, conn:%p, invalid stmt handle", jobj, tsconn);
|
||||||
|
return JNI_SQL_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *name = (*env)->GetStringUTFChars(env, jname, NULL);
|
||||||
|
|
||||||
|
int32_t code = taos_stmt_set_tbname((void*)stmt, name);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
(*env)->ReleaseStringUTFChars(env, jname, name);
|
||||||
|
|
||||||
|
jniError("jobj:%p, conn:%p, code:%s", jobj, tsconn, tstrerror(code));
|
||||||
|
return JNI_TDENGINE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
jniDebug("jobj:%p, conn:%p, set stmt bind table name:%s", jobj, tsconn, name);
|
||||||
|
|
||||||
|
(*env)->ReleaseStringUTFChars(env, jname, name);
|
||||||
|
return JNI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(JNIEnv *env, jobject jobj, jlong stmt,
|
||||||
|
jbyteArray colDataList, jbyteArray lengthList, jbyteArray nullList, jint dataType, jint dataBytes, jint numOfRows, jint colIndex, jlong con) {
|
||||||
|
TAOS *tscon = (TAOS *)con;
|
||||||
|
if (tscon == NULL) {
|
||||||
|
jniError("jobj:%p, connection already closed", jobj);
|
||||||
|
return JNI_CONNECTION_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
TAOS_STMT* pStmt = (TAOS_STMT*) stmt;
|
||||||
|
if (pStmt == NULL) {
|
||||||
|
jniError("jobj:%p, conn:%p, invalid stmt", jobj, tscon);
|
||||||
|
return JNI_SQL_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo refactor
|
||||||
|
jsize len = (*env)->GetArrayLength(env, colDataList);
|
||||||
|
char *colBuf = (char *)calloc(1, len);
|
||||||
|
(*env)->GetByteArrayRegion(env, colDataList, 0, len, (jbyte *)colBuf);
|
||||||
|
if ((*env)->ExceptionCheck(env)) {
|
||||||
|
// todo handle error
|
||||||
|
}
|
||||||
|
|
||||||
|
len = (*env)->GetArrayLength(env, lengthList);
|
||||||
|
char *lengthArray = (char*) calloc(1, len);
|
||||||
|
(*env)->GetByteArrayRegion(env, lengthList, 0, len, (jbyte*) lengthArray);
|
||||||
|
if ((*env)->ExceptionCheck(env)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
len = (*env)->GetArrayLength(env, nullList);
|
||||||
|
char *nullArray = (char*) calloc(1, len);
|
||||||
|
(*env)->GetByteArrayRegion(env, nullList, 0, len, (jbyte*) nullArray);
|
||||||
|
if ((*env)->ExceptionCheck(env)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// bind multi-rows with only one invoke.
|
||||||
|
TAOS_MULTI_BIND* b = calloc(1, sizeof(TAOS_MULTI_BIND));
|
||||||
|
|
||||||
|
b->num = numOfRows;
|
||||||
|
b->buffer_type = dataType; // todo check data type
|
||||||
|
b->buffer_length = IS_VAR_DATA_TYPE(dataType)? dataBytes:tDataTypes[dataType].bytes;
|
||||||
|
b->is_null = nullArray;
|
||||||
|
b->buffer = colBuf;
|
||||||
|
b->length = (int32_t*)lengthArray;
|
||||||
|
|
||||||
|
// set the length and is_null array
|
||||||
|
switch(dataType) {
|
||||||
|
case TSDB_DATA_TYPE_INT:
|
||||||
|
case TSDB_DATA_TYPE_TINYINT:
|
||||||
|
case TSDB_DATA_TYPE_SMALLINT:
|
||||||
|
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||||
|
case TSDB_DATA_TYPE_BIGINT: {
|
||||||
|
int32_t bytes = tDataTypes[dataType].bytes;
|
||||||
|
for(int32_t i = 0; i < numOfRows; ++i) {
|
||||||
|
b->length[i] = bytes;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_NCHAR:
|
||||||
|
case TSDB_DATA_TYPE_BINARY: {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t code = taos_stmt_bind_single_param_batch(pStmt, b, colIndex);
|
||||||
|
tfree(b->length);
|
||||||
|
tfree(b->buffer);
|
||||||
|
tfree(b->is_null);
|
||||||
|
tfree(b);
|
||||||
|
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
jniError("jobj:%p, conn:%p, code:%s", jobj, tscon, tstrerror(code));
|
||||||
|
return JNI_TDENGINE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return JNI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_executeBatchImp(JNIEnv *env, jobject jobj, jlong stmt, jlong con) {
|
||||||
|
TAOS *tscon = (TAOS *)con;
|
||||||
|
if (tscon == NULL) {
|
||||||
|
jniError("jobj:%p, connection already closed", jobj);
|
||||||
|
return JNI_CONNECTION_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
TAOS_STMT *pStmt = (TAOS_STMT*) stmt;
|
||||||
|
if (pStmt == NULL) {
|
||||||
|
jniError("jobj:%p, conn:%p, invalid stmt", jobj, tscon);
|
||||||
|
return JNI_SQL_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
taos_stmt_add_batch(pStmt);
|
||||||
|
int32_t code = taos_stmt_execute(pStmt);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
jniError("jobj:%p, conn:%p, code:%s", jobj, tscon, tstrerror(code));
|
||||||
|
return JNI_TDENGINE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
jniDebug("jobj:%p, conn:%p, batch execute", jobj, tscon);
|
||||||
|
return JNI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_closeStmt(JNIEnv *env, jobject jobj, jlong stmt, jlong con) {
|
||||||
|
TAOS *tscon = (TAOS *)con;
|
||||||
|
if (tscon == NULL) {
|
||||||
|
jniError("jobj:%p, connection already closed", jobj);
|
||||||
|
return JNI_CONNECTION_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
TAOS_STMT *pStmt = (TAOS_STMT*) stmt;
|
||||||
|
if (pStmt == NULL) {
|
||||||
|
jniError("jobj:%p, conn:%p, invalid stmt", jobj, tscon);
|
||||||
|
return JNI_SQL_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t code = taos_stmt_close(pStmt);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
jniError("jobj:%p, conn:%p, code:%s", jobj, tscon, tstrerror(code));
|
||||||
|
return JNI_TDENGINE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
jniDebug("jobj:%p, conn:%p, stmt closed", jobj, tscon);
|
||||||
|
return JNI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
|
@ -326,6 +326,7 @@ TAOS_ROW tscFetchRow(void *param) {
|
||||||
pCmd->command == TSDB_SQL_FETCH ||
|
pCmd->command == TSDB_SQL_FETCH ||
|
||||||
pCmd->command == TSDB_SQL_SHOW ||
|
pCmd->command == TSDB_SQL_SHOW ||
|
||||||
pCmd->command == TSDB_SQL_SHOW_CREATE_TABLE ||
|
pCmd->command == TSDB_SQL_SHOW_CREATE_TABLE ||
|
||||||
|
pCmd->command == TSDB_SQL_SHOW_CREATE_STABLE ||
|
||||||
pCmd->command == TSDB_SQL_SHOW_CREATE_DATABASE ||
|
pCmd->command == TSDB_SQL_SHOW_CREATE_DATABASE ||
|
||||||
pCmd->command == TSDB_SQL_SELECT ||
|
pCmd->command == TSDB_SQL_SELECT ||
|
||||||
pCmd->command == TSDB_SQL_DESCRIBE_TABLE ||
|
pCmd->command == TSDB_SQL_DESCRIBE_TABLE ||
|
||||||
|
@ -679,6 +680,9 @@ static int32_t tscProcessShowCreateTable(SSqlObj *pSql) {
|
||||||
assert(pTableMetaInfo->pTableMeta != NULL);
|
assert(pTableMetaInfo->pTableMeta != NULL);
|
||||||
|
|
||||||
const char* tableName = tNameGetTableName(&pTableMetaInfo->name);
|
const char* tableName = tNameGetTableName(&pTableMetaInfo->name);
|
||||||
|
if (pSql->cmd.command == TSDB_SQL_SHOW_CREATE_STABLE && !UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
||||||
|
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
char *result = (char *)calloc(1, TSDB_MAX_BINARY_LEN);
|
char *result = (char *)calloc(1, TSDB_MAX_BINARY_LEN);
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
@ -709,13 +713,12 @@ static int32_t tscProcessShowCreateDatabase(SSqlObj *pSql) {
|
||||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
SCreateBuilder *param = (SCreateBuilder *)malloc(sizeof(SCreateBuilder));
|
SCreateBuilder *param = (SCreateBuilder *)calloc(1, sizeof(SCreateBuilder));
|
||||||
if (param == NULL) {
|
if (param == NULL) {
|
||||||
free(pInterSql);
|
free(pInterSql);
|
||||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
tNameGetDbName(&pTableMetaInfo->name, param->buf);
|
||||||
strncpy(param->buf, tNameGetTableName(&pTableMetaInfo->name), TSDB_TABLE_NAME_LEN);
|
|
||||||
|
|
||||||
param->pParentSql = pSql;
|
param->pParentSql = pSql;
|
||||||
param->pInterSql = pInterSql;
|
param->pInterSql = pInterSql;
|
||||||
|
@ -907,7 +910,7 @@ int tscProcessLocalCmd(SSqlObj *pSql) {
|
||||||
*/
|
*/
|
||||||
pRes->qId = 0x1;
|
pRes->qId = 0x1;
|
||||||
pRes->numOfRows = 0;
|
pRes->numOfRows = 0;
|
||||||
} else if (pCmd->command == TSDB_SQL_SHOW_CREATE_TABLE) {
|
} else if (pCmd->command == TSDB_SQL_SHOW_CREATE_TABLE || pCmd->command == TSDB_SQL_SHOW_CREATE_STABLE) {
|
||||||
pRes->code = tscProcessShowCreateTable(pSql);
|
pRes->code = tscProcessShowCreateTable(pSql);
|
||||||
} else if (pCmd->command == TSDB_SQL_SHOW_CREATE_DATABASE) {
|
} else if (pCmd->command == TSDB_SQL_SHOW_CREATE_DATABASE) {
|
||||||
pRes->code = tscProcessShowCreateDatabase(pSql);
|
pRes->code = tscProcessShowCreateDatabase(pSql);
|
||||||
|
|
|
@ -29,8 +29,7 @@
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
|
|
||||||
#include "tscLog.h"
|
#include "tscLog.h"
|
||||||
#include "tscSubquery.h"
|
#include "ttoken.h"
|
||||||
#include "tstoken.h"
|
|
||||||
|
|
||||||
#include "tdataformat.h"
|
#include "tdataformat.h"
|
||||||
|
|
||||||
|
@ -68,7 +67,7 @@ int tsParseTime(SStrToken *pToken, int64_t *time, char **next, char *error, int1
|
||||||
} else if (strncmp(pToken->z, "0", 1) == 0 && pToken->n == 1) {
|
} else if (strncmp(pToken->z, "0", 1) == 0 && pToken->n == 1) {
|
||||||
// do nothing
|
// do nothing
|
||||||
} else if (pToken->type == TK_INTEGER) {
|
} else if (pToken->type == TK_INTEGER) {
|
||||||
useconds = tsosStr2int64(pToken->z);
|
useconds = taosStr2int64(pToken->z);
|
||||||
} else {
|
} else {
|
||||||
// strptime("2001-11-12 18:31:01", "%Y-%m-%d %H:%M:%S", &tm);
|
// strptime("2001-11-12 18:31:01", "%Y-%m-%d %H:%M:%S", &tm);
|
||||||
if (taosParseTime(pToken->z, time, pToken->n, timePrec, tsDaylight) != TSDB_CODE_SUCCESS) {
|
if (taosParseTime(pToken->z, time, pToken->n, timePrec, tsDaylight) != TSDB_CODE_SUCCESS) {
|
||||||
|
@ -386,7 +385,7 @@ int32_t tsParseOneColumn(SSchema *pSchema, SStrToken *pToken, char *payload, cha
|
||||||
* The server time/client time should not be mixed up in one sql string
|
* The server time/client time should not be mixed up in one sql string
|
||||||
* Do not employ sort operation is not involved if server time is used.
|
* Do not employ sort operation is not involved if server time is used.
|
||||||
*/
|
*/
|
||||||
static int32_t tsCheckTimestamp(STableDataBlocks *pDataBlocks, const char *start) {
|
int32_t tsCheckTimestamp(STableDataBlocks *pDataBlocks, const char *start) {
|
||||||
// once the data block is disordered, we do NOT keep previous timestamp any more
|
// once the data block is disordered, we do NOT keep previous timestamp any more
|
||||||
if (!pDataBlocks->ordered) {
|
if (!pDataBlocks->ordered) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -411,6 +410,7 @@ static int32_t tsCheckTimestamp(STableDataBlocks *pDataBlocks, const char *start
|
||||||
|
|
||||||
if (k <= pDataBlocks->prevTS && (pDataBlocks->tsSource == TSDB_USE_CLI_TS)) {
|
if (k <= pDataBlocks->prevTS && (pDataBlocks->tsSource == TSDB_USE_CLI_TS)) {
|
||||||
pDataBlocks->ordered = false;
|
pDataBlocks->ordered = false;
|
||||||
|
tscWarn("NOT ordered input timestamp");
|
||||||
}
|
}
|
||||||
|
|
||||||
pDataBlocks->prevTS = k;
|
pDataBlocks->prevTS = k;
|
||||||
|
@ -464,22 +464,23 @@ int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, SSqlCmd *pCmd, int1
|
||||||
if (TK_STRING == sToken.type) {
|
if (TK_STRING == sToken.type) {
|
||||||
// delete escape character: \\, \', \"
|
// delete escape character: \\, \', \"
|
||||||
char delim = sToken.z[0];
|
char delim = sToken.z[0];
|
||||||
|
|
||||||
int32_t cnt = 0;
|
int32_t cnt = 0;
|
||||||
int32_t j = 0;
|
int32_t j = 0;
|
||||||
for (uint32_t k = 1; k < sToken.n - 1; ++k) {
|
for (uint32_t k = 1; k < sToken.n - 1; ++k) {
|
||||||
if (sToken.z[k] == delim || sToken.z[k] == '\\') {
|
if (sToken.z[k] == '\\' || (sToken.z[k] == delim && sToken.z[k + 1] == delim)) {
|
||||||
if (sToken.z[k + 1] == delim) {
|
|
||||||
cnt++;
|
|
||||||
tmpTokenBuf[j] = sToken.z[k + 1];
|
tmpTokenBuf[j] = sToken.z[k + 1];
|
||||||
|
|
||||||
|
cnt++;
|
||||||
j++;
|
j++;
|
||||||
k++;
|
k++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
tmpTokenBuf[j] = sToken.z[k];
|
tmpTokenBuf[j] = sToken.z[k];
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpTokenBuf[j] = 0;
|
tmpTokenBuf[j] = 0;
|
||||||
sToken.z = tmpTokenBuf;
|
sToken.z = tmpTokenBuf;
|
||||||
sToken.n -= 2 + cnt;
|
sToken.n -= 2 + cnt;
|
||||||
|
@ -576,13 +577,14 @@ int32_t tsParseValues(char **str, STableDataBlocks *pDataBlock, int maxRows, SSq
|
||||||
|
|
||||||
index = 0;
|
index = 0;
|
||||||
sToken = tStrGetToken(*str, &index, false);
|
sToken = tStrGetToken(*str, &index, false);
|
||||||
*str += index;
|
|
||||||
if (sToken.n == 0 || sToken.type != TK_RP) {
|
if (sToken.n == 0 || sToken.type != TK_RP) {
|
||||||
tscSQLSyntaxErrMsg(pCmd->payload, ") expected", *str);
|
tscSQLSyntaxErrMsg(pCmd->payload, ") expected", *str);
|
||||||
code = TSDB_CODE_TSC_SQL_SYNTAX_ERROR;
|
code = TSDB_CODE_TSC_SQL_SYNTAX_ERROR;
|
||||||
return -1;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*str += index;
|
||||||
|
|
||||||
(*numOfRows)++;
|
(*numOfRows)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -693,6 +695,8 @@ void tscSortRemoveDataBlockDupRows(STableDataBlocks *dataBuf) {
|
||||||
pBlocks->numOfRows = i + 1;
|
pBlocks->numOfRows = i + 1;
|
||||||
dataBuf->size = sizeof(SSubmitBlk) + dataBuf->rowSize * pBlocks->numOfRows;
|
dataBuf->size = sizeof(SSubmitBlk) + dataBuf->rowSize * pBlocks->numOfRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dataBuf->prevTS = INT64_MIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t doParseInsertStatement(SSqlCmd* pCmd, char **str, STableDataBlocks* dataBuf, int32_t *totalNum) {
|
static int32_t doParseInsertStatement(SSqlCmd* pCmd, char **str, STableDataBlocks* dataBuf, int32_t *totalNum) {
|
||||||
|
@ -705,15 +709,10 @@ static int32_t doParseInsertStatement(SSqlCmd* pCmd, char **str, STableDataBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
code = TSDB_CODE_TSC_INVALID_SQL;
|
code = TSDB_CODE_TSC_INVALID_SQL;
|
||||||
char *tmpTokenBuf = calloc(1, 16*1024); // used for deleting Escape character: \\, \', \"
|
char tmpTokenBuf[16*1024] = {0}; // used for deleting Escape character: \\, \', \"
|
||||||
if (NULL == tmpTokenBuf) {
|
|
||||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t numOfRows = 0;
|
int32_t numOfRows = 0;
|
||||||
code = tsParseValues(str, dataBuf, maxNumOfRows, pCmd, &numOfRows, tmpTokenBuf);
|
code = tsParseValues(str, dataBuf, maxNumOfRows, pCmd, &numOfRows, tmpTokenBuf);
|
||||||
|
|
||||||
free(tmpTokenBuf);
|
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -934,6 +933,42 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC
|
||||||
return tscSQLSyntaxErrMsg(pCmd->payload, ") expected", sToken.z);
|
return tscSQLSyntaxErrMsg(pCmd->payload, ") expected", sToken.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* parse columns after super table tags values.
|
||||||
|
* insert into table_name using super_table(tag_name1, tag_name2) tags(tag_val1, tag_val2)
|
||||||
|
* (normal_col1, normal_col2) values(normal_col1_val, normal_col2_val);
|
||||||
|
* */
|
||||||
|
index = 0;
|
||||||
|
sToken = tStrGetToken(sql, &index, false);
|
||||||
|
sql += index;
|
||||||
|
int numOfColsAfterTags = 0;
|
||||||
|
if (sToken.type == TK_LP) {
|
||||||
|
if (*boundColumn != NULL) {
|
||||||
|
return tscSQLSyntaxErrMsg(pCmd->payload, "bind columns again", sToken.z);
|
||||||
|
} else {
|
||||||
|
*boundColumn = &sToken.z[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
index = 0;
|
||||||
|
sToken = tStrGetToken(sql, &index, false);
|
||||||
|
|
||||||
|
if (sToken.type == TK_RP) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sql += index;
|
||||||
|
++numOfColsAfterTags;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numOfColsAfterTags == 0 && (*boundColumn) != NULL) {
|
||||||
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
|
}
|
||||||
|
|
||||||
|
sToken = tStrGetToken(sql, &index, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = sToken.z;
|
||||||
|
|
||||||
if (tscValidateName(&tableToken) != TSDB_CODE_SUCCESS) {
|
if (tscValidateName(&tableToken) != TSDB_CODE_SUCCESS) {
|
||||||
return tscInvalidSQLErrMsg(pCmd->payload, "invalid table name", *sqlstr);
|
return tscInvalidSQLErrMsg(pCmd->payload, "invalid table name", *sqlstr);
|
||||||
}
|
}
|
||||||
|
@ -975,7 +1010,7 @@ int validateTableName(char *tblName, int len, SStrToken* psTblToken) {
|
||||||
|
|
||||||
psTblToken->n = len;
|
psTblToken->n = len;
|
||||||
psTblToken->type = TK_ID;
|
psTblToken->type = TK_ID;
|
||||||
tSQLGetToken(psTblToken->z, &psTblToken->type);
|
tGetToken(psTblToken->z, &psTblToken->type);
|
||||||
|
|
||||||
return tscValidateName(psTblToken);
|
return tscValidateName(psTblToken);
|
||||||
}
|
}
|
||||||
|
@ -1262,7 +1297,7 @@ int tsParseInsertSql(SSqlObj *pSql) {
|
||||||
goto _clean;
|
goto _clean;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (taosHashGetSize(pCmd->pTableBlockHashList) > 0) { // merge according to vgId
|
if ((pCmd->insertType != TSDB_QUERY_TYPE_STMT_INSERT) && taosHashGetSize(pCmd->pTableBlockHashList) > 0) { // merge according to vgId
|
||||||
if ((code = tscMergeTableDataBlocks(pSql, true)) != TSDB_CODE_SUCCESS) {
|
if ((code = tscMergeTableDataBlocks(pSql, true)) != TSDB_CODE_SUCCESS) {
|
||||||
goto _clean;
|
goto _clean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "tscSubquery.h"
|
#include "tscSubquery.h"
|
||||||
|
|
||||||
int tsParseInsertSql(SSqlObj *pSql);
|
int tsParseInsertSql(SSqlObj *pSql);
|
||||||
|
int32_t tsCheckTimestamp(STableDataBlocks *pDataBlocks, const char *start);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// functions for normal statement preparation
|
// functions for normal statement preparation
|
||||||
|
@ -43,10 +44,32 @@ typedef struct SNormalStmt {
|
||||||
tVariant* params;
|
tVariant* params;
|
||||||
} SNormalStmt;
|
} SNormalStmt;
|
||||||
|
|
||||||
|
typedef struct SMultiTbStmt {
|
||||||
|
bool nameSet;
|
||||||
|
uint64_t currentUid;
|
||||||
|
uint32_t tbNum;
|
||||||
|
SStrToken tbname;
|
||||||
|
SHashObj *pTableHash;
|
||||||
|
SHashObj *pTableBlockHashList; // data block for each table
|
||||||
|
} SMultiTbStmt;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
STMT_INIT = 1,
|
||||||
|
STMT_PREPARE,
|
||||||
|
STMT_SETTBNAME,
|
||||||
|
STMT_BIND,
|
||||||
|
STMT_BIND_COL,
|
||||||
|
STMT_ADD_BATCH,
|
||||||
|
STMT_EXECUTE
|
||||||
|
} STMT_ST;
|
||||||
|
|
||||||
typedef struct STscStmt {
|
typedef struct STscStmt {
|
||||||
bool isInsert;
|
bool isInsert;
|
||||||
|
bool multiTbInsert;
|
||||||
|
int16_t last;
|
||||||
STscObj* taos;
|
STscObj* taos;
|
||||||
SSqlObj* pSql;
|
SSqlObj* pSql;
|
||||||
|
SMultiTbStmt mtb;
|
||||||
SNormalStmt normal;
|
SNormalStmt normal;
|
||||||
} STscStmt;
|
} STscStmt;
|
||||||
|
|
||||||
|
@ -135,7 +158,7 @@ static int normalStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
tscDebug("param %d: type mismatch or invalid", i);
|
tscDebug("0x%"PRIx64" bind column%d: type mismatch or invalid", stmt->pSql->self, i);
|
||||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,7 +174,7 @@ static int normalStmtPrepare(STscStmt* stmt) {
|
||||||
|
|
||||||
while (sql[i] != 0) {
|
while (sql[i] != 0) {
|
||||||
SStrToken token = {0};
|
SStrToken token = {0};
|
||||||
token.n = tSQLGetToken(sql + i, &token.type);
|
token.n = tGetToken(sql + i, &token.type);
|
||||||
|
|
||||||
if (token.type == TK_QUESTION) {
|
if (token.type == TK_QUESTION) {
|
||||||
sql[i] = 0;
|
sql[i] = 0;
|
||||||
|
@ -253,14 +276,69 @@ static char* normalStmtBuildSql(STscStmt* stmt) {
|
||||||
return taosStringBuilderGetResult(&sb, NULL);
|
return taosStringBuilderGetResult(&sb, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int fillColumnsNull(STableDataBlocks* pBlock, int32_t rowNum) {
|
||||||
|
SParsedDataColInfo* spd = &pBlock->boundColumnInfo;
|
||||||
|
int32_t offset = 0;
|
||||||
|
SSchema *schema = (SSchema*)pBlock->pTableMeta->schema;
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < spd->numOfCols; ++i) {
|
||||||
|
if (!spd->cols[i].hasVal) { // current column do not have any value to insert, set it to null
|
||||||
|
for (int32_t n = 0; n < rowNum; ++n) {
|
||||||
|
char *ptr = pBlock->pData + sizeof(SSubmitBlk) + pBlock->rowSize * n + offset;
|
||||||
|
|
||||||
|
if (schema[i].type == TSDB_DATA_TYPE_BINARY) {
|
||||||
|
varDataSetLen(ptr, sizeof(int8_t));
|
||||||
|
*(uint8_t*) varDataVal(ptr) = TSDB_DATA_BINARY_NULL;
|
||||||
|
} else if (schema[i].type == TSDB_DATA_TYPE_NCHAR) {
|
||||||
|
varDataSetLen(ptr, sizeof(int32_t));
|
||||||
|
*(uint32_t*) varDataVal(ptr) = TSDB_DATA_NCHAR_NULL;
|
||||||
|
} else {
|
||||||
|
setNull(ptr, schema[i].type, schema[i].bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += schema[i].bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t fillTablesColumnsNull(SSqlObj* pSql) {
|
||||||
|
SSqlCmd* pCmd = &pSql->cmd;
|
||||||
|
|
||||||
|
STableDataBlocks** p = taosHashIterate(pCmd->pTableBlockHashList, NULL);
|
||||||
|
|
||||||
|
STableDataBlocks* pOneTableBlock = *p;
|
||||||
|
while(pOneTableBlock) {
|
||||||
|
SSubmitBlk* pBlocks = (SSubmitBlk*) pOneTableBlock->pData;
|
||||||
|
if (pBlocks->numOfRows > 0 && pOneTableBlock->boundColumnInfo.numOfBound < pOneTableBlock->boundColumnInfo.numOfCols) {
|
||||||
|
fillColumnsNull(pOneTableBlock, pBlocks->numOfRows);
|
||||||
|
}
|
||||||
|
|
||||||
|
p = taosHashIterate(pCmd->pTableBlockHashList, p);
|
||||||
|
if (p == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pOneTableBlock = *p;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// functions for insertion statement preparation
|
// functions for insertion statement preparation
|
||||||
static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
|
static int doBindParam(STableDataBlocks* pBlock, char* data, SParamInfo* param, TAOS_BIND* bind, int32_t colNum) {
|
||||||
if (bind->is_null != NULL && *(bind->is_null)) {
|
if (bind->is_null != NULL && *(bind->is_null)) {
|
||||||
setNull(data + param->offset, param->type, param->bytes);
|
setNull(data + param->offset, param->type, param->bytes);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (0) {
|
if (0) {
|
||||||
// allow user bind param data with different type
|
// allow user bind param data with different type
|
||||||
union {
|
union {
|
||||||
|
@ -641,6 +719,7 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (bind->buffer_type != param->type) {
|
if (bind->buffer_type != param->type) {
|
||||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||||
|
@ -690,12 +769,90 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(data + param->offset, bind->buffer, size);
|
memcpy(data + param->offset, bind->buffer, size);
|
||||||
|
if (param->offset == 0) {
|
||||||
|
if (tsCheckTimestamp(pBlock, data + param->offset) != TSDB_CODE_SUCCESS) {
|
||||||
|
tscError("invalid timestamp");
|
||||||
|
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MULTI_BIND* bind, int32_t rowNum) {
|
||||||
|
if (bind->buffer_type != param->type || !isValidDataType(param->type)) {
|
||||||
|
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_VAR_DATA_TYPE(param->type) && bind->length == NULL) {
|
||||||
|
tscError("BINARY/NCHAR no length");
|
||||||
|
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < bind->num; ++i) {
|
||||||
|
char* data = pBlock->pData + sizeof(SSubmitBlk) + pBlock->rowSize * (rowNum + i);
|
||||||
|
|
||||||
|
if (bind->is_null != NULL && bind->is_null[i]) {
|
||||||
|
setNull(data + param->offset, param->type, param->bytes);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IS_VAR_DATA_TYPE(param->type)) {
|
||||||
|
memcpy(data + param->offset, (char *)bind->buffer + bind->buffer_length * i, tDataTypes[param->type].bytes);
|
||||||
|
|
||||||
|
if (param->offset == 0) {
|
||||||
|
if (tsCheckTimestamp(pBlock, data + param->offset) != TSDB_CODE_SUCCESS) {
|
||||||
|
tscError("invalid timestamp");
|
||||||
|
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (param->type == TSDB_DATA_TYPE_BINARY) {
|
||||||
|
if (bind->length[i] > (uintptr_t)param->bytes) {
|
||||||
|
tscError("binary length too long, ignore it, max:%d, actual:%d", param->bytes, (int32_t)bind->length[i]);
|
||||||
|
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||||
|
}
|
||||||
|
int16_t bsize = (short)bind->length[i];
|
||||||
|
STR_WITH_SIZE_TO_VARSTR(data + param->offset, (char *)bind->buffer + bind->buffer_length * i, bsize);
|
||||||
|
} else if (param->type == TSDB_DATA_TYPE_NCHAR) {
|
||||||
|
if (bind->length[i] > (uintptr_t)param->bytes) {
|
||||||
|
tscError("nchar string length too long, ignore it, max:%d, actual:%d", param->bytes, (int32_t)bind->length[i]);
|
||||||
|
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t output = 0;
|
||||||
|
if (!taosMbsToUcs4((char *)bind->buffer + bind->buffer_length * i, bind->length[i], varDataVal(data + param->offset), param->bytes - VARSTR_HEADER_SIZE, &output)) {
|
||||||
|
tscError("convert nchar string to UCS4_LE failed:%s", (char*)((char *)bind->buffer + bind->buffer_length * i));
|
||||||
|
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
varDataSetLen(data + param->offset, output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) {
|
static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) {
|
||||||
SSqlCmd* pCmd = &stmt->pSql->cmd;
|
SSqlCmd* pCmd = &stmt->pSql->cmd;
|
||||||
|
STscStmt* pStmt = (STscStmt*)stmt;
|
||||||
|
|
||||||
|
STableDataBlocks* pBlock = NULL;
|
||||||
|
|
||||||
|
if (pStmt->multiTbInsert) {
|
||||||
|
if (pCmd->pTableBlockHashList == NULL) {
|
||||||
|
tscError("0x%"PRIx64" Table block hash list is empty", pStmt->pSql->self);
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pCmd->pTableBlockHashList, (const char*)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid));
|
||||||
|
if (t1 == NULL) {
|
||||||
|
tscError("0x%"PRIx64" no table data block in hash list, uid:%" PRId64 , pStmt->pSql->self, pStmt->mtb.currentUid);
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
pBlock = *t1;
|
||||||
|
} else {
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||||
|
|
||||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||||
|
@ -703,16 +860,15 @@ static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) {
|
||||||
pCmd->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
pCmd->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
STableDataBlocks* pBlock = NULL;
|
|
||||||
|
|
||||||
int32_t ret =
|
int32_t ret =
|
||||||
tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||||
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
|
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
// todo handle error
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t totalDataSize = sizeof(SSubmitBlk) + pCmd->batchSize * pBlock->rowSize;
|
uint32_t totalDataSize = sizeof(SSubmitBlk) + (pCmd->batchSize + 1) * pBlock->rowSize;
|
||||||
if (totalDataSize > pBlock->nAllocSize) {
|
if (totalDataSize > pBlock->nAllocSize) {
|
||||||
const double factor = 1.5;
|
const double factor = 1.5;
|
||||||
|
|
||||||
|
@ -729,9 +885,9 @@ static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) {
|
||||||
for (uint32_t j = 0; j < pBlock->numOfParams; ++j) {
|
for (uint32_t j = 0; j < pBlock->numOfParams; ++j) {
|
||||||
SParamInfo* param = &pBlock->params[j];
|
SParamInfo* param = &pBlock->params[j];
|
||||||
|
|
||||||
int code = doBindParam(data, param, &bind[param->idx]);
|
int code = doBindParam(pBlock, data, param, &bind[param->idx], 1);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
tscDebug("param %d: type mismatch or invalid", param->idx);
|
tscDebug("0x%"PRIx64" bind column %d: type mismatch or invalid", pStmt->pSql->self, param->idx);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -739,9 +895,134 @@ static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int colIdx) {
|
||||||
|
SSqlCmd* pCmd = &stmt->pSql->cmd;
|
||||||
|
STscStmt* pStmt = (STscStmt*)stmt;
|
||||||
|
int rowNum = bind->num;
|
||||||
|
|
||||||
|
STableDataBlocks* pBlock = NULL;
|
||||||
|
|
||||||
|
if (pStmt->multiTbInsert) {
|
||||||
|
if (pCmd->pTableBlockHashList == NULL) {
|
||||||
|
tscError("0x%"PRIx64" Table block hash list is empty", pStmt->pSql->self);
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pCmd->pTableBlockHashList, (const char*)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid));
|
||||||
|
if (t1 == NULL) {
|
||||||
|
tscError("0x%"PRIx64" no table data block in hash list, uid:%" PRId64 , pStmt->pSql->self, pStmt->mtb.currentUid);
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
pBlock = *t1;
|
||||||
|
} else {
|
||||||
|
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||||
|
|
||||||
|
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||||
|
if (pCmd->pTableBlockHashList == NULL) {
|
||||||
|
pCmd->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t ret =
|
||||||
|
tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||||
|
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
|
||||||
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(colIdx == -1 || (colIdx >= 0 && colIdx < pBlock->numOfParams));
|
||||||
|
|
||||||
|
uint32_t totalDataSize = sizeof(SSubmitBlk) + (pCmd->batchSize + rowNum) * pBlock->rowSize;
|
||||||
|
if (totalDataSize > pBlock->nAllocSize) {
|
||||||
|
const double factor = 1.5;
|
||||||
|
|
||||||
|
void* tmp = realloc(pBlock->pData, (uint32_t)(totalDataSize * factor));
|
||||||
|
if (tmp == NULL) {
|
||||||
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
pBlock->pData = (char*)tmp;
|
||||||
|
pBlock->nAllocSize = (uint32_t)(totalDataSize * factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colIdx == -1) {
|
||||||
|
for (uint32_t j = 0; j < pBlock->numOfParams; ++j) {
|
||||||
|
SParamInfo* param = &pBlock->params[j];
|
||||||
|
if (bind[param->idx].num != rowNum) {
|
||||||
|
tscError("0x%"PRIx64" param %d: num[%d:%d] not match", pStmt->pSql->self, param->idx, rowNum, bind[param->idx].num);
|
||||||
|
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int code = doBindBatchParam(pBlock, param, &bind[param->idx], pCmd->batchSize);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
tscError("0x%"PRIx64" bind column %d: type mismatch or invalid", pStmt->pSql->self, param->idx);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pCmd->batchSize += rowNum - 1;
|
||||||
|
} else {
|
||||||
|
SParamInfo* param = &pBlock->params[colIdx];
|
||||||
|
|
||||||
|
int code = doBindBatchParam(pBlock, param, bind, pCmd->batchSize);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
tscError("0x%"PRIx64" bind column %d: type mismatch or invalid", pStmt->pSql->self, param->idx);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colIdx == (pBlock->numOfParams - 1)) {
|
||||||
|
pCmd->batchSize += rowNum - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int insertStmtUpdateBatch(STscStmt* stmt) {
|
||||||
|
SSqlObj* pSql = stmt->pSql;
|
||||||
|
SSqlCmd* pCmd = &pSql->cmd;
|
||||||
|
STableDataBlocks* pBlock = NULL;
|
||||||
|
|
||||||
|
if (pCmd->batchSize > INT16_MAX) {
|
||||||
|
tscError("too many record:%d", pCmd->batchSize);
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (taosHashGetSize(pCmd->pTableBlockHashList) == 0) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pCmd->pTableBlockHashList, (const char*)&stmt->mtb.currentUid, sizeof(stmt->mtb.currentUid));
|
||||||
|
if (t1 == NULL) {
|
||||||
|
tscError("0x%"PRIx64" no table data block in hash list, uid:%" PRId64 , pSql->self, stmt->mtb.currentUid);
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
pBlock = *t1;
|
||||||
|
|
||||||
|
STableMeta* pTableMeta = pBlock->pTableMeta;
|
||||||
|
|
||||||
|
pBlock->size = sizeof(SSubmitBlk) + pCmd->batchSize * pBlock->rowSize;
|
||||||
|
SSubmitBlk* pBlk = (SSubmitBlk*) pBlock->pData;
|
||||||
|
pBlk->numOfRows = pCmd->batchSize;
|
||||||
|
pBlk->dataLen = 0;
|
||||||
|
pBlk->uid = pTableMeta->id.uid;
|
||||||
|
pBlk->tid = pTableMeta->id.tid;
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int insertStmtAddBatch(STscStmt* stmt) {
|
static int insertStmtAddBatch(STscStmt* stmt) {
|
||||||
SSqlCmd* pCmd = &stmt->pSql->cmd;
|
SSqlCmd* pCmd = &stmt->pSql->cmd;
|
||||||
++pCmd->batchSize;
|
++pCmd->batchSize;
|
||||||
|
|
||||||
|
if (stmt->multiTbInsert) {
|
||||||
|
return insertStmtUpdateBatch(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -798,6 +1079,8 @@ static int insertStmtExecute(STscStmt* stmt) {
|
||||||
pBlk->uid = pTableMeta->id.uid;
|
pBlk->uid = pTableMeta->id.uid;
|
||||||
pBlk->tid = pTableMeta->id.tid;
|
pBlk->tid = pTableMeta->id.tid;
|
||||||
|
|
||||||
|
fillTablesColumnsNull(stmt->pSql);
|
||||||
|
|
||||||
int code = tscMergeTableDataBlocks(stmt->pSql, false);
|
int code = tscMergeTableDataBlocks(stmt->pSql, false);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
|
@ -834,6 +1117,88 @@ static int insertStmtExecute(STscStmt* stmt) {
|
||||||
return pSql->res.code;
|
return pSql->res.code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void insertBatchClean(STscStmt* pStmt) {
|
||||||
|
SSqlCmd *pCmd = &pStmt->pSql->cmd;
|
||||||
|
SSqlObj *pSql = pStmt->pSql;
|
||||||
|
int32_t size = taosHashGetSize(pCmd->pTableBlockHashList);
|
||||||
|
|
||||||
|
// data block reset
|
||||||
|
pCmd->batchSize = 0;
|
||||||
|
|
||||||
|
for(int32_t i = 0; i < size; ++i) {
|
||||||
|
if (pCmd->pTableNameList && pCmd->pTableNameList[i]) {
|
||||||
|
tfree(pCmd->pTableNameList[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tfree(pCmd->pTableNameList);
|
||||||
|
|
||||||
|
/*
|
||||||
|
STableDataBlocks** p = taosHashIterate(pCmd->pTableBlockHashList, NULL);
|
||||||
|
|
||||||
|
STableDataBlocks* pOneTableBlock = *p;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
SSubmitBlk* pBlocks = (SSubmitBlk*) pOneTableBlock->pData;
|
||||||
|
|
||||||
|
pOneTableBlock->size = sizeof(SSubmitBlk);
|
||||||
|
|
||||||
|
pBlocks->numOfRows = 0;
|
||||||
|
|
||||||
|
p = taosHashIterate(pCmd->pTableBlockHashList, p);
|
||||||
|
if (p == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pOneTableBlock = *p;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
||||||
|
pCmd->numOfTables = 0;
|
||||||
|
|
||||||
|
taosHashEmpty(pCmd->pTableBlockHashList);
|
||||||
|
tscFreeSqlResult(pSql);
|
||||||
|
tscFreeSubobj(pSql);
|
||||||
|
tfree(pSql->pSubs);
|
||||||
|
pSql->subState.numOfSub = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int insertBatchStmtExecute(STscStmt* pStmt) {
|
||||||
|
int32_t code = 0;
|
||||||
|
|
||||||
|
if(pStmt->mtb.nameSet == false) {
|
||||||
|
tscError("0x%"PRIx64" no table name set", pStmt->pSql->self);
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
pStmt->pSql->retry = pStmt->pSql->maxRetry + 1; //no retry
|
||||||
|
|
||||||
|
if (taosHashGetSize(pStmt->pSql->cmd.pTableBlockHashList) <= 0) { // merge according to vgId
|
||||||
|
tscError("0x%"PRIx64" no data block to insert", pStmt->pSql->self);
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
fillTablesColumnsNull(pStmt->pSql);
|
||||||
|
|
||||||
|
if ((code = tscMergeTableDataBlocks(pStmt->pSql, false)) != TSDB_CODE_SUCCESS) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
code = tscHandleMultivnodeInsert(pStmt->pSql);
|
||||||
|
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for the callback function to post the semaphore
|
||||||
|
tsem_wait(&pStmt->pSql->rspSem);
|
||||||
|
|
||||||
|
insertBatchClean(pStmt);
|
||||||
|
|
||||||
|
return pStmt->pSql->res.code;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// interface functions
|
// interface functions
|
||||||
|
|
||||||
|
@ -865,7 +1230,9 @@ TAOS_STMT* taos_stmt_init(TAOS* taos) {
|
||||||
pSql->signature = pSql;
|
pSql->signature = pSql;
|
||||||
pSql->pTscObj = pObj;
|
pSql->pTscObj = pObj;
|
||||||
pSql->maxRetry = TSDB_MAX_REPLICA;
|
pSql->maxRetry = TSDB_MAX_REPLICA;
|
||||||
|
pSql->isBind = true;
|
||||||
pStmt->pSql = pSql;
|
pStmt->pSql = pSql;
|
||||||
|
pStmt->last = STMT_INIT;
|
||||||
|
|
||||||
return pStmt;
|
return pStmt;
|
||||||
}
|
}
|
||||||
|
@ -878,6 +1245,13 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) {
|
||||||
return TSDB_CODE_TSC_DISCONNECTED;
|
return TSDB_CODE_TSC_DISCONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pStmt->last != STMT_INIT) {
|
||||||
|
tscError("prepare status error, last:%d", pStmt->last);
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
pStmt->last = STMT_PREPARE;
|
||||||
|
|
||||||
SSqlObj* pSql = pStmt->pSql;
|
SSqlObj* pSql = pStmt->pSql;
|
||||||
size_t sqlLen = strlen(sql);
|
size_t sqlLen = strlen(sql);
|
||||||
|
|
||||||
|
@ -916,6 +1290,36 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) {
|
||||||
|
|
||||||
registerSqlObj(pSql);
|
registerSqlObj(pSql);
|
||||||
|
|
||||||
|
int32_t ret = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
|
if ((ret = tsInsertInitialCheck(pSql)) != TSDB_CODE_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t index = 0;
|
||||||
|
SStrToken sToken = tStrGetToken(pCmd->curSql, &index, false);
|
||||||
|
|
||||||
|
if (sToken.n == 0) {
|
||||||
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sToken.n == 1 && sToken.type == TK_QUESTION) {
|
||||||
|
pStmt->multiTbInsert = true;
|
||||||
|
pStmt->mtb.tbname = sToken;
|
||||||
|
pStmt->mtb.nameSet = false;
|
||||||
|
if (pStmt->mtb.pTableHash == NULL) {
|
||||||
|
pStmt->mtb.pTableHash = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, false);
|
||||||
|
}
|
||||||
|
if (pStmt->mtb.pTableBlockHashList == NULL) {
|
||||||
|
pStmt->mtb.pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
pStmt->multiTbInsert = false;
|
||||||
|
memset(&pStmt->mtb, 0, sizeof(pStmt->mtb));
|
||||||
|
|
||||||
int32_t code = tsParseSql(pSql, true);
|
int32_t code = tsParseSql(pSql, true);
|
||||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||||
// wait for the callback function to post the semaphore
|
// wait for the callback function to post the semaphore
|
||||||
|
@ -930,6 +1334,104 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) {
|
||||||
return normalStmtPrepare(pStmt);
|
return normalStmtPrepare(pStmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name) {
|
||||||
|
STscStmt* pStmt = (STscStmt*)stmt;
|
||||||
|
SSqlObj* pSql = pStmt->pSql;
|
||||||
|
SSqlCmd* pCmd = &pSql->cmd;
|
||||||
|
|
||||||
|
if (stmt == NULL || pStmt->pSql == NULL || pStmt->taos == NULL) {
|
||||||
|
terrno = TSDB_CODE_TSC_DISCONNECTED;
|
||||||
|
return TSDB_CODE_TSC_DISCONNECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name == NULL) {
|
||||||
|
terrno = TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
tscError("0x%"PRIx64" name is NULL", pSql->self);
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pStmt->multiTbInsert == false || !tscIsInsertData(pSql->sqlstr)) {
|
||||||
|
terrno = TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
tscError("0x%"PRIx64" not multi table insert", pSql->self);
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pStmt->last == STMT_INIT || pStmt->last == STMT_BIND || pStmt->last == STMT_BIND_COL) {
|
||||||
|
tscError("0x%"PRIx64" settbname status error, last:%d", pSql->self, pStmt->last);
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
pStmt->last = STMT_SETTBNAME;
|
||||||
|
|
||||||
|
uint64_t* uid = (uint64_t*)taosHashGet(pStmt->mtb.pTableHash, name, strlen(name));
|
||||||
|
if (uid != NULL) {
|
||||||
|
pStmt->mtb.currentUid = *uid;
|
||||||
|
|
||||||
|
STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pStmt->mtb.pTableBlockHashList, (const char*)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid));
|
||||||
|
if (t1 == NULL) {
|
||||||
|
tscError("0x%"PRIx64" no table data block in hash list, uid:%" PRId64 , pSql->self, pStmt->mtb.currentUid);
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSubmitBlk* pBlk = (SSubmitBlk*) (*t1)->pData;
|
||||||
|
pCmd->batchSize = pBlk->numOfRows;
|
||||||
|
|
||||||
|
taosHashPut(pCmd->pTableBlockHashList, (void *)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid), (void*)t1, POINTER_BYTES);
|
||||||
|
|
||||||
|
tscDebug("0x%"PRIx64" table:%s is already prepared, uid:%" PRIu64, pSql->self, name, pStmt->mtb.currentUid);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
pStmt->mtb.tbname = tscReplaceStrToken(&pSql->sqlstr, &pStmt->mtb.tbname, name);
|
||||||
|
pStmt->mtb.nameSet = true;
|
||||||
|
|
||||||
|
tscDebug("0x%"PRIx64" SQL: %s", pSql->self, pSql->sqlstr);
|
||||||
|
|
||||||
|
pSql->cmd.parseFinished = 0;
|
||||||
|
pSql->cmd.numOfParams = 0;
|
||||||
|
pSql->cmd.batchSize = 0;
|
||||||
|
|
||||||
|
if (taosHashGetSize(pCmd->pTableBlockHashList) > 0) {
|
||||||
|
SHashObj* hashList = pCmd->pTableBlockHashList;
|
||||||
|
pCmd->pTableBlockHashList = NULL;
|
||||||
|
tscResetSqlCmd(pCmd, true);
|
||||||
|
pCmd->pTableBlockHashList = hashList;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t code = tsParseSql(pStmt->pSql, true);
|
||||||
|
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||||
|
// wait for the callback function to post the semaphore
|
||||||
|
tsem_wait(&pStmt->pSql->rspSem);
|
||||||
|
|
||||||
|
code = pStmt->pSql->res.code;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code == TSDB_CODE_SUCCESS) {
|
||||||
|
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||||
|
|
||||||
|
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||||
|
STableDataBlocks* pBlock = NULL;
|
||||||
|
code = tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||||
|
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSubmitBlk* blk = (SSubmitBlk*)pBlock->pData;
|
||||||
|
blk->numOfRows = 0;
|
||||||
|
|
||||||
|
pStmt->mtb.currentUid = pTableMeta->id.uid;
|
||||||
|
pStmt->mtb.tbNum++;
|
||||||
|
|
||||||
|
taosHashPut(pStmt->mtb.pTableBlockHashList, (void *)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid), (void*)&pBlock, POINTER_BYTES);
|
||||||
|
taosHashPut(pStmt->mtb.pTableHash, name, strlen(name), (char*) &pTableMeta->id.uid, sizeof(pTableMeta->id.uid));
|
||||||
|
|
||||||
|
tscDebug("0x%"PRIx64" table:%s is prepared, uid:%" PRIx64, pSql->self, name, pStmt->mtb.currentUid);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
int taos_stmt_close(TAOS_STMT* stmt) {
|
int taos_stmt_close(TAOS_STMT* stmt) {
|
||||||
STscStmt* pStmt = (STscStmt*)stmt;
|
STscStmt* pStmt = (STscStmt*)stmt;
|
||||||
if (!pStmt->isInsert) {
|
if (!pStmt->isInsert) {
|
||||||
|
@ -942,6 +1444,13 @@ int taos_stmt_close(TAOS_STMT* stmt) {
|
||||||
}
|
}
|
||||||
free(normal->parts);
|
free(normal->parts);
|
||||||
free(normal->sql);
|
free(normal->sql);
|
||||||
|
} else {
|
||||||
|
if (pStmt->multiTbInsert) {
|
||||||
|
taosHashCleanup(pStmt->mtb.pTableHash);
|
||||||
|
pStmt->mtb.pTableBlockHashList = tscDestroyBlockHashTable(pStmt->mtb.pTableBlockHashList, true);
|
||||||
|
taosHashCleanup(pStmt->pSql->cmd.pTableBlockHashList);
|
||||||
|
pStmt->pSql->cmd.pTableBlockHashList = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
taos_free_result(pStmt->pSql);
|
taos_free_result(pStmt->pSql);
|
||||||
|
@ -951,18 +1460,122 @@ int taos_stmt_close(TAOS_STMT* stmt) {
|
||||||
|
|
||||||
int taos_stmt_bind_param(TAOS_STMT* stmt, TAOS_BIND* bind) {
|
int taos_stmt_bind_param(TAOS_STMT* stmt, TAOS_BIND* bind) {
|
||||||
STscStmt* pStmt = (STscStmt*)stmt;
|
STscStmt* pStmt = (STscStmt*)stmt;
|
||||||
|
if (stmt == NULL || pStmt->pSql == NULL || pStmt->taos == NULL) {
|
||||||
|
terrno = TSDB_CODE_TSC_DISCONNECTED;
|
||||||
|
return TSDB_CODE_TSC_DISCONNECTED;
|
||||||
|
}
|
||||||
|
|
||||||
if (pStmt->isInsert) {
|
if (pStmt->isInsert) {
|
||||||
|
if (pStmt->multiTbInsert) {
|
||||||
|
if (pStmt->last != STMT_SETTBNAME && pStmt->last != STMT_ADD_BATCH) {
|
||||||
|
tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last);
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (pStmt->last != STMT_PREPARE && pStmt->last != STMT_ADD_BATCH && pStmt->last != STMT_EXECUTE) {
|
||||||
|
tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last);
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pStmt->last = STMT_BIND;
|
||||||
|
|
||||||
return insertStmtBindParam(pStmt, bind);
|
return insertStmtBindParam(pStmt, bind);
|
||||||
} else {
|
} else {
|
||||||
return normalStmtBindParam(pStmt, bind);
|
return normalStmtBindParam(pStmt, bind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int taos_stmt_bind_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind) {
|
||||||
|
STscStmt* pStmt = (STscStmt*)stmt;
|
||||||
|
|
||||||
|
if (stmt == NULL || pStmt->pSql == NULL || pStmt->taos == NULL) {
|
||||||
|
terrno = TSDB_CODE_TSC_DISCONNECTED;
|
||||||
|
return TSDB_CODE_TSC_DISCONNECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bind == NULL || bind->num <= 0 || bind->num > INT16_MAX) {
|
||||||
|
tscError("0x%"PRIx64" invalid parameter", pStmt->pSql->self);
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pStmt->isInsert) {
|
||||||
|
tscError("0x%"PRIx64" not or invalid batch insert", pStmt->pSql->self);
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pStmt->multiTbInsert) {
|
||||||
|
if (pStmt->last != STMT_SETTBNAME && pStmt->last != STMT_ADD_BATCH) {
|
||||||
|
tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last);
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (pStmt->last != STMT_PREPARE && pStmt->last != STMT_ADD_BATCH && pStmt->last != STMT_EXECUTE) {
|
||||||
|
tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last);
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pStmt->last = STMT_BIND;
|
||||||
|
|
||||||
|
return insertStmtBindParamBatch(pStmt, bind, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int taos_stmt_bind_single_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind, int colIdx) {
|
||||||
|
STscStmt* pStmt = (STscStmt*)stmt;
|
||||||
|
if (stmt == NULL || pStmt->pSql == NULL || pStmt->taos == NULL) {
|
||||||
|
terrno = TSDB_CODE_TSC_DISCONNECTED;
|
||||||
|
return TSDB_CODE_TSC_DISCONNECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bind == NULL || bind->num <= 0 || bind->num > INT16_MAX) {
|
||||||
|
tscError("0x%"PRIx64" invalid parameter", pStmt->pSql->self);
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pStmt->isInsert) {
|
||||||
|
tscError("0x%"PRIx64" not or invalid batch insert", pStmt->pSql->self);
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pStmt->multiTbInsert) {
|
||||||
|
if (pStmt->last != STMT_SETTBNAME && pStmt->last != STMT_ADD_BATCH && pStmt->last != STMT_BIND_COL) {
|
||||||
|
tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last);
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (pStmt->last != STMT_PREPARE && pStmt->last != STMT_ADD_BATCH && pStmt->last != STMT_BIND_COL && pStmt->last != STMT_EXECUTE) {
|
||||||
|
tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last);
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pStmt->last = STMT_BIND_COL;
|
||||||
|
|
||||||
|
return insertStmtBindParamBatch(pStmt, bind, colIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int taos_stmt_add_batch(TAOS_STMT* stmt) {
|
int taos_stmt_add_batch(TAOS_STMT* stmt) {
|
||||||
STscStmt* pStmt = (STscStmt*)stmt;
|
STscStmt* pStmt = (STscStmt*)stmt;
|
||||||
|
if (stmt == NULL || pStmt->pSql == NULL || pStmt->taos == NULL) {
|
||||||
|
terrno = TSDB_CODE_TSC_DISCONNECTED;
|
||||||
|
return TSDB_CODE_TSC_DISCONNECTED;
|
||||||
|
}
|
||||||
|
|
||||||
if (pStmt->isInsert) {
|
if (pStmt->isInsert) {
|
||||||
|
if (pStmt->last != STMT_BIND && pStmt->last != STMT_BIND_COL) {
|
||||||
|
tscError("0x%"PRIx64" add batch status error, last:%d", pStmt->pSql->self, pStmt->last);
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
pStmt->last = STMT_ADD_BATCH;
|
||||||
|
|
||||||
return insertStmtAddBatch(pStmt);
|
return insertStmtAddBatch(pStmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_COM_OPS_NOT_SUPPORT;
|
return TSDB_CODE_COM_OPS_NOT_SUPPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -977,8 +1590,24 @@ int taos_stmt_reset(TAOS_STMT* stmt) {
|
||||||
int taos_stmt_execute(TAOS_STMT* stmt) {
|
int taos_stmt_execute(TAOS_STMT* stmt) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
STscStmt* pStmt = (STscStmt*)stmt;
|
STscStmt* pStmt = (STscStmt*)stmt;
|
||||||
|
if (stmt == NULL || pStmt->pSql == NULL || pStmt->taos == NULL) {
|
||||||
|
terrno = TSDB_CODE_TSC_DISCONNECTED;
|
||||||
|
return TSDB_CODE_TSC_DISCONNECTED;
|
||||||
|
}
|
||||||
|
|
||||||
if (pStmt->isInsert) {
|
if (pStmt->isInsert) {
|
||||||
|
if (pStmt->last != STMT_ADD_BATCH) {
|
||||||
|
tscError("0x%"PRIx64" exec status error, last:%d", pStmt->pSql->self, pStmt->last);
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
pStmt->last = STMT_EXECUTE;
|
||||||
|
|
||||||
|
if (pStmt->multiTbInsert) {
|
||||||
|
ret = insertBatchStmtExecute(pStmt);
|
||||||
|
} else {
|
||||||
ret = insertStmtExecute(pStmt);
|
ret = insertStmtExecute(pStmt);
|
||||||
|
}
|
||||||
} else { // normal stmt query
|
} else { // normal stmt query
|
||||||
char* sql = normalStmtBuildSql(pStmt);
|
char* sql = normalStmtBuildSql(pStmt);
|
||||||
if (sql == NULL) {
|
if (sql == NULL) {
|
||||||
|
@ -1073,7 +1702,7 @@ int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idx<0 || idx>=pBlock->numOfParams) {
|
if (idx<0 || idx>=pBlock->numOfParams) {
|
||||||
tscError("param %d: out of range", idx);
|
tscError("0x%"PRIx64" param %d: out of range", pStmt->pSql->self, idx);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,14 +54,14 @@ void tscAddIntoSqlList(SSqlObj *pSql) {
|
||||||
pSql->next = pObj->sqlList;
|
pSql->next = pObj->sqlList;
|
||||||
if (pObj->sqlList) pObj->sqlList->prev = pSql;
|
if (pObj->sqlList) pObj->sqlList->prev = pSql;
|
||||||
pObj->sqlList = pSql;
|
pObj->sqlList = pSql;
|
||||||
pSql->queryId = queryId++;
|
pSql->queryId = atomic_fetch_add_32(&queryId, 1);
|
||||||
|
|
||||||
pthread_mutex_unlock(&pObj->mutex);
|
pthread_mutex_unlock(&pObj->mutex);
|
||||||
|
|
||||||
pSql->stime = taosGetTimestampMs();
|
pSql->stime = taosGetTimestampMs();
|
||||||
pSql->listed = 1;
|
pSql->listed = 1;
|
||||||
|
|
||||||
tscDebug("0x%"PRIx64" added into sqlList", pSql->self);
|
tscDebug("0x%"PRIx64" added into sqlList, queryId:%u", pSql->self, pSql->queryId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tscSaveSlowQueryFpCb(void *param, TAOS_RES *result, int code) {
|
void tscSaveSlowQueryFpCb(void *param, TAOS_RES *result, int code) {
|
||||||
|
|
|
@ -21,19 +21,19 @@
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "ttype.h"
|
|
||||||
#include "texpr.h"
|
|
||||||
#include "taos.h"
|
#include "taos.h"
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
#include "tcompare.h"
|
#include "tcompare.h"
|
||||||
|
#include "texpr.h"
|
||||||
#include "tname.h"
|
#include "tname.h"
|
||||||
#include "tscLog.h"
|
#include "tscLog.h"
|
||||||
#include "tscUtil.h"
|
#include "tscUtil.h"
|
||||||
#include "tschemautil.h"
|
#include "tschemautil.h"
|
||||||
#include "tsclient.h"
|
#include "tsclient.h"
|
||||||
#include "tstoken.h"
|
|
||||||
#include "tstrbuild.h"
|
#include "tstrbuild.h"
|
||||||
|
#include "ttoken.h"
|
||||||
#include "ttokendef.h"
|
#include "ttokendef.h"
|
||||||
|
#include "ttype.h"
|
||||||
#include "qUtil.h"
|
#include "qUtil.h"
|
||||||
#include "qPlan.h"
|
#include "qPlan.h"
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ static char* getAccountId(SSqlObj* pSql);
|
||||||
|
|
||||||
static bool has(SArray* pFieldList, int32_t startIdx, const char* name);
|
static bool has(SArray* pFieldList, int32_t startIdx, const char* name);
|
||||||
static char* cloneCurrentDBName(SSqlObj* pSql);
|
static char* cloneCurrentDBName(SSqlObj* pSql);
|
||||||
static bool hasSpecifyDB(SStrToken* pTableName);
|
static int32_t getDelimiterIndex(SStrToken* pTableName);
|
||||||
static bool validateTableColumnInfo(SArray* pFieldList, SSqlCmd* pCmd);
|
static bool validateTableColumnInfo(SArray* pFieldList, SSqlCmd* pCmd);
|
||||||
static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pCmd);
|
static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pCmd);
|
||||||
|
|
||||||
|
@ -247,6 +247,38 @@ static int32_t handlePassword(SSqlCmd* pCmd, SStrToken* pPwd) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// validate the out put field type for "UNION ALL" subclause
|
||||||
|
static int32_t normalizeVarDataTypeLength(SSqlCmd* pCmd) {
|
||||||
|
const char* msg1 = "columns in select clause not identical";
|
||||||
|
|
||||||
|
int32_t diffSize = 0;
|
||||||
|
|
||||||
|
// if there is only one element, the limit of clause is the limit of global result.
|
||||||
|
SQueryInfo* pQueryInfo1 = pCmd->pQueryInfo;
|
||||||
|
SQueryInfo* pSibling = pQueryInfo1->sibling;
|
||||||
|
|
||||||
|
while(pSibling != NULL) {
|
||||||
|
int32_t ret = tscFieldInfoCompare(&pQueryInfo1->fieldsInfo, &pSibling->fieldsInfo, &diffSize);
|
||||||
|
if (ret != 0) {
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pSibling = pSibling->sibling;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (diffSize) {
|
||||||
|
pQueryInfo1 = pCmd->pQueryInfo;
|
||||||
|
pSibling = pQueryInfo1->sibling;
|
||||||
|
|
||||||
|
while(pSibling->sibling != NULL) {
|
||||||
|
tscFieldInfoSetSize(&pQueryInfo1->fieldsInfo, &pSibling->fieldsInfo);
|
||||||
|
pSibling = pSibling->sibling;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
||||||
if (pInfo == NULL || pSql == NULL) {
|
if (pInfo == NULL || pSql == NULL) {
|
||||||
return TSDB_CODE_TSC_APP_ERROR;
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
@ -429,17 +461,11 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
||||||
|
|
||||||
case TSDB_SQL_DESCRIBE_TABLE: {
|
case TSDB_SQL_DESCRIBE_TABLE: {
|
||||||
const char* msg1 = "invalid table name";
|
const char* msg1 = "invalid table name";
|
||||||
const char* msg2 = "table name too long";
|
|
||||||
|
|
||||||
SStrToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0);
|
SStrToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0);
|
||||||
if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
|
if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tscValidateTableNameLength(pToken->n)) {
|
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// additional msg has been attached already
|
// additional msg has been attached already
|
||||||
code = tscSetTableFullName(&pTableMetaInfo->name, pToken, pSql);
|
code = tscSetTableFullName(&pTableMetaInfo->name, pToken, pSql);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
@ -448,19 +474,15 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
||||||
|
|
||||||
return tscGetTableMeta(pSql, pTableMetaInfo);
|
return tscGetTableMeta(pSql, pTableMetaInfo);
|
||||||
}
|
}
|
||||||
|
case TSDB_SQL_SHOW_CREATE_STABLE:
|
||||||
case TSDB_SQL_SHOW_CREATE_TABLE: {
|
case TSDB_SQL_SHOW_CREATE_TABLE: {
|
||||||
const char* msg1 = "invalid table name";
|
const char* msg1 = "invalid table name";
|
||||||
const char* msg2 = "table name is too long";
|
|
||||||
|
|
||||||
SStrToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0);
|
SStrToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0);
|
||||||
if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
|
if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tscValidateTableNameLength(pToken->n)) {
|
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
|
||||||
}
|
|
||||||
|
|
||||||
code = tscSetTableFullName(&pTableMetaInfo->name, pToken, pSql);
|
code = tscSetTableFullName(&pTableMetaInfo->name, pToken, pSql);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
|
@ -479,8 +501,7 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
||||||
if (pToken->n > TSDB_DB_NAME_LEN) {
|
if (pToken->n > TSDB_DB_NAME_LEN) {
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||||
}
|
}
|
||||||
|
return tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), pToken);
|
||||||
return tscSetTableFullName(&pTableMetaInfo->name, pToken, pSql);
|
|
||||||
}
|
}
|
||||||
case TSDB_SQL_CFG_DNODE: {
|
case TSDB_SQL_CFG_DNODE: {
|
||||||
const char* msg2 = "invalid configure options or values, such as resetlog / debugFlag 135 / balance 'vnode:2-dnode:2' / monitor 1 ";
|
const char* msg2 = "invalid configure options or values, such as resetlog / debugFlag 135 / balance 'vnode:2-dnode:2' / monitor 1 ";
|
||||||
|
@ -618,8 +639,6 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case TSDB_SQL_SELECT: {
|
case TSDB_SQL_SELECT: {
|
||||||
const char* msg1 = "columns in select clause not identical";
|
|
||||||
|
|
||||||
code = loadAllTableMeta(pSql, pInfo);
|
code = loadAllTableMeta(pSql, pInfo);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
|
@ -648,6 +667,10 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((code = normalizeVarDataTypeLength(pCmd)) != TSDB_CODE_SUCCESS) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
// restore the clause index
|
// restore the clause index
|
||||||
pCmd->clauseIndex = 0;
|
pCmd->clauseIndex = 0;
|
||||||
|
|
||||||
|
@ -655,17 +678,6 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
||||||
pCmd->active = pCmd->pQueryInfo;
|
pCmd->active = pCmd->pQueryInfo;
|
||||||
pCmd->command = pCmd->pQueryInfo->command;
|
pCmd->command = pCmd->pQueryInfo->command;
|
||||||
|
|
||||||
// if there is only one element, the limit of clause is the limit of global result.
|
|
||||||
// validate the select node for "UNION ALL" subclause
|
|
||||||
SQueryInfo* pQueryInfo1 = pCmd->pQueryInfo;
|
|
||||||
while(pQueryInfo1->sibling != NULL) {
|
|
||||||
int32_t ret = tscFieldInfoCompare(&pQueryInfo1->fieldsInfo, &pQueryInfo1->sibling->fieldsInfo);
|
|
||||||
if (ret != 0) {
|
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
|
||||||
}
|
|
||||||
pQueryInfo1 = pQueryInfo1->sibling;
|
|
||||||
}
|
|
||||||
|
|
||||||
pCmd->parseFinished = 1;
|
pCmd->parseFinished = 1;
|
||||||
return TSDB_CODE_SUCCESS; // do not build query message here
|
return TSDB_CODE_SUCCESS; // do not build query message here
|
||||||
}
|
}
|
||||||
|
@ -992,11 +1004,13 @@ int32_t tscSetTableFullName(SName* pName, SStrToken* pTableName, SSqlObj* pSql)
|
||||||
const char* msg1 = "name too long";
|
const char* msg1 = "name too long";
|
||||||
const char* msg2 = "acctId too long";
|
const char* msg2 = "acctId too long";
|
||||||
const char* msg3 = "no acctId";
|
const char* msg3 = "no acctId";
|
||||||
|
const char* msg4 = "db name too long";
|
||||||
|
const char* msg5 = "table name too long";
|
||||||
|
|
||||||
SSqlCmd* pCmd = &pSql->cmd;
|
SSqlCmd* pCmd = &pSql->cmd;
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
int32_t idx = getDelimiterIndex(pTableName);
|
||||||
if (hasSpecifyDB(pTableName)) { // db has been specified in sql string so we ignore current db path
|
if (idx != -1) { // db has been specified in sql string so we ignore current db path
|
||||||
char* acctId = getAccountId(pSql);
|
char* acctId = getAccountId(pSql);
|
||||||
if (acctId == NULL || strlen(acctId) <= 0) {
|
if (acctId == NULL || strlen(acctId) <= 0) {
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||||
|
@ -1006,6 +1020,13 @@ int32_t tscSetTableFullName(SName* pName, SStrToken* pTableName, SSqlObj* pSql)
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||||
}
|
}
|
||||||
|
if (idx >= TSDB_DB_NAME_LEN) {
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pTableName->n - 1 - idx >= TSDB_TABLE_NAME_LEN) {
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
|
||||||
|
}
|
||||||
|
|
||||||
char name[TSDB_TABLE_FNAME_LEN] = {0};
|
char name[TSDB_TABLE_FNAME_LEN] = {0};
|
||||||
strncpy(name, pTableName->z, pTableName->n);
|
strncpy(name, pTableName->z, pTableName->n);
|
||||||
|
@ -1348,14 +1369,13 @@ static char* cloneCurrentDBName(SSqlObj* pSql) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* length limitation, strstr cannot be applied */
|
/* length limitation, strstr cannot be applied */
|
||||||
static bool hasSpecifyDB(SStrToken* pTableName) {
|
static int32_t getDelimiterIndex(SStrToken* pTableName) {
|
||||||
for (uint32_t i = 0; i < pTableName->n; ++i) {
|
for (uint32_t i = 0; i < pTableName->n; ++i) {
|
||||||
if (pTableName->z[i] == TS_PATH_DELIMITER[0]) {
|
if (pTableName->z[i] == TS_PATH_DELIMITER[0]) {
|
||||||
return true;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return -1;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t setObjFullName(char* fullName, const char* account, SStrToken* pDB, SStrToken* tableName, int32_t* xlen) {
|
int32_t setObjFullName(char* fullName, const char* account, SStrToken* pDB, SStrToken* tableName, int32_t* xlen) {
|
||||||
|
@ -1611,11 +1631,27 @@ bool isValidDistinctSql(SQueryInfo* pQueryInfo) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool hasNoneUserDefineExpr(SQueryInfo* pQueryInfo) {
|
||||||
|
size_t numOfExprs = taosArrayGetSize(pQueryInfo->exprList);
|
||||||
|
for (int32_t i = 0; i < numOfExprs; ++i) {
|
||||||
|
SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, i);
|
||||||
|
|
||||||
|
if (TSDB_COL_IS_UD_COL(pExpr->colInfo.flag)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelNodeList, bool isSTable, bool joinQuery,
|
int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelNodeList, bool isSTable, bool joinQuery,
|
||||||
bool timeWindowQuery) {
|
bool timeWindowQuery) {
|
||||||
assert(pSelNodeList != NULL && pCmd != NULL);
|
assert(pSelNodeList != NULL && pCmd != NULL);
|
||||||
|
|
||||||
const char* msg1 = "too many items in selection clause";
|
const char* msg1 = "too many items in selection clause";
|
||||||
|
|
||||||
const char* msg2 = "functions or others can not be mixed up";
|
const char* msg2 = "functions or others can not be mixed up";
|
||||||
const char* msg3 = "not support query expression";
|
const char* msg3 = "not support query expression";
|
||||||
const char* msg4 = "only support distinct one tag";
|
const char* msg4 = "only support distinct one tag";
|
||||||
|
@ -1680,7 +1716,7 @@ int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pS
|
||||||
|
|
||||||
// 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 && !tscQueryTags(pQueryInfo) && !tscQueryBlockInfo(pQueryInfo)) {
|
if ((numOfSrcCols <= 0 || !hasNoneUserDefineExpr(pQueryInfo)) && !tscQueryTags(pQueryInfo) && !tscQueryBlockInfo(pQueryInfo)) {
|
||||||
addPrimaryTsColIntoResult(pQueryInfo, pCmd);
|
addPrimaryTsColIntoResult(pQueryInfo, pCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4620,7 +4656,7 @@ int32_t getTimeRange(STimeWindow* win, tSqlExpr* pRight, int32_t optr, int16_t t
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SStrToken token = {.z = pRight->value.pz, .n = pRight->value.nLen, .type = TK_ID};
|
SStrToken token = {.z = pRight->value.pz, .n = pRight->value.nLen, .type = TK_ID};
|
||||||
int32_t len = tSQLGetToken(pRight->value.pz, &token.type);
|
int32_t len = tGetToken(pRight->value.pz, &token.type);
|
||||||
|
|
||||||
if ((token.type != TK_INTEGER && token.type != TK_FLOAT) || len != pRight->value.nLen) {
|
if ((token.type != TK_INTEGER && token.type != TK_FLOAT) || len != pRight->value.nLen) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
|
@ -5507,13 +5543,13 @@ int32_t validateLocalConfig(SMiscInfo* pOptions) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t validateColumnName(char* name) {
|
int32_t validateColumnName(char* name) {
|
||||||
bool ret = isKeyWord(name, (int32_t)strlen(name));
|
bool ret = taosIsKeyWordToken(name, (int32_t)strlen(name));
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SStrToken token = {.z = name};
|
SStrToken token = {.z = name};
|
||||||
token.n = tSQLGetToken(name, &token.type);
|
token.n = tGetToken(name, &token.type);
|
||||||
|
|
||||||
if (token.type != TK_STRING && token.type != TK_ID) {
|
if (token.type != TK_STRING && token.type != TK_ID) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
|
@ -5524,7 +5560,7 @@ int32_t validateColumnName(char* name) {
|
||||||
strntolower(token.z, token.z, token.n);
|
strntolower(token.z, token.z, token.n);
|
||||||
token.n = (uint32_t)strtrim(token.z);
|
token.n = (uint32_t)strtrim(token.z);
|
||||||
|
|
||||||
int32_t k = tSQLGetToken(token.z, &token.type);
|
int32_t k = tGetToken(token.z, &token.type);
|
||||||
if (k != token.n) {
|
if (k != token.n) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
|
@ -5606,7 +5642,6 @@ int32_t validateLimitNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlN
|
||||||
*/
|
*/
|
||||||
// assert(allVgroupInfoRetrieved(pQueryInfo));
|
// assert(allVgroupInfoRetrieved(pQueryInfo));
|
||||||
|
|
||||||
|
|
||||||
// No tables included. No results generated. Query results are empty.
|
// No tables included. No results generated. Query results are empty.
|
||||||
if (pTableMetaInfo->vgroupList->numOfVgroups == 0) {
|
if (pTableMetaInfo->vgroupList->numOfVgroups == 0) {
|
||||||
tscDebug("0x%"PRIx64" no table in super table, no output result", pSql->self);
|
tscDebug("0x%"PRIx64" no table in super table, no output result", pSql->self);
|
||||||
|
@ -7142,6 +7177,7 @@ int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
||||||
SArray* tableNameList = NULL;
|
SArray* tableNameList = NULL;
|
||||||
SArray* pVgroupList = NULL;
|
SArray* pVgroupList = NULL;
|
||||||
SArray* plist = NULL;
|
SArray* plist = NULL;
|
||||||
|
STableMeta* pTableMeta = NULL;
|
||||||
|
|
||||||
pCmd->pTableMetaMap = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
|
pCmd->pTableMetaMap = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
|
||||||
|
|
||||||
|
@ -7174,7 +7210,7 @@ int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
||||||
|
|
||||||
char buf[80 * 1024] = {0};
|
char buf[80 * 1024] = {0};
|
||||||
assert(maxSize < 80 * 1024);
|
assert(maxSize < 80 * 1024);
|
||||||
STableMeta* pTableMeta = (STableMeta*)buf;
|
pTableMeta = calloc(1, maxSize);
|
||||||
|
|
||||||
plist = taosArrayInit(4, POINTER_BYTES);
|
plist = taosArrayInit(4, POINTER_BYTES);
|
||||||
pVgroupList = taosArrayInit(4, POINTER_BYTES);
|
pVgroupList = taosArrayInit(4, POINTER_BYTES);
|
||||||
|
@ -7189,7 +7225,7 @@ int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
||||||
|
|
||||||
if (pTableMeta->id.uid > 0) {
|
if (pTableMeta->id.uid > 0) {
|
||||||
if (pTableMeta->tableType == TSDB_CHILD_TABLE) {
|
if (pTableMeta->tableType == TSDB_CHILD_TABLE) {
|
||||||
code = tscCreateTableMetaFromCChildMeta(pTableMeta, name);
|
code = tscCreateTableMetaFromCChildMeta(pTableMeta, name, buf);
|
||||||
|
|
||||||
// create the child table meta from super table failed, try load it from mnode
|
// create the child table meta from super table failed, try load it from mnode
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
@ -7222,7 +7258,6 @@ int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_end:
|
_end:
|
||||||
|
|
||||||
if (plist != NULL) {
|
if (plist != NULL) {
|
||||||
taosArrayDestroyEx(plist, freeElem);
|
taosArrayDestroyEx(plist, freeElem);
|
||||||
}
|
}
|
||||||
|
@ -7235,6 +7270,8 @@ _end:
|
||||||
taosArrayDestroy(tableNameList);
|
taosArrayDestroy(tableNameList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tfree(pTableMeta);
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7733,4 +7770,3 @@ bool hasNormalColumnFilter(SQueryInfo* pQueryInfo) {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2503,10 +2503,23 @@ int32_t getMultiTableMetaFromMnode(SSqlObj *pSql, SArray* pNameList, SArray* pVg
|
||||||
int32_t tscGetTableMeta(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo) {
|
int32_t tscGetTableMeta(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo) {
|
||||||
assert(tIsValidName(&pTableMetaInfo->name));
|
assert(tIsValidName(&pTableMetaInfo->name));
|
||||||
|
|
||||||
tfree(pTableMetaInfo->pTableMeta);
|
|
||||||
|
|
||||||
uint32_t size = tscGetTableMetaMaxSize();
|
uint32_t size = tscGetTableMetaMaxSize();
|
||||||
|
if (pTableMetaInfo->pTableMeta == NULL) {
|
||||||
pTableMetaInfo->pTableMeta = calloc(1, size);
|
pTableMetaInfo->pTableMeta = calloc(1, size);
|
||||||
|
pTableMetaInfo->tableMetaSize = size;
|
||||||
|
} else if (pTableMetaInfo->tableMetaSize < size) {
|
||||||
|
char *tmp = realloc(pTableMetaInfo->pTableMeta, size);
|
||||||
|
if (tmp == NULL) {
|
||||||
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
pTableMetaInfo->pTableMeta = (STableMeta *)tmp;
|
||||||
|
memset(pTableMetaInfo->pTableMeta, 0, size);
|
||||||
|
pTableMetaInfo->tableMetaSize = size;
|
||||||
|
} else {
|
||||||
|
//uint32_t s = tscGetTableMetaSize(pTableMetaInfo->pTableMeta);
|
||||||
|
memset(pTableMetaInfo->pTableMeta, 0, size);
|
||||||
|
pTableMetaInfo->tableMetaSize = size;
|
||||||
|
}
|
||||||
|
|
||||||
pTableMetaInfo->pTableMeta->tableType = -1;
|
pTableMetaInfo->pTableMeta->tableType = -1;
|
||||||
pTableMetaInfo->pTableMeta->tableInfo.numOfColumns = -1;
|
pTableMetaInfo->pTableMeta->tableInfo.numOfColumns = -1;
|
||||||
|
@ -2518,10 +2531,13 @@ int32_t tscGetTableMeta(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo) {
|
||||||
taosHashGetClone(tscTableMetaInfo, name, len, NULL, pTableMetaInfo->pTableMeta, -1);
|
taosHashGetClone(tscTableMetaInfo, name, len, NULL, pTableMetaInfo->pTableMeta, -1);
|
||||||
|
|
||||||
// TODO resize the tableMeta
|
// TODO resize the tableMeta
|
||||||
|
char buf[80*1024] = {0};
|
||||||
|
assert(size < 80*1024);
|
||||||
|
|
||||||
STableMeta* pMeta = pTableMetaInfo->pTableMeta;
|
STableMeta* pMeta = pTableMetaInfo->pTableMeta;
|
||||||
if (pMeta->id.uid > 0) {
|
if (pMeta->id.uid > 0) {
|
||||||
if (pMeta->tableType == TSDB_CHILD_TABLE) {
|
if (pMeta->tableType == TSDB_CHILD_TABLE) {
|
||||||
int32_t code = tscCreateTableMetaFromCChildMeta(pTableMetaInfo->pTableMeta, name);
|
int32_t code = tscCreateTableMetaFromCChildMeta(pTableMetaInfo->pTableMeta, name, buf);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return getTableMetaFromMnode(pSql, pTableMetaInfo);
|
return getTableMetaFromMnode(pSql, pTableMetaInfo);
|
||||||
}
|
}
|
||||||
|
@ -2698,6 +2714,7 @@ void tscInitMsgsFp() {
|
||||||
tscProcessMsgRsp[TSDB_SQL_ALTER_DB] = tscProcessAlterDbMsgRsp;
|
tscProcessMsgRsp[TSDB_SQL_ALTER_DB] = tscProcessAlterDbMsgRsp;
|
||||||
|
|
||||||
tscProcessMsgRsp[TSDB_SQL_SHOW_CREATE_TABLE] = tscProcessShowCreateRsp;
|
tscProcessMsgRsp[TSDB_SQL_SHOW_CREATE_TABLE] = tscProcessShowCreateRsp;
|
||||||
|
tscProcessMsgRsp[TSDB_SQL_SHOW_CREATE_STABLE] = tscProcessShowCreateRsp;
|
||||||
tscProcessMsgRsp[TSDB_SQL_SHOW_CREATE_DATABASE] = tscProcessShowCreateRsp;
|
tscProcessMsgRsp[TSDB_SQL_SHOW_CREATE_DATABASE] = tscProcessShowCreateRsp;
|
||||||
|
|
||||||
tscKeepConn[TSDB_SQL_SHOW] = 1;
|
tscKeepConn[TSDB_SQL_SHOW] = 1;
|
||||||
|
|
|
@ -461,6 +461,7 @@ static bool needToFetchNewBlock(SSqlObj* pSql) {
|
||||||
pCmd->command == TSDB_SQL_FETCH ||
|
pCmd->command == TSDB_SQL_FETCH ||
|
||||||
pCmd->command == TSDB_SQL_SHOW ||
|
pCmd->command == TSDB_SQL_SHOW ||
|
||||||
pCmd->command == TSDB_SQL_SHOW_CREATE_TABLE ||
|
pCmd->command == TSDB_SQL_SHOW_CREATE_TABLE ||
|
||||||
|
pCmd->command == TSDB_SQL_SHOW_CREATE_STABLE ||
|
||||||
pCmd->command == TSDB_SQL_SHOW_CREATE_DATABASE ||
|
pCmd->command == TSDB_SQL_SHOW_CREATE_DATABASE ||
|
||||||
pCmd->command == TSDB_SQL_SELECT ||
|
pCmd->command == TSDB_SQL_SELECT ||
|
||||||
pCmd->command == TSDB_SQL_DESCRIBE_TABLE ||
|
pCmd->command == TSDB_SQL_DESCRIBE_TABLE ||
|
||||||
|
|
|
@ -55,9 +55,9 @@ static void skipRemainValue(STSBuf* pTSBuf, tVariant* tag1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
while (tsBufNextPos(pTSBuf)) {
|
while (tsBufNextPos(pTSBuf)) {
|
||||||
STSElem el1 = tsBufGetElem(pTSBuf);
|
el1 = tsBufGetElem(pTSBuf);
|
||||||
|
|
||||||
int32_t res = tVariantCompare(el1.tag, tag1);
|
res = tVariantCompare(el1.tag, tag1);
|
||||||
if (res != 0) { // it is a record with new tag
|
if (res != 0) { // it is a record with new tag
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -624,7 +624,13 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) {
|
||||||
int16_t colId = tscGetJoinTagColIdByUid(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->id.uid);
|
int16_t colId = tscGetJoinTagColIdByUid(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->id.uid);
|
||||||
|
|
||||||
// set the tag column id for executor to extract correct tag value
|
// set the tag column id for executor to extract correct tag value
|
||||||
|
#ifndef _TD_NINGSI_60
|
||||||
pExpr->base.param[0] = (tVariant) {.i64 = colId, .nType = TSDB_DATA_TYPE_BIGINT, .nLen = sizeof(int64_t)};
|
pExpr->base.param[0] = (tVariant) {.i64 = colId, .nType = TSDB_DATA_TYPE_BIGINT, .nLen = sizeof(int64_t)};
|
||||||
|
#else
|
||||||
|
pExpr->base.param[0].i64 = colId;
|
||||||
|
pExpr->base.param[0].nType = TSDB_DATA_TYPE_BIGINT;
|
||||||
|
pExpr->base.param[0].nLen = sizeof(int64_t);
|
||||||
|
#endif
|
||||||
pExpr->base.numOfParams = 1;
|
pExpr->base.numOfParams = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2842,7 +2848,7 @@ static void tscRetrieveFromDnodeCallBack(void *param, TAOS_RES *tres, int numOfR
|
||||||
tscDebug("0x%"PRIx64" sub:%p retrieve numOfRows:%d totalNumOfRows:%" PRIu64 " from ep:%s, orderOfSub:%d",
|
tscDebug("0x%"PRIx64" sub:%p retrieve numOfRows:%d totalNumOfRows:%" PRIu64 " from ep:%s, orderOfSub:%d",
|
||||||
pParentSql->self, pSql, pRes->numOfRows, pState->numOfRetrievedRows, pSql->epSet.fqdn[pSql->epSet.inUse], idx);
|
pParentSql->self, pSql, pRes->numOfRows, pState->numOfRetrievedRows, pSql->epSet.fqdn[pSql->epSet.inUse], idx);
|
||||||
|
|
||||||
if (num > tsMaxNumOfOrderedResults && tscIsProjectionQueryOnSTable(pQueryInfo, 0)) {
|
if (num > tsMaxNumOfOrderedResults && tscIsProjectionQueryOnSTable(pQueryInfo, 0) && !(tscGetQueryInfo(&pParentSql->cmd)->distinctTag)) {
|
||||||
tscError("0x%"PRIx64" sub:0x%"PRIx64" num of OrderedRes is too many, max allowed:%" PRId32 " , current:%" PRId64,
|
tscError("0x%"PRIx64" sub:0x%"PRIx64" num of OrderedRes is too many, max allowed:%" PRId32 " , current:%" PRId64,
|
||||||
pParentSql->self, pSql->self, tsMaxNumOfOrderedResults, num);
|
pParentSql->self, pSql->self, tsMaxNumOfOrderedResults, num);
|
||||||
tscAbortFurtherRetryRetrieval(trsupport, tres, TSDB_CODE_TSC_SORTED_RES_TOO_MANY);
|
tscAbortFurtherRetryRetrieval(trsupport, tres, TSDB_CODE_TSC_SORTED_RES_TOO_MANY);
|
||||||
|
|
|
@ -1350,6 +1350,7 @@ int32_t tscCopyDataBlockToPayload(SSqlObj* pSql, STableDataBlocks* pDataBlock) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pTableMetaInfo->pTableMeta = tscTableMetaDup(pDataBlock->pTableMeta);
|
pTableMetaInfo->pTableMeta = tscTableMetaDup(pDataBlock->pTableMeta);
|
||||||
|
pTableMetaInfo->tableMetaSize = tscGetTableMetaSize(pDataBlock->pTableMeta);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1566,6 +1567,8 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql, bool freeBlockMap) {
|
||||||
|
|
||||||
STableDataBlocks* pOneTableBlock = *p;
|
STableDataBlocks* pOneTableBlock = *p;
|
||||||
while(pOneTableBlock) {
|
while(pOneTableBlock) {
|
||||||
|
SSubmitBlk* pBlocks = (SSubmitBlk*) pOneTableBlock->pData;
|
||||||
|
if (pBlocks->numOfRows > 0) {
|
||||||
// the maximum expanded size in byte when a row-wise data is converted to SDataRow format
|
// the maximum expanded size in byte when a row-wise data is converted to SDataRow format
|
||||||
int32_t expandSize = getRowExpandSize(pOneTableBlock->pTableMeta);
|
int32_t expandSize = getRowExpandSize(pOneTableBlock->pTableMeta);
|
||||||
STableDataBlocks* dataBuf = NULL;
|
STableDataBlocks* dataBuf = NULL;
|
||||||
|
@ -1579,7 +1582,6 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql, bool freeBlockMap) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSubmitBlk* pBlocks = (SSubmitBlk*) pOneTableBlock->pData;
|
|
||||||
int64_t destSize = dataBuf->size + pOneTableBlock->size + pBlocks->numOfRows * expandSize + sizeof(STColumn) * tscGetNumOfColumns(pOneTableBlock->pTableMeta);
|
int64_t destSize = dataBuf->size + pOneTableBlock->size + pBlocks->numOfRows * expandSize + sizeof(STColumn) * tscGetNumOfColumns(pOneTableBlock->pTableMeta);
|
||||||
|
|
||||||
if (dataBuf->nAllocSize < destSize) {
|
if (dataBuf->nAllocSize < destSize) {
|
||||||
|
@ -1627,6 +1629,11 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql, bool freeBlockMap) {
|
||||||
pBlocks->dataLen = htonl(finalLen);
|
pBlocks->dataLen = htonl(finalLen);
|
||||||
dataBuf->numOfTables += 1;
|
dataBuf->numOfTables += 1;
|
||||||
|
|
||||||
|
pBlocks->numOfRows = 0;
|
||||||
|
}else {
|
||||||
|
tscDebug("0x%"PRIx64" table %s data block is empty", pSql->self, pOneTableBlock->tableName.tname);
|
||||||
|
}
|
||||||
|
|
||||||
p = taosHashIterate(pCmd->pTableBlockHashList, p);
|
p = taosHashIterate(pCmd->pTableBlockHashList, p);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
break;
|
break;
|
||||||
|
@ -1748,7 +1755,7 @@ int16_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index) {
|
||||||
return pInfo->pExpr->base.offset;
|
return pInfo->pExpr->base.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tscFieldInfoCompare(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2) {
|
int32_t tscFieldInfoCompare(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2, int32_t *diffSize) {
|
||||||
assert(pFieldInfo1 != NULL && pFieldInfo2 != NULL);
|
assert(pFieldInfo1 != NULL && pFieldInfo2 != NULL);
|
||||||
|
|
||||||
if (pFieldInfo1->numOfOutput != pFieldInfo2->numOfOutput) {
|
if (pFieldInfo1->numOfOutput != pFieldInfo2->numOfOutput) {
|
||||||
|
@ -1760,15 +1767,37 @@ int32_t tscFieldInfoCompare(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFi
|
||||||
TAOS_FIELD* pField2 = tscFieldInfoGetField((SFieldInfo*) pFieldInfo2, i);
|
TAOS_FIELD* pField2 = tscFieldInfoGetField((SFieldInfo*) pFieldInfo2, i);
|
||||||
|
|
||||||
if (pField1->type != pField2->type ||
|
if (pField1->type != pField2->type ||
|
||||||
pField1->bytes != pField2->bytes ||
|
|
||||||
strcasecmp(pField1->name, pField2->name) != 0) {
|
strcasecmp(pField1->name, pField2->name) != 0) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pField1->bytes != pField2->bytes) {
|
||||||
|
*diffSize = 1;
|
||||||
|
|
||||||
|
if (pField2->bytes > pField1->bytes) {
|
||||||
|
assert(IS_VAR_DATA_TYPE(pField1->type));
|
||||||
|
pField1->bytes = pField2->bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t tscFieldInfoSetSize(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2) {
|
||||||
|
assert(pFieldInfo1 != NULL && pFieldInfo2 != NULL);
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < pFieldInfo1->numOfOutput; ++i) {
|
||||||
|
TAOS_FIELD* pField1 = tscFieldInfoGetField((SFieldInfo*) pFieldInfo1, i);
|
||||||
|
TAOS_FIELD* pField2 = tscFieldInfoGetField((SFieldInfo*) pFieldInfo2, i);
|
||||||
|
|
||||||
|
pField2->bytes = pField1->bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int32_t tscGetResRowLength(SArray* pExprList) {
|
int32_t tscGetResRowLength(SArray* pExprList) {
|
||||||
size_t num = taosArrayGetSize(pExprList);
|
size_t num = taosArrayGetSize(pExprList);
|
||||||
if (num == 0) {
|
if (num == 0) {
|
||||||
|
@ -2246,7 +2275,7 @@ void tscColumnListDestroy(SArray* pColumnList) {
|
||||||
static int32_t validateQuoteToken(SStrToken* pToken) {
|
static int32_t validateQuoteToken(SStrToken* pToken) {
|
||||||
tscDequoteAndTrimToken(pToken);
|
tscDequoteAndTrimToken(pToken);
|
||||||
|
|
||||||
int32_t k = tSQLGetToken(pToken->z, &pToken->type);
|
int32_t k = tGetToken(pToken->z, &pToken->type);
|
||||||
|
|
||||||
if (pToken->type == TK_STRING) {
|
if (pToken->type == TK_STRING) {
|
||||||
return tscValidateName(pToken);
|
return tscValidateName(pToken);
|
||||||
|
@ -2314,7 +2343,7 @@ int32_t tscValidateName(SStrToken* pToken) {
|
||||||
tscStrToLower(pToken->z, pToken->n);
|
tscStrToLower(pToken->z, pToken->n);
|
||||||
//pToken->n = (uint32_t)strtrim(pToken->z);
|
//pToken->n = (uint32_t)strtrim(pToken->z);
|
||||||
|
|
||||||
int len = tSQLGetToken(pToken->z, &pToken->type);
|
int len = tGetToken(pToken->z, &pToken->type);
|
||||||
|
|
||||||
// single token, validate it
|
// single token, validate it
|
||||||
if (len == pToken->n) {
|
if (len == pToken->n) {
|
||||||
|
@ -2340,7 +2369,7 @@ int32_t tscValidateName(SStrToken* pToken) {
|
||||||
pToken->n = (uint32_t)strtrim(pToken->z);
|
pToken->n = (uint32_t)strtrim(pToken->z);
|
||||||
}
|
}
|
||||||
|
|
||||||
pToken->n = tSQLGetToken(pToken->z, &pToken->type);
|
pToken->n = tGetToken(pToken->z, &pToken->type);
|
||||||
if (pToken->z[pToken->n] != TS_PATH_DELIMITER[0]) {
|
if (pToken->z[pToken->n] != TS_PATH_DELIMITER[0]) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
|
@ -2357,7 +2386,7 @@ int32_t tscValidateName(SStrToken* pToken) {
|
||||||
|
|
||||||
pToken->z = sep + 1;
|
pToken->z = sep + 1;
|
||||||
pToken->n = (uint32_t)(oldLen - (sep - pStr) - 1);
|
pToken->n = (uint32_t)(oldLen - (sep - pStr) - 1);
|
||||||
int32_t len = tSQLGetToken(pToken->z, &pToken->type);
|
int32_t len = tGetToken(pToken->z, &pToken->type);
|
||||||
if (len != pToken->n || (pToken->type != TK_STRING && pToken->type != TK_ID)) {
|
if (len != pToken->n || (pToken->type != TK_STRING && pToken->type != TK_ID)) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
|
@ -2893,6 +2922,11 @@ STableMetaInfo* tscAddTableMetaInfo(SQueryInfo* pQueryInfo, SName* name, STableM
|
||||||
}
|
}
|
||||||
|
|
||||||
pTableMetaInfo->pTableMeta = pTableMeta;
|
pTableMetaInfo->pTableMeta = pTableMeta;
|
||||||
|
if (pTableMetaInfo->pTableMeta == NULL) {
|
||||||
|
pTableMetaInfo->tableMetaSize = 0;
|
||||||
|
} else {
|
||||||
|
pTableMetaInfo->tableMetaSize = tscGetTableMetaSize(pTableMeta);
|
||||||
|
}
|
||||||
|
|
||||||
if (vgroupList != NULL) {
|
if (vgroupList != NULL) {
|
||||||
pTableMetaInfo->vgroupList = tscVgroupInfoClone(vgroupList);
|
pTableMetaInfo->vgroupList = tscVgroupInfoClone(vgroupList);
|
||||||
|
@ -3168,6 +3202,7 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t
|
||||||
|
|
||||||
pFinalInfo = tscAddTableMetaInfo(pNewQueryInfo, &pTableMetaInfo->name, pTableMeta, pTableMetaInfo->vgroupList,
|
pFinalInfo = tscAddTableMetaInfo(pNewQueryInfo, &pTableMetaInfo->name, pTableMeta, pTableMetaInfo->vgroupList,
|
||||||
pTableMetaInfo->tagColList, pTableMetaInfo->pVgroupTables);
|
pTableMetaInfo->tagColList, pTableMetaInfo->pVgroupTables);
|
||||||
|
|
||||||
} else { // transfer the ownership of pTableMeta to the newly create sql object.
|
} else { // transfer the ownership of pTableMeta to the newly create sql object.
|
||||||
STableMetaInfo* pPrevInfo = tscGetTableMetaInfoFromCmd(&pPrevSql->cmd, 0);
|
STableMetaInfo* pPrevInfo = tscGetTableMetaInfoFromCmd(&pPrevSql->cmd, 0);
|
||||||
if (pPrevInfo->pTableMeta && pPrevInfo->pTableMeta->tableType < 0) {
|
if (pPrevInfo->pTableMeta && pPrevInfo->pTableMeta->tableType < 0) {
|
||||||
|
@ -3377,16 +3412,21 @@ void tscDoQuery(SSqlObj* pSql) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pCmd->command == TSDB_SQL_SELECT) {
|
|
||||||
tscAddIntoSqlList(pSql);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pCmd->dataSourceType == DATA_FROM_DATA_FILE) {
|
if (pCmd->dataSourceType == DATA_FROM_DATA_FILE) {
|
||||||
tscImportDataFromFile(pSql);
|
tscImportDataFromFile(pSql);
|
||||||
} else {
|
} else {
|
||||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
|
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
|
||||||
uint16_t type = pQueryInfo->type;
|
uint16_t type = pQueryInfo->type;
|
||||||
|
|
||||||
|
if ((pCmd->command == TSDB_SQL_SELECT) && (!TSDB_QUERY_HAS_TYPE(type, TSDB_QUERY_TYPE_SUBQUERY)) && (!TSDB_QUERY_HAS_TYPE(type, TSDB_QUERY_TYPE_STABLE_SUBQUERY))) {
|
||||||
|
tscAddIntoSqlList(pSql);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TSDB_QUERY_HAS_TYPE(type, TSDB_QUERY_TYPE_INSERT)) { // multi-vnodes insertion
|
||||||
|
tscHandleMultivnodeInsert(pSql);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (QUERY_IS_JOIN_QUERY(type)) {
|
if (QUERY_IS_JOIN_QUERY(type)) {
|
||||||
if (!TSDB_QUERY_HAS_TYPE(type, TSDB_QUERY_TYPE_SUBQUERY)) {
|
if (!TSDB_QUERY_HAS_TYPE(type, TSDB_QUERY_TYPE_SUBQUERY)) {
|
||||||
tscHandleMasterJoinQuery(pSql);
|
tscHandleMasterJoinQuery(pSql);
|
||||||
|
@ -3648,7 +3688,13 @@ void tscTryQueryNextClause(SSqlObj* pSql, __async_cb_func_t fp) {
|
||||||
|
|
||||||
//backup the total number of result first
|
//backup the total number of result first
|
||||||
int64_t num = pRes->numOfTotal + pRes->numOfClauseTotal;
|
int64_t num = pRes->numOfTotal + pRes->numOfClauseTotal;
|
||||||
|
|
||||||
|
|
||||||
|
// DON't free final since it may be recoreded and used later in APP
|
||||||
|
TAOS_FIELD* finalBk = pRes->final;
|
||||||
|
pRes->final = NULL;
|
||||||
tscFreeSqlResult(pSql);
|
tscFreeSqlResult(pSql);
|
||||||
|
pRes->final = finalBk;
|
||||||
|
|
||||||
pRes->numOfTotal = num;
|
pRes->numOfTotal = num;
|
||||||
|
|
||||||
|
@ -3881,11 +3927,9 @@ CChildTableMeta* tscCreateChildMeta(STableMeta* pTableMeta) {
|
||||||
return cMeta;
|
return cMeta;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tscCreateTableMetaFromCChildMeta(STableMeta* pChild, const char* name) {
|
int32_t tscCreateTableMetaFromCChildMeta(STableMeta* pChild, const char* name, void* buf) {
|
||||||
assert(pChild != NULL);
|
assert(pChild != NULL && buf != NULL);
|
||||||
|
STableMeta* p = buf;
|
||||||
uint32_t size = tscGetTableMetaMaxSize();
|
|
||||||
STableMeta* p = calloc(1, size);
|
|
||||||
|
|
||||||
taosHashGetClone(tscTableMetaInfo, pChild->sTableName, strnlen(pChild->sTableName, TSDB_TABLE_FNAME_LEN), NULL, p, -1);
|
taosHashGetClone(tscTableMetaInfo, pChild->sTableName, strnlen(pChild->sTableName, TSDB_TABLE_FNAME_LEN), NULL, p, -1);
|
||||||
if (p->id.uid > 0) { // tableMeta exists, build child table meta and return
|
if (p->id.uid > 0) { // tableMeta exists, build child table meta and return
|
||||||
|
@ -3896,13 +3940,9 @@ int32_t tscCreateTableMetaFromCChildMeta(STableMeta* pChild, const char* name) {
|
||||||
int32_t total = pChild->tableInfo.numOfColumns + pChild->tableInfo.numOfTags;
|
int32_t total = pChild->tableInfo.numOfColumns + pChild->tableInfo.numOfTags;
|
||||||
|
|
||||||
memcpy(pChild->schema, p->schema, sizeof(SSchema) *total);
|
memcpy(pChild->schema, p->schema, sizeof(SSchema) *total);
|
||||||
|
|
||||||
tfree(p);
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
} else { // super table has been removed, current tableMeta is also expired. remove it here
|
} else { // super table has been removed, current tableMeta is also expired. remove it here
|
||||||
taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
|
taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
|
||||||
|
|
||||||
tfree(p);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4257,7 +4297,7 @@ int tscTransferTableNameList(SSqlObj *pSql, const char *pNameList, int32_t lengt
|
||||||
len = (int32_t)strtrim(tblName);
|
len = (int32_t)strtrim(tblName);
|
||||||
|
|
||||||
SStrToken sToken = {.n = len, .type = TK_ID, .z = tblName};
|
SStrToken sToken = {.n = len, .type = TK_ID, .z = tblName};
|
||||||
tSQLGetToken(tblName, &sToken.type);
|
tGetToken(tblName, &sToken.type);
|
||||||
|
|
||||||
// Check if the table name available or not
|
// Check if the table name available or not
|
||||||
if (tscValidateName(&sToken) != TSDB_CODE_SUCCESS) {
|
if (tscValidateName(&sToken) != TSDB_CODE_SUCCESS) {
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "taos.h"
|
#include "taos.h"
|
||||||
#include "tstoken.h"
|
#include "ttoken.h"
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
@ -98,7 +98,7 @@ TEST(testCase, parse_time) {
|
||||||
taosParseTime(t41, &time, strlen(t41), TSDB_TIME_PRECISION_MILLI, 0);
|
taosParseTime(t41, &time, strlen(t41), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
EXPECT_EQ(time, 852048000999);
|
EXPECT_EQ(time, 852048000999);
|
||||||
|
|
||||||
int64_t k = timezone;
|
// int64_t k = timezone;
|
||||||
char t42[] = "1997-1-1T0:0:0.999999999Z";
|
char t42[] = "1997-1-1T0:0:0.999999999Z";
|
||||||
taosParseTime(t42, &time, strlen(t42), TSDB_TIME_PRECISION_MILLI, 0);
|
taosParseTime(t42, &time, strlen(t42), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
EXPECT_EQ(time, 852048000999 - timezone * MILLISECOND_PER_SECOND);
|
EXPECT_EQ(time, 852048000999 - timezone * MILLISECOND_PER_SECOND);
|
||||||
|
@ -163,7 +163,7 @@ TEST(testCase, parse_time) {
|
||||||
taosParseTime(t13, &time, strlen(t13), TSDB_TIME_PRECISION_MILLI, 0);
|
taosParseTime(t13, &time, strlen(t13), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
EXPECT_EQ(time, -28800 * MILLISECOND_PER_SECOND);
|
EXPECT_EQ(time, -28800 * MILLISECOND_PER_SECOND);
|
||||||
|
|
||||||
char* t = "2021-01-08T02:11:40.000+00:00";
|
char t[] = "2021-01-08T02:11:40.000+00:00";
|
||||||
taosParseTime(t, &time, strlen(t), TSDB_TIME_PRECISION_MILLI, 0);
|
taosParseTime(t, &time, strlen(t), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
printf("%ld\n", time);
|
printf("%ld\n", time);
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,6 +80,7 @@ enum {
|
||||||
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_TABLE_JOIN_RETRIEVE, "join-retrieve" )
|
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_TABLE_JOIN_RETRIEVE, "join-retrieve" )
|
||||||
|
|
||||||
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_SHOW_CREATE_TABLE, "show-create-table")
|
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_SHOW_CREATE_TABLE, "show-create-table")
|
||||||
|
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_SHOW_CREATE_STABLE, "show-create-stable")
|
||||||
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_SHOW_CREATE_DATABASE, "show-create-database")
|
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_SHOW_CREATE_DATABASE, "show-create-database")
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -15,10 +15,7 @@
|
||||||
#ifndef _TD_DATA_FORMAT_H_
|
#ifndef _TD_DATA_FORMAT_H_
|
||||||
#define _TD_DATA_FORMAT_H_
|
#define _TD_DATA_FORMAT_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include "os.h"
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "talgo.h"
|
#include "talgo.h"
|
||||||
#include "ttype.h"
|
#include "ttype.h"
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
|
|
|
@ -87,10 +87,9 @@ tExprNode* exprTreeFromBinary(const void* data, size_t size);
|
||||||
tExprNode* exprTreeFromTableName(const char* tbnameCond);
|
tExprNode* exprTreeFromTableName(const char* tbnameCond);
|
||||||
tExprNode* exprdup(tExprNode* pTree);
|
tExprNode* exprdup(tExprNode* pTree);
|
||||||
|
|
||||||
bool exprTreeApplyFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp *param);
|
void exprTreeToBinary(SBufferWriter* bw, tExprNode* pExprTree);
|
||||||
|
|
||||||
typedef void (*_arithmetic_operator_fn_t)(void *left, int32_t numLeft, int32_t leftType, void *right, int32_t numRight,
|
bool exprTreeApplyFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp *param);
|
||||||
int32_t rightType, void *output, int32_t order);
|
|
||||||
|
|
||||||
void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, void *param, int32_t order,
|
void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, void *param, int32_t order,
|
||||||
char *(*cb)(void *, const char*, int32_t));
|
char *(*cb)(void *, const char*, int32_t));
|
||||||
|
|
|
@ -44,6 +44,7 @@ extern int32_t tsDnodeId;
|
||||||
// common
|
// common
|
||||||
extern int tsRpcTimer;
|
extern int tsRpcTimer;
|
||||||
extern int tsRpcMaxTime;
|
extern int tsRpcMaxTime;
|
||||||
|
extern int tsRpcForceTcp; // all commands go to tcp protocol if this is enabled
|
||||||
extern int32_t tsMaxConnections;
|
extern int32_t tsMaxConnections;
|
||||||
extern int32_t tsMaxShellConns;
|
extern int32_t tsMaxShellConns;
|
||||||
extern int32_t tsShellActivityTimer;
|
extern int32_t tsShellActivityTimer;
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
#include "tstoken.h"
|
#include "ttoken.h"
|
||||||
#include "tvariant.h"
|
#include "tvariant.h"
|
||||||
|
|
||||||
typedef struct SDataStatis {
|
typedef struct SDataStatis {
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
#ifndef TDENGINE_TVARIANT_H
|
#ifndef TDENGINE_TVARIANT_H
|
||||||
#define TDENGINE_TVARIANT_H
|
#define TDENGINE_TVARIANT_H
|
||||||
|
|
||||||
#include "tstoken.h"
|
|
||||||
#include "tarray.h"
|
#include "tarray.h"
|
||||||
|
#include "ttoken.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
|
@ -48,6 +48,7 @@ int32_t tsDnodeId = 0;
|
||||||
// common
|
// common
|
||||||
int32_t tsRpcTimer = 1000;
|
int32_t tsRpcTimer = 1000;
|
||||||
int32_t tsRpcMaxTime = 600; // seconds;
|
int32_t tsRpcMaxTime = 600; // seconds;
|
||||||
|
int32_t tsRpcForceTcp = 0; //disable this, means query, show command use udp protocol as default
|
||||||
int32_t tsMaxShellConns = 50000;
|
int32_t tsMaxShellConns = 50000;
|
||||||
int32_t tsMaxConnections = 5000;
|
int32_t tsMaxConnections = 5000;
|
||||||
int32_t tsShellActivityTimer = 3; // second
|
int32_t tsShellActivityTimer = 3; // second
|
||||||
|
@ -625,6 +626,16 @@ static void doInitGlobalConfig(void) {
|
||||||
cfg.unitType = TAOS_CFG_UTYPE_MS;
|
cfg.unitType = TAOS_CFG_UTYPE_MS;
|
||||||
taosInitConfigOption(cfg);
|
taosInitConfigOption(cfg);
|
||||||
|
|
||||||
|
cfg.option = "rpcForceTcp";
|
||||||
|
cfg.ptr = &tsRpcForceTcp;
|
||||||
|
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||||
|
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_CLIENT;
|
||||||
|
cfg.minValue = 0;
|
||||||
|
cfg.maxValue = 1;
|
||||||
|
cfg.ptrLength = 0;
|
||||||
|
cfg.unitType = TAOS_CFG_UTYPE_NONE;
|
||||||
|
taosInitConfigOption(cfg);
|
||||||
|
|
||||||
cfg.option = "rpcMaxTime";
|
cfg.option = "rpcMaxTime";
|
||||||
cfg.ptr = &tsRpcMaxTime;
|
cfg.ptr = &tsRpcMaxTime;
|
||||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||||
|
@ -921,7 +932,7 @@ static void doInitGlobalConfig(void) {
|
||||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_CLIENT | TSDB_CFG_CTYPE_B_SHOW;
|
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_CLIENT | TSDB_CFG_CTYPE_B_SHOW;
|
||||||
cfg.minValue = -1;
|
cfg.minValue = -1;
|
||||||
cfg.maxValue = 10000000000.0f;
|
cfg.maxValue = 100000000.0f;
|
||||||
cfg.ptrLength = 0;
|
cfg.ptrLength = 0;
|
||||||
cfg.unitType = TAOS_CFG_UTYPE_NONE;
|
cfg.unitType = TAOS_CFG_UTYPE_NONE;
|
||||||
taosInitConfigOption(cfg);
|
taosInitConfigOption(cfg);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
|
|
||||||
#include "tname.h"
|
#include "tname.h"
|
||||||
#include "tstoken.h"
|
#include "ttoken.h"
|
||||||
#include "tvariant.h"
|
#include "tvariant.h"
|
||||||
|
|
||||||
#define VALIDNUMOFCOLS(x) ((x) >= TSDB_MIN_COLUMNS && (x) <= TSDB_MAX_COLUMNS)
|
#define VALIDNUMOFCOLS(x) ((x) >= TSDB_MIN_COLUMNS && (x) <= TSDB_MAX_COLUMNS)
|
||||||
|
|
|
@ -14,14 +14,14 @@
|
||||||
*/
|
*/
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
#include "tvariant.h"
|
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "taos.h"
|
#include "taos.h"
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
#include "tstoken.h"
|
#include "ttoken.h"
|
||||||
#include "ttokendef.h"
|
#include "ttokendef.h"
|
||||||
#include "tutil.h"
|
|
||||||
#include "ttype.h"
|
#include "ttype.h"
|
||||||
|
#include "tutil.h"
|
||||||
|
#include "tvariant.h"
|
||||||
|
|
||||||
void tVariantCreate(tVariant *pVar, SStrToken *token) {
|
void tVariantCreate(tVariant *pVar, SStrToken *token) {
|
||||||
int32_t ret = 0;
|
int32_t ret = 0;
|
||||||
|
@ -49,7 +49,7 @@ void tVariantCreate(tVariant *pVar, SStrToken *token) {
|
||||||
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 != 0) {
|
||||||
SStrToken t = {0};
|
SStrToken t = {0};
|
||||||
tSQLGetToken(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
|
||||||
pVar->nType = -1; // -1 means error type
|
pVar->nType = -1; // -1 means error type
|
||||||
return;
|
return;
|
||||||
|
@ -460,7 +460,7 @@ static FORCE_INLINE int32_t convertToInteger(tVariant *pVariant, int64_t *result
|
||||||
*result = (int64_t) pVariant->dKey;
|
*result = (int64_t) pVariant->dKey;
|
||||||
} else if (pVariant->nType == TSDB_DATA_TYPE_BINARY) {
|
} else if (pVariant->nType == TSDB_DATA_TYPE_BINARY) {
|
||||||
SStrToken token = {.z = pVariant->pz, .n = pVariant->nLen};
|
SStrToken token = {.z = pVariant->pz, .n = pVariant->nLen};
|
||||||
/*int32_t n = */tSQLGetToken(pVariant->pz, &token.type);
|
/*int32_t n = */tGetToken(pVariant->pz, &token.type);
|
||||||
|
|
||||||
if (token.type == TK_NULL) {
|
if (token.type == TK_NULL) {
|
||||||
if (releaseVariantPtr) {
|
if (releaseVariantPtr) {
|
||||||
|
@ -495,10 +495,10 @@ static FORCE_INLINE int32_t convertToInteger(tVariant *pVariant, int64_t *result
|
||||||
wchar_t *endPtr = NULL;
|
wchar_t *endPtr = NULL;
|
||||||
|
|
||||||
SStrToken token = {0};
|
SStrToken token = {0};
|
||||||
token.n = tSQLGetToken(pVariant->pz, &token.type);
|
token.n = tGetToken(pVariant->pz, &token.type);
|
||||||
|
|
||||||
if (token.type == TK_MINUS || token.type == TK_PLUS) {
|
if (token.type == TK_MINUS || token.type == TK_PLUS) {
|
||||||
token.n = tSQLGetToken(pVariant->pz + token.n, &token.type);
|
token.n = tGetToken(pVariant->pz + token.n, &token.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token.type == TK_FLOAT) {
|
if (token.type == TK_FLOAT) {
|
||||||
|
|
|
@ -8,7 +8,7 @@ IF (TD_MVN_INSTALLED)
|
||||||
ADD_CUSTOM_COMMAND(OUTPUT ${JDBC_CMD_NAME}
|
ADD_CUSTOM_COMMAND(OUTPUT ${JDBC_CMD_NAME}
|
||||||
POST_BUILD
|
POST_BUILD
|
||||||
COMMAND mvn -Dmaven.test.skip=true install -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml
|
COMMAND mvn -Dmaven.test.skip=true install -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.28-dist.jar ${LIBRARY_OUTPUT_PATH}
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.29.jar ${LIBRARY_OUTPUT_PATH}
|
||||||
COMMAND mvn -Dmaven.test.skip=true clean -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml
|
COMMAND mvn -Dmaven.test.skip=true clean -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml
|
||||||
COMMENT "build jdbc driver")
|
COMMENT "build jdbc driver")
|
||||||
ADD_CUSTOM_TARGET(${JDBC_TARGET_NAME} ALL WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} DEPENDS ${JDBC_CMD_NAME})
|
ADD_CUSTOM_TARGET(${JDBC_TARGET_NAME} ALL WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} DEPENDS ${JDBC_CMD_NAME})
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
<groupId>com.taosdata.jdbc</groupId>
|
<groupId>com.taosdata.jdbc</groupId>
|
||||||
<artifactId>taos-jdbcdriver</artifactId>
|
<artifactId>taos-jdbcdriver</artifactId>
|
||||||
<version>2.0.28</version>
|
<version>2.0.29</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>JDBCDriver</name>
|
<name>JDBCDriver</name>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>com.taosdata.jdbc</groupId>
|
<groupId>com.taosdata.jdbc</groupId>
|
||||||
<artifactId>taos-jdbcdriver</artifactId>
|
<artifactId>taos-jdbcdriver</artifactId>
|
||||||
<version>2.0.28</version>
|
<version>2.0.29</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<name>JDBCDriver</name>
|
<name>JDBCDriver</name>
|
||||||
<url>https://github.com/taosdata/TDengine/tree/master/src/connector/jdbc</url>
|
<url>https://github.com/taosdata/TDengine/tree/master/src/connector/jdbc</url>
|
||||||
|
@ -122,6 +122,7 @@
|
||||||
<exclude>**/FailOverTest.java</exclude>
|
<exclude>**/FailOverTest.java</exclude>
|
||||||
<exclude>**/InvalidResultSetPointerTest.java</exclude>
|
<exclude>**/InvalidResultSetPointerTest.java</exclude>
|
||||||
<exclude>**/RestfulConnectionTest.java</exclude>
|
<exclude>**/RestfulConnectionTest.java</exclude>
|
||||||
|
<exclude>**/TD4144Test.java</exclude>
|
||||||
</excludes>
|
</excludes>
|
||||||
<testFailureIgnore>true</testFailureIgnore>
|
<testFailureIgnore>true</testFailureIgnore>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
|
@ -84,9 +84,11 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
public InputStream getUnicodeStream(int columnIndex) throws SQLException {
|
public InputStream getUnicodeStream(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed()) {
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
|
||||||
|
}
|
||||||
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
||||||
}
|
}
|
||||||
|
@ -171,6 +173,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
public InputStream getUnicodeStream(String columnLabel) throws SQLException {
|
public InputStream getUnicodeStream(String columnLabel) throws SQLException {
|
||||||
return getUnicodeStream(findColumn(columnLabel));
|
return getUnicodeStream(findColumn(columnLabel));
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ public class TSDBConnection extends AbstractConnection {
|
||||||
this.databaseMetaData.setConnection(this);
|
this.databaseMetaData.setConnection(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TSDBJNIConnector getConnection() {
|
public TSDBJNIConnector getConnector() {
|
||||||
return this.connector;
|
return this.connector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ public class TSDBConnection extends AbstractConnection {
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new TSDBStatement(this, this.connector);
|
return new TSDBStatement(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TSDBSubscribe subscribe(String topic, String sql, boolean restart) throws SQLException {
|
public TSDBSubscribe subscribe(String topic, String sql, boolean restart) throws SQLException {
|
||||||
|
@ -74,14 +74,18 @@ public class TSDBConnection extends AbstractConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
public PreparedStatement prepareStatement(String sql) throws SQLException {
|
public PreparedStatement prepareStatement(String sql) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed()) {
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
|
||||||
return new TSDBPreparedStatement(this, this.connector, sql);
|
}
|
||||||
|
|
||||||
|
return new TSDBPreparedStatement(this, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() throws SQLException {
|
public void close() throws SQLException {
|
||||||
if (isClosed)
|
if (isClosed) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.connector.closeConnection();
|
this.connector.closeConnection();
|
||||||
this.isClosed = true;
|
this.isClosed = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ public abstract class TSDBConstants {
|
||||||
public static final int JNI_FETCH_END = -6;
|
public static final int JNI_FETCH_END = -6;
|
||||||
public static final int JNI_OUT_OF_MEMORY = -7;
|
public static final int JNI_OUT_OF_MEMORY = -7;
|
||||||
// TSDB Data Types
|
// TSDB Data Types
|
||||||
|
public static final int TSDB_DATA_TYPE_NULL = 0;
|
||||||
public static final int TSDB_DATA_TYPE_BOOL = 1;
|
public static final int TSDB_DATA_TYPE_BOOL = 1;
|
||||||
public static final int TSDB_DATA_TYPE_TINYINT = 2;
|
public static final int TSDB_DATA_TYPE_TINYINT = 2;
|
||||||
public static final int TSDB_DATA_TYPE_SMALLINT = 3;
|
public static final int TSDB_DATA_TYPE_SMALLINT = 3;
|
||||||
|
|
|
@ -104,7 +104,7 @@ public class TSDBDriver extends AbstractDriver {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
java.sql.DriverManager.registerDriver(new TSDBDriver());
|
DriverManager.registerDriver(new TSDBDriver());
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw TSDBError.createRuntimeException(TSDBErrorNumbers.ERROR_CANNOT_REGISTER_JNI_DRIVER, e);
|
throw TSDBError.createRuntimeException(TSDBErrorNumbers.ERROR_CANNOT_REGISTER_JNI_DRIVER, e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ package com.taosdata.jdbc;
|
||||||
|
|
||||||
import com.taosdata.jdbc.utils.TaosInfo;
|
import com.taosdata.jdbc.utils.TaosInfo;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.SQLWarning;
|
import java.sql.SQLWarning;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -29,10 +30,13 @@ public class TSDBJNIConnector {
|
||||||
private static volatile Boolean isInitialized = false;
|
private static volatile Boolean isInitialized = false;
|
||||||
|
|
||||||
private TaosInfo taosInfo = TaosInfo.getInstance();
|
private TaosInfo taosInfo = TaosInfo.getInstance();
|
||||||
|
|
||||||
// Connection pointer used in C
|
// Connection pointer used in C
|
||||||
private long taos = TSDBConstants.JNI_NULL_POINTER;
|
private long taos = TSDBConstants.JNI_NULL_POINTER;
|
||||||
|
|
||||||
// result set status in current connection
|
// result set status in current connection
|
||||||
private boolean isResultsetClosed = true;
|
private boolean isResultsetClosed;
|
||||||
|
|
||||||
private int affectedRows = -1;
|
private int affectedRows = -1;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
@ -75,7 +79,6 @@ public class TSDBJNIConnector {
|
||||||
|
|
||||||
public boolean connect(String host, int port, String dbName, String user, String password) throws SQLException {
|
public boolean connect(String host, int port, String dbName, String user, String password) throws SQLException {
|
||||||
if (this.taos != TSDBConstants.JNI_NULL_POINTER) {
|
if (this.taos != TSDBConstants.JNI_NULL_POINTER) {
|
||||||
// this.closeConnectionImp(this.taos);
|
|
||||||
closeConnection();
|
closeConnection();
|
||||||
this.taos = TSDBConstants.JNI_NULL_POINTER;
|
this.taos = TSDBConstants.JNI_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
@ -97,12 +100,6 @@ public class TSDBJNIConnector {
|
||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
*/
|
*/
|
||||||
public long executeQuery(String sql) throws SQLException {
|
public long executeQuery(String sql) throws SQLException {
|
||||||
// close previous result set if the user forgets to invoke the
|
|
||||||
// free method to close previous result set.
|
|
||||||
// if (!this.isResultsetClosed) {
|
|
||||||
// freeResultSet(taosResultSetPointer);
|
|
||||||
// }
|
|
||||||
|
|
||||||
Long pSql = 0l;
|
Long pSql = 0l;
|
||||||
try {
|
try {
|
||||||
pSql = this.executeQueryImp(sql.getBytes(TaosGlobalConfig.getCharset()), this.taos);
|
pSql = this.executeQueryImp(sql.getBytes(TaosGlobalConfig.getCharset()), this.taos);
|
||||||
|
@ -135,6 +132,7 @@ public class TSDBJNIConnector {
|
||||||
|
|
||||||
// Try retrieving result set for the executed SQL using the current connection pointer.
|
// Try retrieving result set for the executed SQL using the current connection pointer.
|
||||||
pSql = this.getResultSetImp(this.taos, pSql);
|
pSql = this.getResultSetImp(this.taos, pSql);
|
||||||
|
// if pSql == 0L that means resultset is closed
|
||||||
isResultsetClosed = (pSql == TSDBConstants.JNI_NULL_POINTER);
|
isResultsetClosed = (pSql == TSDBConstants.JNI_NULL_POINTER);
|
||||||
|
|
||||||
return pSql;
|
return pSql;
|
||||||
|
@ -172,34 +170,11 @@ public class TSDBJNIConnector {
|
||||||
* Free result set operation from C to release result set pointer by JNI
|
* Free result set operation from C to release result set pointer by JNI
|
||||||
*/
|
*/
|
||||||
public int freeResultSet(long pSql) {
|
public int freeResultSet(long pSql) {
|
||||||
int res = TSDBConstants.JNI_SUCCESS;
|
int res = this.freeResultSetImp(this.taos, pSql);
|
||||||
// if (result != taosResultSetPointer && taosResultSetPointer != TSDBConstants.JNI_NULL_POINTER) {
|
|
||||||
// throw new RuntimeException("Invalid result set pointer");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (taosResultSetPointer != TSDBConstants.JNI_NULL_POINTER) {
|
|
||||||
res = this.freeResultSetImp(this.taos, pSql);
|
|
||||||
// taosResultSetPointer = TSDBConstants.JNI_NULL_POINTER;
|
|
||||||
// }
|
|
||||||
|
|
||||||
isResultsetClosed = true;
|
isResultsetClosed = true;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the open result set which is associated to the current connection. If the result set is already
|
|
||||||
* closed, return 0 for success.
|
|
||||||
*/
|
|
||||||
// public int freeResultSet() {
|
|
||||||
// int resCode = TSDBConstants.JNI_SUCCESS;
|
|
||||||
// if (!isResultsetClosed) {
|
|
||||||
// resCode = this.freeResultSetImp(this.taos, this.taosResultSetPointer);
|
|
||||||
// taosResultSetPointer = TSDBConstants.JNI_NULL_POINTER;
|
|
||||||
// isResultsetClosed = true;
|
|
||||||
// }
|
|
||||||
// return resCode;
|
|
||||||
// }
|
|
||||||
|
|
||||||
private native int freeResultSetImp(long connection, long result);
|
private native int freeResultSetImp(long connection, long result);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -246,6 +221,7 @@ public class TSDBJNIConnector {
|
||||||
*/
|
*/
|
||||||
public void closeConnection() throws SQLException {
|
public void closeConnection() throws SQLException {
|
||||||
int code = this.closeConnectionImp(this.taos);
|
int code = this.closeConnectionImp(this.taos);
|
||||||
|
|
||||||
if (code < 0) {
|
if (code < 0) {
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
|
||||||
} else if (code == 0) {
|
} else if (code == 0) {
|
||||||
|
@ -253,6 +229,7 @@ public class TSDBJNIConnector {
|
||||||
} else {
|
} else {
|
||||||
throw new SQLException("Undefined error code returned by TDengine when closing a connection");
|
throw new SQLException("Undefined error code returned by TDengine when closing a connection");
|
||||||
}
|
}
|
||||||
|
|
||||||
// invoke closeConnectionImpl only here
|
// invoke closeConnectionImpl only here
|
||||||
taosInfo.connect_close_increment();
|
taosInfo.connect_close_increment();
|
||||||
}
|
}
|
||||||
|
@ -289,7 +266,7 @@ public class TSDBJNIConnector {
|
||||||
private native void unsubscribeImp(long subscription, boolean isKeep);
|
private native void unsubscribeImp(long subscription, boolean isKeep);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate if a <I>create table</I> sql statement is correct without actually creating that table
|
* Validate if a <I>create table</I> SQL statement is correct without actually creating that table
|
||||||
*/
|
*/
|
||||||
public boolean validateCreateTableSql(String sql) {
|
public boolean validateCreateTableSql(String sql) {
|
||||||
int res = validateCreateTableSqlImp(taos, sql.getBytes());
|
int res = validateCreateTableSqlImp(taos, sql.getBytes());
|
||||||
|
@ -297,4 +274,66 @@ public class TSDBJNIConnector {
|
||||||
}
|
}
|
||||||
|
|
||||||
private native int validateCreateTableSqlImp(long connection, byte[] sqlBytes);
|
private native int validateCreateTableSqlImp(long connection, byte[] sqlBytes);
|
||||||
|
|
||||||
|
public long prepareStmt(String sql) throws SQLException {
|
||||||
|
Long stmt = 0L;
|
||||||
|
try {
|
||||||
|
stmt = prepareStmtImp(sql.getBytes(), this.taos);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_ENCODING);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stmt == TSDBConstants.JNI_CONNECTION_NULL) {
|
||||||
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stmt == TSDBConstants.JNI_SQL_NULL) {
|
||||||
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_SQL_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stmt == TSDBConstants.JNI_OUT_OF_MEMORY) {
|
||||||
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_OUT_OF_MEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
private native long prepareStmtImp(byte[] sql, long con);
|
||||||
|
|
||||||
|
public void setBindTableName(long stmt, String tableName) throws SQLException {
|
||||||
|
int code = setBindTableNameImp(stmt, tableName, this.taos);
|
||||||
|
if (code != TSDBConstants.JNI_SUCCESS) {
|
||||||
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to set table name");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private native int setBindTableNameImp(long stmt, String name, long conn);
|
||||||
|
|
||||||
|
public void bindColumnDataArray(long stmt, ByteBuffer colDataList, ByteBuffer lengthList, ByteBuffer isNullList, int type, int bytes, int numOfRows,int columnIndex) throws SQLException {
|
||||||
|
int code = bindColDataImp(stmt, colDataList.array(), lengthList.array(), isNullList.array(), type, bytes, numOfRows, columnIndex, this.taos);
|
||||||
|
if (code != TSDBConstants.JNI_SUCCESS) {
|
||||||
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to bind column data");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private native int bindColDataImp(long stmt, byte[] colDataList, byte[] lengthList, byte[] isNullList, int type, int bytes, int numOfRows, int columnIndex, long conn);
|
||||||
|
|
||||||
|
public void executeBatch(long stmt) throws SQLException {
|
||||||
|
int code = executeBatchImp(stmt, this.taos);
|
||||||
|
if (code != TSDBConstants.JNI_SUCCESS) {
|
||||||
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to execute batch bind");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private native int executeBatchImp(long stmt, long con);
|
||||||
|
|
||||||
|
public void closeBatch(long stmt) throws SQLException {
|
||||||
|
int code = closeStmt(stmt, this.taos);
|
||||||
|
if (code != TSDBConstants.JNI_SUCCESS) {
|
||||||
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to close batch bind");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private native int closeStmt(long stmt, long con);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,36 +14,44 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
package com.taosdata.jdbc;
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
|
import com.taosdata.jdbc.utils.Utils;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TDengine only supports a subset of the standard SQL, thus this implemetation of the
|
* TDengine only supports a subset of the standard SQL, thus this implementation of the
|
||||||
* standard JDBC API contains more or less some adjustments customized for certain
|
* standard JDBC API contains more or less some adjustments customized for certain
|
||||||
* compatibility needs.
|
* compatibility needs.
|
||||||
*/
|
*/
|
||||||
public class TSDBPreparedStatement extends TSDBStatement implements PreparedStatement {
|
public class TSDBPreparedStatement extends TSDBStatement implements PreparedStatement {
|
||||||
|
|
||||||
private String rawSql;
|
private String rawSql;
|
||||||
private Object[] parameters;
|
private Object[] parameters;
|
||||||
private boolean isPrepared;
|
private boolean isPrepared;
|
||||||
|
|
||||||
|
private ArrayList<ColumnInfo> colData;
|
||||||
|
private String tableName;
|
||||||
|
private long nativeStmtHandle = 0;
|
||||||
|
|
||||||
private volatile TSDBParameterMetaData parameterMetaData;
|
private volatile TSDBParameterMetaData parameterMetaData;
|
||||||
|
|
||||||
TSDBPreparedStatement(TSDBConnection connection, TSDBJNIConnector connecter, String sql) {
|
TSDBPreparedStatement(TSDBConnection connection, String sql) {
|
||||||
super(connection, connecter);
|
super(connection);
|
||||||
init(sql);
|
init(sql);
|
||||||
|
|
||||||
if (sql.contains("?")) {
|
|
||||||
int parameterCnt = 0;
|
int parameterCnt = 0;
|
||||||
|
if (sql.contains("?")) {
|
||||||
for (int i = 0; i < sql.length(); i++) {
|
for (int i = 0; i < sql.length(); i++) {
|
||||||
if ('?' == sql.charAt(i)) {
|
if ('?' == sql.charAt(i)) {
|
||||||
parameterCnt++;
|
parameterCnt++;
|
||||||
|
@ -52,6 +60,12 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
||||||
parameters = new Object[parameterCnt];
|
parameters = new Object[parameterCnt];
|
||||||
this.isPrepared = true;
|
this.isPrepared = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parameterCnt > 1) {
|
||||||
|
// the table name is also a parameter, so ignore it.
|
||||||
|
this.colData = new ArrayList<ColumnInfo>(parameterCnt - 1);
|
||||||
|
this.colData.addAll(Collections.nCopies(parameterCnt - 1, null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init(String sql) {
|
private void init(String sql) {
|
||||||
|
@ -126,28 +140,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
||||||
* @return a string of the native sql statement for TSDB
|
* @return a string of the native sql statement for TSDB
|
||||||
*/
|
*/
|
||||||
private String getNativeSql(String rawSql) throws SQLException {
|
private String getNativeSql(String rawSql) throws SQLException {
|
||||||
String sql = rawSql;
|
return Utils.getNativeSql(rawSql, this.parameters);
|
||||||
for (int i = 0; i < parameters.length; ++i) {
|
|
||||||
Object para = parameters[i];
|
|
||||||
if (para != null) {
|
|
||||||
String paraStr;
|
|
||||||
if (para instanceof byte[]) {
|
|
||||||
paraStr = new String((byte[]) para, Charset.forName("UTF-8"));
|
|
||||||
} else {
|
|
||||||
paraStr = para.toString();
|
|
||||||
}
|
|
||||||
// if para is timestamp or String or byte[] need to translate ' character
|
|
||||||
if (para instanceof Timestamp || para instanceof String || para instanceof byte[]) {
|
|
||||||
paraStr = paraStr.replaceAll("'", "\\\\\\\\'");
|
|
||||||
paraStr = "'" + paraStr + "'";
|
|
||||||
}
|
|
||||||
sql = sql.replaceFirst("[?]", paraStr);
|
|
||||||
} else {
|
|
||||||
sql = sql.replaceFirst("[?]", "NULL");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
clearParameters();
|
|
||||||
return sql;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -280,10 +273,14 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setObject(int parameterIndex, Object x) throws SQLException {
|
public void setObject(int parameterIndex, Object x) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed()) {
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||||
if (parameterIndex < 1 && parameterIndex >= parameters.length)
|
}
|
||||||
|
|
||||||
|
if (parameterIndex < 1 && parameterIndex >= parameters.length) {
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
|
||||||
|
}
|
||||||
|
|
||||||
parameters[parameterIndex - 1] = x;
|
parameters[parameterIndex - 1] = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,8 +317,9 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setRef(int parameterIndex, Ref x) throws SQLException {
|
public void setRef(int parameterIndex, Ref x) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed()) {
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||||
|
}
|
||||||
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
||||||
}
|
}
|
||||||
|
@ -535,4 +533,276 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
// NOTE: the following APIs are not JDBC compatible
|
||||||
|
// set the bind table name
|
||||||
|
private static class ColumnInfo {
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
private ArrayList data;
|
||||||
|
private int type;
|
||||||
|
private int bytes;
|
||||||
|
private boolean typeIsSet;
|
||||||
|
|
||||||
|
public ColumnInfo() {
|
||||||
|
this.typeIsSet = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(int type) throws SQLException {
|
||||||
|
if (this.isTypeSet()) {
|
||||||
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data type has been set");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.typeIsSet = true;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTypeSet() {
|
||||||
|
return this.typeIsSet;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public void setTableName(String name) {
|
||||||
|
this.tableName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> void setValueImpl(int columnIndex, ArrayList<T> list, int type, int bytes) throws SQLException {
|
||||||
|
ColumnInfo col = (ColumnInfo) this.colData.get(columnIndex);
|
||||||
|
if (col == null) {
|
||||||
|
ColumnInfo p = new ColumnInfo();
|
||||||
|
p.setType(type);
|
||||||
|
p.bytes = bytes;
|
||||||
|
p.data = (ArrayList<?>) list.clone();
|
||||||
|
this.colData.set(columnIndex, p);
|
||||||
|
} else {
|
||||||
|
if (col.type != type) {
|
||||||
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data type mismatch");
|
||||||
|
}
|
||||||
|
col.data.addAll(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInt(int columnIndex, ArrayList<Integer> list) throws SQLException {
|
||||||
|
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_INT, Integer.BYTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFloat(int columnIndex, ArrayList<Float> list) throws SQLException {
|
||||||
|
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_FLOAT, Float.BYTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimestamp(int columnIndex, ArrayList<Long> list) throws SQLException {
|
||||||
|
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP, Long.BYTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLong(int columnIndex, ArrayList<Long> list) throws SQLException {
|
||||||
|
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BIGINT, Long.BYTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDouble(int columnIndex, ArrayList<Double> list) throws SQLException {
|
||||||
|
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_DOUBLE, Double.BYTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBoolean(int columnIndex, ArrayList<Boolean> list) throws SQLException {
|
||||||
|
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BOOL, Byte.BYTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setByte(int columnIndex, ArrayList<Byte> list) throws SQLException {
|
||||||
|
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_TINYINT, Byte.BYTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setShort(int columnIndex, ArrayList<Short> list) throws SQLException {
|
||||||
|
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_SMALLINT, Short.BYTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setString(int columnIndex, ArrayList<String> list, int size) throws SQLException {
|
||||||
|
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BINARY, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// note: expand the required space for each NChar character
|
||||||
|
public void setNString(int columnIndex, ArrayList<String> list, int size) throws SQLException {
|
||||||
|
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_NCHAR, size * Integer.BYTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void columnDataAddBatch() throws SQLException {
|
||||||
|
// pass the data block to native code
|
||||||
|
if (rawSql == null) {
|
||||||
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "sql statement not set yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
// table name is not set yet, abort
|
||||||
|
if (this.tableName == null) {
|
||||||
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "table name not set yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
int numOfCols = this.colData.size();
|
||||||
|
if (numOfCols == 0) {
|
||||||
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data not bind");
|
||||||
|
}
|
||||||
|
|
||||||
|
TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector();
|
||||||
|
this.nativeStmtHandle = connector.prepareStmt(rawSql);
|
||||||
|
connector.setBindTableName(this.nativeStmtHandle, this.tableName);
|
||||||
|
|
||||||
|
ColumnInfo colInfo = (ColumnInfo) this.colData.get(0);
|
||||||
|
if (colInfo == null) {
|
||||||
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data not bind");
|
||||||
|
}
|
||||||
|
|
||||||
|
int rows = colInfo.data.size();
|
||||||
|
for (int i = 0; i < numOfCols; ++i) {
|
||||||
|
ColumnInfo col1 = this.colData.get(i);
|
||||||
|
if (col1 == null || !col1.isTypeSet()) {
|
||||||
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data not bind");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rows != col1.data.size()) {
|
||||||
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "the rows in column data not identical");
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteBuffer colDataList = ByteBuffer.allocate(rows * col1.bytes);
|
||||||
|
colDataList.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
|
||||||
|
ByteBuffer lengthList = ByteBuffer.allocate(rows * Integer.BYTES);
|
||||||
|
lengthList.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
|
||||||
|
ByteBuffer isNullList = ByteBuffer.allocate(rows * Byte.BYTES);
|
||||||
|
isNullList.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
|
||||||
|
switch (col1.type) {
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_INT: {
|
||||||
|
for (int j = 0; j < rows; ++j) {
|
||||||
|
Integer val = (Integer) col1.data.get(j);
|
||||||
|
colDataList.putInt(val == null? Integer.MIN_VALUE:val);
|
||||||
|
isNullList.put((byte) (val == null? 1:0));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: {
|
||||||
|
for (int j = 0; j < rows; ++j) {
|
||||||
|
Byte val = (Byte) col1.data.get(j);
|
||||||
|
colDataList.put(val == null? 0:val);
|
||||||
|
isNullList.put((byte) (val == null? 1:0));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_BOOL: {
|
||||||
|
for (int j = 0; j < rows; ++j) {
|
||||||
|
Boolean val = (Boolean) col1.data.get(j);
|
||||||
|
if (val == null) {
|
||||||
|
colDataList.put((byte) 0);
|
||||||
|
} else {
|
||||||
|
colDataList.put((byte) (val? 1:0));
|
||||||
|
}
|
||||||
|
|
||||||
|
isNullList.put((byte) (val == null? 1:0));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: {
|
||||||
|
for (int j = 0; j < rows; ++j) {
|
||||||
|
Short val = (Short) col1.data.get(j);
|
||||||
|
colDataList.putShort(val == null? 0:val);
|
||||||
|
isNullList.put((byte) (val == null? 1:0));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: {
|
||||||
|
for (int j = 0; j < rows; ++j) {
|
||||||
|
Long val = (Long) col1.data.get(j);
|
||||||
|
colDataList.putLong(val == null? 0:val);
|
||||||
|
isNullList.put((byte) (val == null? 1:0));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: {
|
||||||
|
for (int j = 0; j < rows; ++j) {
|
||||||
|
Float val = (Float) col1.data.get(j);
|
||||||
|
colDataList.putFloat(val == null? 0:val);
|
||||||
|
isNullList.put((byte) (val == null? 1:0));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: {
|
||||||
|
for (int j = 0; j < rows; ++j) {
|
||||||
|
Double val = (Double) col1.data.get(j);
|
||||||
|
colDataList.putDouble(val == null? 0:val);
|
||||||
|
isNullList.put((byte) (val == null? 1:0));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_BINARY: {
|
||||||
|
String charset = TaosGlobalConfig.getCharset();
|
||||||
|
for (int j = 0; j < rows; ++j) {
|
||||||
|
String val = (String) col1.data.get(j);
|
||||||
|
|
||||||
|
colDataList.position(j * col1.bytes); // seek to the correct position
|
||||||
|
if (val != null) {
|
||||||
|
byte[] b = null;
|
||||||
|
try {
|
||||||
|
if (col1.type == TSDBConstants.TSDB_DATA_TYPE_BINARY) {
|
||||||
|
b = val.getBytes();
|
||||||
|
} else {
|
||||||
|
b = val.getBytes(charset);
|
||||||
|
}
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val.length() > col1.bytes) {
|
||||||
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "string data too long");
|
||||||
|
}
|
||||||
|
|
||||||
|
colDataList.put(b);
|
||||||
|
lengthList.putInt(b.length);
|
||||||
|
isNullList.put((byte) 0);
|
||||||
|
} else {
|
||||||
|
lengthList.putInt(0);
|
||||||
|
isNullList.put((byte) 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_UTINYINT:
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_USMALLINT:
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_UINT:
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: {
|
||||||
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "not support data types");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
connector.bindColumnDataArray(this.nativeStmtHandle, colDataList, lengthList, isNullList, col1.type, col1.bytes, rows, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void columnDataExecuteBatch() throws SQLException {
|
||||||
|
TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector();
|
||||||
|
connector.executeBatch(this.nativeStmtHandle);
|
||||||
|
this.columnDataClearBatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void columnDataClearBatch() {
|
||||||
|
int size = this.colData.size();
|
||||||
|
this.colData.clear();
|
||||||
|
|
||||||
|
this.colData.addAll(Collections.nCopies(size, null));
|
||||||
|
this.tableName = null; // clear the table name
|
||||||
|
}
|
||||||
|
|
||||||
|
public void columnDataCloseBatch() throws SQLException {
|
||||||
|
TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector();
|
||||||
|
connector.closeBatch(this.nativeStmtHandle);
|
||||||
|
|
||||||
|
this.nativeStmtHandle = 0L;
|
||||||
|
this.tableName = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,6 +109,8 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
|
||||||
public void close() throws SQLException {
|
public void close() throws SQLException {
|
||||||
if (isClosed)
|
if (isClosed)
|
||||||
return;
|
return;
|
||||||
|
if (this.statement == null)
|
||||||
|
return;
|
||||||
if (this.jniConnector != null) {
|
if (this.jniConnector != null) {
|
||||||
int code = this.jniConnector.freeResultSet(this.resultSetPointer);
|
int code = this.jniConnector.freeResultSet(this.resultSetPointer);
|
||||||
if (code == TSDBConstants.JNI_CONNECTION_NULL) {
|
if (code == TSDBConstants.JNI_CONNECTION_NULL) {
|
||||||
|
@ -461,12 +463,13 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isClosed() throws SQLException {
|
public boolean isClosed() throws SQLException {
|
||||||
if (isClosed)
|
|
||||||
return true;
|
|
||||||
if (jniConnector != null) {
|
|
||||||
isClosed = jniConnector.isResultsetClosed();
|
|
||||||
}
|
|
||||||
return isClosed;
|
return isClosed;
|
||||||
|
// if (isClosed)
|
||||||
|
// return true;
|
||||||
|
// if (jniConnector != null) {
|
||||||
|
// isClosed = jniConnector.isResultsetClosed();
|
||||||
|
// }
|
||||||
|
// return isClosed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getNString(int columnIndex) throws SQLException {
|
public String getNString(int columnIndex) throws SQLException {
|
||||||
|
|
|
@ -29,6 +29,8 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.taosdata.jdbc.utils.NullType;
|
||||||
|
|
||||||
public class TSDBResultSetBlockData {
|
public class TSDBResultSetBlockData {
|
||||||
private int numOfRows = 0;
|
private int numOfRows = 0;
|
||||||
private int rowIndex = 0;
|
private int rowIndex = 0;
|
||||||
|
@ -164,59 +166,7 @@ public class TSDBResultSetBlockData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class NullType {
|
|
||||||
private static final byte NULL_BOOL_VAL = 0x2;
|
|
||||||
private static final String NULL_STR = "null";
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
return NullType.NULL_STR;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isBooleanNull(byte val) {
|
|
||||||
return val == NullType.NULL_BOOL_VAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isTinyIntNull(byte val) {
|
|
||||||
return val == Byte.MIN_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isSmallIntNull(short val) {
|
|
||||||
return val == Short.MIN_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isIntNull(int val) {
|
|
||||||
return val == Integer.MIN_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isBigIntNull(long val) {
|
|
||||||
return val == Long.MIN_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isFloatNull(float val) {
|
|
||||||
return Float.isNaN(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isDoubleNull(double val) {
|
|
||||||
return Double.isNaN(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isBinaryNull(byte[] val, int length) {
|
|
||||||
if (length != Byte.BYTES) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return val[0] == 0xFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isNcharNull(byte[] val, int length) {
|
|
||||||
if (length != Integer.BYTES) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (val[0] & val[1] & val[2] & val[3]) == 0xFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The original type may not be a string type, but will be converted to by
|
* The original type may not be a string type, but will be converted to by
|
||||||
|
@ -488,8 +438,8 @@ public class TSDBResultSetBlockData {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String ss = TaosGlobalConfig.getCharset();
|
String charset = TaosGlobalConfig.getCharset();
|
||||||
return new String(dest, ss);
|
return new String(dest, charset);
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,6 +84,7 @@ public class TSDBResultSetRowData {
|
||||||
data.set(col, value);
|
data.set(col, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public int getInt(int col, int srcType) throws SQLException {
|
public int getInt(int col, int srcType) throws SQLException {
|
||||||
Object obj = data.get(col);
|
Object obj = data.get(col);
|
||||||
|
|
||||||
|
@ -128,7 +129,7 @@ public class TSDBResultSetRowData {
|
||||||
long value = (long) obj;
|
long value = (long) obj;
|
||||||
if (value < 0)
|
if (value < 0)
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
|
||||||
return new Long(value).intValue();
|
return Long.valueOf(value).intValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,6 @@ import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
public class TSDBStatement extends AbstractStatement {
|
public class TSDBStatement extends AbstractStatement {
|
||||||
|
|
||||||
private TSDBJNIConnector connector;
|
|
||||||
/**
|
/**
|
||||||
* Status of current statement
|
* Status of current statement
|
||||||
*/
|
*/
|
||||||
|
@ -29,29 +27,26 @@ public class TSDBStatement extends AbstractStatement {
|
||||||
private TSDBConnection connection;
|
private TSDBConnection connection;
|
||||||
private TSDBResultSet resultSet;
|
private TSDBResultSet resultSet;
|
||||||
|
|
||||||
public void setConnection(TSDBConnection connection) {
|
TSDBStatement(TSDBConnection connection) {
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
TSDBStatement(TSDBConnection connection, TSDBJNIConnector connector) {
|
|
||||||
this.connection = connection;
|
|
||||||
this.connector = connector;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ResultSet executeQuery(String sql) throws SQLException {
|
public ResultSet executeQuery(String sql) throws SQLException {
|
||||||
// check if closed
|
// check if closed
|
||||||
if (isClosed())
|
if (isClosed()) {
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: 如果在executeQuery方法中执行insert语句,那么先执行了SQL,再通过pSql来检查是否为一个insert语句,但这个insert SQL已经执行成功了
|
//TODO: 如果在executeQuery方法中执行insert语句,那么先执行了SQL,再通过pSql来检查是否为一个insert语句,但这个insert SQL已经执行成功了
|
||||||
|
|
||||||
// execute query
|
// execute query
|
||||||
long pSql = this.connector.executeQuery(sql);
|
long pSql = this.connection.getConnector().executeQuery(sql);
|
||||||
// if pSql is create/insert/update/delete/alter SQL
|
// if pSql is create/insert/update/delete/alter SQL
|
||||||
if (this.connector.isUpdateQuery(pSql)) {
|
if (this.connection.getConnector().isUpdateQuery(pSql)) {
|
||||||
this.connector.freeResultSet(pSql);
|
this.connection.getConnector().freeResultSet(pSql);
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY);
|
||||||
}
|
}
|
||||||
TSDBResultSet res = new TSDBResultSet(this, this.connector, pSql);
|
TSDBResultSet res = new TSDBResultSet(this, this.connection.getConnector(), pSql);
|
||||||
res.setBatchFetch(this.connection.getBatchFetch());
|
res.setBatchFetch(this.connection.getBatchFetch());
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -60,14 +55,14 @@ public class TSDBStatement extends AbstractStatement {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||||
|
|
||||||
long pSql = this.connector.executeQuery(sql);
|
long pSql = this.connection.getConnector().executeQuery(sql);
|
||||||
// if pSql is create/insert/update/delete/alter SQL
|
// if pSql is create/insert/update/delete/alter SQL
|
||||||
if (!this.connector.isUpdateQuery(pSql)) {
|
if (!this.connection.getConnector().isUpdateQuery(pSql)) {
|
||||||
this.connector.freeResultSet(pSql);
|
this.connection.getConnector().freeResultSet(pSql);
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEUPDATE);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEUPDATE);
|
||||||
}
|
}
|
||||||
int affectedRows = this.connector.getAffectedRows(pSql);
|
int affectedRows = this.connection.getConnector().getAffectedRows(pSql);
|
||||||
this.connector.freeResultSet(pSql);
|
this.connection.getConnector().freeResultSet(pSql);
|
||||||
return affectedRows;
|
return affectedRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,30 +76,29 @@ public class TSDBStatement extends AbstractStatement {
|
||||||
|
|
||||||
public boolean execute(String sql) throws SQLException {
|
public boolean execute(String sql) throws SQLException {
|
||||||
// check if closed
|
// check if closed
|
||||||
if (isClosed())
|
if (isClosed()) {
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||||
|
}
|
||||||
|
|
||||||
// execute query
|
// execute query
|
||||||
long pSql = this.connector.executeQuery(sql);
|
long pSql = this.connection.getConnector().executeQuery(sql);
|
||||||
// if pSql is create/insert/update/delete/alter SQL
|
// if pSql is create/insert/update/delete/alter SQL
|
||||||
if (this.connector.isUpdateQuery(pSql)) {
|
if (this.connection.getConnector().isUpdateQuery(pSql)) {
|
||||||
this.affectedRows = this.connector.getAffectedRows(pSql);
|
this.affectedRows = this.connection.getConnector().getAffectedRows(pSql);
|
||||||
this.connector.freeResultSet(pSql);
|
this.connection.getConnector().freeResultSet(pSql);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.resultSet = new TSDBResultSet(this, this.connector, pSql);
|
this.resultSet = new TSDBResultSet(this, this.connection.getConnector(), pSql);
|
||||||
this.resultSet.setBatchFetch(this.connection.getBatchFetch());
|
this.resultSet.setBatchFetch(this.connection.getBatchFetch());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResultSet getResultSet() throws SQLException {
|
public ResultSet getResultSet() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed()) {
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||||
// long resultSetPointer = connector.getResultSet();
|
}
|
||||||
// TSDBResultSet resSet = null;
|
|
||||||
// if (resultSetPointer != TSDBConstants.JNI_NULL_POINTER) {
|
|
||||||
// resSet = new TSDBResultSet(connector, resultSetPointer);
|
|
||||||
// }
|
|
||||||
return this.resultSet;
|
return this.resultSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,13 +109,21 @@ public class TSDBStatement extends AbstractStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Connection getConnection() throws SQLException {
|
public Connection getConnection() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed()) {
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||||
if (this.connector == null)
|
}
|
||||||
|
|
||||||
|
if (this.connection.getConnector() == null) {
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
return this.connection;
|
return this.connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setConnection(TSDBConnection connection) {
|
||||||
|
this.connection = connection;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isClosed() throws SQLException {
|
public boolean isClosed() throws SQLException {
|
||||||
return isClosed;
|
return isClosed;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ public class RestfulDriver extends AbstractDriver {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
java.sql.DriverManager.registerDriver(new RestfulDriver());
|
DriverManager.registerDriver(new RestfulDriver());
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw TSDBError.createRuntimeException(TSDBErrorNumbers.ERROR_URL_NOT_SET, e);
|
throw TSDBError.createRuntimeException(TSDBErrorNumbers.ERROR_URL_NOT_SET, e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,12 @@ package com.taosdata.jdbc.rs;
|
||||||
|
|
||||||
import com.taosdata.jdbc.TSDBError;
|
import com.taosdata.jdbc.TSDBError;
|
||||||
import com.taosdata.jdbc.TSDBErrorNumbers;
|
import com.taosdata.jdbc.TSDBErrorNumbers;
|
||||||
|
import com.taosdata.jdbc.utils.Utils;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar
|
||||||
public RestfulPreparedStatement(RestfulConnection conn, String database, String sql) {
|
public RestfulPreparedStatement(RestfulConnection conn, String database, String sql) {
|
||||||
super(conn, database);
|
super(conn, database);
|
||||||
this.rawSql = sql;
|
this.rawSql = sql;
|
||||||
|
|
||||||
if (sql.contains("?")) {
|
if (sql.contains("?")) {
|
||||||
int parameterCnt = 0;
|
int parameterCnt = 0;
|
||||||
for (int i = 0; i < sql.length(); i++) {
|
for (int i = 0; i < sql.length(); i++) {
|
||||||
|
@ -58,29 +59,14 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar
|
||||||
return executeUpdate(sql);
|
return executeUpdate(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getNativeSql(String rawSql) throws SQLException {
|
/****
|
||||||
String sql = rawSql;
|
* 将rawSql转换成一条可执行的sql语句,使用属性parameters中的变脸进行替换
|
||||||
for (int i = 0; i < parameters.length; ++i) {
|
* 对于insert into ?.? (?,?,?) using ?.? (?,?,?) tags(?, ?, ?) values(?, ?, ?)
|
||||||
Object para = parameters[i];
|
* @param rawSql,可能是insert、select或其他,使用?做占位符
|
||||||
if (para != null) {
|
* @return
|
||||||
String paraStr;
|
*/
|
||||||
if (para instanceof byte[]) {
|
private String getNativeSql(String rawSql) {
|
||||||
paraStr = new String((byte[]) para, Charset.forName("UTF-8"));
|
return Utils.getNativeSql(rawSql, this.parameters);
|
||||||
} else {
|
|
||||||
paraStr = para.toString();
|
|
||||||
}
|
|
||||||
// if para is timestamp or String or byte[] need to translate ' character
|
|
||||||
if (para instanceof Timestamp || para instanceof String || para instanceof byte[]) {
|
|
||||||
paraStr = paraStr.replaceAll("'", "\\\\\\\\'");
|
|
||||||
paraStr = "'" + paraStr + "'";
|
|
||||||
}
|
|
||||||
sql = sql.replaceFirst("[?]", paraStr);
|
|
||||||
} else {
|
|
||||||
sql = sql.replaceFirst("[?]", "NULL");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
clearParameters();
|
|
||||||
return sql;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -6,11 +6,13 @@ import com.google.common.primitives.Ints;
|
||||||
import com.google.common.primitives.Longs;
|
import com.google.common.primitives.Longs;
|
||||||
import com.google.common.primitives.Shorts;
|
import com.google.common.primitives.Shorts;
|
||||||
import com.taosdata.jdbc.*;
|
import com.taosdata.jdbc.*;
|
||||||
|
import com.taosdata.jdbc.utils.Utils;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
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.format.DateTimeParseException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
@ -18,14 +20,13 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
private volatile boolean isClosed;
|
private volatile boolean isClosed;
|
||||||
private int pos = -1;
|
private int pos = -1;
|
||||||
|
|
||||||
|
|
||||||
private final String database;
|
private final String database;
|
||||||
private final Statement statement;
|
private final Statement statement;
|
||||||
// data
|
// data
|
||||||
private final ArrayList<ArrayList<Object>> resultSet;
|
private final ArrayList<ArrayList<Object>> resultSet = new ArrayList<>();
|
||||||
// meta
|
// meta
|
||||||
private ArrayList<String> columnNames;
|
private ArrayList<String> columnNames = new ArrayList<>();
|
||||||
private ArrayList<Field> columns;
|
private ArrayList<Field> columns = new ArrayList<>();
|
||||||
private RestfulResultSetMetaData metaData;
|
private RestfulResultSetMetaData metaData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,10 +38,46 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
this.database = database;
|
this.database = database;
|
||||||
this.statement = statement;
|
this.statement = statement;
|
||||||
|
|
||||||
// column metadata
|
// get column metadata
|
||||||
JSONArray columnMeta = resultJson.getJSONArray("column_meta");
|
JSONArray columnMeta = resultJson.getJSONArray("column_meta");
|
||||||
columnNames = new ArrayList<>();
|
// get row data
|
||||||
columns = new ArrayList<>();
|
JSONArray data = resultJson.getJSONArray("data");
|
||||||
|
if (data == null || data.isEmpty()) {
|
||||||
|
columnNames.clear();
|
||||||
|
columns.clear();
|
||||||
|
this.resultSet.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// get head
|
||||||
|
JSONArray head = resultJson.getJSONArray("head");
|
||||||
|
// get rows
|
||||||
|
Integer rows = resultJson.getInteger("rows");
|
||||||
|
// parse column_meta
|
||||||
|
if (columnMeta != null) {
|
||||||
|
parseColumnMeta_new(columnMeta);
|
||||||
|
} else {
|
||||||
|
parseColumnMeta_old(head, data, rows);
|
||||||
|
}
|
||||||
|
this.metaData = new RestfulResultSetMetaData(this.database, columns, this);
|
||||||
|
// parse row data
|
||||||
|
resultSet.clear();
|
||||||
|
for (int rowIndex = 0; rowIndex < data.size(); rowIndex++) {
|
||||||
|
ArrayList row = new ArrayList();
|
||||||
|
JSONArray jsonRow = data.getJSONArray(rowIndex);
|
||||||
|
for (int colIndex = 0; colIndex < this.metaData.getColumnCount(); colIndex++) {
|
||||||
|
row.add(parseColumnData(jsonRow, colIndex, columns.get(colIndex).taos_type));
|
||||||
|
}
|
||||||
|
resultSet.add(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* use this method after TDengine-2.0.18.0 to parse column meta, restful add column_meta in resultSet
|
||||||
|
* @Param columnMeta
|
||||||
|
*/
|
||||||
|
private void parseColumnMeta_new(JSONArray columnMeta) throws SQLException {
|
||||||
|
columnNames.clear();
|
||||||
|
columns.clear();
|
||||||
for (int colIndex = 0; colIndex < columnMeta.size(); colIndex++) {
|
for (int colIndex = 0; colIndex < columnMeta.size(); colIndex++) {
|
||||||
JSONArray col = columnMeta.getJSONArray(colIndex);
|
JSONArray col = columnMeta.getJSONArray(colIndex);
|
||||||
String col_name = col.getString(0);
|
String col_name = col.getString(0);
|
||||||
|
@ -50,23 +87,55 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
columnNames.add(col_name);
|
columnNames.add(col_name);
|
||||||
columns.add(new Field(col_name, col_type, col_length, "", taos_type));
|
columns.add(new Field(col_name, col_type, col_length, "", taos_type));
|
||||||
}
|
}
|
||||||
this.metaData = new RestfulResultSetMetaData(this.database, columns, this);
|
}
|
||||||
|
|
||||||
// row data
|
/**
|
||||||
JSONArray data = resultJson.getJSONArray("data");
|
* use this method before TDengine-2.0.18.0 to parse column meta
|
||||||
resultSet = new ArrayList<>();
|
*/
|
||||||
for (int rowIndex = 0; rowIndex < data.size(); rowIndex++) {
|
private void parseColumnMeta_old(JSONArray head, JSONArray data, int rows) {
|
||||||
ArrayList row = new ArrayList();
|
columnNames.clear();
|
||||||
JSONArray jsonRow = data.getJSONArray(rowIndex);
|
columns.clear();
|
||||||
for (int colIndex = 0; colIndex < jsonRow.size(); colIndex++) {
|
for (int colIndex = 0; colIndex < head.size(); colIndex++) {
|
||||||
row.add(parseColumnData(jsonRow, colIndex, columns.get(colIndex).taos_type));
|
String col_name = head.getString(colIndex);
|
||||||
|
columnNames.add(col_name);
|
||||||
|
|
||||||
|
int col_type = Types.NULL;
|
||||||
|
int col_length = 0;
|
||||||
|
int taos_type = TSDBConstants.TSDB_DATA_TYPE_NULL;
|
||||||
|
|
||||||
|
JSONArray row0Json = data.getJSONArray(0);
|
||||||
|
if (colIndex < row0Json.size()) {
|
||||||
|
Object value = row0Json.get(colIndex);
|
||||||
|
if (value instanceof Boolean) {
|
||||||
|
col_type = Types.BOOLEAN;
|
||||||
|
col_length = 1;
|
||||||
|
taos_type = TSDBConstants.TSDB_DATA_TYPE_BOOL;
|
||||||
}
|
}
|
||||||
resultSet.add(row);
|
if (value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Long) {
|
||||||
|
col_type = Types.BIGINT;
|
||||||
|
col_length = 8;
|
||||||
|
taos_type = TSDBConstants.TSDB_DATA_TYPE_BIGINT;
|
||||||
|
}
|
||||||
|
if (value instanceof Float || value instanceof Double || value instanceof BigDecimal) {
|
||||||
|
col_type = Types.DOUBLE;
|
||||||
|
col_length = 8;
|
||||||
|
taos_type = TSDBConstants.TSDB_DATA_TYPE_DOUBLE;
|
||||||
|
}
|
||||||
|
if (value instanceof String) {
|
||||||
|
col_type = Types.NCHAR;
|
||||||
|
col_length = ((String) value).length();
|
||||||
|
taos_type = TSDBConstants.TSDB_DATA_TYPE_NCHAR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
columns.add(new Field(col_name, col_type, col_length, "", taos_type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private Object parseColumnData(JSONArray row, int colIndex, int taosType) throws SQLException {
|
private Object parseColumnData(JSONArray row, int colIndex, int taosType) throws SQLException {
|
||||||
switch (taosType) {
|
switch (taosType) {
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_NULL:
|
||||||
|
return null;
|
||||||
case TSDBConstants.TSDB_DATA_TYPE_BOOL:
|
case TSDBConstants.TSDB_DATA_TYPE_BOOL:
|
||||||
return row.getBoolean(colIndex);
|
return row.getBoolean(colIndex);
|
||||||
case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
|
case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
|
||||||
|
@ -290,8 +359,10 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
wasNull = false;
|
wasNull = false;
|
||||||
if (value instanceof Float || value instanceof Double)
|
if (value instanceof Float)
|
||||||
return (float) value;
|
return (float) value;
|
||||||
|
if (value instanceof Double)
|
||||||
|
return new Float((Double) value);
|
||||||
return Float.parseFloat(value.toString());
|
return Float.parseFloat(value.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,6 +400,9 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
return Shorts.toByteArray((short) value);
|
return Shorts.toByteArray((short) value);
|
||||||
if (value instanceof Byte)
|
if (value instanceof Byte)
|
||||||
return new byte[]{(byte) value};
|
return new byte[]{(byte) value};
|
||||||
|
if (value instanceof Timestamp) {
|
||||||
|
return Utils.formatTimestamp((Timestamp) value).getBytes();
|
||||||
|
}
|
||||||
|
|
||||||
return value.toString().getBytes();
|
return value.toString().getBytes();
|
||||||
}
|
}
|
||||||
|
@ -342,7 +416,9 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
return null;
|
return null;
|
||||||
if (value instanceof Timestamp)
|
if (value instanceof Timestamp)
|
||||||
return new Date(((Timestamp) value).getTime());
|
return new Date(((Timestamp) value).getTime());
|
||||||
return Date.valueOf(value.toString());
|
Date date = null;
|
||||||
|
date = Utils.parseDate(value.toString());
|
||||||
|
return date;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -354,7 +430,13 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
return null;
|
return null;
|
||||||
if (value instanceof Timestamp)
|
if (value instanceof Timestamp)
|
||||||
return new Time(((Timestamp) value).getTime());
|
return new Time(((Timestamp) value).getTime());
|
||||||
return Time.valueOf(value.toString());
|
Time time = null;
|
||||||
|
try {
|
||||||
|
time = Utils.parseTime(value.toString());
|
||||||
|
} catch (DateTimeParseException e) {
|
||||||
|
time = null;
|
||||||
|
}
|
||||||
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -366,14 +448,20 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
return null;
|
return null;
|
||||||
if (value instanceof Timestamp)
|
if (value instanceof Timestamp)
|
||||||
return (Timestamp) value;
|
return (Timestamp) value;
|
||||||
// if (value instanceof Long) {
|
if (value instanceof Long) {
|
||||||
// if (1_0000_0000_0000_0L > (long) value)
|
if (1_0000_0000_0000_0L > (long) value)
|
||||||
// return Timestamp.from(Instant.ofEpochMilli((long) value));
|
return Timestamp.from(Instant.ofEpochMilli((long) value));
|
||||||
// long epochSec = (long) value / 1000_000L;
|
long epochSec = (long) value / 1000_000L;
|
||||||
// long nanoAdjustment = (long) ((long) value % 1000_000L * 1000);
|
long nanoAdjustment = (long) value % 1000_000L * 1000;
|
||||||
// return Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment));
|
return Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment));
|
||||||
// }
|
}
|
||||||
return Timestamp.valueOf(value.toString());
|
Timestamp ret;
|
||||||
|
try {
|
||||||
|
ret = Utils.parseTimestamp(value.toString());
|
||||||
|
} catch (Exception e) {
|
||||||
|
ret = null;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -415,7 +503,13 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
return new BigDecimal(Double.valueOf(value.toString()));
|
return new BigDecimal(Double.valueOf(value.toString()));
|
||||||
if (value instanceof Timestamp)
|
if (value instanceof Timestamp)
|
||||||
return new BigDecimal(((Timestamp) value).getTime());
|
return new BigDecimal(((Timestamp) value).getTime());
|
||||||
return new BigDecimal(value.toString());
|
BigDecimal ret;
|
||||||
|
try {
|
||||||
|
ret = new BigDecimal(value.toString());
|
||||||
|
} catch (Exception e) {
|
||||||
|
ret = null;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -136,21 +136,21 @@ public class RestfulStatement extends AbstractStatement {
|
||||||
throw TSDBError.createSQLException(jsonObject.getInteger("code"), jsonObject.getString("desc"));
|
throw TSDBError.createSQLException(jsonObject.getInteger("code"), jsonObject.getString("desc"));
|
||||||
}
|
}
|
||||||
this.resultSet = null;
|
this.resultSet = null;
|
||||||
this.affectedRows = checkJsonResultSet(jsonObject);
|
this.affectedRows = getAffectedRows(jsonObject);
|
||||||
return this.affectedRows;
|
return this.affectedRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int checkJsonResultSet(JSONObject jsonObject) {
|
private int getAffectedRows(JSONObject jsonObject) throws SQLException {
|
||||||
// create ... SQLs should return 0 , and Restful result is this:
|
// create ... SQLs should return 0 , and Restful result is this:
|
||||||
// {"status": "succ", "head": ["affected_rows"], "data": [[0]], "rows": 1}
|
// {"status": "succ", "head": ["affected_rows"], "data": [[0]], "rows": 1}
|
||||||
JSONArray head = jsonObject.getJSONArray("head");
|
JSONArray head = jsonObject.getJSONArray("head");
|
||||||
|
if (head.size() != 1 || !"affected_rows".equals(head.getString(0)))
|
||||||
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
|
||||||
JSONArray data = jsonObject.getJSONArray("data");
|
JSONArray data = jsonObject.getJSONArray("data");
|
||||||
int rows = Integer.parseInt(jsonObject.getString("rows"));
|
if (data != null)
|
||||||
if (head.size() == 1 && "affected_rows".equals(head.getString(0))
|
return data.getJSONArray(0).getInteger(0);
|
||||||
&& data.size() == 1 && data.getJSONArray(0).getInteger(0) == 0 && rows == 1) {
|
|
||||||
return 0;
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
|
||||||
}
|
|
||||||
return rows;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
package com.taosdata.jdbc.utils;
|
||||||
|
|
||||||
|
public class NullType {
|
||||||
|
private static final byte NULL_BOOL_VAL = 0x2;
|
||||||
|
private static final String NULL_STR = "null";
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return NullType.NULL_STR;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isBooleanNull(byte val) {
|
||||||
|
return val == NullType.NULL_BOOL_VAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isTinyIntNull(byte val) {
|
||||||
|
return val == Byte.MIN_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isSmallIntNull(short val) {
|
||||||
|
return val == Short.MIN_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isIntNull(int val) {
|
||||||
|
return val == Integer.MIN_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isBigIntNull(long val) {
|
||||||
|
return val == Long.MIN_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isFloatNull(float val) {
|
||||||
|
return Float.isNaN(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isDoubleNull(double val) {
|
||||||
|
return Double.isNaN(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isBinaryNull(byte[] val, int length) {
|
||||||
|
if (length != Byte.BYTES) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return val[0] == 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isNcharNull(byte[] val, int length) {
|
||||||
|
if (length != Integer.BYTES) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (val[0] & val[1] & val[2] & val[3]) == 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte getBooleanNull() {
|
||||||
|
return NullType.NULL_BOOL_VAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte getTinyintNull() {
|
||||||
|
return Byte.MIN_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getIntNull() {
|
||||||
|
return Integer.MIN_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static short getSmallIntNull() {
|
||||||
|
return Short.MIN_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long getBigIntNull() {
|
||||||
|
return Long.MIN_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getFloatNull() {
|
||||||
|
return 0x7FF00000;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long getDoubleNull() {
|
||||||
|
return 0x7FFFFF0000000000L;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte getBinaryNull() {
|
||||||
|
return (byte) 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] getNcharNull() {
|
||||||
|
return new byte[] {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,12 +0,0 @@
|
||||||
package com.taosdata.jdbc.utils;
|
|
||||||
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.time.format.DateTimeFormatterBuilder;
|
|
||||||
|
|
||||||
public class UtcTimestampUtil {
|
|
||||||
public static final DateTimeFormatter formatter = new DateTimeFormatterBuilder()
|
|
||||||
.appendPattern("yyyy-MM-ddTHH:mm:ss.SSS+")
|
|
||||||
// .appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true)
|
|
||||||
.toFormatter();
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,188 @@
|
||||||
|
package com.taosdata.jdbc.utils;
|
||||||
|
|
||||||
|
import com.google.common.collect.Range;
|
||||||
|
import com.google.common.collect.RangeSet;
|
||||||
|
import com.google.common.collect.TreeRangeSet;
|
||||||
|
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.sql.Date;
|
||||||
|
import java.sql.Time;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.format.DateTimeFormatterBuilder;
|
||||||
|
import java.time.format.DateTimeParseException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
public class Utils {
|
||||||
|
|
||||||
|
private static Pattern ptn = Pattern.compile(".*?'");
|
||||||
|
|
||||||
|
private static final DateTimeFormatter formatter = new DateTimeFormatterBuilder()
|
||||||
|
.appendPattern("yyyy-MM-dd HH:mm:ss.SSS").toFormatter();
|
||||||
|
private static final DateTimeFormatter formatter2 = new DateTimeFormatterBuilder()
|
||||||
|
.appendPattern("yyyy-MM-dd HH:mm:ss.SSSSSS").toFormatter();
|
||||||
|
|
||||||
|
public static Time parseTime(String timestampStr) throws DateTimeParseException {
|
||||||
|
LocalTime time;
|
||||||
|
try {
|
||||||
|
time = LocalTime.parse(timestampStr, formatter);
|
||||||
|
} catch (DateTimeParseException e) {
|
||||||
|
time = LocalTime.parse(timestampStr, formatter2);
|
||||||
|
}
|
||||||
|
return Time.valueOf(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Date parseDate(String timestampStr) throws DateTimeParseException {
|
||||||
|
LocalDate date;
|
||||||
|
try {
|
||||||
|
date = LocalDate.parse(timestampStr, formatter);
|
||||||
|
} catch (DateTimeParseException e) {
|
||||||
|
date = LocalDate.parse(timestampStr, formatter2);
|
||||||
|
}
|
||||||
|
return Date.valueOf(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Timestamp parseTimestamp(String timeStampStr) {
|
||||||
|
LocalDateTime dateTime;
|
||||||
|
try {
|
||||||
|
dateTime = LocalDateTime.parse(timeStampStr, formatter);
|
||||||
|
} catch (DateTimeParseException e) {
|
||||||
|
dateTime = LocalDateTime.parse(timeStampStr, formatter2);
|
||||||
|
}
|
||||||
|
return Timestamp.valueOf(dateTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String escapeSingleQuota(String origin) {
|
||||||
|
Matcher m = ptn.matcher(origin);
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
int end = 0;
|
||||||
|
while (m.find()) {
|
||||||
|
end = m.end();
|
||||||
|
String seg = origin.substring(m.start(), end);
|
||||||
|
int len = seg.length();
|
||||||
|
if (len == 1) {
|
||||||
|
if ('\'' == seg.charAt(0)) {
|
||||||
|
sb.append("\\'");
|
||||||
|
} else {
|
||||||
|
sb.append(seg);
|
||||||
|
}
|
||||||
|
} else { // len > 1
|
||||||
|
sb.append(seg.substring(0, seg.length() - 2));
|
||||||
|
char lastcSec = seg.charAt(seg.length() - 2);
|
||||||
|
if (lastcSec == '\\') {
|
||||||
|
sb.append("\\'");
|
||||||
|
} else {
|
||||||
|
sb.append(lastcSec);
|
||||||
|
sb.append("\\'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end < origin.length()) {
|
||||||
|
sb.append(origin.substring(end));
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getNativeSql(String rawSql, Object[] parameters) {
|
||||||
|
// toLowerCase
|
||||||
|
String preparedSql = rawSql.trim().toLowerCase();
|
||||||
|
|
||||||
|
String[] clause = new String[0];
|
||||||
|
if (SqlSyntaxValidator.isInsertSql(preparedSql)) {
|
||||||
|
// insert or import
|
||||||
|
clause = new String[]{"values\\s*\\(.*?\\)", "tags\\s*\\(.*?\\)"};
|
||||||
|
}
|
||||||
|
if (SqlSyntaxValidator.isSelectSql(preparedSql)) {
|
||||||
|
// select
|
||||||
|
clause = new String[]{"where\\s*.*"};
|
||||||
|
}
|
||||||
|
Map<Integer, Integer> placeholderPositions = new HashMap<>();
|
||||||
|
RangeSet<Integer> clauseRangeSet = TreeRangeSet.create();
|
||||||
|
findPlaceholderPosition(preparedSql, placeholderPositions);
|
||||||
|
findClauseRangeSet(preparedSql, clause, clauseRangeSet);
|
||||||
|
|
||||||
|
return transformSql(rawSql, parameters, placeholderPositions, clauseRangeSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void findClauseRangeSet(String preparedSql, String[] regexArr, RangeSet<Integer> clauseRangeSet) {
|
||||||
|
clauseRangeSet.clear();
|
||||||
|
for (String regex : regexArr) {
|
||||||
|
Matcher matcher = Pattern.compile(regex).matcher(preparedSql);
|
||||||
|
while (matcher.find()) {
|
||||||
|
int start = matcher.start();
|
||||||
|
int end = matcher.end();
|
||||||
|
clauseRangeSet.add(Range.closed(start, end));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void findPlaceholderPosition(String preparedSql, Map<Integer, Integer> placeholderPosition) {
|
||||||
|
placeholderPosition.clear();
|
||||||
|
Matcher matcher = Pattern.compile("\\?").matcher(preparedSql);
|
||||||
|
int index = 0;
|
||||||
|
while (matcher.find()) {
|
||||||
|
int pos = matcher.start();
|
||||||
|
placeholderPosition.put(index, pos);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
*
|
||||||
|
* @param rawSql
|
||||||
|
* @param paramArr
|
||||||
|
* @param placeholderPosition
|
||||||
|
* @param clauseRangeSet
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static String transformSql(String rawSql, Object[] paramArr, Map<Integer, Integer> placeholderPosition, RangeSet<Integer> clauseRangeSet) {
|
||||||
|
String[] sqlArr = rawSql.split("\\?");
|
||||||
|
|
||||||
|
return IntStream.range(0, sqlArr.length).mapToObj(index -> {
|
||||||
|
if (index == paramArr.length)
|
||||||
|
return sqlArr[index];
|
||||||
|
|
||||||
|
Object para = paramArr[index];
|
||||||
|
String paraStr;
|
||||||
|
if (para != null) {
|
||||||
|
if (para instanceof byte[]) {
|
||||||
|
paraStr = new String((byte[]) para, Charset.forName("UTF-8"));
|
||||||
|
} else {
|
||||||
|
paraStr = para.toString();
|
||||||
|
}
|
||||||
|
// if para is timestamp or String or byte[] need to translate ' character
|
||||||
|
if (para instanceof Timestamp || para instanceof String || para instanceof byte[]) {
|
||||||
|
paraStr = Utils.escapeSingleQuota(paraStr);
|
||||||
|
|
||||||
|
Integer pos = placeholderPosition.get(index);
|
||||||
|
boolean contains = clauseRangeSet.contains(pos);
|
||||||
|
if (contains) {
|
||||||
|
paraStr = "'" + paraStr + "'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
paraStr = "NULL";
|
||||||
|
}
|
||||||
|
return sqlArr[index] + paraStr;
|
||||||
|
}).collect(Collectors.joining());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String formatTimestamp(Timestamp timestamp) {
|
||||||
|
int nanos = timestamp.getNanos();
|
||||||
|
if (nanos % 1000000l != 0)
|
||||||
|
return timestamp.toLocalDateTime().format(formatter2);
|
||||||
|
return timestamp.toLocalDateTime().format(formatter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
package com.taosdata.jdbc;
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -12,17 +13,61 @@ import java.util.Properties;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class SubscribeTest {
|
public class SubscribeTest {
|
||||||
|
|
||||||
Connection connection;
|
Connection connection;
|
||||||
Statement statement;
|
Statement statement;
|
||||||
String dbName = "test";
|
String dbName = "test";
|
||||||
String tName = "t0";
|
String tName = "t0";
|
||||||
String host = "127.0.0.1";
|
String host = "127.0.0.1";
|
||||||
String topic = "test";
|
String topic = "test";
|
||||||
|
private long ts;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void subscribe() {
|
||||||
|
try {
|
||||||
|
String rawSql = "select * from " + dbName + "." + tName + ";";
|
||||||
|
TSDBConnection conn = connection.unwrap(TSDBConnection.class);
|
||||||
|
TSDBSubscribe subscribe = conn.subscribe(topic, rawSql, false);
|
||||||
|
|
||||||
|
for (int j = 0; j < 10; j++) {
|
||||||
|
TimeUnit.SECONDS.sleep(1);
|
||||||
|
TSDBResultSet resSet = subscribe.consume();
|
||||||
|
|
||||||
|
int rowCnt = 0;
|
||||||
|
while (resSet.next()) {
|
||||||
|
if (rowCnt == 0) {
|
||||||
|
long cur_ts = resSet.getTimestamp(1).getTime();
|
||||||
|
int k = resSet.getInt(2);
|
||||||
|
int v = resSet.getInt(3);
|
||||||
|
Assert.assertEquals(ts, cur_ts);
|
||||||
|
Assert.assertEquals(100, k);
|
||||||
|
Assert.assertEquals(1, v);
|
||||||
|
}
|
||||||
|
if (rowCnt == 1) {
|
||||||
|
long cur_ts = resSet.getTimestamp(1).getTime();
|
||||||
|
int k = resSet.getInt(2);
|
||||||
|
int v = resSet.getInt(3);
|
||||||
|
Assert.assertEquals(ts + 1, cur_ts);
|
||||||
|
Assert.assertEquals(101, k);
|
||||||
|
Assert.assertEquals(2, v);
|
||||||
|
|
||||||
|
}
|
||||||
|
rowCnt++;
|
||||||
|
}
|
||||||
|
if (j == 0)
|
||||||
|
Assert.assertEquals(2, rowCnt);
|
||||||
|
resSet.close();
|
||||||
|
}
|
||||||
|
subscribe.close(true);
|
||||||
|
|
||||||
|
|
||||||
|
} catch (SQLException | InterruptedException throwables) {
|
||||||
|
throwables.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void createDatabase() {
|
public void createDatabase() throws SQLException {
|
||||||
try {
|
|
||||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||||
|
@ -33,46 +78,9 @@ public class SubscribeTest {
|
||||||
statement.execute("drop database if exists " + dbName);
|
statement.execute("drop database if exists " + dbName);
|
||||||
statement.execute("create database if not exists " + dbName);
|
statement.execute("create database if not exists " + dbName);
|
||||||
statement.execute("create table if not exists " + dbName + "." + tName + " (ts timestamp, k int, v int)");
|
statement.execute("create table if not exists " + dbName + "." + tName + " (ts timestamp, k int, v int)");
|
||||||
long ts = System.currentTimeMillis();
|
ts = System.currentTimeMillis();
|
||||||
for (int i = 0; i < 2; i++) {
|
statement.executeUpdate("insert into " + dbName + "." + tName + " values (" + ts + ", 100, 1)");
|
||||||
ts += i;
|
statement.executeUpdate("insert into " + dbName + "." + tName + " values (" + (ts + 1) + ", 101, 2)");
|
||||||
String sql = "insert into " + dbName + "." + tName + " values (" + ts + ", " + (100 + i) + ", " + i + ")";
|
|
||||||
statement.executeUpdate(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (ClassNotFoundException | SQLException e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void subscribe() {
|
|
||||||
try {
|
|
||||||
String rawSql = "select * from " + dbName + "." + tName + ";";
|
|
||||||
System.out.println(rawSql);
|
|
||||||
// TSDBSubscribe subscribe = ((TSDBConnection) connection).subscribe(topic, rawSql, false);
|
|
||||||
|
|
||||||
// int a = 0;
|
|
||||||
// while (true) {
|
|
||||||
// TimeUnit.MILLISECONDS.sleep(1000);
|
|
||||||
// TSDBResultSet resSet = subscribe.consume();
|
|
||||||
// while (resSet.next()) {
|
|
||||||
// for (int i = 1; i <= resSet.getMetaData().getColumnCount(); i++) {
|
|
||||||
// System.out.printf(i + ": " + resSet.getString(i) + "\t");
|
|
||||||
// }
|
|
||||||
// System.out.println("\n======" + a + "==========");
|
|
||||||
// }
|
|
||||||
// a++;
|
|
||||||
// if (a >= 2) {
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// resSet.close();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// subscribe.close(true);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
@ -86,6 +94,5 @@ public class SubscribeTest {
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -8,6 +8,8 @@ import org.junit.Test;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
public class TSDBPreparedStatementTest {
|
public class TSDBPreparedStatementTest {
|
||||||
private static final String host = "127.0.0.1";
|
private static final String host = "127.0.0.1";
|
||||||
|
@ -97,6 +99,118 @@ public class TSDBPreparedStatementTest {
|
||||||
Assert.assertEquals(1, result);
|
Assert.assertEquals(1, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void executeTest() throws SQLException {
|
||||||
|
Statement stmt = conn.createStatement();
|
||||||
|
|
||||||
|
int numOfRows = 1000;
|
||||||
|
|
||||||
|
for (int loop = 0; loop < 10; loop++){
|
||||||
|
stmt.execute("drop table if exists weather_test");
|
||||||
|
stmt.execute("create table weather_test(ts timestamp, f1 nchar(4), f2 float, f3 double, f4 timestamp, f5 int, f6 bool, f7 binary(10))");
|
||||||
|
|
||||||
|
TSDBPreparedStatement s = (TSDBPreparedStatement) conn.prepareStatement("insert into ? values(?, ?, ?, ?, ?, ?, ?, ?)");
|
||||||
|
Random r = new Random();
|
||||||
|
s.setTableName("weather_test");
|
||||||
|
|
||||||
|
ArrayList<Long> ts = new ArrayList<Long>();
|
||||||
|
for(int i = 0; i < numOfRows; i++) {
|
||||||
|
ts.add(System.currentTimeMillis() + i);
|
||||||
|
}
|
||||||
|
s.setTimestamp(0, ts);
|
||||||
|
|
||||||
|
int random = 10 + r.nextInt(5);
|
||||||
|
ArrayList<String> s2 = new ArrayList<String>();
|
||||||
|
for(int i = 0; i < numOfRows; i++) {
|
||||||
|
if(i % random == 0) {
|
||||||
|
s2.add(null);
|
||||||
|
}else{
|
||||||
|
s2.add("分支" + i % 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.setNString(1, s2, 4);
|
||||||
|
|
||||||
|
random = 10 + r.nextInt(5);
|
||||||
|
ArrayList<Float> s3 = new ArrayList<Float>();
|
||||||
|
for(int i = 0; i < numOfRows; i++) {
|
||||||
|
if(i % random == 0) {
|
||||||
|
s3.add(null);
|
||||||
|
}else{
|
||||||
|
s3.add(r.nextFloat());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.setFloat(2, s3);
|
||||||
|
|
||||||
|
random = 10 + r.nextInt(5);
|
||||||
|
ArrayList<Double> s4 = new ArrayList<Double>();
|
||||||
|
for(int i = 0; i < numOfRows; i++) {
|
||||||
|
if(i % random == 0) {
|
||||||
|
s4.add(null);
|
||||||
|
}else{
|
||||||
|
s4.add(r.nextDouble());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.setDouble(3, s4);
|
||||||
|
|
||||||
|
random = 10 + r.nextInt(5);
|
||||||
|
ArrayList<Long> ts2 = new ArrayList<Long>();
|
||||||
|
for(int i = 0; i < numOfRows; i++) {
|
||||||
|
if(i % random == 0) {
|
||||||
|
ts2.add(null);
|
||||||
|
}else{
|
||||||
|
ts2.add(System.currentTimeMillis() + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.setTimestamp(4, ts2);
|
||||||
|
|
||||||
|
random = 10 + r.nextInt(5);
|
||||||
|
ArrayList<Integer> vals = new ArrayList<>();
|
||||||
|
for(int i = 0; i < numOfRows; i++) {
|
||||||
|
if(i % random == 0) {
|
||||||
|
vals.add(null);
|
||||||
|
}else{
|
||||||
|
vals.add(r.nextInt());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.setInt(5, vals);
|
||||||
|
|
||||||
|
random = 10 + r.nextInt(5);
|
||||||
|
ArrayList<Boolean> sb = new ArrayList<>();
|
||||||
|
for(int i = 0; i < numOfRows; i++) {
|
||||||
|
if(i % random == 0) {
|
||||||
|
sb.add(null);
|
||||||
|
}else{
|
||||||
|
sb.add(i % 2 == 0 ? true : false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.setBoolean(6, sb);
|
||||||
|
|
||||||
|
random = 10 + r.nextInt(5);
|
||||||
|
ArrayList<String> s5 = new ArrayList<String>();
|
||||||
|
for(int i = 0; i < numOfRows; i++) {
|
||||||
|
if(i % random == 0) {
|
||||||
|
s5.add(null);
|
||||||
|
}else{
|
||||||
|
s5.add("test" + i % 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.setString(7, s5, 10);
|
||||||
|
|
||||||
|
s.columnDataAddBatch();
|
||||||
|
s.columnDataExecuteBatch();
|
||||||
|
s.columnDataCloseBatch();
|
||||||
|
|
||||||
|
String sql = "select * from weather_test";
|
||||||
|
PreparedStatement statement = conn.prepareStatement(sql);
|
||||||
|
ResultSet rs = statement.executeQuery();
|
||||||
|
int rows = 0;
|
||||||
|
while(rs.next()) {
|
||||||
|
rows++;
|
||||||
|
}
|
||||||
|
Assert.assertEquals(numOfRows, rows);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void setBoolean() throws SQLException {
|
public void setBoolean() throws SQLException {
|
||||||
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
||||||
|
|
|
@ -3,7 +3,6 @@ package com.taosdata.jdbc;
|
||||||
import com.google.common.primitives.Ints;
|
import com.google.common.primitives.Ints;
|
||||||
import com.google.common.primitives.Longs;
|
import com.google.common.primitives.Longs;
|
||||||
import com.google.common.primitives.Shorts;
|
import com.google.common.primitives.Shorts;
|
||||||
import com.taosdata.jdbc.rs.RestfulResultSet;
|
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
@ -177,6 +176,7 @@ public class TSDBResultSetTest {
|
||||||
rs.getAsciiStream("f1");
|
rs.getAsciiStream("f1");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
@Test(expected = SQLFeatureNotSupportedException.class)
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
public void getUnicodeStream() throws SQLException {
|
public void getUnicodeStream() throws SQLException {
|
||||||
rs.getUnicodeStream("f1");
|
rs.getUnicodeStream("f1");
|
||||||
|
@ -326,7 +326,7 @@ public class TSDBResultSetTest {
|
||||||
|
|
||||||
@Test(expected = SQLFeatureNotSupportedException.class)
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
public void getRow() throws SQLException {
|
public void getRow() throws SQLException {
|
||||||
int row = rs.getRow();
|
rs.getRow();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = SQLFeatureNotSupportedException.class)
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
@ -405,12 +405,12 @@ public class TSDBResultSetTest {
|
||||||
|
|
||||||
@Test(expected = SQLFeatureNotSupportedException.class)
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
public void updateByte() throws SQLException {
|
public void updateByte() throws SQLException {
|
||||||
rs.updateByte(1, new Byte("0"));
|
rs.updateByte(1, (byte) 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = SQLFeatureNotSupportedException.class)
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
public void updateShort() throws SQLException {
|
public void updateShort() throws SQLException {
|
||||||
rs.updateShort(1, new Short("0"));
|
rs.updateShort(1, (short) 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = SQLFeatureNotSupportedException.class)
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
|
|
@ -0,0 +1,401 @@
|
||||||
|
package com.taosdata.jdbc.cases;
|
||||||
|
|
||||||
|
import org.junit.*;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
|
||||||
|
public class InsertSpecialCharacterJniTest {
|
||||||
|
|
||||||
|
private static final String host = "127.0.0.1";
|
||||||
|
private static Connection conn;
|
||||||
|
private static String dbName = "spec_char_test";
|
||||||
|
private static String tbname1 = "test";
|
||||||
|
private static String tbname2 = "weather";
|
||||||
|
private static String special_character_str_1 = "$asd$$fsfsf$";
|
||||||
|
private static String special_character_str_2 = "\\\\asdfsfsf\\\\";
|
||||||
|
private static String special_character_str_3 = "\\\\asdfsfsf\\";
|
||||||
|
private static String special_character_str_4 = "?asd??fsf?sf?";
|
||||||
|
private static String special_character_str_5 = "?#sd@$f(('<(s[P)>\"){]}f?s[]{}%vaew|\"fsfs^a&d*jhg)(j))(f@~!?$";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase01() throws SQLException {
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
// insert
|
||||||
|
final String sql = "insert into " + tbname1 + "(ts, f1) values(?, ?)";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
pstmt.setTimestamp(1, new Timestamp(now));
|
||||||
|
pstmt.setBytes(2, special_character_str_1.getBytes());
|
||||||
|
int ret = pstmt.executeUpdate();
|
||||||
|
Assert.assertEquals(1, ret);
|
||||||
|
}
|
||||||
|
// query
|
||||||
|
final String query = "select * from ?";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(query)) {
|
||||||
|
pstmt.setString(1, tbname1);
|
||||||
|
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
rs.next();
|
||||||
|
long timestamp = rs.getTimestamp(1).getTime();
|
||||||
|
Assert.assertEquals(now, timestamp);
|
||||||
|
String f1 = new String(rs.getBytes(2));
|
||||||
|
Assert.assertEquals(special_character_str_1, f1);
|
||||||
|
String f2 = rs.getString(3);
|
||||||
|
Assert.assertNull(f2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase02() throws SQLException {
|
||||||
|
//TODO:
|
||||||
|
// Expected :\asdfsfsf\\
|
||||||
|
// Actual :\asdfsfsf\
|
||||||
|
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
// insert
|
||||||
|
final String sql = "insert into " + tbname1 + "(ts, f1) values(?, ?)";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
pstmt.setTimestamp(1, new Timestamp(now));
|
||||||
|
pstmt.setBytes(2, special_character_str_2.getBytes());
|
||||||
|
int ret = pstmt.executeUpdate();
|
||||||
|
Assert.assertEquals(1, ret);
|
||||||
|
}
|
||||||
|
// query
|
||||||
|
final String query = "select * from " + tbname1;
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(query)) {
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
rs.next();
|
||||||
|
long timestamp = rs.getTimestamp(1).getTime();
|
||||||
|
Assert.assertEquals(now, timestamp);
|
||||||
|
String f1 = new String(rs.getBytes(2));
|
||||||
|
//TODO: bug to be fixed
|
||||||
|
// Assert.assertEquals(special_character_str_2, f1);
|
||||||
|
Assert.assertEquals(special_character_str_2.substring(1, special_character_str_1.length() - 1), f1);
|
||||||
|
String f2 = rs.getString(3);
|
||||||
|
Assert.assertNull(f2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLException.class)
|
||||||
|
public void testCase03() throws SQLException {
|
||||||
|
//TODO:
|
||||||
|
// TDengine ERROR (216): Syntax error in SQL
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
// insert
|
||||||
|
final String sql = "insert into " + tbname1 + "(ts, f1) values(?, ?)";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
pstmt.setTimestamp(1, new Timestamp(now));
|
||||||
|
pstmt.setBytes(2, special_character_str_3.getBytes());
|
||||||
|
int ret = pstmt.executeUpdate();
|
||||||
|
Assert.assertEquals(1, ret);
|
||||||
|
}
|
||||||
|
// query
|
||||||
|
final String query = "select * from " + tbname1;
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(query)) {
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
rs.next();
|
||||||
|
long timestamp = rs.getTimestamp(1).getTime();
|
||||||
|
Assert.assertEquals(now, timestamp);
|
||||||
|
String f1 = new String(rs.getBytes(2));
|
||||||
|
Assert.assertEquals(special_character_str_3, f1);
|
||||||
|
String f2 = rs.getString(3);
|
||||||
|
Assert.assertNull(f2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase04() throws SQLException {
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
// insert
|
||||||
|
final String sql = "insert into " + tbname1 + "(ts, f1) values(?, ?)";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
pstmt.setTimestamp(1, new Timestamp(now));
|
||||||
|
pstmt.setBytes(2, special_character_str_4.getBytes());
|
||||||
|
int ret = pstmt.executeUpdate();
|
||||||
|
Assert.assertEquals(1, ret);
|
||||||
|
}
|
||||||
|
// query
|
||||||
|
final String query = "select * from " + tbname1;
|
||||||
|
try (Statement stmt = conn.createStatement()) {
|
||||||
|
ResultSet rs = stmt.executeQuery(query);
|
||||||
|
rs.next();
|
||||||
|
long timestamp = rs.getTimestamp(1).getTime();
|
||||||
|
Assert.assertEquals(now, timestamp);
|
||||||
|
String f1 = new String(rs.getBytes(2));
|
||||||
|
Assert.assertEquals(special_character_str_4, f1);
|
||||||
|
String f2 = rs.getString(3);
|
||||||
|
Assert.assertNull(f2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase05() throws SQLException {
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
// insert
|
||||||
|
final String sql = "insert into " + tbname1 + "(ts, f1) values(?, ?)";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
pstmt.setTimestamp(1, new Timestamp(now));
|
||||||
|
pstmt.setBytes(2, special_character_str_5.getBytes());
|
||||||
|
int ret = pstmt.executeUpdate();
|
||||||
|
Assert.assertEquals(1, ret);
|
||||||
|
}
|
||||||
|
// query
|
||||||
|
final String query = "select * from " + tbname1;
|
||||||
|
try (Statement stmt = conn.createStatement()) {
|
||||||
|
ResultSet rs = stmt.executeQuery(query);
|
||||||
|
rs.next();
|
||||||
|
long timestamp = rs.getTimestamp(1).getTime();
|
||||||
|
Assert.assertEquals(now, timestamp);
|
||||||
|
String f1 = new String(rs.getBytes(2));
|
||||||
|
Assert.assertEquals(special_character_str_5, f1);
|
||||||
|
String f2 = rs.getString(3);
|
||||||
|
Assert.assertNull(f2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase06() throws SQLException {
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
// insert
|
||||||
|
final String sql = "insert into t? using " + tbname2 + " tags(?) values(?, ?, ?)";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
pstmt.setInt(1, 1);
|
||||||
|
pstmt.setString(2, special_character_str_4);
|
||||||
|
pstmt.setTimestamp(3, new Timestamp(now));
|
||||||
|
pstmt.setBytes(4, special_character_str_4.getBytes());
|
||||||
|
int ret = pstmt.executeUpdate();
|
||||||
|
Assert.assertEquals(1, ret);
|
||||||
|
}
|
||||||
|
// query t1
|
||||||
|
final String query = "select * from t1";
|
||||||
|
try (Statement stmt = conn.createStatement()) {
|
||||||
|
ResultSet rs = stmt.executeQuery(query);
|
||||||
|
rs.next();
|
||||||
|
long timestamp = rs.getTimestamp(1).getTime();
|
||||||
|
Assert.assertEquals(now, timestamp);
|
||||||
|
String f1 = new String(rs.getBytes(2));
|
||||||
|
Assert.assertEquals(special_character_str_4, f1);
|
||||||
|
String f2 = rs.getString(3);
|
||||||
|
Assert.assertNull(f2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase07() throws SQLException {
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
// insert
|
||||||
|
final String sql = "insert into " + tbname1 + "(ts, f1, f2) values(?, ?, ?) ; ";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
pstmt.setTimestamp(1, new Timestamp(now));
|
||||||
|
pstmt.setBytes(2, special_character_str_4.getBytes());
|
||||||
|
pstmt.setString(3, special_character_str_4);
|
||||||
|
int ret = pstmt.executeUpdate();
|
||||||
|
Assert.assertEquals(1, ret);
|
||||||
|
}
|
||||||
|
// query
|
||||||
|
final String query = "select * from " + tbname1;
|
||||||
|
try (Statement stmt = conn.createStatement()) {
|
||||||
|
ResultSet rs = stmt.executeQuery(query);
|
||||||
|
rs.next();
|
||||||
|
long timestamp = rs.getTimestamp(1).getTime();
|
||||||
|
Assert.assertEquals(now, timestamp);
|
||||||
|
String f1 = new String(rs.getBytes(2));
|
||||||
|
Assert.assertEquals(special_character_str_4, f1);
|
||||||
|
String f2 = rs.getString(3);
|
||||||
|
Assert.assertEquals(special_character_str_4, f2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLException.class)
|
||||||
|
public void testCase08() throws SQLException {
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
// insert
|
||||||
|
final String sql = "insert into t? using " + tbname2 + " tags(?) values(?, ?, ?) ? ";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
pstmt.setInt(1, 1);
|
||||||
|
pstmt.setString(2, special_character_str_5);
|
||||||
|
pstmt.setTimestamp(3, new Timestamp(now));
|
||||||
|
pstmt.setBytes(4, special_character_str_5.getBytes());
|
||||||
|
int ret = pstmt.executeUpdate();
|
||||||
|
Assert.assertEquals(1, ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase09() throws SQLException {
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
// insert
|
||||||
|
final String sql = "insert into ?.t? using " + tbname2 + " tags(?) values(?, ?, ?) t? using weather tags(?) values(?,?,?) ";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
// t1
|
||||||
|
pstmt.setString(1, dbName);
|
||||||
|
pstmt.setInt(2, 1);
|
||||||
|
pstmt.setString(3, special_character_str_5);
|
||||||
|
pstmt.setTimestamp(4, new Timestamp(now));
|
||||||
|
pstmt.setBytes(5, special_character_str_5.getBytes());
|
||||||
|
// t2
|
||||||
|
pstmt.setInt(7, 2);
|
||||||
|
pstmt.setString(8, special_character_str_5);
|
||||||
|
pstmt.setTimestamp(9, new Timestamp(now));
|
||||||
|
pstmt.setString(11, special_character_str_5);
|
||||||
|
|
||||||
|
int ret = pstmt.executeUpdate();
|
||||||
|
Assert.assertEquals(2, ret);
|
||||||
|
}
|
||||||
|
// query t1
|
||||||
|
String query = "select * from t?";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(query)) {
|
||||||
|
pstmt.setInt(1, 1);
|
||||||
|
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
rs.next();
|
||||||
|
long timestamp = rs.getTimestamp(1).getTime();
|
||||||
|
Assert.assertEquals(now, timestamp);
|
||||||
|
String f1 = new String(rs.getBytes(2));
|
||||||
|
Assert.assertEquals(special_character_str_5, f1);
|
||||||
|
String f2 = rs.getString(3);
|
||||||
|
Assert.assertNull(f2);
|
||||||
|
}
|
||||||
|
// query t2
|
||||||
|
query = "select * from t2";
|
||||||
|
try (Statement stmt = conn.createStatement()) {
|
||||||
|
ResultSet rs = stmt.executeQuery(query);
|
||||||
|
rs.next();
|
||||||
|
long timestamp = rs.getTimestamp(1).getTime();
|
||||||
|
Assert.assertEquals(now, timestamp);
|
||||||
|
byte[] f1 = rs.getBytes(2);
|
||||||
|
Assert.assertNull(f1);
|
||||||
|
String f2 = new String(rs.getBytes(3));
|
||||||
|
Assert.assertEquals(special_character_str_5, f2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase10() throws SQLException {
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
|
||||||
|
// insert
|
||||||
|
final String sql = "insert into t? using ? tags(?) values(?, ?, ?) t? using " + tbname2 + " tags(?) values(?,?,?) ";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
// t1
|
||||||
|
pstmt.setInt(1, 1);
|
||||||
|
pstmt.setString(2, tbname2);
|
||||||
|
pstmt.setString(3, special_character_str_5);
|
||||||
|
pstmt.setTimestamp(4, new Timestamp(now));
|
||||||
|
pstmt.setBytes(5, special_character_str_5.getBytes());
|
||||||
|
// t2
|
||||||
|
pstmt.setInt(7, 2);
|
||||||
|
pstmt.setString(8, special_character_str_5);
|
||||||
|
pstmt.setTimestamp(9, new Timestamp(now));
|
||||||
|
pstmt.setString(11, special_character_str_5);
|
||||||
|
|
||||||
|
int ret = pstmt.executeUpdate();
|
||||||
|
Assert.assertEquals(2, ret);
|
||||||
|
}
|
||||||
|
//query t1
|
||||||
|
String query = "select * from ?.t? where ts < ? and ts >= ? and ? is not null";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(query)) {
|
||||||
|
pstmt.setString(1, dbName);
|
||||||
|
pstmt.setInt(2, 1);
|
||||||
|
pstmt.setTimestamp(3, new Timestamp(System.currentTimeMillis()));
|
||||||
|
pstmt.setTimestamp(4, new Timestamp(0));
|
||||||
|
pstmt.setString(5, "f1");
|
||||||
|
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
rs.next();
|
||||||
|
long timestamp = rs.getTimestamp(1).getTime();
|
||||||
|
Assert.assertEquals(now, timestamp);
|
||||||
|
String f1 = new String(rs.getBytes(2));
|
||||||
|
Assert.assertEquals(special_character_str_5, f1);
|
||||||
|
byte[] f2 = rs.getBytes(3);
|
||||||
|
Assert.assertNull(f2);
|
||||||
|
}
|
||||||
|
// query t2
|
||||||
|
query = "select * from t? where ts < ? and ts >= ? and ? is not null";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(query)) {
|
||||||
|
pstmt.setInt(1, 2);
|
||||||
|
pstmt.setTimestamp(2, new Timestamp(System.currentTimeMillis()));
|
||||||
|
pstmt.setTimestamp(3, new Timestamp(0));
|
||||||
|
pstmt.setString(4, "f2");
|
||||||
|
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
rs.next();
|
||||||
|
long timestamp = rs.getTimestamp(1).getTime();
|
||||||
|
Assert.assertEquals(now, timestamp);
|
||||||
|
byte[] f1 = rs.getBytes(2);
|
||||||
|
Assert.assertNull(f1);
|
||||||
|
String f2 = new String(rs.getBytes(3));
|
||||||
|
Assert.assertEquals(special_character_str_5, f2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLException.class)
|
||||||
|
public void testCase11() throws SQLException {
|
||||||
|
final String speicalCharacterStr = "?#sd@$f(((s[P)){]}f?s[]{}%vs^a&d*jhg)(j))(f@~!?$";
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
|
||||||
|
final String sql = "insert into t? using " + tbname2 + " values(?, ?, 'abc?abc') ";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
pstmt.setInt(1, 1);
|
||||||
|
pstmt.setTimestamp(2, new Timestamp(now));
|
||||||
|
pstmt.setBytes(3, speicalCharacterStr.getBytes());
|
||||||
|
|
||||||
|
int ret = pstmt.executeUpdate();
|
||||||
|
Assert.assertEquals(1, ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase12() throws SQLException {
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
// insert
|
||||||
|
final String sql = "insert into " + tbname1 + "(ts, f1, f2) values(?, 'HelloTDengine', ?) ; ";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
pstmt.setTimestamp(1, new Timestamp(now));
|
||||||
|
pstmt.setString(2, special_character_str_4);
|
||||||
|
int ret = pstmt.executeUpdate();
|
||||||
|
Assert.assertEquals(1, ret);
|
||||||
|
}
|
||||||
|
// query
|
||||||
|
final String query = "select * from " + tbname1;
|
||||||
|
try (Statement stmt = conn.createStatement()) {
|
||||||
|
ResultSet rs = stmt.executeQuery(query);
|
||||||
|
rs.next();
|
||||||
|
long timestamp = rs.getTimestamp(1).getTime();
|
||||||
|
Assert.assertEquals(now, timestamp);
|
||||||
|
String f1 = new String(rs.getBytes(2));
|
||||||
|
Assert.assertEquals("HelloTDengine", f1);
|
||||||
|
String f2 = rs.getString(3);
|
||||||
|
Assert.assertEquals(special_character_str_4, f2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before() throws SQLException {
|
||||||
|
try (Statement stmt = conn.createStatement()) {
|
||||||
|
stmt.execute("drop table if exists " + tbname1 + "");
|
||||||
|
stmt.execute("create table " + tbname1 + "(ts timestamp,f1 binary(64),f2 nchar(64))");
|
||||||
|
stmt.execute("drop table if exists " + tbname2);
|
||||||
|
stmt.execute("create table " + tbname2 + "(ts timestamp, f1 binary(64), f2 nchar(64)) tags(loc nchar(64))");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() throws SQLException {
|
||||||
|
String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata";
|
||||||
|
conn = DriverManager.getConnection(url);
|
||||||
|
try (Statement stmt = conn.createStatement()) {
|
||||||
|
stmt.execute("drop database if exists " + dbName);
|
||||||
|
stmt.execute("create database if not exists " + dbName);
|
||||||
|
stmt.execute("use " + dbName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void afterClass() throws SQLException {
|
||||||
|
if (conn != null)
|
||||||
|
conn.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,400 @@
|
||||||
|
package com.taosdata.jdbc.cases;
|
||||||
|
|
||||||
|
import org.junit.*;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
|
||||||
|
public class InsertSpecialCharacterRestfulTest {
|
||||||
|
|
||||||
|
private static final String host = "127.0.0.1";
|
||||||
|
private static Connection conn;
|
||||||
|
private static String dbName = "spec_char_test";
|
||||||
|
private static String tbname1 = "test";
|
||||||
|
private static String tbname2 = "weather";
|
||||||
|
private static String special_character_str_1 = "$asd$$fsfsf$";
|
||||||
|
private static String special_character_str_2 = "\\\\asdfsfsf\\\\";
|
||||||
|
private static String special_character_str_3 = "\\\\asdfsfsf\\";
|
||||||
|
private static String special_character_str_4 = "?asd??fsf?sf?";
|
||||||
|
private static String special_character_str_5 = "?#sd@$f(('<(s[P)>\"){]}f?s[]{}%vaew|\"fsfs^a&d*jhg)(j))(f@~!?$";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase01() throws SQLException {
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
// insert
|
||||||
|
final String sql = "insert into " + tbname1 + "(ts, f1) values(?, ?)";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
pstmt.setTimestamp(1, new Timestamp(now));
|
||||||
|
pstmt.setBytes(2, special_character_str_1.getBytes());
|
||||||
|
int ret = pstmt.executeUpdate();
|
||||||
|
Assert.assertEquals(1, ret);
|
||||||
|
}
|
||||||
|
// query
|
||||||
|
final String query = "select * from ?";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(query)) {
|
||||||
|
pstmt.setString(1, tbname1);
|
||||||
|
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
rs.next();
|
||||||
|
long timestamp = rs.getTimestamp(1).getTime();
|
||||||
|
Assert.assertEquals(now, timestamp);
|
||||||
|
String f1 = new String(rs.getBytes(2));
|
||||||
|
Assert.assertEquals(special_character_str_1, f1);
|
||||||
|
String f2 = rs.getString(3);
|
||||||
|
Assert.assertNull(f2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase02() throws SQLException {
|
||||||
|
//TODO:
|
||||||
|
// Expected :\asdfsfsf\
|
||||||
|
// Actual :\asdfsfsf\
|
||||||
|
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
// insert
|
||||||
|
final String sql = "insert into " + tbname1 + "(ts, f1) values(?, ?)";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
pstmt.setTimestamp(1, new Timestamp(now));
|
||||||
|
pstmt.setBytes(2, special_character_str_2.getBytes());
|
||||||
|
int ret = pstmt.executeUpdate();
|
||||||
|
Assert.assertEquals(1, ret);
|
||||||
|
}
|
||||||
|
// query
|
||||||
|
final String query = "select * from " + tbname1;
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(query)) {
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
rs.next();
|
||||||
|
long timestamp = rs.getTimestamp(1).getTime();
|
||||||
|
Assert.assertEquals(now, timestamp);
|
||||||
|
String f1 = new String(rs.getBytes(2));
|
||||||
|
//TODO: bug to be fixed
|
||||||
|
// Assert.assertEquals(special_character_str_2, f1);
|
||||||
|
Assert.assertEquals(special_character_str_2.substring(1, special_character_str_1.length() - 1), f1);
|
||||||
|
String f2 = rs.getString(3);
|
||||||
|
Assert.assertNull(f2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLException.class)
|
||||||
|
public void testCase03() throws SQLException {
|
||||||
|
//TODO:
|
||||||
|
// TDengine ERROR (216): Syntax error in SQL
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
// insert
|
||||||
|
final String sql = "insert into " + tbname1 + "(ts, f1) values(?, ?)";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
pstmt.setTimestamp(1, new Timestamp(now));
|
||||||
|
pstmt.setBytes(2, special_character_str_3.getBytes());
|
||||||
|
int ret = pstmt.executeUpdate();
|
||||||
|
Assert.assertEquals(1, ret);
|
||||||
|
}
|
||||||
|
// query
|
||||||
|
final String query = "select * from " + tbname1;
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(query)) {
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
rs.next();
|
||||||
|
long timestamp = rs.getTimestamp(1).getTime();
|
||||||
|
Assert.assertEquals(now, timestamp);
|
||||||
|
String f1 = new String(rs.getBytes(2));
|
||||||
|
Assert.assertEquals(special_character_str_3, f1);
|
||||||
|
String f2 = rs.getString(3);
|
||||||
|
Assert.assertNull(f2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase04() throws SQLException {
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
// insert
|
||||||
|
final String sql = "insert into " + tbname1 + "(ts, f1) values(?, ?)";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
pstmt.setTimestamp(1, new Timestamp(now));
|
||||||
|
pstmt.setBytes(2, special_character_str_4.getBytes());
|
||||||
|
int ret = pstmt.executeUpdate();
|
||||||
|
Assert.assertEquals(1, ret);
|
||||||
|
}
|
||||||
|
// query
|
||||||
|
final String query = "select * from " + tbname1;
|
||||||
|
try (Statement stmt = conn.createStatement()) {
|
||||||
|
ResultSet rs = stmt.executeQuery(query);
|
||||||
|
rs.next();
|
||||||
|
long timestamp = rs.getTimestamp(1).getTime();
|
||||||
|
Assert.assertEquals(now, timestamp);
|
||||||
|
String f1 = new String(rs.getBytes(2));
|
||||||
|
Assert.assertEquals(special_character_str_4, f1);
|
||||||
|
String f2 = rs.getString(3);
|
||||||
|
Assert.assertNull(f2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase05() throws SQLException {
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
// insert
|
||||||
|
final String sql = "insert into " + tbname1 + "(ts, f1) values(?, ?)";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
pstmt.setTimestamp(1, new Timestamp(now));
|
||||||
|
pstmt.setBytes(2, special_character_str_5.getBytes());
|
||||||
|
int ret = pstmt.executeUpdate();
|
||||||
|
Assert.assertEquals(1, ret);
|
||||||
|
}
|
||||||
|
// query
|
||||||
|
final String query = "select * from " + tbname1;
|
||||||
|
try (Statement stmt = conn.createStatement()) {
|
||||||
|
ResultSet rs = stmt.executeQuery(query);
|
||||||
|
rs.next();
|
||||||
|
long timestamp = rs.getTimestamp(1).getTime();
|
||||||
|
Assert.assertEquals(now, timestamp);
|
||||||
|
String f1 = new String(rs.getBytes(2));
|
||||||
|
Assert.assertEquals(special_character_str_5, f1);
|
||||||
|
String f2 = rs.getString(3);
|
||||||
|
Assert.assertNull(f2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase06() throws SQLException {
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
// insert
|
||||||
|
final String sql = "insert into t? using " + tbname2 + " tags(?) values(?, ?, ?)";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
pstmt.setInt(1, 1);
|
||||||
|
pstmt.setString(2, special_character_str_4);
|
||||||
|
pstmt.setTimestamp(3, new Timestamp(now));
|
||||||
|
pstmt.setBytes(4, special_character_str_4.getBytes());
|
||||||
|
int ret = pstmt.executeUpdate();
|
||||||
|
Assert.assertEquals(1, ret);
|
||||||
|
}
|
||||||
|
// query t1
|
||||||
|
final String query = "select * from t1";
|
||||||
|
try (Statement stmt = conn.createStatement()) {
|
||||||
|
ResultSet rs = stmt.executeQuery(query);
|
||||||
|
rs.next();
|
||||||
|
long timestamp = rs.getTimestamp(1).getTime();
|
||||||
|
Assert.assertEquals(now, timestamp);
|
||||||
|
String f1 = new String(rs.getBytes(2));
|
||||||
|
Assert.assertEquals(special_character_str_4, f1);
|
||||||
|
String f2 = rs.getString(3);
|
||||||
|
Assert.assertNull(f2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase07() throws SQLException {
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
// insert
|
||||||
|
final String sql = "insert into " + tbname1 + "(ts, f1, f2) values(?, ?, ?) ; ";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
pstmt.setTimestamp(1, new Timestamp(now));
|
||||||
|
pstmt.setBytes(2, special_character_str_4.getBytes());
|
||||||
|
pstmt.setString(3, special_character_str_4);
|
||||||
|
int ret = pstmt.executeUpdate();
|
||||||
|
Assert.assertEquals(1, ret);
|
||||||
|
}
|
||||||
|
// query
|
||||||
|
final String query = "select * from " + tbname1;
|
||||||
|
try (Statement stmt = conn.createStatement()) {
|
||||||
|
ResultSet rs = stmt.executeQuery(query);
|
||||||
|
rs.next();
|
||||||
|
long timestamp = rs.getTimestamp(1).getTime();
|
||||||
|
Assert.assertEquals(now, timestamp);
|
||||||
|
String f1 = new String(rs.getBytes(2));
|
||||||
|
Assert.assertEquals(special_character_str_4, f1);
|
||||||
|
String f2 = rs.getString(3);
|
||||||
|
Assert.assertEquals(special_character_str_4, f2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLException.class)
|
||||||
|
public void testCase08() throws SQLException {
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
// insert
|
||||||
|
final String sql = "insert into t? using " + tbname2 + " tags(?) values(?, ?, ?) ? ";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
pstmt.setInt(1, 1);
|
||||||
|
pstmt.setString(2, special_character_str_5);
|
||||||
|
pstmt.setTimestamp(3, new Timestamp(now));
|
||||||
|
pstmt.setBytes(4, special_character_str_5.getBytes());
|
||||||
|
int ret = pstmt.executeUpdate();
|
||||||
|
Assert.assertEquals(1, ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase09() throws SQLException {
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
// insert
|
||||||
|
final String sql = "insert into ?.t? using " + tbname2 + " tags(?) values(?, ?, ?) t? using weather tags(?) values(?,?,?) ";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
// t1
|
||||||
|
pstmt.setString(1, dbName);
|
||||||
|
pstmt.setInt(2, 1);
|
||||||
|
pstmt.setString(3, special_character_str_5);
|
||||||
|
pstmt.setTimestamp(4, new Timestamp(now));
|
||||||
|
pstmt.setBytes(5, special_character_str_5.getBytes());
|
||||||
|
// t2
|
||||||
|
pstmt.setInt(7, 2);
|
||||||
|
pstmt.setString(8, special_character_str_5);
|
||||||
|
pstmt.setTimestamp(9, new Timestamp(now));
|
||||||
|
pstmt.setString(11, special_character_str_5);
|
||||||
|
|
||||||
|
int ret = pstmt.executeUpdate();
|
||||||
|
Assert.assertEquals(2, ret);
|
||||||
|
}
|
||||||
|
// query t1
|
||||||
|
String query = "select * from t?";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(query)) {
|
||||||
|
pstmt.setInt(1, 1);
|
||||||
|
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
rs.next();
|
||||||
|
long timestamp = rs.getTimestamp(1).getTime();
|
||||||
|
Assert.assertEquals(now, timestamp);
|
||||||
|
String f1 = new String(rs.getBytes(2));
|
||||||
|
Assert.assertEquals(special_character_str_5, f1);
|
||||||
|
String f2 = rs.getString(3);
|
||||||
|
Assert.assertNull(f2);
|
||||||
|
}
|
||||||
|
// query t2
|
||||||
|
query = "select * from t2";
|
||||||
|
try (Statement stmt = conn.createStatement()) {
|
||||||
|
ResultSet rs = stmt.executeQuery(query);
|
||||||
|
rs.next();
|
||||||
|
long timestamp = rs.getTimestamp(1).getTime();
|
||||||
|
Assert.assertEquals(now, timestamp);
|
||||||
|
byte[] f1 = rs.getBytes(2);
|
||||||
|
Assert.assertNull(f1);
|
||||||
|
String f2 = new String(rs.getBytes(3));
|
||||||
|
Assert.assertEquals(special_character_str_5, f2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase10() throws SQLException {
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
|
||||||
|
// insert
|
||||||
|
final String sql = "insert into t? using ? tags(?) values(?, ?, ?) t? using " + tbname2 + " tags(?) values(?,?,?) ";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
// t1
|
||||||
|
pstmt.setInt(1, 1);
|
||||||
|
pstmt.setString(2, tbname2);
|
||||||
|
pstmt.setString(3, special_character_str_5);
|
||||||
|
pstmt.setTimestamp(4, new Timestamp(now));
|
||||||
|
pstmt.setBytes(5, special_character_str_5.getBytes());
|
||||||
|
// t2
|
||||||
|
pstmt.setInt(7, 2);
|
||||||
|
pstmt.setString(8, special_character_str_5);
|
||||||
|
pstmt.setTimestamp(9, new Timestamp(now));
|
||||||
|
pstmt.setString(11, special_character_str_5);
|
||||||
|
|
||||||
|
int ret = pstmt.executeUpdate();
|
||||||
|
Assert.assertEquals(2, ret);
|
||||||
|
}
|
||||||
|
//query t1
|
||||||
|
String query = "select * from ?.t? where ts < ? and ts >= ? and ? is not null";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(query)) {
|
||||||
|
pstmt.setString(1, dbName);
|
||||||
|
pstmt.setInt(2, 1);
|
||||||
|
pstmt.setTimestamp(3, new Timestamp(System.currentTimeMillis()));
|
||||||
|
pstmt.setTimestamp(4, new Timestamp(0));
|
||||||
|
pstmt.setString(5, "f1");
|
||||||
|
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
rs.next();
|
||||||
|
long timestamp = rs.getTimestamp(1).getTime();
|
||||||
|
Assert.assertEquals(now, timestamp);
|
||||||
|
String f1 = new String(rs.getBytes(2));
|
||||||
|
Assert.assertEquals(special_character_str_5, f1);
|
||||||
|
byte[] f2 = rs.getBytes(3);
|
||||||
|
Assert.assertNull(f2);
|
||||||
|
}
|
||||||
|
// query t2
|
||||||
|
query = "select * from t? where ts < ? and ts >= ? and ? is not null";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(query)) {
|
||||||
|
pstmt.setInt(1, 2);
|
||||||
|
pstmt.setTimestamp(2, new Timestamp(System.currentTimeMillis()));
|
||||||
|
pstmt.setTimestamp(3, new Timestamp(0));
|
||||||
|
pstmt.setString(4, "f2");
|
||||||
|
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
rs.next();
|
||||||
|
long timestamp = rs.getTimestamp(1).getTime();
|
||||||
|
Assert.assertEquals(now, timestamp);
|
||||||
|
byte[] f1 = rs.getBytes(2);
|
||||||
|
Assert.assertNull(f1);
|
||||||
|
String f2 = new String(rs.getBytes(3));
|
||||||
|
Assert.assertEquals(special_character_str_5, f2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLException.class)
|
||||||
|
public void testCase11() throws SQLException {
|
||||||
|
final String speicalCharacterStr = "?#sd@$f(((s[P)){]}f?s[]{}%vs^a&d*jhg)(j))(f@~!?$";
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
|
||||||
|
final String sql = "insert into t? using " + tbname2 + " values(?, ?, 'abc?abc') ";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
pstmt.setInt(1, 1);
|
||||||
|
pstmt.setTimestamp(2, new Timestamp(now));
|
||||||
|
pstmt.setBytes(3, speicalCharacterStr.getBytes());
|
||||||
|
|
||||||
|
int ret = pstmt.executeUpdate();
|
||||||
|
Assert.assertEquals(1, ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase12() throws SQLException {
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
// insert
|
||||||
|
final String sql = "insert into " + tbname1 + "(ts, f1, f2) values(?, 'HelloTDengine', ?) ; ";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
pstmt.setTimestamp(1, new Timestamp(now));
|
||||||
|
pstmt.setString(2, special_character_str_4);
|
||||||
|
int ret = pstmt.executeUpdate();
|
||||||
|
Assert.assertEquals(1, ret);
|
||||||
|
}
|
||||||
|
// query
|
||||||
|
final String query = "select * from " + tbname1;
|
||||||
|
try (Statement stmt = conn.createStatement()) {
|
||||||
|
ResultSet rs = stmt.executeQuery(query);
|
||||||
|
rs.next();
|
||||||
|
long timestamp = rs.getTimestamp(1).getTime();
|
||||||
|
Assert.assertEquals(now, timestamp);
|
||||||
|
String f1 = new String(rs.getBytes(2));
|
||||||
|
Assert.assertEquals("HelloTDengine", f1);
|
||||||
|
String f2 = rs.getString(3);
|
||||||
|
Assert.assertEquals(special_character_str_4, f2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before() throws SQLException {
|
||||||
|
try (Statement stmt = conn.createStatement()) {
|
||||||
|
stmt.execute("drop table if exists " + tbname1 + "");
|
||||||
|
stmt.execute("create table " + tbname1 + "(ts timestamp,f1 binary(64),f2 nchar(64))");
|
||||||
|
stmt.execute("drop table if exists " + tbname2);
|
||||||
|
stmt.execute("create table " + tbname2 + "(ts timestamp, f1 binary(64), f2 nchar(64)) tags(loc nchar(64))");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() throws SQLException {
|
||||||
|
String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata";
|
||||||
|
conn = DriverManager.getConnection(url);
|
||||||
|
try (Statement stmt = conn.createStatement()) {
|
||||||
|
stmt.execute("drop database if exists " + dbName);
|
||||||
|
stmt.execute("create database if not exists " + dbName);
|
||||||
|
stmt.execute("use " + dbName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void afterClass() throws SQLException {
|
||||||
|
if (conn != null)
|
||||||
|
conn.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
package com.taosdata.jdbc.cases;
|
||||||
|
|
||||||
|
import com.taosdata.jdbc.TSDBConnection;
|
||||||
|
import com.taosdata.jdbc.TSDBDriver;
|
||||||
|
import com.taosdata.jdbc.TSDBResultSet;
|
||||||
|
import com.taosdata.jdbc.TSDBSubscribe;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.ResultSetMetaData;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public class TD4144Test {
|
||||||
|
|
||||||
|
private static TSDBConnection connection;
|
||||||
|
private static final String host = "127.0.0.1";
|
||||||
|
|
||||||
|
private static final String topic = "topic-meter-current-bg-10";
|
||||||
|
private static final String sql = "select * from meters where current > 10";
|
||||||
|
private static final String sql2 = "select * from meters where ts >= '2020-08-15 12:20:00.000'";
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() throws SQLException {
|
||||||
|
TSDBSubscribe subscribe = null;
|
||||||
|
TSDBResultSet res = null;
|
||||||
|
boolean hasNext = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
subscribe = connection.subscribe(topic, sql, false);
|
||||||
|
int count = 0;
|
||||||
|
while (true) {
|
||||||
|
// 等待1秒,避免频繁调用 consume,给服务端造成压力
|
||||||
|
TimeUnit.SECONDS.sleep(1);
|
||||||
|
if (res == null) {
|
||||||
|
// 消费数据
|
||||||
|
res = subscribe.consume();
|
||||||
|
hasNext = res.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ResultSetMetaData metaData = res.getMetaData();
|
||||||
|
int number = 0;
|
||||||
|
while (hasNext) {
|
||||||
|
int columnCount = metaData.getColumnCount();
|
||||||
|
for (int i = 1; i <= columnCount; i++) {
|
||||||
|
System.out.print(metaData.getColumnLabel(i) + ": " + res.getString(i) + "\t");
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
count++;
|
||||||
|
number++;
|
||||||
|
hasNext = res.next();
|
||||||
|
if (!hasNext) {
|
||||||
|
res.close();
|
||||||
|
res = null;
|
||||||
|
System.out.println("rows: " + count);
|
||||||
|
}
|
||||||
|
if (hasNext == true && number >= 10) {
|
||||||
|
System.out.println("batch" + number);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SQLException | InterruptedException throwables) {
|
||||||
|
throwables.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if (subscribe != null)
|
||||||
|
subscribe.close(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() throws SQLException {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||||
|
String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata";
|
||||||
|
connection = (DriverManager.getConnection(url, properties)).unwrap(TSDBConnection.class);
|
||||||
|
try (Statement stmt = connection.createStatement()) {
|
||||||
|
stmt.execute("drop database if exists power");
|
||||||
|
stmt.execute("create database if not exists power");
|
||||||
|
stmt.execute("use power");
|
||||||
|
stmt.execute("create table meters(ts timestamp, current float, voltage int, phase int) tags(location binary(64), groupId int)");
|
||||||
|
stmt.execute("create table d1001 using meters tags(\"Beijing.Chaoyang\", 2)");
|
||||||
|
stmt.execute("create table d1002 using meters tags(\"Beijing.Haidian\", 2)");
|
||||||
|
stmt.execute("insert into d1001 values(\"2020-08-15 12:00:00.000\", 12, 220, 1),(\"2020-08-15 12:10:00.000\", 12.3, 220, 2),(\"2020-08-15 12:20:00.000\", 12.2, 220, 1)");
|
||||||
|
stmt.execute("insert into d1002 values(\"2020-08-15 12:00:00.000\", 9.9, 220, 1),(\"2020-08-15 12:10:00.000\", 10.3, 220, 1),(\"2020-08-15 12:20:00.000\", 11.2, 220, 1)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void afterClass() throws SQLException {
|
||||||
|
if (connection != null)
|
||||||
|
connection.close();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
package com.taosdata.jdbc.cases;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.taosdata.jdbc.TSDBDriver;
|
||||||
|
import org.junit.*;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class TD4174Test {
|
||||||
|
private Connection conn;
|
||||||
|
private static final String host = "127.0.0.1";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
long ts = System.currentTimeMillis();
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement("insert into weather values(" + ts + ", ?)")) {
|
||||||
|
JSONObject value = new JSONObject();
|
||||||
|
value.put("name", "John Smith");
|
||||||
|
value.put("age", 20);
|
||||||
|
Assert.assertEquals("{\"name\":\"John Smith\",\"age\":20}",value.toJSONString());
|
||||||
|
pstmt.setString(1, value.toJSONString());
|
||||||
|
|
||||||
|
int ret = pstmt.executeUpdate();
|
||||||
|
Assert.assertEquals(1, ret);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
JSONObject value = new JSONObject();
|
||||||
|
value.put("name", "John Smith");
|
||||||
|
value.put("age", 20);
|
||||||
|
System.out.println(value.toJSONString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before() throws SQLException {
|
||||||
|
String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata";
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||||
|
|
||||||
|
conn = DriverManager.getConnection(url, properties);
|
||||||
|
try (Statement stmt = conn.createStatement()) {
|
||||||
|
stmt.execute("drop database if exists td4174");
|
||||||
|
stmt.execute("create database if not exists td4174");
|
||||||
|
stmt.execute("use td4174");
|
||||||
|
stmt.execute("create table weather(ts timestamp, text binary(64))");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void after() throws SQLException {
|
||||||
|
if (conn != null)
|
||||||
|
conn.close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ import java.util.Properties;
|
||||||
public class TwoTypeTimestampPercisionInRestfulTest {
|
public class TwoTypeTimestampPercisionInRestfulTest {
|
||||||
|
|
||||||
private static final String host = "127.0.0.1";
|
private static final String host = "127.0.0.1";
|
||||||
|
|
||||||
private static final String ms_timestamp_db = "ms_precision_test";
|
private static final String ms_timestamp_db = "ms_precision_test";
|
||||||
private static final String us_timestamp_db = "us_precision_test";
|
private static final String us_timestamp_db = "us_precision_test";
|
||||||
private static final long timestamp1 = System.currentTimeMillis();
|
private static final long timestamp1 = System.currentTimeMillis();
|
||||||
|
@ -94,7 +95,8 @@ public class TwoTypeTimestampPercisionInRestfulTest {
|
||||||
try (Statement stmt = conn3.createStatement()) {
|
try (Statement stmt = conn3.createStatement()) {
|
||||||
ResultSet rs = stmt.executeQuery("select last_row(ts) from " + ms_timestamp_db + ".weather");
|
ResultSet rs = stmt.executeQuery("select last_row(ts) from " + ms_timestamp_db + ".weather");
|
||||||
rs.next();
|
rs.next();
|
||||||
long ts = rs.getTimestamp(1).getTime();
|
Timestamp actual = rs.getTimestamp(1);
|
||||||
|
long ts = actual == null ? 0 : actual.getTime();
|
||||||
Assert.assertEquals(timestamp1, ts);
|
Assert.assertEquals(timestamp1, ts);
|
||||||
ts = rs.getLong(1);
|
ts = rs.getLong(1);
|
||||||
Assert.assertEquals(timestamp1, ts);
|
Assert.assertEquals(timestamp1, ts);
|
||||||
|
@ -110,7 +112,7 @@ public class TwoTypeTimestampPercisionInRestfulTest {
|
||||||
rs.next();
|
rs.next();
|
||||||
|
|
||||||
Timestamp timestamp = rs.getTimestamp(1);
|
Timestamp timestamp = rs.getTimestamp(1);
|
||||||
long ts = timestamp.getTime();
|
long ts = timestamp == null ? 0 : timestamp.getTime();
|
||||||
Assert.assertEquals(timestamp1, ts);
|
Assert.assertEquals(timestamp1, ts);
|
||||||
int nanos = timestamp.getNanos();
|
int nanos = timestamp.getNanos();
|
||||||
Assert.assertEquals(timestamp2 % 1000_000l * 1000, nanos);
|
Assert.assertEquals(timestamp2 % 1000_000l * 1000, nanos);
|
||||||
|
|
|
@ -9,19 +9,19 @@ import java.util.Properties;
|
||||||
|
|
||||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
public class UnsignedNumberJniTest {
|
public class UnsignedNumberJniTest {
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase001() {
|
public void testCase001() {
|
||||||
try (Statement stmt = conn.createStatement()) {
|
try (Statement stmt = conn.createStatement()) {
|
||||||
ResultSet rs = stmt.executeQuery("select * from us_table");
|
ResultSet rs = stmt.executeQuery("select * from us_table");
|
||||||
ResultSetMetaData meta = rs.getMetaData();
|
ResultSetMetaData meta = rs.getMetaData();
|
||||||
|
assertResultSetMetaData(meta);
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
for (int i = 1; i <= meta.getColumnCount(); i++) {
|
Assert.assertEquals(ts, rs.getTimestamp(1).getTime());
|
||||||
System.out.print(meta.getColumnLabel(i) + ": " + rs.getString(i) + "\t");
|
|
||||||
}
|
|
||||||
System.out.println();
|
|
||||||
Assert.assertEquals("127", rs.getString(2));
|
Assert.assertEquals("127", rs.getString(2));
|
||||||
Assert.assertEquals("32767", rs.getString(3));
|
Assert.assertEquals("32767", rs.getString(3));
|
||||||
Assert.assertEquals("2147483647", rs.getString(4));
|
Assert.assertEquals("2147483647", rs.getString(4));
|
||||||
|
@ -37,13 +37,10 @@ public class UnsignedNumberJniTest {
|
||||||
try (Statement stmt = conn.createStatement()) {
|
try (Statement stmt = conn.createStatement()) {
|
||||||
ResultSet rs = stmt.executeQuery("select * from us_table");
|
ResultSet rs = stmt.executeQuery("select * from us_table");
|
||||||
ResultSetMetaData meta = rs.getMetaData();
|
ResultSetMetaData meta = rs.getMetaData();
|
||||||
|
assertResultSetMetaData(meta);
|
||||||
|
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
System.out.print(meta.getColumnLabel(1) + ": " + rs.getTimestamp(1) + "\t");
|
Assert.assertEquals(ts, rs.getTimestamp(1).getTime());
|
||||||
System.out.print(meta.getColumnLabel(2) + ": " + rs.getByte(2) + "\t");
|
|
||||||
System.out.print(meta.getColumnLabel(3) + ": " + rs.getShort(3) + "\t");
|
|
||||||
System.out.print(meta.getColumnLabel(4) + ": " + rs.getInt(4) + "\t");
|
|
||||||
System.out.print(meta.getColumnLabel(5) + ": " + rs.getLong(5) + "\t");
|
|
||||||
System.out.println();
|
|
||||||
Assert.assertEquals(127, rs.getByte(2));
|
Assert.assertEquals(127, rs.getByte(2));
|
||||||
Assert.assertEquals(32767, rs.getShort(3));
|
Assert.assertEquals(32767, rs.getShort(3));
|
||||||
Assert.assertEquals(2147483647, rs.getInt(4));
|
Assert.assertEquals(2147483647, rs.getInt(4));
|
||||||
|
@ -61,16 +58,14 @@ public class UnsignedNumberJniTest {
|
||||||
stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 127, 32767,2147483647, 18446744073709551614)");
|
stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 127, 32767,2147483647, 18446744073709551614)");
|
||||||
ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now);
|
ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now);
|
||||||
ResultSetMetaData meta = rs.getMetaData();
|
ResultSetMetaData meta = rs.getMetaData();
|
||||||
|
assertResultSetMetaData(meta);
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
System.out.print(meta.getColumnLabel(1) + ": " + rs.getTimestamp(1) + "\t");
|
Assert.assertEquals(now, rs.getTimestamp(1).getTime());
|
||||||
System.out.print(meta.getColumnLabel(2) + ": " + rs.getByte(2) + "\t");
|
|
||||||
System.out.print(meta.getColumnLabel(3) + ": " + rs.getShort(3) + "\t");
|
|
||||||
System.out.print(meta.getColumnLabel(4) + ": " + rs.getInt(4) + "\t");
|
|
||||||
System.out.print(meta.getColumnLabel(5) + ": " + rs.getLong(5) + "\t");
|
|
||||||
System.out.println();
|
|
||||||
Assert.assertEquals(127, rs.getByte(2));
|
Assert.assertEquals(127, rs.getByte(2));
|
||||||
Assert.assertEquals(32767, rs.getShort(3));
|
Assert.assertEquals(32767, rs.getShort(3));
|
||||||
Assert.assertEquals(2147483647, rs.getInt(4));
|
Assert.assertEquals(2147483647, rs.getInt(4));
|
||||||
|
Assert.assertEquals("18446744073709551614", rs.getString(5));
|
||||||
|
rs.getLong(5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,15 +77,15 @@ public class UnsignedNumberJniTest {
|
||||||
stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 127, 32767,4294967294, 18446744073709551614)");
|
stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 127, 32767,4294967294, 18446744073709551614)");
|
||||||
ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now);
|
ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now);
|
||||||
ResultSetMetaData meta = rs.getMetaData();
|
ResultSetMetaData meta = rs.getMetaData();
|
||||||
|
assertResultSetMetaData(meta);
|
||||||
|
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
System.out.print(meta.getColumnLabel(1) + ": " + rs.getTimestamp(1) + "\t");
|
Assert.assertEquals(now, rs.getTimestamp(1).getTime());
|
||||||
System.out.print(meta.getColumnLabel(2) + ": " + rs.getByte(2) + "\t");
|
|
||||||
System.out.print(meta.getColumnLabel(3) + ": " + rs.getShort(3) + "\t");
|
|
||||||
System.out.print(meta.getColumnLabel(4) + ": " + rs.getInt(4) + "\t");
|
|
||||||
System.out.print(meta.getColumnLabel(5) + ": " + rs.getLong(5) + "\t");
|
|
||||||
System.out.println();
|
|
||||||
Assert.assertEquals(127, rs.getByte(2));
|
Assert.assertEquals(127, rs.getByte(2));
|
||||||
Assert.assertEquals(32767, rs.getShort(3));
|
Assert.assertEquals(32767, rs.getShort(3));
|
||||||
|
Assert.assertEquals("4294967294", rs.getString(4));
|
||||||
|
Assert.assertEquals("18446744073709551614", rs.getString(5));
|
||||||
|
rs.getInt(4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,15 +97,15 @@ public class UnsignedNumberJniTest {
|
||||||
stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 127, 65534,4294967294, 18446744073709551614)");
|
stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 127, 65534,4294967294, 18446744073709551614)");
|
||||||
ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now);
|
ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now);
|
||||||
ResultSetMetaData meta = rs.getMetaData();
|
ResultSetMetaData meta = rs.getMetaData();
|
||||||
while (rs.next()) {
|
assertResultSetMetaData(meta);
|
||||||
System.out.print(meta.getColumnLabel(1) + ": " + rs.getTimestamp(1) + "\t");
|
|
||||||
System.out.print(meta.getColumnLabel(2) + ": " + rs.getByte(2) + "\t");
|
|
||||||
System.out.print(meta.getColumnLabel(3) + ": " + rs.getShort(3) + "\t");
|
|
||||||
System.out.print(meta.getColumnLabel(4) + ": " + rs.getInt(4) + "\t");
|
|
||||||
System.out.print(meta.getColumnLabel(5) + ": " + rs.getLong(5) + "\t");
|
|
||||||
System.out.println();
|
|
||||||
|
|
||||||
|
while (rs.next()) {
|
||||||
|
Assert.assertEquals(now, rs.getTimestamp(1).getTime());
|
||||||
Assert.assertEquals(127, rs.getByte(2));
|
Assert.assertEquals(127, rs.getByte(2));
|
||||||
|
Assert.assertEquals("65534", rs.getString(3));
|
||||||
|
Assert.assertEquals("4294967294", rs.getString(4));
|
||||||
|
Assert.assertEquals("18446744073709551614", rs.getString(5));
|
||||||
|
rs.getShort(3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,37 +117,27 @@ public class UnsignedNumberJniTest {
|
||||||
stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 254, 65534,4294967294, 18446744073709551614)");
|
stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 254, 65534,4294967294, 18446744073709551614)");
|
||||||
ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now);
|
ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now);
|
||||||
ResultSetMetaData meta = rs.getMetaData();
|
ResultSetMetaData meta = rs.getMetaData();
|
||||||
while (rs.next()) {
|
assertResultSetMetaData(meta);
|
||||||
System.out.print(meta.getColumnLabel(1) + ": " + rs.getTimestamp(1) + "\t");
|
|
||||||
System.out.print(meta.getColumnLabel(2) + ": " + rs.getByte(2) + "\t");
|
|
||||||
System.out.print(meta.getColumnLabel(3) + ": " + rs.getShort(3) + "\t");
|
|
||||||
System.out.print(meta.getColumnLabel(4) + ": " + rs.getInt(4) + "\t");
|
|
||||||
System.out.print(meta.getColumnLabel(5) + ": " + rs.getLong(5) + "\t");
|
|
||||||
System.out.println();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCase007() throws SQLException {
|
|
||||||
try (Statement stmt = conn.createStatement()) {
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 254, 65534,4294967294, 18446744073709551614)");
|
|
||||||
ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now);
|
|
||||||
ResultSetMetaData meta = rs.getMetaData();
|
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
for (int i = 1; i <= meta.getColumnCount(); i++) {
|
Assert.assertEquals(now, rs.getTimestamp(1).getTime());
|
||||||
System.out.print(meta.getColumnLabel(i) + ": " + rs.getString(i) + "\t");
|
|
||||||
}
|
|
||||||
System.out.println();
|
|
||||||
Assert.assertEquals("254", rs.getString(2));
|
Assert.assertEquals("254", rs.getString(2));
|
||||||
Assert.assertEquals("65534", rs.getString(3));
|
Assert.assertEquals("65534", rs.getString(3));
|
||||||
Assert.assertEquals("4294967294", rs.getString(4));
|
Assert.assertEquals("4294967294", rs.getString(4));
|
||||||
Assert.assertEquals("18446744073709551614", rs.getString(5));
|
Assert.assertEquals("18446744073709551614", rs.getString(5));
|
||||||
|
rs.getByte(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void assertResultSetMetaData(ResultSetMetaData meta) throws SQLException {
|
||||||
|
Assert.assertEquals(5, meta.getColumnCount());
|
||||||
|
Assert.assertEquals("ts", meta.getColumnLabel(1));
|
||||||
|
Assert.assertEquals("f1", meta.getColumnLabel(2));
|
||||||
|
Assert.assertEquals("f2", meta.getColumnLabel(3));
|
||||||
|
Assert.assertEquals("f3", meta.getColumnLabel(4));
|
||||||
|
Assert.assertEquals("f4", meta.getColumnLabel(5));
|
||||||
|
}
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void beforeClass() {
|
public static void beforeClass() {
|
||||||
|
@ -160,20 +145,19 @@ public class UnsignedNumberJniTest {
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||||
|
ts = System.currentTimeMillis();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
|
||||||
final String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata";
|
final String url = "jdbc:TAOS://" + host + ":6030/?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_jni");
|
stmt.execute("drop database if exists unsign_jni");
|
||||||
stmt.execute("create database if not exists unsign_jni");
|
stmt.execute("create database if not exists unsign_jni");
|
||||||
stmt.execute("use unsign_jni");
|
stmt.execute("use unsign_jni");
|
||||||
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(now, 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();
|
||||||
} catch (ClassNotFoundException | SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,17 +13,20 @@ 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;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase001() {
|
public void testCase001() {
|
||||||
try (Statement stmt = conn.createStatement()) {
|
try (Statement stmt = conn.createStatement()) {
|
||||||
ResultSet rs = stmt.executeQuery("select * from us_table");
|
ResultSet rs = stmt.executeQuery("select * from us_table");
|
||||||
ResultSetMetaData meta = rs.getMetaData();
|
ResultSetMetaData meta = rs.getMetaData();
|
||||||
|
assertResultSetMetaData(meta);
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
for (int i = 1; i <= meta.getColumnCount(); i++) {
|
Assert.assertEquals(ts, rs.getTimestamp(1).getTime());
|
||||||
System.out.print(meta.getColumnLabel(i) + ": " + rs.getString(i) + "\t");
|
Assert.assertEquals("127", rs.getString(2));
|
||||||
}
|
Assert.assertEquals("32767", rs.getString(3));
|
||||||
System.out.println();
|
Assert.assertEquals("2147483647", rs.getString(4));
|
||||||
|
Assert.assertEquals("9223372036854775807", rs.getString(5));
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -35,13 +38,14 @@ public class UnsignedNumberRestfulTest {
|
||||||
try (Statement stmt = conn.createStatement()) {
|
try (Statement stmt = conn.createStatement()) {
|
||||||
ResultSet rs = stmt.executeQuery("select * from us_table");
|
ResultSet rs = stmt.executeQuery("select * from us_table");
|
||||||
ResultSetMetaData meta = rs.getMetaData();
|
ResultSetMetaData meta = rs.getMetaData();
|
||||||
|
assertResultSetMetaData(meta);
|
||||||
|
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
System.out.print(meta.getColumnLabel(1) + ": " + rs.getTimestamp(1) + "\t");
|
Assert.assertEquals(ts, rs.getTimestamp(1).getTime());
|
||||||
System.out.print(meta.getColumnLabel(2) + ": " + rs.getByte(2) + "\t");
|
Assert.assertEquals(127, rs.getByte(2));
|
||||||
System.out.print(meta.getColumnLabel(3) + ": " + rs.getShort(3) + "\t");
|
Assert.assertEquals(32767, rs.getShort(3));
|
||||||
System.out.print(meta.getColumnLabel(4) + ": " + rs.getInt(4) + "\t");
|
Assert.assertEquals(2147483647, rs.getInt(4));
|
||||||
System.out.print(meta.getColumnLabel(5) + ": " + rs.getLong(5) + "\t");
|
Assert.assertEquals(9223372036854775807l, rs.getLong(5));
|
||||||
System.out.println();
|
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -55,13 +59,14 @@ public class UnsignedNumberRestfulTest {
|
||||||
stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 127, 32767,2147483647, 18446744073709551614)");
|
stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 127, 32767,2147483647, 18446744073709551614)");
|
||||||
ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now);
|
ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now);
|
||||||
ResultSetMetaData meta = rs.getMetaData();
|
ResultSetMetaData meta = rs.getMetaData();
|
||||||
|
assertResultSetMetaData(meta);
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
System.out.print(meta.getColumnLabel(1) + ": " + rs.getTimestamp(1) + "\t");
|
Assert.assertEquals(now, rs.getTimestamp(1).getTime());
|
||||||
System.out.print(meta.getColumnLabel(2) + ": " + rs.getByte(2) + "\t");
|
Assert.assertEquals(127, rs.getByte(2));
|
||||||
System.out.print(meta.getColumnLabel(3) + ": " + rs.getShort(3) + "\t");
|
Assert.assertEquals(32767, rs.getShort(3));
|
||||||
System.out.print(meta.getColumnLabel(4) + ": " + rs.getInt(4) + "\t");
|
Assert.assertEquals(2147483647, rs.getInt(4));
|
||||||
System.out.print(meta.getColumnLabel(5) + ": " + rs.getLong(5) + "\t");
|
Assert.assertEquals("18446744073709551614", rs.getString(5));
|
||||||
System.out.println();
|
rs.getLong(5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,13 +78,15 @@ public class UnsignedNumberRestfulTest {
|
||||||
stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 127, 32767,4294967294, 18446744073709551614)");
|
stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 127, 32767,4294967294, 18446744073709551614)");
|
||||||
ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now);
|
ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now);
|
||||||
ResultSetMetaData meta = rs.getMetaData();
|
ResultSetMetaData meta = rs.getMetaData();
|
||||||
|
assertResultSetMetaData(meta);
|
||||||
|
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
System.out.print(meta.getColumnLabel(1) + ": " + rs.getTimestamp(1) + "\t");
|
Assert.assertEquals(now, rs.getTimestamp(1).getTime());
|
||||||
System.out.print(meta.getColumnLabel(2) + ": " + rs.getByte(2) + "\t");
|
Assert.assertEquals(127, rs.getByte(2));
|
||||||
System.out.print(meta.getColumnLabel(3) + ": " + rs.getShort(3) + "\t");
|
Assert.assertEquals(32767, rs.getShort(3));
|
||||||
System.out.print(meta.getColumnLabel(4) + ": " + rs.getInt(4) + "\t");
|
Assert.assertEquals("4294967294", rs.getString(4));
|
||||||
System.out.print(meta.getColumnLabel(5) + ": " + rs.getLong(5) + "\t");
|
Assert.assertEquals("18446744073709551614", rs.getString(5));
|
||||||
System.out.println();
|
rs.getInt(4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,13 +98,15 @@ public class UnsignedNumberRestfulTest {
|
||||||
stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 127, 65534,4294967294, 18446744073709551614)");
|
stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 127, 65534,4294967294, 18446744073709551614)");
|
||||||
ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now);
|
ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now);
|
||||||
ResultSetMetaData meta = rs.getMetaData();
|
ResultSetMetaData meta = rs.getMetaData();
|
||||||
|
assertResultSetMetaData(meta);
|
||||||
|
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
System.out.print(meta.getColumnLabel(1) + ": " + rs.getTimestamp(1) + "\t");
|
Assert.assertEquals(now, rs.getTimestamp(1).getTime());
|
||||||
System.out.print(meta.getColumnLabel(2) + ": " + rs.getByte(2) + "\t");
|
Assert.assertEquals(127, rs.getByte(2));
|
||||||
System.out.print(meta.getColumnLabel(3) + ": " + rs.getShort(3) + "\t");
|
Assert.assertEquals("65534", rs.getString(3));
|
||||||
System.out.print(meta.getColumnLabel(4) + ": " + rs.getInt(4) + "\t");
|
Assert.assertEquals("4294967294", rs.getString(4));
|
||||||
System.out.print(meta.getColumnLabel(5) + ": " + rs.getLong(5) + "\t");
|
Assert.assertEquals("18446744073709551614", rs.getString(5));
|
||||||
System.out.println();
|
rs.getShort(3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,57 +118,47 @@ public class UnsignedNumberRestfulTest {
|
||||||
stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 254, 65534,4294967294, 18446744073709551614)");
|
stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 254, 65534,4294967294, 18446744073709551614)");
|
||||||
ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now);
|
ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now);
|
||||||
ResultSetMetaData meta = rs.getMetaData();
|
ResultSetMetaData meta = rs.getMetaData();
|
||||||
while (rs.next()) {
|
assertResultSetMetaData(meta);
|
||||||
System.out.print(meta.getColumnLabel(1) + ": " + rs.getTimestamp(1) + "\t");
|
|
||||||
System.out.print(meta.getColumnLabel(2) + ": " + rs.getByte(2) + "\t");
|
|
||||||
System.out.print(meta.getColumnLabel(3) + ": " + rs.getShort(3) + "\t");
|
|
||||||
System.out.print(meta.getColumnLabel(4) + ": " + rs.getInt(4) + "\t");
|
|
||||||
System.out.print(meta.getColumnLabel(5) + ": " + rs.getLong(5) + "\t");
|
|
||||||
System.out.println();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCase007() throws SQLException {
|
|
||||||
try (Statement stmt = conn.createStatement()) {
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 254, 65534,4294967294, 18446744073709551614)");
|
|
||||||
ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now);
|
|
||||||
ResultSetMetaData meta = rs.getMetaData();
|
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
for (int i = 1; i <= meta.getColumnCount(); i++) {
|
Assert.assertEquals(now, rs.getTimestamp(1).getTime());
|
||||||
System.out.print(meta.getColumnLabel(i) + ": " + rs.getString(i) + "\t");
|
|
||||||
}
|
|
||||||
System.out.println();
|
|
||||||
Assert.assertEquals("254", rs.getString(2));
|
Assert.assertEquals("254", rs.getString(2));
|
||||||
Assert.assertEquals("65534", rs.getString(3));
|
Assert.assertEquals("65534", rs.getString(3));
|
||||||
Assert.assertEquals("4294967294", rs.getString(4));
|
Assert.assertEquals("4294967294", rs.getString(4));
|
||||||
Assert.assertEquals("18446744073709551614", rs.getString(5));
|
Assert.assertEquals("18446744073709551614", rs.getString(5));
|
||||||
|
rs.getByte(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void assertResultSetMetaData(ResultSetMetaData meta) throws SQLException {
|
||||||
|
Assert.assertEquals(5, meta.getColumnCount());
|
||||||
|
Assert.assertEquals("ts", meta.getColumnLabel(1));
|
||||||
|
Assert.assertEquals("f1", meta.getColumnLabel(2));
|
||||||
|
Assert.assertEquals("f2", meta.getColumnLabel(3));
|
||||||
|
Assert.assertEquals("f3", meta.getColumnLabel(4));
|
||||||
|
Assert.assertEquals("f4", meta.getColumnLabel(5));
|
||||||
|
}
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void beforeClass() {
|
public static void beforeClass() {
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||||
|
ts = System.currentTimeMillis();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Class.forName("com.taosdata.jdbc.rs.RestfulDriver");
|
|
||||||
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 unsign_restful");
|
||||||
stmt.execute("create database if not exists unsign_restful");
|
stmt.execute("create database if not exists unsign_restful");
|
||||||
stmt.execute("use unsign_restful");
|
stmt.execute("use unsign_restful");
|
||||||
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(now, 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();
|
||||||
} catch (ClassNotFoundException | SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Serializable;
|
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
|
|
||||||
public class RestfulPreparedStatementTest {
|
public class RestfulPreparedStatementTest {
|
||||||
|
@ -371,7 +370,6 @@ public class RestfulPreparedStatementTest {
|
||||||
pstmt_insert.setSQLXML(1, null);
|
pstmt_insert.setSQLXML(1, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void beforeClass() {
|
public static void beforeClass() {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -18,7 +18,6 @@ import java.text.SimpleDateFormat;
|
||||||
public class RestfulResultSetTest {
|
public class RestfulResultSetTest {
|
||||||
|
|
||||||
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 Statement stmt;
|
private static Statement stmt;
|
||||||
private static ResultSet rs;
|
private static ResultSet rs;
|
||||||
|
@ -95,7 +94,8 @@ public class RestfulResultSetTest {
|
||||||
@Test
|
@Test
|
||||||
public void getBigDecimal() throws SQLException {
|
public void getBigDecimal() throws SQLException {
|
||||||
BigDecimal f1 = rs.getBigDecimal("f1");
|
BigDecimal f1 = rs.getBigDecimal("f1");
|
||||||
Assert.assertEquals(1609430400000l, f1.longValue());
|
long actual = (f1 == null) ? 0 : f1.longValue();
|
||||||
|
Assert.assertEquals(1609430400000l, actual);
|
||||||
|
|
||||||
BigDecimal f2 = rs.getBigDecimal("f2");
|
BigDecimal f2 = rs.getBigDecimal("f2");
|
||||||
Assert.assertEquals(1, f2.intValue());
|
Assert.assertEquals(1, f2.intValue());
|
||||||
|
@ -119,7 +119,7 @@ public class RestfulResultSetTest {
|
||||||
@Test
|
@Test
|
||||||
public void getBytes() throws SQLException {
|
public void getBytes() throws SQLException {
|
||||||
byte[] f1 = rs.getBytes("f1");
|
byte[] f1 = rs.getBytes("f1");
|
||||||
Assert.assertEquals("2021-01-01 00:00:00.0", new String(f1));
|
Assert.assertEquals("2021-01-01 00:00:00.000", new String(f1));
|
||||||
|
|
||||||
byte[] f2 = rs.getBytes("f2");
|
byte[] f2 = rs.getBytes("f2");
|
||||||
Assert.assertEquals(1, Ints.fromByteArray(f2));
|
Assert.assertEquals(1, Ints.fromByteArray(f2));
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.taosdata.jdbc.utils;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class UtilsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void escapeSingleQuota() {
|
||||||
|
String s = "'''''a\\'";
|
||||||
|
String news = Utils.escapeSingleQuota(s);
|
||||||
|
Assert.assertEquals("\\'\\'\\'\\'\\'a\\'", news);
|
||||||
|
|
||||||
|
s = "\'''''a\\'";
|
||||||
|
news = Utils.escapeSingleQuota(s);
|
||||||
|
Assert.assertEquals("\\'\\'\\'\\'\\'a\\'", news);
|
||||||
|
|
||||||
|
s = "\'\'\'\''a\\'";
|
||||||
|
news = Utils.escapeSingleQuota(s);
|
||||||
|
Assert.assertEquals("\\'\\'\\'\\'\\'a\\'", news);
|
||||||
|
}
|
||||||
|
}
|
|
@ -202,11 +202,11 @@ function CTaosInterface (config = null, pass = false) {
|
||||||
'taos_connect': [ref.types.void_ptr, [ref.types.char_ptr, ref.types.char_ptr, ref.types.char_ptr, ref.types.char_ptr, ref.types.int]],
|
'taos_connect': [ref.types.void_ptr, [ref.types.char_ptr, ref.types.char_ptr, ref.types.char_ptr, ref.types.char_ptr, ref.types.int]],
|
||||||
//void taos_close(TAOS *taos)
|
//void taos_close(TAOS *taos)
|
||||||
'taos_close': [ref.types.void, [ref.types.void_ptr]],
|
'taos_close': [ref.types.void, [ref.types.void_ptr]],
|
||||||
//int *taos_fetch_lengths(TAOS_RES *taos);
|
//int *taos_fetch_lengths(TAOS_RES *res);
|
||||||
'taos_fetch_lengths': [ref.types.void_ptr, [ref.types.void_ptr]],
|
'taos_fetch_lengths': [ref.types.void_ptr, [ref.types.void_ptr]],
|
||||||
//int taos_query(TAOS *taos, char *sqlstr)
|
//int taos_query(TAOS *taos, char *sqlstr)
|
||||||
'taos_query': [ref.types.void_ptr, [ref.types.void_ptr, ref.types.char_ptr]],
|
'taos_query': [ref.types.void_ptr, [ref.types.void_ptr, ref.types.char_ptr]],
|
||||||
//int taos_affected_rows(TAOS *taos)
|
//int taos_affected_rows(TAOS_RES *res)
|
||||||
'taos_affected_rows': [ref.types.int, [ref.types.void_ptr]],
|
'taos_affected_rows': [ref.types.int, [ref.types.void_ptr]],
|
||||||
//int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows)
|
//int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows)
|
||||||
'taos_fetch_block': [ref.types.int, [ref.types.void_ptr, ref.types.void_ptr]],
|
'taos_fetch_block': [ref.types.int, [ref.types.void_ptr, ref.types.void_ptr]],
|
||||||
|
@ -215,6 +215,7 @@ function CTaosInterface (config = null, pass = false) {
|
||||||
//TAOS_ROW taos_fetch_row(TAOS_RES *res)
|
//TAOS_ROW taos_fetch_row(TAOS_RES *res)
|
||||||
//TAOS_ROW is void **, but we set the return type as a reference instead to get the row
|
//TAOS_ROW is void **, but we set the return type as a reference instead to get the row
|
||||||
'taos_fetch_row': [ref.refType(ref.types.void_ptr2), [ref.types.void_ptr]],
|
'taos_fetch_row': [ref.refType(ref.types.void_ptr2), [ref.types.void_ptr]],
|
||||||
|
'taos_print_row': [ref.types.int, [ref.types.char_ptr, ref.types.void_ptr, ref.types.void_ptr, ref.types.int]],
|
||||||
//int taos_result_precision(TAOS_RES *res)
|
//int taos_result_precision(TAOS_RES *res)
|
||||||
'taos_result_precision': [ref.types.int, [ref.types.void_ptr]],
|
'taos_result_precision': [ref.types.int, [ref.types.void_ptr]],
|
||||||
//void taos_free_result(TAOS_RES *res)
|
//void taos_free_result(TAOS_RES *res)
|
||||||
|
@ -326,8 +327,8 @@ CTaosInterface.prototype.close = function close(connection) {
|
||||||
CTaosInterface.prototype.query = function query(connection, sql) {
|
CTaosInterface.prototype.query = function query(connection, sql) {
|
||||||
return this.libtaos.taos_query(connection, ref.allocCString(sql));
|
return this.libtaos.taos_query(connection, ref.allocCString(sql));
|
||||||
}
|
}
|
||||||
CTaosInterface.prototype.affectedRows = function affectedRows(connection) {
|
CTaosInterface.prototype.affectedRows = function affectedRows(result) {
|
||||||
return this.libtaos.taos_affected_rows(connection);
|
return this.libtaos.taos_affected_rows(result);
|
||||||
}
|
}
|
||||||
CTaosInterface.prototype.useResult = function useResult(result) {
|
CTaosInterface.prototype.useResult = function useResult(result) {
|
||||||
|
|
||||||
|
@ -347,10 +348,9 @@ CTaosInterface.prototype.useResult = function useResult(result) {
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
CTaosInterface.prototype.fetchBlock = function fetchBlock(result, fields) {
|
CTaosInterface.prototype.fetchBlock = function fetchBlock(result, fields) {
|
||||||
//let pblock = ref.ref(ref.ref(ref.NULL)); // equal to our raw data
|
let pblock = ref.NULL_POINTER;
|
||||||
let pblock = this.libtaos.taos_fetch_row(result);
|
let num_of_rows = this.libtaos.taos_fetch_block(result, pblock);
|
||||||
let num_of_rows = 1;
|
if (ref.isNull(pblock.deref()) == true) {
|
||||||
if (ref.isNull(pblock) == true) {
|
|
||||||
return { block: null, num_of_rows: 0 };
|
return { block: null, num_of_rows: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,10 +370,12 @@ CTaosInterface.prototype.fetchBlock = function fetchBlock(result, fields) {
|
||||||
|
|
||||||
let blocks = new Array(fields.length);
|
let blocks = new Array(fields.length);
|
||||||
blocks.fill(null);
|
blocks.fill(null);
|
||||||
//num_of_rows = Math.abs(num_of_rows);
|
num_of_rows = Math.abs(num_of_rows);
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
|
let ptr = pblock.deref();
|
||||||
|
|
||||||
for (let i = 0; i < fields.length; i++) {
|
for (let i = 0; i < fields.length; i++) {
|
||||||
pdata = ref.reinterpret(pblock,8,i*8);
|
pdata = ref.reinterpret(ptr, 8, i * 8);
|
||||||
if (ref.isNull(pdata.readPointer())) {
|
if (ref.isNull(pdata.readPointer())) {
|
||||||
blocks[i] = new Array();
|
blocks[i] = new Array();
|
||||||
} else {
|
} else {
|
||||||
|
@ -381,10 +383,10 @@ CTaosInterface.prototype.fetchBlock = function fetchBlock(result, fields) {
|
||||||
if (!convertFunctions[fields[i]['type']]) {
|
if (!convertFunctions[fields[i]['type']]) {
|
||||||
throw new errors.DatabaseError("Invalid data type returned from database");
|
throw new errors.DatabaseError("Invalid data type returned from database");
|
||||||
}
|
}
|
||||||
blocks[i] = convertFunctions[fields[i]['type']](pdata, 1, fieldlens[i], offset, isMicro);
|
blocks[i] = convertFunctions[fields[i]['type']](pdata, num_of_rows, fieldlens[i], offset, isMicro);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {blocks: blocks, num_of_rows:Math.abs(num_of_rows)}
|
return { blocks: blocks, num_of_rows }
|
||||||
}
|
}
|
||||||
CTaosInterface.prototype.fetchRow = function fetchRow(result, fields) {
|
CTaosInterface.prototype.fetchRow = function fetchRow(result, fields) {
|
||||||
let row = this.libtaos.taos_fetch_row(result);
|
let row = this.libtaos.taos_fetch_row(result);
|
||||||
|
|
|
@ -176,27 +176,22 @@ TDengineCursor.prototype.fetchall = function fetchall(options, callback) {
|
||||||
throw new errors.OperationalError("Invalid use of fetchall, either result or fields from query are null. First execute a query first");
|
throw new errors.OperationalError("Invalid use of fetchall, either result or fields from query are null. First execute a query first");
|
||||||
}
|
}
|
||||||
|
|
||||||
let data = [];
|
let num_of_rows = this._chandle.affectedRows(this._result);
|
||||||
|
let data = new Array(num_of_rows);
|
||||||
|
|
||||||
this._rowcount = 0;
|
this._rowcount = 0;
|
||||||
//let nodetime = 0;
|
|
||||||
let time = 0;
|
let time = 0;
|
||||||
const obs = new PerformanceObserver((items) => {
|
const obs = new PerformanceObserver((items) => {
|
||||||
time += items.getEntries()[0].duration;
|
time += items.getEntries()[0].duration;
|
||||||
performance.clearMarks();
|
performance.clearMarks();
|
||||||
});
|
});
|
||||||
/*
|
|
||||||
const obs2 = new PerformanceObserver((items) => {
|
|
||||||
nodetime += items.getEntries()[0].duration;
|
|
||||||
performance.clearMarks();
|
|
||||||
});
|
|
||||||
obs2.observe({ entryTypes: ['measure'] });
|
|
||||||
performance.mark('nodea');
|
|
||||||
*/
|
|
||||||
obs.observe({ entryTypes: ['measure'] });
|
obs.observe({ entryTypes: ['measure'] });
|
||||||
performance.mark('A');
|
performance.mark('A');
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
||||||
let blockAndRows = this._chandle.fetchBlock(this._result, this._fields);
|
let blockAndRows = this._chandle.fetchBlock(this._result, this._fields);
|
||||||
|
// console.log(blockAndRows);
|
||||||
|
// break;
|
||||||
let block = blockAndRows.blocks;
|
let block = blockAndRows.blocks;
|
||||||
let num_of_rows = blockAndRows.num_of_rows;
|
let num_of_rows = blockAndRows.num_of_rows;
|
||||||
if (num_of_rows == 0) {
|
if (num_of_rows == 0) {
|
||||||
|
@ -205,16 +200,18 @@ TDengineCursor.prototype.fetchall = function fetchall(options, callback) {
|
||||||
this._rowcount += num_of_rows;
|
this._rowcount += num_of_rows;
|
||||||
let numoffields = this._fields.length;
|
let numoffields = this._fields.length;
|
||||||
for (let i = 0; i < num_of_rows; i++) {
|
for (let i = 0; i < num_of_rows; i++) {
|
||||||
data.push([]);
|
// data.push([]);
|
||||||
|
|
||||||
let rowBlock = new Array(numoffields);
|
let rowBlock = new Array(numoffields);
|
||||||
for (let j = 0; j < numoffields; j++) {
|
for (let j = 0; j < numoffields; j++) {
|
||||||
rowBlock[j] = block[j][i];
|
rowBlock[j] = block[j][i];
|
||||||
}
|
}
|
||||||
data[data.length-1] = (rowBlock);
|
data[this._rowcount - num_of_rows + i] = (rowBlock);
|
||||||
|
// data.push(rowBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
performance.mark('B');
|
performance.mark('B');
|
||||||
performance.measure('query', 'A', 'B');
|
performance.measure('query', 'A', 'B');
|
||||||
let response = this._createSetResponse(this._rowcount, time)
|
let response = this._createSetResponse(this._rowcount, time)
|
||||||
|
|
|
@ -1,285 +0,0 @@
|
||||||
{
|
|
||||||
"name": "td2.0-connector",
|
|
||||||
"version": "2.0.6",
|
|
||||||
"lockfileVersion": 1,
|
|
||||||
"requires": true,
|
|
||||||
"dependencies": {
|
|
||||||
"array-index": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/array-index/-/array-index-1.0.0.tgz",
|
|
||||||
"integrity": "sha1-7FanSe4QPk4Ix5C5w1PfFgVbl/k=",
|
|
||||||
"requires": {
|
|
||||||
"debug": "^2.2.0",
|
|
||||||
"es6-symbol": "^3.0.2"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"debug": {
|
|
||||||
"version": "2.6.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
|
||||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
|
||||||
"requires": {
|
|
||||||
"ms": "2.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ms": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
|
||||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"d": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
|
|
||||||
"requires": {
|
|
||||||
"es5-ext": "^0.10.50",
|
|
||||||
"type": "^1.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"debug": {
|
|
||||||
"version": "4.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
|
||||||
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
|
||||||
"requires": {
|
|
||||||
"ms": "2.1.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"es5-ext": {
|
|
||||||
"version": "0.10.53",
|
|
||||||
"resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
|
|
||||||
"integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
|
|
||||||
"requires": {
|
|
||||||
"es6-iterator": "~2.0.3",
|
|
||||||
"es6-symbol": "~3.1.3",
|
|
||||||
"next-tick": "~1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"es6-iterator": {
|
|
||||||
"version": "2.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
|
|
||||||
"integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
|
|
||||||
"requires": {
|
|
||||||
"d": "1",
|
|
||||||
"es5-ext": "^0.10.35",
|
|
||||||
"es6-symbol": "^3.1.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"es6-symbol": {
|
|
||||||
"version": "3.1.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
|
|
||||||
"integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
|
|
||||||
"requires": {
|
|
||||||
"d": "^1.0.1",
|
|
||||||
"ext": "^1.1.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ext": {
|
|
||||||
"version": "1.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz",
|
|
||||||
"integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==",
|
|
||||||
"requires": {
|
|
||||||
"type": "^2.0.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"type": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz",
|
|
||||||
"integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA=="
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ffi-napi": {
|
|
||||||
"version": "3.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/ffi-napi/-/ffi-napi-3.1.0.tgz",
|
|
||||||
"integrity": "sha512-EsHO+sP2p/nUC/3l/l8m9niee1BLm4asUFDzkkBGR4kYVgp2KqdAYUomZhkKtzim4Fq7mcYHjpUaIHsMqs+E1g==",
|
|
||||||
"requires": {
|
|
||||||
"debug": "^4.1.1",
|
|
||||||
"get-uv-event-loop-napi-h": "^1.0.5",
|
|
||||||
"node-addon-api": "^2.0.0",
|
|
||||||
"node-gyp-build": "^4.2.1",
|
|
||||||
"ref-napi": "^2.0.1",
|
|
||||||
"ref-struct-di": "^1.1.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"ref-napi": {
|
|
||||||
"version": "2.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/ref-napi/-/ref-napi-2.1.2.tgz",
|
|
||||||
"integrity": "sha512-aFl+vrIuLWUXMUTQGAwGAuSNLX3Ub5W3iVP8b7KyFFZUdn4+i4U1TXXTop0kCTUfGNu8glBGVz4lowkwMcPVVA==",
|
|
||||||
"requires": {
|
|
||||||
"debug": "^4.1.1",
|
|
||||||
"get-symbol-from-current-process-h": "^1.0.2",
|
|
||||||
"node-addon-api": "^2.0.0",
|
|
||||||
"node-gyp-build": "^4.2.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"get-symbol-from-current-process-h": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/get-symbol-from-current-process-h/-/get-symbol-from-current-process-h-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-syloC6fsCt62ELLrr1VKBM1ggOpMdetX9hTrdW77UQdcApPHLmf7CI7OKcN1c9kYuNxKcDe4iJ4FY9sX3aw2xw=="
|
|
||||||
},
|
|
||||||
"get-uv-event-loop-napi-h": {
|
|
||||||
"version": "1.0.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/get-uv-event-loop-napi-h/-/get-uv-event-loop-napi-h-1.0.6.tgz",
|
|
||||||
"integrity": "sha512-t5c9VNR84nRoF+eLiz6wFrEp1SE2Acg0wS+Ysa2zF0eROes+LzOfuTaVHxGy8AbS8rq7FHEJzjnCZo1BupwdJg==",
|
|
||||||
"requires": {
|
|
||||||
"get-symbol-from-current-process-h": "^1.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ms": {
|
|
||||||
"version": "2.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
|
||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
|
||||||
},
|
|
||||||
"next-tick": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
|
|
||||||
"integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw="
|
|
||||||
},
|
|
||||||
"node-addon-api": {
|
|
||||||
"version": "2.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz",
|
|
||||||
"integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA=="
|
|
||||||
},
|
|
||||||
"node-gyp-build": {
|
|
||||||
"version": "4.2.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz",
|
|
||||||
"integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg=="
|
|
||||||
},
|
|
||||||
"ref-array-napi": {
|
|
||||||
"version": "1.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/ref-array-napi/-/ref-array-napi-1.2.1.tgz",
|
|
||||||
"integrity": "sha512-jQp2WWSucmxkqVfoNfm7yDlDeGu3liAbzqfwjNybL80ooLOCnCZpAK2woDInY+lxNOK/VlIVSqeDEYb4gVPuNQ==",
|
|
||||||
"requires": {
|
|
||||||
"array-index": "1",
|
|
||||||
"debug": "2",
|
|
||||||
"ref-napi": "^1.4.2"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"debug": {
|
|
||||||
"version": "2.6.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
|
||||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
|
||||||
"requires": {
|
|
||||||
"ms": "2.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ms": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
|
||||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
|
||||||
},
|
|
||||||
"ref-napi": {
|
|
||||||
"version": "1.5.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/ref-napi/-/ref-napi-1.5.2.tgz",
|
|
||||||
"integrity": "sha512-hwyNmWpUkt1bDWDW4aiwCoC+SJfJO69UIdjqssNqdaS0sYJpgqzosGg/rLtk69UoQ8drZdI9yyQefM7eEMM3Gw==",
|
|
||||||
"requires": {
|
|
||||||
"debug": "^3.1.0",
|
|
||||||
"node-addon-api": "^2.0.0",
|
|
||||||
"node-gyp-build": "^4.2.1"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"debug": {
|
|
||||||
"version": "3.2.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
|
|
||||||
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
|
|
||||||
"requires": {
|
|
||||||
"ms": "^2.1.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ms": {
|
|
||||||
"version": "2.1.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
|
||||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ref-napi": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/ref-napi/-/ref-napi-3.0.1.tgz",
|
|
||||||
"integrity": "sha512-W3rcb0E+tlO9u9ySFnX5vifInwwPGToOfFgTZUHJBNiOBsW0NNvgHz2zJN7ctABo/2yIlgdPQUvuqqfORIF4LA==",
|
|
||||||
"requires": {
|
|
||||||
"debug": "^4.1.1",
|
|
||||||
"get-symbol-from-current-process-h": "^1.0.2",
|
|
||||||
"node-addon-api": "^2.0.0",
|
|
||||||
"node-gyp-build": "^4.2.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ref-struct-di": {
|
|
||||||
"version": "1.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/ref-struct-di/-/ref-struct-di-1.1.1.tgz",
|
|
||||||
"integrity": "sha512-2Xyn/0Qgz89VT+++WP0sTosdm9oeowLP23wRJYhG4BFdMUrLj3jhwHZNEytYNYgtPKLNTP3KJX4HEgBvM1/Y2g==",
|
|
||||||
"requires": {
|
|
||||||
"debug": "^3.1.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"debug": {
|
|
||||||
"version": "3.2.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
|
|
||||||
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
|
|
||||||
"requires": {
|
|
||||||
"ms": "^2.1.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ref-struct-napi": {
|
|
||||||
"version": "1.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/ref-struct-napi/-/ref-struct-napi-1.1.1.tgz",
|
|
||||||
"integrity": "sha512-YgS5/d7+kT5zgtySYI5ieH0hREdv+DabgDvoczxsui0f9VLm0rrDcWEj4DHKehsH+tJnVMsLwuyctWgvdEcVRw==",
|
|
||||||
"requires": {
|
|
||||||
"debug": "2",
|
|
||||||
"ref-napi": "^1.4.2"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"debug": {
|
|
||||||
"version": "2.6.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
|
||||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
|
||||||
"requires": {
|
|
||||||
"ms": "2.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ms": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
|
||||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
|
||||||
},
|
|
||||||
"ref-napi": {
|
|
||||||
"version": "1.5.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/ref-napi/-/ref-napi-1.5.2.tgz",
|
|
||||||
"integrity": "sha512-hwyNmWpUkt1bDWDW4aiwCoC+SJfJO69UIdjqssNqdaS0sYJpgqzosGg/rLtk69UoQ8drZdI9yyQefM7eEMM3Gw==",
|
|
||||||
"requires": {
|
|
||||||
"debug": "^3.1.0",
|
|
||||||
"node-addon-api": "^2.0.0",
|
|
||||||
"node-gyp-build": "^4.2.1"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"debug": {
|
|
||||||
"version": "3.2.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
|
|
||||||
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
|
|
||||||
"requires": {
|
|
||||||
"ms": "^2.1.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ms": {
|
|
||||||
"version": "2.1.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
|
||||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"version": "1.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
|
|
||||||
"integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "td2.0-connector",
|
"name": "td2.0-connector",
|
||||||
"version": "2.0.6",
|
"version": "2.0.7",
|
||||||
"description": "A Node.js connector for TDengine.",
|
"description": "A Node.js connector for TDengine.",
|
||||||
"main": "tdengine.js",
|
"main": "tdengine.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
#define CHK_TEST(statement) \
|
#define CHK_TEST(statement) \
|
||||||
do { \
|
do { \
|
||||||
D("testing: %s", #statement); \
|
D("testing: %s", #statement); \
|
||||||
int r = (statement); \
|
int _r = (statement); \
|
||||||
if (r) { \
|
if (_r) { \
|
||||||
D("testing failed: %s", #statement); \
|
D("testing failed: %s", #statement); \
|
||||||
return 1; \
|
return 1; \
|
||||||
} \
|
} \
|
||||||
|
@ -181,7 +181,7 @@ static int do_statement(SQLHSTMT stmt, const char *statement) {
|
||||||
r = traverse_cols(stmt, cols);
|
r = traverse_cols(stmt, cols);
|
||||||
char buf[4096];
|
char buf[4096];
|
||||||
while (1) {
|
while (1) {
|
||||||
SQLRETURN r = SQLFetch(stmt);
|
r = SQLFetch(stmt);
|
||||||
if (r==SQL_NO_DATA) break;
|
if (r==SQL_NO_DATA) break;
|
||||||
CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "");
|
CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "");
|
||||||
for (size_t i=0; i<cols; ++i) {
|
for (size_t i=0; i<cols; ++i) {
|
||||||
|
|
|
@ -1762,8 +1762,8 @@ static SQLRETURN tsdb_conn_prepare(stmt_t *stmt) {
|
||||||
tsdb_stmt->tsdb_params = tsdb_params;
|
tsdb_stmt->tsdb_params = tsdb_params;
|
||||||
|
|
||||||
for (int i=0; i<nums; ++i) {
|
for (int i=0; i<nums; ++i) {
|
||||||
SQLRETURN r = do_fill_param(stmt, i);
|
SQLRETURN _r = do_fill_param(stmt, i);
|
||||||
if (r) return r;
|
if (_r) return _r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,154 @@
|
||||||
|
|
||||||
|
# Created by https://www.toptal.com/developers/gitignore/api/python
|
||||||
|
# Edit at https://www.toptal.com/developers/gitignore?templates=python
|
||||||
|
|
||||||
|
### Python ###
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
pip-wheel-metadata/
|
||||||
|
share/python-wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.nox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
*.py,cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
pytestdebug.log
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
db.sqlite3
|
||||||
|
db.sqlite3-journal
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
doc/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# IPython
|
||||||
|
profile_default/
|
||||||
|
ipython_config.py
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
.python-version
|
||||||
|
|
||||||
|
# pipenv
|
||||||
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||||
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||||
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||||
|
# install all needed dependencies.
|
||||||
|
#Pipfile.lock
|
||||||
|
|
||||||
|
# poetry
|
||||||
|
#poetry.lock
|
||||||
|
|
||||||
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||||
|
__pypackages__/
|
||||||
|
|
||||||
|
# Celery stuff
|
||||||
|
celerybeat-schedule
|
||||||
|
celerybeat.pid
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
# .env
|
||||||
|
.env/
|
||||||
|
.venv/
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
pythonenv*
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
.dmypy.json
|
||||||
|
dmypy.json
|
||||||
|
|
||||||
|
# Pyre type checker
|
||||||
|
.pyre/
|
||||||
|
|
||||||
|
# pytype static type analyzer
|
||||||
|
.pytype/
|
||||||
|
|
||||||
|
# operating system-related files
|
||||||
|
# file properties cache/storage on macOS
|
||||||
|
*.DS_Store
|
||||||
|
# thumbnail cache on Windows
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# profiling data
|
||||||
|
.prof
|
||||||
|
|
||||||
|
|
||||||
|
# End of https://www.toptal.com/developers/gitignore/api/python
|
|
@ -0,0 +1,17 @@
|
||||||
|
# TDengine Connector for Python
|
||||||
|
|
||||||
|
[TDengine] connector for Python enables python programs to access TDengine, using an API which is compliant with the Python DB API 2.0 (PEP-249). It uses TDengine C client library for client server communications.
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pip install git+https://github.com/taosdata/TDengine-connector-python
|
||||||
|
```
|
||||||
|
|
||||||
|
## Source Code
|
||||||
|
|
||||||
|
[TDengine] connector for Python source code is hosted on [GitHub](https://github.com/taosdata/TDengine-connector-python).
|
||||||
|
|
||||||
|
## License - AGPL
|
||||||
|
|
||||||
|
Keep same with [TDengine](https://github.com/taosdata/TDengine).
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue