提交 1b783530 编写于 作者: haoranc's avatar haoranc

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

...@@ -131,10 +131,10 @@ cmake .. -DCPUTYPE=mips64 && cmake --build . ...@@ -131,10 +131,10 @@ cmake .. -DCPUTYPE=mips64 && cmake --build .
### On Windows platform ### On Windows platform
If you use the Visual Studio 2013, please open a command window by executing "cmd.exe". If you use the Visual Studio 2013, please open a command window by executing "cmd.exe".
Please specify "x86_amd64" for 64 bits Windows or specify "x86" is for 32 bits Windows when you execute vcvarsall.bat. Please specify "amd64" for 64 bits Windows or specify "x86" is for 32 bits Windows when you execute vcvarsall.bat.
```cmd ```cmd
mkdir debug && cd debug mkdir debug && cd debug
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" < x86_amd64 | x86 > "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" < amd64 | x86 >
cmake .. -G "NMake Makefiles" cmake .. -G "NMake Makefiles"
nmake nmake
``` ```
......
...@@ -32,7 +32,7 @@ ELSEIF (TD_WINDOWS) ...@@ -32,7 +32,7 @@ ELSEIF (TD_WINDOWS)
#INSTALL(TARGETS taos RUNTIME DESTINATION driver) #INSTALL(TARGETS taos RUNTIME DESTINATION driver)
#INSTALL(TARGETS shell RUNTIME DESTINATION .) #INSTALL(TARGETS shell RUNTIME DESTINATION .)
IF (TD_MVN_INSTALLED) IF (TD_MVN_INSTALLED)
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.29.jar DESTINATION connector/jdbc) INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.30.jar DESTINATION connector/jdbc)
ENDIF () ENDIF ()
ELSEIF (TD_DARWIN) ELSEIF (TD_DARWIN)
SET(TD_MAKE_INSTALL_SH "${TD_COMMUNITY_DIR}/packaging/tools/make_install.sh") SET(TD_MAKE_INSTALL_SH "${TD_COMMUNITY_DIR}/packaging/tools/make_install.sh")
......
...@@ -361,6 +361,7 @@ public void setShort(int columnIndex, ArrayList<Short> list) throws SQLException ...@@ -361,6 +361,7 @@ public void setShort(int columnIndex, ArrayList<Short> list) throws SQLException
public void setString(int columnIndex, ArrayList<String> list, int size) throws SQLException public void setString(int columnIndex, ArrayList<String> list, int size) throws SQLException
public void setNString(int columnIndex, ArrayList<String> list, int size) throws SQLException public void setNString(int columnIndex, ArrayList<String> list, int size) throws SQLException
``` ```
其中 setString 和 setNString 都要求用户在 size 参数里声明表定义中对应列的列宽。
### <a class="anchor" id="subscribe"></a>订阅 ### <a class="anchor" id="subscribe"></a>订阅
......
...@@ -301,7 +301,7 @@ TDengine的异步API均采用非阻塞调用模式。应用程序可以用多线 ...@@ -301,7 +301,7 @@ TDengine的异步API均采用非阻塞调用模式。应用程序可以用多线
2. 调用 `taos_stmt_prepare` 解析 INSERT 语句; 2. 调用 `taos_stmt_prepare` 解析 INSERT 语句;
3. 如果 INSERT 语句中预留了表名但没有预留 TAGS,那么调用 `taos_stmt_set_tbname` 来设置表名; 3. 如果 INSERT 语句中预留了表名但没有预留 TAGS,那么调用 `taos_stmt_set_tbname` 来设置表名;
4. 如果 INSERT 语句中既预留了表名又预留了 TAGS(例如 INSERT 语句采取的是自动建表的方式),那么调用 `taos_stmt_set_tbname_tags` 来设置表名和 TAGS 的值; 4. 如果 INSERT 语句中既预留了表名又预留了 TAGS(例如 INSERT 语句采取的是自动建表的方式),那么调用 `taos_stmt_set_tbname_tags` 来设置表名和 TAGS 的值;
5. 调用 `taos_stmt_bind_param_batch` 以多列的方式设置 VALUES 的值; 5. 调用 `taos_stmt_bind_param_batch` 以多列的方式设置 VALUES 的值,或者调用 `taos_stmt_bind_param` 以单行的方式设置 VALUES 的值
6. 调用 `taos_stmt_add_batch` 把当前绑定的参数加入批处理; 6. 调用 `taos_stmt_add_batch` 把当前绑定的参数加入批处理;
7. 可以重复第 3~6 步,为批处理加入更多的数据行; 7. 可以重复第 3~6 步,为批处理加入更多的数据行;
8. 调用 `taos_stmt_execute` 执行已经准备好的批处理指令; 8. 调用 `taos_stmt_execute` 执行已经准备好的批处理指令;
...@@ -338,17 +338,17 @@ typedef struct TAOS_BIND { ...@@ -338,17 +338,17 @@ typedef struct TAOS_BIND {
- `int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name)` - `int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name)`
(2.1.1.0 版本新增) (2.1.1.0 版本新增,仅支持用于替换 INSERT 语句中的参数值
当 SQL 语句中的表名使用了 `?` 占位时,可以使用此函数绑定一个具体的表名。 当 SQL 语句中的表名使用了 `?` 占位时,可以使用此函数绑定一个具体的表名。
- `int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags)` - `int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags)`
(2.1.2.0 版本新增) (2.1.2.0 版本新增,仅支持用于替换 INSERT 语句中的参数值
当 SQL 语句中的表名和 TAGS 都使用了 `?` 占位时,可以使用此函数绑定具体的表名和具体的 TAGS 取值。最典型的使用场景是使用了自动建表功能的 INSERT 语句(目前版本不支持指定具体的 TAGS 列)。tags 参数中的列数量需要与 SQL 语句中要求的 TAGS 数量完全一致。 当 SQL 语句中的表名和 TAGS 都使用了 `?` 占位时,可以使用此函数绑定具体的表名和具体的 TAGS 取值。最典型的使用场景是使用了自动建表功能的 INSERT 语句(目前版本不支持指定具体的 TAGS 列)。tags 参数中的列数量需要与 SQL 语句中要求的 TAGS 数量完全一致。
- `int taos_stmt_bind_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind)` - `int taos_stmt_bind_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind)`
(2.1.1.0 版本新增) (2.1.1.0 版本新增,仅支持用于替换 INSERT 语句中的参数值
以多列的方式传递待绑定的数据,需要保证这里传递的数据列的顺序、列的数量与 SQL 语句中的 VALUES 参数完全一致。TAOS_MULTI_BIND 的具体定义如下: 以多列的方式传递待绑定的数据,需要保证这里传递的数据列的顺序、列的数量与 SQL 语句中的 VALUES 参数完全一致。TAOS_MULTI_BIND 的具体定义如下:
```c ```c
......
...@@ -1306,7 +1306,7 @@ SELECT AVG(current), MAX(current), LEASTSQUARES(current, start_val, step_val), P ...@@ -1306,7 +1306,7 @@ SELECT AVG(current), MAX(current), LEASTSQUARES(current, start_val, step_val), P
- 数据库名最大长度为 32 - 数据库名最大长度为 32
- 表名最大长度为 192,每行数据最大长度 16k 个字符(注意:数据行内每个 BINARY/NCHAR 类型的列还会额外占用 2 个字节的存储位置) - 表名最大长度为 192,每行数据最大长度 16k 个字符(注意:数据行内每个 BINARY/NCHAR 类型的列还会额外占用 2 个字节的存储位置)
- 列名最大长度为 64,最多允许 1024 列,最少需要 2 列,第一列必须是时间戳 - 列名最大长度为 64,最多允许 1024 列,最少需要 2 列,第一列必须是时间戳
- 标签最多允许 128 个,可以 1 个,标签总长度不超过 16k 个字符 - 标签名最大长度为 64,最多允许 128 个,可以 1 个,一个表中标签值的总长度不超过 16k 个字符
- SQL 语句最大长度 65480 个字符,但可通过系统配置参数 maxSQLLength 修改,最长可配置为 1M - SQL 语句最大长度 65480 个字符,但可通过系统配置参数 maxSQLLength 修改,最长可配置为 1M
- SELECT 语句的查询结果,最多允许返回 1024 列(语句中的函数调用可能也会占用一些列空间),超限时需要显式指定较少的返回数据列,以避免语句执行报错。 - SELECT 语句的查询结果,最多允许返回 1024 列(语句中的函数调用可能也会占用一些列空间),超限时需要显式指定较少的返回数据列,以避免语句执行报错。
- 库的数目,超级表的数目、表的数目,系统不做限制,仅受系统资源限制 - 库的数目,超级表的数目、表的数目,系统不做限制,仅受系统资源限制
......
...@@ -123,6 +123,7 @@ int32_t tscGetDataBlockFromList(SHashObj* pHashList, int64_t id, int32_t size, i ...@@ -123,6 +123,7 @@ int32_t tscGetDataBlockFromList(SHashObj* pHashList, int64_t id, int32_t size, i
*/ */
bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo); bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo);
bool tscIsTWAQuery(SQueryInfo* pQueryInfo); bool tscIsTWAQuery(SQueryInfo* pQueryInfo);
bool tscIsDiffQuery(SQueryInfo* pQueryInfo);
bool tscIsSessionWindowQuery(SQueryInfo* pQueryInfo); bool tscIsSessionWindowQuery(SQueryInfo* pQueryInfo);
bool tscIsSecondStageQuery(SQueryInfo* pQueryInfo); bool tscIsSecondStageQuery(SQueryInfo* pQueryInfo);
bool tsIsArithmeticQueryOnAggResult(SQueryInfo* pQueryInfo); bool tsIsArithmeticQueryOnAggResult(SQueryInfo* pQueryInfo);
...@@ -132,7 +133,6 @@ bool hasTagValOutput(SQueryInfo* pQueryInfo); ...@@ -132,7 +133,6 @@ bool hasTagValOutput(SQueryInfo* pQueryInfo);
bool timeWindowInterpoRequired(SQueryInfo *pQueryInfo); bool timeWindowInterpoRequired(SQueryInfo *pQueryInfo);
bool isStabledev(SQueryInfo* pQueryInfo); bool isStabledev(SQueryInfo* pQueryInfo);
bool isTsCompQuery(SQueryInfo* pQueryInfo); bool isTsCompQuery(SQueryInfo* pQueryInfo);
bool isSimpleAggregate(SQueryInfo* pQueryInfo);
bool isBlockDistQuery(SQueryInfo* pQueryInfo); bool isBlockDistQuery(SQueryInfo* pQueryInfo);
bool isSimpleAggregateRv(SQueryInfo* pQueryInfo); bool isSimpleAggregateRv(SQueryInfo* pQueryInfo);
...@@ -214,7 +214,7 @@ void tscColumnListDestroy(SArray* pColList); ...@@ -214,7 +214,7 @@ void tscColumnListDestroy(SArray* pColList);
void tscColumnListCopy(SArray* dst, const SArray* src, uint64_t tableUid); void tscColumnListCopy(SArray* dst, const SArray* src, uint64_t tableUid);
void tscColumnListCopyAll(SArray* dst, const SArray* src); void tscColumnListCopyAll(SArray* dst, const SArray* src);
void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo); void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo, uint64_t objId);
void tscDequoteAndTrimToken(SStrToken* pToken); void tscDequoteAndTrimToken(SStrToken* pToken);
int32_t tscValidateName(SStrToken* pToken); int32_t tscValidateName(SStrToken* pToken);
...@@ -329,9 +329,7 @@ STableMeta* tscTableMetaDup(STableMeta* pTableMeta); ...@@ -329,9 +329,7 @@ STableMeta* tscTableMetaDup(STableMeta* pTableMeta);
SVgroupsInfo* tscVgroupsInfoDup(SVgroupsInfo* pVgroupsInfo); SVgroupsInfo* tscVgroupsInfoDup(SVgroupsInfo* pVgroupsInfo);
int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAttr, void* addr); int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAttr, void* addr);
void* createQInfoFromQueryNode(SQueryInfo* pQueryInfo, STableGroupInfo* pTableGroupInfo, SOperatorInfo* pOperator, char* sql, void* addr, int32_t stage, uint64_t qId);
void tsCreateSQLFunctionCtx(SQueryInfo* pQueryInfo, SQLFunctionCtx* pCtx, SSchema* pSchema);
void* createQInfoFromQueryNode(SQueryInfo* pQueryInfo, STableGroupInfo* pTableGroupInfo, SOperatorInfo* pOperator, char* sql, void* addr, int32_t stage);
void* malloc_throw(size_t size); void* malloc_throw(size_t size);
void* calloc_throw(size_t nmemb, size_t size); void* calloc_throw(size_t nmemb, size_t size);
......
...@@ -320,7 +320,7 @@ int32_t tscCreateResPointerInfo(SSqlRes *pRes, SQueryInfo *pQueryInfo); ...@@ -320,7 +320,7 @@ int32_t tscCreateResPointerInfo(SSqlRes *pRes, SQueryInfo *pQueryInfo);
void tscSetResRawPtr(SSqlRes* pRes, SQueryInfo* pQueryInfo); void tscSetResRawPtr(SSqlRes* pRes, SQueryInfo* pQueryInfo);
void tscSetResRawPtrRv(SSqlRes* pRes, SQueryInfo* pQueryInfo, SSDataBlock* pBlock); void tscSetResRawPtrRv(SSqlRes* pRes, SQueryInfo* pQueryInfo, SSDataBlock* pBlock);
void handleDownstreamOperator(SSqlObj** pSqlList, int32_t numOfUpstream, SQueryInfo* px, SSqlRes* pOutput); void handleDownstreamOperator(SSqlObj** pSqlList, int32_t numOfUpstream, SQueryInfo* px, SSqlObj* pParent);
void destroyTableNameList(SInsertStatementParam* pInsertParam); void destroyTableNameList(SInsertStatementParam* pInsertParam);
void tscResetSqlCmd(SSqlCmd *pCmd, bool removeMeta); void tscResetSqlCmd(SSqlCmd *pCmd, bool removeMeta);
......
...@@ -144,7 +144,7 @@ static void tscAsyncFetchRowsProxy(void *param, TAOS_RES *tres, int numOfRows) { ...@@ -144,7 +144,7 @@ static void tscAsyncFetchRowsProxy(void *param, TAOS_RES *tres, int numOfRows) {
} }
// local merge has handle this situation during super table non-projection query. // local merge has handle this situation during super table non-projection query.
if (pCmd->command != TSDB_SQL_RETRIEVE_LOCALMERGE) { if (pCmd->command != TSDB_SQL_RETRIEVE_GLOBALMERGE) {
pRes->numOfClauseTotal += pRes->numOfRows; pRes->numOfClauseTotal += pRes->numOfRows;
} }
...@@ -174,7 +174,7 @@ static void tscProcessAsyncRetrieveImpl(void *param, TAOS_RES *tres, int numOfRo ...@@ -174,7 +174,7 @@ static void tscProcessAsyncRetrieveImpl(void *param, TAOS_RES *tres, int numOfRo
} }
pSql->fp = fp; pSql->fp = fp;
if (pCmd->command != TSDB_SQL_RETRIEVE_LOCALMERGE && pCmd->command < TSDB_SQL_LOCAL) { if (pCmd->command != TSDB_SQL_RETRIEVE_GLOBALMERGE && pCmd->command < TSDB_SQL_LOCAL) {
pCmd->command = (pCmd->command > TSDB_SQL_MGMT) ? TSDB_SQL_RETRIEVE : TSDB_SQL_FETCH; pCmd->command = (pCmd->command > TSDB_SQL_MGMT) ? TSDB_SQL_RETRIEVE : TSDB_SQL_FETCH;
} }
...@@ -257,14 +257,14 @@ void taos_fetch_rows_a(TAOS_RES *tres, __async_cb_func_t fp, void *param) { ...@@ -257,14 +257,14 @@ void taos_fetch_rows_a(TAOS_RES *tres, __async_cb_func_t fp, void *param) {
} }
return; return;
} else if (pCmd->command == TSDB_SQL_RETRIEVE || pCmd->command == TSDB_SQL_RETRIEVE_LOCALMERGE) { } else if (pCmd->command == TSDB_SQL_RETRIEVE || pCmd->command == TSDB_SQL_RETRIEVE_GLOBALMERGE) {
// in case of show command, return no data // in case of show command, return no data
(*pSql->fetchFp)(param, pSql, 0); (*pSql->fetchFp)(param, pSql, 0);
} else { } else {
assert(0); assert(0);
} }
} else { // current query is not completed, continue retrieve from node } else { // current query is not completed, continue retrieve from node
if (pCmd->command != TSDB_SQL_RETRIEVE_LOCALMERGE && pCmd->command < TSDB_SQL_LOCAL) { if (pCmd->command != TSDB_SQL_RETRIEVE_GLOBALMERGE && pCmd->command < TSDB_SQL_LOCAL) {
pCmd->command = (pCmd->command > TSDB_SQL_MGMT) ? TSDB_SQL_RETRIEVE : TSDB_SQL_FETCH; pCmd->command = (pCmd->command > TSDB_SQL_MGMT) ? TSDB_SQL_RETRIEVE : TSDB_SQL_FETCH;
} }
......
...@@ -323,7 +323,7 @@ TAOS_ROW tscFetchRow(void *param) { ...@@ -323,7 +323,7 @@ TAOS_ROW tscFetchRow(void *param) {
// current data set are exhausted, fetch more data from node // current data set are exhausted, fetch more data from node
if (pRes->row >= pRes->numOfRows && (pRes->completed != true || hasMoreVnodesToTry(pSql) || hasMoreClauseToTry(pSql)) && if (pRes->row >= pRes->numOfRows && (pRes->completed != true || hasMoreVnodesToTry(pSql) || hasMoreClauseToTry(pSql)) &&
(pCmd->command == TSDB_SQL_RETRIEVE || (pCmd->command == TSDB_SQL_RETRIEVE ||
pCmd->command == TSDB_SQL_RETRIEVE_LOCALMERGE || pCmd->command == TSDB_SQL_RETRIEVE_GLOBALMERGE ||
pCmd->command == TSDB_SQL_TABLE_JOIN_RETRIEVE || pCmd->command == TSDB_SQL_TABLE_JOIN_RETRIEVE ||
pCmd->command == TSDB_SQL_FETCH || pCmd->command == TSDB_SQL_FETCH ||
pCmd->command == TSDB_SQL_SHOW || pCmd->command == TSDB_SQL_SHOW ||
......
...@@ -78,6 +78,16 @@ typedef struct STscStmt { ...@@ -78,6 +78,16 @@ typedef struct STscStmt {
SNormalStmt normal; SNormalStmt normal;
} STscStmt; } STscStmt;
#define STMT_RET(c) do { \
int32_t _code = c; \
if (pStmt && pStmt->pSql) { pStmt->pSql->res.code = _code; } else {terrno = _code;} \
return _code; \
} while (0)
static int32_t invalidOperationMsg(char* dstBuffer, const char* errMsg) {
return tscInvalidOperationMsg(dstBuffer, errMsg, NULL);
}
static int normalStmtAddPart(SNormalStmt* stmt, bool isParam, char* str, uint32_t len) { static int normalStmtAddPart(SNormalStmt* stmt, bool isParam, char* str, uint32_t len) {
uint16_t size = stmt->numParts + 1; uint16_t size = stmt->numParts + 1;
if (size > stmt->sizeParts) { if (size > stmt->sizeParts) {
...@@ -163,8 +173,8 @@ static int normalStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) { ...@@ -163,8 +173,8 @@ static int normalStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) {
break; break;
default: default:
tscDebug("0x%"PRIx64" bind column%d: type mismatch or invalid", stmt->pSql->self, i); tscError("0x%"PRIx64" bind column%d: type mismatch or invalid", stmt->pSql->self, i);
return TSDB_CODE_TSC_INVALID_VALUE; return invalidOperationMsg(tscGetErrorMsgPayload(&stmt->pSql->cmd), "bind type mismatch or invalid");
} }
} }
...@@ -727,6 +737,7 @@ static int doBindParam(STableDataBlocks* pBlock, char* data, SParamInfo* param, ...@@ -727,6 +737,7 @@ static int doBindParam(STableDataBlocks* pBlock, char* data, SParamInfo* param,
#endif #endif
if (bind->buffer_type != param->type) { if (bind->buffer_type != param->type) {
tscError("column type mismatch");
return TSDB_CODE_TSC_INVALID_VALUE; return TSDB_CODE_TSC_INVALID_VALUE;
} }
...@@ -754,6 +765,7 @@ static int doBindParam(STableDataBlocks* pBlock, char* data, SParamInfo* param, ...@@ -754,6 +765,7 @@ static int doBindParam(STableDataBlocks* pBlock, char* data, SParamInfo* param,
case TSDB_DATA_TYPE_BINARY: case TSDB_DATA_TYPE_BINARY:
if ((*bind->length) > (uintptr_t)param->bytes) { if ((*bind->length) > (uintptr_t)param->bytes) {
tscError("column length is too big");
return TSDB_CODE_TSC_INVALID_VALUE; return TSDB_CODE_TSC_INVALID_VALUE;
} }
size = (short)*bind->length; size = (short)*bind->length;
...@@ -763,6 +775,7 @@ static int doBindParam(STableDataBlocks* pBlock, char* data, SParamInfo* param, ...@@ -763,6 +775,7 @@ static int doBindParam(STableDataBlocks* pBlock, char* data, SParamInfo* param,
case TSDB_DATA_TYPE_NCHAR: { case TSDB_DATA_TYPE_NCHAR: {
int32_t output = 0; int32_t output = 0;
if (!taosMbsToUcs4(bind->buffer, *bind->length, varDataVal(data + param->offset), param->bytes - VARSTR_HEADER_SIZE, &output)) { if (!taosMbsToUcs4(bind->buffer, *bind->length, varDataVal(data + param->offset), param->bytes - VARSTR_HEADER_SIZE, &output)) {
tscError("convert nchar failed");
return TSDB_CODE_TSC_INVALID_VALUE; return TSDB_CODE_TSC_INVALID_VALUE;
} }
varDataSetLen(data + param->offset, output); varDataSetLen(data + param->offset, output);
...@@ -787,6 +800,7 @@ static int doBindParam(STableDataBlocks* pBlock, char* data, SParamInfo* param, ...@@ -787,6 +800,7 @@ static int doBindParam(STableDataBlocks* pBlock, char* data, SParamInfo* param,
static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MULTI_BIND* bind, int32_t rowNum) { static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MULTI_BIND* bind, int32_t rowNum) {
if (bind->buffer_type != param->type || !isValidDataType(param->type)) { if (bind->buffer_type != param->type || !isValidDataType(param->type)) {
tscError("column mismatch or invalid");
return TSDB_CODE_TSC_INVALID_VALUE; return TSDB_CODE_TSC_INVALID_VALUE;
} }
...@@ -892,8 +906,8 @@ static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) { ...@@ -892,8 +906,8 @@ static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) {
int code = doBindParam(pBlock, data, param, &bind[param->idx], 1); int code = doBindParam(pBlock, data, param, &bind[param->idx], 1);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
tscDebug("0x%"PRIx64" bind column %d: type mismatch or invalid", pStmt->pSql->self, param->idx); tscDebug("0x%"PRIx64" bind column %d: type mismatch or invalid", pStmt->pSql->self, param->idx);
return code; return invalidOperationMsg(tscGetErrorMsgPayload(&stmt->pSql->cmd), "bind column type mismatch or invalid");
} }
} }
...@@ -957,13 +971,13 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c ...@@ -957,13 +971,13 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c
SParamInfo* param = &pBlock->params[j]; SParamInfo* param = &pBlock->params[j];
if (bind[param->idx].num != rowNum) { if (bind[param->idx].num != rowNum) {
tscError("0x%"PRIx64" param %d: num[%d:%d] not match", pStmt->pSql->self, param->idx, rowNum, bind[param->idx].num); tscError("0x%"PRIx64" param %d: num[%d:%d] not match", pStmt->pSql->self, param->idx, rowNum, bind[param->idx].num);
return TSDB_CODE_TSC_INVALID_VALUE; return invalidOperationMsg(tscGetErrorMsgPayload(&stmt->pSql->cmd), "bind row num mismatch");
} }
int code = doBindBatchParam(pBlock, param, &bind[param->idx], pCmd->batchSize); int code = doBindBatchParam(pBlock, param, &bind[param->idx], pCmd->batchSize);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
tscError("0x%"PRIx64" bind column %d: type mismatch or invalid", pStmt->pSql->self, param->idx); tscError("0x%"PRIx64" bind column %d: type mismatch or invalid", pStmt->pSql->self, param->idx);
return code; return invalidOperationMsg(tscGetErrorMsgPayload(&stmt->pSql->cmd), "bind column type mismatch or invalid");
} }
} }
...@@ -974,7 +988,7 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c ...@@ -974,7 +988,7 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c
int code = doBindBatchParam(pBlock, param, bind, pCmd->batchSize); int code = doBindBatchParam(pBlock, param, bind, pCmd->batchSize);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
tscError("0x%"PRIx64" bind column %d: type mismatch or invalid", pStmt->pSql->self, param->idx); tscError("0x%"PRIx64" bind column %d: type mismatch or invalid", pStmt->pSql->self, param->idx);
return code; return invalidOperationMsg(tscGetErrorMsgPayload(&stmt->pSql->cmd), "bind column type mismatch or invalid");
} }
if (colIdx == (pBlock->numOfParams - 1)) { if (colIdx == (pBlock->numOfParams - 1)) {
...@@ -993,7 +1007,7 @@ static int insertStmtUpdateBatch(STscStmt* stmt) { ...@@ -993,7 +1007,7 @@ static int insertStmtUpdateBatch(STscStmt* stmt) {
if (pCmd->batchSize > INT16_MAX) { if (pCmd->batchSize > INT16_MAX) {
tscError("too many record:%d", pCmd->batchSize); tscError("too many record:%d", pCmd->batchSize);
return TSDB_CODE_TSC_APP_ERROR; return invalidOperationMsg(tscGetErrorMsgPayload(&stmt->pSql->cmd), "too many records");
} }
if (taosHashGetSize(pCmd->insertParam.pTableBlockHashList) == 0) { if (taosHashGetSize(pCmd->insertParam.pTableBlockHashList) == 0) {
...@@ -1057,7 +1071,8 @@ static int insertStmtReset(STscStmt* pStmt) { ...@@ -1057,7 +1071,8 @@ static int insertStmtReset(STscStmt* pStmt) {
static int insertStmtExecute(STscStmt* stmt) { static int insertStmtExecute(STscStmt* stmt) {
SSqlCmd* pCmd = &stmt->pSql->cmd; SSqlCmd* pCmd = &stmt->pSql->cmd;
if (pCmd->batchSize == 0) { if (pCmd->batchSize == 0) {
return TSDB_CODE_TSC_INVALID_VALUE; tscError("no records bind");
return invalidOperationMsg(tscGetErrorMsgPayload(&stmt->pSql->cmd), "no records bind");
} }
if (taosHashGetSize(pCmd->insertParam.pTableBlockHashList) == 0) { if (taosHashGetSize(pCmd->insertParam.pTableBlockHashList) == 0) {
...@@ -1174,7 +1189,7 @@ static int insertBatchStmtExecute(STscStmt* pStmt) { ...@@ -1174,7 +1189,7 @@ static int insertBatchStmtExecute(STscStmt* pStmt) {
if(pStmt->mtb.nameSet == false) { if(pStmt->mtb.nameSet == false) {
tscError("0x%"PRIx64" no table name set", pStmt->pSql->self); tscError("0x%"PRIx64" no table name set", pStmt->pSql->self);
return TSDB_CODE_TSC_APP_ERROR; return invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), "no table name set");
} }
pStmt->pSql->retry = pStmt->pSql->maxRetry + 1; //no retry pStmt->pSql->retry = pStmt->pSql->maxRetry + 1; //no retry
...@@ -1215,7 +1230,8 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) { ...@@ -1215,7 +1230,8 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) {
int32_t index = 0; int32_t index = 0;
SStrToken sToken = tStrGetToken(pCmd->insertParam.sql, &index, false); SStrToken sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
if (sToken.n == 0) { if (sToken.n == 0) {
return TSDB_CODE_TSC_INVALID_OPERATION; tscError("table is is expected, sql:%s", pCmd->insertParam.sql);
return tscSQLSyntaxErrMsg(pCmd->payload, "table name is expected", pCmd->insertParam.sql);
} }
if (sToken.n == 1 && sToken.type == TK_QUESTION) { if (sToken.n == 1 && sToken.type == TK_QUESTION) {
...@@ -1237,24 +1253,28 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) { ...@@ -1237,24 +1253,28 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
if (sToken.n <= 0 || sToken.type != TK_USING) { if (sToken.n <= 0 || sToken.type != TK_USING) {
return tscSQLSyntaxErrMsg(pCmd->payload, "keywords USING is expected", sToken.z); tscError("keywords USING is expected, sql:%s", pCmd->insertParam.sql);
return tscSQLSyntaxErrMsg(pCmd->payload, "keywords USING is expected", sToken.z ? sToken.z : pCmd->insertParam.sql);
} }
sToken = tStrGetToken(pCmd->insertParam.sql, &index, false); sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
if (sToken.n <= 0 || ((sToken.type != TK_ID) && (sToken.type != TK_STRING))) { if (sToken.n <= 0 || ((sToken.type != TK_ID) && (sToken.type != TK_STRING))) {
return tscSQLSyntaxErrMsg(pCmd->payload, "invalid token", sToken.z); tscError("invalid token, sql:%s", pCmd->insertParam.sql);
return tscSQLSyntaxErrMsg(pCmd->payload, "invalid token", sToken.z ? sToken.z : pCmd->insertParam.sql);
} }
pStmt->mtb.stbname = sToken; pStmt->mtb.stbname = sToken;
sToken = tStrGetToken(pCmd->insertParam.sql, &index, false); sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
if (sToken.n <= 0 || sToken.type != TK_TAGS) { if (sToken.n <= 0 || sToken.type != TK_TAGS) {
return tscSQLSyntaxErrMsg(pCmd->payload, "keyword TAGS expected", sToken.z); tscError("keyword TAGS expected, sql:%s", pCmd->insertParam.sql);
return tscSQLSyntaxErrMsg(pCmd->payload, "keyword TAGS expected", sToken.z ? sToken.z : pCmd->insertParam.sql);
} }
sToken = tStrGetToken(pCmd->insertParam.sql, &index, false); sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
if (sToken.n <= 0 || sToken.type != TK_LP) { if (sToken.n <= 0 || sToken.type != TK_LP) {
return tscSQLSyntaxErrMsg(pCmd->payload, ") expected", sToken.z); tscError("( expected, sql:%s", pCmd->insertParam.sql);
return tscSQLSyntaxErrMsg(pCmd->payload, "( expected", sToken.z ? sToken.z : pCmd->insertParam.sql);
} }
pStmt->mtb.tags = taosArrayInit(4, sizeof(SStrToken)); pStmt->mtb.tags = taosArrayInit(4, sizeof(SStrToken));
...@@ -1264,7 +1284,8 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) { ...@@ -1264,7 +1284,8 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) {
while (loopCont) { while (loopCont) {
sToken = tStrGetToken(pCmd->insertParam.sql, &index, false); sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
if (sToken.n <= 0) { if (sToken.n <= 0) {
return TSDB_CODE_TSC_INVALID_OPERATION; tscError("unexpected sql end, sql:%s", pCmd->insertParam.sql);
return tscSQLSyntaxErrMsg(pCmd->payload, "unexpected sql end", pCmd->insertParam.sql);
} }
switch (sToken.type) { switch (sToken.type) {
...@@ -1272,7 +1293,8 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) { ...@@ -1272,7 +1293,8 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) {
loopCont = 0; loopCont = 0;
break; break;
case TK_VALUES: case TK_VALUES:
return TSDB_CODE_TSC_INVALID_OPERATION; tscError("unexpected token values, sql:%s", pCmd->insertParam.sql);
return tscSQLSyntaxErrMsg(pCmd->payload, "unexpected token", sToken.z);
case TK_QUESTION: case TK_QUESTION:
pStmt->mtb.tagSet = false; //continue pStmt->mtb.tagSet = false; //continue
default: default:
...@@ -1282,12 +1304,14 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) { ...@@ -1282,12 +1304,14 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) {
} }
if (taosArrayGetSize(pStmt->mtb.tags) <= 0) { if (taosArrayGetSize(pStmt->mtb.tags) <= 0) {
return TSDB_CODE_TSC_INVALID_OPERATION; tscError("no tags, sql:%s", pCmd->insertParam.sql);
return tscSQLSyntaxErrMsg(pCmd->payload, "no tags", pCmd->insertParam.sql);
} }
sToken = tStrGetToken(pCmd->insertParam.sql, &index, false); sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
if (sToken.n <= 0 || (sToken.type != TK_VALUES && sToken.type != TK_LP)) { if (sToken.n <= 0 || (sToken.type != TK_VALUES && sToken.type != TK_LP)) {
return TSDB_CODE_TSC_INVALID_OPERATION; tscError("sql error, sql:%s", pCmd->insertParam.sql);
return tscSQLSyntaxErrMsg(pCmd->payload, "sql error", sToken.z ? sToken.z : pCmd->insertParam.sql);
} }
pStmt->mtb.values = sToken; pStmt->mtb.values = sToken;
...@@ -1329,8 +1353,8 @@ int stmtGenInsertStatement(SSqlObj* pSql, STscStmt* pStmt, const char* name, TAO ...@@ -1329,8 +1353,8 @@ int stmtGenInsertStatement(SSqlObj* pSql, STscStmt* pStmt, const char* name, TAO
} else { } else {
if (tags[j].buffer == NULL) { if (tags[j].buffer == NULL) {
free(str); free(str);
tscError("empty"); tscError("empty tag value in params");
return TSDB_CODE_TSC_APP_ERROR; return invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), "empty tag value in params");
} }
ret = converToStr(str + len, tags[j].buffer_type, tags[j].buffer, tags[j].length ? (int32_t)*tags[j].length : -1, &l); ret = converToStr(str + len, tags[j].buffer_type, tags[j].buffer, tags[j].length ? (int32_t)*tags[j].length : -1, &l);
...@@ -1387,13 +1411,15 @@ int stmtGenInsertStatement(SSqlObj* pSql, STscStmt* pStmt, const char* name, TAO ...@@ -1387,13 +1411,15 @@ int stmtGenInsertStatement(SSqlObj* pSql, STscStmt* pStmt, const char* name, TAO
TAOS_STMT* taos_stmt_init(TAOS* taos) { TAOS_STMT* taos_stmt_init(TAOS* taos) {
STscObj* pObj = (STscObj*)taos; STscObj* pObj = (STscObj*)taos;
STscStmt* pStmt = NULL;
if (pObj == NULL || pObj->signature != pObj) { if (pObj == NULL || pObj->signature != pObj) {
terrno = TSDB_CODE_TSC_DISCONNECTED; terrno = TSDB_CODE_TSC_DISCONNECTED;
tscError("connection disconnected"); tscError("connection disconnected");
return NULL; return NULL;
} }
STscStmt* pStmt = calloc(1, sizeof(STscStmt)); pStmt = calloc(1, sizeof(STscStmt));
if (pStmt == NULL) { if (pStmt == NULL) {
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
tscError("failed to allocate memory for statement"); tscError("failed to allocate memory for statement");
...@@ -1410,6 +1436,14 @@ TAOS_STMT* taos_stmt_init(TAOS* taos) { ...@@ -1410,6 +1436,14 @@ TAOS_STMT* taos_stmt_init(TAOS* taos) {
return NULL; return NULL;
} }
if (TSDB_CODE_SUCCESS != tscAllocPayload(&pSql->cmd, TSDB_DEFAULT_PAYLOAD_SIZE)) {
free(pSql);
free(pStmt);
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
tscError("failed to malloc payload buffer");
return NULL;
}
tsem_init(&pSql->rspSem, 0, 0); tsem_init(&pSql->rspSem, 0, 0);
pSql->signature = pSql; pSql->signature = pSql;
pSql->pTscObj = pObj; pSql->pTscObj = pObj;
...@@ -1425,13 +1459,12 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) { ...@@ -1425,13 +1459,12 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) {
STscStmt* pStmt = (STscStmt*)stmt; STscStmt* pStmt = (STscStmt*)stmt;
if (stmt == NULL || pStmt->taos == NULL || pStmt->pSql == NULL) { if (stmt == NULL || pStmt->taos == NULL || pStmt->pSql == NULL) {
terrno = TSDB_CODE_TSC_DISCONNECTED; STMT_RET(TSDB_CODE_TSC_DISCONNECTED);
return TSDB_CODE_TSC_DISCONNECTED;
} }
if (pStmt->last != STMT_INIT) { if (pStmt->last != STMT_INIT) {
tscError("prepare status error, last:%d", pStmt->last); tscError("prepare status error, last:%d", pStmt->last);
return TSDB_CODE_TSC_APP_ERROR; STMT_RET(invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), "prepare status error"));
} }
pStmt->last = STMT_PREPARE; pStmt->last = STMT_PREPARE;
...@@ -1447,17 +1480,11 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) { ...@@ -1447,17 +1480,11 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) {
pCmd->insertParam.insertType = TSDB_QUERY_TYPE_STMT_INSERT; pCmd->insertParam.insertType = TSDB_QUERY_TYPE_STMT_INSERT;
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE)) {
tscError("%p failed to malloc payload buffer", pSql);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
pSql->sqlstr = realloc(pSql->sqlstr, sqlLen + 1); pSql->sqlstr = realloc(pSql->sqlstr, sqlLen + 1);
if (pSql->sqlstr == NULL) { if (pSql->sqlstr == NULL) {
tscError("%p failed to malloc sql string buffer", pSql); tscError("%p failed to malloc sql string buffer", pSql);
free(pCmd->payload); STMT_RET(TSDB_CODE_TSC_OUT_OF_MEMORY);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
} }
pRes->qId = 0; pRes->qId = 0;
...@@ -1476,11 +1503,11 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) { ...@@ -1476,11 +1503,11 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) {
int32_t ret = stmtParseInsertTbTags(pSql, pStmt); int32_t ret = stmtParseInsertTbTags(pSql, pStmt);
if (ret != TSDB_CODE_SUCCESS) { if (ret != TSDB_CODE_SUCCESS) {
return ret; STMT_RET(ret);
} }
if (pStmt->multiTbInsert) { if (pStmt->multiTbInsert) {
return TSDB_CODE_SUCCESS; STMT_RET(TSDB_CODE_SUCCESS);
} }
memset(&pStmt->mtb, 0, sizeof(pStmt->mtb)); memset(&pStmt->mtb, 0, sizeof(pStmt->mtb));
...@@ -1489,14 +1516,14 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) { ...@@ -1489,14 +1516,14 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) {
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
// wait for the callback function to post the semaphore // wait for the callback function to post the semaphore
tsem_wait(&pSql->rspSem); tsem_wait(&pSql->rspSem);
return pSql->res.code; STMT_RET(pSql->res.code);
} }
return code; STMT_RET(code);
} }
pStmt->isInsert = false; pStmt->isInsert = false;
return normalStmtPrepare(pStmt); STMT_RET(normalStmtPrepare(pStmt));
} }
int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags) { int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags) {
...@@ -1505,25 +1532,22 @@ int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags ...@@ -1505,25 +1532,22 @@ int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags
SSqlCmd* pCmd = &pSql->cmd; SSqlCmd* pCmd = &pSql->cmd;
if (stmt == NULL || pStmt->pSql == NULL || pStmt->taos == NULL) { if (stmt == NULL || pStmt->pSql == NULL || pStmt->taos == NULL) {
terrno = TSDB_CODE_TSC_DISCONNECTED; STMT_RET(TSDB_CODE_TSC_DISCONNECTED);
return TSDB_CODE_TSC_DISCONNECTED;
} }
if (name == NULL) { if (name == NULL) {
terrno = TSDB_CODE_TSC_APP_ERROR;
tscError("0x%"PRIx64" name is NULL", pSql->self); tscError("0x%"PRIx64" name is NULL", pSql->self);
return TSDB_CODE_TSC_APP_ERROR; STMT_RET(invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), "name is NULL"));
} }
if (pStmt->multiTbInsert == false || !tscIsInsertData(pSql->sqlstr)) { if (pStmt->multiTbInsert == false || !tscIsInsertData(pSql->sqlstr)) {
terrno = TSDB_CODE_TSC_APP_ERROR; tscError("0x%"PRIx64" not multiple table insert", pSql->self);
tscError("0x%"PRIx64" not multi table insert", pSql->self); STMT_RET(invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), "not multiple table insert"));
return TSDB_CODE_TSC_APP_ERROR;
} }
if (pStmt->last == STMT_INIT || pStmt->last == STMT_BIND || pStmt->last == STMT_BIND_COL) { if (pStmt->last == STMT_INIT || pStmt->last == STMT_BIND || pStmt->last == STMT_BIND_COL) {
tscError("0x%"PRIx64" settbname status error, last:%d", pSql->self, pStmt->last); tscError("0x%"PRIx64" set_tbname_tags status error, last:%d", pSql->self, pStmt->last);
return TSDB_CODE_TSC_APP_ERROR; STMT_RET(invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), "set_tbname_tags status error"));
} }
pStmt->last = STMT_SETTBNAME; pStmt->last = STMT_SETTBNAME;
...@@ -1535,7 +1559,7 @@ int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags ...@@ -1535,7 +1559,7 @@ int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags
STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pStmt->mtb.pTableBlockHashList, (const char*)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid)); STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pStmt->mtb.pTableBlockHashList, (const char*)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid));
if (t1 == NULL) { if (t1 == NULL) {
tscError("0x%"PRIx64" no table data block in hash list, uid:%" PRId64 , pSql->self, pStmt->mtb.currentUid); tscError("0x%"PRIx64" no table data block in hash list, uid:%" PRId64 , pSql->self, pStmt->mtb.currentUid);
return TSDB_CODE_TSC_APP_ERROR; STMT_RET(TSDB_CODE_TSC_APP_ERROR);
} }
SSubmitBlk* pBlk = (SSubmitBlk*) (*t1)->pData; SSubmitBlk* pBlk = (SSubmitBlk*) (*t1)->pData;
...@@ -1544,7 +1568,7 @@ int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags ...@@ -1544,7 +1568,7 @@ int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags
taosHashPut(pCmd->insertParam.pTableBlockHashList, (void *)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid), (void*)t1, POINTER_BYTES); taosHashPut(pCmd->insertParam.pTableBlockHashList, (void *)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid), (void*)t1, POINTER_BYTES);
tscDebug("0x%"PRIx64" table:%s is already prepared, uid:%" PRIu64, pSql->self, name, pStmt->mtb.currentUid); tscDebug("0x%"PRIx64" table:%s is already prepared, uid:%" PRIu64, pSql->self, name, pStmt->mtb.currentUid);
return TSDB_CODE_SUCCESS; STMT_RET(TSDB_CODE_SUCCESS);
} }
if (pStmt->mtb.tagSet) { if (pStmt->mtb.tagSet) {
...@@ -1552,12 +1576,12 @@ int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags ...@@ -1552,12 +1576,12 @@ int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags
} else { } else {
if (tags == NULL) { if (tags == NULL) {
tscError("No tags set"); tscError("No tags set");
return TSDB_CODE_TSC_APP_ERROR; STMT_RET(invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), "no tags set"));
} }
int32_t ret = stmtGenInsertStatement(pSql, pStmt, name, tags); int32_t ret = stmtGenInsertStatement(pSql, pStmt, name, tags);
if (ret != TSDB_CODE_SUCCESS) { if (ret != TSDB_CODE_SUCCESS) {
return ret; STMT_RET(ret);
} }
} }
...@@ -1591,7 +1615,7 @@ int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags ...@@ -1591,7 +1615,7 @@ int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags
code = tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk), code = tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL); pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
return code; STMT_RET(code);
} }
SSubmitBlk* blk = (SSubmitBlk*)pBlock->pData; SSubmitBlk* blk = (SSubmitBlk*)pBlock->pData;
...@@ -1606,7 +1630,7 @@ int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags ...@@ -1606,7 +1630,7 @@ int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags
tscDebug("0x%"PRIx64" table:%s is prepared, uid:%" PRIx64, pSql->self, name, pStmt->mtb.currentUid); tscDebug("0x%"PRIx64" table:%s is prepared, uid:%" PRIx64, pSql->self, name, pStmt->mtb.currentUid);
} }
return code; STMT_RET(code);
} }
...@@ -1639,35 +1663,34 @@ int taos_stmt_close(TAOS_STMT* stmt) { ...@@ -1639,35 +1663,34 @@ int taos_stmt_close(TAOS_STMT* stmt) {
} }
taos_free_result(pStmt->pSql); taos_free_result(pStmt->pSql);
free(pStmt); tfree(pStmt);
return TSDB_CODE_SUCCESS; STMT_RET(TSDB_CODE_SUCCESS);
} }
int taos_stmt_bind_param(TAOS_STMT* stmt, TAOS_BIND* bind) { int taos_stmt_bind_param(TAOS_STMT* stmt, TAOS_BIND* bind) {
STscStmt* pStmt = (STscStmt*)stmt; STscStmt* pStmt = (STscStmt*)stmt;
if (stmt == NULL || pStmt->pSql == NULL || pStmt->taos == NULL) { if (stmt == NULL || pStmt->pSql == NULL || pStmt->taos == NULL) {
terrno = TSDB_CODE_TSC_DISCONNECTED; STMT_RET(TSDB_CODE_TSC_DISCONNECTED);
return TSDB_CODE_TSC_DISCONNECTED;
} }
if (pStmt->isInsert) { if (pStmt->isInsert) {
if (pStmt->multiTbInsert) { if (pStmt->multiTbInsert) {
if (pStmt->last != STMT_SETTBNAME && pStmt->last != STMT_ADD_BATCH) { if (pStmt->last != STMT_SETTBNAME && pStmt->last != STMT_ADD_BATCH) {
tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last); tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last);
return TSDB_CODE_TSC_APP_ERROR; STMT_RET(invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), "bind param status error"));
} }
} else { } else {
if (pStmt->last != STMT_PREPARE && pStmt->last != STMT_ADD_BATCH && pStmt->last != STMT_EXECUTE) { if (pStmt->last != STMT_PREPARE && pStmt->last != STMT_ADD_BATCH && pStmt->last != STMT_EXECUTE) {
tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last); tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last);
return TSDB_CODE_TSC_APP_ERROR; STMT_RET(invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), "bind param status error"));
} }
} }
pStmt->last = STMT_BIND; pStmt->last = STMT_BIND;
return insertStmtBindParam(pStmt, bind); STMT_RET(insertStmtBindParam(pStmt, bind));
} else { } else {
return normalStmtBindParam(pStmt, bind); STMT_RET(normalStmtBindParam(pStmt, bind));
} }
} }
...@@ -1676,69 +1699,67 @@ int taos_stmt_bind_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind) { ...@@ -1676,69 +1699,67 @@ int taos_stmt_bind_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind) {
STscStmt* pStmt = (STscStmt*)stmt; STscStmt* pStmt = (STscStmt*)stmt;
if (stmt == NULL || pStmt->pSql == NULL || pStmt->taos == NULL) { if (stmt == NULL || pStmt->pSql == NULL || pStmt->taos == NULL) {
terrno = TSDB_CODE_TSC_DISCONNECTED; STMT_RET(TSDB_CODE_TSC_DISCONNECTED);
return TSDB_CODE_TSC_DISCONNECTED;
} }
if (bind == NULL || bind->num <= 0 || bind->num > INT16_MAX) { if (bind == NULL || bind->num <= 0 || bind->num > INT16_MAX) {
tscError("0x%"PRIx64" invalid parameter", pStmt->pSql->self); tscError("0x%"PRIx64" invalid parameter", pStmt->pSql->self);
return TSDB_CODE_TSC_APP_ERROR; STMT_RET(invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), "invalid bind param"));
} }
if (!pStmt->isInsert) { if (!pStmt->isInsert) {
tscError("0x%"PRIx64" not or invalid batch insert", pStmt->pSql->self); tscError("0x%"PRIx64" not or invalid batch insert", pStmt->pSql->self);
return TSDB_CODE_TSC_APP_ERROR; STMT_RET(invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), "not or invalid batch insert"));
} }
if (pStmt->multiTbInsert) { if (pStmt->multiTbInsert) {
if (pStmt->last != STMT_SETTBNAME && pStmt->last != STMT_ADD_BATCH) { if (pStmt->last != STMT_SETTBNAME && pStmt->last != STMT_ADD_BATCH) {
tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last); tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last);
return TSDB_CODE_TSC_APP_ERROR; STMT_RET(invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), "bind param status error"));
} }
} else { } else {
if (pStmt->last != STMT_PREPARE && pStmt->last != STMT_ADD_BATCH && pStmt->last != STMT_EXECUTE) { if (pStmt->last != STMT_PREPARE && pStmt->last != STMT_ADD_BATCH && pStmt->last != STMT_EXECUTE) {
tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last); tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last);
return TSDB_CODE_TSC_APP_ERROR; STMT_RET(invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), "bind param status error"));
} }
} }
pStmt->last = STMT_BIND; pStmt->last = STMT_BIND;
return insertStmtBindParamBatch(pStmt, bind, -1); STMT_RET(insertStmtBindParamBatch(pStmt, bind, -1));
} }
int taos_stmt_bind_single_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind, int colIdx) { int taos_stmt_bind_single_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind, int colIdx) {
STscStmt* pStmt = (STscStmt*)stmt; STscStmt* pStmt = (STscStmt*)stmt;
if (stmt == NULL || pStmt->pSql == NULL || pStmt->taos == NULL) { if (stmt == NULL || pStmt->pSql == NULL || pStmt->taos == NULL) {
terrno = TSDB_CODE_TSC_DISCONNECTED; STMT_RET(TSDB_CODE_TSC_DISCONNECTED);
return TSDB_CODE_TSC_DISCONNECTED;
} }
if (bind == NULL || bind->num <= 0 || bind->num > INT16_MAX) { if (bind == NULL || bind->num <= 0 || bind->num > INT16_MAX) {
tscError("0x%"PRIx64" invalid parameter", pStmt->pSql->self); tscError("0x%"PRIx64" invalid parameter", pStmt->pSql->self);
return TSDB_CODE_TSC_APP_ERROR; STMT_RET(invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), "invalid bind param"));
} }
if (!pStmt->isInsert) { if (!pStmt->isInsert) {
tscError("0x%"PRIx64" not or invalid batch insert", pStmt->pSql->self); tscError("0x%"PRIx64" not or invalid batch insert", pStmt->pSql->self);
return TSDB_CODE_TSC_APP_ERROR; STMT_RET(invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), "not or invalid batch insert"));
} }
if (pStmt->multiTbInsert) { if (pStmt->multiTbInsert) {
if (pStmt->last != STMT_SETTBNAME && pStmt->last != STMT_ADD_BATCH && pStmt->last != STMT_BIND_COL) { if (pStmt->last != STMT_SETTBNAME && pStmt->last != STMT_ADD_BATCH && pStmt->last != STMT_BIND_COL) {
tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last); tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last);
return TSDB_CODE_TSC_APP_ERROR; STMT_RET(invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), "bind param status error"));
} }
} else { } else {
if (pStmt->last != STMT_PREPARE && pStmt->last != STMT_ADD_BATCH && pStmt->last != STMT_BIND_COL && pStmt->last != STMT_EXECUTE) { if (pStmt->last != STMT_PREPARE && pStmt->last != STMT_ADD_BATCH && pStmt->last != STMT_BIND_COL && pStmt->last != STMT_EXECUTE) {
tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last); tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last);
return TSDB_CODE_TSC_APP_ERROR; STMT_RET(invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), "bind param status error"));
} }
} }
pStmt->last = STMT_BIND_COL; pStmt->last = STMT_BIND_COL;
return insertStmtBindParamBatch(pStmt, bind, colIdx); STMT_RET(insertStmtBindParamBatch(pStmt, bind, colIdx));
} }
...@@ -1746,44 +1767,42 @@ int taos_stmt_bind_single_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind, in ...@@ -1746,44 +1767,42 @@ int taos_stmt_bind_single_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind, in
int taos_stmt_add_batch(TAOS_STMT* stmt) { int taos_stmt_add_batch(TAOS_STMT* stmt) {
STscStmt* pStmt = (STscStmt*)stmt; STscStmt* pStmt = (STscStmt*)stmt;
if (stmt == NULL || pStmt->pSql == NULL || pStmt->taos == NULL) { if (stmt == NULL || pStmt->pSql == NULL || pStmt->taos == NULL) {
terrno = TSDB_CODE_TSC_DISCONNECTED; STMT_RET(TSDB_CODE_TSC_DISCONNECTED);
return TSDB_CODE_TSC_DISCONNECTED;
} }
if (pStmt->isInsert) { if (pStmt->isInsert) {
if (pStmt->last != STMT_BIND && pStmt->last != STMT_BIND_COL) { if (pStmt->last != STMT_BIND && pStmt->last != STMT_BIND_COL) {
tscError("0x%"PRIx64" add batch status error, last:%d", pStmt->pSql->self, pStmt->last); tscError("0x%"PRIx64" add batch status error, last:%d", pStmt->pSql->self, pStmt->last);
return TSDB_CODE_TSC_APP_ERROR; STMT_RET(invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), "add batch status error"));
} }
pStmt->last = STMT_ADD_BATCH; pStmt->last = STMT_ADD_BATCH;
return insertStmtAddBatch(pStmt); STMT_RET(insertStmtAddBatch(pStmt));
} }
return TSDB_CODE_COM_OPS_NOT_SUPPORT; STMT_RET(TSDB_CODE_COM_OPS_NOT_SUPPORT);
} }
int taos_stmt_reset(TAOS_STMT* stmt) { int taos_stmt_reset(TAOS_STMT* stmt) {
STscStmt* pStmt = (STscStmt*)stmt; STscStmt* pStmt = (STscStmt*)stmt;
if (pStmt->isInsert) { if (pStmt->isInsert) {
return insertStmtReset(pStmt); STMT_RET(insertStmtReset(pStmt));
} }
return TSDB_CODE_SUCCESS; STMT_RET(TSDB_CODE_SUCCESS);
} }
int taos_stmt_execute(TAOS_STMT* stmt) { int taos_stmt_execute(TAOS_STMT* stmt) {
int ret = 0; int ret = 0;
STscStmt* pStmt = (STscStmt*)stmt; STscStmt* pStmt = (STscStmt*)stmt;
if (stmt == NULL || pStmt->pSql == NULL || pStmt->taos == NULL) { if (stmt == NULL || pStmt->pSql == NULL || pStmt->taos == NULL) {
terrno = TSDB_CODE_TSC_DISCONNECTED; STMT_RET(TSDB_CODE_TSC_DISCONNECTED);
return TSDB_CODE_TSC_DISCONNECTED;
} }
if (pStmt->isInsert) { if (pStmt->isInsert) {
if (pStmt->last != STMT_ADD_BATCH) { if (pStmt->last != STMT_ADD_BATCH) {
tscError("0x%"PRIx64" exec status error, last:%d", pStmt->pSql->self, pStmt->last); tscError("0x%"PRIx64" exec status error, last:%d", pStmt->pSql->self, pStmt->last);
return TSDB_CODE_TSC_APP_ERROR; STMT_RET(invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), "exec status error"));
} }
pStmt->last = STMT_EXECUTE; pStmt->last = STMT_EXECUTE;
...@@ -1809,7 +1828,7 @@ int taos_stmt_execute(TAOS_STMT* stmt) { ...@@ -1809,7 +1828,7 @@ int taos_stmt_execute(TAOS_STMT* stmt) {
} }
} }
return ret; STMT_RET(ret);
} }
TAOS_RES *taos_stmt_use_result(TAOS_STMT* stmt) { TAOS_RES *taos_stmt_use_result(TAOS_STMT* stmt) {
...@@ -1833,32 +1852,30 @@ int taos_stmt_is_insert(TAOS_STMT *stmt, int *insert) { ...@@ -1833,32 +1852,30 @@ int taos_stmt_is_insert(TAOS_STMT *stmt, int *insert) {
STscStmt* pStmt = (STscStmt*)stmt; STscStmt* pStmt = (STscStmt*)stmt;
if (stmt == NULL || pStmt->taos == NULL || pStmt->pSql == NULL) { if (stmt == NULL || pStmt->taos == NULL || pStmt->pSql == NULL) {
terrno = TSDB_CODE_TSC_DISCONNECTED; STMT_RET(TSDB_CODE_TSC_DISCONNECTED);
return TSDB_CODE_TSC_DISCONNECTED;
} }
if (insert) *insert = pStmt->isInsert; if (insert) *insert = pStmt->isInsert;
return TSDB_CODE_SUCCESS; STMT_RET(TSDB_CODE_SUCCESS);
} }
int taos_stmt_num_params(TAOS_STMT *stmt, int *nums) { int taos_stmt_num_params(TAOS_STMT *stmt, int *nums) {
STscStmt* pStmt = (STscStmt*)stmt; STscStmt* pStmt = (STscStmt*)stmt;
if (stmt == NULL || pStmt->taos == NULL || pStmt->pSql == NULL) { if (stmt == NULL || pStmt->taos == NULL || pStmt->pSql == NULL) {
terrno = TSDB_CODE_TSC_DISCONNECTED; STMT_RET(TSDB_CODE_TSC_DISCONNECTED);
return TSDB_CODE_TSC_DISCONNECTED;
} }
if (pStmt->isInsert) { if (pStmt->isInsert) {
SSqlObj* pSql = pStmt->pSql; SSqlObj* pSql = pStmt->pSql;
SSqlCmd *pCmd = &pSql->cmd; SSqlCmd *pCmd = &pSql->cmd;
*nums = pCmd->insertParam.numOfParams; *nums = pCmd->insertParam.numOfParams;
return TSDB_CODE_SUCCESS; STMT_RET(TSDB_CODE_SUCCESS);
} else { } else {
SNormalStmt* normal = &pStmt->normal; SNormalStmt* normal = &pStmt->normal;
*nums = normal->numParams; *nums = normal->numParams;
return TSDB_CODE_SUCCESS; STMT_RET(TSDB_CODE_SUCCESS);
} }
} }
...@@ -1866,8 +1883,7 @@ int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes) { ...@@ -1866,8 +1883,7 @@ int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes) {
STscStmt* pStmt = (STscStmt*)stmt; STscStmt* pStmt = (STscStmt*)stmt;
if (stmt == NULL || pStmt->taos == NULL || pStmt->pSql == NULL) { if (stmt == NULL || pStmt->taos == NULL || pStmt->pSql == NULL) {
terrno = TSDB_CODE_TSC_DISCONNECTED; STMT_RET(TSDB_CODE_TSC_DISCONNECTED);
return TSDB_CODE_TSC_DISCONNECTED;
} }
if (pStmt->isInsert) { if (pStmt->isInsert) {
...@@ -1884,24 +1900,37 @@ int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes) { ...@@ -1884,24 +1900,37 @@ int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes) {
tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk), tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL); pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
if (ret != 0) { if (ret != 0) {
// todo handle error STMT_RET(ret);
} }
if (idx<0 || idx>=pBlock->numOfParams) { if (idx<0 || idx>=pBlock->numOfParams) {
tscError("0x%"PRIx64" param %d: out of range", pStmt->pSql->self, idx); tscError("0x%"PRIx64" param %d: out of range", pStmt->pSql->self, idx);
abort(); STMT_RET(invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), "idx out of range"));
} }
SParamInfo* param = &pBlock->params[idx]; SParamInfo* param = &pBlock->params[idx];
if (type) *type = param->type; if (type) *type = param->type;
if (bytes) *bytes = param->bytes; if (bytes) *bytes = param->bytes;
return TSDB_CODE_SUCCESS; STMT_RET(TSDB_CODE_SUCCESS);
} else { } else {
return TSDB_CODE_TSC_APP_ERROR; STMT_RET(TSDB_CODE_COM_OPS_NOT_SUPPORT);
}
}
char *taos_stmt_errstr(TAOS_STMT *stmt) {
STscStmt* pStmt = (STscStmt*)stmt;
if (stmt == NULL) {
return (char*) tstrerror(terrno);
} }
return taos_errstr(pStmt->pSql);
} }
const char *taos_data_type(int type) { const char *taos_data_type(int type) {
switch (type) { switch (type) {
case TSDB_DATA_TYPE_NULL: return "TSDB_DATA_TYPE_NULL"; case TSDB_DATA_TYPE_NULL: return "TSDB_DATA_TYPE_NULL";
......
...@@ -63,6 +63,9 @@ static SExprInfo* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t colIndex, int3 ...@@ -63,6 +63,9 @@ static SExprInfo* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t colIndex, int3
static int32_t setShowInfo(SSqlObj* pSql, SSqlInfo* pInfo); static int32_t setShowInfo(SSqlObj* pSql, SSqlInfo* pInfo);
static char* getAccountId(SSqlObj* pSql); static char* getAccountId(SSqlObj* pSql);
static bool serializeExprListToVariant(SArray* pList, tVariant **dest, int16_t colType);
static int32_t validateParamOfRelationIn(tVariant *pVar, int32_t colType);
static bool has(SArray* pFieldList, int32_t startIdx, const char* name); static bool has(SArray* pFieldList, int32_t startIdx, const char* name);
static char* cloneCurrentDBName(SSqlObj* pSql); static char* cloneCurrentDBName(SSqlObj* pSql);
static int32_t getDelimiterIndex(SStrToken* pTableName); static int32_t getDelimiterIndex(SStrToken* pTableName);
...@@ -134,14 +137,97 @@ static bool validateDebugFlag(int32_t v); ...@@ -134,14 +137,97 @@ static bool validateDebugFlag(int32_t v);
static int32_t checkQueryRangeForFill(SSqlCmd* pCmd, SQueryInfo* pQueryInfo); static int32_t checkQueryRangeForFill(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
static int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo); static int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo);
static bool isTimeWindowQuery(SQueryInfo* pQueryInfo) { static bool isTimeWindowQuery(SQueryInfo* pQueryInfo) {
return pQueryInfo->interval.interval > 0 || pQueryInfo->sessionWindow.gap > 0; return pQueryInfo->interval.interval > 0 || pQueryInfo->sessionWindow.gap > 0;
} }
int16_t getNewResColId(SSqlCmd* pCmd) { int16_t getNewResColId(SSqlCmd* pCmd) {
return pCmd->resColumnId--; return pCmd->resColumnId--;
} }
// serialize expr in exprlist to binary
// formate "type | size | value"
bool serializeExprListToVariant(SArray* pList, tVariant **dst, int16_t colType) {
bool ret = false;
if (!pList || pList->size <= 0) {
return ret;
}
if (colType == TSDB_DATA_TYPE_DOUBLE || colType == TSDB_DATA_TYPE_FLOAT) {
return ret;
}
tSqlExprItem* item = (tSqlExprItem *)taosArrayGet(pList, 0);
int32_t firstTokenType = item->pNode->token.type;
int32_t type = firstTokenType;
//nchar to binary and
toTSDBType(type);
if (type != colType && (type != TSDB_DATA_TYPE_BINARY || colType != TSDB_DATA_TYPE_NCHAR)) {
return false;
}
type = colType;
SBufferWriter bw = tbufInitWriter( NULL, false );
tbufEnsureCapacity(&bw, 512);
int32_t size = (int32_t)(pList->size);
tbufWriteUint32(&bw, type);
tbufWriteInt32(&bw, size);
for (int32_t i = 0; i < size; i++) {
tSqlExpr* pSub = ((tSqlExprItem*)(taosArrayGet(pList, i)))->pNode;
// check all the token type in expr list same or not
if (firstTokenType != pSub->token.type) {
break;
}
toTSDBType(pSub->token.type);
tVariant var;
tVariantCreate(&var, &pSub->token);
if (type == TSDB_DATA_TYPE_BOOL || type == TSDB_DATA_TYPE_TINYINT || type == TSDB_DATA_TYPE_SMALLINT
|| type == TSDB_DATA_TYPE_BIGINT || type == TSDB_DATA_TYPE_INT) {
tbufWriteInt64(&bw, var.i64);
} else if (type == TSDB_DATA_TYPE_DOUBLE || type == TSDB_DATA_TYPE_FLOAT) {
tbufWriteDouble(&bw, var.dKey);
} else if (type == TSDB_DATA_TYPE_BINARY){
tbufWriteBinary(&bw, var.pz, var.nLen);
} else if (type == TSDB_DATA_TYPE_NCHAR) {
char *buf = (char *)calloc(1, (var.nLen + 1)*TSDB_NCHAR_SIZE);
if (tVariantDump(&var, buf, type, false) != TSDB_CODE_SUCCESS) {
free(buf);
tVariantDestroy(&var);
break;
}
tbufWriteBinary(&bw, buf, twcslen((wchar_t *)buf) * TSDB_NCHAR_SIZE);
free(buf);
}
tVariantDestroy(&var);
if (i == size - 1) { ret = true;}
}
if (ret == true) {
if ((*dst = calloc(1, sizeof(tVariant))) != NULL) {
tVariantCreateFromBinary(*dst, tbufGetData(&bw, false), tbufTell(&bw), TSDB_DATA_TYPE_BINARY);
} else {
ret = false;
}
}
tbufCloseWriter(&bw);
return ret;
}
static int32_t validateParamOfRelationIn(tVariant *pVar, int32_t colType) {
if (pVar->nType != TSDB_DATA_TYPE_BINARY) {
return -1;
}
SBufferReader br = tbufInitReader(pVar->pz, pVar->nLen, false);
return colType == TSDB_DATA_TYPE_NCHAR ? 0 : (tbufReadUint32(&br) == colType ? 0: -1);
}
static uint8_t convertOptr(SStrToken *pToken) { static uint8_t convertOptr(SStrToken *pToken) {
switch (pToken->type) { switch (pToken->type) {
case TK_LT: case TK_LT:
...@@ -162,6 +248,7 @@ static uint8_t convertOptr(SStrToken *pToken) { ...@@ -162,6 +248,7 @@ static uint8_t convertOptr(SStrToken *pToken) {
return TSDB_RELATION_EQUAL; return TSDB_RELATION_EQUAL;
case TK_PLUS: case TK_PLUS:
return TSDB_BINARY_OP_ADD; return TSDB_BINARY_OP_ADD;
case TK_MINUS: case TK_MINUS:
return TSDB_BINARY_OP_SUBTRACT; return TSDB_BINARY_OP_SUBTRACT;
case TK_STAR: case TK_STAR:
...@@ -177,6 +264,8 @@ static uint8_t convertOptr(SStrToken *pToken) { ...@@ -177,6 +264,8 @@ static uint8_t convertOptr(SStrToken *pToken) {
return TSDB_RELATION_ISNULL; return TSDB_RELATION_ISNULL;
case TK_NOTNULL: case TK_NOTNULL:
return TSDB_RELATION_NOTNULL; return TSDB_RELATION_NOTNULL;
case TK_IN:
return TSDB_RELATION_IN;
default: { return 0; } default: { return 0; }
} }
} }
...@@ -2157,11 +2246,14 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col ...@@ -2157,11 +2246,14 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
case TSDB_FUNC_MIN: case TSDB_FUNC_MIN:
case TSDB_FUNC_MAX: case TSDB_FUNC_MAX:
case TSDB_FUNC_DIFF: case TSDB_FUNC_DIFF:
case TSDB_FUNC_DERIVATIVE:
case TSDB_FUNC_STDDEV: case TSDB_FUNC_STDDEV:
case TSDB_FUNC_LEASTSQR: { case TSDB_FUNC_LEASTSQR: {
// 1. valid the number of parameters // 1. valid the number of parameters
if (pItem->pNode->pParam == NULL || (functionId != TSDB_FUNC_LEASTSQR && taosArrayGetSize(pItem->pNode->pParam) != 1) || int32_t numOfParams = (pItem->pNode->pParam == NULL)? 0: (int32_t) taosArrayGetSize(pItem->pNode->pParam);
(functionId == TSDB_FUNC_LEASTSQR && taosArrayGetSize(pItem->pNode->pParam) != 3)) { if (pItem->pNode->pParam == NULL ||
(functionId != TSDB_FUNC_LEASTSQR && functionId != TSDB_FUNC_DERIVATIVE && numOfParams != 1) ||
((functionId == TSDB_FUNC_LEASTSQR || functionId == TSDB_FUNC_DERIVATIVE) && numOfParams != 3)) {
/* no parameters or more than one parameter for function */ /* no parameters or more than one parameter for function */
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
} }
...@@ -2182,11 +2274,13 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col ...@@ -2182,11 +2274,13 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
// 2. check if sql function can be applied on this column data type // 2. check if sql function can be applied on this column data type
pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
STableComInfo info = tscGetTableInfo(pTableMetaInfo->pTableMeta);
SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
if (!IS_NUMERIC_TYPE(pSchema->type)) { if (!IS_NUMERIC_TYPE(pSchema->type)) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
} else if (IS_UNSIGNED_NUMERIC_TYPE(pSchema->type) && functionId == TSDB_FUNC_DIFF) { } else if (IS_UNSIGNED_NUMERIC_TYPE(pSchema->type) && (functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_DERIVATIVE)) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg9); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg9);
} }
...@@ -2200,11 +2294,11 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col ...@@ -2200,11 +2294,11 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
} }
// set the first column ts for diff query // set the first column ts for diff query
if (functionId == TSDB_FUNC_DIFF) { if (functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_DERIVATIVE) {
colIndex += 1; colIndex += 1;
SColumnIndex indexTS = {.tableIndex = index.tableIndex, .columnIndex = 0}; SColumnIndex indexTS = {.tableIndex = index.tableIndex, .columnIndex = 0};
SExprInfo* pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &indexTS, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, SExprInfo* pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &indexTS, TSDB_DATA_TYPE_TIMESTAMP,
getNewResColId(pCmd), TSDB_KEYSIZE, false); TSDB_KEYSIZE, getNewResColId(pCmd), TSDB_KEYSIZE, false);
SColumnList ids = createColumnList(1, 0, 0); SColumnList ids = createColumnList(1, 0, 0);
insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS_DUMMY].name, pExpr); insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS_DUMMY].name, pExpr);
...@@ -2230,12 +2324,29 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col ...@@ -2230,12 +2324,29 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
tscExprAddParams(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double)); tscExprAddParams(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, DOUBLE_BYTES);
} else if (functionId == TSDB_FUNC_IRATE) { } else if (functionId == TSDB_FUNC_IRATE) {
STableComInfo info = tscGetTableInfo(pTableMetaInfo->pTableMeta);
int64_t prec = info.precision; int64_t prec = info.precision;
tscExprAddParams(&pExpr->base, (char*)&prec, TSDB_DATA_TYPE_BIGINT, LONG_BYTES); tscExprAddParams(&pExpr->base, (char*)&prec, TSDB_DATA_TYPE_BIGINT, LONG_BYTES);
} else if (functionId == TSDB_FUNC_DERIVATIVE) {
char val[8] = {0};
int64_t tickPerSec = 0;
if (tVariantDump(&pParamElem[1].pNode->value, (char*) &tickPerSec, TSDB_DATA_TYPE_BIGINT, true) < 0) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
if (info.precision == TSDB_TIME_PRECISION_MILLI) {
tickPerSec /= 1000;
}
tscExprAddParams(&pExpr->base, (char*) &tickPerSec, TSDB_DATA_TYPE_BIGINT, LONG_BYTES);
memset(val, 0, tListLen(val));
if (tVariantDump(&pParamElem[2].pNode->value, val, TSDB_DATA_TYPE_BIGINT, true) < 0) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
tscExprAddParams(&pExpr->base, val, TSDB_DATA_TYPE_BIGINT, LONG_BYTES);
} }
SColumnList ids = createColumnList(1, index.tableIndex, index.columnIndex); SColumnList ids = createColumnList(1, index.tableIndex, index.columnIndex);
...@@ -2935,8 +3046,8 @@ void tscRestoreFuncForSTableQuery(SQueryInfo* pQueryInfo) { ...@@ -2935,8 +3046,8 @@ void tscRestoreFuncForSTableQuery(SQueryInfo* pQueryInfo) {
} }
bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
const char* msg1 = "TWA not allowed to apply to super table directly"; const char* msg1 = "TWA/Diff not allowed to apply to super table directly";
const char* msg2 = "TWA only support group by tbname for super table query"; const char* msg2 = "TWA/Diff only support group by tbname for super table query";
const char* msg3 = "function not support for super table query"; const char* msg3 = "function not support for super table query";
// filter sql function not supported by metric query yet. // filter sql function not supported by metric query yet.
...@@ -2949,7 +3060,7 @@ bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) ...@@ -2949,7 +3060,7 @@ bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo)
} }
} }
if (tscIsTWAQuery(pQueryInfo)) { if (tscIsTWAQuery(pQueryInfo) || tscIsDiffQuery(pQueryInfo)) {
if (pQueryInfo->groupbyExpr.numOfGroupCols == 0) { if (pQueryInfo->groupbyExpr.numOfGroupCols == 0) {
invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
return true; return true;
...@@ -3207,6 +3318,25 @@ static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, ...@@ -3207,6 +3318,25 @@ static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo,
retVal = tVariantDump(&pRight->value, (char*)&pColumnFilter->upperBndd, colType, false); retVal = tVariantDump(&pRight->value, (char*)&pColumnFilter->upperBndd, colType, false);
// TK_GT,TK_GE,TK_EQ,TK_NE are based on the pColumn->lowerBndd // TK_GT,TK_GE,TK_EQ,TK_NE are based on the pColumn->lowerBndd
} else if (pExpr->tokenId == TK_IN) {
tVariant *pVal;
if (pRight->tokenId != TK_SET || !serializeExprListToVariant(pRight->pParam, &pVal, colType) || colType == TSDB_DATA_TYPE_TIMESTAMP) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg);
}
if (validateParamOfRelationIn(pVal, colType) != TSDB_CODE_SUCCESS) {
tVariantDestroy(pVal);
free(pVal);
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg);
}
pColumnFilter->pz = (int64_t)calloc(1, pVal->nLen + 1);
pColumnFilter->len = pVal->nLen;
pColumnFilter->filterstr = 1;
memcpy((char *)(pColumnFilter->pz), (char *)(pVal->pz), pVal->nLen);
//retVal = tVariantDump(pVal, (char *)(pColumnFilter->pz), TSDB_DATA_TYPE_BINARY, false);
tVariantDestroy(pVal);
free(pVal);
} else if (colType == TSDB_DATA_TYPE_BINARY) { } else if (colType == TSDB_DATA_TYPE_BINARY) {
pColumnFilter->pz = (int64_t)calloc(1, bufLen * TSDB_NCHAR_SIZE); pColumnFilter->pz = (int64_t)calloc(1, bufLen * TSDB_NCHAR_SIZE);
pColumnFilter->len = pRight->value.nLen; pColumnFilter->len = pRight->value.nLen;
...@@ -3255,6 +3385,9 @@ static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, ...@@ -3255,6 +3385,9 @@ static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo,
case TK_NOTNULL: case TK_NOTNULL:
pColumnFilter->lowerRelOptr = TSDB_RELATION_NOTNULL; pColumnFilter->lowerRelOptr = TSDB_RELATION_NOTNULL;
break; break;
case TK_IN:
pColumnFilter->lowerRelOptr = TSDB_RELATION_IN;
break;
default: default:
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg);
} }
...@@ -3370,7 +3503,7 @@ static int32_t extractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SC ...@@ -3370,7 +3503,7 @@ static int32_t extractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SC
&& pExpr->tokenId != TK_ISNULL && pExpr->tokenId != TK_ISNULL
&& pExpr->tokenId != TK_NOTNULL && pExpr->tokenId != TK_NOTNULL
&& pExpr->tokenId != TK_LIKE && pExpr->tokenId != TK_LIKE
) { && pExpr->tokenId != TK_IN) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
} }
} else { } else {
...@@ -3380,7 +3513,7 @@ static int32_t extractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SC ...@@ -3380,7 +3513,7 @@ static int32_t extractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SC
if (pSchema->type == TSDB_DATA_TYPE_BOOL) { if (pSchema->type == TSDB_DATA_TYPE_BOOL) {
int32_t t = pExpr->tokenId; int32_t t = pExpr->tokenId;
if (t != TK_EQ && t != TK_NE && t != TK_NOTNULL && t != TK_ISNULL) { if (t != TK_EQ && t != TK_NE && t != TK_NOTNULL && t != TK_ISNULL && t != TK_IN) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3);
} }
} }
...@@ -4422,7 +4555,11 @@ static int32_t validateTagCondExpr(SSqlCmd* pCmd, tExprNode *p) { ...@@ -4422,7 +4555,11 @@ static int32_t validateTagCondExpr(SSqlCmd* pCmd, tExprNode *p) {
free(tmp); free(tmp);
} else { } else {
double tmp; double tmp;
retVal = tVariantDump(vVariant, (char*)&tmp, schemaType, false); if (p->_node.optr == TSDB_RELATION_IN) {
retVal = validateParamOfRelationIn(vVariant, schemaType);
} else {
retVal = tVariantDump(vVariant, (char*)&tmp, schemaType, false);
}
} }
if (retVal != TSDB_CODE_SUCCESS) { if (retVal != TSDB_CODE_SUCCESS) {
...@@ -6376,7 +6513,7 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { ...@@ -6376,7 +6513,7 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
} }
if (IS_MULTIOUTPUT(aAggs[functId].status) && functId != TSDB_FUNC_TOP && functId != TSDB_FUNC_BOTTOM && if (IS_MULTIOUTPUT(aAggs[functId].status) && functId != TSDB_FUNC_TOP && functId != TSDB_FUNC_BOTTOM &&
functId != TSDB_FUNC_TAGPRJ && functId != TSDB_FUNC_PRJ) { functId != TSDB_FUNC_DIFF && functId != TSDB_FUNC_TAGPRJ && functId != TSDB_FUNC_PRJ) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
} }
...@@ -6858,7 +6995,7 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { ...@@ -6858,7 +6995,7 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
const char* msg6 = "from missing in subclause"; const char* msg6 = "from missing in subclause";
const char* msg7 = "time interval is required"; const char* msg7 = "time interval is required";
const char* msg8 = "the first column should be primary timestamp column"; const char* msg8 = "the first column should be primary timestamp column";
SSqlCmd* pCmd = &pSql->cmd; SSqlCmd* pCmd = &pSql->cmd;
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
assert(pQueryInfo->numOfTables == 1); assert(pQueryInfo->numOfTables == 1);
...@@ -7812,14 +7949,15 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf ...@@ -7812,14 +7949,15 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
} }
{ // set the query info { // set the query info
pQueryInfo->projectionQuery = tscIsProjectionQuery(pQueryInfo); pQueryInfo->projectionQuery = tscIsProjectionQuery(pQueryInfo);
pQueryInfo->hasFilter = tscHasColumnFilter(pQueryInfo); pQueryInfo->hasFilter = tscHasColumnFilter(pQueryInfo);
pQueryInfo->simpleAgg = isSimpleAggregateRv(pQueryInfo); pQueryInfo->simpleAgg = isSimpleAggregateRv(pQueryInfo);
pQueryInfo->onlyTagQuery = onlyTagPrjFunction(pQueryInfo); pQueryInfo->onlyTagQuery = onlyTagPrjFunction(pQueryInfo);
pQueryInfo->groupbyColumn = tscGroupbyColumn(pQueryInfo); pQueryInfo->groupbyColumn = tscGroupbyColumn(pQueryInfo);
pQueryInfo->arithmeticOnAgg = tsIsArithmeticQueryOnAggResult(pQueryInfo); pQueryInfo->arithmeticOnAgg = tsIsArithmeticQueryOnAggResult(pQueryInfo);
pQueryInfo->orderProjectQuery = tscOrderedProjectionQueryOnSTable(pQueryInfo, 0); pQueryInfo->orderProjectQuery = tscOrderedProjectionQueryOnSTable(pQueryInfo, 0);
pQueryInfo->diffQuery = tscIsDiffQuery(pQueryInfo);
SExprInfo** p = NULL; SExprInfo** p = NULL;
int32_t numOfExpr = 0; int32_t numOfExpr = 0;
...@@ -7930,6 +8068,24 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS ...@@ -7930,6 +8068,24 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS
} }
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} else if (pSqlExpr->tokenId == TK_SET) {
int32_t type = -1;
STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta;
if (pCols != NULL) {
SColIndex* idx = taosArrayGet(pCols, 0);
SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, idx->colIndex);
if (pSchema != NULL) {
type = pSchema->type;
}
}
tVariant *pVal;
if (serializeExprListToVariant(pSqlExpr->pParam, &pVal, type) == false) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), "not support filter expression");
}
*pExpr = calloc(1, sizeof(tExprNode));
(*pExpr)->nodeType = TSQL_NODE_VALUE;
(*pExpr)->pVal = pVal;
} else { } else {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), "not support filter expression"); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), "not support filter expression");
} }
......
...@@ -1588,7 +1588,7 @@ int tscProcessLocalRetrieveRsp(SSqlObj *pSql) { ...@@ -1588,7 +1588,7 @@ int tscProcessLocalRetrieveRsp(SSqlObj *pSql) {
return tscLocalResultCommonBuilder(pSql, numOfRes); return tscLocalResultCommonBuilder(pSql, numOfRes);
} }
int tscProcessRetrieveLocalMergeRsp(SSqlObj *pSql) { int tscProcessRetrieveGlobalMergeRsp(SSqlObj *pSql) {
SSqlRes *pRes = &pSql->res; SSqlRes *pRes = &pSql->res;
SSqlCmd* pCmd = &pSql->cmd; SSqlCmd* pCmd = &pSql->cmd;
...@@ -1615,12 +1615,13 @@ int tscProcessRetrieveLocalMergeRsp(SSqlObj *pSql) { ...@@ -1615,12 +1615,13 @@ int tscProcessRetrieveLocalMergeRsp(SSqlObj *pSql) {
taosArrayPush(group, &tableKeyInfo); taosArrayPush(group, &tableKeyInfo);
taosArrayPush(tableGroupInfo.pGroupList, &group); taosArrayPush(tableGroupInfo.pGroupList, &group);
pQueryInfo->pQInfo = createQInfoFromQueryNode(pQueryInfo, &tableGroupInfo, NULL, NULL, pRes->pMerger, MERGE_STAGE); tscDebug("0x%"PRIx64" create QInfo 0x%"PRIx64" to execute query processing", pSql->self, pSql->self);
pQueryInfo->pQInfo = createQInfoFromQueryNode(pQueryInfo, &tableGroupInfo, NULL, NULL, pRes->pMerger, MERGE_STAGE, pSql->self);
} }
uint64_t localQueryId = 0; uint64_t localQueryId = pSql->self;
qTableQuery(pQueryInfo->pQInfo, &localQueryId); qTableQuery(pQueryInfo->pQInfo, &localQueryId);
convertQueryResult(pRes, pQueryInfo); convertQueryResult(pRes, pQueryInfo, pSql->self);
code = pRes->code; code = pRes->code;
if (pRes->code == TSDB_CODE_SUCCESS) { if (pRes->code == TSDB_CODE_SUCCESS) {
...@@ -2689,7 +2690,7 @@ void tscInitMsgsFp() { ...@@ -2689,7 +2690,7 @@ void tscInitMsgsFp() {
tscProcessMsgRsp[TSDB_SQL_RETRIEVE_EMPTY_RESULT] = tscProcessEmptyResultRsp; tscProcessMsgRsp[TSDB_SQL_RETRIEVE_EMPTY_RESULT] = tscProcessEmptyResultRsp;
tscProcessMsgRsp[TSDB_SQL_RETRIEVE_LOCALMERGE] = tscProcessRetrieveLocalMergeRsp; tscProcessMsgRsp[TSDB_SQL_RETRIEVE_GLOBALMERGE] = tscProcessRetrieveGlobalMergeRsp;
tscProcessMsgRsp[TSDB_SQL_ALTER_TABLE] = tscProcessAlterTableMsgRsp; tscProcessMsgRsp[TSDB_SQL_ALTER_TABLE] = tscProcessAlterTableMsgRsp;
tscProcessMsgRsp[TSDB_SQL_ALTER_DB] = tscProcessAlterDbMsgRsp; tscProcessMsgRsp[TSDB_SQL_ALTER_DB] = tscProcessAlterDbMsgRsp;
......
...@@ -456,7 +456,7 @@ static bool needToFetchNewBlock(SSqlObj* pSql) { ...@@ -456,7 +456,7 @@ static bool needToFetchNewBlock(SSqlObj* pSql) {
return (pRes->completed != true || hasMoreVnodesToTry(pSql) || hasMoreClauseToTry(pSql)) && return (pRes->completed != true || hasMoreVnodesToTry(pSql) || hasMoreClauseToTry(pSql)) &&
(pCmd->command == TSDB_SQL_RETRIEVE || (pCmd->command == TSDB_SQL_RETRIEVE ||
pCmd->command == TSDB_SQL_RETRIEVE_LOCALMERGE || pCmd->command == TSDB_SQL_RETRIEVE_GLOBALMERGE ||
pCmd->command == TSDB_SQL_TABLE_JOIN_RETRIEVE || pCmd->command == TSDB_SQL_TABLE_JOIN_RETRIEVE ||
pCmd->command == TSDB_SQL_FETCH || pCmd->command == TSDB_SQL_FETCH ||
pCmd->command == TSDB_SQL_SHOW || pCmd->command == TSDB_SQL_SHOW ||
......
...@@ -1977,9 +1977,8 @@ void tscHandleMasterJoinQuery(SSqlObj* pSql) { ...@@ -1977,9 +1977,8 @@ void tscHandleMasterJoinQuery(SSqlObj* pSql) {
} }
memset(pSql->subState.states, 0, sizeof(*pSql->subState.states) * pSql->subState.numOfSub); memset(pSql->subState.states, 0, sizeof(*pSql->subState.states) * pSql->subState.numOfSub);
tscDebug("0x%"PRIx64" reset all sub states to 0", pSql->self); tscDebug("0x%"PRIx64" reset all sub states to 0, start subquery, total:%d", pSql->self, pQueryInfo->numOfTables);
tscDebug("0x%"PRIx64" start subquery, total:%d", pSql->self, pQueryInfo->numOfTables);
for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
SJoinSupporter *pSupporter = tscCreateJoinSupporter(pSql, i); SJoinSupporter *pSupporter = tscCreateJoinSupporter(pSql, i);
if (pSupporter == NULL) { // failed to create support struct, abort current query if (pSupporter == NULL) { // failed to create support struct, abort current query
...@@ -2424,7 +2423,7 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) { ...@@ -2424,7 +2423,7 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) {
// pRes->code check only serves in launching metric sub-queries // pRes->code check only serves in launching metric sub-queries
if (pRes->code == TSDB_CODE_TSC_QUERY_CANCELLED) { if (pRes->code == TSDB_CODE_TSC_QUERY_CANCELLED) {
pCmd->command = TSDB_SQL_RETRIEVE_LOCALMERGE; // enable the abort of kill super table function. pCmd->command = TSDB_SQL_RETRIEVE_GLOBALMERGE; // enable the abort of kill super table function.
return pRes->code; return pRes->code;
} }
...@@ -2780,7 +2779,7 @@ static void tscAllDataRetrievedFromDnode(SRetrieveSupport *trsupport, SSqlObj* p ...@@ -2780,7 +2779,7 @@ static void tscAllDataRetrievedFromDnode(SRetrieveSupport *trsupport, SSqlObj* p
if (code == TSDB_CODE_SUCCESS && trsupport->pExtMemBuffer == NULL) { if (code == TSDB_CODE_SUCCESS && trsupport->pExtMemBuffer == NULL) {
pParentSql->cmd.command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; // no result, set the result empty pParentSql->cmd.command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; // no result, set the result empty
} else { } else {
pParentSql->cmd.command = TSDB_SQL_RETRIEVE_LOCALMERGE; pParentSql->cmd.command = TSDB_SQL_RETRIEVE_GLOBALMERGE;
} }
tscCreateResPointerInfo(&pParentSql->res, pPQueryInfo); tscCreateResPointerInfo(&pParentSql->res, pPQueryInfo);
...@@ -3502,7 +3501,7 @@ static UNUSED_FUNC bool tscHasRemainDataInSubqueryResultSet(SSqlObj *pSql) { ...@@ -3502,7 +3501,7 @@ static UNUSED_FUNC bool tscHasRemainDataInSubqueryResultSet(SSqlObj *pSql) {
} }
void* createQInfoFromQueryNode(SQueryInfo* pQueryInfo, STableGroupInfo* pTableGroupInfo, SOperatorInfo* pSourceOperator, void* createQInfoFromQueryNode(SQueryInfo* pQueryInfo, STableGroupInfo* pTableGroupInfo, SOperatorInfo* pSourceOperator,
char* sql, void* merger, int32_t stage) { char* sql, void* merger, int32_t stage, uint64_t qId) {
assert(pQueryInfo != NULL); assert(pQueryInfo != NULL);
SQInfo *pQInfo = (SQInfo *)calloc(1, sizeof(SQInfo)); SQInfo *pQInfo = (SQInfo *)calloc(1, sizeof(SQInfo));
if (pQInfo == NULL) { if (pQInfo == NULL) {
...@@ -3511,7 +3510,7 @@ void* createQInfoFromQueryNode(SQueryInfo* pQueryInfo, STableGroupInfo* pTableGr ...@@ -3511,7 +3510,7 @@ void* createQInfoFromQueryNode(SQueryInfo* pQueryInfo, STableGroupInfo* pTableGr
// to make sure third party won't overwrite this structure // to make sure third party won't overwrite this structure
pQInfo->signature = pQInfo; pQInfo->signature = pQInfo;
pQInfo->qId = qId;
SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv; SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv;
SQueryAttr *pQueryAttr = &pQInfo->query; SQueryAttr *pQueryAttr = &pQInfo->query;
......
...@@ -222,6 +222,8 @@ bool tscIsProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex) { ...@@ -222,6 +222,8 @@ bool tscIsProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex) {
functionId != TSDB_FUNC_TS && functionId != TSDB_FUNC_TS &&
functionId != TSDB_FUNC_ARITHM && functionId != TSDB_FUNC_ARITHM &&
functionId != TSDB_FUNC_TS_COMP && functionId != TSDB_FUNC_TS_COMP &&
functionId != TSDB_FUNC_DIFF &&
functionId != TSDB_FUNC_TS_DUMMY &&
functionId != TSDB_FUNC_TID_TAG) { functionId != TSDB_FUNC_TID_TAG) {
return false; return false;
} }
...@@ -434,6 +436,23 @@ bool tscIsTWAQuery(SQueryInfo* pQueryInfo) { ...@@ -434,6 +436,23 @@ bool tscIsTWAQuery(SQueryInfo* pQueryInfo) {
return false; return false;
} }
bool tscIsDiffQuery(SQueryInfo* pQueryInfo) {
size_t num = tscNumOfExprs(pQueryInfo);
for(int32_t i = 0; i < num; ++i) {
SExprInfo* pExpr = tscExprGet(pQueryInfo, i);
if (pExpr == NULL || pExpr->base.functionId == TSDB_FUNC_TS_DUMMY) {
continue;
}
if (pExpr->base.functionId == TSDB_FUNC_DIFF) {
return true;
}
}
return false;
}
bool tscIsSessionWindowQuery(SQueryInfo* pQueryInfo) { bool tscIsSessionWindowQuery(SQueryInfo* pQueryInfo) {
return pQueryInfo->sessionWindow.gap > 0; return pQueryInfo->sessionWindow.gap > 0;
} }
...@@ -467,42 +486,12 @@ bool tscNeedReverseScan(SQueryInfo* pQueryInfo) { ...@@ -467,42 +486,12 @@ bool tscNeedReverseScan(SQueryInfo* pQueryInfo) {
return false; return false;
} }
bool isSimpleAggregate(SQueryInfo* pQueryInfo) {
if (pQueryInfo->interval.interval > 0) {
return false;
}
// Note:top/bottom query is fixed output query
if (tscIsTopBotQuery(pQueryInfo) || tscGroupbyColumn(pQueryInfo) || isTsCompQuery(pQueryInfo)) {
return true;
}
size_t numOfExprs = tscNumOfExprs(pQueryInfo);
for (int32_t i = 0; i < numOfExprs; ++i) {
SExprInfo* pExpr = tscExprGet(pQueryInfo, i);
if (pExpr == NULL) {
continue;
}
int32_t functionId = pExpr->base.functionId;
if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TS_DUMMY) {
continue;
}
if (!IS_MULTIOUTPUT(aAggs[functionId].status)) {
return true;
}
}
return false;
}
bool isSimpleAggregateRv(SQueryInfo* pQueryInfo) { bool isSimpleAggregateRv(SQueryInfo* pQueryInfo) {
if (pQueryInfo->interval.interval > 0 || pQueryInfo->sessionWindow.gap > 0) { if (pQueryInfo->interval.interval > 0 || pQueryInfo->sessionWindow.gap > 0) {
return false; return false;
} }
if (tscGroupbyColumn(pQueryInfo) || isTsCompQuery(pQueryInfo)) { if (tscIsDiffQuery(pQueryInfo)) {
return false; return false;
} }
...@@ -518,13 +507,13 @@ bool isSimpleAggregateRv(SQueryInfo* pQueryInfo) { ...@@ -518,13 +507,13 @@ bool isSimpleAggregateRv(SQueryInfo* pQueryInfo) {
continue; continue;
} }
if (!IS_MULTIOUTPUT(aAggs[functionId].status)) { if ((!IS_MULTIOUTPUT(aAggs[functionId].status)) ||
(functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_TS_COMP)) {
return true; return true;
} }
} }
return false; return false;
} }
bool isBlockDistQuery(SQueryInfo* pQueryInfo) { bool isBlockDistQuery(SQueryInfo* pQueryInfo) {
...@@ -812,6 +801,7 @@ static void fetchNextBlockIfCompleted(SOperatorInfo* pOperator, bool* newgroup) ...@@ -812,6 +801,7 @@ static void fetchNextBlockIfCompleted(SOperatorInfo* pOperator, bool* newgroup)
for (int32_t i = 0; i < pOperator->numOfUpstream; ++i) { for (int32_t i = 0; i < pOperator->numOfUpstream; ++i) {
SJoinStatus* pStatus = &pJoinInfo->status[i]; SJoinStatus* pStatus = &pJoinInfo->status[i];
if (pStatus->pBlock == NULL || pStatus->index >= pStatus->pBlock->info.rows) { if (pStatus->pBlock == NULL || pStatus->index >= pStatus->pBlock->info.rows) {
tscDebug("Retrieve nest query result, index:%d, total:%d", i, pOperator->numOfUpstream);
pStatus->pBlock = pOperator->upstream[i]->exec(pOperator->upstream[i], newgroup); pStatus->pBlock = pOperator->upstream[i]->exec(pOperator->upstream[i], newgroup);
pStatus->index = 0; pStatus->index = 0;
...@@ -1056,7 +1046,7 @@ SOperatorInfo* createJoinOperatorInfo(SOperatorInfo** pUpstream, int32_t numOfUp ...@@ -1056,7 +1046,7 @@ SOperatorInfo* createJoinOperatorInfo(SOperatorInfo** pUpstream, int32_t numOfUp
return pOperator; return pOperator;
} }
void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo) { void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo, uint64_t objId) {
// set the correct result // set the correct result
SSDataBlock* p = pQueryInfo->pQInfo->runtimeEnv.outputBuf; SSDataBlock* p = pQueryInfo->pQInfo->runtimeEnv.outputBuf;
pRes->numOfRows = (p != NULL)? p->info.rows: 0; pRes->numOfRows = (p != NULL)? p->info.rows: 0;
...@@ -1066,6 +1056,7 @@ void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo) { ...@@ -1066,6 +1056,7 @@ void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo) {
tscSetResRawPtrRv(pRes, pQueryInfo, p); tscSetResRawPtrRv(pRes, pQueryInfo, p);
} }
tscDebug("0x%"PRIx64" retrieve result in pRes, numOfRows:%d", objId, pRes->numOfRows);
pRes->row = 0; pRes->row = 0;
pRes->completed = (pRes->numOfRows == 0); pRes->completed = (pRes->numOfRows == 0);
} }
...@@ -1088,7 +1079,9 @@ static void createInputDataFilterInfo(SQueryInfo* px, int32_t numOfCol1, int32_t ...@@ -1088,7 +1079,9 @@ static void createInputDataFilterInfo(SQueryInfo* px, int32_t numOfCol1, int32_t
tfree(tableCols); tfree(tableCols);
} }
void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQueryInfo* px, SSqlRes* pOutput) { void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQueryInfo* px, SSqlObj* pSql) {
SSqlRes* pOutput = &pSql->res;
// handle the following query process // handle the following query process
if (px->pQInfo == NULL) { if (px->pQInfo == NULL) {
SColumnInfo* pColumnInfo = extractColumnInfoFromResult(px->colList); SColumnInfo* pColumnInfo = extractColumnInfoFromResult(px->colList);
...@@ -1168,7 +1161,9 @@ void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQue ...@@ -1168,7 +1161,9 @@ void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQue
} }
} }
px->pQInfo = createQInfoFromQueryNode(px, &tableGroupInfo, pSourceOperator, NULL, NULL, MASTER_SCAN); tscDebug("0x%"PRIx64" create QInfo 0x%"PRIx64" to execute the main query while all nest queries are ready", pSql->self, pSql->self);
px->pQInfo = createQInfoFromQueryNode(px, &tableGroupInfo, pSourceOperator, NULL, NULL, MASTER_SCAN, pSql->self);
tfree(pColumnInfo); tfree(pColumnInfo);
tfree(schema); tfree(schema);
...@@ -1176,9 +1171,9 @@ void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQue ...@@ -1176,9 +1171,9 @@ void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQue
pSourceOperator->pRuntimeEnv = &px->pQInfo->runtimeEnv; pSourceOperator->pRuntimeEnv = &px->pQInfo->runtimeEnv;
} }
uint64_t qId = 0; uint64_t qId = pSql->self;
qTableQuery(px->pQInfo, &qId); qTableQuery(px->pQInfo, &qId);
convertQueryResult(pOutput, px); convertQueryResult(pOutput, px, pSql->self);
} }
static void tscDestroyResPointerInfo(SSqlRes* pRes) { static void tscDestroyResPointerInfo(SSqlRes* pRes) {
...@@ -1374,7 +1369,7 @@ void tscFreeSqlObj(SSqlObj* pSql) { ...@@ -1374,7 +1369,7 @@ void tscFreeSqlObj(SSqlObj* pSql) {
SSqlCmd* pCmd = &pSql->cmd; SSqlCmd* pCmd = &pSql->cmd;
int32_t cmd = pCmd->command; int32_t cmd = pCmd->command;
if (cmd < TSDB_SQL_INSERT || cmd == TSDB_SQL_RETRIEVE_LOCALMERGE || cmd == TSDB_SQL_RETRIEVE_EMPTY_RESULT || if (cmd < TSDB_SQL_INSERT || cmd == TSDB_SQL_RETRIEVE_GLOBALMERGE || cmd == TSDB_SQL_RETRIEVE_EMPTY_RESULT ||
cmd == TSDB_SQL_TABLE_JOIN_RETRIEVE) { cmd == TSDB_SQL_TABLE_JOIN_RETRIEVE) {
tscRemoveFromSqlList(pSql); tscRemoveFromSqlList(pSql);
} }
...@@ -2177,6 +2172,7 @@ size_t tscNumOfExprs(SQueryInfo* pQueryInfo) { ...@@ -2177,6 +2172,7 @@ size_t tscNumOfExprs(SQueryInfo* pQueryInfo) {
return taosArrayGetSize(pQueryInfo->exprList); return taosArrayGetSize(pQueryInfo->exprList);
} }
// todo REFACTOR
void tscExprAddParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes) { void tscExprAddParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes) {
assert (pExpr != NULL || argument != NULL || bytes != 0); assert (pExpr != NULL || argument != NULL || bytes != 0);
...@@ -3278,7 +3274,6 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t ...@@ -3278,7 +3274,6 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t
pNewQueryInfo->numOfTables = 0; pNewQueryInfo->numOfTables = 0;
pNewQueryInfo->pTableMetaInfo = NULL; pNewQueryInfo->pTableMetaInfo = NULL;
pNewQueryInfo->bufLen = pQueryInfo->bufLen; pNewQueryInfo->bufLen = pQueryInfo->bufLen;
pNewQueryInfo->buf = malloc(pQueryInfo->bufLen); pNewQueryInfo->buf = malloc(pQueryInfo->bufLen);
if (pNewQueryInfo->buf == NULL) { if (pNewQueryInfo->buf == NULL) {
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
...@@ -3438,7 +3433,7 @@ void doRetrieveSubqueryData(SSchedMsg *pMsg) { ...@@ -3438,7 +3433,7 @@ void doRetrieveSubqueryData(SSchedMsg *pMsg) {
} }
SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd); SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd);
handleDownstreamOperator(pSql->pSubs, pSql->subState.numOfSub, pQueryInfo, &pSql->res); handleDownstreamOperator(pSql->pSubs, pSql->subState.numOfSub, pQueryInfo, pSql);
pSql->res.qId = -1; pSql->res.qId = -1;
if (pSql->res.code == TSDB_CODE_SUCCESS) { if (pSql->res.code == TSDB_CODE_SUCCESS) {
...@@ -3468,13 +3463,12 @@ static void tscSubqueryRetrieveCallback(void* param, TAOS_RES* tres, int code) { ...@@ -3468,13 +3463,12 @@ static void tscSubqueryRetrieveCallback(void* param, TAOS_RES* tres, int code) {
} }
pParentSql->cmd.active = pParentSql->cmd.pQueryInfo; pParentSql->cmd.active = pParentSql->cmd.pQueryInfo;
pParentSql->res.qId = -1;
SSchedMsg schedMsg = {0}; if (pSql->res.code == TSDB_CODE_SUCCESS) {
schedMsg.fp = doRetrieveSubqueryData; (*pSql->fp)(pParentSql->param, pParentSql, pParentSql->res.numOfRows);
schedMsg.ahandle = (void *)pParentSql; } else {
schedMsg.thandle = (void *)1; tscAsyncResultOnError(pParentSql);
schedMsg.msg = 0; }
taosScheduleTask(tscQhandle, &schedMsg);
} }
// todo handle the failure // todo handle the failure
...@@ -4238,7 +4232,8 @@ int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAt ...@@ -4238,7 +4232,8 @@ int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAt
pQueryAttr->hasTagResults = hasTagValOutput(pQueryInfo); pQueryAttr->hasTagResults = hasTagValOutput(pQueryInfo);
pQueryAttr->stabledev = isStabledev(pQueryInfo); pQueryAttr->stabledev = isStabledev(pQueryInfo);
pQueryAttr->tsCompQuery = isTsCompQuery(pQueryInfo); pQueryAttr->tsCompQuery = isTsCompQuery(pQueryInfo);
pQueryAttr->simpleAgg = isSimpleAggregate(pQueryInfo); pQueryAttr->diffQuery = tscIsDiffQuery(pQueryInfo);
pQueryAttr->simpleAgg = isSimpleAggregateRv(pQueryInfo);
pQueryAttr->needReverseScan = tscNeedReverseScan(pQueryInfo); pQueryAttr->needReverseScan = tscNeedReverseScan(pQueryInfo);
pQueryAttr->stableQuery = QUERY_IS_STABLE_QUERY(pQueryInfo->type); pQueryAttr->stableQuery = QUERY_IS_STABLE_QUERY(pQueryInfo->type);
pQueryAttr->groupbyColumn = (!pQueryInfo->stateWindow) && tscGroupbyColumn(pQueryInfo); pQueryAttr->groupbyColumn = (!pQueryInfo->stateWindow) && tscGroupbyColumn(pQueryInfo);
...@@ -4257,7 +4252,6 @@ int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAt ...@@ -4257,7 +4252,6 @@ int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAt
pQueryAttr->fillType = pQueryInfo->fillType; pQueryAttr->fillType = pQueryInfo->fillType;
pQueryAttr->havingNum = pQueryInfo->havingFieldNum; pQueryAttr->havingNum = pQueryInfo->havingFieldNum;
if (pQueryInfo->order.order == TSDB_ORDER_ASC) { // TODO refactor if (pQueryInfo->order.order == TSDB_ORDER_ASC) { // TODO refactor
pQueryAttr->window = pQueryInfo->window; pQueryAttr->window = pQueryInfo->window;
} else { } else {
......
...@@ -76,7 +76,7 @@ enum { ...@@ -76,7 +76,7 @@ enum {
// SQL below for client local // SQL below for client local
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_LOCAL, "local" ) TSDB_DEFINE_SQL_TYPE( TSDB_SQL_LOCAL, "local" )
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_DESCRIBE_TABLE, "describe-table" ) TSDB_DEFINE_SQL_TYPE( TSDB_SQL_DESCRIBE_TABLE, "describe-table" )
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_RETRIEVE_LOCALMERGE, "retrieve-localmerge" ) TSDB_DEFINE_SQL_TYPE( TSDB_SQL_RETRIEVE_GLOBALMERGE, "retrieve-globalmerge" )
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_TABLE_JOIN_RETRIEVE, "join-retrieve" ) TSDB_DEFINE_SQL_TYPE( TSDB_SQL_TABLE_JOIN_RETRIEVE, "join-retrieve" )
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_SHOW_CREATE_TABLE, "show-create-table") TSDB_DEFINE_SQL_TYPE( TSDB_SQL_SHOW_CREATE_TABLE, "show-create-table")
......
...@@ -94,6 +94,8 @@ bool exprTreeApplyFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp ...@@ -94,6 +94,8 @@ bool exprTreeApplyFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp
void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, void *param, int32_t order, void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, void *param, int32_t order,
char *(*cb)(void *, const char*, int32_t)); char *(*cb)(void *, const char*, int32_t));
void buildFilterSetFromBinary(void **q, const char *buf, int32_t len);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
...@@ -466,6 +466,32 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) { ...@@ -466,6 +466,32 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) {
return expr; return expr;
} }
void buildFilterSetFromBinary(void **q, const char *buf, int32_t len) {
SBufferReader br = tbufInitReader(buf, len, false);
uint32_t type = tbufReadUint32(&br);
SHashObj *pObj = taosHashInit(256, taosGetDefaultHashFunction(type), true, false);
int dummy = -1;
int32_t sz = tbufReadInt32(&br);
for (int32_t i = 0; i < sz; i++) {
if (type == TSDB_DATA_TYPE_BOOL || type == TSDB_DATA_TYPE_TINYINT || type == TSDB_DATA_TYPE_SMALLINT || type == TSDB_DATA_TYPE_BIGINT || type == TSDB_DATA_TYPE_INT) {
int64_t val = tbufReadInt64(&br);
taosHashPut(pObj, (char *)&val, sizeof(val), &dummy, sizeof(dummy));
} else if (type == TSDB_DATA_TYPE_DOUBLE || type == TSDB_DATA_TYPE_FLOAT) {
double val = tbufReadDouble(&br);
taosHashPut(pObj, (char *)&val, sizeof(val), &dummy, sizeof(dummy));
} else if (type == TSDB_DATA_TYPE_BINARY) {
size_t t = 0;
const char *val = tbufReadBinary(&br, &t);
taosHashPut(pObj, (char *)val, t, &dummy, sizeof(dummy));
} else if (type == TSDB_DATA_TYPE_NCHAR) {
size_t t = 0;
const char *val = tbufReadBinary(&br, &t);
taosHashPut(pObj, (char *)val, t, &dummy, sizeof(dummy));
}
}
*q = (void *)pObj;
}
tExprNode* exprdup(tExprNode* pNode) { tExprNode* exprdup(tExprNode* pNode) {
if (pNode == NULL) { if (pNode == NULL) {
return NULL; return NULL;
......
...@@ -8,10 +8,9 @@ IF (TD_MVN_INSTALLED) ...@@ -8,10 +8,9 @@ IF (TD_MVN_INSTALLED)
ADD_CUSTOM_COMMAND(OUTPUT ${JDBC_CMD_NAME} ADD_CUSTOM_COMMAND(OUTPUT ${JDBC_CMD_NAME}
POST_BUILD POST_BUILD
COMMAND mvn -Dmaven.test.skip=true install -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml COMMAND mvn -Dmaven.test.skip=true install -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.29.jar ${LIBRARY_OUTPUT_PATH} COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.30.jar ${LIBRARY_OUTPUT_PATH}
COMMAND mvn -Dmaven.test.skip=true clean -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml COMMAND mvn -Dmaven.test.skip=true clean -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml
COMMENT "build jdbc driver") COMMENT "build jdbc driver")
ADD_CUSTOM_TARGET(${JDBC_TARGET_NAME} ALL WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} DEPENDS ${JDBC_CMD_NAME}) ADD_CUSTOM_TARGET(${JDBC_TARGET_NAME} ALL WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} DEPENDS ${JDBC_CMD_NAME})
ENDIF () ENDIF ()
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<groupId>com.taosdata.jdbc</groupId> <groupId>com.taosdata.jdbc</groupId>
<artifactId>taos-jdbcdriver</artifactId> <artifactId>taos-jdbcdriver</artifactId>
<version>2.0.29</version> <version>2.0.30</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>JDBCDriver</name> <name>JDBCDriver</name>
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.taosdata.jdbc</groupId> <groupId>com.taosdata.jdbc</groupId>
<artifactId>taos-jdbcdriver</artifactId> <artifactId>taos-jdbcdriver</artifactId>
<version>2.0.29</version> <version>2.0.30</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>JDBCDriver</name> <name>JDBCDriver</name>
<url>https://github.com/taosdata/TDengine/tree/master/src/connector/jdbc</url> <url>https://github.com/taosdata/TDengine/tree/master/src/connector/jdbc</url>
......
...@@ -12,6 +12,9 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da ...@@ -12,6 +12,9 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da
private final static int DRIVER_MAJAR_VERSION = 2; private final static int DRIVER_MAJAR_VERSION = 2;
private final static int DRIVER_MINOR_VERSION = 0; private final static int DRIVER_MINOR_VERSION = 0;
private String precision = "ms";
private String database;
public boolean allProceduresAreCallable() throws SQLException { public boolean allProceduresAreCallable() throws SQLException {
return false; return false;
} }
...@@ -493,102 +496,105 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da ...@@ -493,102 +496,105 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da
public abstract ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException; public abstract ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException;
protected ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types, Connection connection) throws SQLException { private List<ColumnMetaData> buildGetTablesColumnMetaDataList() {
try (Statement stmt = connection.createStatement()) { List<ColumnMetaData> columnMetaDataList = new ArrayList<>();
if (catalog == null || catalog.isEmpty()) columnMetaDataList.add(buildTableCatalogMeta(1)); // 1. TABLE_CAT
return null; columnMetaDataList.add(buildTableSchemaMeta(2)); // 2. TABLE_SCHEM
columnMetaDataList.add(buildTableNameMeta(3)); // 3. TABLE_NAME
ResultSet databases = stmt.executeQuery("show databases"); columnMetaDataList.add(buildTableTypeMeta(4)); // 4. TABLE_TYPE
String dbname = null; columnMetaDataList.add(buildRemarksMeta(5)); // 5. remarks
while (databases.next()) { columnMetaDataList.add(buildTypeCatMeta(6)); // 6. TYPE_CAT
dbname = databases.getString("name"); columnMetaDataList.add(buildTypeSchemaMeta(7)); // 7. TYPE_SCHEM
if (dbname.equalsIgnoreCase(catalog)) columnMetaDataList.add(buildTypeNameMeta(8)); // 8. TYPE_NAME
break; columnMetaDataList.add(buildSelfReferencingColName(9)); // 9. SELF_REFERENCING_COL_NAME
} columnMetaDataList.add(buildRefGenerationMeta(10)); // 10. REF_GENERATION
databases.close(); return columnMetaDataList;
if (dbname == null) }
return null;
private ColumnMetaData buildTypeCatMeta(int colIndex) {
ColumnMetaData col6 = new ColumnMetaData();
col6.setColIndex(colIndex);
col6.setColName("TYPE_CAT");
col6.setColType(Types.NCHAR);
return col6;
}
private ColumnMetaData buildTypeSchemaMeta(int colIndex) {
ColumnMetaData col7 = new ColumnMetaData();
col7.setColIndex(colIndex);
col7.setColName("TYPE_SCHEM");
col7.setColType(Types.NCHAR);
return col7;
}
private ColumnMetaData buildTypeNameMeta(int colIndex) {
ColumnMetaData col8 = new ColumnMetaData();
col8.setColIndex(colIndex);
col8.setColName("TYPE_NAME");
col8.setColType(Types.NCHAR);
return col8;
}
private ColumnMetaData buildSelfReferencingColName(int colIndex) {
ColumnMetaData col9 = new ColumnMetaData();
col9.setColIndex(colIndex);
col9.setColName("SELF_REFERENCING_COL_NAME");
col9.setColType(Types.NCHAR);
return col9;
}
private ColumnMetaData buildRefGenerationMeta(int colIndex) {
ColumnMetaData col10 = new ColumnMetaData();
col10.setColIndex(colIndex);
col10.setColName("REF_GENERATION");
col10.setColType(Types.NCHAR);
return col10;
}
stmt.execute("use " + dbname); protected ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types, Connection connection) throws SQLException {
DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); if (catalog == null || catalog.isEmpty())
List<ColumnMetaData> columnMetaDataList = new ArrayList<>(); return null;
ColumnMetaData col1 = new ColumnMetaData(); if (!isAvailableCatalog(connection, catalog))
col1.setColIndex(1); return new EmptyResultSet();
col1.setColName("TABLE_CAT");
col1.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col1);
ColumnMetaData col2 = new ColumnMetaData();
col2.setColIndex(2);
col2.setColName("TABLE_SCHEM");
col2.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col2);
ColumnMetaData col3 = new ColumnMetaData();
col3.setColIndex(3);
col3.setColName("TABLE_NAME");
col3.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col3);
ColumnMetaData col4 = new ColumnMetaData();
col4.setColIndex(4);
col4.setColName("TABLE_TYPE");
col4.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col4);
ColumnMetaData col5 = new ColumnMetaData();
col5.setColIndex(5);
col5.setColName("REMARKS");
col5.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col5);
ColumnMetaData col6 = new ColumnMetaData();
col6.setColIndex(6);
col6.setColName("TYPE_CAT");
col6.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col6);
ColumnMetaData col7 = new ColumnMetaData();
col7.setColIndex(7);
col7.setColName("TYPE_SCHEM");
col7.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col7);
ColumnMetaData col8 = new ColumnMetaData();
col8.setColIndex(8);
col8.setColName("TYPE_NAME");
col8.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col8);
ColumnMetaData col9 = new ColumnMetaData();
col9.setColIndex(9);
col9.setColName("SELF_REFERENCING_COL_NAME");
col9.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col9);
ColumnMetaData col10 = new ColumnMetaData();
col10.setColIndex(10);
col10.setColName("REF_GENERATION");
col10.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col10);
resultSet.setColumnMetaDataList(columnMetaDataList);
List<TSDBResultSetRowData> rowDataList = new ArrayList<>(); DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet();
// set column metadata list
resultSet.setColumnMetaDataList(buildGetTablesColumnMetaDataList());
// set row data
List<TSDBResultSetRowData> rowDataList = new ArrayList<>();
try (Statement stmt = connection.createStatement()) {
stmt.execute("use " + catalog);
ResultSet tables = stmt.executeQuery("show tables"); ResultSet tables = stmt.executeQuery("show tables");
while (tables.next()) { while (tables.next()) {
TSDBResultSetRowData rowData = new TSDBResultSetRowData(10); TSDBResultSetRowData rowData = new TSDBResultSetRowData(10);
rowData.setString(0, dbname); //table_cat rowData.setStringValue(1, catalog); //TABLE_CAT
rowData.setString(1, null); //TABLE_SCHEM rowData.setStringValue(2, null); //TABLE_SCHEM
rowData.setString(2, tables.getString("table_name")); //TABLE_NAME rowData.setStringValue(3, tables.getString("table_name")); //TABLE_NAME
rowData.setString(3, "TABLE"); //TABLE_TYPE rowData.setStringValue(4, "TABLE"); //TABLE_TYPE
rowData.setString(4, ""); //REMARKS rowData.setStringValue(5, ""); //REMARKS
rowDataList.add(rowData); rowDataList.add(rowData);
} }
ResultSet stables = stmt.executeQuery("show stables"); ResultSet stables = stmt.executeQuery("show stables");
while (stables.next()) { while (stables.next()) {
TSDBResultSetRowData rowData = new TSDBResultSetRowData(10); TSDBResultSetRowData rowData = new TSDBResultSetRowData(10);
rowData.setString(0, dbname); //TABLE_CAT rowData.setStringValue(1, catalog); //TABLE_CAT
rowData.setString(1, null); //TABLE_SCHEM rowData.setStringValue(2, null); //TABLE_SCHEM
rowData.setString(2, stables.getString("name")); //TABLE_NAME rowData.setStringValue(3, stables.getString("name")); //TABLE_NAME
rowData.setString(3, "TABLE"); //TABLE_TYPE rowData.setStringValue(4, "TABLE"); //TABLE_TYPE
rowData.setString(4, "STABLE"); //REMARKS rowData.setStringValue(5, "STABLE"); //REMARKS
rowDataList.add(rowData); rowDataList.add(rowData);
} }
resultSet.setRowDataList(rowDataList); resultSet.setRowDataList(rowDataList);
return resultSet;
} }
return resultSet;
}
private ColumnMetaData buildTableTypeMeta(int colIndex) {
ColumnMetaData col4 = new ColumnMetaData();
col4.setColIndex(colIndex);
col4.setColName("TABLE_TYPE");
col4.setColType(Types.NCHAR);
return col4;
} }
public ResultSet getSchemas() throws SQLException { public ResultSet getSchemas() throws SQLException {
...@@ -597,25 +603,24 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da ...@@ -597,25 +603,24 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da
public abstract ResultSet getCatalogs() throws SQLException; public abstract ResultSet getCatalogs() throws SQLException;
private List<ColumnMetaData> buildTableTypesColumnMetadataList() {
List<ColumnMetaData> columnMetaDataList = new ArrayList<>();
columnMetaDataList.add(buildTableTypeMeta(1));
return columnMetaDataList;
}
public ResultSet getTableTypes() throws SQLException { public ResultSet getTableTypes() throws SQLException {
DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet();
// set up ColumnMetaDataList // set up ColumnMetaDataList
List<ColumnMetaData> columnMetaDataList = new ArrayList<>(); resultSet.setColumnMetaDataList(buildTableTypesColumnMetadataList());
ColumnMetaData colMetaData = new ColumnMetaData();
colMetaData.setColIndex(0);
colMetaData.setColName("TABLE_TYPE");
colMetaData.setColSize(10);
colMetaData.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(colMetaData);
resultSet.setColumnMetaDataList(columnMetaDataList);
// set up rowDataList // set up rowDataList
List<TSDBResultSetRowData> rowDataList = new ArrayList<>(); List<TSDBResultSetRowData> rowDataList = new ArrayList<>();
TSDBResultSetRowData rowData = new TSDBResultSetRowData(1); TSDBResultSetRowData rowData = new TSDBResultSetRowData(1);
rowData.setString(0, "TABLE"); rowData.setStringValue(1, "TABLE");
rowDataList.add(rowData); rowDataList.add(rowData);
rowData = new TSDBResultSetRowData(1); rowData = new TSDBResultSetRowData(1);
rowData.setString(0, "STABLE"); rowData.setStringValue(1, "STABLE");
rowDataList.add(rowData); rowDataList.add(rowData);
resultSet.setRowDataList(rowDataList); resultSet.setRowDataList(rowDataList);
...@@ -625,278 +630,330 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da ...@@ -625,278 +630,330 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da
public abstract ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException; public abstract ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException;
protected ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern, Connection conn) { protected ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern, Connection conn) {
try (Statement stmt = conn.createStatement()) { if (catalog == null || catalog.isEmpty())
if (catalog == null || catalog.isEmpty()) return null;
return null; if (!isAvailableCatalog(conn, catalog))
return new EmptyResultSet();
ResultSet databases = stmt.executeQuery("show databases");
String dbname = null;
while (databases.next()) {
dbname = databases.getString("name");
if (dbname.equalsIgnoreCase(catalog))
break;
}
databases.close();
if (dbname == null)
return null;
stmt.execute("use " + dbname); DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet();
DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); // set up ColumnMetaDataList
// set up ColumnMetaDataList resultSet.setColumnMetaDataList(buildGetColumnsColumnMetaDataList());
// set up rowDataList
List<ColumnMetaData> columnMetaDataList = new ArrayList<>(); List<TSDBResultSetRowData> rowDataList = new ArrayList<>();
// TABLE_CAT try (Statement stmt = conn.createStatement()) {
ColumnMetaData col1 = new ColumnMetaData(); ResultSet rs = stmt.executeQuery("describe " + catalog + "." + tableNamePattern);
col1.setColIndex(1); int rowIndex = 0;
col1.setColName("TABLE_CAT");
col1.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col1);
// TABLE_SCHEM
ColumnMetaData col2 = new ColumnMetaData();
col2.setColIndex(2);
col2.setColName("TABLE_SCHEM");
col2.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col2);
// TABLE_NAME
ColumnMetaData col3 = new ColumnMetaData();
col3.setColIndex(3);
col3.setColName("TABLE_NAME");
col3.setColSize(193);
col3.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col3);
// COLUMN_NAME
ColumnMetaData col4 = new ColumnMetaData();
col4.setColIndex(4);
col4.setColName("COLUMN_NAME");
col4.setColSize(65);
col4.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col4);
// DATA_TYPE
ColumnMetaData col5 = new ColumnMetaData();
col5.setColIndex(5);
col5.setColName("DATA_TYPE");
col5.setColType(TSDBConstants.TSDB_DATA_TYPE_INT);
columnMetaDataList.add(col5);
// TYPE_NAME
ColumnMetaData col6 = new ColumnMetaData();
col6.setColIndex(6);
col6.setColName("TYPE_NAME");
col6.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col6);
// COLUMN_SIZE
ColumnMetaData col7 = new ColumnMetaData();
col7.setColIndex(7);
col7.setColName("COLUMN_SIZE");
col7.setColType(TSDBConstants.TSDB_DATA_TYPE_INT);
columnMetaDataList.add(col7);
// BUFFER_LENGTH, not used
ColumnMetaData col8 = new ColumnMetaData();
col8.setColIndex(8);
col8.setColName("BUFFER_LENGTH");
columnMetaDataList.add(col8);
// DECIMAL_DIGITS
ColumnMetaData col9 = new ColumnMetaData();
col9.setColIndex(9);
col9.setColName("DECIMAL_DIGITS");
col9.setColType(TSDBConstants.TSDB_DATA_TYPE_INT);
columnMetaDataList.add(col9);
// add NUM_PREC_RADIX
ColumnMetaData col10 = new ColumnMetaData();
col10.setColIndex(10);
col10.setColName("NUM_PREC_RADIX");
col10.setColType(TSDBConstants.TSDB_DATA_TYPE_INT);
columnMetaDataList.add(col10);
// NULLABLE
ColumnMetaData col11 = new ColumnMetaData();
col11.setColIndex(11);
col11.setColName("NULLABLE");
col11.setColType(TSDBConstants.TSDB_DATA_TYPE_INT);
columnMetaDataList.add(col11);
// REMARKS
ColumnMetaData col12 = new ColumnMetaData();
col12.setColIndex(12);
col12.setColName("REMARKS");
col12.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col12);
// COLUMN_DEF
ColumnMetaData col13 = new ColumnMetaData();
col13.setColIndex(13);
col13.setColName("COLUMN_DEF");
col13.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col13);
//SQL_DATA_TYPE
ColumnMetaData col14 = new ColumnMetaData();
col14.setColIndex(14);
col14.setColName("SQL_DATA_TYPE");
col14.setColType(TSDBConstants.TSDB_DATA_TYPE_INT);
columnMetaDataList.add(col14);
//SQL_DATETIME_SUB
ColumnMetaData col15 = new ColumnMetaData();
col15.setColIndex(15);
col15.setColName("SQL_DATETIME_SUB");
col15.setColType(TSDBConstants.TSDB_DATA_TYPE_INT);
columnMetaDataList.add(col15);
//CHAR_OCTET_LENGTH
ColumnMetaData col16 = new ColumnMetaData();
col16.setColIndex(16);
col16.setColName("CHAR_OCTET_LENGTH");
col16.setColType(TSDBConstants.TSDB_DATA_TYPE_INT);
columnMetaDataList.add(col16);
//ORDINAL_POSITION
ColumnMetaData col17 = new ColumnMetaData();
col17.setColIndex(17);
col17.setColName("ORDINAL_POSITION");
col17.setColType(TSDBConstants.TSDB_DATA_TYPE_INT);
columnMetaDataList.add(col17);
// IS_NULLABLE
ColumnMetaData col18 = new ColumnMetaData();
col18.setColIndex(18);
col18.setColName("IS_NULLABLE");
col18.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col18);
//SCOPE_CATALOG
ColumnMetaData col19 = new ColumnMetaData();
col19.setColIndex(19);
col19.setColName("SCOPE_CATALOG");
col19.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col19);
//SCOPE_SCHEMA
ColumnMetaData col20 = new ColumnMetaData();
col20.setColIndex(20);
col20.setColName("SCOPE_SCHEMA");
col20.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col20);
//SCOPE_TABLE
ColumnMetaData col21 = new ColumnMetaData();
col21.setColIndex(21);
col21.setColName("SCOPE_TABLE");
col21.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col21);
//SOURCE_DATA_TYPE
ColumnMetaData col22 = new ColumnMetaData();
col22.setColIndex(22);
col22.setColName("SOURCE_DATA_TYPE");
col22.setColType(TSDBConstants.TSDB_DATA_TYPE_SMALLINT);
columnMetaDataList.add(col22);
//IS_AUTOINCREMENT
ColumnMetaData col23 = new ColumnMetaData();
col23.setColIndex(23);
col23.setColName("IS_AUTOINCREMENT");
col23.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col23);
//IS_GENERATEDCOLUMN
ColumnMetaData col24 = new ColumnMetaData();
col24.setColIndex(24);
col24.setColName("IS_GENERATEDCOLUMN");
col24.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col24);
resultSet.setColumnMetaDataList(columnMetaDataList);
// set up rowDataList
ResultSet rs = stmt.executeQuery("describe " + dbname + "." + tableNamePattern);
List<TSDBResultSetRowData> rowDataList = new ArrayList<>();
int index = 0;
while (rs.next()) { while (rs.next()) {
TSDBResultSetRowData rowData = new TSDBResultSetRowData(24); TSDBResultSetRowData rowData = new TSDBResultSetRowData(24);
// set TABLE_CAT // set TABLE_CAT
rowData.setString(0, dbname); rowData.setStringValue(1, catalog);
// set TABLE_SCHEM
rowData.setStringValue(2, null);
// set TABLE_NAME // set TABLE_NAME
rowData.setString(2, tableNamePattern); rowData.setStringValue(3, tableNamePattern);
// set COLUMN_NAME // set COLUMN_NAME
rowData.setString(3, rs.getString("Field")); rowData.setStringValue(4, rs.getString("Field"));
// set DATA_TYPE // set DATA_TYPE
String typeName = rs.getString("Type"); String typeName = rs.getString("Type");
rowData.setInt(4, getDataType(typeName)); rowData.setIntValue(5, TSDBConstants.typeName2JdbcType(typeName));
// set TYPE_NAME // set TYPE_NAME
rowData.setString(5, typeName); rowData.setStringValue(6, typeName);
// set COLUMN_SIZE // set COLUMN_SIZE
int length = rs.getInt("Length"); int length = rs.getInt("Length");
rowData.setInt(6, getColumnSize(typeName, length)); rowData.setIntValue(7, calculateColumnSize(typeName, precision, length));
// set BUFFER LENGTH
rowData.setStringValue(8, null);
// set DECIMAL_DIGITS // set DECIMAL_DIGITS
rowData.setInt(8, getDecimalDigits(typeName)); Integer decimalDigits = calculateDecimalDigits(typeName);
if (decimalDigits != null) {
rowData.setIntValue(9, decimalDigits);
} else {
rowData.setStringValue(9, null);
}
// set NUM_PREC_RADIX // set NUM_PREC_RADIX
rowData.setInt(9, 10); rowData.setIntValue(10, 10);
// set NULLABLE // set NULLABLE
rowData.setInt(10, getNullable(index, typeName)); rowData.setIntValue(11, isNullable(rowIndex, typeName));
// set REMARKS // set REMARKS
rowData.setString(11, rs.getString("Note")); String note = rs.getString("Note");
rowData.setStringValue(12, note.trim().isEmpty() ? null : note);
rowDataList.add(rowData); rowDataList.add(rowData);
index++; rowIndex++;
} }
resultSet.setRowDataList(rowDataList); resultSet.setRowDataList(rowDataList);
return resultSet;
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
return null; return resultSet;
} }
protected int getNullable(int index, String typeName) { private int isNullable(int index, String typeName) {
if (index == 0 && "TIMESTAMP".equals(typeName)) if (index == 0 && "TIMESTAMP".equals(typeName))
return DatabaseMetaData.columnNoNulls; return DatabaseMetaData.columnNoNulls;
return DatabaseMetaData.columnNullable; return DatabaseMetaData.columnNullable;
} }
protected int getColumnSize(String typeName, int length) { private Integer calculateColumnSize(String typeName, String precisionType, int length) {
switch (typeName) { switch (typeName) {
case "TIMESTAMP": case "TIMESTAMP":
return 23; return precisionType.equals("ms") ? TSDBConstants.TIMESTAMP_MS_PRECISION : TSDBConstants.TIMESTAMP_US_PRECISION;
default: case "BOOL":
return 0; return TSDBConstants.BOOLEAN_PRECISION;
} case "TINYINT":
} return TSDBConstants.TINYINT_PRECISION;
case "SMALLINT":
protected int getDecimalDigits(String typeName) { return TSDBConstants.SMALLINT_PRECISION;
switch (typeName) { case "INT":
return TSDBConstants.INT_PRECISION;
case "BIGINT":
return TSDBConstants.BIGINT_PRECISION;
case "FLOAT": case "FLOAT":
return 5; return TSDBConstants.FLOAT_PRECISION;
case "DOUBLE": case "DOUBLE":
return 9; return TSDBConstants.DOUBLE_PRECISION;
case "NCHAR":
case "BINARY":
return length;
default: default:
return 0; return null;
} }
} }
protected int getDataType(String typeName) { private Integer calculateDecimalDigits(String typeName) {
switch (typeName) { switch (typeName) {
case "TIMESTAMP": case "TINYINT":
return Types.TIMESTAMP; case "SMALLINT":
case "INT": case "INT":
return Types.INTEGER;
case "BIGINT": case "BIGINT":
return Types.BIGINT; return 0;
case "FLOAT":
return Types.FLOAT;
case "DOUBLE":
return Types.DOUBLE;
case "BINARY":
return Types.BINARY;
case "SMALLINT":
return Types.SMALLINT;
case "TINYINT":
return Types.TINYINT;
case "BOOL":
return Types.BOOLEAN;
case "NCHAR":
return Types.NCHAR;
default: default:
return Types.NULL; return null;
} }
} }
public ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern) private ColumnMetaData buildTableCatalogMeta(int colIndex) {
throws SQLException { ColumnMetaData col1 = new ColumnMetaData();
col1.setColIndex(colIndex);
col1.setColName("TABLE_CAT");
col1.setColType(Types.NCHAR);
return col1;
}
private ColumnMetaData buildTableSchemaMeta(int colIndex) {
ColumnMetaData col2 = new ColumnMetaData();
col2.setColIndex(colIndex);
col2.setColName("TABLE_SCHEM");
col2.setColType(Types.NCHAR);
return col2;
}
private ColumnMetaData buildTableNameMeta(int colIndex) {
ColumnMetaData col3 = new ColumnMetaData();
col3.setColIndex(colIndex);
col3.setColName("TABLE_NAME");
col3.setColSize(193);
col3.setColType(Types.NCHAR);
return col3;
}
private ColumnMetaData buildColumnNameMeta(int colIndex) {
ColumnMetaData col4 = new ColumnMetaData();
col4.setColIndex(colIndex);
col4.setColName("COLUMN_NAME");
col4.setColSize(65);
col4.setColType(Types.NCHAR);
return col4;
}
private ColumnMetaData buildDataTypeMeta(int colIndex) {
ColumnMetaData col5 = new ColumnMetaData();
col5.setColIndex(colIndex);
col5.setColName("DATA_TYPE");
col5.setColType(Types.INTEGER);
return col5;
}
private ColumnMetaData buildColumnSizeMeta() {
ColumnMetaData col7 = new ColumnMetaData();
col7.setColIndex(7);
col7.setColName("COLUMN_SIZE");
col7.setColType(Types.INTEGER);
return col7;
}
private ColumnMetaData buildBufferLengthMeta() {
ColumnMetaData col8 = new ColumnMetaData();
col8.setColIndex(8);
col8.setColName("BUFFER_LENGTH");
return col8;
}
private ColumnMetaData buildDecimalDigitsMeta() {
ColumnMetaData col9 = new ColumnMetaData();
col9.setColIndex(9);
col9.setColName("DECIMAL_DIGITS");
col9.setColType(Types.INTEGER);
return col9;
}
private ColumnMetaData buildNumPrecRadixMeta() {
ColumnMetaData col10 = new ColumnMetaData();
col10.setColIndex(10);
col10.setColName("NUM_PREC_RADIX");
col10.setColType(Types.INTEGER);
return col10;
}
private ColumnMetaData buildNullableMeta() {
ColumnMetaData col11 = new ColumnMetaData();
col11.setColIndex(11);
col11.setColName("NULLABLE");
col11.setColType(Types.INTEGER);
return col11;
}
private ColumnMetaData buildRemarksMeta(int colIndex) {
ColumnMetaData col12 = new ColumnMetaData();
col12.setColIndex(colIndex);
col12.setColName("REMARKS");
col12.setColType(Types.NCHAR);
return col12;
}
private ColumnMetaData buildColumnDefMeta() {
ColumnMetaData col13 = new ColumnMetaData();
col13.setColIndex(13);
col13.setColName("COLUMN_DEF");
col13.setColType(Types.NCHAR);
return col13;
}
private ColumnMetaData buildSqlDataTypeMeta() {
ColumnMetaData col14 = new ColumnMetaData();
col14.setColIndex(14);
col14.setColName("SQL_DATA_TYPE");
col14.setColType(Types.INTEGER);
return col14;
}
private ColumnMetaData buildSqlDatetimeSubMeta() {
ColumnMetaData col15 = new ColumnMetaData();
col15.setColIndex(15);
col15.setColName("SQL_DATETIME_SUB");
col15.setColType(Types.INTEGER);
return col15;
}
private ColumnMetaData buildCharOctetLengthMeta() {
ColumnMetaData col16 = new ColumnMetaData();
col16.setColIndex(16);
col16.setColName("CHAR_OCTET_LENGTH");
col16.setColType(Types.INTEGER);
return col16;
}
private ColumnMetaData buildOrdinalPositionMeta() {
ColumnMetaData col17 = new ColumnMetaData();
col17.setColIndex(17);
col17.setColName("ORDINAL_POSITION");
col17.setColType(Types.INTEGER);
return col17;
}
private ColumnMetaData buildIsNullableMeta() {
ColumnMetaData col18 = new ColumnMetaData();
col18.setColIndex(18);
col18.setColName("IS_NULLABLE");
col18.setColType(Types.NCHAR);
return col18;
}
private ColumnMetaData buildScopeCatalogMeta() {
ColumnMetaData col19 = new ColumnMetaData();
col19.setColIndex(19);
col19.setColName("SCOPE_CATALOG");
col19.setColType(Types.NCHAR);
return col19;
}
private ColumnMetaData buildScopeSchemaMeta() {
ColumnMetaData col20 = new ColumnMetaData();
col20.setColIndex(20);
col20.setColName("SCOPE_SCHEMA");
col20.setColType(Types.NCHAR);
return col20;
}
private ColumnMetaData buildScopeTableMeta() {
ColumnMetaData col21 = new ColumnMetaData();
col21.setColIndex(21);
col21.setColName("SCOPE_TABLE");
col21.setColType(Types.NCHAR);
return col21;
}
private ColumnMetaData buildSourceDataTypeMeta() {
ColumnMetaData col22 = new ColumnMetaData();
col22.setColIndex(22);
col22.setColName("SOURCE_DATA_TYPE");
col22.setColType(TSDBConstants.TSDB_DATA_TYPE_SMALLINT);
return col22;
}
private ColumnMetaData buildIsAutoIncrementMeta() {
ColumnMetaData col23 = new ColumnMetaData();
col23.setColIndex(23);
col23.setColName("IS_AUTOINCREMENT");
col23.setColType(Types.NCHAR);
return col23;
}
private ColumnMetaData buildIsGeneratedColumnMeta() {
ColumnMetaData col24 = new ColumnMetaData();
col24.setColIndex(24);
col24.setColName("IS_GENERATEDCOLUMN");
col24.setColType(Types.NCHAR);
return col24;
}
private List<ColumnMetaData> buildGetColumnsColumnMetaDataList() {
List<ColumnMetaData> columnMetaDataList = new ArrayList<>();
columnMetaDataList.add(buildTableCatalogMeta(1)); //1. TABLE_CAT
columnMetaDataList.add(buildTableSchemaMeta(2)); //2. TABLE_SCHEMA
columnMetaDataList.add(buildTableNameMeta(3)); //3. TABLE_NAME
columnMetaDataList.add(buildColumnNameMeta(4)); //4. COLUMN_NAME
columnMetaDataList.add(buildDataTypeMeta(5)); //5. DATA_TYPE
columnMetaDataList.add(buildTypeNameMeta(6)); //6. TYPE_NAME
columnMetaDataList.add(buildColumnSizeMeta()); //7. COLUMN_SIZE
columnMetaDataList.add(buildBufferLengthMeta()); //8. BUFFER_LENGTH, not used
columnMetaDataList.add(buildDecimalDigitsMeta()); //9. DECIMAL_DIGITS
columnMetaDataList.add(buildNumPrecRadixMeta()); //10. NUM_PREC_RADIX
columnMetaDataList.add(buildNullableMeta()); //11. NULLABLE
columnMetaDataList.add(buildRemarksMeta(12)); //12. REMARKS
columnMetaDataList.add(buildColumnDefMeta()); //13. COLUMN_DEF
columnMetaDataList.add(buildSqlDataTypeMeta()); //14. SQL_DATA_TYPE
columnMetaDataList.add(buildSqlDatetimeSubMeta()); //15. SQL_DATETIME_SUB
columnMetaDataList.add(buildCharOctetLengthMeta()); //16. CHAR_OCTET_LENGTH
columnMetaDataList.add(buildOrdinalPositionMeta()); //17. ORDINAL_POSITION
columnMetaDataList.add(buildIsNullableMeta()); //18. IS_NULLABLE
columnMetaDataList.add(buildScopeCatalogMeta()); //19. SCOPE_CATALOG
columnMetaDataList.add(buildScopeSchemaMeta()); //20. SCOPE_SCHEMA
columnMetaDataList.add(buildScopeTableMeta()); //21. SCOPE_TABLE
columnMetaDataList.add(buildSourceDataTypeMeta()); //22. SOURCE_DATA_TYPE
columnMetaDataList.add(buildIsAutoIncrementMeta()); //23. IS_AUTOINCREMENT
columnMetaDataList.add(buildIsGeneratedColumnMeta()); //24. IS_GENERATEDCOLUMN
return columnMetaDataList;
}
public ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern) throws SQLException {
return getEmptyResultSet(); return getEmptyResultSet();
} }
public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern) public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern) throws SQLException {
throws SQLException {
return getEmptyResultSet(); return getEmptyResultSet();
} }
public ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable) public ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable) throws SQLException {
throws SQLException {
return getEmptyResultSet(); return getEmptyResultSet();
} }
...@@ -914,8 +971,7 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da ...@@ -914,8 +971,7 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da
return getEmptyResultSet(); return getEmptyResultSet();
} }
public ResultSet getCrossReference(String parentCatalog, String parentSchema, String parentTable, public ResultSet getCrossReference(String parentCatalog, String parentSchema, String parentTable, String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException {
String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException {
return getEmptyResultSet(); return getEmptyResultSet();
} }
...@@ -923,8 +979,7 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da ...@@ -923,8 +979,7 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da
return getEmptyResultSet(); return getEmptyResultSet();
} }
public ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate) public ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate) throws SQLException {
throws SQLException {
return getEmptyResultSet(); return getEmptyResultSet();
} }
...@@ -976,8 +1031,7 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da ...@@ -976,8 +1031,7 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da
return false; return false;
} }
public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types) public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types) throws SQLException {
throws SQLException {
return getEmptyResultSet(); return getEmptyResultSet();
} }
...@@ -1005,8 +1059,7 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da ...@@ -1005,8 +1059,7 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da
public abstract ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException; public abstract ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException;
public ResultSet getAttributes(String catalog, String schemaPattern, String typeNamePattern, public ResultSet getAttributes(String catalog, String schemaPattern, String typeNamePattern, String attributeNamePattern) throws SQLException {
String attributeNamePattern) throws SQLException {
return getEmptyResultSet(); return getEmptyResultSet();
} }
...@@ -1069,18 +1122,15 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da ...@@ -1069,18 +1122,15 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da
return getEmptyResultSet(); return getEmptyResultSet();
} }
public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern) public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern) throws SQLException {
throws SQLException {
return getEmptyResultSet(); return getEmptyResultSet();
} }
public ResultSet getFunctionColumns(String catalog, String schemaPattern, String functionNamePattern, public ResultSet getFunctionColumns(String catalog, String schemaPattern, String functionNamePattern, String columnNamePattern) throws SQLException {
String columnNamePattern) throws SQLException {
return getEmptyResultSet(); return getEmptyResultSet();
} }
public ResultSet getPseudoColumns(String catalog, String schemaPattern, String tableNamePattern, public ResultSet getPseudoColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException {
String columnNamePattern) throws SQLException {
return getEmptyResultSet(); return getEmptyResultSet();
} }
...@@ -1093,164 +1143,142 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da ...@@ -1093,164 +1143,142 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da
} }
protected ResultSet getCatalogs(Connection conn) throws SQLException { protected ResultSet getCatalogs(Connection conn) throws SQLException {
try (Statement stmt = conn.createStatement()) { DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet();
DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); // set up ColumnMetaDataList
// set up ColumnMetaDataList List<ColumnMetaData> columnMetaDataList = new ArrayList<>();
List<ColumnMetaData> columnMetaDataList = new ArrayList<>(); columnMetaDataList.add(buildTableCatalogMeta(1)); // 1. TABLE_CAT
// TABLE_CAT resultSet.setColumnMetaDataList(columnMetaDataList);
ColumnMetaData col1 = new ColumnMetaData();
col1.setColIndex(1);
col1.setColName("TABLE_CAT");
col1.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col1);
resultSet.setColumnMetaDataList(columnMetaDataList);
try (Statement stmt = conn.createStatement()) {
List<TSDBResultSetRowData> rowDataList = new ArrayList<>(); List<TSDBResultSetRowData> rowDataList = new ArrayList<>();
ResultSet rs = stmt.executeQuery("show databases"); ResultSet rs = stmt.executeQuery("show databases");
while (rs.next()) { while (rs.next()) {
TSDBResultSetRowData rowData = new TSDBResultSetRowData(1); TSDBResultSetRowData rowData = new TSDBResultSetRowData(1);
rowData.setString(0, rs.getString("name")); rowData.setStringValue(1, rs.getString("name"));
rowDataList.add(rowData); rowDataList.add(rowData);
} }
resultSet.setRowDataList(rowDataList); resultSet.setRowDataList(rowDataList);
return resultSet;
} }
return resultSet;
} }
protected ResultSet getPrimaryKeys(String catalog, String schema, String table, Connection conn) throws SQLException { protected ResultSet getPrimaryKeys(String catalog, String schema, String table, Connection conn) throws SQLException {
try (Statement stmt = conn.createStatement()) { if (catalog == null || catalog.isEmpty())
if (catalog == null || catalog.isEmpty()) return null;
return null; if (!isAvailableCatalog(conn, catalog))
return new EmptyResultSet();
ResultSet databases = stmt.executeQuery("show databases"); DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet();
String dbname = null; try (Statement stmt = conn.createStatement()) {
while (databases.next()) {
dbname = databases.getString("name");
if (dbname.equalsIgnoreCase(catalog))
break;
}
databases.close();
if (dbname == null)
return null;
stmt.execute("use " + dbname);
DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet();
// set up ColumnMetaDataList // set up ColumnMetaDataList
List<ColumnMetaData> columnMetaDataList = new ArrayList<>(); resultSet.setColumnMetaDataList(buildGetPrimaryKeysMetadataList());
// TABLE_CAT
ColumnMetaData col1 = new ColumnMetaData();
col1.setColIndex(0);
col1.setColName("TABLE_CAT");
col1.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col1);
// TABLE_SCHEM
ColumnMetaData col2 = new ColumnMetaData();
col2.setColIndex(1);
col2.setColName("TABLE_SCHEM");
col2.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col2);
// TABLE_NAME
ColumnMetaData col3 = new ColumnMetaData();
col3.setColIndex(2);
col3.setColName("TABLE_NAME");
col3.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col3);
// COLUMN_NAME
ColumnMetaData col4 = new ColumnMetaData();
col4.setColIndex(3);
col4.setColName("COLUMN_NAME");
col4.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col4);
// KEY_SEQ
ColumnMetaData col5 = new ColumnMetaData();
col5.setColIndex(4);
col5.setColName("KEY_SEQ");
col5.setColType(TSDBConstants.TSDB_DATA_TYPE_INT);
columnMetaDataList.add(col5);
// PK_NAME
ColumnMetaData col6 = new ColumnMetaData();
col6.setColIndex(5);
col6.setColName("PK_NAME");
col6.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col6);
resultSet.setColumnMetaDataList(columnMetaDataList);
// set rowData // set rowData
List<TSDBResultSetRowData> rowDataList = new ArrayList<>(); List<TSDBResultSetRowData> rowDataList = new ArrayList<>();
ResultSet rs = stmt.executeQuery("describe " + dbname + "." + table); ResultSet rs = stmt.executeQuery("describe " + catalog + "." + table);
rs.next(); rs.next();
TSDBResultSetRowData rowData = new TSDBResultSetRowData(6); TSDBResultSetRowData rowData = new TSDBResultSetRowData(6);
rowData.setString(0, null); rowData.setStringValue(1, catalog);
rowData.setString(1, null); rowData.setStringValue(2, null);
rowData.setString(2, table); rowData.setStringValue(3, table);
String pkName = rs.getString(1); String primaryKey = rs.getString("Field");
rowData.setString(3, pkName); rowData.setStringValue(4, primaryKey);
rowData.setInt(4, 1); rowData.setShortValue(5, (short) 1);
rowData.setString(5, pkName); rowData.setStringValue(6, primaryKey);
rowDataList.add(rowData); rowDataList.add(rowData);
resultSet.setRowDataList(rowDataList); resultSet.setRowDataList(rowDataList);
return resultSet;
} }
return resultSet;
} }
protected ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern, Connection conn) throws SQLException { private List<ColumnMetaData> buildGetPrimaryKeysMetadataList() {
try (Statement stmt = conn.createStatement()) { List<ColumnMetaData> columnMetaDataList = new ArrayList<>();
if (catalog == null || catalog.isEmpty()) columnMetaDataList.add(buildTableCatalogMeta(1)); // 1. TABLE_CAT
return null; columnMetaDataList.add(buildTableSchemaMeta(2)); // 2. TABLE_SCHEM
columnMetaDataList.add(buildTableNameMeta(3)); // 3. TABLE_NAME
columnMetaDataList.add(buildColumnNameMeta(4)); // 4. COLUMN_NAME
columnMetaDataList.add(buildKeySeqMeta(5)); // 5. KEY_SEQ
columnMetaDataList.add(buildPrimaryKeyNameMeta(6)); // 6. PK_NAME
return columnMetaDataList;
}
private ColumnMetaData buildKeySeqMeta(int colIndex) {
ColumnMetaData col5 = new ColumnMetaData();
col5.setColIndex(colIndex);
col5.setColName("KEY_SEQ");
col5.setColType(Types.SMALLINT);
return col5;
}
private ColumnMetaData buildPrimaryKeyNameMeta(int colIndex) {
ColumnMetaData col6 = new ColumnMetaData();
col6.setColIndex(colIndex);
col6.setColName("PK_NAME");
col6.setColType(Types.NCHAR);
return col6;
}
private boolean isAvailableCatalog(Connection connection, String catalog) {
try (Statement stmt = connection.createStatement()) {
ResultSet databases = stmt.executeQuery("show databases"); ResultSet databases = stmt.executeQuery("show databases");
String dbname = null;
while (databases.next()) { while (databases.next()) {
dbname = databases.getString("name"); String dbname = databases.getString("name");
this.database = dbname;
this.precision = databases.getString("precision");
if (dbname.equalsIgnoreCase(catalog)) if (dbname.equalsIgnoreCase(catalog))
break; return true;
} }
databases.close(); databases.close();
if (dbname == null) } catch (SQLException e) {
return null; e.printStackTrace();
}
return false;
}
stmt.execute("use " + dbname); protected ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern, Connection conn) throws SQLException {
DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); if (catalog == null || catalog.isEmpty())
// set up ColumnMetaDataList return null;
List<ColumnMetaData> columnMetaDataList = new ArrayList<>();
// TABLE_CAT if (!isAvailableCatalog(conn, catalog)) {
ColumnMetaData col1 = new ColumnMetaData(); return new EmptyResultSet();
col1.setColIndex(0); }
col1.setColName("TABLE_CAT");
col1.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col1);
// TABLE_SCHEM
ColumnMetaData col2 = new ColumnMetaData();
col2.setColIndex(1);
col2.setColName("TABLE_SCHEM");
col2.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col2);
// TABLE_NAME
ColumnMetaData col3 = new ColumnMetaData();
col3.setColIndex(2);
col3.setColName("TABLE_NAME");
col3.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col3);
// SUPERTABLE_NAME
ColumnMetaData col4 = new ColumnMetaData();
col4.setColIndex(3);
col4.setColName("SUPERTABLE_NAME");
col4.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(col4);
resultSet.setColumnMetaDataList(columnMetaDataList);
DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet();
try (Statement stmt = conn.createStatement()) {
// set up ColumnMetaDataList
resultSet.setColumnMetaDataList(buildGetSuperTablesColumnMetaDataList());
// set result set row data
stmt.execute("use " + catalog);
ResultSet rs = stmt.executeQuery("show tables like '" + tableNamePattern + "'"); ResultSet rs = stmt.executeQuery("show tables like '" + tableNamePattern + "'");
List<TSDBResultSetRowData> rowDataList = new ArrayList<>(); List<TSDBResultSetRowData> rowDataList = new ArrayList<>();
while (rs.next()) { while (rs.next()) {
TSDBResultSetRowData rowData = new TSDBResultSetRowData(4); TSDBResultSetRowData rowData = new TSDBResultSetRowData(4);
rowData.setString(2, rs.getString(1)); rowData.setStringValue(1, catalog);
rowData.setString(3, rs.getString(4)); rowData.setStringValue(2, null);
rowData.setStringValue(3, rs.getString("table_name"));
rowData.setStringValue(4, rs.getString("stable_name"));
rowDataList.add(rowData); rowDataList.add(rowData);
} }
resultSet.setRowDataList(rowDataList); resultSet.setRowDataList(rowDataList);
return resultSet;
} }
return resultSet;
}
private List<ColumnMetaData> buildGetSuperTablesColumnMetaDataList() {
List<ColumnMetaData> columnMetaDataList = new ArrayList<>();
columnMetaDataList.add(buildTableCatalogMeta(1)); // 1. TABLE_CAT
columnMetaDataList.add(buildTableSchemaMeta(2)); // 2. TABLE_SCHEM
columnMetaDataList.add(buildTableNameMeta(3)); // 3. TABLE_NAME
columnMetaDataList.add(buildSuperTableNameMeta(4)); // 4. SUPERTABLE_NAME
return columnMetaDataList;
} }
private ColumnMetaData buildSuperTableNameMeta(int colIndex) {
ColumnMetaData col4 = new ColumnMetaData();
col4.setColIndex(colIndex);
col4.setColName("SUPERTABLE_NAME");
col4.setColType(Types.NCHAR);
return col4;
}
} }
\ No newline at end of file
package com.taosdata.jdbc; package com.taosdata.jdbc;
import com.sun.org.apache.xpath.internal.operations.Bool;
import java.sql.ParameterMetaData; import java.sql.ParameterMetaData;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Timestamp; import java.sql.Timestamp;
...@@ -49,6 +51,22 @@ public abstract class AbstractParameterMetaData extends WrapperImpl implements P ...@@ -49,6 +51,22 @@ public abstract class AbstractParameterMetaData extends WrapperImpl implements P
if (param < 1 && param >= parameters.length) if (param < 1 && param >= parameters.length)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
if (parameters[param - 1] instanceof Boolean)
return TSDBConstants.BOOLEAN_PRECISION;
if (parameters[param - 1] instanceof Byte)
return TSDBConstants.TINYINT_PRECISION;
if (parameters[param - 1] instanceof Short)
return TSDBConstants.SMALLINT_PRECISION;
if (parameters[param - 1] instanceof Integer)
return TSDBConstants.INT_PRECISION;
if (parameters[param - 1] instanceof Long)
return TSDBConstants.BIGINT_PRECISION;
if (parameters[param - 1] instanceof Timestamp)
return TSDBConstants.TIMESTAMP_MS_PRECISION;
if (parameters[param - 1] instanceof Float)
return TSDBConstants.FLOAT_PRECISION;
if (parameters[param - 1] instanceof Double)
return TSDBConstants.DOUBLE_PRECISION;
if (parameters[param - 1] instanceof String) if (parameters[param - 1] instanceof String)
return ((String) parameters[param - 1]).length(); return ((String) parameters[param - 1]).length();
if (parameters[param - 1] instanceof byte[]) if (parameters[param - 1] instanceof byte[])
...@@ -60,6 +78,11 @@ public abstract class AbstractParameterMetaData extends WrapperImpl implements P ...@@ -60,6 +78,11 @@ public abstract class AbstractParameterMetaData extends WrapperImpl implements P
public int getScale(int param) throws SQLException { public int getScale(int param) throws SQLException {
if (param < 1 && param >= parameters.length) if (param < 1 && param >= parameters.length)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
if (parameters[param - 1] instanceof Float)
return TSDBConstants.FLOAT_SCALE;
if (parameters[param - 1] instanceof Double)
return TSDBConstants.DOUBLE_SCALE;
return 0; return 0;
} }
......
...@@ -66,10 +66,16 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet ...@@ -66,10 +66,16 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
public abstract byte[] getBytes(int columnIndex) throws SQLException; public abstract byte[] getBytes(int columnIndex) throws SQLException;
@Override @Override
public abstract Date getDate(int columnIndex) throws SQLException; public Date getDate(int columnIndex) throws SQLException {
Timestamp timestamp = getTimestamp(columnIndex);
return timestamp == null ? null : new Date(timestamp.getTime());
}
@Override @Override
public abstract Time getTime(int columnIndex) throws SQLException; public Time getTime(int columnIndex) throws SQLException {
Timestamp timestamp = getTimestamp(columnIndex);
return timestamp == null ? null : new Time(timestamp.getTime());
}
@Override @Override
public abstract Timestamp getTimestamp(int columnIndex) throws SQLException; public abstract Timestamp getTimestamp(int columnIndex) throws SQLException;
......
...@@ -14,76 +14,42 @@ ...@@ -14,76 +14,42 @@
*****************************************************************************/ *****************************************************************************/
package com.taosdata.jdbc; package com.taosdata.jdbc;
import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.net.URL;
import java.sql.Date;
import java.sql.*; import java.sql.*;
import java.util.*; import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;
/* /*
* TDengine only supports a subset of the standard SQL, thus this implemetation of the * TDengine only supports a subset of the standard SQL, thus this implementation of the
* standard JDBC API contains more or less some adjustments customized for certain * standard JDBC API contains more or less some adjustments customized for certain
* compatibility needs. * compatibility needs.
*/ */
public class DatabaseMetaDataResultSet implements ResultSet { public class DatabaseMetaDataResultSet extends AbstractResultSet {
private List<ColumnMetaData> columnMetaDataList; private List<ColumnMetaData> columnMetaDataList = new ArrayList<>();
private List<TSDBResultSetRowData> rowDataList; private List<TSDBResultSetRowData> rowDataList = new ArrayList<>();
private TSDBResultSetRowData rowCursor; private TSDBResultSetRowData rowCursor;
// position of cursor, starts from 0 as beforeFirst, increases as next() is called // position of cursor, starts from 0 as beforeFirst, increases as next() is called
private int cursorRowNumber = 0; private int cursorRowNumber = 0;
public DatabaseMetaDataResultSet() {
rowDataList = new ArrayList<TSDBResultSetRowData>();
columnMetaDataList = new ArrayList<ColumnMetaData>();
}
public List<TSDBResultSetRowData> getRowDataList() {
return rowDataList;
}
public void setRowDataList(List<TSDBResultSetRowData> rowDataList) { public void setRowDataList(List<TSDBResultSetRowData> rowDataList) {
this.rowDataList = rowDataList; this.rowDataList = rowDataList;
} }
public List<ColumnMetaData> getColumnMetaDataList() {
return columnMetaDataList;
}
public void setColumnMetaDataList(List<ColumnMetaData> columnMetaDataList) { public void setColumnMetaDataList(List<ColumnMetaData> columnMetaDataList) {
this.columnMetaDataList = columnMetaDataList; this.columnMetaDataList = columnMetaDataList;
} }
public TSDBResultSetRowData getRowCursor() {
return rowCursor;
}
public void setRowCursor(TSDBResultSetRowData rowCursor) {
this.rowCursor = rowCursor;
}
@Override @Override
public boolean next() throws SQLException { public boolean next() throws SQLException {
// boolean ret = false;
// if (rowDataList.size() > 0) {
// ret = rowDataList.iterator().hasNext();
// if (ret) {
// rowCursor = rowDataList.iterator().next();
// cursorRowNumber++;
// }
// }
// return ret;
/**** add by zyyang 2020-09-29 ****************/
boolean ret = false; boolean ret = false;
if (!rowDataList.isEmpty() && cursorRowNumber < rowDataList.size()) { if (!rowDataList.isEmpty() && cursorRowNumber < rowDataList.size()) {
rowCursor = rowDataList.get(cursorRowNumber++); rowCursor = rowDataList.get(cursorRowNumber++);
ret = true; ret = true;
} }
return ret; return ret;
} }
...@@ -99,189 +65,72 @@ public class DatabaseMetaDataResultSet implements ResultSet { ...@@ -99,189 +65,72 @@ public class DatabaseMetaDataResultSet implements ResultSet {
@Override @Override
public String getString(int columnIndex) throws SQLException { public String getString(int columnIndex) throws SQLException {
columnIndex--; int colType = columnMetaDataList.get(columnIndex - 1).getColType();
int colType = columnMetaDataList.get(columnIndex).getColType(); int nativeType = TSDBConstants.jdbcType2TaosType(colType);
return rowCursor.getString(columnIndex, colType); return rowCursor.getString(columnIndex, nativeType);
} }
@Override @Override
public boolean getBoolean(int columnIndex) throws SQLException { public boolean getBoolean(int columnIndex) throws SQLException {
columnIndex--; int colType = columnMetaDataList.get(columnIndex - 1).getColType();
return rowCursor.getBoolean(columnIndex, columnMetaDataList.get(columnIndex).getColType()); int nativeType = TSDBConstants.jdbcType2TaosType(colType);
return rowCursor.getBoolean(columnIndex, nativeType);
} }
@Override @Override
public byte getByte(int columnIndex) throws SQLException { public byte getByte(int columnIndex) throws SQLException {
columnIndex--; int colType = columnMetaDataList.get(columnIndex - 1).getColType();
return (byte) rowCursor.getInt(columnIndex, columnMetaDataList.get(columnIndex).getColType()); int nativeType = TSDBConstants.jdbcType2TaosType(colType);
return (byte) rowCursor.getInt(columnIndex, nativeType);
} }
@Override @Override
public short getShort(int columnIndex) throws SQLException { public short getShort(int columnIndex) throws SQLException {
columnIndex--; int colType = columnMetaDataList.get(columnIndex - 1).getColType();
return (short) rowCursor.getInt(columnIndex, columnMetaDataList.get(columnIndex).getColType()); int nativeType = TSDBConstants.jdbcType2TaosType(colType);
return (short) rowCursor.getInt(columnIndex, nativeType);
} }
@Override @Override
public int getInt(int columnIndex) throws SQLException { public int getInt(int columnIndex) throws SQLException {
columnIndex--; int colType = columnMetaDataList.get(columnIndex - 1).getColType();
return rowCursor.getInt(columnIndex, columnMetaDataList.get(columnIndex).getColType()); int nativeType = TSDBConstants.jdbcType2TaosType(colType);
return rowCursor.getInt(columnIndex, nativeType);
} }
@Override @Override
public long getLong(int columnIndex) throws SQLException { public long getLong(int columnIndex) throws SQLException {
columnIndex--; int colType = columnMetaDataList.get(columnIndex - 1).getColType();
return rowCursor.getLong(columnIndex, columnMetaDataList.get(columnIndex).getColType()); int nativeType = TSDBConstants.jdbcType2TaosType(colType);
return rowCursor.getLong(columnIndex, nativeType);
} }
@Override @Override
public float getFloat(int columnIndex) throws SQLException { public float getFloat(int columnIndex) throws SQLException {
columnIndex--; int colType = columnMetaDataList.get(columnIndex - 1).getColType();
return rowCursor.getFloat(columnIndex, columnMetaDataList.get(columnIndex).getColType()); int nativeType = TSDBConstants.jdbcType2TaosType(colType);
return rowCursor.getFloat(columnIndex, nativeType);
} }
@Override @Override
public double getDouble(int columnIndex) throws SQLException { public double getDouble(int columnIndex) throws SQLException {
columnIndex--; int colType = columnMetaDataList.get(columnIndex - 1).getColType();
return rowCursor.getDouble(columnIndex, columnMetaDataList.get(columnIndex).getColType()); int nativeType = TSDBConstants.jdbcType2TaosType(colType);
} return rowCursor.getDouble(columnIndex, nativeType);
@Override
public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
columnIndex--;
return new BigDecimal(rowCursor.getDouble(columnIndex, columnMetaDataList.get(columnIndex).getColType()));
} }
@Override @Override
public byte[] getBytes(int columnIndex) throws SQLException { public byte[] getBytes(int columnIndex) throws SQLException {
columnIndex--; int colType = columnMetaDataList.get(columnIndex - 1).getColType();
return (rowCursor.getString(columnIndex, columnMetaDataList.get(columnIndex).getColType())).getBytes(); int nativeType = TSDBConstants.jdbcType2TaosType(colType);
} return (rowCursor.getString(columnIndex, nativeType)).getBytes();
@Override
public Date getDate(int columnIndex) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public Time getTime(int columnIndex) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
} }
@Override @Override
public Timestamp getTimestamp(int columnIndex) throws SQLException { public Timestamp getTimestamp(int columnIndex) throws SQLException {
columnIndex--; int colType = columnMetaDataList.get(columnIndex - 1).getColType();
return rowCursor.getTimestamp(columnIndex); int nativeType = TSDBConstants.jdbcType2TaosType(colType);
} return rowCursor.getTimestamp(columnIndex,nativeType);
@Override
public InputStream getAsciiStream(int columnIndex) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public InputStream getUnicodeStream(int columnIndex) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public InputStream getBinaryStream(int columnIndex) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public String getString(String columnLabel) throws SQLException {
return getString(findColumn(columnLabel));
}
@Override
public boolean getBoolean(String columnLabel) throws SQLException {
return getBoolean(findColumn(columnLabel));
}
@Override
public byte getByte(String columnLabel) throws SQLException {
return getByte(findColumn(columnLabel));
}
@Override
public short getShort(String columnLabel) throws SQLException {
return getShort(findColumn(columnLabel));
}
@Override
public int getInt(String columnLabel) throws SQLException {
return getInt(findColumn(columnLabel));
}
@Override
public long getLong(String columnLabel) throws SQLException {
return getLong(findColumn(columnLabel));
}
@Override
public float getFloat(String columnLabel) throws SQLException {
return getFloat(findColumn(columnLabel));
}
@Override
public double getDouble(String columnLabel) throws SQLException {
return getDouble(findColumn(columnLabel));
}
@Override
public BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException {
return getBigDecimal(findColumn(columnLabel));
}
@Override
public byte[] getBytes(String columnLabel) throws SQLException {
return getBytes(findColumn(columnLabel));
}
@Override
public Date getDate(String columnLabel) throws SQLException {
return getDate(findColumn(columnLabel));
}
@Override
public Time getTime(String columnLabel) throws SQLException {
return getTime(findColumn(columnLabel));
}
@Override
public Timestamp getTimestamp(String columnLabel) throws SQLException {
return getTimestamp(findColumn(columnLabel));
}
@Override
public InputStream getAsciiStream(String columnLabel) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public InputStream getUnicodeStream(String columnLabel) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public InputStream getBinaryStream(String columnLabel) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public SQLWarning getWarnings() throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void clearWarnings() throws SQLException {
}
@Override
public String getCursorName() throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
} }
@Override @Override
...@@ -291,12 +140,7 @@ public class DatabaseMetaDataResultSet implements ResultSet { ...@@ -291,12 +140,7 @@ public class DatabaseMetaDataResultSet implements ResultSet {
@Override @Override
public Object getObject(int columnIndex) throws SQLException { public Object getObject(int columnIndex) throws SQLException {
return rowCursor.get(columnIndex); return rowCursor.getObject(columnIndex);
}
@Override
public Object getObject(String columnLabel) throws SQLException {
return rowCursor.get(findColumn(columnLabel));
} }
@Override @Override
...@@ -304,31 +148,19 @@ public class DatabaseMetaDataResultSet implements ResultSet { ...@@ -304,31 +148,19 @@ public class DatabaseMetaDataResultSet implements ResultSet {
Iterator<ColumnMetaData> colMetaDataIt = this.columnMetaDataList.iterator(); Iterator<ColumnMetaData> colMetaDataIt = this.columnMetaDataList.iterator();
while (colMetaDataIt.hasNext()) { while (colMetaDataIt.hasNext()) {
ColumnMetaData colMetaData = colMetaDataIt.next(); ColumnMetaData colMetaData = colMetaDataIt.next();
if (colMetaData.getColName() != null && colMetaData.getColName().equalsIgnoreCase(columnLabel)) { if (colMetaData.getColName() != null && colMetaData.getColName().equals(columnLabel)) {
return colMetaData.getColIndex() + 1; return colMetaData.getColIndex();
} }
} }
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
} }
@Override
public Reader getCharacterStream(int columnIndex) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public Reader getCharacterStream(String columnLabel) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override @Override
public BigDecimal getBigDecimal(int columnIndex) throws SQLException { public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
return new BigDecimal(rowCursor.getDouble(columnIndex, columnMetaDataList.get(columnIndex).getColType())); int colType = columnMetaDataList.get(columnIndex - 1).getColType();
} int nativeType = TSDBConstants.jdbcType2TaosType(colType);
double value = rowCursor.getDouble(columnIndex, nativeType);
@Override return new BigDecimal(value);
public BigDecimal getBigDecimal(String columnLabel) throws SQLException {
return getBigDecimal(findColumn(columnLabel));
} }
@Override @Override
...@@ -378,7 +210,6 @@ public class DatabaseMetaDataResultSet implements ResultSet { ...@@ -378,7 +210,6 @@ public class DatabaseMetaDataResultSet implements ResultSet {
} else { } else {
return 0; return 0;
} }
} }
@Override @Override
...@@ -397,680 +228,23 @@ public class DatabaseMetaDataResultSet implements ResultSet { ...@@ -397,680 +228,23 @@ public class DatabaseMetaDataResultSet implements ResultSet {
} }
@Override @Override
public void setFetchDirection(int direction) throws SQLException { public Statement getStatement() throws SQLException {
return null;
}
@Override
public int getFetchDirection() throws SQLException {
return ResultSet.FETCH_FORWARD;
}
@Override
public void setFetchSize(int rows) throws SQLException {
}
@Override
public int getFetchSize() throws SQLException {
return 0;
}
@Override
public int getType() throws SQLException {
return ResultSet.TYPE_FORWARD_ONLY;
}
@Override
public int getConcurrency() throws SQLException {
return ResultSet.CONCUR_READ_ONLY;
}
@Override
public boolean rowUpdated() throws SQLException {
return false;
} }
@Override public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
public boolean rowInserted() throws SQLException { //TODO: calendar is not used
return false; return getTimestamp(columnIndex);
} }
@Override @Override
public boolean rowDeleted() throws SQLException { public boolean isClosed() throws SQLException {
return false; return false;
} }
@Override @Override
public void updateNull(int columnIndex) throws SQLException { public String getNString(int columnIndex) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); return getString(columnIndex);
}
@Override
public void updateBoolean(int columnIndex, boolean x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateByte(int columnIndex, byte x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateShort(int columnIndex, short x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateInt(int columnIndex, int x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateLong(int columnIndex, long x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateFloat(int columnIndex, float x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateDouble(int columnIndex, double x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateString(int columnIndex, String x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateBytes(int columnIndex, byte[] x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateDate(int columnIndex, Date x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateTime(int columnIndex, Time x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateObject(int columnIndex, Object x, int scaleOrLength) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateObject(int columnIndex, Object x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateNull(String columnLabel) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateBoolean(String columnLabel, boolean x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateByte(String columnLabel, byte x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateShort(String columnLabel, short x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateInt(String columnLabel, int x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateLong(String columnLabel, long x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateFloat(String columnLabel, float x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateDouble(String columnLabel, double x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateBigDecimal(String columnLabel, BigDecimal x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateString(String columnLabel, String x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
} }
@Override
public void updateBytes(String columnLabel, byte[] x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateDate(String columnLabel, Date x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateTime(String columnLabel, Time x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateTimestamp(String columnLabel, Timestamp x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateAsciiStream(String columnLabel, InputStream x, int length) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateBinaryStream(String columnLabel, InputStream x, int length) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateCharacterStream(String columnLabel, Reader reader, int length) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateObject(String columnLabel, Object x, int scaleOrLength) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateObject(String columnLabel, Object x) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void insertRow() throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void updateRow() throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void deleteRow() throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void refreshRow() throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void cancelRowUpdates() throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void moveToInsertRow() throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void moveToCurrentRow() throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public Statement getStatement() throws SQLException {
return null;
}
@Override
public Object getObject(int columnIndex, Map<String, Class<?>> map) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public Ref getRef(int columnIndex) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public Blob getBlob(int columnIndex) throws SQLException {
return null;
}
@Override
public Clob getClob(int columnIndex) throws SQLException {
return null;
}
@Override
public Array getArray(int columnIndex) throws SQLException {
return null;
}
@Override
public Object getObject(String columnLabel, Map<String, Class<?>> map) throws SQLException {
return null;
}
@Override
public Ref getRef(String columnLabel) throws SQLException {
return null;
}
@Override
public Blob getBlob(String columnLabel) throws SQLException {
return null;
}
@Override
public Clob getClob(String columnLabel) throws SQLException {
return null;
}
@Override
public Array getArray(String columnLabel) throws SQLException {
return null;
}
@Override
public Date getDate(int columnIndex, Calendar cal) throws SQLException {
return null;
}
@Override
public Date getDate(String columnLabel, Calendar cal) throws SQLException {
return null;
}
@Override
public Time getTime(int columnIndex, Calendar cal) throws SQLException {
return null;
}
@Override
public Time getTime(String columnLabel, Calendar cal) throws SQLException {
return null;
}
@Override
public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
return null;
}
@Override
public Timestamp getTimestamp(String columnLabel, Calendar cal) throws SQLException {
return null;
}
@Override
public URL getURL(int columnIndex) throws SQLException {
return null;
}
@Override
public URL getURL(String columnLabel) throws SQLException {
return null;
}
@Override
public void updateRef(int columnIndex, Ref x) throws SQLException {
}
@Override
public void updateRef(String columnLabel, Ref x) throws SQLException {
}
@Override
public void updateBlob(int columnIndex, Blob x) throws SQLException {
}
@Override
public void updateBlob(String columnLabel, Blob x) throws SQLException {
}
@Override
public void updateClob(int columnIndex, Clob x) throws SQLException {
}
@Override
public void updateClob(String columnLabel, Clob x) throws SQLException {
}
@Override
public void updateArray(int columnIndex, Array x) throws SQLException {
}
@Override
public void updateArray(String columnLabel, Array x) throws SQLException {
}
@Override
public RowId getRowId(int columnIndex) throws SQLException {
return null;
}
@Override
public RowId getRowId(String columnLabel) throws SQLException {
return null;
}
@Override
public void updateRowId(int columnIndex, RowId x) throws SQLException {
}
@Override
public void updateRowId(String columnLabel, RowId x) throws SQLException {
}
@Override
public int getHoldability() throws SQLException {
return 0;
}
@Override
public boolean isClosed() throws SQLException {
return false;
}
@Override
public void updateNString(int columnIndex, String nString) throws SQLException {
}
@Override
public void updateNString(String columnLabel, String nString) throws SQLException {
}
@Override
public void updateNClob(int columnIndex, NClob nClob) throws SQLException {
}
@Override
public void updateNClob(String columnLabel, NClob nClob) throws SQLException {
}
@Override
public NClob getNClob(int columnIndex) throws SQLException {
return null;
}
@Override
public NClob getNClob(String columnLabel) throws SQLException {
return null;
}
@Override
public SQLXML getSQLXML(int columnIndex) throws SQLException {
return null;
}
@Override
public SQLXML getSQLXML(String columnLabel) throws SQLException {
return null;
}
@Override
public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException {
}
@Override
public void updateSQLXML(String columnLabel, SQLXML xmlObject) throws SQLException {
}
@Override
public String getNString(int columnIndex) throws SQLException {
return null;
}
@Override
public String getNString(String columnLabel) throws SQLException {
return null;
}
@Override
public Reader getNCharacterStream(int columnIndex) throws SQLException {
return null;
}
@Override
public Reader getNCharacterStream(String columnLabel) throws SQLException {
return null;
}
@Override
public void updateNCharacterStream(int columnIndex, Reader x, long length) throws SQLException {
}
@Override
public void updateNCharacterStream(String columnLabel, Reader reader, long length) throws SQLException {
}
@Override
public void updateAsciiStream(int columnIndex, InputStream x, long length) throws SQLException {
}
@Override
public void updateBinaryStream(int columnIndex, InputStream x, long length) throws SQLException {
}
@Override
public void updateCharacterStream(int columnIndex, Reader x, long length) throws SQLException {
}
@Override
public void updateAsciiStream(String columnLabel, InputStream x, long length) throws SQLException {
}
@Override
public void updateBinaryStream(String columnLabel, InputStream x, long length) throws SQLException {
}
@Override
public void updateCharacterStream(String columnLabel, Reader reader, long length) throws SQLException {
}
@Override
public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException {
}
@Override
public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException {
}
@Override
public void updateClob(int columnIndex, Reader reader, long length) throws SQLException {
}
@Override
public void updateClob(String columnLabel, Reader reader, long length) throws SQLException {
}
@Override
public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException {
}
@Override
public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException {
}
@Override
public void updateNCharacterStream(int columnIndex, Reader x) throws SQLException {
}
@Override
public void updateNCharacterStream(String columnLabel, Reader reader) throws SQLException {
}
@Override
public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException {
}
@Override
public void updateBinaryStream(int columnIndex, InputStream x) throws SQLException {
}
@Override
public void updateCharacterStream(int columnIndex, Reader x) throws SQLException {
}
@Override
public void updateAsciiStream(String columnLabel, InputStream x) throws SQLException {
}
@Override
public void updateBinaryStream(String columnLabel, InputStream x) throws SQLException {
}
@Override
public void updateCharacterStream(String columnLabel, Reader reader) throws SQLException {
}
@Override
public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException {
}
@Override
public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException {
}
@Override
public void updateClob(int columnIndex, Reader reader) throws SQLException {
}
@Override
public void updateClob(String columnLabel, Reader reader) throws SQLException {
}
@Override
public void updateNClob(int columnIndex, Reader reader) throws SQLException {
}
@Override
public void updateNClob(String columnLabel, Reader reader) throws SQLException {
}
@Override
public <T> T getObject(int columnIndex, Class<T> type) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public <T> T getObject(String columnLabel, Class<T> type) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}
private int getTrueColumnIndex(int columnIndex) throws SQLException {
if (columnIndex < 1) {
throw new SQLException("Column Index out of range, " + columnIndex + " < " + 1);
}
int numOfCols = this.columnMetaDataList.size();
if (columnIndex > numOfCols) {
throw new SQLException("Column Index out of range, " + columnIndex + " > " + numOfCols);
}
return columnIndex - 1;
}
} }
...@@ -41,15 +41,15 @@ public abstract class TSDBConstants { ...@@ -41,15 +41,15 @@ public abstract class TSDBConstants {
public static final int TSDB_DATA_TYPE_BINARY = 8; public static final int TSDB_DATA_TYPE_BINARY = 8;
public static final int TSDB_DATA_TYPE_TIMESTAMP = 9; public static final int TSDB_DATA_TYPE_TIMESTAMP = 9;
public static final int TSDB_DATA_TYPE_NCHAR = 10; public static final int TSDB_DATA_TYPE_NCHAR = 10;
/* /**
系统增加新的无符号数据类型,分别是: * 系统增加新的无符号数据类型,分别是:
unsigned tinyint, 数值范围:0-254, NULL 为255 * unsigned tinyint, 数值范围:0-254, NULL 为255
unsigned smallint,数值范围: 0-65534, NULL 为65535 * unsigned smallint,数值范围: 0-65534, NULL 为65535
unsigned int,数值范围:0-4294967294,NULL 为4294967295u * unsigned int,数值范围:0-4294967294,NULL 为4294967295u
unsigned bigint,数值范围:0-18446744073709551614u,NULL 为18446744073709551615u。 * unsigned bigint,数值范围:0-18446744073709551614u,NULL 为18446744073709551615u。
example: * example:
create table tb(ts timestamp, a tinyint unsigned, b smallint unsigned, c int unsigned, d bigint unsigned); * create table tb(ts timestamp, a tinyint unsigned, b smallint unsigned, c int unsigned, d bigint unsigned);
*/ */
public static final int TSDB_DATA_TYPE_UTINYINT = 11; //unsigned tinyint public static final int TSDB_DATA_TYPE_UTINYINT = 11; //unsigned tinyint
public static final int TSDB_DATA_TYPE_USMALLINT = 12; //unsigned smallint public static final int TSDB_DATA_TYPE_USMALLINT = 12; //unsigned smallint
public static final int TSDB_DATA_TYPE_UINT = 13; //unsigned int public static final int TSDB_DATA_TYPE_UINT = 13; //unsigned int
...@@ -57,6 +57,47 @@ public abstract class TSDBConstants { ...@@ -57,6 +57,47 @@ public abstract class TSDBConstants {
// nchar column max length // nchar column max length
public static final int maxFieldSize = 16 * 1024; public static final int maxFieldSize = 16 * 1024;
// precision for data types
public static final int BOOLEAN_PRECISION = 1;
public static final int TINYINT_PRECISION = 4;
public static final int SMALLINT_PRECISION = 6;
public static final int INT_PRECISION = 11;
public static final int BIGINT_PRECISION = 20;
public static final int FLOAT_PRECISION = 12;
public static final int DOUBLE_PRECISION = 22;
public static final int TIMESTAMP_MS_PRECISION = 23;
public static final int TIMESTAMP_US_PRECISION = 26;
// scale for data types
public static final int FLOAT_SCALE = 31;
public static final int DOUBLE_SCALE = 31;
public static int typeName2JdbcType(String type) {
switch (type.toUpperCase()) {
case "TIMESTAMP":
return Types.TIMESTAMP;
case "INT":
return Types.INTEGER;
case "BIGINT":
return Types.BIGINT;
case "FLOAT":
return Types.FLOAT;
case "DOUBLE":
return Types.DOUBLE;
case "BINARY":
return Types.BINARY;
case "SMALLINT":
return Types.SMALLINT;
case "TINYINT":
return Types.TINYINT;
case "BOOL":
return Types.BOOLEAN;
case "NCHAR":
return Types.NCHAR;
default:
return Types.NULL;
}
}
public static int taosType2JdbcType(int taosType) throws SQLException { public static int taosType2JdbcType(int taosType) throws SQLException {
switch (taosType) { switch (taosType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL: case TSDBConstants.TSDB_DATA_TYPE_BOOL:
...@@ -88,7 +129,7 @@ public abstract class TSDBConstants { ...@@ -88,7 +129,7 @@ public abstract class TSDBConstants {
} }
public static String taosType2JdbcTypeName(int taosType) throws SQLException { public static String taosType2JdbcTypeName(int taosType) throws SQLException {
switch (taosType){ switch (taosType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL: case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return "BOOL"; return "BOOL";
case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: case TSDBConstants.TSDB_DATA_TYPE_UTINYINT:
...@@ -119,7 +160,7 @@ public abstract class TSDBConstants { ...@@ -119,7 +160,7 @@ public abstract class TSDBConstants {
} }
public static int jdbcType2TaosType(int jdbcType) throws SQLException { public static int jdbcType2TaosType(int jdbcType) throws SQLException {
switch (jdbcType){ switch (jdbcType) {
case Types.BOOLEAN: case Types.BOOLEAN:
return TSDBConstants.TSDB_DATA_TYPE_BOOL; return TSDBConstants.TSDB_DATA_TYPE_BOOL;
case Types.TINYINT: case Types.TINYINT:
...@@ -145,7 +186,7 @@ public abstract class TSDBConstants { ...@@ -145,7 +186,7 @@ public abstract class TSDBConstants {
} }
public static String jdbcType2TaosTypeName(int jdbcType) throws SQLException { public static String jdbcType2TaosTypeName(int jdbcType) throws SQLException {
switch (jdbcType){ switch (jdbcType) {
case Types.BOOLEAN: case Types.BOOLEAN:
return "BOOL"; return "BOOL";
case Types.TINYINT: case Types.TINYINT:
......
...@@ -16,13 +16,13 @@ ...@@ -16,13 +16,13 @@
*/ */
package com.taosdata.jdbc; package com.taosdata.jdbc;
import com.taosdata.jdbc.utils.TaosInfo;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.SQLWarning; import java.sql.SQLWarning;
import java.util.List; import java.util.List;
import com.taosdata.jdbc.utils.TaosInfo;
/** /**
* JNI connector * JNI connector
*/ */
...@@ -30,10 +30,10 @@ public class TSDBJNIConnector { ...@@ -30,10 +30,10 @@ public class TSDBJNIConnector {
private static volatile Boolean isInitialized = false; private static volatile Boolean isInitialized = false;
private TaosInfo taosInfo = TaosInfo.getInstance(); private TaosInfo taosInfo = TaosInfo.getInstance();
// Connection pointer used in C // Connection pointer used in C
private long taos = TSDBConstants.JNI_NULL_POINTER; private long taos = TSDBConstants.JNI_NULL_POINTER;
// result set status in current connection // result set status in current connection
private boolean isResultsetClosed; private boolean isResultsetClosed;
...@@ -194,7 +194,9 @@ public class TSDBJNIConnector { ...@@ -194,7 +194,9 @@ public class TSDBJNIConnector {
* Get schema metadata * Get schema metadata
*/ */
public int getSchemaMetaData(long resultSet, List<ColumnMetaData> columnMetaData) { public int getSchemaMetaData(long resultSet, List<ColumnMetaData> columnMetaData) {
return this.getSchemaMetaDataImp(this.taos, resultSet, columnMetaData); int ret = this.getSchemaMetaDataImp(this.taos, resultSet, columnMetaData);
columnMetaData.stream().forEach(column -> column.setColIndex(column.getColIndex() + 1));
return ret;
} }
private native int getSchemaMetaDataImp(long connection, long resultSet, List<ColumnMetaData> columnMetaData); private native int getSchemaMetaDataImp(long connection, long resultSet, List<ColumnMetaData> columnMetaData);
...@@ -221,7 +223,7 @@ public class TSDBJNIConnector { ...@@ -221,7 +223,7 @@ public class TSDBJNIConnector {
*/ */
public void closeConnection() throws SQLException { public void closeConnection() throws SQLException {
int code = this.closeConnectionImp(this.taos); int code = this.closeConnectionImp(this.taos);
if (code < 0) { if (code < 0) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
} else if (code == 0) { } else if (code == 0) {
...@@ -229,7 +231,7 @@ public class TSDBJNIConnector { ...@@ -229,7 +231,7 @@ public class TSDBJNIConnector {
} else { } else {
throw new SQLException("Undefined error code returned by TDengine when closing a connection"); throw new SQLException("Undefined error code returned by TDengine when closing a connection");
} }
// invoke closeConnectionImpl only here // invoke closeConnectionImpl only here
taosInfo.connect_close_increment(); taosInfo.connect_close_increment();
} }
...@@ -274,67 +276,76 @@ public class TSDBJNIConnector { ...@@ -274,67 +276,76 @@ public class TSDBJNIConnector {
} }
private native int validateCreateTableSqlImp(long connection, byte[] sqlBytes); private native int validateCreateTableSqlImp(long connection, byte[] sqlBytes);
public long prepareStmt(String sql) throws SQLException { public long prepareStmt(String sql) throws SQLException {
Long stmt = prepareStmtImp(sql.getBytes(), this.taos); Long stmt;
if (stmt == TSDBConstants.JNI_TDENGINE_ERROR) { try {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_SQL); stmt = prepareStmtImp(sql.getBytes(), this.taos);
} else if (stmt == TSDBConstants.JNI_CONNECTION_NULL) { } catch (Exception e) {
e.printStackTrace();
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_ENCODING);
}
if (stmt == TSDBConstants.JNI_CONNECTION_NULL) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
} else if (stmt == TSDBConstants.JNI_SQL_NULL) { }
if (stmt == TSDBConstants.JNI_SQL_NULL) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_SQL_NULL); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_SQL_NULL);
} else if (stmt == TSDBConstants.JNI_OUT_OF_MEMORY) { }
if (stmt == TSDBConstants.JNI_OUT_OF_MEMORY) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_OUT_OF_MEMORY); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_OUT_OF_MEMORY);
} }
return stmt; return stmt;
} }
private native long prepareStmtImp(byte[] sql, long con); private native long prepareStmtImp(byte[] sql, long con);
public void setBindTableName(long stmt, String tableName) throws SQLException { public void setBindTableName(long stmt, String tableName) throws SQLException {
int code = setBindTableNameImp(stmt, tableName, this.taos); int code = setBindTableNameImp(stmt, tableName, this.taos);
if (code != TSDBConstants.JNI_SUCCESS) { if (code != TSDBConstants.JNI_SUCCESS) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to set table name"); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to set table name");
} }
} }
private native int setBindTableNameImp(long stmt, String name, long conn); private native int setBindTableNameImp(long stmt, String name, long conn);
public void setBindTableNameAndTags(long stmt, String tableName, int numOfTags, ByteBuffer tags, ByteBuffer typeList, ByteBuffer lengthList, ByteBuffer nullList) throws SQLException { public void setBindTableNameAndTags(long stmt, String tableName, int numOfTags, ByteBuffer tags, ByteBuffer typeList, ByteBuffer lengthList, ByteBuffer nullList) throws SQLException {
int code = setTableNameTagsImp(stmt, tableName, numOfTags, tags.array(), typeList.array(), lengthList.array(), int code = setTableNameTagsImp(stmt, tableName, numOfTags, tags.array(), typeList.array(), lengthList.array(),
nullList.array(), this.taos); nullList.array(), this.taos);
if (code != TSDBConstants.JNI_SUCCESS) { if (code != TSDBConstants.JNI_SUCCESS) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to bind table name and corresponding tags"); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to bind table name and corresponding tags");
} }
} }
private native int setTableNameTagsImp(long stmt, String name, int numOfTags, byte[] tags, byte[] typeList, byte[] lengthList, byte[] nullList, long conn); private native int setTableNameTagsImp(long stmt, String name, int numOfTags, byte[] tags, byte[] typeList, byte[] lengthList, byte[] nullList, long conn);
public void bindColumnDataArray(long stmt, ByteBuffer colDataList, ByteBuffer lengthList, ByteBuffer isNullList, int type, int bytes, int numOfRows,int columnIndex) throws SQLException { public void bindColumnDataArray(long stmt, ByteBuffer colDataList, ByteBuffer lengthList, ByteBuffer isNullList, int type, int bytes, int numOfRows, int columnIndex) throws SQLException {
int code = bindColDataImp(stmt, colDataList.array(), lengthList.array(), isNullList.array(), type, bytes, numOfRows, columnIndex, this.taos); int code = bindColDataImp(stmt, colDataList.array(), lengthList.array(), isNullList.array(), type, bytes, numOfRows, columnIndex, this.taos);
if (code != TSDBConstants.JNI_SUCCESS) { if (code != TSDBConstants.JNI_SUCCESS) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to bind column data"); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to bind column data");
} }
} }
private native int bindColDataImp(long stmt, byte[] colDataList, byte[] lengthList, byte[] isNullList, int type, int bytes, int numOfRows, int columnIndex, long conn); private native int bindColDataImp(long stmt, byte[] colDataList, byte[] lengthList, byte[] isNullList, int type, int bytes, int numOfRows, int columnIndex, long conn);
public void executeBatch(long stmt) throws SQLException { public void executeBatch(long stmt) throws SQLException {
int code = executeBatchImp(stmt, this.taos); int code = executeBatchImp(stmt, this.taos);
if (code != TSDBConstants.JNI_SUCCESS) { if (code != TSDBConstants.JNI_SUCCESS) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to execute batch bind"); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to execute batch bind");
} }
} }
private native int executeBatchImp(long stmt, long con); private native int executeBatchImp(long stmt, long con);
public void closeBatch(long stmt) throws SQLException { public void closeBatch(long stmt) throws SQLException {
int code = closeStmt(stmt, this.taos); int code = closeStmt(stmt, this.taos);
if (code != TSDBConstants.JNI_SUCCESS) { if (code != TSDBConstants.JNI_SUCCESS) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to close batch bind"); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to close batch bind");
} }
} }
private native int closeStmt(long stmt, long con); private native int closeStmt(long stmt, long con);
} }
...@@ -39,18 +39,18 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -39,18 +39,18 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
private String rawSql; private String rawSql;
private Object[] parameters; private Object[] parameters;
private boolean isPrepared; private boolean isPrepared;
private ArrayList<ColumnInfo> colData; private ArrayList<ColumnInfo> colData;
private ArrayList<TableTagInfo> tableTags; private ArrayList<TableTagInfo> tableTags;
private int tagValueLength; private int tagValueLength;
private String tableName; private String tableName;
private long nativeStmtHandle = 0; private long nativeStmtHandle = 0;
private volatile TSDBParameterMetaData parameterMetaData; private volatile TSDBParameterMetaData parameterMetaData;
TSDBPreparedStatement(TSDBConnection connection, String sql) { TSDBPreparedStatement(TSDBConnection connection, String sql) {
super(connection); super(connection);
init(sql); init(sql);
int parameterCnt = 0; int parameterCnt = 0;
...@@ -64,11 +64,11 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -64,11 +64,11 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
this.isPrepared = true; this.isPrepared = true;
} }
if (parameterCnt > 1) { if (parameterCnt > 1) {
// the table name is also a parameter, so ignore it. // the table name is also a parameter, so ignore it.
this.colData = new ArrayList<ColumnInfo>(); this.colData = new ArrayList<ColumnInfo>();
this.tableTags = new ArrayList<TableTagInfo>(); this.tableTags = new ArrayList<TableTagInfo>();
} }
} }
private void init(String sql) { private void init(String sql) {
...@@ -205,9 +205,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -205,9 +205,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
@Override @Override
public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException { public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
if (isClosed()) setObject(parameterIndex, x.doubleValue());
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
} }
@Override @Override
...@@ -222,16 +220,12 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -222,16 +220,12 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
@Override @Override
public void setDate(int parameterIndex, Date x) throws SQLException { public void setDate(int parameterIndex, Date x) throws SQLException {
if (isClosed()) setObject(parameterIndex, new Timestamp(x.getTime()));
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
} }
@Override @Override
public void setTime(int parameterIndex, Time x) throws SQLException { public void setTime(int parameterIndex, Time x) throws SQLException {
if (isClosed()) setObject(parameterIndex, new Timestamp(x.getTime()));
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
} }
@Override @Override
...@@ -279,11 +273,10 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -279,11 +273,10 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
if (isClosed()) { if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
} }
if (parameterIndex < 1 && parameterIndex >= parameters.length) { if (parameterIndex < 1 && parameterIndex >= parameters.length) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
} }
parameters[parameterIndex - 1] = x; parameters[parameterIndex - 1] = x;
} }
...@@ -323,7 +316,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -323,7 +316,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
if (isClosed()) { if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
} }
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
} }
...@@ -350,9 +343,9 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -350,9 +343,9 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
@Override @Override
public ResultSetMetaData getMetaData() throws SQLException { public ResultSetMetaData getMetaData() throws SQLException {
if (isClosed()) if (this.getResultSet() == null)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); return null;
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); return getResultSet().getMetaData();
} }
@Override @Override
...@@ -396,10 +389,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -396,10 +389,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
if (isClosed()) if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
if (parameterMetaData == null) { return new TSDBParameterMetaData(parameters);
this.parameterMetaData = new TSDBParameterMetaData(parameters);
}
return this.parameterMetaData;
} }
@Override @Override
...@@ -411,9 +401,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -411,9 +401,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
@Override @Override
public void setNString(int parameterIndex, String value) throws SQLException { public void setNString(int parameterIndex, String value) throws SQLException {
if (isClosed()) setString(parameterIndex, value);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
} }
@Override @Override
...@@ -536,489 +524,495 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -536,489 +524,495 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
} }
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// NOTE: the following APIs are not JDBC compatible // NOTE: the following APIs are not JDBC compatible
// set the bind table name // set the bind table name
private static class ColumnInfo { private static class ColumnInfo {
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
private ArrayList data; private ArrayList data;
private int type; private int type;
private int bytes; private int bytes;
private boolean typeIsSet; private boolean typeIsSet;
public ColumnInfo() { public ColumnInfo() {
this.typeIsSet = false; this.typeIsSet = false;
} }
public void setType(int type) throws SQLException { public void setType(int type) throws SQLException {
if (this.isTypeSet()) { if (this.isTypeSet()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data type has been set"); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data type has been set");
} }
this.typeIsSet = true; this.typeIsSet = true;
this.type = type; this.type = type;
} }
public boolean isTypeSet() { public boolean isTypeSet() {
return this.typeIsSet; return this.typeIsSet;
} }
}; }
;
private static class TableTagInfo { private static class TableTagInfo {
private boolean isNull; private boolean isNull;
private Object value; private Object value;
private int type; private int type;
public TableTagInfo(Object value, int type) {
this.value = value; public TableTagInfo(Object value, int type) {
this.type = type; this.value = value;
} this.type = type;
}
public static TableTagInfo createNullTag(int type) {
TableTagInfo info = new TableTagInfo(null, type); public static TableTagInfo createNullTag(int type) {
info.isNull = true; TableTagInfo info = new TableTagInfo(null, type);
return info; info.isNull = true;
} return info;
}; }
}
;
public void setTableName(String name) { public void setTableName(String name) {
this.tableName = name; this.tableName = name;
} }
private void ensureTagCapacity(int index) { private void ensureTagCapacity(int index) {
if (this.tableTags.size() < index + 1) { if (this.tableTags.size() < index + 1) {
int delta = index + 1 - this.tableTags.size(); int delta = index + 1 - this.tableTags.size();
this.tableTags.addAll(Collections.nCopies(delta, null)); this.tableTags.addAll(Collections.nCopies(delta, null));
} }
} }
public void setTagNull(int index, int type) { public void setTagNull(int index, int type) {
ensureTagCapacity(index); ensureTagCapacity(index);
this.tableTags.set(index, TableTagInfo.createNullTag(type)); this.tableTags.set(index, TableTagInfo.createNullTag(type));
} }
public void setTagBoolean(int index, boolean value) { public void setTagBoolean(int index, boolean value) {
ensureTagCapacity(index); ensureTagCapacity(index);
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BOOL)); this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BOOL));
this.tagValueLength += Byte.BYTES; this.tagValueLength += Byte.BYTES;
} }
public void setTagInt(int index, int value) { public void setTagInt(int index, int value) {
ensureTagCapacity(index); ensureTagCapacity(index);
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_INT)); this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_INT));
this.tagValueLength += Integer.BYTES; this.tagValueLength += Integer.BYTES;
} }
public void setTagByte(int index, byte value) { public void setTagByte(int index, byte value) {
ensureTagCapacity(index); ensureTagCapacity(index);
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_TINYINT)); this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_TINYINT));
this.tagValueLength += Byte.BYTES; this.tagValueLength += Byte.BYTES;
} }
public void setTagShort(int index, short value) { public void setTagShort(int index, short value) {
ensureTagCapacity(index); ensureTagCapacity(index);
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_SMALLINT)); this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_SMALLINT));
this.tagValueLength += Short.BYTES; this.tagValueLength += Short.BYTES;
} }
public void setTagLong(int index, long value) { public void setTagLong(int index, long value) {
ensureTagCapacity(index); ensureTagCapacity(index);
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BIGINT)); this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BIGINT));
this.tagValueLength += Long.BYTES; this.tagValueLength += Long.BYTES;
} }
public void setTagTimestamp(int index, long value) { public void setTagTimestamp(int index, long value) {
ensureTagCapacity(index); ensureTagCapacity(index);
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP)); this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP));
this.tagValueLength += Long.BYTES; this.tagValueLength += Long.BYTES;
} }
public void setTagFloat(int index, float value) { public void setTagFloat(int index, float value) {
ensureTagCapacity(index); ensureTagCapacity(index);
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_FLOAT)); this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_FLOAT));
this.tagValueLength += Float.BYTES; this.tagValueLength += Float.BYTES;
} }
public void setTagDouble(int index, double value) { public void setTagDouble(int index, double value) {
ensureTagCapacity(index); ensureTagCapacity(index);
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_DOUBLE)); this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_DOUBLE));
this.tagValueLength += Double.BYTES; this.tagValueLength += Double.BYTES;
} }
public void setTagString(int index, String value) { public void setTagString(int index, String value) {
ensureTagCapacity(index); ensureTagCapacity(index);
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BINARY)); this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BINARY));
this.tagValueLength += value.getBytes().length; this.tagValueLength += value.getBytes().length;
} }
public void setTagNString(int index, String value) { public void setTagNString(int index, String value) {
ensureTagCapacity(index); ensureTagCapacity(index);
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_NCHAR)); this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_NCHAR));
String charset = TaosGlobalConfig.getCharset(); String charset = TaosGlobalConfig.getCharset();
try { try {
this.tagValueLength += value.getBytes(charset).length; this.tagValueLength += value.getBytes(charset).length;
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public <T> void setValueImpl(int columnIndex, ArrayList<T> list, int type, int bytes) throws SQLException { public <T> void setValueImpl(int columnIndex, ArrayList<T> list, int type, int bytes) throws SQLException {
if (this.colData.size() == 0) { if (this.colData.size() == 0) {
this.colData.addAll(Collections.nCopies(this.parameters.length - 1 - this.tableTags.size(), null)); this.colData.addAll(Collections.nCopies(this.parameters.length - 1 - this.tableTags.size(), null));
}
}
ColumnInfo col = (ColumnInfo) this.colData.get(columnIndex); ColumnInfo col = (ColumnInfo) this.colData.get(columnIndex);
if (col == null) { if (col == null) {
ColumnInfo p = new ColumnInfo(); ColumnInfo p = new ColumnInfo();
p.setType(type); p.setType(type);
p.bytes = bytes; p.bytes = bytes;
p.data = (ArrayList<?>) list.clone(); p.data = (ArrayList<?>) list.clone();
this.colData.set(columnIndex, p); this.colData.set(columnIndex, p);
} else { } else {
if (col.type != type) { if (col.type != type) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data type mismatch"); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data type mismatch");
} }
col.data.addAll(list); col.data.addAll(list);
} }
} }
public void setInt(int columnIndex, ArrayList<Integer> list) throws SQLException { public void setInt(int columnIndex, ArrayList<Integer> list) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_INT, Integer.BYTES); setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_INT, Integer.BYTES);
} }
public void setFloat(int columnIndex, ArrayList<Float> list) throws SQLException { public void setFloat(int columnIndex, ArrayList<Float> list) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_FLOAT, Float.BYTES); setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_FLOAT, Float.BYTES);
} }
public void setTimestamp(int columnIndex, ArrayList<Long> list) throws SQLException { public void setTimestamp(int columnIndex, ArrayList<Long> list) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP, Long.BYTES); setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP, Long.BYTES);
} }
public void setLong(int columnIndex, ArrayList<Long> list) throws SQLException { public void setLong(int columnIndex, ArrayList<Long> list) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BIGINT, Long.BYTES); setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BIGINT, Long.BYTES);
} }
public void setDouble(int columnIndex, ArrayList<Double> list) throws SQLException { public void setDouble(int columnIndex, ArrayList<Double> list) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_DOUBLE, Double.BYTES); setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_DOUBLE, Double.BYTES);
} }
public void setBoolean(int columnIndex, ArrayList<Boolean> list) throws SQLException { public void setBoolean(int columnIndex, ArrayList<Boolean> list) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BOOL, Byte.BYTES); setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BOOL, Byte.BYTES);
} }
public void setByte(int columnIndex, ArrayList<Byte> list) throws SQLException { public void setByte(int columnIndex, ArrayList<Byte> list) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_TINYINT, Byte.BYTES); setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_TINYINT, Byte.BYTES);
} }
public void setShort(int columnIndex, ArrayList<Short> list) throws SQLException { public void setShort(int columnIndex, ArrayList<Short> list) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_SMALLINT, Short.BYTES); setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_SMALLINT, Short.BYTES);
} }
public void setString(int columnIndex, ArrayList<String> list, int size) throws SQLException { public void setString(int columnIndex, ArrayList<String> list, int size) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BINARY, size); setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BINARY, size);
} }
// note: expand the required space for each NChar character // note: expand the required space for each NChar character
public void setNString(int columnIndex, ArrayList<String> list, int size) throws SQLException { public void setNString(int columnIndex, ArrayList<String> list, int size) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_NCHAR, size * Integer.BYTES); setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_NCHAR, size * Integer.BYTES);
} }
public void columnDataAddBatch() throws SQLException { public void columnDataAddBatch() throws SQLException {
// pass the data block to native code // pass the data block to native code
if (rawSql == null) { if (rawSql == null) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "sql statement not set yet"); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "sql statement not set yet");
} }
// table name is not set yet, abort // table name is not set yet, abort
if (this.tableName == null) { if (this.tableName == null) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "table name not set yet"); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "table name not set yet");
} }
int numOfCols = this.colData.size(); int numOfCols = this.colData.size();
if (numOfCols == 0) { if (numOfCols == 0) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data not bind"); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data not bind");
} }
TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector(); TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector();
this.nativeStmtHandle = connector.prepareStmt(rawSql); this.nativeStmtHandle = connector.prepareStmt(rawSql);
if (this.tableTags == null) { if (this.tableTags == null) {
connector.setBindTableName(this.nativeStmtHandle, this.tableName); connector.setBindTableName(this.nativeStmtHandle, this.tableName);
} else { } else {
int num = this.tableTags.size(); int num = this.tableTags.size();
ByteBuffer tagDataList = ByteBuffer.allocate(this.tagValueLength); ByteBuffer tagDataList = ByteBuffer.allocate(this.tagValueLength);
tagDataList.order(ByteOrder.LITTLE_ENDIAN); tagDataList.order(ByteOrder.LITTLE_ENDIAN);
ByteBuffer typeList = ByteBuffer.allocate(num); ByteBuffer typeList = ByteBuffer.allocate(num);
typeList.order(ByteOrder.LITTLE_ENDIAN); typeList.order(ByteOrder.LITTLE_ENDIAN);
ByteBuffer lengthList = ByteBuffer.allocate(num * Long.BYTES); ByteBuffer lengthList = ByteBuffer.allocate(num * Long.BYTES);
lengthList.order(ByteOrder.LITTLE_ENDIAN); lengthList.order(ByteOrder.LITTLE_ENDIAN);
ByteBuffer isNullList = ByteBuffer.allocate(num * Integer.BYTES); ByteBuffer isNullList = ByteBuffer.allocate(num * Integer.BYTES);
isNullList.order(ByteOrder.LITTLE_ENDIAN); isNullList.order(ByteOrder.LITTLE_ENDIAN);
for (int i = 0; i < num; ++i) { for (int i = 0; i < num; ++i) {
TableTagInfo tag = this.tableTags.get(i); TableTagInfo tag = this.tableTags.get(i);
if (tag.isNull) { if (tag.isNull) {
typeList.put((byte) tag.type); typeList.put((byte) tag.type);
isNullList.putInt(1); isNullList.putInt(1);
lengthList.putLong(0); lengthList.putLong(0);
continue; continue;
} }
switch (tag.type) { switch (tag.type) {
case TSDBConstants.TSDB_DATA_TYPE_INT: { case TSDBConstants.TSDB_DATA_TYPE_INT: {
Integer val = (Integer) tag.value; Integer val = (Integer) tag.value;
tagDataList.putInt(val); tagDataList.putInt(val);
lengthList.putLong(Integer.BYTES); lengthList.putLong(Integer.BYTES);
break; break;
} }
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: { case TSDBConstants.TSDB_DATA_TYPE_TINYINT: {
Byte val = (Byte) tag.value; Byte val = (Byte) tag.value;
tagDataList.put(val); tagDataList.put(val);
lengthList.putLong(Byte.BYTES); lengthList.putLong(Byte.BYTES);
break; break;
} }
case TSDBConstants.TSDB_DATA_TYPE_BOOL: { case TSDBConstants.TSDB_DATA_TYPE_BOOL: {
Boolean val = (Boolean) tag.value; Boolean val = (Boolean) tag.value;
tagDataList.put((byte) (val ? 1 : 0)); tagDataList.put((byte) (val ? 1 : 0));
lengthList.putLong(Byte.BYTES); lengthList.putLong(Byte.BYTES);
break; break;
} }
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: { case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: {
Short val = (Short) tag.value; Short val = (Short) tag.value;
tagDataList.putShort(val); tagDataList.putShort(val);
lengthList.putLong(Short.BYTES); lengthList.putLong(Short.BYTES);
break; break;
} }
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: { case TSDBConstants.TSDB_DATA_TYPE_BIGINT: {
Long val = (Long) tag.value; Long val = (Long) tag.value;
tagDataList.putLong(val == null ? 0 : val); tagDataList.putLong(val == null ? 0 : val);
lengthList.putLong(Long.BYTES); lengthList.putLong(Long.BYTES);
break; break;
} }
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: { case TSDBConstants.TSDB_DATA_TYPE_FLOAT: {
Float val = (Float) tag.value; Float val = (Float) tag.value;
tagDataList.putFloat(val == null ? 0 : val); tagDataList.putFloat(val == null ? 0 : val);
lengthList.putLong(Float.BYTES); lengthList.putLong(Float.BYTES);
break; break;
} }
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: { case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: {
Double val = (Double) tag.value; Double val = (Double) tag.value;
tagDataList.putDouble(val == null ? 0 : val); tagDataList.putDouble(val == null ? 0 : val);
lengthList.putLong(Double.BYTES); lengthList.putLong(Double.BYTES);
break; break;
} }
case TSDBConstants.TSDB_DATA_TYPE_NCHAR: case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
case TSDBConstants.TSDB_DATA_TYPE_BINARY: { case TSDBConstants.TSDB_DATA_TYPE_BINARY: {
String charset = TaosGlobalConfig.getCharset(); String charset = TaosGlobalConfig.getCharset();
String val = (String) tag.value; String val = (String) tag.value;
byte[] b = null; byte[] b = null;
try { try {
if (tag.type == TSDBConstants.TSDB_DATA_TYPE_BINARY) { if (tag.type == TSDBConstants.TSDB_DATA_TYPE_BINARY) {
b = val.getBytes(); b = val.getBytes();
} else { } else {
b = val.getBytes(charset); b = val.getBytes(charset);
} }
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
e.printStackTrace(); e.printStackTrace();
} }
tagDataList.put(b); tagDataList.put(b);
lengthList.putLong(b.length); lengthList.putLong(b.length);
break; break;
} }
case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: case TSDBConstants.TSDB_DATA_TYPE_UTINYINT:
case TSDBConstants.TSDB_DATA_TYPE_USMALLINT: case TSDBConstants.TSDB_DATA_TYPE_USMALLINT:
case TSDBConstants.TSDB_DATA_TYPE_UINT: case TSDBConstants.TSDB_DATA_TYPE_UINT:
case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: { case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "not support data types"); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "not support data types");
} }
} }
typeList.put((byte) tag.type); typeList.put((byte) tag.type);
isNullList.putInt(tag.isNull? 1 : 0); isNullList.putInt(tag.isNull ? 1 : 0);
} }
connector.setBindTableNameAndTags(this.nativeStmtHandle, this.tableName, this.tableTags.size(), tagDataList, connector.setBindTableNameAndTags(this.nativeStmtHandle, this.tableName, this.tableTags.size(), tagDataList,
typeList, lengthList, isNullList); typeList, lengthList, isNullList);
} }
ColumnInfo colInfo = (ColumnInfo) this.colData.get(0); ColumnInfo colInfo = (ColumnInfo) this.colData.get(0);
if (colInfo == null) { if (colInfo == null) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data not bind"); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data not bind");
} }
int rows = colInfo.data.size(); int rows = colInfo.data.size();
for (int i = 0; i < numOfCols; ++i) { for (int i = 0; i < numOfCols; ++i) {
ColumnInfo col1 = this.colData.get(i); ColumnInfo col1 = this.colData.get(i);
if (col1 == null || !col1.isTypeSet()) { if (col1 == null || !col1.isTypeSet()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data not bind"); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data not bind");
} }
if (rows != col1.data.size()) { if (rows != col1.data.size()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "the rows in column data not identical"); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "the rows in column data not identical");
} }
ByteBuffer colDataList = ByteBuffer.allocate(rows * col1.bytes); ByteBuffer colDataList = ByteBuffer.allocate(rows * col1.bytes);
colDataList.order(ByteOrder.LITTLE_ENDIAN); colDataList.order(ByteOrder.LITTLE_ENDIAN);
ByteBuffer lengthList = ByteBuffer.allocate(rows * Integer.BYTES); ByteBuffer lengthList = ByteBuffer.allocate(rows * Integer.BYTES);
lengthList.order(ByteOrder.LITTLE_ENDIAN); lengthList.order(ByteOrder.LITTLE_ENDIAN);
ByteBuffer isNullList = ByteBuffer.allocate(rows * Byte.BYTES); ByteBuffer isNullList = ByteBuffer.allocate(rows * Byte.BYTES);
isNullList.order(ByteOrder.LITTLE_ENDIAN); isNullList.order(ByteOrder.LITTLE_ENDIAN);
switch (col1.type) { switch (col1.type) {
case TSDBConstants.TSDB_DATA_TYPE_INT: { case TSDBConstants.TSDB_DATA_TYPE_INT: {
for (int j = 0; j < rows; ++j) { for (int j = 0; j < rows; ++j) {
Integer val = (Integer) col1.data.get(j); Integer val = (Integer) col1.data.get(j);
colDataList.putInt(val == null? Integer.MIN_VALUE:val); colDataList.putInt(val == null ? Integer.MIN_VALUE : val);
isNullList.put((byte) (val == null? 1:0)); isNullList.put((byte) (val == null ? 1 : 0));
} }
break; break;
} }
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: { case TSDBConstants.TSDB_DATA_TYPE_TINYINT: {
for (int j = 0; j < rows; ++j) { for (int j = 0; j < rows; ++j) {
Byte val = (Byte) col1.data.get(j); Byte val = (Byte) col1.data.get(j);
colDataList.put(val == null? 0:val); colDataList.put(val == null ? 0 : val);
isNullList.put((byte) (val == null? 1:0)); isNullList.put((byte) (val == null ? 1 : 0));
} }
break; break;
} }
case TSDBConstants.TSDB_DATA_TYPE_BOOL: { case TSDBConstants.TSDB_DATA_TYPE_BOOL: {
for (int j = 0; j < rows; ++j) { for (int j = 0; j < rows; ++j) {
Boolean val = (Boolean) col1.data.get(j); Boolean val = (Boolean) col1.data.get(j);
if (val == null) { if (val == null) {
colDataList.put((byte) 0); colDataList.put((byte) 0);
} else { } else {
colDataList.put((byte) (val? 1:0)); colDataList.put((byte) (val ? 1 : 0));
} }
isNullList.put((byte) (val == null? 1:0)); isNullList.put((byte) (val == null ? 1 : 0));
} }
break; break;
} }
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: { case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: {
for (int j = 0; j < rows; ++j) { for (int j = 0; j < rows; ++j) {
Short val = (Short) col1.data.get(j); Short val = (Short) col1.data.get(j);
colDataList.putShort(val == null? 0:val); colDataList.putShort(val == null ? 0 : val);
isNullList.put((byte) (val == null? 1:0)); isNullList.put((byte) (val == null ? 1 : 0));
} }
break; break;
} }
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: { case TSDBConstants.TSDB_DATA_TYPE_BIGINT: {
for (int j = 0; j < rows; ++j) { for (int j = 0; j < rows; ++j) {
Long val = (Long) col1.data.get(j); Long val = (Long) col1.data.get(j);
colDataList.putLong(val == null? 0:val); colDataList.putLong(val == null ? 0 : val);
isNullList.put((byte) (val == null? 1:0)); isNullList.put((byte) (val == null ? 1 : 0));
} }
break; break;
} }
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: { case TSDBConstants.TSDB_DATA_TYPE_FLOAT: {
for (int j = 0; j < rows; ++j) { for (int j = 0; j < rows; ++j) {
Float val = (Float) col1.data.get(j); Float val = (Float) col1.data.get(j);
colDataList.putFloat(val == null? 0:val); colDataList.putFloat(val == null ? 0 : val);
isNullList.put((byte) (val == null? 1:0)); isNullList.put((byte) (val == null ? 1 : 0));
} }
break; break;
} }
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: { case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: {
for (int j = 0; j < rows; ++j) { for (int j = 0; j < rows; ++j) {
Double val = (Double) col1.data.get(j); Double val = (Double) col1.data.get(j);
colDataList.putDouble(val == null? 0:val); colDataList.putDouble(val == null ? 0 : val);
isNullList.put((byte) (val == null? 1:0)); isNullList.put((byte) (val == null ? 1 : 0));
} }
break; break;
} }
case TSDBConstants.TSDB_DATA_TYPE_NCHAR: case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
case TSDBConstants.TSDB_DATA_TYPE_BINARY: { case TSDBConstants.TSDB_DATA_TYPE_BINARY: {
String charset = TaosGlobalConfig.getCharset(); String charset = TaosGlobalConfig.getCharset();
for (int j = 0; j < rows; ++j) { for (int j = 0; j < rows; ++j) {
String val = (String) col1.data.get(j); String val = (String) col1.data.get(j);
colDataList.position(j * col1.bytes); // seek to the correct position colDataList.position(j * col1.bytes); // seek to the correct position
if (val != null) { if (val != null) {
byte[] b = null; byte[] b = null;
try { try {
if (col1.type == TSDBConstants.TSDB_DATA_TYPE_BINARY) { if (col1.type == TSDBConstants.TSDB_DATA_TYPE_BINARY) {
b = val.getBytes(); b = val.getBytes();
} else { } else {
b = val.getBytes(charset); b = val.getBytes(charset);
} }
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
e.printStackTrace(); e.printStackTrace();
} }
if (val.length() > col1.bytes) { if (val.length() > col1.bytes) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "string data too long"); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "string data too long");
} }
colDataList.put(b); colDataList.put(b);
lengthList.putInt(b.length); lengthList.putInt(b.length);
isNullList.put((byte) 0); isNullList.put((byte) 0);
} else { } else {
lengthList.putInt(0); lengthList.putInt(0);
isNullList.put((byte) 1); isNullList.put((byte) 1);
} }
} }
break; break;
} }
case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: case TSDBConstants.TSDB_DATA_TYPE_UTINYINT:
case TSDBConstants.TSDB_DATA_TYPE_USMALLINT: case TSDBConstants.TSDB_DATA_TYPE_USMALLINT:
case TSDBConstants.TSDB_DATA_TYPE_UINT: case TSDBConstants.TSDB_DATA_TYPE_UINT:
case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: { case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "not support data types"); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "not support data types");
} }
}; }
;
connector.bindColumnDataArray(this.nativeStmtHandle, colDataList, lengthList, isNullList, col1.type, col1.bytes, rows, i);
} connector.bindColumnDataArray(this.nativeStmtHandle, colDataList, lengthList, isNullList, col1.type, col1.bytes, rows, i);
} }
}
public void columnDataExecuteBatch() throws SQLException {
TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector(); public void columnDataExecuteBatch() throws SQLException {
connector.executeBatch(this.nativeStmtHandle); TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector();
this.columnDataClearBatch(); connector.executeBatch(this.nativeStmtHandle);
} this.columnDataClearBatch();
}
public void columnDataClearBatch() { public void columnDataClearBatch() {
int size = this.colData.size(); int size = this.colData.size();
this.colData.clear(); this.colData.clear();
this.colData.addAll(Collections.nCopies(size, null)); this.colData.addAll(Collections.nCopies(size, null));
this.tableName = null; // clear the table name this.tableName = null; // clear the table name
} }
public void columnDataCloseBatch() throws SQLException { public void columnDataCloseBatch() throws SQLException {
TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector(); TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector();
connector.closeBatch(this.nativeStmtHandle); connector.closeBatch(this.nativeStmtHandle);
this.nativeStmtHandle = 0L; this.nativeStmtHandle = 0L;
this.tableName = null; this.tableName = null;
} }
} }
...@@ -133,9 +133,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -133,9 +133,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return this.blockData.getString(columnIndex - 1); return this.blockData.getString(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) { if (!lastWasNull) {
res = this.rowData.getString(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType();
res = this.rowData.getString(columnIndex, nativeType);
} }
return res; return res;
} }
...@@ -147,9 +148,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -147,9 +148,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return this.blockData.getBoolean(columnIndex - 1); return this.blockData.getBoolean(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) { if (!lastWasNull) {
res = this.rowData.getBoolean(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType();
res = this.rowData.getBoolean(columnIndex, nativeType);
} }
return res; return res;
} }
...@@ -161,9 +163,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -161,9 +163,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return (byte) this.blockData.getInt(columnIndex - 1); return (byte) this.blockData.getInt(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) { if (!lastWasNull) {
res = (byte) this.rowData.getInt(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType();
res = (byte) this.rowData.getInt(columnIndex, nativeType);
} }
return res; return res;
} }
...@@ -175,9 +178,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -175,9 +178,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return (short) this.blockData.getInt(columnIndex - 1); return (short) this.blockData.getInt(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) { if (!lastWasNull) {
res = (short) this.rowData.getInt(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType();
res = (short) this.rowData.getInt(columnIndex, nativeType);
} }
return res; return res;
} }
...@@ -189,9 +193,11 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -189,9 +193,11 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return this.blockData.getInt(columnIndex - 1); return this.blockData.getInt(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) { if (!lastWasNull) {
res = this.rowData.getInt(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType();
res = this.rowData.getInt(columnIndex, nativeType);
} }
return res; return res;
} }
...@@ -203,13 +209,15 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -203,13 +209,15 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return this.blockData.getLong(columnIndex - 1); return this.blockData.getLong(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) { if (!lastWasNull) {
Object value = this.rowData.get(columnIndex - 1); Object value = this.rowData.getObject(columnIndex);
if (value instanceof Timestamp) if (value instanceof Timestamp) {
res = ((Timestamp) value).getTime(); res = ((Timestamp) value).getTime();
else } else {
res = this.rowData.getLong(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType();
res = this.rowData.getLong(columnIndex, nativeType);
}
} }
return res; return res;
} }
...@@ -221,9 +229,11 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -221,9 +229,11 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return (float) this.blockData.getDouble(columnIndex - 1); return (float) this.blockData.getDouble(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) if (!lastWasNull) {
res = this.rowData.getFloat(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType();
res = this.rowData.getFloat(columnIndex, nativeType);
}
return res; return res;
} }
...@@ -235,9 +245,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -235,9 +245,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return this.blockData.getDouble(columnIndex - 1); return this.blockData.getDouble(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) { if (!lastWasNull) {
res = this.rowData.getDouble(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType();
res = this.rowData.getDouble(columnIndex, nativeType);
} }
return res; return res;
} }
...@@ -245,34 +256,27 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -245,34 +256,27 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
public byte[] getBytes(int columnIndex) throws SQLException { public byte[] getBytes(int columnIndex) throws SQLException {
checkAvailability(columnIndex, this.columnMetaDataList.size()); checkAvailability(columnIndex, this.columnMetaDataList.size());
Object value = this.rowData.get(columnIndex - 1); Object value = this.rowData.getObject(columnIndex);
if (value == null) if (value == null)
return null; return null;
int colType = this.columnMetaDataList.get(columnIndex - 1).getColType(); int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType();
switch (colType) { switch (nativeType) {
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return Longs.toByteArray((Long) value); return Longs.toByteArray((long) value);
case TSDBConstants.TSDB_DATA_TYPE_INT: case TSDBConstants.TSDB_DATA_TYPE_INT:
return Ints.toByteArray((int) value); return Ints.toByteArray((int) value);
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
return Shorts.toByteArray((Short) value); return Shorts.toByteArray((short) value);
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
return new byte[]{(byte) value}; return new byte[]{(byte) value};
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
return (byte[]) value;
case TSDBConstants.TSDB_DATA_TYPE_BOOL:
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
default:
return value.toString().getBytes();
} }
return value.toString().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 { public Timestamp getTimestamp(int columnIndex) throws SQLException {
...@@ -282,9 +286,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -282,9 +286,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return this.blockData.getTimestamp(columnIndex - 1); return this.blockData.getTimestamp(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) { if (!lastWasNull) {
res = this.rowData.getTimestamp(columnIndex - 1); int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType();
res = this.rowData.getTimestamp(columnIndex, nativeType);
} }
return res; return res;
} }
...@@ -304,13 +309,9 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -304,13 +309,9 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return this.blockData.get(columnIndex - 1); return this.blockData.get(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) { if (!lastWasNull) {
int colType = this.columnMetaDataList.get(columnIndex - 1).getColType(); res = this.rowData.getObject(columnIndex);
if (colType == TSDBConstants.TSDB_DATA_TYPE_BINARY)
res = ((String) this.rowData.get(columnIndex - 1)).getBytes();
else
res = this.rowData.get(columnIndex - 1);
} }
return res; return res;
} }
...@@ -318,7 +319,7 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -318,7 +319,7 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
public int findColumn(String columnLabel) throws SQLException { public int findColumn(String columnLabel) throws SQLException {
for (ColumnMetaData colMetaData : this.columnMetaDataList) { for (ColumnMetaData colMetaData : this.columnMetaDataList) {
if (colMetaData.getColName() != null && colMetaData.getColName().equalsIgnoreCase(columnLabel)) { if (colMetaData.getColName() != null && colMetaData.getColName().equalsIgnoreCase(columnLabel)) {
return colMetaData.getColIndex() + 1; return colMetaData.getColIndex();
} }
} }
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
...@@ -329,25 +330,25 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -329,25 +330,25 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return new BigDecimal(this.blockData.getLong(columnIndex - 1)); return new BigDecimal(this.blockData.getLong(columnIndex - 1));
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
BigDecimal res = null; BigDecimal res = null;
if (!lastWasNull) { if (!lastWasNull) {
int colType = this.columnMetaDataList.get(columnIndex - 1).getColType(); int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType();
switch (colType) { switch (nativeType) {
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
case TSDBConstants.TSDB_DATA_TYPE_INT: case TSDBConstants.TSDB_DATA_TYPE_INT:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
res = new BigDecimal(Long.valueOf(this.rowData.get(columnIndex - 1).toString())); res = new BigDecimal(Long.valueOf(this.rowData.getObject(columnIndex).toString()));
break; break;
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
res = new BigDecimal(Double.valueOf(this.rowData.get(columnIndex - 1).toString())); res = new BigDecimal(Double.valueOf(this.rowData.getObject(columnIndex).toString()));
break; break;
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
return new BigDecimal(((Timestamp) this.rowData.get(columnIndex - 1)).getTime()); return new BigDecimal(((Timestamp) this.rowData.getObject(columnIndex)).getTime());
default: default:
res = new BigDecimal(this.rowData.get(columnIndex - 1).toString()); res = new BigDecimal(this.rowData.getObject(columnIndex).toString());
} }
} }
return res; return res;
......
...@@ -113,6 +113,7 @@ public class TSDBResultSetMetaData extends WrapperImpl implements ResultSetMetaD ...@@ -113,6 +113,7 @@ public class TSDBResultSetMetaData extends WrapperImpl implements ResultSetMetaD
ColumnMetaData columnMetaData = this.colMetaDataList.get(column - 1); ColumnMetaData columnMetaData = this.colMetaDataList.get(column - 1);
switch (columnMetaData.getColType()) { switch (columnMetaData.getColType()) {
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return 5; return 5;
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
*****************************************************************************/ *****************************************************************************/
package com.taosdata.jdbc; package com.taosdata.jdbc;
import com.taosdata.jdbc.utils.NullType;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Timestamp; import java.sql.Timestamp;
...@@ -22,11 +24,13 @@ import java.util.ArrayList; ...@@ -22,11 +24,13 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
public class TSDBResultSetRowData { public class TSDBResultSetRowData {
private ArrayList<Object> data; private ArrayList<Object> data;
private int colSize = 0; private int colSize;
public TSDBResultSetRowData(int colSize) { public TSDBResultSetRowData(int colSize) {
this.setColSize(colSize); this.colSize = colSize;
this.clear();
} }
public void clear() { public void clear() {
...@@ -41,68 +45,104 @@ public class TSDBResultSetRowData { ...@@ -41,68 +45,104 @@ public class TSDBResultSetRowData {
} }
public boolean wasNull(int col) { public boolean wasNull(int col) {
return data.get(col) == null; return data.get(col - 1) == null;
}
/**
* $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api
*/
public void setBooleanValue(int col, boolean value) {
setBoolean(col - 1, value);
} }
/**
* !!! this method is invoked by JNI method and the index start from 0 in C implementations
*/
public void setBoolean(int col, boolean value) { public void setBoolean(int col, boolean value) {
data.set(col, value); data.set(col, value);
} }
public boolean getBoolean(int col, int srcType) throws SQLException { public boolean getBoolean(int col, int nativeType) throws SQLException {
Object obj = data.get(col); Object obj = data.get(col - 1);
switch (srcType) { switch (nativeType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL: case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return (Boolean) obj; return (Boolean) obj;
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return ((Float) obj) == 1.0 ? Boolean.TRUE : Boolean.FALSE;
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
return ((Double) obj) == 1.0 ? Boolean.TRUE : Boolean.FALSE;
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
return ((Byte) obj) == 1 ? Boolean.TRUE : Boolean.FALSE; return ((Byte) obj) == 1 ? Boolean.TRUE : Boolean.FALSE;
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
return ((Short) obj) == 1 ? Boolean.TRUE : Boolean.FALSE; return ((Short) obj) == 1 ? Boolean.TRUE : Boolean.FALSE;
case TSDBConstants.TSDB_DATA_TYPE_INT: case TSDBConstants.TSDB_DATA_TYPE_INT:
return ((Integer) obj) == 1 ? Boolean.TRUE : Boolean.FALSE; return ((Integer) obj) == 1 ? Boolean.TRUE : Boolean.FALSE;
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return ((Long) obj) == 1L ? Boolean.TRUE : Boolean.FALSE; return ((Long) obj) == 1L ? Boolean.TRUE : Boolean.FALSE;
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
case TSDBConstants.TSDB_DATA_TYPE_NCHAR: {
return obj.toString().contains("1");
}
default: default:
return false; return false;
} }
} }
/**
* $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api
*/
public void setByteValue(int colIndex, byte value) {
setByte(colIndex - 1, value);
}
/**
* !!! this method is invoked by JNI method and the index start from 0 in C implementations
*/
public void setByte(int col, byte value) { public void setByte(int col, byte value) {
data.set(col, value); data.set(col, value);
} }
/**
* $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api
*/
public void setShortValue(int colIndex, short value) {
setShort(colIndex - 1, value);
}
/**
* !!! this method is invoked by JNI method and the index start from 0 in C implementations
*/
public void setShort(int col, short value) { public void setShort(int col, short value) {
data.set(col, value); data.set(col, value);
} }
/**
* $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api
*/
public void setIntValue(int colIndex, int value) {
setInt(colIndex - 1, value);
}
/**
* !!! this method is invoked by JNI method and the index start from 0 in C implementations
*/
public void setInt(int col, int value) { public void setInt(int col, int value) {
data.set(col, value); data.set(col, value);
} }
@SuppressWarnings("deprecation") public int getInt(int col, int nativeType) throws SQLException {
public int getInt(int col, int srcType) throws SQLException { Object obj = data.get(col - 1);
Object obj = data.get(col); if (obj == null)
return NullType.getIntNull();
switch (srcType) { switch (nativeType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL: case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return Boolean.TRUE.equals(obj) ? 1 : 0; return Boolean.TRUE.equals(obj) ? 1 : 0;
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return ((Float) obj).intValue();
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
return ((Double) obj).intValue();
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
return (Byte) obj; return (Byte) obj;
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
return (Short) obj; return (Short) obj;
case TSDBConstants.TSDB_DATA_TYPE_INT: case TSDBConstants.TSDB_DATA_TYPE_INT:
return (Integer) obj; return (Integer) obj;
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
return ((Long) obj).intValue(); return ((Long) obj).intValue();
case TSDBConstants.TSDB_DATA_TYPE_NCHAR: case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
case TSDBConstants.TSDB_DATA_TYPE_BINARY: case TSDBConstants.TSDB_DATA_TYPE_BINARY:
...@@ -131,33 +171,46 @@ public class TSDBResultSetRowData { ...@@ -131,33 +171,46 @@ public class TSDBResultSetRowData {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
return Long.valueOf(value).intValue(); return Long.valueOf(value).intValue();
} }
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return ((Float) obj).intValue();
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
return ((Double) obj).intValue();
default:
return 0;
} }
}
return 0; /**
* $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api
*/
public void setLongValue(int colIndex, long value) {
setLong(colIndex - 1, value);
} }
/**
* !!! this method is invoked by JNI method and the index start from 0 in C implementations
*/
public void setLong(int col, long value) { public void setLong(int col, long value) {
data.set(col, value); data.set(col, value);
} }
public long getLong(int col, int srcType) throws SQLException { public long getLong(int col, int nativeType) throws SQLException {
Object obj = data.get(col); Object obj = data.get(col - 1);
if (obj == null) {
return NullType.getBigIntNull();
}
switch (srcType) { switch (nativeType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL: case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return Boolean.TRUE.equals(obj) ? 1 : 0; return Boolean.TRUE.equals(obj) ? 1 : 0;
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return ((Float) obj).longValue();
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
return ((Double) obj).longValue();
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
return (Byte) obj; return (Byte) obj;
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
return (Short) obj; return (Short) obj;
case TSDBConstants.TSDB_DATA_TYPE_INT: case TSDBConstants.TSDB_DATA_TYPE_INT:
return (Integer) obj; return (Integer) obj;
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
return (Long) obj; return (Long) obj;
case TSDBConstants.TSDB_DATA_TYPE_NCHAR: case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
case TSDBConstants.TSDB_DATA_TYPE_BINARY: case TSDBConstants.TSDB_DATA_TYPE_BINARY:
...@@ -186,19 +239,35 @@ public class TSDBResultSetRowData { ...@@ -186,19 +239,35 @@ public class TSDBResultSetRowData {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
return value; return value;
} }
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return ((Float) obj).longValue();
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
return ((Double) obj).longValue();
default:
return 0;
} }
}
return 0; /**
* $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api
*/
public void setFloatValue(int colIndex, float value) {
setFloat(colIndex - 1, value);
} }
/**
* !!! this method is invoked by JNI method and the index start from 0 in C implementations
*/
public void setFloat(int col, float value) { public void setFloat(int col, float value) {
data.set(col, value); data.set(col, value);
} }
public float getFloat(int col, int srcType) { public float getFloat(int col, int nativeType) {
Object obj = data.get(col); Object obj = data.get(col - 1);
if (obj == null)
return NullType.getFloatNull();
switch (srcType) { switch (nativeType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL: case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return Boolean.TRUE.equals(obj) ? 1 : 0; return Boolean.TRUE.equals(obj) ? 1 : 0;
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
...@@ -214,19 +283,31 @@ public class TSDBResultSetRowData { ...@@ -214,19 +283,31 @@ public class TSDBResultSetRowData {
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return (Long) obj; return (Long) obj;
default:
return NullType.getFloatNull();
} }
}
return 0; /**
* $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api
*/
public void setDoubleValue(int colIndex, double value) {
setDouble(colIndex - 1, value);
} }
/**
* !!! this method is invoked by JNI method and the index start from 0 in C implementations
*/
public void setDouble(int col, double value) { public void setDouble(int col, double value) {
data.set(col, value); data.set(col, value);
} }
public double getDouble(int col, int srcType) { public double getDouble(int col, int nativeType) {
Object obj = data.get(col); Object obj = data.get(col - 1);
if (obj == null)
return NullType.getDoubleNull();
switch (srcType) { switch (nativeType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL: case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return Boolean.TRUE.equals(obj) ? 1 : 0; return Boolean.TRUE.equals(obj) ? 1 : 0;
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
...@@ -242,16 +323,46 @@ public class TSDBResultSetRowData { ...@@ -242,16 +323,46 @@ public class TSDBResultSetRowData {
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return (Long) obj; return (Long) obj;
default:
return NullType.getDoubleNull();
} }
}
return 0; /**
* $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api
*/
public void setStringValue(int colIndex, String value) {
data.set(colIndex - 1, value);
} }
/**
* !!! this method is invoked by JNI method and the index start from 0 in C implementations
*/
public void setString(int col, String value) { public void setString(int col, String value) {
data.set(col, value); // TODO:
// !!!NOTE!!!
// this is very confusing problem which related to JNI-method implementation,
// the JNI method return a String(encoded in UTF) for BINARY value, which means the JNI method will invoke
// this setString(int, String) to handle BINARY value, we need to build a byte[] with default charsetEncoding
data.set(col, value == null ? null : value.getBytes());
}
/**
* $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api
*/
public void setByteArrayValue(int colIndex, byte[] value) {
setByteArray(colIndex - 1, value);
} }
/**
* !!! this method is invoked by JNI method and the index start from 0 in C implementations
*/
public void setByteArray(int col, byte[] value) { public void setByteArray(int col, byte[] value) {
// TODO:
// !!!NOTE!!!
// this is very confusing problem which related to JNI-method implementation,
// the JNI method return a byte[] for NCHAR value, which means the JNI method will invoke
// this setByteArr(int, byte[]) to handle NCHAR value, we need to build a String with charsetEncoding by TaosGlobalConfig
try { try {
data.set(col, new String(value, TaosGlobalConfig.getCharset())); data.set(col, new String(value, TaosGlobalConfig.getCharset()));
} catch (Exception e) { } catch (Exception e) {
...@@ -259,47 +370,56 @@ public class TSDBResultSetRowData { ...@@ -259,47 +370,56 @@ public class TSDBResultSetRowData {
} }
} }
/** public String getString(int col, int nativeType) {
* The original type may not be a string type, but will be converted to by calling this method Object obj = data.get(col - 1);
* if (obj == null)
* @param col column index return null;
* @return
*/ switch (nativeType) {
public String getString(int col, int srcType) {
switch (srcType) {
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
return (String) data.get(col);
case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: { case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: {
Byte value = new Byte(String.valueOf(data.get(col))); Byte value = new Byte(String.valueOf(obj));
if (value >= 0) if (value >= 0)
return value.toString(); return value.toString();
return Integer.toString(value & 0xff); return Integer.toString(value & 0xff);
} }
case TSDBConstants.TSDB_DATA_TYPE_USMALLINT: { case TSDBConstants.TSDB_DATA_TYPE_USMALLINT: {
Short value = new Short(String.valueOf(data.get(col))); Short value = new Short(String.valueOf(obj));
if (value >= 0) if (value >= 0)
return value.toString(); return value.toString();
return Integer.toString(value & 0xffff); return Integer.toString(value & 0xffff);
} }
case TSDBConstants.TSDB_DATA_TYPE_UINT: { case TSDBConstants.TSDB_DATA_TYPE_UINT: {
Integer value = new Integer(String.valueOf(data.get(col))); Integer value = new Integer(String.valueOf(obj));
if (value >= 0) if (value >= 0)
return value.toString(); return value.toString();
return Long.toString(value & 0xffffffffl); return Long.toString(value & 0xffffffffl);
} }
case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: { case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: {
Long value = new Long(String.valueOf(data.get(col))); Long value = new Long(String.valueOf(obj));
if (value >= 0) if (value >= 0)
return value.toString(); return value.toString();
long lowValue = value & 0x7fffffffffffffffL; long lowValue = value & 0x7fffffffffffffffL;
return BigDecimal.valueOf(lowValue).add(BigDecimal.valueOf(Long.MAX_VALUE)).add(BigDecimal.valueOf(1)).toString(); return BigDecimal.valueOf(lowValue).add(BigDecimal.valueOf(Long.MAX_VALUE)).add(BigDecimal.valueOf(1)).toString();
} }
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
return new String((byte[]) obj);
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
return (String) obj;
default: default:
return String.valueOf(data.get(col)); return String.valueOf(obj);
} }
} }
/**
* $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api
*/
public void setTimestampValue(int colIndex, long value) {
setTimestamp(colIndex - 1, value);
}
/**
* !!! this method is invoked by JNI method and the index start from 0 in C implementations
*/
public void setTimestamp(int col, long ts) { public void setTimestamp(int col, long ts) {
//TODO: this implementation contains logical error //TODO: this implementation contains logical error
// when precision is us the (long ts) is 16 digital number // when precision is us the (long ts) is 16 digital number
...@@ -316,28 +436,20 @@ public class TSDBResultSetRowData { ...@@ -316,28 +436,20 @@ public class TSDBResultSetRowData {
} }
} }
public Timestamp getTimestamp(int col) { public Timestamp getTimestamp(int col, int nativeType) {
return (Timestamp) data.get(col); Object obj = data.get(col - 1);
} if (obj == null)
return null;
public Object get(int col) { switch (nativeType) {
return data.get(col); case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
} return new Timestamp((Long) obj);
default:
public int getColSize() { return (Timestamp) obj;
return colSize; }
}
private void setColSize(int colSize) {
this.colSize = colSize;
this.clear();
} }
public ArrayList<Object> getData() { public Object getObject(int col) {
return data; return data.get(col - 1);
} }
public void setData(ArrayList<Object> data) {
this.data = (ArrayList<Object>) data.clone();
}
} }
...@@ -32,14 +32,15 @@ public class TSDBStatement extends AbstractStatement { ...@@ -32,14 +32,15 @@ public class TSDBStatement extends AbstractStatement {
} }
public ResultSet executeQuery(String sql) throws SQLException { public ResultSet executeQuery(String sql) throws SQLException {
// check if closed
if (isClosed()) { if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
} }
//TODO:
//TODO: 如果在executeQuery方法中执行insert语句,那么先执行了SQL,再通过pSql来检查是否为一个insert语句,但这个insert SQL已经执行成功了 // this is an unreasonable implementation, if the paratemer is a insert statement,
// the JNI connector will execute the sql at first and return a pointer: pSql,
// execute query // we use this pSql and invoke the isUpdateQuery(long pSql) method to decide .
// but the insert sql is already executed in database.
//execute query
long pSql = this.connection.getConnector().executeQuery(sql); long pSql = this.connection.getConnector().executeQuery(sql);
// if pSql is create/insert/update/delete/alter SQL // if pSql is create/insert/update/delete/alter SQL
if (this.connection.getConnector().isUpdateQuery(pSql)) { if (this.connection.getConnector().isUpdateQuery(pSql)) {
......
...@@ -95,16 +95,7 @@ public class Utils { ...@@ -95,16 +95,7 @@ public class Utils {
public static String getNativeSql(String rawSql, Object[] parameters) { public static String getNativeSql(String rawSql, Object[] parameters) {
// toLowerCase // toLowerCase
String preparedSql = rawSql.trim().toLowerCase(); String preparedSql = rawSql.trim().toLowerCase();
String[] clause = new String[]{"values\\s*\\(.*?\\)", "tags\\s*\\(.*?\\)", "where\\s*.*"};
String[] clause = new String[0];
if (SqlSyntaxValidator.isInsertSql(preparedSql)) {
// insert or import
clause = new String[]{"values\\s*\\(.*?\\)", "tags\\s*\\(.*?\\)"};
}
if (SqlSyntaxValidator.isSelectSql(preparedSql)) {
// select
clause = new String[]{"where\\s*.*"};
}
Map<Integer, Integer> placeholderPositions = new HashMap<>(); Map<Integer, Integer> placeholderPositions = new HashMap<>();
RangeSet<Integer> clauseRangeSet = TreeRangeSet.create(); RangeSet<Integer> clauseRangeSet = TreeRangeSet.create();
findPlaceholderPosition(preparedSql, placeholderPositions); findPlaceholderPosition(preparedSql, placeholderPositions);
......
...@@ -32,20 +32,34 @@ public class TSDBConnectionTest { ...@@ -32,20 +32,34 @@ public class TSDBConnectionTest {
} }
@Test @Test
public void subscribe() { public void runSubscribe() {
try { try {
// given
TSDBConnection unwrap = conn.unwrap(TSDBConnection.class); TSDBConnection unwrap = conn.unwrap(TSDBConnection.class);
TSDBSubscribe subscribe = unwrap.subscribe("topic1", "select * from log.log", false); TSDBSubscribe subscribe = unwrap.subscribe("topic1", "select * from log.log", false);
// when
TSDBResultSet rs = subscribe.consume(); TSDBResultSet rs = subscribe.consume();
ResultSetMetaData metaData = rs.getMetaData(); ResultSetMetaData metaData = rs.getMetaData();
for (int count = 0; count < 10 && rs.next(); count++) {
for (int i = 1; i <= metaData.getColumnCount(); i++) { // then
String value = rs.getString(i);
System.out.print(metaData.getColumnLabel(i) + ":" + value + "\t");
}
System.out.println();
}
Assert.assertNotNull(rs); Assert.assertNotNull(rs);
Assert.assertEquals(4, metaData.getColumnCount());
Assert.assertEquals("ts", metaData.getColumnLabel(1));
Assert.assertEquals("level", metaData.getColumnLabel(2));
Assert.assertEquals("content", metaData.getColumnLabel(3));
Assert.assertEquals("ipaddr", metaData.getColumnLabel(4));
rs.next();
// row 1
{
Assert.assertNotNull(rs.getTimestamp(1));
Assert.assertNotNull(rs.getTimestamp("ts"));
Assert.assertNotNull(rs.getByte(2));
Assert.assertNotNull(rs.getByte("level"));
Assert.assertNotNull(rs.getString(3));
Assert.assertNotNull(rs.getString("content"));
Assert.assertNotNull(rs.getString(4));
Assert.assertNotNull(rs.getString("ipaddr"));
}
subscribe.close(false); subscribe.close(false);
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
......
...@@ -7,9 +7,11 @@ import java.util.Properties; ...@@ -7,9 +7,11 @@ import java.util.Properties;
public class TSDBDatabaseMetaDataTest { public class TSDBDatabaseMetaDataTest {
private static final String host = "127.0.0.1"; private static final String host = "127.0.0.1";
private static final String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata";
private static Connection connection; private static Connection connection;
private static TSDBDatabaseMetaData metaData; private static TSDBDatabaseMetaData metaData;
@Test @Test
public void unwrap() throws SQLException { public void unwrap() throws SQLException {
TSDBDatabaseMetaData unwrap = metaData.unwrap(TSDBDatabaseMetaData.class); TSDBDatabaseMetaData unwrap = metaData.unwrap(TSDBDatabaseMetaData.class);
...@@ -33,7 +35,7 @@ public class TSDBDatabaseMetaDataTest { ...@@ -33,7 +35,7 @@ public class TSDBDatabaseMetaDataTest {
@Test @Test
public void getURL() throws SQLException { public void getURL() throws SQLException {
Assert.assertEquals("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata", metaData.getURL()); Assert.assertEquals(url, metaData.getURL());
} }
@Test @Test
...@@ -627,17 +629,32 @@ public class TSDBDatabaseMetaDataTest { ...@@ -627,17 +629,32 @@ public class TSDBDatabaseMetaDataTest {
@Test @Test
public void getTables() throws SQLException { public void getTables() throws SQLException {
System.out.println("****************************************************"); ResultSet rs = metaData.getTables("log", "", null, null);
ResultSet tables = metaData.getTables("log", "", null, null); ResultSetMetaData meta = rs.getMetaData();
ResultSetMetaData metaData = tables.getMetaData(); Assert.assertNotNull(rs);
while (tables.next()) { rs.next();
System.out.print(metaData.getColumnLabel(1) + ":" + tables.getString(1) + "\t"); {
System.out.print(metaData.getColumnLabel(3) + ":" + tables.getString(3) + "\t"); // TABLE_CAT
System.out.print(metaData.getColumnLabel(4) + ":" + tables.getString(4) + "\t"); Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1));
System.out.print(metaData.getColumnLabel(5) + ":" + tables.getString(5) + "\n"); Assert.assertEquals("log", rs.getString(1));
Assert.assertEquals("log", rs.getString("TABLE_CAT"));
// TABLE_SCHEM
Assert.assertEquals("TABLE_SCHEM", meta.getColumnLabel(2));
Assert.assertEquals(null, rs.getString(2));
Assert.assertEquals(null, rs.getString("TABLE_SCHEM"));
// TABLE_NAME
Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3));
Assert.assertNotNull(rs.getString(3));
Assert.assertNotNull(rs.getString("TABLE_NAME"));
// TABLE_TYPE
Assert.assertEquals("TABLE_TYPE", meta.getColumnLabel(4));
Assert.assertEquals("TABLE", rs.getString(4));
Assert.assertEquals("TABLE", rs.getString("TABLE_TYPE"));
// REMARKS
Assert.assertEquals("REMARKS", meta.getColumnLabel(5));
Assert.assertEquals("", rs.getString(5));
Assert.assertEquals("", rs.getString("REMARKS"));
} }
System.out.println();
Assert.assertNotNull(tables);
} }
@Test @Test
...@@ -647,46 +664,130 @@ public class TSDBDatabaseMetaDataTest { ...@@ -647,46 +664,130 @@ public class TSDBDatabaseMetaDataTest {
@Test @Test
public void getCatalogs() throws SQLException { public void getCatalogs() throws SQLException {
System.out.println("****************************************************"); ResultSet rs = metaData.getCatalogs();
ResultSetMetaData meta = rs.getMetaData();
ResultSet catalogs = metaData.getCatalogs(); rs.next();
ResultSetMetaData meta = catalogs.getMetaData(); {
while (catalogs.next()) { // TABLE_CAT
for (int i = 1; i <= meta.getColumnCount(); i++) { Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1));
System.out.print(meta.getColumnLabel(i) + ": " + catalogs.getString(i)); Assert.assertNotNull(rs.getString(1));
} Assert.assertNotNull(rs.getString("TABLE_CAT"));
System.out.println();
} }
} }
@Test @Test
public void getTableTypes() throws SQLException { public void getTableTypes() throws SQLException {
System.out.println("****************************************************");
ResultSet tableTypes = metaData.getTableTypes(); ResultSet tableTypes = metaData.getTableTypes();
while (tableTypes.next()) { tableTypes.next();
System.out.println(tableTypes.getString("TABLE_TYPE")); // tableTypes: table
{
Assert.assertEquals("TABLE", tableTypes.getString(1));
Assert.assertEquals("TABLE", tableTypes.getString("TABLE_TYPE"));
}
tableTypes.next();
// tableTypes: stable
{
Assert.assertEquals("STABLE", tableTypes.getString(1));
Assert.assertEquals("STABLE", tableTypes.getString("TABLE_TYPE"));
} }
Assert.assertNotNull(metaData.getTableTypes());
} }
@Test @Test
public void getColumns() throws SQLException { public void getColumns() throws SQLException {
System.out.println("****************************************************"); // when
ResultSet columns = metaData.getColumns("log", "", "dn", ""); ResultSet columns = metaData.getColumns("log", "", "dn", "");
// then
ResultSetMetaData meta = columns.getMetaData(); ResultSetMetaData meta = columns.getMetaData();
while (columns.next()) { columns.next();
System.out.print(meta.getColumnLabel(1) + ": " + columns.getString(1) + "\t"); // column: 1
System.out.print(meta.getColumnLabel(3) + ": " + columns.getString(3) + "\t"); {
System.out.print(meta.getColumnLabel(4) + ": " + columns.getString(4) + "\t"); // TABLE_CAT
System.out.print(meta.getColumnLabel(5) + ": " + columns.getString(5) + "\t"); Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1));
System.out.print(meta.getColumnLabel(6) + ": " + columns.getString(6) + "\t"); Assert.assertEquals("log", columns.getString(1));
System.out.print(meta.getColumnLabel(7) + ": " + columns.getString(7) + "\t"); Assert.assertEquals("log", columns.getString("TABLE_CAT"));
System.out.print(meta.getColumnLabel(9) + ": " + columns.getString(9) + "\t"); // TABLE_NAME
System.out.print(meta.getColumnLabel(10) + ": " + columns.getString(10) + "\t"); Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3));
System.out.print(meta.getColumnLabel(11) + ": " + columns.getString(11) + "\n"); Assert.assertEquals("dn", columns.getString(3));
System.out.print(meta.getColumnLabel(12) + ": " + columns.getString(12) + "\n"); Assert.assertEquals("dn", columns.getString("TABLE_NAME"));
// COLUMN_NAME
Assert.assertEquals("COLUMN_NAME", meta.getColumnLabel(4));
Assert.assertEquals("ts", columns.getString(4));
Assert.assertEquals("ts", columns.getString("COLUMN_NAME"));
// DATA_TYPE
Assert.assertEquals("DATA_TYPE", meta.getColumnLabel(5));
Assert.assertEquals(Types.TIMESTAMP, columns.getInt(5));
Assert.assertEquals(Types.TIMESTAMP, columns.getInt("DATA_TYPE"));
// TYPE_NAME
Assert.assertEquals("TYPE_NAME", meta.getColumnLabel(6));
Assert.assertEquals("TIMESTAMP", columns.getString(6));
Assert.assertEquals("TIMESTAMP", columns.getString("TYPE_NAME"));
// COLUMN_SIZE
Assert.assertEquals("COLUMN_SIZE", meta.getColumnLabel(7));
Assert.assertEquals(26, columns.getInt(7));
Assert.assertEquals(26, columns.getInt("COLUMN_SIZE"));
// DECIMAL_DIGITS
Assert.assertEquals("DECIMAL_DIGITS", meta.getColumnLabel(9));
Assert.assertEquals(Integer.MIN_VALUE, columns.getInt(9));
Assert.assertEquals(Integer.MIN_VALUE, columns.getInt("DECIMAL_DIGITS"));
Assert.assertEquals(null, columns.getString(9));
Assert.assertEquals(null, columns.getString("DECIMAL_DIGITS"));
// NUM_PREC_RADIX
Assert.assertEquals("NUM_PREC_RADIX", meta.getColumnLabel(10));
Assert.assertEquals(10, columns.getInt(10));
Assert.assertEquals(10, columns.getInt("NUM_PREC_RADIX"));
// NULLABLE
Assert.assertEquals("NULLABLE", meta.getColumnLabel(11));
Assert.assertEquals(DatabaseMetaData.columnNoNulls, columns.getInt(11));
Assert.assertEquals(DatabaseMetaData.columnNoNulls, columns.getInt("NULLABLE"));
// REMARKS
Assert.assertEquals("REMARKS", meta.getColumnLabel(12));
Assert.assertEquals(null, columns.getString(12));
Assert.assertEquals(null, columns.getString("REMARKS"));
}
columns.next();
// column: 2
{
// TABLE_CAT
Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1));
Assert.assertEquals("log", columns.getString(1));
Assert.assertEquals("log", columns.getString("TABLE_CAT"));
// TABLE_NAME
Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3));
Assert.assertEquals("dn", columns.getString(3));
Assert.assertEquals("dn", columns.getString("TABLE_NAME"));
// COLUMN_NAME
Assert.assertEquals("COLUMN_NAME", meta.getColumnLabel(4));
Assert.assertEquals("cpu_taosd", columns.getString(4));
Assert.assertEquals("cpu_taosd", columns.getString("COLUMN_NAME"));
// DATA_TYPE
Assert.assertEquals("DATA_TYPE", meta.getColumnLabel(5));
Assert.assertEquals(Types.FLOAT, columns.getInt(5));
Assert.assertEquals(Types.FLOAT, columns.getInt("DATA_TYPE"));
// TYPE_NAME
Assert.assertEquals("TYPE_NAME", meta.getColumnLabel(6));
Assert.assertEquals("FLOAT", columns.getString(6));
Assert.assertEquals("FLOAT", columns.getString("TYPE_NAME"));
// COLUMN_SIZE
Assert.assertEquals("COLUMN_SIZE", meta.getColumnLabel(7));
Assert.assertEquals(12, columns.getInt(7));
Assert.assertEquals(12, columns.getInt("COLUMN_SIZE"));
// DECIMAL_DIGITS
Assert.assertEquals("DECIMAL_DIGITS", meta.getColumnLabel(9));
Assert.assertEquals(Integer.MIN_VALUE, columns.getInt(9));
Assert.assertEquals(Integer.MIN_VALUE, columns.getInt("DECIMAL_DIGITS"));
Assert.assertEquals(null, columns.getString(9));
Assert.assertEquals(null, columns.getString("DECIMAL_DIGITS"));
// NUM_PREC_RADIX
Assert.assertEquals("NUM_PREC_RADIX", meta.getColumnLabel(10));
Assert.assertEquals(10, columns.getInt(10));
Assert.assertEquals(10, columns.getInt("NUM_PREC_RADIX"));
// NULLABLE
Assert.assertEquals("NULLABLE", meta.getColumnLabel(11));
Assert.assertEquals(DatabaseMetaData.columnNullable, columns.getInt(11));
Assert.assertEquals(DatabaseMetaData.columnNullable, columns.getInt("NULLABLE"));
// REMARKS
Assert.assertEquals("REMARKS", meta.getColumnLabel(12));
Assert.assertEquals(null, columns.getString(12));
} }
} }
...@@ -712,17 +813,35 @@ public class TSDBDatabaseMetaDataTest { ...@@ -712,17 +813,35 @@ public class TSDBDatabaseMetaDataTest {
@Test @Test
public void getPrimaryKeys() throws SQLException { public void getPrimaryKeys() throws SQLException {
System.out.println("****************************************************");
ResultSet rs = metaData.getPrimaryKeys("log", "", "dn1"); ResultSet rs = metaData.getPrimaryKeys("log", "", "dn1");
while (rs.next()) { ResultSetMetaData meta = rs.getMetaData();
System.out.println("TABLE_NAME: " + rs.getString("TABLE_NAME")); rs.next();
System.out.println("COLUMN_NAME: " + rs.getString("COLUMN_NAME")); {
System.out.println("KEY_SEQ: " + rs.getString("KEY_SEQ")); // TABLE_CAT
System.out.println("PK_NAME: " + rs.getString("PK_NAME")); Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1));
Assert.assertEquals("log", rs.getString(1));
Assert.assertEquals("log", rs.getString("TABLE_CAT"));
// TABLE_SCHEM
Assert.assertEquals("TABLE_SCHEM", meta.getColumnLabel(2));
Assert.assertEquals(null, rs.getString(2));
Assert.assertEquals(null, rs.getString("TABLE_SCHEM"));
// TABLE_NAME
Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3));
Assert.assertEquals("dn1", rs.getString(3));
Assert.assertEquals("dn1", rs.getString("TABLE_NAME"));
// COLUMN_NAME
Assert.assertEquals("COLUMN_NAME", meta.getColumnLabel(4));
Assert.assertEquals("ts", rs.getString(4));
Assert.assertEquals("ts", rs.getString("COLUMN_NAME"));
// KEY_SEQ
Assert.assertEquals("KEY_SEQ", meta.getColumnLabel(5));
Assert.assertEquals(1, rs.getShort(5));
Assert.assertEquals(1, rs.getShort("KEY_SEQ"));
// DATA_TYPE
Assert.assertEquals("PK_NAME", meta.getColumnLabel(6));
Assert.assertEquals("ts", rs.getString(6));
Assert.assertEquals("ts", rs.getString("PK_NAME"));
} }
Assert.assertNotNull(rs);
} }
@Test @Test
...@@ -847,14 +966,27 @@ public class TSDBDatabaseMetaDataTest { ...@@ -847,14 +966,27 @@ public class TSDBDatabaseMetaDataTest {
@Test @Test
public void getSuperTables() throws SQLException { public void getSuperTables() throws SQLException {
System.out.println("****************************************************");
ResultSet rs = metaData.getSuperTables("log", "", "dn1"); ResultSet rs = metaData.getSuperTables("log", "", "dn1");
while (rs.next()) { ResultSetMetaData meta = rs.getMetaData();
System.out.println("TABLE_NAME: " + rs.getString("TABLE_NAME")); rs.next();
System.out.println("SUPERTABLE_NAME: " + rs.getString("SUPERTABLE_NAME")); {
// TABLE_CAT
Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1));
Assert.assertEquals("log", rs.getString(1));
Assert.assertEquals("log", rs.getString("TABLE_CAT"));
// TABLE_CAT
Assert.assertEquals("TABLE_SCHEM", meta.getColumnLabel(2));
Assert.assertEquals(null, rs.getString(2));
Assert.assertEquals(null, rs.getString("TABLE_SCHEM"));
// TABLE_CAT
Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3));
Assert.assertEquals("dn1", rs.getString(3));
Assert.assertEquals("dn1", rs.getString("TABLE_NAME"));
// TABLE_CAT
Assert.assertEquals("SUPERTABLE_NAME", meta.getColumnLabel(4));
Assert.assertEquals("dn", rs.getString(4));
Assert.assertEquals("dn", rs.getString("SUPERTABLE_NAME"));
} }
Assert.assertNotNull(rs);
} }
@Test @Test
...@@ -951,15 +1083,12 @@ public class TSDBDatabaseMetaDataTest { ...@@ -951,15 +1083,12 @@ public class TSDBDatabaseMetaDataTest {
@BeforeClass @BeforeClass
public static void beforeClass() { public static void beforeClass() {
try { try {
Class.forName("com.taosdata.jdbc.TSDBDriver");
Properties properties = new Properties(); Properties properties = new Properties();
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata", properties); connection = DriverManager.getConnection(url, properties);
metaData = connection.getMetaData().unwrap(TSDBDatabaseMetaData.class); metaData = connection.getMetaData().unwrap(TSDBDatabaseMetaData.class);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
......
...@@ -45,9 +45,9 @@ public class TSDBJNIConnectorTest { ...@@ -45,9 +45,9 @@ public class TSDBJNIConnectorTest {
rowData = new TSDBResultSetRowData(columnSize); rowData = new TSDBResultSetRowData(columnSize);
// iterate resultSet // iterate resultSet
for (int i = 0; next(connector, pSql); i++) { for (int i = 0; next(connector, pSql); i++) {
System.out.println("col[" + i + "] size: " + rowData.getColSize()); // System.out.println("col[" + i + "] size: " + rowData.getColSize());
rowData.getData().stream().forEach(col -> System.out.print(col + "\t")); // rowData.getData().stream().forEach(col -> System.out.print(col + "\t"));
System.out.println(); // System.out.println();
} }
// close resultSet // close resultSet
code = connector.freeResultSet(pSql); code = connector.freeResultSet(pSql);
......
...@@ -54,16 +54,17 @@ public class TSDBParameterMetaDataTest { ...@@ -54,16 +54,17 @@ public class TSDBParameterMetaDataTest {
@Test @Test
public void getPrecision() throws SQLException { public void getPrecision() throws SQLException {
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(1)); //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))
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(2)); Assert.assertEquals(TSDBConstants.TIMESTAMP_MS_PRECISION, parameterMetaData_insert.getPrecision(1));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(3)); Assert.assertEquals(TSDBConstants.INT_PRECISION, parameterMetaData_insert.getPrecision(2));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(4)); Assert.assertEquals(TSDBConstants.BIGINT_PRECISION, parameterMetaData_insert.getPrecision(3));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(5)); Assert.assertEquals(TSDBConstants.FLOAT_PRECISION, parameterMetaData_insert.getPrecision(4));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(6)); Assert.assertEquals(TSDBConstants.DOUBLE_PRECISION, parameterMetaData_insert.getPrecision(5));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(7)); Assert.assertEquals(TSDBConstants.SMALLINT_PRECISION, parameterMetaData_insert.getPrecision(6));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(8)); Assert.assertEquals(TSDBConstants.TINYINT_PRECISION, parameterMetaData_insert.getPrecision(7));
Assert.assertEquals(5, parameterMetaData_insert.getPrecision(9)); Assert.assertEquals(TSDBConstants.BOOLEAN_PRECISION, parameterMetaData_insert.getPrecision(8));
Assert.assertEquals(5, parameterMetaData_insert.getPrecision(10)); Assert.assertEquals("hello".getBytes().length, parameterMetaData_insert.getPrecision(9));
Assert.assertEquals("涛思数据".length(), parameterMetaData_insert.getPrecision(10));
} }
@Test @Test
...@@ -71,8 +72,8 @@ public class TSDBParameterMetaDataTest { ...@@ -71,8 +72,8 @@ public class TSDBParameterMetaDataTest {
Assert.assertEquals(0, parameterMetaData_insert.getScale(1)); Assert.assertEquals(0, parameterMetaData_insert.getScale(1));
Assert.assertEquals(0, parameterMetaData_insert.getScale(2)); Assert.assertEquals(0, parameterMetaData_insert.getScale(2));
Assert.assertEquals(0, parameterMetaData_insert.getScale(3)); Assert.assertEquals(0, parameterMetaData_insert.getScale(3));
Assert.assertEquals(0, parameterMetaData_insert.getScale(4)); Assert.assertEquals(31, parameterMetaData_insert.getScale(4));
Assert.assertEquals(0, parameterMetaData_insert.getScale(5)); Assert.assertEquals(31, parameterMetaData_insert.getScale(5));
Assert.assertEquals(0, parameterMetaData_insert.getScale(6)); Assert.assertEquals(0, parameterMetaData_insert.getScale(6));
Assert.assertEquals(0, parameterMetaData_insert.getScale(7)); Assert.assertEquals(0, parameterMetaData_insert.getScale(7));
Assert.assertEquals(0, parameterMetaData_insert.getScale(8)); Assert.assertEquals(0, parameterMetaData_insert.getScale(8));
...@@ -124,10 +125,16 @@ public class TSDBParameterMetaDataTest { ...@@ -124,10 +125,16 @@ public class TSDBParameterMetaDataTest {
@Test @Test
public void getParameterMode() throws SQLException { public void getParameterMode() throws SQLException {
for (int i = 1; i <= parameterMetaData_insert.getParameterCount(); i++) { Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(1));
int parameterMode = parameterMetaData_insert.getParameterMode(i); Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(2));
Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMode); Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(3));
} Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(4));
Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(5));
Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(6));
Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(7));
Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(8));
Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(9));
Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(10));
} }
@Test @Test
...@@ -144,7 +151,6 @@ public class TSDBParameterMetaDataTest { ...@@ -144,7 +151,6 @@ public class TSDBParameterMetaDataTest {
@BeforeClass @BeforeClass
public static void beforeClass() { public static void beforeClass() {
try { try {
Class.forName("com.taosdata.jdbc.TSDBDriver");
conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"); conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata");
try (Statement stmt = conn.createStatement()) { try (Statement stmt = conn.createStatement()) {
stmt.execute("drop database if exists test_pstmt"); stmt.execute("drop database if exists test_pstmt");
...@@ -164,7 +170,7 @@ public class TSDBParameterMetaDataTest { ...@@ -164,7 +170,7 @@ public class TSDBParameterMetaDataTest {
pstmt_insert.setObject(7, Byte.MAX_VALUE); pstmt_insert.setObject(7, Byte.MAX_VALUE);
pstmt_insert.setObject(8, true); pstmt_insert.setObject(8, true);
pstmt_insert.setObject(9, "hello".getBytes()); pstmt_insert.setObject(9, "hello".getBytes());
pstmt_insert.setObject(10, "Hello"); pstmt_insert.setObject(10, "涛思数据");
parameterMetaData_insert = pstmt_insert.getParameterMetaData(); parameterMetaData_insert = pstmt_insert.getParameterMetaData();
pstmt_select = conn.prepareStatement(sql_select); pstmt_select = conn.prepareStatement(sql_select);
...@@ -173,7 +179,7 @@ public class TSDBParameterMetaDataTest { ...@@ -173,7 +179,7 @@ public class TSDBParameterMetaDataTest {
pstmt_select.setInt(3, 0); pstmt_select.setInt(3, 0);
parameterMetaData_select = pstmt_select.getParameterMetaData(); parameterMetaData_select = pstmt_select.getParameterMetaData();
} catch (ClassNotFoundException | SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
......
package com.taosdata.jdbc; package com.taosdata.jdbc;
import org.junit.AfterClass; import org.junit.*;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.IOException; import java.io.IOException;
import java.io.Serializable; import java.math.BigDecimal;
import java.sql.*; import java.sql.*;
import java.util.ArrayList; import java.time.LocalTime;
import java.util.Random;
public class TSDBPreparedStatementTest { public class TSDBPreparedStatementTest {
private static final String host = "127.0.0.1"; private static final String host = "127.0.0.1";
private static Connection conn; private static Connection conn;
private static final String sql_insert = "insert into t1 values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; private static final String sql_insert = "insert into t1 values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
private static PreparedStatement pstmt_insert; private static final String sql_select = "select * from t1 where ts >= ? and ts < ? and f1 >= ?";
private static final String sql_select = "select * from t1 where ts > ? and ts <= ? and f1 >= ?";
private static PreparedStatement pstmt_select; private PreparedStatement pstmt_insert;
private PreparedStatement pstmt_select;
//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))
@Test @Test
public void executeQuery() throws SQLException { public void executeQuery() throws SQLException {
long end = System.currentTimeMillis(); // given
long start = end - 1000 * 60 * 60; long ts = System.currentTimeMillis();
pstmt_insert.setTimestamp(1, new Timestamp(ts));
pstmt_insert.setInt(2, 2);
pstmt_insert.setLong(3, 3l);
pstmt_insert.setFloat(4, 3.14f);
pstmt_insert.setDouble(5, 3.1415);
pstmt_insert.setShort(6, (short) 6);
pstmt_insert.setByte(7, (byte) 7);
pstmt_insert.setBoolean(8, true);
pstmt_insert.setBytes(9, "abc".getBytes());
pstmt_insert.setString(10, "涛思数据");
pstmt_insert.executeUpdate();
long start = ts - 1000 * 60 * 60;
long end = ts + 1000 * 60 * 60;
pstmt_select.setTimestamp(1, new Timestamp(start)); pstmt_select.setTimestamp(1, new Timestamp(start));
pstmt_select.setTimestamp(2, new Timestamp(end)); pstmt_select.setTimestamp(2, new Timestamp(end));
pstmt_select.setInt(3, 0); pstmt_select.setInt(3, 0);
// when
ResultSet rs = pstmt_select.executeQuery(); ResultSet rs = pstmt_select.executeQuery();
Assert.assertNotNull(rs);
ResultSetMetaData meta = rs.getMetaData(); ResultSetMetaData meta = rs.getMetaData();
while (rs.next()) { rs.next();
for (int i = 1; i <= meta.getColumnCount(); i++) {
System.out.print(meta.getColumnLabel(i) + ": " + rs.getString(i) + "\t"); // then
} assertMetaData(meta);
System.out.println(); {
Assert.assertNotNull(rs);
Assert.assertEquals(ts, rs.getTimestamp(1).getTime());
Assert.assertEquals(2, rs.getInt(2));
Assert.assertEquals(2, rs.getInt("f1"));
Assert.assertEquals(3l, rs.getLong(3));
Assert.assertEquals(3l, rs.getLong("f2"));
Assert.assertEquals(3.14f, rs.getFloat(4), 0.0);
Assert.assertEquals(3.14f, rs.getFloat("f3"), 0.0);
Assert.assertEquals(3.1415, rs.getDouble(5), 0.0);
Assert.assertEquals(3.1415, rs.getDouble("f4"), 0.0);
Assert.assertEquals((short) 6, rs.getShort(6));
Assert.assertEquals((short) 6, rs.getShort("f5"));
Assert.assertEquals((byte) 7, rs.getByte(7));
Assert.assertEquals((byte) 7, rs.getByte("f6"));
Assert.assertTrue(rs.getBoolean(8));
Assert.assertTrue(rs.getBoolean("f7"));
Assert.assertArrayEquals("abc".getBytes(), rs.getBytes(9));
Assert.assertArrayEquals("abc".getBytes(), rs.getBytes("f8"));
Assert.assertEquals("涛思数据", rs.getString(10));
Assert.assertEquals("涛思数据", rs.getString("f9"));
} }
} }
@Test private void assertMetaData(ResultSetMetaData meta) throws SQLException {
public void executeUpdate() throws SQLException { Assert.assertEquals(10, meta.getColumnCount());
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); Assert.assertEquals("ts", meta.getColumnLabel(1));
pstmt_insert.setFloat(4, 3.14f); Assert.assertEquals("f1", meta.getColumnLabel(2));
int result = pstmt_insert.executeUpdate(); Assert.assertEquals("f2", meta.getColumnLabel(3));
Assert.assertEquals(1, result); Assert.assertEquals("f3", meta.getColumnLabel(4));
Assert.assertEquals("f4", meta.getColumnLabel(5));
Assert.assertEquals("f5", meta.getColumnLabel(6));
Assert.assertEquals("f6", meta.getColumnLabel(7));
Assert.assertEquals("f7", meta.getColumnLabel(8));
Assert.assertEquals("f8", meta.getColumnLabel(9));
Assert.assertEquals("f9", meta.getColumnLabel(10));
} }
@Test @Test
public void setNull() throws SQLException { public void setNullForTimestamp() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); // given
long ts = System.currentTimeMillis();
// when
pstmt_insert.setTimestamp(1, new Timestamp(ts));
pstmt_insert.setNull(2, Types.INTEGER); pstmt_insert.setNull(2, Types.INTEGER);
int result = pstmt_insert.executeUpdate(); int result = pstmt_insert.executeUpdate();
// then
Assert.assertEquals(1, result); Assert.assertEquals(1, result);
try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from t1");
ResultSetMetaData meta = rs.getMetaData();
assertMetaData(meta);
rs.next();
assertAllNullExceptTimestamp(rs, ts);
}
}
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); private void assertAllNullExceptTimestamp(ResultSet rs, long ts) throws SQLException {
Assert.assertNotNull(rs);
Assert.assertEquals(ts, rs.getTimestamp(1).getTime());
Assert.assertEquals(0, rs.getInt(2));
Assert.assertEquals(0, rs.getInt("f1"));
Assert.assertEquals(0, rs.getLong(3));
Assert.assertEquals(0, rs.getLong("f2"));
Assert.assertEquals(0, rs.getFloat(4), 0.0);
Assert.assertEquals(0, rs.getFloat("f3"), 0.0);
Assert.assertEquals(0, rs.getDouble(5), 0.0);
Assert.assertEquals(0, rs.getDouble("f4"), 0.0);
Assert.assertEquals(0, rs.getShort(6));
Assert.assertEquals(0, rs.getShort("f5"));
Assert.assertEquals(0, rs.getByte(7));
Assert.assertEquals(0, rs.getByte("f6"));
Assert.assertFalse(rs.getBoolean(8));
Assert.assertFalse(rs.getBoolean("f7"));
Assert.assertNull(rs.getBytes(9));
Assert.assertNull(rs.getBytes("f8"));
Assert.assertNull(rs.getString(10));
Assert.assertNull(rs.getString("f9"));
}
@Test
public void setNullForInteger() throws SQLException {
// given
long ts = System.currentTimeMillis();
// when
pstmt_insert.setTimestamp(1, new Timestamp(ts));
pstmt_insert.setNull(3, Types.BIGINT); pstmt_insert.setNull(3, Types.BIGINT);
result = pstmt_insert.executeUpdate(); int result = pstmt_insert.executeUpdate();
// then
Assert.assertEquals(1, result); Assert.assertEquals(1, result);
try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from t1");
ResultSetMetaData meta = rs.getMetaData();
assertMetaData(meta);
rs.next();
assertAllNullExceptTimestamp(rs, ts);
}
}
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); @Test
public void setNullForFloat() throws SQLException {
// given
long ts = System.currentTimeMillis();
// when
pstmt_insert.setTimestamp(1, new Timestamp(ts));
pstmt_insert.setNull(4, Types.FLOAT); pstmt_insert.setNull(4, Types.FLOAT);
result = pstmt_insert.executeUpdate(); int result = pstmt_insert.executeUpdate();
Assert.assertEquals(1, result);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); // then
pstmt_insert.setNull(5, Types.DOUBLE);
result = pstmt_insert.executeUpdate();
Assert.assertEquals(1, result); Assert.assertEquals(1, result);
try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from t1");
ResultSetMetaData meta = rs.getMetaData();
assertMetaData(meta);
rs.next();
assertAllNullExceptTimestamp(rs, ts);
}
}
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); @Test
pstmt_insert.setNull(6, Types.SMALLINT); public void setNullForDouble() throws SQLException {
result = pstmt_insert.executeUpdate(); // given
Assert.assertEquals(1, result); long ts = System.currentTimeMillis();
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); // when
pstmt_insert.setNull(7, Types.TINYINT); pstmt_insert.setTimestamp(1, new Timestamp(ts));
result = pstmt_insert.executeUpdate(); pstmt_insert.setNull(5, Types.DOUBLE);
Assert.assertEquals(1, result); int result = pstmt_insert.executeUpdate();
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); // then
pstmt_insert.setNull(8, Types.BOOLEAN);
result = pstmt_insert.executeUpdate();
Assert.assertEquals(1, result); Assert.assertEquals(1, result);
try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from t1");
ResultSetMetaData meta = rs.getMetaData();
assertMetaData(meta);
rs.next();
assertAllNullExceptTimestamp(rs, ts);
}
}
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); @Test
pstmt_insert.setNull(9, Types.BINARY); public void setNullForSmallInt() throws SQLException {
result = pstmt_insert.executeUpdate(); // given
Assert.assertEquals(1, result); long ts = System.currentTimeMillis();
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); // when
pstmt_insert.setNull(10, Types.NCHAR); pstmt_insert.setTimestamp(1, new Timestamp(ts));
result = pstmt_insert.executeUpdate(); pstmt_insert.setNull(6, Types.SMALLINT);
Assert.assertEquals(1, result); int result = pstmt_insert.executeUpdate();
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); // then
pstmt_insert.setNull(10, Types.OTHER);
result = pstmt_insert.executeUpdate();
Assert.assertEquals(1, result); Assert.assertEquals(1, result);
try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from t1");
ResultSetMetaData meta = rs.getMetaData();
assertMetaData(meta);
rs.next();
assertAllNullExceptTimestamp(rs, ts);
}
} }
@Test @Test
public void executeTest() throws SQLException { public void setNullForTinyInt() throws SQLException {
Statement stmt = conn.createStatement(); // given
long ts = System.currentTimeMillis();
int numOfRows = 1000;
// when
for (int loop = 0; loop < 10; loop++){ pstmt_insert.setTimestamp(1, new Timestamp(ts));
stmt.execute("drop table if exists weather_test"); pstmt_insert.setNull(7, Types.TINYINT);
stmt.execute("create table weather_test(ts timestamp, f1 nchar(4), f2 float, f3 double, f4 timestamp, f5 int, f6 bool, f7 binary(10))"); int result = pstmt_insert.executeUpdate();
TSDBPreparedStatement s = (TSDBPreparedStatement) conn.prepareStatement("insert into ? values(?, ?, ?, ?, ?, ?, ?, ?)"); // then
Random r = new Random(); Assert.assertEquals(1, result);
s.setTableName("weather_test"); try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from t1");
ArrayList<Long> ts = new ArrayList<Long>(); ResultSetMetaData meta = rs.getMetaData();
for(int i = 0; i < numOfRows; i++) { assertMetaData(meta);
ts.add(System.currentTimeMillis() + i); rs.next();
} assertAllNullExceptTimestamp(rs, ts);
s.setTimestamp(0, ts);
int random = 10 + r.nextInt(5);
ArrayList<String> s2 = new ArrayList<String>();
for(int i = 0; i < numOfRows; i++) {
if(i % random == 0) {
s2.add(null);
}else{
s2.add("分支" + i % 4);
}
}
s.setNString(1, s2, 4);
random = 10 + r.nextInt(5);
ArrayList<Float> s3 = new ArrayList<Float>();
for(int i = 0; i < numOfRows; i++) {
if(i % random == 0) {
s3.add(null);
}else{
s3.add(r.nextFloat());
}
}
s.setFloat(2, s3);
random = 10 + r.nextInt(5);
ArrayList<Double> s4 = new ArrayList<Double>();
for(int i = 0; i < numOfRows; i++) {
if(i % random == 0) {
s4.add(null);
}else{
s4.add(r.nextDouble());
}
}
s.setDouble(3, s4);
random = 10 + r.nextInt(5);
ArrayList<Long> ts2 = new ArrayList<Long>();
for(int i = 0; i < numOfRows; i++) {
if(i % random == 0) {
ts2.add(null);
}else{
ts2.add(System.currentTimeMillis() + i);
}
}
s.setTimestamp(4, ts2);
random = 10 + r.nextInt(5);
ArrayList<Integer> vals = new ArrayList<>();
for(int i = 0; i < numOfRows; i++) {
if(i % random == 0) {
vals.add(null);
}else{
vals.add(r.nextInt());
}
}
s.setInt(5, vals);
random = 10 + r.nextInt(5);
ArrayList<Boolean> sb = new ArrayList<>();
for(int i = 0; i < numOfRows; i++) {
if(i % random == 0) {
sb.add(null);
}else{
sb.add(i % 2 == 0 ? true : false);
}
}
s.setBoolean(6, sb);
random = 10 + r.nextInt(5);
ArrayList<String> s5 = new ArrayList<String>();
for(int i = 0; i < numOfRows; i++) {
if(i % random == 0) {
s5.add(null);
}else{
s5.add("test" + i % 10);
}
}
s.setString(7, s5, 10);
s.columnDataAddBatch();
s.columnDataExecuteBatch();
s.columnDataCloseBatch();
String sql = "select * from weather_test";
PreparedStatement statement = conn.prepareStatement(sql);
ResultSet rs = statement.executeQuery();
int rows = 0;
while(rs.next()) {
rows++;
}
Assert.assertEquals(numOfRows, rows);
} }
} }
@Test @Test
public void bindDataSelectColumnTest() throws SQLException { public void setNullForBoolean() throws SQLException {
Statement stmt = conn.createStatement(); // given
long ts = System.currentTimeMillis();
int numOfRows = 1000;
// when
for (int loop = 0; loop < 10; loop++){ pstmt_insert.setTimestamp(1, new Timestamp(ts));
stmt.execute("drop table if exists weather_test"); pstmt_insert.setNull(8, Types.BOOLEAN);
stmt.execute("create table weather_test(ts timestamp, f1 nchar(4), f2 float, f3 double, f4 timestamp, f5 int, f6 bool, f7 binary(10))"); int result = pstmt_insert.executeUpdate();
TSDBPreparedStatement s = (TSDBPreparedStatement) conn.prepareStatement("insert into ? (ts, f1, f7) values(?, ?, ?)"); // then
Random r = new Random(); Assert.assertEquals(1, result);
s.setTableName("weather_test"); try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from t1");
ArrayList<Long> ts = new ArrayList<Long>(); ResultSetMetaData meta = rs.getMetaData();
for(int i = 0; i < numOfRows; i++) { assertMetaData(meta);
ts.add(System.currentTimeMillis() + i); rs.next();
} assertAllNullExceptTimestamp(rs, ts);
s.setTimestamp(0, ts);
int random = 10 + r.nextInt(5);
ArrayList<String> s2 = new ArrayList<String>();
for(int i = 0; i < numOfRows; i++) {
if(i % random == 0) {
s2.add(null);
}else{
s2.add("分支" + i % 4);
}
}
s.setNString(1, s2, 4);
random = 10 + r.nextInt(5);
ArrayList<String> s3 = new ArrayList<String>();
for(int i = 0; i < numOfRows; i++) {
if(i % random == 0) {
s3.add(null);
}else{
s3.add("test" + i % 10);
}
}
s.setString(2, s3, 10);
s.columnDataAddBatch();
s.columnDataExecuteBatch();
s.columnDataCloseBatch();
String sql = "select * from weather_test";
PreparedStatement statement = conn.prepareStatement(sql);
ResultSet rs = statement.executeQuery();
int rows = 0;
while(rs.next()) {
rows++;
}
Assert.assertEquals(numOfRows, rows);
} }
} }
@Test @Test
public void bindDataWithSingleTagTest() throws SQLException { public void setNullForBinary() throws SQLException {
Statement stmt = conn.createStatement(); // given
long ts = System.currentTimeMillis();
String types[] = new String[] {"tinyint", "smallint", "int", "bigint", "bool", "float", "double", "binary(10)", "nchar(10)"}; // when
pstmt_insert.setTimestamp(1, new Timestamp(ts));
for (String type : types) { pstmt_insert.setNull(9, Types.BINARY);
stmt.execute("drop table if exists weather_test"); int result = pstmt_insert.executeUpdate();
stmt.execute("create table weather_test(ts timestamp, f1 nchar(10), f2 binary(10)) tags (t " + type + ")");
int numOfRows = 1; // then
Assert.assertEquals(1, result);
TSDBPreparedStatement s = (TSDBPreparedStatement) conn.prepareStatement("insert into ? using weather_test tags(?) values(?, ?, ?)"); try (Statement stmt = conn.createStatement()) {
Random r = new Random(); ResultSet rs = stmt.executeQuery("select * from t1");
s.setTableName("w1"); ResultSetMetaData meta = rs.getMetaData();
assertMetaData(meta);
switch(type) { rs.next();
case "tinyint": assertAllNullExceptTimestamp(rs, ts);
case "smallint":
case "int":
case "bigint":
s.setTagInt(0, 1);
break;
case "float":
s.setTagFloat(0, 1.23f);
break;
case "double":
s.setTagDouble(0, 3.14159265);
break;
case "bool":
s.setTagBoolean(0, true);
break;
case "binary(10)":
s.setTagString(0, "test");
break;
case "nchar(10)":
s.setTagNString(0, "test");
break;
default:
break;
}
ArrayList<Long> ts = new ArrayList<Long>();
for(int i = 0; i < numOfRows; i++) {
ts.add(System.currentTimeMillis() + i);
}
s.setTimestamp(0, ts);
int random = 10 + r.nextInt(5);
ArrayList<String> s2 = new ArrayList<String>();
for(int i = 0; i < numOfRows; i++) {
s2.add("分支" + i % 4);
}
s.setNString(1, s2, 10);
random = 10 + r.nextInt(5);
ArrayList<String> s3 = new ArrayList<String>();
for(int i = 0; i < numOfRows; i++) {
s3.add("test" + i % 4);
}
s.setString(2, s3, 10);
s.columnDataAddBatch();
s.columnDataExecuteBatch();
s.columnDataCloseBatch();
String sql = "select * from weather_test";
PreparedStatement statement = conn.prepareStatement(sql);
ResultSet rs = statement.executeQuery();
int rows = 0;
while(rs.next()) {
rows++;
}
Assert.assertEquals(numOfRows, rows);
} }
} }
@Test @Test
public void bindDataWithMultipleTagsTest() throws SQLException { public void setNullForNchar() throws SQLException {
Statement stmt = conn.createStatement(); // given
long ts = System.currentTimeMillis();
stmt.execute("drop table if exists weather_test");
stmt.execute("create table weather_test(ts timestamp, f1 nchar(10), f2 binary(10)) tags (t1 int, t2 binary(10))"); // when
pstmt_insert.setTimestamp(1, new Timestamp(ts));
int numOfRows = 1; pstmt_insert.setNull(10, Types.NCHAR);
int result = pstmt_insert.executeUpdate();
TSDBPreparedStatement s = (TSDBPreparedStatement) conn.prepareStatement("insert into ? using weather_test tags(?,?) (ts, f2) values(?, ?)");
s.setTableName("w2"); // then
s.setTagInt(0, 1); Assert.assertEquals(1, result);
s.setTagString(1, "test"); try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from t1");
ResultSetMetaData meta = rs.getMetaData();
ArrayList<Long> ts = new ArrayList<Long>(); assertMetaData(meta);
for(int i = 0; i < numOfRows; i++) { rs.next();
ts.add(System.currentTimeMillis() + i); assertAllNullExceptTimestamp(rs, ts);
}
s.setTimestamp(0, ts);
ArrayList<String> s2 = new ArrayList<String>();
for(int i = 0; i < numOfRows; i++) {
s2.add("test" + i % 4);
} }
s.setString(1, s2, 10); }
s.columnDataAddBatch(); @Test
s.columnDataExecuteBatch(); public void createTwoSameDbTest() throws SQLException {
s.columnDataCloseBatch(); Statement stmt = conn.createStatement();
String sql = "select * from weather_test"; stmt.execute("create database dbtest");
PreparedStatement statement = conn.prepareStatement(sql); Assert.assertThrows(SQLException.class, () -> stmt.execute("create database dbtest"));
ResultSet rs = statement.executeQuery();
int rows = 0;
while(rs.next()) {
rows++;
}
Assert.assertEquals(numOfRows, rows);
} }
@Test @Test
public void setBoolean() throws SQLException { public void setBoolean() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); // given
long ts = System.currentTimeMillis();
// when
pstmt_insert.setTimestamp(1, new Timestamp(ts));
pstmt_insert.setBoolean(8, true); pstmt_insert.setBoolean(8, true);
int ret = pstmt_insert.executeUpdate(); int result = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
// then
Assert.assertEquals(1, result);
try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from t1");
ResultSetMetaData meta = rs.getMetaData();
assertMetaData(meta);
rs.next();
{
Assert.assertNotNull(rs);
Assert.assertEquals(ts, rs.getTimestamp(1).getTime());
Assert.assertEquals(ts, rs.getTimestamp("ts").getTime());
Assert.assertTrue(rs.getBoolean(8));
Assert.assertTrue(rs.getBoolean("f7"));
}
}
} }
@Test @Test
public void setByte() throws SQLException { public void setByte() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); // given
long ts = System.currentTimeMillis();
// when
pstmt_insert.setTimestamp(1, new Timestamp(ts));
pstmt_insert.setByte(7, (byte) 0x001); pstmt_insert.setByte(7, (byte) 0x001);
int ret = pstmt_insert.executeUpdate(); int result = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
// then
Assert.assertEquals(1, result);
try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from t1");
ResultSetMetaData meta = rs.getMetaData();
assertMetaData(meta);
rs.next();
{
Assert.assertNotNull(rs);
Assert.assertEquals(ts, rs.getTimestamp(1).getTime());
Assert.assertEquals(ts, rs.getTimestamp("ts").getTime());
Assert.assertEquals((byte) 0x001, rs.getByte(7));
Assert.assertEquals((byte) 0x001, rs.getByte("f6"));
}
}
} }
@Test @Test
public void setShort() throws SQLException { public void setShort() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); // given
long ts = System.currentTimeMillis();
// when
pstmt_insert.setTimestamp(1, new Timestamp(ts));
pstmt_insert.setShort(6, (short) 2); pstmt_insert.setShort(6, (short) 2);
int ret = pstmt_insert.executeUpdate(); int result = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
// then
Assert.assertEquals(1, result);
try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from t1");
ResultSetMetaData meta = rs.getMetaData();
assertMetaData(meta);
rs.next();
{
Assert.assertNotNull(rs);
Assert.assertEquals(ts, rs.getTimestamp(1).getTime());
Assert.assertEquals(ts, rs.getTimestamp("ts").getTime());
Assert.assertEquals((short) 2, rs.getByte(6));
Assert.assertEquals((short) 2, rs.getByte("f5"));
}
}
} }
@Test @Test
public void setInt() throws SQLException { public void setInt() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); // given
long ts = System.currentTimeMillis();
// when
pstmt_insert.setTimestamp(1, new Timestamp(ts));
pstmt_insert.setInt(2, 10086); pstmt_insert.setInt(2, 10086);
int ret = pstmt_insert.executeUpdate(); int result = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
// then
Assert.assertEquals(1, result);
try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from t1");
ResultSetMetaData meta = rs.getMetaData();
assertMetaData(meta);
rs.next();
{
Assert.assertNotNull(rs);
Assert.assertEquals(ts, rs.getTimestamp(1).getTime());
Assert.assertEquals(ts, rs.getTimestamp("ts").getTime());
Assert.assertEquals(10086, rs.getInt(2));
Assert.assertEquals(10086, rs.getInt("f1"));
}
}
} }
@Test @Test
public void setLong() throws SQLException { public void setLong() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); // given
long ts = System.currentTimeMillis();
// when
pstmt_insert.setTimestamp(1, new Timestamp(ts));
pstmt_insert.setLong(3, Long.MAX_VALUE); pstmt_insert.setLong(3, Long.MAX_VALUE);
int ret = pstmt_insert.executeUpdate(); int result = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
// then
Assert.assertEquals(1, result);
try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from t1");
ResultSetMetaData meta = rs.getMetaData();
assertMetaData(meta);
rs.next();
{
Assert.assertNotNull(rs);
Assert.assertEquals(ts, rs.getTimestamp(1).getTime());
Assert.assertEquals(ts, rs.getTimestamp("ts").getTime());
Assert.assertEquals(Long.MAX_VALUE, rs.getLong(3));
Assert.assertEquals(Long.MAX_VALUE, rs.getLong("f2"));
}
}
} }
@Test @Test
public void setFloat() throws SQLException { public void setFloat() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); // given
long ts = System.currentTimeMillis();
// when
pstmt_insert.setTimestamp(1, new Timestamp(ts));
pstmt_insert.setFloat(4, 3.14f); pstmt_insert.setFloat(4, 3.14f);
int ret = pstmt_insert.executeUpdate(); int result = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
// then
Assert.assertEquals(1, result);
try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from t1");
ResultSetMetaData meta = rs.getMetaData();
assertMetaData(meta);
rs.next();
{
Assert.assertNotNull(rs);
Assert.assertEquals(ts, rs.getTimestamp(1).getTime());
Assert.assertEquals(ts, rs.getTimestamp("ts").getTime());
Assert.assertEquals(3.14f, rs.getFloat(4), 0.0f);
Assert.assertEquals(3.14f, rs.getFloat("f3"), 0.0f);
}
}
} }
@Test @Test
public void setDouble() throws SQLException { public void setDouble() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); // given
long ts = System.currentTimeMillis();
// when
pstmt_insert.setTimestamp(1, new Timestamp(ts));
pstmt_insert.setDouble(5, 3.14444); pstmt_insert.setDouble(5, 3.14444);
int ret = pstmt_insert.executeUpdate(); int result = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
}
@Test(expected = SQLFeatureNotSupportedException.class) // then
public void setBigDecimal() throws SQLException { Assert.assertEquals(1, result);
pstmt_insert.setBigDecimal(1, null); try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from t1");
ResultSetMetaData meta = rs.getMetaData();
assertMetaData(meta);
rs.next();
{
Assert.assertNotNull(rs);
Assert.assertEquals(ts, rs.getTimestamp(1).getTime());
Assert.assertEquals(ts, rs.getTimestamp("ts").getTime());
Assert.assertEquals(3.14444, rs.getDouble(5), 0.0);
Assert.assertEquals(3.14444, rs.getDouble("f4"), 0.0);
}
}
} }
@Test @Test
public void setString() throws SQLException { public void setBigDecimal() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); // given
pstmt_insert.setString(10, "aaaa"); long ts = System.currentTimeMillis();
boolean execute = pstmt_insert.execute(); BigDecimal bigDecimal = new BigDecimal(3.14444);
Assert.assertFalse(execute);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); // when
pstmt_insert.setString(10, new Person("john", 33, true).toString()); pstmt_insert.setTimestamp(1, new Timestamp(ts));
Assert.assertFalse(pstmt_insert.execute()); pstmt_insert.setBigDecimal(5, bigDecimal);
int result = pstmt_insert.executeUpdate();
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); // then
pstmt_insert.setString(10, new Person("john", 33, true).toString().replaceAll("'", "\"")); Assert.assertEquals(1, result);
Assert.assertFalse(pstmt_insert.execute()); try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from t1");
ResultSetMetaData meta = rs.getMetaData();
assertMetaData(meta);
rs.next();
{
Assert.assertNotNull(rs);
Assert.assertEquals(ts, rs.getTimestamp(1).getTime());
Assert.assertEquals(ts, rs.getTimestamp("ts").getTime());
Assert.assertEquals(3.14444, rs.getDouble(5), 0.0);
Assert.assertEquals(3.14444, rs.getDouble("f4"), 0.0);
}
}
} }
class Person { @Test
String name; public void setString() throws SQLException {
int age; // given
boolean sex; long ts = System.currentTimeMillis();
String f9 = "{\"name\": \"john\", \"age\": 10, \"address\": \"192.168.1.100\"}";
public Person(String name, int age, boolean sex) { // when
this.name = name; pstmt_insert.setTimestamp(1, new Timestamp(ts));
this.age = age; pstmt_insert.setString(10, f9);
this.sex = sex; int result = pstmt_insert.executeUpdate();
}
@Override // then
public String toString() { Assert.assertEquals(1, result);
return "Person{" + try (Statement stmt = conn.createStatement()) {
"name='" + name + '\'' + ResultSet rs = stmt.executeQuery("select * from t1");
", age=" + age + ResultSetMetaData meta = rs.getMetaData();
", sex=" + sex + assertMetaData(meta);
'}'; rs.next();
{
Assert.assertNotNull(rs);
Assert.assertEquals(ts, rs.getTimestamp(1).getTime());
Assert.assertEquals(ts, rs.getTimestamp("ts").getTime());
Assert.assertEquals(f9, rs.getString(10));
Assert.assertEquals(f9, rs.getString("f9"));
}
} }
} }
@Test @Test
public void setBytes() throws SQLException, IOException { public void setBytes() throws SQLException, IOException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); // given
long ts = System.currentTimeMillis();
byte[] f8 = "{\"name\": \"john\", \"age\": 10, \"address\": \"192.168.1.100\"}".getBytes();
// ByteArrayOutputStream baos = new ByteArrayOutputStream(); // when
// ObjectOutputStream oos = new ObjectOutputStream(baos); pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
// oos.writeObject(new Person("john", 33, true)); pstmt_insert.setBytes(9, f8);
// oos.flush(); int result = pstmt_insert.executeUpdate();
// byte[] bytes = baos.toByteArray();
// pstmt_insert.setBytes(9, bytes);
pstmt_insert.setBytes(9, new Person("john", 33, true).toString().getBytes()); // then
int ret = pstmt_insert.executeUpdate(); Assert.assertEquals(1, result);
Assert.assertEquals(1, ret); try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from t1");
ResultSetMetaData meta = rs.getMetaData();
assertMetaData(meta);
rs.next();
{
Assert.assertNotNull(rs);
Assert.assertEquals(ts, rs.getTimestamp(1).getTime());
Assert.assertEquals(ts, rs.getTimestamp("ts").getTime());
Assert.assertArrayEquals(f8, rs.getBytes(9));
Assert.assertArrayEquals(f8, rs.getBytes("f8"));
}
}
} }
@Test(expected = SQLFeatureNotSupportedException.class) @Test
public void setDate() throws SQLException { public void setDate() throws SQLException {
pstmt_insert.setDate(1, new Date(System.currentTimeMillis())); // given
long ts = new java.util.Date().getTime();
// when
pstmt_insert.setDate(1, new Date(ts));
int result = pstmt_insert.executeUpdate();
// then
Assert.assertEquals(1, result);
try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from t1");
ResultSetMetaData meta = rs.getMetaData();
assertMetaData(meta);
rs.next();
{
Assert.assertNotNull(rs);
Assert.assertEquals(ts, rs.getTimestamp(1).getTime());
Assert.assertEquals(ts, rs.getTimestamp("ts").getTime());
}
}
} }
@Test(expected = SQLFeatureNotSupportedException.class) @Test
public void setTime() throws SQLException { public void setTime() throws SQLException {
pstmt_insert.setTime(1, new Time(System.currentTimeMillis())); // given
long ts = System.currentTimeMillis();
// when
pstmt_insert.setTime(1, new Time(ts));
int result = pstmt_insert.executeUpdate();
// then
Assert.assertEquals(1, result);
try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from t1");
ResultSetMetaData meta = rs.getMetaData();
assertMetaData(meta);
rs.next();
{
Assert.assertNotNull(rs);
Assert.assertEquals(ts, rs.getTimestamp(1).getTime());
Assert.assertEquals(ts, rs.getTimestamp("ts").getTime());
}
}
} }
@Test @Test
public void setTimestamp() throws SQLException { public void setTimestamp() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); // given
int ret = pstmt_insert.executeUpdate(); long ts = System.currentTimeMillis();
Assert.assertEquals(1, ret);
// when
pstmt_insert.setTimestamp(1, new Timestamp(ts));
int result = pstmt_insert.executeUpdate();
// then
Assert.assertEquals(1, result);
try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from t1");
ResultSetMetaData meta = rs.getMetaData();
assertMetaData(meta);
rs.next();
{
Assert.assertNotNull(rs);
Assert.assertEquals(ts, rs.getTimestamp(1).getTime());
Assert.assertEquals(ts, rs.getTimestamp("ts").getTime());
}
}
} }
@Test(expected = SQLFeatureNotSupportedException.class) @Test(expected = SQLFeatureNotSupportedException.class)
...@@ -530,72 +659,6 @@ public class TSDBPreparedStatementTest { ...@@ -530,72 +659,6 @@ public class TSDBPreparedStatementTest {
pstmt_insert.setBinaryStream(1, null); pstmt_insert.setBinaryStream(1, null);
} }
@Test
public void clearParameters() throws SQLException {
pstmt_insert.clearParameters();
}
@Test
public void setObject() throws SQLException {
pstmt_insert.setObject(1, new Timestamp(System.currentTimeMillis()));
int ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(2, 111);
ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(3, Long.MAX_VALUE);
ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(4, 3.14159265354f);
ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(5, Double.MAX_VALUE);
ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(6, Short.MAX_VALUE);
ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(7, Byte.MAX_VALUE);
ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(8, true);
ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(9, "hello".getBytes());
ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(10, "Hello");
ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
}
@Test
public void execute() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
int ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
executeQuery();
}
@Test(expected = SQLFeatureNotSupportedException.class) @Test(expected = SQLFeatureNotSupportedException.class)
public void setCharacterStream() throws SQLException { public void setCharacterStream() throws SQLException {
pstmt_insert.setCharacterStream(1, null); pstmt_insert.setCharacterStream(1, null);
...@@ -621,9 +684,17 @@ public class TSDBPreparedStatementTest { ...@@ -621,9 +684,17 @@ public class TSDBPreparedStatementTest {
pstmt_insert.setArray(1, null); pstmt_insert.setArray(1, null);
} }
@Test(expected = SQLFeatureNotSupportedException.class) @Test
public void getMetaData() throws SQLException { public void getMetaData() throws SQLException {
pstmt_insert.getMetaData(); // given
long ts = System.currentTimeMillis();
// when
pstmt_insert.setTimestamp(1, new Timestamp(ts));
ResultSetMetaData metaData = pstmt_insert.getMetaData();
// then
Assert.assertNull(metaData);
} }
@Test(expected = SQLFeatureNotSupportedException.class) @Test(expected = SQLFeatureNotSupportedException.class)
...@@ -633,9 +704,46 @@ public class TSDBPreparedStatementTest { ...@@ -633,9 +704,46 @@ public class TSDBPreparedStatementTest {
@Test @Test
public void getParameterMetaData() throws SQLException { public void getParameterMetaData() throws SQLException {
// given
long ts = System.currentTimeMillis();
pstmt_insert.setTimestamp(1, new Timestamp(ts));
pstmt_insert.setInt(2, 2);
pstmt_insert.setLong(3, 3l);
pstmt_insert.setFloat(4, 3.14f);
pstmt_insert.setDouble(5, 3.1415);
pstmt_insert.setShort(6, (short) 6);
pstmt_insert.setByte(7, (byte) 7);
pstmt_insert.setBoolean(8, true);
pstmt_insert.setBytes(9, "abc".getBytes());
pstmt_insert.setString(10, "涛思数据");
// when
ParameterMetaData parameterMetaData = pstmt_insert.getParameterMetaData(); ParameterMetaData parameterMetaData = pstmt_insert.getParameterMetaData();
// then
Assert.assertNotNull(parameterMetaData); Assert.assertNotNull(parameterMetaData);
//TODO: modify the test case Assert.assertEquals(10, parameterMetaData.getParameterCount());
Assert.assertEquals(Types.TIMESTAMP, parameterMetaData.getParameterType(1));
Assert.assertEquals(Types.INTEGER, parameterMetaData.getParameterType(2));
Assert.assertEquals(Types.BIGINT, parameterMetaData.getParameterType(3));
Assert.assertEquals(Types.FLOAT, parameterMetaData.getParameterType(4));
Assert.assertEquals(Types.DOUBLE, parameterMetaData.getParameterType(5));
Assert.assertEquals(Types.SMALLINT, parameterMetaData.getParameterType(6));
Assert.assertEquals(Types.TINYINT, parameterMetaData.getParameterType(7));
Assert.assertEquals(Types.BOOLEAN, parameterMetaData.getParameterType(8));
Assert.assertEquals(Types.BINARY, parameterMetaData.getParameterType(9));
Assert.assertEquals(Types.NCHAR, parameterMetaData.getParameterType(10));
Assert.assertEquals("TIMESTAMP", parameterMetaData.getParameterTypeName(1));
Assert.assertEquals("INT", parameterMetaData.getParameterTypeName(2));
Assert.assertEquals("BIGINT", parameterMetaData.getParameterTypeName(3));
Assert.assertEquals("FLOAT", parameterMetaData.getParameterTypeName(4));
Assert.assertEquals("DOUBLE", parameterMetaData.getParameterTypeName(5));
Assert.assertEquals("SMALLINT", parameterMetaData.getParameterTypeName(6));
Assert.assertEquals("TINYINT", parameterMetaData.getParameterTypeName(7));
Assert.assertEquals("BOOL", parameterMetaData.getParameterTypeName(8));
Assert.assertEquals("BINARY", parameterMetaData.getParameterTypeName(9));
Assert.assertEquals("NCHAR", parameterMetaData.getParameterTypeName(10));
} }
@Test(expected = SQLFeatureNotSupportedException.class) @Test(expected = SQLFeatureNotSupportedException.class)
...@@ -643,9 +751,9 @@ public class TSDBPreparedStatementTest { ...@@ -643,9 +751,9 @@ public class TSDBPreparedStatementTest {
pstmt_insert.setRowId(1, null); pstmt_insert.setRowId(1, null);
} }
@Test(expected = SQLFeatureNotSupportedException.class) @Test
public void setNString() throws SQLException { public void setNString() throws SQLException {
pstmt_insert.setNString(1, null); setString();
} }
@Test(expected = SQLFeatureNotSupportedException.class) @Test(expected = SQLFeatureNotSupportedException.class)
...@@ -663,22 +771,45 @@ public class TSDBPreparedStatementTest { ...@@ -663,22 +771,45 @@ public class TSDBPreparedStatementTest {
pstmt_insert.setSQLXML(1, null); pstmt_insert.setSQLXML(1, null);
} }
@Before
public void before() {
try {
Statement stmt = conn.createStatement();
stmt.execute("drop table if exists weather");
stmt.execute("create table if not exists 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 if not exists t1 using weather tags('beijing')");
stmt.close();
pstmt_insert = conn.prepareStatement(sql_insert);
pstmt_select = conn.prepareStatement(sql_select);
} catch (SQLException e) {
e.printStackTrace();
}
}
@After
public void after() {
try {
if (pstmt_insert != null)
pstmt_insert.close();
if (pstmt_select != null)
pstmt_select.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
@BeforeClass @BeforeClass
public static void beforeClass() { public static void beforeClass() {
try { try {
Class.forName("com.taosdata.jdbc.TSDBDriver");
conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"); conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata");
try (Statement stmt = conn.createStatement()) { try (Statement stmt = conn.createStatement()) {
stmt.execute("drop database if exists test_pstmt_jni"); stmt.execute("drop database if exists test_pstmt_jni");
stmt.execute("create database if not exists test_pstmt_jni"); stmt.execute("create database if not exists test_pstmt_jni");
stmt.execute("use test_pstmt_jni"); stmt.execute("use test_pstmt_jni");
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); } catch (SQLException e) {
pstmt_select = conn.prepareStatement(sql_select);
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
...@@ -686,10 +817,6 @@ public class TSDBPreparedStatementTest { ...@@ -686,10 +817,6 @@ public class TSDBPreparedStatementTest {
@AfterClass @AfterClass
public static void afterClass() { public static void afterClass() {
try { try {
if (pstmt_insert != null)
pstmt_insert.close();
if (pstmt_select != null)
pstmt_select.close();
if (conn != null) if (conn != null)
conn.close(); conn.close();
} catch (SQLException e) { } catch (SQLException e) {
......
...@@ -14,6 +14,7 @@ import java.math.BigDecimal; ...@@ -14,6 +14,7 @@ import java.math.BigDecimal;
import java.sql.*; import java.sql.*;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Arrays;
public class TSDBResultSetTest { public class TSDBResultSetTest {
...@@ -133,7 +134,7 @@ public class TSDBResultSetTest { ...@@ -133,7 +134,7 @@ public class TSDBResultSetTest {
Assert.assertEquals(3.1415926, Double.valueOf(new String(f5)), 0.000000f); Assert.assertEquals(3.1415926, Double.valueOf(new String(f5)), 0.000000f);
byte[] f6 = rs.getBytes("f6"); byte[] f6 = rs.getBytes("f6");
Assert.assertEquals("abc", new String(f6)); Assert.assertTrue(Arrays.equals("abc".getBytes(), f6));
byte[] f7 = rs.getBytes("f7"); byte[] f7 = rs.getBytes("f7");
Assert.assertEquals((short) 10, Shorts.fromByteArray(f7)); Assert.assertEquals((short) 10, Shorts.fromByteArray(f7));
...@@ -176,8 +177,7 @@ public class TSDBResultSetTest { ...@@ -176,8 +177,7 @@ public class TSDBResultSetTest {
rs.getAsciiStream("f1"); rs.getAsciiStream("f1");
} }
@SuppressWarnings("deprecation") @Test(expected = SQLFeatureNotSupportedException.class)
@Test(expected = SQLFeatureNotSupportedException.class)
public void getUnicodeStream() throws SQLException { public void getUnicodeStream() throws SQLException {
rs.getUnicodeStream("f1"); rs.getUnicodeStream("f1");
} }
...@@ -646,7 +646,6 @@ public class TSDBResultSetTest { ...@@ -646,7 +646,6 @@ public class TSDBResultSetTest {
@BeforeClass @BeforeClass
public static void beforeClass() { public static void beforeClass() {
try { try {
Class.forName("com.taosdata.jdbc.TSDBDriver");
conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"); conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata");
stmt = conn.createStatement(); stmt = conn.createStatement();
stmt.execute("create database if not exists restful_test"); stmt.execute("create database if not exists restful_test");
...@@ -656,10 +655,9 @@ public class TSDBResultSetTest { ...@@ -656,10 +655,9 @@ public class TSDBResultSetTest {
stmt.execute("insert into restful_test.weather values('2021-01-01 00:00:00.000', 1, 100, 3.1415, 3.1415926, 'abc', 10, 10, true, '涛思数据')"); stmt.execute("insert into restful_test.weather values('2021-01-01 00:00:00.000', 1, 100, 3.1415, 3.1415926, 'abc', 10, 10, true, '涛思数据')");
rs = stmt.executeQuery("select * from restful_test.weather"); rs = stmt.executeQuery("select * from restful_test.weather");
rs.next(); rs.next();
} catch (ClassNotFoundException | SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
@AfterClass @AfterClass
......
...@@ -387,15 +387,12 @@ public class TSDBStatementTest { ...@@ -387,15 +387,12 @@ public class TSDBStatementTest {
@BeforeClass @BeforeClass
public static void beforeClass() { public static void beforeClass() {
try { try {
Class.forName("com.taosdata.jdbc.TSDBDriver");
Properties properties = new Properties(); Properties properties = new Properties();
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata", properties); conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata", properties);
stmt = conn.createStatement(); stmt = conn.createStatement();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
......
...@@ -10,6 +10,7 @@ import java.sql.*; ...@@ -10,6 +10,7 @@ import java.sql.*;
import java.util.Properties; import java.util.Properties;
public class RestfulDatabaseMetaDataTest { public class RestfulDatabaseMetaDataTest {
private static final String host = "127.0.0.1"; private static final String host = "127.0.0.1";
private static final String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata"; private static final String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata";
private static Connection connection; private static Connection connection;
...@@ -632,17 +633,32 @@ public class RestfulDatabaseMetaDataTest { ...@@ -632,17 +633,32 @@ public class RestfulDatabaseMetaDataTest {
@Test @Test
public void getTables() throws SQLException { public void getTables() throws SQLException {
System.out.println("****************************************************"); ResultSet rs = metaData.getTables("log", "", null, null);
ResultSet tables = metaData.getTables("log", "", null, null); ResultSetMetaData meta = rs.getMetaData();
ResultSetMetaData metaData = tables.getMetaData(); Assert.assertNotNull(rs);
while (tables.next()) { rs.next();
System.out.print(metaData.getColumnLabel(1) + ":" + tables.getString(1) + "\t"); {
System.out.print(metaData.getColumnLabel(3) + ":" + tables.getString(3) + "\t"); // TABLE_CAT
System.out.print(metaData.getColumnLabel(4) + ":" + tables.getString(4) + "\t"); Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1));
System.out.print(metaData.getColumnLabel(5) + ":" + tables.getString(5) + "\n"); Assert.assertEquals("log", rs.getString(1));
Assert.assertEquals("log", rs.getString("TABLE_CAT"));
// TABLE_SCHEM
Assert.assertEquals("TABLE_SCHEM", meta.getColumnLabel(2));
Assert.assertEquals(null, rs.getString(2));
Assert.assertEquals(null, rs.getString("TABLE_SCHEM"));
// TABLE_NAME
Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3));
Assert.assertNotNull(rs.getString(3));
Assert.assertNotNull(rs.getString("TABLE_NAME"));
// TABLE_TYPE
Assert.assertEquals("TABLE_TYPE", meta.getColumnLabel(4));
Assert.assertEquals("TABLE", rs.getString(4));
Assert.assertEquals("TABLE", rs.getString("TABLE_TYPE"));
// REMARKS
Assert.assertEquals("REMARKS", meta.getColumnLabel(5));
Assert.assertEquals("", rs.getString(5));
Assert.assertEquals("", rs.getString("REMARKS"));
} }
System.out.println();
Assert.assertNotNull(tables);
} }
@Test @Test
...@@ -652,46 +668,130 @@ public class RestfulDatabaseMetaDataTest { ...@@ -652,46 +668,130 @@ public class RestfulDatabaseMetaDataTest {
@Test @Test
public void getCatalogs() throws SQLException { public void getCatalogs() throws SQLException {
System.out.println("****************************************************"); ResultSet rs = metaData.getCatalogs();
ResultSetMetaData meta = rs.getMetaData();
ResultSet catalogs = metaData.getCatalogs(); rs.next();
ResultSetMetaData meta = catalogs.getMetaData(); {
while (catalogs.next()) { // TABLE_CAT
for (int i = 1; i <= meta.getColumnCount(); i++) { Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1));
System.out.print(meta.getColumnLabel(i) + ": " + catalogs.getString(i)); Assert.assertNotNull(rs.getString(1));
} Assert.assertNotNull(rs.getString("TABLE_CAT"));
System.out.println();
} }
} }
@Test @Test
public void getTableTypes() throws SQLException { public void getTableTypes() throws SQLException {
System.out.println("****************************************************");
ResultSet tableTypes = metaData.getTableTypes(); ResultSet tableTypes = metaData.getTableTypes();
while (tableTypes.next()) { tableTypes.next();
System.out.println(tableTypes.getString("TABLE_TYPE")); // tableTypes: table
{
Assert.assertEquals("TABLE", tableTypes.getString(1));
Assert.assertEquals("TABLE", tableTypes.getString("TABLE_TYPE"));
}
tableTypes.next();
// tableTypes: stable
{
Assert.assertEquals("STABLE", tableTypes.getString(1));
Assert.assertEquals("STABLE", tableTypes.getString("TABLE_TYPE"));
} }
Assert.assertNotNull(metaData.getTableTypes());
} }
@Test @Test
public void getColumns() throws SQLException { public void getColumns() throws SQLException {
System.out.println("****************************************************"); // when
ResultSet columns = metaData.getColumns("log", "", "dn", ""); ResultSet columns = metaData.getColumns("log", "", "dn", "");
// then
ResultSetMetaData meta = columns.getMetaData(); ResultSetMetaData meta = columns.getMetaData();
while (columns.next()) { columns.next();
System.out.print(meta.getColumnLabel(1) + ": " + columns.getString(1) + "\t"); // column: 1
System.out.print(meta.getColumnLabel(3) + ": " + columns.getString(3) + "\t"); {
System.out.print(meta.getColumnLabel(4) + ": " + columns.getString(4) + "\t"); // TABLE_CAT
System.out.print(meta.getColumnLabel(5) + ": " + columns.getString(5) + "\t"); Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1));
System.out.print(meta.getColumnLabel(6) + ": " + columns.getString(6) + "\t"); Assert.assertEquals("log", columns.getString(1));
System.out.print(meta.getColumnLabel(7) + ": " + columns.getString(7) + "\t"); Assert.assertEquals("log", columns.getString("TABLE_CAT"));
System.out.print(meta.getColumnLabel(9) + ": " + columns.getString(9) + "\t"); // TABLE_NAME
System.out.print(meta.getColumnLabel(10) + ": " + columns.getString(10) + "\t"); Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3));
System.out.print(meta.getColumnLabel(11) + ": " + columns.getString(11) + "\n"); Assert.assertEquals("dn", columns.getString(3));
System.out.print(meta.getColumnLabel(12) + ": " + columns.getString(12) + "\n"); Assert.assertEquals("dn", columns.getString("TABLE_NAME"));
// COLUMN_NAME
Assert.assertEquals("COLUMN_NAME", meta.getColumnLabel(4));
Assert.assertEquals("ts", columns.getString(4));
Assert.assertEquals("ts", columns.getString("COLUMN_NAME"));
// DATA_TYPE
Assert.assertEquals("DATA_TYPE", meta.getColumnLabel(5));
Assert.assertEquals(Types.TIMESTAMP, columns.getInt(5));
Assert.assertEquals(Types.TIMESTAMP, columns.getInt("DATA_TYPE"));
// TYPE_NAME
Assert.assertEquals("TYPE_NAME", meta.getColumnLabel(6));
Assert.assertEquals("TIMESTAMP", columns.getString(6));
Assert.assertEquals("TIMESTAMP", columns.getString("TYPE_NAME"));
// COLUMN_SIZE
Assert.assertEquals("COLUMN_SIZE", meta.getColumnLabel(7));
Assert.assertEquals(26, columns.getInt(7));
Assert.assertEquals(26, columns.getInt("COLUMN_SIZE"));
// DECIMAL_DIGITS
Assert.assertEquals("DECIMAL_DIGITS", meta.getColumnLabel(9));
Assert.assertEquals(Integer.MIN_VALUE, columns.getInt(9));
Assert.assertEquals(Integer.MIN_VALUE, columns.getInt("DECIMAL_DIGITS"));
Assert.assertEquals(null, columns.getString(9));
Assert.assertEquals(null, columns.getString("DECIMAL_DIGITS"));
// NUM_PREC_RADIX
Assert.assertEquals("NUM_PREC_RADIX", meta.getColumnLabel(10));
Assert.assertEquals(10, columns.getInt(10));
Assert.assertEquals(10, columns.getInt("NUM_PREC_RADIX"));
// NULLABLE
Assert.assertEquals("NULLABLE", meta.getColumnLabel(11));
Assert.assertEquals(DatabaseMetaData.columnNoNulls, columns.getInt(11));
Assert.assertEquals(DatabaseMetaData.columnNoNulls, columns.getInt("NULLABLE"));
// REMARKS
Assert.assertEquals("REMARKS", meta.getColumnLabel(12));
Assert.assertEquals(null, columns.getString(12));
Assert.assertEquals(null, columns.getString("REMARKS"));
}
columns.next();
// column: 2
{
// TABLE_CAT
Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1));
Assert.assertEquals("log", columns.getString(1));
Assert.assertEquals("log", columns.getString("TABLE_CAT"));
// TABLE_NAME
Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3));
Assert.assertEquals("dn", columns.getString(3));
Assert.assertEquals("dn", columns.getString("TABLE_NAME"));
// COLUMN_NAME
Assert.assertEquals("COLUMN_NAME", meta.getColumnLabel(4));
Assert.assertEquals("cpu_taosd", columns.getString(4));
Assert.assertEquals("cpu_taosd", columns.getString("COLUMN_NAME"));
// DATA_TYPE
Assert.assertEquals("DATA_TYPE", meta.getColumnLabel(5));
Assert.assertEquals(Types.FLOAT, columns.getInt(5));
Assert.assertEquals(Types.FLOAT, columns.getInt("DATA_TYPE"));
// TYPE_NAME
Assert.assertEquals("TYPE_NAME", meta.getColumnLabel(6));
Assert.assertEquals("FLOAT", columns.getString(6));
Assert.assertEquals("FLOAT", columns.getString("TYPE_NAME"));
// COLUMN_SIZE
Assert.assertEquals("COLUMN_SIZE", meta.getColumnLabel(7));
Assert.assertEquals(12, columns.getInt(7));
Assert.assertEquals(12, columns.getInt("COLUMN_SIZE"));
// DECIMAL_DIGITS
Assert.assertEquals("DECIMAL_DIGITS", meta.getColumnLabel(9));
Assert.assertEquals(Integer.MIN_VALUE, columns.getInt(9));
Assert.assertEquals(Integer.MIN_VALUE, columns.getInt("DECIMAL_DIGITS"));
Assert.assertEquals(null, columns.getString(9));
Assert.assertEquals(null, columns.getString("DECIMAL_DIGITS"));
// NUM_PREC_RADIX
Assert.assertEquals("NUM_PREC_RADIX", meta.getColumnLabel(10));
Assert.assertEquals(10, columns.getInt(10));
Assert.assertEquals(10, columns.getInt("NUM_PREC_RADIX"));
// NULLABLE
Assert.assertEquals("NULLABLE", meta.getColumnLabel(11));
Assert.assertEquals(DatabaseMetaData.columnNullable, columns.getInt(11));
Assert.assertEquals(DatabaseMetaData.columnNullable, columns.getInt("NULLABLE"));
// REMARKS
Assert.assertEquals("REMARKS", meta.getColumnLabel(12));
Assert.assertEquals(null, columns.getString(12));
} }
} }
...@@ -717,17 +817,35 @@ public class RestfulDatabaseMetaDataTest { ...@@ -717,17 +817,35 @@ public class RestfulDatabaseMetaDataTest {
@Test @Test
public void getPrimaryKeys() throws SQLException { public void getPrimaryKeys() throws SQLException {
System.out.println("****************************************************");
ResultSet rs = metaData.getPrimaryKeys("log", "", "dn1"); ResultSet rs = metaData.getPrimaryKeys("log", "", "dn1");
while (rs.next()) { ResultSetMetaData meta = rs.getMetaData();
System.out.println("TABLE_NAME: " + rs.getString("TABLE_NAME")); rs.next();
System.out.println("COLUMN_NAME: " + rs.getString("COLUMN_NAME")); {
System.out.println("KEY_SEQ: " + rs.getString("KEY_SEQ")); // TABLE_CAT
System.out.println("PK_NAME: " + rs.getString("PK_NAME")); Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1));
Assert.assertEquals("log", rs.getString(1));
Assert.assertEquals("log", rs.getString("TABLE_CAT"));
// TABLE_SCHEM
Assert.assertEquals("TABLE_SCHEM", meta.getColumnLabel(2));
Assert.assertEquals(null, rs.getString(2));
Assert.assertEquals(null, rs.getString("TABLE_SCHEM"));
// TABLE_NAME
Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3));
Assert.assertEquals("dn1", rs.getString(3));
Assert.assertEquals("dn1", rs.getString("TABLE_NAME"));
// COLUMN_NAME
Assert.assertEquals("COLUMN_NAME", meta.getColumnLabel(4));
Assert.assertEquals("ts", rs.getString(4));
Assert.assertEquals("ts", rs.getString("COLUMN_NAME"));
// KEY_SEQ
Assert.assertEquals("KEY_SEQ", meta.getColumnLabel(5));
Assert.assertEquals(1, rs.getShort(5));
Assert.assertEquals(1, rs.getShort("KEY_SEQ"));
// DATA_TYPE
Assert.assertEquals("PK_NAME", meta.getColumnLabel(6));
Assert.assertEquals("ts", rs.getString(6));
Assert.assertEquals("ts", rs.getString("PK_NAME"));
} }
Assert.assertNotNull(rs);
} }
@Test @Test
...@@ -852,14 +970,27 @@ public class RestfulDatabaseMetaDataTest { ...@@ -852,14 +970,27 @@ public class RestfulDatabaseMetaDataTest {
@Test @Test
public void getSuperTables() throws SQLException { public void getSuperTables() throws SQLException {
System.out.println("****************************************************");
ResultSet rs = metaData.getSuperTables("log", "", "dn1"); ResultSet rs = metaData.getSuperTables("log", "", "dn1");
while (rs.next()) { ResultSetMetaData meta = rs.getMetaData();
System.out.println("TABLE_NAME: " + rs.getString("TABLE_NAME")); rs.next();
System.out.println("SUPERTABLE_NAME: " + rs.getString("SUPERTABLE_NAME")); {
// TABLE_CAT
Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1));
Assert.assertEquals("log", rs.getString(1));
Assert.assertEquals("log", rs.getString("TABLE_CAT"));
// TABLE_CAT
Assert.assertEquals("TABLE_SCHEM", meta.getColumnLabel(2));
Assert.assertEquals(null, rs.getString(2));
Assert.assertEquals(null, rs.getString("TABLE_SCHEM"));
// TABLE_CAT
Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3));
Assert.assertEquals("dn1", rs.getString(3));
Assert.assertEquals("dn1", rs.getString("TABLE_NAME"));
// TABLE_CAT
Assert.assertEquals("SUPERTABLE_NAME", meta.getColumnLabel(4));
Assert.assertEquals("dn", rs.getString(4));
Assert.assertEquals("dn", rs.getString("SUPERTABLE_NAME"));
} }
Assert.assertNotNull(rs);
} }
@Test @Test
......
...@@ -54,16 +54,17 @@ public class RestfulParameterMetaDataTest { ...@@ -54,16 +54,17 @@ public class RestfulParameterMetaDataTest {
@Test @Test
public void getPrecision() throws SQLException { public void getPrecision() throws SQLException {
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(1)); //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))
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(2)); Assert.assertEquals(TSDBConstants.TIMESTAMP_MS_PRECISION, parameterMetaData_insert.getPrecision(1));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(3)); Assert.assertEquals(TSDBConstants.INT_PRECISION, parameterMetaData_insert.getPrecision(2));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(4)); Assert.assertEquals(TSDBConstants.BIGINT_PRECISION, parameterMetaData_insert.getPrecision(3));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(5)); Assert.assertEquals(TSDBConstants.FLOAT_PRECISION, parameterMetaData_insert.getPrecision(4));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(6)); Assert.assertEquals(TSDBConstants.DOUBLE_PRECISION, parameterMetaData_insert.getPrecision(5));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(7)); Assert.assertEquals(TSDBConstants.SMALLINT_PRECISION, parameterMetaData_insert.getPrecision(6));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(8)); Assert.assertEquals(TSDBConstants.TINYINT_PRECISION, parameterMetaData_insert.getPrecision(7));
Assert.assertEquals(5, parameterMetaData_insert.getPrecision(9)); Assert.assertEquals(TSDBConstants.BOOLEAN_PRECISION, parameterMetaData_insert.getPrecision(8));
Assert.assertEquals(5, parameterMetaData_insert.getPrecision(10)); Assert.assertEquals("hello".getBytes().length, parameterMetaData_insert.getPrecision(9));
Assert.assertEquals("涛思数据".length(), parameterMetaData_insert.getPrecision(10));
} }
@Test @Test
...@@ -71,8 +72,8 @@ public class RestfulParameterMetaDataTest { ...@@ -71,8 +72,8 @@ public class RestfulParameterMetaDataTest {
Assert.assertEquals(0, parameterMetaData_insert.getScale(1)); Assert.assertEquals(0, parameterMetaData_insert.getScale(1));
Assert.assertEquals(0, parameterMetaData_insert.getScale(2)); Assert.assertEquals(0, parameterMetaData_insert.getScale(2));
Assert.assertEquals(0, parameterMetaData_insert.getScale(3)); Assert.assertEquals(0, parameterMetaData_insert.getScale(3));
Assert.assertEquals(0, parameterMetaData_insert.getScale(4)); Assert.assertEquals(31, parameterMetaData_insert.getScale(4));
Assert.assertEquals(0, parameterMetaData_insert.getScale(5)); Assert.assertEquals(31, parameterMetaData_insert.getScale(5));
Assert.assertEquals(0, parameterMetaData_insert.getScale(6)); Assert.assertEquals(0, parameterMetaData_insert.getScale(6));
Assert.assertEquals(0, parameterMetaData_insert.getScale(7)); Assert.assertEquals(0, parameterMetaData_insert.getScale(7));
Assert.assertEquals(0, parameterMetaData_insert.getScale(8)); Assert.assertEquals(0, parameterMetaData_insert.getScale(8));
...@@ -164,7 +165,7 @@ public class RestfulParameterMetaDataTest { ...@@ -164,7 +165,7 @@ public class RestfulParameterMetaDataTest {
pstmt_insert.setObject(7, Byte.MAX_VALUE); pstmt_insert.setObject(7, Byte.MAX_VALUE);
pstmt_insert.setObject(8, true); pstmt_insert.setObject(8, true);
pstmt_insert.setObject(9, "hello".getBytes()); pstmt_insert.setObject(9, "hello".getBytes());
pstmt_insert.setObject(10, "Hello"); pstmt_insert.setObject(10, "涛思数据");
parameterMetaData_insert = pstmt_insert.getParameterMetaData(); parameterMetaData_insert = pstmt_insert.getParameterMetaData();
pstmt_select = conn.prepareStatement(sql_select); pstmt_select = conn.prepareStatement(sql_select);
......
...@@ -124,6 +124,7 @@ int taos_stmt_add_batch(TAOS_STMT *stmt); ...@@ -124,6 +124,7 @@ int taos_stmt_add_batch(TAOS_STMT *stmt);
int taos_stmt_execute(TAOS_STMT *stmt); int taos_stmt_execute(TAOS_STMT *stmt);
TAOS_RES * taos_stmt_use_result(TAOS_STMT *stmt); TAOS_RES * taos_stmt_use_result(TAOS_STMT *stmt);
int taos_stmt_close(TAOS_STMT *stmt); int taos_stmt_close(TAOS_STMT *stmt);
char * taos_stmt_errstr(TAOS_STMT *stmt);
DLL_EXPORT TAOS_RES *taos_query(TAOS *taos, const char *sql); DLL_EXPORT TAOS_RES *taos_query(TAOS *taos, const char *sql);
DLL_EXPORT TAOS_ROW taos_fetch_row(TAOS_RES *res); DLL_EXPORT TAOS_ROW taos_fetch_row(TAOS_RES *res);
......
...@@ -66,17 +66,19 @@ extern "C" { ...@@ -66,17 +66,19 @@ extern "C" {
#define TSDB_FUNC_RATE 29 #define TSDB_FUNC_RATE 29
#define TSDB_FUNC_IRATE 30 #define TSDB_FUNC_IRATE 30
#define TSDB_FUNC_TID_TAG 31 #define TSDB_FUNC_TID_TAG 31
#define TSDB_FUNC_BLKINFO 32 #define TSDB_FUNC_DERIVATIVE 32
#define TSDB_FUNC_BLKINFO 33
#define TSDB_FUNC_HISTOGRAM 33
#define TSDB_FUNC_HLL 34
#define TSDB_FUNC_MODE 35 #define TSDB_FUNC_HISTOGRAM 34
#define TSDB_FUNC_SAMPLE 36 #define TSDB_FUNC_HLL 35
#define TSDB_FUNC_CEIL 37 #define TSDB_FUNC_MODE 36
#define TSDB_FUNC_FLOOR 38 #define TSDB_FUNC_SAMPLE 37
#define TSDB_FUNC_ROUND 39 #define TSDB_FUNC_CEIL 38
#define TSDB_FUNC_MAVG 40 #define TSDB_FUNC_FLOOR 39
#define TSDB_FUNC_CSUM 41 #define TSDB_FUNC_ROUND 40
#define TSDB_FUNC_MAVG 41
#define TSDB_FUNC_CSUM 42
#define TSDB_FUNCSTATE_SO 0x1u // single output #define TSDB_FUNCSTATE_SO 0x1u // single output
#define TSDB_FUNCSTATE_MO 0x2u // dynamic number of output, not multinumber of output e.g., TOP/BOTTOM #define TSDB_FUNCSTATE_MO 0x2u // dynamic number of output, not multinumber of output e.g., TOP/BOTTOM
......
...@@ -113,6 +113,7 @@ typedef struct SColumnFilterElem { ...@@ -113,6 +113,7 @@ typedef struct SColumnFilterElem {
int16_t bytes; // column length int16_t bytes; // column length
__filter_func_t fp; __filter_func_t fp;
SColumnFilterInfo filterInfo; SColumnFilterInfo filterInfo;
void *q;
} SColumnFilterElem; } SColumnFilterElem;
typedef struct SSingleColumnFilterInfo { typedef struct SSingleColumnFilterInfo {
...@@ -185,6 +186,7 @@ typedef struct SQueryAttr { ...@@ -185,6 +186,7 @@ typedef struct SQueryAttr {
bool queryBlockDist; // if query data block distribution bool queryBlockDist; // if query data block distribution
bool stabledev; // super table stddev query bool stabledev; // super table stddev query
bool tsCompQuery; // is tscomp query bool tsCompQuery; // is tscomp query
bool diffQuery; // is diff query
bool simpleAgg; bool simpleAgg;
bool pointInterpQuery; // point interpolation query bool pointInterpQuery; // point interpolation query
bool needReverseScan; // need reverse scan bool needReverseScan; // need reverse scan
...@@ -245,6 +247,7 @@ typedef struct SQueryRuntimeEnv { ...@@ -245,6 +247,7 @@ typedef struct SQueryRuntimeEnv {
void* pQueryHandle; void* pQueryHandle;
int32_t prevGroupId; // previous executed group id int32_t prevGroupId; // previous executed group id
bool enableGroupData;
SDiskbasedResultBuf* pResultBuf; // query result buffer based on blocked-wised disk file SDiskbasedResultBuf* pResultBuf; // query result buffer based on blocked-wised disk file
SHashObj* pResultRowHashTable; // quick locate the window object for each result SHashObj* pResultRowHashTable; // quick locate the window object for each result
char* keyBuf; // window key buffer char* keyBuf; // window key buffer
...@@ -386,6 +389,7 @@ typedef struct STableScanInfo { ...@@ -386,6 +389,7 @@ typedef struct STableScanInfo {
int64_t elapsedTime; int64_t elapsedTime;
int32_t tableIndex; int32_t tableIndex;
int32_t prevGroupId; // previous table group id
} STableScanInfo; } STableScanInfo;
typedef struct STagScanInfo { typedef struct STagScanInfo {
......
...@@ -138,6 +138,7 @@ typedef struct SQueryInfo { ...@@ -138,6 +138,7 @@ typedef struct SQueryInfo {
bool hasFilter; bool hasFilter;
bool onlyTagQuery; bool onlyTagQuery;
bool orderProjectQuery; bool orderProjectQuery;
bool diffQuery;
bool stateWindow; bool stateWindow;
} SQueryInfo; } SQueryInfo;
......
...@@ -161,6 +161,14 @@ typedef struct SRateInfo { ...@@ -161,6 +161,14 @@ typedef struct SRateInfo {
bool isIRate; // true for IRate functions, false for Rate functions bool isIRate; // true for IRate functions, false for Rate functions
} SRateInfo; } SRateInfo;
typedef struct SDerivInfo {
double prevValue; // previous value
TSKEY prevTs; // previous timestamp
bool ignoreNegative;// ignore the negative value
int64_t tsWindow; // time window for derivative
bool valueSet; // the value has been set already
} SDerivInfo;
int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, int16_t *type, int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, int16_t *type,
int16_t *bytes, int32_t *interBytes, int16_t extLength, bool isSuperTable) { int16_t *bytes, int32_t *interBytes, int16_t extLength, bool isSuperTable) {
if (!isValidDataType(dataType)) { if (!isValidDataType(dataType)) {
...@@ -189,7 +197,9 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI ...@@ -189,7 +197,9 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
*bytes = (int16_t)(dataBytes + sizeof(int16_t) + sizeof(int64_t) + sizeof(int32_t) + sizeof(int32_t) + VARSTR_HEADER_SIZE); *bytes = (int16_t)(dataBytes + sizeof(int16_t) + sizeof(int64_t) + sizeof(int32_t) + sizeof(int32_t) + VARSTR_HEADER_SIZE);
*interBytes = 0; *interBytes = 0;
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} else if (functionId == TSDB_FUNC_BLKINFO) { }
if (functionId == TSDB_FUNC_BLKINFO) {
*type = TSDB_DATA_TYPE_BINARY; *type = TSDB_DATA_TYPE_BINARY;
*bytes = 16384; *bytes = 16384;
*interBytes = 0; *interBytes = 0;
...@@ -216,7 +226,14 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI ...@@ -216,7 +226,14 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
*interBytes = POINTER_BYTES; *interBytes = POINTER_BYTES;
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
if (functionId == TSDB_FUNC_DERIVATIVE) {
*type = TSDB_DATA_TYPE_DOUBLE;
*bytes = sizeof(double); // this results is compressed ts data, only one byte
*interBytes = sizeof(SDerivInfo);
return TSDB_CODE_SUCCESS;
}
if (isSuperTable) { if (isSuperTable) {
if (functionId == TSDB_FUNC_MIN || functionId == TSDB_FUNC_MAX) { if (functionId == TSDB_FUNC_MIN || functionId == TSDB_FUNC_MAX) {
*type = TSDB_DATA_TYPE_BINARY; *type = TSDB_DATA_TYPE_BINARY;
...@@ -3393,7 +3410,7 @@ enum { ...@@ -3393,7 +3410,7 @@ enum {
}; };
static bool diff_function_setup(SQLFunctionCtx *pCtx) { static bool diff_function_setup(SQLFunctionCtx *pCtx) {
if (function_setup(pCtx)) { if (!function_setup(pCtx)) {
return false; return false;
} }
...@@ -3402,16 +3419,237 @@ static bool diff_function_setup(SQLFunctionCtx *pCtx) { ...@@ -3402,16 +3419,237 @@ static bool diff_function_setup(SQLFunctionCtx *pCtx) {
return false; return false;
} }
static bool deriv_function_setup(SQLFunctionCtx *pCtx) {
if (!function_setup(pCtx)) {
return false;
}
// diff function require the value is set to -1
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
SDerivInfo* pDerivInfo = GET_ROWCELL_INTERBUF(pResInfo);
pDerivInfo->ignoreNegative = pCtx->param[2].i64;
pDerivInfo->prevTs = -1;
pDerivInfo->tsWindow = pCtx->param[0].i64;
pDerivInfo->valueSet = false;
return false;
}
static void deriv_function(SQLFunctionCtx *pCtx) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
SDerivInfo* pDerivInfo = GET_ROWCELL_INTERBUF(pResInfo);
void *data = GET_INPUT_DATA_LIST(pCtx);
bool isFirstBlock = (pDerivInfo->valueSet == false);
int32_t notNullElems = 0;
int32_t step = GET_FORWARD_DIRECTION_FACTOR(pCtx->order);
int32_t i = (pCtx->order == TSDB_ORDER_ASC) ? 0 : pCtx->size - 1;
TSKEY *pTimestamp = pCtx->ptsOutputBuf;
TSKEY *tsList = GET_TS_LIST(pCtx);
double *pOutput = (double *)pCtx->pOutput;
switch (pCtx->inputType) {
case TSDB_DATA_TYPE_INT: {
int32_t *pData = (int32_t *)data;
for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((const char *)&pData[i], pCtx->inputType)) {
continue;
}
if (!pDerivInfo->valueSet) { // initial value is not set yet
pDerivInfo->valueSet = true;
} else {
*pOutput = ((pData[i] - pDerivInfo->prevValue) * pDerivInfo->tsWindow) / (tsList[i] - pDerivInfo->prevTs);
if (pDerivInfo->ignoreNegative && *pOutput < 0) {
} else {
*pTimestamp = tsList[i];
pOutput += 1;
pTimestamp += 1;
}
}
pDerivInfo->prevValue = pData[i];
pDerivInfo->prevTs = tsList[i];
notNullElems++;
}
break;
};
case TSDB_DATA_TYPE_BIGINT: {
int64_t *pData = (int64_t *)data;
for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((const char *)&pData[i], pCtx->inputType)) {
continue;
}
if (!pDerivInfo->valueSet) { // initial value is not set yet
pDerivInfo->valueSet = true;
} else {
*pOutput = ((pData[i] - pDerivInfo->prevValue) * pDerivInfo->tsWindow) / (tsList[i] - pDerivInfo->prevTs);
if (pDerivInfo->ignoreNegative && *pOutput < 0) {
} else {
*pTimestamp = tsList[i];
pOutput += 1;
pTimestamp += 1;
}
}
pDerivInfo->prevValue = (double) pData[i];
pDerivInfo->prevTs = tsList[i];
notNullElems++;
}
break;
}
case TSDB_DATA_TYPE_DOUBLE: {
double *pData = (double *)data;
for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((const char *)&pData[i], pCtx->inputType)) {
continue;
}
if (!pDerivInfo->valueSet) { // initial value is not set yet
pDerivInfo->valueSet = true;
} else {
*pOutput = ((pData[i] - pDerivInfo->prevValue) * pDerivInfo->tsWindow) / (tsList[i] - pDerivInfo->prevTs);
if (pDerivInfo->ignoreNegative && *pOutput < 0) {
} else {
*pTimestamp = tsList[i];
pOutput += 1;
pTimestamp += 1;
}
}
pDerivInfo->prevValue = pData[i];
pDerivInfo->prevTs = tsList[i];
notNullElems++;
}
break;
}
case TSDB_DATA_TYPE_FLOAT: {
float *pData = (float *)data;
for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((const char *)&pData[i], pCtx->inputType)) {
continue;
}
if (!pDerivInfo->valueSet) { // initial value is not set yet
pDerivInfo->valueSet = true;
} else {
*pOutput = ((pData[i] - pDerivInfo->prevValue) * pDerivInfo->tsWindow) / (tsList[i] - pDerivInfo->prevTs);
if (pDerivInfo->ignoreNegative && *pOutput < 0) {
} else {
*pTimestamp = tsList[i];
pOutput += 1;
pTimestamp += 1;
}
}
pDerivInfo->prevValue = pData[i];
pDerivInfo->prevTs = tsList[i];
notNullElems++;
}
break;
}
case TSDB_DATA_TYPE_SMALLINT: {
int16_t *pData = (int16_t *)data;
for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((const char *)&pData[i], pCtx->inputType)) {
continue;
}
if (!pDerivInfo->valueSet) { // initial value is not set yet
pDerivInfo->valueSet = true;
} else {
*pOutput = ((pData[i] - pDerivInfo->prevValue) * pDerivInfo->tsWindow) / (tsList[i] - pDerivInfo->prevTs);
if (pDerivInfo->ignoreNegative && *pOutput < 0) {
} else {
*pTimestamp = tsList[i];
pOutput += 1;
pTimestamp += 1;
}
}
pDerivInfo->prevValue = pData[i];
pDerivInfo->prevTs = tsList[i];
notNullElems++;
}
break;
}
case TSDB_DATA_TYPE_TINYINT: {
int8_t *pData = (int8_t *)data;
for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((char *)&pData[i], pCtx->inputType)) {
continue;
}
if (!pDerivInfo->valueSet) { // initial value is not set yet
pDerivInfo->valueSet = true;
} else {
*pOutput = ((pData[i] - pDerivInfo->prevValue) * pDerivInfo->tsWindow) / (tsList[i] - pDerivInfo->prevTs);
if (pDerivInfo->ignoreNegative && *pOutput < 0) {
} else {
*pTimestamp = tsList[i];
pOutput += 1;
pTimestamp += 1;
}
}
pDerivInfo->prevValue = pData[i];
pDerivInfo->prevTs = tsList[i];
notNullElems++;
}
break;
}
default:
qError("error input type");
}
// initial value is not set yet, all data block are null
if (!pDerivInfo->valueSet || notNullElems <= 0) {
/*
* 1. current block and blocks before are full of null
* 2. current block may be null value
*/
assert(pCtx->hasNull);
} else {
int32_t forwardStep = (isFirstBlock) ? notNullElems - 1 : notNullElems;
GET_RES_INFO(pCtx)->numOfRes += forwardStep;
}
}
#define DIFF_IMPL(ctx, d, type) \
do { \
if ((ctx)->param[1].nType == INITIAL_VALUE_NOT_ASSIGNED) { \
(ctx)->param[1].nType = (ctx)->inputType; \
*(type *)&(ctx)->param[1].i64 = *(type *)(d); \
} else { \
*(type *)(ctx)->pOutput = *(type *)(d) - (*(type *)(&(ctx)->param[1].i64)); \
*(type *)(&(ctx)->param[1].i64) = *(type *)(d); \
*(int64_t *)(ctx)->ptsOutputBuf = GET_TS_DATA(ctx, index); \
} \
} while (0);
// TODO difference in date column // TODO difference in date column
static void diff_function(SQLFunctionCtx *pCtx) { static void diff_function(SQLFunctionCtx *pCtx) {
void *data = GET_INPUT_DATA_LIST(pCtx); void *data = GET_INPUT_DATA_LIST(pCtx);
bool isFirstBlock = (pCtx->param[1].nType == INITIAL_VALUE_NOT_ASSIGNED); bool isFirstBlock = (pCtx->param[1].nType == INITIAL_VALUE_NOT_ASSIGNED);
int32_t notNullElems = 0; int32_t notNullElems = 0;
int32_t step = GET_FORWARD_DIRECTION_FACTOR(pCtx->order); int32_t step = GET_FORWARD_DIRECTION_FACTOR(pCtx->order);
int32_t i = (pCtx->order == TSDB_ORDER_ASC) ? 0 : pCtx->size - 1; int32_t i = (pCtx->order == TSDB_ORDER_ASC) ? 0 : pCtx->size - 1;
TSKEY* pTimestamp = pCtx->ptsOutputBuf; TSKEY* pTimestamp = pCtx->ptsOutputBuf;
TSKEY* tsList = GET_TS_LIST(pCtx); TSKEY* tsList = GET_TS_LIST(pCtx);
...@@ -3419,29 +3657,19 @@ static void diff_function(SQLFunctionCtx *pCtx) { ...@@ -3419,29 +3657,19 @@ static void diff_function(SQLFunctionCtx *pCtx) {
case TSDB_DATA_TYPE_INT: { case TSDB_DATA_TYPE_INT: {
int32_t *pData = (int32_t *)data; int32_t *pData = (int32_t *)data;
int32_t *pOutput = (int32_t *)pCtx->pOutput; int32_t *pOutput = (int32_t *)pCtx->pOutput;
for (; i < pCtx->size && i >= 0; i += step) { for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) { if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) {
continue; continue;
} }
if (pCtx->param[1].nType == INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet if (pCtx->param[1].nType != INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet
pCtx->param[1].i64 = pData[i];
pCtx->param[1].nType = pCtx->inputType;
} else if ((i == 0 && pCtx->order == TSDB_ORDER_ASC) || (i == pCtx->size - 1 && pCtx->order == TSDB_ORDER_DESC)) {
*pOutput = (int32_t)(pData[i] - pCtx->param[1].i64);
*pTimestamp = tsList[i];
pOutput += 1;
pTimestamp += 1;
} else {
*pOutput = (int32_t)(pData[i] - pCtx->param[1].i64); // direct previous may be null *pOutput = (int32_t)(pData[i] - pCtx->param[1].i64); // direct previous may be null
*pTimestamp = tsList[i]; *pTimestamp = tsList[i];
pOutput += 1;
pOutput += 1;
pTimestamp += 1; pTimestamp += 1;
} }
pCtx->param[1].i64 = pData[i]; pCtx->param[1].i64 = pData[i];
pCtx->param[1].nType = pCtx->inputType; pCtx->param[1].nType = pCtx->inputType;
notNullElems++; notNullElems++;
...@@ -3451,29 +3679,19 @@ static void diff_function(SQLFunctionCtx *pCtx) { ...@@ -3451,29 +3679,19 @@ static void diff_function(SQLFunctionCtx *pCtx) {
case TSDB_DATA_TYPE_BIGINT: { case TSDB_DATA_TYPE_BIGINT: {
int64_t *pData = (int64_t *)data; int64_t *pData = (int64_t *)data;
int64_t *pOutput = (int64_t *)pCtx->pOutput; int64_t *pOutput = (int64_t *)pCtx->pOutput;
for (; i < pCtx->size && i >= 0; i += step) { for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) { if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) {
continue; continue;
} }
if (pCtx->param[1].nType == INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet if (pCtx->param[1].nType != INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet
pCtx->param[1].i64 = pData[i]; *pOutput = pData[i] - pCtx->param[1].i64; // direct previous may be null
pCtx->param[1].nType = pCtx->inputType;
} else if ((i == 0 && pCtx->order == TSDB_ORDER_ASC) || (i == pCtx->size - 1 && pCtx->order == TSDB_ORDER_DESC)) {
*pOutput = pData[i] - pCtx->param[1].i64;
*pTimestamp = tsList[i]; *pTimestamp = tsList[i];
pOutput += 1;
pOutput += 1;
pTimestamp += 1;
} else {
*pOutput = pData[i] - pCtx->param[1].i64;
*pTimestamp = tsList[i];
pOutput += 1;
pTimestamp += 1; pTimestamp += 1;
} }
pCtx->param[1].i64 = pData[i]; pCtx->param[1].i64 = pData[i];
pCtx->param[1].nType = pCtx->inputType; pCtx->param[1].nType = pCtx->inputType;
notNullElems++; notNullElems++;
...@@ -3483,27 +3701,19 @@ static void diff_function(SQLFunctionCtx *pCtx) { ...@@ -3483,27 +3701,19 @@ static void diff_function(SQLFunctionCtx *pCtx) {
case TSDB_DATA_TYPE_DOUBLE: { case TSDB_DATA_TYPE_DOUBLE: {
double *pData = (double *)data; double *pData = (double *)data;
double *pOutput = (double *)pCtx->pOutput; double *pOutput = (double *)pCtx->pOutput;
for (; i < pCtx->size && i >= 0; i += step) { for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) { if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) {
continue; continue;
} }
if (pCtx->param[1].nType == INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet if (pCtx->param[1].nType != INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet
pCtx->param[1].dKey = pData[i]; *pOutput = pData[i] - pCtx->param[1].dKey; // direct previous may be null
pCtx->param[1].nType = pCtx->inputType;
} else if ((i == 0 && pCtx->order == TSDB_ORDER_ASC) || (i == pCtx->size - 1 && pCtx->order == TSDB_ORDER_DESC)) {
*pOutput = pData[i] - pCtx->param[1].dKey;
*pTimestamp = tsList[i];
pOutput += 1;
pTimestamp += 1;
} else {
*pOutput = pData[i] - pCtx->param[1].dKey;
*pTimestamp = tsList[i]; *pTimestamp = tsList[i];
pOutput += 1; pOutput += 1;
pTimestamp += 1; pTimestamp += 1;
} }
pCtx->param[1].dKey = pData[i]; pCtx->param[1].dKey = pData[i];
pCtx->param[1].nType = pCtx->inputType; pCtx->param[1].nType = pCtx->inputType;
notNullElems++; notNullElems++;
...@@ -3513,30 +3723,19 @@ static void diff_function(SQLFunctionCtx *pCtx) { ...@@ -3513,30 +3723,19 @@ static void diff_function(SQLFunctionCtx *pCtx) {
case TSDB_DATA_TYPE_FLOAT: { case TSDB_DATA_TYPE_FLOAT: {
float *pData = (float *)data; float *pData = (float *)data;
float *pOutput = (float *)pCtx->pOutput; float *pOutput = (float *)pCtx->pOutput;
for (; i < pCtx->size && i >= 0; i += step) { for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) { if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) {
continue; continue;
} }
if (pCtx->param[1].nType == INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet if (pCtx->param[1].nType != INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet
pCtx->param[1].dKey = pData[i]; *pOutput = (float)(pData[i] - pCtx->param[1].dKey); // direct previous may be null
pCtx->param[1].nType = pCtx->inputType;
} else if ((i == 0 && pCtx->order == TSDB_ORDER_ASC) || (i == pCtx->size - 1 && pCtx->order == TSDB_ORDER_DESC)) {
*pOutput = (float)(pData[i] - pCtx->param[1].dKey);
*pTimestamp = tsList[i];
pOutput += 1;
pTimestamp += 1;
} else {
*pOutput = (float)(pData[i] - pCtx->param[1].dKey);
*pTimestamp = tsList[i]; *pTimestamp = tsList[i];
pOutput += 1;
pOutput += 1;
pTimestamp += 1; pTimestamp += 1;
} }
// keep the last value, the remain may be all null
pCtx->param[1].dKey = pData[i]; pCtx->param[1].dKey = pData[i];
pCtx->param[1].nType = pCtx->inputType; pCtx->param[1].nType = pCtx->inputType;
notNullElems++; notNullElems++;
...@@ -3546,60 +3745,42 @@ static void diff_function(SQLFunctionCtx *pCtx) { ...@@ -3546,60 +3745,42 @@ static void diff_function(SQLFunctionCtx *pCtx) {
case TSDB_DATA_TYPE_SMALLINT: { case TSDB_DATA_TYPE_SMALLINT: {
int16_t *pData = (int16_t *)data; int16_t *pData = (int16_t *)data;
int16_t *pOutput = (int16_t *)pCtx->pOutput; int16_t *pOutput = (int16_t *)pCtx->pOutput;
for (; i < pCtx->size && i >= 0; i += step) { for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) { if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) {
continue; continue;
} }
if (pCtx->param[1].nType == INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet if (pCtx->param[1].nType != INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet
pCtx->param[1].i64 = pData[i]; *pOutput = (int16_t)(pData[i] - pCtx->param[1].i64); // direct previous may be null
pCtx->param[1].nType = pCtx->inputType;
} else if ((i == 0 && pCtx->order == TSDB_ORDER_ASC) || (i == pCtx->size - 1 && pCtx->order == TSDB_ORDER_DESC)) {
*pOutput = (int16_t)(pData[i] - pCtx->param[1].i64);
*pTimestamp = tsList[i];
pOutput += 1;
pTimestamp += 1;
} else {
*pOutput = (int16_t)(pData[i] - pCtx->param[1].i64);
*pTimestamp = tsList[i]; *pTimestamp = tsList[i];
pOutput += 1;
pOutput += 1;
pTimestamp += 1; pTimestamp += 1;
} }
pCtx->param[1].i64 = pData[i]; pCtx->param[1].i64 = pData[i];
pCtx->param[1].nType = pCtx->inputType; pCtx->param[1].nType = pCtx->inputType;
notNullElems++; notNullElems++;
} }
break; break;
} }
case TSDB_DATA_TYPE_TINYINT: { case TSDB_DATA_TYPE_TINYINT: {
int8_t *pData = (int8_t *)data; int8_t *pData = (int8_t *)data;
int8_t *pOutput = (int8_t *)pCtx->pOutput; int8_t *pOutput = (int8_t *)pCtx->pOutput;
for (; i < pCtx->size && i >= 0; i += step) { for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((char *)&pData[i], pCtx->inputType)) { if (pCtx->hasNull && isNull((char *)&pData[i], pCtx->inputType)) {
continue; continue;
} }
if (pCtx->param[1].nType == INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet if (pCtx->param[1].nType != INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet
pCtx->param[1].i64 = pData[i]; *pOutput = (int8_t)(pData[i] - pCtx->param[1].i64); // direct previous may be null
pCtx->param[1].nType = pCtx->inputType;
} else if ((i == 0 && pCtx->order == TSDB_ORDER_ASC) || (i == pCtx->size - 1 && pCtx->order == TSDB_ORDER_DESC)) {
*pOutput = (int8_t)(pData[i] - pCtx->param[1].i64);
*pTimestamp = tsList[i];
pOutput += 1;
pTimestamp += 1;
} else {
*pOutput = (int8_t)(pData[i] - pCtx->param[1].i64);
*pTimestamp = tsList[i]; *pTimestamp = tsList[i];
pOutput += 1;
pOutput += 1;
pTimestamp += 1; pTimestamp += 1;
} }
pCtx->param[1].i64 = pData[i]; pCtx->param[1].i64 = pData[i];
pCtx->param[1].nType = pCtx->inputType; pCtx->param[1].nType = pCtx->inputType;
notNullElems++; notNullElems++;
...@@ -3609,7 +3790,7 @@ static void diff_function(SQLFunctionCtx *pCtx) { ...@@ -3609,7 +3790,7 @@ static void diff_function(SQLFunctionCtx *pCtx) {
default: default:
qError("error input type"); qError("error input type");
} }
// initial value is not set yet // initial value is not set yet
if (pCtx->param[1].nType == INITIAL_VALUE_NOT_ASSIGNED || notNullElems <= 0) { if (pCtx->param[1].nType == INITIAL_VALUE_NOT_ASSIGNED || notNullElems <= 0) {
/* /*
...@@ -3619,36 +3800,24 @@ static void diff_function(SQLFunctionCtx *pCtx) { ...@@ -3619,36 +3800,24 @@ static void diff_function(SQLFunctionCtx *pCtx) {
assert(pCtx->hasNull); assert(pCtx->hasNull);
} else { } else {
int32_t forwardStep = (isFirstBlock) ? notNullElems - 1 : notNullElems; int32_t forwardStep = (isFirstBlock) ? notNullElems - 1 : notNullElems;
GET_RES_INFO(pCtx)->numOfRes += forwardStep; GET_RES_INFO(pCtx)->numOfRes += forwardStep;
} }
} }
#define DIFF_IMPL(ctx, d, type) \
do { \
if ((ctx)->param[1].nType == INITIAL_VALUE_NOT_ASSIGNED) { \
(ctx)->param[1].nType = (ctx)->inputType; \
*(type *)&(ctx)->param[1].i64 = *(type *)(d); \
} else { \
*(type *)(ctx)->pOutput = *(type *)(d) - (*(type *)(&(ctx)->param[1].i64)); \
*(type *)(&(ctx)->param[1].i64) = *(type *)(d); \
*(int64_t *)(ctx)->ptsOutputBuf = GET_TS_DATA(ctx, index); \
} \
} while (0);
static void diff_function_f(SQLFunctionCtx *pCtx, int32_t index) { static void diff_function_f(SQLFunctionCtx *pCtx, int32_t index) {
char *pData = GET_INPUT_DATA(pCtx, index); char *pData = GET_INPUT_DATA(pCtx, index);
if (pCtx->hasNull && isNull(pData, pCtx->inputType)) { if (pCtx->hasNull && isNull(pData, pCtx->inputType)) {
return; return;
} }
// the output start from the second source element // the output start from the second source element
if (pCtx->param[1].nType != INITIAL_VALUE_NOT_ASSIGNED) { // initial value is set if (pCtx->param[1].nType != INITIAL_VALUE_NOT_ASSIGNED) { // initial value is set
GET_RES_INFO(pCtx)->numOfRes += 1; GET_RES_INFO(pCtx)->numOfRes += 1;
} }
int32_t step = 1/*GET_FORWARD_DIRECTION_FACTOR(pCtx->order)*/; int32_t step = 1/*GET_FORWARD_DIRECTION_FACTOR(pCtx->order)*/;
switch (pCtx->inputType) { switch (pCtx->inputType) {
case TSDB_DATA_TYPE_INT: { case TSDB_DATA_TYPE_INT: {
if (pCtx->param[1].nType == INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet if (pCtx->param[1].nType == INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet
...@@ -3684,7 +3853,7 @@ static void diff_function_f(SQLFunctionCtx *pCtx, int32_t index) { ...@@ -3684,7 +3853,7 @@ static void diff_function_f(SQLFunctionCtx *pCtx, int32_t index) {
default: default:
qError("error input type"); qError("error input type");
} }
if (GET_RES_INFO(pCtx)->numOfRes > 0) { if (GET_RES_INFO(pCtx)->numOfRes > 0) {
pCtx->pOutput += pCtx->outputBytes * step; pCtx->pOutput += pCtx->outputBytes * step;
pCtx->ptsOutputBuf = (char *)pCtx->ptsOutputBuf + TSDB_KEYSIZE * step; pCtx->ptsOutputBuf = (char *)pCtx->ptsOutputBuf + TSDB_KEYSIZE * step;
...@@ -4606,7 +4775,7 @@ static void rate_function_f(SQLFunctionCtx *pCtx, int32_t index) { ...@@ -4606,7 +4775,7 @@ static void rate_function_f(SQLFunctionCtx *pCtx, int32_t index) {
pRateInfo->lastValue = v; pRateInfo->lastValue = v;
pRateInfo->lastKey = primaryKey[index]; pRateInfo->lastKey = primaryKey[index];
SET_VAL(pCtx, 1, 1); SET_VAL(pCtx, 1, 1);
// set has result flag // set has result flag
...@@ -4630,7 +4799,7 @@ static void rate_func_copy(SQLFunctionCtx *pCtx) { ...@@ -4630,7 +4799,7 @@ static void rate_func_copy(SQLFunctionCtx *pCtx) {
static void rate_finalizer(SQLFunctionCtx *pCtx) { static void rate_finalizer(SQLFunctionCtx *pCtx) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
SRateInfo *pRateInfo = (SRateInfo *)GET_ROWCELL_INTERBUF(pResInfo); SRateInfo *pRateInfo = (SRateInfo *)GET_ROWCELL_INTERBUF(pResInfo);
if (pRateInfo->hasResult != DATA_SET_FLAG) { if (pRateInfo->hasResult != DATA_SET_FLAG) {
setNull(pCtx->pOutput, TSDB_DATA_TYPE_DOUBLE, sizeof(double)); setNull(pCtx->pOutput, TSDB_DATA_TYPE_DOUBLE, sizeof(double));
return; return;
...@@ -5215,7 +5384,7 @@ SAggFunctionInfo aAggs[] = {{ ...@@ -5215,7 +5384,7 @@ SAggFunctionInfo aAggs[] = {{
"diff", "diff",
TSDB_FUNC_DIFF, TSDB_FUNC_DIFF,
TSDB_FUNC_INVALID_ID, TSDB_FUNC_INVALID_ID,
TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_NEED_TS, TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_NEED_TS,
diff_function_setup, diff_function_setup,
diff_function, diff_function,
diff_function_f, diff_function_f,
...@@ -5315,8 +5484,20 @@ SAggFunctionInfo aAggs[] = {{ ...@@ -5315,8 +5484,20 @@ SAggFunctionInfo aAggs[] = {{
noop1, noop1,
dataBlockRequired, dataBlockRequired,
}, },
{ //32
"derivative", // return table id and the corresponding tags for join match and subscribe
TSDB_FUNC_DERIVATIVE,
TSDB_FUNC_INVALID_ID,
TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_NEED_TS,
deriv_function_setup,
deriv_function,
noop2,
doFinalizer,
noop1,
dataBlockRequired,
},
{ {
// 32 // 33
"_block_dist", // return table id and the corresponding tags for join match and subscribe "_block_dist", // return table id and the corresponding tags for join match and subscribe
TSDB_FUNC_BLKINFO, TSDB_FUNC_BLKINFO,
TSDB_FUNC_BLKINFO, TSDB_FUNC_BLKINFO,
......
...@@ -1681,6 +1681,8 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf ...@@ -1681,6 +1681,8 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf
SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
pRuntimeEnv->prevGroupId = INT32_MIN; pRuntimeEnv->prevGroupId = INT32_MIN;
pRuntimeEnv->enableGroupData = false;
pRuntimeEnv->pQueryAttr = pQueryAttr; pRuntimeEnv->pQueryAttr = pQueryAttr;
pRuntimeEnv->pResultRowHashTable = taosHashInit(numOfTables, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK); pRuntimeEnv->pResultRowHashTable = taosHashInit(numOfTables, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
...@@ -2652,7 +2654,7 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa ...@@ -2652,7 +2654,7 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa
pTableScanInfo->rowCellInfoOffset) != TSDB_CODE_SUCCESS) { pTableScanInfo->rowCellInfoOffset) != TSDB_CODE_SUCCESS) {
longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY); longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
} }
} else if (pQueryAttr->stableQuery && (!pQueryAttr->tsCompQuery)) { // stable aggregate, not interval aggregate or normal column aggregate } else if (pQueryAttr->stableQuery && (!pQueryAttr->tsCompQuery) && (!pQueryAttr->diffQuery)) { // stable aggregate, not interval aggregate or normal column aggregate
doSetTableGroupOutputBuf(pRuntimeEnv, pTableScanInfo->pResultRowInfo, pTableScanInfo->pCtx, doSetTableGroupOutputBuf(pRuntimeEnv, pTableScanInfo->pResultRowInfo, pTableScanInfo->pCtx,
pTableScanInfo->rowCellInfoOffset, pTableScanInfo->numOfOutput, pTableScanInfo->rowCellInfoOffset, pTableScanInfo->numOfOutput,
pRuntimeEnv->current->groupIndex); pRuntimeEnv->current->groupIndex);
...@@ -3119,8 +3121,8 @@ void setDefaultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SOptrBasicInfo *pInfo, i ...@@ -3119,8 +3121,8 @@ void setDefaultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SOptrBasicInfo *pInfo, i
assert(pCtx[i].pOutput != NULL); assert(pCtx[i].pOutput != NULL);
// set the timestamp output buffer for top/bottom/diff query // set the timestamp output buffer for top/bottom/diff query
int32_t functionId = pCtx[i].functionId; int32_t fid = pCtx[i].functionId;
if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_DIFF) { if (fid == TSDB_FUNC_TOP || fid == TSDB_FUNC_BOTTOM || fid == TSDB_FUNC_DIFF || fid == TSDB_FUNC_DERIVATIVE) {
pCtx[i].ptsOutputBuf = pCtx[0].pOutput; pCtx[i].ptsOutputBuf = pCtx[0].pOutput;
} }
} }
...@@ -4271,6 +4273,14 @@ static SSDataBlock* doTableScanImpl(void* param, bool* newgroup) { ...@@ -4271,6 +4273,14 @@ static SSDataBlock* doTableScanImpl(void* param, bool* newgroup) {
pRuntimeEnv->current = *pTableQueryInfo; pRuntimeEnv->current = *pTableQueryInfo;
doTableQueryInfoTimeWindowCheck(pQueryAttr, *pTableQueryInfo); doTableQueryInfoTimeWindowCheck(pQueryAttr, *pTableQueryInfo);
if (pRuntimeEnv->enableGroupData) {
if(pTableScanInfo->prevGroupId != -1 && pTableScanInfo->prevGroupId != (*pTableQueryInfo)->groupIndex) {
*newgroup = true;
}
}
pTableScanInfo->prevGroupId = (*pTableQueryInfo)->groupIndex;
} }
// this function never returns error? // this function never returns error?
...@@ -4417,6 +4427,7 @@ SOperatorInfo* createTableScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* ...@@ -4417,6 +4427,7 @@ SOperatorInfo* createTableScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv*
pInfo->reverseTimes = 0; pInfo->reverseTimes = 0;
pInfo->order = pRuntimeEnv->pQueryAttr->order.order; pInfo->order = pRuntimeEnv->pQueryAttr->order.order;
pInfo->current = 0; pInfo->current = 0;
// pInfo->prevGroupId = -1;
SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo));
pOperator->name = "TableScanOperator"; pOperator->name = "TableScanOperator";
...@@ -4439,6 +4450,8 @@ SOperatorInfo* createTableSeqScanOperator(void* pTsdbQueryHandle, SQueryRuntimeE ...@@ -4439,6 +4450,8 @@ SOperatorInfo* createTableSeqScanOperator(void* pTsdbQueryHandle, SQueryRuntimeE
pInfo->reverseTimes = 0; pInfo->reverseTimes = 0;
pInfo->order = pRuntimeEnv->pQueryAttr->order.order; pInfo->order = pRuntimeEnv->pQueryAttr->order.order;
pInfo->current = 0; pInfo->current = 0;
pInfo->prevGroupId = -1;
pRuntimeEnv->enableGroupData = true;
SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo));
pOperator->name = "TableSeqScanOperator"; pOperator->name = "TableSeqScanOperator";
...@@ -4543,6 +4556,7 @@ SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, SQueryRuntime ...@@ -4543,6 +4556,7 @@ SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, SQueryRuntime
pInfo->reverseTimes = reverseTime; pInfo->reverseTimes = reverseTime;
pInfo->current = 0; pInfo->current = 0;
pInfo->order = pRuntimeEnv->pQueryAttr->order.order; pInfo->order = pRuntimeEnv->pQueryAttr->order.order;
// pInfo->prevGroupId = -1;
SOperatorInfo* pOptr = calloc(1, sizeof(SOperatorInfo)); SOperatorInfo* pOptr = calloc(1, sizeof(SOperatorInfo));
pOptr->name = "DataBlocksOptimizedScanOperator"; pOptr->name = "DataBlocksOptimizedScanOperator";
...@@ -4921,10 +4935,17 @@ static SSDataBlock* doArithmeticOperation(void* param, bool* newgroup) { ...@@ -4921,10 +4935,17 @@ static SSDataBlock* doArithmeticOperation(void* param, bool* newgroup) {
} }
// Return result of the previous group in the firstly. // Return result of the previous group in the firstly.
if (*newgroup && pRes->info.rows > 0) { if (*newgroup) {
pArithInfo->existDataBlock = pBlock; if (pRes->info.rows > 0) {
clearNumOfRes(pInfo->pCtx, pOperator->numOfOutput); pArithInfo->existDataBlock = pBlock;
return pInfo->pRes; clearNumOfRes(pInfo->pCtx, pOperator->numOfOutput);
return pInfo->pRes;
} else { // init output buffer for a new group data
for (int32_t j = 0; j < pOperator->numOfOutput; ++j) {
aAggs[pInfo->pCtx[j].functionId].xFinalize(&pInfo->pCtx[j]);
}
initCtxOutputBuffer(pInfo->pCtx, pOperator->numOfOutput);
}
} }
STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current; STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
...@@ -6921,6 +6942,10 @@ int32_t doCreateFilterInfo(SColumnInfo* pCols, int32_t numOfCols, int32_t numOfF ...@@ -6921,6 +6942,10 @@ int32_t doCreateFilterInfo(SColumnInfo* pCols, int32_t numOfCols, int32_t numOfF
} }
pSingleColFilter->bytes = pCols[i].bytes; pSingleColFilter->bytes = pCols[i].bytes;
if (lower == TSDB_RELATION_IN) {
buildFilterSetFromBinary(&pSingleColFilter->q, (char *)(pSingleColFilter->filterInfo.pz), (int32_t)(pSingleColFilter->filterInfo.len));
}
} }
j++; j++;
...@@ -6933,6 +6958,9 @@ int32_t doCreateFilterInfo(SColumnInfo* pCols, int32_t numOfCols, int32_t numOfF ...@@ -6933,6 +6958,9 @@ int32_t doCreateFilterInfo(SColumnInfo* pCols, int32_t numOfCols, int32_t numOfF
void* doDestroyFilterInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols) { void* doDestroyFilterInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols) {
for (int32_t i = 0; i < numOfFilterCols; ++i) { for (int32_t i = 0; i < numOfFilterCols; ++i) {
if (pFilterInfo[i].numOfFilters > 0) { if (pFilterInfo[i].numOfFilters > 0) {
if (pFilterInfo[i].pFilters->filterInfo.lowerRelOptr == TSDB_RELATION_IN) {
taosHashCleanup((SHashObj *)(pFilterInfo[i].pFilters->q));
}
tfree(pFilterInfo[i].pFilters); tfree(pFilterInfo[i].pFilters);
} }
} }
...@@ -7442,7 +7470,6 @@ int32_t doDumpQueryResult(SQInfo *pQInfo, char *data) { ...@@ -7442,7 +7470,6 @@ int32_t doDumpQueryResult(SQInfo *pQInfo, char *data) {
doCopyQueryResultToMsg(pQInfo, (int32_t)pRuntimeEnv->outputBuf->info.rows, data); doCopyQueryResultToMsg(pQInfo, (int32_t)pRuntimeEnv->outputBuf->info.rows, data);
} }
pRuntimeEnv->resultInfo.total += pRuntimeEnv->outputBuf->info.rows;
qDebug("QInfo:0x%"PRIx64" current numOfRes rows:%d, total:%" PRId64, pQInfo->qId, qDebug("QInfo:0x%"PRIx64" current numOfRes rows:%d, total:%" PRId64, pQInfo->qId,
pRuntimeEnv->outputBuf->info.rows, pRuntimeEnv->resultInfo.total); pRuntimeEnv->outputBuf->info.rows, pRuntimeEnv->resultInfo.total);
......
...@@ -253,6 +253,27 @@ bool isNullOperator(SColumnFilterElem *pFilter, const char* minval, const char* ...@@ -253,6 +253,27 @@ bool isNullOperator(SColumnFilterElem *pFilter, const char* minval, const char*
bool notNullOperator(SColumnFilterElem *pFilter, const char* minval, const char* maxval, int16_t type) { bool notNullOperator(SColumnFilterElem *pFilter, const char* minval, const char* maxval, int16_t type) {
return true; return true;
} }
bool inOperator(SColumnFilterElem *pFilter, const char* minval, const char* maxval, int16_t type) {
if (type == TSDB_DATA_TYPE_BOOL || type == TSDB_DATA_TYPE_TINYINT || type == TSDB_DATA_TYPE_SMALLINT || type == TSDB_DATA_TYPE_BIGINT || type == TSDB_DATA_TYPE_INT) {
int64_t minv = -1, maxv = -1;
GET_TYPED_DATA(minv, int64_t, type, minval);
GET_TYPED_DATA(maxv, int64_t, type, maxval);
if (minv == maxv) {
return NULL != taosHashGet((SHashObj *)pFilter->q, (char *)&minv, sizeof(minv));
}
return true;
} else if (type == TSDB_DATA_TYPE_DOUBLE || type == TSDB_DATA_TYPE_DOUBLE) {
double v;
GET_TYPED_DATA(v, double, type, minval);
return NULL != taosHashGet((SHashObj *)pFilter->q, (char *)&v, sizeof(v));
} else if (type == TSDB_DATA_TYPE_BINARY) {
return NULL != taosHashGet((SHashObj *)pFilter->q, varDataVal(minval), varDataLen(minval));
} else if (type == TSDB_DATA_TYPE_NCHAR){
return NULL != taosHashGet((SHashObj *)pFilter->q, varDataVal(minval), varDataLen(minval));
}
return false;
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
bool rangeFilter_ii(SColumnFilterElem *pFilter, const char *minval, const char *maxval, int16_t type) { bool rangeFilter_ii(SColumnFilterElem *pFilter, const char *minval, const char *maxval, int16_t type) {
...@@ -389,6 +410,7 @@ bool (*filterOperators[])(SColumnFilterElem *pFilter, const char* minval, const ...@@ -389,6 +410,7 @@ bool (*filterOperators[])(SColumnFilterElem *pFilter, const char* minval, const
likeOperator, likeOperator,
isNullOperator, isNullOperator,
notNullOperator, notNullOperator,
inOperator,
}; };
bool (*rangeFilterOperators[])(SColumnFilterElem *pFilter, const char* minval, const char* maxval, int16_t type) = { bool (*rangeFilterOperators[])(SColumnFilterElem *pFilter, const char* minval, const char* maxval, int16_t type) = {
...@@ -397,6 +419,7 @@ bool (*rangeFilterOperators[])(SColumnFilterElem *pFilter, const char* minval, c ...@@ -397,6 +419,7 @@ bool (*rangeFilterOperators[])(SColumnFilterElem *pFilter, const char* minval, c
rangeFilter_ie, rangeFilter_ie,
rangeFilter_ei, rangeFilter_ei,
rangeFilter_ii, rangeFilter_ii,
}; };
__filter_func_t getFilterOperator(int32_t lowerOptr, int32_t upperOptr) { __filter_func_t getFilterOperator(int32_t lowerOptr, int32_t upperOptr) {
......
...@@ -531,7 +531,7 @@ SArray* createTableScanPlan(SQueryAttr* pQueryAttr) { ...@@ -531,7 +531,7 @@ SArray* createTableScanPlan(SQueryAttr* pQueryAttr) {
} else { } else {
if (pQueryAttr->queryBlockDist) { if (pQueryAttr->queryBlockDist) {
op = OP_TableBlockInfoScan; op = OP_TableBlockInfoScan;
} else if (pQueryAttr->tsCompQuery || pQueryAttr->pointInterpQuery) { } else if (pQueryAttr->tsCompQuery || pQueryAttr->pointInterpQuery || pQueryAttr->diffQuery) {
op = OP_TableSeqScan; op = OP_TableSeqScan;
} else if (pQueryAttr->needReverseScan) { } else if (pQueryAttr->needReverseScan) {
op = OP_DataBlocksOptScan; op = OP_DataBlocksOptScan;
...@@ -605,7 +605,7 @@ SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr) { ...@@ -605,7 +605,7 @@ SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr) {
taosArrayPush(plan, &op); taosArrayPush(plan, &op);
} }
} else if (pQueryAttr->simpleAgg) { } else if (pQueryAttr->simpleAgg) {
if (pQueryAttr->stableQuery && !pQueryAttr->tsCompQuery) { if (pQueryAttr->stableQuery && !pQueryAttr->tsCompQuery && !pQueryAttr->diffQuery) {
op = OP_MultiTableAggregate; op = OP_MultiTableAggregate;
} else { } else {
op = OP_Aggregate; op = OP_Aggregate;
......
...@@ -241,15 +241,16 @@ bool qTableQuery(qinfo_t qinfo, uint64_t *qId) { ...@@ -241,15 +241,16 @@ bool qTableQuery(qinfo_t qinfo, uint64_t *qId) {
bool newgroup = false; bool newgroup = false;
pRuntimeEnv->outputBuf = pRuntimeEnv->proot->exec(pRuntimeEnv->proot, &newgroup); pRuntimeEnv->outputBuf = pRuntimeEnv->proot->exec(pRuntimeEnv->proot, &newgroup);
pRuntimeEnv->resultInfo.total += GET_NUM_OF_RESULTS(pRuntimeEnv);
if (isQueryKilled(pQInfo)) { if (isQueryKilled(pQInfo)) {
qDebug("QInfo:0x%"PRIx64" query is killed", pQInfo->qId); qDebug("QInfo:0x%"PRIx64" query is killed", pQInfo->qId);
} else if (GET_NUM_OF_RESULTS(pRuntimeEnv) == 0) { } else if (GET_NUM_OF_RESULTS(pRuntimeEnv) == 0) {
qDebug("QInfo:0x%"PRIx64" over, %u tables queried, %"PRId64" rows are returned", pQInfo->qId, pRuntimeEnv->tableqinfoGroupInfo.numOfTables, qDebug("QInfo:0x%"PRIx64" over, %u tables queried, total %"PRId64" rows returned", pQInfo->qId, pRuntimeEnv->tableqinfoGroupInfo.numOfTables,
pRuntimeEnv->resultInfo.total); pRuntimeEnv->resultInfo.total);
} else { } else {
qDebug("QInfo:0x%"PRIx64" query paused, %d rows returned, numOfTotal:%" PRId64 " rows", qDebug("QInfo:0x%"PRIx64" query paused, %d rows returned, total:%" PRId64 " rows", pQInfo->qId,
pQInfo->qId, GET_NUM_OF_RESULTS(pRuntimeEnv), pRuntimeEnv->resultInfo.total + GET_NUM_OF_RESULTS(pRuntimeEnv)); GET_NUM_OF_RESULTS(pRuntimeEnv), pRuntimeEnv->resultInfo.total);
} }
return doBuildResCheck(pQInfo); return doBuildResCheck(pQInfo);
......
...@@ -2397,6 +2397,8 @@ static void destroyHelper(void* param) { ...@@ -2397,6 +2397,8 @@ static void destroyHelper(void* param) {
tQueryInfo* pInfo = (tQueryInfo*)param; tQueryInfo* pInfo = (tQueryInfo*)param;
if (pInfo->optr != TSDB_RELATION_IN) { if (pInfo->optr != TSDB_RELATION_IN) {
tfree(pInfo->q); tfree(pInfo->q);
} else {
taosHashCleanup((SHashObj *)(pInfo->q));
} }
free(param); free(param);
...@@ -3155,11 +3157,23 @@ void filterPrepare(void* expr, void* param) { ...@@ -3155,11 +3157,23 @@ void filterPrepare(void* expr, void* param) {
pInfo->sch = *pSchema; pInfo->sch = *pSchema;
pInfo->optr = pExpr->_node.optr; pInfo->optr = pExpr->_node.optr;
pInfo->compare = getComparFunc(pSchema->type, pInfo->optr); pInfo->compare = getComparFunc(pInfo->sch.type, pInfo->optr);
pInfo->indexed = pTSSchema->columns->colId == pInfo->sch.colId; pInfo->indexed = pTSSchema->columns->colId == pInfo->sch.colId;
if (pInfo->optr == TSDB_RELATION_IN) { if (pInfo->optr == TSDB_RELATION_IN) {
pInfo->q = (char*) pCond->arr; int dummy = -1;
SHashObj *pObj = NULL;
if (pInfo->sch.colId == TSDB_TBNAME_COLUMN_INDEX) {
pObj = taosHashInit(256, taosGetDefaultHashFunction(pInfo->sch.type), true, false);
SArray *arr = (SArray *)(pCond->arr);
for (size_t i = 0; i < taosArrayGetSize(arr); i++) {
char* p = taosArrayGetP(arr, i);
taosHashPut(pObj, varDataVal(p),varDataLen(p), &dummy, sizeof(dummy));
}
} else {
buildFilterSetFromBinary((void **)&pObj, pCond->pz, pCond->nLen);
}
pInfo->q = (char *)pObj;
} else if (pCond != NULL) { } else if (pCond != NULL) {
uint32_t size = pCond->nLen * TSDB_NCHAR_SIZE; uint32_t size = pCond->nLen * TSDB_NCHAR_SIZE;
if (size < (uint32_t)pSchema->bytes) { if (size < (uint32_t)pSchema->bytes) {
...@@ -3330,6 +3344,20 @@ static bool tableFilterFp(const void* pNode, void* param) { ...@@ -3330,6 +3344,20 @@ static bool tableFilterFp(const void* pNode, void* param) {
} else if (pInfo->optr == TSDB_RELATION_NOTNULL) { } else if (pInfo->optr == TSDB_RELATION_NOTNULL) {
return (val != NULL) && (!isNull(val, pInfo->sch.type)); return (val != NULL) && (!isNull(val, pInfo->sch.type));
} }
} else if (pInfo->optr == TSDB_RELATION_IN) {
int type = pInfo->sch.type;
if (type == TSDB_DATA_TYPE_BOOL || type == TSDB_DATA_TYPE_TINYINT || type == TSDB_DATA_TYPE_SMALLINT || type == TSDB_DATA_TYPE_BIGINT || type == TSDB_DATA_TYPE_INT) {
int64_t v;
GET_TYPED_DATA(v, int64_t, pInfo->sch.type, val);
return NULL != taosHashGet((SHashObj *)pInfo->q, (char *)&v, sizeof(v));
} else if (type == TSDB_DATA_TYPE_DOUBLE || type == TSDB_DATA_TYPE_DOUBLE) {
double v;
GET_TYPED_DATA(v, double, pInfo->sch.type, val);
return NULL != taosHashGet((SHashObj *)pInfo->q, (char *)&v, sizeof(v));
} else if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR){
return NULL != taosHashGet((SHashObj *)pInfo->q, varDataVal(val), varDataLen(val));
}
} }
int32_t ret = 0; int32_t ret = 0;
...@@ -3672,14 +3700,18 @@ static int32_t setQueryCond(tQueryInfo *queryColInfo, SQueryCond* pCond) { ...@@ -3672,14 +3700,18 @@ static int32_t setQueryCond(tQueryInfo *queryColInfo, SQueryCond* pCond) {
if (optr == TSDB_RELATION_GREATER || optr == TSDB_RELATION_GREATER_EQUAL || if (optr == TSDB_RELATION_GREATER || optr == TSDB_RELATION_GREATER_EQUAL ||
optr == TSDB_RELATION_EQUAL || optr == TSDB_RELATION_NOT_EQUAL) { optr == TSDB_RELATION_EQUAL || optr == TSDB_RELATION_NOT_EQUAL) {
pCond->start = calloc(1, sizeof(SEndPoint)); pCond->start = calloc(1, sizeof(SEndPoint));
pCond->start->optr = queryColInfo->optr; pCond->start->optr = queryColInfo->optr;
pCond->start->v = queryColInfo->q; pCond->start->v = queryColInfo->q;
} else if (optr == TSDB_RELATION_LESS || optr == TSDB_RELATION_LESS_EQUAL) { } else if (optr == TSDB_RELATION_LESS || optr == TSDB_RELATION_LESS_EQUAL) {
pCond->end = calloc(1, sizeof(SEndPoint)); pCond->end = calloc(1, sizeof(SEndPoint));
pCond->end->optr = queryColInfo->optr; pCond->end->optr = queryColInfo->optr;
pCond->end->v = queryColInfo->q; pCond->end->v = queryColInfo->q;
} else if (optr == TSDB_RELATION_IN || optr == TSDB_RELATION_LIKE) { } else if (optr == TSDB_RELATION_IN) {
pCond->start = calloc(1, sizeof(SEndPoint));
pCond->start->optr = queryColInfo->optr;
pCond->start->v = queryColInfo->q;
} else if (optr == TSDB_RELATION_LIKE) {
assert(0); assert(0);
} }
...@@ -3764,6 +3796,19 @@ static void queryIndexedColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SAr ...@@ -3764,6 +3796,19 @@ static void queryIndexedColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SAr
taosArrayPush(result, &info); taosArrayPush(result, &info);
} }
} else if (optr == TSDB_RELATION_IN) {
while(tSkipListIterNext(iter)) {
SSkipListNode* pNode = tSkipListIterGet(iter);
int32_t ret = pQueryInfo->compare(SL_GET_NODE_KEY(pSkipList, pNode), cond.start->v);
if (ret != 0) {
break;
}
STableKeyInfo info = {.pTable = (void*)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
taosArrayPush(result, &info);
}
} else { } else {
assert(0); assert(0);
} }
...@@ -3857,7 +3902,7 @@ void getTableListfromSkipList(tExprNode *pExpr, SSkipList *pSkipList, SArray *re ...@@ -3857,7 +3902,7 @@ void getTableListfromSkipList(tExprNode *pExpr, SSkipList *pSkipList, SArray *re
param->setupInfoFn(pExpr, param->pExtInfo); param->setupInfoFn(pExpr, param->pExtInfo);
tQueryInfo *pQueryInfo = pExpr->_node.info; tQueryInfo *pQueryInfo = pExpr->_node.info;
if (pQueryInfo->indexed && pQueryInfo->optr != TSDB_RELATION_LIKE) { if (pQueryInfo->indexed && (pQueryInfo->optr != TSDB_RELATION_LIKE && pQueryInfo->optr != TSDB_RELATION_IN)) {
queryIndexedColumn(pSkipList, pQueryInfo, result); queryIndexedColumn(pSkipList, pQueryInfo, result);
} else { } else {
queryIndexlessColumn(pSkipList, pQueryInfo, result, param->nodeFilterFn); queryIndexlessColumn(pSkipList, pQueryInfo, result, param->nodeFilterFn);
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "ttype.h" #include "ttype.h"
#include "tcompare.h" #include "tcompare.h"
#include "tarray.h" #include "tarray.h"
#include "hash.h"
int32_t compareInt32Val(const void *pLeft, const void *pRight) { int32_t compareInt32Val(const void *pLeft, const void *pRight) {
int32_t left = GET_INT32_VAL(pLeft), right = GET_INT32_VAL(pRight); int32_t left = GET_INT32_VAL(pLeft), right = GET_INT32_VAL(pRight);
...@@ -291,9 +292,12 @@ int32_t taosArrayCompareString(const void* a, const void* b) { ...@@ -291,9 +292,12 @@ int32_t taosArrayCompareString(const void* a, const void* b) {
return compareLenPrefixedStr(x, y); return compareLenPrefixedStr(x, y);
} }
static int32_t compareFindStrInArray(const void* pLeft, const void* pRight) { //static int32_t compareFindStrInArray(const void* pLeft, const void* pRight) {
const SArray* arr = (const SArray*) pRight; // const SArray* arr = (const SArray*) pRight;
return taosArraySearchString(arr, pLeft, taosArrayCompareString, TD_EQ) == NULL ? 0 : 1; // return taosArraySearchString(arr, pLeft, taosArrayCompareString, TD_EQ) == NULL ? 0 : 1;
//}
static int32_t compareFindItemInSet(const void *pLeft, const void* pRight) {
return NULL != taosHashGet((SHashObj *)pRight, varDataVal(pLeft), varDataLen(pLeft)) ? 1 : 0;
} }
static int32_t compareWStrPatternComp(const void* pLeft, const void* pRight) { static int32_t compareWStrPatternComp(const void* pLeft, const void* pRight) {
...@@ -325,7 +329,7 @@ __compar_fn_t getComparFunc(int32_t type, int32_t optr) { ...@@ -325,7 +329,7 @@ __compar_fn_t getComparFunc(int32_t type, int32_t optr) {
if (optr == TSDB_RELATION_LIKE) { /* wildcard query using like operator */ if (optr == TSDB_RELATION_LIKE) { /* wildcard query using like operator */
comparFn = compareStrPatternComp; comparFn = compareStrPatternComp;
} else if (optr == TSDB_RELATION_IN) { } else if (optr == TSDB_RELATION_IN) {
comparFn = compareFindStrInArray; comparFn = compareFindItemInSet;
} else { /* normal relational comparFn */ } else { /* normal relational comparFn */
comparFn = compareLenPrefixedStr; comparFn = compareLenPrefixedStr;
} }
......
...@@ -342,7 +342,9 @@ void verify_prepare(TAOS* taos) { ...@@ -342,7 +342,9 @@ void verify_prepare(TAOS* taos) {
sql = "insert into m1 values(?,?,?,?,?,?,?,?,?,?)"; sql = "insert into m1 values(?,?,?,?,?,?,?,?,?,?)";
code = taos_stmt_prepare(stmt, sql, 0); code = taos_stmt_prepare(stmt, sql, 0);
if (code != 0){ if (code != 0){
printf("\033[31mfailed to execute taos_stmt_prepare. code:0x%x\033[0m\n", code); printf("\033[31mfailed to execute taos_stmt_prepare. error:%s\033[0m\n", taos_stmt_errstr(stmt));
taos_stmt_close(stmt);
return;
} }
v.ts = 1591060628000; v.ts = 1591060628000;
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
...@@ -365,8 +367,8 @@ void verify_prepare(TAOS* taos) { ...@@ -365,8 +367,8 @@ void verify_prepare(TAOS* taos) {
taos_stmt_add_batch(stmt); taos_stmt_add_batch(stmt);
} }
if (taos_stmt_execute(stmt) != 0) { if (taos_stmt_execute(stmt) != 0) {
printf("\033[31mfailed to execute insert statement.error:%s\033[0m\n", taos_stmt_errstr(stmt));
taos_stmt_close(stmt); taos_stmt_close(stmt);
printf("\033[31mfailed to execute insert statement.\033[0m\n");
return; return;
} }
taos_stmt_close(stmt); taos_stmt_close(stmt);
...@@ -378,8 +380,8 @@ void verify_prepare(TAOS* taos) { ...@@ -378,8 +380,8 @@ void verify_prepare(TAOS* taos) {
v.v2 = 15; v.v2 = 15;
taos_stmt_bind_param(stmt, params + 2); taos_stmt_bind_param(stmt, params + 2);
if (taos_stmt_execute(stmt) != 0) { if (taos_stmt_execute(stmt) != 0) {
printf("\033[31mfailed to execute select statement.error:%s\033[0m\n", taos_stmt_errstr(stmt));
taos_stmt_close(stmt); taos_stmt_close(stmt);
printf("\033[31mfailed to execute select statement.\033[0m\n");
return; return;
} }
...@@ -530,12 +532,16 @@ void verify_prepare2(TAOS* taos) { ...@@ -530,12 +532,16 @@ void verify_prepare2(TAOS* taos) {
sql = "insert into ? (ts, b, v1, v2, v4, v8, f4, f8, bin, blob) values(?,?,?,?,?,?,?,?,?,?)"; sql = "insert into ? (ts, b, v1, v2, v4, v8, f4, f8, bin, blob) values(?,?,?,?,?,?,?,?,?,?)";
code = taos_stmt_prepare(stmt, sql, 0); code = taos_stmt_prepare(stmt, sql, 0);
if (code != 0) { if (code != 0) {
printf("\033[31mfailed to execute taos_stmt_prepare. code:0x%x\033[0m\n", code); printf("\033[31mfailed to execute taos_stmt_prepare. error:%s\033[0m\n", taos_stmt_errstr(stmt));
taos_stmt_close(stmt);
return;
} }
code = taos_stmt_set_tbname(stmt, "m1"); code = taos_stmt_set_tbname(stmt, "m1");
if (code != 0){ if (code != 0){
printf("\033[31mfailed to execute taos_stmt_prepare. code:0x%x\033[0m\n", code); printf("\033[31mfailed to execute taos_stmt_prepare. error:%s\033[0m\n", taos_stmt_errstr(stmt));
taos_stmt_close(stmt);
return;
} }
int64_t ts = 1591060628000; int64_t ts = 1591060628000;
...@@ -569,7 +575,8 @@ void verify_prepare2(TAOS* taos) { ...@@ -569,7 +575,8 @@ void verify_prepare2(TAOS* taos) {
taos_stmt_add_batch(stmt); taos_stmt_add_batch(stmt);
if (taos_stmt_execute(stmt) != 0) { if (taos_stmt_execute(stmt) != 0) {
printf("\033[31mfailed to execute insert statement.\033[0m\n"); printf("\033[31mfailed to execute insert statement.error:%s\033[0m\n", taos_stmt_errstr(stmt));
taos_stmt_close(stmt);
return; return;
} }
...@@ -596,7 +603,8 @@ void verify_prepare2(TAOS* taos) { ...@@ -596,7 +603,8 @@ void verify_prepare2(TAOS* taos) {
taos_stmt_bind_param(stmt, qparams); taos_stmt_bind_param(stmt, qparams);
if (taos_stmt_execute(stmt) != 0) { if (taos_stmt_execute(stmt) != 0) {
printf("\033[31mfailed to execute select statement.\033[0m\n"); printf("\033[31mfailed to execute select statement.error:%s\033[0m\n", taos_stmt_errstr(stmt));
taos_stmt_close(stmt);
return; return;
} }
...@@ -776,12 +784,16 @@ void verify_prepare3(TAOS* taos) { ...@@ -776,12 +784,16 @@ void verify_prepare3(TAOS* taos) {
sql = "insert into ? using st1 tags(?,?) values(?,?,?,?,?,?,?,?,?,?)"; sql = "insert into ? using st1 tags(?,?) values(?,?,?,?,?,?,?,?,?,?)";
code = taos_stmt_prepare(stmt, sql, 0); code = taos_stmt_prepare(stmt, sql, 0);
if (code != 0){ if (code != 0){
printf("\033[31mfailed to execute taos_stmt_prepare. code:0x%x\033[0m\n", code); printf("\033[31mfailed to execute taos_stmt_prepare. error:%s\033[0m\n", taos_stmt_errstr(stmt));
taos_stmt_close(stmt);
return;
} }
code = taos_stmt_set_tbname_tags(stmt, "m1", tags); code = taos_stmt_set_tbname_tags(stmt, "m1", tags);
if (code != 0){ if (code != 0){
printf("\033[31mfailed to execute taos_stmt_prepare. code:0x%x\033[0m\n", code); printf("\033[31mfailed to execute taos_stmt_prepare. error:%s\033[0m\n", taos_stmt_errstr(stmt));
taos_stmt_close(stmt);
return;
} }
int64_t ts = 1591060628000; int64_t ts = 1591060628000;
...@@ -815,7 +827,8 @@ void verify_prepare3(TAOS* taos) { ...@@ -815,7 +827,8 @@ void verify_prepare3(TAOS* taos) {
taos_stmt_add_batch(stmt); taos_stmt_add_batch(stmt);
if (taos_stmt_execute(stmt) != 0) { if (taos_stmt_execute(stmt) != 0) {
printf("\033[31mfailed to execute insert statement.\033[0m\n"); printf("\033[31mfailed to execute insert statement.error:%s\033[0m\n", taos_stmt_errstr(stmt));
taos_stmt_close(stmt);
return; return;
} }
taos_stmt_close(stmt); taos_stmt_close(stmt);
...@@ -842,7 +855,8 @@ void verify_prepare3(TAOS* taos) { ...@@ -842,7 +855,8 @@ void verify_prepare3(TAOS* taos) {
taos_stmt_bind_param(stmt, qparams); taos_stmt_bind_param(stmt, qparams);
if (taos_stmt_execute(stmt) != 0) { if (taos_stmt_execute(stmt) != 0) {
printf("\033[31mfailed to execute select statement.\033[0m\n"); printf("\033[31mfailed to execute select statement.error:%s\033[0m\n", taos_stmt_errstr(stmt));
taos_stmt_close(stmt);
return; return;
} }
......
###################################################################
# Copyright (c) 2016 by TAOS Technologies, Inc.
# All rights reserved.
#
# This file is proprietary and confidential to TAOS Technologies.
# No part of this file may be reproduced, stored, transmitted,
# disclosed or used in any form or by any means other than as
# expressly provided by the written permission from Jianhui Tao
#
###################################################################
# -*- coding: utf-8 -*-
import sys
import taos
from util.log import tdLog
from util.cases import tdCases
from util.sql import tdSql
from util.dnodes import tdDnodes
class TDTestCase:
def init(self, conn, logSql):
tdLog.debug("start to execute %s" % __file__)
tdSql.init(conn.cursor(), logSql)
self.ts = 1538548685000
def run(self):
tdSql.prepare()
print("==============step1")
tdSql.execute(
"create table if not exists st (ts timestamp, tagtype int) tags(dev nchar(50))")
tdSql.execute(
'CREATE TABLE if not exists dev_001 using st tags("dev_01")')
tdSql.execute(
'CREATE TABLE if not exists dev_002 using st tags("dev_02")')
print("==============step2")
tdSql.error("select * from db.st where ts in ('2020-05-13 10:00:00.000')")
tdSql.execute(
"""INSERT INTO dev_001(ts, tagtype) VALUES('2020-05-13 10:00:00.000', 1),
('2020-05-13 10:00:00.001', 1)
dev_002 VALUES('2020-05-13 10:00:00.001', 1)""")
# TAG nchar
tdSql.query('select count(ts) from db.st where dev in ("dev_01")')
tdSql.checkRows(1)
tdSql.checkData(0, 0, 2)
tdSql.query('select count(ts) from db.st where dev in ("dev_01", "dev_01")')
tdSql.checkRows(1)
tdSql.checkData(0, 0, 2)
tdSql.query('select count(ts) from db.st where dev in ("dev_01", "dev_01", "dev_02")')
tdSql.checkRows(1)
tdSql.checkData(0, 0, 3)
# colume int
tdSql.query("select count(ts) from db.st where tagtype in (1)")
tdSql.checkRows(1)
tdSql.checkData(0, 0, 3)
tdSql.query("select count(ts) from db.st where tagtype in (1, 2)")
tdSql.checkRows(1)
tdSql.checkData(0, 0, 3)
tdSql.execute(
"""INSERT INTO dev_001(ts, tagtype) VALUES('2020-05-13 10:00:01.000', 2),
('2020-05-13 10:00:02.001', 2)
dev_002 VALUES('2020-05-13 10:00:03.001', 2)""")
tdSql.query("select count(ts) from db.st where tagtype in (1, 2)")
tdSql.checkRows(1)
tdSql.checkData(0, 0, 6)
tdSql.execute("create table tb(ts timestamp, c1 int, c2 binary(10), c3 nchar(10), c4 float, c5 bool)")
for i in range(10):
tdSql.execute("insert into tb values(%d, %d, 'binary%d', 'nchar%d', %f, %d)" % (self.ts + i, i, i, i, i + 0.1, i % 2))
#binary
tdSql.query('select count(ts) from db.tb where c2 in ("binary1")')
tdSql.checkRows(1)
tdSql.checkData(0, 0, 1)
tdSql.query('select count(ts) from db.tb where c2 in ("binary1", "binary2", "binary1")')
tdSql.checkRows(1)
tdSql.checkData(0, 0, 2)
#bool
#tdSql.query('select count(ts) from db.tb where c5 in (true)')
#tdSql.checkRows(1)
#tdSql.checkData(0, 0, 5)
#float
#tdSql.query('select count(ts) from db.tb where c4 in (0.1)')
#tdSql.checkRows(1)
#tdSql.checkData(0, 0, 1)
#nchar
tdSql.query('select count(ts) from db.tb where c3 in ("nchar0")')
tdSql.checkRows(1)
tdSql.checkData(0, 0, 1)
#tdSql.query("select tbname, dev from dev_001")
#tdSql.checkRows(1)
#tdSql.checkData(0, 0, 'dev_001')
#tdSql.checkData(0, 1, 'dev_01')
#tdSql.query("select tbname, dev, tagtype from dev_001")
#tdSql.checkRows(2)
### test case for https://jira.taosdata.com:18080/browse/TD-1930
#tdSql.execute("create table tb(ts timestamp, c1 int, c2 binary(10), c3 nchar(10), c4 float, c5 bool)")
#for i in range(10):
# tdSql.execute("insert into tb values(%d, %d, 'binary%d', 'nchar%d', %f, %d)" % (self.ts + i, i, i, i, i + 0.1, i % 2))
#
#tdSql.error("select * from tb where c2 = binary2")
#tdSql.error("select * from tb where c3 = nchar2")
#tdSql.query("select * from tb where c2 = 'binary2' ")
#tdSql.checkRows(1)
#tdSql.query("select * from tb where c3 = 'nchar2' ")
#tdSql.checkRows(1)
#tdSql.query("select * from tb where c1 = '2' ")
#tdSql.checkRows(1)
#tdSql.query("select * from tb where c1 = 2 ")
#tdSql.checkRows(1)
#tdSql.query("select * from tb where c4 = '0.1' ")
#tdSql.checkRows(1)
#tdSql.query("select * from tb where c4 = 0.1 ")
#tdSql.checkRows(1)
#tdSql.query("select * from tb where c5 = true ")
#tdSql.checkRows(5)
#tdSql.query("select * from tb where c5 = 'true' ")
#tdSql.checkRows(5)
## For jira: https://jira.taosdata.com:18080/browse/TD-2850
#tdSql.execute("create database 'Test' ")
#tdSql.execute("use 'Test' ")
#tdSql.execute("create table 'TB'(ts timestamp, 'Col1' int) tags('Tag1' int)")
#tdSql.execute("insert into 'Tb0' using tb tags(1) values(now, 1)")
#tdSql.query("select * from tb")
#tdSql.checkRows(1)
def stop(self):
tdSql.close()
tdLog.success("%s successfully executed" % __file__)
tdCases.addWindows(__file__, TDTestCase())
tdCases.addLinux(__file__, TDTestCase())
...@@ -1458,8 +1458,783 @@ int stmt_funcb_autoctb3(TAOS_STMT *stmt) { ...@@ -1458,8 +1458,783 @@ int stmt_funcb_autoctb3(TAOS_STMT *stmt) {
//1 tables 10 records
int stmt_funcb_autoctb4(TAOS_STMT *stmt) {
struct {
int64_t *ts;
int8_t b[10];
int8_t v1[10];
int16_t v2[10];
int32_t v4[10];
int64_t v8[10];
float f4[10];
double f8[10];
char bin[10][40];
} v = {0};
v.ts = malloc(sizeof(int64_t) * 1 * 10);
int *lb = malloc(10 * sizeof(int));
TAOS_BIND *tags = calloc(1, sizeof(TAOS_BIND) * 9 * 1);
TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * 1*5);
// int one_null = 1;
int one_not_null = 0;
char* is_null = malloc(sizeof(char) * 10);
char* no_null = malloc(sizeof(char) * 10);
for (int i = 0; i < 10; ++i) {
lb[i] = 40;
no_null[i] = 0;
is_null[i] = (i % 10 == 2) ? 1 : 0;
v.b[i] = (int8_t)(i % 2);
v.v1[i] = (int8_t)((i+1) % 2);
v.v2[i] = (int16_t)i;
v.v4[i] = (int32_t)(i+1);
v.v8[i] = (int64_t)(i+2);
v.f4[i] = (float)(i+3);
v.f8[i] = (double)(i+4);
memset(v.bin[i], '0'+i%10, 40);
}
for (int i = 0; i < 5; i+=5) {
params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
params[i+0].buffer_length = sizeof(int64_t);
params[i+0].buffer = &v.ts[10*i/10];
params[i+0].length = NULL;
params[i+0].is_null = no_null;
params[i+0].num = 10;
params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL;
params[i+1].buffer_length = sizeof(int8_t);
params[i+1].buffer = v.b;
params[i+1].length = NULL;
params[i+1].is_null = is_null;
params[i+1].num = 10;
params[i+2].buffer_type = TSDB_DATA_TYPE_INT;
params[i+2].buffer_length = sizeof(int32_t);
params[i+2].buffer = v.v4;
params[i+2].length = NULL;
params[i+2].is_null = is_null;
params[i+2].num = 10;
params[i+3].buffer_type = TSDB_DATA_TYPE_BIGINT;
params[i+3].buffer_length = sizeof(int64_t);
params[i+3].buffer = v.v8;
params[i+3].length = NULL;
params[i+3].is_null = is_null;
params[i+3].num = 10;
params[i+4].buffer_type = TSDB_DATA_TYPE_DOUBLE;
params[i+4].buffer_length = sizeof(double);
params[i+4].buffer = v.f8;
params[i+4].length = NULL;
params[i+4].is_null = is_null;
params[i+4].num = 10;
}
int64_t tts = 1591060628000;
for (int i = 0; i < 10; ++i) {
v.ts[i] = tts + i;
}
for (int i = 0; i < 1; ++i) {
tags[i+0].buffer_type = TSDB_DATA_TYPE_BOOL;
tags[i+0].buffer = v.b;
tags[i+0].is_null = &one_not_null;
tags[i+0].length = NULL;
tags[i+1].buffer_type = TSDB_DATA_TYPE_SMALLINT;
tags[i+1].buffer = v.v2;
tags[i+1].is_null = &one_not_null;
tags[i+1].length = NULL;
tags[i+2].buffer_type = TSDB_DATA_TYPE_FLOAT;
tags[i+2].buffer = v.f4;
tags[i+2].is_null = &one_not_null;
tags[i+2].length = NULL;
tags[i+3].buffer_type = TSDB_DATA_TYPE_BINARY;
tags[i+3].buffer = v.bin;
tags[i+3].is_null = &one_not_null;
tags[i+3].length = (uintptr_t *)lb;
}
unsigned long long starttime = getCurrentTime();
char *sql = "insert into ? using stb1 tags(1,?,2,?,4,?,6.0,?,'b') (ts,b,v4,v8,f8) values(?,?,?,?,?)";
int code = taos_stmt_prepare(stmt, sql, 0);
if (code != 0){
printf("failed to execute taos_stmt_prepare. code:0x%x\n", code);
exit(1);
}
int id = 0;
for (int zz = 0; zz < 1; zz++) {
char buf[32];
sprintf(buf, "m%d", zz);
code = taos_stmt_set_tbname_tags(stmt, buf, tags);
if (code != 0){
printf("failed to execute taos_stmt_set_tbname_tags. code:0x%x\n", code);
}
taos_stmt_bind_param_batch(stmt, params + id * 5);
taos_stmt_add_batch(stmt);
}
if (taos_stmt_execute(stmt) != 0) {
printf("failed to execute insert statement.\n");
exit(1);
}
++id;
unsigned long long endtime = getCurrentTime();
printf("insert total %d records, used %u seconds, avg:%u useconds\n", 10, (endtime-starttime)/1000000UL, (endtime-starttime)/(10));
free(v.ts);
free(lb);
free(params);
free(is_null);
free(no_null);
free(tags);
return 0;
}
//1 tables 10 records
int stmt_funcb_autoctb_e1(TAOS_STMT *stmt) {
struct {
int64_t *ts;
int8_t b[10];
int8_t v1[10];
int16_t v2[10];
int32_t v4[10];
int64_t v8[10];
float f4[10];
double f8[10];
char bin[10][40];
} v = {0};
v.ts = malloc(sizeof(int64_t) * 1 * 10);
int *lb = malloc(10 * sizeof(int));
TAOS_BIND *tags = calloc(1, sizeof(TAOS_BIND) * 9 * 1);
TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * 1*10);
// int one_null = 1;
int one_not_null = 0;
char* is_null = malloc(sizeof(char) * 10);
char* no_null = malloc(sizeof(char) * 10);
for (int i = 0; i < 10; ++i) {
lb[i] = 40;
no_null[i] = 0;
is_null[i] = (i % 10 == 2) ? 1 : 0;
v.b[i] = (int8_t)(i % 2);
v.v1[i] = (int8_t)((i+1) % 2);
v.v2[i] = (int16_t)i;
v.v4[i] = (int32_t)(i+1);
v.v8[i] = (int64_t)(i+2);
v.f4[i] = (float)(i+3);
v.f8[i] = (double)(i+4);
memset(v.bin[i], '0'+i%10, 40);
}
for (int i = 0; i < 10; i+=10) {
params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
params[i+0].buffer_length = sizeof(int64_t);
params[i+0].buffer = &v.ts[10*i/10];
params[i+0].length = NULL;
params[i+0].is_null = no_null;
params[i+0].num = 10;
params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL;
params[i+1].buffer_length = sizeof(int8_t);
params[i+1].buffer = v.b;
params[i+1].length = NULL;
params[i+1].is_null = is_null;
params[i+1].num = 10;
params[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT;
params[i+2].buffer_length = sizeof(int8_t);
params[i+2].buffer = v.v1;
params[i+2].length = NULL;
params[i+2].is_null = is_null;
params[i+2].num = 10;
params[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT;
params[i+3].buffer_length = sizeof(int16_t);
params[i+3].buffer = v.v2;
params[i+3].length = NULL;
params[i+3].is_null = is_null;
params[i+3].num = 10;
params[i+4].buffer_type = TSDB_DATA_TYPE_INT;
params[i+4].buffer_length = sizeof(int32_t);
params[i+4].buffer = v.v4;
params[i+4].length = NULL;
params[i+4].is_null = is_null;
params[i+4].num = 10;
params[i+5].buffer_type = TSDB_DATA_TYPE_BIGINT;
params[i+5].buffer_length = sizeof(int64_t);
params[i+5].buffer = v.v8;
params[i+5].length = NULL;
params[i+5].is_null = is_null;
params[i+5].num = 10;
params[i+6].buffer_type = TSDB_DATA_TYPE_FLOAT;
params[i+6].buffer_length = sizeof(float);
params[i+6].buffer = v.f4;
params[i+6].length = NULL;
params[i+6].is_null = is_null;
params[i+6].num = 10;
params[i+7].buffer_type = TSDB_DATA_TYPE_DOUBLE;
params[i+7].buffer_length = sizeof(double);
params[i+7].buffer = v.f8;
params[i+7].length = NULL;
params[i+7].is_null = is_null;
params[i+7].num = 10;
params[i+8].buffer_type = TSDB_DATA_TYPE_BINARY;
params[i+8].buffer_length = 40;
params[i+8].buffer = v.bin;
params[i+8].length = lb;
params[i+8].is_null = is_null;
params[i+8].num = 10;
params[i+9].buffer_type = TSDB_DATA_TYPE_BINARY;
params[i+9].buffer_length = 40;
params[i+9].buffer = v.bin;
params[i+9].length = lb;
params[i+9].is_null = is_null;
params[i+9].num = 10;
}
int64_t tts = 1591060628000;
for (int i = 0; i < 10; ++i) {
v.ts[i] = tts + i;
}
for (int i = 0; i < 1; ++i) {
tags[i+0].buffer_type = TSDB_DATA_TYPE_BOOL;
tags[i+0].buffer = v.b;
tags[i+0].is_null = &one_not_null;
tags[i+0].length = NULL;
tags[i+1].buffer_type = TSDB_DATA_TYPE_SMALLINT;
tags[i+1].buffer = v.v2;
tags[i+1].is_null = &one_not_null;
tags[i+1].length = NULL;
tags[i+2].buffer_type = TSDB_DATA_TYPE_FLOAT;
tags[i+2].buffer = v.f4;
tags[i+2].is_null = &one_not_null;
tags[i+2].length = NULL;
tags[i+3].buffer_type = TSDB_DATA_TYPE_BINARY;
tags[i+3].buffer = v.bin;
tags[i+3].is_null = &one_not_null;
tags[i+3].length = (uintptr_t *)lb;
}
unsigned long long starttime = getCurrentTime();
char *sql = "insert into ? using stb1 (id1,id2,id3,id4,id5,id6,id7,id8,id9) tags(1,?,2,?,4,?,6.0,?,'b') values(?,?,?,?,?,?,?,?,?,?)";
int code = taos_stmt_prepare(stmt, sql, 0);
if (code != 0){
printf("failed to execute taos_stmt_prepare. error:%s\n", taos_stmt_errstr(stmt));
return -1;
}
int id = 0;
for (int zz = 0; zz < 1; zz++) {
char buf[32];
sprintf(buf, "m%d", zz);
code = taos_stmt_set_tbname_tags(stmt, buf, tags);
if (code != 0){
printf("failed to execute taos_stmt_set_tbname_tags. code:0x%x\n", code);
}
taos_stmt_bind_param_batch(stmt, params + id * 10);
taos_stmt_add_batch(stmt);
}
if (taos_stmt_execute(stmt) != 0) {
printf("failed to execute insert statement.\n");
exit(1);
}
++id;
unsigned long long endtime = getCurrentTime();
printf("insert total %d records, used %u seconds, avg:%u useconds\n", 10, (endtime-starttime)/1000000UL, (endtime-starttime)/(10));
free(v.ts);
free(lb);
free(params);
free(is_null);
free(no_null);
free(tags);
return 0;
}
//1 tables 10 records
int stmt_funcb_autoctb_e2(TAOS_STMT *stmt) {
struct {
int64_t *ts;
int8_t b[10];
int8_t v1[10];
int16_t v2[10];
int32_t v4[10];
int64_t v8[10];
float f4[10];
double f8[10];
char bin[10][40];
} v = {0};
v.ts = malloc(sizeof(int64_t) * 1 * 10);
int *lb = malloc(10 * sizeof(int));
TAOS_BIND *tags = calloc(1, sizeof(TAOS_BIND) * 9 * 1);
TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * 1*10);
// int one_null = 1;
int one_not_null = 0;
char* is_null = malloc(sizeof(char) * 10);
char* no_null = malloc(sizeof(char) * 10);
for (int i = 0; i < 10; ++i) {
lb[i] = 40;
no_null[i] = 0;
is_null[i] = (i % 10 == 2) ? 1 : 0;
v.b[i] = (int8_t)(i % 2);
v.v1[i] = (int8_t)((i+1) % 2);
v.v2[i] = (int16_t)i;
v.v4[i] = (int32_t)(i+1);
v.v8[i] = (int64_t)(i+2);
v.f4[i] = (float)(i+3);
v.f8[i] = (double)(i+4);
memset(v.bin[i], '0'+i%10, 40);
}
for (int i = 0; i < 10; i+=10) {
params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
params[i+0].buffer_length = sizeof(int64_t);
params[i+0].buffer = &v.ts[10*i/10];
params[i+0].length = NULL;
params[i+0].is_null = no_null;
params[i+0].num = 10;
params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL;
params[i+1].buffer_length = sizeof(int8_t);
params[i+1].buffer = v.b;
params[i+1].length = NULL;
params[i+1].is_null = is_null;
params[i+1].num = 10;
params[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT;
params[i+2].buffer_length = sizeof(int8_t);
params[i+2].buffer = v.v1;
params[i+2].length = NULL;
params[i+2].is_null = is_null;
params[i+2].num = 10;
params[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT;
params[i+3].buffer_length = sizeof(int16_t);
params[i+3].buffer = v.v2;
params[i+3].length = NULL;
params[i+3].is_null = is_null;
params[i+3].num = 10;
params[i+4].buffer_type = TSDB_DATA_TYPE_INT;
params[i+4].buffer_length = sizeof(int32_t);
params[i+4].buffer = v.v4;
params[i+4].length = NULL;
params[i+4].is_null = is_null;
params[i+4].num = 10;
params[i+5].buffer_type = TSDB_DATA_TYPE_BIGINT;
params[i+5].buffer_length = sizeof(int64_t);
params[i+5].buffer = v.v8;
params[i+5].length = NULL;
params[i+5].is_null = is_null;
params[i+5].num = 10;
params[i+6].buffer_type = TSDB_DATA_TYPE_FLOAT;
params[i+6].buffer_length = sizeof(float);
params[i+6].buffer = v.f4;
params[i+6].length = NULL;
params[i+6].is_null = is_null;
params[i+6].num = 10;
params[i+7].buffer_type = TSDB_DATA_TYPE_DOUBLE;
params[i+7].buffer_length = sizeof(double);
params[i+7].buffer = v.f8;
params[i+7].length = NULL;
params[i+7].is_null = is_null;
params[i+7].num = 10;
params[i+8].buffer_type = TSDB_DATA_TYPE_BINARY;
params[i+8].buffer_length = 40;
params[i+8].buffer = v.bin;
params[i+8].length = lb;
params[i+8].is_null = is_null;
params[i+8].num = 10;
params[i+9].buffer_type = TSDB_DATA_TYPE_BINARY;
params[i+9].buffer_length = 40;
params[i+9].buffer = v.bin;
params[i+9].length = lb;
params[i+9].is_null = is_null;
params[i+9].num = 10;
}
int64_t tts = 1591060628000;
for (int i = 0; i < 10; ++i) {
v.ts[i] = tts + i;
}
for (int i = 0; i < 1; ++i) {
tags[i+0].buffer_type = TSDB_DATA_TYPE_INT;
tags[i+0].buffer = v.v4;
tags[i+0].is_null = &one_not_null;
tags[i+0].length = NULL;
tags[i+1].buffer_type = TSDB_DATA_TYPE_BOOL;
tags[i+1].buffer = v.b;
tags[i+1].is_null = &one_not_null;
tags[i+1].length = NULL;
tags[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT;
tags[i+2].buffer = v.v1;
tags[i+2].is_null = &one_not_null;
tags[i+2].length = NULL;
tags[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT;
tags[i+3].buffer = v.v2;
tags[i+3].is_null = &one_not_null;
tags[i+3].length = NULL;
tags[i+4].buffer_type = TSDB_DATA_TYPE_BIGINT;
tags[i+4].buffer = v.v8;
tags[i+4].is_null = &one_not_null;
tags[i+4].length = NULL;
tags[i+5].buffer_type = TSDB_DATA_TYPE_FLOAT;
tags[i+5].buffer = v.f4;
tags[i+5].is_null = &one_not_null;
tags[i+5].length = NULL;
tags[i+6].buffer_type = TSDB_DATA_TYPE_DOUBLE;
tags[i+6].buffer = v.f8;
tags[i+6].is_null = &one_not_null;
tags[i+6].length = NULL;
tags[i+7].buffer_type = TSDB_DATA_TYPE_BINARY;
tags[i+7].buffer = v.bin;
tags[i+7].is_null = &one_not_null;
tags[i+7].length = (uintptr_t *)lb;
tags[i+8].buffer_type = TSDB_DATA_TYPE_NCHAR;
tags[i+8].buffer = v.bin;
tags[i+8].is_null = &one_not_null;
tags[i+8].length = (uintptr_t *)lb;
}
unsigned long long starttime = getCurrentTime();
char *sql = "insert into ? using stb1 tags(?,?,?,?,?,?,?,?,?) values(?,?,?,?,?,?,?,?,?,?)";
int code = taos_stmt_prepare(stmt, sql, 0);
if (code != 0){
printf("failed to execute taos_stmt_prepare. code:0x%x\n", code);
exit(1);
}
int id = 0;
for (int zz = 0; zz < 1; zz++) {
char buf[32];
sprintf(buf, "m%d", zz);
code = taos_stmt_set_tbname_tags(stmt, buf, NULL);
if (code != 0){
printf("failed to execute taos_stmt_set_tbname_tags. code:%s\n", taos_stmt_errstr(stmt));
return -1;
}
taos_stmt_bind_param_batch(stmt, params + id * 10);
taos_stmt_add_batch(stmt);
}
if (taos_stmt_execute(stmt) != 0) {
printf("failed to execute insert statement.\n");
exit(1);
}
++id;
unsigned long long endtime = getCurrentTime();
printf("insert total %d records, used %u seconds, avg:%u useconds\n", 10, (endtime-starttime)/1000000UL, (endtime-starttime)/(10));
free(v.ts);
free(lb);
free(params);
free(is_null);
free(no_null);
free(tags);
return 0;
}
//1 tables 10 records
int stmt_funcb_autoctb_e3(TAOS_STMT *stmt) {
struct {
int64_t *ts;
int8_t b[10];
int8_t v1[10];
int16_t v2[10];
int32_t v4[10];
int64_t v8[10];
float f4[10];
double f8[10];
char bin[10][40];
} v = {0};
v.ts = malloc(sizeof(int64_t) * 1 * 10);
int *lb = malloc(10 * sizeof(int));
TAOS_BIND *tags = calloc(1, sizeof(TAOS_BIND) * 9 * 1);
TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * 1*10);
// int one_null = 1;
int one_not_null = 0;
char* is_null = malloc(sizeof(char) * 10);
char* no_null = malloc(sizeof(char) * 10);
for (int i = 0; i < 10; ++i) {
lb[i] = 40;
no_null[i] = 0;
is_null[i] = (i % 10 == 2) ? 1 : 0;
v.b[i] = (int8_t)(i % 2);
v.v1[i] = (int8_t)((i+1) % 2);
v.v2[i] = (int16_t)i;
v.v4[i] = (int32_t)(i+1);
v.v8[i] = (int64_t)(i+2);
v.f4[i] = (float)(i+3);
v.f8[i] = (double)(i+4);
memset(v.bin[i], '0'+i%10, 40);
}
for (int i = 0; i < 10; i+=10) {
params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
params[i+0].buffer_length = sizeof(int64_t);
params[i+0].buffer = &v.ts[10*i/10];
params[i+0].length = NULL;
params[i+0].is_null = no_null;
params[i+0].num = 10;
params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL;
params[i+1].buffer_length = sizeof(int8_t);
params[i+1].buffer = v.b;
params[i+1].length = NULL;
params[i+1].is_null = is_null;
params[i+1].num = 10;
params[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT;
params[i+2].buffer_length = sizeof(int8_t);
params[i+2].buffer = v.v1;
params[i+2].length = NULL;
params[i+2].is_null = is_null;
params[i+2].num = 10;
params[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT;
params[i+3].buffer_length = sizeof(int16_t);
params[i+3].buffer = v.v2;
params[i+3].length = NULL;
params[i+3].is_null = is_null;
params[i+3].num = 10;
params[i+4].buffer_type = TSDB_DATA_TYPE_INT;
params[i+4].buffer_length = sizeof(int32_t);
params[i+4].buffer = v.v4;
params[i+4].length = NULL;
params[i+4].is_null = is_null;
params[i+4].num = 10;
params[i+5].buffer_type = TSDB_DATA_TYPE_BIGINT;
params[i+5].buffer_length = sizeof(int64_t);
params[i+5].buffer = v.v8;
params[i+5].length = NULL;
params[i+5].is_null = is_null;
params[i+5].num = 10;
params[i+6].buffer_type = TSDB_DATA_TYPE_FLOAT;
params[i+6].buffer_length = sizeof(float);
params[i+6].buffer = v.f4;
params[i+6].length = NULL;
params[i+6].is_null = is_null;
params[i+6].num = 10;
params[i+7].buffer_type = TSDB_DATA_TYPE_DOUBLE;
params[i+7].buffer_length = sizeof(double);
params[i+7].buffer = v.f8;
params[i+7].length = NULL;
params[i+7].is_null = is_null;
params[i+7].num = 10;
params[i+8].buffer_type = TSDB_DATA_TYPE_BINARY;
params[i+8].buffer_length = 40;
params[i+8].buffer = v.bin;
params[i+8].length = lb;
params[i+8].is_null = is_null;
params[i+8].num = 10;
params[i+9].buffer_type = TSDB_DATA_TYPE_BINARY;
params[i+9].buffer_length = 40;
params[i+9].buffer = v.bin;
params[i+9].length = lb;
params[i+9].is_null = is_null;
params[i+9].num = 10;
}
int64_t tts = 1591060628000;
for (int i = 0; i < 10; ++i) {
v.ts[i] = tts + i;
}
for (int i = 0; i < 1; ++i) {
tags[i+0].buffer_type = TSDB_DATA_TYPE_INT;
tags[i+0].buffer = v.v4;
tags[i+0].is_null = &one_not_null;
tags[i+0].length = NULL;
tags[i+1].buffer_type = TSDB_DATA_TYPE_BOOL;
tags[i+1].buffer = v.b;
tags[i+1].is_null = &one_not_null;
tags[i+1].length = NULL;
tags[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT;
tags[i+2].buffer = v.v1;
tags[i+2].is_null = &one_not_null;
tags[i+2].length = NULL;
tags[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT;
tags[i+3].buffer = v.v2;
tags[i+3].is_null = &one_not_null;
tags[i+3].length = NULL;
tags[i+4].buffer_type = TSDB_DATA_TYPE_BIGINT;
tags[i+4].buffer = v.v8;
tags[i+4].is_null = &one_not_null;
tags[i+4].length = NULL;
tags[i+5].buffer_type = TSDB_DATA_TYPE_FLOAT;
tags[i+5].buffer = v.f4;
tags[i+5].is_null = &one_not_null;
tags[i+5].length = NULL;
tags[i+6].buffer_type = TSDB_DATA_TYPE_DOUBLE;
tags[i+6].buffer = v.f8;
tags[i+6].is_null = &one_not_null;
tags[i+6].length = NULL;
tags[i+7].buffer_type = TSDB_DATA_TYPE_BINARY;
tags[i+7].buffer = v.bin;
tags[i+7].is_null = &one_not_null;
tags[i+7].length = (uintptr_t *)lb;
tags[i+8].buffer_type = TSDB_DATA_TYPE_NCHAR;
tags[i+8].buffer = v.bin;
tags[i+8].is_null = &one_not_null;
tags[i+8].length = (uintptr_t *)lb;
}
unsigned long long starttime = getCurrentTime();
char *sql = "insert into ? using stb1 (id1,id2,id3,id4,id5,id6,id7,id8,id9) tags(?,?,?,?,?,?,?,?,?) values(?,?,?,?,?,?,?,?,?,?)";
int code = taos_stmt_prepare(stmt, sql, 0);
if (code != 0){
printf("failed to execute taos_stmt_prepare. code:%s\n", taos_stmt_errstr(stmt));
return -1;
//exit(1);
}
int id = 0;
for (int zz = 0; zz < 1; zz++) {
char buf[32];
sprintf(buf, "m%d", zz);
code = taos_stmt_set_tbname_tags(stmt, buf, NULL);
if (code != 0){
printf("failed to execute taos_stmt_set_tbname_tags. code:0x%x\n", code);
return -1;
}
taos_stmt_bind_param_batch(stmt, params + id * 10);
taos_stmt_add_batch(stmt);
}
if (taos_stmt_execute(stmt) != 0) {
printf("failed to execute insert statement.\n");
exit(1);
}
++id;
unsigned long long endtime = getCurrentTime();
printf("insert total %d records, used %u seconds, avg:%u useconds\n", 10, (endtime-starttime)/1000000UL, (endtime-starttime)/(10));
free(v.ts);
free(lb);
free(params);
free(is_null);
free(no_null);
free(tags);
return 0;
}
//1 tables 10 records //1 tables 10 records
int stmt_funcb_autoctb_e1(TAOS_STMT *stmt) { int stmt_funcb_autoctb_e4(TAOS_STMT *stmt) {
struct { struct {
int64_t *ts; int64_t *ts;
int8_t b[10]; int8_t b[10];
...@@ -1579,35 +2354,60 @@ int stmt_funcb_autoctb_e1(TAOS_STMT *stmt) { ...@@ -1579,35 +2354,60 @@ int stmt_funcb_autoctb_e1(TAOS_STMT *stmt) {
for (int i = 0; i < 1; ++i) { for (int i = 0; i < 1; ++i) {
tags[i+0].buffer_type = TSDB_DATA_TYPE_BOOL; tags[i+0].buffer_type = TSDB_DATA_TYPE_INT;
tags[i+0].buffer = v.b; tags[i+0].buffer = v.v4;
tags[i+0].is_null = &one_not_null; tags[i+0].is_null = &one_not_null;
tags[i+0].length = NULL; tags[i+0].length = NULL;
tags[i+1].buffer_type = TSDB_DATA_TYPE_SMALLINT; tags[i+1].buffer_type = TSDB_DATA_TYPE_BOOL;
tags[i+1].buffer = v.v2; tags[i+1].buffer = v.b;
tags[i+1].is_null = &one_not_null; tags[i+1].is_null = &one_not_null;
tags[i+1].length = NULL; tags[i+1].length = NULL;
tags[i+2].buffer_type = TSDB_DATA_TYPE_FLOAT; tags[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT;
tags[i+2].buffer = v.f4; tags[i+2].buffer = v.v1;
tags[i+2].is_null = &one_not_null; tags[i+2].is_null = &one_not_null;
tags[i+2].length = NULL; tags[i+2].length = NULL;
tags[i+3].buffer_type = TSDB_DATA_TYPE_BINARY; tags[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT;
tags[i+3].buffer = v.bin; tags[i+3].buffer = v.v2;
tags[i+3].is_null = &one_not_null; tags[i+3].is_null = &one_not_null;
tags[i+3].length = (uintptr_t *)lb; tags[i+3].length = NULL;
tags[i+4].buffer_type = TSDB_DATA_TYPE_BIGINT;
tags[i+4].buffer = v.v8;
tags[i+4].is_null = &one_not_null;
tags[i+4].length = NULL;
tags[i+5].buffer_type = TSDB_DATA_TYPE_FLOAT;
tags[i+5].buffer = v.f4;
tags[i+5].is_null = &one_not_null;
tags[i+5].length = NULL;
tags[i+6].buffer_type = TSDB_DATA_TYPE_DOUBLE;
tags[i+6].buffer = v.f8;
tags[i+6].is_null = &one_not_null;
tags[i+6].length = NULL;
tags[i+7].buffer_type = TSDB_DATA_TYPE_BINARY;
tags[i+7].buffer = v.bin;
tags[i+7].is_null = &one_not_null;
tags[i+7].length = (uintptr_t *)lb;
tags[i+8].buffer_type = TSDB_DATA_TYPE_NCHAR;
tags[i+8].buffer = v.bin;
tags[i+8].is_null = &one_not_null;
tags[i+8].length = (uintptr_t *)lb;
} }
unsigned long long starttime = getCurrentTime(); unsigned long long starttime = getCurrentTime();
char *sql = "insert into ? using stb1 (id1,id2,id3,id4,id5,id6,id7,id8,id9) tags(1,?,2,?,4,?,6.0,?,'b') values(?,?,?,?,?,?,?,?,?,?)"; char *sql = "insert into ? using stb1 tags(?,?,?,?,?,?,?,?,?) values(?,?,?,?,?,?,?,?,?,?)";
int code = taos_stmt_prepare(stmt, sql, 0); int code = taos_stmt_prepare(stmt, sql, 0);
if (code != 0){ if (code != 0){
printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); printf("failed to execute taos_stmt_prepare. code:%s\n", taos_stmt_errstr(stmt));
return -1; exit(1);
} }
int id = 0; int id = 0;
...@@ -1616,10 +2416,22 @@ int stmt_funcb_autoctb_e1(TAOS_STMT *stmt) { ...@@ -1616,10 +2416,22 @@ int stmt_funcb_autoctb_e1(TAOS_STMT *stmt) {
sprintf(buf, "m%d", zz); sprintf(buf, "m%d", zz);
code = taos_stmt_set_tbname_tags(stmt, buf, tags); code = taos_stmt_set_tbname_tags(stmt, buf, tags);
if (code != 0){ if (code != 0){
printf("failed to execute taos_stmt_set_tbname_tags. code:0x%x\n", code); printf("failed to execute taos_stmt_set_tbname_tags. error:%s\n", taos_stmt_errstr(stmt));
exit(1);
} }
taos_stmt_bind_param_batch(stmt, params + id * 10); code = taos_stmt_bind_param_batch(stmt, params + id * 10);
if (code != 0) {
printf("failed to execute taos_stmt_bind_param_batch. error:%s\n", taos_stmt_errstr(stmt));
exit(1);
}
code = taos_stmt_bind_param_batch(stmt, params + id * 10);
if (code != 0) {
printf("failed to execute taos_stmt_bind_param_batch. error:%s\n", taos_stmt_errstr(stmt));
return -1;
}
taos_stmt_add_batch(stmt); taos_stmt_add_batch(stmt);
} }
...@@ -1647,8 +2459,9 @@ int stmt_funcb_autoctb_e1(TAOS_STMT *stmt) { ...@@ -1647,8 +2459,9 @@ int stmt_funcb_autoctb_e1(TAOS_STMT *stmt) {
//1 tables 10 records //1 tables 10 records
int stmt_funcb_autoctb_e2(TAOS_STMT *stmt) { int stmt_funcb_autoctb_e5(TAOS_STMT *stmt) {
struct { struct {
int64_t *ts; int64_t *ts;
int8_t b[10]; int8_t b[10];
...@@ -1818,23 +2631,34 @@ int stmt_funcb_autoctb_e2(TAOS_STMT *stmt) { ...@@ -1818,23 +2631,34 @@ int stmt_funcb_autoctb_e2(TAOS_STMT *stmt) {
unsigned long long starttime = getCurrentTime(); unsigned long long starttime = getCurrentTime();
char *sql = "insert into ? using stb1 tags(?,?,?,?,?,?,?,?,?) values(?,?,?,?,?,?,?,?,?,?)"; char *sql = "insert into ? using stb1 tags(?,?,?,?,?,?,?,?,?) values(?,?,?,?,?,?,?,?,?,?)";
int code = taos_stmt_prepare(stmt, sql, 0); int code = taos_stmt_prepare(NULL, sql, 0);
if (code != 0){ if (code != 0){
printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); printf("failed to execute taos_stmt_prepare. code:%s\n", taos_stmt_errstr(NULL));
exit(1); return -1;
} }
int id = 0; int id = 0;
for (int zz = 0; zz < 1; zz++) { for (int zz = 0; zz < 1; zz++) {
char buf[32]; char buf[32];
sprintf(buf, "m%d", zz); sprintf(buf, "m%d", zz);
code = taos_stmt_set_tbname_tags(stmt, buf, NULL); code = taos_stmt_set_tbname_tags(stmt, buf, tags);
if (code != 0){ if (code != 0){
printf("failed to execute taos_stmt_set_tbname_tags. code:0x%x\n", code); printf("failed to execute taos_stmt_set_tbname_tags. error:%s\n", taos_stmt_errstr(stmt));
return -1; exit(1);
} }
taos_stmt_bind_param_batch(stmt, params + id * 10); code = taos_stmt_bind_param_batch(stmt, params + id * 10);
if (code != 0) {
printf("failed to execute taos_stmt_bind_param_batch. error:%s\n", taos_stmt_errstr(stmt));
exit(1);
}
code = taos_stmt_bind_param_batch(stmt, params + id * 10);
if (code != 0) {
printf("failed to execute taos_stmt_bind_param_batch. error:%s\n", taos_stmt_errstr(stmt));
return -1;
}
taos_stmt_add_batch(stmt); taos_stmt_add_batch(stmt);
} }
...@@ -3375,6 +4199,9 @@ void check_result(TAOS *taos, char *tname, int printr, int expected) { ...@@ -3375,6 +4199,9 @@ void check_result(TAOS *taos, char *tname, int printr, int expected) {
char sql[255] = "SELECT * FROM "; char sql[255] = "SELECT * FROM ";
TAOS_RES *result; TAOS_RES *result;
//FORCE NO PRINT
printr = 0;
strcat(sql, tname); strcat(sql, tname);
result = taos_query(taos, sql); result = taos_query(taos, sql);
...@@ -3835,7 +4662,7 @@ void* runcase(void *par) { ...@@ -3835,7 +4662,7 @@ void* runcase(void *par) {
#endif #endif
#if 1 #if 1
prepare(taos, 1, 1); prepare(taos, 1, 1);
stmt = taos_stmt_init(taos); stmt = taos_stmt_init(taos);
...@@ -3859,9 +4686,9 @@ void* runcase(void *par) { ...@@ -3859,9 +4686,9 @@ void* runcase(void *par) {
stmt = taos_stmt_init(taos); stmt = taos_stmt_init(taos);
printf("1t+10r+bm+autoctb start\n"); printf("1t+10r+bm+autoctb1 start\n");
stmt_funcb_autoctb1(stmt); stmt_funcb_autoctb1(stmt);
printf("1t+10r+bm+autoctb end\n"); printf("1t+10r+bm+autoctb1 end\n");
printf("check result start\n"); printf("check result start\n");
check_result(taos, "m0", 1, 10); check_result(taos, "m0", 1, 10);
printf("check result end\n"); printf("check result end\n");
...@@ -3874,9 +4701,9 @@ void* runcase(void *par) { ...@@ -3874,9 +4701,9 @@ void* runcase(void *par) {
stmt = taos_stmt_init(taos); stmt = taos_stmt_init(taos);
printf("1t+10r+bm+autoctb start\n"); printf("1t+10r+bm+autoctb2 start\n");
stmt_funcb_autoctb2(stmt); stmt_funcb_autoctb2(stmt);
printf("1t+10r+bm+autoctb end\n"); printf("1t+10r+bm+autoctb2 end\n");
printf("check result start\n"); printf("check result start\n");
check_result(taos, "m0", 1, 10); check_result(taos, "m0", 1, 10);
printf("check result end\n"); printf("check result end\n");
...@@ -3890,9 +4717,9 @@ void* runcase(void *par) { ...@@ -3890,9 +4717,9 @@ void* runcase(void *par) {
stmt = taos_stmt_init(taos); stmt = taos_stmt_init(taos);
printf("1t+10r+bm+autoctb start\n"); printf("1t+10r+bm+autoctb3 start\n");
stmt_funcb_autoctb3(stmt); stmt_funcb_autoctb3(stmt);
printf("1t+10r+bm+autoctb end\n"); printf("1t+10r+bm+autoctb3 end\n");
printf("check result start\n"); printf("check result start\n");
check_result(taos, "m0", 1, 10); check_result(taos, "m0", 1, 10);
printf("check result end\n"); printf("check result end\n");
...@@ -3900,11 +4727,27 @@ void* runcase(void *par) { ...@@ -3900,11 +4727,27 @@ void* runcase(void *par) {
#endif #endif
#if 1 #if 1
prepare(taos, 1, 0); prepare(taos, 1, 0);
stmt = taos_stmt_init(taos); stmt = taos_stmt_init(taos);
printf("1t+10r+bm+autoctb4 start\n");
stmt_funcb_autoctb4(stmt);
printf("1t+10r+bm+autoctb4 end\n");
printf("check result start\n");
check_result(taos, "m0", 1, 10);
printf("check result end\n");
taos_stmt_close(stmt);
#endif
#if 1
prepare(taos, 1, 0);
stmt = taos_stmt_init(taos);
printf("1t+10r+bm+autoctb+e1 start\n"); printf("1t+10r+bm+autoctb+e1 start\n");
stmt_funcb_autoctb_e1(stmt); stmt_funcb_autoctb_e1(stmt);
printf("1t+10r+bm+autoctb+e1 end\n"); printf("1t+10r+bm+autoctb+e1 end\n");
...@@ -3930,6 +4773,52 @@ void* runcase(void *par) { ...@@ -3930,6 +4773,52 @@ void* runcase(void *par) {
#endif #endif
#if 1
prepare(taos, 1, 0);
stmt = taos_stmt_init(taos);
printf("1t+10r+bm+autoctb+e3 start\n");
stmt_funcb_autoctb_e3(stmt);
printf("1t+10r+bm+autoctb+e3 end\n");
printf("check result start\n");
//check_result(taos, "m0", 1, 0);
printf("check result end\n");
taos_stmt_close(stmt);
#endif
#if 1
prepare(taos, 1, 0);
stmt = taos_stmt_init(taos);
printf("1t+10r+bm+autoctb+e4 start\n");
stmt_funcb_autoctb_e4(stmt);
printf("1t+10r+bm+autoctb+e4 end\n");
printf("check result start\n");
//check_result(taos, "m0", 1, 0);
printf("check result end\n");
taos_stmt_close(stmt);
#endif
#if 1
prepare(taos, 1, 0);
stmt = taos_stmt_init(taos);
printf("1t+10r+bm+autoctb+e5 start\n");
stmt_funcb_autoctb_e5(stmt);
printf("1t+10r+bm+autoctb+e5 end\n");
printf("check result start\n");
//check_result(taos, "m0", 1, 0);
printf("check result end\n");
taos_stmt_close(stmt);
#endif
#if 1 #if 1
prepare(taos, 1, 1); prepare(taos, 1, 1);
...@@ -4138,6 +5027,8 @@ void* runcase(void *par) { ...@@ -4138,6 +5027,8 @@ void* runcase(void *par) {
#endif #endif
printf("test end\n");
return NULL; return NULL;
} }
......
...@@ -1811,10 +1811,6 @@ if $data09 != 3 then ...@@ -1811,10 +1811,6 @@ if $data09 != 3 then
return -1 return -1
endi endi
sql select st0.*,st1.* from st0, st1 where st1.id1=st0.id1 and st0.ts=st1.ts and st1.ts=st0.ts and st0.id1=st1.id1 order by st0.ts limit 5 offset 5 sql select st0.*,st1.* from st0, st1 where st1.id1=st0.id1 and st0.ts=st1.ts and st1.ts=st0.ts and st0.id1=st1.id1 order by st0.ts limit 5 offset 5
if $rows != 5 then if $rows != 5 then
return -1 return -1
...@@ -2294,7 +2290,6 @@ if $data19 != 9925 then ...@@ -2294,7 +2290,6 @@ if $data19 != 9925 then
return -1 return -1
endi endi
sql_error select tb0_1.*, tb1_1.* from tb0_1, tb1_1 where tb0_1.f1=tb1_1.f1; sql_error select tb0_1.*, tb1_1.* from tb0_1, tb1_1 where tb0_1.f1=tb1_1.f1;
sql_error select tb0_1.*, tb1_1.* from tb0_1, tb1_1 where tb0_1.ts=tb1_1.ts and tb0_1.id1=tb1_1.id2; sql_error select tb0_1.*, tb1_1.* from tb0_1, tb1_1 where tb0_1.ts=tb1_1.ts and tb0_1.id1=tb1_1.id2;
sql_error select tb0_5.*, tb1_5.*,tb2_5.*,tb3_5.*,tb4_5.*,tb5_5.*, tb6_5.*,tb7_5.*,tb8_5.*,tb9_5.*,tba_5.* from tb0_5, tb1_5, tb2_5, tb3_5, tb4_5,tb5_5, tb6_5, tb7_5, tb8_5, tb9_5, tba_5 where tb9_5.ts=tb8_5.ts and tb8_5.ts=tb7_5.ts and tb7_5.ts=tb6_5.ts and tb6_5.ts=tb5_5.ts and tb5_5.ts=tb4_5.ts and tb4_5.ts=tb3_5.ts and tb3_5.ts=tb2_5.ts and tb2_5.ts=tb1_5.ts and tb1_5.ts=tb0_5.ts and tb0_5.ts=tba_5.ts; sql_error select tb0_5.*, tb1_5.*,tb2_5.*,tb3_5.*,tb4_5.*,tb5_5.*, tb6_5.*,tb7_5.*,tb8_5.*,tb9_5.*,tba_5.* from tb0_5, tb1_5, tb2_5, tb3_5, tb4_5,tb5_5, tb6_5, tb7_5, tb8_5, tb9_5, tba_5 where tb9_5.ts=tb8_5.ts and tb8_5.ts=tb7_5.ts and tb7_5.ts=tb6_5.ts and tb6_5.ts=tb5_5.ts and tb5_5.ts=tb4_5.ts and tb4_5.ts=tb3_5.ts and tb3_5.ts=tb2_5.ts and tb2_5.ts=tb1_5.ts and tb1_5.ts=tb0_5.ts and tb0_5.ts=tba_5.ts;
...@@ -2317,10 +2312,4 @@ sql_error select last(*) from st0, st1 where st0.ts=st1.ts and st0.id1=st1.id1 g ...@@ -2317,10 +2312,4 @@ sql_error select last(*) from st0, st1 where st0.ts=st1.ts and st0.id1=st1.id1 g
sql_error select st0.*,st1.*,st2.*,st3.*,st4.*,st5.*,st6.*,st7.*,st8.*,st9.* from st0,st1,st2,st3,st4,st5,st6,st7,st8,st9 where st0.ts=st2.ts and st0.ts=st4.ts and st0.ts=st6.ts and st0.ts=st8.ts and st1.ts=st3.ts and st3.ts=st5.ts and st5.ts=st7.ts and st7.ts=st9.ts and st0.id1=st2.id1 and st0.id1=st4.id1 and st0.id1=st6.id1 and st0.id1=st8.id1 and st1.id1=st3.id1 and st3.id1=st5.id1 and st5.id1=st7.id1 and st7.id1=st9.id1; sql_error select st0.*,st1.*,st2.*,st3.*,st4.*,st5.*,st6.*,st7.*,st8.*,st9.* from st0,st1,st2,st3,st4,st5,st6,st7,st8,st9 where st0.ts=st2.ts and st0.ts=st4.ts and st0.ts=st6.ts and st0.ts=st8.ts and st1.ts=st3.ts and st3.ts=st5.ts and st5.ts=st7.ts and st7.ts=st9.ts and st0.id1=st2.id1 and st0.id1=st4.id1 and st0.id1=st6.id1 and st0.id1=st8.id1 and st1.id1=st3.id1 and st3.id1=st5.id1 and st5.id1=st7.id1 and st7.id1=st9.id1;
sql_error select st0.*,st1.*,st2.*,st3.*,st4.*,st5.*,st6.*,st7.*,st8.*,st9.* from st0,st1,st2,st3,st4,st5,st6,st7,st8,st9,sta where st0.ts=st2.ts and st0.ts=st4.ts and st0.ts=st6.ts and st0.ts=st8.ts and st1.ts=st3.ts and st3.ts=st5.ts and st5.ts=st7.ts and st7.ts=st9.ts and st0.ts=st1.ts and st0.id1=st2.id1 and st0.id1=st4.id1 and st0.id1=st6.id1 and st0.id1=st8.id1 and st1.id1=st3.id1 and st3.id1=st5.id1 and st5.id1=st7.id1 and st7.id1=st9.id1 and st0.id1=st1.id1 and st0.id1=sta.id1 and st0.ts=sta.ts; sql_error select st0.*,st1.*,st2.*,st3.*,st4.*,st5.*,st6.*,st7.*,st8.*,st9.* from st0,st1,st2,st3,st4,st5,st6,st7,st8,st9,sta where st0.ts=st2.ts and st0.ts=st4.ts and st0.ts=st6.ts and st0.ts=st8.ts and st1.ts=st3.ts and st3.ts=st5.ts and st5.ts=st7.ts and st7.ts=st9.ts and st0.ts=st1.ts and st0.id1=st2.id1 and st0.id1=st4.id1 and st0.id1=st6.id1 and st0.id1=st8.id1 and st1.id1=st3.id1 and st3.id1=st5.id1 and st5.id1=st7.id1 and st7.id1=st9.id1 and st0.id1=st1.id1 and st0.id1=sta.id1 and st0.ts=sta.ts;
system sh/exec.sh -n dnode1 -s stop -x SIGINT system sh/exec.sh -n dnode1 -s stop -x SIGINT
...@@ -9,7 +9,7 @@ sql connect ...@@ -9,7 +9,7 @@ sql connect
print ======================== dnode1 start print ======================== dnode1 start
$db = testdb $db = testdb
sql drop database if exists $db
sql create database $db cachelast 2 sql create database $db cachelast 2
sql use $db sql use $db
......
...@@ -39,6 +39,7 @@ run general/parser/slimit1.sim ...@@ -39,6 +39,7 @@ run general/parser/slimit1.sim
run general/parser/slimit_alter_tags.sim run general/parser/slimit_alter_tags.sim
run general/parser/tbnameIn.sim run general/parser/tbnameIn.sim
run general/parser/join.sim run general/parser/join.sim
#run general/parser/join_multitables.sim
run general/parser/join_multivnode.sim run general/parser/join_multivnode.sim
run general/parser/join_manyblocks.sim run general/parser/join_manyblocks.sim
run general/parser/projection_limit_offset.sim run general/parser/projection_limit_offset.sim
......
...@@ -151,18 +151,12 @@ sql_error select last(*) from wh_mt1 where c5 in ('1') ...@@ -151,18 +151,12 @@ sql_error select last(*) from wh_mt1 where c5 in ('1')
sql_error select last(*) from wh_mt1_tb1 where c5 in ('1') sql_error select last(*) from wh_mt1_tb1 where c5 in ('1')
sql_error select last(*) from wh_mt1 where c6 in ('1') sql_error select last(*) from wh_mt1 where c6 in ('1')
sql_error select last(*) from wh_mt1_tb1 where c6 in ('1') sql_error select last(*) from wh_mt1_tb1 where c6 in ('1')
sql_error select last(*) from wh_mt1 where c7 in ('binary') #sql_error select last(*) from wh_mt1 where c7 in ('binary')
sql_error select last(*) from wh_mt1_tb1 where c7 in ('binary') #sql_error select last(*) from wh_mt1_tb1 where c7 in ('binary')
sql_error select last(*) from wh_mt1 where c8 in ('nchar') #sql_error select last(*) from wh_mt1 where c8 in ('nchar')
sql_error select last(*) from wh_mt1_tb1 where c9 in (true, false) #sql_error select last(*) from wh_mt1_tb1 where c9 in (true, false)
sql_error select last(*) from wh_mt1 where c10 in ('2019-01-01 00:00:00.000') sql_error select last(*) from wh_mt1 where c10 in ('2019-01-01 00:00:00.000')
sql_error select last(*) from wh_mt1_tb1 where c10 in ('2019-01-01 00:00:00.000') sql_error select last(*) from wh_mt1_tb1 where c10 in ('2019-01-01 00:00:00.000')
sql_error select last(*) from wh_mt1 where t1 in ('binary')
sql_error select last(*) from wh_mt1 where t2 in (1)
sql_error select last(*) from wh_mt1 where t3 in (1)
sql_error select last(*) from wh_mt1 where t4 in (1)
sql_error select last(*) from wh_mt1 where t5 in (1)
sql_error select last(*) from wh_mt1 where t6 in (1)
sql select last(*) from wh_mt1 where c1 = 1 sql select last(*) from wh_mt1 where c1 = 1
if $rows != 1 then if $rows != 1 then
return -1 return -1
...@@ -359,4 +353,4 @@ if $rows != 0 then ...@@ -359,4 +353,4 @@ if $rows != 0 then
endi endi
system sh/exec.sh -n dnode1 -s stop -x SIGINT system sh/exec.sh -n dnode1 -s stop -x SIGINT
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册