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

This commit is contained in:
tomchon 2021-06-07 20:44:27 +08:00
commit 1b78353009
60 changed files with 4411 additions and 3079 deletions

View File

@ -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
``` ```

View File

@ -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")

View File

@ -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>订阅

View File

@ -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. 可以重复第 36 步,为批处理加入更多的数据行; 7. 可以重复第 36 步,为批处理加入更多的数据行;
8. 调用 `taos_stmt_execute` 执行已经准备好的批处理指令; 8. 调用 `taos_stmt_execute` 执行已经准备好的批处理指令;
@ -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

View File

@ -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 列(语句中的函数调用可能也会占用一些列空间),超限时需要显式指定较少的返回数据列,以避免语句执行报错。
- 库的数目,超级表的数目、表的数目,系统不做限制,仅受系统资源限制 - 库的数目,超级表的数目、表的数目,系统不做限制,仅受系统资源限制

View File

@ -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);
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);
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);
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);

View File

@ -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);

View File

@ -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
} }
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) {
} }
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;
} }

View File

@ -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 ||

View File

@ -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) {
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,
#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,
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,
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,
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) {
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
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
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
} }
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
} 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
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) {
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) {
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) {
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) {
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) {
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
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
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
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
} 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
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
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) {
} }
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) {
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
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) {
} }
} }
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) {
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) {
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) {
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";

View File

@ -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);
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) {
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) {
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
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
// 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
} }
// 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
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) {
} }
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)
} }
} }
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,
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,
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
&& 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
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) {
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) {
} }
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) {
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
} }
{ // 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
} }
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");
} }

View File

@ -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) {
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() {
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;

View File

@ -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 ||

View File

@ -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) {
// 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
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) {
} }
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
// 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;

View File

@ -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) {
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) {
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) {
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)
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
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) {
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
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
} }
} }
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
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) {
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) {
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
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) {
} }
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) {
} }
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
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
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 {

View File

@ -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")

View File

@ -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

View File

@ -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;

View File

@ -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 ()

View File

@ -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>

View File

@ -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>

View File

@ -1,5 +1,7 @@
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
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
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;
} }

View File

@ -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;

View File

@ -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-4294967294NULL 为4294967295u * unsigned int数值范围0-4294967294NULL 为4294967295u
unsigned bigint数值范围0-18446744073709551614uNULL 为18446744073709551615u * unsigned bigint数值范围0-18446744073709551614uNULL 为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 {
// 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 {
} }
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 {
} }
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 {
} }
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:

View File

@ -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 {
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 {
* 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 {
*/ */
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 {
} 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 {
} }
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);
} }

View File

@ -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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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;

View File

@ -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:

View File

@ -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;
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 {
} }
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 {
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 {
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 {
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 {
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 {
} }
} }
/** 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 {
} }
} }
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;
switch (nativeType) {
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return new Timestamp((Long) obj);
default:
return (Timestamp) obj;
}
} }
public Object get(int col) { public Object getObject(int col) {
return data.get(col); return data.get(col - 1);
} }
public int getColSize() {
return colSize;
}
private void setColSize(int colSize) {
this.colSize = colSize;
this.clear();
}
public ArrayList<Object> getData() {
return data;
}
public void setData(ArrayList<Object> data) {
this.data = (ArrayList<Object>) data.clone();
}
} }

View File

@ -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)) {

View File

@ -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);

View File

@ -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();

View File

@ -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 {
@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 {
@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 {
@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 {
@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 {
@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 {
@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();
} }

View File

@ -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);

View File

@ -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 {
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 {
@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 {
@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 {
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 {
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();
} }
} }

View File

@ -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 {
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 {
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 {
@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 {
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

View File

@ -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();
} }

View File

@ -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 {
@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 {
@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 {
@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 {
@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

View File

@ -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 {
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 {
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);

View File

@ -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);

View File

@ -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_HISTOGRAM 34
#define TSDB_FUNC_MODE 35 #define TSDB_FUNC_HLL 35
#define TSDB_FUNC_SAMPLE 36 #define TSDB_FUNC_MODE 36
#define TSDB_FUNC_CEIL 37 #define TSDB_FUNC_SAMPLE 37
#define TSDB_FUNC_FLOOR 38 #define TSDB_FUNC_CEIL 38
#define TSDB_FUNC_ROUND 39 #define TSDB_FUNC_FLOOR 39
#define TSDB_FUNC_MAVG 40 #define TSDB_FUNC_ROUND 40
#define TSDB_FUNC_CSUM 41 #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

View File

@ -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 {
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 {
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 {
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 {

View File

@ -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;

View File

@ -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
*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
*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 {
}; };
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,206 +3419,194 @@ static bool diff_function_setup(SQLFunctionCtx *pCtx) {
return false; return false;
} }
// TODO difference in date column static bool deriv_function_setup(SQLFunctionCtx *pCtx) {
static void diff_function(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); void *data = GET_INPUT_DATA_LIST(pCtx);
bool isFirstBlock = (pCtx->param[1].nType == INITIAL_VALUE_NOT_ASSIGNED); bool isFirstBlock = (pDerivInfo->valueSet == false);
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);
double *pOutput = (double *)pCtx->pOutput;
switch (pCtx->inputType) { switch (pCtx->inputType) {
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;
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 (!pDerivInfo->valueSet) { // initial value is not set yet
pCtx->param[1].i64 = pData[i]; pDerivInfo->valueSet = true;
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 { } else {
*pOutput = (int32_t)(pData[i] - pCtx->param[1].i64); // direct previous may be null *pOutput = ((pData[i] - pDerivInfo->prevValue) * pDerivInfo->tsWindow) / (tsList[i] - pDerivInfo->prevTs);
*pTimestamp = tsList[i]; if (pDerivInfo->ignoreNegative && *pOutput < 0) {
} else {
pOutput += 1; *pTimestamp = tsList[i];
pTimestamp += 1; pOutput += 1;
pTimestamp += 1;
}
} }
pCtx->param[1].i64 = pData[i]; pDerivInfo->prevValue = pData[i];
pCtx->param[1].nType = pCtx->inputType; pDerivInfo->prevTs = tsList[i];
notNullElems++; notNullElems++;
} }
break; break;
}; };
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;
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 (!pDerivInfo->valueSet) { // initial value is not set yet
pCtx->param[1].i64 = pData[i]; pDerivInfo->valueSet = true;
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];
pOutput += 1;
pTimestamp += 1;
} else { } else {
*pOutput = pData[i] - pCtx->param[1].i64; *pOutput = ((pData[i] - pDerivInfo->prevValue) * pDerivInfo->tsWindow) / (tsList[i] - pDerivInfo->prevTs);
*pTimestamp = tsList[i]; if (pDerivInfo->ignoreNegative && *pOutput < 0) {
} else {
pOutput += 1; *pTimestamp = tsList[i];
pTimestamp += 1; pOutput += 1;
pTimestamp += 1;
}
} }
pCtx->param[1].i64 = pData[i]; pDerivInfo->prevValue = (double) pData[i];
pCtx->param[1].nType = pCtx->inputType; pDerivInfo->prevTs = tsList[i];
notNullElems++; notNullElems++;
} }
break; break;
} }
case TSDB_DATA_TYPE_DOUBLE: { case TSDB_DATA_TYPE_DOUBLE: {
double *pData = (double *)data; double *pData = (double *)data;
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 (!pDerivInfo->valueSet) { // initial value is not set yet
pCtx->param[1].dKey = pData[i]; pDerivInfo->valueSet = true;
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 { } else {
*pOutput = pData[i] - pCtx->param[1].dKey; *pOutput = ((pData[i] - pDerivInfo->prevValue) * pDerivInfo->tsWindow) / (tsList[i] - pDerivInfo->prevTs);
*pTimestamp = tsList[i]; if (pDerivInfo->ignoreNegative && *pOutput < 0) {
pOutput += 1; } else {
pTimestamp += 1; *pTimestamp = tsList[i];
pOutput += 1;
pTimestamp += 1;
}
} }
pCtx->param[1].dKey = pData[i]; pDerivInfo->prevValue = pData[i];
pCtx->param[1].nType = pCtx->inputType; pDerivInfo->prevTs = tsList[i];
notNullElems++; notNullElems++;
} }
break; break;
} }
case TSDB_DATA_TYPE_FLOAT: { case TSDB_DATA_TYPE_FLOAT: {
float *pData = (float *)data; float *pData = (float *)data;
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 (!pDerivInfo->valueSet) { // initial value is not set yet
pCtx->param[1].dKey = pData[i]; pDerivInfo->valueSet = true;
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 { } else {
*pOutput = (float)(pData[i] - pCtx->param[1].dKey); *pOutput = ((pData[i] - pDerivInfo->prevValue) * pDerivInfo->tsWindow) / (tsList[i] - pDerivInfo->prevTs);
*pTimestamp = tsList[i]; if (pDerivInfo->ignoreNegative && *pOutput < 0) {
} else {
pOutput += 1; *pTimestamp = tsList[i];
pTimestamp += 1; pOutput += 1;
pTimestamp += 1;
}
} }
// keep the last value, the remain may be all null pDerivInfo->prevValue = pData[i];
pCtx->param[1].dKey = pData[i]; pDerivInfo->prevTs = tsList[i];
pCtx->param[1].nType = pCtx->inputType;
notNullElems++; notNullElems++;
} }
break; break;
} }
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;
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 (!pDerivInfo->valueSet) { // initial value is not set yet
pCtx->param[1].i64 = pData[i]; pDerivInfo->valueSet = true;
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 { } else {
*pOutput = (int16_t)(pData[i] - pCtx->param[1].i64); *pOutput = ((pData[i] - pDerivInfo->prevValue) * pDerivInfo->tsWindow) / (tsList[i] - pDerivInfo->prevTs);
*pTimestamp = tsList[i]; if (pDerivInfo->ignoreNegative && *pOutput < 0) {
} else {
pOutput += 1; *pTimestamp = tsList[i];
pTimestamp += 1; pOutput += 1;
pTimestamp += 1;
}
} }
pCtx->param[1].i64 = pData[i]; pDerivInfo->prevValue = pData[i];
pCtx->param[1].nType = pCtx->inputType; pDerivInfo->prevTs = tsList[i];
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;
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 (!pDerivInfo->valueSet) { // initial value is not set yet
pCtx->param[1].i64 = pData[i]; pDerivInfo->valueSet = true;
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 { } else {
*pOutput = (int8_t)(pData[i] - pCtx->param[1].i64); *pOutput = ((pData[i] - pDerivInfo->prevValue) * pDerivInfo->tsWindow) / (tsList[i] - pDerivInfo->prevTs);
*pTimestamp = tsList[i]; if (pDerivInfo->ignoreNegative && *pOutput < 0) {
} else {
pOutput += 1; *pTimestamp = tsList[i];
pTimestamp += 1;
pOutput += 1;
pTimestamp += 1;
}
} }
pCtx->param[1].i64 = pData[i]; pDerivInfo->prevValue = pData[i];
pCtx->param[1].nType = pCtx->inputType; pDerivInfo->prevTs = tsList[i];
notNullElems++; notNullElems++;
} }
break; break;
@ -3609,9 +3614,9 @@ 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, all data block are null
if (pCtx->param[1].nType == INITIAL_VALUE_NOT_ASSIGNED || notNullElems <= 0) { if (!pDerivInfo->valueSet || notNullElems <= 0) {
/* /*
* 1. current block and blocks before are full of null * 1. current block and blocks before are full of null
* 2. current block may be null value * 2. current block may be null value
@ -3619,7 +3624,6 @@ 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;
} }
} }
@ -3636,19 +3640,184 @@ static void diff_function(SQLFunctionCtx *pCtx) {
} \ } \
} while (0); } while (0);
// TODO difference in date column
static void diff_function(SQLFunctionCtx *pCtx) {
void *data = GET_INPUT_DATA_LIST(pCtx);
bool isFirstBlock = (pCtx->param[1].nType == INITIAL_VALUE_NOT_ASSIGNED);
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);
switch (pCtx->inputType) {
case TSDB_DATA_TYPE_INT: {
int32_t *pData = (int32_t *)data;
int32_t *pOutput = (int32_t *)pCtx->pOutput;
for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) {
continue;
}
if (pCtx->param[1].nType != INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet
*pOutput = (int32_t)(pData[i] - pCtx->param[1].i64); // direct previous may be null
*pTimestamp = tsList[i];
pOutput += 1;
pTimestamp += 1;
}
pCtx->param[1].i64 = pData[i];
pCtx->param[1].nType = pCtx->inputType;
notNullElems++;
}
break;
};
case TSDB_DATA_TYPE_BIGINT: {
int64_t *pData = (int64_t *)data;
int64_t *pOutput = (int64_t *)pCtx->pOutput;
for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) {
continue;
}
if (pCtx->param[1].nType != INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet
*pOutput = pData[i] - pCtx->param[1].i64; // direct previous may be null
*pTimestamp = tsList[i];
pOutput += 1;
pTimestamp += 1;
}
pCtx->param[1].i64 = pData[i];
pCtx->param[1].nType = pCtx->inputType;
notNullElems++;
}
break;
}
case TSDB_DATA_TYPE_DOUBLE: {
double *pData = (double *)data;
double *pOutput = (double *)pCtx->pOutput;
for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) {
continue;
}
if (pCtx->param[1].nType != INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet
*pOutput = pData[i] - pCtx->param[1].dKey; // direct previous may be null
*pTimestamp = tsList[i];
pOutput += 1;
pTimestamp += 1;
}
pCtx->param[1].dKey = pData[i];
pCtx->param[1].nType = pCtx->inputType;
notNullElems++;
}
break;
}
case TSDB_DATA_TYPE_FLOAT: {
float *pData = (float *)data;
float *pOutput = (float *)pCtx->pOutput;
for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) {
continue;
}
if (pCtx->param[1].nType != INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet
*pOutput = (float)(pData[i] - pCtx->param[1].dKey); // direct previous may be null
*pTimestamp = tsList[i];
pOutput += 1;
pTimestamp += 1;
}
pCtx->param[1].dKey = pData[i];
pCtx->param[1].nType = pCtx->inputType;
notNullElems++;
}
break;
}
case TSDB_DATA_TYPE_SMALLINT: {
int16_t *pData = (int16_t *)data;
int16_t *pOutput = (int16_t *)pCtx->pOutput;
for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) {
continue;
}
if (pCtx->param[1].nType != INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet
*pOutput = (int16_t)(pData[i] - pCtx->param[1].i64); // direct previous may be null
*pTimestamp = tsList[i];
pOutput += 1;
pTimestamp += 1;
}
pCtx->param[1].i64 = pData[i];
pCtx->param[1].nType = pCtx->inputType;
notNullElems++;
}
break;
}
case TSDB_DATA_TYPE_TINYINT: {
int8_t *pData = (int8_t *)data;
int8_t *pOutput = (int8_t *)pCtx->pOutput;
for (; i < pCtx->size && i >= 0; i += step) {
if (pCtx->hasNull && isNull((char *)&pData[i], pCtx->inputType)) {
continue;
}
if (pCtx->param[1].nType != INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet
*pOutput = (int8_t)(pData[i] - pCtx->param[1].i64); // direct previous may be null
*pTimestamp = tsList[i];
pOutput += 1;
pTimestamp += 1;
}
pCtx->param[1].i64 = pData[i];
pCtx->param[1].nType = pCtx->inputType;
notNullElems++;
}
break;
}
default:
qError("error input type");
}
// initial value is not set yet
if (pCtx->param[1].nType == INITIAL_VALUE_NOT_ASSIGNED || 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;
}
}
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) {
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) {
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) {
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[] = {{
"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[] = {{
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,

View File

@ -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
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
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) {
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*
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
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
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) {
} }
// 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
} }
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
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) {
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);

View File

@ -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
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
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) {

View File

@ -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) {
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;

View File

@ -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);

View File

@ -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) {
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) {
} 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) {
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
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
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);

View File

@ -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) {
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) {
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;
} }

View File

@ -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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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;
} }

163
tests/pytest/query/in.py Normal file
View File

@ -0,0 +1,163 @@
###################################################################
# 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())

View File

@ -1458,6 +1458,160 @@ 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 //1 tables 10 records
int stmt_funcb_autoctb_e1(TAOS_STMT *stmt) { int stmt_funcb_autoctb_e1(TAOS_STMT *stmt) {
struct { struct {
@ -1606,7 +1760,7 @@ int stmt_funcb_autoctb_e1(TAOS_STMT *stmt) {
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 (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); 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. error:%s\n", taos_stmt_errstr(stmt));
return -1; return -1;
} }
@ -1824,6 +1978,224 @@ int stmt_funcb_autoctb_e2(TAOS_STMT *stmt) {
exit(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:%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; int id = 0;
for (int zz = 0; zz < 1; zz++) { for (int zz = 0; zz < 1; zz++) {
char buf[32]; char buf[32];
@ -1860,6 +2232,458 @@ int stmt_funcb_autoctb_e2(TAOS_STMT *stmt) {
//1 tables 10 records
int stmt_funcb_autoctb_e4(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:%s\n", taos_stmt_errstr(stmt));
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. 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));
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);
}
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_e5(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(NULL, sql, 0);
if (code != 0){
printf("failed to execute taos_stmt_prepare. code:%s\n", taos_stmt_errstr(NULL));
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. 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));
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);
}
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;
}
//300 tables 60 records //300 tables 60 records
int stmt_funcb1(TAOS_STMT *stmt) { int stmt_funcb1(TAOS_STMT *stmt) {
struct { struct {
@ -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) {
#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) {
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) {
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) {
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) {
#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) {
#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) {
#endif #endif
printf("test end\n");
return NULL; return NULL;
} }

View File

@ -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
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
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

View File

@ -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

View File

@ -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

View File

@ -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
endi endi
system sh/exec.sh -n dnode1 -s stop -x SIGINT system sh/exec.sh -n dnode1 -s stop -x SIGINT