diff --git a/src/client/src/tscAsync.c b/src/client/src/tscAsync.c index 9a85fbf8f65193d6239c6b58bf0c6577d77a6250..34ecc25c59507f836078164130440f89627e86e7 100644 --- a/src/client/src/tscAsync.c +++ b/src/client/src/tscAsync.c @@ -347,8 +347,8 @@ void tscProcessAsyncRes(SSchedMsg *pMsg) { (*pSql->fp)(pSql->param, taosres, code); if (shouldFree) { - tscFreeSqlObj(pSql); tscTrace("%p Async sql is automatically freed in async res", pSql); + tscFreeSqlObj(pSql); } } diff --git a/src/client/src/tscProfile.c b/src/client/src/tscProfile.c index a7a774b3a8ce71a608d15ec9a71f931a7a59a06a..ab214384ad816950db30a7708e7bb332a9cb21b6 100644 --- a/src/client/src/tscProfile.c +++ b/src/client/src/tscProfile.c @@ -292,7 +292,7 @@ void tscKillConnection(STscObj *pObj) { pthread_mutex_unlock(&pObj->mutex); - taos_close(pObj); - tscTrace("connection:%p is killed", pObj); + + taos_close(pObj); } diff --git a/src/client/src/tscSecondaryMerge.c b/src/client/src/tscSecondaryMerge.c index 51a59005f001f7555a3ffc2e5c7e15ed111af988..d87ee4b81bfe8091ac3a41d23906083a03589684 100644 --- a/src/client/src/tscSecondaryMerge.c +++ b/src/client/src/tscSecondaryMerge.c @@ -233,6 +233,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd } assert(idx >= pReducer->numOfBuffer); if (idx == 0) { + free(pReducer); return; } diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index d2091e45acff35a0e14841021fe1f673479a0d6d..94fba04b3e613ac380ff2d3ad1e62afbe24c1ee2 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -400,7 +400,7 @@ void *tscProcessMsgFromServer(char *msg, void *ahandle, void *thandle) { pObj, pObj->signature); taosAddConnIntoCache(tscConnCache, pSql->thandle, pSql->ip, pSql->vnode, pObj->user); tscFreeSqlObj(pSql); - return ahandle; + return NULL; } SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0); @@ -600,8 +600,8 @@ void *tscProcessMsgFromServer(char *msg, void *ahandle, void *thandle) { taos_close(pObj); tscTrace("%p Async sql close failed connection", pSql); } else { - tscFreeSqlObj(pSql); tscTrace("%p Async sql is automatically freed", pSql); + tscFreeSqlObj(pSql); } } } diff --git a/src/client/src/tscSql.c b/src/client/src/tscSql.c index 99bc9632deeff8bf98c8090e0fac7604104f84c9..a0089379a9c71434ed1a7aa7547724145241b89f 100644 --- a/src/client/src/tscSql.c +++ b/src/client/src/tscSql.c @@ -796,8 +796,8 @@ void taos_free_result_imp(TAOS_RES *res, int keepCmd) { tscTrace("%p qhandle is null, abort free, fp:%p", pSql, pSql->fp); if (pSql->fp != NULL) { pSql->thandle = NULL; - tscFreeSqlObj(pSql); tscTrace("%p Async SqlObj is freed by app", pSql); + tscFreeSqlObj(pSql); } else if (keepCmd) { tscFreeSqlResult(pSql); } else { diff --git a/src/client/src/tscStream.c b/src/client/src/tscStream.c index 8dc8ad49b5b134c9cc3f5bd3987ae61c5273f33c..94fb35d52231746da27d21a755cad823c806321f 100644 --- a/src/client/src/tscStream.c +++ b/src/client/src/tscStream.c @@ -582,10 +582,10 @@ void taos_close_stream(TAOS_STREAM *handle) { tscRemoveFromStreamList(pStream, pSql); taosTmrStopA(&(pStream->pTimer)); + tscTrace("%p stream:%p is closed", pSql, pStream); tscFreeSqlObj(pSql); pStream->pSql = NULL; - tscTrace("%p stream:%p is closed", pSql, pStream); tfree(pStream); } } diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index 1073eec6ea7de122d311620f058abfcf97f09bdb..dbd3f464eaf457b9002bb5cd6af6bfd88e5cfbc1 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -87,6 +87,7 @@ void tscGetMetricMetaCacheKey(SQueryInfo* pQueryInfo, char* str, uint64_t uid) { MD5Update(&ctx, (uint8_t*)tmp, keyLen); char* pStr = base64_encode(ctx.digest, tListLen(ctx.digest)); strcpy(str, pStr); + free(pStr); } free(tmp); diff --git a/src/kit/shell/src/shellImport.c b/src/kit/shell/src/shellImport.c index dd04f935e7a30f6a8775b831c3ec726855f520f4..0d0e7e9855ff19dcc885df3730ad90cb1a15e80e 100644 --- a/src/kit/shell/src/shellImport.c +++ b/src/kit/shell/src/shellImport.c @@ -141,6 +141,7 @@ static void shellSourceFile(TAOS *con, char *fptr) { if (wordexp(fptr, &full_path, 0) != 0) { fprintf(stderr, "ERROR: illegal file name\n"); + free(cmd); return; } @@ -166,6 +167,7 @@ static void shellSourceFile(TAOS *con, char *fptr) { if (f == NULL) { fprintf(stderr, "ERROR: failed to open file %s\n", fname); wordfree(&full_path); + free(cmd); return; } diff --git a/src/modules/http/src/httpAuth.c b/src/modules/http/src/httpAuth.c index 4503accc0acdc74f1035b91bb2b85a344eb143fe..1ba11aba09789433b476c34864906fa13891dafc 100644 --- a/src/modules/http/src/httpAuth.c +++ b/src/modules/http/src/httpAuth.c @@ -75,6 +75,8 @@ bool httpParseTaosdAuthToken(HttpContext *pContext, char *token, int len) { unsigned char *base64 = base64_decode(token, len, &outlen); if (base64 == NULL || outlen == 0) { httpError("context:%p, fd:%d, ip:%s, taosd token:%s parsed error", pContext, pContext->fd, pContext->ipstr, token); + if (base64) + free(base64); return false; } if (outlen != (TSDB_USER_LEN + TSDB_PASSWORD_LEN)) { diff --git a/src/rpc/src/ttcpclient.c b/src/rpc/src/ttcpclient.c index 3d39be92fe4fd1c4476e35d56b88ed2fa5c9e474..297e916fbbdef614f0db3c5fa9cab41e01f6a1d7 100644 --- a/src/rpc/src/ttcpclient.c +++ b/src/rpc/src/ttcpclient.c @@ -206,17 +206,20 @@ void *taosInitTcpClient(char *ip, uint16_t port, char *label, int num, void *fp, if (pthread_mutex_init(&(pTcp->mutex), NULL) < 0) { tError("%s failed to init TCP mutex, reason:%s", label, strerror(errno)); + free(pTcp); return NULL; } if (pthread_cond_init(&(pTcp->fdReady), NULL) != 0) { tError("%s init TCP condition variable failed, reason:%s\n", label, strerror(errno)); + free(pTcp); return NULL; } pTcp->pollFd = epoll_create(10); // size does not matter if (pTcp->pollFd < 0) { tError("%s failed to create TCP epoll", label); + free(pTcp); return NULL; } @@ -226,6 +229,7 @@ void *taosInitTcpClient(char *ip, uint16_t port, char *label, int num, void *fp, pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE); if (pthread_create(&(pTcp->thread), &thattr, taosReadTcpData, (void *)(pTcp)) != 0) { tError("%s failed to create TCP read data thread, reason:%s", label, strerror(errno)); + free(pTcp); return NULL; } diff --git a/src/rpc/src/ttcpserver.c b/src/rpc/src/ttcpserver.c index 663bfcdf8ee86008b0cfa4803725af1866a950bf..9d2c4e713d38dbba187a8e94b57de85d8c94cdda 100644 --- a/src/rpc/src/ttcpserver.c +++ b/src/rpc/src/ttcpserver.c @@ -389,6 +389,7 @@ void *taosInitTcpServer(char *ip, uint16_t port, char *label, int numOfThreads, pServerObj->pThreadObj = (SThreadObj *)malloc(sizeof(SThreadObj) * (size_t)numOfThreads); if (pServerObj->pThreadObj == NULL) { tError("TCP:%s no enough memory", label); + free(pServerObj); return NULL; } memset(pServerObj->pThreadObj, 0, sizeof(SThreadObj) * (size_t)numOfThreads); @@ -401,17 +402,23 @@ void *taosInitTcpServer(char *ip, uint16_t port, char *label, int numOfThreads, if (pthread_mutex_init(&(pThreadObj->threadMutex), NULL) < 0) { tError("%s failed to init TCP process data mutex, reason:%s", label, strerror(errno)); + free(pServerObj->pThreadObj); + free(pServerObj); return NULL; } if (pthread_cond_init(&(pThreadObj->fdReady), NULL) != 0) { tError("%s init TCP condition variable failed, reason:%s\n", label, strerror(errno)); + free(pServerObj->pThreadObj); + free(pServerObj); return NULL; } pThreadObj->pollFd = epoll_create(10); // size does not matter if (pThreadObj->pollFd < 0) { tError("%s failed to create TCP epoll", label); + free(pServerObj->pThreadObj); + free(pServerObj); return NULL; } @@ -419,6 +426,8 @@ void *taosInitTcpServer(char *ip, uint16_t port, char *label, int numOfThreads, pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE); if (pthread_create(&(pThreadObj->thread), &thattr, (void *)taosProcessTcpData, (void *)(pThreadObj)) != 0) { tError("%s failed to create TCP process data thread, reason:%s", label, strerror(errno)); + free(pServerObj->pThreadObj); + free(pServerObj); return NULL; } @@ -430,6 +439,8 @@ void *taosInitTcpServer(char *ip, uint16_t port, char *label, int numOfThreads, pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE); if (pthread_create(&(pServerObj->thread), &thattr, (void *)taosAcceptTcpConnection, (void *)(pServerObj)) != 0) { tError("%s failed to create TCP accept thread, reason:%s", label, strerror(errno)); + free(pServerObj->pThreadObj); + free(pServerObj); return NULL; } diff --git a/src/system/detail/src/mgmtMeter.c b/src/system/detail/src/mgmtMeter.c index a2a6ed8a7d3e506ddfcd1926683a0d823906c36a..207443fb8e6ea32861f8125b692229d689b927a9 100644 --- a/src/system/detail/src/mgmtMeter.c +++ b/src/system/detail/src/mgmtMeter.c @@ -567,6 +567,7 @@ int mgmtCreateMeter(SDbObj *pDb, SCreateTableMsg *pCreate) { pMetric = mgmtGetMeter(pTagData); if (pMetric == NULL) { mError("table:%s, corresponding super table does not exist", pCreate->meterId); + free(pMeter); return TSDB_CODE_INVALID_TABLE; } diff --git a/src/system/detail/src/mgmtSupertableQuery.c b/src/system/detail/src/mgmtSupertableQuery.c index 347b54595eea5ab786d622e68c2befd122f76e07..b0b73d3a761cb304de96fd3495ec6dc390b1c1f8 100644 --- a/src/system/detail/src/mgmtSupertableQuery.c +++ b/src/system/detail/src/mgmtSupertableQuery.c @@ -711,7 +711,6 @@ static int32_t mgmtFilterMeterByIndex(STabObj* pMetric, tQueryResultset* pRes, c // failed to build expression, no result, return immediately if (pExpr == NULL) { mError("metric:%s, no result returned, error in super table query expression:%s", pMetric->meterId, pCond); - tfree(pCond); return TSDB_CODE_OPS_NOT_SUPPORT; } else { // query according to the binary expression diff --git a/src/system/detail/src/vnodeQueryImpl.c b/src/system/detail/src/vnodeQueryImpl.c index 4addadd72be27d0d45f8ed3477dd9306708f8458..877602c97fafe2fcb03304049ecc27c0519e4bdd 100644 --- a/src/system/detail/src/vnodeQueryImpl.c +++ b/src/system/detail/src/vnodeQueryImpl.c @@ -5837,6 +5837,7 @@ int32_t doMergeMetersResultsToGroupRes(STableQuerySupportObj *pSupporter, SQuery } else { // copy data to disk buffer if (buffer[0]->numOfElems == pQuery->pointsToRead) { if (flushFromResultBuf(pSupporter, pQuery, pRuntimeEnv) != TSDB_CODE_SUCCESS) { + tfree(pTree); return -1; } diff --git a/src/util/src/textbuffer.c b/src/util/src/textbuffer.c index 8ce090d335ea8105d22d2342de9d9a3e61b4592f..1d1ddf698cf528b826b0ecc49d61f6a6d1e231fe 100644 --- a/src/util/src/textbuffer.c +++ b/src/util/src/textbuffer.c @@ -914,6 +914,7 @@ void tColModelDisplay(SColumnModel *pModel, void *pData, int32_t numOfRows, int3 char buf[4096] = {0}; taosUcs4ToMbs(val, pModel->pFields[j].field.bytes, buf); printf("%s\t", buf); + break; } case TSDB_DATA_TYPE_BINARY: { printBinaryData(val, pModel->pFields[j].field.bytes); @@ -965,6 +966,7 @@ void tColModelDisplayEx(SColumnModel *pModel, void *pData, int32_t numOfRows, in char buf[128] = {0}; taosUcs4ToMbs(val, pModel->pFields[j].field.bytes, buf); printf("%s\t", buf); + break; } case TSDB_DATA_TYPE_BINARY: { printBinaryDataEx(val, pModel->pFields[j].field.bytes, ¶m[j]); diff --git a/tests/examples/c/prepare.c b/tests/examples/c/prepare.c new file mode 100644 index 0000000000000000000000000000000000000000..207df9cf2f103d3d69c1d95f96f183eeb67e0cfe --- /dev/null +++ b/tests/examples/c/prepare.c @@ -0,0 +1,191 @@ +// TAOS standard API example. The same syntax as MySQL, but only a subet +// to compile: gcc -o prepare prepare.c -ltaos + +#include +#include +#include + +// # #include "taos.h" // TAOS header file +#include "taos.h" + + +void taosMsleep(int mseconds); + +int main(int argc, char *argv[]) +{ + TAOS *taos; + TAOS_RES *result; + TAOS_STMT *stmt; + + // connect to server + if (argc < 2) { + printf("please input server ip \n"); + return 0; + } + + // init TAOS + taos_init(); + + 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_query(taos, "drop database demo"); + if (taos_query(taos, "create database demo") != 0) { + printf("failed to create database, reason:%s\n", taos_errstr(taos)); + exit(1); + } + + taos_query(taos, "use demo"); + + + // create table + const char* sql = "create table m1 (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, bin binary(40), blob nchar(10))"; + if (taos_query(taos, sql) != 0) { + printf("failed to create table, reason:%s\n", taos_errstr(taos)); + exit(1); + } + + // sleep for one second to make sure table is created on data node + // taosMsleep(1000); + + // insert 10 records + 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}; + + stmt = taos_stmt_init(taos); + 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; + + strcpy(v.blob, "一二三四五六七八九十"); + params[9].buffer_type = TSDB_DATA_TYPE_NCHAR; + params[9].buffer_length = strlen(v.blob); + params[9].buffer = v.blob; + params[9].length = ¶ms[9].buffer_length; + params[9].is_null = NULL; + + int is_null = 1; + + sql = "insert into m1 values(?,?,?,?,?,?,?,?,?,?)"; + taos_stmt_prepare(stmt, sql, 0); + v.ts = 0; + for (int i = 0; i < 10; ++i) { + for (int j = 1; j < 10; ++j) { + params[j].is_null = ((i == j) ? &is_null : 0); + } + v.b = (int8_t)i % 2; + v.v1 = (int8_t)i; + v.v2 = (int16_t)(i * 2); + v.v4 = (int32_t)(i * 4); + v.v8 = (int64_t)(i * 8); + v.f4 = (float)(i * 40); + v.f8 = (double)(i * 80); + for (int j = 0; j < sizeof(v.bin) - 1; ++j) { + v.bin[j] = (char)(i + '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); + } + taos_stmt_close(stmt); + + // query the records + stmt = taos_stmt_init(taos); + taos_stmt_prepare(stmt, "SELECT * FROM m1 WHERE v1 > ? AND v2 < ?", 0); + v.v1 = 5; + v.v2 = 15; + taos_stmt_bind_param(stmt, params + 2); + if (taos_stmt_execute(stmt) != 0) { + printf("failed to execute select statement.\n"); + exit(1); + } + + result = taos_stmt_use_result(stmt); + + TAOS_ROW row; + int rows = 0; + int num_fields = taos_num_fields(result); + TAOS_FIELD *fields = taos_fetch_fields(result); + char temp[256]; + + // fetch the records row by row + while ((row = taos_fetch_row(result))) { + rows++; + taos_print_row(temp, row, fields, num_fields); + printf("%s\n", temp); + } + + taos_free_result(result); + taos_stmt_close(stmt); + + return getchar(); +} +