Merge branch 'master' into test/chr
This commit is contained in:
commit
23093b6f29
|
@ -1,30 +1,49 @@
|
||||||
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_depth: 1
|
||||||
|
|
||||||
clone_folder: c:\dev\TDengine
|
init:
|
||||||
clone_depth: 1
|
|
||||||
|
|
||||||
init:
|
|
||||||
- call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" %ARCH%
|
- call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" %ARCH%
|
||||||
|
|
||||||
before_build:
|
before_build:
|
||||||
- cd c:\dev\TDengine
|
- cd c:\dev\TDengine
|
||||||
- md build
|
- md build
|
||||||
|
|
||||||
build_script:
|
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,188 @@
|
||||||
|
---
|
||||||
|
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
|
||||||
|
when:
|
||||||
|
branch:
|
||||||
|
- develop
|
||||||
|
- master
|
||||||
|
|
||||||
|
- name: smoke_test
|
||||||
|
image: python:3.8
|
||||||
|
commands:
|
||||||
|
- pip3 install psutil
|
||||||
|
- pip3 install guppy3
|
||||||
|
- pip3 install src/connector/python/linux/python3/
|
||||||
|
- cd tests
|
||||||
|
- ./test-all.sh smoke
|
||||||
|
when:
|
||||||
|
branch:
|
||||||
|
- develop
|
||||||
|
- master
|
||||||
|
|
||||||
|
|
||||||
|
- name: crash_gen
|
||||||
|
image: python:3.8
|
||||||
|
commands:
|
||||||
|
- pip3 install requests
|
||||||
|
- pip3 install src/connector/python/linux/python3/
|
||||||
|
- pip3 install psutil
|
||||||
|
- pip3 install guppy3
|
||||||
|
- cd tests/pytest
|
||||||
|
- ./crash_gen.sh -a -p -t 4 -s 2000
|
||||||
|
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
|
||||||
|
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
|
||||||
|
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
|
||||||
|
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
|
||||||
|
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
|
||||||
|
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
|
|
@ -13,7 +13,7 @@ branches:
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: focal
|
dist: bionic
|
||||||
language: c
|
language: c
|
||||||
|
|
||||||
git:
|
git:
|
||||||
|
@ -28,8 +28,8 @@ matrix:
|
||||||
- build-essential
|
- build-essential
|
||||||
- cmake
|
- cmake
|
||||||
- net-tools
|
- net-tools
|
||||||
- python3-pip
|
- python3.8
|
||||||
- python3-setuptools
|
- libc6-dbg
|
||||||
- valgrind
|
- valgrind
|
||||||
- psmisc
|
- psmisc
|
||||||
- unixodbc
|
- unixodbc
|
||||||
|
@ -39,6 +39,8 @@ matrix:
|
||||||
before_script:
|
before_script:
|
||||||
- export TZ=Asia/Harbin
|
- export TZ=Asia/Harbin
|
||||||
- date
|
- date
|
||||||
|
- curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && python3.8 get-pip.py
|
||||||
|
- python3.8 -m pip install --upgrade pip setuptools
|
||||||
- cd ${TRAVIS_BUILD_DIR}
|
- cd ${TRAVIS_BUILD_DIR}
|
||||||
- mkdir debug
|
- mkdir debug
|
||||||
- cd debug
|
- cd debug
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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.25-dist.jar DESTINATION connector/jdbc)
|
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.28-dist.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.0.20.2")
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
IF (DEFINED VERCOMPATIBLE)
|
IF (DEFINED VERCOMPATIBLE)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
name: tdengine
|
name: tdengine
|
||||||
base: core18
|
base: core18
|
||||||
version: '2.0.20.0'
|
version: '2.0.20.2'
|
||||||
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 +72,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.0.20.2
|
||||||
- usr/lib/libtaos.so.1
|
- usr/lib/libtaos.so.1
|
||||||
- usr/lib/libtaos.so
|
- usr/lib/libtaos.so
|
||||||
|
|
||||||
|
|
|
@ -168,7 +168,8 @@ void tscFieldInfoClear(SFieldInfo* pFieldInfo);
|
||||||
|
|
||||||
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);
|
||||||
|
int32_t tscFieldInfoSetSize(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2);
|
||||||
|
|
||||||
void addExprParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes);
|
void addExprParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes);
|
||||||
|
|
||||||
|
|
|
@ -642,17 +642,25 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
||||||
// set the command/global limit parameters from the first subclause to the sqlcmd object
|
// set the command/global limit parameters from the first subclause to the sqlcmd object
|
||||||
SQueryInfo* pQueryInfo1 = tscGetQueryInfoDetail(pCmd, 0);
|
SQueryInfo* pQueryInfo1 = tscGetQueryInfoDetail(pCmd, 0);
|
||||||
pCmd->command = pQueryInfo1->command;
|
pCmd->command = pQueryInfo1->command;
|
||||||
|
int32_t diffSize = 0;
|
||||||
|
|
||||||
// if there is only one element, the limit of clause is the limit of global result.
|
// if there is only one element, the limit of clause is the limit of global result.
|
||||||
for (int32_t i = 1; i < pCmd->numOfClause; ++i) {
|
for (int32_t i = 1; i < pCmd->numOfClause; ++i) {
|
||||||
SQueryInfo* pQueryInfo2 = tscGetQueryInfoDetail(pCmd, i);
|
SQueryInfo* pQueryInfo2 = tscGetQueryInfoDetail(pCmd, i);
|
||||||
|
|
||||||
int32_t ret = tscFieldInfoCompare(&pQueryInfo1->fieldsInfo, &pQueryInfo2->fieldsInfo);
|
int32_t ret = tscFieldInfoCompare(&pQueryInfo1->fieldsInfo, &pQueryInfo2->fieldsInfo, &diffSize);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (diffSize) {
|
||||||
|
for (int32_t i = 1; i < pCmd->numOfClause; ++i) {
|
||||||
|
SQueryInfo* pQueryInfo2 = tscGetQueryInfoDetail(pCmd, i);
|
||||||
|
tscFieldInfoSetSize(&pQueryInfo1->fieldsInfo, &pQueryInfo2->fieldsInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
|
@ -1606,6 +1614,22 @@ 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 parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, SArray* pSelectList, bool isSTable, bool joinQuery, bool timeWindowQuery) {
|
int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, SArray* pSelectList, bool isSTable, bool joinQuery, bool timeWindowQuery) {
|
||||||
assert(pSelectList != NULL && pCmd != NULL);
|
assert(pSelectList != NULL && pCmd != NULL);
|
||||||
const char* msg1 = "too many columns in selection clause";
|
const char* msg1 = "too many columns in selection clause";
|
||||||
|
@ -1670,7 +1694,7 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, SArray* pSelectLis
|
||||||
|
|
||||||
// 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);
|
addPrimaryTsColIntoResult(pQueryInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1098,7 +1098,7 @@ int16_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index) {
|
||||||
return pInfo->pSqlExpr->offset;
|
return pInfo->pSqlExpr->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) {
|
||||||
|
@ -1110,15 +1110,36 @@ 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) {
|
||||||
|
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) {
|
||||||
|
@ -2682,7 +2703,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;
|
||||||
|
|
||||||
|
|
|
@ -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.25-dist.jar ${LIBRARY_OUTPUT_PATH}
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.28-dist.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.25</version>
|
<version>2.0.28</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.25</version>
|
<version>2.0.28</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>
|
||||||
|
|
|
@ -4,13 +4,23 @@ import java.sql.*;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
public abstract class AbstractConnection extends WrapperImpl implements Connection {
|
public abstract class AbstractConnection extends WrapperImpl implements Connection {
|
||||||
|
|
||||||
protected volatile boolean isClosed;
|
protected volatile boolean isClosed;
|
||||||
protected volatile String catalog;
|
protected volatile String catalog;
|
||||||
protected volatile Properties clientInfoProps = new Properties();
|
protected final Properties clientInfoProps = new Properties();
|
||||||
|
|
||||||
|
protected AbstractConnection(Properties properties) {
|
||||||
|
Set<String> propNames = properties.stringPropertyNames();
|
||||||
|
for (String propName : propNames) {
|
||||||
|
clientInfoProps.setProperty(propName, properties.getProperty(propName));
|
||||||
|
}
|
||||||
|
String timestampFormat = properties.getProperty(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT, "STRING");
|
||||||
|
clientInfoProps.setProperty(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT, timestampFormat);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public abstract Statement createStatement() throws SQLException;
|
public abstract Statement createStatement() throws SQLException;
|
||||||
|
@ -35,7 +45,6 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAutoCommit(boolean autoCommit) throws SQLException {
|
public void setAutoCommit(boolean autoCommit) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
|
@ -441,8 +450,7 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti
|
||||||
if (isClosed)
|
if (isClosed)
|
||||||
throw (SQLClientInfoException) TSDBError.createSQLException(TSDBErrorNumbers.ERROR_SQLCLIENT_EXCEPTION_ON_CONNECTION_CLOSED);
|
throw (SQLClientInfoException) TSDBError.createSQLException(TSDBErrorNumbers.ERROR_SQLCLIENT_EXCEPTION_ON_CONNECTION_CLOSED);
|
||||||
|
|
||||||
if (clientInfoProps == null)
|
if (clientInfoProps != null)
|
||||||
clientInfoProps = new Properties();
|
|
||||||
clientInfoProps.setProperty(name, value);
|
clientInfoProps.setProperty(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import java.util.Map;
|
||||||
|
|
||||||
public abstract class AbstractResultSet extends WrapperImpl implements ResultSet {
|
public abstract class AbstractResultSet extends WrapperImpl implements ResultSet {
|
||||||
private int fetchSize;
|
private int fetchSize;
|
||||||
|
protected boolean wasNull;
|
||||||
|
|
||||||
protected void checkAvailability(int columnIndex, int bounds) throws SQLException {
|
protected void checkAvailability(int columnIndex, int bounds) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
|
@ -28,7 +29,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean wasNull() throws SQLException {
|
public boolean wasNull() throws SQLException {
|
||||||
return false;
|
return wasNull;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -28,6 +28,7 @@ public class TSDBConnection extends AbstractConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
public TSDBConnection(Properties info, TSDBDatabaseMetaData meta) throws SQLException {
|
public TSDBConnection(Properties info, TSDBDatabaseMetaData meta) throws SQLException {
|
||||||
|
super(info);
|
||||||
this.databaseMetaData = meta;
|
this.databaseMetaData = meta;
|
||||||
connect(info.getProperty(TSDBDriver.PROPERTY_KEY_HOST),
|
connect(info.getProperty(TSDBDriver.PROPERTY_KEY_HOST),
|
||||||
Integer.parseInt(info.getProperty(TSDBDriver.PROPERTY_KEY_PORT, "0")),
|
Integer.parseInt(info.getProperty(TSDBDriver.PROPERTY_KEY_PORT, "0")),
|
||||||
|
|
|
@ -95,11 +95,16 @@ public class TSDBDriver extends AbstractDriver {
|
||||||
*/
|
*/
|
||||||
public static final String PROPERTY_KEY_BATCH_LOAD = "batchfetch";
|
public static final String PROPERTY_KEY_BATCH_LOAD = "batchfetch";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* timestamp format for JDBC-RESTful,should one of the options: string or timestamp or utc
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_KEY_TIMESTAMP_FORMAT = "timestampFormat";
|
||||||
|
|
||||||
private TSDBDatabaseMetaData dbMetaData = null;
|
private TSDBDatabaseMetaData dbMetaData = null;
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,11 +14,12 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
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.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.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
@ -33,17 +34,9 @@ import java.util.regex.Pattern;
|
||||||
public class TSDBPreparedStatement extends TSDBStatement implements PreparedStatement {
|
public class TSDBPreparedStatement extends TSDBStatement implements PreparedStatement {
|
||||||
|
|
||||||
private String rawSql;
|
private String rawSql;
|
||||||
private String sql;
|
|
||||||
// private ArrayList<Object> parameters = new ArrayList<>();
|
|
||||||
private Object[] parameters;
|
private Object[] parameters;
|
||||||
private boolean isPrepared;
|
private boolean isPrepared;
|
||||||
|
|
||||||
//start with insert or import and is case-insensitive
|
|
||||||
private static Pattern savePattern = Pattern.compile("(?i)^\\s*(insert|import)");
|
|
||||||
// is insert or import
|
|
||||||
private boolean isSaved;
|
|
||||||
|
|
||||||
// private SavedPreparedStatement savedPreparedStatement;
|
|
||||||
private volatile TSDBParameterMetaData parameterMetaData;
|
private volatile TSDBParameterMetaData parameterMetaData;
|
||||||
|
|
||||||
TSDBPreparedStatement(TSDBConnection connection, TSDBJNIConnector connecter, String sql) {
|
TSDBPreparedStatement(TSDBConnection connection, TSDBJNIConnector connecter, String sql) {
|
||||||
|
@ -65,35 +58,11 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
||||||
private void init(String sql) {
|
private void init(String sql) {
|
||||||
this.rawSql = sql;
|
this.rawSql = sql;
|
||||||
preprocessSql();
|
preprocessSql();
|
||||||
// this.isSaved = isSavedSql(this.rawSql);
|
|
||||||
// if (this.isSaved) {
|
|
||||||
// try {
|
|
||||||
// this.savedPreparedStatement = new SavedPreparedStatement(this.rawSql, this);
|
|
||||||
// } catch (SQLException e) {
|
|
||||||
// e.printStackTrace();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* if the precompiled sql is insert or import
|
|
||||||
*
|
|
||||||
* @param sql
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private boolean isSavedSql(String sql) {
|
|
||||||
Matcher matcher = savePattern.matcher(sql);
|
|
||||||
return matcher.find();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int[] executeBatch() throws SQLException {
|
public int[] executeBatch() throws SQLException {
|
||||||
// if (isSaved) {
|
|
||||||
// return this.savedPreparedStatement.executeBatch();
|
|
||||||
// } else {
|
|
||||||
return super.executeBatch();
|
return super.executeBatch();
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -157,152 +126,64 @@ 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) {
|
|
||||||
// for (int i = 0; i < parameters.length; i++) {
|
|
||||||
// Object para = parameters[i];
|
|
||||||
// if (para != null) {
|
|
||||||
// String paraStr = para.toString();
|
|
||||||
// if (para instanceof Timestamp || para instanceof String) {
|
|
||||||
// paraStr = "'" + paraStr + "'";
|
|
||||||
// }
|
|
||||||
// this.sql = this.sql.replaceFirst("[?]", paraStr);
|
|
||||||
// } else {
|
|
||||||
// this.sql = this.sql.replaceFirst("[?]", "NULL");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// parameters = new Object[parameters.length];
|
|
||||||
// return sql;
|
|
||||||
// }
|
|
||||||
|
|
||||||
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
|
||||||
public ResultSet executeQuery() throws SQLException {
|
public ResultSet executeQuery() throws SQLException {
|
||||||
// if (isSaved) {
|
|
||||||
// this.savedPreparedStatement.executeBatchInternal();
|
|
||||||
// return null;
|
|
||||||
// } else {
|
|
||||||
|
|
||||||
if (!isPrepared)
|
if (!isPrepared)
|
||||||
return executeQuery(this.rawSql);
|
return executeQuery(this.rawSql);
|
||||||
|
|
||||||
final String sql = getNativeSql(this.rawSql);
|
final String sql = getNativeSql(this.rawSql);
|
||||||
return executeQuery(sql);
|
return executeQuery(sql);
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int executeUpdate() throws SQLException {
|
public int executeUpdate() throws SQLException {
|
||||||
// if (isSaved) {
|
|
||||||
// return this.savedPreparedStatement.executeBatchInternal();
|
|
||||||
// } else {
|
|
||||||
if (!isPrepared)
|
if (!isPrepared)
|
||||||
return executeUpdate(this.rawSql);
|
return executeUpdate(this.rawSql);
|
||||||
String sql = getNativeSql(this.rawSql);
|
String sql = getNativeSql(this.rawSql);
|
||||||
return executeUpdate(sql);
|
return executeUpdate(sql);
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isSupportedSQLType(int sqlType) {
|
|
||||||
switch (sqlType) {
|
|
||||||
case Types.TIMESTAMP:
|
|
||||||
case Types.INTEGER:
|
|
||||||
case Types.BIGINT:
|
|
||||||
case Types.FLOAT:
|
|
||||||
case Types.DOUBLE:
|
|
||||||
case Types.SMALLINT:
|
|
||||||
case Types.TINYINT:
|
|
||||||
case Types.BOOLEAN:
|
|
||||||
case Types.BINARY:
|
|
||||||
case Types.NCHAR:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setNull(int parameterIndex, int sqlType) throws SQLException {
|
public void setNull(int parameterIndex, int sqlType) throws SQLException {
|
||||||
if (isClosed())
|
setObject(parameterIndex, null);
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
|
||||||
if (!isSupportedSQLType(sqlType) || parameterIndex < 0)
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
|
|
||||||
// if (parameterIndex >= parameters.size())
|
|
||||||
// throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_BOUNDARY);
|
|
||||||
|
|
||||||
setObject(parameterIndex, "NULL");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBoolean(int parameterIndex, boolean x) throws SQLException {
|
public void setBoolean(int parameterIndex, boolean x) throws SQLException {
|
||||||
if (isClosed())
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
|
||||||
|
|
||||||
setObject(parameterIndex, x);
|
setObject(parameterIndex, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setByte(int parameterIndex, byte x) throws SQLException {
|
public void setByte(int parameterIndex, byte x) throws SQLException {
|
||||||
if (isClosed())
|
setObject(parameterIndex, x);
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
|
||||||
setObject(parameterIndex,x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setShort(int parameterIndex, short x) throws SQLException {
|
public void setShort(int parameterIndex, short x) throws SQLException {
|
||||||
if (isClosed())
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
|
||||||
setObject(parameterIndex, x);
|
setObject(parameterIndex, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setInt(int parameterIndex, int x) throws SQLException {
|
public void setInt(int parameterIndex, int x) throws SQLException {
|
||||||
if (isClosed())
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
|
||||||
setObject(parameterIndex, x);
|
setObject(parameterIndex, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setLong(int parameterIndex, long x) throws SQLException {
|
public void setLong(int parameterIndex, long x) throws SQLException {
|
||||||
if (isClosed())
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
|
||||||
setObject(parameterIndex, x);
|
setObject(parameterIndex, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setFloat(int parameterIndex, float x) throws SQLException {
|
public void setFloat(int parameterIndex, float x) throws SQLException {
|
||||||
if (isClosed())
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
|
||||||
setObject(parameterIndex, x);
|
setObject(parameterIndex, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDouble(int parameterIndex, double x) throws SQLException {
|
public void setDouble(int parameterIndex, double x) throws SQLException {
|
||||||
if (isClosed())
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
|
||||||
setObject(parameterIndex, x);
|
setObject(parameterIndex, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,17 +196,12 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setString(int parameterIndex, String x) throws SQLException {
|
public void setString(int parameterIndex, String x) throws SQLException {
|
||||||
if (isClosed())
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
|
||||||
setObject(parameterIndex, x);
|
setObject(parameterIndex, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBytes(int parameterIndex, byte[] x) throws SQLException {
|
public void setBytes(int parameterIndex, byte[] x) throws SQLException {
|
||||||
if (isClosed())
|
setObject(parameterIndex, x);
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
|
||||||
|
|
||||||
setObject(parameterIndex,x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -344,8 +220,6 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
|
public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
|
||||||
if (isClosed())
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
|
||||||
setObject(parameterIndex, x);
|
setObject(parameterIndex, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,7 +234,6 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
||||||
public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
|
public void setUnicodeStream(int parameterIndex, InputStream x, int length) 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,8 +248,6 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
||||||
public void clearParameters() throws SQLException {
|
public void clearParameters() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||||
|
|
||||||
// parameters.clear();
|
|
||||||
parameters = new Object[parameters.length];
|
parameters = new Object[parameters.length];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,43 +255,29 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
||||||
public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
|
public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||||
|
setObject(parameterIndex, x);
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setObject(int parameterIndex, Object x) throws SQLException {
|
public void setObject(int parameterIndex, Object x) throws SQLException {
|
||||||
// if (isSaved) {
|
if (isClosed())
|
||||||
// this.savedPreparedStatement.setParam(parameterIndex, x);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||||
// } else {
|
|
||||||
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;
|
||||||
// parameters.add(x);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute() throws SQLException {
|
public boolean execute() throws SQLException {
|
||||||
// if (isSaved) {
|
|
||||||
// int result = this.savedPreparedStatement.executeBatchInternal();
|
|
||||||
// return result > 0;
|
|
||||||
// } else {
|
|
||||||
if (!isPrepared)
|
if (!isPrepared)
|
||||||
return execute(this.rawSql);
|
return execute(this.rawSql);
|
||||||
|
|
||||||
final String sql = getNativeSql(this.rawSql);
|
final String sql = getNativeSql(this.rawSql);
|
||||||
|
|
||||||
return execute(sql);
|
return execute(sql);
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addBatch() throws SQLException {
|
public void addBatch() throws SQLException {
|
||||||
// if (isSaved) {
|
|
||||||
// this.savedPreparedStatement.addBatch();
|
|
||||||
// } else {
|
|
||||||
if (this.batchedArgs == null) {
|
if (this.batchedArgs == null) {
|
||||||
batchedArgs = new ArrayList<>();
|
batchedArgs = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
@ -431,7 +288,6 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
||||||
String sql = this.getConnection().nativeSQL(this.rawSql);
|
String sql = this.getConnection().nativeSQL(this.rawSql);
|
||||||
addBatch(sql);
|
addBatch(sql);
|
||||||
}
|
}
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -475,7 +331,6 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
||||||
public ResultSetMetaData getMetaData() throws SQLException {
|
public ResultSetMetaData getMetaData() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||||
// return this.getResultSet().getMetaData();
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -203,6 +203,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
|
||||||
|
|
||||||
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
|
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
|
||||||
if (!lastWasNull) {
|
if (!lastWasNull) {
|
||||||
|
Object value = this.rowData.get(columnIndex - 1);
|
||||||
|
if (value instanceof Timestamp)
|
||||||
|
res = ((Timestamp) value).getTime();
|
||||||
|
else
|
||||||
res = this.rowData.getLong(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType());
|
res = this.rowData.getLong(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType());
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
@ -273,7 +277,6 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
|
||||||
checkAvailability(columnIndex, this.columnMetaDataList.size());
|
checkAvailability(columnIndex, this.columnMetaDataList.size());
|
||||||
|
|
||||||
Timestamp res = null;
|
Timestamp res = null;
|
||||||
|
|
||||||
if (this.getBatchFetch())
|
if (this.getBatchFetch())
|
||||||
return this.blockData.getTimestamp(columnIndex - 1);
|
return this.blockData.getTimestamp(columnIndex - 1);
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ package com.taosdata.jdbc;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
|
@ -299,7 +300,19 @@ public class TSDBResultSetRowData {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTimestamp(int col, long ts) {
|
public void setTimestamp(int col, long ts) {
|
||||||
|
//TODO: this implementation contains logical error
|
||||||
|
// when precision is us the (long ts) is 16 digital number
|
||||||
|
// when precision is ms, the (long ts) is 13 digital number
|
||||||
|
// we need a JNI function like this:
|
||||||
|
// public void setTimestamp(int col, long epochSecond, long nanoAdjustment)
|
||||||
|
if (ts < 1_0000_0000_0000_0L) {
|
||||||
data.set(col, new Timestamp(ts));
|
data.set(col, new Timestamp(ts));
|
||||||
|
} else {
|
||||||
|
long epochSec = ts / 1000_000l;
|
||||||
|
long nanoAdjustment = ts % 1000_000l * 1000l;
|
||||||
|
Timestamp timestamp = Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment));
|
||||||
|
data.set(col, timestamp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Timestamp getTimestamp(int col) {
|
public Timestamp getTimestamp(int col) {
|
||||||
|
|
|
@ -22,6 +22,7 @@ public class RestfulConnection extends AbstractConnection {
|
||||||
private final DatabaseMetaData metadata;
|
private final DatabaseMetaData metadata;
|
||||||
|
|
||||||
public RestfulConnection(String host, String port, Properties props, String database, String url) {
|
public RestfulConnection(String host, String port, Properties props, String database, String url) {
|
||||||
|
super(props);
|
||||||
this.host = host;
|
this.host = host;
|
||||||
this.port = Integer.parseInt(port);
|
this.port = Integer.parseInt(port);
|
||||||
this.database = database;
|
this.database = database;
|
||||||
|
|
|
@ -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
|
||||||
|
@ -221,7 +207,7 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||||
|
|
||||||
setObject(parameterIndex,x);
|
setObject(parameterIndex, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -5,13 +5,12 @@ import com.alibaba.fastjson.JSONObject;
|
||||||
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.AbstractResultSet;
|
import com.taosdata.jdbc.*;
|
||||||
import com.taosdata.jdbc.TSDBConstants;
|
|
||||||
import com.taosdata.jdbc.TSDBError;
|
|
||||||
import com.taosdata.jdbc.TSDBErrorNumbers;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
@ -19,6 +18,7 @@ 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
|
||||||
|
@ -65,7 +65,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object parseColumnData(JSONArray row, int colIndex, int taosType) {
|
private Object parseColumnData(JSONArray row, int colIndex, int taosType) throws SQLException {
|
||||||
switch (taosType) {
|
switch (taosType) {
|
||||||
case TSDBConstants.TSDB_DATA_TYPE_BOOL:
|
case TSDBConstants.TSDB_DATA_TYPE_BOOL:
|
||||||
return row.getBoolean(colIndex);
|
return row.getBoolean(colIndex);
|
||||||
|
@ -81,8 +81,44 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
return row.getFloat(colIndex);
|
return row.getFloat(colIndex);
|
||||||
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
|
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
|
||||||
return row.getDouble(colIndex);
|
return row.getDouble(colIndex);
|
||||||
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
|
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: {
|
||||||
return new Timestamp(row.getDate(colIndex).getTime());
|
if (row.get(colIndex) == null)
|
||||||
|
return null;
|
||||||
|
String timestampFormat = this.statement.getConnection().getClientInfo(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT);
|
||||||
|
if ("TIMESTAMP".equalsIgnoreCase(timestampFormat)) {
|
||||||
|
Long value = row.getLong(colIndex);
|
||||||
|
//TODO: this implementation has bug if the timestamp bigger than 9999_9999_9999_9
|
||||||
|
if (value < 1_0000_0000_0000_0L)
|
||||||
|
return new Timestamp(value);
|
||||||
|
long epochSec = value / 1000_000l;
|
||||||
|
long nanoAdjustment = value % 1000_000l * 1000l;
|
||||||
|
return Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment));
|
||||||
|
}
|
||||||
|
if ("UTC".equalsIgnoreCase(timestampFormat)) {
|
||||||
|
String value = row.getString(colIndex);
|
||||||
|
long epochSec = Timestamp.valueOf(value.substring(0, 19).replace("T", " ")).getTime() / 1000;
|
||||||
|
int fractionalSec = Integer.parseInt(value.substring(20, value.length() - 5));
|
||||||
|
long nanoAdjustment = 0;
|
||||||
|
if (value.length() > 28) {
|
||||||
|
// ms timestamp: yyyy-MM-ddTHH:mm:ss.SSSSSS+0x00
|
||||||
|
nanoAdjustment = fractionalSec * 1000l;
|
||||||
|
} else {
|
||||||
|
// ms timestamp: yyyy-MM-ddTHH:mm:ss.SSS+0x00
|
||||||
|
nanoAdjustment = fractionalSec * 1000_000l;
|
||||||
|
}
|
||||||
|
ZoneOffset zoneOffset = ZoneOffset.of(value.substring(value.length() - 5));
|
||||||
|
Instant instant = Instant.ofEpochSecond(epochSec, nanoAdjustment).atOffset(zoneOffset).toInstant();
|
||||||
|
return Timestamp.from(instant);
|
||||||
|
}
|
||||||
|
String value = row.getString(colIndex);
|
||||||
|
if (value.length() <= 23) // ms timestamp: yyyy-MM-dd HH:mm:ss.SSS
|
||||||
|
return row.getTimestamp(colIndex);
|
||||||
|
// us timestamp: yyyy-MM-dd HH:mm:ss.SSSSSS
|
||||||
|
long epochSec = Timestamp.valueOf(value.substring(0, 19)).getTime() / 1000;
|
||||||
|
long nanoAdjustment = Integer.parseInt(value.substring(20)) * 1000l;
|
||||||
|
Timestamp timestamp = Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment));
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
|
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
|
||||||
return row.getString(colIndex) == null ? null : row.getString(colIndex).getBytes();
|
return row.getString(colIndex) == null ? null : row.getString(colIndex).getBytes();
|
||||||
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
|
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
|
||||||
|
@ -126,12 +162,12 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public boolean wasNull() throws SQLException {
|
// public boolean wasNull() throws SQLException {
|
||||||
if (isClosed())
|
// if (isClosed())
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
|
// throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
|
||||||
return resultSet.isEmpty();
|
// return resultSet.isEmpty();
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getString(int columnIndex) throws SQLException {
|
public String getString(int columnIndex) throws SQLException {
|
||||||
|
@ -150,8 +186,11 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
checkAvailability(columnIndex, resultSet.get(pos).size());
|
checkAvailability(columnIndex, resultSet.get(pos).size());
|
||||||
|
|
||||||
Object value = resultSet.get(pos).get(columnIndex - 1);
|
Object value = resultSet.get(pos).get(columnIndex - 1);
|
||||||
if (value == null)
|
if (value == null) {
|
||||||
|
wasNull = true;
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
wasNull = false;
|
||||||
if (value instanceof Boolean)
|
if (value instanceof Boolean)
|
||||||
return (boolean) value;
|
return (boolean) value;
|
||||||
return Boolean.valueOf(value.toString());
|
return Boolean.valueOf(value.toString());
|
||||||
|
@ -162,8 +201,11 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
checkAvailability(columnIndex, resultSet.get(pos).size());
|
checkAvailability(columnIndex, resultSet.get(pos).size());
|
||||||
|
|
||||||
Object value = resultSet.get(pos).get(columnIndex - 1);
|
Object value = resultSet.get(pos).get(columnIndex - 1);
|
||||||
if (value == null)
|
if (value == null) {
|
||||||
|
wasNull = true;
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
wasNull = false;
|
||||||
long valueAsLong = Long.parseLong(value.toString());
|
long valueAsLong = Long.parseLong(value.toString());
|
||||||
if (valueAsLong == Byte.MIN_VALUE)
|
if (valueAsLong == Byte.MIN_VALUE)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -183,8 +225,11 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
checkAvailability(columnIndex, resultSet.get(pos).size());
|
checkAvailability(columnIndex, resultSet.get(pos).size());
|
||||||
|
|
||||||
Object value = resultSet.get(pos).get(columnIndex - 1);
|
Object value = resultSet.get(pos).get(columnIndex - 1);
|
||||||
if (value == null)
|
if (value == null) {
|
||||||
|
wasNull = true;
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
wasNull = false;
|
||||||
long valueAsLong = Long.parseLong(value.toString());
|
long valueAsLong = Long.parseLong(value.toString());
|
||||||
if (valueAsLong == Short.MIN_VALUE)
|
if (valueAsLong == Short.MIN_VALUE)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -198,8 +243,11 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
checkAvailability(columnIndex, resultSet.get(pos).size());
|
checkAvailability(columnIndex, resultSet.get(pos).size());
|
||||||
|
|
||||||
Object value = resultSet.get(pos).get(columnIndex - 1);
|
Object value = resultSet.get(pos).get(columnIndex - 1);
|
||||||
if (value == null)
|
if (value == null) {
|
||||||
|
wasNull = true;
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
wasNull = false;
|
||||||
long valueAsLong = Long.parseLong(value.toString());
|
long valueAsLong = Long.parseLong(value.toString());
|
||||||
if (valueAsLong == Integer.MIN_VALUE)
|
if (valueAsLong == Integer.MIN_VALUE)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -213,9 +261,14 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
checkAvailability(columnIndex, resultSet.get(pos).size());
|
checkAvailability(columnIndex, resultSet.get(pos).size());
|
||||||
|
|
||||||
Object value = resultSet.get(pos).get(columnIndex - 1);
|
Object value = resultSet.get(pos).get(columnIndex - 1);
|
||||||
if (value == null)
|
if (value == null) {
|
||||||
|
wasNull = true;
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
wasNull = false;
|
||||||
|
if (value instanceof Timestamp) {
|
||||||
|
return ((Timestamp) value).getTime();
|
||||||
|
}
|
||||||
long valueAsLong = 0;
|
long valueAsLong = 0;
|
||||||
try {
|
try {
|
||||||
valueAsLong = Long.parseLong(value.toString());
|
valueAsLong = Long.parseLong(value.toString());
|
||||||
|
@ -232,8 +285,11 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
checkAvailability(columnIndex, resultSet.get(pos).size());
|
checkAvailability(columnIndex, resultSet.get(pos).size());
|
||||||
|
|
||||||
Object value = resultSet.get(pos).get(columnIndex - 1);
|
Object value = resultSet.get(pos).get(columnIndex - 1);
|
||||||
if (value == null)
|
if (value == null) {
|
||||||
|
wasNull = true;
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
wasNull = false;
|
||||||
if (value instanceof Float || value instanceof Double)
|
if (value instanceof Float || value instanceof Double)
|
||||||
return (float) value;
|
return (float) value;
|
||||||
return Float.parseFloat(value.toString());
|
return Float.parseFloat(value.toString());
|
||||||
|
@ -244,8 +300,11 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
checkAvailability(columnIndex, resultSet.get(pos).size());
|
checkAvailability(columnIndex, resultSet.get(pos).size());
|
||||||
|
|
||||||
Object value = resultSet.get(pos).get(columnIndex - 1);
|
Object value = resultSet.get(pos).get(columnIndex - 1);
|
||||||
if (value == null)
|
if (value == null) {
|
||||||
|
wasNull = true;
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
wasNull = false;
|
||||||
if (value instanceof Double || value instanceof Float)
|
if (value instanceof Double || value instanceof Float)
|
||||||
return (double) value;
|
return (double) value;
|
||||||
return Double.parseDouble(value.toString());
|
return Double.parseDouble(value.toString());
|
||||||
|
@ -307,6 +366,13 @@ 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 (1_0000_0000_0000_0L > (long) value)
|
||||||
|
// return Timestamp.from(Instant.ofEpochMilli((long) value));
|
||||||
|
// long epochSec = (long) value / 1000_000L;
|
||||||
|
// long nanoAdjustment = (long) ((long) value % 1000_000L * 1000);
|
||||||
|
// return Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment));
|
||||||
|
// }
|
||||||
return Timestamp.valueOf(value.toString());
|
return Timestamp.valueOf(value.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.taosdata.jdbc.AbstractStatement;
|
import com.taosdata.jdbc.AbstractStatement;
|
||||||
|
import com.taosdata.jdbc.TSDBDriver;
|
||||||
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.HttpClientPoolUtil;
|
import com.taosdata.jdbc.utils.HttpClientPoolUtil;
|
||||||
|
@ -34,14 +35,11 @@ public class RestfulStatement extends AbstractStatement {
|
||||||
if (!SqlSyntaxValidator.isValidForExecuteQuery(sql))
|
if (!SqlSyntaxValidator.isValidForExecuteQuery(sql))
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_QUERY, "not a valid sql for executeQuery: " + sql);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_QUERY, "not a valid sql for executeQuery: " + sql);
|
||||||
|
|
||||||
final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
|
|
||||||
if (SqlSyntaxValidator.isDatabaseUnspecifiedQuery(sql)) {
|
if (SqlSyntaxValidator.isDatabaseUnspecifiedQuery(sql)) {
|
||||||
return executeOneQuery(url, sql);
|
return executeOneQuery(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (this.database != null && !this.database.trim().replaceAll("\\s","").isEmpty())
|
return executeOneQuery(sql);
|
||||||
// HttpClientPoolUtil.execute(url, "use " + this.database);
|
|
||||||
return executeOneQuery(url, sql);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -56,8 +54,6 @@ public class RestfulStatement extends AbstractStatement {
|
||||||
return executeOneUpdate(url, sql);
|
return executeOneUpdate(url, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (this.database != null && !this.database.trim().replaceAll("\\s", "").isEmpty())
|
|
||||||
// HttpClientPoolUtil.execute(url, "use " + this.database);
|
|
||||||
return executeOneUpdate(url, sql);
|
return executeOneUpdate(url, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,14 +74,21 @@ public class RestfulStatement extends AbstractStatement {
|
||||||
|
|
||||||
//如果执行了use操作应该将当前Statement的catalog设置为新的database
|
//如果执行了use操作应该将当前Statement的catalog设置为新的database
|
||||||
boolean result = true;
|
boolean result = true;
|
||||||
final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
|
String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
|
||||||
|
if (conn.getClientInfo(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT).equals("TIMESTAMP")) {
|
||||||
|
url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sqlt";
|
||||||
|
}
|
||||||
|
if (conn.getClientInfo(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT).equals("UTC")) {
|
||||||
|
url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sqlutc";
|
||||||
|
}
|
||||||
|
|
||||||
if (SqlSyntaxValidator.isUseSql(sql)) {
|
if (SqlSyntaxValidator.isUseSql(sql)) {
|
||||||
HttpClientPoolUtil.execute(url, sql);
|
HttpClientPoolUtil.execute(url, sql);
|
||||||
this.database = sql.trim().replace("use", "").trim();
|
this.database = sql.trim().replace("use", "").trim();
|
||||||
this.conn.setCatalog(this.database);
|
this.conn.setCatalog(this.database);
|
||||||
result = false;
|
result = false;
|
||||||
} else if (SqlSyntaxValidator.isDatabaseUnspecifiedQuery(sql)) {
|
} else if (SqlSyntaxValidator.isDatabaseUnspecifiedQuery(sql)) {
|
||||||
executeOneQuery(url, sql);
|
executeOneQuery(sql);
|
||||||
} else if (SqlSyntaxValidator.isDatabaseUnspecifiedUpdate(sql)) {
|
} else if (SqlSyntaxValidator.isDatabaseUnspecifiedUpdate(sql)) {
|
||||||
executeOneUpdate(url, sql);
|
executeOneUpdate(url, sql);
|
||||||
result = false;
|
result = false;
|
||||||
|
@ -101,11 +104,18 @@ public class RestfulStatement extends AbstractStatement {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResultSet executeOneQuery(String url, String sql) throws SQLException {
|
private ResultSet executeOneQuery(String sql) throws SQLException {
|
||||||
if (!SqlSyntaxValidator.isValidForExecuteQuery(sql))
|
if (!SqlSyntaxValidator.isValidForExecuteQuery(sql))
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_QUERY, "not a valid sql for executeQuery: " + sql);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_QUERY, "not a valid sql for executeQuery: " + sql);
|
||||||
|
|
||||||
// row data
|
// row data
|
||||||
|
String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
|
||||||
|
String timestampFormat = conn.getClientInfo(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT);
|
||||||
|
if ("TIMESTAMP".equalsIgnoreCase(timestampFormat))
|
||||||
|
url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sqlt";
|
||||||
|
if ("UTC".equalsIgnoreCase(timestampFormat))
|
||||||
|
url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sqlutc";
|
||||||
|
|
||||||
String result = HttpClientPoolUtil.execute(url, sql);
|
String result = HttpClientPoolUtil.execute(url, sql);
|
||||||
JSONObject resultJson = JSON.parseObject(result);
|
JSONObject resultJson = JSON.parseObject(result);
|
||||||
if (resultJson.getString("status").equals("error")) {
|
if (resultJson.getString("status").equals("error")) {
|
||||||
|
@ -126,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,12 @@
|
||||||
|
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,135 @@
|
||||||
|
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.Timestamp;
|
||||||
|
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(".*?'");
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -12,6 +12,7 @@ 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";
|
||||||
|
@ -19,10 +20,38 @@ public class SubscribeTest {
|
||||||
String host = "127.0.0.1";
|
String host = "127.0.0.1";
|
||||||
String topic = "test";
|
String topic = "test";
|
||||||
|
|
||||||
@Before
|
@Test
|
||||||
public void createDatabase() {
|
public void subscribe() {
|
||||||
try {
|
try {
|
||||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
String rawSql = "select * from " + dbName + "." + tName + ";";
|
||||||
|
TSDBConnection conn = connection.unwrap(TSDBConnection.class);
|
||||||
|
TSDBSubscribe subscribe = conn.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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void createDatabase() throws SQLException {
|
||||||
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");
|
||||||
|
@ -34,45 +63,8 @@ public class SubscribeTest {
|
||||||
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();
|
long 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 +78,5 @@ public class SubscribeTest {
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -50,6 +50,51 @@ public class TSDBPreparedStatementTest {
|
||||||
pstmt_insert.setNull(2, Types.INTEGER);
|
pstmt_insert.setNull(2, Types.INTEGER);
|
||||||
int result = pstmt_insert.executeUpdate();
|
int result = pstmt_insert.executeUpdate();
|
||||||
Assert.assertEquals(1, result);
|
Assert.assertEquals(1, result);
|
||||||
|
|
||||||
|
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
||||||
|
pstmt_insert.setNull(3, Types.BIGINT);
|
||||||
|
result = pstmt_insert.executeUpdate();
|
||||||
|
Assert.assertEquals(1, result);
|
||||||
|
|
||||||
|
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
||||||
|
pstmt_insert.setNull(4, Types.FLOAT);
|
||||||
|
result = pstmt_insert.executeUpdate();
|
||||||
|
Assert.assertEquals(1, result);
|
||||||
|
|
||||||
|
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
||||||
|
pstmt_insert.setNull(5, Types.DOUBLE);
|
||||||
|
result = pstmt_insert.executeUpdate();
|
||||||
|
Assert.assertEquals(1, result);
|
||||||
|
|
||||||
|
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
||||||
|
pstmt_insert.setNull(6, Types.SMALLINT);
|
||||||
|
result = pstmt_insert.executeUpdate();
|
||||||
|
Assert.assertEquals(1, result);
|
||||||
|
|
||||||
|
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
||||||
|
pstmt_insert.setNull(7, Types.TINYINT);
|
||||||
|
result = pstmt_insert.executeUpdate();
|
||||||
|
Assert.assertEquals(1, result);
|
||||||
|
|
||||||
|
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
||||||
|
pstmt_insert.setNull(8, Types.BOOLEAN);
|
||||||
|
result = pstmt_insert.executeUpdate();
|
||||||
|
Assert.assertEquals(1, result);
|
||||||
|
|
||||||
|
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
||||||
|
pstmt_insert.setNull(9, Types.BINARY);
|
||||||
|
result = pstmt_insert.executeUpdate();
|
||||||
|
Assert.assertEquals(1, result);
|
||||||
|
|
||||||
|
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
||||||
|
pstmt_insert.setNull(10, Types.NCHAR);
|
||||||
|
result = pstmt_insert.executeUpdate();
|
||||||
|
Assert.assertEquals(1, result);
|
||||||
|
|
||||||
|
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
||||||
|
pstmt_insert.setNull(10, Types.OTHER);
|
||||||
|
result = pstmt_insert.executeUpdate();
|
||||||
|
Assert.assertEquals(1, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -129,7 +174,7 @@ public class TSDBPreparedStatementTest {
|
||||||
Assert.assertFalse(pstmt_insert.execute());
|
Assert.assertFalse(pstmt_insert.execute());
|
||||||
}
|
}
|
||||||
|
|
||||||
class Person implements Serializable {
|
class Person {
|
||||||
String name;
|
String name;
|
||||||
int age;
|
int age;
|
||||||
boolean sex;
|
boolean sex;
|
||||||
|
|
|
@ -160,6 +160,7 @@ public class TSDBResultSetTest {
|
||||||
@Test
|
@Test
|
||||||
public void getTime() throws SQLException {
|
public void getTime() throws SQLException {
|
||||||
Time f1 = rs.getTime("f1");
|
Time f1 = rs.getTime("f1");
|
||||||
|
Assert.assertNotNull(f1);
|
||||||
Assert.assertEquals("00:00:00", f1.toString());
|
Assert.assertEquals("00:00:00", f1.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ public class DriverAutoloadTest {
|
||||||
final String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata";
|
final String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata";
|
||||||
Connection conn = DriverManager.getConnection(url, properties);
|
Connection conn = DriverManager.getConnection(url, properties);
|
||||||
Assert.assertNotNull(conn);
|
Assert.assertNotNull(conn);
|
||||||
|
conn.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -27,6 +28,7 @@ public class DriverAutoloadTest {
|
||||||
final String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata";
|
final String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata";
|
||||||
Connection conn = DriverManager.getConnection(url, properties);
|
Connection conn = DriverManager.getConnection(url, properties);
|
||||||
Assert.assertNotNull(conn);
|
Assert.assertNotNull(conn);
|
||||||
|
conn.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,400 @@
|
||||||
|
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(0, special_character_str_1.length() - 2), 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,401 @@
|
||||||
|
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 final String host = "master";
|
||||||
|
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(0, special_character_str_1.length() - 2), 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,64 @@
|
||||||
|
package com.taosdata.jdbc.cases;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
|
||||||
|
public class NullValueInResultSetForJdbcJniTest {
|
||||||
|
|
||||||
|
private static final String host = "127.0.0.1";
|
||||||
|
Connection conn;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
try (Statement stmt = conn.createStatement()) {
|
||||||
|
ResultSet rs = stmt.executeQuery("select * from weather");
|
||||||
|
ResultSetMetaData meta = rs.getMetaData();
|
||||||
|
while (rs.next()) {
|
||||||
|
for (int i = 1; i <= meta.getColumnCount(); i++) {
|
||||||
|
Object value = rs.getObject(i);
|
||||||
|
System.out.print(meta.getColumnLabel(i) + ": " + value + "\t");
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before() throws SQLException {
|
||||||
|
final 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 test_null");
|
||||||
|
stmt.execute("create database if not exists test_null");
|
||||||
|
stmt.execute("use test_null");
|
||||||
|
stmt.execute("create table weather(ts timestamp, f1 int, f2 bigint, f3 float, f4 double, f5 smallint, f6 tinyint, f7 bool, f8 binary(64), f9 nchar(64))");
|
||||||
|
stmt.executeUpdate("insert into weather(ts, f1) values(now+1s, 1)");
|
||||||
|
stmt.executeUpdate("insert into weather(ts, f2) values(now+2s, 2)");
|
||||||
|
stmt.executeUpdate("insert into weather(ts, f3) values(now+3s, 3.0)");
|
||||||
|
stmt.executeUpdate("insert into weather(ts, f4) values(now+4s, 4.0)");
|
||||||
|
stmt.executeUpdate("insert into weather(ts, f5) values(now+5s, 5)");
|
||||||
|
stmt.executeUpdate("insert into weather(ts, f6) values(now+6s, 6)");
|
||||||
|
stmt.executeUpdate("insert into weather(ts, f7) values(now+7s, true)");
|
||||||
|
stmt.executeUpdate("insert into weather(ts, f8) values(now+8s, 'hello')");
|
||||||
|
stmt.executeUpdate("insert into weather(ts, f9) values(now+9s, '涛思数据')");
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void after() {
|
||||||
|
try {
|
||||||
|
if (conn != null)
|
||||||
|
conn.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
package com.taosdata.jdbc.cases;
|
||||||
|
|
||||||
|
import com.taosdata.jdbc.TSDBDriver;
|
||||||
|
import com.taosdata.jdbc.utils.TimestampUtil;
|
||||||
|
import org.junit.*;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class TD3841Test {
|
||||||
|
private static final String host = "127.0.0.1";
|
||||||
|
private static Properties properties;
|
||||||
|
private static Connection conn_restful;
|
||||||
|
private static Connection conn_jni;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRestful() throws SQLException {
|
||||||
|
String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata";
|
||||||
|
conn_restful = DriverManager.getConnection(url, properties);
|
||||||
|
|
||||||
|
try (Statement stmt = conn_restful.createStatement()) {
|
||||||
|
stmt.execute("drop database if exists test_null");
|
||||||
|
stmt.execute("create database if not exists test_null");
|
||||||
|
stmt.execute("use test_null");
|
||||||
|
stmt.execute("create table weather(ts timestamp, f1 timestamp, f2 int, f3 bigint, f4 float, f5 double, f6 smallint, f7 tinyint, f8 bool, f9 binary(64), f10 nchar(64))");
|
||||||
|
stmt.executeUpdate("insert into weather(ts, f1) values(now+1s, " + TimestampUtil.datetimeToLong("2021-04-21 12:00:00.000") + ")");
|
||||||
|
ResultSet rs = stmt.executeQuery("select * from weather");
|
||||||
|
rs.next();
|
||||||
|
|
||||||
|
Assert.assertEquals("2021-04-21 12:00:00.000", TimestampUtil.longToDatetime(rs.getTimestamp(2).getTime()));
|
||||||
|
Assert.assertEquals(true, rs.getInt(3) == 0 && rs.wasNull());
|
||||||
|
Assert.assertEquals(true, rs.getLong(4) == 0 && rs.wasNull());
|
||||||
|
Assert.assertEquals(true, rs.getFloat(5) == 0.0f && rs.wasNull());
|
||||||
|
Assert.assertEquals(true, rs.getDouble(6) == 0.0f && rs.wasNull());
|
||||||
|
Assert.assertEquals(true, rs.getByte(7) == 0 && rs.wasNull());
|
||||||
|
Assert.assertEquals(true, rs.getShort(8) == 0 && rs.wasNull());
|
||||||
|
Assert.assertEquals(null, rs.getBytes(9));
|
||||||
|
Assert.assertEquals(null, rs.getString(10));
|
||||||
|
|
||||||
|
rs.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testJNI() throws SQLException {
|
||||||
|
final String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata";
|
||||||
|
conn_jni = DriverManager.getConnection(url, properties);
|
||||||
|
|
||||||
|
try (Statement stmt = conn_jni.createStatement()) {
|
||||||
|
stmt.execute("drop database if exists test_null");
|
||||||
|
stmt.execute("create database if not exists test_null");
|
||||||
|
stmt.execute("use test_null");
|
||||||
|
stmt.execute("create table weather(ts timestamp, f1 timestamp, f2 int, f3 bigint, f4 float, f5 double, f6 smallint, f7 tinyint, f8 bool, f9 binary(64), f10 nchar(64))");
|
||||||
|
stmt.executeUpdate("insert into weather(ts, f1) values(now+1s, " + TimestampUtil.datetimeToLong("2021-04-21 12:00:00.000") + ")");
|
||||||
|
ResultSet rs = stmt.executeQuery("select * from weather");
|
||||||
|
rs.next();
|
||||||
|
|
||||||
|
Assert.assertEquals("2021-04-21 12:00:00.000", TimestampUtil.longToDatetime(rs.getTimestamp(2).getTime()));
|
||||||
|
Assert.assertEquals(true, rs.getInt(3) == 0 && rs.wasNull());
|
||||||
|
Assert.assertEquals(true, rs.getLong(4) == 0 && rs.wasNull());
|
||||||
|
Assert.assertEquals(true, rs.getFloat(5) == 0.0f && rs.wasNull());
|
||||||
|
Assert.assertEquals(true, rs.getDouble(6) == 0.0f && rs.wasNull());
|
||||||
|
Assert.assertEquals(true, rs.getByte(7) == 0 && rs.wasNull());
|
||||||
|
Assert.assertEquals(true, rs.getShort(8) == 0 && rs.wasNull());
|
||||||
|
Assert.assertEquals(null, rs.getBytes(9));
|
||||||
|
Assert.assertEquals(null, rs.getString(10));
|
||||||
|
|
||||||
|
rs.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() {
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void afterClass() throws SQLException {
|
||||||
|
if (conn_restful != null)
|
||||||
|
conn_restful.close();
|
||||||
|
if (conn_jni != null)
|
||||||
|
conn_jni.close();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
package com.taosdata.jdbc.cases;
|
||||||
|
|
||||||
|
|
||||||
|
import com.taosdata.jdbc.TSDBDriver;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class TwoTypeTimestampPercisionInJniTest {
|
||||||
|
|
||||||
|
private static final String host = "127.0.0.1";
|
||||||
|
private static final String ms_timestamp_db = "ms_precision_test";
|
||||||
|
private static final String us_timestamp_db = "us_precision_test";
|
||||||
|
private static final long timestamp1 = System.currentTimeMillis();
|
||||||
|
private static final long timestamp2 = timestamp1 * 1000 + 123;
|
||||||
|
|
||||||
|
private static Connection conn;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase1() {
|
||||||
|
try (Statement stmt = conn.createStatement()) {
|
||||||
|
ResultSet rs = stmt.executeQuery("select last_row(ts) from " + ms_timestamp_db + ".weather");
|
||||||
|
rs.next();
|
||||||
|
long ts = rs.getTimestamp(1).getTime();
|
||||||
|
Assert.assertEquals(timestamp1, ts);
|
||||||
|
ts = rs.getLong(1);
|
||||||
|
Assert.assertEquals(timestamp1, ts);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase2() {
|
||||||
|
try (Statement stmt = conn.createStatement()) {
|
||||||
|
ResultSet rs = stmt.executeQuery("select last_row(ts) from " + us_timestamp_db + ".weather");
|
||||||
|
rs.next();
|
||||||
|
|
||||||
|
Timestamp timestamp = rs.getTimestamp(1);
|
||||||
|
System.out.println(timestamp);
|
||||||
|
long ts = timestamp.getTime();
|
||||||
|
Assert.assertEquals(timestamp1, ts);
|
||||||
|
int nanos = timestamp.getNanos();
|
||||||
|
Assert.assertEquals(timestamp2 % 1000_000l * 1000, nanos);
|
||||||
|
|
||||||
|
ts = rs.getLong(1);
|
||||||
|
Assert.assertEquals(timestamp1, ts);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() throws SQLException {
|
||||||
|
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");
|
||||||
|
|
||||||
|
String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata";
|
||||||
|
conn = DriverManager.getConnection(url, properties);
|
||||||
|
|
||||||
|
Statement stmt = conn.createStatement();
|
||||||
|
stmt.execute("drop database if exists " + ms_timestamp_db);
|
||||||
|
stmt.execute("create database if not exists " + ms_timestamp_db + " precision 'ms'");
|
||||||
|
stmt.execute("create table " + ms_timestamp_db + ".weather(ts timestamp, f1 int)");
|
||||||
|
stmt.executeUpdate("insert into " + ms_timestamp_db + ".weather(ts,f1) values(" + timestamp1 + ", 127)");
|
||||||
|
|
||||||
|
stmt.execute("drop database if exists " + us_timestamp_db);
|
||||||
|
stmt.execute("create database if not exists " + us_timestamp_db + " precision 'us'");
|
||||||
|
stmt.execute("create table " + us_timestamp_db + ".weather(ts timestamp, f1 int)");
|
||||||
|
stmt.executeUpdate("insert into " + us_timestamp_db + ".weather(ts,f1) values(" + timestamp2 + ", 127)");
|
||||||
|
stmt.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void afterClass() {
|
||||||
|
try {
|
||||||
|
if (conn != null)
|
||||||
|
conn.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,168 @@
|
||||||
|
package com.taosdata.jdbc.cases;
|
||||||
|
|
||||||
|
|
||||||
|
import com.taosdata.jdbc.TSDBDriver;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class TwoTypeTimestampPercisionInRestfulTest {
|
||||||
|
|
||||||
|
private static final String host = "127.0.0.1";
|
||||||
|
private static final String ms_timestamp_db = "ms_precision_test";
|
||||||
|
private static final String us_timestamp_db = "us_precision_test";
|
||||||
|
private static final long timestamp1 = System.currentTimeMillis();
|
||||||
|
private static final long timestamp2 = timestamp1 * 1000 + 123;
|
||||||
|
|
||||||
|
private static Connection conn1;
|
||||||
|
private static Connection conn2;
|
||||||
|
private static Connection conn3;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase1() {
|
||||||
|
try (Statement stmt = conn1.createStatement()) {
|
||||||
|
ResultSet rs = stmt.executeQuery("select last_row(ts) from " + ms_timestamp_db + ".weather");
|
||||||
|
rs.next();
|
||||||
|
long ts = rs.getTimestamp(1).getTime();
|
||||||
|
Assert.assertEquals(timestamp1, ts);
|
||||||
|
ts = rs.getLong(1);
|
||||||
|
Assert.assertEquals(timestamp1, ts);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase2() {
|
||||||
|
try (Statement stmt = conn1.createStatement()) {
|
||||||
|
ResultSet rs = stmt.executeQuery("select last_row(ts) from " + us_timestamp_db + ".weather");
|
||||||
|
rs.next();
|
||||||
|
|
||||||
|
Timestamp timestamp = rs.getTimestamp(1);
|
||||||
|
long ts = timestamp.getTime();
|
||||||
|
Assert.assertEquals(timestamp1, ts);
|
||||||
|
int nanos = timestamp.getNanos();
|
||||||
|
Assert.assertEquals(timestamp2 % 1000_000l * 1000, nanos);
|
||||||
|
|
||||||
|
ts = rs.getLong(1);
|
||||||
|
Assert.assertEquals(timestamp1, ts);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase3() {
|
||||||
|
try (Statement stmt = conn2.createStatement()) {
|
||||||
|
ResultSet rs = stmt.executeQuery("select last_row(ts) from " + ms_timestamp_db + ".weather");
|
||||||
|
rs.next();
|
||||||
|
Timestamp rsTimestamp = rs.getTimestamp(1);
|
||||||
|
long ts = rsTimestamp.getTime();
|
||||||
|
Assert.assertEquals(timestamp1, ts);
|
||||||
|
ts = rs.getLong(1);
|
||||||
|
Assert.assertEquals(timestamp1, ts);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase4() {
|
||||||
|
try (Statement stmt = conn2.createStatement()) {
|
||||||
|
ResultSet rs = stmt.executeQuery("select last_row(ts) from " + us_timestamp_db + ".weather");
|
||||||
|
rs.next();
|
||||||
|
|
||||||
|
Timestamp timestamp = rs.getTimestamp(1);
|
||||||
|
long ts = timestamp.getTime();
|
||||||
|
Assert.assertEquals(timestamp1, ts);
|
||||||
|
int nanos = timestamp.getNanos();
|
||||||
|
Assert.assertEquals(timestamp2 % 1000_000l * 1000, nanos);
|
||||||
|
|
||||||
|
ts = rs.getLong(1);
|
||||||
|
Assert.assertEquals(timestamp1, ts);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase5() {
|
||||||
|
try (Statement stmt = conn3.createStatement()) {
|
||||||
|
ResultSet rs = stmt.executeQuery("select last_row(ts) from " + ms_timestamp_db + ".weather");
|
||||||
|
rs.next();
|
||||||
|
long ts = rs.getTimestamp(1).getTime();
|
||||||
|
Assert.assertEquals(timestamp1, ts);
|
||||||
|
ts = rs.getLong(1);
|
||||||
|
Assert.assertEquals(timestamp1, ts);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase6() {
|
||||||
|
try (Statement stmt = conn3.createStatement()) {
|
||||||
|
ResultSet rs = stmt.executeQuery("select last_row(ts) from " + us_timestamp_db + ".weather");
|
||||||
|
rs.next();
|
||||||
|
|
||||||
|
Timestamp timestamp = rs.getTimestamp(1);
|
||||||
|
long ts = timestamp.getTime();
|
||||||
|
Assert.assertEquals(timestamp1, ts);
|
||||||
|
int nanos = timestamp.getNanos();
|
||||||
|
Assert.assertEquals(timestamp2 % 1000_000l * 1000, nanos);
|
||||||
|
|
||||||
|
ts = rs.getLong(1);
|
||||||
|
Assert.assertEquals(timestamp1, ts);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() throws SQLException {
|
||||||
|
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");
|
||||||
|
// properties.setProperty(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT, "TIMESTAMP");
|
||||||
|
|
||||||
|
String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata";
|
||||||
|
conn1 = DriverManager.getConnection(url, properties);
|
||||||
|
|
||||||
|
url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata×tampFormat=timestamp";
|
||||||
|
conn2 = DriverManager.getConnection(url, properties);
|
||||||
|
|
||||||
|
url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata×tampFormat=utc";
|
||||||
|
conn3 = DriverManager.getConnection(url, properties);
|
||||||
|
|
||||||
|
Statement stmt = conn1.createStatement();
|
||||||
|
stmt.execute("drop database if exists " + ms_timestamp_db);
|
||||||
|
stmt.execute("create database if not exists " + ms_timestamp_db + " precision 'ms'");
|
||||||
|
stmt.execute("create table " + ms_timestamp_db + ".weather(ts timestamp, f1 int)");
|
||||||
|
stmt.executeUpdate("insert into " + ms_timestamp_db + ".weather(ts,f1) values(" + timestamp1 + ", 127)");
|
||||||
|
|
||||||
|
stmt.execute("drop database if exists " + us_timestamp_db);
|
||||||
|
stmt.execute("create database if not exists " + us_timestamp_db + " precision 'us'");
|
||||||
|
stmt.execute("create table " + us_timestamp_db + ".weather(ts timestamp, f1 int)");
|
||||||
|
stmt.executeUpdate("insert into " + us_timestamp_db + ".weather(ts,f1) values(" + timestamp2 + ", 127)");
|
||||||
|
stmt.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void afterClass() {
|
||||||
|
try {
|
||||||
|
if (conn1 != null)
|
||||||
|
conn1.close();
|
||||||
|
if (conn2 != null)
|
||||||
|
conn2.close();
|
||||||
|
if (conn3 != null)
|
||||||
|
conn3.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,11 +6,11 @@ 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 {
|
||||||
private static final String host = "127.0.0.1";
|
private static final String host = "127.0.0.1";
|
||||||
|
// private static final String host = "master";
|
||||||
private static Connection conn;
|
private static Connection conn;
|
||||||
private static final String sql_insert = "insert into t1 values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
private static final String sql_insert = "insert into t1 values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||||
private static PreparedStatement pstmt_insert;
|
private static PreparedStatement pstmt_insert;
|
||||||
|
@ -50,6 +50,51 @@ public class RestfulPreparedStatementTest {
|
||||||
pstmt_insert.setNull(2, Types.INTEGER);
|
pstmt_insert.setNull(2, Types.INTEGER);
|
||||||
int result = pstmt_insert.executeUpdate();
|
int result = pstmt_insert.executeUpdate();
|
||||||
Assert.assertEquals(1, result);
|
Assert.assertEquals(1, result);
|
||||||
|
|
||||||
|
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
||||||
|
pstmt_insert.setNull(3, Types.BIGINT);
|
||||||
|
result = pstmt_insert.executeUpdate();
|
||||||
|
Assert.assertEquals(1, result);
|
||||||
|
|
||||||
|
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
||||||
|
pstmt_insert.setNull(4, Types.FLOAT);
|
||||||
|
result = pstmt_insert.executeUpdate();
|
||||||
|
Assert.assertEquals(1, result);
|
||||||
|
|
||||||
|
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
||||||
|
pstmt_insert.setNull(5, Types.DOUBLE);
|
||||||
|
result = pstmt_insert.executeUpdate();
|
||||||
|
Assert.assertEquals(1, result);
|
||||||
|
|
||||||
|
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
||||||
|
pstmt_insert.setNull(6, Types.SMALLINT);
|
||||||
|
result = pstmt_insert.executeUpdate();
|
||||||
|
Assert.assertEquals(1, result);
|
||||||
|
|
||||||
|
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
||||||
|
pstmt_insert.setNull(7, Types.TINYINT);
|
||||||
|
result = pstmt_insert.executeUpdate();
|
||||||
|
Assert.assertEquals(1, result);
|
||||||
|
|
||||||
|
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
||||||
|
pstmt_insert.setNull(8, Types.BOOLEAN);
|
||||||
|
result = pstmt_insert.executeUpdate();
|
||||||
|
Assert.assertEquals(1, result);
|
||||||
|
|
||||||
|
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
||||||
|
pstmt_insert.setNull(9, Types.BINARY);
|
||||||
|
result = pstmt_insert.executeUpdate();
|
||||||
|
Assert.assertEquals(1, result);
|
||||||
|
|
||||||
|
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
||||||
|
pstmt_insert.setNull(10, Types.NCHAR);
|
||||||
|
result = pstmt_insert.executeUpdate();
|
||||||
|
Assert.assertEquals(1, result);
|
||||||
|
|
||||||
|
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
||||||
|
pstmt_insert.setNull(10, Types.OTHER);
|
||||||
|
result = pstmt_insert.executeUpdate();
|
||||||
|
Assert.assertEquals(1, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -129,7 +174,7 @@ public class RestfulPreparedStatementTest {
|
||||||
Assert.assertFalse(pstmt_insert.execute());
|
Assert.assertFalse(pstmt_insert.execute());
|
||||||
}
|
}
|
||||||
|
|
||||||
class Person implements Serializable {
|
private class Person {
|
||||||
String name;
|
String name;
|
||||||
int age;
|
int age;
|
||||||
boolean sex;
|
boolean sex;
|
||||||
|
|
|
@ -160,6 +160,7 @@ public class RestfulResultSetTest {
|
||||||
@Test
|
@Test
|
||||||
public void getTime() throws SQLException {
|
public void getTime() throws SQLException {
|
||||||
Time f1 = rs.getTime("f1");
|
Time f1 = rs.getTime("f1");
|
||||||
|
Assert.assertNotNull(f1);
|
||||||
Assert.assertEquals("00:00:00", f1.toString());
|
Assert.assertEquals("00:00:00", f1.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -99,11 +99,13 @@ enum _describe_table_index {
|
||||||
TSDB_MAX_DESCRIBE_METRIC
|
TSDB_MAX_DESCRIBE_METRIC
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define COL_NOTE_LEN 128
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char field[TSDB_COL_NAME_LEN + 1];
|
char field[TSDB_COL_NAME_LEN + 1];
|
||||||
char type[16];
|
char type[16];
|
||||||
int length;
|
int length;
|
||||||
char note[128];
|
char note[COL_NOTE_LEN];
|
||||||
} SColDes;
|
} SColDes;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -523,7 +525,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
/* Parse our arguments; every option seen by parse_opt will be
|
/* Parse our arguments; every option seen by parse_opt will be
|
||||||
reflected in arguments. */
|
reflected in arguments. */
|
||||||
if (argc > 1)
|
if (argc > 2)
|
||||||
parse_args(argc, argv, &g_args);
|
parse_args(argc, argv, &g_args);
|
||||||
|
|
||||||
argp_parse(&argp, argc, argv, 0, 0, &g_args);
|
argp_parse(&argp, argc, argv, 0, 0, &g_args);
|
||||||
|
@ -1188,16 +1190,16 @@ int taosGetTableDes(char* dbName, char *table, STableDef *tableDes, TAOS* taosCo
|
||||||
case TSDB_DATA_TYPE_BINARY: {
|
case TSDB_DATA_TYPE_BINARY: {
|
||||||
memset(tableDes->cols[i].note, 0, sizeof(tableDes->cols[i].note));
|
memset(tableDes->cols[i].note, 0, sizeof(tableDes->cols[i].note));
|
||||||
tableDes->cols[i].note[0] = '\'';
|
tableDes->cols[i].note[0] = '\'';
|
||||||
char tbuf[COMMAND_SIZE];
|
char tbuf[COL_NOTE_LEN];
|
||||||
converStringToReadable((char *)row[0], length[0], tbuf, COMMAND_SIZE);
|
converStringToReadable((char *)row[0], length[0], tbuf, COL_NOTE_LEN);
|
||||||
char* pstr = stpcpy(&(tableDes->cols[i].note[1]), tbuf);
|
char* pstr = stpcpy(&(tableDes->cols[i].note[1]), tbuf);
|
||||||
*(pstr++) = '\'';
|
*(pstr++) = '\'';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TSDB_DATA_TYPE_NCHAR: {
|
case TSDB_DATA_TYPE_NCHAR: {
|
||||||
memset(tableDes->cols[i].note, 0, sizeof(tableDes->cols[i].note));
|
memset(tableDes->cols[i].note, 0, sizeof(tableDes->cols[i].note));
|
||||||
char tbuf[COMMAND_SIZE];
|
char tbuf[COL_NOTE_LEN-2]; // need reserve 2 bytes for ' '
|
||||||
convertNCharToReadable((char *)row[0], length[0], tbuf, COMMAND_SIZE);
|
convertNCharToReadable((char *)row[0], length[0], tbuf, COL_NOTE_LEN);
|
||||||
sprintf(tableDes->cols[i].note, "\'%s\'", tbuf);
|
sprintf(tableDes->cols[i].note, "\'%s\'", tbuf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -295,7 +295,7 @@ void *rpcOpen(const SRpcInit *pInit) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pRpc->pCache = rpcOpenConnCache(pRpc->sessions, rpcCloseConn, pRpc->tmrCtrl, pRpc->idleTime * 30);
|
pRpc->pCache = rpcOpenConnCache(pRpc->sessions, rpcCloseConn, pRpc->tmrCtrl, pRpc->idleTime * 20);
|
||||||
if ( pRpc->pCache == NULL ) {
|
if ( pRpc->pCache == NULL ) {
|
||||||
tError("%s failed to init connection cache", pRpc->label);
|
tError("%s failed to init connection cache", pRpc->label);
|
||||||
rpcClose(pRpc);
|
rpcClose(pRpc);
|
||||||
|
|
|
@ -539,7 +539,7 @@ static void taosNetTestServer(char *host, int32_t startPort, int32_t pkgLen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void taosNetTest(char *role, char *host, int32_t port, int32_t pkgLen) {
|
void taosNetTest(char *role, char *host, int32_t port, int32_t pkgLen) {
|
||||||
// tscEmbedded = 1;
|
tscEmbedded = 1;
|
||||||
if (host == NULL) host = tsLocalFqdn;
|
if (host == NULL) host = tsLocalFqdn;
|
||||||
if (port == 0) port = tsServerPort;
|
if (port == 0) port = tsServerPort;
|
||||||
if (pkgLen <= 10) pkgLen = 1000;
|
if (pkgLen <= 10) pkgLen = 1000;
|
||||||
|
@ -550,6 +550,7 @@ void taosNetTest(char *role, char *host, int32_t port, int32_t pkgLen) {
|
||||||
} else if (0 == strcmp("server", role)) {
|
} else if (0 == strcmp("server", role)) {
|
||||||
taosNetTestServer(host, port, pkgLen);
|
taosNetTestServer(host, port, pkgLen);
|
||||||
} else if (0 == strcmp("rpc", role)) {
|
} else if (0 == strcmp("rpc", role)) {
|
||||||
|
tscEmbedded = 0;
|
||||||
taosNetTestRpc(host, port, pkgLen);
|
taosNetTestRpc(host, port, pkgLen);
|
||||||
} else if (0 == strcmp("sync", role)) {
|
} else if (0 == strcmp("sync", role)) {
|
||||||
taosNetCheckSync(host, port);
|
taosNetCheckSync(host, port);
|
||||||
|
@ -559,5 +560,5 @@ void taosNetTest(char *role, char *host, int32_t port, int32_t pkgLen) {
|
||||||
taosNetTestStartup(host, port);
|
taosNetTestStartup(host, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
// tscEmbedded = 0;
|
tscEmbedded = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17332,3 +17332,168 @@
|
||||||
fun:PyVectorcall_Call
|
fun:PyVectorcall_Call
|
||||||
fun:_PyEval_EvalFrameDefault
|
fun:_PyEval_EvalFrameDefault
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
<insert_a_suppression_name_here>
|
||||||
|
Memcheck:Leak
|
||||||
|
match-leak-kinds: definite
|
||||||
|
fun:malloc
|
||||||
|
fun:lib_build_and_cache_attr
|
||||||
|
fun:lib_getattr
|
||||||
|
fun:_PyEval_EvalFrameDefault
|
||||||
|
fun:_PyFunction_Vectorcall
|
||||||
|
fun:_PyEval_EvalFrameDefault
|
||||||
|
fun:_PyEval_EvalCodeWithName
|
||||||
|
fun:PyEval_EvalCode
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
fun:PyVectorcall_Call
|
||||||
|
fun:_PyEval_EvalFrameDefault
|
||||||
|
}
|
||||||
|
{
|
||||||
|
<insert_a_suppression_name_here>
|
||||||
|
Memcheck:Leak
|
||||||
|
match-leak-kinds: definite
|
||||||
|
fun:malloc
|
||||||
|
fun:lib_build_and_cache_attr
|
||||||
|
fun:lib_getattr
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
fun:_PyEval_EvalFrameDefault
|
||||||
|
fun:_PyFunction_Vectorcall
|
||||||
|
fun:_PyEval_EvalFrameDefault
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
fun:_PyEval_EvalFrameDefault
|
||||||
|
fun:PyEval_EvalCode
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
fun:_PyEval_EvalFrameDefault
|
||||||
|
fun:_PyEval_EvalCodeWithName
|
||||||
|
}
|
||||||
|
{
|
||||||
|
<insert_a_suppression_name_here>
|
||||||
|
Memcheck:Leak
|
||||||
|
match-leak-kinds: definite
|
||||||
|
fun:malloc
|
||||||
|
fun:_my_Py_InitModule
|
||||||
|
fun:lib_getattr
|
||||||
|
fun:b_init_cffi_1_0_external_module
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
fun:PyObject_CallMethod
|
||||||
|
fun:_cffi_init
|
||||||
|
fun:PyInit__bcrypt
|
||||||
|
fun:_PyImport_LoadDynamicModuleWithSpec
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
fun:PyVectorcall_Call
|
||||||
|
fun:_PyEval_EvalFrameDefault
|
||||||
|
}
|
||||||
|
{
|
||||||
|
<insert_a_suppression_name_here>
|
||||||
|
Memcheck:Leak
|
||||||
|
match-leak-kinds: definite
|
||||||
|
fun:malloc
|
||||||
|
fun:_PyObject_GC_New
|
||||||
|
fun:lib_getattr
|
||||||
|
fun:ffi_internal_new
|
||||||
|
fun:b_init_cffi_1_0_external_module
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
fun:PyObject_CallMethod
|
||||||
|
fun:_cffi_init
|
||||||
|
fun:PyInit__bcrypt
|
||||||
|
fun:_PyImport_LoadDynamicModuleWithSpec
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
fun:PyVectorcall_Call
|
||||||
|
}
|
||||||
|
{
|
||||||
|
<insert_a_suppression_name_here>
|
||||||
|
Memcheck:Leak
|
||||||
|
match-leak-kinds: definite
|
||||||
|
fun:malloc
|
||||||
|
fun:lib_build_cpython_func.isra.87
|
||||||
|
fun:lib_build_and_cache_attr
|
||||||
|
fun:lib_getattr
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
fun:_PyEval_EvalFrameDefault
|
||||||
|
fun:_PyFunction_Vectorcall
|
||||||
|
fun:_PyEval_EvalFrameDefault
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
fun:_PyEval_EvalFrameDefault
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
fun:_PyEval_EvalFrameDefault
|
||||||
|
}
|
||||||
|
{
|
||||||
|
<insert_a_suppression_name_here>
|
||||||
|
Memcheck:Leak
|
||||||
|
match-leak-kinds: definite
|
||||||
|
fun:malloc
|
||||||
|
fun:lib_build_and_cache_attr
|
||||||
|
fun:lib_getattr
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
fun:_PyEval_EvalFrameDefault
|
||||||
|
fun:_PyFunction_Vectorcall
|
||||||
|
fun:_PyEval_EvalFrameDefault
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
fun:_PyEval_EvalFrameDefault
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
fun:_PyEval_EvalFrameDefault
|
||||||
|
fun:_PyEval_EvalCodeWithName
|
||||||
|
}
|
||||||
|
{
|
||||||
|
<insert_a_suppression_name_here>
|
||||||
|
Memcheck:Leak
|
||||||
|
match-leak-kinds: definite
|
||||||
|
fun:malloc
|
||||||
|
fun:_my_Py_InitModule
|
||||||
|
fun:b_init_cffi_1_0_external_module
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
fun:PyObject_CallMethod
|
||||||
|
fun:_cffi_init
|
||||||
|
fun:PyInit__bcrypt
|
||||||
|
fun:_PyImport_LoadDynamicModuleWithSpec
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
fun:PyVectorcall_Call
|
||||||
|
fun:_PyEval_EvalFrameDefault
|
||||||
|
}
|
||||||
|
{
|
||||||
|
<insert_a_suppression_name_here>
|
||||||
|
Memcheck:Leak
|
||||||
|
match-leak-kinds: definite
|
||||||
|
fun:malloc
|
||||||
|
fun:_my_Py_InitModule
|
||||||
|
fun:b_init_cffi_1_0_external_module
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
fun:PyObject_CallMethod
|
||||||
|
fun:PyInit__openssl
|
||||||
|
fun:_PyImport_LoadDynamicModuleWithSpec
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
fun:PyVectorcall_Call
|
||||||
|
fun:_PyEval_EvalFrameDefault
|
||||||
|
}
|
||||||
|
{
|
||||||
|
<insert_a_suppression_name_here>
|
||||||
|
Memcheck:Leak
|
||||||
|
match-leak-kinds: definite
|
||||||
|
fun:malloc
|
||||||
|
fun:_PyObject_GC_New
|
||||||
|
fun:ffi_internal_new
|
||||||
|
fun:b_init_cffi_1_0_external_module
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
fun:PyObject_CallMethod
|
||||||
|
fun:_cffi_init
|
||||||
|
fun:PyInit__bcrypt
|
||||||
|
fun:_PyImport_LoadDynamicModuleWithSpec
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
obj:/usr/bin/python3.8
|
||||||
|
fun:PyVectorcall_Call
|
||||||
|
}
|
|
@ -23,6 +23,7 @@ python3 ./test.py -f insert/insertIntoTwoTables.py
|
||||||
python3 ./test.py -f insert/before_1970.py
|
python3 ./test.py -f insert/before_1970.py
|
||||||
python3 bug2265.py
|
python3 bug2265.py
|
||||||
python3 ./test.py -f insert/bug3654.py
|
python3 ./test.py -f insert/bug3654.py
|
||||||
|
python3 ./test.py -f insert/insertDynamicColBeforeVal.py
|
||||||
|
|
||||||
#table
|
#table
|
||||||
python3 ./test.py -f table/alter_wal0.py
|
python3 ./test.py -f table/alter_wal0.py
|
||||||
|
@ -225,6 +226,7 @@ python3 ./test.py -f query/queryStddevWithGroupby.py
|
||||||
python3 ./test.py -f query/querySecondtscolumnTowherenow.py
|
python3 ./test.py -f query/querySecondtscolumnTowherenow.py
|
||||||
python3 ./test.py -f query/queryFilterTswithDateUnit.py
|
python3 ./test.py -f query/queryFilterTswithDateUnit.py
|
||||||
python3 ./test.py -f query/queryTscomputWithNow.py
|
python3 ./test.py -f query/queryTscomputWithNow.py
|
||||||
|
python3 ./test.py -f query/computeErrorinWhere.py
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,136 @@
|
||||||
|
###################################################################
|
||||||
|
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# This file is proprietary and confidential to TAOS Technologies.
|
||||||
|
# No part of this file may be reproduced, stored, transmitted,
|
||||||
|
# disclosed or used in any form or by any means other than as
|
||||||
|
# expressly provided by the written permission from Jianhui Tao
|
||||||
|
#
|
||||||
|
###################################################################
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from util.log import *
|
||||||
|
from util.cases import *
|
||||||
|
from util.sql import *
|
||||||
|
from util.dnodes import *
|
||||||
|
|
||||||
|
|
||||||
|
class TDTestCase:
|
||||||
|
def init(self, conn, logSql):
|
||||||
|
tdLog.debug("start to execute %s" % __file__)
|
||||||
|
tdSql.init(conn.cursor(), logSql)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
tdSql.prepare()
|
||||||
|
tdSql.execute("drop database if exists db")
|
||||||
|
tdSql.execute("create database if not exists db keep 3650")
|
||||||
|
tdSql.execute("use db")
|
||||||
|
|
||||||
|
tdLog.printNoPrefix("==========step1:create table")
|
||||||
|
tdSql.execute(
|
||||||
|
"create table stb1 (ts timestamp, c11 int, c12 float ) TAGS(t11 int, t12 int )"
|
||||||
|
)
|
||||||
|
|
||||||
|
tdLog.printNoPrefix("==========step2:insert data with new syntax")
|
||||||
|
tdSql.execute(
|
||||||
|
"insert into t1 using stb1(t11, t12) tags(11, 12) (ts, c11, c12) values (now, 10, 20)"
|
||||||
|
)
|
||||||
|
|
||||||
|
# case for tag-value
|
||||||
|
tdSql.execute(
|
||||||
|
"insert into t2 using stb1(t11) tags(21) (ts, c11, c12) values (now-1m, 11, 21)"
|
||||||
|
)
|
||||||
|
tdSql.execute(
|
||||||
|
"insert into t3 using stb1 tags(31, 32) (ts, c11, c12) values (now-2m, 12, 22)"
|
||||||
|
)
|
||||||
|
tdSql.error(
|
||||||
|
"insert into t4 using stb1(t11, t12) (ts, c11, c12) values (now-3m, 13, 23)"
|
||||||
|
)
|
||||||
|
tdSql.error(
|
||||||
|
"insert into t5 using stb1(t11, t12) tags() (ts, c11, c12) values (now-4m, 14, 24)"
|
||||||
|
)
|
||||||
|
tdSql.error(
|
||||||
|
"insert into t6 using stb1(t11, t12) tags(41) (ts, c11, c12) values (now-5m, 15, 25)"
|
||||||
|
)
|
||||||
|
tdSql.error(
|
||||||
|
"insert into t7 using stb1(t12) tags(51, 52) (ts, c11, c12) values (now-6m, 16, 26)"
|
||||||
|
)
|
||||||
|
tdSql.execute(
|
||||||
|
"insert into t8 using stb1(t11, t12) tags('61', 62) (ts, c11, c12) values (now-7m, 17, 27)"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# case for col-value
|
||||||
|
tdSql.execute(
|
||||||
|
"insert into t9 using stb1(t11, t12) tags(71, 72) values (now-8m, 18, 28)"
|
||||||
|
)
|
||||||
|
tdSql.error(
|
||||||
|
"insert into t10 using stb1(t11, t12) tags(81, 82) (ts, c11, c12) values ()"
|
||||||
|
)
|
||||||
|
tdSql.error(
|
||||||
|
"insert into t11 using stb1(t11, t12) tags(91, 92) (ts, c11, c12) "
|
||||||
|
)
|
||||||
|
tdSql.error(
|
||||||
|
"insert into t12 using stb1(t11, t12) tags(101, 102) values (now-9m, 19)"
|
||||||
|
)
|
||||||
|
tdSql.error(
|
||||||
|
"insert into t13 using stb1(t11, t12) tags(111, 112) (ts, c11) values (now-10m, 110, 210)"
|
||||||
|
)
|
||||||
|
tdSql.error(
|
||||||
|
"insert into t14 using stb1(t11, t12) tags(121, 122) (ts, c11, c12) values (now-11m, 111)"
|
||||||
|
)
|
||||||
|
tdSql.execute(
|
||||||
|
"insert into t15 using stb1(t11, t12) tags(131, 132) (ts, c11, c12) values (now-12m, NULL , 212)"
|
||||||
|
)
|
||||||
|
tdSql.execute(
|
||||||
|
"insert into t16 using stb1(t11, t12) tags(141, 142) (ts, c11, c12) values (now-13m, 'NULL', 213)"
|
||||||
|
)
|
||||||
|
tdSql.error(
|
||||||
|
"insert into t17 using stb1(t11, t12) tags(151, 152) (ts, c11, c12) values (now-14m, Nan, 214)"
|
||||||
|
)
|
||||||
|
tdSql.error(
|
||||||
|
"insert into t18 using stb1(t11, t12) tags(161, 162) (ts, c11, c12) values (now-15m, 'NaN', 215)"
|
||||||
|
)
|
||||||
|
tdSql.execute(
|
||||||
|
"insert into t19 using stb1(t11, t12) tags(171, 172) (ts, c11) values (now-16m, 216)"
|
||||||
|
)
|
||||||
|
tdSql.error(
|
||||||
|
"insert into t20 using stb1(t11, t12) tags(181, 182) (c11, c12) values (117, 217)"
|
||||||
|
)
|
||||||
|
|
||||||
|
# multi-col_value
|
||||||
|
tdSql.execute(
|
||||||
|
"insert into t21 using stb1(t11, t12) tags(191, 192) (ts, c11, c12) values (now-17m, 118, 218)(now-18m, 119, 219)"
|
||||||
|
)
|
||||||
|
tdSql.execute(
|
||||||
|
"insert into t22 using stb1(t11, t12) tags(201, 202) values (now-19m, 120, 220)(now-19m, 121, 221)"
|
||||||
|
)
|
||||||
|
tdSql.error(
|
||||||
|
"insert into t23 using stb1(t11, t12) tags(211, 212) values (now-20m, 122, 222) (ts, c11, c12) values (now-21m, 123, 223)"
|
||||||
|
)
|
||||||
|
tdSql.error(
|
||||||
|
"insert into t24 using stb1(t11, t12) tags(221, 222) (ts, c11, c12) values (now-22m, 124, 224) (ts, c11, c12) values (now-23m, 125, 225)"
|
||||||
|
)
|
||||||
|
tdSql.execute(
|
||||||
|
"insert into t25 (ts, c11, c12) using stb1(t11, t12) tags(231, 232) values (now-24m, 126, 226)(now-25m, 127, 227)"
|
||||||
|
)
|
||||||
|
tdSql.error(
|
||||||
|
"insert into t26 (ts, c11, c12) values (now-24m, 128, 228)(now-25m, 129, 229) using stb1(t11, t12) tags(241, 242) "
|
||||||
|
)
|
||||||
|
tdSql.error(
|
||||||
|
"insert into t27 (ts, c11, c12) values (now-24m, 130, 230) using stb1(t11, t12) tags(251, 252) "
|
||||||
|
)
|
||||||
|
|
||||||
|
tdSql.query("show tables")
|
||||||
|
tdSql.checkRows(21)
|
||||||
|
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
tdSql.close()
|
||||||
|
tdLog.success("%s successfully executed" % __file__)
|
||||||
|
|
||||||
|
tdCases.addWindows(__file__, TDTestCase())
|
||||||
|
tdCases.addLinux(__file__, TDTestCase())
|
|
@ -0,0 +1,136 @@
|
||||||
|
# No part of this file may be reproduced, stored, transmitted,
|
||||||
|
# disclosed or used in any form or by any means other than as
|
||||||
|
# expressly provided by the written permission from Jianhui Tao
|
||||||
|
#
|
||||||
|
###################################################################
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from util.log import *
|
||||||
|
from util.cases import *
|
||||||
|
from util.sql import *
|
||||||
|
from util.dnodes import *
|
||||||
|
|
||||||
|
|
||||||
|
class TDTestCase:
|
||||||
|
def init(self, conn, logSql):
|
||||||
|
tdLog.debug(f"start to execute {__file__}")
|
||||||
|
tdSql.init(conn.cursor(), logSql)
|
||||||
|
|
||||||
|
def insertnow(self):
|
||||||
|
tdSql.execute("drop database if exists dbcom")
|
||||||
|
tdSql.execute("create database if not exists dbcom keep 36500")
|
||||||
|
tdSql.execute("use dbcom")
|
||||||
|
|
||||||
|
tdSql.execute(
|
||||||
|
"create table stbcom (ts timestamp, c1 int, c2 tinyint, c3 smallint, c4 bigint, c5 float, c6 double) TAGS(t1 int)"
|
||||||
|
)
|
||||||
|
tdSql.execute("create table tcom1 using stbcom tags(1)")
|
||||||
|
|
||||||
|
# timestamp list:
|
||||||
|
# 0 -> "1970-01-01 08:00:00" | -28800000 -> "1970-01-01 00:00:00" | -946800000000 -> "1940-01-01 00:00:00"
|
||||||
|
# -631180800000 -> "1950-01-01 00:00:00"
|
||||||
|
|
||||||
|
tdSql.execute("insert into tcom1 values (now-1d, 1, 11, 21, 31, 41.0, 51.1)")
|
||||||
|
tdSql.execute("insert into tcom1 values (now-2d, 2, 12, 22, 32, 42.0, 52.1)")
|
||||||
|
tdSql.execute("insert into tcom1 values (now-3d, 3, 13, 23, 33, 43.0, 53.1)")
|
||||||
|
tdSql.execute("insert into tcom1 values (now-4d, 4, 14, 24, 34, 44.0, 54.1)")
|
||||||
|
|
||||||
|
def querycom(self):
|
||||||
|
tdSql.query("select * from tcom1 where c1=2-1")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.query("select * from tcom1 where c1=-1+2")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.query("select * from tcom1 where c1=1.0*1.0")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.query("select * from tcom1 where c1=1.0/1.0")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.query("select * from tcom1 where c1>1.0/1.0")
|
||||||
|
tdSql.checkRows(3)
|
||||||
|
tdSql.query("select * from tcom1 where c1<1.0/1.0")
|
||||||
|
tdSql.checkRows(0)
|
||||||
|
|
||||||
|
tdSql.query("select * from tcom1 where c2=12-1")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.query("select * from tcom1 where c2=-1+12")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.query("select * from tcom1 where c2=11.0*1.0")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.query("select * from tcom1 where c2=11.0/1.0")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.query("select * from tcom1 where c2>11.0/1.0")
|
||||||
|
tdSql.checkRows(3)
|
||||||
|
tdSql.query("select * from tcom1 where c2<11.0/1.0")
|
||||||
|
tdSql.checkRows(0)
|
||||||
|
|
||||||
|
tdSql.query("select * from tcom1 where c3=22-1")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.query("select * from tcom1 where c3=-1+22")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.query("select * from tcom1 where c3=21.0*1.0")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.query("select * from tcom1 where c3=21.0/1.0")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.query("select * from tcom1 where c3>21.0/1.0")
|
||||||
|
tdSql.checkRows(3)
|
||||||
|
tdSql.query("select * from tcom1 where c3<21.0/1.0")
|
||||||
|
tdSql.checkRows(0)
|
||||||
|
|
||||||
|
tdSql.query("select * from tcom1 where c4=32-1")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.query("select * from tcom1 where c4=-1+32")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.query("select * from tcom1 where c4=31.0*1.0")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.query("select * from tcom1 where c4=31.0/1.0")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.query("select * from tcom1 where c4>31.0/1.0")
|
||||||
|
tdSql.checkRows(3)
|
||||||
|
tdSql.query("select * from tcom1 where c4<31.0/1.0")
|
||||||
|
tdSql.checkRows(0)
|
||||||
|
|
||||||
|
tdSql.query("select * from tcom1 where c5=42-1")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.query("select * from tcom1 where c5=-1+42")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.query("select * from tcom1 where c5=41*1")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.query("select * from tcom1 where c5=41/1")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.query("select * from tcom1 where c5>41/1")
|
||||||
|
tdSql.checkRows(3)
|
||||||
|
tdSql.query("select * from tcom1 where c5<41/1")
|
||||||
|
tdSql.checkRows(0)
|
||||||
|
tdSql.query("select * from tcom1 where c5=42.000000008-1.0000000099999999999999")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.query("select * from tcom1 where c5=42.0008-1.0000099999999999999")
|
||||||
|
tdSql.checkRows(0)
|
||||||
|
|
||||||
|
tdSql.query("select * from tcom1 where c6=52-0.9")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.query("select * from tcom1 where c6=-0.9+52")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.query("select * from tcom1 where c6=51.1*1")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.query("select * from tcom1 where c6=51.1/1")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.query("select * from tcom1 where c6>51.1/1")
|
||||||
|
tdSql.checkRows(3)
|
||||||
|
tdSql.query("select * from tcom1 where c6<51.1/1")
|
||||||
|
tdSql.checkRows(0)
|
||||||
|
tdSql.query("select * from tcom1 where c6=52.100000000000008-1.000000000000009")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.insertnow()
|
||||||
|
self.querycom()
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
tdSql.close()
|
||||||
|
tdLog.success(f"{__file__} successfully executed")
|
||||||
|
|
||||||
|
|
||||||
|
tdCases.addWindows(__file__, TDTestCase())
|
||||||
|
tdCases.addLinux(__file__, TDTestCase())
|
|
@ -2,36 +2,36 @@
|
||||||
ulimit -c unlimited
|
ulimit -c unlimited
|
||||||
|
|
||||||
# insert
|
# insert
|
||||||
python3 ./test.py $1 -f insert/basic.py
|
python3.8 ./test.py $1 -f insert/basic.py
|
||||||
python3 ./test.py $1 -s && sleep 1
|
python3.8 ./test.py $1 -s && sleep 1
|
||||||
python3 ./test.py $1 -f insert/bigint.py
|
python3.8 ./test.py $1 -f insert/bigint.py
|
||||||
python3 ./test.py $1 -s && sleep 1
|
python3.8 ./test.py $1 -s && sleep 1
|
||||||
python3 ./test.py $1 -f insert/nchar.py
|
python3.8 ./test.py $1 -f insert/nchar.py
|
||||||
python3 ./test.py $1 -s && sleep 1
|
python3.8 ./test.py $1 -s && sleep 1
|
||||||
python3 ./test.py $1 -f insert/multi.py
|
python3.8 ./test.py $1 -f insert/multi.py
|
||||||
python3 ./test.py $1 -s && sleep 1
|
python3.8 ./test.py $1 -s && sleep 1
|
||||||
|
|
||||||
# table
|
# table
|
||||||
python3 ./test.py $1 -f table/column_name.py
|
python3.8 ./test.py $1 -f table/column_name.py
|
||||||
python3 ./test.py $1 -s && sleep 1
|
python3.8 ./test.py $1 -s && sleep 1
|
||||||
python3 ./test.py $1 -f table/column_num.py
|
python3.8 ./test.py $1 -f table/column_num.py
|
||||||
python3 ./test.py $1 -s && sleep 1
|
python3.8 ./test.py $1 -s && sleep 1
|
||||||
python3 ./test.py $1 -f table/db_table.py
|
python3.8 ./test.py $1 -f table/db_table.py
|
||||||
python3 ./test.py $1 -s && sleep 1
|
python3.8 ./test.py $1 -s && sleep 1
|
||||||
|
|
||||||
# import
|
# import
|
||||||
python3 ./test.py $1 -f import_merge/importDataLastSub.py
|
python3.8 ./test.py $1 -f import_merge/importDataLastSub.py
|
||||||
python3 ./test.py $1 -s && sleep 1
|
python3.8 ./test.py $1 -s && sleep 1
|
||||||
|
|
||||||
#tag
|
#tag
|
||||||
python3 ./test.py $1 -f tag_lite/filter.py
|
python3.8 ./test.py $1 -f tag_lite/filter.py
|
||||||
python3 ./test.py $1 -s && sleep 1
|
python3.8 ./test.py $1 -s && sleep 1
|
||||||
|
|
||||||
#query
|
#query
|
||||||
python3 ./test.py $1 -f query/filter.py
|
python3.8 ./test.py $1 -f query/filter.py
|
||||||
python3 ./test.py $1 -s && sleep 1
|
python3.8 ./test.py $1 -s && sleep 1
|
||||||
|
|
||||||
# client
|
# client
|
||||||
python3 ./test.py $1 -f client/client.py
|
python3.8 ./test.py $1 -f client/client.py
|
||||||
python3 ./test.py $1 -s && sleep 1
|
python3.8 ./test.py $1 -s && sleep 1
|
||||||
|
|
||||||
|
|
|
@ -136,6 +136,11 @@ class TDSql:
|
||||||
def checkData(self, row, col, data):
|
def checkData(self, row, col, data):
|
||||||
self.checkRowCol(row, col)
|
self.checkRowCol(row, col)
|
||||||
if self.queryResult[row][col] != data:
|
if self.queryResult[row][col] != data:
|
||||||
|
if self.cursor.istype(col, "TIMESTAMP") and self.queryResult[row][col] == datetime.datetime.fromisoformat(data):
|
||||||
|
tdLog.info("sql:%s, row:%d col:%d data:%s == expect:%s" %
|
||||||
|
(self.sql, row, col, self.queryResult[row][col], data))
|
||||||
|
return
|
||||||
|
|
||||||
if str(self.queryResult[row][col]) == str(data):
|
if str(self.queryResult[row][col]) == str(data):
|
||||||
tdLog.info("sql:%s, row:%d col:%d data:%s == expect:%s" %
|
tdLog.info("sql:%s, row:%d col:%d data:%s == expect:%s" %
|
||||||
(self.sql, row, col, self.queryResult[row][col], data))
|
(self.sql, row, col, self.queryResult[row][col], data))
|
||||||
|
|
|
@ -358,6 +358,13 @@ if $data00 != 0.300000000 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
|
||||||
|
print =============================> td-3996
|
||||||
|
sql select 'abc' as res from t1 where f1 < 0
|
||||||
|
if $rows != 0 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
|
||||||
print ======================udc with normal column group by
|
print ======================udc with normal column group by
|
||||||
|
|
||||||
sql_error select from t1
|
sql_error select from t1
|
||||||
|
|
|
@ -139,6 +139,34 @@ if $data10 != 1 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
|
||||||
|
sql select 'ab' as options from union_tb1 limit 1 union all select 'dd' as options from union_tb0 limit 1;
|
||||||
|
if $rows != 2 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data00 != @ab@ then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data10 != @dd@ then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
|
||||||
|
sql select 'ab' as options from union_tb1 limit 1 union all select '1234567' as options from union_tb0 limit 1;
|
||||||
|
if $rows != 2 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data00 != @ab@ then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data10 != @1234567@ then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
|
||||||
# mixed order
|
# mixed order
|
||||||
sql select ts, c1 from union_tb1 order by ts asc limit 10 union all select ts, c1 from union_tb0 order by ts desc limit 2 union all select ts, c1 from union_tb2 order by ts asc limit 10
|
sql select ts, c1 from union_tb1 order by ts asc limit 10 union all select ts, c1 from union_tb0 order by ts desc limit 2 union all select ts, c1 from union_tb2 order by ts asc limit 10
|
||||||
if $rows != 22 then
|
if $rows != 22 then
|
||||||
|
@ -421,6 +449,16 @@ if $data10 != @union_db0@ then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
|
||||||
|
sql select 'aaa' as option from union_tb1 where c1 < 0 limit 1 union all select 'bbb' as option from union_tb0 limit 1
|
||||||
|
if $rows != 1 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data00 != @bbb@ then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
|
||||||
sql_error show tables union all show tables
|
sql_error show tables union all show tables
|
||||||
sql_error show stables union all show stables
|
sql_error show stables union all show stables
|
||||||
sql_error show databases union all show databases
|
sql_error show databases union all show databases
|
||||||
|
|
Loading…
Reference in New Issue