提交 0610e32a 编写于 作者: S Shengliang Guan

Merge branch 'develop' into hotfix/TD-3574

......@@ -171,6 +171,8 @@ matrix:
- build-essential
- cmake
- binutils-2.26
- unixodbc
- unixodbc-dev
env:
- DESC="trusty/gcc-4.8/bintuils-2.26 build"
......@@ -198,6 +200,8 @@ matrix:
packages:
- build-essential
- cmake
- unixodbc
- unixodbc-dev
before_script:
- export TZ=Asia/Harbin
......@@ -252,6 +256,8 @@ matrix:
packages:
- build-essential
- cmake
- unixodbc
- unixodbc-dev
env:
- DESC="arm64 xenial build"
......@@ -280,6 +286,7 @@ matrix:
addons:
homebrew:
- cmake
- unixodbc
script:
- cd ${TRAVIS_BUILD_DIR}
......
......@@ -17,6 +17,7 @@ SET(TD_MQTT FALSE)
SET(TD_TSDB_PLUGINS FALSE)
SET(TD_STORAGE FALSE)
SET(TD_TOPIC FALSE)
SET(TD_MODULE FALSE)
SET(TD_COVER FALSE)
SET(TD_MEM_CHECK FALSE)
......
......@@ -6,6 +6,7 @@ node {
}
def skipstage=0
def abortPreviousBuilds() {
def currentJobName = env.JOB_NAME
def currentBuildNumber = env.BUILD_NUMBER.toInteger()
......@@ -24,7 +25,7 @@ def abortPreviousBuilds() {
build.doKill() //doTerm(),doKill(),doTerm()
}
}
//abort previous build
// abort previous build
abortPreviousBuilds()
def abort_previous(){
def buildNumber = env.BUILD_NUMBER as int
......@@ -32,19 +33,20 @@ def abort_previous(){
milestone(buildNumber)
}
def pre_test(){
sh '''
sudo rmtaos || echo "taosd has not installed"
'''
sh '''
killall -9 taosd ||echo "no taosd running"
killall -9 gdb || echo "no gdb running"
cd ${WKC}
git checkout develop
git reset --hard HEAD~10 >/dev/null
git pull >/dev/null
git fetch origin +refs/pull/${CHANGE_ID}/merge
git checkout -qf FETCH_HEAD
git --no-pager diff --name-only FETCH_HEAD $(git merge-base FETCH_HEAD develop)|grep -v -E '.*md|//src//connector|Jenkinsfile'
find ${WKC}/tests/pytest -name \'*\'.sql -exec rm -rf {} \\;
cd ${WK}
git reset --hard HEAD~10
......@@ -79,6 +81,10 @@ pipeline {
changeRequest()
}
steps {
script{
abort_previous()
abortPreviousBuilds()
}
sh'''
cp -r ${WORKSPACE} ${WORKSPACE}.tes
cd ${WORKSPACE}.tes
......@@ -179,6 +185,14 @@ pipeline {
rm -rf /var/log/taos/*
./handle_crash_gen_val_log.sh
'''
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
sh '''
cd ${WKC}/tests/pytest
rm -rf /var/lib/taos/*
rm -rf /var/log/taos/*
./handle_taosd_val_log.sh
'''
}
timeout(time: 45, unit: 'MINUTES'){
sh '''
date
......@@ -209,6 +223,11 @@ pipeline {
cd ${WKC}/tests
./test-all.sh b3fq
date'''
sh '''
date
cd ${WKC}/tests
./test-all.sh full example
date'''
}
}
}
......@@ -266,7 +285,7 @@ pipeline {
date
cd ${WKC}/tests
./test-all.sh b7fq
date'''
date'''
}
}
}
......
......@@ -258,10 +258,16 @@ TDengine 社区生态中也有一些非常友好的第三方连接器,可以
TDengine 的测试框架和所有测试例全部开源。
点击[这里](tests/How-To-Run-Test-And-How-To-Add-New-Test-Case.md),了解如何运行测试例和添加新的测试例。
点击 [这里](tests/How-To-Run-Test-And-How-To-Add-New-Test-Case.md),了解如何运行测试例和添加新的测试例。
# 成为社区贡献者
点击[这里](https://www.taosdata.com/cn/contributor/),了解如何成为 TDengine 的贡献者。
#加入技术交流群
TDengine官方社群「物联网大数据群」对外开放,欢迎您加入讨论。搜索微信号 "tdengine",加小T为好友,即可入群。
点击 [这里](https://www.taosdata.com/cn/contributor/),了解如何成为 TDengine 的贡献者。
# 加入技术交流群
TDengine 官方社群「物联网大数据群」对外开放,欢迎您加入讨论。搜索微信号 "tdengine",加小T为好友,即可入群。
# [谁在使用TDengine](https://github.com/taosdata/TDengine/issues/2432)
欢迎所有 TDengine 用户及贡献者在 [这里](https://github.com/taosdata/TDengine/issues/2432) 分享您在当前工作中开发/使用 TDengine 的故事。
......@@ -31,7 +31,7 @@ For user manual, system design and architecture, engineering blogs, refer to [TD
# Building
At the moment, TDengine only supports building and running on Linux systems. You can choose to [install from packages](https://www.taosdata.com/en/getting-started/#Install-from-Package) or from the source code. This quick guide is for installation from the source only.
To build TDengine, use [CMake](https://cmake.org/) 3.5 or higher versions in the project directory.
To build TDengine, use [CMake](https://cmake.org/) 2.8.12.x or higher versions in the project directory.
## Install tools
......@@ -250,3 +250,6 @@ Please follow the [contribution guidelines](CONTRIBUTING.md) to contribute to th
Add WeChat “tdengine” to join the group,you can communicate with other users.
# [User List](https://github.com/taosdata/TDengine/issues/2432)
If you are using TDengine and feel it helps or you'd like to do some contributions, please add your company to [user list](https://github.com/taosdata/TDengine/issues/2432) and let us know your needs.
......@@ -29,6 +29,10 @@ IF (TD_TOPIC)
ADD_DEFINITIONS(-D_TOPIC)
ENDIF ()
IF (TD_MODULE)
ADD_DEFINITIONS(-D_MODULE)
ENDIF ()
IF (TD_GODLL)
ADD_DEFINITIONS(-D_TD_GO_DLL_)
ENDIF ()
......
......@@ -17,6 +17,14 @@ ELSEIF (${TOPIC} MATCHES "false")
MESSAGE(STATUS "Build without topic plugins")
ENDIF ()
IF (${TD_MODULE} MATCHES "true")
SET(TD_MODULE TRUE)
MESSAGE(STATUS "Build with module plugins")
ELSEIF (${TOPIC} MATCHES "false")
SET(TD_MODULE FALSE)
MESSAGE(STATUS "Build without module plugins")
ENDIF ()
IF (${COVER} MATCHES "true")
SET(TD_COVER TRUE)
MESSAGE(STATUS "Build with test coverage")
......
......@@ -32,7 +32,7 @@ ELSEIF (TD_WINDOWS)
#INSTALL(TARGETS taos RUNTIME DESTINATION driver)
#INSTALL(TARGETS shell RUNTIME DESTINATION .)
IF (TD_MVN_INSTALLED)
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.22-dist.jar DESTINATION connector/jdbc)
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.24-dist.jar DESTINATION connector/jdbc)
ENDIF ()
ELSEIF (TD_DARWIN)
SET(TD_MAKE_INSTALL_SH "${TD_COMMUNITY_DIR}/packaging/tools/make_install.sh")
......
......@@ -120,7 +120,7 @@ TDengine是一个高效的存储、查询、分析时序大数据的平台,专
* [TDengine性能对比测试工具](https://www.taosdata.com/blog/2020/01/18/1166.html)
* [IDEA数据库管理工具可视化使用TDengine](https://www.taosdata.com/blog/2020/08/27/1767.html)
* [基于eletron开发的跨平台TDengine图形化管理工具](https://github.com/skye0207/TDengineGUI)
* [DataX,支持TDengine的离线数据采集/同步工具](https://github.com/alibaba/DataX)
* [DataX,支持TDengine的离线数据采集/同步工具](https://github.com/wgzhao/DataX)(文档:[读取插件](https://github.com/wgzhao/DataX/blob/master/docs/src/main/sphinx/reader/tdenginereader.md)[写入插件](https://github.com/wgzhao/DataX/blob/master/docs/src/main/sphinx/writer/tdenginewriter.md)
## TDengine与其他数据库的对比测试
......
......@@ -179,18 +179,18 @@ taos> select avg(f1), max(f2), min(f3) from test.t10 interval(10s);
### TDengine服务器支持的平台列表
| | **CentOS** **6/7/8** | **Ubuntu** **16/18/20** | **Other Linux** | **统信****UOS** | **银河****/****中标麒麟** | **凝思** **V60/V80** |
| | **CentOS 6/7/8** | **Ubuntu 16/18/20** | **Other Linux** | **统信 UOS** | **银河/中标麒麟** | **凝思 V60/V80** |
| -------------- | --------------------- | ------------------------ | --------------- | --------------- | ------------------------- | --------------------- |
| X64 | ● | ● | | ○ | ● | ● |
| 树莓派ARM32 | | ● | ● | | | |
| 龙芯MIPS64 | | | ● | | | |
| 鲲鹏 ARM64 | | ○ | ○ | | ● | |
| 申威 Alpha64 | | | ○ | ● | | |
| 飞腾ARM64 | | ○优麒麟 | | | | |
| 海光X64 | ● | ● | ● | ○ | ● | ● |
| 瑞芯微ARM64/32 | | | ○ | | | |
| 全志ARM64/32 | | | ○ | | | |
| 炬力ARM64/32 | | | ○ | | | |
| 树莓派 ARM32 | | ● | ● | | | |
| 龙芯 MIPS64 | | | ● | | | |
| 鲲鹏 ARM64 | | ○ | ○ | | ● | |
| 申威 Alpha64 | | | ○ | ● | | |
| 飞腾 ARM64 | | ○ 优麒麟 | | | | |
| 海光 X64 | ● | ● | ● | ○ | ● | ● |
| 瑞芯微 ARM64/32 | | | ○ | | | |
| 全志 ARM64/32 | | | ○ | | | |
| 炬力 ARM64/32 | | | ○ | | | |
| TI ARM32 | | | ○ | | | |
注: ● 表示经过官方测试验证, ○ 表示非官方测试验证。
......@@ -203,7 +203,7 @@ taos> select avg(f1), max(f2), min(f3) from test.t10 interval(10s);
对照矩阵如下:
| **CPU** | **X64 64bit** | | | **X86 32bit** | **ARM64** | **ARM32** | **MIPS ** **龙芯** | **Alpha ** **申威** | **X64 ** **海光** |
| **CPU** | **X64 64bit** | | | **X86 32bit** | **ARM64** | **ARM32** | **MIPS 龙芯** | **Alpha 申威** | **X64 海光** |
| ----------- | --------------- | --------- | --------- | --------------- | --------- | --------- | ------------------- | -------------------- | ------------------ |
| **OS** | **Linux** | **Win64** | **Win32** | **Win32** | **Linux** | **Linux** | **Linux** | **Linux** | **Linux** |
| **C/C++** | ● | ● | ● | ○ | ● | ● | ● | ● | ● |
......
......@@ -451,7 +451,8 @@ Query OK, 1 row(s) in set (0.000141s)
| taos-jdbcdriver 版本 | TDengine 版本 | JDK 版本 |
| -------------------- | ----------------- | -------- |
| 2.0.12 及以上 | 2.0.8.0 及以上 | 1.8.x |
| 2.0.22 | 2.0.18.0 及以上 | 1.8.x |
| 2.0.12 - 2.0.21 | 2.0.8.0 - 2.0.17.0 | 1.8.x |
| 2.0.4 - 2.0.11 | 2.0.0.0 - 2.0.7.x | 1.8.x |
| 1.0.3 | 1.6.1.x 及以上 | 1.8.x |
| 1.0.2 | 1.6.1.x 及以上 | 1.8.x |
......@@ -470,9 +471,11 @@ TDengine 目前支持时间戳、数字、字符、布尔类型,与 Java 对
| BIGINT | java.lang.Long |
| FLOAT | java.lang.Float |
| DOUBLE | java.lang.Double |
| SMALLINT, TINYINT | java.lang.Short |
| SMALLINT | java.lang.Short |
| TINYINT | java.lang.Byte |
| BOOL | java.lang.Boolean |
| BINARY, NCHAR | java.lang.String |
| BINARY | byte array |
| NCHAR | java.lang.String |
......
......@@ -111,9 +111,10 @@ taos>
**提示:**
- 任何已经加入集群在线的数据节点,都可以作为后续待加入节点的firstEP。
- firstEp这个参数仅仅在该数据节点首次加入集群时有作用,加入集群后,该数据节点会保存最新的mnode的End Point列表,不再依赖这个参数。
- 两个没有配置firstEp参数的数据节点dnode启动后,会独立运行起来。这个时候,无法将其中一个数据节点加入到另外一个数据节点,形成集群。**无法将两个独立的集群合并成为新的集群**
- 任何已经加入集群在线的数据节点,都可以作为后续待加入节点的 firstEP。
- firstEp 这个参数仅仅在该数据节点首次加入集群时有作用,加入集群后,该数据节点会保存最新的 mnode 的 End Point 列表,不再依赖这个参数。
- 接下来,配置文件中的 firstEp 参数就主要在客户端连接的时候使用了,例如 taos shell 如果不加参数,会默认连接由 firstEp 指定的节点。
- 两个没有配置 firstEp 参数的数据节点 dnode 启动后,会独立运行起来。这个时候,无法将其中一个数据节点加入到另外一个数据节点,形成集群。**无法将两个独立的集群合并成为新的集群**
## <a class="anchor" id="management"></a>数据节点管理
......
......@@ -6,19 +6,27 @@
### 内存需求
每个 DB 可以创建固定数目的 vgroup,默认与 CPU 核数相同,可通过 maxVgroupsPerDb 配置;vgroup 中的每个副本会是一个 vnode;每个 vnode 会占用固定大小的内存(大小与数据库的配置参数 blocks 和 cache 有关);每个 Table 会占用与标签总长度有关的内存;此外,系统会有一些固定的内存开销。因此,每个 DB 需要的系统内存可通过如下公式计算:
每个 Database 可以创建固定数目的 vgroup,默认与 CPU 核数相同,可通过 maxVgroupsPerDb 配置;vgroup 中的每个副本会是一个 vnode;每个 vnode 会占用固定大小的内存(大小与数据库的配置参数 blocks 和 cache 有关);每个 Table 会占用与标签总长度有关的内存;此外,系统会有一些固定的内存开销。因此,每个 DB 需要的系统内存可通过如下公式计算:
```
Memory Size = maxVgroupsPerDb * (blocks * cache + 10MB) + numOfTables * (tagSizePerTable + 0.5KB)
Database Memory Size = maxVgroupsPerDb * (blocks * cache + 10MB) + numOfTables * (tagSizePerTable + 0.5KB)
```
示例:假设是 4 核机器,cache 是缺省大小 16M, blocks 是缺省值 6,假设有 10 万张表,标签总长度是 256 字节,则总的内存需求为:4 \* (16 \* 6 + 10) + 100000 \* (0.25 + 0.5) / 1000 = 499M。
示例:假设是 4 核机器,cache 是缺省大小 16M, blocks 是缺省值 6,并且一个 DB 中有 10 万张表,标签总长度是 256 字节,则这个 DB 总的内存需求为:4 \* (16 \* 6 + 10) + 100000 \* (0.25 + 0.5) / 1000 = 499M。
注意:从这个公式计算得到的内存容量,应理解为系统的“必要需求”,而不是“内存总数”。在实际运行的生产系统中,由于操作系统缓存、资源管理调度等方面的需要,内存规划应当在计算结果的基础上保留一定冗余,以维持系统状态和系统性能的稳定性。
在实际的系统运维中,我们通常会更关心 TDengine 服务进程(taosd)会占用的内存量。
```
taosd 内存总量 = vnode 内存 + mnode 内存 + 查询内存
```
其中:
1. “vnode 内存”指的是集群中所有的 Database 存储分摊到当前 taosd 节点上所占用的内存资源。可以按上文“Database Memory Size”计算公式估算每个 DB 的内存占用量进行加总,再按集群中总共的 TDengine 节点数做平均(如果设置为多副本,则还需要乘以对应的副本倍数)。
2. “mnode 内存”指的是集群中管理节点所占用的资源。如果一个 taosd 节点上分布有 mnode 管理节点,则内存消耗还需要增加“0.2KB * 集群中数据表总数”。
3. “查询内存”指的是服务端处理查询请求时所需要占用的内存。单条查询语句至少会占用“0.2KB * 查询涉及的数据表总数”的内存量。
实际运行的系统往往会根据数据特点的不同,将数据存放在不同的 DB 里。因此做规划时,也需要考虑
注意:以上内存估算方法,主要讲解了系统的“必须内存需求”,而不是“内存总数上限”。在实际运行的生产环境中,由于操作系统缓存、资源管理调度等方面的原因,内存规划应当在估算结果的基础上保留一定冗余,以维持系统状态和系统性能的稳定性。并且,生产环境通常会配置系统资源的监控工具,以便及时发现硬件资源的紧缺情况
如果内存充裕,可以加大 Blocks 的配置,这样更多数据将保存在内存里,提高查询速度。
最后,如果内存充裕,可以考虑加大 Blocks 的配置,这样更多数据将保存在内存里,提高查询速度。
### CPU 需求
......
......@@ -249,7 +249,7 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
3) TAGS 列名不能为预留关键字;
4) TAGS 最多允许128个,至少1个,总长度不超过16k个字符
4) TAGS 最多允许 128 个,至少 1 个,总长度不超过 16 KB
- **删除超级表**
......
......@@ -29,6 +29,9 @@
# number of threads per CPU core
# numOfThreadsPerCore 1.0
# number of threads to commit cache data
# numOfCommitThreads 4
# the proportion of total CPU cores available for query processing
# 2.0: the query threads will be set to double of the CPU cores.
# 1.0: all CPU cores are available for query processing [default].
......
......@@ -19,6 +19,6 @@ ADD_SUBDIRECTORY(tsdb)
ADD_SUBDIRECTORY(wal)
ADD_SUBDIRECTORY(cq)
ADD_SUBDIRECTORY(dnode)
#ADD_SUBDIRECTORY(connector/odbc)
ADD_SUBDIRECTORY(connector/odbc)
ADD_SUBDIRECTORY(connector/jdbc)
......@@ -83,6 +83,22 @@ typedef struct SJoinSupporter {
SArray* pVgroupTables;
} SJoinSupporter;
typedef struct SMergeCtx {
SJoinSupporter* p;
int32_t idx;
SArray* res;
int8_t compared;
}SMergeCtx;
typedef struct SMergeTsCtx {
SJoinSupporter* p;
STSBuf* res;
int64_t numOfInput;
int8_t compared;
}SMergeTsCtx;
typedef struct SVgroupTableInfo {
SVgroupInfo vgInfo;
SArray* itemList; //SArray<STableIdInfo>
......@@ -183,6 +199,7 @@ int32_t tscSqlExprCopy(SArray* dst, const SArray* src, uint64_t uid, bool deep
void tscSqlExprInfoDestroy(SArray* pExprInfo);
SColumn* tscColumnClone(const SColumn* src);
bool tscColumnExists(SArray* pColumnList, SColumnIndex* pColIndex);
SColumn* tscColumnListInsert(SArray* pColList, SColumnIndex* colIndex);
SArray* tscColumnListClone(const SArray* src, int16_t tableIndex);
void tscColumnListDestroy(SArray* pColList);
......
......@@ -142,15 +142,15 @@ typedef struct SCond {
} SCond;
typedef struct SJoinNode {
char tableName[TSDB_TABLE_FNAME_LEN];
uint64_t uid;
int16_t tagColId;
SArray* tsJoin;
SArray* tagJoin;
} SJoinNode;
typedef struct SJoinInfo {
bool hasJoin;
SJoinNode left;
SJoinNode right;
bool hasJoin;
SJoinNode* joinTables[TSDB_MAX_JOIN_TABLE_NUM];
} SJoinInfo;
typedef struct STagCond {
......@@ -284,7 +284,7 @@ typedef struct {
char * pRsp;
int32_t rspType;
int32_t rspLen;
uint64_t qhandle;
uint64_t qId;
int64_t useconds;
int64_t offset; // offset value from vnode during projection query of stable
int32_t row;
......@@ -367,7 +367,7 @@ typedef struct SSqlObj {
int64_t svgroupRid;
int64_t squeryLock;
int32_t retryReason; // previous error code
struct SSqlObj *prev, *next;
int64_t self;
} SSqlObj;
......
......@@ -160,8 +160,8 @@ static void tscProcessAsyncRetrieveImpl(void *param, TAOS_RES *tres, int numOfRo
SSqlCmd *pCmd = &pSql->cmd;
SSqlRes *pRes = &pSql->res;
if ((pRes->qhandle == 0 || numOfRows != 0) && pCmd->command < TSDB_SQL_LOCAL) {
if (pRes->qhandle == 0 && numOfRows != 0) {
if ((pRes->qId == 0 || numOfRows != 0) && pCmd->command < TSDB_SQL_LOCAL) {
if (pRes->qId == 0 && numOfRows != 0) {
tscError("qhandle is NULL");
} else {
pRes->code = numOfRows;
......@@ -208,7 +208,7 @@ void taos_fetch_rows_a(TAOS_RES *taosa, __async_cb_func_t fp, void *param) {
pSql->fetchFp = fp;
pSql->fp = tscAsyncFetchRowsProxy;
if (pRes->qhandle == 0) {
if (pRes->qId == 0) {
tscError("qhandle is NULL");
pRes->code = TSDB_CODE_TSC_INVALID_QHANDLE;
pSql->param = param;
......@@ -310,9 +310,50 @@ void tscAsyncResultOnError(SSqlObj* pSql) {
taosScheduleTask(tscQhandle, &schedMsg);
}
int tscSendMsgToServer(SSqlObj *pSql);
static int32_t updateMetaBeforeRetryQuery(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, SQueryInfo* pQueryInfo) {
// handle the invalid table error code for super table.
// update the pExpr info, colList info, number of table columns
// TODO Re-parse this sql and issue the corresponding subquery as an alternative for this case.
if (pSql->retryReason == TSDB_CODE_TDB_INVALID_TABLE_ID) {
int32_t numOfExprs = (int32_t) tscSqlExprNumOfExprs(pQueryInfo);
int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
int32_t numOfTags = tscGetNumOfTags(pTableMetaInfo->pTableMeta);
SSchema *pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
for (int32_t i = 0; i < numOfExprs; ++i) {
SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i);
pExpr->uid = pTableMetaInfo->pTableMeta->id.uid;
if (pExpr->colInfo.colIndex >= 0) {
int32_t index = pExpr->colInfo.colIndex;
if ((TSDB_COL_IS_NORMAL_COL(pExpr->colInfo.flag) && index >= numOfCols) ||
(TSDB_COL_IS_TAG(pExpr->colInfo.flag) && (index < numOfCols || index >= (numOfCols + numOfTags)))) {
return pSql->retryReason;
}
int tscSendMsgToServer(SSqlObj *pSql);
if ((pSchema[pExpr->colInfo.colIndex].colId != pExpr->colInfo.colId) &&
strcasecmp(pExpr->colInfo.name, pSchema[pExpr->colInfo.colIndex].name) != 0) {
return pSql->retryReason;
}
}
}
// validate the table columns information
for (int32_t i = 0; i < taosArrayGetSize(pQueryInfo->colList); ++i) {
SColumn *pCol = taosArrayGetP(pQueryInfo->colList, i);
if (pCol->colIndex.columnIndex >= numOfCols) {
return pSql->retryReason;
}
}
} else {
// do nothing
}
return TSDB_CODE_SUCCESS;
}
void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
SSqlObj* pSql = (SSqlObj*)taosAcquireRef(tscObjRef, (int64_t)param);
......@@ -339,7 +380,8 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, (TSDB_QUERY_TYPE_STABLE_SUBQUERY|TSDB_QUERY_TYPE_SUBQUERY|TSDB_QUERY_TYPE_TAG_FILTER_QUERY))) {
tscDebug("%p update local table meta, continue to process sql and send the corresponding query", pSql);
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
code = tscGetTableMeta(pSql, pTableMetaInfo);
assert(code == TSDB_CODE_TSC_ACTION_IN_PROGRESS || code == TSDB_CODE_SUCCESS);
......@@ -349,6 +391,10 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
}
assert((tscGetNumOfTags(pTableMetaInfo->pTableMeta) != 0));
code = updateMetaBeforeRetryQuery(pSql, pTableMetaInfo, pQueryInfo);
if (code != TSDB_CODE_SUCCESS) {
goto _error;
}
// tscProcessSql can add error into async res
tscProcessSql(pSql);
......
......@@ -309,7 +309,7 @@ TAOS_ROW tscFetchRow(void *param) {
SSqlCmd *pCmd = &pSql->cmd;
SSqlRes *pRes = &pSql->res;
if (pRes->qhandle == 0 ||
if (pRes->qId == 0 ||
pCmd->command == TSDB_SQL_RETRIEVE_EMPTY_RESULT ||
pCmd->command == TSDB_SQL_INSERT) {
return NULL;
......@@ -905,7 +905,7 @@ int tscProcessLocalCmd(SSqlObj *pSql) {
* set the qhandle to be 1 in order to pass the qhandle check, and to call partial release function to
* free allocated resources and remove the SqlObj from sql query linked list
*/
pRes->qhandle = 0x1;
pRes->qId = 0x1;
pRes->numOfRows = 0;
} else if (pCmd->command == TSDB_SQL_SHOW_CREATE_TABLE) {
pRes->code = tscProcessShowCreateTable(pSql);
......
......@@ -1607,7 +1607,7 @@ void tscInitResObjForLocalQuery(SSqlObj *pObj, int32_t numOfRes, int32_t rowLen)
tscDestroyLocalMerger(pObj);
}
pRes->qhandle = 1; // hack to pass the safety check in fetch_row function
pRes->qId = 1; // hack to pass the safety check in fetch_row function
pRes->numOfRows = 0;
pRes->row = 0;
......
......@@ -261,7 +261,7 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
return TSDB_CODE_SUCCESS;
}
if (1) {
if (0) {
// allow user bind param data with different type
union {
int8_t v1;
......@@ -903,7 +903,7 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) {
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
pRes->qhandle = 0;
pRes->qId = 0;
pRes->numOfRows = 1;
strtolower(pSql->sqlstr, sql);
......@@ -1057,14 +1057,28 @@ int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes) {
}
if (pStmt->isInsert) {
SSqlObj* pSql = pStmt->pSql;
SSqlCmd *pCmd = &pSql->cmd;
STableDataBlocks* pBlock = taosArrayGetP(pCmd->pDataBlocks, 0);
SSqlCmd* pCmd = &pStmt->pSql->cmd;
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0, 0);
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
if (pCmd->pTableBlockHashList == NULL) {
pCmd->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
}
STableDataBlocks* pBlock = NULL;
assert(pCmd->numOfParams == pBlock->numOfParams);
if (idx < 0 || idx >= pBlock->numOfParams) return -1;
int32_t ret =
tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
if (ret != 0) {
// todo handle error
}
if (idx<0 || idx>=pBlock->numOfParams) {
tscError("param %d: out of range", idx);
abort();
}
SParamInfo* param = pBlock->params + idx;
SParamInfo* param = &pBlock->params[idx];
if (type) *type = param->type;
if (bytes) *bytes = param->bytes;
......
......@@ -249,8 +249,8 @@ int tscBuildQueryStreamDesc(void *pMsg, STscObj *pObj) {
pQdesc->stime = htobe64(pSql->stime);
pQdesc->queryId = htonl(pSql->queryId);
//pQdesc->useconds = htobe64(pSql->res.useconds);
pQdesc->useconds = htobe64(now - pSql->stime);
pQdesc->qHandle = htobe64(pSql->res.qhandle);
pQdesc->useconds = htobe64(now - pSql->stime); // use local time instead of sever rsp elapsed time
pQdesc->qHandle = htobe64(pSql->res.qId);
pHeartbeat->numOfQueries++;
pQdesc++;
......
......@@ -670,7 +670,18 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) {
if ((code = setKillInfo(pSql, pInfo, pInfo->type)) != TSDB_CODE_SUCCESS) {
return code;
}
break;
}
case TSDB_SQL_SYNC_DB_REPLICA: {
const char* msg1 = "invalid db name";
SStrToken* pzName = taosArrayGet(pInfo->pMiscInfo->a, 0);
assert(taosArrayGetSize(pInfo->pMiscInfo->a) == 1);
code = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), pzName);
if (code != TSDB_CODE_SUCCESS) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
}
break;
}
......@@ -966,12 +977,18 @@ int32_t parseSlidingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* pSl
int32_t tscSetTableFullName(STableMetaInfo* pTableMetaInfo, SStrToken* pTableName, SSqlObj* pSql) {
const char* msg1 = "name too long";
const char* msg2 = "acctId too long";
const char* msg3 = "no acctId";
SSqlCmd* pCmd = &pSql->cmd;
int32_t code = TSDB_CODE_SUCCESS;
if (hasSpecifyDB(pTableName)) { // db has been specified in sql string so we ignore current db path
code = tNameSetAcctId(&pTableMetaInfo->name, getAccountId(pSql));
char* acctId = getAccountId(pSql);
if (acctId == NULL || strlen(acctId) <= 0) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
}
code = tNameSetAcctId(&pTableMetaInfo->name, acctId);
if (code != 0) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
......@@ -3342,24 +3359,26 @@ static int32_t getColumnQueryCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSq
}
}
static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr) {
const char* msg1 = "invalid join query condition";
const char* msg2 = "invalid table name in join query";
static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr) {
int32_t code = 0;
const char* msg1 = "timestamp required for join tables";
const char* msg3 = "type of join columns must be identical";
const char* msg4 = "invalid column name in join condition";
const char* msg5 = "only support one join tag for each table";
if (pExpr == NULL) {
return TSDB_CODE_SUCCESS;
}
if (!tSqlExprIsParentOfLeaf(pExpr)) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
code = checkAndSetJoinCondInfo(pCmd, pQueryInfo, pExpr->pLeft);
if (code) {
return code;
}
return checkAndSetJoinCondInfo(pCmd, pQueryInfo, pExpr->pRight);
}
STagCond* pTagCond = &pQueryInfo->tagCond;
SJoinNode* pLeft = &pTagCond->joinInfo.left;
SJoinNode* pRight = &pTagCond->joinInfo.right;
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
......@@ -3368,13 +3387,28 @@ static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr*
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
SSchema* pTagSchema1 = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
pLeft->uid = pTableMetaInfo->pTableMeta->id.uid;
pLeft->tagColId = pTagSchema1->colId;
assert(index.tableIndex >= 0 && index.tableIndex < TSDB_MAX_JOIN_TABLE_NUM);
int32_t code = tNameExtractFullName(&pTableMetaInfo->name, pLeft->tableName);
if (code != TSDB_CODE_SUCCESS) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
SJoinNode **leftNode = &pQueryInfo->tagCond.joinInfo.joinTables[index.tableIndex];
if (*leftNode == NULL) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
}
(*leftNode)->uid = pTableMetaInfo->pTableMeta->id.uid;
(*leftNode)->tagColId = pTagSchema1->colId;
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
if (!tscColumnExists(pTableMetaInfo->tagColList, &index)) {
tscColumnListInsert(pTableMetaInfo->tagColList, &index);
if (taosArrayGetSize(pTableMetaInfo->tagColList) > 1) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
}
}
}
int16_t leftIdx = index.tableIndex;
index = (SColumnIndex)COLUMN_INDEX_INITIALIZER;
if (getColumnIndexByName(pCmd, &pExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
......@@ -3384,20 +3418,55 @@ static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr*
pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
SSchema* pTagSchema2 = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
pRight->uid = pTableMetaInfo->pTableMeta->id.uid;
pRight->tagColId = pTagSchema2->colId;
assert(index.tableIndex >= 0 && index.tableIndex < TSDB_MAX_JOIN_TABLE_NUM);
code = tNameExtractFullName(&pTableMetaInfo->name, pRight->tableName);
if (code != TSDB_CODE_SUCCESS) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
SJoinNode **rightNode = &pQueryInfo->tagCond.joinInfo.joinTables[index.tableIndex];
if (*rightNode == NULL) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
}
(*rightNode)->uid = pTableMetaInfo->pTableMeta->id.uid;
(*rightNode)->tagColId = pTagSchema2->colId;
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
if (!tscColumnExists(pTableMetaInfo->tagColList, &index)) {
tscColumnListInsert(pTableMetaInfo->tagColList, &index);
if (taosArrayGetSize(pTableMetaInfo->tagColList) > 1) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
}
}
}
int16_t rightIdx = index.tableIndex;
if (pTagSchema1->type != pTagSchema2->type) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
}
pTagCond->joinInfo.hasJoin = true;
if ((*leftNode)->tagJoin == NULL) {
(*leftNode)->tagJoin = taosArrayInit(2, sizeof(int16_t));
}
if ((*rightNode)->tagJoin == NULL) {
(*rightNode)->tagJoin = taosArrayInit(2, sizeof(int16_t));
}
taosArrayPush((*leftNode)->tagJoin, &rightIdx);
taosArrayPush((*rightNode)->tagJoin, &leftIdx);
pQueryInfo->tagCond.joinInfo.hasJoin = true;
return TSDB_CODE_SUCCESS;
}
static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr) {
if (pExpr == NULL) {
return TSDB_CODE_SUCCESS;
}
return checkAndSetJoinCondInfo(pCmd, pQueryInfo, pExpr);
}
static int32_t validateSQLExpr(SSqlCmd* pCmd, tSqlExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList,
......@@ -3663,7 +3732,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql
const char* msg1 = "table query cannot use tags filter";
const char* msg2 = "illegal column name";
const char* msg3 = "only one query time range allowed";
const char* msg4 = "only one join condition allowed";
const char* msg4 = "too many join tables";
const char* msg5 = "not support ordinary column join";
const char* msg6 = "only one query condition on tbname allowed";
const char* msg7 = "only in/like allowed in filter table name";
......@@ -3694,6 +3763,47 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql
TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_QUERY);
pCondExpr->tsJoin = true;
assert(index.tableIndex >= 0 && index.tableIndex < TSDB_MAX_JOIN_TABLE_NUM);
SJoinNode **leftNode = &pQueryInfo->tagCond.joinInfo.joinTables[index.tableIndex];
if (*leftNode == NULL) {
*leftNode = calloc(1, sizeof(SJoinNode));
if (*leftNode == NULL) {
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
}
int16_t leftIdx = index.tableIndex;
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
if (getColumnIndexByName(pCmd, &pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
if (index.tableIndex < 0 || index.tableIndex >= TSDB_MAX_JOIN_TABLE_NUM) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
}
SJoinNode **rightNode = &pQueryInfo->tagCond.joinInfo.joinTables[index.tableIndex];
if (*rightNode == NULL) {
*rightNode = calloc(1, sizeof(SJoinNode));
if (*rightNode == NULL) {
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
}
int16_t rightIdx = index.tableIndex;
if ((*leftNode)->tsJoin == NULL) {
(*leftNode)->tsJoin = taosArrayInit(2, sizeof(int16_t));
}
if ((*rightNode)->tsJoin == NULL) {
(*rightNode)->tsJoin = taosArrayInit(2, sizeof(int16_t));
}
taosArrayPush((*leftNode)->tsJoin, &rightIdx);
taosArrayPush((*rightNode)->tsJoin, &leftIdx);
/*
* to release expression, e.g., m1.ts = m2.ts,
* since this expression is used to set the join query type
......@@ -3751,10 +3861,6 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql
return TSDB_CODE_TSC_INVALID_SQL;
}
if (pCondExpr->pJoinExpr != NULL) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
}
pQueryInfo->type |= TSDB_QUERY_TYPE_JOIN_QUERY;
ret = setExprToCond(&pCondExpr->pJoinExpr, *pExpr, NULL, parentOptr, pQueryInfo->msg);
*pExpr = NULL;
......@@ -3982,7 +4088,8 @@ static bool validateFilterExpr(SQueryInfo* pQueryInfo) {
static int32_t getTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr) {
const char* msg0 = "invalid timestamp";
const char* msg1 = "only one time stamp window allowed";
int32_t code = 0;
if (pExpr == NULL) {
return TSDB_CODE_SUCCESS;
}
......@@ -3992,8 +4099,11 @@ static int32_t getTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlE
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
}
getTimeRangeFromExpr(pCmd, pQueryInfo, pExpr->pLeft);
code = getTimeRangeFromExpr(pCmd, pQueryInfo, pExpr->pLeft);
if (code) {
return code;
}
return getTimeRangeFromExpr(pCmd, pQueryInfo, pExpr->pRight);
} else {
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
......@@ -4074,6 +4184,7 @@ static void cleanQueryExpr(SCondExpr* pCondExpr) {
}
}
/*
static void doAddJoinTagsColumnsIntoTagList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondExpr* pCondExpr) {
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
if (QUERY_IS_JOIN_QUERY(pQueryInfo->type) && UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
......@@ -4096,6 +4207,7 @@ static void doAddJoinTagsColumnsIntoTagList(SSqlCmd* pCmd, SQueryInfo* pQueryInf
tscColumnListInsert(pTableMetaInfo->tagColList, &index);
}
}
*/
static int32_t validateTagCondExpr(SSqlCmd* pCmd, tExprNode *p) {
const char *msg1 = "invalid tag operator";
......@@ -4239,6 +4351,102 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE
return ret;
}
int32_t validateJoinNodes(SQueryInfo* pQueryInfo, SSqlObj* pSql) {
const char* msg1 = "timestamp required for join tables";
const char* msg2 = "tag required for join stables";
for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
SJoinNode *node = pQueryInfo->tagCond.joinInfo.joinTables[i];
if (node == NULL || node->tsJoin == NULL || taosArrayGetSize(node->tsJoin) <= 0) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg1);
}
}
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
SJoinNode *node = pQueryInfo->tagCond.joinInfo.joinTables[i];
if (node == NULL || node->tagJoin == NULL || taosArrayGetSize(node->tagJoin) <= 0) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg2);
}
}
}
return TSDB_CODE_SUCCESS;
}
void mergeJoinNodesImpl(int8_t* r, int8_t* p, int16_t* tidx, SJoinNode** nodes, int32_t type) {
SJoinNode *node = nodes[*tidx];
SArray* arr = (type == 0) ? node->tsJoin : node->tagJoin;
size_t size = taosArrayGetSize(arr);
p[*tidx] = 1;
for (int32_t j = 0; j < size; j++) {
int16_t* idx = taosArrayGet(arr, j);
r[*idx] = 1;
if (p[*idx] == 0) {
mergeJoinNodesImpl(r, p, idx, nodes, type);
}
}
}
int32_t mergeJoinNodes(SQueryInfo* pQueryInfo, SSqlObj* pSql) {
const char* msg1 = "not all join tables have same timestamp";
const char* msg2 = "not all join tables have same tag";
int8_t r[TSDB_MAX_JOIN_TABLE_NUM] = {0};
int8_t p[TSDB_MAX_JOIN_TABLE_NUM] = {0};
for (int16_t i = 0; i < pQueryInfo->numOfTables; ++i) {
mergeJoinNodesImpl(r, p, &i, pQueryInfo->tagCond.joinInfo.joinTables, 0);
taosArrayClear(pQueryInfo->tagCond.joinInfo.joinTables[i]->tsJoin);
for (int32_t j = 0; j < TSDB_MAX_JOIN_TABLE_NUM; ++j) {
if (r[j]) {
taosArrayPush(pQueryInfo->tagCond.joinInfo.joinTables[i]->tsJoin, &j);
}
}
memset(r, 0, sizeof(r));
memset(p, 0, sizeof(p));
}
if (taosArrayGetSize(pQueryInfo->tagCond.joinInfo.joinTables[0]->tsJoin) != pQueryInfo->numOfTables) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg1);
}
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
for (int16_t i = 0; i < pQueryInfo->numOfTables; ++i) {
mergeJoinNodesImpl(r, p, &i, pQueryInfo->tagCond.joinInfo.joinTables, 1);
taosArrayClear(pQueryInfo->tagCond.joinInfo.joinTables[i]->tagJoin);
for (int32_t j = 0; j < TSDB_MAX_JOIN_TABLE_NUM; ++j) {
if (r[j]) {
taosArrayPush(pQueryInfo->tagCond.joinInfo.joinTables[i]->tagJoin, &j);
}
}
memset(r, 0, sizeof(r));
memset(p, 0, sizeof(p));
}
if (taosArrayGetSize(pQueryInfo->tagCond.joinInfo.joinTables[0]->tagJoin) != pQueryInfo->numOfTables) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg2);
}
}
return TSDB_CODE_SUCCESS;
}
int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql) {
if (pExpr == NULL) {
return TSDB_CODE_SUCCESS;
......@@ -4284,17 +4492,17 @@ int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql
// 4. get the table name query condition
if ((ret = getTablenameCond(&pSql->cmd, pQueryInfo, condExpr.pTableCond, &sb)) != TSDB_CODE_SUCCESS) {
return ret;
goto PARSE_WHERE_EXIT;
}
// 5. other column query condition
if ((ret = getColumnQueryCondInfo(&pSql->cmd, pQueryInfo, condExpr.pColumnCond, TK_AND)) != TSDB_CODE_SUCCESS) {
return ret;
goto PARSE_WHERE_EXIT;
}
// 6. join condition
if ((ret = getJoinCondInfo(&pSql->cmd, pQueryInfo, condExpr.pJoinExpr)) != TSDB_CODE_SUCCESS) {
return ret;
goto PARSE_WHERE_EXIT;
}
// 7. query condition for table name
......@@ -4302,12 +4510,29 @@ int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql
ret = setTableCondForSTableQuery(&pSql->cmd, pQueryInfo, getAccountId(pSql), condExpr.pTableCond, condExpr.tableCondIndex, &sb);
taosStringBuilderDestroy(&sb);
if (ret) {
goto PARSE_WHERE_EXIT;
}
if (!validateFilterExpr(pQueryInfo)) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg2);
ret = invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg2);
goto PARSE_WHERE_EXIT;
}
doAddJoinTagsColumnsIntoTagList(&pSql->cmd, pQueryInfo, &condExpr);
//doAddJoinTagsColumnsIntoTagList(&pSql->cmd, pQueryInfo, &condExpr);
if (condExpr.tsJoin) {
ret = validateJoinNodes(pQueryInfo, pSql);
if (ret) {
goto PARSE_WHERE_EXIT;
}
ret = mergeJoinNodes(pQueryInfo, pSql);
if (ret) {
goto PARSE_WHERE_EXIT;
}
}
PARSE_WHERE_EXIT:
cleanQueryExpr(&condExpr);
return ret;
......@@ -6520,7 +6745,6 @@ int32_t doValidateSqlNode(SSqlObj* pSql, SQuerySqlNode* pQuerySqlNode, int32_t i
const char* msg1 = "point interpolation query needs timestamp";
const char* msg2 = "fill only available for interval query";
const char* msg3 = "start(end) time of query range required or time range too large";
const char* msg4 = "illegal number of tables in from clause";
const char* msg5 = "too many columns in selection clause";
const char* msg6 = "too many tables in from clause";
const char* msg7 = "invalid table alias name";
......@@ -6557,14 +6781,11 @@ int32_t doValidateSqlNode(SSqlObj* pSql, SQuerySqlNode* pQuerySqlNode, int32_t i
}
size_t fromSize = taosArrayGetSize(pQuerySqlNode->from->tableList);
if (fromSize > TSDB_MAX_JOIN_TABLE_NUM) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
if (fromSize > TSDB_MAX_JOIN_TABLE_NUM * 2) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
}
pQueryInfo->command = TSDB_SQL_SELECT;
if (fromSize > 2) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
}
// set all query tables, which are maybe more than one.
for (int32_t i = 0; i < fromSize; ++i) {
......
......@@ -350,8 +350,8 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
taosMsleep(duration);
}
pSql->retryReason = rpcMsg->code;
rpcMsg->code = tscRenewTableMeta(pSql, 0);
// if there is an error occurring, proceed to the following error handling procedure.
if (rpcMsg->code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
taosReleaseRef(tscObjRef, handle);
......@@ -508,7 +508,7 @@ int tscBuildFetchMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex);
pRetrieveMsg->free = htons(pQueryInfo->type);
pRetrieveMsg->qhandle = htobe64(pSql->res.qhandle);
pRetrieveMsg->qId = htobe64(pSql->res.qId);
// todo valid the vgroupId at the client side
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
......@@ -520,7 +520,7 @@ int tscBuildFetchMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
assert(pVgroupInfo->vgroups[vgIndex].vgId > 0 && vgIndex < pTableMetaInfo->vgroupList->numOfVgroups);
pRetrieveMsg->header.vgId = htonl(pVgroupInfo->vgroups[vgIndex].vgId);
tscDebug("%p build fetch msg from vgId:%d, vgIndex:%d, qhandle:%" PRIX64, pSql, pVgroupInfo->vgroups[vgIndex].vgId, vgIndex, pSql->res.qhandle);
tscDebug("%p build fetch msg from vgId:%d, vgIndex:%d, qhandle:%" PRIX64, pSql, pVgroupInfo->vgroups[vgIndex].vgId, vgIndex, pSql->res.qId);
} else {
int32_t numOfVgroups = (int32_t)taosArrayGetSize(pTableMetaInfo->pVgroupTables);
assert(vgIndex >= 0 && vgIndex < numOfVgroups);
......@@ -528,12 +528,12 @@ int tscBuildFetchMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SVgroupTableInfo* pTableIdList = taosArrayGet(pTableMetaInfo->pVgroupTables, vgIndex);
pRetrieveMsg->header.vgId = htonl(pTableIdList->vgInfo.vgId);
tscDebug("%p build fetch msg from vgId:%d, vgIndex:%d, qhandle:%" PRIX64, pSql, pTableIdList->vgInfo.vgId, vgIndex, pSql->res.qhandle);
tscDebug("%p build fetch msg from vgId:%d, vgIndex:%d, qId:%" PRIu64, pSql, pTableIdList->vgInfo.vgId, vgIndex, pSql->res.qId);
}
} else {
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
pRetrieveMsg->header.vgId = htonl(pTableMeta->vgId);
tscDebug("%p build fetch msg from only one vgroup, vgId:%d, qhandle:%" PRIX64, pSql, pTableMeta->vgId, pSql->res.qhandle);
tscDebug("%p build fetch msg from only one vgroup, vgId:%d, qId:%" PRIu64, pSql, pTableMeta->vgId, pSql->res.qId);
}
pSql->cmd.payloadLen = sizeof(SRetrieveTableMsg);
......@@ -1294,6 +1294,23 @@ int32_t tscBuildUseDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
return TSDB_CODE_SUCCESS;
}
int32_t tscBuildSyncDbReplicaMsg(SSqlObj* pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
pCmd->payloadLen = sizeof(SSyncDbMsg);
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) {
tscError("%p failed to malloc for query msg", pSql);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
SSyncDbMsg *pSyncMsg = (SSyncDbMsg *)pCmd->payload;
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
tNameExtractFullName(&pTableMetaInfo->name, pSyncMsg->db);
pCmd->msgType = TSDB_MSG_TYPE_CM_SYNC_DB;
return TSDB_CODE_SUCCESS;
}
int32_t tscBuildShowMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
STscObj *pObj = pSql->pTscObj;
SSqlCmd *pCmd = &pSql->cmd;
......@@ -1566,7 +1583,7 @@ int tscBuildRetrieveFromMgmtMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
SRetrieveTableMsg *pRetrieveMsg = (SRetrieveTableMsg*)pCmd->payload;
pRetrieveMsg->qhandle = htobe64(pSql->res.qhandle);
pRetrieveMsg->qId = htobe64(pSql->res.qId);
pRetrieveMsg->free = htons(pQueryInfo->type);
return TSDB_CODE_SUCCESS;
......@@ -2117,7 +2134,7 @@ int tscProcessShowRsp(SSqlObj *pSql) {
pShow = (SShowRsp *)pRes->pRsp;
pShow->qhandle = htobe64(pShow->qhandle);
pRes->qhandle = pShow->qhandle;
pRes->qId = pShow->qhandle;
tscResetForNextRetrieve(pRes);
pMetaMsg = &(pShow->tableMeta);
......@@ -2299,11 +2316,12 @@ int tscProcessQueryRsp(SSqlObj *pSql) {
SSqlRes *pRes = &pSql->res;
SQueryTableRsp *pQuery = (SQueryTableRsp *)pRes->pRsp;
pQuery->qhandle = htobe64(pQuery->qhandle);
pRes->qhandle = pQuery->qhandle;
pQuery->qId = htobe64(pQuery->qId);
pRes->qId = pQuery->qId;
pRes->data = NULL;
tscResetForNextRetrieve(pRes);
tscDebug("%p query rsp received, qId:%"PRIu64, pSql, pRes->qId);
return 0;
}
......@@ -2361,7 +2379,8 @@ int tscProcessRetrieveRspFromNode(SSqlObj *pSql) {
}
pRes->row = 0;
tscDebug("%p numOfRows:%d, offset:%" PRId64 ", complete:%d", pSql, pRes->numOfRows, pRes->offset, pRes->completed);
tscDebug("%p numOfRows:%d, offset:%" PRId64 ", complete:%d, qId:%"PRIu64, pSql, pRes->numOfRows, pRes->offset,
pRes->completed, pRes->qId);
return 0;
}
......@@ -2574,6 +2593,7 @@ void tscInitMsgsFp() {
tscBuildMsg[TSDB_SQL_DROP_USER] = tscBuildDropUserAcctMsg;
tscBuildMsg[TSDB_SQL_DROP_ACCT] = tscBuildDropUserAcctMsg;
tscBuildMsg[TSDB_SQL_DROP_DB] = tscBuildDropDbMsg;
tscBuildMsg[TSDB_SQL_SYNC_DB_REPLICA] = tscBuildSyncDbReplicaMsg;
tscBuildMsg[TSDB_SQL_DROP_TABLE] = tscBuildDropTableMsg;
tscBuildMsg[TSDB_SQL_ALTER_USER] = tscBuildUserMsg;
tscBuildMsg[TSDB_SQL_CREATE_DNODE] = tscBuildCreateDnodeMsg;
......
......@@ -476,7 +476,7 @@ TAOS_ROW taos_fetch_row(TAOS_RES *res) {
SSqlCmd *pCmd = &pSql->cmd;
SSqlRes *pRes = &pSql->res;
if (pRes->qhandle == 0 ||
if (pRes->qId == 0 ||
pRes->code == TSDB_CODE_TSC_QUERY_CANCELLED ||
pCmd->command == TSDB_SQL_RETRIEVE_EMPTY_RESULT ||
pCmd->command == TSDB_SQL_INSERT) {
......@@ -508,7 +508,7 @@ int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) {
SSqlCmd *pCmd = &pSql->cmd;
SSqlRes *pRes = &pSql->res;
if (pRes->qhandle == 0 ||
if (pRes->qId == 0 ||
pRes->code == TSDB_CODE_TSC_QUERY_CANCELLED ||
pCmd->command == TSDB_SQL_RETRIEVE_EMPTY_RESULT ||
pCmd->command == TSDB_SQL_INSERT) {
......@@ -554,7 +554,7 @@ static bool tscKillQueryInDnode(SSqlObj* pSql) {
SSqlCmd* pCmd = &pSql->cmd;
SSqlRes* pRes = &pSql->res;
if (pRes == NULL || pRes->qhandle == 0) {
if (pRes == NULL || pRes->qId == 0) {
return true;
}
......@@ -1050,7 +1050,7 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) {
* If qhandle is NOT set 0, the function of taos_free_result() will send message to server by calling tscProcessSql()
* to free connection, which may cause segment fault, when the parse phrase is not even successfully executed.
*/
pRes->qhandle = 0;
pRes->qId = 0;
free(str);
if (code != TSDB_CODE_SUCCESS) {
......
......@@ -149,7 +149,7 @@ static SSub* tscCreateSubscription(STscObj* pObj, const char* topic, const char*
}
strtolower(pSql->sqlstr, pSql->sqlstr);
pRes->qhandle = 0;
pRes->qId = 0;
pRes->numOfRows = 1;
code = tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE);
......@@ -448,7 +448,7 @@ SSqlObj* recreateSqlObj(SSub* pSub) {
return NULL;
}
pRes->qhandle = 0;
pRes->qId = 0;
pRes->numOfRows = 1;
int code = tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE);
......@@ -546,7 +546,7 @@ TAOS_RES *taos_consume(TAOS_SUB *tsub) {
uint32_t type = pQueryInfo->type;
tscFreeSqlResult(pSql);
pRes->numOfRows = 1;
pRes->qhandle = 0;
pRes->qId = 0;
pSql->cmd.command = TSDB_SQL_SELECT;
pQueryInfo->type = type;
......
此差异已折叠。
......@@ -1279,6 +1279,34 @@ int32_t tscSqlExprCopy(SArray* dst, const SArray* src, uint64_t uid, bool deepco
return 0;
}
bool tscColumnExists(SArray* pColumnList, SColumnIndex* pColIndex) {
// ignore the tbname columnIndex to be inserted into source list
if (pColIndex->columnIndex < 0) {
return false;
}
size_t numOfCols = taosArrayGetSize(pColumnList);
int16_t col = pColIndex->columnIndex;
int32_t i = 0;
while (i < numOfCols) {
SColumn* pCol = taosArrayGetP(pColumnList, i);
if ((pCol->colIndex.columnIndex != col) || (pCol->colIndex.tableIndex != pColIndex->tableIndex)) {
++i;
continue;
} else {
break;
}
}
if (i >= numOfCols || numOfCols == 0) {
return false;
}
return true;
}
SColumn* tscColumnListInsert(SArray* pColumnList, SColumnIndex* pColIndex) {
// ignore the tbname columnIndex to be inserted into source list
if (pColIndex->columnIndex < 0) {
......@@ -1583,7 +1611,25 @@ int32_t tscTagCondCopy(STagCond* dest, const STagCond* src) {
dest->tbnameCond.uid = src->tbnameCond.uid;
dest->tbnameCond.len = src->tbnameCond.len;
memcpy(&dest->joinInfo, &src->joinInfo, sizeof(SJoinInfo));
dest->joinInfo.hasJoin = src->joinInfo.hasJoin;
for (int32_t i = 0; i < TSDB_MAX_JOIN_TABLE_NUM; ++i) {
if (src->joinInfo.joinTables[i]) {
dest->joinInfo.joinTables[i] = calloc(1, sizeof(SJoinNode));
memcpy(dest->joinInfo.joinTables[i], src->joinInfo.joinTables[i], sizeof(SJoinNode));
if (src->joinInfo.joinTables[i]->tsJoin) {
dest->joinInfo.joinTables[i]->tsJoin = taosArrayDup(src->joinInfo.joinTables[i]->tsJoin);
}
if (src->joinInfo.joinTables[i]->tagJoin) {
dest->joinInfo.joinTables[i]->tagJoin = taosArrayDup(src->joinInfo.joinTables[i]->tagJoin);
}
}
}
dest->relType = src->relType;
if (src->pCond == NULL) {
......@@ -1629,6 +1675,23 @@ void tscTagCondRelease(STagCond* pTagCond) {
taosArrayDestroy(pTagCond->pCond);
}
for (int32_t i = 0; i < TSDB_MAX_JOIN_TABLE_NUM; ++i) {
SJoinNode *node = pTagCond->joinInfo.joinTables[i];
if (node == NULL) {
continue;
}
if (node->tsJoin != NULL) {
taosArrayDestroy(node->tsJoin);
}
if (node->tagJoin != NULL) {
taosArrayDestroy(node->tagJoin);
}
tfree(node);
}
memset(pTagCond, 0, sizeof(STagCond));
}
......@@ -2318,16 +2381,21 @@ void tscDoQuery(SSqlObj* pSql) {
}
int16_t tscGetJoinTagColIdByUid(STagCond* pTagCond, uint64_t uid) {
if (pTagCond->joinInfo.left.uid == uid) {
return pTagCond->joinInfo.left.tagColId;
} else if (pTagCond->joinInfo.right.uid == uid) {
return pTagCond->joinInfo.right.tagColId;
} else {
assert(0);
return -1;
int32_t i = 0;
while (i < TSDB_MAX_JOIN_TABLE_NUM) {
SJoinNode* node = pTagCond->joinInfo.joinTables[i];
if (node && node->uid == uid) {
return node->tagColId;
}
i++;
}
assert(0);
return -1;
}
int16_t tscGetTagColIndexById(STableMeta* pTableMeta, int16_t colId) {
int32_t numOfTags = tscGetNumOfTags(pTableMeta);
......
......@@ -51,6 +51,7 @@ enum {
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_ALTER_ACCT, "alter-acct" )
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_ALTER_TABLE, "alter-table" )
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_ALTER_DB, "alter-db" )
TSDB_DEFINE_SQL_TYPE(TSDB_SQL_SYNC_DB_REPLICA, "sync db-replica")
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_CREATE_MNODE, "create-mnode" )
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_DROP_MNODE, "drop-mnode" )
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_CREATE_DNODE, "create-dnode" )
......@@ -87,13 +88,13 @@ enum {
*/
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_RETRIEVE_EMPTY_RESULT, "retrieve-empty-result" )
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_RESET_CACHE, "reset-cache" )
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_SERV_STATUS, "serv-status" )
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_CURRENT_DB, "current-db" )
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_RESET_CACHE, "reset-cache" )
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_SERV_STATUS, "serv-status" )
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_CURRENT_DB, "current-db" )
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_SERV_VERSION, "serv-version" )
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_CLI_VERSION, "cli-version" )
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_CLI_VERSION, "cli-version" )
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_CURRENT_USER, "current-user ")
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_CFG_LOCAL, "cfg-local" )
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_CFG_LOCAL, "cfg-local" )
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_MAX, "max" )
};
......
......@@ -51,7 +51,7 @@ int32_t tsMaxShellConns = 50000;
int32_t tsMaxConnections = 5000;
int32_t tsShellActivityTimer = 3; // second
float tsNumOfThreadsPerCore = 1.0f;
int32_t tsNumOfCommitThreads = 1;
int32_t tsNumOfCommitThreads = 4;
float tsRatioOfQueryCores = 1.0f;
int8_t tsDaylight = 0;
char tsTimezone[TSDB_TIMEZONE_LEN] = {0};
......@@ -71,7 +71,7 @@ int32_t tsMaxBinaryDisplayWidth = 30;
int32_t tsCompressMsgSize = -1;
// client
int32_t tsMaxSQLStringLen = TSDB_MAX_SQL_LEN;
int32_t tsMaxSQLStringLen = TSDB_MAX_ALLOWED_SQL_LEN;
int8_t tsTscEnableRecordSql = 0;
// the maximum number of results for projection query on super table that are returned from
......
......@@ -8,7 +8,7 @@ IF (TD_MVN_INSTALLED)
ADD_CUSTOM_COMMAND(OUTPUT ${JDBC_CMD_NAME}
POST_BUILD
COMMAND mvn -Dmaven.test.skip=true install -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.22-dist.jar ${LIBRARY_OUTPUT_PATH}
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.24-dist.jar ${LIBRARY_OUTPUT_PATH}
COMMAND mvn -Dmaven.test.skip=true clean -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml
COMMENT "build jdbc driver")
ADD_CUSTOM_TARGET(${JDBC_TARGET_NAME} ALL WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} DEPENDS ${JDBC_CMD_NAME})
......
......@@ -5,7 +5,7 @@
<groupId>com.taosdata.jdbc</groupId>
<artifactId>taos-jdbcdriver</artifactId>
<version>2.0.22</version>
<version>2.0.24</version>
<packaging>jar</packaging>
<name>JDBCDriver</name>
......@@ -37,17 +37,6 @@
</developers>
<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
......@@ -61,21 +50,20 @@
<artifactId>httpclient</artifactId>
<version>4.5.8</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>29.0-jre</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
......
......@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.taosdata.jdbc</groupId>
<artifactId>taos-jdbcdriver</artifactId>
<version>2.0.22</version>
<version>2.0.24</version>
<packaging>jar</packaging>
<name>JDBCDriver</name>
<url>https://github.com/taosdata/TDengine/tree/master/src/connector/jdbc</url>
......@@ -43,7 +43,6 @@
<version>4.13</version>
<scope>test</scope>
</dependency>
<!-- for restful -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
......@@ -55,7 +54,11 @@
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>29.0-jre</version>
</dependency>
</dependencies>
<build>
......
......@@ -30,9 +30,12 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
// do nothing
return sql;
}
@Override
public void setAutoCommit(boolean autoCommit) throws SQLException {
if (isClosed())
......@@ -448,7 +451,6 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti
if (isClosed)
throw (SQLClientInfoException) TSDBError.createSQLException(TSDBErrorNumbers.ERROR_SQLCLIENT_EXCEPTION_ON_CONNECTION_CLOSED);
for (Enumeration<Object> enumer = properties.keys(); enumer.hasMoreElements(); ) {
String name = (String) enumer.nextElement();
clientInfoProps.put(name, properties.getProperty(name));
......
package com.taosdata.jdbc;
import java.sql.ParameterMetaData;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
public abstract class AbstractParameterMetaData extends WrapperImpl implements ParameterMetaData {
private final Object[] parameters;
public AbstractParameterMetaData(Object[] parameters) {
this.parameters = parameters;
}
@Override
public int getParameterCount() throws SQLException {
return parameters.length;
}
@Override
public int isNullable(int param) throws SQLException {
return ParameterMetaData.parameterNullableUnknown;
}
@Override
public boolean isSigned(int param) throws SQLException {
if (param < 1 && param >= parameters.length)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
if (parameters[param - 1] instanceof Byte)
return true;
if (parameters[param - 1] instanceof Short)
return true;
if (parameters[param - 1] instanceof Integer)
return true;
if (parameters[param - 1] instanceof Long)
return true;
if (parameters[param - 1] instanceof Float)
return true;
if (parameters[param - 1] instanceof Double)
return true;
return false;
}
@Override
public int getPrecision(int param) throws SQLException {
if (param < 1 && param >= parameters.length)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
if (parameters[param - 1] instanceof String)
return ((String) parameters[param - 1]).length();
if (parameters[param - 1] instanceof byte[])
return ((byte[]) parameters[param - 1]).length;
return 0;
}
@Override
public int getScale(int param) throws SQLException {
if (param < 1 && param >= parameters.length)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
return 0;
}
@Override
public int getParameterType(int param) throws SQLException {
if (param < 1 && param >= parameters.length)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
if (parameters[param - 1] instanceof Timestamp)
return Types.TIMESTAMP;
if (parameters[param - 1] instanceof Byte)
return Types.TINYINT;
if (parameters[param - 1] instanceof Short)
return Types.SMALLINT;
if (parameters[param - 1] instanceof Integer)
return Types.INTEGER;
if (parameters[param - 1] instanceof Long)
return Types.BIGINT;
if (parameters[param - 1] instanceof Float)
return Types.FLOAT;
if (parameters[param - 1] instanceof Double)
return Types.DOUBLE;
if (parameters[param - 1] instanceof String)
return Types.NCHAR;
if (parameters[param - 1] instanceof byte[])
return Types.BINARY;
if (parameters[param - 1] instanceof Boolean)
return Types.BOOLEAN;
return Types.OTHER;
}
@Override
public String getParameterTypeName(int param) throws SQLException {
if (param < 1 && param >= parameters.length)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
if (parameters[param - 1] instanceof Timestamp)
return TSDBConstants.jdbcType2TaosTypeName(Types.TIMESTAMP);
if (parameters[param - 1] instanceof Byte)
return TSDBConstants.jdbcType2TaosTypeName(Types.TINYINT);
if (parameters[param - 1] instanceof Short)
return TSDBConstants.jdbcType2TaosTypeName(Types.SMALLINT);
if (parameters[param - 1] instanceof Integer)
return TSDBConstants.jdbcType2TaosTypeName(Types.INTEGER);
if (parameters[param - 1] instanceof Long)
return TSDBConstants.jdbcType2TaosTypeName(Types.BIGINT);
if (parameters[param - 1] instanceof Float)
return TSDBConstants.jdbcType2TaosTypeName(Types.FLOAT);
if (parameters[param - 1] instanceof Double)
return TSDBConstants.jdbcType2TaosTypeName(Types.DOUBLE);
if (parameters[param - 1] instanceof String)
return TSDBConstants.jdbcType2TaosTypeName(Types.NCHAR);
if (parameters[param - 1] instanceof byte[])
return TSDBConstants.jdbcType2TaosTypeName(Types.BINARY);
if (parameters[param - 1] instanceof Boolean)
return TSDBConstants.jdbcType2TaosTypeName(Types.BOOLEAN);
return parameters[param - 1].getClass().getName();
}
@Override
public String getParameterClassName(int param) throws SQLException {
if (param < 1 && param >= parameters.length)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
return parameters[param - 1].getClass().getName();
}
@Override
public int getParameterMode(int param) throws SQLException {
if (param < 1 && param >= parameters.length)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
return ParameterMetaData.parameterModeUnknown;
}
}
......@@ -11,6 +11,15 @@ import java.util.Map;
public abstract class AbstractResultSet extends WrapperImpl implements ResultSet {
private int fetchSize;
protected void checkAvailability(int columnIndex, int bounds) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
if (columnIndex < 1)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "Column Index out of range, " + columnIndex + " < 1");
if (columnIndex > bounds)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "Column Index out of range, " + columnIndex + " > " + bounds);
}
@Override
public abstract boolean next() throws SQLException;
......@@ -46,38 +55,20 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
@Override
public abstract double getDouble(int columnIndex) throws SQLException;
@Deprecated
@Override
public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
return getBigDecimal(columnIndex);
}
@Override
public byte[] getBytes(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public abstract byte[] getBytes(int columnIndex) throws SQLException;
@Override
public Date getDate(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public abstract Date getDate(int columnIndex) throws SQLException;
@Override
public Time getTime(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public abstract Time getTime(int columnIndex) throws SQLException;
@Override
public abstract Timestamp getTimestamp(int columnIndex) throws SQLException;
......@@ -147,9 +138,10 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
return getDouble(findColumn(columnLabel));
}
@Deprecated
@Override
public BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException {
return getBigDecimal(findColumn(columnLabel));
return getBigDecimal(findColumn(columnLabel), scale);
}
@Override
......@@ -214,12 +206,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
public abstract ResultSetMetaData getMetaData() throws SQLException;
@Override
public Object getObject(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public abstract Object getObject(int columnIndex) throws SQLException;
@Override
public Object getObject(String columnLabel) throws SQLException {
......@@ -243,12 +230,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
}
@Override
public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public abstract BigDecimal getBigDecimal(int columnIndex) throws SQLException;
@Override
public BigDecimal getBigDecimal(String columnLabel) throws SQLException {
......@@ -718,9 +700,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
@Override
public Object getObject(String columnLabel, Map<String, Class<?>> map) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
return getObject(findColumn(columnLabel), map);
}
@Override
......@@ -760,9 +740,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
@Override
public Date getDate(String columnLabel, Calendar cal) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
return getDate(findColumn(columnLabel), cal);
}
@Override
......@@ -774,23 +752,15 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
@Override
public Time getTime(String columnLabel, Calendar cal) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
return getTime(findColumn(columnLabel), cal);
}
@Override
public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public abstract Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException;
@Override
public Timestamp getTimestamp(String columnLabel, Calendar cal) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
return getTimestamp(findColumn(columnLabel), cal);
}
@Override
......@@ -1198,9 +1168,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
@Override
public <T> T getObject(String columnLabel, Class<T> type) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
return getObject(findColumn(columnLabel), type);
}
}
......@@ -9,6 +9,8 @@ public abstract class AbstractStatement extends WrapperImpl implements Statement
protected List<String> batchedArgs;
private int fetchSize;
@Override
public abstract ResultSet executeQuery(String sql) throws SQLException;
......
package com.taosdata.jdbc;
import com.taosdata.jdbc.bean.TSDBPreparedParam;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* this class is used to precompile the sql of tdengine insert or import ops
*/
public class SavedPreparedStatement {
private TSDBPreparedStatement tsdbPreparedStatement;
/**
* sql param List
*/
private List<TSDBPreparedParam> sqlParamList;
/**
* init param according the sql
*/
private TSDBPreparedParam initPreparedParam;
/**
* is table name dynamic in the prepared sql
*/
private boolean isTableNameDynamic;
/**
* insert or import sql template pattern, the template are the following:
* <p>
* insert/import into tableName [(field1, field2, ...)] [using stables tags(?, ?, ...) ] values(?, ?, ...) (?, ?, ...)
* <p>
* we split it to three part:
* 1. prefix, insert/import
* 2. middle, tableName [(field1, field2, ...)] [using stables tags(?, ?, ...) ]
* 3. valueList, the content after values, for example (?, ?, ...) (?, ?, ...)
*/
private Pattern sqlPattern = Pattern.compile("(?s)(?i)^\\s*(INSERT|IMPORT)\\s+INTO\\s+((?<tablename>\\S+)\\s*(\\(.*\\))?\\s+(USING\\s+(?<stableName>\\S+)\\s+TAGS\\s*\\((?<tagValue>.+)\\))?)\\s*VALUES\\s*(?<valueList>\\(.*\\)).*");
/**
* the raw sql template
*/
private String sql;
/**
* the prefix part of sql
*/
private String prefix;
/**
* the middle part of sql
*/
private String middle;
private int middleParamSize;
/**
* the valueList part of sql
*/
private String valueList;
private int valueListSize;
/**
* default param value
*/
private static final String DEFAULT_VALUE = "NULL";
private static final String PLACEHOLDER = "?";
private String tableName;
/**
* is the parameter add to batch list
*/
private boolean isAddBatch;
public SavedPreparedStatement(String sql, TSDBPreparedStatement tsdbPreparedStatement) throws SQLException {
this.sql = sql;
this.tsdbPreparedStatement = tsdbPreparedStatement;
this.sqlParamList = new ArrayList<>();
parsePreparedParam(this.sql);
}
/**
* parse the init param according the sql param
*
* @param sql
*/
private void parsePreparedParam(String sql) throws SQLException {
Matcher matcher = sqlPattern.matcher(sql);
if (matcher.find()) {
tableName = matcher.group("tablename");
if (tableName != null && PLACEHOLDER.equals(tableName)) {
// the table name is dynamic
this.isTableNameDynamic = true;
}
prefix = matcher.group(1);
middle = matcher.group(2);
valueList = matcher.group("valueList");
if (middle != null && !"".equals(middle)) {
middleParamSize = parsePlaceholder(middle);
}
if (valueList != null && !"".equals(valueList)) {
valueListSize = parsePlaceholder(valueList);
}
initPreparedParam = initDefaultParam(tableName, middleParamSize, valueListSize);
} else {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_SQL);
}
}
private TSDBPreparedParam initDefaultParam(String tableName, int middleParamSize, int valueListSize) {
TSDBPreparedParam tsdbPreparedParam = new TSDBPreparedParam(tableName);
tsdbPreparedParam.setMiddleParamList(getDefaultParamList(middleParamSize));
tsdbPreparedParam.setValueList(getDefaultParamList(valueListSize));
return tsdbPreparedParam;
}
/**
* generate the default param value list
*
* @param paramSize
* @return
*/
private List<Object> getDefaultParamList(int paramSize) {
List<Object> paramList = new ArrayList<>(paramSize);
if (paramSize > 0) {
for (int i = 0; i < paramSize; i++) {
paramList.add(i, DEFAULT_VALUE);
}
}
return paramList;
}
/**
* calculate the placeholder num
*
* @param value
* @return
*/
private int parsePlaceholder(String value) {
Pattern pattern = Pattern.compile("[?]");
Matcher matcher = pattern.matcher(value);
int result = 0;
while (matcher.find()) {
result++;
}
return result;
}
/**
* set current row params
*
* @param parameterIndex the first parameter is 1, the second is 2, ...
* @param x the parameter value
*/
public void setParam(int parameterIndex, Object x) throws SQLException {
int paramSize = this.middleParamSize + this.valueListSize;
String errorMsg = String.format("the parameterIndex %s out of the range [1, %s]", parameterIndex, paramSize);
if (parameterIndex < 1 || parameterIndex > paramSize) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE,errorMsg);
}
this.isAddBatch = false; //set isAddBatch to false
if (x == null) {
x = DEFAULT_VALUE; // set default null string
}
parameterIndex = parameterIndex - 1; // start from 0 in param list
if (this.middleParamSize > 0 && parameterIndex >= 0 && parameterIndex < this.middleParamSize) {
this.initPreparedParam.setMiddleParam(parameterIndex, x);
return;
}
if (this.valueListSize > 0 && parameterIndex >= this.middleParamSize && parameterIndex < paramSize) {
this.initPreparedParam.setValueParam(parameterIndex - this.middleParamSize, x);
return;
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE,errorMsg);
}
public void addBatch() {
addCurrentRowParamToList();
this.initPreparedParam = initDefaultParam(tableName, middleParamSize, valueListSize);
}
/**
* add current param to batch list
*/
private void addCurrentRowParamToList() {
if (initPreparedParam != null && (this.middleParamSize > 0 || this.valueListSize > 0)) {
this.sqlParamList.add(initPreparedParam); // add current param to batch list
}
this.isAddBatch = true;
}
/**
* execute the sql with batch sql
*
* @return
* @throws SQLException
*/
public int[] executeBatch() throws SQLException {
int result = executeBatchInternal();
return new int[]{result};
}
public int executeBatchInternal() throws SQLException {
if (!isAddBatch) {
addCurrentRowParamToList(); // add current param to batch list
}
//1. generate batch sql
String sql = generateExecuteSql();
//2. execute batch sql
int result = executeSql(sql);
//3. clear batch param list
this.sqlParamList.clear();
return result;
}
/**
* generate the batch sql
*
* @return
*/
private String generateExecuteSql() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(prefix);
stringBuilder.append(" into ");
if (!isTableNameDynamic) {
// tablename will not need to be replaced
String middleValue = replaceMiddleListParam(middle, sqlParamList);
stringBuilder.append(middleValue);
stringBuilder.append(" values");
stringBuilder.append(replaceValueListParam(valueList, sqlParamList));
} else {
// need to replace tablename
if (sqlParamList.size() > 0) {
TSDBPreparedParam firstPreparedParam = sqlParamList.get(0);
//replace middle part and value part of first row
String firstRow = replaceMiddleAndValuePart(firstPreparedParam);
stringBuilder.append(firstRow);
//the first param in the middleParamList is the tableName
String lastTableName = firstPreparedParam.getMiddleParamList().get(0).toString();
if (sqlParamList.size() > 1) {
for (int i = 1; i < sqlParamList.size(); i++) {
TSDBPreparedParam currentParam = sqlParamList.get(i);
String currentTableName = currentParam.getMiddleParamList().get(0).toString();
if (lastTableName.equalsIgnoreCase(currentTableName)) {
// tablename is same with the last row ,so only need to append the part of value
String values = replaceTemplateParam(valueList, currentParam.getValueList());
stringBuilder.append(values);
} else {
// tablename difference with the last row
//need to replace middle part and value part
String row = replaceMiddleAndValuePart(currentParam);
stringBuilder.append(row);
lastTableName = currentTableName;
}
}
}
} else {
stringBuilder.append(middle);
stringBuilder.append(" values");
stringBuilder.append(valueList);
}
}
return stringBuilder.toString();
}
/**
* replace the middle and value part
*
* @param tsdbPreparedParam
* @return
*/
private String replaceMiddleAndValuePart(TSDBPreparedParam tsdbPreparedParam) {
StringBuilder stringBuilder = new StringBuilder(" ");
String middlePart = replaceTemplateParam(middle, tsdbPreparedParam.getMiddleParamList());
stringBuilder.append(middlePart);
stringBuilder.append(" values ");
String valuePart = replaceTemplateParam(valueList, tsdbPreparedParam.getValueList());
stringBuilder.append(valuePart);
stringBuilder.append(" ");
return stringBuilder.toString();
}
/**
* replace the placeholder of the middle part of sql template with TSDBPreparedParam list
*
* @param template
* @param sqlParamList
* @return
*/
private String replaceMiddleListParam(String template, List<TSDBPreparedParam> sqlParamList) {
if (sqlParamList.size() > 0) {
//becase once the subTableName is static then will be ignore the tag which after the first setTag
return replaceTemplateParam(template, sqlParamList.get(0).getMiddleParamList());
}
return template;
}
/**
* replace the placeholder of the template with TSDBPreparedParam list
*
* @param template
* @param sqlParamList
* @return
*/
private String replaceValueListParam(String template, List<TSDBPreparedParam> sqlParamList) {
StringBuilder stringBuilder = new StringBuilder();
if (sqlParamList.size() > 0) {
for (TSDBPreparedParam tsdbPreparedParam : sqlParamList) {
String tmp = replaceTemplateParam(template, tsdbPreparedParam.getValueList());
stringBuilder.append(tmp);
}
} else {
stringBuilder.append(template);
}
return stringBuilder.toString();
}
/**
* replace the placeholder of the template with paramList
*
* @param template
* @param paramList
* @return
*/
private String replaceTemplateParam(String template, List<Object> paramList) {
if (paramList.size() > 0) {
String tmp = template;
for (int i = 0; i < paramList.size(); ++i) {
String paraStr = getParamString(paramList.get(i));
tmp = tmp.replaceFirst("[" + PLACEHOLDER + "]", paraStr);
}
return tmp;
} else {
return template;
}
}
/**
* get the string of param object
*
* @param paramObj
* @return
*/
private String getParamString(Object paramObj) {
String paraStr = paramObj.toString();
if (paramObj instanceof Timestamp || (paramObj instanceof String && !DEFAULT_VALUE.equalsIgnoreCase(paraStr))) {
paraStr = "'" + paraStr + "'";
}
return paraStr;
}
private int executeSql(String sql) throws SQLException {
return tsdbPreparedStatement.executeUpdate(sql);
}
}
......@@ -27,10 +27,6 @@ public class TSDBConnection extends AbstractConnection {
return this.batchFetch;
}
public void setBatchFetch(Boolean batchFetch) {
this.batchFetch = batchFetch;
}
public TSDBConnection(Properties info, TSDBDatabaseMetaData meta) throws SQLException {
this.databaseMetaData = meta;
connect(info.getProperty(TSDBDriver.PROPERTY_KEY_HOST),
......@@ -61,9 +57,7 @@ public class TSDBConnection extends AbstractConnection {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
TSDBStatement statement = new TSDBStatement(this, this.connector);
statement.setConnection(this);
return statement;
return new TSDBStatement(this, this.connector);
}
public TSDBSubscribe subscribe(String topic, String sql, boolean restart) throws SQLException {
......@@ -79,10 +73,8 @@ public class TSDBConnection extends AbstractConnection {
}
public PreparedStatement prepareStatement(String sql) throws SQLException {
if (isClosed()) {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
return new TSDBPreparedStatement(this, this.connector, sql);
}
......@@ -104,11 +96,4 @@ public class TSDBConnection extends AbstractConnection {
return this.databaseMetaData;
}
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
}
}
\ No newline at end of file
package com.taosdata.jdbc;
public class TSDBParameterMetaData extends AbstractParameterMetaData {
public TSDBParameterMetaData(Object[] parameters) {
super(parameters);
}
}
......@@ -18,6 +18,7 @@ import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.net.URL;
import java.nio.charset.Charset;
import java.sql.*;
import java.util.ArrayList;
import java.util.Calendar;
......@@ -30,36 +31,49 @@ import java.util.regex.Pattern;
* compatibility needs.
*/
public class TSDBPreparedStatement extends TSDBStatement implements PreparedStatement {
protected String rawSql;
protected String sql;
protected ArrayList<Object> parameters = new ArrayList<>();
private String rawSql;
private String sql;
// private ArrayList<Object> parameters = new ArrayList<>();
private Object[] parameters;
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 ParameterMetaData parameterMetaData;
// private SavedPreparedStatement savedPreparedStatement;
private volatile TSDBParameterMetaData parameterMetaData;
TSDBPreparedStatement(TSDBConnection connection, TSDBJNIConnector connecter, String sql) {
super(connection, connecter);
init(sql);
if (sql.contains("?")) {
int parameterCnt = 0;
for (int i = 0; i < sql.length(); i++) {
if ('?' == sql.charAt(i)) {
parameterCnt++;
}
}
parameters = new Object[parameterCnt];
this.isPrepared = true;
}
}
private void init(String sql) {
this.rawSql = sql;
preprocessSql();
// this.isSaved = isSavedSql(this.rawSql);
// if (this.isSaved) {
// try {
// this.savedPreparedStatement = new SavedPreparedStatement(this.rawSql, this);
// } catch (SQLException e) {
// e.printStackTrace();
// }
// }
this.isSaved = isSavedSql(this.rawSql);
if (this.isSaved) {
try {
this.savedPreparedStatement = new SavedPreparedStatement(this.rawSql, this);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
......@@ -75,19 +89,11 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
@Override
public int[] executeBatch() throws SQLException {
if (isSaved) {
return this.savedPreparedStatement.executeBatch();
} else {
return super.executeBatch();
}
}
public ArrayList<Object> getParameters() {
return parameters;
}
public void setParameters(ArrayList<Object> parameters) {
this.parameters = parameters;
// if (isSaved) {
// return this.savedPreparedStatement.executeBatch();
// } else {
return super.executeBatch();
// }
}
/*
......@@ -151,41 +157,73 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
*
* @return a string of the native sql statement for TSDB
*/
private String getNativeSql() {
this.sql = this.rawSql;
for (int i = 0; i < parameters.size(); ++i) {
Object para = parameters.get(i);
// 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 {
String sql = 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) {
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 + "'";
}
this.sql = this.sql.replaceFirst("[?]", paraStr);
sql = sql.replaceFirst("[?]", paraStr);
} else {
this.sql = this.sql.replaceFirst("[?]", "NULL");
sql = sql.replaceFirst("[?]", "NULL");
}
}
parameters.clear();
clearParameters();
return sql;
}
@Override
public ResultSet executeQuery() throws SQLException {
if (isSaved) {
this.savedPreparedStatement.executeBatchInternal();
return null;
} else {
return super.executeQuery(getNativeSql());
}
// if (isSaved) {
// this.savedPreparedStatement.executeBatchInternal();
// return null;
// } else {
if (!isPrepared)
return executeQuery(this.rawSql);
final String sql = getNativeSql(this.rawSql);
return executeQuery(sql);
// }
}
@Override
public int executeUpdate() throws SQLException {
if (isSaved) {
return this.savedPreparedStatement.executeBatchInternal();
} else {
return super.executeUpdate(getNativeSql());
}
// if (isSaved) {
// return this.savedPreparedStatement.executeBatchInternal();
// } else {
if (!isPrepared)
return executeUpdate(this.rawSql);
String sql = getNativeSql(this.rawSql);
return executeUpdate(sql);
// }
}
private boolean isSupportedSQLType(int sqlType) {
......@@ -201,35 +239,6 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
case Types.BINARY:
case Types.NCHAR:
return true;
case Types.ARRAY:
case Types.BIT:
case Types.BLOB:
case Types.CHAR:
case Types.CLOB:
case Types.DATALINK:
case Types.DATE:
case Types.DECIMAL:
case Types.DISTINCT:
case Types.JAVA_OBJECT:
case Types.LONGNVARCHAR:
case Types.LONGVARBINARY:
case Types.LONGVARCHAR:
case Types.NCLOB:
case Types.NULL:
case Types.NUMERIC:
case Types.NVARCHAR:
case Types.OTHER:
case Types.REAL:
case Types.REF:
case Types.REF_CURSOR:
case Types.ROWID:
case Types.SQLXML:
case Types.STRUCT:
case Types.TIME:
case Types.TIME_WITH_TIMEZONE:
case Types.TIMESTAMP_WITH_TIMEZONE:
case Types.VARBINARY:
case Types.VARCHAR:
default:
return false;
}
......@@ -259,7 +268,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
public void setByte(int parameterIndex, byte x) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
setObject(parameterIndex,x);
}
@Override
......@@ -315,7 +324,8 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
public void setBytes(int parameterIndex, byte[] x) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
setObject(parameterIndex,x);
}
@Override
......@@ -365,45 +375,63 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
public void clearParameters() throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
parameters.clear();
// parameters.clear();
parameters = new Object[parameters.length];
}
@Override
public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void setObject(int parameterIndex, Object x) throws SQLException {
if (isSaved) {
this.savedPreparedStatement.setParam(parameterIndex, x);
} else {
parameters.add(x);
}
// if (isSaved) {
// this.savedPreparedStatement.setParam(parameterIndex, x);
// } else {
if (parameterIndex < 1 && parameterIndex >= parameters.length)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
parameters[parameterIndex - 1] = x;
// parameters.add(x);
// }
}
@Override
public boolean execute() throws SQLException {
if (isSaved) {
int result = this.savedPreparedStatement.executeBatchInternal();
return result > 0;
} else {
return super.execute(getNativeSql());
}
// if (isSaved) {
// int result = this.savedPreparedStatement.executeBatchInternal();
// return result > 0;
// } else {
if (!isPrepared)
return execute(this.rawSql);
final String sql = getNativeSql(this.rawSql);
return execute(sql);
// }
}
@Override
public void addBatch() throws SQLException {
if (isSaved) {
this.savedPreparedStatement.addBatch();
// if (isSaved) {
// this.savedPreparedStatement.addBatch();
// } else {
if (this.batchedArgs == null) {
batchedArgs = new ArrayList<>();
}
if (!isPrepared) {
addBatch(this.rawSql);
} else {
if (this.batchedArgs == null) {
batchedArgs = new ArrayList<>();
}
super.addBatch(getNativeSql());
String sql = this.getConnection().nativeSQL(this.rawSql);
addBatch(sql);
}
// }
}
@Override
......@@ -491,9 +519,11 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
public ParameterMetaData getParameterMetaData() throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
//TODO: parameterMetaData not supported
// return null;
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
if (parameterMetaData == null) {
this.parameterMetaData = new TSDBParameterMetaData(parameters);
}
return this.parameterMetaData;
}
@Override
......
......@@ -14,9 +14,14 @@
*****************************************************************************/
package com.taosdata.jdbc;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
import com.google.common.primitives.Shorts;
import java.math.BigDecimal;
import java.sql.*;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
public class TSDBResultSet extends AbstractResultSet implements ResultSet {
......@@ -120,158 +125,189 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
}
public String getString(int columnIndex) throws SQLException {
String res = null;
int colIndex = getTrueColumnIndex(columnIndex);
checkAvailability(columnIndex, this.columnMetaDataList.size());
String res = null;
if (this.getBatchFetch())
return this.blockData.getString(colIndex);
return this.blockData.getString(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(colIndex);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
if (!lastWasNull) {
res = this.rowData.getString(colIndex, this.columnMetaDataList.get(colIndex).getColType());
res = this.rowData.getString(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType());
}
return res;
}
public boolean getBoolean(int columnIndex) throws SQLException {
boolean res = false;
int colIndex = getTrueColumnIndex(columnIndex);
checkAvailability(columnIndex, this.columnMetaDataList.size());
boolean res = false;
if (this.getBatchFetch())
return this.blockData.getBoolean(colIndex);
return this.blockData.getBoolean(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(colIndex);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
if (!lastWasNull) {
res = this.rowData.getBoolean(colIndex, this.columnMetaDataList.get(colIndex).getColType());
res = this.rowData.getBoolean(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType());
}
return res;
}
public byte getByte(int columnIndex) throws SQLException {
byte res = 0;
int colIndex = getTrueColumnIndex(columnIndex);
checkAvailability(columnIndex, this.columnMetaDataList.size());
byte res = 0;
if (this.getBatchFetch())
return (byte) this.blockData.getInt(colIndex);
return (byte) this.blockData.getInt(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(colIndex);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
if (!lastWasNull) {
res = (byte) this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType());
res = (byte) this.rowData.getInt(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType());
}
return res;
}
public short getShort(int columnIndex) throws SQLException {
short res = 0;
int colIndex = getTrueColumnIndex(columnIndex);
checkAvailability(columnIndex, this.columnMetaDataList.size());
short res = 0;
if (this.getBatchFetch())
return (short) this.blockData.getInt(colIndex);
return (short) this.blockData.getInt(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(colIndex);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
if (!lastWasNull) {
res = (short) this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType());
res = (short) this.rowData.getInt(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType());
}
return res;
}
public int getInt(int columnIndex) throws SQLException {
int res = 0;
int colIndex = getTrueColumnIndex(columnIndex);
checkAvailability(columnIndex, this.columnMetaDataList.size());
int res = 0;
if (this.getBatchFetch())
return this.blockData.getInt(colIndex);
return this.blockData.getInt(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(colIndex);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
if (!lastWasNull) {
res = this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType());
res = this.rowData.getInt(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType());
}
return res;
}
public long getLong(int columnIndex) throws SQLException {
long res = 0L;
int colIndex = getTrueColumnIndex(columnIndex);
checkAvailability(columnIndex, this.columnMetaDataList.size());
long res = 0L;
if (this.getBatchFetch())
return this.blockData.getLong(colIndex);
return this.blockData.getLong(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(colIndex);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
if (!lastWasNull) {
res = this.rowData.getLong(colIndex, this.columnMetaDataList.get(colIndex).getColType());
res = this.rowData.getLong(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType());
}
return res;
}
public float getFloat(int columnIndex) throws SQLException {
float res = 0;
int colIndex = getTrueColumnIndex(columnIndex);
checkAvailability(columnIndex, this.columnMetaDataList.size());
float res = 0;
if (this.getBatchFetch())
return (float) this.blockData.getDouble(colIndex);
return (float) this.blockData.getDouble(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(colIndex);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
if (!lastWasNull)
res = this.rowData.getFloat(colIndex, this.columnMetaDataList.get(colIndex).getColType());
res = this.rowData.getFloat(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType());
return res;
}
public double getDouble(int columnIndex) throws SQLException {
double res = 0;
int colIndex = getTrueColumnIndex(columnIndex);
checkAvailability(columnIndex, this.columnMetaDataList.size());
double res = 0;
if (this.getBatchFetch())
return this.blockData.getDouble(colIndex);
return this.blockData.getDouble(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(colIndex);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
if (!lastWasNull) {
res = this.rowData.getDouble(colIndex, this.columnMetaDataList.get(colIndex).getColType());
res = this.rowData.getDouble(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType());
}
return res;
}
@Deprecated
public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
return new BigDecimal(getLong(columnIndex));
public byte[] getBytes(int columnIndex) throws SQLException {
checkAvailability(columnIndex, this.columnMetaDataList.size());
Object value = this.rowData.get(columnIndex - 1);
if (value == null)
return null;
int colType = this.columnMetaDataList.get(columnIndex - 1).getColType();
switch (colType) {
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return Longs.toByteArray((Long) value);
case TSDBConstants.TSDB_DATA_TYPE_INT:
return Ints.toByteArray((int) value);
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
return Shorts.toByteArray((Short) value);
case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
return new byte[]{(byte) value};
}
return value.toString().getBytes();
}
public byte[] getBytes(int columnIndex) throws SQLException {
return getString(columnIndex).getBytes();
@Override
public Date getDate(int columnIndex) throws SQLException {
Timestamp timestamp = getTimestamp(columnIndex);
return timestamp == null ? null : new Date(timestamp.getTime());
}
@Override
public Time getTime(int columnIndex) throws SQLException {
Timestamp timestamp = getTimestamp(columnIndex);
return timestamp == null ? null : new Time(timestamp.getTime());
}
public Timestamp getTimestamp(int columnIndex) throws SQLException {
checkAvailability(columnIndex, this.columnMetaDataList.size());
Timestamp res = null;
int colIndex = getTrueColumnIndex(columnIndex);
if (this.getBatchFetch())
return this.blockData.getTimestamp(columnIndex);
return this.blockData.getTimestamp(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(colIndex);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
if (!lastWasNull) {
res = this.rowData.getTimestamp(colIndex);
res = this.rowData.getTimestamp(columnIndex - 1);
}
return res;
}
public ResultSetMetaData getMetaData() throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
return new TSDBResultSetMetaData(this.columnMetaDataList);
}
@Override
public Object getObject(int columnIndex) throws SQLException {
int colIndex = getTrueColumnIndex(columnIndex);
checkAvailability(columnIndex, this.columnMetaDataList.size());
Object res = null;
if (this.getBatchFetch())
return this.blockData.get(colIndex);
return this.blockData.get(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(colIndex);
return this.rowData.get(colIndex);
}
@Override
public Object getObject(String columnLabel) throws SQLException {
return this.getObject(this.findColumn(columnLabel));
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
if (!lastWasNull) {
int colType = this.columnMetaDataList.get(columnIndex - 1).getColType();
if (colType == TSDBConstants.TSDB_DATA_TYPE_BINARY)
res = ((String) this.rowData.get(columnIndex - 1)).getBytes();
else
res = this.rowData.get(columnIndex - 1);
}
return res;
}
public int findColumn(String columnLabel) throws SQLException {
......@@ -285,14 +321,31 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
@Override
public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
int colIndex = getTrueColumnIndex(columnIndex);
if (this.getBatchFetch())
return new BigDecimal(this.blockData.getLong(columnIndex - 1));
if (!this.getBatchFetch()) {
this.lastWasNull = this.rowData.wasNull(colIndex);
return new BigDecimal(this.rowData.getLong(colIndex, this.columnMetaDataList.get(colIndex).getColType()));
} else {
return new BigDecimal(this.blockData.getLong(colIndex));
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
BigDecimal res = null;
if (!lastWasNull) {
int colType = this.columnMetaDataList.get(columnIndex - 1).getColType();
switch (colType) {
case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
case TSDBConstants.TSDB_DATA_TYPE_INT:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
res = new BigDecimal(Long.valueOf(this.rowData.get(columnIndex - 1).toString()));
break;
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
res = new BigDecimal(Double.valueOf(this.rowData.get(columnIndex - 1).toString()));
break;
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
return new BigDecimal(((Timestamp) this.rowData.get(columnIndex - 1)).getTime());
default:
res = new BigDecimal(this.rowData.get(columnIndex - 1).toString());
}
}
return res;
}
@Override
......@@ -398,6 +451,12 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
return this.statement;
}
@Override
public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
//TODO:did not use the specified timezone in cal
return getTimestamp(columnIndex);
}
public boolean isClosed() throws SQLException {
if (isClosed)
return true;
......@@ -408,17 +467,7 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
}
public String getNString(int columnIndex) throws SQLException {
int colIndex = getTrueColumnIndex(columnIndex);
return (String) rowData.get(colIndex);
return getString(columnIndex);
}
private int getTrueColumnIndex(int columnIndex) throws SQLException {
if (columnIndex < 1)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "columnIndex(" + columnIndex + "): < 1");
int numOfCols = this.columnMetaDataList.size();
if (columnIndex > numOfCols)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "columnIndex: " + columnIndex);
return columnIndex - 1;
}
}
......@@ -22,136 +22,160 @@ import java.util.List;
public class TSDBResultSetMetaData extends WrapperImpl implements ResultSetMetaData {
List<ColumnMetaData> colMetaDataList = null;
public TSDBResultSetMetaData(List<ColumnMetaData> metaDataList) {
this.colMetaDataList = metaDataList;
}
public int getColumnCount() throws SQLException {
return colMetaDataList.size();
}
public boolean isAutoIncrement(int column) throws SQLException {
return false;
}
public boolean isCaseSensitive(int column) throws SQLException {
return false;
}
public boolean isSearchable(int column) throws SQLException {
if (column == 1) {
return true;
}
return false;
}
public boolean isCurrency(int column) throws SQLException {
return false;
}
public int isNullable(int column) throws SQLException {
if (column == 1) {
return columnNoNulls;
}
return columnNullable;
}
public boolean isSigned(int column) throws SQLException {
ColumnMetaData meta = this.colMetaDataList.get(column - 1);
switch (meta.getColType()) {
case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
case TSDBConstants.TSDB_DATA_TYPE_INT:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
return true;
default:
return false;
}
}
public int getColumnDisplaySize(int column) throws SQLException {
return colMetaDataList.get(column - 1).getColSize();
}
public String getColumnLabel(int column) throws SQLException {
return colMetaDataList.get(column - 1).getColName();
}
public String getColumnName(int column) throws SQLException {
return colMetaDataList.get(column - 1).getColName();
}
public String getSchemaName(int column) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public int getPrecision(int column) throws SQLException {
ColumnMetaData columnMetaData = this.colMetaDataList.get(column - 1);
switch (columnMetaData.getColType()) {
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return 5;
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
return 9;
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
return columnMetaData.getColSize();
default:
return 0;
}
}
public int getScale(int column) throws SQLException {
ColumnMetaData meta = this.colMetaDataList.get(column - 1);
switch (meta.getColType()) {
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return 5;
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
return 9;
default:
return 0;
}
}
public String getTableName(int column) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public String getCatalogName(int column) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public int getColumnType(int column) throws SQLException {
ColumnMetaData meta = this.colMetaDataList.get(column - 1);
return TSDBConstants.taosType2JdbcType(meta.getColType());
}
public String getColumnTypeName(int column) throws SQLException {
ColumnMetaData meta = this.colMetaDataList.get(column - 1);
return TSDBConstants.taosType2JdbcTypeName(meta.getColType());
}
public boolean isReadOnly(int column) throws SQLException {
return true;
}
public boolean isWritable(int column) throws SQLException {
return false;
}
public boolean isDefinitelyWritable(int column) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public String getColumnClassName(int column) throws SQLException {
int columnType = getColumnType(column);
String columnClassName = "";
switch (columnType) {
case Types.TIMESTAMP:
columnClassName = Timestamp.class.getName();
List<ColumnMetaData> colMetaDataList;
public TSDBResultSetMetaData(List<ColumnMetaData> metaDataList) {
this.colMetaDataList = metaDataList;
}
public int getColumnCount() throws SQLException {
return colMetaDataList.size();
}
public boolean isAutoIncrement(int column) throws SQLException {
return false;
}
public boolean isCaseSensitive(int column) throws SQLException {
return false;
}
public boolean isSearchable(int column) throws SQLException {
if (column == 1) {
return true;
}
return false;
}
public boolean isCurrency(int column) throws SQLException {
return false;
}
public int isNullable(int column) throws SQLException {
if (column < 1 && column >= colMetaDataList.size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
if (column == 1) {
return columnNoNulls;
}
return columnNullable;
}
public boolean isSigned(int column) throws SQLException {
if (column < 1 && column >= colMetaDataList.size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
ColumnMetaData meta = this.colMetaDataList.get(column - 1);
switch (meta.getColType()) {
case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
case TSDBConstants.TSDB_DATA_TYPE_INT:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
return true;
default:
return false;
}
}
public int getColumnDisplaySize(int column) throws SQLException {
if (column < 1 && column >= colMetaDataList.size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
return colMetaDataList.get(column - 1).getColSize();
}
public String getColumnLabel(int column) throws SQLException {
if (column < 1 && column >= colMetaDataList.size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
return colMetaDataList.get(column - 1).getColName();
}
public String getColumnName(int column) throws SQLException {
if (column < 1 && column >= colMetaDataList.size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
return colMetaDataList.get(column - 1).getColName();
}
public String getSchemaName(int column) throws SQLException {
if (column < 1 && column >= colMetaDataList.size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public int getPrecision(int column) throws SQLException {
if (column < 1 && column >= colMetaDataList.size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
ColumnMetaData columnMetaData = this.colMetaDataList.get(column - 1);
switch (columnMetaData.getColType()) {
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return 5;
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
return 9;
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
return columnMetaData.getColSize();
default:
return 0;
}
}
public int getScale(int column) throws SQLException {
if (column < 1 && column >= colMetaDataList.size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
ColumnMetaData meta = this.colMetaDataList.get(column - 1);
switch (meta.getColType()) {
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return 5;
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
return 9;
default:
return 0;
}
}
public String getTableName(int column) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public String getCatalogName(int column) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public int getColumnType(int column) throws SQLException {
ColumnMetaData meta = this.colMetaDataList.get(column - 1);
return TSDBConstants.taosType2JdbcType(meta.getColType());
}
public String getColumnTypeName(int column) throws SQLException {
ColumnMetaData meta = this.colMetaDataList.get(column - 1);
return TSDBConstants.taosType2JdbcTypeName(meta.getColType());
}
public boolean isReadOnly(int column) throws SQLException {
return true;
}
public boolean isWritable(int column) throws SQLException {
return false;
}
public boolean isDefinitelyWritable(int column) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public String getColumnClassName(int column) throws SQLException {
int columnType = getColumnType(column);
String columnClassName = "";
switch (columnType) {
case Types.TIMESTAMP:
columnClassName = Timestamp.class.getName();
break;
case Types.CHAR:
columnClassName = String.class.getName();
......@@ -168,8 +192,8 @@ public class TSDBResultSetMetaData extends WrapperImpl implements ResultSetMetaD
case Types.INTEGER:
columnClassName = Integer.class.getName();
break;
case Types.SMALLINT:
columnClassName = Short.class.getName();
case Types.SMALLINT:
columnClassName = Short.class.getName();
break;
case Types.TINYINT:
columnClassName = Byte.class.getName();
......@@ -177,7 +201,7 @@ public class TSDBResultSetMetaData extends WrapperImpl implements ResultSetMetaD
case Types.BIT:
columnClassName = Boolean.class.getName();
break;
}
}
return columnClassName;
}
}
}
......@@ -21,18 +21,13 @@ import java.util.ArrayList;
import java.util.Collections;
public class TSDBResultSetRowData {
private ArrayList<Object> data = null;
private ArrayList<Object> data;
private int colSize = 0;
public TSDBResultSetRowData(int colSize) {
this.setColSize(colSize);
}
public TSDBResultSetRowData() {
this.data = new ArrayList<>();
this.setColSize(0);
}
public void clear() {
if (this.data != null) {
this.data.clear();
......@@ -71,9 +66,9 @@ public class TSDBResultSetRowData {
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return ((Long) obj) == 1L ? Boolean.TRUE : Boolean.FALSE;
default:
return false;
}
return Boolean.TRUE;
}
public void setByte(int col, byte value) {
......@@ -198,7 +193,7 @@ public class TSDBResultSetRowData {
data.set(col, value);
}
public float getFloat(int col, int srcType) throws SQLException {
public float getFloat(int col, int srcType) {
Object obj = data.get(col);
switch (srcType) {
......@@ -226,7 +221,7 @@ public class TSDBResultSetRowData {
data.set(col, value);
}
public double getDouble(int col, int srcType) throws SQLException {
public double getDouble(int col, int srcType) {
Object obj = data.get(col);
switch (srcType) {
......@@ -267,9 +262,8 @@ public class TSDBResultSetRowData {
*
* @param col column index
* @return
* @throws SQLException
*/
public String getString(int col, int srcType) throws SQLException {
public String getString(int col, int srcType) {
switch (srcType) {
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
......@@ -305,11 +299,11 @@ public class TSDBResultSetRowData {
}
public void setTimestamp(int col, long ts) {
data.set(col, ts);
data.set(col, new Timestamp(ts));
}
public Timestamp getTimestamp(int col) {
return new Timestamp((Long) data.get(col));
return (Timestamp) data.get(col);
}
public Object get(int col) {
......@@ -320,7 +314,7 @@ public class TSDBResultSetRowData {
return colSize;
}
public void setColSize(int colSize) {
private void setColSize(int colSize) {
this.colSize = colSize;
this.clear();
}
......
package com.taosdata.jdbc.bean;
import java.util.List;
/**
* tdengine batch insert or import param object
*/
public class TSDBPreparedParam {
/**
* tableName, if sTable Name is not null, and this is sub table name.
*/
private String tableName;
/**
* sub middle param list
*/
private List<Object> middleParamList;
/**
* value list
*/
private List<Object> valueList;
public TSDBPreparedParam(String tableName) {
this.tableName = tableName;
}
public String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public List<Object> getMiddleParamList() {
return middleParamList;
}
public void setMiddleParamList(List<Object> middleParamList) {
this.middleParamList = middleParamList;
}
public void setMiddleParam(int parameterIndex, Object x) {
this.middleParamList.set(parameterIndex, x);
}
public List<Object> getValueList() {
return valueList;
}
public void setValueList(List<Object> valueList) {
this.valueList = valueList;
}
public void setValueParam(int parameterIndex, Object x) {
this.valueList.set(parameterIndex, x);
}
}
package com.taosdata.jdbc.rs;
import com.taosdata.jdbc.*;
import java.sql.*;
import com.taosdata.jdbc.AbstractConnection;
import com.taosdata.jdbc.TSDBDriver;
import com.taosdata.jdbc.TSDBError;
import com.taosdata.jdbc.TSDBErrorNumbers;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class RestfulConnection extends AbstractConnection {
......@@ -55,7 +61,6 @@ public class RestfulConnection extends AbstractConnection {
public DatabaseMetaData getMetaData() throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
;
return this.metadata;
}
......
......@@ -17,7 +17,7 @@ public class RestfulDriver extends AbstractDriver {
static {
try {
DriverManager.registerDriver(new RestfulDriver());
java.sql.DriverManager.registerDriver(new RestfulDriver());
} catch (SQLException e) {
throw TSDBError.createRuntimeException(TSDBErrorNumbers.ERROR_URL_NOT_SET, e);
}
......
package com.taosdata.jdbc.rs;
import com.taosdata.jdbc.AbstractParameterMetaData;
public class RestfulParameterMetaData extends AbstractParameterMetaData {
RestfulParameterMetaData(Object[] parameters) {
super(parameters);
}
}
......@@ -7,6 +7,7 @@ import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.net.URL;
import java.nio.charset.Charset;
import java.sql.*;
import java.util.Calendar;
......@@ -30,7 +31,9 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar
parameters = new Object[parameterCnt];
this.isPrepared = true;
}
//TODO: build parameterMetaData
// build parameterMetaData
this.parameterMetaData = new RestfulParameterMetaData(parameters);
}
@Override
......@@ -60,8 +63,15 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar
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) {
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);
......@@ -92,7 +102,7 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar
public void setByte(int parameterIndex, byte x) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
setObject(parameterIndex, x);
}
@Override
......@@ -153,7 +163,7 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar
public void setBytes(int parameterIndex, byte[] x) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
setObject(parameterIndex, x);
}
@Override
......@@ -210,19 +220,16 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar
public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
setObject(parameterIndex,x);
}
@Override
public void setObject(int parameterIndex, Object x) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
if (parameterIndex < 1 && parameterIndex >= parameters.length)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
parameters[parameterIndex - 1] = x;
}
@Override
......
......@@ -2,13 +2,18 @@ package com.taosdata.jdbc.rs;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
import com.google.common.primitives.Shorts;
import com.taosdata.jdbc.AbstractResultSet;
import com.taosdata.jdbc.TSDBConstants;
import com.taosdata.jdbc.TSDBError;
import com.taosdata.jdbc.TSDBErrorNumbers;
import java.math.BigDecimal;
import java.sql.*;
import java.util.ArrayList;
import java.util.Calendar;
public class RestfulResultSet extends AbstractResultSet implements ResultSet {
private volatile boolean isClosed;
......@@ -16,7 +21,6 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
private final String database;
private final Statement statement;
// private final JSONObject resultJson;
// data
private final ArrayList<ArrayList<Object>> resultSet;
// meta
......@@ -32,7 +36,6 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
public RestfulResultSet(String database, Statement statement, JSONObject resultJson) throws SQLException {
this.database = database;
this.statement = statement;
// this.resultJson = resultJson;
// column metadata
JSONArray columnMeta = resultJson.getJSONArray("column_meta");
......@@ -73,7 +76,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
case TSDBConstants.TSDB_DATA_TYPE_INT:
return row.getInteger(colIndex);
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return row.getBigInteger(colIndex);
return row.getLong(colIndex);
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return row.getFloat(colIndex);
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
......@@ -81,9 +84,11 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
return new Timestamp(row.getDate(colIndex).getTime());
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
return row.getString(colIndex).getBytes();
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
default:
return row.getString(colIndex);
default:
return row.get(colIndex);
}
}
......@@ -130,37 +135,33 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
@Override
public String getString(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
if (columnIndex > resultSet.get(pos).size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "Column Index out of range, " + columnIndex + " > " + resultSet.get(pos).size());
checkAvailability(columnIndex, resultSet.get(pos).size());
columnIndex = getTrueColumnIndex(columnIndex);
Object value = resultSet.get(pos).get(columnIndex);
return value == null ? null : value.toString();
Object value = resultSet.get(pos).get(columnIndex - 1);
if (value == null)
return null;
if (value instanceof byte[])
return new String((byte[]) value);
return value.toString();
}
@Override
public boolean getBoolean(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
if (columnIndex > resultSet.get(pos).size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "Column Index out of range, " + columnIndex + " > " + resultSet.get(pos).size());
checkAvailability(columnIndex, resultSet.get(pos).size());
columnIndex = getTrueColumnIndex(columnIndex);
int result = getInt(columnIndex);
return result == 0 ? false : true;
Object value = resultSet.get(pos).get(columnIndex - 1);
if (value == null)
return false;
if (value instanceof Boolean)
return (boolean) value;
return Boolean.valueOf(value.toString());
}
@Override
public byte getByte(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
if (columnIndex > resultSet.get(pos).size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "Column Index out of range, " + columnIndex + " > " + resultSet.get(pos).size());
checkAvailability(columnIndex, resultSet.get(pos).size());
columnIndex = getTrueColumnIndex(columnIndex);
Object value = resultSet.get(pos).get(columnIndex);
Object value = resultSet.get(pos).get(columnIndex - 1);
if (value == null)
return 0;
long valueAsLong = Long.parseLong(value.toString());
......@@ -179,13 +180,9 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
@Override
public short getShort(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
if (columnIndex > resultSet.get(pos).size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "Column Index out of range, " + columnIndex + " > " + resultSet.get(pos).size());
checkAvailability(columnIndex, resultSet.get(pos).size());
columnIndex = getTrueColumnIndex(columnIndex);
Object value = resultSet.get(pos).get(columnIndex);
Object value = resultSet.get(pos).get(columnIndex - 1);
if (value == null)
return 0;
long valueAsLong = Long.parseLong(value.toString());
......@@ -198,13 +195,9 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
@Override
public int getInt(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
if (columnIndex > resultSet.get(pos).size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "Column Index out of range, " + columnIndex + " > " + resultSet.get(pos).size());
checkAvailability(columnIndex, resultSet.get(pos).size());
columnIndex = getTrueColumnIndex(columnIndex);
Object value = resultSet.get(pos).get(columnIndex);
Object value = resultSet.get(pos).get(columnIndex - 1);
if (value == null)
return 0;
long valueAsLong = Long.parseLong(value.toString());
......@@ -217,13 +210,9 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
@Override
public long getLong(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
if (columnIndex > resultSet.get(pos).size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "Column Index out of range, " + columnIndex + " > " + resultSet.get(pos).size());
checkAvailability(columnIndex, resultSet.get(pos).size());
columnIndex = getTrueColumnIndex(columnIndex);
Object value = resultSet.get(pos).get(columnIndex);
Object value = resultSet.get(pos).get(columnIndex - 1);
if (value == null)
return 0;
......@@ -240,64 +229,99 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
@Override
public float getFloat(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
if (columnIndex > resultSet.get(pos).size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "Column Index out of range, " + columnIndex + " > " + resultSet.get(pos).size());
checkAvailability(columnIndex, resultSet.get(pos).size());
columnIndex = getTrueColumnIndex(columnIndex);
return Float.parseFloat(resultSet.get(pos).get(columnIndex).toString());
Object value = resultSet.get(pos).get(columnIndex - 1);
if (value == null)
return 0;
if (value instanceof Float || value instanceof Double)
return (float) value;
return Float.parseFloat(value.toString());
}
@Override
public double getDouble(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
if (columnIndex > resultSet.get(pos).size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "Column Index out of range, " + columnIndex + " > " + resultSet.get(pos).size());
checkAvailability(columnIndex, resultSet.get(pos).size());
columnIndex = getTrueColumnIndex(columnIndex);
return Double.parseDouble(resultSet.get(pos).get(columnIndex).toString());
Object value = resultSet.get(pos).get(columnIndex - 1);
if (value == null)
return 0;
if (value instanceof Double || value instanceof Float)
return (double) value;
return Double.parseDouble(value.toString());
}
private int getTrueColumnIndex(int columnIndex) throws SQLException {
if (columnIndex < 1) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE
, "Column Index out of range, " + columnIndex + " < 1");
}
@Override
public byte[] getBytes(int columnIndex) throws SQLException {
checkAvailability(columnIndex, resultSet.get(pos).size());
int numOfCols = resultSet.get(pos).size();
if (columnIndex > numOfCols) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE
, "Column Index out of range, " + columnIndex + " > " + numOfCols);
}
Object value = resultSet.get(pos).get(columnIndex - 1);
if (value == null)
return null;
if (value instanceof byte[])
return (byte[]) value;
if (value instanceof String)
return ((String) value).getBytes();
if (value instanceof Long)
return Longs.toByteArray((long) value);
if (value instanceof Integer)
return Ints.toByteArray((int) value);
if (value instanceof Short)
return Shorts.toByteArray((short) value);
if (value instanceof Byte)
return new byte[]{(byte) value};
return value.toString().getBytes();
}
return columnIndex - 1;
@Override
public Date getDate(int columnIndex) throws SQLException {
checkAvailability(columnIndex, resultSet.get(pos).size());
Object value = resultSet.get(pos).get(columnIndex - 1);
if (value == null)
return null;
if (value instanceof Timestamp)
return new Date(((Timestamp) value).getTime());
return Date.valueOf(value.toString());
}
@Override
public Time getTime(int columnIndex) throws SQLException {
checkAvailability(columnIndex, resultSet.get(pos).size());
Object value = resultSet.get(pos).get(columnIndex - 1);
if (value == null)
return null;
if (value instanceof Timestamp)
return new Time(((Timestamp) value).getTime());
return Time.valueOf(value.toString());
}
@Override
public Timestamp getTimestamp(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
checkAvailability(columnIndex, resultSet.get(pos).size());
columnIndex = getTrueColumnIndex(columnIndex);
String strDate = resultSet.get(pos).get(columnIndex).toString();
// strDate = strDate.substring(1, strDate.length() - 1);
return Timestamp.valueOf(strDate);
Object value = resultSet.get(pos).get(columnIndex - 1);
if (value == null)
return null;
if (value instanceof Timestamp)
return (Timestamp) value;
return Timestamp.valueOf(value.toString());
}
/*************************************************************************************************************/
@Override
public ResultSetMetaData getMetaData() throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
return this.metaData;
}
@Override
public Object getObject(String columnLabel) throws SQLException {
return getObject(findColumn(columnLabel));
public Object getObject(int columnIndex) throws SQLException {
checkAvailability(columnIndex, resultSet.get(pos).size());
return resultSet.get(pos).get(columnIndex - 1);
}
@Override
......@@ -311,6 +335,23 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
return columnIndex + 1;
}
@Override
public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
checkAvailability(columnIndex, resultSet.get(pos).size());
Object value = resultSet.get(pos).get(columnIndex - 1);
if (value == null)
return null;
if (value instanceof Long || value instanceof Integer || value instanceof Short || value instanceof Byte)
return new BigDecimal(Long.valueOf(value.toString()));
if (value instanceof Double || value instanceof Float)
return new BigDecimal(Double.valueOf(value.toString()));
if (value instanceof Timestamp)
return new BigDecimal(((Timestamp) value).getTime());
return new BigDecimal(value.toString());
}
@Override
public boolean isBeforeFirst() throws SQLException {
if (isClosed())
......@@ -471,6 +512,12 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
return this.statement;
}
@Override
public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
//TODO:did not use the specified timezone in cal
return getTimestamp(columnIndex);
}
@Override
public boolean isClosed() throws SQLException {
return isClosed;
......
package com.taosdata.jdbc;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import javax.sql.rowset.serial.SerialBlob;
import javax.sql.rowset.serial.SerialClob;
import java.io.UnsupportedEncodingException;
import java.sql.*;
import java.util.HashMap;
import java.util.Properties;
import static org.junit.Assert.assertEquals;
public class ResultSetTest {
static Connection connection;
static Statement statement;
static String dbName = "test";
static String tName = "t0";
static String host = "localhost";
static ResultSet resSet;
@BeforeClass
public static void createDatabaseAndTable() {
try {
Class.forName("com.taosdata.jdbc.TSDBDriver");
Properties properties = new Properties();
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/", properties);
statement = connection.createStatement();
statement.executeUpdate("drop database if exists " + dbName);
statement.executeUpdate("create database if not exists " + dbName);
statement.execute("use " + dbName);
statement.executeUpdate("create table if not exists " + dbName + "." + tName + " (ts timestamp, k1 int, k2 bigint, k3 float, k4 double, k5 binary(30), k6 smallint, k7 bool, k8 nchar(20))");
} catch (ClassNotFoundException | SQLException e) {
return;
}
}
@Test
public void testResultSet() {
String sql;
long ts = 1496732686000l;
int v1 = 2147483600;
long v2 = ts + 1000;
float v3 = 3.1415926f;
double v4 = 3.1415926535897;
String v5 = "涛思数据,强~!";
short v6 = 12;
boolean v7 = false;
String v8 = "TDengine is powerful";
sql = "insert into " + dbName + "." + tName + " values (" + ts + "," + v1 + "," + v2 + "," + v3 + "," + v4
+ ",\"" + v5 + "\"," + v6 + "," + v7 + ",\"" + v8 + "\")";
try {
statement.executeUpdate(sql);
assertEquals(1, statement.getUpdateCount());
} catch (SQLException e) {
assert false : "insert error " + e.getMessage();
}
try {
statement.execute("select * from " + dbName + "." + tName + " where ts = " + ts);
resSet = statement.getResultSet();
System.out.println(((TSDBResultSet) resSet).getRowData());
while (resSet.next()) {
assertEquals(ts, resSet.getLong(1));
assertEquals(ts, resSet.getLong("ts"));
System.out.println(resSet.getTimestamp(1));
assertEquals(v1, resSet.getInt(2));
assertEquals(v1, resSet.getInt("k1"));
assertEquals(v2, resSet.getLong(3));
assertEquals(v2, resSet.getLong("k2"));
assertEquals(v3, resSet.getFloat(4), 7);
assertEquals(v3, resSet.getFloat("k3"), 7);
assertEquals(v4, resSet.getDouble(5), 13);
assertEquals(v4, resSet.getDouble("k4"), 13);
assertEquals(v5, resSet.getString(6));
assertEquals(v5, resSet.getString("k5"));
assertEquals(v6, resSet.getShort(7));
assertEquals(v6, resSet.getShort("k6"));
assertEquals(v7, resSet.getBoolean(8));
assertEquals(v7, resSet.getBoolean("k7"));
assertEquals(v8, resSet.getString(9));
assertEquals(v8, resSet.getString("k8"));
resSet.getBytes(9);
resSet.getObject(6);
resSet.getObject("k8");
}
if (!resSet.isClosed()) {
resSet.close();
}
} catch (SQLException e) {
assert false : "insert error " + e.getMessage();
}
}
@Test(expected = SQLException.class)
public void testUnsupport() throws SQLException, UnsupportedEncodingException {
statement.execute("show databases");
resSet = statement.getResultSet();
Assert.assertNotNull(resSet.unwrap(TSDBResultSet.class));
Assert.assertTrue(resSet.isWrapperFor(TSDBResultSet.class));
resSet.getUnicodeStream(null);
resSet.getBinaryStream(null);
resSet.getAsciiStream("");
resSet.getUnicodeStream(null);
resSet.getBinaryStream(null);
resSet.getWarnings();
resSet.clearWarnings();
resSet.getCursorName();
resSet.getCharacterStream(null);
resSet.getCharacterStream(null);
resSet.isBeforeFirst();
resSet.isAfterLast();
resSet.isFirst();
resSet.isLast();
resSet.beforeFirst();
resSet.afterLast();
resSet.first();
resSet.last();
resSet.getRow();
resSet.absolute(1);
resSet.relative(1);
resSet.previous();
resSet.setFetchDirection(0);
resSet.getFetchDirection();
resSet.setFetchSize(0);
resSet.getFetchSize();
resSet.getConcurrency();
resSet.rowUpdated();
resSet.rowInserted();
resSet.rowDeleted();
resSet.updateNull(null);
resSet.updateBoolean(0, true);
resSet.updateByte(0, (byte) 2);
resSet.updateShort(0, (short) 1);
resSet.updateInt(0, 0);
resSet.updateLong(0, 0l);
resSet.updateFloat(0, 3.14f);
resSet.updateDouble(0, 3.1415);
resSet.updateBigDecimal(null, null);
resSet.updateString(null, null);
resSet.updateBytes(null, null);
resSet.updateDate(null, null);
resSet.updateTime(null, null);
resSet.updateTimestamp(null, null);
resSet.updateAsciiStream(null, null);
resSet.updateBinaryStream(null, null);
resSet.updateCharacterStream(null, null);
resSet.updateObject(null, null);
resSet.updateObject(null, null);
resSet.updateNull(null);
resSet.updateBoolean("", false);
resSet.updateByte("", (byte) 1);
resSet.updateShort("", (short) 1);
resSet.updateInt("", 0);
resSet.updateLong("", 0l);
resSet.updateFloat("", 3.14f);
resSet.updateDouble("", 3.1415);
resSet.updateBigDecimal(null, null);
resSet.updateString(null, null);
resSet.updateBytes(null, null);
resSet.updateDate(null, null);
resSet.updateTime(null, null);
resSet.updateTimestamp(null, null);
resSet.updateAsciiStream(null, null);
resSet.updateBinaryStream(null, null);
resSet.updateCharacterStream(null, null);
resSet.updateObject(null, null);
resSet.updateObject(null, null);
resSet.insertRow();
resSet.updateRow();
resSet.deleteRow();
resSet.refreshRow();
resSet.cancelRowUpdates();
resSet.moveToInsertRow();
resSet.moveToCurrentRow();
resSet.getStatement();
resSet.getObject(0, new HashMap<>());
resSet.getRef(null);
resSet.getBlob(null);
resSet.getClob(null);
resSet.getArray(null);
resSet.getObject("", new HashMap<>());
resSet.getRef(null);
resSet.getBlob(null);
resSet.getClob(null);
resSet.getArray(null);
resSet.getDate(null, null);
resSet.getDate(null, null);
resSet.getTime(null, null);
resSet.getTime(null, null);
resSet.getTimestamp(null, null);
resSet.getTimestamp(null, null);
resSet.getURL(null);
resSet.getURL(null);
resSet.updateRef(null, null);
resSet.updateRef(null, null);
resSet.updateBlob(0, new SerialBlob("".getBytes("UTF8")));
resSet.updateBlob("", new SerialBlob("".getBytes("UTF8")));
resSet.updateClob("", new SerialClob("".toCharArray()));
resSet.updateClob(0, new SerialClob("".toCharArray()));
resSet.updateArray(null, null);
resSet.updateArray(null, null);
resSet.getRowId(null);
resSet.getRowId(null);
resSet.updateRowId(null, null);
resSet.updateRowId(null, null);
resSet.getHoldability();
resSet.updateNString(null, null);
resSet.updateNString(null, null);
resSet.getNClob(null);
resSet.getNClob(null);
resSet.getSQLXML(null);
resSet.getSQLXML(null);
resSet.updateSQLXML(null, null);
resSet.updateSQLXML(null, null);
resSet.getNCharacterStream(null);
resSet.getNCharacterStream(null);
resSet.updateNCharacterStream(null, null);
resSet.updateNCharacterStream(null, null);
resSet.updateAsciiStream(null, null);
resSet.updateBinaryStream(null, null);
resSet.updateCharacterStream(null, null);
resSet.updateAsciiStream(null, null);
resSet.updateBinaryStream(null, null);
resSet.updateCharacterStream(null, null);
resSet.updateNCharacterStream(null, null);
resSet.updateNCharacterStream(null, null);
resSet.updateAsciiStream(null, null);
resSet.updateBinaryStream(null, null);
resSet.updateCharacterStream(null, null);
resSet.updateAsciiStream(null, null);
resSet.updateBinaryStream(null, null);
resSet.updateCharacterStream(null, null);
}
@Test
public void testBatch() throws SQLException {
String[] sqls = new String[]{"insert into test.t0 values (1496732686001,2147483600,1496732687000,3.1415925,3.1415926535897," +
"'涛思数据,强~',12,0,'TDengine is powerful')", "insert into test.t0 values (1496732686002,2147483600,1496732687000,3.1415925,3.1415926535897," +
"'涛思数据,强~',12,1,'TDengine is powerful')"};
for (String sql : sqls) {
statement.addBatch(sql);
}
int[] res = statement.executeBatch();
assertEquals(res.length, 2);
statement.clearBatch();
}
@AfterClass
public static void close() {
try {
statement.executeUpdate("drop database " + dbName);
if (statement != null)
statement.close();
if (connection != null)
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
......@@ -233,7 +233,7 @@ public class TSDBConnectionTest {
int status = rs.getInt("server_status()");
Assert.assertEquals(1, status);
conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
}
@Test(expected = SQLFeatureNotSupportedException.class)
......
package com.taosdata.jdbc;
import com.taosdata.jdbc.rs.RestfulParameterMetaData;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import java.sql.*;
public class TSDBParameterMetaDataTest {
private static final String host = "127.0.0.1";
private static Connection conn;
private static final String sql_insert = "insert into t1 values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
private static PreparedStatement pstmt_insert;
private static final String sql_select = "select * from t1 where ts > ? and ts <= ? and f1 >= ?";
private static PreparedStatement pstmt_select;
private static ParameterMetaData parameterMetaData_insert;
private static ParameterMetaData parameterMetaData_select;
@Test
public void getParameterCount() throws SQLException {
Assert.assertEquals(10, parameterMetaData_insert.getParameterCount());
}
@Test
public void isNullable() throws SQLException {
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(1));
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(2));
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(3));
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(4));
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(5));
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(6));
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(7));
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(8));
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(9));
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(10));
}
@Test
public void isSigned() throws SQLException {
Assert.assertEquals(false, parameterMetaData_insert.isSigned(1));
Assert.assertEquals(true, parameterMetaData_insert.isSigned(2));
Assert.assertEquals(true, parameterMetaData_insert.isSigned(3));
Assert.assertEquals(true, parameterMetaData_insert.isSigned(4));
Assert.assertEquals(true, parameterMetaData_insert.isSigned(5));
Assert.assertEquals(true, parameterMetaData_insert.isSigned(6));
Assert.assertEquals(true, parameterMetaData_insert.isSigned(7));
Assert.assertEquals(false, parameterMetaData_insert.isSigned(8));
Assert.assertEquals(false, parameterMetaData_insert.isSigned(9));
Assert.assertEquals(false, parameterMetaData_insert.isSigned(10));
}
@Test
public void getPrecision() throws SQLException {
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(1));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(2));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(3));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(4));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(5));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(6));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(7));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(8));
Assert.assertEquals(5, parameterMetaData_insert.getPrecision(9));
Assert.assertEquals(5, parameterMetaData_insert.getPrecision(10));
}
@Test
public void getScale() throws SQLException {
Assert.assertEquals(0, parameterMetaData_insert.getScale(1));
Assert.assertEquals(0, parameterMetaData_insert.getScale(2));
Assert.assertEquals(0, parameterMetaData_insert.getScale(3));
Assert.assertEquals(0, parameterMetaData_insert.getScale(4));
Assert.assertEquals(0, parameterMetaData_insert.getScale(5));
Assert.assertEquals(0, parameterMetaData_insert.getScale(6));
Assert.assertEquals(0, parameterMetaData_insert.getScale(7));
Assert.assertEquals(0, parameterMetaData_insert.getScale(8));
Assert.assertEquals(0, parameterMetaData_insert.getScale(9));
Assert.assertEquals(0, parameterMetaData_insert.getScale(10));
}
@Test
public void getParameterType() throws SQLException {
Assert.assertEquals(Types.TIMESTAMP, parameterMetaData_insert.getParameterType(1));
Assert.assertEquals(Types.INTEGER, parameterMetaData_insert.getParameterType(2));
Assert.assertEquals(Types.BIGINT, parameterMetaData_insert.getParameterType(3));
Assert.assertEquals(Types.FLOAT, parameterMetaData_insert.getParameterType(4));
Assert.assertEquals(Types.DOUBLE, parameterMetaData_insert.getParameterType(5));
Assert.assertEquals(Types.SMALLINT, parameterMetaData_insert.getParameterType(6));
Assert.assertEquals(Types.TINYINT, parameterMetaData_insert.getParameterType(7));
Assert.assertEquals(Types.BOOLEAN, parameterMetaData_insert.getParameterType(8));
Assert.assertEquals(Types.BINARY, parameterMetaData_insert.getParameterType(9));
Assert.assertEquals(Types.NCHAR, parameterMetaData_insert.getParameterType(10));
}
@Test
public void getParameterTypeName() throws SQLException {
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.TIMESTAMP), parameterMetaData_insert.getParameterTypeName(1));
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.INTEGER), parameterMetaData_insert.getParameterTypeName(2));
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.BIGINT), parameterMetaData_insert.getParameterTypeName(3));
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.FLOAT), parameterMetaData_insert.getParameterTypeName(4));
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.DOUBLE), parameterMetaData_insert.getParameterTypeName(5));
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.SMALLINT), parameterMetaData_insert.getParameterTypeName(6));
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.TINYINT), parameterMetaData_insert.getParameterTypeName(7));
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.BOOLEAN), parameterMetaData_insert.getParameterTypeName(8));
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.BINARY), parameterMetaData_insert.getParameterTypeName(9));
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.NCHAR), parameterMetaData_insert.getParameterTypeName(10));
}
@Test
public void getParameterClassName() throws SQLException {
Assert.assertEquals(Timestamp.class.getName(), parameterMetaData_insert.getParameterClassName(1));
Assert.assertEquals(Integer.class.getName(), parameterMetaData_insert.getParameterClassName(2));
Assert.assertEquals(Long.class.getName(), parameterMetaData_insert.getParameterClassName(3));
Assert.assertEquals(Float.class.getName(), parameterMetaData_insert.getParameterClassName(4));
Assert.assertEquals(Double.class.getName(), parameterMetaData_insert.getParameterClassName(5));
Assert.assertEquals(Short.class.getName(), parameterMetaData_insert.getParameterClassName(6));
Assert.assertEquals(Byte.class.getName(), parameterMetaData_insert.getParameterClassName(7));
Assert.assertEquals(Boolean.class.getName(), parameterMetaData_insert.getParameterClassName(8));
Assert.assertEquals(byte[].class.getName(), parameterMetaData_insert.getParameterClassName(9));
Assert.assertEquals(String.class.getName(), parameterMetaData_insert.getParameterClassName(10));
}
@Test
public void getParameterMode() throws SQLException {
for (int i = 1; i <= parameterMetaData_insert.getParameterCount(); i++) {
int parameterMode = parameterMetaData_insert.getParameterMode(i);
Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMode);
}
}
@Test
public void unwrap() throws SQLException {
TSDBParameterMetaData unwrap = parameterMetaData_insert.unwrap(TSDBParameterMetaData.class);
Assert.assertNotNull(unwrap);
}
@Test
public void isWrapperFor() throws SQLException {
Assert.assertTrue(parameterMetaData_insert.isWrapperFor(TSDBParameterMetaData.class));
}
@BeforeClass
public static void beforeClass() {
try {
Class.forName("com.taosdata.jdbc.TSDBDriver");
conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata");
try (Statement stmt = conn.createStatement()) {
stmt.execute("drop database if exists test_pstmt");
stmt.execute("create database if not exists test_pstmt");
stmt.execute("use test_pstmt");
stmt.execute("create table weather(ts timestamp, f1 int, f2 bigint, f3 float, f4 double, f5 smallint, f6 tinyint, f7 bool, f8 binary(64), f9 nchar(64)) tags(loc nchar(64))");
stmt.execute("create table t1 using weather tags('beijing')");
}
pstmt_insert = conn.prepareStatement(sql_insert);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(2, 111);
pstmt_insert.setObject(3, Long.MAX_VALUE);
pstmt_insert.setObject(4, 3.14159265354f);
pstmt_insert.setObject(5, Double.MAX_VALUE);
pstmt_insert.setObject(6, Short.MAX_VALUE);
pstmt_insert.setObject(7, Byte.MAX_VALUE);
pstmt_insert.setObject(8, true);
pstmt_insert.setObject(9, "hello".getBytes());
pstmt_insert.setObject(10, "Hello");
parameterMetaData_insert = pstmt_insert.getParameterMetaData();
pstmt_select = conn.prepareStatement(sql_select);
pstmt_select.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_select.setTimestamp(2, new Timestamp(System.currentTimeMillis() + 10000));
pstmt_select.setInt(3, 0);
parameterMetaData_select = pstmt_select.getParameterMetaData();
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
@AfterClass
public static void afterClass() {
try {
if (pstmt_insert != null)
pstmt_insert.close();
if (pstmt_select != null)
pstmt_select.close();
if (conn != null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
\ No newline at end of file
!c/
node_modules/
package-lock.json
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册