diff --git a/include/client/taos.h b/include/client/taos.h index 8f02d5610f..8b3fd14118 100644 --- a/include/client/taos.h +++ b/include/client/taos.h @@ -92,38 +92,14 @@ typedef struct taosField { typedef void (*__taos_async_fn_t)(void *param, TAOS_RES *, int code); -typedef struct TAOS_BIND { - int buffer_type; - void *buffer; - uintptr_t buffer_length; // unused - uintptr_t *length; - int *is_null; - - int is_unsigned; // unused - int *error; // unused - union { - int64_t ts; - int8_t b; - int8_t v1; - int16_t v2; - int32_t v4; - int64_t v8; - float f4; - double f8; - unsigned char *bin; - char *nchar; - } u; - unsigned int allocated; -} TAOS_BIND; - -typedef struct TAOS_MULTI_BIND { +typedef struct TAOS_BIND_v2 { int buffer_type; void *buffer; - uintptr_t buffer_length; + int32_t buffer_length; int32_t *length; char *is_null; int num; -} TAOS_MULTI_BIND; +} TAOS_BIND_v2; typedef enum { SET_CONF_RET_SUCC = 0, @@ -152,34 +128,34 @@ 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 *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 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 *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_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 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_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_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); diff --git a/include/common/trow.h b/include/common/trow.h index a98b03fd53..7b0c009a11 100644 --- a/include/common/trow.h +++ b/include/common/trow.h @@ -684,6 +684,43 @@ static int32_t tdSRowResetBuf(SRowBuilder *pBuilder, void *pBuf) { return TSDB_CODE_SUCCESS; } +/** + * @brief The invoker is responsible for memory alloc/dealloc. + * + * @param pBuilder + * @param pBuf Output buffer of STSRow + */ +static int32_t tdSRowGetBuf(SRowBuilder *pBuilder, void *pBuf) { + pBuilder->pBuf = (STSRow *)pBuf; + if (!pBuilder->pBuf) { + TASSERT(0); + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } + + TASSERT(pBuilder->nBitmaps > 0 && pBuilder->flen > 0); + + uint32_t len = 0; + switch (pBuilder->rowType) { + case TD_ROW_TP: +#ifdef TD_SUPPORT_BITMAP + pBuilder->pBitmap = tdGetBitmapAddrTp(pBuilder->pBuf, pBuilder->flen); +#endif + break; + case TD_ROW_KV: +#ifdef TD_SUPPORT_BITMAP + pBuilder->pBitmap = tdGetBitmapAddrKv(pBuilder->pBuf, pBuilder->nBoundCols); +#endif + break; + default: + TASSERT(0); + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } + return TSDB_CODE_SUCCESS; +} + + /** * @brief 由调用方管理存储空间的分配及释放,一次输入多个参数 * diff --git a/include/libs/nodes/querynodes.h b/include/libs/nodes/querynodes.h index d2f73e4071..93282f658a 100644 --- a/include/libs/nodes/querynodes.h +++ b/include/libs/nodes/querynodes.h @@ -283,12 +283,12 @@ typedef struct SVgDataBlocks { } SVgDataBlocks; typedef struct SVnodeModifOpStmt { - ENodeType nodeType; - ENodeType sqlNodeType; - SArray* pDataBlocks; // data block for each vgroup, SArray. - uint8_t payloadType; // EPayloadType. 0: K-V payload for non-prepare insert, 1: rawPayload for prepare insert - uint32_t insertType; // insert data from [file|sql statement| bound statement] - const char* sql; // current sql statement position + ENodeType nodeType; + ENodeType sqlNodeType; + SArray* pDataBlocks; // data block for each vgroup, SArray. + uint8_t payloadType; // EPayloadType. 0: K-V payload for non-prepare insert, 1: rawPayload for prepare insert + uint32_t insertType; // insert data from [file|sql statement| bound statement] + const char* sql; // current sql statement position } SVnodeModifOpStmt; typedef struct SExplainOptions { diff --git a/include/libs/parser/parser.h b/include/libs/parser/parser.h index 02cd073226..58482735ba 100644 --- a/include/libs/parser/parser.h +++ b/include/libs/parser/parser.h @@ -21,6 +21,15 @@ extern "C" { #endif #include "querynodes.h" +#include "query.h" + +typedef struct SStmtCallback { + TAOS_STMT* pStmt; + int32_t (*getTbNameFn)(TAOS_STMT*, char**); + int32_t (*setBindInfoFn)(TAOS_STMT*, STableMeta*, void*); + int32_t (*setExecInfoFn)(TAOS_STMT*, SHashObj*, SHashObj*); + int32_t (*getExecInfoFn)(TAOS_STMT*, SHashObj**, SHashObj**); +} SStmtCallback; typedef struct SParseContext { uint64_t requestId; @@ -34,6 +43,7 @@ typedef struct SParseContext { char *pMsg; // extended error message if exists to help identifying the problem in sql statement. int32_t msgLen; // max length of the msg struct SCatalog *pCatalog; + SStmtCallback *pStmtCb; } SParseContext; typedef struct SCmdMsgInfo { @@ -66,11 +76,27 @@ typedef struct SQuery { } SQuery; int32_t qParseQuerySql(SParseContext* pCxt, SQuery** pQuery); +bool isInsertSql(const char* pStr, size_t length); void qDestroyQuery(SQuery* pQueryNode); int32_t qExtractResultSchema(const SNode* pRoot, int32_t* numOfCols, SSchema** pSchema); +int32_t qBuildStmtOutput(SQuery* pQuery, SHashObj* pVgHash, SHashObj* pBlockHash); +int32_t qResetStmtDataBlock(void* block, bool keepBuf); +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 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); +void destroyBoundColumnInfo(void* pBoundInfo); +int32_t qCreateSName(SName* pName, const char* pTableName, int32_t acctId, char* dbName, char *msgBuf, int32_t msgBufLen); + + #ifdef __cplusplus } #endif diff --git a/include/libs/planner/planner.h b/include/libs/planner/planner.h index f343295c56..eba70b8098 100644 --- a/include/libs/planner/planner.h +++ b/include/libs/planner/planner.h @@ -45,7 +45,6 @@ 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); -typedef TAOS_MULTI_BIND TAOS_BIND_v2; // todo remove int32_t qStmtBindParam(SQueryPlan* pPlan, TAOS_BIND_v2* pParams); // Convert to subplan to string for the scheduler to send to the executor diff --git a/include/util/taoserror.h b/include/util/taoserror.h index 14d0160137..e04ff2730a 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -132,6 +132,9 @@ int32_t* taosGetErrno(); #define TSDB_CODE_TSC_INVALID_JSON_TYPE TAOS_DEF_ERROR_CODE(0, 0x0222) #define TSDB_CODE_TSC_VALUE_OUT_OF_RANGE TAOS_DEF_ERROR_CODE(0, 0x0223) #define TSDB_CODE_TSC_INVALID_INPUT TAOS_DEF_ERROR_CODE(0, 0X0224) +#define TSDB_CODE_TSC_STMT_API_ERROR TAOS_DEF_ERROR_CODE(0, 0X0225) +#define TSDB_CODE_TSC_STMT_TBNAME_ERROR TAOS_DEF_ERROR_CODE(0, 0X0226) +#define TSDB_CODE_TSC_STMT_CLAUSE_ERROR TAOS_DEF_ERROR_CODE(0, 0X0227) // mnode-common #define TSDB_CODE_MND_APP_ERROR TAOS_DEF_ERROR_CODE(0, 0x0300) diff --git a/source/client/inc/clientInt.h b/source/client/inc/clientInt.h index 9363cf00a2..35932cc13e 100644 --- a/source/client/inc/clientInt.h +++ b/source/client/inc/clientInt.h @@ -205,7 +205,8 @@ typedef struct SRequestObj { char* sqlstr; // sql string int32_t sqlLen; int64_t self; - char* msgBuf; // error msg buffer + char* msgBuf; + int32_t msgBufLen; int32_t code; SArray* dbList; SArray* tableList; @@ -278,7 +279,8 @@ void initMsgHandleFp(); TAOS* taos_connect_internal(const char* ip, const char* user, const char* pass, const char* auth, const char* db, uint16_t port, int connType); -int32_t parseSql(SRequestObj* pRequest, bool topicQuery, SQuery** pQuery); +int32_t parseSql(SRequestObj* pRequest, bool topicQuery, SQuery** pQuery, SStmtCallback* pStmtCb); + int32_t getPlan(SRequestObj* pRequest, SQuery* pQuery, SQueryPlan** pPlan, SArray* pNodeList); int32_t buildRequest(STscObj* pTscObj, const char* sql, int sqlLen, SRequestObj** pRequest); @@ -302,6 +304,9 @@ int hbAddConnInfo(SAppHbMgr* pAppHbMgr, SClientHbKey connKey, void* key, void* v // --- mq void hbMgrInitMqHbRspHandle(); +SRequestObj* launchQueryImpl(SRequestObj* pRequest, SQuery* pQuery, int32_t code, bool keepQuery); + + #ifdef __cplusplus } #endif diff --git a/source/client/inc/clientStmt.h b/source/client/inc/clientStmt.h index c29361758d..219257ba74 100644 --- a/source/client/inc/clientStmt.h +++ b/source/client/inc/clientStmt.h @@ -19,6 +19,9 @@ #ifdef __cplusplus extern "C" { #endif +#include "catalog.h" + +typedef void STableDataBlocks; typedef enum { STMT_TYPE_INSERT = 1, @@ -26,17 +29,64 @@ typedef enum { STMT_TYPE_QUERY, } STMT_TYPE; -typedef struct STscStmt { - STMT_TYPE type; - //int16_t last; - //STscObj* taos; - //SSqlObj* pSql; - //SMultiTbStmt mtb; - //SNormalStmt normal; +typedef enum { + STMT_INIT = 1, + STMT_PREPARE, + STMT_SETTBNAME, + STMT_SETTAGS, + STMT_FETCH_TAG_FIELDS, + STMT_FETCH_COL_FIELDS, + STMT_BIND, + STMT_BIND_COL, + STMT_ADD_BATCH, + STMT_EXECUTE, +} STMT_STATUS; - //int numOfRows; +typedef struct SStmtTableCache { + STableDataBlocks* pDataBlock; + void* boundTags; +} SStmtTableCache; + +typedef struct SStmtBindInfo { + bool needParse; + uint64_t tbUid; + uint64_t tbSuid; + int32_t sBindRowNum; + int32_t sBindLastIdx; + int8_t tbType; + void* boundTags; + char* tbName; + SName sname; +} SStmtBindInfo; + +typedef struct SStmtExecInfo { + SRequestObj* pRequest; + SHashObj* pVgHash; + SHashObj* pBlockHash; +} SStmtExecInfo; + +typedef struct SStmtSQLInfo { + STMT_TYPE type; + STMT_STATUS status; + bool autoCreate; + uint64_t runTimes; + SHashObj* pTableCache; //SHash + SQuery* pQuery; + char* sqlStr; + int32_t sqlLen; +} SStmtSQLInfo; + +typedef struct STscStmt { + STscObj* taos; + SCatalog* pCatalog; + int32_t affectedRows; + + SStmtSQLInfo sql; + SStmtExecInfo exec; + SStmtBindInfo bInfo; } STscStmt; + #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) #define STMT_ERR_JRET(c) do { code = c; if (code != TSDB_CODE_SUCCESS) { terrno = code; goto _return; } } while (0) @@ -44,16 +94,16 @@ typedef struct STscStmt { TAOS_STMT *stmtInit(TAOS *taos); int stmtClose(TAOS_STMT *stmt); int stmtExec(TAOS_STMT *stmt); -char *stmtErrstr(TAOS_STMT *stmt); +const char *stmtErrstr(TAOS_STMT *stmt); int stmtAffectedRows(TAOS_STMT *stmt); -int stmtBind(TAOS_STMT *stmt, TAOS_BIND *bind); int stmtPrepare(TAOS_STMT *stmt, const char *sql, unsigned long length); -int stmtSetTbNameTags(TAOS_STMT *stmt, const char *name, TAOS_BIND *tags); +int stmtSetTbName(TAOS_STMT *stmt, const char *tbName); +int stmtSetTbTags(TAOS_STMT *stmt, TAOS_BIND_v2 *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_MULTI_BIND *bind); +int stmtBindBatch(TAOS_STMT *stmt, TAOS_BIND_v2 *bind, int32_t colIdx); #ifdef __cplusplus diff --git a/source/client/src/clientEnv.c b/source/client/src/clientEnv.c index ad736fb195..0b75e3a30b 100644 --- a/source/client/src/clientEnv.c +++ b/source/client/src/clientEnv.c @@ -186,6 +186,7 @@ void *createRequest(STscObj *pObj, __taos_async_fn_t fp, void *param, int32_t ty pRequest->pTscObj = pObj; pRequest->body.fp = fp; // not used it yet pRequest->msgBuf = taosMemoryCalloc(1, ERROR_MSG_BUF_DEFAULT_SIZE); + pRequest->msgBufLen = ERROR_MSG_BUF_DEFAULT_SIZE; tsem_init(&pRequest->body.rspSem, 0, 0); registerRequest(pRequest); diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index 632df51d8c..0011c8baf3 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -157,7 +157,7 @@ int32_t buildRequest(STscObj* pTscObj, const char* sql, int sqlLen, SRequestObj* return TSDB_CODE_SUCCESS; } -int32_t parseSql(SRequestObj* pRequest, bool topicQuery, SQuery** pQuery) { +int32_t parseSql(SRequestObj* pRequest, bool topicQuery, SQuery** pQuery, SStmtCallback* pStmtCb) { STscObj* pTscObj = pRequest->pTscObj; SParseContext cxt = { @@ -170,6 +170,7 @@ int32_t parseSql(SRequestObj* pRequest, bool topicQuery, SQuery** pQuery) { .pMsg = pRequest->msgBuf, .msgLen = ERROR_MSG_BUF_DEFAULT_SIZE, .pTransporter = pTscObj->pAppInfo->pTransporter, + .pStmtCb = pStmtCb, }; cxt.mgmtEpSet = getEpSet_s(&pTscObj->pAppInfo->mgmtEp); @@ -298,16 +299,9 @@ int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList return pRequest->code; } -SRequestObj* execQueryImpl(STscObj* pTscObj, const char* sql, int sqlLen) { - SRequestObj* pRequest = NULL; - SQuery* pQuery = NULL; +SRequestObj* launchQueryImpl(SRequestObj* pRequest, SQuery* pQuery, int32_t code, bool keepQuery) { SArray* pNodeList = taosArrayInit(4, sizeof(struct SQueryNodeAddr)); - int32_t code = buildRequest(pTscObj, sql, sqlLen, &pRequest); - if (TSDB_CODE_SUCCESS == code) { - code = parseSql(pRequest, false, &pQuery); - } - if (TSDB_CODE_SUCCESS == code) { switch (pQuery->execMode) { case QUERY_EXEC_MODE_LOCAL: @@ -331,7 +325,10 @@ SRequestObj* execQueryImpl(STscObj* pTscObj, const char* sql, int sqlLen) { } taosArrayDestroy(pNodeList); - qDestroyQuery(pQuery); + if (!keepQuery) { + qDestroyQuery(pQuery); + } + if (NULL != pRequest && TSDB_CODE_SUCCESS != code) { pRequest->code = terrno; } @@ -339,6 +336,19 @@ SRequestObj* execQueryImpl(STscObj* pTscObj, const char* sql, int sqlLen) { return pRequest; } + +SRequestObj* launchQuery(STscObj* pTscObj, const char* sql, int sqlLen) { + SRequestObj* pRequest = NULL; + SQuery* pQuery = NULL; + + int32_t code = buildRequest(pTscObj, sql, sqlLen, &pRequest); + if (TSDB_CODE_SUCCESS == code) { + code = parseSql(pRequest, false, &pQuery, NULL); + } + + return launchQueryImpl(pRequest, pQuery, code, false); +} + int32_t refreshMeta(STscObj* pTscObj, SRequestObj* pRequest) { SCatalog* pCatalog = NULL; int32_t code = 0; @@ -383,7 +393,7 @@ SRequestObj* execQuery(STscObj* pTscObj, const char* sql, int sqlLen) { int32_t code = 0; while (retryNum++ < REQUEST_MAX_TRY_TIMES) { - pRequest = execQueryImpl(pTscObj, sql, sqlLen); + pRequest = launchQuery(pTscObj, sql, sqlLen); if (TSDB_CODE_SUCCESS == pRequest->code || !NEED_CLIENT_HANDLE_ERROR(pRequest->code)) { break; } @@ -715,7 +725,8 @@ static int32_t doConvertUCS4(SReqResultInfo* pResultInfo, int32_t numOfRows, int int32_t len = taosUcs4ToMbs((TdUcs4*)varDataVal(pStart), varDataLen(pStart), varDataVal(p)); ASSERT(len <= bytes); - + ASSERT((p + len) < (pResultInfo->convertBuf[i] + colLength[i])); + varDataSetLen(p, len); pCol->offset[j] = (p - pResultInfo->convertBuf[i]); p += (len + VARSTR_HEADER_SIZE); diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c index 6472dea556..e730f0a34a 100644 --- a/source/client/src/clientMain.c +++ b/source/client/src/clientMain.c @@ -128,6 +128,10 @@ const char *taos_errstr(TAOS_RES *res) { } void taos_free_result(TAOS_RES *res) { + if (NULL == res) { + return; + } + if (TD_RES_QUERY(res)) { SRequestObj *pRequest = (SRequestObj *)res; destroyRequest(pRequest); @@ -579,56 +583,6 @@ TAOS_STMT *taos_stmt_init(TAOS *taos) { return stmtInit(taos); } -int taos_stmt_close(TAOS_STMT *stmt) { - if (stmt == NULL) { - tscError("NULL parameter for %s", __FUNCTION__); - terrno = TSDB_CODE_INVALID_PARA; - return terrno; - } - - return stmtClose(stmt); -} - -int taos_stmt_execute(TAOS_STMT *stmt) { - if (stmt == NULL) { - tscError("NULL parameter for %s", __FUNCTION__); - terrno = TSDB_CODE_INVALID_PARA; - return terrno; - } - - return stmtExec(stmt); -} - -char *taos_stmt_errstr(TAOS_STMT *stmt) { - if (stmt == NULL) { - tscError("NULL parameter for %s", __FUNCTION__); - terrno = TSDB_CODE_INVALID_PARA; - return NULL; - } - - return stmtErrstr(stmt); -} - -int taos_stmt_affected_rows(TAOS_STMT *stmt) { - if (stmt == NULL) { - tscError("NULL parameter for %s", __FUNCTION__); - terrno = TSDB_CODE_INVALID_PARA; - return 0; - } - - return stmtAffectedRows(stmt); -} - -int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_BIND *bind) { - if (stmt == NULL || bind == NULL) { - tscError("NULL parameter for %s", __FUNCTION__); - terrno = TSDB_CODE_INVALID_PARA; - return terrno; - } - - return stmtBind(stmt, bind); -} - int taos_stmt_prepare(TAOS_STMT *stmt, const char *sql, unsigned long length) { if (stmt == NULL || sql == NULL) { tscError("NULL parameter for %s", __FUNCTION__); @@ -639,14 +593,23 @@ 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 *tags) { - if (stmt == NULL || name == NULL || tags == NULL) { +int taos_stmt_set_tbname_tags(TAOS_STMT *stmt, const char *name, TAOS_BIND_v2 *tags) { + if (stmt == NULL || name == NULL) { tscError("NULL parameter for %s", __FUNCTION__); terrno = TSDB_CODE_INVALID_PARA; return terrno; } - return stmtSetTbNameTags(stmt, name, tags); + int32_t code = stmtSetTbName(stmt, name); + if (code) { + return code; + } + + if (tags) { + return stmtSetTbTags(stmt, tags); + } + + return TSDB_CODE_SUCCESS; } int taos_stmt_set_tbname(TAOS_STMT *stmt, const char *name) { @@ -656,7 +619,75 @@ int taos_stmt_set_tbname(TAOS_STMT *stmt, const char *name) { return terrno; } - return stmtSetTbNameTags(stmt, name, NULL); + return stmtSetTbName(stmt, name); +} + +int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_BIND_v2 *bind) { + if (stmt == NULL || bind == NULL) { + tscError("NULL parameter for %s", __FUNCTION__); + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } + + if (bind->num > 1) { + tscError("invalid bind number %d for %s", bind->num, __FUNCTION__); + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } + + return stmtBindBatch(stmt, bind, -1); +} + +int taos_stmt_bind_param_batch(TAOS_STMT *stmt, TAOS_BIND_v2 *bind) { + if (stmt == NULL || bind == NULL) { + tscError("NULL parameter for %s", __FUNCTION__); + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } + + if (bind->num <= 0 || bind->num > INT16_MAX) { + tscError("invalid bind num %d", bind->num); + 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) { + if (stmt == NULL || bind == NULL) { + tscError("NULL parameter for %s", __FUNCTION__); + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } + + if (colIdx < 0) { + tscError("invalid bind column idx %d", colIdx); + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } + + return stmtBindBatch(stmt, bind, colIdx); +} + +int taos_stmt_add_batch(TAOS_STMT *stmt) { + if (stmt == NULL) { + tscError("NULL parameter for %s", __FUNCTION__); + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } + + return stmtAddBatch(stmt); +} + +int taos_stmt_execute(TAOS_STMT *stmt) { + if (stmt == NULL) { + tscError("NULL parameter for %s", __FUNCTION__); + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } + + return stmtExec(stmt); } int taos_stmt_is_insert(TAOS_STMT *stmt, int *insert) { @@ -679,16 +710,6 @@ int taos_stmt_num_params(TAOS_STMT *stmt, int *nums) { return stmtGetParamNum(stmt, nums); } -int taos_stmt_add_batch(TAOS_STMT *stmt) { - if (stmt == NULL) { - tscError("NULL parameter for %s", __FUNCTION__); - terrno = TSDB_CODE_INVALID_PARA; - return terrno; - } - - return stmtAddBatch(stmt); -} - TAOS_RES *taos_stmt_use_result(TAOS_STMT *stmt) { if (stmt == NULL) { tscError("NULL parameter for %s", __FUNCTION__); @@ -699,14 +720,28 @@ TAOS_RES *taos_stmt_use_result(TAOS_STMT *stmt) { return stmtUseResult(stmt); } -int taos_stmt_bind_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind) { - if (stmt == NULL || bind == NULL) { +char *taos_stmt_errstr(TAOS_STMT *stmt) { + return (char *)stmtErrstr(stmt); +} + +int taos_stmt_affected_rows(TAOS_STMT *stmt) { + if (stmt == NULL) { + tscError("NULL parameter for %s", __FUNCTION__); + terrno = TSDB_CODE_INVALID_PARA; + return 0; + } + + return stmtAffectedRows(stmt); +} + +int taos_stmt_close(TAOS_STMT *stmt) { + if (stmt == NULL) { tscError("NULL parameter for %s", __FUNCTION__); terrno = TSDB_CODE_INVALID_PARA; return terrno; } - return stmtBindBatch(stmt, bind); + return stmtClose(stmt); } TAOS_RES *taos_schemaless_insert(TAOS *taos, char *lines[], int numLines, int protocol, int precision) { diff --git a/source/client/src/clientStmt.c b/source/client/src/clientStmt.c index 8c4cff9251..8a5134e02a 100644 --- a/source/client/src/clientStmt.c +++ b/source/client/src/clientStmt.c @@ -4,86 +4,539 @@ #include "clientStmt.h" #include "tdef.h" +int32_t stmtSwitchStatus(STscStmt* pStmt, STMT_STATUS newStatus) { + switch (newStatus) { + case STMT_SETTBNAME: + break; + default: + break; + } + + //STMT_ERR_RET(TSDB_CODE_TSC_STMT_API_ERROR); + + pStmt->sql.status = newStatus; + + return TSDB_CODE_SUCCESS; +} + + +int32_t stmtGetTbName(TAOS_STMT *stmt, char **tbName) { + STscStmt* pStmt = (STscStmt*)stmt; + + pStmt->sql.type = STMT_TYPE_MULTI_INSERT; + + if (NULL == pStmt->bInfo.tbName) { + tscError("no table name set"); + STMT_ERR_RET(TSDB_CODE_TSC_STMT_TBNAME_ERROR); + } + + *tbName = pStmt->bInfo.tbName; + + return TSDB_CODE_SUCCESS; +} + +int32_t stmtSetBindInfo(TAOS_STMT* stmt, STableMeta* pTableMeta, void* tags) { + STscStmt* pStmt = (STscStmt*)stmt; + + pStmt->bInfo.tbUid = pTableMeta->uid; + pStmt->bInfo.tbSuid = pTableMeta->suid; + pStmt->bInfo.tbType = pTableMeta->tableType; + pStmt->bInfo.boundTags = tags; + + return TSDB_CODE_SUCCESS; +} + +int32_t stmtSetExecInfo(TAOS_STMT* stmt, SHashObj* pVgHash, SHashObj* pBlockHash) { + STscStmt* pStmt = (STscStmt*)stmt; + + pStmt->exec.pVgHash = pVgHash; + pStmt->exec.pBlockHash = pBlockHash; + + return TSDB_CODE_SUCCESS; +} + +int32_t stmtGetExecInfo(TAOS_STMT* stmt, SHashObj** pVgHash, SHashObj** pBlockHash) { + STscStmt* pStmt = (STscStmt*)stmt; + + *pVgHash = pStmt->exec.pVgHash; + *pBlockHash = pStmt->exec.pBlockHash; + + return TSDB_CODE_SUCCESS; +} + +int32_t stmtCacheBlock(STscStmt *pStmt) { + if (pStmt->sql.type != STMT_TYPE_MULTI_INSERT) { + 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; + } + + if (taosHashGet(pStmt->sql.pTableCache, &uid, sizeof(uid))) { + return TSDB_CODE_SUCCESS; + } + + STableDataBlocks** pSrc = taosHashGet(pStmt->exec.pBlockHash, &uid, sizeof(uid)); + STableDataBlocks* pDst = NULL; + + STMT_ERR_RET(qCloneStmtDataBlock(&pDst, *pSrc)); + + SStmtTableCache cache = { + .pDataBlock = pDst, + .boundTags = pStmt->bInfo.boundTags, + }; + + if (taosHashPut(pStmt->sql.pTableCache, &uid, sizeof(uid), &cache, sizeof(cache))) { + return TSDB_CODE_OUT_OF_MEMORY; + } + + pStmt->bInfo.boundTags = NULL; + + return TSDB_CODE_SUCCESS; +} + +int32_t stmtParseSql(STscStmt* pStmt) { + SStmtCallback stmtCb = { + .pStmt = pStmt, + .getTbNameFn = stmtGetTbName, + .setBindInfoFn = stmtSetBindInfo, + .setExecInfoFn = stmtSetExecInfo, + .getExecInfoFn = stmtGetExecInfo, + }; + + if (NULL == pStmt->exec.pRequest) { + STMT_ERR_RET(buildRequest(pStmt->taos, pStmt->sql.sqlStr, pStmt->sql.sqlLen, &pStmt->exec.pRequest)); + } + + STMT_ERR_RET(parseSql(pStmt->exec.pRequest, false, &pStmt->sql.pQuery, &stmtCb)); + + pStmt->bInfo.needParse = false; + + switch (nodeType(pStmt->sql.pQuery->pRoot)) { + case QUERY_NODE_VNODE_MODIF_STMT: + if (0 == pStmt->sql.type) { + pStmt->sql.type = STMT_TYPE_INSERT; + } + break; + case QUERY_NODE_SELECT_STMT: + pStmt->sql.type = STMT_TYPE_QUERY; + break; + default: + tscError("not supported stmt type %d", nodeType(pStmt->sql.pQuery->pRoot)); + STMT_ERR_RET(TSDB_CODE_TSC_STMT_CLAUSE_ERROR); + } + + STMT_ERR_RET(stmtCacheBlock(pStmt)); + + return TSDB_CODE_SUCCESS; +} + +int32_t stmtCleanBindInfo(STscStmt* pStmt) { + pStmt->bInfo.tbUid = 0; + pStmt->bInfo.tbSuid = 0; + pStmt->bInfo.tbType = 0; + pStmt->bInfo.needParse = true; + + taosMemoryFreeClear(pStmt->bInfo.tbName); + destroyBoundColumnInfo(pStmt->bInfo.boundTags); + taosMemoryFreeClear(pStmt->bInfo.boundTags); + + return TSDB_CODE_SUCCESS; +} + +int32_t stmtCleanExecInfo(STscStmt* pStmt, bool keepTable) { + taos_free_result(pStmt->exec.pRequest); + pStmt->exec.pRequest = NULL; + + void *pIter = taosHashIterate(pStmt->exec.pBlockHash, NULL); + while (pIter) { + STableDataBlocks* pBlocks = *(STableDataBlocks**)pIter; + uint64_t *key = taosHashGetKey(pIter, NULL); + + if (keepTable && (*key == pStmt->bInfo.tbUid)) { + STMT_ERR_RET(qResetStmtDataBlock(pBlocks, true)); + + pIter = taosHashIterate(pStmt->exec.pBlockHash, pIter); + continue; + } + + qFreeStmtDataBlock(pBlocks); + taosHashRemove(pStmt->exec.pBlockHash, key, sizeof(*key)); + + pIter = taosHashIterate(pStmt->exec.pBlockHash, pIter); + } + + if (keepTable) { + return TSDB_CODE_SUCCESS; + } + + taosHashCleanup(pStmt->exec.pBlockHash); + pStmt->exec.pBlockHash = NULL; + + STMT_ERR_RET(stmtCleanBindInfo(pStmt)); + + return TSDB_CODE_SUCCESS; +} + +int32_t stmtCleanSQLInfo(STscStmt* pStmt) { + taosMemoryFree(pStmt->sql.sqlStr); + qDestroyQuery(pStmt->sql.pQuery); + + void *pIter = taosHashIterate(pStmt->sql.pTableCache, NULL); + while (pIter) { + SStmtTableCache* pCache = (SStmtTableCache*)pIter; + + qDestroyStmtDataBlock(pCache->pDataBlock); + destroyBoundColumnInfo(pCache->boundTags); + + pIter = taosHashIterate(pStmt->sql.pTableCache, pIter); + } + taosHashCleanup(pStmt->sql.pTableCache); + pStmt->sql.pTableCache = NULL; + + memset(&pStmt->sql, 0, sizeof(pStmt->sql)); + + STMT_ERR_RET(stmtCleanExecInfo(pStmt, false)); + STMT_ERR_RET(stmtCleanBindInfo(pStmt)); + + return TSDB_CODE_SUCCESS; +} + +int32_t stmtGetFromCache(STscStmt* pStmt) { + pStmt->bInfo.needParse = true; + + if (NULL == pStmt->sql.pTableCache || taosHashGetSize(pStmt->sql.pTableCache) <= 0) { + return TSDB_CODE_SUCCESS; + } + + if (NULL == pStmt->pCatalog) { + STMT_ERR_RET(catalogGetHandle(pStmt->taos->pAppInfo->clusterId, &pStmt->pCatalog)); + } + + STableMeta *pTableMeta = NULL; + SEpSet ep = getEpSet_s(&pStmt->taos->pAppInfo->mgmtEp); + STMT_ERR_RET(catalogGetTableMeta(pStmt->pCatalog, pStmt->taos->pAppInfo->pTransporter, &ep, &pStmt->bInfo.sname, &pTableMeta)); + + if (pTableMeta->uid == pStmt->bInfo.tbUid) { + pStmt->bInfo.needParse = false; + + return TSDB_CODE_SUCCESS; + } + + if (taosHashGet(pStmt->exec.pBlockHash, &pTableMeta->uid, sizeof(pTableMeta->uid))) { + SStmtTableCache* pCache = taosHashGet(pStmt->sql.pTableCache, &pTableMeta->uid, sizeof(pTableMeta->uid)); + if (NULL == pCache) { + tscError("table uid %" PRIx64 "found in exec blockHash, but not in sql blockHash", pTableMeta->uid); + STMT_ERR_RET(TSDB_CODE_TSC_APP_ERROR); + } + + pStmt->bInfo.needParse = false; + + pStmt->bInfo.tbUid = pTableMeta->uid; + pStmt->bInfo.tbSuid = pTableMeta->suid; + pStmt->bInfo.tbType = pTableMeta->tableType; + pStmt->bInfo.boundTags = pCache->boundTags; + + return TSDB_CODE_SUCCESS; + } + + SStmtTableCache* pCache = taosHashGet(pStmt->sql.pTableCache, &pTableMeta->uid, sizeof(pTableMeta->uid)); + if (pCache) { + pStmt->bInfo.needParse = false; + + pStmt->bInfo.tbUid = pTableMeta->uid; + pStmt->bInfo.tbSuid = pTableMeta->suid; + pStmt->bInfo.tbType = pTableMeta->tableType; + pStmt->bInfo.boundTags = pCache->boundTags; + + STableDataBlocks* pNewBlock = NULL; + STMT_ERR_RET(qRebuildStmtDataBlock(&pNewBlock, pCache->pDataBlock)); + + if (taosHashPut(pStmt->exec.pBlockHash, &pStmt->bInfo.tbUid, sizeof(pStmt->bInfo.tbUid), &pNewBlock, POINTER_BYTES)) { + STMT_ERR_RET(TSDB_CODE_OUT_OF_MEMORY); + } + + return TSDB_CODE_SUCCESS; + } + + STMT_ERR_RET(stmtCleanBindInfo(pStmt)); + + return TSDB_CODE_SUCCESS; +} + +int32_t stmtResetStmt(STscStmt* pStmt) { + STMT_ERR_RET(stmtCleanSQLInfo(pStmt)); + + pStmt->sql.pTableCache = taosHashInit(100, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK); + if (NULL == pStmt->sql.pTableCache) { + terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; + STMT_ERR_RET(terrno); + } + + pStmt->sql.status = STMT_INIT; + + return TSDB_CODE_SUCCESS; +} + + TAOS_STMT *stmtInit(TAOS *taos) { STscObj* pObj = (STscObj*)taos; STscStmt* pStmt = NULL; -#if 0 pStmt = taosMemoryCalloc(1, sizeof(STscStmt)); - if (pStmt == NULL) { + if (NULL == pStmt) { terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; - tscError("failed to allocate memory for statement"); return NULL; } + + pStmt->sql.pTableCache = taosHashInit(100, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK); + if (NULL == pStmt->sql.pTableCache) { + terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; + taosMemoryFree(pStmt); + return NULL; + } + pStmt->taos = pObj; - - SSqlObj* pSql = calloc(1, sizeof(SSqlObj)); - - if (pSql == NULL) { - free(pStmt); - terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; - tscError("failed to allocate memory for statement"); - 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); - pSql->signature = pSql; - pSql->pTscObj = pObj; - pSql->maxRetry = TSDB_MAX_REPLICA; - pStmt->pSql = pSql; - pStmt->last = STMT_INIT; - pStmt->numOfRows = 0; - registerSqlObj(pSql); -#endif - + pStmt->bInfo.needParse = true; + pStmt->sql.status = STMT_INIT; + return pStmt; } -int stmtClose(TAOS_STMT *stmt) { +int stmtPrepare(TAOS_STMT *stmt, const char *sql, unsigned long length) { + STscStmt* pStmt = (STscStmt*)stmt; + + if (pStmt->sql.status >= STMT_PREPARE) { + STMT_ERR_RET(stmtResetStmt(pStmt)); + } + + STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_PREPARE)); + + if (length <= 0) { + length = strlen(sql); + } + + pStmt->sql.sqlStr = strndup(sql, length); + pStmt->sql.sqlLen = length; + + return TSDB_CODE_SUCCESS; +} + + +int stmtSetTbName(TAOS_STMT *stmt, const char *tbName) { + STscStmt* pStmt = (STscStmt*)stmt; + + STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_SETTBNAME)); + + if (NULL == pStmt->exec.pRequest) { + STMT_ERR_RET(buildRequest(pStmt->taos, pStmt->sql.sqlStr, pStmt->sql.sqlLen, &pStmt->exec.pRequest)); + } + + STMT_ERR_RET(qCreateSName(&pStmt->bInfo.sname, tbName, pStmt->taos->acctId, pStmt->exec.pRequest->pDb, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen)); + + STMT_ERR_RET(stmtGetFromCache(pStmt)); + + if (pStmt->bInfo.needParse) { + taosMemoryFree(pStmt->bInfo.tbName); + pStmt->bInfo.tbName = strdup(tbName); + } + + return TSDB_CODE_SUCCESS; +} + +int stmtSetTbTags(TAOS_STMT *stmt, TAOS_BIND_v2 *tags) { + STscStmt* pStmt = (STscStmt*)stmt; + + STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_SETTAGS)); + + if (pStmt->bInfo.needParse) { + STMT_ERR_RET(stmtParseSql(pStmt)); + } + + 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); + STMT_ERR_RET(TSDB_CODE_QRY_APP_ERROR); + } + + STMT_ERR_RET(qBindStmtTagsValue(*pDataBlock, pStmt->bInfo.boundTags, pStmt->bInfo.tbSuid, &pStmt->bInfo.sname, tags, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen)); + + return TSDB_CODE_SUCCESS; +} + + +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)); + } + + if (STMT_TYPE_QUERY == pStmt->sql.type) { + tscError("invalid operation to get query tag fileds"); + STMT_ERR_RET(TSDB_CODE_TSC_STMT_API_ERROR); + } + + 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); + STMT_ERR_RET(TSDB_CODE_QRY_APP_ERROR); + } + + STMT_ERR_RET(qBuildStmtTagFields(*pDataBlock, pStmt->bInfo.boundTags, fieldNum, fields)); + + 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)); + } + + if (STMT_TYPE_QUERY == pStmt->sql.type) { + tscError("invalid operation to get query column fileds"); + STMT_ERR_RET(TSDB_CODE_TSC_STMT_API_ERROR); + } + + 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); + STMT_ERR_RET(TSDB_CODE_QRY_APP_ERROR); + } + + STMT_ERR_RET(qBuildStmtColFields(*pDataBlock, fieldNum, fields)); + + return TSDB_CODE_SUCCESS; +} + +int stmtBindBatch(TAOS_STMT *stmt, TAOS_BIND_v2 *bind, int32_t colIdx) { + STscStmt* pStmt = (STscStmt*)stmt; + + STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_BIND)); + + if (pStmt->bInfo.needParse && pStmt->sql.runTimes && pStmt->sql.type > 0 && STMT_TYPE_MULTI_INSERT != pStmt->sql.type) { + pStmt->bInfo.needParse = false; + } + + if (NULL == pStmt->exec.pRequest) { + STMT_ERR_RET(buildRequest(pStmt->taos, pStmt->sql.sqlStr, pStmt->sql.sqlLen, &pStmt->exec.pRequest)); + } + + if (pStmt->bInfo.needParse) { + STMT_ERR_RET(stmtParseSql(pStmt)); + } + + 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); + STMT_ERR_RET(TSDB_CODE_QRY_APP_ERROR); + } + + if (colIdx < 0) { + qBindStmtColsValue(*pDataBlock, bind, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen); + } else { + if (colIdx != (pStmt->bInfo.sBindLastIdx + 1) && colIdx != 0) { + tscError("bind column index not in sequence"); + STMT_ERR_RET(TSDB_CODE_QRY_APP_ERROR); + } + + pStmt->bInfo.sBindLastIdx = colIdx; + + if (0 == colIdx) { + pStmt->bInfo.sBindRowNum = bind->num; + } + + qBindStmtSingleColValue(*pDataBlock, bind, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen, colIdx, pStmt->bInfo.sBindRowNum); + } + + return TSDB_CODE_SUCCESS; +} + + +int stmtAddBatch(TAOS_STMT *stmt) { + STscStmt* pStmt = (STscStmt*)stmt; + + STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_ADD_BATCH)); + + STMT_ERR_RET(stmtCacheBlock(pStmt)); + return TSDB_CODE_SUCCESS; } int stmtExec(TAOS_STMT *stmt) { - return TSDB_CODE_SUCCESS; + STscStmt* pStmt = (STscStmt*)stmt; + int32_t code = 0; + + 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); + + STMT_ERR_JRET(pStmt->exec.pRequest->code); + + pStmt->affectedRows += taos_affected_rows(pStmt->exec.pRequest); + +_return: + + stmtCleanExecInfo(pStmt, (code ? false : true)); + + ++pStmt->sql.runTimes; + + STMT_RET(code); } -char *stmtErrstr(TAOS_STMT *stmt) { - return NULL; + +int stmtClose(TAOS_STMT *stmt) { + STscStmt* pStmt = (STscStmt*)stmt; + + STMT_RET(stmtCleanSQLInfo(pStmt)); +} + +const char *stmtErrstr(TAOS_STMT *stmt) { + STscStmt* pStmt = (STscStmt*)stmt; + + if (stmt == NULL) { + return (char*) tstrerror(terrno); + } + + if (pStmt->exec.pRequest) { + pStmt->exec.pRequest->code = terrno; + } + + return taos_errstr(pStmt->exec.pRequest); } int stmtAffectedRows(TAOS_STMT *stmt) { - return TSDB_CODE_SUCCESS; -} - -int stmtBind(TAOS_STMT *stmt, TAOS_BIND *bind) { - return TSDB_CODE_SUCCESS; -} - -int stmtPrepare(TAOS_STMT *stmt, const char *sql, unsigned long length) { - return TSDB_CODE_SUCCESS; -} - -int stmtSetTbNameTags(TAOS_STMT *stmt, const char *name, TAOS_BIND *tags) { - return TSDB_CODE_SUCCESS; + return ((STscStmt*)stmt)->affectedRows; } int stmtIsInsert(TAOS_STMT *stmt, int *insert) { + STscStmt* pStmt = (STscStmt*)stmt; + + if (pStmt->sql.type) { + *insert = (STMT_TYPE_INSERT == pStmt->sql.type || STMT_TYPE_MULTI_INSERT == pStmt->sql.type); + } else { + *insert = isInsertSql(pStmt->sql.sqlStr, 0); + } + return TSDB_CODE_SUCCESS; } int stmtGetParamNum(TAOS_STMT *stmt, int *nums) { - return TSDB_CODE_SUCCESS; -} - -int stmtAddBatch(TAOS_STMT *stmt) { + STMT_ERR_RET(stmtFetchColFields(stmt, nums, NULL)); + return TSDB_CODE_SUCCESS; } @@ -91,9 +544,5 @@ TAOS_RES *stmtUseResult(TAOS_STMT *stmt) { return NULL; } -int stmtBindBatch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind) { - return TSDB_CODE_SUCCESS; -} - diff --git a/source/client/src/tmq.c b/source/client/src/tmq.c index 90a589c36c..d404edac91 100644 --- a/source/client/src/tmq.c +++ b/source/client/src/tmq.c @@ -615,7 +615,7 @@ TAOS_RES* tmq_create_stream(TAOS* taos, const char* streamName, const char* tbNa int32_t code = 0; CHECK_CODE_GOTO(buildRequest(pTscObj, sql, sqlLen, &pRequest), _return); - CHECK_CODE_GOTO(parseSql(pRequest, false, &pQueryNode), _return); + CHECK_CODE_GOTO(parseSql(pRequest, false, &pQueryNode, NULL), _return); // todo check for invalid sql statement and return with error code diff --git a/source/common/src/trow.c b/source/common/src/trow.c index ba05d732c3..c73f26e6da 100644 --- a/source/common/src/trow.c +++ b/source/common/src/trow.c @@ -519,8 +519,9 @@ static int32_t tdAppendKvRowToDataCol(STSRow *pRow, STSchema *pSchema, SDataCols SKvRowIdx *pIdx = tdKvRowColIdxAt(pRow, rcol); int16_t colIdx = -1; if (pIdx) { - colIdx = POINTER_DISTANCE(pRow->data, pIdx) / sizeof(SKvRowIdx); + colIdx = POINTER_DISTANCE(pIdx, TD_ROW_COL_IDX(pRow)) / sizeof(SKvRowIdx); } + TASSERT(colIdx >= 0); SCellVal sVal = {0}; if (pIdx->colId == pDataCol->colId) { if (tdGetKvRowValOfCol(&sVal, pRow, pBitmap, pIdx->offset, colIdx) < 0) { diff --git a/source/libs/parser/inc/parInsertData.h b/source/libs/parser/inc/parInsertData.h index cf87f57d4f..ed7267655c 100644 --- a/source/libs/parser/inc/parInsertData.h +++ b/source/libs/parser/inc/parInsertData.h @@ -89,7 +89,7 @@ static FORCE_INLINE int32_t getExtendedRowSize(STableDataBlocks *pBlock) { (int32_t)TD_BITMAP_BYTES(pTableInfo->numOfColumns - 1); } -static FORCE_INLINE void getSTSRowAppendInfo(SSchema *pSchema, uint8_t rowType, SParsedDataColInfo *spd, col_id_t idx, +static FORCE_INLINE void getSTSRowAppendInfo(uint8_t rowType, SParsedDataColInfo *spd, col_id_t idx, int32_t *toffset, col_id_t *colIdx) { col_id_t schemaIdx = 0; if (IS_DATA_COL_ORDERED(spd)) { @@ -131,7 +131,6 @@ static FORCE_INLINE int32_t setBlockInfo(SSubmitBlk *pBlocks, STableDataBlocks* int32_t schemaIdxCompar(const void *lhs, const void *rhs); int32_t boundIdxCompar(const void *lhs, const void *rhs); void setBoundColumnInfo(SParsedDataColInfo *pColList, SSchema *pSchema, col_id_t numOfCols); -void destroyBoundColumnInfo(SParsedDataColInfo* pColList); void destroyBlockArrayList(SArray* pDataBlockList); void destroyBlockHashmap(SHashObj* pDataBlockHash); int initRowBuilder(SRowBuilder *pBuilder, int16_t schemaVer, SParsedDataColInfo *pColInfo); @@ -139,5 +138,7 @@ int32_t allocateMemIfNeed(STableDataBlocks *pDataBlock, int32_t rowSize, int32_t int32_t getDataBlockFromList(SHashObj* pHashList, int64_t id, int32_t size, int32_t startOffset, int32_t rowSize, const STableMeta* pTableMeta, STableDataBlocks** dataBlocks, SArray* pBlockList, SVCreateTbReq* pCreateTbReq); int32_t mergeTableDataBlocks(SHashObj* pHashObj, uint8_t payloadType, SArray** pVgDataBlocks); +int32_t buildCreateTbMsg(STableDataBlocks* pBlocks, SVCreateTbReq* pCreateTbReq); +int32_t allocateMemForSize(STableDataBlocks *pDataBlock, int32_t allSize); #endif // TDENGINE_DATABLOCKMGT_H diff --git a/source/libs/parser/inc/parInt.h b/source/libs/parser/inc/parInt.h index ea01caf9d7..87348e292e 100644 --- a/source/libs/parser/inc/parInt.h +++ b/source/libs/parser/inc/parInt.h @@ -21,6 +21,8 @@ extern "C" { #endif #include "parser.h" +#include "parToken.h" +#include "parUtil.h" int32_t parseInsertSql(SParseContext* pContext, SQuery** pQuery); int32_t parse(SParseContext* pParseCxt, SQuery** pQuery); diff --git a/source/libs/parser/src/parInsert.c b/source/libs/parser/src/parInsert.c index 22c4908629..f21a738032 100644 --- a/source/libs/parser/src/parInsert.c +++ b/source/libs/parser/src/parInsert.c @@ -40,29 +40,21 @@ sToken = tStrGetToken(pSql, &index, false); \ } while (0) -#define CHECK_CODE(expr) \ - do { \ - int32_t code = expr; \ - if (TSDB_CODE_SUCCESS != code) { \ - return code; \ - } \ - } while (0) - typedef struct SInsertParseContext { - SParseContext* pComCxt; // input - char* pSql; // input - SMsgBuf msg; // input - STableMeta* pTableMeta; // each table - SParsedDataColInfo tags; // each table - SKVRowBuilder tagsBuilder; // each table - SVCreateTbReq createTblReq; // each table - SHashObj* pVgroupsHashObj; // global - SHashObj* pTableBlockHashObj; // global - SHashObj* pSubTableHashObj; // global - SArray* pTableDataBlocks; // global - SArray* pVgDataBlocks; // global - int32_t totalNum; + SParseContext* pComCxt; // input + char *pSql; // input + SMsgBuf msg; // input + STableMeta* pTableMeta; // each table + SParsedDataColInfo tags; // each table + SKVRowBuilder tagsBuilder; // each table + SVCreateTbReq createTblReq; // each table + SHashObj* pVgroupsHashObj; // global + SHashObj* pTableBlockHashObj; // global + SHashObj* pSubTableHashObj; // global + SArray* pVgDataBlocks; // global + int32_t totalNum; SVnodeModifOpStmt* pOutput; + SStmtCallback* pStmtCb; } SInsertParseContext; typedef int32_t (*_row_append_fn_t)(SMsgBuf* pMsgBuf, const void* value, int32_t len, void* param); @@ -70,6 +62,29 @@ typedef int32_t (*_row_append_fn_t)(SMsgBuf* pMsgBuf, const void* value, int32_t static uint8_t TRUE_VALUE = (uint8_t)TSDB_TRUE; static uint8_t FALSE_VALUE = (uint8_t)TSDB_FALSE; +typedef struct SKvParam { + SKVRowBuilder *builder; + SSchema *schema; + char buf[TSDB_MAX_TAGS_LEN]; +} SKvParam; + +typedef struct SMemParam { + SRowBuilder* rb; + SSchema* schema; + int32_t toffset; + col_id_t colIdx; +} SMemParam; + + +#define CHECK_CODE(expr) \ + do { \ + int32_t code = expr; \ + if (TSDB_CODE_SUCCESS != code) { \ + return code; \ + } \ + } while (0) + + static int32_t skipInsertInto(SInsertParseContext* pCxt) { SToken sToken; NEXT_TOKEN(pCxt->pSql, sToken); @@ -163,7 +178,8 @@ static int32_t buildName(SInsertParseContext* pCxt, SToken* pStname, char* fullD return TSDB_CODE_SUCCESS; } -static int32_t createSName(SName* pName, SToken* pTableName, SParseContext* pParseCtx, SMsgBuf* pMsgBuf) { + +static int32_t createSName(SName* pName, SToken* pTableName, int32_t acctId, const char* dbName, SMsgBuf* pMsgBuf) { const char* msg1 = "name too long"; const char* msg2 = "invalid database name"; const char* msg3 = "db is not specified"; @@ -179,7 +195,7 @@ static int32_t createSName(SName* pName, SToken* pTableName, SParseContext* pPar strncpy(name, pTableName->z, dbLen); dbLen = strdequote(name); - code = tNameSetDbName(pName, pParseCtx->acctId, name, dbLen); + code = tNameSetDbName(pName, acctId, name, dbLen); if (code != TSDB_CODE_SUCCESS) { return buildInvalidOperationMsg(pMsgBuf, msg1); } @@ -204,11 +220,11 @@ static int32_t createSName(SName* pName, SToken* pTableName, SParseContext* pPar strncpy(name, pTableName->z, pTableName->n); strdequote(name); - if (pParseCtx->db == NULL) { + if (dbName == NULL) { return buildInvalidOperationMsg(pMsgBuf, msg3); } - code = tNameSetDbName(pName, pParseCtx->acctId, pParseCtx->db, strlen(pParseCtx->db)); + code = tNameSetDbName(pName, acctId, dbName, strlen(dbName)); if (code != TSDB_CODE_SUCCESS) { code = buildInvalidOperationMsg(pMsgBuf, msg2); return code; @@ -225,8 +241,8 @@ static int32_t createSName(SName* pName, SToken* pTableName, SParseContext* pPar static int32_t getTableMetaImpl(SInsertParseContext* pCxt, SToken* pTname, bool isStb) { SParseContext* pBasicCtx = pCxt->pComCxt; - SName name = {0}; - createSName(&name, pTname, pBasicCtx, &pCxt->msg); + SName name = {0}; + createSName(&name, pTname, pBasicCtx->acctId, pBasicCtx->db, &pCxt->msg); if (isStb) { CHECK_CODE(catalogGetSTableMeta(pBasicCtx->pCatalog, pBasicCtx->pTransporter, &pBasicCtx->mgmtEpSet, &name, &pCxt->pTableMeta)); @@ -299,7 +315,7 @@ static int32_t buildOutput(SInsertParseContext* pCxt) { return TSDB_CODE_SUCCESS; } -static int32_t checkTimestamp(STableDataBlocks* pDataBlocks, const char* start) { +int32_t checkTimestamp(STableDataBlocks *pDataBlocks, const char *start) { // once the data block is disordered, we do NOT keep previous timestamp any more if (!pDataBlocks->ordered) { return TSDB_CODE_SUCCESS; @@ -441,7 +457,7 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int if (isNullStr(pToken)) { if (TSDB_DATA_TYPE_TIMESTAMP == pSchema->type && PRIMARYKEY_TIMESTAMP_COL_ID == pSchema->colId) { - return buildSyntaxErrMsg(pMsgBuf, "primary timestamp can not be null", pToken->z); + return buildSyntaxErrMsg(pMsgBuf, "primary timestamp should not be null", pToken->z); } return func(pMsgBuf, NULL, 0, param); @@ -603,13 +619,6 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int return TSDB_CODE_FAILED; } -typedef struct SMemParam { - SRowBuilder* rb; - SSchema* schema; - int32_t toffset; - col_id_t colIdx; -} SMemParam; - static FORCE_INLINE int32_t MemRowAppend(SMsgBuf* pMsgBuf, const void* value, int32_t len, void* param) { SMemParam* pa = (SMemParam*)param; SRowBuilder* rb = pa->rb; @@ -718,14 +727,8 @@ static int32_t parseBoundColumns(SInsertParseContext* pCxt, SParsedDataColInfo* return TSDB_CODE_SUCCESS; } -typedef struct SKvParam { - SKVRowBuilder* builder; - SSchema* schema; - char buf[TSDB_MAX_TAGS_LEN]; -} SKvParam; - -static int32_t KvRowAppend(SMsgBuf* pMsgBuf, const void* value, int32_t len, void* param) { - SKvParam* pa = (SKvParam*)param; +static int32_t KvRowAppend(SMsgBuf* pMsgBuf, const void *value, int32_t len, void *param) { + SKvParam* pa = (SKvParam*) param; int8_t type = pa->schema->type; int16_t colId = pa->schema->colId; @@ -760,13 +763,13 @@ static int32_t KvRowAppend(SMsgBuf* pMsgBuf, const void* value, int32_t len, voi return TSDB_CODE_SUCCESS; } -static int32_t buildCreateTbReq(SInsertParseContext* pCxt, const SName* pName, SKVRow row) { +static int32_t buildCreateTbReq(SVCreateTbReq *pTbReq, const SName* pName, SKVRow row, int64_t suid) { char dbFName[TSDB_DB_FNAME_LEN] = {0}; tNameGetFullDbName(pName, dbFName); - pCxt->createTblReq.type = TD_CHILD_TABLE; - pCxt->createTblReq.name = strdup(pName->tname); - pCxt->createTblReq.ctbCfg.suid = pCxt->pTableMeta->suid; - pCxt->createTblReq.ctbCfg.pTag = row; + pTbReq->type = TD_CHILD_TABLE; + pTbReq->name = strdup(pName->tname); + pTbReq->ctbCfg.suid = suid; + pTbReq->ctbCfg.pTag = row; return TSDB_CODE_SUCCESS; } @@ -778,23 +781,42 @@ static int32_t parseTagsClause(SInsertParseContext* pCxt, SSchema* pSchema, uint } SKvParam param = {.builder = &pCxt->tagsBuilder}; - SToken sToken; - char tmpTokenBuf[TSDB_MAX_BYTES_PER_ROW] = {0}; // used for deleting Escape character: \\, \', \" + SToken sToken; + bool isParseBindParam = false; + char tmpTokenBuf[TSDB_MAX_BYTES_PER_ROW] = {0}; // used for deleting Escape character: \\, \', \" for (int i = 0; i < pCxt->tags.numOfBound; ++i) { NEXT_TOKEN_WITH_PREV(pCxt->pSql, sToken); - SSchema* pTagSchema = &pSchema[pCxt->tags.boundColumns[i] - 1]; // colId starts with 1 + + if (sToken.type == TK_NK_QUESTION) { + isParseBindParam = true; + if (NULL == pCxt->pStmtCb) { + return buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", sToken.z); + } + + continue; + } + + if (isParseBindParam) { + return buildInvalidOperationMsg(&pCxt->msg, "no mix usage for ? and tag values"); + } + + SSchema* pTagSchema = &pSchema[pCxt->tags.boundColumns[i] - 1]; // colId starts with 1 param.schema = pTagSchema; CHECK_CODE( parseValueToken(&pCxt->pSql, &sToken, pTagSchema, precision, tmpTokenBuf, KvRowAppend, ¶m, &pCxt->msg)); } + if (isParseBindParam) { + return TSDB_CODE_SUCCESS; + } + SKVRow row = tdGetKVRowFromBuilder(&pCxt->tagsBuilder); if (NULL == row) { return buildInvalidOperationMsg(&pCxt->msg, "tag value expected"); } tdSortKVRowByColIdx(row); - return buildCreateTbReq(pCxt, pName, row); + return buildCreateTbReq(&pCxt->createTblReq, pName, row, pCxt->pTableMeta->suid); } static int32_t cloneTableMeta(STableMeta* pSrc, STableMeta** pDst) { @@ -818,7 +840,7 @@ static int32_t storeTableMeta(SHashObj* pHash, const char* pName, int32_t len, S // pSql -> stb_name [(tag1_name, ...)] TAGS (tag1_value, ...) static int32_t parseUsingClause(SInsertParseContext* pCxt, SToken* pTbnameToken) { SName name; - createSName(&name, pTbnameToken, pCxt->pComCxt, &pCxt->msg); + createSName(&name, pTbnameToken, pCxt->pComCxt->acctId, pCxt->pComCxt->db, &pCxt->msg); char tbFName[TSDB_TABLE_FNAME_LEN]; tNameExtractFullName(&name, tbFName); int32_t len = strlen(tbFName); @@ -863,8 +885,7 @@ static int32_t parseUsingClause(SInsertParseContext* pCxt, SToken* pTbnameToken) return TSDB_CODE_SUCCESS; } -static int parseOneRow(SInsertParseContext* pCxt, STableDataBlocks* pDataBlocks, int16_t timePrec, int32_t* len, - char* tmpTokenBuf) { +static int parseOneRow(SInsertParseContext* pCxt, STableDataBlocks* pDataBlocks, int16_t timePrec, bool* gotRow, char* tmpTokenBuf) { SParsedDataColInfo* spd = &pDataBlocks->boundColumnInfo; SRowBuilder* pBuilder = &pDataBlocks->rowBuilder; STSRow* row = (STSRow*)(pDataBlocks->pData + pDataBlocks->size); // skip the SSubmitBlk header @@ -879,8 +900,22 @@ static int parseOneRow(SInsertParseContext* pCxt, STableDataBlocks* pDataBlocks, for (int i = 0; i < spd->numOfBound; ++i) { NEXT_TOKEN_WITH_PREV(pCxt->pSql, sToken); SSchema* pSchema = &schema[spd->boundColumns[i] - 1]; + + if (sToken.type == TK_NK_QUESTION) { + isParseBindParam = true; + if (NULL == pCxt->pStmtCb) { + return buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", sToken.z); + } + + continue; + } + + if (isParseBindParam) { + return buildInvalidOperationMsg(&pCxt->msg, "no mix usage for ? and values"); + } + param.schema = pSchema; - getSTSRowAppendInfo(schema, pBuilder->rowType, spd, i, ¶m.toffset, ¶m.colIdx); + getSTSRowAppendInfo(pBuilder->rowType, spd, i, ¶m.toffset, ¶m.colIdx); CHECK_CODE(parseValueToken(&pCxt->pSql, &sToken, pSchema, timePrec, tmpTokenBuf, MemRowAppend, ¶m, &pCxt->msg)); if (PRIMARYKEY_TIMESTAMP_COL_ID == pSchema->colId) { @@ -899,6 +934,8 @@ static int parseOneRow(SInsertParseContext* pCxt, STableDataBlocks* pDataBlocks, } } } + + *gotRow = true; } // *len = pBuilder->extendedRowSize; @@ -929,20 +966,24 @@ static int32_t parseValues(SInsertParseContext* pCxt, STableDataBlocks* pDataBlo maxRows = tSize; } - int32_t len = 0; - CHECK_CODE(parseOneRow(pCxt, pDataBlock, tinfo.precision, &len, tmpTokenBuf)); - pDataBlock->size += extendedRowSize; // len; + bool gotRow = false; + CHECK_CODE(parseOneRow(pCxt, pDataBlock, tinfo.precision, &gotRow, tmpTokenBuf)); + if (gotRow) { + pDataBlock->size += extendedRowSize; //len; + } NEXT_TOKEN(pCxt->pSql, sToken); if (TK_NK_RP != sToken.type) { return buildSyntaxErrMsg(&pCxt->msg, ") expected", sToken.z); } - (*numOfRows)++; + if (gotRow) { + (*numOfRows)++; + } } - if (0 == (*numOfRows)) { - return buildSyntaxErrMsg(&pCxt->msg, "no any data points", NULL); + if (0 == (*numOfRows) && (!TSDB_QUERY_HAS_TYPE(pCxt->pOutput->insertType, TSDB_QUERY_TYPE_STMT_INSERT))) { + return buildSyntaxErrMsg(&pCxt->msg, "no any data points", NULL); } return TSDB_CODE_SUCCESS; } @@ -964,7 +1005,7 @@ static int32_t parseValuesClause(SInsertParseContext* pCxt, STableDataBlocks* da return TSDB_CODE_SUCCESS; } -static void destroyCreateSubTbReq(SVCreateTbReq* pReq) { +void destroyCreateSubTbReq(SVCreateTbReq* pReq) { taosMemoryFreeClear(pReq->name); taosMemoryFreeClear(pReq->ctbCfg.pTag); } @@ -998,7 +1039,6 @@ static void destroyInsertParseContext(SInsertParseContext* pCxt) { taosHashCleanup(pCxt->pVgroupsHashObj); destroyBlockHashmap(pCxt->pTableBlockHashObj); - destroyBlockArrayList(pCxt->pTableDataBlocks); destroyBlockArrayList(pCxt->pVgDataBlocks); } @@ -1008,23 +1048,41 @@ static void destroyInsertParseContext(SInsertParseContext* pCxt) { // VALUES (field1_value, ...) [(field1_value2, ...) ...] | FILE csv_file_path // [...]; static int32_t parseInsertBody(SInsertParseContext* pCxt) { + int32_t tbNum = 0; + // for each table while (1) { - destroyInsertParseContextForTable(pCxt); - SToken sToken; + char *tbName = NULL; + // pSql -> tb_name ... NEXT_TOKEN(pCxt->pSql, sToken); // no data in the sql string anymore. if (sToken.n == 0) { - if (0 == pCxt->totalNum) { + if (0 == pCxt->totalNum && (!TSDB_QUERY_HAS_TYPE(pCxt->pOutput->insertType, TSDB_QUERY_TYPE_STMT_INSERT))) { return buildInvalidOperationMsg(&pCxt->msg, "no data in sql"); - ; } break; } + if (TSDB_QUERY_HAS_TYPE(pCxt->pOutput->insertType, TSDB_QUERY_TYPE_STMT_INSERT) && tbNum > 0) { + return buildInvalidOperationMsg(&pCxt->msg, "single table allowed in one stmt");; + } + + destroyInsertParseContextForTable(pCxt); + + if (TK_NK_QUESTION == sToken.type) { + if (pCxt->pStmtCb) { + CHECK_CODE((*pCxt->pStmtCb->getTbNameFn)(pCxt->pStmtCb->pStmt, &tbName)); + + sToken.z = tbName; + sToken.n = strlen(tbName); + } else { + return buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", sToken.z); + } + } + SToken tbnameToken = sToken; NEXT_TOKEN(pCxt->pSql, sToken); @@ -1050,7 +1108,9 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) { if (TK_VALUES == sToken.type) { // pSql -> (field1_value, ...) [(field1_value2, ...) ...] CHECK_CODE(parseValuesClause(pCxt, dataBuf)); - pCxt->pOutput->insertType = TSDB_QUERY_TYPE_INSERT; + TSDB_QUERY_SET_TYPE(pCxt->pOutput->insertType, TSDB_QUERY_TYPE_INSERT); + + tbNum++; continue; } @@ -1063,14 +1123,32 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) { } // todo pCxt->pOutput->insertType = TSDB_QUERY_TYPE_FILE_INSERT; + + tbNum++; continue; } return buildSyntaxErrMsg(&pCxt->msg, "keyword VALUES or FILE is expected", sToken.z); } + + if (TSDB_QUERY_HAS_TYPE(pCxt->pOutput->insertType, TSDB_QUERY_TYPE_STMT_INSERT)) { + SParsedDataColInfo *tags = taosMemoryMalloc(sizeof(pCxt->tags)); + if (NULL == tags) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + memcpy(tags, &pCxt->tags, sizeof(pCxt->tags)); + (*pCxt->pStmtCb->setBindInfoFn)(pCxt->pStmtCb->pStmt, pCxt->pTableMeta, tags); + memset(&pCxt->tags, 0, sizeof(pCxt->tags)); + + (*pCxt->pStmtCb->setExecInfoFn)(pCxt->pStmtCb->pStmt, pCxt->pVgroupsHashObj, pCxt->pTableBlockHashObj); + pCxt->pVgroupsHashObj = NULL; + pCxt->pTableBlockHashObj = NULL; + + return TSDB_CODE_SUCCESS; + } + // merge according to vgId - if (!TSDB_QUERY_HAS_TYPE(pCxt->pOutput->insertType, TSDB_QUERY_TYPE_STMT_INSERT) && - taosHashGetSize(pCxt->pTableBlockHashObj) > 0) { + if (taosHashGetSize(pCxt->pTableBlockHashObj) > 0) { CHECK_CODE(mergeTableDataBlocks(pCxt->pTableBlockHashObj, pCxt->pOutput->payloadType, &pCxt->pVgDataBlocks)); } return buildOutput(pCxt); @@ -1084,29 +1162,43 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) { // [...]; int32_t parseInsertSql(SParseContext* pContext, SQuery** pQuery) { SInsertParseContext context = { - .pComCxt = pContext, - .pSql = (char*)pContext->pSql, - .msg = {.buf = pContext->pMsg, .len = pContext->msgLen}, - .pTableMeta = NULL, - .pVgroupsHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, false), - .pTableBlockHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false), - .pSubTableHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), true, false), - .totalNum = 0, - .pOutput = (SVnodeModifOpStmt*)nodesMakeNode(QUERY_NODE_VNODE_MODIF_STMT)}; + .pComCxt = pContext, + .pSql = (char*) pContext->pSql, + .msg = {.buf = pContext->pMsg, .len = pContext->msgLen}, + .pTableMeta = NULL, + .pSubTableHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), true, false), + .totalNum = 0, + .pOutput = (SVnodeModifOpStmt*)nodesMakeNode(QUERY_NODE_VNODE_MODIF_STMT), + .pStmtCb = pContext->pStmtCb + }; - if (NULL == context.pVgroupsHashObj || NULL == context.pTableBlockHashObj || NULL == context.pSubTableHashObj || - NULL == context.pOutput) { + if (pContext->pStmtCb && *pQuery) { + (*pContext->pStmtCb->getExecInfoFn)(pContext->pStmtCb->pStmt, &context.pVgroupsHashObj, &context.pTableBlockHashObj); + } else { + context.pVgroupsHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, false); + context.pTableBlockHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false); + } + + if (NULL == context.pVgroupsHashObj || NULL == context.pTableBlockHashObj || + NULL == context.pSubTableHashObj || NULL == context.pOutput) { return TSDB_CODE_TSC_OUT_OF_MEMORY; } - *pQuery = taosMemoryCalloc(1, sizeof(SQuery)); - if (NULL == *pQuery) { - return TSDB_CODE_OUT_OF_MEMORY; + if (pContext->pStmtCb) { + TSDB_QUERY_SET_TYPE(context.pOutput->insertType, TSDB_QUERY_TYPE_STMT_INSERT); } - (*pQuery)->execMode = QUERY_EXEC_MODE_SCHEDULE; - (*pQuery)->haveResultSet = false; - (*pQuery)->msgType = TDMT_VND_SUBMIT; - (*pQuery)->pRoot = (SNode*)context.pOutput; + + if (NULL == *pQuery) { + *pQuery = taosMemoryCalloc(1, sizeof(SQuery)); + if (NULL == *pQuery) { + return TSDB_CODE_OUT_OF_MEMORY; + } + (*pQuery)->execMode = QUERY_EXEC_MODE_SCHEDULE; + (*pQuery)->haveResultSet = false; + (*pQuery)->msgType = TDMT_VND_SUBMIT; + (*pQuery)->pRoot = (SNode*)context.pOutput; + } + context.pOutput->payloadType = PAYLOAD_TYPE_KV; int32_t code = skipInsertInto(&context); @@ -1116,3 +1208,318 @@ int32_t parseInsertSql(SParseContext* pContext, SQuery** pQuery) { destroyInsertParseContext(&context); return code; } + + +int32_t qCreateSName(SName* pName, const char* pTableName, int32_t acctId, char* dbName, char *msgBuf, int32_t msgBufLen) { + SMsgBuf msg = {.buf = msgBuf, .len =msgBufLen}; + SToken sToken; + int32_t code = 0; + char *tbName = NULL; + + NEXT_TOKEN(pTableName, sToken); + + if (sToken.n == 0) { + return buildInvalidOperationMsg(&msg, "empty table name"); + } + + code = createSName(pName, &sToken, acctId, dbName, &msg); + if (code) { + return code; + } + + NEXT_TOKEN(pTableName, sToken); + + if (sToken.n > 0) { + return buildInvalidOperationMsg(&msg, "table name format is wrong"); + } + + return TSDB_CODE_SUCCESS; +} + + +int32_t qBuildStmtOutput(SQuery* pQuery, SHashObj* pVgHash, SHashObj* pBlockHash) { + SVnodeModifOpStmt *modifyNode = (SVnodeModifOpStmt *)pQuery->pRoot; + int32_t code = 0; + SInsertParseContext insertCtx = { + .pVgroupsHashObj = pVgHash, + .pTableBlockHashObj = pBlockHash, + .pOutput = (SVnodeModifOpStmt*)pQuery->pRoot, + }; + + // merge according to vgId + if (taosHashGetSize(insertCtx.pTableBlockHashObj) > 0) { + CHECK_CODE(mergeTableDataBlocks(insertCtx.pTableBlockHashObj, modifyNode->payloadType, &insertCtx.pVgDataBlocks)); + } + + CHECK_CODE(buildOutput(&insertCtx)); + + 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}; + SParsedDataColInfo* tags = (SParsedDataColInfo*)boundTags; + if (NULL == tags) { + return TSDB_CODE_QRY_APP_ERROR; + } + + SKVRowBuilder tagBuilder; + if (tdInitKVRowBuilder(&tagBuilder) < 0) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + + SSchema* pSchema = getTableTagSchema(pDataBlock->pTableMeta); + SKvParam param = {.builder = &tagBuilder}; + + for (int c = 0; c < tags->numOfBound; ++c) { + if (bind[c].is_null && bind[c].is_null[0]) { + KvRowAppend(&pBuf, NULL, 0, ¶m); + continue; + } + + SSchema* pTagSchema = &pSchema[tags->boundColumns[c] - 1]; // colId starts with 1 + param.schema = pTagSchema; + + int32_t colLen = pTagSchema->bytes; + if (IS_VAR_DATA_TYPE(pTagSchema->type)) { + colLen = bind[c].length[0]; + } + + CHECK_CODE(KvRowAppend(&pBuf, (char *)bind[c].buffer, colLen, ¶m)); + } + + SKVRow row = tdGetKVRowFromBuilder(&tagBuilder); + if (NULL == row) { + tdDestroyKVRowBuilder(&tagBuilder); + return buildInvalidOperationMsg(&pBuf, "tag value expected"); + } + tdSortKVRowByColIdx(row); + + SVCreateTbReq tbReq = {0}; + CHECK_CODE(buildCreateTbReq(&tbReq, pName, row, suid)); + CHECK_CODE(buildCreateTbMsg(pDataBlock, &tbReq)); + + destroyCreateSubTbReq(&tbReq); + tdDestroyKVRowBuilder(&tagBuilder); + + 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); + SParsedDataColInfo* spd = &pDataBlock->boundColumnInfo; + SRowBuilder* pBuilder = &pDataBlock->rowBuilder; + SMemParam param = {.rb = pBuilder}; + SMsgBuf pBuf = {.buf = msgBuf, .len = msgBufLen}; + int32_t rowNum = bind->num; + + CHECK_CODE(initRowBuilder(&pDataBlock->rowBuilder, pDataBlock->pTableMeta->sversion, &pDataBlock->boundColumnInfo)); + + CHECK_CODE(allocateMemForSize(pDataBlock, extendedRowSize * bind->num)); + + for (int32_t r = 0; r < bind->num; ++r) { + STSRow* row = (STSRow*)(pDataBlock->pData + pDataBlock->size); // skip the SSubmitBlk header + tdSRowResetBuf(pBuilder, row); + + // 1. set the parsed value from sql string + for (int c = 0; c < spd->numOfBound; ++c) { + SSchema* pColSchema = &pSchema[spd->boundColumns[c] - 1]; + + if (bind[c].buffer_type != pColSchema->type) { + return buildInvalidOperationMsg(&pBuf, "column type mis-match with buffer type"); + } + + if (bind[c].num != rowNum) { + return buildInvalidOperationMsg(&pBuf, "row number in each bind param should be the same"); + } + + param.schema = pColSchema; + getSTSRowAppendInfo(pBuilder->rowType, spd, c, ¶m.toffset, ¶m.colIdx); + + if (bind[c].is_null && bind[c].is_null[r]) { + if (pColSchema->colId == PRIMARYKEY_TIMESTAMP_COL_ID) { + return buildInvalidOperationMsg(&pBuf, "primary timestamp should not be NULL"); + } + + CHECK_CODE(MemRowAppend(&pBuf, NULL, 0, ¶m)); + } else { + int32_t colLen = pColSchema->bytes; + if (IS_VAR_DATA_TYPE(pColSchema->type)) { + colLen = bind[c].length[r]; + } + + CHECK_CODE(MemRowAppend(&pBuf, (char *)bind[c].buffer + bind[c].buffer_length * r, colLen, ¶m)); + } + + if (PRIMARYKEY_TIMESTAMP_COL_ID == pColSchema->colId) { + TSKEY tsKey = TD_ROW_KEY(row); + checkTimestamp(pDataBlock, (const char *)&tsKey); + } + } + + // set the null value for the columns that do not assign values + if ((spd->numOfBound < spd->numOfCols) && TD_IS_TP_ROW(row)) { + for (int32_t i = 0; i < spd->numOfCols; ++i) { + if (spd->cols[i].valStat == VAL_STAT_NONE) { // the primary TS key is not VAL_STAT_NONE + tdAppendColValToTpRow(pBuilder, TD_VTYPE_NONE, getNullValue(pSchema[i].type), true, pSchema[i].type, i, + spd->cols[i].toffset); + } + } + } + + pDataBlock->size += extendedRowSize; + } + + SSubmitBlk *pBlocks = (SSubmitBlk *)(pDataBlock->pData); + if (TSDB_CODE_SUCCESS != setBlockInfo(pBlocks, pDataBlock, bind->num)) { + return buildInvalidOperationMsg(&pBuf, "too many rows in sql, total number of rows should be less than 32767"); + } + + 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); + SParsedDataColInfo* spd = &pDataBlock->boundColumnInfo; + SRowBuilder* pBuilder = &pDataBlock->rowBuilder; + SMemParam param = {.rb = pBuilder}; + SMsgBuf pBuf = {.buf = msgBuf, .len = msgBufLen}; + bool rowStart = (0 == colIdx); + bool rowEnd = ((colIdx + 1) == spd->numOfBound); + + if (rowStart) { + CHECK_CODE(initRowBuilder(&pDataBlock->rowBuilder, pDataBlock->pTableMeta->sversion, &pDataBlock->boundColumnInfo)); + CHECK_CODE(allocateMemForSize(pDataBlock, extendedRowSize * bind->num)); + } + + for (int32_t r = 0; r < bind->num; ++r) { + STSRow* row = (STSRow*)(pDataBlock->pData + pDataBlock->size + extendedRowSize * r); // skip the SSubmitBlk header + if (rowStart) { + tdSRowResetBuf(pBuilder, row); + } else { + tdSRowGetBuf(pBuilder, row); + } + + SSchema* pColSchema = &pSchema[spd->boundColumns[colIdx] - 1]; + + if (bind->buffer_type != pColSchema->type) { + return buildInvalidOperationMsg(&pBuf, "column type mis-match with buffer type"); + } + + if (bind->num != rowNum) { + return buildInvalidOperationMsg(&pBuf, "row number in each bind param should be the same"); + } + + param.schema = pColSchema; + getSTSRowAppendInfo(pBuilder->rowType, spd, colIdx, ¶m.toffset, ¶m.colIdx); + + if (bind->is_null && bind->is_null[r]) { + if (pColSchema->colId == PRIMARYKEY_TIMESTAMP_COL_ID) { + return buildInvalidOperationMsg(&pBuf, "primary timestamp should not be NULL"); + } + + CHECK_CODE(MemRowAppend(&pBuf, NULL, 0, ¶m)); + } else { + int32_t colLen = pColSchema->bytes; + if (IS_VAR_DATA_TYPE(pColSchema->type)) { + colLen = bind->length[r]; + } + + CHECK_CODE(MemRowAppend(&pBuf, (char *)bind->buffer + bind->buffer_length * r, colLen, ¶m)); + } + + if (PRIMARYKEY_TIMESTAMP_COL_ID == pColSchema->colId) { + TSKEY tsKey = TD_ROW_KEY(row); + checkTimestamp(pDataBlock, (const char *)&tsKey); + } + + // set the null value for the columns that do not assign values + if (rowEnd && (spd->numOfBound < spd->numOfCols) && TD_IS_TP_ROW(row)) { + for (int32_t i = 0; i < spd->numOfCols; ++i) { + if (spd->cols[i].valStat == VAL_STAT_NONE) { // the primary TS key is not VAL_STAT_NONE + tdAppendColValToTpRow(pBuilder, TD_VTYPE_NONE, getNullValue(pSchema[i].type), true, pSchema[i].type, i, + spd->cols[i].toffset); + } + } + } + } + + if (rowEnd) { + pDataBlock->size += extendedRowSize * bind->num; + + SSubmitBlk *pBlocks = (SSubmitBlk *)(pDataBlock->pData); + if (TSDB_CODE_SUCCESS != setBlockInfo(pBlocks, pDataBlock, bind->num)) { + return buildInvalidOperationMsg(&pBuf, "too many rows in sql, total number of rows should be less than 32767"); + } + } + + return TSDB_CODE_SUCCESS; +} + + +int32_t buildBoundFields(SParsedDataColInfo *boundInfo, SSchema *pSchema, int32_t *fieldNum, TAOS_FIELD** fields) { + if (fields) { + *fields = taosMemoryCalloc(boundInfo->numOfBound, sizeof(TAOS_FIELD)); + if (NULL == *fields) { + return TSDB_CODE_OUT_OF_MEMORY; + } + + for (int32_t i = 0; i < boundInfo->numOfBound; ++i) { + SSchema* pTagSchema = &pSchema[boundInfo->boundColumns[i] - 1]; + strcpy((*fields)[i].name, pTagSchema->name); + (*fields)[i].type = pTagSchema->type; + (*fields)[i].bytes = pTagSchema->bytes; + } + } + + *fieldNum = boundInfo->numOfBound; + + return TSDB_CODE_SUCCESS; +} + + +int32_t qBuildStmtTagFields(void *pBlock, void *boundTags, int32_t *fieldNum, TAOS_FIELD** fields) { + STableDataBlocks *pDataBlock = (STableDataBlocks *)pBlock; + SParsedDataColInfo* tags = (SParsedDataColInfo*)boundTags; + if (NULL == tags) { + return TSDB_CODE_QRY_APP_ERROR; + } + + SSchema* pSchema = getTableTagSchema(pDataBlock->pTableMeta); + if (tags->numOfBound <= 0) { + *fieldNum = 0; + *fields = NULL; + + return TSDB_CODE_SUCCESS; + } + + CHECK_CODE(buildBoundFields(tags, pSchema, fieldNum, fields)); + + return TSDB_CODE_SUCCESS; +} + +int32_t qBuildStmtColFields(void *pBlock, int32_t *fieldNum, TAOS_FIELD** fields) { + STableDataBlocks *pDataBlock = (STableDataBlocks *)pBlock; + SSchema* pSchema = getTableColumnSchema(pDataBlock->pTableMeta); + if (pDataBlock->boundColumnInfo.numOfBound <= 0) { + *fieldNum = 0; + if (fields) { + *fields = NULL; + } + + return TSDB_CODE_SUCCESS; + } + + CHECK_CODE(buildBoundFields(&pDataBlock->boundColumnInfo, pSchema, fieldNum, fields)); + + return TSDB_CODE_SUCCESS; +} + + + diff --git a/source/libs/parser/src/parInsertData.c b/source/libs/parser/src/parInsertData.c index 088b25d544..bf30915fcb 100644 --- a/source/libs/parser/src/parInsertData.c +++ b/source/libs/parser/src/parInsertData.c @@ -18,6 +18,7 @@ #include "catalog.h" #include "parUtil.h" #include "querynodes.h" +#include "parInt.h" #define IS_RAW_PAYLOAD(t) \ (((int)(t)) == PAYLOAD_TYPE_RAW) // 0: K-V payload for non-prepare insert, 1: rawPayload for prepare insert @@ -102,7 +103,13 @@ int32_t boundIdxCompar(const void *lhs, const void *rhs) { } } -void destroyBoundColumnInfo(SParsedDataColInfo* pColList) { +void destroyBoundColumnInfo(void* pBoundInfo) { + if (NULL == pBoundInfo) { + return; + } + + SParsedDataColInfo* pColList = (SParsedDataColInfo*)pBoundInfo; + taosMemoryFreeClear(pColList->boundColumns); taosMemoryFreeClear(pColList->cols); taosMemoryFreeClear(pColList->colIdxInfo); @@ -149,7 +156,7 @@ static int32_t createDataBlock(size_t defaultSize, int32_t rowSize, int32_t star return TSDB_CODE_SUCCESS; } -static int32_t buildCreateTbMsg(STableDataBlocks* pBlocks, SVCreateTbReq* pCreateTbReq) { +int32_t buildCreateTbMsg(STableDataBlocks* pBlocks, SVCreateTbReq* pCreateTbReq) { int32_t len = tSerializeSVCreateTbReq(NULL, pCreateTbReq); if (pBlocks->nAllocSize - pBlocks->size < len) { pBlocks->nAllocSize += len + pBlocks->rowSize; @@ -506,6 +513,28 @@ int32_t mergeTableDataBlocks(SHashObj* pHashObj, uint8_t payloadType, SArray** p return TSDB_CODE_SUCCESS; } +int32_t allocateMemForSize(STableDataBlocks *pDataBlock, int32_t allSize) { + size_t remain = pDataBlock->nAllocSize - pDataBlock->size; + uint32_t nAllocSizeOld = pDataBlock->nAllocSize; + + // expand the allocated size + if (remain < allSize) { + pDataBlock->nAllocSize = (pDataBlock->size + allSize) * 1.5; + + char *tmp = taosMemoryRealloc(pDataBlock->pData, (size_t)pDataBlock->nAllocSize); + if (tmp != NULL) { + pDataBlock->pData = tmp; + memset(pDataBlock->pData + pDataBlock->size, 0, pDataBlock->nAllocSize - pDataBlock->size); + } else { + // do nothing, if allocate more memory failed + pDataBlock->nAllocSize = nAllocSizeOld; + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + } + + return TSDB_CODE_SUCCESS; +} + int32_t allocateMemIfNeed(STableDataBlocks *pDataBlock, int32_t rowSize, int32_t * numOfRows) { size_t remain = pDataBlock->nAllocSize - pDataBlock->size; const int factor = 5; @@ -541,3 +570,84 @@ int initRowBuilder(SRowBuilder *pBuilder, int16_t schemaVer, SParsedDataColInfo pColInfo->boundNullLen); return TSDB_CODE_SUCCESS; } + + +int32_t qResetStmtDataBlock(void* block, bool keepBuf) { + STableDataBlocks* pBlock = (STableDataBlocks*)block; + + if (keepBuf) { + taosMemoryFreeClear(pBlock->pData); + pBlock->pData = taosMemoryMalloc(TSDB_PAYLOAD_SIZE); + if (NULL == pBlock->pData) { + return TSDB_CODE_OUT_OF_MEMORY; + } + memset(pBlock->pData, 0, sizeof(SSubmitBlk)); + } else { + pBlock->pData = NULL; + } + + pBlock->ordered = true; + pBlock->prevTS = INT64_MIN; + pBlock->size = sizeof(SSubmitBlk); + pBlock->tsSource = -1; + pBlock->numOfTables = 1; + pBlock->nAllocSize = TSDB_PAYLOAD_SIZE; + pBlock->headerSize = pBlock->size; + + memset(&pBlock->rowBuilder, 0, sizeof(pBlock->rowBuilder)); + + return TSDB_CODE_SUCCESS; +} + + +int32_t qCloneStmtDataBlock(void** pDst, void* pSrc) { + *pDst = taosMemoryMalloc(sizeof(STableDataBlocks)); + if (NULL == *pDst) { + return TSDB_CODE_OUT_OF_MEMORY; + } + + memcpy(*pDst, pSrc, sizeof(STableDataBlocks)); + ((STableDataBlocks*)(*pDst))->cloned = true; + + return qResetStmtDataBlock(*pDst, false); +} + +int32_t qRebuildStmtDataBlock(void** pDst, void* pSrc) { + int32_t code = qCloneStmtDataBlock(pDst, pSrc); + if (code) { + return code; + } + + STableDataBlocks *pBlock = (STableDataBlocks*)*pDst; + pBlock->pData = taosMemoryMalloc(pBlock->nAllocSize); + if (NULL == pBlock->pData) { + qFreeStmtDataBlock(pBlock); + return TSDB_CODE_OUT_OF_MEMORY; + } + + memset(pBlock->pData, 0, sizeof(SSubmitBlk)); + + return TSDB_CODE_SUCCESS; +} + + +void qFreeStmtDataBlock(void* pDataBlock) { + if (pDataBlock == NULL) { + return; + } + + taosMemoryFreeClear(((STableDataBlocks*)pDataBlock)->pData); + taosMemoryFreeClear(pDataBlock); +} + +void qDestroyStmtDataBlock(void* pBlock) { + if (pBlock == NULL) { + return; + } + + STableDataBlocks* pDataBlock = (STableDataBlocks*)pBlock; + + pDataBlock->cloned = false; + destroyDataBlock(pDataBlock); +} + diff --git a/source/libs/parser/src/parser.c b/source/libs/parser/src/parser.c index ebe76cc129..e2e2207c70 100644 --- a/source/libs/parser/src/parser.c +++ b/source/libs/parser/src/parser.c @@ -18,7 +18,11 @@ #include "parInt.h" #include "parToken.h" -static bool isInsertSql(const char* pStr, size_t length) { +bool isInsertSql(const char* pStr, size_t length) { + if (NULL == pStr) { + return false; + } + int32_t index = 0; do { @@ -68,4 +72,4 @@ void qDestroyQuery(SQuery* pQueryNode) { int32_t qExtractResultSchema(const SNode* pRoot, int32_t* numOfCols, SSchema** pSchema) { return extractResultSchema(pRoot, numOfCols, pSchema); -} \ No newline at end of file +} diff --git a/source/util/src/terror.c b/source/util/src/terror.c index ded42365b6..9332cb481e 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -138,6 +138,9 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_JSON, "Invalid JSON format") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_JSON_TYPE, "Invalid JSON data type") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_VALUE_OUT_OF_RANGE, "Value out of range") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_INPUT, "Invalid tsc input") +TAOS_DEFINE_ERROR(TSDB_CODE_TSC_STMT_API_ERROR, "Stmt API usage error") +TAOS_DEFINE_ERROR(TSDB_CODE_TSC_STMT_TBNAME_ERROR, "Stmt table name not set") +TAOS_DEFINE_ERROR(TSDB_CODE_TSC_STMT_CLAUSE_ERROR, "not supported stmt clause") // mnode-common TAOS_DEFINE_ERROR(TSDB_CODE_MND_APP_ERROR, "Mnode internal error") diff --git a/tests/script/api/batchprepare.c b/tests/script/api/batchprepare.c index de1050850d..2e046bd3ff 100644 --- a/tests/script/api/batchprepare.c +++ b/tests/script/api/batchprepare.c @@ -5,840 +5,932 @@ #include #include #include +#include #include #include "../../../include/client/taos.h" +int32_t shortColList[] = {TSDB_DATA_TYPE_TIMESTAMP, TSDB_DATA_TYPE_INT}; +int32_t fullColList[] = {TSDB_DATA_TYPE_TIMESTAMP, TSDB_DATA_TYPE_BOOL, TSDB_DATA_TYPE_TINYINT, TSDB_DATA_TYPE_UTINYINT, TSDB_DATA_TYPE_SMALLINT, TSDB_DATA_TYPE_USMALLINT, TSDB_DATA_TYPE_INT, TSDB_DATA_TYPE_UINT, TSDB_DATA_TYPE_BIGINT, TSDB_DATA_TYPE_UBIGINT, TSDB_DATA_TYPE_FLOAT, TSDB_DATA_TYPE_DOUBLE, TSDB_DATA_TYPE_BINARY, TSDB_DATA_TYPE_NCHAR}; +int32_t bindColTypeList[] = {TSDB_DATA_TYPE_TIMESTAMP, TSDB_DATA_TYPE_NCHAR}; + +#define tListLen(x) (sizeof(x) / sizeof((x)[0])) + typedef struct { - TAOS *taos; - int idx; -}T_par; + int64_t* tsData; + bool* boolData; + int8_t* tinyData; + uint8_t* utinyData; + int16_t* smallData; + uint16_t* usmallData; + int32_t* intData; + uint32_t* uintData; + int64_t* bigData; + uint64_t* ubigData; + float* floatData; + double* doubleData; + char* binaryData; + char* isNull; + int32_t* binaryLen; + TAOS_BIND_v2* pBind; + char* sql; + int32_t* colTypes; + int32_t colNum; +} BindData; -void taosMsleep(int mseconds); +int32_t gVarCharSize = 10; +int32_t gVarCharLen = 5; -unsigned long long getCurrentTime(){ - struct timeval tv; - if (taosGetTimeOfDay(&tv) != 0) { - perror("Failed to get current time in ms"); - exit(EXIT_FAILURE); +int32_t gExecLoopTimes = 1; // no change +int32_t gFullColNum = tListLen(fullColList); + +int insertMBSETest1(TAOS_STMT *stmt); +int insertMBSETest2(TAOS_STMT *stmt); +int insertMBMETest1(TAOS_STMT *stmt); +int insertMBMETest2(TAOS_STMT *stmt); +int insertMBMETest3(TAOS_STMT *stmt); +int insertMBMETest4(TAOS_STMT *stmt); +int insertMPMETest1(TAOS_STMT *stmt); + + + + +typedef struct { + char caseDesc[128]; + int32_t colNum; + int32_t *colList; // full table column list + bool autoCreate; + bool fullCol; + int32_t (*runFn)(TAOS_STMT*); + int32_t tblNum; + int32_t rowNum; + int32_t bindRowNum; + int32_t bindColNum; // equal colNum in full column case + int32_t bindNullNum; + int32_t runTimes; +} CaseCfg; + +CaseCfg gCase[] = { + {"insert:MBSE1-FULL", tListLen(shortColList), shortColList, false, true, insertMBSETest1, 1, 10, 10, 0, 0, 1}, + {"insert:MBSE1-FULL", tListLen(shortColList), shortColList, false, true, insertMBSETest1, 10, 100, 10, 0, 0, 1}, + + {"insert:MBSE1-FULL", tListLen(fullColList), fullColList, false, true, insertMBSETest1, 10, 10, 2, 0, 0, 1}, + {"insert:MBSE1-C012", tListLen(fullColList), fullColList, false, false, insertMBSETest1, 10, 10, 2, 12, 0, 1}, + {"insert:MBSE1-C002", tListLen(fullColList), fullColList, false, false, insertMBSETest1, 10, 10, 2, 2, 0, 1}, + + {"insert:MBSE2-FULL", tListLen(fullColList), fullColList, false, true, insertMBSETest2, 10, 10, 2, 0, 0, 1}, + {"insert:MBSE2-C012", tListLen(fullColList), fullColList, false, false, insertMBSETest2, 10, 10, 2, 12, 0, 1}, + {"insert:MBSE2-C002", tListLen(fullColList), fullColList, false, false, insertMBSETest2, 10, 10, 2, 2, 0, 1}, + + {"insert:MBME1-FULL", tListLen(fullColList), fullColList, false, true, insertMBMETest1, 10, 10, 2, 0, 0, 1}, + {"insert:MBME1-C012", tListLen(fullColList), fullColList, false, false, insertMBMETest1, 10, 10, 2, 12, 0, 1}, + {"insert:MBME1-C002", tListLen(fullColList), fullColList, false, false, insertMBMETest1, 10, 10, 2, 2, 0, 1}, + + {"insert:MBME2-FULL", tListLen(fullColList), fullColList, false, true, insertMBMETest2, 10, 10, 2, 0, 0, 1}, + {"insert:MBME2-C012", tListLen(fullColList), fullColList, false, false, insertMBMETest2, 10, 10, 2, 12, 0, 1}, + {"insert:MBME2-C002", tListLen(fullColList), fullColList, false, false, insertMBMETest2, 10, 10, 2, 2, 0, 1}, + + {"insert:MBME3-FULL", tListLen(fullColList), fullColList, false, true, insertMBMETest3, 10, 10, 2, 0, 0, 1}, + {"insert:MBME3-C012", tListLen(fullColList), fullColList, false, false, insertMBMETest3, 10, 10, 2, 12, 0, 1}, + {"insert:MBME3-C002", tListLen(fullColList), fullColList, false, false, insertMBMETest3, 10, 10, 2, 2, 0, 1}, + + {"insert:MBME4-FULL", tListLen(fullColList), fullColList, false, true, insertMBMETest4, 10, 10, 2, 0, 0, 1}, + {"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 { + int32_t bindNullNum; + bool autoCreate; + bool checkParamNum; + bool printRes; + bool printCreateTblSql; + bool printInsertSql; + int32_t rowNum; //row num for one table + int32_t bindColNum; + int32_t bindRowNum; //row num for once bind + int32_t bindColTypeNum; + int32_t* bindColTypeList; + int32_t runTimes; +} CaseCtrl; + +CaseCtrl gCaseCtrl = { + .bindNullNum = 0, + .autoCreate = false, + .printCreateTblSql = false, + .printInsertSql = true, + .rowNum = 0, + .bindColNum = 0, + .bindRowNum = 0, + .bindColTypeNum = 0, + .bindColTypeList = NULL, + .checkParamNum = false, + .printRes = true, + .runTimes = 0, +}; + +int32_t taosGetTimeOfDay(struct timeval *tv) { + return gettimeofday(tv, NULL); +} +void *taosMemoryMalloc(uint64_t size) { + return malloc(size); +} + +void *taosMemoryCalloc(int32_t num, int32_t size) { + return calloc(num, size); +} +void taosMemoryFree(const void *ptr) { + if (ptr == NULL) return; + + return free((void*)ptr); +} + +static int64_t taosGetTimestampMs() { + struct timeval systemTime; + taosGetTimeOfDay(&systemTime); + return (int64_t)systemTime.tv_sec * 1000L + (int64_t)systemTime.tv_usec/1000; +} + +static int64_t taosGetTimestampUs() { + struct timeval systemTime; + taosGetTimeOfDay(&systemTime); + return (int64_t)systemTime.tv_sec * 1000000L + (int64_t)systemTime.tv_usec; +} + +bool colExists(TAOS_BIND_v2* pBind, int32_t dataType) { + int32_t i = 0; + while (true) { + if (0 == pBind[i].buffer_type) { + return false; } - return (uint64_t)tv.tv_sec * 1000000ULL + (uint64_t)tv.tv_usec; + if (pBind[i].buffer_type == dataType) { + return true; + } + + ++i; + } +} + +void generateInsertSQL(BindData *data) { + int32_t len = sprintf(data->sql, "insert into %s ", (gCurCase->tblNum > 1 ? "? " : "t0 ")); + if (!gCurCase->fullCol) { + len += sprintf(data->sql + len, "("); + for (int c = 0; c < gCurCase->bindColNum; ++c) { + if (c) { + len += sprintf(data->sql + len, ","); + } + switch (data->pBind[c].buffer_type) { + case TSDB_DATA_TYPE_BOOL: + len += sprintf(data->sql + len, "booldata"); + break; + case TSDB_DATA_TYPE_TINYINT: + len += sprintf(data->sql + len, "tinydata"); + break; + case TSDB_DATA_TYPE_SMALLINT: + len += sprintf(data->sql + len, "smalldata"); + break; + case TSDB_DATA_TYPE_INT: + len += sprintf(data->sql + len, "intdata"); + break; + case TSDB_DATA_TYPE_BIGINT: + len += sprintf(data->sql + len, "bigdata"); + break; + case TSDB_DATA_TYPE_FLOAT: + len += sprintf(data->sql + len, "floatdata"); + break; + case TSDB_DATA_TYPE_DOUBLE: + len += sprintf(data->sql + len, "doubledata"); + break; + case TSDB_DATA_TYPE_VARCHAR: + len += sprintf(data->sql + len, "binarydata"); + break; + case TSDB_DATA_TYPE_TIMESTAMP: + len += sprintf(data->sql + len, "ts"); + break; + case TSDB_DATA_TYPE_NCHAR: + len += sprintf(data->sql + len, "nchardata"); + break; + case TSDB_DATA_TYPE_UTINYINT: + len += sprintf(data->sql + len, "utinydata"); + break; + case TSDB_DATA_TYPE_USMALLINT: + len += sprintf(data->sql + len, "usmalldata"); + break; + case TSDB_DATA_TYPE_UINT: + len += sprintf(data->sql + len, "uintdata"); + break; + case TSDB_DATA_TYPE_UBIGINT: + len += sprintf(data->sql + len, "ubigdata"); + break; + default: + printf("invalid col type:%d", data->pBind[c].buffer_type); + exit(1); + } + } + + len += sprintf(data->sql + len, ") "); + } + + len += sprintf(data->sql + len, "values ("); + for (int c = 0; c < gCurCase->bindColNum; ++c) { + if (c) { + len += sprintf(data->sql + len, ","); + } + len += sprintf(data->sql + len, "?"); + } + len += sprintf(data->sql + len, ")"); + + if (gCaseCtrl.printInsertSql) { + printf("SQL: %s\n", data->sql); + } +} + +void generateDataType(BindData *data, int32_t bindIdx, int32_t colIdx, int32_t *dataType) { + if (bindIdx < gCurCase->bindColNum) { + if (gCaseCtrl.bindColTypeNum) { + *dataType = gCaseCtrl.bindColTypeList[colIdx]; + return; + } else if (gCurCase->fullCol) { + *dataType = gCurCase->colList[bindIdx]; + return; + } else if (0 == colIdx) { + *dataType = TSDB_DATA_TYPE_TIMESTAMP; + return; + } else { + while (true) { + *dataType = rand() % (TSDB_DATA_TYPE_MAX - 1) + 1; + if (*dataType == TSDB_DATA_TYPE_JSON || *dataType == TSDB_DATA_TYPE_DECIMAL + || *dataType == TSDB_DATA_TYPE_BLOB || *dataType == TSDB_DATA_TYPE_MEDIUMBLOB + || *dataType == TSDB_DATA_TYPE_VARBINARY) { + continue; + } + + if (colExists(data->pBind, *dataType)) { + continue; + } + + break; + } + } + } else { + *dataType = data->pBind[bindIdx%gCurCase->bindColNum].buffer_type; + } +} + +int32_t prepareColData(BindData *data, int32_t bindIdx, int32_t rowIdx, int32_t colIdx) { + int32_t dataType = TSDB_DATA_TYPE_TIMESTAMP; + + generateDataType(data, bindIdx, colIdx, &dataType); + + switch (dataType) { + case TSDB_DATA_TYPE_BOOL: + data->pBind[bindIdx].buffer_length = sizeof(bool); + data->pBind[bindIdx].buffer = data->boolData + rowIdx; + data->pBind[bindIdx].length = NULL; + data->pBind[bindIdx].is_null = data->isNull ? (data->isNull + rowIdx) : NULL; + break; + case TSDB_DATA_TYPE_TINYINT: + data->pBind[bindIdx].buffer_length = sizeof(int8_t); + data->pBind[bindIdx].buffer = data->tinyData + rowIdx; + data->pBind[bindIdx].length = NULL; + data->pBind[bindIdx].is_null = data->isNull ? (data->isNull + rowIdx) : NULL; + break; + case TSDB_DATA_TYPE_SMALLINT: + data->pBind[bindIdx].buffer_length = sizeof(int16_t); + data->pBind[bindIdx].buffer = data->smallData + rowIdx; + data->pBind[bindIdx].length = NULL; + data->pBind[bindIdx].is_null = data->isNull ? (data->isNull + rowIdx) : NULL; + break; + case TSDB_DATA_TYPE_INT: + data->pBind[bindIdx].buffer_length = sizeof(int32_t); + data->pBind[bindIdx].buffer = data->intData + rowIdx; + data->pBind[bindIdx].length = NULL; + data->pBind[bindIdx].is_null = data->isNull ? (data->isNull + rowIdx) : NULL; + break; + case TSDB_DATA_TYPE_BIGINT: + data->pBind[bindIdx].buffer_length = sizeof(int64_t); + data->pBind[bindIdx].buffer = data->bigData + rowIdx; + data->pBind[bindIdx].length = NULL; + data->pBind[bindIdx].is_null = data->isNull ? (data->isNull + rowIdx) : NULL; + break; + case TSDB_DATA_TYPE_FLOAT: + data->pBind[bindIdx].buffer_length = sizeof(float); + data->pBind[bindIdx].buffer = data->floatData + rowIdx; + data->pBind[bindIdx].length = NULL; + data->pBind[bindIdx].is_null = data->isNull ? (data->isNull + rowIdx) : NULL; + break; + case TSDB_DATA_TYPE_DOUBLE: + data->pBind[bindIdx].buffer_length = sizeof(double); + data->pBind[bindIdx].buffer = data->doubleData + rowIdx; + data->pBind[bindIdx].length = NULL; + data->pBind[bindIdx].is_null = data->isNull ? (data->isNull + rowIdx) : NULL; + break; + case TSDB_DATA_TYPE_VARCHAR: + data->pBind[bindIdx].buffer_length = gVarCharSize; + data->pBind[bindIdx].buffer = data->binaryData + rowIdx * gVarCharSize; + data->pBind[bindIdx].length = data->binaryLen; + data->pBind[bindIdx].is_null = data->isNull ? (data->isNull + rowIdx) : NULL; + break; + case TSDB_DATA_TYPE_TIMESTAMP: + data->pBind[bindIdx].buffer_length = sizeof(int64_t); + data->pBind[bindIdx].buffer = data->tsData + rowIdx; + data->pBind[bindIdx].length = NULL; + data->pBind[bindIdx].is_null = NULL; + break; + case TSDB_DATA_TYPE_NCHAR: + data->pBind[bindIdx].buffer_length = gVarCharSize; + data->pBind[bindIdx].buffer = data->binaryData + rowIdx * gVarCharSize; + data->pBind[bindIdx].length = data->binaryLen; + data->pBind[bindIdx].is_null = data->isNull ? (data->isNull + rowIdx) : NULL; + break; + case TSDB_DATA_TYPE_UTINYINT: + data->pBind[bindIdx].buffer_length = sizeof(uint8_t); + data->pBind[bindIdx].buffer = data->utinyData + rowIdx; + data->pBind[bindIdx].length = NULL; + data->pBind[bindIdx].is_null = data->isNull ? (data->isNull + rowIdx) : NULL; + break; + case TSDB_DATA_TYPE_USMALLINT: + data->pBind[bindIdx].buffer_length = sizeof(uint16_t); + data->pBind[bindIdx].buffer = data->usmallData + rowIdx; + data->pBind[bindIdx].length = NULL; + data->pBind[bindIdx].is_null = data->isNull ? (data->isNull + rowIdx) : NULL; + break; + case TSDB_DATA_TYPE_UINT: + data->pBind[bindIdx].buffer_length = sizeof(uint32_t); + data->pBind[bindIdx].buffer = data->uintData + rowIdx; + data->pBind[bindIdx].length = NULL; + data->pBind[bindIdx].is_null = data->isNull ? (data->isNull + rowIdx) : NULL; + break; + case TSDB_DATA_TYPE_UBIGINT: + data->pBind[bindIdx].buffer_length = sizeof(uint64_t); + data->pBind[bindIdx].buffer = data->ubigData + rowIdx; + data->pBind[bindIdx].length = NULL; + data->pBind[bindIdx].is_null = data->isNull ? (data->isNull + rowIdx) : NULL; + break; + default: + printf("invalid col type:%d", dataType); + exit(1); + } + + data->pBind[bindIdx].buffer_type = dataType; + data->pBind[bindIdx].num = gCurCase->bindRowNum; + + return 0; } - - - -int stmt_scol_func1(TAOS_STMT *stmt) { - struct { - int64_t ts; - int8_t b; - int8_t v1; - int16_t v2; - int32_t v4; - int64_t v8; - float f4; - double f8; - char bin[40]; - char blob[80]; - } v = {0}; +int32_t prepareData(BindData *data) { + static int64_t tsData = 1591060628000; + uint64_t allRowNum = gCurCase->rowNum * gCurCase->tblNum; - TAOS_BIND params[10]; - params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; - params[0].buffer_length = sizeof(v.ts); - params[0].buffer = &v.ts; - params[0].length = ¶ms[0].buffer_length; - params[0].is_null = NULL; - - params[1].buffer_type = TSDB_DATA_TYPE_TINYINT; - params[1].buffer_length = sizeof(v.v1); - params[1].buffer = &v.v1; - params[1].length = ¶ms[1].buffer_length; - params[1].is_null = NULL; - - params[2].buffer_type = TSDB_DATA_TYPE_SMALLINT; - params[2].buffer_length = sizeof(v.v2); - params[2].buffer = &v.v2; - params[2].length = ¶ms[2].buffer_length; - params[2].is_null = NULL; - - params[3].buffer_type = TSDB_DATA_TYPE_FLOAT; - params[3].buffer_length = sizeof(v.f4); - params[3].buffer = &v.f4; - params[3].length = ¶ms[3].buffer_length; - params[3].is_null = NULL; - - params[4].buffer_type = TSDB_DATA_TYPE_BINARY; - params[4].buffer_length = sizeof(v.bin); - params[4].buffer = v.bin; - params[4].length = ¶ms[4].buffer_length; - params[4].is_null = NULL; - - params[5].buffer_type = TSDB_DATA_TYPE_BINARY; - params[5].buffer_length = sizeof(v.bin); - params[5].buffer = v.bin; - params[5].length = ¶ms[5].buffer_length; - params[5].is_null = NULL; - - char *sql = "insert into ? (ts, v1,v2,f4,bin,bin2) values(?,?,?,?,?,?)"; - int code = taos_stmt_prepare(stmt, sql, 0); - if (code != 0){ - printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); + 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->tsData = taosMemoryMalloc(allRowNum * sizeof(int64_t)); + data->boolData = taosMemoryMalloc(allRowNum * sizeof(bool)); + data->tinyData = taosMemoryMalloc(allRowNum * sizeof(int8_t)); + data->utinyData = taosMemoryMalloc(allRowNum * sizeof(uint8_t)); + data->smallData = taosMemoryMalloc(allRowNum * sizeof(int16_t)); + data->usmallData = taosMemoryMalloc(allRowNum * sizeof(uint16_t)); + data->intData = taosMemoryMalloc(allRowNum * sizeof(int32_t)); + data->uintData = taosMemoryMalloc(allRowNum * sizeof(uint32_t)); + data->bigData = taosMemoryMalloc(allRowNum * sizeof(int64_t)); + data->ubigData = taosMemoryMalloc(allRowNum * sizeof(uint64_t)); + data->floatData = taosMemoryMalloc(allRowNum * sizeof(float)); + data->doubleData = taosMemoryMalloc(allRowNum * sizeof(double)); + data->binaryData = taosMemoryMalloc(allRowNum * gVarCharSize); + data->binaryLen = taosMemoryMalloc(allRowNum * sizeof(int32_t)); + if (gCurCase->bindNullNum) { + data->isNull = taosMemoryCalloc(allRowNum, sizeof(char)); } - for (int zz = 0; zz < 10; zz++) { - char buf[32]; - sprintf(buf, "m%d", zz); - code = taos_stmt_set_tbname(stmt, buf); - if (code != 0){ - printf("failed to execute taos_stmt_set_tbname. code:0x%x\n", code); - exit(1); - } - v.ts = 1591060628000 + zz * 10; - for (int i = 0; i < 10; ++i) { - v.ts += 1; + for (int32_t i = 0; i < allRowNum; ++i) { + data->tsData[i] = tsData++; + data->boolData[i] = i % 2; + data->tinyData[i] = i; + data->utinyData[i] = i+1; + data->smallData[i] = i; + data->usmallData[i] = i+1; + data->intData[i] = i; + data->uintData[i] = i+1; + data->bigData[i] = i; + data->ubigData[i] = i+1; + data->floatData[i] = i; + data->doubleData[i] = i+1; + memset(data->binaryData + gVarCharSize * i, 'a'+i%26, gVarCharLen); + if (gCurCase->bindNullNum) { + data->isNull[i] = i % 2; + } + data->binaryLen[i] = gVarCharLen; + } - v.b = (int8_t)(i+zz*10) % 2; - v.v1 = (int8_t)(i+zz*10); - v.v2 = (int16_t)((i+zz*10) * 2); - v.v4 = (int32_t)((i+zz*10) * 4); - v.v8 = (int64_t)((i+zz*10) * 8); - v.f4 = (float)((i+zz*10) * 40); - v.f8 = (double)((i+zz*10) * 80); - for (int j = 0; j < sizeof(v.bin) - 1; ++j) { - v.bin[j] = (char)((i)%10 + '0'); - } - - taos_stmt_bind_param(stmt, params); - taos_stmt_add_batch(stmt); + for (int b = 0; b < (allRowNum/gCurCase->bindRowNum); b++) { + for (int c = 0; c < gCurCase->bindColNum; ++c) { + prepareColData(data, b*gCurCase->bindColNum+c, b*gCurCase->bindRowNum, c); } } - if (taos_stmt_execute(stmt) != 0) { - printf("failed to execute insert statement.\n"); + generateInsertSQL(data); + + return 0; +} + +void destroyData(BindData *data) { + taosMemoryFree(data->tsData); + taosMemoryFree(data->boolData); + taosMemoryFree(data->tinyData); + taosMemoryFree(data->utinyData); + taosMemoryFree(data->smallData); + taosMemoryFree(data->usmallData); + taosMemoryFree(data->intData); + taosMemoryFree(data->uintData); + taosMemoryFree(data->bigData); + taosMemoryFree(data->ubigData); + taosMemoryFree(data->floatData); + taosMemoryFree(data->doubleData); + taosMemoryFree(data->binaryData); + taosMemoryFree(data->binaryLen); + taosMemoryFree(data->isNull); + taosMemoryFree(data->pBind); + taosMemoryFree(data->colTypes); +} + +int32_t bpBindParam(TAOS_STMT *stmt, TAOS_BIND_v2 *bind) { + static int32_t n = 0; + + if (gCurCase->bindRowNum > 1) { + if (0 == (n++%2)) { + if (taos_stmt_bind_param_batch(stmt, bind)) { + printf("taos_stmt_bind_param_batch error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } + } else { + for (int32_t i = 0; i < gCurCase->bindColNum; ++i) { + if (taos_stmt_bind_single_param_batch(stmt, bind++, i)) { + printf("taos_stmt_bind_single_param_batch error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } + } + } + } else { + if (taos_stmt_bind_param(stmt, bind)) { + printf("taos_stmt_bind_param error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } + } + + return 0; +} + +void bpCheckIsInsert(TAOS_STMT *stmt) { + int32_t isInsert = 0; + if (taos_stmt_is_insert(stmt, &isInsert)) { + printf("taos_stmt_is_insert error:%s\n", taos_stmt_errstr(stmt)); exit(1); } - return 0; + if (0 == isInsert) { + printf("is insert failed\n"); + exit(1); + } } - - -int stmt_scol_func2(TAOS_STMT *stmt) { - struct { - int64_t ts; - int8_t b; - int8_t v1; - int16_t v2; - int32_t v4; - int64_t v8; - float f4; - double f8; - char bin[40]; - char blob[80]; - } v = {0}; - - TAOS_BIND params[10]; - params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; - params[0].buffer_length = sizeof(v.ts); - params[0].buffer = &v.ts; - params[0].length = ¶ms[0].buffer_length; - params[0].is_null = NULL; - - params[1].buffer_type = TSDB_DATA_TYPE_TINYINT; - params[1].buffer_length = sizeof(v.v1); - params[1].buffer = &v.v1; - params[1].length = ¶ms[1].buffer_length; - params[1].is_null = NULL; - - params[2].buffer_type = TSDB_DATA_TYPE_SMALLINT; - params[2].buffer_length = sizeof(v.v2); - params[2].buffer = &v.v2; - params[2].length = ¶ms[2].buffer_length; - params[2].is_null = NULL; - - params[3].buffer_type = TSDB_DATA_TYPE_FLOAT; - params[3].buffer_length = sizeof(v.f4); - params[3].buffer = &v.f4; - params[3].length = ¶ms[3].buffer_length; - params[3].is_null = NULL; - - params[4].buffer_type = TSDB_DATA_TYPE_BINARY; - params[4].buffer_length = sizeof(v.bin); - params[4].buffer = v.bin; - params[4].length = ¶ms[4].buffer_length; - params[4].is_null = NULL; - - params[5].buffer_type = TSDB_DATA_TYPE_BINARY; - params[5].buffer_length = sizeof(v.bin); - params[5].buffer = v.bin; - params[5].length = ¶ms[5].buffer_length; - params[5].is_null = NULL; - - char *sql = "insert into m0 (ts, v1,v2,f4,bin,bin2) values(?,?,?,?,?,?)"; - int code = taos_stmt_prepare(stmt, sql, 0); - if (code != 0){ - printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); - } - - for (int zz = 0; zz < 10; zz++) { - v.ts = 1591060628000 + zz * 10; - for (int i = 0; i < 10; ++i) { - v.ts += 1; - - v.b = (int8_t)(i+zz*10) % 2; - v.v1 = (int8_t)(i+zz*10); - v.v2 = (int16_t)((i+zz*10) * 2); - v.v4 = (int32_t)((i+zz*10) * 4); - v.v8 = (int64_t)((i+zz*10) * 8); - v.f4 = (float)((i+zz*10) * 40); - v.f8 = (double)((i+zz*10) * 80); - for (int j = 0; j < sizeof(v.bin) - 1; ++j) { - v.bin[j] = (char)((i)%10 + '0'); - } - - taos_stmt_bind_param(stmt, params); - taos_stmt_add_batch(stmt); - } - } - - if (taos_stmt_execute(stmt) != 0) { - printf("failed to execute insert statement.\n"); +void bpCheckParamNum(TAOS_STMT *stmt) { + int32_t num = 0; + if (taos_stmt_num_params(stmt, &num)) { + printf("taos_stmt_num_params error:%s\n", taos_stmt_errstr(stmt)); exit(1); } - return 0; + if (gCurCase->bindColNum != num) { + printf("is insert failed\n"); + exit(1); + } +} + +void bpCheckAffectedRows(TAOS_STMT *stmt, int32_t times) { + int32_t rows = taos_stmt_affected_rows(stmt); + int32_t insertNum = gCurCase->rowNum * gCurCase->tblNum * times; + if (insertNum != rows) { + printf("affected rows %d mis-match with insert num %d\n", rows, insertNum); + exit(1); + } } +/* prepare [settbname [bind add]] exec */ +int insertMBSETest1(TAOS_STMT *stmt) { + BindData data = {0}; + prepareData(&data); - -//300 tables 60 records -int stmt_scol_func3(TAOS_STMT *stmt) { - struct { - int64_t *ts; - int8_t b[60]; - int8_t v1[60]; - int16_t v2[60]; - int32_t v4[60]; - int64_t v8[60]; - float f4[60]; - double f8[60]; - char bin[60][40]; - } v = {0}; - - v.ts = taosMemoryMalloc(sizeof(int64_t) * 900000 * 60); - - int *lb = taosMemoryMalloc(60 * sizeof(int)); - - 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); - - for (int i = 0; i < 60; ++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 < 9000000; 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_TINYINT; - params[i+1].buffer_length = sizeof(int8_t); - params[i+1].buffer = v.v1; - params[i+1].length = NULL; - params[i+1].is_null = no_null; - params[i+1].num = 10; - - params[i+2].buffer_type = TSDB_DATA_TYPE_SMALLINT; - params[i+2].buffer_length = sizeof(int16_t); - params[i+2].buffer = v.v2; - params[i+2].length = NULL; - params[i+2].is_null = no_null; - params[i+2].num = 10; - - params[i+3].buffer_type = TSDB_DATA_TYPE_FLOAT; - params[i+3].buffer_length = sizeof(float); - params[i+3].buffer = v.f4; - params[i+3].length = NULL; - params[i+3].is_null = no_null; - params[i+3].num = 10; - - params[i+4].buffer_type = TSDB_DATA_TYPE_BINARY; - params[i+4].buffer_length = 40; - params[i+4].buffer = v.bin; - params[i+4].length = lb; - params[i+4].is_null = no_null; - params[i+4].num = 10; - - params[i+5].buffer_type = TSDB_DATA_TYPE_BINARY; - params[i+5].buffer_length = 40; - params[i+5].buffer = v.bin; - params[i+5].length = lb; - params[i+5].is_null = no_null; - params[i+5].num = 10; - - } - - int64_t tts = 1591060628000; - for (int i = 0; i < 54000000; ++i) { - v.ts[i] = tts + i; - } - - unsigned long long starttime = getCurrentTime(); - - char *sql = "insert into ? (ts, v1,v2,f4,bin,bin2) values(?,?,?,?,?,?)"; - int code = taos_stmt_prepare(stmt, sql, 0); + int code = taos_stmt_prepare(stmt, data.sql, 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)); + exit(1); } - int id = 0; - for (int l = 0; l < 2; l++) { - for (int zz = 0; zz < 300; zz++) { + bpCheckIsInsert(stmt); + + int32_t bindTimes = gCurCase->rowNum/gCurCase->bindRowNum; + for (int32_t t = 0; t< gCurCase->tblNum; ++t) { + if (gCurCase->tblNum > 1) { char buf[32]; - sprintf(buf, "m%d", zz); + sprintf(buf, "t%d", t); code = taos_stmt_set_tbname(stmt, buf); if (code != 0){ - printf("failed to execute taos_stmt_set_tbname. code:0x%x\n", code); + printf("taos_stmt_set_tbname error:%s\n", taos_stmt_errstr(stmt)); + exit(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", 3000*300*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*300*60)); - - taosMemoryFree(v.ts); - taosMemoryFree(lb); - taosMemoryFree(params); - taosMemoryFree(is_null); - taosMemoryFree(no_null); - - return 0; -} - - - -//10 tables 10 records single column bind -int stmt_scol_func4(TAOS_STMT *stmt) { - struct { - int64_t *ts; - int8_t b[60]; - int8_t v1[60]; - int16_t v2[60]; - int32_t v4[60]; - int64_t v8[60]; - float f4[60]; - double f8[60]; - char bin[60][40]; - } v = {0}; - - v.ts = taosMemoryMalloc(sizeof(int64_t) * 1000 * 60); - - int *lb = taosMemoryMalloc(60 * sizeof(int)); - - TAOS_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 1000*10); - char* is_null = taosMemoryMalloc(sizeof(char) * 60); - char* no_null = taosMemoryMalloc(sizeof(char) * 60); - - for (int i = 0; i < 60; ++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 < 10000; 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 = 2; + if (gCaseCtrl.checkParamNum) { + bpCheckParamNum(stmt); + } - 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 = no_null; - params[i+1].num = 2; - - 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 = no_null; - params[i+2].num = 2; - - 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 = no_null; - params[i+3].num = 2; - - 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 = no_null; - params[i+4].num = 2; - } - - int64_t tts = 1591060628000; - for (int i = 0; i < 60000; ++i) { - v.ts[i] = tts + i; - } - - unsigned long long starttime = getCurrentTime(); - - char *sql = "insert into ? (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); - } - - int id = 0; - for (int l = 0; l < 10; l++) { - for (int zz = 0; zz < 10; zz++) { - char buf[32]; - sprintf(buf, "m%d", zz); - code = taos_stmt_set_tbname(stmt, buf); - if (code != 0){ - printf("failed to execute taos_stmt_set_tbname. code:0x%x\n", code); - } - - for (int col=0; col < 10; ++col) { - taos_stmt_bind_single_param_batch(stmt, params + id++, col); + for (int32_t b = 0; b bindColNum + b*gCurCase->bindColNum)) { + exit(1); } - taos_stmt_add_batch(stmt); - } - - if (taos_stmt_execute(stmt) != 0) { - printf("failed to execute insert statement.\n"); - exit(1); + if (taos_stmt_add_batch(stmt)) { + printf("taos_stmt_add_batch error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } } } - unsigned long long endtime = getCurrentTime(); - printf("insert total %d records, used %u seconds, avg:%u useconds\n", 3000*300*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*300*60)); + if (taos_stmt_execute(stmt) != 0) { + printf("taos_stmt_execute error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } - taosMemoryFree(v.ts); - taosMemoryFree(lb); - taosMemoryFree(params); - taosMemoryFree(is_null); - taosMemoryFree(no_null); + bpCheckIsInsert(stmt); + bpCheckAffectedRows(stmt, 1); + + destroyData(&data); return 0; } +/* prepare [settbname bind add] exec */ +int insertMBSETest2(TAOS_STMT *stmt) { + BindData data = {0}; + prepareData(&data); -int stmt_func1(TAOS_STMT *stmt) { - struct { - int64_t ts; - int8_t b; - int8_t v1; - int16_t v2; - int32_t v4; - int64_t v8; - float f4; - double f8; - char bin[40]; - char blob[80]; - } v = {0}; - - TAOS_BIND params[10]; - params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; - params[0].buffer_length = sizeof(v.ts); - params[0].buffer = &v.ts; - params[0].length = ¶ms[0].buffer_length; - params[0].is_null = NULL; - - params[1].buffer_type = TSDB_DATA_TYPE_BOOL; - params[1].buffer_length = sizeof(v.b); - params[1].buffer = &v.b; - params[1].length = ¶ms[1].buffer_length; - params[1].is_null = NULL; - - params[2].buffer_type = TSDB_DATA_TYPE_TINYINT; - params[2].buffer_length = sizeof(v.v1); - params[2].buffer = &v.v1; - params[2].length = ¶ms[2].buffer_length; - params[2].is_null = NULL; - - params[3].buffer_type = TSDB_DATA_TYPE_SMALLINT; - params[3].buffer_length = sizeof(v.v2); - params[3].buffer = &v.v2; - params[3].length = ¶ms[3].buffer_length; - params[3].is_null = NULL; - - params[4].buffer_type = TSDB_DATA_TYPE_INT; - params[4].buffer_length = sizeof(v.v4); - params[4].buffer = &v.v4; - params[4].length = ¶ms[4].buffer_length; - params[4].is_null = NULL; - - params[5].buffer_type = TSDB_DATA_TYPE_BIGINT; - params[5].buffer_length = sizeof(v.v8); - params[5].buffer = &v.v8; - params[5].length = ¶ms[5].buffer_length; - params[5].is_null = NULL; - - params[6].buffer_type = TSDB_DATA_TYPE_FLOAT; - params[6].buffer_length = sizeof(v.f4); - params[6].buffer = &v.f4; - params[6].length = ¶ms[6].buffer_length; - params[6].is_null = NULL; - - params[7].buffer_type = TSDB_DATA_TYPE_DOUBLE; - params[7].buffer_length = sizeof(v.f8); - params[7].buffer = &v.f8; - params[7].length = ¶ms[7].buffer_length; - params[7].is_null = NULL; - - params[8].buffer_type = TSDB_DATA_TYPE_BINARY; - params[8].buffer_length = sizeof(v.bin); - params[8].buffer = v.bin; - params[8].length = ¶ms[8].buffer_length; - params[8].is_null = NULL; - - params[9].buffer_type = TSDB_DATA_TYPE_BINARY; - params[9].buffer_length = sizeof(v.bin); - params[9].buffer = v.bin; - params[9].length = ¶ms[9].buffer_length; - params[9].is_null = NULL; - - int is_null = 1; - - char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?)"; - int code = taos_stmt_prepare(stmt, sql, 0); + int code = taos_stmt_prepare(stmt, data.sql, 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)); + exit(1); } + + bpCheckIsInsert(stmt); + + int32_t bindTimes = gCurCase->rowNum/gCurCase->bindRowNum; + + for (int32_t b = 0; b tblNum; ++t) { + if (gCurCase->tblNum > 1) { + char buf[32]; + sprintf(buf, "t%d", t); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("taos_stmt_set_tbname error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } + } + + if (bpBindParam(stmt, data.pBind + t*bindTimes*gCurCase->bindColNum + b*gCurCase->bindColNum)) { + exit(1); + } + + if (gCaseCtrl.checkParamNum) { + bpCheckParamNum(stmt); + } + + if (taos_stmt_add_batch(stmt)) { + printf("taos_stmt_add_batch error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } + } + } + + if (taos_stmt_execute(stmt) != 0) { + printf("taos_stmt_execute error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } + + bpCheckIsInsert(stmt); + bpCheckAffectedRows(stmt, 1); + + destroyData(&data); + + return 0; +} + +/* prepare [settbname [bind add] exec] */ +int insertMBMETest1(TAOS_STMT *stmt) { + BindData data = {0}; + prepareData(&data); - for (int zz = 0; zz < 10; zz++) { - char buf[32]; - sprintf(buf, "m%d", zz); - code = taos_stmt_set_tbname(stmt, buf); + int code = taos_stmt_prepare(stmt, data.sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } + + bpCheckIsInsert(stmt); + + int32_t bindTimes = gCurCase->rowNum/gCurCase->bindRowNum; + for (int32_t t = 0; t< gCurCase->tblNum; ++t) { + if (gCurCase->tblNum > 1) { + char buf[32]; + sprintf(buf, "t%d", t); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("taos_stmt_set_tbname error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } + } + + if (gCaseCtrl.checkParamNum) { + bpCheckParamNum(stmt); + } + + for (int32_t b = 0; b bindColNum + b*gCurCase->bindColNum)) { + exit(1); + } + + if (taos_stmt_add_batch(stmt)) { + printf("taos_stmt_add_batch error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } + } + + if (taos_stmt_execute(stmt) != 0) { + printf("taos_stmt_execute error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } + } + + bpCheckIsInsert(stmt); + bpCheckAffectedRows(stmt, 1); + + destroyData(&data); + + return 0; +} + +/* prepare [settbname [bind add exec]] */ +int insertMBMETest2(TAOS_STMT *stmt) { + BindData data = {0}; + prepareData(&data); + + int code = taos_stmt_prepare(stmt, data.sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } + + bpCheckIsInsert(stmt); + + int32_t bindTimes = gCurCase->rowNum/gCurCase->bindRowNum; + for (int32_t t = 0; t< gCurCase->tblNum; ++t) { + if (gCurCase->tblNum > 1) { + char buf[32]; + sprintf(buf, "t%d", t); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("taos_stmt_set_tbname error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } + } + + for (int32_t b = 0; b bindColNum + b*gCurCase->bindColNum)) { + exit(1); + } + + if (gCaseCtrl.checkParamNum) { + bpCheckParamNum(stmt); + } + + if (taos_stmt_add_batch(stmt)) { + printf("taos_stmt_add_batch error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } + + if (taos_stmt_execute(stmt) != 0) { + printf("taos_stmt_execute error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } + } + } + + bpCheckIsInsert(stmt); + bpCheckAffectedRows(stmt, 1); + + destroyData(&data); + + return 0; +} + +/* prepare [settbname [settbname bind add exec]] */ +int insertMBMETest3(TAOS_STMT *stmt) { + BindData data = {0}; + prepareData(&data); + + int code = taos_stmt_prepare(stmt, data.sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } + + bpCheckIsInsert(stmt); + + int32_t bindTimes = gCurCase->rowNum/gCurCase->bindRowNum; + for (int32_t t = 0; t< gCurCase->tblNum; ++t) { + if (gCurCase->tblNum > 1) { + char buf[32]; + sprintf(buf, "t%d", t); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("taos_stmt_set_tbname error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } + } + + if (gCaseCtrl.checkParamNum) { + bpCheckParamNum(stmt); + } + + for (int32_t b = 0; b tblNum > 1) { + char buf[32]; + sprintf(buf, "t%d", t); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("taos_stmt_set_tbname error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } + } + + if (bpBindParam(stmt, data.pBind + t*bindTimes*gCurCase->bindColNum + b*gCurCase->bindColNum)) { + exit(1); + } + + if (taos_stmt_add_batch(stmt)) { + printf("taos_stmt_add_batch error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } + + if (taos_stmt_execute(stmt) != 0) { + printf("taos_stmt_execute error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } + } + } + + bpCheckIsInsert(stmt); + bpCheckAffectedRows(stmt, 1); + + destroyData(&data); + + return 0; +} + + +/* prepare [settbname bind add exec] */ +int insertMBMETest4(TAOS_STMT *stmt) { + BindData data = {0}; + prepareData(&data); + + int code = taos_stmt_prepare(stmt, data.sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } + + bpCheckIsInsert(stmt); + + int32_t bindTimes = gCurCase->rowNum/gCurCase->bindRowNum; + + for (int32_t b = 0; b tblNum; ++t) { + if (gCurCase->tblNum > 1) { + char buf[32]; + sprintf(buf, "t%d", t); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("taos_stmt_set_tbname error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } + } + + if (bpBindParam(stmt, data.pBind + t*bindTimes*gCurCase->bindColNum + b*gCurCase->bindColNum)) { + exit(1); + } + + if (gCaseCtrl.checkParamNum) { + bpCheckParamNum(stmt); + } + + if (taos_stmt_add_batch(stmt)) { + printf("taos_stmt_add_batch error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } + + if (taos_stmt_execute(stmt) != 0) { + printf("taos_stmt_execute error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } + } + } + + bpCheckIsInsert(stmt); + bpCheckAffectedRows(stmt, 1); + + destroyData(&data); + + return 0; +} + +/* [prepare [settbname [bind add] exec]] */ +int insertMPMETest1(TAOS_STMT *stmt) { + int32_t loop = 0; + + while (gCurCase->bindColNum >= 2) { + BindData data = {0}; + prepareData(&data); + + int code = taos_stmt_prepare(stmt, data.sql, 0); if (code != 0){ - printf("failed to execute taos_stmt_set_tbname. code:0x%x\n", code); - } - v.ts = 1591060628000 + zz * 10; - for (int i = 0; i < 10; ++i) { - v.ts += 1; - for (int j = 1; j < 10; ++j) { - params[j].is_null = ((i == j) ? &is_null : 0); - } - v.b = (int8_t)(i+zz*10) % 2; - v.v1 = (int8_t)(i+zz*10); - v.v2 = (int16_t)((i+zz*10) * 2); - v.v4 = (int32_t)((i+zz*10) * 4); - v.v8 = (int64_t)((i+zz*10) * 8); - v.f4 = (float)((i+zz*10) * 40); - v.f8 = (double)((i+zz*10) * 80); - for (int j = 0; j < sizeof(v.bin) - 1; ++j) { - v.bin[j] = (char)((i+zz)%10 + '0'); - } - - taos_stmt_bind_param(stmt, params); - taos_stmt_add_batch(stmt); - } - } - - if (taos_stmt_execute(stmt) != 0) { - printf("failed to execute insert statement.\n"); - exit(1); - } - - return 0; -} - - -int stmt_func2(TAOS_STMT *stmt) { - struct { - int64_t ts; - int8_t b; - int8_t v1; - int16_t v2; - int32_t v4; - int64_t v8; - float f4; - double f8; - char bin[40]; - char blob[80]; - } v = {0}; - - TAOS_BIND params[10]; - params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; - params[0].buffer_length = sizeof(v.ts); - params[0].buffer = &v.ts; - params[0].length = ¶ms[0].buffer_length; - params[0].is_null = NULL; - - params[1].buffer_type = TSDB_DATA_TYPE_BOOL; - params[1].buffer_length = sizeof(v.b); - params[1].buffer = &v.b; - params[1].length = ¶ms[1].buffer_length; - params[1].is_null = NULL; - - params[2].buffer_type = TSDB_DATA_TYPE_TINYINT; - params[2].buffer_length = sizeof(v.v1); - params[2].buffer = &v.v1; - params[2].length = ¶ms[2].buffer_length; - params[2].is_null = NULL; - - params[3].buffer_type = TSDB_DATA_TYPE_SMALLINT; - params[3].buffer_length = sizeof(v.v2); - params[3].buffer = &v.v2; - params[3].length = ¶ms[3].buffer_length; - params[3].is_null = NULL; - - params[4].buffer_type = TSDB_DATA_TYPE_INT; - params[4].buffer_length = sizeof(v.v4); - params[4].buffer = &v.v4; - params[4].length = ¶ms[4].buffer_length; - params[4].is_null = NULL; - - params[5].buffer_type = TSDB_DATA_TYPE_BIGINT; - params[5].buffer_length = sizeof(v.v8); - params[5].buffer = &v.v8; - params[5].length = ¶ms[5].buffer_length; - params[5].is_null = NULL; - - params[6].buffer_type = TSDB_DATA_TYPE_FLOAT; - params[6].buffer_length = sizeof(v.f4); - params[6].buffer = &v.f4; - params[6].length = ¶ms[6].buffer_length; - params[6].is_null = NULL; - - params[7].buffer_type = TSDB_DATA_TYPE_DOUBLE; - params[7].buffer_length = sizeof(v.f8); - params[7].buffer = &v.f8; - params[7].length = ¶ms[7].buffer_length; - params[7].is_null = NULL; - - params[8].buffer_type = TSDB_DATA_TYPE_BINARY; - params[8].buffer_length = sizeof(v.bin); - params[8].buffer = v.bin; - params[8].length = ¶ms[8].buffer_length; - params[8].is_null = NULL; - - params[9].buffer_type = TSDB_DATA_TYPE_BINARY; - params[9].buffer_length = sizeof(v.bin); - params[9].buffer = v.bin; - params[9].length = ¶ms[9].buffer_length; - params[9].is_null = NULL; - - int is_null = 1; - - char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?)"; - int code = taos_stmt_prepare(stmt, sql, 0); - if (code != 0){ - printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); - } - - for (int l = 0; l < 100; l++) { - for (int zz = 0; zz < 10; zz++) { - char buf[32]; - sprintf(buf, "m%d", zz); - code = taos_stmt_set_tbname(stmt, buf); - if (code != 0){ - printf("failed to execute taos_stmt_set_tbname. code:0x%x\n", code); - } - v.ts = 1591060628000 + zz * 100 * l; - for (int i = 0; i < zz; ++i) { - v.ts += 1; - for (int j = 1; j < 10; ++j) { - params[j].is_null = ((i == j) ? &is_null : 0); - } - v.b = (int8_t)(i+zz*10) % 2; - v.v1 = (int8_t)(i+zz*10); - v.v2 = (int16_t)((i+zz*10) * 2); - v.v4 = (int32_t)((i+zz*10) * 4); - v.v8 = (int64_t)((i+zz*10) * 8); - v.f4 = (float)((i+zz*10) * 40); - v.f8 = (double)((i+zz*10) * 80); - for (int j = 0; j < sizeof(v.bin) - 1; ++j) { - v.bin[j] = (char)((i+zz)%10 + '0'); - } - - taos_stmt_bind_param(stmt, params); - taos_stmt_add_batch(stmt); - } - } - - if (taos_stmt_execute(stmt) != 0) { - printf("failed to execute insert statement.\n"); + printf("failed to execute taos_stmt_prepare. error:%s\n", taos_stmt_errstr(stmt)); exit(1); } - } + bpCheckIsInsert(stmt); + int32_t bindTimes = gCurCase->rowNum/gCurCase->bindRowNum; + for (int32_t t = 0; t< gCurCase->tblNum; ++t) { + if (gCurCase->tblNum > 1) { + char buf[32]; + sprintf(buf, "t%d", t); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("taos_stmt_set_tbname error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } + } - return 0; -} - - - - -int stmt_func3(TAOS_STMT *stmt) { - struct { - int64_t ts; - int8_t b; - int8_t v1; - int16_t v2; - int32_t v4; - int64_t v8; - float f4; - double f8; - char bin[40]; - char blob[80]; - } v = {0}; - - TAOS_BIND params[10]; - params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; - params[0].buffer_length = sizeof(v.ts); - params[0].buffer = &v.ts; - params[0].length = ¶ms[0].buffer_length; - params[0].is_null = NULL; - - params[1].buffer_type = TSDB_DATA_TYPE_BOOL; - params[1].buffer_length = sizeof(v.b); - params[1].buffer = &v.b; - params[1].length = ¶ms[1].buffer_length; - params[1].is_null = NULL; - - params[2].buffer_type = TSDB_DATA_TYPE_TINYINT; - params[2].buffer_length = sizeof(v.v1); - params[2].buffer = &v.v1; - params[2].length = ¶ms[2].buffer_length; - params[2].is_null = NULL; - - params[3].buffer_type = TSDB_DATA_TYPE_SMALLINT; - params[3].buffer_length = sizeof(v.v2); - params[3].buffer = &v.v2; - params[3].length = ¶ms[3].buffer_length; - params[3].is_null = NULL; - - params[4].buffer_type = TSDB_DATA_TYPE_INT; - params[4].buffer_length = sizeof(v.v4); - params[4].buffer = &v.v4; - params[4].length = ¶ms[4].buffer_length; - params[4].is_null = NULL; - - params[5].buffer_type = TSDB_DATA_TYPE_BIGINT; - params[5].buffer_length = sizeof(v.v8); - params[5].buffer = &v.v8; - params[5].length = ¶ms[5].buffer_length; - params[5].is_null = NULL; - - params[6].buffer_type = TSDB_DATA_TYPE_FLOAT; - params[6].buffer_length = sizeof(v.f4); - params[6].buffer = &v.f4; - params[6].length = ¶ms[6].buffer_length; - params[6].is_null = NULL; - - params[7].buffer_type = TSDB_DATA_TYPE_DOUBLE; - params[7].buffer_length = sizeof(v.f8); - params[7].buffer = &v.f8; - params[7].length = ¶ms[7].buffer_length; - params[7].is_null = NULL; - - params[8].buffer_type = TSDB_DATA_TYPE_BINARY; - params[8].buffer_length = sizeof(v.bin); - params[8].buffer = v.bin; - params[8].length = ¶ms[8].buffer_length; - params[8].is_null = NULL; - - params[9].buffer_type = TSDB_DATA_TYPE_BINARY; - params[9].buffer_length = sizeof(v.bin); - params[9].buffer = v.bin; - params[9].length = ¶ms[9].buffer_length; - params[9].is_null = NULL; - - int is_null = 1; - - char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?)"; - int code = taos_stmt_prepare(stmt, sql, 0); - if (code != 0){ - printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); - } - - for (int l = 0; l < 100; l++) { - for (int zz = 0; zz < 10; zz++) { - char buf[32]; - sprintf(buf, "m%d", zz); - code = taos_stmt_set_tbname(stmt, buf); - if (code != 0){ - printf("failed to execute taos_stmt_set_tbname. code:0x%x\n", code); - } - v.ts = 1591060628000 + zz * 100 * l; - for (int i = 0; i < zz; ++i) { - v.ts += 1; - for (int j = 1; j < 10; ++j) { - params[j].is_null = ((i == j) ? &is_null : 0); + if (gCaseCtrl.checkParamNum) { + bpCheckParamNum(stmt); + } + + for (int32_t b = 0; b bindColNum + b*gCurCase->bindColNum)) { + exit(1); } - v.b = (int8_t)(i+zz*10) % 2; - v.v1 = (int8_t)(i+zz*10); - v.v2 = (int16_t)((i+zz*10) * 2); - v.v4 = (int32_t)((i+zz*10) * 4); - v.v8 = (int64_t)((i+zz*10) * 8); - v.f4 = (float)((i+zz*10) * 40); - v.f8 = (double)((i+zz*10) * 80); - for (int j = 0; j < sizeof(v.bin) - 1; ++j) { - v.bin[j] = (char)((i+zz)%10 + '0'); + + if (taos_stmt_add_batch(stmt)) { + printf("taos_stmt_add_batch error:%s\n", taos_stmt_errstr(stmt)); + exit(1); } + } - taos_stmt_bind_param(stmt, params); - taos_stmt_add_batch(stmt); + if (taos_stmt_execute(stmt) != 0) { + printf("taos_stmt_execute error:%s\n", taos_stmt_errstr(stmt)); + exit(1); } } + + bpCheckIsInsert(stmt); + + destroyData(&data); + + gCurCase->bindColNum -= 2; + gCurCase->fullCol = false; + loop++; } + bpCheckAffectedRows(stmt, loop); + + gExecLoopTimes = loop; - if (taos_stmt_execute(stmt) != 0) { - printf("failed to execute insert statement.\n"); - exit(1); - } - - return 0; } +#if 0 //1 tables 10 records int stmt_funcb_autoctb1(TAOS_STMT *stmt) { @@ -859,7 +951,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_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 1*10); + TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 1*10); // int one_null = 1; int one_not_null = 0; @@ -1008,7 +1100,7 @@ int stmt_funcb_autoctb1(TAOS_STMT *stmt) { } - unsigned long long starttime = getCurrentTime(); + unsigned long long starttime = taosGetTimestampUs(); char *sql = "insert into ? using stb1 tags(?,?,?,?,?,?,?,?,?) values(?,?,?,?,?,?,?,?,?,?)"; int code = taos_stmt_prepare(stmt, sql, 0); @@ -1037,7 +1129,7 @@ int stmt_funcb_autoctb1(TAOS_STMT *stmt) { ++id; - unsigned long long endtime = getCurrentTime(); + unsigned long long endtime = taosGetTimestampUs(); printf("insert total %d records, used %u seconds, avg:%u useconds\n", 10, (endtime-starttime)/1000000UL, (endtime-starttime)/(10)); taosMemoryFree(v.ts); @@ -1072,7 +1164,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_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 1*10); + TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 1*10); // int one_null = 1; int one_not_null = 0; @@ -1221,7 +1313,7 @@ int stmt_funcb_autoctb2(TAOS_STMT *stmt) { } - unsigned long long starttime = getCurrentTime(); + unsigned long long starttime = taosGetTimestampUs(); char *sql = "insert into ? using stb1 tags(1,true,2,3,4,5.0,6.0,'a','b') values(?,?,?,?,?,?,?,?,?,?)"; int code = taos_stmt_prepare(stmt, sql, 0); @@ -1250,7 +1342,7 @@ int stmt_funcb_autoctb2(TAOS_STMT *stmt) { ++id; - unsigned long long endtime = getCurrentTime(); + unsigned long long endtime = taosGetTimestampUs(); printf("insert total %d records, used %u seconds, avg:%u useconds\n", 10, (endtime-starttime)/1000000UL, (endtime-starttime)/(10)); taosMemoryFree(v.ts); @@ -1286,7 +1378,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_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 1*10); + TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 1*10); // int one_null = 1; int one_not_null = 0; @@ -1410,7 +1502,7 @@ int stmt_funcb_autoctb3(TAOS_STMT *stmt) { } - unsigned long long starttime = getCurrentTime(); + unsigned long long starttime = taosGetTimestampUs(); char *sql = "insert into ? using stb1 tags(1,?,2,?,4,?,6.0,?,'b') values(?,?,?,?,?,?,?,?,?,?)"; int code = taos_stmt_prepare(stmt, sql, 0); @@ -1439,7 +1531,7 @@ int stmt_funcb_autoctb3(TAOS_STMT *stmt) { ++id; - unsigned long long endtime = getCurrentTime(); + unsigned long long endtime = taosGetTimestampUs(); printf("insert total %d records, used %u seconds, avg:%u useconds\n", 10, (endtime-starttime)/1000000UL, (endtime-starttime)/(10)); taosMemoryFree(v.ts); @@ -1477,7 +1569,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_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 1*5); + TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 1*5); // int one_null = 1; int one_not_null = 0; @@ -1565,7 +1657,7 @@ int stmt_funcb_autoctb4(TAOS_STMT *stmt) { } - unsigned long long starttime = getCurrentTime(); + unsigned long long starttime = taosGetTimestampUs(); 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); @@ -1594,7 +1686,7 @@ int stmt_funcb_autoctb4(TAOS_STMT *stmt) { ++id; - unsigned long long endtime = getCurrentTime(); + unsigned long long endtime = taosGetTimestampUs(); printf("insert total %d records, used %u seconds, avg:%u useconds\n", 10, (endtime-starttime)/1000000UL, (endtime-starttime)/(10)); taosMemoryFree(v.ts); @@ -1630,7 +1722,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_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 1*10); + TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 1*10); // int one_null = 1; int one_not_null = 0; @@ -1754,7 +1846,7 @@ int stmt_funcb_autoctb_e1(TAOS_STMT *stmt) { } - unsigned long long starttime = getCurrentTime(); + unsigned long long starttime = taosGetTimestampUs(); 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); @@ -1783,7 +1875,7 @@ int stmt_funcb_autoctb_e1(TAOS_STMT *stmt) { ++id; - unsigned long long endtime = getCurrentTime(); + unsigned long long endtime = taosGetTimestampUs(); printf("insert total %d records, used %u seconds, avg:%u useconds\n", 10, (endtime-starttime)/1000000UL, (endtime-starttime)/(10)); taosMemoryFree(v.ts); @@ -1819,7 +1911,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_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 1*10); + TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 1*10); // int one_null = 1; int one_not_null = 0; @@ -1968,7 +2060,7 @@ int stmt_funcb_autoctb_e2(TAOS_STMT *stmt) { } - unsigned long long starttime = getCurrentTime(); + unsigned long long starttime = taosGetTimestampUs(); char *sql = "insert into ? using stb1 tags(?,?,?,?,?,?,?,?,?) values(?,?,?,?,?,?,?,?,?,?)"; int code = taos_stmt_prepare(stmt, sql, 0); @@ -1998,7 +2090,7 @@ int stmt_funcb_autoctb_e2(TAOS_STMT *stmt) { ++id; - unsigned long long endtime = getCurrentTime(); + unsigned long long endtime = taosGetTimestampUs(); printf("insert total %d records, used %u seconds, avg:%u useconds\n", 10, (endtime-starttime)/1000000UL, (endtime-starttime)/(10)); taosMemoryFree(v.ts); @@ -2036,7 +2128,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_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 1*10); + TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 1*10); // int one_null = 1; int one_not_null = 0; @@ -2185,7 +2277,7 @@ int stmt_funcb_autoctb_e3(TAOS_STMT *stmt) { } - unsigned long long starttime = getCurrentTime(); + unsigned long long starttime = taosGetTimestampUs(); 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); @@ -2216,7 +2308,7 @@ int stmt_funcb_autoctb_e3(TAOS_STMT *stmt) { ++id; - unsigned long long endtime = getCurrentTime(); + unsigned long long endtime = taosGetTimestampUs(); printf("insert total %d records, used %u seconds, avg:%u useconds\n", 10, (endtime-starttime)/1000000UL, (endtime-starttime)/(10)); taosMemoryFree(v.ts); @@ -2251,7 +2343,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_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 1*10); + TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 1*10); // int one_null = 1; int one_not_null = 0; @@ -2400,7 +2492,7 @@ int stmt_funcb_autoctb_e4(TAOS_STMT *stmt) { } - unsigned long long starttime = getCurrentTime(); + unsigned long long starttime = taosGetTimestampUs(); char *sql = "insert into ? using stb1 tags(?,?,?,?,?,?,?,?,?) values(?,?,?,?,?,?,?,?,?,?)"; int code = taos_stmt_prepare(stmt, sql, 0); @@ -2441,7 +2533,7 @@ int stmt_funcb_autoctb_e4(TAOS_STMT *stmt) { ++id; - unsigned long long endtime = getCurrentTime(); + unsigned long long endtime = taosGetTimestampUs(); printf("insert total %d records, used %u seconds, avg:%u useconds\n", 10, (endtime-starttime)/1000000UL, (endtime-starttime)/(10)); taosMemoryFree(v.ts); @@ -2478,7 +2570,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_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 1*10); + TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 1*10); // int one_null = 1; int one_not_null = 0; @@ -2627,7 +2719,7 @@ int stmt_funcb_autoctb_e5(TAOS_STMT *stmt) { } - unsigned long long starttime = getCurrentTime(); + unsigned long long starttime = taosGetTimestampUs(); char *sql = "insert into ? using stb1 tags(?,?,?,?,?,?,?,?,?) values(?,?,?,?,?,?,?,?,?,?)"; int code = taos_stmt_prepare(NULL, sql, 0); @@ -2668,7 +2760,7 @@ int stmt_funcb_autoctb_e5(TAOS_STMT *stmt) { ++id; - unsigned long long endtime = getCurrentTime(); + unsigned long long endtime = taosGetTimestampUs(); printf("insert total %d records, used %u seconds, avg:%u useconds\n", 10, (endtime-starttime)/1000000UL, (endtime-starttime)/(10)); taosMemoryFree(v.ts); @@ -2681,488 +2773,6 @@ int stmt_funcb_autoctb_e5(TAOS_STMT *stmt) { return 0; } - - -//300 tables 60 records -int stmt_funcb1(TAOS_STMT *stmt) { - struct { - int64_t *ts; - int8_t b[60]; - int8_t v1[60]; - int16_t v2[60]; - int32_t v4[60]; - int64_t v8[60]; - float f4[60]; - double f8[60]; - char bin[60][40]; - } v = {0}; - - v.ts = taosMemoryMalloc(sizeof(int64_t) * 900000 * 60); - - int *lb = taosMemoryMalloc(60 * sizeof(int)); - - 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); - - for (int i = 0; i < 60; ++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 < 9000000; 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[60*i/10]; - params[i+0].length = NULL; - params[i+0].is_null = no_null; - params[i+0].num = 60; - - 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 = 60; - - 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 = 60; - - 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 = 60; - - 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 = 60; - - 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 = 60; - - 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 = 60; - - 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 = 60; - - 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 = 60; - - 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 = 60; - - } - - int64_t tts = 1591060628000; - for (int i = 0; i < 54000000; ++i) { - v.ts[i] = tts + i; - } - - unsigned long long starttime = getCurrentTime(); - - char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?)"; - int code = taos_stmt_prepare(stmt, sql, 0); - if (code != 0){ - printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); - } - - int id = 0; - for (int l = 0; l < 3000; l++) { - for (int zz = 0; zz < 300; zz++) { - char buf[32]; - sprintf(buf, "m%d", zz); - code = taos_stmt_set_tbname(stmt, buf); - if (code != 0){ - printf("failed to execute taos_stmt_set_tbname. code:0x%x\n", code); - } - - taos_stmt_bind_param_batch(stmt, params + id * 10); - taos_stmt_add_batch(stmt); - } - - if (taos_stmt_execute(stmt) != 0) { - printf("failed to execute insert statement.\n"); - exit(1); - } - - ++id; - } - - unsigned long long endtime = getCurrentTime(); - printf("insert total %d records, used %u seconds, avg:%u useconds\n", 3000*300*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*300*60)); - - taosMemoryFree(v.ts); - taosMemoryFree(lb); - taosMemoryFree(params); - taosMemoryFree(is_null); - taosMemoryFree(no_null); - - return 0; -} - - -//1table 18000 reocrds -int stmt_funcb2(TAOS_STMT *stmt) { - struct { - int64_t *ts; - int8_t b[18000]; - int8_t v1[18000]; - int16_t v2[18000]; - int32_t v4[18000]; - int64_t v8[18000]; - float f4[18000]; - double f8[18000]; - char bin[18000][40]; - } v = {0}; - - v.ts = taosMemoryMalloc(sizeof(int64_t) * 900000 * 60); - - int *lb = taosMemoryMalloc(18000 * sizeof(int)); - - 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); - - for (int i = 0; i < 18000; ++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 < 30000; 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[18000*i/10]; - params[i+0].length = NULL; - params[i+0].is_null = no_null; - params[i+0].num = 18000; - - 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 = 18000; - - 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 = 18000; - - 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 = 18000; - - 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 = 18000; - - 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 = 18000; - - 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 = 18000; - - 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 = 18000; - - 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 = 18000; - - 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 = 18000; - - } - - int64_t tts = 1591060628000; - for (int i = 0; i < 54000000; ++i) { - v.ts[i] = tts + i; - } - - unsigned long long starttime = getCurrentTime(); - - char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?)"; - int code = taos_stmt_prepare(stmt, sql, 0); - if (code != 0){ - printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); - } - - int id = 0; - for (int l = 0; l < 10; l++) { - for (int zz = 0; zz < 300; zz++) { - char buf[32]; - sprintf(buf, "m%d", zz); - code = taos_stmt_set_tbname(stmt, buf); - if (code != 0){ - printf("failed to execute taos_stmt_set_tbname. code:0x%x\n", code); - } - - taos_stmt_bind_param_batch(stmt, params + id * 10); - taos_stmt_add_batch(stmt); - - if (taos_stmt_execute(stmt) != 0) { - printf("failed to execute insert statement.\n"); - exit(1); - } - ++id; - - } - - } - - unsigned long long endtime = getCurrentTime(); - printf("insert total %d records, used %u seconds, avg:%u useconds\n", 3000*300*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*300*60)); - - taosMemoryFree(v.ts); - taosMemoryFree(lb); - taosMemoryFree(params); - taosMemoryFree(is_null); - taosMemoryFree(no_null); - - return 0; -} - - -//disorder -int stmt_funcb3(TAOS_STMT *stmt) { - struct { - int64_t *ts; - int8_t b[60]; - int8_t v1[60]; - int16_t v2[60]; - int32_t v4[60]; - int64_t v8[60]; - float f4[60]; - double f8[60]; - char bin[60][40]; - } v = {0}; - - v.ts = taosMemoryMalloc(sizeof(int64_t) * 900000 * 60); - - int *lb = taosMemoryMalloc(60 * sizeof(int)); - - 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); - - for (int i = 0; i < 60; ++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 < 9000000; 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[60*i/10]; - params[i+0].length = NULL; - params[i+0].is_null = no_null; - params[i+0].num = 60; - - 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 = 60; - - 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 = 60; - - 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 = 60; - - 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 = 60; - - 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 = 60; - - 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 = 60; - - 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 = 60; - - 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 = 60; - - 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 = 60; - - } - - int64_t tts = 1591060628000; - int64_t ttt = 0; - for (int i = 0; i < 54000000; ++i) { - v.ts[i] = tts + i; - if (i > 0 && i%60 == 0) { - ttt = v.ts[i-1]; - v.ts[i-1] = v.ts[i-60]; - v.ts[i-60] = ttt; - } - } - - unsigned long long starttime = getCurrentTime(); - - char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?)"; - int code = taos_stmt_prepare(stmt, sql, 0); - if (code != 0){ - printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); - } - - int id = 0; - for (int l = 0; l < 3000; l++) { - for (int zz = 0; zz < 300; zz++) { - char buf[32]; - sprintf(buf, "m%d", zz); - code = taos_stmt_set_tbname(stmt, buf); - if (code != 0){ - printf("failed to execute taos_stmt_set_tbname. code:0x%x\n", code); - } - - taos_stmt_bind_param_batch(stmt, params + id * 10); - taos_stmt_add_batch(stmt); - } - - if (taos_stmt_execute(stmt) != 0) { - printf("failed to execute insert statement.\n"); - exit(1); - } - - ++id; - } - - unsigned long long endtime = getCurrentTime(); - printf("insert total %d records, used %u seconds, avg:%u useconds\n", 3000*300*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*300*60)); - - taosMemoryFree(v.ts); - taosMemoryFree(lb); - taosMemoryFree(params); - taosMemoryFree(is_null); - taosMemoryFree(no_null); - - return 0; -} - - - - //samets int stmt_funcb4(TAOS_STMT *stmt) { struct { @@ -3181,7 +2791,7 @@ int stmt_funcb4(TAOS_STMT *stmt) { int *lb = taosMemoryMalloc(60 * sizeof(int)); - TAOS_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 900000*10); + TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 900000*10); char* is_null = taosMemoryMalloc(sizeof(char) * 60); char* no_null = taosMemoryMalloc(sizeof(char) * 60); @@ -3277,7 +2887,7 @@ int stmt_funcb4(TAOS_STMT *stmt) { v.ts[i] = tts; } - unsigned long long starttime = getCurrentTime(); + unsigned long long starttime = taosGetTimestampUs(); char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?)"; int code = taos_stmt_prepare(stmt, sql, 0); @@ -3307,7 +2917,7 @@ int stmt_funcb4(TAOS_STMT *stmt) { ++id; } - unsigned long long endtime = getCurrentTime(); + unsigned long long endtime = taosGetTimestampUs(); printf("insert total %d records, used %u seconds, avg:%u useconds\n", 3000*300*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*300*60)); taosMemoryFree(v.ts); @@ -3340,7 +2950,7 @@ int stmt_funcb5(TAOS_STMT *stmt) { int *lb = taosMemoryMalloc(18000 * sizeof(int)); - TAOS_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 3000*10); + TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 3000*10); char* is_null = taosMemoryMalloc(sizeof(char) * 18000); char* no_null = taosMemoryMalloc(sizeof(char) * 18000); @@ -3436,7 +3046,7 @@ int stmt_funcb5(TAOS_STMT *stmt) { v.ts[i] = tts + i; } - unsigned long long starttime = getCurrentTime(); + unsigned long long starttime = taosGetTimestampUs(); char *sql = "insert into m0 values(?,?,?,?,?,?,?,?,?,?)"; int code = taos_stmt_prepare(stmt, sql, 0); @@ -3460,7 +3070,7 @@ int stmt_funcb5(TAOS_STMT *stmt) { } - unsigned long long endtime = getCurrentTime(); + unsigned long long endtime = taosGetTimestampUs(); printf("insert total %d records, used %u seconds, avg:%u useconds\n", 3000*300*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*300*60)); taosMemoryFree(v.ts); @@ -3484,7 +3094,7 @@ int stmt_funcb_ssz1(TAOS_STMT *stmt) { int *lb = taosMemoryMalloc(30000 * sizeof(int)); - TAOS_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 3000*10); + TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 3000*10); char* no_null = taosMemoryMalloc(sizeof(int) * 200000); for (int i = 0; i < 30000; ++i) { @@ -3514,7 +3124,7 @@ int stmt_funcb_ssz1(TAOS_STMT *stmt) { v.ts[i] = tts + i; } - unsigned long long starttime = getCurrentTime(); + unsigned long long starttime = taosGetTimestampUs(); char *sql = "insert into ? values(?,?)"; int code = taos_stmt_prepare(stmt, sql, 0); @@ -3545,7 +3155,7 @@ int stmt_funcb_ssz1(TAOS_STMT *stmt) { } - unsigned long long endtime = getCurrentTime(); + unsigned long long endtime = taosGetTimestampUs(); printf("insert total %d records, used %u seconds, avg:%u useconds\n", 3000*300*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*300*60)); taosMemoryFree(v.ts); @@ -3575,7 +3185,7 @@ int stmt_funcb_s1(TAOS_STMT *stmt) { int *lb = taosMemoryMalloc(60 * sizeof(int)); - TAOS_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 900000*10); + TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 900000*10); char* is_null = taosMemoryMalloc(sizeof(char) * 60); char* no_null = taosMemoryMalloc(sizeof(char) * 60); @@ -3671,7 +3281,7 @@ int stmt_funcb_s1(TAOS_STMT *stmt) { v.ts[i] = tts + i; } - unsigned long long starttime = getCurrentTime(); + unsigned long long starttime = taosGetTimestampUs(); char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?)"; int code = taos_stmt_prepare(stmt, sql, 0); @@ -3702,7 +3312,7 @@ int stmt_funcb_s1(TAOS_STMT *stmt) { } - unsigned long long endtime = getCurrentTime(); + unsigned long long endtime = taosGetTimestampUs(); printf("insert total %d records, used %u seconds, avg:%u useconds\n", 3000*300*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*300*60)); taosMemoryFree(v.ts); @@ -3737,7 +3347,7 @@ int stmt_funcb_sc1(TAOS_STMT *stmt) { int *lb = taosMemoryMalloc(60 * sizeof(int)); - TAOS_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 900000*10); + TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 900000*10); char* is_null = taosMemoryMalloc(sizeof(char) * 60); char* no_null = taosMemoryMalloc(sizeof(char) * 60); @@ -3833,7 +3443,7 @@ int stmt_funcb_sc1(TAOS_STMT *stmt) { v.ts[i] = tts + i; } - unsigned long long starttime = getCurrentTime(); + unsigned long long starttime = taosGetTimestampUs(); char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?)"; int code = taos_stmt_prepare(stmt, sql, 0); @@ -3864,7 +3474,7 @@ int stmt_funcb_sc1(TAOS_STMT *stmt) { } } - unsigned long long endtime = getCurrentTime(); + unsigned long long endtime = taosGetTimestampUs(); printf("insert total %d records, used %u seconds, avg:%u useconds\n", 3000*300*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*300*60)); taosMemoryFree(v.ts); @@ -3895,7 +3505,7 @@ int stmt_funcb_sc2(TAOS_STMT *stmt) { int *lb = taosMemoryMalloc(60 * sizeof(int)); - TAOS_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 900000*10); + TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 900000*10); char* is_null = taosMemoryMalloc(sizeof(char) * 60); char* no_null = taosMemoryMalloc(sizeof(char) * 60); @@ -3991,7 +3601,7 @@ int stmt_funcb_sc2(TAOS_STMT *stmt) { v.ts[i] = tts + i; } - unsigned long long starttime = getCurrentTime(); + unsigned long long starttime = taosGetTimestampUs(); char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?)"; int code = taos_stmt_prepare(stmt, sql, 0); @@ -4024,7 +3634,7 @@ int stmt_funcb_sc2(TAOS_STMT *stmt) { } - unsigned long long endtime = getCurrentTime(); + unsigned long long endtime = taosGetTimestampUs(); printf("insert total %d records, used %u seconds, avg:%u useconds\n", 3000*300*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*300*60)); taosMemoryFree(v.ts); @@ -4055,7 +3665,7 @@ int stmt_funcb_sc3(TAOS_STMT *stmt) { int *lb = taosMemoryMalloc(60 * sizeof(int)); - TAOS_MULTI_BIND *params = taosMemoryCalloc(1, sizeof(TAOS_MULTI_BIND) * 60*10); + TAOS_BIND_v2 *params = taosMemoryCalloc(1, sizeof(TAOS_BIND_v2) * 60*10); char* is_null = taosMemoryMalloc(sizeof(char) * 60); char* no_null = taosMemoryMalloc(sizeof(char) * 60); @@ -4152,7 +3762,7 @@ int stmt_funcb_sc3(TAOS_STMT *stmt) { v.ts[i] = tts + i; } - unsigned long long starttime = getCurrentTime(); + unsigned long long starttime = taosGetTimestampUs(); char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?)"; int code = taos_stmt_prepare(stmt, sql, 0); @@ -4181,7 +3791,7 @@ int stmt_funcb_sc3(TAOS_STMT *stmt) { exit(1); } - unsigned long long endtime = getCurrentTime(); + unsigned long long endtime = taosGetTimestampUs(); printf("insert total %d records, used %u seconds, avg:%u useconds\n", 3000*300*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*300*60)); taosMemoryFree(v.ts); @@ -4192,15 +3802,12 @@ int stmt_funcb_sc3(TAOS_STMT *stmt) { return 0; } +#endif - -void check_result(TAOS *taos, char *tname, int printr, int expected) { +void prepareCheckResultImpl(TAOS *taos, char *tname, bool printr, int expected) { char sql[255] = "SELECT * FROM "; TAOS_RES *result; - //FORCE NO PRINT - printr = 0; - strcat(sql, tname); result = taos_query(taos, sql); @@ -4229,9 +3836,9 @@ void check_result(TAOS *taos, char *tname, int printr, int expected) { } if (rows == expected) { - printf("%d rows are fetched as expectation\n", rows); + printf("%d rows are fetched as expected from %s\n", rows, tname); } else { - printf("!!!expect %d rows, but %d rows are fetched\n", expected, rows); + printf("!!!expect %d rows, but %d rows are fetched from %s\n", expected, rows, tname); exit(1); } @@ -4240,6 +3847,22 @@ void check_result(TAOS *taos, char *tname, int printr, int expected) { } +void prepareCheckResult(TAOS *taos) { + char buf[32]; + for (int32_t t = 0; t< gCurCase->tblNum; ++t) { + if (gCurCase->tblNum > 1) { + sprintf(buf, "t%d", t); + } else { + sprintf(buf, "t%d", 0); + } + + prepareCheckResultImpl(taos, buf, gCaseCtrl.printRes, gCurCase->rowNum * gExecLoopTimes); + } + + gExecLoopTimes = 1; +} + + //120table 60 record each table int sql_perf1(TAOS *taos) { @@ -4263,7 +3886,7 @@ int sql_perf1(TAOS *taos) { } - unsigned long long starttime = getCurrentTime(); + int64_t starttime = taosGetTimestampUs(); for (int i = 0; i < 3000; ++i) { result = taos_query(taos, sql[i]); int code = taos_errno(result); @@ -4275,7 +3898,7 @@ int sql_perf1(TAOS *taos) { taos_free_result(result); } - unsigned long long endtime = getCurrentTime(); + int64_t endtime = taosGetTimestampUs(); printf("insert total %d records, used %u seconds, avg:%.1f useconds\n", 3000*120*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*120*60)); for (int i = 0; i < 3000; i++) { @@ -4291,7 +3914,7 @@ int sql_perf1(TAOS *taos) { //one table 60 records one time int sql_perf_s1(TAOS *taos) { - char **sql = taosMemoryCalloc(1, sizeof(char*) * 360000); + char **sql = calloc(1, sizeof(char*) * 360000); TAOS_RES *result; for (int i = 0; i < 360000; i++) { @@ -4316,7 +3939,7 @@ int sql_perf_s1(TAOS *taos) { } - unsigned long long starttime = getCurrentTime(); + unsigned long long starttime = taosGetTimestampUs(); for (int i = 0; i < 360000; ++i) { result = taos_query(taos, sql[i]); int code = taos_errno(result); @@ -4328,7 +3951,7 @@ int sql_perf_s1(TAOS *taos) { taos_free_result(result); } - unsigned long long endtime = getCurrentTime(); + unsigned long long endtime = taosGetTimestampUs(); printf("insert total %d records, used %u seconds, avg:%.1f useconds\n", 3000*120*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*120*60)); for (int i = 0; i < 360000; i++) { @@ -4363,7 +3986,7 @@ int sql_s_perf1(TAOS *taos) { } - unsigned long long starttime = getCurrentTime(); + unsigned long long starttime = taosGetTimestampUs(); for (int i = 0; i < 3000; ++i) { result = taos_query(taos, sql[i]); int code = taos_errno(result); @@ -4375,7 +3998,7 @@ int sql_s_perf1(TAOS *taos) { taos_free_result(result); } - unsigned long long endtime = getCurrentTime(); + unsigned long long endtime = taosGetTimestampUs(); printf("insert total %d records, used %u seconds, avg:%.1f useconds\n", 3000*120*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*120*60)); for (int i = 0; i < 3000; i++) { @@ -4385,8 +4008,131 @@ int sql_s_perf1(TAOS *taos) { return 0; } +void generateCreateTableSQL(char *buf, int32_t tblIdx, int32_t colNum, int32_t *colList, bool stable) { + int32_t blen = 0; + blen = sprintf(buf, "create table %s%d ", (stable ? "st" : "t"), tblIdx); + if (stable) { + blen += sprintf(buf + blen, "tags ("); + for (int c = 0; c < colNum; ++c) { + if (c > 0) { + blen += sprintf(buf + blen, ","); + } + switch (colList[c]) { + case TSDB_DATA_TYPE_BOOL: + blen += sprintf(buf + blen, "tbooldata bool"); + break; + case TSDB_DATA_TYPE_TINYINT: + blen += sprintf(buf + blen, "ttinydata tinyint"); + break; + case TSDB_DATA_TYPE_SMALLINT: + blen += sprintf(buf + blen, "tsmalldata smallint"); + break; + case TSDB_DATA_TYPE_INT: + blen += sprintf(buf + blen, "tintdata int"); + break; + case TSDB_DATA_TYPE_BIGINT: + blen += sprintf(buf + blen, "tbigdata bigint"); + break; + case TSDB_DATA_TYPE_FLOAT: + blen += sprintf(buf + blen, "tfloatdata float"); + break; + case TSDB_DATA_TYPE_DOUBLE: + blen += sprintf(buf + blen, "tdoubledata double"); + break; + case TSDB_DATA_TYPE_VARCHAR: + blen += sprintf(buf + blen, "tbinarydata binary(%d)", gVarCharSize); + break; + case TSDB_DATA_TYPE_TIMESTAMP: + blen += sprintf(buf + blen, "tts ts"); + break; + case TSDB_DATA_TYPE_NCHAR: + blen += sprintf(buf + blen, "tnchardata nchar(%d)", gVarCharSize); + break; + case TSDB_DATA_TYPE_UTINYINT: + blen += sprintf(buf + blen, "tutinydata tinyint unsigned"); + break; + case TSDB_DATA_TYPE_USMALLINT: + blen += sprintf(buf + blen, "tusmalldata smallint unsigned"); + break; + case TSDB_DATA_TYPE_UINT: + blen += sprintf(buf + blen, "tuintdata int unsigned"); + break; + case TSDB_DATA_TYPE_UBIGINT: + blen += sprintf(buf + blen, "tubigdata bigint unsigned"); + break; + default: + printf("invalid col type:%d", colList[c]); + exit(1); + } + } -void prepare(TAOS *taos, int bigsize, int createChildTable) { + blen += sprintf(buf + blen, ")"); + } + + blen += sprintf(buf + blen, " ("); + + for (int c = 0; c < colNum; ++c) { + if (c > 0) { + blen += sprintf(buf + blen, ","); + } + + switch (colList[c]) { + case TSDB_DATA_TYPE_BOOL: + blen += sprintf(buf + blen, "booldata bool"); + break; + case TSDB_DATA_TYPE_TINYINT: + blen += sprintf(buf + blen, "tinydata tinyint"); + break; + case TSDB_DATA_TYPE_SMALLINT: + blen += sprintf(buf + blen, "smalldata smallint"); + break; + case TSDB_DATA_TYPE_INT: + blen += sprintf(buf + blen, "intdata int"); + break; + case TSDB_DATA_TYPE_BIGINT: + blen += sprintf(buf + blen, "bigdata bigint"); + break; + case TSDB_DATA_TYPE_FLOAT: + blen += sprintf(buf + blen, "floatdata float"); + break; + case TSDB_DATA_TYPE_DOUBLE: + blen += sprintf(buf + blen, "doubledata double"); + break; + case TSDB_DATA_TYPE_VARCHAR: + blen += sprintf(buf + blen, "binarydata binary(%d)", gVarCharSize); + break; + case TSDB_DATA_TYPE_TIMESTAMP: + blen += sprintf(buf + blen, "ts timestamp"); + break; + case TSDB_DATA_TYPE_NCHAR: + blen += sprintf(buf + blen, "nchardata nchar(%d)", gVarCharSize); + break; + case TSDB_DATA_TYPE_UTINYINT: + blen += sprintf(buf + blen, "utinydata tinyint unsigned"); + break; + case TSDB_DATA_TYPE_USMALLINT: + blen += sprintf(buf + blen, "usmalldata smallint unsigned"); + break; + case TSDB_DATA_TYPE_UINT: + blen += sprintf(buf + blen, "uintdata int unsigned"); + break; + case TSDB_DATA_TYPE_UBIGINT: + blen += sprintf(buf + blen, "ubigdata bigint unsigned"); + break; + default: + printf("invalid col type:%d", colList[c]); + exit(1); + } + } + + blen += sprintf(buf + blen, ")"); + + if (gCaseCtrl.printCreateTblSql) { + printf("Create Table SQL:%s\n", buf); + } +} + +void prepare(TAOS *taos, int32_t colNum, int32_t *colList, int autoCreate) { TAOS_RES *result; int code; @@ -4405,15 +4151,11 @@ void prepare(TAOS *taos, int bigsize, int createChildTable) { result = taos_query(taos, "use demo"); taos_free_result(result); - if (createChildTable) { + if (!autoCreate) { // create table - for (int i = 0 ; i < 300; i++) { + for (int i = 0 ; i < 10; i++) { char buf[1024]; - if (bigsize) { - sprintf(buf, "create table m%d (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, bin binary(40), bin2 binary(40))", i) ; - } else { - sprintf(buf, "create table m%d (ts timestamp, b int)", i) ; - } + generateCreateTableSQL(buf, i, colNum, colList, false); result = taos_query(taos, buf); code = taos_errno(result); if (code != 0) { @@ -4425,12 +4167,7 @@ void prepare(TAOS *taos, int bigsize, int createChildTable) { } } else { char buf[1024]; - if (bigsize) { - sprintf(buf, "create stable stb1 (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, bin binary(40), bin2 binary(40))" - " tags(id1 int, id2 bool, id3 tinyint, id4 smallint, id5 bigint, id6 float, id7 double, id8 binary(40), id9 nchar(40))") ; - } else { - sprintf(buf, "create stable stb1 (ts timestamp, b int) tags(id1 int, id2 bool, id3 tinyint, id4 smallint, id5 bigint, id6 float, id7 double, id8 binary(40), id9 nchar(40))") ; - } + generateCreateTableSQL(buf, 1, colNum, colList, true); result = taos_query(taos, buf); code = taos_errno(result); @@ -4444,652 +4181,135 @@ void prepare(TAOS *taos, int bigsize, int createChildTable) { } +void* runcase(TAOS *taos) { + TAOS_STMT *stmt = NULL; + int32_t caseIdx = 0; + for (int32_t i = 0; i < sizeof(gCase)/sizeof(gCase[0]); ++i) { + CaseCfg cfg = gCase[i]; + gCurCase = &cfg; -void preparem(TAOS *taos, int bigsize, int idx) { - TAOS_RES *result; - int code; - char dbname[32],sql[255]; - - sprintf(dbname, "demo%d", idx); - sprintf(sql, "drop database %s", dbname); - - - result = taos_query(taos, sql); - taos_free_result(result); - - sprintf(sql, "create database %s keep 36500", dbname); - result = taos_query(taos, sql); - code = taos_errno(result); - if (code != 0) { - printf("failed to create database, reason:%s\n", taos_errstr(result)); - taos_free_result(result); - exit(1); - } - taos_free_result(result); - - sprintf(sql, "use %s", dbname); - result = taos_query(taos, sql); - taos_free_result(result); - - // create table - for (int i = 0 ; i < 300; i++) { - char buf[1024]; - if (bigsize) { - sprintf(buf, "create table m%d (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, bin binary(40), bin2 binary(40))", i) ; - } else { - sprintf(buf, "create table m%d (ts timestamp, b int)", i) ; + if ((gCaseCtrl.bindColTypeNum || gCaseCtrl.bindColNum) && (gCurCase->colNum != gFullColNum)) { + continue; } - result = taos_query(taos, buf); - code = taos_errno(result); - if (code != 0) { - printf("failed to create table, reason:%s\n", taos_errstr(result)); - taos_free_result(result); - exit(1); + + printf("* Case %d - %s Begin *\n", caseIdx, gCurCase->caseDesc); + + if (gCaseCtrl.runTimes) { + gCurCase->runTimes = gCaseCtrl.runTimes; } - taos_free_result(result); + + if (gCaseCtrl.rowNum) { + gCurCase->rowNum = gCaseCtrl.rowNum; + } + + if (gCurCase->fullCol) { + gCurCase->bindColNum = gCurCase->colNum; + } + + gCurCase->bindNullNum = gCaseCtrl.bindNullNum; + gCurCase->autoCreate = gCaseCtrl.autoCreate; + if (gCaseCtrl.bindColNum) { + gCurCase->bindColNum = gCaseCtrl.bindColNum; + gCurCase->fullCol = false; + } + if (gCaseCtrl.bindRowNum) { + gCurCase->bindRowNum = gCaseCtrl.bindRowNum; + } + if (gCaseCtrl.bindColTypeNum) { + gCurCase->bindColNum = gCaseCtrl.bindColTypeNum; + gCurCase->fullCol = false; + } + + for (int32_t n = 0; n < gCurCase->runTimes; ++n) { + prepare(taos, gCurCase->colNum, gCurCase->colList, gCurCase->autoCreate); + + stmt = taos_stmt_init(taos); + if (NULL == stmt) { + printf("taos_stmt_init failed, error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } + + (*gCurCase->runFn)(stmt); + + prepareCheckResult(taos); + + taos_stmt_close(stmt); + } + + printf("* Case %d - %s End *\n", caseIdx, gCurCase->caseDesc); + + caseIdx++; } -} - - - -//void runcase(TAOS *taos, int idx) { -void* runcase(void *par) { - T_par* tpar = (T_par *)par; - TAOS *taos = tpar->taos; - int idx = tpar->idx; - - TAOS_STMT *stmt; - - (void)idx; - - -#if 1 - prepare(taos, 1, 1); - - stmt = taos_stmt_init(taos); - - printf("10t+10records+specifycol start\n"); - stmt_scol_func1(stmt); - printf("10t+10records+specifycol end\n"); - printf("check result start\n"); - check_result(taos, "m0", 1, 10); - check_result(taos, "m1", 1, 10); - check_result(taos, "m2", 1, 10); - check_result(taos, "m3", 1, 10); - check_result(taos, "m4", 1, 10); - check_result(taos, "m5", 1, 10); - check_result(taos, "m6", 1, 10); - check_result(taos, "m7", 1, 10); - check_result(taos, "m8", 1, 10); - check_result(taos, "m9", 1, 10); - printf("check result end\n"); - taos_stmt_close(stmt); -#endif - - -#if 1 - prepare(taos, 1, 1); - - stmt = taos_stmt_init(taos); - - printf("1t+100records+specifycol start\n"); - stmt_scol_func2(stmt); - printf("1t+100records+specifycol end\n"); - printf("check result start\n"); - check_result(taos, "m0", 1, 100); - printf("check result end\n"); - taos_stmt_close(stmt); -#endif - - -#if 1 - prepare(taos, 1, 1); - - stmt = taos_stmt_init(taos); - - printf("300t+10r+bm+specifycol start\n"); - stmt_scol_func3(stmt); - printf("300t+10r+bm+specifycol end\n"); - printf("check result start\n"); - check_result(taos, "m0", 1, 20); - check_result(taos, "m1", 1, 20); - check_result(taos, "m111", 1, 20); - check_result(taos, "m223", 1, 20); - check_result(taos, "m299", 1, 20); - printf("check result end\n"); - taos_stmt_close(stmt); - -#endif - -#if 1 - prepare(taos, 1, 1); - - stmt = taos_stmt_init(taos); - - printf("10t+2r+bm+specifycol start\n"); - stmt_scol_func4(stmt); - printf("10t+2r+bm+specifycol end\n"); - printf("check result start\n"); - check_result(taos, "m0", 1, 20); - check_result(taos, "m1", 1, 20); - check_result(taos, "m2", 1, 20); - check_result(taos, "m3", 1, 20); - check_result(taos, "m4", 1, 20); - check_result(taos, "m5", 1, 20); - check_result(taos, "m6", 1, 20); - check_result(taos, "m7", 1, 20); - check_result(taos, "m8", 1, 20); - check_result(taos, "m9", 1, 20); - printf("check result end\n"); - taos_stmt_close(stmt); - -#endif - - -#if 1 - prepare(taos, 1, 1); - - stmt = taos_stmt_init(taos); - - printf("10t+10records start\n"); - stmt_func1(stmt); - printf("10t+10records end\n"); - printf("check result start\n"); - check_result(taos, "m0", 1, 10); - check_result(taos, "m1", 1, 10); - check_result(taos, "m2", 1, 10); - check_result(taos, "m3", 1, 10); - check_result(taos, "m4", 1, 10); - check_result(taos, "m5", 1, 10); - check_result(taos, "m6", 1, 10); - check_result(taos, "m7", 1, 10); - check_result(taos, "m8", 1, 10); - check_result(taos, "m9", 1, 10); - printf("check result end\n"); - taos_stmt_close(stmt); - -#endif - -#if 1 - prepare(taos, 1, 1); - - stmt = taos_stmt_init(taos); - - printf("10t+[0,1,2...9]records start\n"); - stmt_func2(stmt); - printf("10t+[0,1,2...9]records end\n"); - printf("check result start\n"); - check_result(taos, "m0", 0, 0); - check_result(taos, "m1", 0, 100); - check_result(taos, "m2", 0, 200); - check_result(taos, "m3", 0, 300); - check_result(taos, "m4", 0, 400); - check_result(taos, "m5", 0, 500); - check_result(taos, "m6", 0, 600); - check_result(taos, "m7", 0, 700); - check_result(taos, "m8", 0, 800); - check_result(taos, "m9", 0, 900); - printf("check result end\n"); - taos_stmt_close(stmt); - -#endif - -#if 1 - prepare(taos, 1, 1); - - stmt = taos_stmt_init(taos); - - printf("10t+[0,100,200...900]records start\n"); - stmt_func3(stmt); - printf("10t+[0,100,200...900]records end\n"); - printf("check result start\n"); - check_result(taos, "m0", 0, 0); - check_result(taos, "m1", 0, 100); - check_result(taos, "m2", 0, 200); - check_result(taos, "m3", 0, 300); - check_result(taos, "m4", 0, 400); - check_result(taos, "m5", 0, 500); - check_result(taos, "m6", 0, 600); - check_result(taos, "m7", 0, 700); - check_result(taos, "m8", 0, 800); - check_result(taos, "m9", 0, 900); - printf("check result end\n"); - taos_stmt_close(stmt); - -#endif - - -#if 1 - prepare(taos, 1, 1); - - stmt = taos_stmt_init(taos); - - printf("300t+60r+bm start\n"); - stmt_funcb1(stmt); - printf("300t+60r+bm end\n"); - printf("check result start\n"); - check_result(taos, "m0", 0, 180000); - check_result(taos, "m1", 0, 180000); - check_result(taos, "m111", 0, 180000); - check_result(taos, "m223", 0, 180000); - check_result(taos, "m299", 0, 180000); - 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+autoctb1 start\n"); - stmt_funcb_autoctb1(stmt); - printf("1t+10r+bm+autoctb1 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+autoctb2 start\n"); - stmt_funcb_autoctb2(stmt); - printf("1t+10r+bm+autoctb2 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+autoctb3 start\n"); - stmt_funcb_autoctb3(stmt); - printf("1t+10r+bm+autoctb3 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+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"); - stmt_funcb_autoctb_e1(stmt); - printf("1t+10r+bm+autoctb+e1 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+e2 start\n"); - stmt_funcb_autoctb_e2(stmt); - printf("1t+10r+bm+autoctb+e2 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+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 - prepare(taos, 1, 1); - - stmt = taos_stmt_init(taos); - - printf("1t+18000r+bm start\n"); - stmt_funcb2(stmt); - printf("1t+18000r+bm end\n"); - printf("check result start\n"); - check_result(taos, "m0", 0, 180000); - check_result(taos, "m1", 0, 180000); - check_result(taos, "m111", 0, 180000); - check_result(taos, "m223", 0, 180000); - check_result(taos, "m299", 0, 180000); - printf("check result end\n"); - taos_stmt_close(stmt); - -#endif - -#if 1 - prepare(taos, 1, 1); - - stmt = taos_stmt_init(taos); - - printf("300t+60r+disorder+bm start\n"); - stmt_funcb3(stmt); - printf("300t+60r+disorder+bm end\n"); - printf("check result start\n"); - check_result(taos, "m0", 0, 180000); - check_result(taos, "m1", 0, 180000); - check_result(taos, "m111", 0, 180000); - check_result(taos, "m223", 0, 180000); - check_result(taos, "m299", 0, 180000); - printf("check result end\n"); - taos_stmt_close(stmt); - -#endif - - -#if 1 - prepare(taos, 1, 1); - - stmt = taos_stmt_init(taos); - - printf("300t+60r+samets+bm start\n"); - stmt_funcb4(stmt); - printf("300t+60r+samets+bm end\n"); - printf("check result start\n"); - check_result(taos, "m0", 0, 1); - check_result(taos, "m1", 0, 1); - check_result(taos, "m111", 0, 1); - check_result(taos, "m223", 0, 1); - check_result(taos, "m299", 0, 1); - printf("check result end\n"); - taos_stmt_close(stmt); -#endif - -#if 1 - prepare(taos, 1, 1); - - stmt = taos_stmt_init(taos); - - printf("1t+18000r+nodyntable+bm start\n"); - stmt_funcb5(stmt); - printf("1t+18000r+nodyntable+bm end\n"); - printf("check result start\n"); - check_result(taos, "m0", 0, 180000); - printf("check result end\n"); - taos_stmt_close(stmt); - -#endif - - -#if 1 - prepare(taos, 1, 1); - - stmt = taos_stmt_init(taos); - - printf("300t+60r+bm+sc start\n"); - stmt_funcb_sc1(stmt); - printf("300t+60r+bm+sc end\n"); - printf("check result start\n"); - check_result(taos, "m0", 0, 180000); - check_result(taos, "m1", 0, 180000); - check_result(taos, "m111", 0, 180000); - check_result(taos, "m223", 0, 180000); - check_result(taos, "m299", 0, 180000); - printf("check result end\n"); - taos_stmt_close(stmt); -#endif - -#if 1 - prepare(taos, 1, 1); - - stmt = taos_stmt_init(taos); - - printf("1t+60r+bm+sc start\n"); - stmt_funcb_sc2(stmt); - printf("1t+60r+bm+sc end\n"); - printf("check result start\n"); - check_result(taos, "m0", 0, 180000); - check_result(taos, "m1", 0, 180000); - check_result(taos, "m111", 0, 180000); - check_result(taos, "m223", 0, 180000); - check_result(taos, "m299", 0, 180000); - printf("check result end\n"); - taos_stmt_close(stmt); - -#endif - -#if 1 - prepare(taos, 1, 1); - - stmt = taos_stmt_init(taos); - - printf("10t+[1...10]r+bm+sc start\n"); - stmt_funcb_sc3(stmt); - printf("10t+[1...10]r+bm+sc end\n"); - printf("check result start\n"); - check_result(taos, "m0", 1, 1); - check_result(taos, "m1", 1, 2); - check_result(taos, "m2", 1, 3); - check_result(taos, "m3", 1, 4); - check_result(taos, "m4", 1, 5); - check_result(taos, "m5", 1, 6); - check_result(taos, "m6", 1, 7); - check_result(taos, "m7", 1, 8); - check_result(taos, "m8", 1, 9); - check_result(taos, "m9", 1, 10); - printf("check result end\n"); - taos_stmt_close(stmt); - -#endif - - -#if 1 - prepare(taos, 1, 1); - - stmt = taos_stmt_init(taos); - - printf("1t+60r+bm start\n"); - stmt_funcb_s1(stmt); - printf("1t+60r+bm end\n"); - printf("check result start\n"); - check_result(taos, "m0", 0, 180000); - check_result(taos, "m1", 0, 180000); - check_result(taos, "m111", 0, 180000); - check_result(taos, "m223", 0, 180000); - check_result(taos, "m299", 0, 180000); - printf("check result end\n"); - taos_stmt_close(stmt); - -#endif - - -#if 1 - prepare(taos, 1, 1); - - (void)stmt; - printf("120t+60r+sql start\n"); - sql_perf1(taos); - printf("120t+60r+sql end\n"); - printf("check result start\n"); - check_result(taos, "m0", 0, 180000); - check_result(taos, "m1", 0, 180000); - check_result(taos, "m34", 0, 180000); - check_result(taos, "m67", 0, 180000); - check_result(taos, "m99", 0, 180000); - printf("check result end\n"); -#endif - -#if 1 - prepare(taos, 1, 1); - - (void)stmt; - printf("1t+60r+sql start\n"); - sql_perf_s1(taos); - printf("1t+60r+sql end\n"); - printf("check result start\n"); - check_result(taos, "m0", 0, 180000); - check_result(taos, "m1", 0, 180000); - check_result(taos, "m34", 0, 180000); - check_result(taos, "m67", 0, 180000); - check_result(taos, "m99", 0, 180000); - printf("check result end\n"); -#endif - - -#if 1 - preparem(taos, 0, idx); - - stmt = taos_stmt_init(taos); - - printf("1t+30000r+bm start\n"); - stmt_funcb_ssz1(stmt); - printf("1t+30000r+bm end\n"); - printf("check result start\n"); - check_result(taos, "m0", 0, 300000); - check_result(taos, "m1", 0, 300000); - check_result(taos, "m111", 0, 300000); - check_result(taos, "m223", 0, 300000); - check_result(taos, "m299", 0, 300000); - printf("check result end\n"); - taos_stmt_close(stmt); - -#endif - printf("test end\n"); return NULL; } +void runAll(TAOS *taos) { + printf("Normal Test\n"); + runcase(taos); + + printf("Null Test\n"); + gCaseCtrl.bindNullNum = 1; + runcase(taos); + gCaseCtrl.bindNullNum = 0; + + printf("Bind Row Test\n"); + gCaseCtrl.bindRowNum = 1; + runcase(taos); + gCaseCtrl.bindRowNum = 0; + + printf("Row Num Test\n"); + gCaseCtrl.rowNum = 1000; + gCaseCtrl.printRes = false; + runcase(taos); + gCaseCtrl.rowNum = 0; + gCaseCtrl.printRes = true; + + printf("Runtimes Test\n"); + gCaseCtrl.runTimes = 2; + runcase(taos); + gCaseCtrl.runTimes = 0; + + printf("Check Param Test\n"); + gCaseCtrl.checkParamNum = true; + runcase(taos); + gCaseCtrl.checkParamNum = false; + + printf("Bind Col Num Test\n"); + gCaseCtrl.bindColNum = 6; + runcase(taos); + gCaseCtrl.bindColNum = 0; + + printf("Bind Col Type Test\n"); + gCaseCtrl.bindColTypeNum = tListLen(bindColTypeList); + gCaseCtrl.bindColTypeList = bindColTypeList; + runcase(taos); +} + int main(int argc, char *argv[]) { - TAOS *taos[4]; + TAOS *taos = NULL; + srand(time(NULL)); + // connect to server if (argc < 2) { printf("please input server ip \n"); return 0; } - taos[0] = taos_connect(argv[1], "root", "taosdata", NULL, 0); + taos = taos_connect(argv[1], "root", "taosdata", NULL, 0); if (taos == NULL) { printf("failed to connect to db, reason:%s\n", taos_errstr(taos)); exit(1); } - taos[1] = taos_connect(argv[1], "root", "taosdata", NULL, 0); - if (taos == NULL) { - printf("failed to connect to db, reason:%s\n", taos_errstr(taos)); - exit(1); - } + runAll(taos); - taos[2] = taos_connect(argv[1], "root", "taosdata", NULL, 0); - if (taos == NULL) { - printf("failed to connect to db, reason:%s\n", taos_errstr(taos)); - exit(1); - } - - taos[3] = taos_connect(argv[1], "root", "taosdata", NULL, 0); - if (taos == NULL) { - printf("failed to connect to db, reason:%s\n", taos_errstr(taos)); - exit(1); - } - - TdThread *pThreadList = (TdThread *) taosMemoryCalloc(sizeof(TdThread), 4); - - TdThreadAttr thattr; - taosThreadAttrInit(&thattr); - taosThreadAttrSetDetachState(&thattr, PTHREAD_CREATE_JOINABLE); - T_par par[4]; - - par[0].taos = taos[0]; - par[0].idx = 0; - par[1].taos = taos[1]; - par[1].idx = 1; - par[2].taos = taos[2]; - par[2].idx = 2; - par[3].taos = taos[3]; - par[3].idx = 3; - - taosThreadCreate(&(pThreadList[0]), &thattr, runcase, (void *)&par[0]); - //taosThreadCreate(&(pThreadList[1]), &thattr, runcase, (void *)&par[1]); - //taosThreadCreate(&(pThreadList[2]), &thattr, runcase, (void *)&par[2]); - //taosThreadCreate(&(pThreadList[3]), &thattr, runcase, (void *)&par[3]); - - while(1) { - taosSsleep(1); - } return 0; } diff --git a/tests/script/api/makefile b/tests/script/api/makefile index 92d0a89b0f..46a172cc3a 100644 --- a/tests/script/api/makefile +++ b/tests/script/api/makefile @@ -4,18 +4,14 @@ ROOT=./ TARGET=exe LFLAGS = '-Wl,-rpath,/usr/local/taos/driver/' -ltaos -lpthread -lm -lrt -CFLAGS = -O0 -g -Wall -Wno-deprecated -fPIC -Wno-unused-result -Wconversion \ +CFLAGS = -O0 -g -Wno-deprecated -fPIC -Wno-unused-result -Wconversion \ -Wno-char-subscripts -D_REENTRANT -Wno-format -D_REENTRANT -DLINUX \ - -Wno-unused-function -D_M_X64 -I/usr/local/taos/include -std=gnu99 \ - -fsanitize=address + -Wno-unused-function -D_M_X64 -I/usr/local/taos/include -std=gnu99 -Wno-sign-conversion all: $(TARGET) exe: gcc $(CFLAGS) ./batchprepare.c -o $(ROOT)batchprepare $(LFLAGS) - gcc $(CFLAGS) ./stmtBatchTest.c -o $(ROOT)stmtBatchTest $(LFLAGS) - gcc $(CFLAGS) ./stmtTest.c -o $(ROOT)stmtTest $(LFLAGS) - gcc $(CFLAGS) ./stmt_function.c -o $(ROOT)stmt_function $(LFLAGS) clean: rm $(ROOT)batchprepare