diff --git a/src/client/inc/tscUtil.h b/src/client/inc/tscUtil.h index 8d82c65cee5cb26c3a4a37e6bbe6076dae28aaa5..83261ec561e0e7161fca658fbd54d0b8197bbb9a 100644 --- a/src/client/inc/tscUtil.h +++ b/src/client/inc/tscUtil.h @@ -110,7 +110,7 @@ void* tscDestroyBlockArrayList(SArray* pDataBlockList); void* tscDestroyBlockHashTable(SHashObj* pBlockHashTable); int32_t tscCopyDataBlockToPayload(SSqlObj* pSql, STableDataBlocks* pDataBlock); -int32_t tscMergeTableDataBlocks(SSqlObj* pSql); +int32_t tscMergeTableDataBlocks(SSqlObj* pSql, bool freeBlockMap); int32_t tscGetDataBlockFromList(SHashObj* pHashList, int64_t id, int32_t size, int32_t startOffset, int32_t rowSize, const char* tableId, STableMeta* pTableMeta, STableDataBlocks** dataBlocks, SArray* pBlockList); diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h index 901ae0359e66a5aba438599110027efd263c87ae..652e5bdd47b5bfa3adfdb8b8f58e94399c4de810 100644 --- a/src/client/inc/tsclient.h +++ b/src/client/inc/tsclient.h @@ -235,7 +235,7 @@ typedef struct { int32_t numOfTablesInSubmit; }; - uint32_t insertType; + uint32_t insertType; // TODO remove it int32_t clauseIndex; // index of multiple subclause query char * curSql; // current sql, resume position of sql after parsing paused diff --git a/src/client/src/tscParseInsert.c b/src/client/src/tscParseInsert.c index 7151c33393577e877dd011b27df44dfc69be089d..0c7af5d4e3d8b61445b25c94cf5eda021ceba3e9 100644 --- a/src/client/src/tscParseInsert.c +++ b/src/client/src/tscParseInsert.c @@ -1281,7 +1281,7 @@ int tsParseInsertSql(SSqlObj *pSql) { } if (taosHashGetSize(pCmd->pTableBlockHashList) > 0) { // merge according to vgId - if ((code = tscMergeTableDataBlocks(pSql)) != TSDB_CODE_SUCCESS) { + if ((code = tscMergeTableDataBlocks(pSql, true)) != TSDB_CODE_SUCCESS) { goto _clean; } } @@ -1336,15 +1336,6 @@ int tsParseSql(SSqlObj *pSql, bool initial) { } if (tscIsInsertData(pSql->sqlstr)) { - /* - * Set the fp before parse the sql string, in case of getTableMeta failed, in which - * the error handle callback function can rightfully restore the user-defined callback function (fp). - */ - if (initial && (pSql->cmd.insertType != TSDB_QUERY_TYPE_STMT_INSERT)) { - pSql->fetchFp = pSql->fp; - pSql->fp = (void(*)())tscHandleMultivnodeInsert; - } - if (initial && ((ret = tsInsertInitialCheck(pSql)) != TSDB_CODE_SUCCESS)) { return ret; } @@ -1398,7 +1389,7 @@ static int doPackSendDataBlock(SSqlObj *pSql, int32_t numOfRows, STableDataBlock return tscInvalidSQLErrMsg(pCmd->payload, "too many rows in sql, total number of rows should be less than 32767", NULL); } - if ((code = tscMergeTableDataBlocks(pSql)) != TSDB_CODE_SUCCESS) { + if ((code = tscMergeTableDataBlocks(pSql, true)) != TSDB_CODE_SUCCESS) { return code; } diff --git a/src/client/src/tscPrepare.c b/src/client/src/tscPrepare.c index 981b354c8a964272058397e8e4b019ca49fe7ac3..7c69c16b049e45a763118ccd5a43e3ab3337ed46 100644 --- a/src/client/src/tscPrepare.c +++ b/src/client/src/tscPrepare.c @@ -255,7 +255,6 @@ static char* normalStmtBuildSql(STscStmt* stmt) { //////////////////////////////////////////////////////////////////////////////// // functions for insertion statement preparation - static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) { if (bind->is_null != NULL && *(bind->is_null)) { setNull(data + param->offset, param->type, param->bytes); @@ -697,61 +696,44 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) { static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) { SSqlCmd* pCmd = &stmt->pSql->cmd; - int32_t alloced = 1, binded = 0; - if (pCmd->batchSize > 0) { - alloced = (pCmd->batchSize + 1) / 2; - binded = pCmd->batchSize / 2; + STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0, 0); + + STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; + if (pCmd->pTableBlockHashList == NULL) { + pCmd->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false); } - size_t size = taosArrayGetSize(pCmd->pDataBlocks); - for (int32_t i = 0; i < size; ++i) { - STableDataBlocks* pBlock = taosArrayGetP(pCmd->pDataBlocks, i); - uint32_t totalDataSize = pBlock->size - sizeof(SSubmitBlk); - uint32_t dataSize = totalDataSize / alloced; - assert(dataSize * alloced == totalDataSize); - - if (alloced == binded) { - totalDataSize += dataSize + sizeof(SSubmitBlk); - if (totalDataSize > pBlock->nAllocSize) { - const double factor = 1.5; - void* tmp = realloc(pBlock->pData, (uint32_t)(totalDataSize * factor)); - if (tmp == NULL) { - return TSDB_CODE_TSC_OUT_OF_MEMORY; - } - pBlock->pData = (char*)tmp; - pBlock->nAllocSize = (uint32_t)(totalDataSize * factor); - } - } + STableDataBlocks* pBlock = NULL; - char* data = pBlock->pData + sizeof(SSubmitBlk) + dataSize * binded; - for (uint32_t j = 0; j < pBlock->numOfParams; ++j) { - SParamInfo* param = pBlock->params + j; - int code = doBindParam(data, param, bind + param->idx); - if (code != TSDB_CODE_SUCCESS) { - tscDebug("param %d: type mismatch or invalid", param->idx); - return code; - } - } + int32_t ret = + tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk), + pTableMeta->tableInfo.rowSize, pTableMetaInfo->name, pTableMeta, &pBlock, NULL); + if (ret != 0) { + // todo handle error } - // actual work of all data blocks is done, update block size and numOfRows. - // note we don't do this block by block during the binding process, because - // we cannot recover if something goes wrong. - pCmd->batchSize = binded * 2 + 1; + uint32_t totalDataSize = sizeof(SSubmitBlk) + pCmd->batchSize * pBlock->rowSize; + if (totalDataSize > pBlock->nAllocSize) { + const double factor = 1.5; - if (binded < alloced) { - return TSDB_CODE_SUCCESS; - } + void* tmp = realloc(pBlock->pData, (uint32_t)(totalDataSize * factor)); + if (tmp == NULL) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } - size_t total = taosArrayGetSize(pCmd->pDataBlocks); - for (int32_t i = 0; i < total; ++i) { - STableDataBlocks* pBlock = taosArrayGetP(pCmd->pDataBlocks, i); + pBlock->pData = (char*)tmp; + pBlock->nAllocSize = (uint32_t)(totalDataSize * factor); + } - uint32_t totalDataSize = pBlock->size - sizeof(SSubmitBlk); - pBlock->size += totalDataSize / alloced; + char* data = pBlock->pData + sizeof(SSubmitBlk) + pBlock->rowSize * pCmd->batchSize; + for (uint32_t j = 0; j < pBlock->numOfParams; ++j) { + SParamInfo* param = &pBlock->params[j]; - SSubmitBlk* pSubmit = (SSubmitBlk*)pBlock->pData; - pSubmit->numOfRows += pSubmit->numOfRows / alloced; + int code = doBindParam(data, param, &bind[param->idx]); + if (code != TSDB_CODE_SUCCESS) { + tscDebug("param %d: type mismatch or invalid", param->idx); + return code; + } } return TSDB_CODE_SUCCESS; @@ -759,9 +741,7 @@ static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) { static int insertStmtAddBatch(STscStmt* stmt) { SSqlCmd* pCmd = &stmt->pSql->cmd; - if ((pCmd->batchSize % 2) == 1) { - ++pCmd->batchSize; - } + ++pCmd->batchSize; return TSDB_CODE_SUCCESS; } @@ -793,50 +773,66 @@ static int insertStmtExecute(STscStmt* stmt) { if (pCmd->batchSize == 0) { return TSDB_CODE_TSC_INVALID_VALUE; } - if ((pCmd->batchSize % 2) == 1) { - ++pCmd->batchSize; - } - STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); assert(pCmd->numOfClause == 1); + if (taosHashGetSize(pCmd->pTableBlockHashList) == 0) { + return TSDB_CODE_SUCCESS; + } - if (taosHashGetSize(pCmd->pTableBlockHashList) > 0) { - // merge according to vgid - int code = tscMergeTableDataBlocks(stmt->pSql); - if (code != TSDB_CODE_SUCCESS) { - return code; - } - - STableDataBlocks *pDataBlock = taosArrayGetP(pCmd->pDataBlocks, 0); - code = tscCopyDataBlockToPayload(stmt->pSql, pDataBlock); - if (code != TSDB_CODE_SUCCESS) { - return code; - } + STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0, 0); - // set the next sent data vnode index in data block arraylist - pTableMetaInfo->vgroupIndex = 1; - } else { - pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks); + STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; + if (pCmd->pTableBlockHashList == NULL) { + pCmd->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false); } - SSqlObj *pSql = stmt->pSql; - SSqlRes *pRes = &pSql->res; - pRes->numOfRows = 0; - pRes->numOfTotal = 0; - pRes->numOfClauseTotal = 0; + STableDataBlocks* pBlock = NULL; + + int32_t ret = + tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk), + pTableMeta->tableInfo.rowSize, pTableMetaInfo->name, pTableMeta, &pBlock, NULL); + assert(ret == 0); + pBlock->size = sizeof(SSubmitBlk) + pCmd->batchSize * pBlock->rowSize; + SSubmitBlk* pBlk = (SSubmitBlk*) pBlock->pData; + pBlk->numOfRows = pCmd->batchSize; + pBlk->dataLen = 0; + pBlk->uid = pTableMeta->id.uid; + pBlk->tid = pTableMeta->id.tid; + + int code = tscMergeTableDataBlocks(stmt->pSql, false); + if (code != TSDB_CODE_SUCCESS) { + return code; + } - pRes->qhandle = 0; + STableDataBlocks* pDataBlock = taosArrayGetP(pCmd->pDataBlocks, 0); + code = tscCopyDataBlockToPayload(stmt->pSql, pDataBlock); + if (code != TSDB_CODE_SUCCESS) { + return code; + } - pSql->cmd.insertType = 0; - pSql->fetchFp = waitForQueryRsp; - pSql->fp = (void(*)())tscHandleMultivnodeInsert; + SSqlObj* pSql = stmt->pSql; + SSqlRes* pRes = &pSql->res; + pRes->numOfRows = 0; + pRes->numOfTotal = 0; - tscDoQuery(pSql); + tscProcessSql(pSql); // wait for the callback function to post the semaphore tsem_wait(&pSql->rspSem); - return pSql->res.code; + // data block reset + pCmd->batchSize = 0; + for(int32_t i = 0; i < pCmd->numOfTables; ++i) { + if (pCmd->pTableNameList && pCmd->pTableNameList[i]) { + tfree(pCmd->pTableNameList[i]); + } + } + + pCmd->numOfTables = 0; + tfree(pCmd->pTableNameList); + pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks); + + return pSql->res.code; } //////////////////////////////////////////////////////////////////////////////// @@ -867,11 +863,11 @@ TAOS_STMT* taos_stmt_init(TAOS* taos) { } tsem_init(&pSql->rspSem, 0, 0); - pSql->signature = pSql; - pSql->pTscObj = pObj; - pSql->maxRetry = TSDB_MAX_REPLICA; + pSql->signature = pSql; + pSql->pTscObj = pObj; + pSql->maxRetry = TSDB_MAX_REPLICA; + pStmt->pSql = pSql; - pStmt->pSql = pSql; return pStmt; } @@ -890,7 +886,9 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) { SSqlRes *pRes = &pSql->res; pSql->param = (void*) pSql; pSql->fp = waitForQueryRsp; - pSql->cmd.insertType = TSDB_QUERY_TYPE_STMT_INSERT; + pSql->fetchFp = waitForQueryRsp; + + pCmd->insertType = TSDB_QUERY_TYPE_STMT_INSERT; if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE)) { tscError("%p failed to malloc payload buffer", pSql); @@ -956,8 +954,9 @@ int taos_stmt_bind_param(TAOS_STMT* stmt, TAOS_BIND* bind) { STscStmt* pStmt = (STscStmt*)stmt; if (pStmt->isInsert) { return insertStmtBindParam(pStmt, bind); + } else { + return normalStmtBindParam(pStmt, bind); } - return normalStmtBindParam(pStmt, bind); } int taos_stmt_add_batch(TAOS_STMT* stmt) { @@ -981,7 +980,7 @@ int taos_stmt_execute(TAOS_STMT* stmt) { STscStmt* pStmt = (STscStmt*)stmt; if (pStmt->isInsert) { ret = insertStmtExecute(pStmt); - } else { + } else { // normal stmt query char* sql = normalStmtBuildSql(pStmt); if (sql == NULL) { ret = TSDB_CODE_TSC_OUT_OF_MEMORY; @@ -995,6 +994,7 @@ int taos_stmt_execute(TAOS_STMT* stmt) { free(sql); } } + return ret; } diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 62791e750a35a98df9b132809165f0aea6b18f7c..537e81413fdd74f54d74c1bb887f28498b0b7379 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -483,9 +483,9 @@ int tscProcessSql(SSqlObj *pSql) { pSql->res.code = TSDB_CODE_TSC_APP_ERROR; return pSql->res.code; } - } else if (pCmd->command < TSDB_SQL_LOCAL) { + } else if (pCmd->command >= TSDB_SQL_LOCAL) { //pSql->epSet = tscMgmtEpSet; - } else { // local handler +// } else { // local handler return (*tscProcessMsgRsp[pCmd->command])(pSql); } diff --git a/src/client/src/tscSql.c b/src/client/src/tscSql.c index 3f25d7a14d90a4d8aac6ca33b53d34f721b9847b..a8c872a2a3bf46e337132e99e6c6428e12f64d04 100644 --- a/src/client/src/tscSql.c +++ b/src/client/src/tscSql.c @@ -781,6 +781,7 @@ bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col) { int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) { int len = 0; + for (int i = 0; i < num_fields; ++i) { if (i > 0) { str[len++] = ' '; @@ -838,13 +839,15 @@ int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) case TSDB_DATA_TYPE_BINARY: case TSDB_DATA_TYPE_NCHAR: { - size_t xlen = 0; - for (xlen = 0; xlen < fields[i].bytes - VARSTR_HEADER_SIZE; xlen++) { - char c = ((char *)row[i])[xlen]; - if (c == 0) break; - str[len++] = c; + int32_t charLen = varDataLen(row[i] - VARSTR_HEADER_SIZE); + if (fields[i].type == TSDB_DATA_TYPE_BINARY) { + assert(charLen <= fields[i].bytes); + } else { + assert(charLen <= fields[i].bytes * TSDB_NCHAR_SIZE); } - str[len] = 0; + + memcpy(str + len, row[i], charLen); + len += charLen; } break; case TSDB_DATA_TYPE_TIMESTAMP: diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index 9a8aa917e70f978c2d5c4f0038223479eb10bbd3..5073f55ce7b668fd86ae1056a44de118fbdc0543 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -603,6 +603,7 @@ int32_t tscCopyDataBlockToPayload(SSqlObj* pSql, STableDataBlocks* pDataBlock) { assert(pCmd->numOfClause == 1); STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); + // todo refactor // set the correct table meta object, the table meta has been locked in pDataBlocks, so it must be in the cache if (pTableMetaInfo->pTableMeta != pDataBlock->pTableMeta) { tstrncpy(pTableMetaInfo->name, pDataBlock->tableName, sizeof(pTableMetaInfo->name)); @@ -689,7 +690,6 @@ int32_t tscCreateDataBlock(size_t initialSize, int32_t rowSize, int32_t startOff int32_t tscGetDataBlockFromList(SHashObj* pHashList, int64_t id, int32_t size, int32_t startOffset, int32_t rowSize, const char* tableId, STableMeta* pTableMeta, STableDataBlocks** dataBlocks, SArray* pBlockList) { *dataBlocks = NULL; - STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pHashList, (const char*)&id, sizeof(id)); if (t1 != NULL) { *dataBlocks = *t1; @@ -785,9 +785,13 @@ static int32_t getRowExpandSize(STableMeta* pTableMeta) { return result; } -static void extractTableNameList(SSqlCmd* pCmd) { +static void extractTableNameList(SSqlCmd* pCmd, bool freeBlockMap) { pCmd->numOfTables = (int32_t) taosHashGetSize(pCmd->pTableBlockHashList); - pCmd->pTableNameList = calloc(pCmd->numOfTables, POINTER_BYTES); + if (pCmd->pTableNameList == NULL) { + pCmd->pTableNameList = calloc(pCmd->numOfTables, POINTER_BYTES); + } else { + memset(pCmd->pTableNameList, 0, pCmd->numOfTables * POINTER_BYTES); + } STableDataBlocks **p1 = taosHashIterate(pCmd->pTableBlockHashList, NULL); int32_t i = 0; @@ -797,10 +801,12 @@ static void extractTableNameList(SSqlCmd* pCmd) { p1 = taosHashIterate(pCmd->pTableBlockHashList, p1); } - pCmd->pTableBlockHashList = tscDestroyBlockHashTable(pCmd->pTableBlockHashList); + if (freeBlockMap) { + pCmd->pTableBlockHashList = tscDestroyBlockHashTable(pCmd->pTableBlockHashList); + } } -int32_t tscMergeTableDataBlocks(SSqlObj* pSql) { +int32_t tscMergeTableDataBlocks(SSqlObj* pSql, bool freeBlockMap) { const int INSERT_HEAD_SIZE = sizeof(SMsgDesc) + sizeof(SSubmitMsg); SSqlCmd* pCmd = &pSql->cmd; @@ -880,7 +886,7 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql) { pOneTableBlock = *p; } - extractTableNameList(pCmd); + extractTableNameList(pCmd, freeBlockMap); // free the table data blocks; pCmd->pDataBlocks = pVnodeDataBlockList; @@ -2196,7 +2202,7 @@ void tscDoQuery(SSqlObj* pSql) { SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); uint16_t type = pQueryInfo->type; - if (pSql->fp == (void(*)())tscHandleMultivnodeInsert) { // multi-vnodes insertion + if (TSDB_QUERY_HAS_TYPE(type, TSDB_QUERY_TYPE_INSERT)) { // multi-vnodes insertion tscHandleMultivnodeInsert(pSql); return; } diff --git a/src/client/tests/resultFieldTest.cpp b/src/client/tests/cliTest.cpp similarity index 58% rename from src/client/tests/resultFieldTest.cpp rename to src/client/tests/cliTest.cpp index c917f0ebafa02480c372e8d7bb611588bad8e54a..5cfe61d92a1ea36cc41585e314e907a10ea9ff59 100644 --- a/src/client/tests/resultFieldTest.cpp +++ b/src/client/tests/cliTest.cpp @@ -2,15 +2,117 @@ #include #include "taos.h" +#include "tglobal.h" namespace { static int64_t start_ts = 1433955661000; + +void stmtInsertTest() { + TAOS* conn = taos_connect("ubuntu", "root", "taosdata", 0, 0); + if (conn == NULL) { + printf("Failed to connect to DB, reason:%s", taos_errstr(conn)); + exit(-1); + } + + TAOS_RES* res = taos_query(conn, "use test"); + taos_free_result(res); + + const char* sql = "insert into t1 values(?, ?, ?, ?)"; + TAOS_STMT* stmt = taos_stmt_init(conn); + + int32_t ret = taos_stmt_prepare(stmt, sql, 0); + ASSERT_EQ(ret, 0); + + //ts timestamp, k int, a binary(11), b nchar(4) + struct { + int64_t ts; + int k; + char* a; + char* b; + } v = {0}; + + TAOS_BIND params[4]; + 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_INT; + params[1].buffer_length = sizeof(v.k); + params[1].buffer = &v.k; + params[1].length = ¶ms[1].buffer_length; + params[1].is_null = NULL; + + params[2].buffer_type = TSDB_DATA_TYPE_BINARY; + params[2].buffer_length = sizeof(v.a); + params[2].buffer = &v.a; + params[2].is_null = NULL; + + params[3].buffer_type = TSDB_DATA_TYPE_NCHAR; + params[3].buffer_length = sizeof(v.b); + params[3].buffer = &v.b; + params[3].is_null = NULL; + + v.ts = start_ts + 20; + v.k = 123; + + char* str = "abc"; + uintptr_t len = strlen(str); + + v.a = str; + params[2].length = &len; + params[2].buffer_length = len; + params[2].buffer = str; + + char* nstr = "999"; + uintptr_t len1 = strlen(nstr); + + v.b = nstr; + params[3].buffer_length = len1; + params[3].buffer = nstr; + params[3].length = &len1; + + taos_stmt_bind_param(stmt, params); + taos_stmt_add_batch(stmt); + + if (taos_stmt_execute(stmt) != 0) { + printf("\033[31mfailed to execute insert statement.\033[0m\n"); + return; + } + + v.ts = start_ts + 30; + v.k = 911; + + str = "92"; + len = strlen(str); + + params[2].length = &len; + params[2].buffer_length = len; + params[2].buffer = str; + + nstr = "1920"; + len1 = strlen(nstr); + + params[3].buffer_length = len1; + params[3].buffer = nstr; + params[3].length = &len1; + + taos_stmt_bind_param(stmt, params); + taos_stmt_add_batch(stmt); + + ret = taos_stmt_execute(stmt); + if (ret != 0) { + printf("%p\n", ret); + printf("\033[31mfailed to execute insert statement.\033[0m\n"); + return; + } + + taos_stmt_close(stmt); + taos_close(conn); } -/* test parse time function */ -TEST(testCase, result_field_test) { - taos_options(TSDB_OPTION_CONFIGDIR, "~/first/cfg"); - taos_init(); +void validateResultFields() { TAOS* conn = taos_connect("ubuntu", "root", "taosdata", 0, 0); if (conn == NULL) { printf("Failed to connect to DB, reason:%s", taos_errstr(conn)); @@ -134,5 +236,31 @@ TEST(testCase, result_field_test) { ASSERT_STREQ(fields[6].name, "first(ts)"); taos_free_result(res); + + // update the configure parameter, the result field name will be changed + tsKeepOriginalColumnName = 1; + res = taos_query(conn, "select first(ts, a, k, k, b, b, ts) from t1"); + ASSERT_EQ(taos_num_fields(res), 7); + + fields = taos_fetch_fields(res); + ASSERT_EQ(fields[0].bytes, 8); + ASSERT_EQ(fields[0].type, TSDB_DATA_TYPE_TIMESTAMP); + ASSERT_STREQ(fields[0].name, "ts"); + + ASSERT_EQ(fields[2].bytes, 4); + ASSERT_EQ(fields[2].type, TSDB_DATA_TYPE_INT); + ASSERT_STREQ(fields[2].name, "k"); + + taos_free_result(res); + taos_close(conn); } +} +/* test parse time function */ +TEST(testCase, result_field_test) { + taos_options(TSDB_OPTION_CONFIGDIR, "~/first/cfg"); + taos_init(); + + validateResultFields(); + stmtInsertTest(); +} diff --git a/tests/examples/c/demo.c b/tests/examples/c/demo.c index 54e81d33b9c7a948dc75996828bc07634d4664ae..9cbcee45a24409f8fdacef79085eb4f9e7e4435f 100644 --- a/tests/examples/c/demo.c +++ b/tests/examples/c/demo.c @@ -93,15 +93,15 @@ void Test(TAOS *taos, char *qstr, int index) { // if (taos_query(taos, qstr)) { // printf("insert row: %i, reason:%s\n", i, taos_errstr(taos)); // } - TAOS_RES *result = taos_query(taos, qstr); - if (result) { + TAOS_RES *result1 = taos_query(taos, qstr); + if (result1) { printf("insert row: %i\n", i); } else { printf("failed to insert row: %i, reason:%s\n", i, "null result"/*taos_errstr(result)*/); - taos_free_result(result); + taos_free_result(result1); exit(1); } - taos_free_result(result); + taos_free_result(result1); } printf("success to insert rows, total %d rows\n", i); diff --git a/tests/script/general/parser/columnValue_unsign.sim b/tests/script/general/parser/columnValue_unsign.sim index 895b13961ef729544a9ac14c85e4e37e6f723423..6e9a37fdb60f3ddbb847a092c4a7745316c68b01 100644 --- a/tests/script/general/parser/columnValue_unsign.sim +++ b/tests/script/general/parser/columnValue_unsign.sim @@ -111,7 +111,8 @@ if $rows != 1 then return -1 endi -if $data00 != 6.000000000 then +if $data00 != NULL then + print expect NULL, actual:$data00 return -1 endi @@ -167,7 +168,7 @@ if $data01 != 4 then return -1 endi -// todo insert more rows and chec it +## todo insert more rows and chec it sql select first(a),count(b),last(c),sum(b),spread(d),avg(c),min(b),max(a),stddev(a) from mt_unsigned_1; if $rows != 1 then return -1