未验证 提交 901cf55f 编写于 作者: D dapan1121 提交者: GitHub

Merge pull request #11891 from taosdata/feature/qnode

feat: handle null value
......@@ -93,14 +93,14 @@ typedef struct taosField {
typedef void (*__taos_async_fn_t)(void *param, TAOS_RES *, int code);
typedef struct TAOS_BIND_v2 {
int buffer_type;
void *buffer;
int32_t buffer_length;
int32_t *length;
char *is_null;
int num;
} TAOS_BIND_v2;
typedef struct TAOS_MULTI_BIND {
int buffer_type;
void *buffer;
uintptr_t buffer_length;
int32_t *length;
char *is_null;
int num;
} TAOS_MULTI_BIND;
typedef enum {
SET_CONF_RET_SUCC = 0,
......@@ -129,35 +129,35 @@ DLL_EXPORT void taos_close(TAOS *taos);
const char *taos_data_type(int type);
DLL_EXPORT TAOS_STMT *taos_stmt_init(TAOS *taos);
DLL_EXPORT int taos_stmt_prepare(TAOS_STMT *stmt, const char *sql, unsigned long length);
DLL_EXPORT int taos_stmt_set_tbname_tags(TAOS_STMT *stmt, const char *name, TAOS_BIND_v2 *tags);
DLL_EXPORT int taos_stmt_set_tbname(TAOS_STMT *stmt, const char *name);
DLL_EXPORT int taos_stmt_set_sub_tbname(TAOS_STMT *stmt, const char *name);
DLL_EXPORT int taos_stmt_is_insert(TAOS_STMT *stmt, int *insert);
DLL_EXPORT int taos_stmt_num_params(TAOS_STMT *stmt, int *nums);
DLL_EXPORT int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes);
DLL_EXPORT int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_BIND_v2 *bind);
DLL_EXPORT int taos_stmt_bind_param_batch(TAOS_STMT *stmt, TAOS_BIND_v2 *bind);
DLL_EXPORT int taos_stmt_bind_single_param_batch(TAOS_STMT *stmt, TAOS_BIND_v2 *bind, int colIdx);
DLL_EXPORT int taos_stmt_add_batch(TAOS_STMT *stmt);
DLL_EXPORT int taos_stmt_execute(TAOS_STMT *stmt);
DLL_EXPORT TAOS_RES *taos_stmt_use_result(TAOS_STMT *stmt);
DLL_EXPORT int taos_stmt_close(TAOS_STMT *stmt);
DLL_EXPORT char *taos_stmt_errstr(TAOS_STMT *stmt);
DLL_EXPORT int taos_stmt_affected_rows(TAOS_STMT *stmt);
DLL_EXPORT int taos_stmt_affected_rows_once(TAOS_STMT *stmt);
DLL_EXPORT TAOS_RES *taos_query(TAOS *taos, const char *sql);
DLL_EXPORT TAOS_RES *taos_query_l(TAOS *taos, const char *sql, int sqlLen);
DLL_EXPORT TAOS_ROW taos_fetch_row(TAOS_RES *res);
DLL_EXPORT int taos_result_precision(TAOS_RES *res); // get the time precision of result
DLL_EXPORT void taos_free_result(TAOS_RES *res);
DLL_EXPORT int taos_field_count(TAOS_RES *res);
DLL_EXPORT int taos_num_fields(TAOS_RES *res);
DLL_EXPORT int taos_affected_rows(TAOS_RES *res);
DLL_EXPORT TAOS_STMT *taos_stmt_init(TAOS *taos);
DLL_EXPORT int taos_stmt_prepare(TAOS_STMT *stmt, const char *sql, unsigned long length);
DLL_EXPORT int taos_stmt_set_tbname_tags(TAOS_STMT *stmt, const char *name, TAOS_MULTI_BIND *tags);
DLL_EXPORT int taos_stmt_set_tbname(TAOS_STMT *stmt, const char *name);
DLL_EXPORT int taos_stmt_set_sub_tbname(TAOS_STMT *stmt, const char *name);
DLL_EXPORT int taos_stmt_is_insert(TAOS_STMT *stmt, int *insert);
DLL_EXPORT int taos_stmt_num_params(TAOS_STMT *stmt, int *nums);
DLL_EXPORT int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes);
DLL_EXPORT int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind);
DLL_EXPORT int taos_stmt_bind_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind);
DLL_EXPORT int taos_stmt_bind_single_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int colIdx);
DLL_EXPORT int taos_stmt_add_batch(TAOS_STMT *stmt);
DLL_EXPORT int taos_stmt_execute(TAOS_STMT *stmt);
DLL_EXPORT TAOS_RES *taos_stmt_use_result(TAOS_STMT *stmt);
DLL_EXPORT int taos_stmt_close(TAOS_STMT *stmt);
DLL_EXPORT char *taos_stmt_errstr(TAOS_STMT *stmt);
DLL_EXPORT int taos_stmt_affected_rows(TAOS_STMT *stmt);
DLL_EXPORT int taos_stmt_affected_rows_once(TAOS_STMT *stmt);
DLL_EXPORT TAOS_RES *taos_query(TAOS *taos, const char *sql);
DLL_EXPORT TAOS_RES *taos_query_l(TAOS *taos, const char *sql, int sqlLen);
DLL_EXPORT TAOS_ROW taos_fetch_row(TAOS_RES *res);
DLL_EXPORT int taos_result_precision(TAOS_RES *res); // get the time precision of result
DLL_EXPORT void taos_free_result(TAOS_RES *res);
DLL_EXPORT int taos_field_count(TAOS_RES *res);
DLL_EXPORT int taos_num_fields(TAOS_RES *res);
DLL_EXPORT int taos_affected_rows(TAOS_RES *res);
DLL_EXPORT TAOS_FIELD *taos_fetch_fields(TAOS_RES *res);
DLL_EXPORT int taos_select_db(TAOS *taos, const char *db);
......
......@@ -88,11 +88,11 @@ int32_t qCloneStmtDataBlock(void** pDst, void* pSrc);
void qFreeStmtDataBlock(void* pDataBlock);
int32_t qRebuildStmtDataBlock(void** pDst, void* pSrc);
void qDestroyStmtDataBlock(void* pBlock);
int32_t qBindStmtColsValue(void *pBlock, TAOS_BIND_v2 *bind, char *msgBuf, int32_t msgBufLen);
int32_t qBindStmtSingleColValue(void *pBlock, TAOS_BIND_v2 *bind, char *msgBuf, int32_t msgBufLen, int32_t colIdx, int32_t rowNum);
int32_t qBindStmtColsValue(void *pBlock, TAOS_MULTI_BIND *bind, char *msgBuf, int32_t msgBufLen);
int32_t qBindStmtSingleColValue(void *pBlock, TAOS_MULTI_BIND *bind, char *msgBuf, int32_t msgBufLen, int32_t colIdx, int32_t rowNum);
int32_t qBuildStmtColFields(void *pDataBlock, int32_t *fieldNum, TAOS_FIELD** fields);
int32_t qBuildStmtTagFields(void *pBlock, void *boundTags, int32_t *fieldNum, TAOS_FIELD** fields);
int32_t qBindStmtTagsValue(void *pBlock, void *boundTags, int64_t suid, SName *pName, TAOS_BIND_v2 *bind, char *msgBuf, int32_t msgBufLen);
int32_t qBindStmtTagsValue(void *pBlock, void *boundTags, int64_t suid, SName *pName, TAOS_MULTI_BIND *bind, char *msgBuf, int32_t msgBufLen);
void destroyBoundColumnInfo(void* pBoundInfo);
int32_t qCreateSName(SName* pName, const char* pTableName, int32_t acctId, char* dbName, char *msgBuf, int32_t msgBufLen);
......
......@@ -50,7 +50,7 @@ int32_t qCreateQueryPlan(SPlanContext* pCxt, SQueryPlan** pPlan, SArray* pExecNo
// @pSource one execution location of this group of datasource subplans
int32_t qSetSubplanExecutionNode(SSubplan* pSubplan, int32_t groupId, SDownstreamSourceNode* pSource);
int32_t qStmtBindParam(SQueryPlan* pPlan, TAOS_BIND_v2* pParams);
int32_t qStmtBindParam(SQueryPlan* pPlan, TAOS_MULTI_BIND* pParams, int32_t colIdx);
// Convert to subplan to string for the scheduler to send to the executor
int32_t qSubPlanToString(const SSubplan* pSubplan, char** pStr, int32_t* pLen);
......
......@@ -195,6 +195,8 @@ typedef enum EOperatorType {
OP_TYPE_JSON_CONTAINS
} EOperatorType;
#define OP_TYPE_CALC_MAX OP_TYPE_BIT_OR
typedef enum ELogicConditionType {
LOGIC_COND_TYPE_AND = 1,
LOGIC_COND_TYPE_OR,
......
......@@ -310,6 +310,9 @@ int hbAddConnInfo(SAppHbMgr* pAppHbMgr, SClientHbKey connKey, void* key, void* v
void hbMgrInitMqHbRspHandle();
SRequestObj* launchQueryImpl(SRequestObj* pRequest, SQuery* pQuery, int32_t code, bool keepQuery);
int32_t getQueryPlan(SRequestObj* pRequest, SQuery* pQuery, SArray** pNodeList);
int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList);
#ifdef __cplusplus
}
......
......@@ -34,8 +34,7 @@ typedef enum {
STMT_PREPARE,
STMT_SETTBNAME,
STMT_SETTAGS,
STMT_FETCH_TAG_FIELDS,
STMT_FETCH_COL_FIELDS,
STMT_FETCH_FIELDS,
STMT_BIND,
STMT_BIND_COL,
STMT_ADD_BATCH,
......@@ -75,6 +74,8 @@ typedef struct SStmtSQLInfo {
SQuery* pQuery;
char* sqlStr;
int32_t sqlLen;
SArray* nodeList;
SQueryPlan* pQueryPlan;
} SStmtSQLInfo;
typedef struct STscStmt {
......@@ -87,6 +88,8 @@ typedef struct STscStmt {
SStmtBindInfo bInfo;
} STscStmt;
#define STMT_STATUS_NE(S) (pStmt->sql.status != STMT_##S)
#define STMT_STATUS_EQ(S) (pStmt->sql.status == STMT_##S)
#define STMT_ERR_RET(c) do { int32_t _code = c; if (_code != TSDB_CODE_SUCCESS) { terrno = _code; return _code; } } while (0)
#define STMT_RET(c) do { int32_t _code = c; if (_code != TSDB_CODE_SUCCESS) { terrno = _code; } return _code; } while (0)
......@@ -97,14 +100,15 @@ int stmtClose(TAOS_STMT *stmt);
int stmtExec(TAOS_STMT *stmt);
const char *stmtErrstr(TAOS_STMT *stmt);
int stmtAffectedRows(TAOS_STMT *stmt);
int stmtAffectedRowsOnce(TAOS_STMT *stmt);
int stmtPrepare(TAOS_STMT *stmt, const char *sql, unsigned long length);
int stmtSetTbName(TAOS_STMT *stmt, const char *tbName);
int stmtSetTbTags(TAOS_STMT *stmt, TAOS_BIND_v2 *tags);
int stmtSetTbTags(TAOS_STMT *stmt, TAOS_MULTI_BIND *tags);
int stmtIsInsert(TAOS_STMT *stmt, int *insert);
int stmtGetParamNum(TAOS_STMT *stmt, int *nums);
int stmtAddBatch(TAOS_STMT *stmt);
TAOS_RES *stmtUseResult(TAOS_STMT *stmt);
int stmtBindBatch(TAOS_STMT *stmt, TAOS_BIND_v2 *bind, int32_t colIdx);
int stmtBindBatch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int32_t colIdx);
#ifdef __cplusplus
......
......@@ -305,6 +305,11 @@ int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList
return pRequest->code;
}
int32_t getQueryPlan(SRequestObj* pRequest, SQuery* pQuery, SArray** pNodeList) {
*pNodeList = taosArrayInit(4, sizeof(struct SQueryNodeAddr));
return getPlan(pRequest, pQuery, &pRequest->body.pDag, *pNodeList);
}
SRequestObj* launchQueryImpl(SRequestObj* pRequest, SQuery* pQuery, int32_t code, bool keepQuery) {
if (TSDB_CODE_SUCCESS == code) {
switch (pQuery->execMode) {
......
......@@ -603,7 +603,7 @@ int taos_stmt_prepare(TAOS_STMT *stmt, const char *sql, unsigned long length) {
return stmtPrepare(stmt, sql, length);
}
int taos_stmt_set_tbname_tags(TAOS_STMT *stmt, const char *name, TAOS_BIND_v2 *tags) {
int taos_stmt_set_tbname_tags(TAOS_STMT *stmt, const char *name, TAOS_MULTI_BIND *tags) {
if (stmt == NULL || name == NULL) {
tscError("NULL parameter for %s", __FUNCTION__);
terrno = TSDB_CODE_INVALID_PARA;
......@@ -636,7 +636,7 @@ int taos_stmt_set_sub_tbname(TAOS_STMT *stmt, const char *name) {
return taos_stmt_set_tbname(stmt, name);
}
int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_BIND_v2 *bind) {
int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind) {
if (stmt == NULL || bind == NULL) {
tscError("NULL parameter for %s", __FUNCTION__);
terrno = TSDB_CODE_INVALID_PARA;
......@@ -652,7 +652,7 @@ int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_BIND_v2 *bind) {
return stmtBindBatch(stmt, bind, -1);
}
int taos_stmt_bind_param_batch(TAOS_STMT *stmt, TAOS_BIND_v2 *bind) {
int taos_stmt_bind_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind) {
if (stmt == NULL || bind == NULL) {
tscError("NULL parameter for %s", __FUNCTION__);
terrno = TSDB_CODE_INVALID_PARA;
......@@ -665,10 +665,18 @@ int taos_stmt_bind_param_batch(TAOS_STMT *stmt, TAOS_BIND_v2 *bind) {
return terrno;
}
int32_t insert = 0;
stmtIsInsert(stmt, &insert);
if (0 == insert && bind->num > 1) {
tscError("only one row data allowed for query");
terrno = TSDB_CODE_INVALID_PARA;
return terrno;
}
return stmtBindBatch(stmt, bind, -1);
}
int taos_stmt_bind_single_param_batch(TAOS_STMT *stmt, TAOS_BIND_v2 *bind, int colIdx) {
int taos_stmt_bind_single_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int colIdx) {
if (stmt == NULL || bind == NULL) {
tscError("NULL parameter for %s", __FUNCTION__);
terrno = TSDB_CODE_INVALID_PARA;
......@@ -680,6 +688,14 @@ int taos_stmt_bind_single_param_batch(TAOS_STMT *stmt, TAOS_BIND_v2 *bind, int c
terrno = TSDB_CODE_INVALID_PARA;
return terrno;
}
int32_t insert = 0;
stmtIsInsert(stmt, &insert);
if (0 == insert && bind->num > 1) {
tscError("only one row data allowed for query");
terrno = TSDB_CODE_INVALID_PARA;
return terrno;
}
return stmtBindBatch(stmt, bind, colIdx);
}
......@@ -748,6 +764,16 @@ int taos_stmt_affected_rows(TAOS_STMT *stmt) {
return stmtAffectedRows(stmt);
}
int taos_stmt_affected_rows_once(TAOS_STMT *stmt) {
if (stmt == NULL) {
tscError("NULL parameter for %s", __FUNCTION__);
terrno = TSDB_CODE_INVALID_PARA;
return 0;
}
return stmtAffectedRowsOnce(stmt);
}
int taos_stmt_close(TAOS_STMT *stmt) {
if (stmt == NULL) {
tscError("NULL parameter for %s", __FUNCTION__);
......
......@@ -5,14 +5,52 @@
#include "tdef.h"
int32_t stmtSwitchStatus(STscStmt* pStmt, STMT_STATUS newStatus) {
int32_t code = 0;
switch (newStatus) {
case STMT_PREPARE:
break;
case STMT_SETTBNAME:
if (STMT_STATUS_EQ(INIT) || STMT_STATUS_EQ(BIND) || STMT_STATUS_EQ(BIND_COL)) {
code = TSDB_CODE_TSC_STMT_API_ERROR;
}
break;
case STMT_SETTAGS:
if (STMT_STATUS_NE(SETTBNAME)) {
code = TSDB_CODE_TSC_STMT_API_ERROR;
}
break;
case STMT_FETCH_FIELDS:
if (STMT_STATUS_EQ(INIT)) {
code = TSDB_CODE_TSC_STMT_API_ERROR;
}
break;
case STMT_BIND:
if (STMT_STATUS_EQ(INIT) || STMT_STATUS_EQ(BIND_COL)) {
code = TSDB_CODE_TSC_STMT_API_ERROR;
}
break;
case STMT_BIND_COL:
if (STMT_STATUS_EQ(INIT) || STMT_STATUS_EQ(BIND)) {
code = TSDB_CODE_TSC_STMT_API_ERROR;
}
break;
case STMT_ADD_BATCH:
if (STMT_STATUS_NE(BIND) && STMT_STATUS_NE(BIND_COL) && STMT_STATUS_NE(FETCH_FIELDS)) {
code = TSDB_CODE_TSC_STMT_API_ERROR;
}
break;
case STMT_EXECUTE:
if (STMT_STATUS_NE(ADD_BATCH) && STMT_STATUS_NE(FETCH_FIELDS)) {
code = TSDB_CODE_TSC_STMT_API_ERROR;
}
break;
default:
code = TSDB_CODE_TSC_APP_ERROR;
break;
}
//STMT_ERR_RET(TSDB_CODE_TSC_STMT_API_ERROR);
STMT_ERR_RET(code);
pStmt->sql.status = newStatus;
......@@ -69,15 +107,10 @@ int32_t stmtCacheBlock(STscStmt *pStmt) {
return TSDB_CODE_SUCCESS;
}
uint64_t uid;
if (TSDB_CHILD_TABLE == pStmt->bInfo.tbType) {
uid = pStmt->bInfo.tbSuid;
} else {
ASSERT(TSDB_NORMAL_TABLE == pStmt->bInfo.tbType);
uid = pStmt->bInfo.tbUid;
}
uint64_t uid = pStmt->bInfo.tbUid;
uint64_t tuid = (TSDB_CHILD_TABLE == pStmt->bInfo.tbType) ? pStmt->bInfo.tbSuid : uid;
if (taosHashGet(pStmt->sql.pTableCache, &uid, sizeof(uid))) {
if (taosHashGet(pStmt->sql.pTableCache, &tuid, sizeof(tuid))) {
return TSDB_CODE_SUCCESS;
}
......@@ -91,7 +124,7 @@ int32_t stmtCacheBlock(STscStmt *pStmt) {
.boundTags = pStmt->bInfo.boundTags,
};
if (taosHashPut(pStmt->sql.pTableCache, &uid, sizeof(uid), &cache, sizeof(cache))) {
if (taosHashPut(pStmt->sql.pTableCache, &tuid, sizeof(tuid), &cache, sizeof(cache))) {
return TSDB_CODE_OUT_OF_MEMORY;
}
......@@ -149,9 +182,11 @@ int32_t stmtCleanBindInfo(STscStmt* pStmt) {
return TSDB_CODE_SUCCESS;
}
int32_t stmtCleanExecInfo(STscStmt* pStmt, bool keepTable) {
taos_free_result(pStmt->exec.pRequest);
pStmt->exec.pRequest = NULL;
int32_t stmtCleanExecInfo(STscStmt* pStmt, bool keepTable, bool freeRequest) {
if (STMT_TYPE_QUERY != pStmt->sql.type || freeRequest) {
taos_free_result(pStmt->exec.pRequest);
pStmt->exec.pRequest = NULL;
}
void *pIter = taosHashIterate(pStmt->exec.pBlockHash, NULL);
while (pIter) {
......@@ -186,7 +221,9 @@ int32_t stmtCleanExecInfo(STscStmt* pStmt, bool keepTable) {
int32_t stmtCleanSQLInfo(STscStmt* pStmt) {
taosMemoryFree(pStmt->sql.sqlStr);
qDestroyQuery(pStmt->sql.pQuery);
qDestroyQueryPlan(pStmt->sql.pQueryPlan);
taosArrayDestroy(pStmt->sql.nodeList);
void *pIter = taosHashIterate(pStmt->sql.pTableCache, NULL);
while (pIter) {
SStmtTableCache* pCache = (SStmtTableCache*)pIter;
......@@ -201,7 +238,7 @@ int32_t stmtCleanSQLInfo(STscStmt* pStmt) {
memset(&pStmt->sql, 0, sizeof(pStmt->sql));
STMT_ERR_RET(stmtCleanExecInfo(pStmt, false));
STMT_ERR_RET(stmtCleanExecInfo(pStmt, false, true));
STMT_ERR_RET(stmtCleanBindInfo(pStmt));
return TSDB_CODE_SUCCESS;
......@@ -333,6 +370,13 @@ int stmtSetTbName(TAOS_STMT *stmt, const char *tbName) {
STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_SETTBNAME));
int32_t insert = 0;
stmtIsInsert(stmt, &insert);
if (0 == insert) {
tscError("set tb name not available for none insert statement");
STMT_ERR_RET(TSDB_CODE_TSC_STMT_API_ERROR);
}
if (NULL == pStmt->exec.pRequest) {
STMT_ERR_RET(buildRequest(pStmt->taos, pStmt->sql.sqlStr, pStmt->sql.sqlLen, &pStmt->exec.pRequest));
}
......@@ -349,7 +393,7 @@ int stmtSetTbName(TAOS_STMT *stmt, const char *tbName) {
return TSDB_CODE_SUCCESS;
}
int stmtSetTbTags(TAOS_STMT *stmt, TAOS_BIND_v2 *tags) {
int stmtSetTbTags(TAOS_STMT *stmt, TAOS_MULTI_BIND *tags) {
STscStmt* pStmt = (STscStmt*)stmt;
STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_SETTAGS));
......@@ -370,15 +414,7 @@ int stmtSetTbTags(TAOS_STMT *stmt, TAOS_BIND_v2 *tags) {
}
int32_t stmtFetchTagFields(TAOS_STMT *stmt, int32_t *fieldNum, TAOS_FIELD** fields) {
STscStmt* pStmt = (STscStmt*)stmt;
STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_FETCH_TAG_FIELDS));
if (pStmt->bInfo.needParse) {
STMT_ERR_RET(stmtParseSql(pStmt));
}
int32_t stmtFetchTagFields(STscStmt* pStmt, int32_t *fieldNum, TAOS_FIELD** fields) {
if (STMT_TYPE_QUERY == pStmt->sql.type) {
tscError("invalid operation to get query tag fileds");
STMT_ERR_RET(TSDB_CODE_TSC_STMT_API_ERROR);
......@@ -395,15 +431,7 @@ int32_t stmtFetchTagFields(TAOS_STMT *stmt, int32_t *fieldNum, TAOS_FIELD** fiel
return TSDB_CODE_SUCCESS;
}
int32_t stmtFetchColFields(TAOS_STMT *stmt, int32_t *fieldNum, TAOS_FIELD** fields) {
STscStmt* pStmt = (STscStmt*)stmt;
STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_FETCH_COL_FIELDS));
if (pStmt->bInfo.needParse) {
STMT_ERR_RET(stmtParseSql(pStmt));
}
int32_t stmtFetchColFields(STscStmt* pStmt, int32_t *fieldNum, TAOS_FIELD** fields) {
if (STMT_TYPE_QUERY == pStmt->sql.type) {
tscError("invalid operation to get query column fileds");
STMT_ERR_RET(TSDB_CODE_TSC_STMT_API_ERROR);
......@@ -420,7 +448,7 @@ int32_t stmtFetchColFields(TAOS_STMT *stmt, int32_t *fieldNum, TAOS_FIELD** fiel
return TSDB_CODE_SUCCESS;
}
int stmtBindBatch(TAOS_STMT *stmt, TAOS_BIND_v2 *bind, int32_t colIdx) {
int stmtBindBatch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int32_t colIdx) {
STscStmt* pStmt = (STscStmt*)stmt;
STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_BIND));
......@@ -429,6 +457,11 @@ int stmtBindBatch(TAOS_STMT *stmt, TAOS_BIND_v2 *bind, int32_t colIdx) {
pStmt->bInfo.needParse = false;
}
if (pStmt->exec.pRequest && STMT_TYPE_QUERY == pStmt->sql.type && pStmt->sql.runTimes) {
taos_free_result(pStmt->exec.pRequest);
pStmt->exec.pRequest = NULL;
}
if (NULL == pStmt->exec.pRequest) {
STMT_ERR_RET(buildRequest(pStmt->taos, pStmt->sql.sqlStr, pStmt->sql.sqlLen, &pStmt->exec.pRequest));
}
......@@ -437,6 +470,16 @@ int stmtBindBatch(TAOS_STMT *stmt, TAOS_BIND_v2 *bind, int32_t colIdx) {
STMT_ERR_RET(stmtParseSql(pStmt));
}
if (STMT_TYPE_QUERY == pStmt->sql.type) {
if (NULL == pStmt->sql.pQueryPlan) {
STMT_ERR_RET(getQueryPlan(pStmt->exec.pRequest, pStmt->sql.pQuery, &pStmt->sql.nodeList));
pStmt->sql.pQueryPlan = pStmt->exec.pRequest->body.pDag;
pStmt->exec.pRequest->body.pDag = NULL;
}
STMT_RET(qStmtBindParam(pStmt->sql.pQueryPlan, bind, colIdx));
}
STableDataBlocks **pDataBlock = (STableDataBlocks**)taosHashGet(pStmt->exec.pBlockHash, (const char*)&pStmt->bInfo.tbUid, sizeof(pStmt->bInfo.tbUid));
if (NULL == pDataBlock) {
tscError("table uid %" PRIx64 "not found in exec blockHash", pStmt->bInfo.tbUid);
......@@ -480,10 +523,13 @@ int stmtExec(TAOS_STMT *stmt) {
STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_EXECUTE));
STMT_ERR_RET(qBuildStmtOutput(pStmt->sql.pQuery, pStmt->exec.pVgHash, pStmt->exec.pBlockHash));
launchQueryImpl(pStmt->exec.pRequest, pStmt->sql.pQuery, TSDB_CODE_SUCCESS, true);
if (STMT_TYPE_QUERY == pStmt->sql.type) {
scheduleQuery(pStmt->exec.pRequest, pStmt->sql.pQueryPlan, pStmt->sql.nodeList);
} else {
STMT_ERR_RET(qBuildStmtOutput(pStmt->sql.pQuery, pStmt->exec.pVgHash, pStmt->exec.pBlockHash));
launchQueryImpl(pStmt->exec.pRequest, pStmt->sql.pQuery, TSDB_CODE_SUCCESS, true);
}
STMT_ERR_JRET(pStmt->exec.pRequest->code);
pStmt->exec.affectedRows = taos_affected_rows(pStmt->exec.pRequest);
......@@ -491,7 +537,7 @@ int stmtExec(TAOS_STMT *stmt) {
_return:
stmtCleanExecInfo(pStmt, (code ? false : true));
stmtCleanExecInfo(pStmt, (code ? false : true), false);
++pStmt->sql.runTimes;
......@@ -523,6 +569,10 @@ int stmtAffectedRows(TAOS_STMT *stmt) {
return ((STscStmt*)stmt)->affectedRows;
}
int stmtAffectedRowsOnce(TAOS_STMT *stmt) {
return ((STscStmt*)stmt)->exec.affectedRows;
}
int stmtIsInsert(TAOS_STMT *stmt, int *insert) {
STscStmt* pStmt = (STscStmt*)stmt;
......@@ -536,13 +586,38 @@ int stmtIsInsert(TAOS_STMT *stmt, int *insert) {
}
int stmtGetParamNum(TAOS_STMT *stmt, int *nums) {
STMT_ERR_RET(stmtFetchColFields(stmt, nums, NULL));
STscStmt* pStmt = (STscStmt*)stmt;
STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_FETCH_FIELDS));
if (pStmt->bInfo.needParse) {
STMT_ERR_RET(stmtParseSql(pStmt));
}
if (STMT_TYPE_QUERY == pStmt->sql.type) {
if (NULL == pStmt->sql.pQueryPlan) {
STMT_ERR_RET(getQueryPlan(pStmt->exec.pRequest, pStmt->sql.pQuery, &pStmt->sql.nodeList));
pStmt->sql.pQueryPlan = pStmt->exec.pRequest->body.pDag;
pStmt->exec.pRequest->body.pDag = NULL;
}
*nums = (pStmt->sql.pQueryPlan->pPlaceholderValues) ? pStmt->sql.pQueryPlan->pPlaceholderValues->length : 0;
} else {
STMT_ERR_RET(stmtFetchColFields(stmt, nums, NULL));
}
return TSDB_CODE_SUCCESS;
}
TAOS_RES *stmtUseResult(TAOS_STMT *stmt) {
return NULL;
STscStmt* pStmt = (STscStmt*)stmt;
if (STMT_TYPE_QUERY != pStmt->sql.type) {
tscError("useResult only for query statement");
return NULL;
}
return pStmt->exec.pRequest;
}
......
......@@ -1256,10 +1256,9 @@ int32_t qBuildStmtOutput(SQuery* pQuery, SHashObj* pVgHash, SHashObj* pBlockHash
return TSDB_CODE_SUCCESS;
}
int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, SName* pName, TAOS_BIND_v2* bind, char* msgBuf,
int32_t msgBufLen) {
STableDataBlocks* pDataBlock = (STableDataBlocks*)pBlock;
SMsgBuf pBuf = {.buf = msgBuf, .len = msgBufLen};
int32_t qBindStmtTagsValue(void *pBlock, void *boundTags, int64_t suid, SName *pName, TAOS_MULTI_BIND *bind, char *msgBuf, int32_t msgBufLen){
STableDataBlocks *pDataBlock = (STableDataBlocks *)pBlock;
SMsgBuf pBuf = {.buf = msgBuf, .len = msgBufLen};
SParsedDataColInfo* tags = (SParsedDataColInfo*)boundTags;
if (NULL == tags) {
return TSDB_CODE_QRY_APP_ERROR;
......@@ -1307,10 +1306,11 @@ int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, SName* p
return TSDB_CODE_SUCCESS;
}
int32_t qBindStmtColsValue(void* pBlock, TAOS_BIND_v2* bind, char* msgBuf, int32_t msgBufLen) {
STableDataBlocks* pDataBlock = (STableDataBlocks*)pBlock;
SSchema* pSchema = getTableColumnSchema(pDataBlock->pTableMeta);
int32_t extendedRowSize = getExtendedRowSize(pDataBlock);
int32_t qBindStmtColsValue(void *pBlock, TAOS_MULTI_BIND *bind, char *msgBuf, int32_t msgBufLen) {
STableDataBlocks *pDataBlock = (STableDataBlocks *)pBlock;
SSchema* pSchema = getTableColumnSchema(pDataBlock->pTableMeta);
int32_t extendedRowSize = getExtendedRowSize(pDataBlock);
SParsedDataColInfo* spd = &pDataBlock->boundColumnInfo;
SRowBuilder* pBuilder = &pDataBlock->rowBuilder;
SMemParam param = {.rb = pBuilder};
......@@ -1381,11 +1381,10 @@ int32_t qBindStmtColsValue(void* pBlock, TAOS_BIND_v2* bind, char* msgBuf, int32
return TSDB_CODE_SUCCESS;
}
int32_t qBindStmtSingleColValue(void* pBlock, TAOS_BIND_v2* bind, char* msgBuf, int32_t msgBufLen, int32_t colIdx,
int32_t rowNum) {
STableDataBlocks* pDataBlock = (STableDataBlocks*)pBlock;
SSchema* pSchema = getTableColumnSchema(pDataBlock->pTableMeta);
int32_t extendedRowSize = getExtendedRowSize(pDataBlock);
int32_t qBindStmtSingleColValue(void *pBlock, TAOS_MULTI_BIND *bind, char *msgBuf, int32_t msgBufLen, int32_t colIdx, int32_t rowNum) {
STableDataBlocks *pDataBlock = (STableDataBlocks *)pBlock;
SSchema* pSchema = getTableColumnSchema(pDataBlock->pTableMeta);
int32_t extendedRowSize = getExtendedRowSize(pDataBlock);
SParsedDataColInfo* spd = &pDataBlock->boundColumnInfo;
SRowBuilder* pBuilder = &pDataBlock->rowBuilder;
SMemParam param = {.rb = pBuilder};
......
......@@ -101,8 +101,8 @@ int32_t qSetSubplanExecutionNode(SSubplan* subplan, int32_t groupId, SDownstream
return setSubplanExecutionNode(subplan->pNode, groupId, pSource);
}
static int32_t setValueByBindParam(SValueNode* pVal, TAOS_BIND_v2* pParam) {
if (1 == *(pParam->is_null)) {
static int32_t setValueByBindParam(SValueNode* pVal, TAOS_MULTI_BIND* pParam) {
if (pParam->is_null && 1 == *(pParam->is_null)) {
pVal->node.resType.type = TSDB_DATA_TYPE_NULL;
pVal->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_NULL].bytes;
return TSDB_CODE_SUCCESS;
......@@ -168,10 +168,18 @@ static int32_t setValueByBindParam(SValueNode* pVal, TAOS_BIND_v2* pParam) {
return TSDB_CODE_SUCCESS;
}
int32_t qStmtBindParam(SQueryPlan* pPlan, TAOS_BIND_v2* pParams) {
int32_t index = 0;
SNode* pNode = NULL;
FOREACH(pNode, pPlan->pPlaceholderValues) { setValueByBindParam((SValueNode*)pNode, pParams + index); }
int32_t qStmtBindParam(SQueryPlan* pPlan, TAOS_MULTI_BIND* pParams, int32_t colIdx) {
if (colIdx < 0) {
int32_t index = 0;
SNode* pNode = NULL;
FOREACH(pNode, pPlan->pPlaceholderValues) {
setValueByBindParam((SValueNode*)pNode, pParams + index);
++index;
}
} else {
setValueByBindParam((SValueNode*)nodesListGetNode(pPlan->pPlaceholderValues, colIdx), pParams);
}
return TSDB_CODE_SUCCESS;
}
......
......@@ -26,7 +26,7 @@ class PlanStmtTest : public PlannerTestBase {
}
void bindParam(int32_t val) {
TAOS_BIND_v2* pBind = pBindParams_ + paramNo_++;
TAOS_MULTI_BIND* pBind = pBindParams_ + paramNo_++;
pBind->buffer_type = TSDB_DATA_TYPE_INT;
pBind->num = 1;
pBind->buffer_length = sizeof(int32_t);
......@@ -42,9 +42,9 @@ class PlanStmtTest : public PlannerTestBase {
// todo
}
private:
TAOS_BIND_v2* pBindParams_;
int32_t paramNo_;
private:
TAOS_MULTI_BIND* pBindParams_;
int32_t paramNo_;
};
TEST_F(PlanStmtTest, stmt) {
......
......@@ -34,6 +34,7 @@ typedef struct SScalarCtx {
#define SCL_IS_CONST_NODE(_node) ((NULL == (_node)) || (QUERY_NODE_VALUE == (_node)->type) || (QUERY_NODE_NODE_LIST == (_node)->type))
#define SCL_IS_CONST_CALC(_ctx) (NULL == (_ctx)->pBlockList)
#define SCL_IS_NULL_VALUE_NODE(_node) ((QUERY_NODE_VALUE == nodeType(_node)) && (TSDB_DATA_TYPE_NULL == ((SValueNode *)_node)->node.resType.type))
#define sclFatal(...) qFatal(__VA_ARGS__)
#define sclError(...) qError(__VA_ARGS__)
......
......@@ -1031,18 +1031,29 @@ int32_t fltAddGroupUnitFromNode(SFilterInfo *info, SNode* tree, SArray *group) {
SScalarParam out = {.columnData = taosMemoryCalloc(1, sizeof(SColumnInfoData))};
out.columnData->info.type = type;
out.columnData->info.bytes = tDataTypes[type].bytes;
for (int32_t i = 0; i < listNode->pNodeList->length; ++i) {
SValueNode *valueNode = (SValueNode *)cell->pNode;
code = doConvertDataType(valueNode, &out);
if (code) {
// fltError("convert from %d to %d failed", in.type, out.type);
FLT_ERR_RET(code);
}
len = tDataTypes[type].bytes;
if (valueNode->node.resType.type != type) {
code = doConvertDataType(valueNode, &out);
if (code) {
// fltError("convert from %d to %d failed", in.type, out.type);
FLT_ERR_RET(code);
}
len = tDataTypes[type].bytes;
filterAddField(info, NULL, (void**) &out.columnData->pData, FLD_TYPE_VALUE, &right, len, true);
filterAddField(info, NULL, (void**) &out.columnData->pData, FLD_TYPE_VALUE, &right, len, true);
out.columnData->pData = NULL;
} else {
void *data = taosMemoryCalloc(1, tDataTypes[type].bytes);
if (NULL == data) {
FLT_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
}
memcpy(data, nodesGetValueFromNode(valueNode), tDataTypes[type].bytes);
filterAddField(info, NULL, (void**) &data, FLD_TYPE_VALUE, &right, len, true);
}
filterAddUnit(info, OP_TYPE_EQUAL, &left, &right, &uidx);
SFilterGroup fgroup = {0};
......@@ -3576,6 +3587,11 @@ EDealRes fltReviseRewriter(SNode** pNode, void* pContext) {
return DEAL_RES_CONTINUE;
}
if (node->opType == OP_TYPE_NOT_IN || node->opType == OP_TYPE_NOT_LIKE || node->opType > OP_TYPE_IS_NOT_NULL) {
stat->scalarMode = true;
return DEAL_RES_CONTINUE;
}
if (NULL == node->pRight) {
if (scalarGetOperatorParamNum(node->opType) > 1) {
fltError("invalid operator, pRight:%p, nodeType:%d, opType:%d", node->pRight, nodeType(node), node->opType);
......@@ -3599,7 +3615,7 @@ EDealRes fltReviseRewriter(SNode** pNode, void* pContext) {
return DEAL_RES_CONTINUE;
}
if ((QUERY_NODE_COLUMN != nodeType(node->pRight)) && (QUERY_NODE_VALUE != nodeType(node->pRight))) {
if ((QUERY_NODE_COLUMN != nodeType(node->pRight)) && (QUERY_NODE_VALUE != nodeType(node->pRight)) && (QUERY_NODE_NODE_LIST != nodeType(node->pRight))) {
stat->scalarMode = true;
return DEAL_RES_CONTINUE;
}
......@@ -3774,11 +3790,12 @@ bool filterExecute(SFilterInfo *info, SSDataBlock *pSrc, int8_t** p, SColumnData
SDataType type = {.type = TSDB_DATA_TYPE_BOOL, .bytes = sizeof(bool)};
output.columnData = createColumnInfoData(&type, pSrc->info.rows);
*p = (int8_t *)output.columnData->pData;
SArray *pList = taosArrayInit(1, POINTER_BYTES);
taosArrayPush(pList, &pSrc);
FLT_ERR_RET(scalarCalculate(info->sclCtx.node, pList, &output));
*p = (int8_t *)output.columnData->pData;
taosArrayDestroy(pList);
return false;
}
......
......@@ -71,7 +71,7 @@ int32_t scalarGenerateSetFromList(void **data, void *pNode, uint32_t type) {
for (int32_t i = 0; i < nodeList->pNodeList->length; ++i) {
SValueNode *valueNode = (SValueNode *)cell->pNode;
if (valueNode->node.resType.type != type) {
out.columnData->info.type = type;
out.columnData->info.bytes = tDataTypes[type].bytes;
......@@ -176,7 +176,7 @@ int32_t sclInitParam(SNode* node, SScalarParam *param, SScalarCtx *ctx, int32_t
SCL_RET(TSDB_CODE_QRY_INVALID_INPUT);
}
SCL_ERR_RET(scalarGenerateSetFromList((void**) &param->pHashFilter, node, nodeList->dataType.type));
SCL_ERR_RET(scalarGenerateSetFromList((void **)&param->pHashFilter, node, nodeList->dataType.type));
if (taosHashPut(ctx->pRes, &node, POINTER_BYTES, param, sizeof(*param))) {
taosHashCleanup(param->pHashFilter);
sclError("taosHashPut nodeList failed, size:%d", (int32_t)sizeof(*param));
......@@ -483,6 +483,79 @@ _return:
SCL_RET(code);
}
EDealRes sclRewriteBasedOnOptr(SNode** pNode, SScalarCtx *ctx, EOperatorType opType) {
if (opType <= OP_TYPE_CALC_MAX) {
SValueNode *res = (SValueNode *)nodesMakeNode(QUERY_NODE_VALUE);
if (NULL == res) {
sclError("make value node failed");
ctx->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
return DEAL_RES_ERROR;
}
res->node.resType.type = TSDB_DATA_TYPE_NULL;
nodesDestroyNode(*pNode);
*pNode = (SNode*)res;
} else {
SValueNode *res = (SValueNode *)nodesMakeNode(QUERY_NODE_VALUE);
if (NULL == res) {
sclError("make value node failed");
ctx->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
return DEAL_RES_ERROR;
}
res->node.resType.type = TSDB_DATA_TYPE_BOOL;
res->datum.b = false;
nodesDestroyNode(*pNode);
*pNode = (SNode*)res;
}
return DEAL_RES_CONTINUE;
}
EDealRes sclRewriteOperatorForNullValue(SNode** pNode, SScalarCtx *ctx) {
SOperatorNode *node = (SOperatorNode *)*pNode;
if (node->pLeft && (QUERY_NODE_VALUE == nodeType(node->pLeft))) {
SValueNode *valueNode = (SValueNode *)node->pLeft;
if (TSDB_DATA_TYPE_NULL == valueNode->node.resType.type && (node->opType != OP_TYPE_IS_NULL && node->opType != OP_TYPE_IS_NOT_NULL)) {
return sclRewriteBasedOnOptr(pNode, ctx, node->opType);
}
}
if (node->pRight && (QUERY_NODE_VALUE == nodeType(node->pRight))) {
SValueNode *valueNode = (SValueNode *)node->pRight;
if (TSDB_DATA_TYPE_NULL == valueNode->node.resType.type && (node->opType != OP_TYPE_IS_NULL && node->opType != OP_TYPE_IS_NOT_NULL)) {
return sclRewriteBasedOnOptr(pNode, ctx, node->opType);
}
}
if (node->pRight && (QUERY_NODE_NODE_LIST == nodeType(node->pRight))) {
SNodeListNode *listNode = (SNodeListNode *)node->pRight;
SNode* tnode = NULL;
WHERE_EACH(tnode, listNode->pNodeList) {
if (SCL_IS_NULL_VALUE_NODE(tnode)) {
if (node->opType == OP_TYPE_IN) {
ERASE_NODE(listNode->pNodeList);
continue;
} else { //OP_TYPE_NOT_IN
return sclRewriteBasedOnOptr(pNode, ctx, node->opType);
}
}
WHERE_NEXT;
}
if (listNode->pNodeList->length <= 0) {
return sclRewriteBasedOnOptr(pNode, ctx, node->opType);
}
}
return DEAL_RES_CONTINUE;
}
EDealRes sclRewriteFunction(SNode** pNode, SScalarCtx *ctx) {
SFunctionNode *node = (SFunctionNode *)*pNode;
SNode* tnode = NULL;
......@@ -575,12 +648,8 @@ EDealRes sclRewriteLogic(SNode** pNode, SScalarCtx *ctx) {
EDealRes sclRewriteOperator(SNode** pNode, SScalarCtx *ctx) {
SOperatorNode *node = (SOperatorNode *)*pNode;
if (!SCL_IS_CONST_NODE(node->pLeft)) {
return DEAL_RES_CONTINUE;
}
if (!SCL_IS_CONST_NODE(node->pRight)) {
return DEAL_RES_CONTINUE;
if ((!SCL_IS_CONST_NODE(node->pLeft)) || (!SCL_IS_CONST_NODE(node->pRight))) {
return sclRewriteOperatorForNullValue(pNode, ctx);
}
SScalarParam output = {.columnData = taosMemoryCalloc(1, sizeof(SColumnInfoData))};
......
......@@ -1369,7 +1369,8 @@ void vectorCompareImpl(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *
if (pRight->pHashFilter != NULL) {
for (; i >= 0 && i < pLeft->numOfRows; i += step) {
if (colDataIsNull_s(pLeft->columnData, i)) {
colDataAppendNULL(pOut->columnData, i);
bool res = false;
colDataAppendInt8(pOut->columnData, i, (int8_t*)&res);
continue;
}
......@@ -1383,7 +1384,8 @@ void vectorCompareImpl(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *
if (pLeft->numOfRows == pRight->numOfRows) {
for (; i < pRight->numOfRows && i >= 0; i += step) {
if (colDataIsNull_s(pLeft->columnData, i) || colDataIsNull_s(pRight->columnData, i)) {
colDataAppendNULL(pOut->columnData, i);
bool res = false;
colDataAppendInt8(pOut->columnData, i, (int8_t*)&res);
continue; // TODO set null or ignore
}
......@@ -1404,8 +1406,9 @@ void vectorCompareImpl(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *
} else if (pRight->numOfRows == 1) {
ASSERT(pLeft->pHashFilter == NULL);
for (; i >= 0 && i < pLeft->numOfRows; i += step) {
if (colDataIsNull_s(pLeft->columnData, i)) {
colDataAppendNULL(pOut->columnData, i);
if (colDataIsNull_s(pLeft->columnData, i) || colDataIsNull_s(pRight->columnData, 0)) {
bool res = false;
colDataAppendInt8(pOut->columnData, i, (int8_t*)&res);
continue;
}
......@@ -1424,8 +1427,9 @@ void vectorCompareImpl(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *
}
} else if (pLeft->numOfRows == 1) {
for (; i >= 0 && i < pRight->numOfRows; i += step) {
if (colDataIsNull_s(pRight->columnData, i)) {
colDataAppendNULL(pOut->columnData, i);
if (colDataIsNull_s(pRight->columnData, i) || colDataIsNull_s(pLeft->columnData, 0)) {
bool res = false;
colDataAppendInt8(pOut->columnData, i, (int8_t*)&res);
continue;
}
......
......@@ -31,7 +31,7 @@ typedef struct {
char* binaryData;
char* isNull;
int32_t* binaryLen;
TAOS_BIND_v2* pBind;
TAOS_MULTI_BIND* pBind;
char* sql;
int32_t* colTypes;
int32_t colNum;
......@@ -97,15 +97,14 @@ CaseCfg gCase[] = {
{"insert:MBME4-C012", tListLen(fullColList), fullColList, false, false, insertMBMETest4, 10, 10, 2, 12, 0, 1},
{"insert:MBME4-C002", tListLen(fullColList), fullColList, false, false, insertMBMETest4, 10, 10, 2, 2, 0, 1},
{"insert:MPME1-FULL", tListLen(fullColList), fullColList, false, true, insertMPMETest1, 10, 10, 2, 0, 0, 1},
{"insert:MPME1-C012", tListLen(fullColList), fullColList, false, false, insertMPMETest1, 10, 10, 2, 12, 0, 1},
};
CaseCfg *gCurCase = NULL;
typedef struct {
char caseCatalog[255];
int32_t bindNullNum;
bool autoCreate;
bool checkParamNum;
......@@ -118,6 +117,8 @@ typedef struct {
int32_t bindColTypeNum;
int32_t* bindColTypeList;
int32_t runTimes;
int32_t caseIdx;
int32_t caseRunNum;
} CaseCtrl;
CaseCtrl gCaseCtrl = {
......@@ -133,6 +134,8 @@ CaseCtrl gCaseCtrl = {
.checkParamNum = false,
.printRes = true,
.runTimes = 0,
.caseIdx = -1,
.caseRunNum = -1,
};
int32_t taosGetTimeOfDay(struct timeval *tv) {
......@@ -163,7 +166,7 @@ static int64_t taosGetTimestampUs() {
return (int64_t)systemTime.tv_sec * 1000000L + (int64_t)systemTime.tv_usec;
}
bool colExists(TAOS_BIND_v2* pBind, int32_t dataType) {
bool colExists(TAOS_MULTI_BIND* pBind, int32_t dataType) {
int32_t i = 0;
while (true) {
if (0 == pBind[i].buffer_type) {
......@@ -393,7 +396,7 @@ int32_t prepareData(BindData *data) {
data->colNum = 0;
data->colTypes = taosMemoryCalloc(30, sizeof(int32_t));
data->sql = taosMemoryCalloc(1, 1024);
data->pBind = taosMemoryCalloc((allRowNum/gCurCase->bindRowNum)*gCurCase->bindColNum, sizeof(TAOS_BIND_v2));
data->pBind = taosMemoryCalloc((allRowNum/gCurCase->bindRowNum)*gCurCase->bindColNum, sizeof(TAOS_MULTI_BIND));
data->tsData = taosMemoryMalloc(allRowNum * sizeof(int64_t));
data->boolData = taosMemoryMalloc(allRowNum * sizeof(bool));
data->tinyData = taosMemoryMalloc(allRowNum * sizeof(int8_t));
......@@ -463,7 +466,7 @@ void destroyData(BindData *data) {
taosMemoryFree(data->colTypes);
}
int32_t bpBindParam(TAOS_STMT *stmt, TAOS_BIND_v2 *bind) {
int32_t bpBindParam(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind) {
static int32_t n = 0;
if (gCurCase->bindRowNum > 1) {
......@@ -951,7 +954,7 @@ int stmt_funcb_autoctb1(TAOS_STMT *stmt) {
int *lb = taosMemoryMalloc(10 * sizeof(int));
TAOS_BIND *tags = taosMemoryCalloc(1, sizeof(TAOS_BIND) * 9 * 1);
TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 1*10);
TAOS_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 1*10);
// int one_null = 1;
int one_not_null = 0;
......@@ -1164,7 +1167,7 @@ int stmt_funcb_autoctb2(TAOS_STMT *stmt) {
int *lb = taosMemoryMalloc(10 * sizeof(int));
TAOS_BIND *tags = taosMemoryCalloc(1, sizeof(TAOS_BIND) * 9 * 1);
TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 1*10);
TAOS_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 1*10);
// int one_null = 1;
int one_not_null = 0;
......@@ -1378,7 +1381,7 @@ int stmt_funcb_autoctb3(TAOS_STMT *stmt) {
int *lb = taosMemoryMalloc(10 * sizeof(int));
TAOS_BIND *tags = taosMemoryCalloc(1, sizeof(TAOS_BIND) * 9 * 1);
TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 1*10);
TAOS_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 1*10);
// int one_null = 1;
int one_not_null = 0;
......@@ -1569,7 +1572,7 @@ int stmt_funcb_autoctb4(TAOS_STMT *stmt) {
int *lb = taosMemoryMalloc(10 * sizeof(int));
TAOS_BIND *tags = taosMemoryCalloc(1, sizeof(TAOS_BIND) * 9 * 1);
TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 1*5);
TAOS_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 1*5);
// int one_null = 1;
int one_not_null = 0;
......@@ -1722,7 +1725,7 @@ int stmt_funcb_autoctb_e1(TAOS_STMT *stmt) {
int *lb = taosMemoryMalloc(10 * sizeof(int));
TAOS_BIND *tags = taosMemoryCalloc(1, sizeof(TAOS_BIND) * 9 * 1);
TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 1*10);
TAOS_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 1*10);
// int one_null = 1;
int one_not_null = 0;
......@@ -1911,7 +1914,7 @@ int stmt_funcb_autoctb_e2(TAOS_STMT *stmt) {
int *lb = taosMemoryMalloc(10 * sizeof(int));
TAOS_BIND *tags = taosMemoryCalloc(1, sizeof(TAOS_BIND) * 9 * 1);
TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 1*10);
TAOS_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 1*10);
// int one_null = 1;
int one_not_null = 0;
......@@ -2128,7 +2131,7 @@ int stmt_funcb_autoctb_e3(TAOS_STMT *stmt) {
int *lb = taosMemoryMalloc(10 * sizeof(int));
TAOS_BIND *tags = taosMemoryCalloc(1, sizeof(TAOS_BIND) * 9 * 1);
TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 1*10);
TAOS_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 1*10);
// int one_null = 1;
int one_not_null = 0;
......@@ -2343,7 +2346,7 @@ int stmt_funcb_autoctb_e4(TAOS_STMT *stmt) {
int *lb = taosMemoryMalloc(10 * sizeof(int));
TAOS_BIND *tags = taosMemoryCalloc(1, sizeof(TAOS_BIND) * 9 * 1);
TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 1*10);
TAOS_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 1*10);
// int one_null = 1;
int one_not_null = 0;
......@@ -2570,7 +2573,7 @@ int stmt_funcb_autoctb_e5(TAOS_STMT *stmt) {
int *lb = taosMemoryMalloc(10 * sizeof(int));
TAOS_BIND *tags = taosMemoryCalloc(1, sizeof(TAOS_BIND) * 9 * 1);
TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 1*10);
TAOS_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 1*10);
// int one_null = 1;
int one_not_null = 0;
......@@ -2791,7 +2794,7 @@ int stmt_funcb4(TAOS_STMT *stmt) {
int *lb = taosMemoryMalloc(60 * sizeof(int));
TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 900000*10);
TAOS_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 900000*10);
char* is_null = taosMemoryMalloc(sizeof(char) * 60);
char* no_null = taosMemoryMalloc(sizeof(char) * 60);
......@@ -2950,7 +2953,7 @@ int stmt_funcb5(TAOS_STMT *stmt) {
int *lb = taosMemoryMalloc(18000 * sizeof(int));
TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 3000*10);
TAOS_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 3000*10);
char* is_null = taosMemoryMalloc(sizeof(char) * 18000);
char* no_null = taosMemoryMalloc(sizeof(char) * 18000);
......@@ -3094,7 +3097,7 @@ int stmt_funcb_ssz1(TAOS_STMT *stmt) {
int *lb = taosMemoryMalloc(30000 * sizeof(int));
TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 3000*10);
TAOS_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 3000*10);
char* no_null = taosMemoryMalloc(sizeof(int) * 200000);
for (int i = 0; i < 30000; ++i) {
......@@ -3185,7 +3188,7 @@ int stmt_funcb_s1(TAOS_STMT *stmt) {
int *lb = taosMemoryMalloc(60 * sizeof(int));
TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 900000*10);
TAOS_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 900000*10);
char* is_null = taosMemoryMalloc(sizeof(char) * 60);
char* no_null = taosMemoryMalloc(sizeof(char) * 60);
......@@ -3347,7 +3350,7 @@ int stmt_funcb_sc1(TAOS_STMT *stmt) {
int *lb = taosMemoryMalloc(60 * sizeof(int));
TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 900000*10);
TAOS_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 900000*10);
char* is_null = taosMemoryMalloc(sizeof(char) * 60);
char* no_null = taosMemoryMalloc(sizeof(char) * 60);
......@@ -3505,7 +3508,7 @@ int stmt_funcb_sc2(TAOS_STMT *stmt) {
int *lb = taosMemoryMalloc(60 * sizeof(int));
TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 900000*10);
TAOS_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 900000*10);
char* is_null = taosMemoryMalloc(sizeof(char) * 60);
char* no_null = taosMemoryMalloc(sizeof(char) * 60);
......@@ -3665,7 +3668,7 @@ int stmt_funcb_sc3(TAOS_STMT *stmt) {
int *lb = taosMemoryMalloc(60 * sizeof(int));
TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 60*10);
TAOS_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 60*10);
char* is_null = taosMemoryMalloc(sizeof(char) * 60);
char* no_null = taosMemoryMalloc(sizeof(char) * 60);
......@@ -4183,9 +4186,15 @@ void prepare(TAOS *taos, int32_t colNum, int32_t *colList, int autoCreate) {
void* runcase(TAOS *taos) {
TAOS_STMT *stmt = NULL;
int32_t caseIdx = 0;
static int32_t caseIdx = 0;
static int32_t caseRunNum = 0;
int64_t beginUs, endUs, totalUs;
for (int32_t i = 0; i < sizeof(gCase)/sizeof(gCase[0]); ++i) {
if (gCaseCtrl.caseRunNum > 0 && caseRunNum >= gCaseCtrl.caseRunNum) {
break;
}
CaseCfg cfg = gCase[i];
gCurCase = &cfg;
......@@ -4193,7 +4202,10 @@ void* runcase(TAOS *taos) {
continue;
}
printf("* Case %d - %s Begin *\n", caseIdx, gCurCase->caseDesc);
if (gCaseCtrl.caseIdx >= 0 && caseIdx < gCaseCtrl.caseIdx) {
caseIdx++;
continue;
}
if (gCaseCtrl.runTimes) {
gCurCase->runTimes = gCaseCtrl.runTimes;
......@@ -4220,10 +4232,15 @@ void* runcase(TAOS *taos) {
gCurCase->bindColNum = gCaseCtrl.bindColTypeNum;
gCurCase->fullCol = false;
}
printf("* Case %d - [%s]%s Begin *\n", caseIdx, gCaseCtrl.caseCatalog, gCurCase->caseDesc);
totalUs = 0;
for (int32_t n = 0; n < gCurCase->runTimes; ++n) {
prepare(taos, gCurCase->colNum, gCurCase->colList, gCurCase->autoCreate);
beginUs = taosGetTimestampUs();
stmt = taos_stmt_init(taos);
if (NULL == stmt) {
printf("taos_stmt_init failed, error:%s\n", taos_stmt_errstr(stmt));
......@@ -4232,62 +4249,73 @@ void* runcase(TAOS *taos) {
(*gCurCase->runFn)(stmt);
prepareCheckResult(taos);
taos_stmt_close(stmt);
endUs = taosGetTimestampUs();
totalUs += (endUs - beginUs);
prepareCheckResult(taos);
}
printf("* Case %d - %s End *\n", caseIdx, gCurCase->caseDesc);
printf("* Case %d - [%s]%s [AvgTime:%.3fms] End *\n", caseIdx, gCaseCtrl.caseCatalog, gCurCase->caseDesc, ((double)totalUs)/1000/gCurCase->runTimes);
caseIdx++;
caseRunNum++;
}
printf("test end\n");
return NULL;
}
void runAll(TAOS *taos) {
printf("Normal Test\n");
strcpy(gCaseCtrl.caseCatalog, "Normal Test");
printf("%s Begin\n", gCaseCtrl.caseCatalog);
runcase(taos);
printf("Null Test\n");
strcpy(gCaseCtrl.caseCatalog, "Null Test");
printf("%s Begin\n", gCaseCtrl.caseCatalog);
gCaseCtrl.bindNullNum = 1;
runcase(taos);
gCaseCtrl.bindNullNum = 0;
printf("Bind Row Test\n");
strcpy(gCaseCtrl.caseCatalog, "Bind Row Test");
printf("%s Begin\n", gCaseCtrl.caseCatalog);
gCaseCtrl.bindRowNum = 1;
runcase(taos);
gCaseCtrl.bindRowNum = 0;
printf("Row Num Test\n");
strcpy(gCaseCtrl.caseCatalog, "Row Num Test");
printf("%s Begin\n", gCaseCtrl.caseCatalog);
gCaseCtrl.rowNum = 1000;
gCaseCtrl.printRes = false;
runcase(taos);
gCaseCtrl.rowNum = 0;
gCaseCtrl.printRes = true;
printf("Runtimes Test\n");
strcpy(gCaseCtrl.caseCatalog, "Runtimes Test");
printf("%s Begin\n", gCaseCtrl.caseCatalog);
gCaseCtrl.runTimes = 2;
runcase(taos);
gCaseCtrl.runTimes = 0;
printf("Check Param Test\n");
strcpy(gCaseCtrl.caseCatalog, "Check Param Test");
printf("%s Begin\n", gCaseCtrl.caseCatalog);
gCaseCtrl.checkParamNum = true;
runcase(taos);
gCaseCtrl.checkParamNum = false;
printf("Bind Col Num Test\n");
strcpy(gCaseCtrl.caseCatalog, "Bind Col Num Test");
printf("%s Begin\n", gCaseCtrl.caseCatalog);
gCaseCtrl.bindColNum = 6;
runcase(taos);
gCaseCtrl.bindColNum = 0;
printf("Bind Col Type Test\n");
strcpy(gCaseCtrl.caseCatalog, "Bind Col Type Test");
printf("%s Begin\n", gCaseCtrl.caseCatalog);
gCaseCtrl.bindColTypeNum = tListLen(bindColTypeList);
gCaseCtrl.bindColTypeList = bindColTypeList;
runcase(taos);
printf("All Test End\n");
}
int main(int argc, char *argv[])
......
......@@ -34,6 +34,7 @@
./test.sh -f tsim/query/charScalarFunction.sim
./test.sh -f tsim/query/explain.sim
./test.sh -f tsim/query/session.sim
./test.sh -f tsim/query/scalarNull.sim
# ---- qnode
./test.sh -f tsim/qnode/basic1.sim
......
system sh/stop_dnodes.sh
system sh/deploy.sh -n dnode1 -i 1
system sh/cfg.sh -n dnode1 -c wallevel -v 2
system sh/cfg.sh -n dnode1 -c numOfMnodes -v 1
print ========= start dnode1 as LEADER
system sh/exec.sh -n dnode1 -s start
sleep 2000
sql connect
print ======== step1
sql create database db1 vgroups 3;
sql use db1;
sql show databases;
sql create stable st1 (ts timestamp, f1 int, f2 binary(200)) tags(t1 int);
sql create table tb1 using st1 tags(1);
sql insert into tb1 values ('2022-04-26 15:15:00', 1, "a");
sql insert into tb1 values ('2022-04-26 15:15:01', 2, "b");
sql insert into tb1 values ('2022-04-26 15:15:02', 3, "c");
sql insert into tb1 values ('2022-04-26 15:15:03', 4, "d");
sql insert into tb1 values ('2022-04-26 15:15:04', 5, "e");
sql insert into tb1 values ('2022-04-26 15:15:05', 6, "f");
sql insert into tb1 values ('2022-04-26 15:15:06', null, null);
sql insert into tb1 values ('2022-04-26 15:15:07', null, "g");
sql insert into tb1 values ('2022-04-26 15:15:08', 7, null);
sql select * from tb1 where f1 in (1,2,3);
if $rows != 3 then
return -1
endi
sql select * from tb1 where f1 <>3;
if $rows != 6 then
return -1
endi
sql select * from tb1 where f1 in (1,2,3,null);
if $rows != 3 then
return -1
endi
sql select * from tb1 where f1 not in (1,2,3,null);
if $rows != 0 then
return -1
endi
sql select * from tb1 where f1 in (null);
if $rows != 0 then
return -1
endi
sql select * from tb1 where f1 = null;
if $rows != 0 then
return -1
endi
sql select * from tb1 where f1 <> null;
if $rows != 0 then
return -1
endi
sql select * from tb1 where f1 + 3 <> null;
if $rows != 0 then
return -1
endi
sql select * from tb1 where f1+1 <>3+null;
if $rows != 0 then
return -1
endi
sql select * from tb1 where f1+1*null <>3+null;
if $rows != 0 then
return -1
endi
sql select * from tb1 where null;
if $rows != 0 then
return -1
endi
sql select * from tb1 where null = null;
if $rows != 0 then
return -1
endi
sql select * from tb1 where null <> null;
if $rows != 0 then
return -1
endi
#TODO: ENABLE IT
#sql select * from tb1 where not (null <> null);
#if $rows != 9 then
# return -1
#endi
#TODO: MOVE IT TO NORMAL CASE
sql_error select * from tb1 where not (null);
system sh/exec.sh -n dnode1 -s stop -x SIGINT
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册