diff --git a/source/client/inc/clientInt.h b/source/client/inc/clientInt.h index 7d7e51bc27..49cb12cccd 100644 --- a/source/client/inc/clientInt.h +++ b/source/client/inc/clientInt.h @@ -235,7 +235,7 @@ void initMsgHandleFp(); TAOS* taos_connect_internal(const char* ip, const char* user, const char* pass, const char* auth, const char* db, uint16_t port); -void* doFetchRow(SRequestObj* pRequest); +void* doFetchRow(SRequestObj* pRequest, bool setupOneRowPtr); int32_t setResultDataPtr(SReqResultInfo* pResultInfo, TAOS_FIELD* pFields, int32_t numOfCols, int32_t numOfRows); diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index 6e65a4267f..e8dddb1238 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -545,7 +545,42 @@ TAOS* taos_connect_l(const char* ip, int ipLen, const char* user, int userLen, c return taos_connect(ipStr, userStr, passStr, dbStr, port); } -void* doFetchRow(SRequestObj* pRequest) { +static void doSetOneRowPtr(SReqResultInfo* pResultInfo) { + for (int32_t i = 0; i < pResultInfo->numOfCols; ++i) { + SResultColumn* pCol = &pResultInfo->pCol[i]; + + int32_t type = pResultInfo->fields[i].type; + int32_t bytes = pResultInfo->fields[i].bytes; + + if (IS_VAR_DATA_TYPE(type)) { + if (pCol->offset[pResultInfo->current] != -1) { + char* pStart = pResultInfo->pCol[i].offset[pResultInfo->current] + pResultInfo->pCol[i].pData; + + pResultInfo->length[i] = varDataLen(pStart); + pResultInfo->row[i] = varDataVal(pStart); + + if (type == TSDB_DATA_TYPE_NCHAR) { + int32_t len = taosUcs4ToMbs((TdUcs4*)varDataVal(pStart), varDataLen(pStart), varDataVal(pResultInfo->convertBuf[i])); + ASSERT(len <= bytes); + + pResultInfo->row[i] = varDataVal(pResultInfo->convertBuf[i]); + varDataSetLen(pResultInfo->convertBuf[i], len); + pResultInfo->length[i] = len; + } + } else { + pResultInfo->row[i] = NULL; + } + } else { + if (!colDataIsNull_f(pCol->nullbitmap, pResultInfo->current)) { + pResultInfo->row[i] = pResultInfo->pCol[i].pData + bytes * pResultInfo->current; + } else { + pResultInfo->row[i] = NULL; + } + } + } +} + +void* doFetchRow(SRequestObj* pRequest, bool setupOneRowPtr) { assert(pRequest != NULL); SReqResultInfo* pResultInfo = &pRequest->body.resInfo; @@ -555,17 +590,20 @@ void* doFetchRow(SRequestObj* pRequest) { if (pRequest->type == TDMT_VND_QUERY) { // All data has returned to App already, no need to try again if (pResultInfo->completed) { + pResultInfo->numOfRows = 0; return NULL; } SReqResultInfo* pResInfo = &pRequest->body.resInfo; pRequest->code = schedulerFetchRows(pRequest->body.queryJob, (void**)&pResInfo->pData); if (pRequest->code != TSDB_CODE_SUCCESS) { + pResultInfo->numOfRows = 0; return NULL; } pRequest->code = setQueryResultFromRsp(&pRequest->body.resInfo, (SRetrieveTableRsp*)pResInfo->pData); if (pRequest->code != TSDB_CODE_SUCCESS) { + pResultInfo->numOfRows = 0; return NULL; } @@ -633,41 +671,11 @@ void* doFetchRow(SRequestObj* pRequest) { } _return: - - for (int32_t i = 0; i < pResultInfo->numOfCols; ++i) { - SResultColumn* pCol = &pResultInfo->pCol[i]; - - int32_t type = pResultInfo->fields[i].type; - int32_t bytes = pResultInfo->fields[i].bytes; - - if (IS_VAR_DATA_TYPE(type)) { - if (pCol->offset[pResultInfo->current] != -1) { - char* pStart = pResultInfo->pCol[i].offset[pResultInfo->current] + pResultInfo->pCol[i].pData; - - pResultInfo->length[i] = varDataLen(pStart); - pResultInfo->row[i] = varDataVal(pStart); - - if (type == TSDB_DATA_TYPE_NCHAR) { - int32_t len = taosUcs4ToMbs((TdUcs4*)varDataVal(pStart), varDataLen(pStart), varDataVal(pResultInfo->convertBuf[i])); - ASSERT(len <= bytes); - - pResultInfo->row[i] = varDataVal(pResultInfo->convertBuf[i]); - varDataSetLen(pResultInfo->convertBuf[i], len); - pResultInfo->length[i] = len; - } - } else { - pResultInfo->row[i] = NULL; - } - } else { - if (!colDataIsNull_f(pCol->nullbitmap, pResultInfo->current)) { - pResultInfo->row[i] = pResultInfo->pCol[i].pData + bytes * pResultInfo->current; - } else { - pResultInfo->row[i] = NULL; - } - } + if (setupOneRowPtr) { + doSetOneRowPtr(pResultInfo); + pResultInfo->current += 1; } - pResultInfo->current += 1; return pResultInfo->row; } diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c index 00e1bf61e6..a84aebabc8 100644 --- a/source/client/src/clientMain.c +++ b/source/client/src/clientMain.c @@ -138,20 +138,20 @@ TAOS_RES *taos_query(TAOS *taos, const char *sql) { return taos_query_l(taos, sql, (int32_t) strlen(sql)); } -TAOS_ROW taos_fetch_row(TAOS_RES *pRes) { - if (pRes == NULL) { +TAOS_ROW taos_fetch_row(TAOS_RES *res) { + if (res == NULL) { return NULL; } - SRequestObj *pRequest = (SRequestObj *) pRes; + SRequestObj *pRequest = (SRequestObj *) res; if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT || pRequest->code != TSDB_CODE_SUCCESS || - taos_num_fields(pRes) == 0) { + taos_num_fields(res) == 0) { return NULL; } - return doFetchRow(pRequest); + return doFetchRow(pRequest, true); } int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) { @@ -330,7 +330,26 @@ bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col) { } int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) { - return 0; + if (res == NULL) { + return 0; + } + + SRequestObj *pRequest = (SRequestObj *) res; + if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || + pRequest->type == TSDB_SQL_INSERT || + pRequest->code != TSDB_CODE_SUCCESS || + taos_num_fields(res) == 0) { + return 0; + } + + doFetchRow(pRequest, false); + + // TODO refactor + SReqResultInfo* pResultInfo = &pRequest->body.resInfo; + pResultInfo->current = pResultInfo->numOfRows; + *rows = pResultInfo->row; + + return pResultInfo->numOfRows; } int taos_validate_sql(TAOS *taos, const char *sql) {