diff --git a/.travis.yml b/.travis.yml index 2c3fd31911..fcb2e8f22f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,13 @@ # # Build Matrix # +branches: + only: + - master + - develop + - coverity_scan + - /^.*ci-.*$/ + matrix: - os: linux dist: bionic diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h index bd956aeb74..90364987bb 100644 --- a/src/client/inc/tsclient.h +++ b/src/client/inc/tsclient.h @@ -349,7 +349,7 @@ typedef struct SSqlStream { int32_t tscInitRpc(const char *user, const char *secret, void** pDnodeConn); void tscInitMsgsFp(); -int tsParseSql(SSqlObj *pSql, bool multiVnodeInsertion); +int tsParseSql(SSqlObj *pSql, bool initialParse); void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcIpSet *pIpSet); int tscProcessSql(SSqlObj *pSql); diff --git a/src/client/src/TSDBJNIConnector.c b/src/client/src/TSDBJNIConnector.c index 4ee916c184..287e061da0 100644 --- a/src/client/src/TSDBJNIConnector.c +++ b/src/client/src/TSDBJNIConnector.c @@ -342,7 +342,7 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getResultSetImp( STscObj *pObj = pSql->pTscObj; if (tscIsUpdateQuery(pSql)) { - taos_free_result(pSql); // free result here + // taos_free_result(pSql); // free result here jniTrace("jobj:%p, conn:%p, no resultset, %p", jobj, pObj, (void *)tres); return 0; } else { @@ -383,7 +383,7 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getAffectedRowsIm } jint ret = taos_affected_rows((SSqlObj *)res); - jniTrace("jobj:%p, conn:%p, sql:%p, affect rows:%d", jobj, tscon, (SSqlObj*)res, ret); + jniTrace("jobj:%p, conn:%p, sql:%p, res: %p, affect rows:%d", jobj, tscon, (void *)con, (void *)res, ret); return ret; } @@ -409,10 +409,10 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getSchemaMetaData // jobject arrayListObj = (*env)->NewObject(env, g_arrayListClass, g_arrayListConstructFp, ""); if (num_fields == 0) { - jniError("jobj:%p, conn:%p, resultset:%p, fields size is %d", jobj, tscon, (void*)res, num_fields); + jniError("jobj:%p, conn:%p, resultset:%p, fields size is %d", jobj, tscon, (void *)res, num_fields); return JNI_NUM_OF_FIELDS_0; } else { - jniTrace("jobj:%p, conn:%p, resultset:%p, fields size is %d", jobj, tscon, (void*)res, num_fields); + jniTrace("jobj:%p, conn:%p, resultset:%p, fields size is %d", jobj, tscon, (void *)res, num_fields); for (int i = 0; i < num_fields; ++i) { jobject metadataObj = (*env)->NewObject(env, g_metadataClass, g_metadataConstructFp); (*env)->SetIntField(env, metadataObj, g_metadataColtypeField, fields[i].type); diff --git a/src/client/src/tscAsync.c b/src/client/src/tscAsync.c index 3fedc9e7ad..2b99d23099 100644 --- a/src/client/src/tscAsync.c +++ b/src/client/src/tscAsync.c @@ -39,39 +39,26 @@ static void tscProcessAsyncRetrieveImpl(void *param, TAOS_RES *tres, int numOfRo static void tscAsyncFetchRowsProxy(void *param, TAOS_RES *tres, int numOfRows); static void tscAsyncFetchSingleRowProxy(void *param, TAOS_RES *tres, int numOfRows); -int doAsyncParseSql(SSqlObj* pSql) { - SSqlCmd* pCmd = &pSql->cmd; - SSqlRes* pRes = &pSql->res; - int32_t code = tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE); - if (code != TSDB_CODE_SUCCESS) { - tscError("failed to malloc payload"); - tscQueueAsyncRes(pSql); -// tscQueueAsyncRes(pSql->fp, pSql->param, TSDB_CODE_TSC_OUT_OF_MEMORY); - return code; - } - - pRes->qhandle = 0; - pRes->numOfRows = 1; - - tscDump("%p SQL: %s", pSql, pSql->sqlstr); - return tsParseSql(pSql, true); -} - void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, void (*fp)(), void* param, const char* sqlstr, size_t sqlLen) { pSql->signature = pSql; pSql->param = param; pSql->pTscObj = pObj; pSql->maxRetry = TSDB_MAX_REPLICA_NUM; pSql->fp = fp; + pSql->sqlstr = calloc(1, sqlLen + 1); if (pSql->sqlstr == NULL) { tscError("%p failed to malloc sql string buffer", pSql); tscQueueAsyncError(pSql->fp, pSql->param, TSDB_CODE_TSC_OUT_OF_MEMORY); return; } + strtolower(pSql->sqlstr, sqlstr); - - int32_t code = doAsyncParseSql(pSql); + + tscDump("%p SQL: %s", pSql, pSql->sqlstr); + pSql->cmd.curSql = pSql->sqlstr; + + int32_t code = tsParseSql(pSql, true); if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) return; if (code != TSDB_CODE_SUCCESS) { diff --git a/src/client/src/tscParseInsert.c b/src/client/src/tscParseInsert.c index d821271857..aa9204e62a 100644 --- a/src/client/src/tscParseInsert.c +++ b/src/client/src/tscParseInsert.c @@ -1014,42 +1014,37 @@ static int32_t validateDataSource(SSqlCmd *pCmd, int8_t type, const char *sql) { * @param pSql * @return */ -int doParseInsertSql(SSqlObj *pSql, char *str) { +int tsParseInsertSql(SSqlObj *pSql) { SSqlCmd *pCmd = &pSql->cmd; + char* str = pCmd->curSql; int32_t totalNum = 0; int32_t code = TSDB_CODE_SUCCESS; - STableMetaInfo *pTableMetaInfo = NULL; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); assert(pQueryInfo != NULL); + STableMetaInfo *pTableMetaInfo = NULL; if (pQueryInfo->numOfTables == 0) { pTableMetaInfo = tscAddEmptyMetaInfo(pQueryInfo); } else { pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); } - // TODO: 2048 is added because TSDB_MAX_TAGS_LEN now is 65536 - // but TSDB_PAYLOAD_SIZE is 65380 + // TODO: 2048 is added because TSDB_MAX_TAGS_LEN now is 65536, but TSDB_PAYLOAD_SIZE is 65380 if ((code = tscAllocPayload(pCmd, TSDB_PAYLOAD_SIZE + 2048)) != TSDB_CODE_SUCCESS) { return code; } - assert(((NULL == pCmd->curSql) && (NULL == pCmd->pTableList)) - || ((NULL != pCmd->curSql) && (NULL != pCmd->pTableList))); - - if ((NULL == pCmd->curSql) && (NULL == pCmd->pTableList)) { + if (NULL == pCmd->pTableList) { pCmd->pTableList = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false); pSql->cmd.pDataBlocks = tscCreateBlockArrayList(); if (NULL == pCmd->pTableList || NULL == pSql->cmd.pDataBlocks) { code = TSDB_CODE_TSC_OUT_OF_MEMORY; - goto _error_clean; + goto _error; } } else { - assert((NULL != pCmd->curSql) && (NULL != pCmd->pTableList)); str = pCmd->curSql; } @@ -1075,7 +1070,7 @@ int doParseInsertSql(SSqlObj *pSql, char *str) { */ if (totalNum == 0) { code = TSDB_CODE_TSC_INVALID_SQL; - goto _error_clean; + goto _error; } else { break; } @@ -1086,11 +1081,11 @@ int doParseInsertSql(SSqlObj *pSql, char *str) { // Check if the table name available or not if (validateTableName(sToken.z, sToken.n) != TSDB_CODE_SUCCESS) { code = tscInvalidSQLErrMsg(pCmd->payload, "table name invalid", sToken.z); - goto _error_clean; + goto _error; } if ((code = tscSetTableFullName(pTableMetaInfo, &sToken, pSql)) != TSDB_CODE_SUCCESS) { - goto _error_clean; + goto _error; } ptrdiff_t pos = pCmd->curSql - pSql->sqlstr; @@ -1103,20 +1098,19 @@ int doParseInsertSql(SSqlObj *pSql, char *str) { * interrupted position. */ if (TSDB_CODE_TSC_ACTION_IN_PROGRESS == code) { - tscTrace("%p waiting for get table meta during insert, then resume from offset: %" PRId64 " , %s", pSql, + tscTrace("%p waiting for get table meta during insert, then resume from offset: %" PRId64 ", %s", pSql, pos, pCmd->curSql); return code; } - // todo add to return - tscError("%p async insert parse error, code:%d, %s", pSql, code, tstrerror(code)); + tscError("%p async insert parse error, code:%d, reason:%s", pSql, code, tstrerror(code)); pCmd->curSql = NULL; - goto _error_clean; // TODO: should _clean or _error_clean to async flow ???? + goto _error; } if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { code = tscInvalidSQLErrMsg(pCmd->payload, "insert data into super table is not supported", NULL); - goto _error_clean; + goto _error; } index = 0; @@ -1125,7 +1119,7 @@ int doParseInsertSql(SSqlObj *pSql, char *str) { if (sToken.n == 0) { code = tscInvalidSQLErrMsg(pCmd->payload, "keyword VALUES or FILE required", sToken.z); - goto _error_clean; + goto _error; } STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta); @@ -1137,7 +1131,7 @@ int doParseInsertSql(SSqlObj *pSql, char *str) { tscSetAssignedColumnInfo(&spd, pSchema, tinfo.numOfColumns); if (validateDataSource(pCmd, DATA_FROM_SQL_STRING, sToken.z) != TSDB_CODE_SUCCESS) { - goto _error_clean; + goto _error; } /* @@ -1146,11 +1140,11 @@ int doParseInsertSql(SSqlObj *pSql, char *str) { */ code = doParseInsertStatement(pSql, pCmd->pTableList, &str, &spd, &totalNum); if (code != TSDB_CODE_SUCCESS) { - goto _error_clean; + goto _error; } } else if (sToken.type == TK_FILE) { if (validateDataSource(pCmd, DATA_FROM_DATA_FILE, sToken.z) != TSDB_CODE_SUCCESS) { - goto _error_clean; + goto _error; } index = 0; @@ -1158,7 +1152,7 @@ int doParseInsertSql(SSqlObj *pSql, char *str) { str += index; if (sToken.n == 0) { code = tscInvalidSQLErrMsg(pCmd->payload, "file path is required following keyword FILE", sToken.z); - goto _error_clean; + goto _error; } char fname[PATH_MAX] = {0}; @@ -1168,7 +1162,7 @@ int doParseInsertSql(SSqlObj *pSql, char *str) { wordexp_t full_path; if (wordexp(fname, &full_path, 0) != 0) { code = tscInvalidSQLErrMsg(pCmd->payload, "invalid filename", sToken.z); - goto _error_clean; + goto _error; } strcpy(fname, full_path.we_wordv[0]); wordfree(&full_path); @@ -1179,7 +1173,7 @@ int doParseInsertSql(SSqlObj *pSql, char *str) { int32_t ret = tscCreateDataBlock(PATH_MAX, tinfo.rowSize, sizeof(SSubmitBlk), pTableMetaInfo->name, pTableMeta, &pDataBlock); if (ret != TSDB_CODE_SUCCESS) { - goto _error_clean; + goto _error; } tscAppendDataBlock(pCmd->pDataBlocks, pDataBlock); @@ -1190,7 +1184,7 @@ int doParseInsertSql(SSqlObj *pSql, char *str) { SSchema * pSchema = tscGetTableSchema(pTableMeta); if (validateDataSource(pCmd, DATA_FROM_SQL_STRING, sToken.z) != TSDB_CODE_SUCCESS) { - goto _error_clean; + goto _error; } SParsedDataColInfo spd = {0}; @@ -1226,7 +1220,7 @@ int doParseInsertSql(SSqlObj *pSql, char *str) { if (spd.hasVal[t] == true) { code = tscInvalidSQLErrMsg(pCmd->payload, "duplicated column name", sToken.z); - goto _error_clean; + goto _error; } spd.hasVal[t] = true; @@ -1237,13 +1231,13 @@ int doParseInsertSql(SSqlObj *pSql, char *str) { if (!findColumnIndex) { code = tscInvalidSQLErrMsg(pCmd->payload, "invalid column name", sToken.z); - goto _error_clean; + goto _error; } } if (spd.numOfAssignedCols == 0 || spd.numOfAssignedCols > tinfo.numOfColumns) { code = tscInvalidSQLErrMsg(pCmd->payload, "column name expected", sToken.z); - goto _error_clean; + goto _error; } index = 0; @@ -1252,16 +1246,16 @@ int doParseInsertSql(SSqlObj *pSql, char *str) { if (sToken.type != TK_VALUES) { code = tscInvalidSQLErrMsg(pCmd->payload, "keyword VALUES is expected", sToken.z); - goto _error_clean; + goto _error; } code = doParseInsertStatement(pSql, pCmd->pTableList, &str, &spd, &totalNum); if (code != TSDB_CODE_SUCCESS) { - goto _error_clean; + goto _error; } } else { code = tscInvalidSQLErrMsg(pCmd->payload, "keyword VALUES or FILE are required", sToken.z); - goto _error_clean; + goto _error; } } @@ -1272,7 +1266,7 @@ int doParseInsertSql(SSqlObj *pSql, char *str) { if (pCmd->pDataBlocks->nSize > 0) { // merge according to vgId if ((code = tscMergeTableDataBlocks(pSql, pCmd->pDataBlocks)) != TSDB_CODE_SUCCESS) { - goto _error_clean; + goto _error; } } else { pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks); @@ -1281,7 +1275,7 @@ int doParseInsertSql(SSqlObj *pSql, char *str) { code = TSDB_CODE_SUCCESS; goto _clean; -_error_clean: +_error: pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks); _clean: @@ -1294,7 +1288,7 @@ _clean: return code; } -int tsParseInsertSql(SSqlObj *pSql) { +int tsInsertInitialCheck(SSqlObj *pSql) { if (!pSql->pTscObj->writeAuth) { return TSDB_CODE_TSC_NO_WRITE_AUTH; } @@ -1312,30 +1306,24 @@ int tsParseInsertSql(SSqlObj *pSql) { SQueryInfo *pQueryInfo = NULL; tscGetQueryInfoDetailSafely(pCmd, pCmd->clauseIndex, &pQueryInfo); - TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT); - TSDB_QUERY_SET_TYPE(pQueryInfo->type, pCmd->insertType); + TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT | pCmd->insertType); sToken = tStrGetToken(pSql->sqlstr, &index, false, 0, NULL); if (sToken.type != TK_INTO) { return tscInvalidSQLErrMsg(pCmd->payload, "keyword INTO is expected", sToken.z); } - return doParseInsertSql(pSql, pSql->sqlstr + index); + pCmd->curSql = sToken.z + sToken.n; + return TSDB_CODE_SUCCESS; } int tsParseSql(SSqlObj *pSql, bool initialParse) { int32_t ret = TSDB_CODE_SUCCESS; - - if (initialParse) { - assert(!pSql->cmd.parseFinished); + SSqlCmd* pCmd = &pSql->cmd; - char* p = pSql->sqlstr; - pSql->sqlstr = NULL; - - tscPartiallyFreeSqlObj(pSql); - pSql->sqlstr = p; - } else if (!pSql->cmd.parseFinished) { - tscTrace("continue parse sql: %s", pSql->cmd.curSql); + tscTrace("------------------%p, initial:%d, sqlstr:%s", pSql, initialParse, pSql->sqlstr); + if (!pCmd->parseFinished) { + tscTrace("%p resume to parse sql: %s", pSql, pCmd->curSql); } if (tscIsInsertData(pSql->sqlstr)) { @@ -1347,14 +1335,18 @@ int tsParseSql(SSqlObj *pSql, bool initialParse) { pSql->fetchFp = pSql->fp; pSql->fp = (void(*)())tscHandleMultivnodeInsert; } - + + if (initialParse && ((ret = tsInsertInitialCheck(pSql)) != TSDB_CODE_SUCCESS)) { + return ret; + } + ret = tsParseInsertSql(pSql); } else { ret = tscAllocPayload(&pSql->cmd, TSDB_DEFAULT_PAYLOAD_SIZE); if (TSDB_CODE_SUCCESS != ret) { return ret; } - + SSqlInfo SQLInfo = qSQLParse(pSql->sqlstr); ret = tscToSQLCmd(pSql, &SQLInfo); SQLInfoDestroy(&SQLInfo); @@ -1362,11 +1354,9 @@ int tsParseSql(SSqlObj *pSql, bool initialParse) { /* * the pRes->code may be modified or released by another thread in tscTableMetaCallBack function, - * so do NOT use pRes->code to determine if the getTableMeta/getMetricMeta function - * invokes new threads to get data from mnode or simply retrieves data from cache. - * - * do NOT assign return code to pRes->code for the same reason since it may be released by another thread - * pRes->code = ret; + * so do NOT use pRes->code to determine if the getTableMeta function + * invokes new threads to get data from mgmt node or simply retrieves data from cache. + * do NOT assign return code to pRes->code for the same reason since it may be released by another thread already. */ return ret; } diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 6164c005b9..d8d43508b5 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -1482,7 +1482,8 @@ int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIndex, tSQLExpr const char* msg5 = "parameter is out of range [0, 100]"; const char* msg6 = "function applied to tags not allowed"; const char* msg7 = "normal table can not apply this function"; - + const char* msg8 = "multi-columns selection does not support alias column name"; + switch (optr) { case TK_COUNT: { if (pItem->pNode->pParam != NULL && pItem->pNode->pParam->nExpr != 1) { @@ -1689,6 +1690,10 @@ int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIndex, tSQLExpr return invalidSqlErrMsg(pQueryInfo->msg, msg3); } + if (pItem->pNode->pParam->nExpr > 1 && (pItem->aliasName != NULL && strlen(pItem->aliasName) > 0)) { + return invalidSqlErrMsg(pQueryInfo->msg, msg8); + } + /* in first/last function, multiple columns can be add to resultset */ for (int32_t i = 0; i < pItem->pNode->pParam->nExpr; ++i) { tSQLExprItem* pParamElem = &(pItem->pNode->pParam->a[i]); @@ -1755,6 +1760,11 @@ int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIndex, tSQLExpr } else { // select * from xxx int32_t numOfFields = 0; + // multicolumn selection does not support alias name + if (pItem->aliasName != NULL && strlen(pItem->aliasName) > 0) { + return invalidSqlErrMsg(pQueryInfo->msg, msg8); + } + for (int32_t j = 0; j < pQueryInfo->numOfTables; ++j) { pTableMetaInfo = tscGetMetaInfo(pQueryInfo, j); SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta); diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 1384dcecff..6e3602b69d 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -198,8 +198,6 @@ int tscSendMsgToServer(SSqlObj *pSql) { }; pSql->SRpcReqContext = rpcSendRequest(pObj->pDnodeConn, &pSql->ipList, &rpcMsg); - assert(pSql->SRpcReqContext != NULL); - return TSDB_CODE_SUCCESS; } diff --git a/src/client/src/tscSql.c b/src/client/src/tscSql.c index 0fa841bc7c..47a602a6fb 100644 --- a/src/client/src/tscSql.c +++ b/src/client/src/tscSql.c @@ -488,7 +488,7 @@ static bool tscFreeQhandleInVnode(SSqlObj* pSql) { (pCmd->command == TSDB_SQL_SELECT && pSql->pStream == NULL && pTableMetaInfo->pTableMeta != NULL)) { pCmd->command = (pCmd->command > TSDB_SQL_MGMT) ? TSDB_SQL_RETRIEVE : TSDB_SQL_FETCH; - tscTrace("%p start to send msg to free qhandle in dnode, command:%s", pSql, sqlCmd[pCmd->command]); + tscTrace("%p send msg to dnode to free qhandle ASAP, command:%s", pSql, sqlCmd[pCmd->command]); pSql->freed = 1; tscProcessSql(pSql); @@ -510,18 +510,17 @@ static bool tscFreeQhandleInVnode(SSqlObj* pSql) { void taos_free_result(TAOS_RES *res) { SSqlObj *pSql = (SSqlObj *)res; - tscTrace("%p start to free result", res); - + if (pSql == NULL || pSql->signature != pSql) { - tscTrace("%p result has been freed", pSql); + tscTrace("%p sqlObj has been freed", pSql); return; } // The semaphore can not be changed while freeing async sub query objects. SSqlRes *pRes = &pSql->res; if (pRes == NULL || pRes->qhandle == 0) { - tscTrace("%p SqlObj is freed by app, qhandle is null", pSql); tscFreeSqlObj(pSql); + tscTrace("%p SqlObj is freed by app, qhandle is null", pSql); return; } @@ -529,6 +528,7 @@ void taos_free_result(TAOS_RES *res) { SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); if (pQueryInfo == NULL) { tscFreeSqlObj(pSql); + tscTrace("%p SqlObj is freed by app", pSql); return; } @@ -713,7 +713,6 @@ int taos_validate_sql(TAOS *taos, const char *sql) { SSqlRes *pRes = &pSql->res; SSqlCmd *pCmd = &pSql->cmd; - pRes->numOfRows = 1; pRes->numOfTotal = 0; pRes->numOfClauseTotal = 0; diff --git a/src/client/src/tscStream.c b/src/client/src/tscStream.c index 6fc934b6c0..86a41b7ba4 100644 --- a/src/client/src/tscStream.c +++ b/src/client/src/tscStream.c @@ -503,8 +503,10 @@ TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sqlstr, void (*fp)(void *p } strtolower(pSql->sqlstr, sqlstr); + tscDump("%p SQL: %s", pSql, pSql->sqlstr); tsem_init(&pSql->rspSem, 0, 0); - int32_t code = doAsyncParseSql(pSql); + + int32_t code = tsParseSql(pSql, true); if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { sem_wait(&pSql->rspSem); } diff --git a/src/client/src/tscSubquery.c b/src/client/src/tscSubquery.c index 985f0c1d5b..bb57da86fd 100644 --- a/src/client/src/tscSubquery.c +++ b/src/client/src/tscSubquery.c @@ -1165,8 +1165,8 @@ int32_t tscLaunchJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); pSql->res.qhandle = 0x1; - pSql->res.numOfRows = 0; - + assert(pSql->res.numOfRows == 0); + if (pSql->pSubs == NULL) { pSql->pSubs = calloc(pSupporter->pState->numOfTotal, POINTER_BYTES); if (pSql->pSubs == NULL) { @@ -1364,7 +1364,7 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) { tOrderDescriptor *pDesc = NULL; SColumnModel * pModel = NULL; - pRes->qhandle = 1; // hack the qhandle check + pRes->qhandle = 0x1; // hack the qhandle check const uint32_t nBufferSize = (1u << 16); // 64KB @@ -1845,34 +1845,42 @@ void tscRetrieveDataRes(void *param, TAOS_RES *tres, int code) { } } -static void multiVnodeInsertMerge(void* param, TAOS_RES* tres, int numOfRows) { +static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows) { SInsertSupporter *pSupporter = (SInsertSupporter *)param; SSqlObj* pParentObj = pSupporter->pSql; SSqlCmd* pParentCmd = &pParentObj->cmd; SSubqueryState* pState = pSupporter->pState; - // increase the total inserted rows + // record the total inserted rows if (numOfRows > 0) { - pParentObj->res.numOfRows += numOfRows; + if (tres != pParentObj) { + pParentObj->res.numOfRows += numOfRows; + } } else { SSqlObj* pSql = (SSqlObj*) tres; assert(pSql != NULL && pSql->res.code == numOfRows); pParentObj->res.code = pSql->res.code; } - - taos_free_result(tres); + + + // it is not the initial sqlObj, free it + if (tres != pParentObj) { + taos_free_result(tres); + } else { + assert(pParentObj->pSubs[0] == tres); + } + tfree(pSupporter); if (atomic_sub_fetch_32(&pState->numOfRemain, 1) > 0) { return; } tscTrace("%p Async insertion completed, total inserted:%" PRId64, pParentObj, pParentObj->res.numOfRows); - - tfree(pState); - + // release data block data + tfree(pState); pParentCmd->pDataBlocks = tscDestroyBlockArrayList(pParentCmd->pDataBlocks); // restore user defined fp @@ -1886,9 +1894,7 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) { SSqlRes *pRes = &pSql->res; SSqlCmd *pCmd = &pSql->cmd; - pRes->qhandle = 1; // hack the qhandle check SDataBlockList *pDataBlocks = pCmd->pDataBlocks; - pSql->pSubs = calloc(pDataBlocks->nSize, POINTER_BYTES); pSql->numOfSubs = pDataBlocks->nSize; assert(pDataBlocks->nSize > 0); @@ -1896,31 +1902,54 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) { tscTrace("%p submit data to %d vnode(s)", pSql, pDataBlocks->nSize); SSubqueryState *pState = calloc(1, sizeof(SSubqueryState)); pState->numOfTotal = pSql->numOfSubs; + pState->numOfRemain = pSql->numOfSubs; - + pRes->code = TSDB_CODE_SUCCESS; - - int32_t i = 0; + + SInsertSupporter* pSupporter = calloc(1, sizeof(SInsertSupporter)); + pSupporter->pSql = pSql; + pSupporter->pState = pState; + + pSql->fp = multiVnodeInsertFinalize; + pSql->param = pSupporter; + pSql->pSubs[0] = pSql; // the first sub insert points back to itself + tscTrace("%p sub:%p create subObj success. orderOfSub:%d", pSql, pSql, 0); + + int32_t code = tscCopyDataBlockToPayload(pSql, pDataBlocks->pData[0]); + if (code != TSDB_CODE_SUCCESS) { + tscTrace("%p prepare submit data block failed in async insertion, vnodeIdx:%d, total:%d, code:%d", pSql, 0, + pDataBlocks->nSize, code); + goto _error; + } + + int32_t i = 1; for (; i < pSql->numOfSubs; ++i) { - SInsertSupporter* pSupporter = calloc(1, sizeof(SInsertSupporter)); - pSupporter->pSql = pSql; - pSupporter->pState = pState; + SInsertSupporter* pSupporter1 = calloc(1, sizeof(SInsertSupporter)); + pSupporter1->pSql = pSql; + pSupporter1->pState = pState; - SSqlObj *pNew = createSubqueryObj(pSql, 0, multiVnodeInsertMerge, pSupporter, TSDB_SQL_INSERT, NULL); + SSqlObj *pNew = createSubqueryObj(pSql, 0, multiVnodeInsertFinalize, pSupporter, TSDB_SQL_INSERT, NULL); if (pNew == NULL) { tscError("%p failed to malloc buffer for subObj, orderOfSub:%d, reason:%s", pSql, i, strerror(errno)); - break; + goto _error; } /* * assign the callback function to fetchFp to make sure that the error process function can restore - * the callback function (multiVnodeInsertMerge) correctly. + * the callback function (multiVnodeInsertFinalize) correctly. */ pNew->fetchFp = pNew->fp; pSql->pSubs[i] = pNew; - pNew->fetchFp = pNew->fp; - - tscTrace("%p sub:%p create subObj success. orderOfSub:%d", pSql, pNew, i); + + code = tscCopyDataBlockToPayload(pNew, pDataBlocks->pData[i]); + if (code != TSDB_CODE_SUCCESS) { + tscTrace("%p prepare submit data block failed in async insertion, vnodeIdx:%d, total:%d, code:%d", pSql, i, + pDataBlocks->nSize, code); + goto _error; + } else { + tscTrace("%p sub:%p create subObj success. orderOfSub:%d", pSql, pNew, i); + } } if (i < pSql->numOfSubs) { @@ -1928,21 +1957,30 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) { pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY; return pRes->code; // free all allocated resource } - - for (int32_t j = 0; j < pSql->numOfSubs; ++j) { + + // use the local variable + int32_t numOfSub = pSql->numOfSubs; + for (int32_t j = 0; j < numOfSub; ++j) { SSqlObj *pSub = pSql->pSubs[j]; - int32_t code = tscCopyDataBlockToPayload(pSub, pDataBlocks->pData[j]); - - if (code != TSDB_CODE_SUCCESS) { - tscTrace("%p prepare submit data block failed in async insertion, vnodeIdx:%d, total:%d, code:%d", pSql, j, - pDataBlocks->nSize, code); - } - tscTrace("%p sub:%p launch sub insert, orderOfSub:%d", pSql, pSub, j); tscProcessSql(pSub); } return TSDB_CODE_SUCCESS; + + _error: + // restore the udf fp + pSql->fp = pSql->fetchFp; + + tfree(pState); + tfree(pSql->param); + + for(int32_t j = 1; j < i; ++j) { + tfree(pSql->pSubs[j]->param); + taos_free_result(pSql->pSubs[j]); + } + + return TSDB_CODE_TSC_OUT_OF_MEMORY; } void tscBuildResFromSubqueries(SSqlObj *pSql) { diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index cbf1aa12be..110a435e57 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -1581,24 +1581,6 @@ void tscClearSubqueryInfo(SSqlCmd* pCmd) { } } -void doRemoveTableMetaInfo(SQueryInfo* pQueryInfo, int32_t index, bool removeFromCache) { - if (index < 0 || index >= pQueryInfo->numOfTables) { - return; - } - - STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index); - - tscClearTableMetaInfo(pTableMetaInfo, removeFromCache); - free(pTableMetaInfo); - - int32_t after = pQueryInfo->numOfTables - index - 1; - if (after > 0) { - memmove(&pQueryInfo->pTableMetaInfo[index], &pQueryInfo->pTableMetaInfo[index + 1], after * POINTER_BYTES); - } - - pQueryInfo->numOfTables -= 1; -} - void clearAllTableMetaInfo(SQueryInfo* pQueryInfo, const char* address, bool removeFromCache) { tscTrace("%p deref the table meta in cache, numOfTables:%d", address, pQueryInfo->numOfTables); diff --git a/src/connector/jdbc/.classpath b/src/connector/jdbc/.classpath new file mode 100644 index 0000000000..39abf1c5e9 --- /dev/null +++ b/src/connector/jdbc/.classpath @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/connector/jdbc/.project b/src/connector/jdbc/.project new file mode 100644 index 0000000000..656ab58d20 --- /dev/null +++ b/src/connector/jdbc/.project @@ -0,0 +1,23 @@ + + + taos-jdbcdriver + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/src/connector/jdbc/.settings/org.eclipse.core.resources.prefs b/src/connector/jdbc/.settings/org.eclipse.core.resources.prefs deleted file mode 100755 index 1935ba2ee4..0000000000 --- a/src/connector/jdbc/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,5 +0,0 @@ -eclipse.preferences.version=1 -encoding//src/main/java=GBK -encoding//src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java=UTF-8 -encoding//src/main/resources=UTF-8 -encoding/=UTF-8 diff --git a/src/connector/jdbc/.settings/org.eclipse.jdt.core.prefs b/src/connector/jdbc/.settings/org.eclipse.jdt.core.prefs deleted file mode 100755 index 5ce4518899..0000000000 --- a/src/connector/jdbc/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,13 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.6 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.source=1.6 diff --git a/src/connector/jdbc/.settings/org.eclipse.m2e.core.prefs b/src/connector/jdbc/.settings/org.eclipse.m2e.core.prefs deleted file mode 100755 index f897a7f1cb..0000000000 --- a/src/connector/jdbc/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/src/connector/jdbc/pom.xml b/src/connector/jdbc/pom.xml index 36f1a1010c..5aa4f6a2e3 100755 --- a/src/connector/jdbc/pom.xml +++ b/src/connector/jdbc/pom.xml @@ -1,105 +1,136 @@ - 4.0.0 - - com.taosdata.jdbc - taos-jdbcdriver - 1.0.3 - jar - - JDBCDriver - https://github.com/taosdata/TDengine/tree/master/src/connector/jdbc - TDengine JDBC Driver - - - - GNU AFFERO GENERAL PUBLIC LICENSE Version 3 - https://github.com/taosdata/TDengine/blob/master/LICENSE - repo - - - - - scm:git:git://github.com/taosdata/TDengine.git - scm:git:git@github.com:taosdata/TDengine.git - https://github.com/taosdata/TDengine/tree/master/src/connector/jdbc - HEAD - - - - - taosdata - support@taosdata.com - https://www.taosdata.com/ - https://www.taosdata.com/ - - - - - UTF-8 - 1.8 - - 3.6.0 - - 1.1.2 - 3.5 - - - - - commons-logging - commons-logging - ${commons-logging.version} - - - * - * - - - - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - - - - - - - org.apache.maven.plugins - maven-assembly-plugin - 3.0.0 - - - - src/main/assembly/assembly-jar.xml - - - - - make-assembly - package - - single - - - - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - UTF-8 - ${java.version} - ${java.version} - true - true - - - - - - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + com.taosdata.jdbc + taos-jdbcdriver + 1.0.3 + jar + JDBCDriver + https://github.com/taosdata/TDengine/tree/master/src/connector/jdbc + TDengine JDBC Driver + + + GNU AFFERO GENERAL PUBLIC LICENSE Version 3 + https://github.com/taosdata/TDengine/blob/master/LICENSE + repo + + + + scm:git:git://github.com/taosdata/TDengine.git + scm:git:git@github.com:taosdata/TDengine.git + https://github.com/taosdata/TDengine/tree/master/src/connector/jdbc + HEAD + + + + taosdata + support@taosdata.com + https://www.taosdata.com/ + https://www.taosdata.com/ + + + + UTF-8 + 1.8 + 3.6.0 + 1.1.2 + 3.5 + + + + commons-logging + commons-logging + ${commons-logging.version} + + + * + * + + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + org.jacoco + jacoco-maven-plugin + 0.8.3 + + + junit + junit + 4.13 + test + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 3.0.0 + + + src/main/assembly/assembly-jar.xml + + + + + make-assembly + package + + single + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + UTF-8 + ${java.version} + ${java.version} + true + true + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12.4 + + true + + + + org.jacoco + jacoco-maven-plugin + 0.8.3 + + + com/**/* + + + + + pre-test + + prepare-agent + + + + post-test + test + + report + + + + + + diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDatabaseMetaData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDatabaseMetaData.java index 6cb3263e56..804e09c6b3 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDatabaseMetaData.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDatabaseMetaData.java @@ -527,8 +527,9 @@ public class TSDBDatabaseMetaData implements java.sql.DatabaseMetaData { public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException { - if (conn != null && !conn.isClosed()) { - Statement stmt = conn.createStatement(); + Statement stmt = null; + if (null != conn && !conn.isClosed()) { + stmt = conn.createStatement(); if (catalog == null || catalog.length() < 1) { catalog = conn.getCatalog(); } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBError.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBError.java deleted file mode 100644 index bb1b2afd07..0000000000 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBError.java +++ /dev/null @@ -1,223 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2019 TAOS Data, Inc. - * - * This program is free software: you can use, redistribute, and/or modify - * it under the terms of the GNU Affero General Public License, version 3 - * or later ("AGPL"), as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - *****************************************************************************/ -package com.taosdata.jdbc; - -import java.util.HashMap; -import java.util.Map; - -/** - * - * TDengine error code and error message enumeration. - * - */ -public enum TSDBError { - - TSDB_CODE_SUCCESS(0, "success"), - TSDB_CODE_ACTION_IN_PROGRESS(1, "in progress"), - TSDB_CODE_LAST_SESSION_NOT_FINISHED(5, "last session not finished"), - TSDB_CODE_INVALID_SESSION_ID(6, "invalid session ID"), - TSDB_CODE_INVALID_TRAN_ID(7, "invalid tran ID"), - TSDB_CODE_INVALID_MSG_TYPE(8, "invalid msg type"), - TSDB_CODE_ALREADY_PROCESSED(9, "alredy processed"), - TSDB_CODE_AUTH_FAILURE(10, "authentication failure"), - TSDB_CODE_WRONG_MSG_SIZE(11, "wrong msg size"), - TSDB_CODE_UNEXPECTED_RESPONSE(12, "unexpected response"), - TSDB_CODE_INVALID_RESPONSE_TYPE(13, "invalid response type"), - TSDB_CODE_NO_RESOURCE(14, "no resource"), - TSDB_CODE_INVALID_TIME_STAMP(15, "invalid time stamp"), - TSDB_CODE_MISMATCHED_METER_ID(16, "mismatched meter ID"), - TSDB_CODE_ACTION_TRANS_NOT_FINISHED(17, "transcation not finished"), - TSDB_CODE_ACTION_NOT_ONLINE(18, "not online"), - TSDB_CODE_ACTION_SEND_FAILD(19, "send failed"), - TSDB_CODE_NOT_ACTIVE_SESSION(20, "not active session"), - TSDB_CODE_INSERT_FAILED(21, "insert failed"), - TSDB_CODE_APP_ERROR(22, "App error"), - TSDB_CODE_INVALID_IE(23, "invalid IE"), - TSDB_CODE_INVALID_VALUE(24, "invalid value"), - TSDB_CODE_REDIRECT(25, "service not available"), - TSDB_CODE_ALREADY_THERE(26, "already there"), - TSDB_CODE_INVALID_TABLE_ID(27, "invalid meter ID"), - TSDB_CODE_INVALID_SQL(28, "invalid SQL"), // this message often comes with additional info which will vary based on the specific error situation - TSDB_CODE_NETWORK_UNAVAIL(29, "failed to connect to server"), - TSDB_CODE_INVALID_MSG_LEN(30, "invalid msg len"), - TSDB_CODE_INVALID_DB(31, "invalid DB"), - TSDB_CODE_INVALID_TABLE(32, "invalid table"), - TSDB_CODE_DB_ALREADY_EXIST(33, "DB already there"), - TSDB_CODE_TABLE_ALREADY_EXIST(34, "table already there"), - TSDB_CODE_INVALID_USER(35, "invalid user name"), - TSDB_CODE_INVALID_ACCT(36, "invalid acct name"), - TSDB_CODE_INVALID_PASS(37, "invalid password"), - TSDB_CODE_DB_NOT_SELECTED(38, "DB not selected"), - TSDB_CODE_MEMORY_CORRUPTED(39, "memory corrupted"), - TSDB_CODE_USER_ALREADY_EXIST(40, "user name exists"), - TSDB_CODE_NO_RIGHTS(41, "not authorized"), - TSDB_CODE_DISCONNECTED(42, "login disconnected), login again"), - TSDB_CODE_NO_MASTER(43, "mgmt master node not available"), - TSDB_CODE_NOT_CONFIGURED(44, "not configured"), - TSDB_CODE_INVALID_OPTION(45, "invalid option"), - TSDB_CODE_NODE_OFFLINE(46, "node offline"), - TSDB_CODE_SYNC_REQUIRED(47, "sync required"), - TSDB_CODE_NO_ENOUGH_DNODES(48, "more dnodes are needed"), - TSDB_CODE_UNSYNCED(49, "node in unsynced state"), - TSDB_CODE_TOO_SLOW(50, "too slow"), - TSDB_CODE_OTHERS(51, "others"), - TSDB_CODE_NO_REMOVE_MASTER(52, "can't remove dnode which is master"), - TSDB_CODE_WRONG_SCHEMA(53, "wrong schema"), - TSDB_CODE_NO_RESULT(54, "no results"), - TSDB_CODE_TOO_MANY_USERS(55, "num of users execeed maxUsers"), - TSDB_CODE_TOO_MANY_DATABSES(56, "num of databases execeed maxDbs"), - TSDB_CODE_TOO_MANY_TABLES(57, "num of tables execeed maxTables"), - TSDB_CODE_TOO_MANY_DNODES(58, "num of dnodes execeed maxDnodes"), - TSDB_CODE_TOO_MANY_ACCTS(59, "num of accounts execeed maxAccts"), - TSDB_CODE_ACCT_ALREADY_EXIST(60, "accout name exists"), - TSDB_CODE_DNODE_ALREADY_EXIST(61, "dnode ip exists"), - TSDB_CODE_SDB_ERROR(62, "sdb error"), - TSDB_CODE_METRICMETA_EXPIRED(63, "metric meta expired"), // local cached metric-meta expired causes error in metric query - TSDB_CODE_NOT_READY(64, "not ready"), // peer is not ready to process data - TSDB_CODE_MAX_SESSIONS(65, "too many sessions on server"), // too many sessions - TSDB_CODE_MAX_CONNECTIONS(66, "too many sessions from app"), // too many connections - TSDB_CODE_SESSION_ALREADY_EXIST(67, "session to dest is already there"), - TSDB_CODE_NO_QSUMMARY(68, "query list not there), please show again"), - TSDB_CODE_SERV_OUT_OF_MEMORY(69, "server out of memory"), - TSDB_CODE_INVALID_QHANDLE(70, "invalid query handle"), - TSDB_CODE_RELATED_TABLES_EXIST(71, "tables related to metric exist"), - TSDB_CODE_MONITOR_DB_FORBEIDDEN(72, "can't drop monitor database or tables"), - TSDB_CODE_VG_COMMITLOG_INIT_FAILED(73, "commit log init failed"), - TSDB_CODE_VG_INIT_FAILED(74, "vgroup init failed"), - TSDB_CODE_DATA_ALREADY_IMPORTED(75, "data is already imported"), - TSDB_CODE_OPS_NOT_SUPPORT(76, "not supported operation"), - TSDB_CODE_INVALID_QUERY_ID(77, "invalid query id string"), - TSDB_CODE_INVALID_STREAM_ID(78, "invalid stream id string"), - TSDB_CODE_INVALID_CONNECTION(79, "invalid connection string"), - TSDB_CODE_ACTION_NOT_BALANCED(80, "dnode not balanced"), - TSDB_CODE_CLI_OUT_OF_MEMORY(81, "client out of memory"), - TSDB_CODE_DATA_OVERFLOW(82, "data value overflow"), - TSDB_CODE_QUERY_CANCELLED(83, "query cancelled"), - TSDB_CODE_GRANT_POINT_LIMITED(84, "grant points limited"), - TSDB_CODE_GRANT_EXPIRED(85, "grant expired"), - TSDB_CODE_CLI_NO_DISKSPACE(86, "client no disk space"), - TSDB_CODE_FILE_CORRUPTED(87, "DB file corrupted"), - TSDB_CODE_INVALID_CLIENT_VERSION(88, "version of client and server not match"); - - private long errCode; - private String errMessage; - private static Map errorCodeMap = new HashMap<>(86); - static { - errorCodeMap.put(0, "success"); - errorCodeMap.put(1, "in progress"); - errorCodeMap.put(5, "last session not finished"); - errorCodeMap.put(6, "invalid session ID"); - errorCodeMap.put(7, "invalid tran ID"); - errorCodeMap.put(8, "invalid msg type"); - errorCodeMap.put(9, "alredy processed"); - errorCodeMap.put(10, "authentication failure"); - errorCodeMap.put(11, "wrong msg size"); - errorCodeMap.put(12, "unexpected response"); - errorCodeMap.put(13, "invalid response type"); - errorCodeMap.put(14, "no resource"); - errorCodeMap.put(15, "invalid time stamp"); - errorCodeMap.put(16, "mismatched meter ID"); - errorCodeMap.put(17, "transcation not finished"); - errorCodeMap.put(18, "not online"); - errorCodeMap.put(19, "send failed"); - errorCodeMap.put(20, "not active session"); - errorCodeMap.put(21, "insert failed"); - errorCodeMap.put(22, "App error"); - errorCodeMap.put(23, "invalid IE"); - errorCodeMap.put(24, "invalid value"); - errorCodeMap.put(25, "service not available"); - errorCodeMap.put(26, "already there"); - errorCodeMap.put(27, "invalid meter ID"); - errorCodeMap.put(28, "invalid SQL"); // this message often comes with additional info which will vary based on the specific error situation - errorCodeMap.put(29, "failed to connect to server"); - errorCodeMap.put(30, "invalid msg len"); - errorCodeMap.put(31, "invalid DB"); - errorCodeMap.put(32, "invalid table"); - errorCodeMap.put(33, "DB already there"); - errorCodeMap.put(34, "table already there"); - errorCodeMap.put(35, "invalid user name"); - errorCodeMap.put(36, "invalid acct name"); - errorCodeMap.put(37, "invalid password"); - errorCodeMap.put(38, "DB not selected"); - errorCodeMap.put(39, "memory corrupted"); - errorCodeMap.put(40, "user name exists"); - errorCodeMap.put(41, "not authorized"); - errorCodeMap.put(42, "login disconnected); login again"); - errorCodeMap.put(43, "mgmt master node not available"); - errorCodeMap.put(44, "not configured"); - errorCodeMap.put(45, "invalid option"); - errorCodeMap.put(46, "node offline"); - errorCodeMap.put(47, "sync required"); - errorCodeMap.put(48, "more dnodes are needed"); - errorCodeMap.put(49, "node in unsynced state"); - errorCodeMap.put(50, "too slow"); - errorCodeMap.put(51, "others"); - errorCodeMap.put(52, "can't remove dnode which is master"); - errorCodeMap.put(53, "wrong schema"); - errorCodeMap.put(54, "no results"); - errorCodeMap.put(55, "num of users execeed maxUsers"); - errorCodeMap.put(56, "num of databases execeed maxDbs"); - errorCodeMap.put(57, "num of tables execeed maxTables"); - errorCodeMap.put(58, "num of dnodes execeed maxDnodes"); - errorCodeMap.put(59, "num of accounts execeed maxAccts"); - errorCodeMap.put(60, "accout name exists"); - errorCodeMap.put(61, "dnode ip exists"); - errorCodeMap.put(62, "sdb error"); - errorCodeMap.put(63, "metric meta expired"); // local cached metric-meta expired causes error in metric query - errorCodeMap.put(64, "not ready"); // peer is not ready to process data - errorCodeMap.put(65, "too many sessions on server"); // too many sessions - errorCodeMap.put(66, "too many sessions from app"); // too many connections - errorCodeMap.put(67, "session to dest is already there"); - errorCodeMap.put(68, "query list not there); please show again"); - errorCodeMap.put(69, "server out of memory"); - errorCodeMap.put(70, "invalid query handle"); - errorCodeMap.put(71, "tables related to metric exist"); - errorCodeMap.put(72, "can't drop monitor database or tables"); - errorCodeMap.put(73, "commit log init failed"); - errorCodeMap.put(74, "vgroup init failed"); - errorCodeMap.put(75, "data is already imported"); - errorCodeMap.put(76, "not supported operation"); - errorCodeMap.put(77, "invalid query id string"); - errorCodeMap.put(78, "invalid stream id string"); - errorCodeMap.put(79, "invalid connection string"); - errorCodeMap.put(80, "dnode not balanced"); - errorCodeMap.put(81, "client out of memory"); - errorCodeMap.put(82, "data value overflow"); - errorCodeMap.put(83, "query cancelled"); - errorCodeMap.put(84, "grant points limited"); - errorCodeMap.put(85, "grant expired"); - errorCodeMap.put(86, "client no disk space"); - errorCodeMap.put(87, "DB file corrupted"); - errorCodeMap.put(88, "version of client and server not match"); - } - - TSDBError(long code, String message) { - this.errCode = code; - this.errMessage = message; - } - - public long getErrCode() { - return this.errCode; - } - - public String getErrMessage() { - return this.errMessage; - } - - public static String getErrMessageByCode(long errCode) { - return errorCodeMap.get(errCode); - } - -} diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java index 8bb7084604..e9acffe0e3 100755 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java @@ -19,7 +19,7 @@ import java.sql.SQLWarning; import java.util.List; public class TSDBJNIConnector { - static volatile Boolean isInitialized = false; + private static volatile Boolean isInitialized = false; static { System.loadLibrary("taos"); @@ -51,8 +51,6 @@ public class TSDBJNIConnector { /** * Returns the status of last result set in current connection - * - * @return */ public boolean isResultsetClosed() { return this.isResultsetClosed; @@ -112,7 +110,7 @@ public class TSDBJNIConnector { * * @throws SQLException */ - public int executeQuery(String sql) throws SQLException { + public long executeQuery(String sql) throws SQLException { if (!this.isResultsetClosed) { freeResultSet(taosResultSetPointer); } @@ -127,7 +125,6 @@ public class TSDBJNIConnector { } int code = this.getErrCode(pSql); - affectedRows = code; if (code < 0) { affectedRows = -1; if (code == TSDBConstants.JNI_TDENGINE_ERROR) { @@ -146,7 +143,7 @@ public class TSDBJNIConnector { if (taosResultSetPointer != TSDBConstants.JNI_NULL_POINTER) { isResultsetClosed = false; } - return code; + return pSql; } private native long executeQueryImp(byte[] sqlBytes, long connection); @@ -199,8 +196,6 @@ public class TSDBJNIConnector { /** * Close the open result set which is associated to the current connection. If the result set is already * closed, return 0 for success. - * - * @return */ public int freeResultSet() { int resCode = TSDBConstants.JNI_SUCCESS; @@ -217,7 +212,7 @@ public class TSDBJNIConnector { /** * Get affected rows count */ - public int getAffectedRows(Long pSql) { + public int getAffectedRows(long pSql) { int affectedRows = this.affectedRows; if (affectedRows < 0) { affectedRows = this.getAffectedRowsImp(this.taos, pSql); @@ -225,7 +220,7 @@ public class TSDBJNIConnector { return affectedRows; } - private native int getAffectedRowsImp(long connection, Long pSql); + private native int getAffectedRowsImp(long connection, long pSql); /** * Get schema metadata diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java index dbe1e41e6b..1cf024f30e 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java @@ -51,13 +51,16 @@ public class TSDBStatement implements Statement { if (isClosed) { throw new SQLException("Invalid method call on a closed statement."); } - this.connecter.executeQuery(sql); + pSql = this.connecter.executeQuery(sql); long resultSetPointer = this.connecter.getResultSet(); if (resultSetPointer == TSDBConstants.JNI_CONNECTION_NULL) { + this.connecter.freeResultSet(pSql); throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); } else if (resultSetPointer == TSDBConstants.JNI_NULL_POINTER) { +// create/insert/update/del/alter + this.connecter.freeResultSet(pSql); return null; } else { return new TSDBResultSet(this.connecter, resultSetPointer); @@ -68,17 +71,18 @@ public class TSDBStatement implements Statement { if (isClosed) { throw new SQLException("Invalid method call on a closed statement."); } - long res = this.connecter.executeQuery(sql); + pSql = this.connecter.executeQuery(sql); long resultSetPointer = this.connecter.getResultSet(); if (resultSetPointer == TSDBConstants.JNI_CONNECTION_NULL) { - this.connecter.freeResultSet(res); + this.connecter.freeResultSet(pSql); throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); } else if (resultSetPointer != TSDBConstants.JNI_NULL_POINTER) { this.connecter.freeResultSet(); throw new SQLException("The executed SQL is not a DML or a DDL"); } else { - int num = this.connecter.getAffectedRows(res); + int num = this.connecter.getAffectedRows(pSql); + this.connecter.freeResultSet(pSql); return num; } } @@ -146,16 +150,19 @@ public class TSDBStatement implements Statement { throw new SQLException("Invalid method call on a closed statement."); } boolean res = true; - this.connecter.executeQuery(sql); + pSql = this.connecter.executeQuery(sql); long resultSetPointer = this.connecter.getResultSet(); if (resultSetPointer == TSDBConstants.JNI_CONNECTION_NULL) { + this.connecter.freeResultSet(pSql); throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); } else if (resultSetPointer == TSDBConstants.JNI_NULL_POINTER) { // no result set is retrieved res = false; } - return res; + this.connecter.freeResultSet(pSql); + + return res; } public ResultSet getResultSet() throws SQLException { diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBSubscribe.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBSubscribe.java index 3b479aafc3..e20c6a815c 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBSubscribe.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBSubscribe.java @@ -171,8 +171,7 @@ public class TSDBSubscribe { state = 1; try { - TSDBResultSet resultSet = consume(subscription); - callBack.invoke(resultSet); + callBack.invoke(consume(subscription)); } catch (Exception e) { this.cancel(); throw new RuntimeException(e); diff --git a/src/connector/jdbc/src/test/java/TestAsyncTSDBSubscribe.java b/src/connector/jdbc/src/test/java/TestAsyncTSDBSubscribe.java index 5b2b6367ec..55ab2fdc52 100644 --- a/src/connector/jdbc/src/test/java/TestAsyncTSDBSubscribe.java +++ b/src/connector/jdbc/src/test/java/TestAsyncTSDBSubscribe.java @@ -3,10 +3,11 @@ import org.apache.commons.lang3.StringUtils; import java.sql.Connection; import java.sql.DriverManager; +import java.sql.SQLException; import java.util.Properties; public class TestAsyncTSDBSubscribe { - public static void main(String[] args) { + public static void main(String[] args) throws SQLException { String usage = "java -cp taos-jdbcdriver-1.0.3_dev-dist.jar com.taosdata.jdbc.TSDBSubscribe -db dbName -topic topicName " + "-tname tableName -h host"; if (args.length < 2) { @@ -38,15 +39,18 @@ public class TestAsyncTSDBSubscribe { } Connection connection = null; - TSDBSubscribe subscribe = null; long subscribId = 0; try { Class.forName("com.taosdata.jdbc.TSDBDriver"); Properties properties = new Properties(); - properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host); + properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host); + properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/" + dbName + "?user=root&password=taosdata", properties); String rawSql = "select * from " + tName + ";"; - subscribe = ((TSDBConnection) connection).createSubscribe(); + TSDBSubscribe subscribe = ((TSDBConnection) connection).createSubscribe(); subscribId = subscribe.subscribe(topic, rawSql, false, 1000, new CallBack("first")); long subscribId2 = subscribe.subscribe("test", rawSql, false, 1000, new CallBack("second")); int a = 0; @@ -55,6 +59,9 @@ public class TestAsyncTSDBSubscribe { System.err.println("cancel subscribe"); } catch (Exception e) { e.printStackTrace(); + if (null != connection && !connection.isClosed()) { + connection.close(); + } } } diff --git a/src/connector/jdbc/src/test/java/TestPreparedStatement.java b/src/connector/jdbc/src/test/java/TestPreparedStatement.java index 3b84645b5b..2e387206a4 100644 --- a/src/connector/jdbc/src/test/java/TestPreparedStatement.java +++ b/src/connector/jdbc/src/test/java/TestPreparedStatement.java @@ -6,24 +6,31 @@ import java.util.Properties; public class TestPreparedStatement { - public static void main(String[] args) { + public static void main(String[] args) throws SQLException { + Connection connection = null; try { Class.forName("com.taosdata.jdbc.TSDBDriver"); Properties properties = new Properties(); properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, "localhost"); - Connection connection = DriverManager.getConnection("jdbc:TAOS://localhost:0/?user=root&password=taosdata", properties); + connection = DriverManager.getConnection("jdbc:TAOS://localhost:0/?user=root&password=taosdata", properties); String rawSql = "select * from test.log0601"; // String[] params = new String[]{"ts", "c1"}; PreparedStatement pstmt = (TSDBPreparedStatement) connection.prepareStatement(rawSql); ResultSet resSet = pstmt.executeQuery(); while(resSet.next()) { for (int i = 1; i <= resSet.getMetaData().getColumnCount(); i++) { - System.out.printf("%d: %s\n", i, resSet.getString(i)); + System.out.printf("%d: %s \n", i, resSet.getString(i)); } } + resSet.close(); + pstmt.close(); + connection.close(); } catch (Exception e) { e.printStackTrace(); + if (null != connection) { + connection.close(); + } } } } diff --git a/src/connector/jdbc/src/test/java/TestTSDBDatabaseMetaData.java b/src/connector/jdbc/src/test/java/TestTSDBDatabaseMetaData.java index 519d7c6ab1..f7e0e78441 100644 --- a/src/connector/jdbc/src/test/java/TestTSDBDatabaseMetaData.java +++ b/src/connector/jdbc/src/test/java/TestTSDBDatabaseMetaData.java @@ -1,29 +1,33 @@ import com.taosdata.jdbc.TSDBDriver; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.DriverManager; -import java.sql.ResultSet; +import java.sql.*; import java.util.Properties; public class TestTSDBDatabaseMetaData { - public static void main(String[] args) { + public static void main(String[] args) throws SQLException { + Connection connection = null; + DatabaseMetaData dbMetaData = null; + ResultSet resSet = null; try { Class.forName("com.taosdata.jdbc.TSDBDriver"); Properties properties = new Properties(); - properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, "192.168.1.114"); - Connection connection = DriverManager.getConnection("jdbc:TAOS://192.168.1.114:0/?user=root&password=taosdata", properties); - DatabaseMetaData dbMetaData = connection.getMetaData(); - ResultSet resSet = dbMetaData.getCatalogs(); + properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, "localhost"); + connection = DriverManager.getConnection("jdbc:TAOS://localhost:0/?user=root&password=taosdata", properties); + dbMetaData = connection.getMetaData(); + resSet = dbMetaData.getCatalogs(); while(resSet.next()) { for (int i = 1; i <= resSet.getMetaData().getColumnCount(); i++) { System.out.printf("dbMetaData.getCatalogs(%d) = %s\n", i, resSet.getString(i)); } } + resSet.close(); } catch (Exception e) { e.printStackTrace(); + if (null != connection) { + connection.close(); + } } } } diff --git a/src/connector/jdbc/src/test/java/TestTSDBSubscribe.java b/src/connector/jdbc/src/test/java/TestTSDBSubscribe.java index f12924c8a6..f628f3cada 100644 --- a/src/connector/jdbc/src/test/java/TestTSDBSubscribe.java +++ b/src/connector/jdbc/src/test/java/TestTSDBSubscribe.java @@ -46,16 +46,20 @@ public class TestTSDBSubscribe { try { Class.forName("com.taosdata.jdbc.TSDBDriver"); Properties properties = new Properties(); - properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host); + properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host); + properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/" + dbName + "?user=root&password=taosdata" , properties); String rawSql = "select * from " + tName + ";"; subscribe = ((TSDBConnection) connection).createSubscribe(); subscribId = subscribe.subscribe(topic, rawSql, false, 1000); int a = 0; + TSDBResultSet resSet = null; while (true) { Thread.sleep(900); - TSDBResultSet resSet = subscribe.consume(subscribId); + resSet = subscribe.consume(subscribId); while (resSet.next()) { for (int i = 1; i <= resSet.getMetaData().getColumnCount(); i++) { diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/AsyncSubscribeTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/AsyncSubscribeTest.java new file mode 100644 index 0000000000..98b0d38b8d --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/AsyncSubscribeTest.java @@ -0,0 +1,99 @@ +package com.taosdata.jdbc; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Properties; + +import static org.junit.Assert.assertTrue; + +public class AsyncSubscribeTest { + Connection connection = null; + Statement statement = null; + String dbName = "test"; + String tName = "t0"; + String host = "localhost"; + String topic = "test"; + long subscribId = 0; + + @Before + public void createDatabase() throws SQLException { + try { + Class.forName("com.taosdata.jdbc.TSDBDriver"); + } catch (ClassNotFoundException e) { + return; + } + Properties properties = new Properties(); + properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host); + properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); + connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/" + "?user=root&password=taosdata" + , properties); + + statement = connection.createStatement(); + statement.executeUpdate("create database if not exists " + dbName); + statement.executeUpdate("create table if not exists " + dbName + "." + tName + " (ts timestamp, k int, v int)"); + long ts = System.currentTimeMillis(); + for (int i = 0; i < 2; i++) { + ts += i; + statement.executeUpdate("insert into \" + dbName + \".\" + tName + \" values (" + ts + ", " + (100 + i) + ", " + i + ")"); + } + } + + @Test + public void subscribe() throws Exception { + TSDBSubscribe subscribe = null; + try { + String rawSql = "select * from " + dbName + "." + tName + ";"; + System.out.println(rawSql); + subscribe = ((TSDBConnection) connection).createSubscribe(); + subscribId = subscribe.subscribe(topic, rawSql, false, 1000, new CallBack("first")); + + assertTrue(subscribId > 0); + } catch (Exception e) { + e.printStackTrace(); + } + + Thread.sleep(2000); + subscribe.unsubscribe(subscribId, true); + } + + private static class CallBack implements TSDBSubscribeCallBack { + private String name = ""; + + public CallBack(String name) { + this.name = name; + } + + @Override + public void invoke(TSDBResultSet resultSet) { + try { + while (null != resultSet && resultSet.next()) { + System.out.print("callback_" + name + ": "); + for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++) { + System.out.printf(i + ": " + resultSet.getString(i) + "\t"); + } + System.out.println(); + } + resultSet.close(); + + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + @After + public void close() throws Exception { + statement.executeQuery("drop database test"); + statement.close(); + connection.close(); + Thread.sleep(10); + } +} \ No newline at end of file diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/ConnectionTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/ConnectionTest.java new file mode 100644 index 0000000000..5e5dabfe81 --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/ConnectionTest.java @@ -0,0 +1,62 @@ +package com.taosdata.jdbc; + +import org.junit.Test; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Properties; + +import static org.junit.Assert.assertTrue; + +public class ConnectionTest { + static Connection connection = null; + static Statement statement = null; + static String dbName = "test"; + static String stbName = "st"; + static String host = "localhost"; + + @Test + public void testConnection() throws SQLException { + try { + Class.forName("com.taosdata.jdbc.TSDBDriver"); + } catch (ClassNotFoundException e) { + return; + } + Properties properties = new Properties(); + properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host); + properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); + connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/" + "?user=root&password=taosdata" + , properties); + + assertTrue(null != connection); + statement = connection.createStatement(); + assertTrue(null != statement); + + // try reconnect + connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/" + "?user=root&password=taosdata" + , properties); + + try { + statement.execute("create database if not exists " + dbName); + } catch (SQLException e) { + assert false : "create database error: " + e.getMessage(); + } + + try { + if (!connection.isClosed()) { + if (!statement.isClosed()) { + statement.executeUpdate("drop database " + dbName); + statement.close(); + } + connection.close(); + Thread.sleep(10); + } + } catch (Exception e) { + assert false : "close connection error: " + e.getMessage(); + } + } +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/DatabaseMetaDataTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/DatabaseMetaDataTest.java new file mode 100644 index 0000000000..20ebc093ec --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/DatabaseMetaDataTest.java @@ -0,0 +1,245 @@ +package com.taosdata.jdbc; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.sql.*; +import java.util.Properties; + +public class DatabaseMetaDataTest { + static Connection connection = null; + static PreparedStatement statement = null; + static String dbName = "test"; + static String tName = "t0"; + static String host = "localhost"; + + @BeforeClass + public static void createConnection() throws SQLException { + try { + Class.forName("com.taosdata.jdbc.TSDBDriver"); + } catch (ClassNotFoundException e) { + return; + } + Properties properties = new Properties(); + properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host); + properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); + connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/" + "?user=root&password=taosdata", + properties); + + String sql = "drop database if exists " + dbName; + statement = (TSDBPreparedStatement) connection.prepareStatement(sql); + statement.executeUpdate("create database if not exists " + dbName); + statement.executeUpdate("create table if not exists " + dbName + "." + tName + " (ts timestamp, k int, v int)"); + } + + @Test + public void testMetaDataTest() throws SQLException { + + DatabaseMetaData databaseMetaData = connection.getMetaData(); + ResultSet resultSet = databaseMetaData.getTables(dbName, "t*", "t*", new String[]{"t"}); + while (resultSet.next()) { + for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++) { + System.out.printf("%d: %s\n", i, resultSet.getString(i)); + } + } + resultSet.close(); + databaseMetaData.isWrapperFor(null); + databaseMetaData.allProceduresAreCallable(); + databaseMetaData.allTablesAreSelectable(); + databaseMetaData.getURL(); + databaseMetaData.getUserName(); + databaseMetaData.isReadOnly(); + databaseMetaData.nullsAreSortedHigh(); + databaseMetaData.nullsAreSortedLow(); + databaseMetaData.nullsAreSortedAtStart(); + databaseMetaData.nullsAreSortedAtEnd(); + databaseMetaData.getDatabaseProductName(); + databaseMetaData.getDatabaseProductVersion(); + databaseMetaData.getDriverName(); + databaseMetaData.getDriverVersion(); + databaseMetaData.getDriverMajorVersion(); + databaseMetaData.getDriverMinorVersion(); + databaseMetaData.usesLocalFiles(); + databaseMetaData.usesLocalFilePerTable(); + databaseMetaData.supportsMixedCaseIdentifiers(); + databaseMetaData.storesUpperCaseIdentifiers(); + databaseMetaData.storesLowerCaseIdentifiers(); + databaseMetaData.storesMixedCaseIdentifiers(); + databaseMetaData.supportsMixedCaseQuotedIdentifiers(); + databaseMetaData.storesUpperCaseQuotedIdentifiers(); + databaseMetaData.storesLowerCaseQuotedIdentifiers(); + databaseMetaData.storesMixedCaseQuotedIdentifiers(); + databaseMetaData.getIdentifierQuoteString(); + databaseMetaData.getSQLKeywords(); + databaseMetaData.getNumericFunctions(); + databaseMetaData.getStringFunctions(); + databaseMetaData.getSystemFunctions(); + databaseMetaData.getTimeDateFunctions(); + databaseMetaData.getSearchStringEscape(); + databaseMetaData.getExtraNameCharacters(); + databaseMetaData.supportsAlterTableWithAddColumn(); + databaseMetaData.supportsAlterTableWithDropColumn(); + databaseMetaData.supportsColumnAliasing(); + databaseMetaData.nullPlusNonNullIsNull(); + databaseMetaData.supportsConvert(); + databaseMetaData.supportsConvert(0, 0); + databaseMetaData.supportsTableCorrelationNames(); + databaseMetaData.supportsDifferentTableCorrelationNames(); + databaseMetaData.supportsExpressionsInOrderBy(); + databaseMetaData.supportsOrderByUnrelated(); + databaseMetaData.supportsGroupBy(); + databaseMetaData.supportsGroupByUnrelated(); + databaseMetaData.supportsGroupByBeyondSelect(); + databaseMetaData.supportsLikeEscapeClause(); + databaseMetaData.supportsMultipleResultSets(); + databaseMetaData.supportsMultipleTransactions(); + databaseMetaData.supportsNonNullableColumns(); + databaseMetaData.supportsMinimumSQLGrammar(); + databaseMetaData.supportsCoreSQLGrammar(); + databaseMetaData.supportsExtendedSQLGrammar(); + databaseMetaData.supportsANSI92EntryLevelSQL(); + databaseMetaData.supportsANSI92IntermediateSQL(); + databaseMetaData.supportsANSI92FullSQL(); + databaseMetaData.supportsIntegrityEnhancementFacility(); + databaseMetaData.supportsOuterJoins(); + databaseMetaData.supportsFullOuterJoins(); + databaseMetaData.supportsLimitedOuterJoins(); + databaseMetaData.getSchemaTerm(); + databaseMetaData.getProcedureTerm(); + databaseMetaData.getCatalogTerm(); + databaseMetaData.isCatalogAtStart(); + databaseMetaData.getCatalogSeparator(); + databaseMetaData.supportsSchemasInDataManipulation(); + databaseMetaData.supportsSchemasInProcedureCalls(); + databaseMetaData.supportsSchemasInTableDefinitions(); + databaseMetaData.supportsSchemasInIndexDefinitions(); + databaseMetaData.supportsSchemasInPrivilegeDefinitions(); + databaseMetaData.supportsCatalogsInDataManipulation(); + databaseMetaData.supportsCatalogsInProcedureCalls(); + databaseMetaData.supportsCatalogsInTableDefinitions(); + databaseMetaData.supportsCatalogsInIndexDefinitions(); + databaseMetaData.supportsCatalogsInPrivilegeDefinitions(); + databaseMetaData.supportsPositionedDelete(); + databaseMetaData.supportsPositionedUpdate(); + databaseMetaData.supportsSelectForUpdate(); + databaseMetaData.supportsStoredProcedures(); + databaseMetaData.supportsSubqueriesInComparisons(); + databaseMetaData.supportsSubqueriesInExists(); + databaseMetaData.supportsSubqueriesInIns(); + databaseMetaData.supportsSubqueriesInQuantifieds(); + databaseMetaData.supportsCorrelatedSubqueries(); + databaseMetaData.supportsUnion(); + databaseMetaData.supportsUnionAll(); + databaseMetaData.supportsOpenCursorsAcrossCommit(); + databaseMetaData.supportsOpenCursorsAcrossRollback(); + databaseMetaData.supportsOpenStatementsAcrossCommit(); + databaseMetaData.supportsOpenStatementsAcrossRollback(); + databaseMetaData.getMaxBinaryLiteralLength(); + databaseMetaData.getMaxCharLiteralLength(); + databaseMetaData.getMaxColumnNameLength(); + databaseMetaData.getMaxColumnsInGroupBy(); + databaseMetaData.getMaxColumnsInIndex(); + databaseMetaData.getMaxColumnsInOrderBy(); + databaseMetaData.getMaxColumnsInSelect(); + databaseMetaData.getMaxColumnsInTable(); + databaseMetaData.getMaxConnections(); + databaseMetaData.getMaxCursorNameLength(); + databaseMetaData.getMaxIndexLength(); + databaseMetaData.getMaxSchemaNameLength(); + databaseMetaData.getMaxProcedureNameLength(); + databaseMetaData.getMaxCatalogNameLength(); + databaseMetaData.getMaxRowSize(); + databaseMetaData.doesMaxRowSizeIncludeBlobs(); + databaseMetaData.getMaxStatementLength(); + databaseMetaData.getMaxStatements(); + databaseMetaData.getMaxTableNameLength(); + databaseMetaData.getMaxTablesInSelect(); + databaseMetaData.getMaxUserNameLength(); + databaseMetaData.getDefaultTransactionIsolation(); + databaseMetaData.supportsTransactions(); + databaseMetaData.supportsTransactionIsolationLevel(0); + databaseMetaData.supportsDataDefinitionAndDataManipulationTransactions(); + databaseMetaData.supportsDataManipulationTransactionsOnly(); + databaseMetaData.dataDefinitionCausesTransactionCommit(); + databaseMetaData.dataDefinitionIgnoredInTransactions(); + try { + databaseMetaData.getProcedures("", "", ""); + } catch (Exception e) { + } + try { + databaseMetaData.getProcedureColumns("", "", "", ""); + } catch (Exception e) { + } + try { + databaseMetaData.getTables("", "", "", new String[]{""}); + } catch (Exception e) { + } + databaseMetaData.getSchemas(); + databaseMetaData.getCatalogs(); +// databaseMetaData.getTableTypes(); + + databaseMetaData.getColumns("", "", "", ""); + databaseMetaData.getColumnPrivileges("", "", "", ""); + databaseMetaData.getTablePrivileges("", "", ""); + databaseMetaData.getBestRowIdentifier("", "", "", 0, false); + databaseMetaData.getVersionColumns("", "", ""); + databaseMetaData.getPrimaryKeys("", "", ""); + databaseMetaData.getImportedKeys("", "", ""); + databaseMetaData.getExportedKeys("", "", ""); + databaseMetaData.getCrossReference("", "", "", "", "", ""); + databaseMetaData.getTypeInfo(); + databaseMetaData.getIndexInfo("", "", "", false, false); + databaseMetaData.supportsResultSetType(0); + databaseMetaData.supportsResultSetConcurrency(0, 0); + databaseMetaData.ownUpdatesAreVisible(0); + databaseMetaData.ownDeletesAreVisible(0); + databaseMetaData.ownInsertsAreVisible(0); + databaseMetaData.othersUpdatesAreVisible(0); + databaseMetaData.othersDeletesAreVisible(0); + databaseMetaData.othersInsertsAreVisible(0); + databaseMetaData.updatesAreDetected(0); + databaseMetaData.deletesAreDetected(0); + databaseMetaData.insertsAreDetected(0); + databaseMetaData.supportsBatchUpdates(); + databaseMetaData.getUDTs("", "", "", new int[]{0}); + databaseMetaData.getConnection(); + databaseMetaData.supportsSavepoints(); + databaseMetaData.supportsNamedParameters(); + databaseMetaData.supportsMultipleOpenResults(); + databaseMetaData.supportsGetGeneratedKeys(); + databaseMetaData.getSuperTypes("", "", ""); + databaseMetaData.getSuperTables("", "", ""); + databaseMetaData.getAttributes("", "", "", ""); + databaseMetaData.supportsResultSetHoldability(0); + databaseMetaData.getResultSetHoldability(); + databaseMetaData.getDatabaseMajorVersion(); + databaseMetaData.getDatabaseMinorVersion(); + databaseMetaData.getJDBCMajorVersion(); + databaseMetaData.getJDBCMinorVersion(); + databaseMetaData.getSQLStateType(); + databaseMetaData.locatorsUpdateCopy(); + databaseMetaData.supportsStatementPooling(); + databaseMetaData.getRowIdLifetime(); + databaseMetaData.getSchemas("", ""); + databaseMetaData.supportsStoredFunctionsUsingCallSyntax(); + databaseMetaData.autoCommitFailureClosesAllResultSets(); + databaseMetaData.getClientInfoProperties(); + databaseMetaData.getFunctions("", "", ""); + databaseMetaData.getFunctionColumns("", "", "", ""); + databaseMetaData.getPseudoColumns("", "", "", ""); + databaseMetaData.generatedKeyAlwaysReturned(); + + } + + @AfterClass + public static void close() throws Exception { + statement.executeUpdate("drop database " + dbName); + statement.close(); + connection.close(); + Thread.sleep(10); + + } +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/ImportTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/ImportTest.java new file mode 100644 index 0000000000..b42d46aefe --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/ImportTest.java @@ -0,0 +1,93 @@ +package com.taosdata.jdbc; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.sql.*; +import java.util.Properties; + +import static org.junit.Assert.assertEquals; + +public class ImportTest { + Connection connection = null; + Statement statement = null; + String dbName = "test"; + String tName = "t0"; + String host = "localhost"; + + @Before + public void createDatabase() throws SQLException { + try { + Class.forName("com.taosdata.jdbc.TSDBDriver"); + } catch (ClassNotFoundException e) { + return; + } + Properties properties = new Properties(); + properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host); + properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); + connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/" + "?user=root&password=taosdata" + , properties); + + statement = connection.createStatement(); + statement.executeUpdate("drop database if exists " + dbName); + statement.executeUpdate("create database if not exists " + dbName); + statement.executeUpdate("create table if not exists " + dbName + "." + tName + " (ts timestamp, k int, v int)"); + + } + + @Test + public void insertData() throws Exception { + long ts = 1496732686000l; + + for (int i = 0; i < 50; i++) { + ts++; + int row = statement.executeUpdate("insert into " + dbName + "." + tName + " values (" + ts + ", " + (100 + i) + ", " + i + ")"); + System.out.println("insert into " + dbName + "." + tName + " values (" + ts + ", " + (100 + i) + ", " + i + ")\t" + row); + assertEquals(1, row); + } + } + + @Test + public void selectData() throws Exception { + insertData(); + String sql = "select * from test.t0"; + ResultSet resSet = statement.executeQuery(sql); + + while (resSet.next()) { + for (int i = 1; i <= resSet.getMetaData().getColumnCount(); i++) { + System.out.printf(i + ": " + resSet.getString(i) + "\t"); + } + } + resSet.close(); + } + + @Test + public void importData() throws Exception { + // 避免时间重复 + long ts = 1496732686000l; + + StringBuilder sqlBuilder = new StringBuilder("insert into ").append(dbName).append(".").append(tName).append(" values "); + + for (int i = 0; i < 50; i++) { + int a = i / 5; + long t = ts + a; + sqlBuilder.append("(").append(t).append(",").append((100 + i)).append(",").append(i).append(") "); + } + System.out.println(sqlBuilder.toString()); + int rows = statement.executeUpdate(sqlBuilder.toString()); + System.out.println(rows); + assertEquals(10, rows); + } + + @After + public void close() throws Exception { + statement.executeUpdate("drop database " + dbName); + statement.close(); + connection.close(); + Thread.sleep(10); + + } +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/PreparedStatementTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/PreparedStatementTest.java new file mode 100644 index 0000000000..4c49727a7f --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/PreparedStatementTest.java @@ -0,0 +1,201 @@ +package com.taosdata.jdbc; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import java.sql.*; +import java.util.Properties; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +@FixMethodOrder(MethodSorters.DEFAULT) +public class PreparedStatementTest { + static Connection connection = null; + static PreparedStatement statement = null; + static String dbName = "test"; + static String tName = "t0"; + static String host = "localhost"; + static ResultSet resSet = null; + + @BeforeClass + public static void createConnection() throws SQLException { + try { + Class.forName("com.taosdata.jdbc.TSDBDriver"); + } catch (ClassNotFoundException e) { + return; + } + Properties properties = new Properties(); + properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host); + properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); + connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/" + "?user=root&password=taosdata", + properties); + + String sql = "drop database if exists " + dbName; + statement = (TSDBPreparedStatement) connection.prepareStatement(sql); + + } + + @Test + public void createTableAndQuery() throws SQLException { + long ts = System.currentTimeMillis(); + + statement.executeUpdate("create database if not exists " + dbName); + statement.executeUpdate("create table if not exists " + dbName + "." + tName + "(ts timestamp, k1 int)"); + statement.executeUpdate("insert into " + dbName + "." + tName + " values (" + ts + ", 1)"); + + PreparedStatement selectStatement = connection.prepareStatement("select * from " + dbName + "." + tName); + + ResultSet resultSet = selectStatement.executeQuery(); + assertTrue(null != resultSet); + + boolean isClosed = statement.isClosed(); + assertEquals(false, isClosed); + } + + @Test + public void testPreparedStatement() throws SQLException { + long ts = System.currentTimeMillis() + 20000; + PreparedStatement saveStatement = connection + .prepareStatement("insert into " + dbName + "." + tName + " values (" + ts + ", 1)"); + + int affectedRows = saveStatement.executeUpdate(); + assertTrue(1 == affectedRows); + } + + @Test + public void testSavedPreparedStatement() throws SQLException { + long ts = System.currentTimeMillis(); + + TSDBPreparedStatement saveStatement = (TSDBPreparedStatement) connection + .prepareStatement("insert into " + dbName + "." + tName + " values (?, ?)"); + + saveStatement.setObject(1, ts + 10000); + saveStatement.setObject(2, 3); + int rows = saveStatement.executeUpdate(); + assertEquals(1, rows); + } + + @Test + public void testUnsupport() { + // if(null == resSet) { + // return; + // } + TSDBPreparedStatement tsdbStatement = (TSDBPreparedStatement) statement; + try { + tsdbStatement.unwrap(null); + } catch (SQLException e) { + } + try { + tsdbStatement.isWrapperFor(null); + } catch (SQLException e) { + } + try { + tsdbStatement.getMaxFieldSize(); + } catch (SQLException e) { + } + try { + tsdbStatement.setMaxFieldSize(0); + } catch (SQLException e) { + } + try { + tsdbStatement.setEscapeProcessing(true); + } catch (SQLException e) { + } + try { + tsdbStatement.cancel(); + } catch (SQLException e) { + } + try { + tsdbStatement.getWarnings(); + } catch (SQLException e) { + } + try { + tsdbStatement.clearWarnings(); + } catch (SQLException e) { + } + try { + tsdbStatement.setCursorName(null); + } catch (SQLException e) { + } + try { + tsdbStatement.getMoreResults(); + } catch (SQLException e) { + } + try { + tsdbStatement.setFetchDirection(0); + } catch (SQLException e) { + } + try { + tsdbStatement.getFetchDirection(); + } catch (SQLException e) { + } + try { + tsdbStatement.getResultSetConcurrency(); + } catch (SQLException e) { + } + try { + tsdbStatement.getResultSetType(); + } catch (SQLException e) { + } + try { + tsdbStatement.getConnection(); + } catch (SQLException e) { + } + try { + tsdbStatement.getMoreResults(); + } catch (SQLException e) { + } + try { + tsdbStatement.getGeneratedKeys(); + } catch (SQLException e) { + } + try { + tsdbStatement.executeUpdate(null, 0); + } catch (SQLException e) { + } + try { + tsdbStatement.executeUpdate(null, new int[]{0}); + } catch (SQLException e) { + } + try { + tsdbStatement.executeUpdate(null, new String[]{"str1", "str2"}); + } catch (SQLException e) { + } + try { + tsdbStatement.getResultSetHoldability(); + } catch (SQLException e) { + } + try { + tsdbStatement.setPoolable(true); + } catch (SQLException e) { + } + try { + tsdbStatement.isPoolable(); + } catch (SQLException e) { + } + try { + tsdbStatement.closeOnCompletion(); + } catch (SQLException e) { + } + try { + tsdbStatement.isCloseOnCompletion(); + } catch (SQLException e) { + } + } + + @AfterClass + public static void close() throws Exception { + statement.executeUpdate("drop database " + dbName); + statement.close(); + connection.close(); + Thread.sleep(10); + + } + +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/ResultSetTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/ResultSetTest.java new file mode 100644 index 0000000000..2b74a98db2 --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/ResultSetTest.java @@ -0,0 +1,829 @@ +package com.taosdata.jdbc; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import javax.sql.rowset.serial.SerialBlob; +import javax.sql.rowset.serial.SerialClob; +import java.sql.*; +import java.util.HashMap; +import java.util.Properties; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class ResultSetTest { + static Connection connection = null; + static Statement statement = null; + static String dbName = "test"; + static String tName = "t0"; + static String host = "localhost"; + static ResultSet resSet = null; + + @BeforeClass + public static void createDatabaseAndTable() throws SQLException { + try { + Class.forName("com.taosdata.jdbc.TSDBDriver"); + } catch (ClassNotFoundException e) { + return; + } + Properties properties = new Properties(); + properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host); + properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); + + connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/" + "?user=root&password=taosdata" + , properties); + + statement = connection.createStatement(); + statement.executeUpdate("drop database if exists " + dbName); + statement.executeUpdate("create database if not exists " + dbName); + statement.executeUpdate("create table if not exists " + dbName + "." + tName + + " (ts timestamp, k1 int, k2 bigint, k3 float, k4 double, k5 binary(30), k6 smallint, k7 bool, k8 nchar(20))"); + + statement.executeQuery("use " + dbName); + } + + @Test + public void testResultSet() { + String sql = null; + long ts = 1496732686000l; + int v1 = 2147483600; + long v2 = ts + 1000; + float v3 = 3.1415926f; + double v4 = 3.1415926535897; + String v5 = "涛思数据,强~!"; + short v6 = 12; + boolean v7 = false; + String v8 = "TDengine is powerful"; + + sql = "insert into " + dbName + "." + tName + " values (" + ts + "," + v1 + "," + v2 + "," + v3 + "," + v4 + + ",\"" + v5 + "\"," + v6 + "," + v7 + ",\"" + v8 + "\")"; + + try { + statement.executeUpdate(sql); + assertEquals(1, statement.getUpdateCount()); + } catch (SQLException e) { + assert false : "insert error " + e.getMessage(); + } + + try { + statement.executeQuery("select * from " + dbName + "." + tName); + resSet = statement.getResultSet(); + System.out.println(((TSDBResultSet) resSet).getRowData()); + while (resSet.next()) { + assertEquals(ts, resSet.getLong(1)); + assertEquals(ts, resSet.getLong("ts")); + + System.out.println(resSet.getTimestamp(1)); + + assertEquals(v1, resSet.getInt(2)); + assertEquals(v1, resSet.getInt("k1")); + + assertEquals(v2, resSet.getLong(3)); + assertEquals(v2, resSet.getLong("k2")); + + assertEquals(v3, resSet.getFloat(4), 7); + assertEquals(v3, resSet.getFloat("k3"), 7); + + assertEquals(v4, resSet.getDouble(5), 13); + assertEquals(v4, resSet.getDouble("k4"), 13); + + assertEquals(v5, resSet.getString(6)); + assertEquals(v5, resSet.getString("k5")); + + assertEquals(v6, resSet.getShort(7)); + assertEquals(v6, resSet.getShort("k6")); + + assertEquals(v7, resSet.getBoolean(8)); + assertEquals(v7, resSet.getBoolean("k7")); + + assertEquals(v8, resSet.getString(9)); + assertEquals(v8, resSet.getString("k8")); + + resSet.getBytes(9); + resSet.getObject(6); + resSet.getObject("k8"); + } + if (!resSet.isClosed()) { + resSet.close(); + } + } catch (SQLException e) { + assert false : "insert error " + e.getMessage(); + } + } + + @Test + public void testUnsupport() throws SQLException { + statement.executeQuery("show databases"); + resSet = statement.getResultSet(); + try { + resSet.unwrap(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.isWrapperFor(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getAsciiStream(0); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getUnicodeStream(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getBinaryStream(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getAsciiStream(""); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getUnicodeStream(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getBinaryStream(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getWarnings(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.clearWarnings(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getCursorName(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getCharacterStream(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getCharacterStream(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.isBeforeFirst(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.isAfterLast(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.isFirst(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.isLast(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.beforeFirst(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.afterLast(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.first(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.last(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getRow(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.absolute(1); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.relative(1); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.previous(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.setFetchDirection(0); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getFetchDirection(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.setFetchSize(0); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getFetchSize(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getConcurrency(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.rowUpdated(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.rowInserted(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.rowDeleted(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateNull(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateBoolean(0, true); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateByte(0, (byte) 2); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateShort(0, (short) 1); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateInt(0, 0); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateLong(0, 0l); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateFloat(0, 3.14f); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateDouble(0, 3.1415); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateBigDecimal(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateString(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateBytes(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateDate(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateTime(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateTimestamp(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateAsciiStream(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateBinaryStream(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateCharacterStream(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateObject(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateObject(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateNull(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateBoolean("", false); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateByte("", (byte) 1); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateShort("", (short) 1); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateInt("", 0); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateLong("", 0l); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateFloat("", 3.14f); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateDouble("", 3.1415); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateBigDecimal(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateString(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateBytes(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateDate(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateTime(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateTimestamp(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateAsciiStream(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateBinaryStream(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateCharacterStream(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateObject(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateObject(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.insertRow(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateRow(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.deleteRow(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.refreshRow(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.cancelRowUpdates(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.moveToInsertRow(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.moveToCurrentRow(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getStatement(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getObject(0, new HashMap<>()); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getRef(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getBlob(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getClob(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getArray(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getObject("", new HashMap<>()); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getRef(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getBlob(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getClob(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getArray(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getDate(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getDate(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getTime(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getTime(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getTimestamp(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getTimestamp(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getURL(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getURL(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateRef(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateRef(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateBlob(0, new SerialBlob("".getBytes("UTF8"))); + } catch (Exception e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateBlob("", new SerialBlob("".getBytes("UTF8"))); + } catch (Exception e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateClob("", new SerialClob("".toCharArray())); + } catch (Exception e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateClob(0, new SerialClob("".toCharArray())); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateArray(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateArray(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getRowId(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getRowId(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateRowId(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateRowId(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getHoldability(); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateNString(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateNString(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + + try { + resSet.getNClob(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getNClob(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getSQLXML(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getSQLXML(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateSQLXML(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateSQLXML(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getNCharacterStream(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.getNCharacterStream(null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateNCharacterStream(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateNCharacterStream(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateAsciiStream(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateBinaryStream(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateCharacterStream(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateAsciiStream(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateBinaryStream(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateCharacterStream(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + + try { + resSet.updateNCharacterStream(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateNCharacterStream(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateAsciiStream(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateBinaryStream(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateCharacterStream(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateAsciiStream(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateBinaryStream(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + try { + resSet.updateCharacterStream(null, null); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("this operation is NOT supported currently!")); + } + } + + @Test + public void testBatch() throws SQLException { + String[] sqls = new String[]{"insert into test.t0 values (1496732686001,2147483600,1496732687000,3.1415925,3.1415926\n" + + "535897,\"涛思数据,强~!\",12,12,\"TDengine is powerful\")", "insert into test.t0 values (1496732686002,2147483600,1496732687000,3.1415925,3.1415926\n" + + "535897,\"涛思数据,强~!\",12,12,\"TDengine is powerful\")"}; + for (String sql : sqls) { + statement.addBatch(sql); + } + int[] res = statement.executeBatch(); + assertEquals(res.length, 2); + statement.clearBatch(); + } + + @AfterClass + public static void close() throws Exception { + statement.executeUpdate("drop database " + dbName); + statement.close(); + connection.close(); + Thread.sleep(10); + + } + +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/SelectTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/SelectTest.java new file mode 100644 index 0000000000..282ca6c1a7 --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/SelectTest.java @@ -0,0 +1,72 @@ +package com.taosdata.jdbc; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.sql.*; +import java.util.Properties; + +import static org.junit.Assert.assertEquals; + +public class SelectTest { + Connection connection = null; + Statement statement = null; + String dbName = "test"; + String tName = "t0"; + String host = "localhost"; + + @Before + public void createDatabaseAndTable() throws SQLException { + try { + Class.forName("com.taosdata.jdbc.TSDBDriver"); + } catch (ClassNotFoundException e) { + return; + } + Properties properties = new Properties(); + properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host); + properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); + connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/" + "?user=root&password=taosdata" + , properties); + + statement = connection.createStatement(); + statement.executeUpdate("drop database if exists " + dbName); + statement.executeUpdate("create database if not exists " + dbName); + statement.executeUpdate("create table if not exists " + dbName + "." + tName + " (ts timestamp, k int, v int)"); + + } + + @Test + public void selectData() throws SQLException { + long ts = 1496732686000l; + + for (int i = 0; i < 50; i++) { + ts++; + int row = statement.executeUpdate("insert into " + dbName + "." + tName + " values (" + ts + ", " + (100 + i) + ", " + i + ")"); + System.out.println("insert into " + dbName + "." + tName + " values (" + ts + ", " + (100 + i) + ", " + i + ")\t" + row); + assertEquals(1, row); + } + + String sql = "select * from " + dbName + "." + tName; + ResultSet resSet = statement.executeQuery(sql); + + int num = 0; + while (resSet.next()) { + num++; + } + resSet.close(); + + assertEquals(num, 50); + } + + @After + public void close() throws Exception { + statement.executeUpdate("drop database " + dbName); + statement.close(); + connection.close(); + Thread.sleep(10); + + } +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/StableTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/StableTest.java new file mode 100644 index 0000000000..b275112e18 --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/StableTest.java @@ -0,0 +1,123 @@ +package com.taosdata.jdbc; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import java.sql.*; +import java.util.Properties; + +import static org.junit.Assert.assertEquals; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class StableTest { + static Connection connection = null; + static Statement statement = null; + static String dbName = "test"; + static String stbName = "st"; + static String host = "localhost"; + + @BeforeClass + public static void createDatabase() throws SQLException { + try { + Class.forName("com.taosdata.jdbc.TSDBDriver"); + } catch (ClassNotFoundException e) { + return; + } + Properties properties = new Properties(); + properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host); + properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); + connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/" + "?user=root&password=taosdata" + , properties); + + statement = connection.createStatement(); + statement.executeUpdate("create database if not exists " + dbName); + statement.executeQuery("use " + dbName); + } + +// @Test + public void createStable() { + String sql = "create table " + stbName + " (ts timestamp, v1 int, v2 int) tags (tg nchar(20)) "; + + try { + statement.executeUpdate(sql); + } catch (SQLException e) { + assert false : "error create stable" + e.getMessage(); + } + } + +// @Test + public void createTable() { + String sql = "create table t1 using " + stbName + " tags (\"beijing\")"; + + try { + statement.executeUpdate(sql); + } catch (SQLException e) { + assert false : "error create table" + e.getMessage(); + } + } + + @Test + public void describeSTable() { + createStable(); + String sql = "describe " + stbName; + int num = 0; + System.out.println("describe stable"); + try { + ResultSet res = statement.executeQuery(sql); + while (res.next()) { + for (int i = 1; i <= res.getMetaData().getColumnCount(); i++) { + System.out.printf("%d: %s\n", i, res.getString(i)); + } + num++; + } + res.close(); + assertEquals(4, num); + } catch (SQLException e) { + assert false : "error describe stable" + e.getMessage(); + } + } + + @Test + public void describeTable() { + createTable(); + String sql = "describe t1"; + int num = 0; + System.out.println("describe table"); + try { + ResultSet res = statement.executeQuery(sql); + while (res.next()) { + for (int i = 1; i <= res.getMetaData().getColumnCount(); i++) { + System.out.printf("%d: %s\n", i, res.getString(i)); + } + num++; + } + res.close(); + assertEquals(4, num); + } catch (SQLException e) { + assert false : "error describe stable" + e.getMessage(); + } + } + + // @Test + public void validCreateSql() { + String sql = "create table t2 using " + stbName + " tags (\"beijing\")"; + boolean valid = ((TSDBConnection) connection).getConnection().validateCreateTableSql(sql); + assertEquals(true, valid); + } + + @AfterClass + public static void close() throws Exception { + if (!statement.isClosed()) { + statement.executeUpdate("drop database " + dbName); + statement.close(); + connection.close(); + Thread.sleep(10); + + } + } +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/StatementTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/StatementTest.java new file mode 100644 index 0000000000..4be68519c5 --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/StatementTest.java @@ -0,0 +1,174 @@ +package com.taosdata.jdbc; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.sql.*; +import java.util.Properties; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class StatementTest { + static Connection connection = null; + static Statement statement = null; + static String dbName = "test"; + static String tName = "t0"; + static String host = "localhost"; + static ResultSet resSet = null; + + @BeforeClass + public static void createConnection() throws SQLException { + try { + Class.forName("com.taosdata.jdbc.TSDBDriver"); + } catch (ClassNotFoundException e) { + return; + } + Properties properties = new Properties(); + properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host); + properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); + connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/" + "?user=root&password=taosdata" + , properties); + + statement = connection.createStatement(); + statement.executeUpdate("drop database if exists " + dbName); + + } + + @Test + public void createTableAndQuery() throws SQLException { + long ts = System.currentTimeMillis(); + + statement.executeUpdate("create database if not exists " + dbName); + statement.executeUpdate("create table if not exists " + dbName + "." + tName + "(ts timestamp, k1 int)"); + statement.executeUpdate("insert into " + dbName + "." + tName + " values (" + ts + ", 1)"); + statement.executeQuery("select * from " + dbName + "." + tName); + ResultSet resultSet = statement.getResultSet(); + assertTrue(null != resultSet); + + boolean isClosed = statement.isClosed(); + assertEquals(false, isClosed); + } + + @Test + public void testUnsupport() { +// if(null == resSet) { +// return; +// } + TSDBStatement tsdbStatement = (TSDBStatement) statement; + try { + tsdbStatement.unwrap(null); + } catch (SQLException e) { + } + try { + tsdbStatement.isWrapperFor(null); + } catch (SQLException e) { + } + try { + tsdbStatement.getMaxFieldSize(); + } catch (SQLException e) { + } + try { + tsdbStatement.setMaxFieldSize(0); + } catch (SQLException e) { + } + try { + tsdbStatement.setEscapeProcessing(true); + } catch (SQLException e) { + } + try { + tsdbStatement.cancel(); + } catch (SQLException e) { + } + try { + tsdbStatement.getWarnings(); + } catch (SQLException e) { + } + try { + tsdbStatement.clearWarnings(); + } catch (SQLException e) { + } + try { + tsdbStatement.setCursorName(null); + } catch (SQLException e) { + } + try { + tsdbStatement.getMoreResults(); + } catch (SQLException e) { + } + try { + tsdbStatement.setFetchDirection(0); + } catch (SQLException e) { + } + try { + tsdbStatement.getFetchDirection(); + } catch (SQLException e) { + } + try { + tsdbStatement.getResultSetConcurrency(); + } catch (SQLException e) { + } + try { + tsdbStatement.getResultSetType(); + } catch (SQLException e) { + } + try { + tsdbStatement.getConnection(); + } catch (SQLException e) { + } + try { + tsdbStatement.getMoreResults(); + } catch (SQLException e) { + } + try { + tsdbStatement.getGeneratedKeys(); + } catch (SQLException e) { + } + try { + tsdbStatement.executeUpdate(null, 0); + } catch (SQLException e) { + } + try { + tsdbStatement.executeUpdate(null, new int[]{0}); + } catch (SQLException e) { + } + try { + tsdbStatement.executeUpdate(null, new String[]{"str1", "str2"}); + } catch (SQLException e) { + } + try { + tsdbStatement.getResultSetHoldability(); + } catch (SQLException e) { + } + try { + tsdbStatement.setPoolable(true); + } catch (SQLException e) { + } + try { + tsdbStatement.isPoolable(); + } catch (SQLException e) { + } + try { + tsdbStatement.closeOnCompletion(); + } catch (SQLException e) { + } + try { + tsdbStatement.isCloseOnCompletion(); + } catch (SQLException e) { + } + } + + @AfterClass + public static void close() throws Exception { + if (!statement.isClosed()) { + statement.executeUpdate("drop database " + dbName); + statement.close(); + connection.close(); + Thread.sleep(10); + + } + } +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/SubscribeTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/SubscribeTest.java new file mode 100644 index 0000000000..25f7f7a285 --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/SubscribeTest.java @@ -0,0 +1,94 @@ +package com.taosdata.jdbc; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Properties; + +import static org.junit.Assert.assertTrue; + +public class SubscribeTest { + Connection connection = null; + Statement statement = null; + String dbName = "test"; + String tName = "t0"; + String host = "localhost"; + String topic = "test"; + + @Before + public void createDatabase() throws SQLException { + try { + Class.forName("com.taosdata.jdbc.TSDBDriver"); + } catch (ClassNotFoundException e) { + return; + } + Properties properties = new Properties(); + properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host); + properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); + connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/" + "?user=root&password=taosdata" + , properties); + + statement = connection.createStatement(); + statement.executeUpdate("create database if not exists " + dbName); + statement.executeUpdate("create table if not exists " + dbName + "." + tName + " (ts timestamp, k int, v int)"); + long ts = System.currentTimeMillis(); + for (int i = 0; i < 2; i++) { + ts += i; + statement.executeUpdate("insert into \" + dbName + \".\" + tName + \" values (" + ts + ", " + (100 + i) + ", " + i + ")"); + } + } + + @Test + public void subscribe() throws Exception { + TSDBSubscribe subscribe = null; + long subscribId = 0; + try { + + String rawSql = "select * from " + dbName + "." + tName + ";"; + System.out.println(rawSql); + subscribe = ((TSDBConnection) connection).createSubscribe(); + subscribId = subscribe.subscribe(topic, rawSql, false, 1000); + + assertTrue(subscribId > 0); + + int a = 0; + while (true) { + Thread.sleep(900); + TSDBResultSet resSet = subscribe.consume(subscribId); + + while (resSet.next()) { + for (int i = 1; i <= resSet.getMetaData().getColumnCount(); i++) { + System.out.printf(i + ": " + resSet.getString(i) + "\t"); + } + System.out.println("\n======" + a + "=========="); + } + resSet.close(); + a++; + if (a >= 2) { + break; + } + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (null != subscribe && 0 != subscribId) { + subscribe.unsubscribe(subscribId, true); + } + } + } + + @After + public void close() throws Exception { + statement.executeQuery("drop database " + dbName); + statement.close(); + connection.close(); + Thread.sleep(10); + } +} \ No newline at end of file diff --git a/src/kit/taosdump/taosdump.c b/src/kit/taosdump/taosdump.c index 7fa7ffa3a9..ccef783709 100644 --- a/src/kit/taosdump/taosdump.c +++ b/src/kit/taosdump/taosdump.c @@ -425,6 +425,7 @@ int taosGetTableRecordInfo(char *table, STableRecordInfo *pTableRecordInfo) { int taosDumpOut(SDumpArguments *arguments) { TAOS_ROW row; + TAOS_RES* result = NULL; char *temp = NULL; FILE *fp = NULL; int count = 0; @@ -464,7 +465,7 @@ int taosDumpOut(SDumpArguments *arguments) { taosDumpCharset(fp); sprintf(command, "show databases"); - TAOS_RES* result = taos_query(taos, command); + result = taos_query(taos, command); int32_t code = taos_errno(result); if (code != 0) { fprintf(stderr, "failed to run command: %s, reason: %s\n", command, taos_errstr(result)); @@ -571,7 +572,7 @@ int taosDumpOut(SDumpArguments *arguments) { fclose(fp); taos_close(taos); taos_free_result(result); - free(temp); + tfree(temp); taosFreeDbInfos(); return 0; @@ -579,7 +580,7 @@ _exit_failure: fclose(fp); taos_close(taos); taos_free_result(result); - free(temp); + tfree(temp); taosFreeDbInfos(); return -1; } diff --git a/src/kit/taosnetwork/client.c b/src/kit/taosnetwork/client.c index 65b866a99b..b2c7f729b5 100644 --- a/src/kit/taosnetwork/client.c +++ b/src/kit/taosnetwork/client.c @@ -13,6 +13,7 @@ * along with this program. If not, see . */ +#include #include #include #include @@ -34,6 +35,36 @@ typedef struct { char *host[15]; } info; +typedef struct Arguments { + char * host; + uint16_t port; + uint16_t max_port; +} SArguments; + +static struct argp_option options[] = { + {0, 'h', "host", 0, "The host to connect to TDEngine. Default is localhost.", 0}, + {0, 'p', "port", 0, "The TCP or UDP port number to use for the connection. Default is 6020.", 1}, + {0, 'm', "max port", 0, "The max TCP or UDP port number to use for the connection. Default is 6050.", 2}}; + +static error_t parse_opt(int key, char *arg, struct argp_state *state) { + + SArguments *arguments = state->input; + switch (key) { + case 'h': + arguments->host = arg; + break; + case 'p': + arguments->port = atoi(arg); + break; + case 'm': + arguments->max_port = atoi(arg); + break; + } + return 0; +} + +static struct argp argp = {options, parse_opt, 0, 0}; + void *checkPort(void *sarg) { info *pinfo = (info *)sarg; int port = pinfo->port; @@ -97,7 +128,7 @@ void *checkUPort(void *sarg) { sprintf(sendbuf, "send msg port_%d by udp", port); - socklen_t sin_size = sizeof(*(struct sockaddr*)&serverAddr); + socklen_t sin_size = sizeof(*(struct sockaddr *)&serverAddr); sendto(clientSocket, sendbuf, strlen(sendbuf), 0, (struct sockaddr *)&serverAddr, (int)sin_size); @@ -113,14 +144,19 @@ void *checkUPort(void *sarg) { return NULL; } -int main() { - int port = 6020; - char *host = "127.0.0.1"; +int main(int argc, char *argv[]) { + SArguments arguments = {"127.0.0.1", 6020, 6050}; + + argp_parse(&argp, argc, argv, 0, 0, &arguments); + + printf("host: %s\tport: %d\tmax_port: %d\n", arguments.host, arguments.port, arguments.max_port); + + int port = arguments.port; + char *host = arguments.host; info *tinfo = malloc(sizeof(info)); info *uinfo = malloc(sizeof(info)); - for (size_t i = 0; i < 30; i++) { - port++; + for (; port < arguments.max_port; port++) { printf("For test: %s:%d\n", host, port); *tinfo->host = host; diff --git a/src/kit/taosnetwork/server.c b/src/kit/taosnetwork/server.c index 7dcc9cbeda..c967828f0b 100644 --- a/src/kit/taosnetwork/server.c +++ b/src/kit/taosnetwork/server.c @@ -13,6 +13,7 @@ * along with this program. If not, see . */ +#include #include #include #include @@ -34,6 +35,36 @@ typedef struct { int type; // 0: tcp, 1: udo, default: 0 } info; +typedef struct Arguments { + char * host; + uint16_t port; + uint16_t max_port; +} SArguments; + +static struct argp_option options[] = { + {0, 'h', "host", 0, "The host to connect to TDEngine. Default is localhost.", 0}, + {0, 'p', "port", 0, "The TCP or UDP port number to use for the connection. Default is 6020.", 1}, + {0, 'm', "max port", 0, "The max TCP or UDP port number to use for the connection. Default is 6050.", 2}}; + +static error_t parse_opt(int key, char *arg, struct argp_state *state) { + + SArguments *arguments = state->input; + switch (key) { + case 'h': + arguments->host = arg; + break; + case 'p': + arguments->port = atoi(arg); + break; + case 'm': + arguments->max_port = atoi(arg); + break; + } + return 0; +} + +static struct argp argp = {options, parse_opt, 0, 0}; + static void *bindPort(void *sarg) { info *pinfo = (info *)sarg; int port = pinfo->port; @@ -170,15 +201,21 @@ static void *bindUPort(void *sarg) { } -int main() { - int port = 6020; - pthread_t *pids = malloc(60 * sizeof(pthread_t)); - info * infos = malloc(30 * sizeof(info)); - info * uinfos = malloc(30 * sizeof(info)); +int main(int argc, char *argv[]) { + SArguments arguments = {"127.0.0.1", 6020, 6050}; + argp_parse(&argp, argc, argv, 0, 0, &arguments); + int port = arguments.port; - for (size_t i = 0; i < 30; i++) { - port++; + int num = arguments.max_port - arguments.port; + if (num < 0) { + num = 1; + } + pthread_t *pids = malloc(2 * num * sizeof(pthread_t)); + info * infos = malloc(num * sizeof(info)); + info * uinfos = malloc(num * sizeof(info)); + + for (size_t i = 0; i < num; i++) { info *pinfo = infos++; pinfo->port = port; @@ -191,14 +228,15 @@ int main() { info *uinfo = uinfos++; uinfo->port = port; uinfo->type = 1; - if (pthread_create(pids + 30 + i, NULL, bindUPort, uinfo) != 0) //创建线程 + port++; + if (pthread_create(pids + num + i, NULL, bindUPort, uinfo) != 0) //创建线程 { //创建线程失败 printf("创建线程失败: %d.\n", port); exit(0); } } - for (int i = 0; i < 30; i++) { + for (int i = 0; i < num; i++) { pthread_join(pids[i], NULL); - pthread_join(pids[(10 + i)], NULL); + pthread_join(pids[(num + i)], NULL); } } diff --git a/src/kit/taosnetwork/taosnetwork_client.c b/src/kit/taosnetwork/taosnetwork_client.c deleted file mode 100644 index 072610a035..0000000000 --- a/src/kit/taosnetwork/taosnetwork_client.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * This program is free software: you can use, redistribute, and/or modify - * it under the terms of the GNU Affero General Public License, version 3 - * or later ("AGPL"), as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#define SERVER_PORT 8000 -#define SIZE 200 - -int main() { - struct sockaddr_in servaddr, cliaddr; - socklen_t cliaddr_len; - int client_sockfd; - char buf[SIZE]; - char recvbuf[SIZE]; - - int i, n, flag = 0; - - int len, iDataNum; - - client_sockfd = socket(AF_INET, SOCK_STREAM, 0); - bzero(&servaddr, sizeof(servaddr)); - servaddr.sin_family = AF_INET; - servaddr.sin_addr.s_addr = htonl(INADDR_ANY); - servaddr.sin_port = htons(SERVER_PORT); - - if (connect(client_sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) { - printf("Connected error..\n"); - return 0; - } - printf("Connected to server..\n"); - - /*循环的发送接收信息并打印接收信息(可以按需发送)--recv返回接收到的字节数,send返回发送的字节数*/ - while (1) { - printf("Enter string to send:"); - scanf("%s", buf); - if (!strcmp(buf, "quit")) { - break; - } - len = (sizeof buf); - - recvbuf[0] = '\0'; - - iDataNum = recv(client_sockfd, recvbuf, SIZE, 0); - - recvbuf[iDataNum] = '\0'; - - printf("%s\n", recvbuf); - } - return 0; -} diff --git a/src/kit/taosnetwork/taosnetwork_server.c b/src/kit/taosnetwork/taosnetwork_server.c deleted file mode 100644 index 1ec20716fa..0000000000 --- a/src/kit/taosnetwork/taosnetwork_server.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * This program is free software: you can use, redistribute, and/or modify - * it under the terms of the GNU Affero General Public License, version 3 - * or later ("AGPL"), as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#define SERVER_PORT 8000 -#define SIZE 200 - -int main() { - struct sockaddr_in servaddr, cliaddr; - socklen_t cliaddr_len; - int listenfd, connfd; - char buf[BUFSIZ]; - int i, n, flag = 0; - - listenfd = socket(AF_INET, SOCK_STREAM, 0); - bzero(&servaddr, sizeof(servaddr)); - servaddr.sin_family = AF_INET; - servaddr.sin_addr.s_addr = htonl(INADDR_ANY); - servaddr.sin_port = htons(SERVER_PORT); - bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); - listen(listenfd, 20); - - printf("Accepting connections..\n"); - while (1) { - cliaddr_len = sizeof(cliaddr); - connfd = accept(listenfd, (struct sockaddr *)&cliaddr, - &cliaddr_len); //如果得不到客户端发来的消息,将会被阻塞,一直等到消息到来 - n = read(connfd, buf, SIZE); //如果n<=0,表示客户端已断开 - while (1) { - if (n != 0) { - for (i = 0; i < n; i++) printf("%c", buf[i]); //输出客户端发来的信息 - } else { - printf("Client say close the connection..\n"); - break; - } - n = read(connfd, buf, SIZE); - } - close(connfd); - } -} diff --git a/src/kit/taosnetwork/test_client.c b/src/kit/taosnetwork/test_client.c deleted file mode 100644 index 0c863c6a99..0000000000 --- a/src/kit/taosnetwork/test_client.c +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include -#include -#include -#include - -#define SERVER_PORT 8888 -#define BUFF_LEN 512 -#define SERVER_IP "172.0.5.182" - -void udp_msg_sender(int fd, struct sockaddr* dst) {} - -/* - client: - socket-->sendto-->revcfrom-->close -*/ - -int main(int argc, char* argv[]) { - int client_fd; - struct sockaddr_in ser_addr; - - client_fd = socket(AF_INET, SOCK_DGRAM, 0); - if (client_fd < 0) { - printf("create socket fail!\n"); - return -1; - } - - memset(&ser_addr, 0, sizeof(ser_addr)); - ser_addr.sin_family = AF_INET; - // ser_addr.sin_addr.s_addr = inet_addr(SERVER_IP); - ser_addr.sin_addr.s_addr = htonl(INADDR_ANY); //注意网络序转换 - ser_addr.sin_port = htons(SERVER_PORT); //注意网络序转换 - - socklen_t len; - struct sockaddr_in src; - while (1) { - char buf[BUFF_LEN] = "TEST UDP MSG!\n"; - len = sizeof(*(struct sockaddr*)&ser_addr); - printf("client:%s\n", buf); //打印自己发送的信息 - sendto(client_fd, buf, BUFF_LEN, 0, (struct sockaddr*)&ser_addr, len); - memset(buf, 0, BUFF_LEN); - recvfrom(client_fd, buf, BUFF_LEN, 0, (struct sockaddr*)&src, &len); //接收来自server的信息 - printf("server:%s\n", buf); - sleep(1); //一秒发送一次消息 - } - - close(client_fd); - - return 0; -} \ No newline at end of file diff --git a/src/kit/taosnetwork/test_server.c b/src/kit/taosnetwork/test_server.c deleted file mode 100644 index 3bfbaa4f7c..0000000000 --- a/src/kit/taosnetwork/test_server.c +++ /dev/null @@ -1,63 +0,0 @@ -#include -#include -#include -#include -#include - -#define SERVER_PORT 8888 -#define BUFF_LEN 1024 - -void handle_udp_msg(int fd) { - char buf[BUFF_LEN]; //接收缓冲区,1024字节 - socklen_t len; - int count; - struct sockaddr_in clent_addr; // clent_addr用于记录发送方的地址信息 - while (1) { - memset(buf, 0, BUFF_LEN); - len = sizeof(clent_addr); - count = - recvfrom(fd, buf, BUFF_LEN, 0, (struct sockaddr*)&clent_addr, &len); // recvfrom是拥塞函数,没有数据就一直拥塞 - if (count == -1) { - printf("recieve data fail!\n"); - return; - } - printf("client:%s\n", buf); //打印client发过来的信息 - memset(buf, 0, BUFF_LEN); - sprintf(buf, "I have recieved %d bytes data!\n", count); //回复client - printf("server:%s\n", buf); //打印自己发送的信息给 - sendto(fd, buf, BUFF_LEN, 0, (struct sockaddr*)&clent_addr, - len); //发送信息给client,注意使用了clent_addr结构体指针 - } -} - -/* - server: - socket-->bind-->recvfrom-->sendto-->close -*/ - -int main(int argc, char* argv[]) { - int server_fd, ret; - struct sockaddr_in ser_addr; - - server_fd = socket(AF_INET, SOCK_DGRAM, 0); // AF_INET:IPV4;SOCK_DGRAM:UDP - if (server_fd < 0) { - printf("create socket fail!\n"); - return -1; - } - - memset(&ser_addr, 0, sizeof(ser_addr)); - ser_addr.sin_family = AF_INET; - ser_addr.sin_addr.s_addr = htonl(INADDR_ANY); // IP地址,需要进行网络序转换,INADDR_ANY:本地地址 - ser_addr.sin_port = htons(SERVER_PORT); //端口号,需要网络序转换 - - ret = bind(server_fd, (struct sockaddr*)&ser_addr, sizeof(ser_addr)); - if (ret < 0) { - printf("socket bind fail!\n"); - return -1; - } - - handle_udp_msg(server_fd); //处理接收到的数据 - - close(server_fd); - return 0; -} \ No newline at end of file diff --git a/src/mnode/src/mnodeDnode.c b/src/mnode/src/mnodeDnode.c index e3ea08aece..0f2bbb8235 100644 --- a/src/mnode/src/mnodeDnode.c +++ b/src/mnode/src/mnodeDnode.c @@ -365,8 +365,10 @@ static int32_t mnodeProcessDnodeStatusMsg(SMnodeMsg *pMsg) { mnodeUpdateVgroupStatus(pVgroup, pDnode, pVload); pAccess->vgId = htonl(pVload->vgId); pAccess->accessState = pVgroup->accessState; + pAccess++; mnodeDecVgroupRef(pVgroup); } + } if (pDnode->status == TAOS_DN_STATUS_OFFLINE) { diff --git a/src/plugins/mqtt/src/mqttSystem.c b/src/plugins/mqtt/src/mqttSystem.c index e9af733d07..f123d153d1 100644 --- a/src/plugins/mqtt/src/mqttSystem.c +++ b/src/plugins/mqtt/src/mqttSystem.c @@ -122,12 +122,11 @@ void mqttCleanUpSystem() { } void mqtt_PublishCallback(void** unused, struct mqtt_response_publish* published) { - mqttPrint("mqtt_PublishCallback"); /* note that published->topic_name is NOT null-terminated (here we'll change it to a c-string) */ char* topic_name = (char*)malloc(published->topic_name_size + 1); memcpy(topic_name, published->topic_name, published->topic_name_size); topic_name[published->topic_name_size] = '\0'; - mqttPrint("Received publish('%s'): %s", topic_name, (const char*)published->application_message); + mqttPrint("received publish('%s'): %s", topic_name, (const char*)published->application_message); char _token[128] = {0}; char _dbname[128] = {0}; char _tablename[128] = {0}; @@ -166,12 +165,12 @@ void* mqttClientRefresher(void* client) { mqtt_sync((struct mqtt_client*)client); taosMsleep(100); } - mqttPrint("Exit mqttClientRefresher"); + mqttTrace("quit refresher"); return NULL; } void mqttCleanup(int status, int sockfd, pthread_t* client_daemon) { - mqttPrint("mqttCleanup"); + mqttPrint("clean up mqtt module"); if (sockfd != -1) close(sockfd); if (client_daemon != NULL) pthread_cancel(*client_daemon); } @@ -197,7 +196,7 @@ void mqttQueryInsertCallback(void* param, TAOS_RES* result, int32_t code) { } void mqttReconnectClient(struct mqtt_client* client, void** reconnect_state_vptr) { - mqttPrint("mqttReconnectClient"); + mqttPrint("reconnect client"); struct reconnect_state_t* reconnect_state = *((struct reconnect_state_t**)reconnect_state_vptr); /* Close the clients socket if this isn't the initial reconnect call */ @@ -213,7 +212,7 @@ void mqttReconnectClient(struct mqtt_client* client, void** reconnect_state_vptr /* Open a new socket. */ int sockfd = open_nb_socket(reconnect_state->hostname, reconnect_state->port); if (sockfd == -1) { - mqttError("Failed to open socket: "); + mqttError("failed to open socket: "); mqttCleanup(EXIT_FAILURE, sockfd, NULL); } diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index 69db734588..007a511adf 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -577,15 +577,24 @@ static void rpcReleaseConn(SRpcConn *pConn) { size_t size = snprintf(hashstr, sizeof(hashstr), "%x:%x:%x:%d", pConn->peerIp, pConn->linkUid, pConn->peerId, pConn->connType); taosHashRemove(pRpc->hash, hashstr, size); rpcFreeMsg(pConn->pRspMsg); // it may have a response msg saved, but not request msg - } + pConn->pRspMsg = NULL; - // lockedBy can not be reset, since it maybe hold by a thread - int sid = pConn->sid; - int64_t lockedBy = pConn->lockedBy; - memset(pConn, 0, sizeof(SRpcConn)); - pConn->lockedBy = lockedBy; - taosFreeId(pRpc->idPool, sid); + if (pConn->pReqMsg) rpcFreeCont(pConn->pReqMsg); + } + // memset could not be used, since lockeBy can not be reset + pConn->inType = 0; + pConn->outType = 0; + pConn->inTranId = 0; + pConn->outTranId = 0; + pConn->secured = 0; + pConn->peerIp = 0; + pConn->peerPort = 0; + pConn->pReqMsg = NULL; + pConn->reqMsgLen = 0; + pConn->pContext = NULL; + + taosFreeId(pRpc->idPool, pConn->sid); tTrace("%s, rpc connection is released", pConn->info); } @@ -644,7 +653,6 @@ static SRpcConn *rpcAllocateServerConn(SRpcInfo *pRpc, SRecvInfo *pRecv) { terrno = TSDB_CODE_RPC_MAX_SESSIONS; } else { pConn = pRpc->connList + sid; - memset(pConn, 0, sizeof(SRpcConn)); memcpy(pConn->user, pHead->user, tListLen(pConn->user)); pConn->pRpc = pRpc; pConn->sid = sid; @@ -885,6 +893,7 @@ static SRpcConn *rpcProcessMsgHead(SRpcInfo *pRpc, SRecvInfo *pRecv) { static void rpcReportBrokenLinkToServer(SRpcConn *pConn) { SRpcInfo *pRpc = pConn->pRpc; + if (pConn->pReqMsg == NULL) return; // if there are pending request, notify the app rpcAddRef(pRpc); @@ -897,6 +906,8 @@ static void rpcReportBrokenLinkToServer(SRpcConn *pConn) { rpcMsg.handle = pConn; rpcMsg.msgType = pConn->inType; rpcMsg.code = TSDB_CODE_RPC_NETWORK_UNAVAIL; + pConn->pReqMsg = NULL; + pConn->reqMsgLen = 0; if (pRpc->cfp) (*(pRpc->cfp))(&rpcMsg, NULL); } diff --git a/src/util/src/tcompare.c b/src/util/src/tcompare.c index f9d306e625..889d38ff20 100644 --- a/src/util/src/tcompare.c +++ b/src/util/src/tcompare.c @@ -191,9 +191,7 @@ int WCSPatternMatch(const wchar_t *patterStr, const wchar_t *str, size_t size, c break; } - str++; - - int32_t ret = WCSPatternMatch(&patterStr[i], str, wcslen(str), pInfo); + int32_t ret = WCSPatternMatch(&patterStr[i], ++str, size - n - 1, pInfo); if (ret != TSDB_PATTERN_NOMATCH) { return ret; } @@ -241,9 +239,11 @@ static int32_t compareFindStrInArray(const void* pLeft, const void* pRight) { static int32_t compareWStrPatternComp(const void* pLeft, const void* pRight) { SPatternCompareInfo pInfo = {'%', '_'}; - + wchar_t pattern[128] = {0}; - memcpy(pattern, varDataVal(pRight), varDataLen(pRight)/TSDB_NCHAR_SIZE); + assert(TSDB_PATTERN_STRING_MAX_LEN < 128); + + memcpy(pattern, varDataVal(pRight), varDataLen(pRight)); assert(varDataLen(pRight) < 128); int32_t ret = WCSPatternMatch(pattern, varDataVal(pLeft), varDataLen(pLeft)/TSDB_NCHAR_SIZE, &pInfo); diff --git a/src/util/src/tlog.c b/src/util/src/tlog.c index f5129c96c0..c4597d86ed 100644 --- a/src/util/src/tlog.c +++ b/src/util/src/tlog.c @@ -327,7 +327,7 @@ void taosPrintLog(const char *flags, int32_t dflag, const char *format, ...) { curTime = timeSecs.tv_sec; ptm = localtime_r(&curTime, &Tm); - len = sprintf(buffer, "%02d/%02d %02d:%02d:%02d.%06d 0x%" PRId64 " ", ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, + len = sprintf(buffer, "%02d/%02d %02d:%02d:%02d.%06d 0x%" PRIx64 " ", ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, (int32_t)timeSecs.tv_usec, taosGetPthreadId()); len += sprintf(buffer + len, "%s", flags); @@ -414,7 +414,7 @@ void taosPrintLongString(const char *flags, int32_t dflag, const char *format, . curTime = timeSecs.tv_sec; ptm = localtime_r(&curTime, &Tm); - len = sprintf(buffer, "%02d/%02d %02d:%02d:%02d.%06d 0x%" PRId64 " ", ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, + len = sprintf(buffer, "%02d/%02d %02d:%02d:%02d.%06d 0x%" PRIx64 " ", ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, (int32_t)timeSecs.tv_usec, taosGetPthreadId()); len += sprintf(buffer + len, "%s", flags); diff --git a/src/util/src/tutil.c b/src/util/src/tutil.c index 4469ad79b1..150767643f 100644 --- a/src/util/src/tutil.c +++ b/src/util/src/tutil.c @@ -36,6 +36,7 @@ uint32_t taosRand(void) #else uint32_t taosRand(void) { +/* int fd; int seed; @@ -51,6 +52,8 @@ uint32_t taosRand(void) } return (uint32_t)seed; +*/ + return rand(); } #endif diff --git a/tests/pytest/alter/alter_table_crash.py b/tests/pytest/alter/alter_table_crash.py new file mode 100644 index 0000000000..903bb60e6a --- /dev/null +++ b/tests/pytest/alter/alter_table_crash.py @@ -0,0 +1,83 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +import sys +import taos +from util.log import * +from util.cases import * +from util.sql import * +from util.dnodes import * + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor()) + + def run(self): + tdSql.prepare() + + print("==============Case 1: add column, restart taosd, drop the same colum then add it back") + tdSql.execute( + "create table st(ts timestamp, speed int) tags(loc nchar(20))") + tdSql.execute( + "insert into t1 using st tags('beijing') values(now, 1)") + tdSql.execute( + "alter table st add column tbcol binary(20)") + + # restart taosd + tdDnodes.forcestop(1) + tdDnodes.start(1) + + tdSql.execute( + "alter table st drop column tbcol") + tdSql.execute( + "alter table st add column tbcol binary(20)") + + tdSql.query("select * from st") + tdSql.checkRows(1) + + + print("==============Case 2: keep adding columns, restart taosd") + tdSql.execute( + "create table dt(ts timestamp, tbcol1 tinyint) tags(tgcol1 tinyint)") + tdSql.execute( + "alter table dt add column tbcol2 int") + tdSql.execute( + "alter table dt add column tbcol3 smallint") + tdSql.execute( + "alter table dt add column tbcol4 bigint") + tdSql.execute( + "alter table dt add column tbcol5 float") + tdSql.execute( + "alter table dt add column tbcol6 double") + tdSql.execute( + "alter table dt add column tbcol7 bool") + tdSql.execute( + "alter table dt add column tbcol8 nchar(20)") + tdSql.execute( + "alter table dt add column tbcol9 binary(20)") + + # restart taosd + tdDnodes.forcestop(1) + tdDnodes.start(1) + + tdSql.query("select * from st") + tdSql.checkRows(0) + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/pytest/fulltest.sh b/tests/pytest/fulltest.sh index dfa3b55048..0bacd63ec1 100755 --- a/tests/pytest/fulltest.sh +++ b/tests/pytest/fulltest.sh @@ -126,6 +126,9 @@ python3 ./test.py -f import_merge/importInsertThenImport.py python3 ./test.py -f user/user_create.py python3 ./test.py -f user/pass_len.py +# stable +python3 ./test.py -f stable/query_after_reset.py + # table python3 ./test.py -f table/del_stable.py @@ -138,7 +141,11 @@ python3 ./test.py -f query/filterAllIntTypes.py python3 ./test.py -f query/filterFloatAndDouble.py python3 ./test.py -f query/filterOtherTypes.py python3 ./test.py -f query/querySort.py +python3 ./test.py -f query/queryJoin.py #stream python3 ./test.py -f stream/stream1.py python3 ./test.py -f stream/stream2.py + +#alter table +python3 ./test.py -f alter/alter_table_crash.py \ No newline at end of file diff --git a/tests/pytest/query/queryJoin.py b/tests/pytest/query/queryJoin.py new file mode 100644 index 0000000000..b1a0aaed6b --- /dev/null +++ b/tests/pytest/query/queryJoin.py @@ -0,0 +1,128 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +import sys +import taos +from util.log import * +from util.cases import * +from util.sql import * + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor()) + + def run(self): + tdSql.prepare() + + print("======= Step 1 prepare data=========") + tdSql.execute( + "create table stb1 (ts timestamp, c1 int, c2 float) tags(t1 int, t2 binary(10), t3 nchar(10))") + tdSql.execute( + '''insert into tb1 using stb1 tags(1,'tb1', '表1') values ('2020-04-18 15:00:00.000', 1, 0.1) + ('2020-04-18 15:00:01.000', 1,0.1) ('2020-04-18 15:00:03.000', 3, 0.3) ('2020-04-18 15:00:04.000', 4,0.4)''') + tdSql.execute( + '''insert into tb2 using stb1 tags(2,'tb2', '表2') values ('2020-04-18 15:00:00.000', 21, 2.1) + ('2020-04-18 15:00:01.000', 22,2.2) ('2020-04-18 15:00:02.000', 22, 2.1) ('2020-04-18 15:00:03.000', 23,2.2)''') + + tdSql.execute( + "create table stb_t (ts timestamp, temperature int, humidity float) tags(id int, name binary(10), dscrption nchar(10))") + tdSql.execute( + '''insert into tb_t1 using stb_t tags(1,'tb_t1', '温度表1') values ('2020-04-18 15:00:00.000', 25, 0.5) + ('2020-04-18 15:00:01.000', 25, 0.5) ('2020-04-18 15:00:02.000', 26, 0.7) ('2020-04-18 15:00:03.000', 27, 0.8)''') + tdSql.execute( + '''insert into tb_t2 using stb_t tags(2,'tb_t2', '温度表2') values ('2020-04-18 15:00:00.000', 33, 0.9) + ('2020-04-18 15:00:01.000', 35, 1.1) ('2020-04-18 15:00:03.000', 36, 1.3) ('2020-04-18 15:00:04.000', 37, 1.4)''') + + tdSql.execute( + "create table stb_p (ts timestamp, pressure float) tags(id int, name binary(10), dscrption nchar(10), location binary(20))") + tdSql.execute( + '''insert into tb_p1 using stb_p tags(1,'tb_p1', '压力计1', 'beijing') values ('2020-04-18 15:00:00.000', 76.6) + ('2020-04-18 15:00:01.000', 76.5) ('2020-04-18 15:00:01.500', 77.1) ('2020-04-18 15:00:02.000', 75.3) + ('2020-04-18 15:00:03.000', 75.1) ('2020-04-18 15:00:04.500', 77.3)''') + tdSql.execute( + '''insert into tb_p2 using stb_p tags(2,'tb_p2', '压力计2', 'shenzhen') values ('2020-04-18 14:59:59.000', 74.6) + ('2020-04-18 15:00:01.000', 74.5) ('2020-04-18 15:00:01.500', 73.6) ('2020-04-18 15:00:02.000', 74.5) + ('2020-04-18 15:00:02.500', 73.9) ('2020-04-18 15:00:03.000', 73.5)''') + + tdSql.execute( + "create table stb_v (ts timestamp, velocity float) tags(id int, name binary(10), dscrption nchar(10), location binary(20))") + tdSql.execute( + '''insert into tb_v1 using stb_v tags(1,'tb_v1', '速度计1', 'beijing ') values ('2020-04-18 15:00:00.000', 176.6) + ('2020-04-18 15:00:01.000', 176.5)''') + tdSql.execute( + '''insert into tb_v2 using stb_v tags(2,'tb_v2', '速度计2', 'shenzhen') values ('2020-04-18 15:00:00.000', 171.6) + ('2020-04-18 15:00:01.000', 171.5)''') + + # explicit join should not work + tdSql.error("select * from stb_p join stb_t on (stb_p.id = stb_t.id)") + tdSql.error("select * from tb1 join tb2 on (tb1.ts=tb2.ts)") + tdSql.error( + "select * from stb_p join stb_t on (stb_p.ts=stb_t.ts and stb_p.id = stb_t.id)") + + # alias should not work + tdSql.error("select * from stb_p p join stb_t t on (p.id = t.id)") + + # join queries + tdSql.query( + "select * from stb_p, stb_t where stb_p.ts=stb_t.ts and stb_p.id = stb_t.id") + tdSql.checkRows(6) + + tdSql.query( + "select * from stb_p, stb_t where stb_p.ts=stb_t.ts and stb_p.id = stb_t.id order by ts desc") + tdSql.checkColumnSorted(0, "desc") + + tdSql.error( + "select ts, pressure, temperature, id, dscrption from stb_p, stb_t where stb_p.ts=stb_t.ts and stb_p.id = stb_t.id") + + tdSql.query("select stb_p.ts, pressure, stb_t.temperature, stb_p.id, stb_p.dscrption from stb_p, stb_t where stb_p.ts=stb_t.ts and stb_p.id = stb_t.id") + tdSql.checkRows(6) + + tdSql.query("select stb_t.ts, stb_p.pressure, stb_t.temperature,stb_p.id,stb_p.dscrption from stb_p, stb_t where stb_p.ts=stb_t.ts and stb_p.id = stb_t.id") + tdSql.checkRows(6) + + tdSql.error( + "select stb_t.ts, stb_t.dscrption, stb_t.temperature, stb_t.id, stb_p.dscrption, stb_p.pressure from stb_p, stb_t where stb_p.ts=stb_t.ts and stb_p.id = stb_t.id group by name") + tdSql.error( + "select stb_t.ts, stb_t.dscrption, stb_t.temperature, stb_t.id, stb_p.dscrption, stb_p.pressure from stb_p, stb_t where stb_p.ts=stb_t.ts and stb_p.id = stb_t.id group by stb_t.name") + tdSql.error( + "select stb_t.ts, stb_t.dscrption, stb_t.temperature, stb_t.id, stb_p.dscrption, stb_p.pressure from stb_p, stb_t where stb_p.ts=stb_t.ts and stb_p.id = stb_t.id group by stb_t.id") + tdSql.error( + "select stb_t.ts, stb_t.dscrption, stb_t.temperature, stb_t.id, stb_p.dscrption, stb_p.pressure from stb_p, stb_t where stb_p.ts=stb_t.ts and stb_p.id = stb_t.name;") + tdSql.error( + "select stb_t.ts, stb_t.dscrption, stb_t.temperature, stb_t.id, stb_p.dscrption, stb_p.pressure from stb_p, stb_t where stb_p.ts=stb_t.ts and stb_p.location = stb_t.name") + + tdSql.execute("alter table stb_t add tag pid int") + tdSql.execute("alter table tb_t1 set tag pid=2") + tdSql.execute("alter table tb_t2 set tag pid=1") + + tdSql.query("select stb_t.ts, stb_t.dscrption, stb_t.temperature, stb_t.id, stb_p.dscrption, stb_p.pressure from stb_p, stb_t where stb_p.ts=stb_t.ts and stb_p.id = stb_t.pid") + tdSql.checkRows(3) + + tdSql.query("select stb_t.ts, stb_t.dscrption, stb_t.temperature, stb_t.id, stb_p.dscrption, stb_p.pressure from stb_p, stb_t where stb_p.ts=stb_t.ts and stb_p.id = stb_t.id") + tdSql.checkRows(6) + + tdSql.query("select stb_t.ts, stb_t.dscrption, stb_t.temperature, stb_t.id, stb_p.dscrption, stb_p.pressure from stb_p, stb_t where stb_p.ts=stb_t.ts and stb_p.id = stb_t.id") + tdSql.checkRows(6) + + tdSql.query("select stb_t.ts, stb_t.dscrption, stb_t.temperature, stb_t.pid, stb_p.id, stb_p.dscrption, stb_p.pressure,stb_v.velocity from stb_p, stb_t, stb_v where stb_p.ts=stb_t.ts and stb_p.ts=stb_v.ts and stb_p.id = stb_t.id") + tdSql.checkRows(2) + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/pytest/stable/query_after_reset.py b/tests/pytest/stable/query_after_reset.py new file mode 100644 index 0000000000..2bc171ae5d --- /dev/null +++ b/tests/pytest/stable/query_after_reset.py @@ -0,0 +1,177 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +import sys +import random +from util.log import * +from util.cases import * +from util.sql import * +from util.dnodes import * + + +class Test: + def __init__(self): + self.current_tb = "" + self.last_tb = "" + self.written = 0 + + def create_table(self): + tdLog.info("create a table") + self.current_tb = "tb%d" % int(round(time.time() * 1000)) + tdLog.info("current table %s" % self.current_tb) + + if (self.current_tb == self.last_tb): + return + else: + tdSql.execute( + 'create table %s (ts timestamp, speed int)' % + self.current_tb) + self.last_tb = self.current_tb + self.written = 0 + + def insert_data(self): + tdLog.info("will insert data to table") + if (self.current_tb == ""): + tdLog.info("no table, create first") + self.create_table() + + tdLog.info("insert data to table") + insertRows = 10 + tdLog.info("insert %d rows to %s" % (insertRows, self.last_tb)) + for i in range(0, insertRows): + ret = tdSql.execute( + 'insert into %s values (now + %dm, %d)' % + (self.last_tb, i, i)) + self.written = self.written + 1 + + tdLog.info("insert earlier data") + tdSql.execute('insert into %s values (now - 5m , 10)' % self.last_tb) + self.written = self.written + 1 + tdSql.execute('insert into %s values (now - 6m , 10)' % self.last_tb) + self.written = self.written + 1 + tdSql.execute('insert into %s values (now - 7m , 10)' % self.last_tb) + self.written = self.written + 1 + tdSql.execute('insert into %s values (now - 8m , 10)' % self.last_tb) + self.written = self.written + 1 + + def query_data(self): + if (self.written > 0): + tdLog.info("query data from table") + tdSql.query("select * from %s" % self.last_tb) + tdSql.checkRows(self.written) + + def query_stable(self): + tdLog.info("query super table") + tdSql.query("select * from st") + tdSql.checkRows(1) + + def create_stable(self): + tdLog.info("create a super table and sub-table and insert data") + tdSql.execute( + "create table if not exists st (ts timestamp, tagtype int) tags(dev nchar(50))") + tdSql.execute( + 'CREATE TABLE if not exists dev_001 using st tags("dev_01")') + tdSql.execute( + "INSERT INTO dev_001(ts, tagtype) VALUES('2020-05-13 10:00:00.000', 1)") + + def stop_database(self): + tdLog.info("stop databae") + tdDnodes.stop(1) + + def restart_database(self): + tdLog.info("restart databae") + tdDnodes.stop(1) + tdDnodes.start(1) + tdLog.sleep(5) + + def force_restart(self): + tdLog.info("force restart database") + tdDnodes.forcestop(1) + tdDnodes.start(1) + tdLog.sleep(5) + + def drop_table(self): + if (self.current_tb != ""): + tdLog.info("drop current tb %s" % self.current_tb) + tdSql.execute("drop table %s" % self.current_tb) + self.current_tb = "" + self.last_tb = "" + self.written = 0 + + def reset_query_cache(self): + tdLog.info("reset query cache") + tdSql.execute("reset query cache") + tdLog.sleep(1) + + def reset_database(self): + tdLog.info("reset database") + tdDnodes.forcestop(1) + tdDnodes.deploy(1) + self.current_tb = "" + self.last_tb = "" + self.written = 0 + tdDnodes.start(1) + tdSql.prepare() + + def delete_datafiles(self): + tdLog.info("delete data files") + dnodesDir = tdDnodes.getDnodesRootDir() + dataDir = dnodesDir + '/dnode1/*' + deleteCmd = 'rm -rf %s' % dataDir + os.system(deleteCmd) + + self.current_tb = "" + self.last_tb = "" + self.written = 0 + tdDnodes.start(1) + tdSql.prepare() + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), logSql) + + def run(self): + tdSql.prepare() + + test = Test() + + switch = { + 1: test.create_table, + 2: test.insert_data, + 3: test.query_data, + 4: test.create_stable, + 5: test.restart_database, + 6: test.force_restart, + 7: test.drop_table, + 8: test.reset_query_cache, + 9: test.reset_database, + 10: test.delete_datafiles, + 11: test.query_stable, + 12: test.stop_database, + } + + switch.get(4, lambda: "ERROR")() + switch.get(12, lambda: "ERROR")() + switch.get(10, lambda: "ERROR")() + switch.get(5, lambda: "ERROR")() + switch.get(11, lambda: "ERROR")() + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/script/general/parser/stream_on_sys.sim b/tests/script/general/parser/stream_on_sys.sim index 5170ddb036..5405e09256 100644 --- a/tests/script/general/parser/stream_on_sys.sim +++ b/tests/script/general/parser/stream_on_sys.sim @@ -22,12 +22,12 @@ $i = 0 sql use $db -sql create table cpustrm as select count(*), avg(cpu_taosd), max(cpu_taosd), min(cpu_taosd), avg(cpu_system), max(cpu_cores), min(cpu_cores), last(cpu_cores) from log.dn_192_168_0_1 interval(4s) sliding(2s) -sql create table memstrm as select count(*), avg(mem_taosd), max(mem_taosd), min(mem_taosd), avg(mem_system), first(mem_total), last(mem_total) from log.dn_192_168_0_1 interval(4s) sliding(2s) -sql create table diskstrm as select count(*), avg(disk_used), last(disk_used), avg(disk_total), first(disk_total) from log.dn_192_168_0_1 interval(4s) sliding(2s) -sql create table bandstrm as select count(*), avg(band_speed), last(band_speed) from log.dn_192_168_0_1 interval(4s) sliding(2s) -sql create table reqstrm as select count(*), avg(req_http), last(req_http), avg(req_select), last(req_select), avg(req_insert), last(req_insert) from log.dn_192_168_0_1 interval(4s) sliding(2s) -sql create table iostrm as select count(*), avg(io_read), last(io_read), avg(io_write), last(io_write) from log.dn_192_168_0_1 interval(4s) sliding(2s) +sql create table cpustrm as select count(*), avg(cpu_taosd), max(cpu_taosd), min(cpu_taosd), avg(cpu_system), max(cpu_cores), min(cpu_cores), last(cpu_cores) from log.dn1 interval(4s) sliding(2s) +sql create table memstrm as select count(*), avg(mem_taosd), max(mem_taosd), min(mem_taosd), avg(mem_system), first(mem_total), last(mem_total) from log.dn1 interval(4s) sliding(2s) +sql create table diskstrm as select count(*), avg(disk_used), last(disk_used), avg(disk_total), first(disk_total) from log.dn1 interval(4s) sliding(2s) +sql create table bandstrm as select count(*), avg(band_speed), last(band_speed) from log.dn1 interval(4s) sliding(2s) +sql create table reqstrm as select count(*), avg(req_http), last(req_http), avg(req_select), last(req_select), avg(req_insert), last(req_insert) from log.dn1 interval(4s) sliding(2s) +sql create table iostrm as select count(*), avg(io_read), last(io_read), avg(io_write), last(io_write) from log.dn1 interval(4s) sliding(2s) sleep 20000 sql select * from cpustrm if $rows <= 0 then diff --git a/tests/script/general/stream/new_stream.sim b/tests/script/general/stream/new_stream.sim index abc06faaef..001602079b 100644 --- a/tests/script/general/stream/new_stream.sim +++ b/tests/script/general/stream/new_stream.sim @@ -1,12 +1,11 @@ -#system sh/stop_dnodes.sh +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/cfg.sh -n dnode1 -c walLevel -v 0 +system sh/cfg.sh -n dnode1 -c tableMetaKeepTimer -v 10 +system sh/exec.sh -n dnode1 -s start -#system sh/deploy.sh -n dnode1 -i 1 -#system sh/cfg.sh -n dnode1 -c walLevel -v 0 -#system sh/cfg.sh -n dnode1 -c tableMetaKeepTimer -v 10 -#system sh/exec.sh -n dnode1 -s start - -#sleep 3000 +sleep 3000 sql connect print ======================== dnode1 start diff --git a/tests/test-all.sh b/tests/test-all.sh index 0c91229120..275c6b1677 100755 --- a/tests/test-all.sh +++ b/tests/test-all.sh @@ -1,22 +1,5 @@ #!/bin/bash -function runSimCaseOneByOne { - while read -r line; do - if [[ $line =~ ^run.* ]]; then - case=`echo $line | awk '{print $2}'` - ./test.sh -f $case 2>&1 | grep 'success\|failed\|fault' | grep -v 'default' | tee -a out.log - fi - done < $1 -} - -function runPyCaseOneByOne { - while read -r line; do - if [[ $line =~ ^python.* ]]; then - $line 2>&1 | grep 'successfully executed\|failed\|fault' | grep -v 'default'| tee -a pytest-out.log - fi - done < $1 -} - # Color setting RED='\033[0;31m' GREEN='\033[1;32m' @@ -24,15 +7,46 @@ GREEN_DARK='\033[0;32m' GREEN_UNDERLINE='\033[4;32m' NC='\033[0m' +function runSimCaseOneByOne { + while read -r line; do + if [[ $line =~ ^run.* ]]; then + case=`echo $line | awk '{print $NF}'` + start_time=`date +%s` + ./test.sh -f $case > /dev/null 2>&1 && \ + echo -e "${GREEN}$case success${NC}" | tee -a out.log || \ + echo -e "${RED}$case failed${NC}" | tee -a out.log + end_time=`date +%s` + echo execution time of $case was `expr $end_time - $start_time`s. | tee -a out.log + fi + done < $1 +} + +function runPyCaseOneByOne { + while read -r line; do + if [[ $line =~ ^python.* ]]; then + if [[ $line != *sleep* ]]; then + case=`echo $line|awk '{print $NF}'` + start_time=`date +%s` + $line > /dev/null 2>&1 && \ + echo -e "${GREEN}$case success${NC}" | tee -a pytest-out.log || \ + echo -e "${RED}$case failed${NC}" | tee -a pytest-out.log + end_time=`date +%s` + echo execution time of $case was `expr $end_time - $start_time`s. | tee -a pytest-out.log + else + $line > /dev/null 2>&1 + fi + fi + done < $1 +} + totalFailed=0 totalPyFailed=0 - -current_dir=`pwd` +tests_dir=`pwd` if [ "$2" != "python" ]; then echo "### run TSIM test case ###" - cd $current_dir/script + cd $tests_dir/script [ -f out.log ] && rm -f out.log if [ "$1" == "cron" ]; then @@ -53,13 +67,13 @@ if [ "$2" != "python" ]; then totalSuccess=`expr $totalSuccess - $totalBasic` fi - echo -e "${GREEN} ### Total $totalSuccess TSIM case(s) succeed! ### ${NC}" + echo -e "\n${GREEN} ### Total $totalSuccess TSIM case(s) succeed! ### ${NC}" totalFailed=`grep 'failed\|fault' out.log | wc -l` # echo -e "${RED} ### Total $totalFailed TSIM case(s) failed! ### ${NC}" if [ "$totalFailed" -ne "0" ]; then - echo -e "${RED} ### Total $totalFailed TSIM case(s) failed! ### ${NC}" + echo -e "\n${RED} ### Total $totalFailed TSIM case(s) failed! ### ${NC}" # exit $totalFailed fi @@ -67,7 +81,27 @@ fi if [ "$2" != "sim" ]; then echo "### run Python test case ###" - cd $current_dir/pytest + + cd $tests_dir + IN_TDINTERNAL="community" + + if [[ "$tests_dir" == *"$IN_TDINTERNAL"* ]]; then + cd ../.. + else + cd ../ + fi + + TOP_DIR=`pwd` + TAOSLIB_DIR=`find . -name "libtaos.so"|grep -w lib|head -n1` + if [[ "$TAOSLIB_DIR" == *"$IN_TDINTERNAL"* ]]; then + LIB_DIR=`find . -name "libtaos.so"|grep -w lib|head -n1|cut -d '/' --fields=2,3,4,5` + else + LIB_DIR=`find . -name "libtaos.so"|grep -w lib|head -n1|cut -d '/' --fields=2,3,4` + fi + + export LD_LIBRARY_PATH=$TOP_DIR/$LIB_DIR:$LD_LIBRARY_PATH + + cd $tests_dir/pytest [ -f pytest-out.log ] && rm -f pytest-out.log @@ -81,15 +115,15 @@ if [ "$2" != "sim" ]; then echo "### run Python smoke test ###" runPyCaseOneByOne smoketest.sh fi - totalPySuccess=`grep 'successfully executed' pytest-out.log | wc -l` + totalPySuccess=`grep 'success' pytest-out.log | wc -l` if [ "$totalPySuccess" -gt "0" ]; then - echo -e "${GREEN} ### Total $totalPySuccess python case(s) succeed! ### ${NC}" + echo -e "\n${GREEN} ### Total $totalPySuccess python case(s) succeed! ### ${NC}" fi totalPyFailed=`grep 'failed\|fault' pytest-out.log | wc -l` if [ "$totalPyFailed" -ne "0" ]; then - echo -e "${RED} ### Total $totalPyFailed python case(s) failed! ### ${NC}" + echo -e "\n${RED} ### Total $totalPyFailed python case(s) failed! ### ${NC}" # exit $totalPyFailed fi fi