提交 f6067e1b 编写于 作者: H hjxilinx

[td-168] fix bug in var string handling

上级 64a2c841
...@@ -280,6 +280,7 @@ typedef struct { ...@@ -280,6 +280,7 @@ typedef struct {
SResRec * pGroupRec; SResRec * pGroupRec;
char * data; char * data;
void ** tsrow; void ** tsrow;
int32_t* length; // length for each field for current row
char ** buffer; // Buffer used to put multibytes encoded using unicode (wchar_t) char ** buffer; // Buffer used to put multibytes encoded using unicode (wchar_t)
SColumnIndex * pColumnIndex; SColumnIndex * pColumnIndex;
struct SLocalReducer *pLocalReducer; struct SLocalReducer *pLocalReducer;
...@@ -421,7 +422,7 @@ int32_t tscInvalidSQLErrMsg(char *msg, const char *additionalInfo, const char *s ...@@ -421,7 +422,7 @@ int32_t tscInvalidSQLErrMsg(char *msg, const char *additionalInfo, const char *s
void tscQueueAsyncFreeResult(SSqlObj *pSql); void tscQueueAsyncFreeResult(SSqlObj *pSql);
int32_t tscToSQLCmd(SSqlObj *pSql, struct SSqlInfo *pInfo); int32_t tscToSQLCmd(SSqlObj *pSql, struct SSqlInfo *pInfo);
char * tscGetResultColumnChr(SSqlRes *pRes, SQueryInfo *pQueryInfo, int32_t column, int16_t bytes); void tscGetResultColumnChr(SSqlRes *pRes, SFieldInfo* pFieldInfo, int32_t column);
extern void * pVnodeConn; extern void * pVnodeConn;
extern void * tscCacheHandle; extern void * tscCacheHandle;
......
...@@ -317,7 +317,7 @@ void tscProcessFetchRow(SSchedMsg *pMsg) { ...@@ -317,7 +317,7 @@ void tscProcessFetchRow(SSchedMsg *pMsg) {
SFieldSupInfo* pSup = taosArrayGet(pQueryInfo->fieldsInfo.pSupportInfo, i); SFieldSupInfo* pSup = taosArrayGet(pQueryInfo->fieldsInfo.pSupportInfo, i);
if (pSup->pSqlExpr != NULL) { if (pSup->pSqlExpr != NULL) {
pRes->tsrow[i] = tscGetResultColumnChr(pRes, pQueryInfo, i, pSup->pSqlExpr->resBytes); tscGetResultColumnChr(pRes, &pQueryInfo->fieldsInfo, i);
} else { } else {
// todo add // todo add
} }
......
...@@ -425,7 +425,7 @@ int taos_fetch_block_impl(TAOS_RES *res, TAOS_ROW *rows) { ...@@ -425,7 +425,7 @@ int taos_fetch_block_impl(TAOS_RES *res, TAOS_ROW *rows) {
assert(0); assert(0);
for (int i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) { for (int i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) {
pRes->tsrow[i] = tscGetResultColumnChr(pRes, pQueryInfo, i, 0); tscGetResultColumnChr(pRes, &pQueryInfo->fieldsInfo, i);
} }
*rows = pRes->tsrow; *rows = pRes->tsrow;
...@@ -725,6 +725,15 @@ char *taos_get_server_info(TAOS *taos) { ...@@ -725,6 +725,15 @@ char *taos_get_server_info(TAOS *taos) {
return pObj->sversion; return pObj->sversion;
} }
int* taos_fetch_lengths(TAOS_RES *res) {
SSqlObj* pSql = (SSqlObj* ) res;
if (pSql == NULL || pSql->signature != pSql) {
return NULL;
}
return pSql->res.length;
}
char *taos_get_client_info() { return version; } char *taos_get_client_info() { return version; }
void taos_stop_query(TAOS_RES *res) { void taos_stop_query(TAOS_RES *res) {
...@@ -796,7 +805,7 @@ int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) ...@@ -796,7 +805,7 @@ int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields)
case TSDB_DATA_TYPE_BINARY: case TSDB_DATA_TYPE_BINARY:
case TSDB_DATA_TYPE_NCHAR: { case TSDB_DATA_TYPE_NCHAR: {
size_t xlen = 0; size_t xlen = 0;
for (xlen = 0; xlen <= fields[i].bytes; xlen++) { for (xlen = 0; xlen < fields[i].bytes - VARSTR_HEADER_SIZE; xlen++) {
char c = ((char *)row[i])[xlen]; char c = ((char *)row[i])[xlen];
if (c == 0) break; if (c == 0) break;
str[len++] = c; str[len++] = c;
......
...@@ -1849,6 +1849,7 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) { ...@@ -1849,6 +1849,7 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) {
if (pRes->tsrow == NULL) { if (pRes->tsrow == NULL) {
pRes->tsrow = calloc(numOfExprs, POINTER_BYTES); pRes->tsrow = calloc(numOfExprs, POINTER_BYTES);
pRes->length = calloc(numOfExprs, sizeof(int32_t));
} }
bool success = false; bool success = false;
...@@ -1967,7 +1968,7 @@ void **doSetResultRowData(SSqlObj *pSql, bool finalResult) { ...@@ -1967,7 +1968,7 @@ void **doSetResultRowData(SSqlObj *pSql, bool finalResult) {
for (int i = 0; i < tscNumOfFields(pQueryInfo); ++i) { for (int i = 0; i < tscNumOfFields(pQueryInfo); ++i) {
SFieldSupInfo* pSup = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, i); SFieldSupInfo* pSup = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, i);
if (pSup->pSqlExpr != NULL) { if (pSup->pSqlExpr != NULL) {
pRes->tsrow[i] = tscGetResultColumnChr(pRes, pQueryInfo, i, pSup->pSqlExpr->resBytes); tscGetResultColumnChr(pRes, &pQueryInfo->fieldsInfo, i);
} }
// primary key column cannot be null in interval query, no need to check // primary key column cannot be null in interval query, no need to check
......
...@@ -210,7 +210,7 @@ bool tscNonOrderedProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableI ...@@ -210,7 +210,7 @@ bool tscNonOrderedProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableI
return false; return false;
} }
// order by column exists, not a non-ordered projection query // order by columnIndex exists, not a non-ordered projection query
return pQueryInfo->order.orderColId < 0; return pQueryInfo->order.orderColId < 0;
} }
...@@ -219,7 +219,7 @@ bool tscOrderedProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableInde ...@@ -219,7 +219,7 @@ bool tscOrderedProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableInde
return false; return false;
} }
// order by column exists, a non-ordered projection query // order by columnIndex exists, a non-ordered projection query
return pQueryInfo->order.orderColId >= 0; return pQueryInfo->order.orderColId >= 0;
} }
...@@ -286,13 +286,15 @@ int32_t tscCreateResPointerInfo(SSqlRes* pRes, SQueryInfo* pQueryInfo) { ...@@ -286,13 +286,15 @@ int32_t tscCreateResPointerInfo(SSqlRes* pRes, SQueryInfo* pQueryInfo) {
int32_t numOfOutput = pQueryInfo->fieldsInfo.numOfOutput; int32_t numOfOutput = pQueryInfo->fieldsInfo.numOfOutput;
pRes->numOfCols = numOfOutput; pRes->numOfCols = numOfOutput;
pRes->tsrow = calloc(POINTER_BYTES, numOfOutput); pRes->tsrow = calloc(numOfOutput, POINTER_BYTES);
pRes->buffer = calloc(POINTER_BYTES, numOfOutput); pRes->length = calloc(numOfOutput, sizeof(int32_t)); // todo refactor
pRes->buffer = calloc(numOfOutput, POINTER_BYTES);
// not enough memory // not enough memory
if (pRes->tsrow == NULL || (pRes->buffer == NULL && pRes->numOfCols > 0)) { if (pRes->tsrow == NULL || (pRes->buffer == NULL && pRes->numOfCols > 0)) {
tfree(pRes->tsrow); tfree(pRes->tsrow);
tfree(pRes->buffer); tfree(pRes->buffer);
tfree(pRes->length);
pRes->code = TSDB_CODE_CLI_OUT_OF_MEMORY; pRes->code = TSDB_CODE_CLI_OUT_OF_MEMORY;
return pRes->code; return pRes->code;
...@@ -312,6 +314,7 @@ void tscDestroyResPointerInfo(SSqlRes* pRes) { ...@@ -312,6 +314,7 @@ void tscDestroyResPointerInfo(SSqlRes* pRes) {
tfree(pRes->pRsp); tfree(pRes->pRsp);
tfree(pRes->tsrow); tfree(pRes->tsrow);
tfree(pRes->length);
tfree(pRes->pGroupRec); tfree(pRes->pGroupRec);
tfree(pRes->pColumnIndex); tfree(pRes->pColumnIndex);
...@@ -592,7 +595,7 @@ int32_t tscGetDataBlockFromList(void* pHashList, SDataBlockList* pDataBlockList, ...@@ -592,7 +595,7 @@ int32_t tscGetDataBlockFromList(void* pHashList, SDataBlockList* pDataBlockList,
} }
static int trimDataBlock(void* pDataBlock, STableDataBlocks* pTableDataBlock) { static int trimDataBlock(void* pDataBlock, STableDataBlocks* pTableDataBlock) {
// TODO: optimize this function // TODO: optimize this function, handle the case while binary is not presented
int len = 0; int len = 0;
STableMeta* pTableMeta = pTableDataBlock->pTableMeta; STableMeta* pTableMeta = pTableDataBlock->pTableMeta;
...@@ -924,7 +927,7 @@ static SSqlExpr* doBuildSqlExpr(SQueryInfo* pQueryInfo, int16_t functionId, SCol ...@@ -924,7 +927,7 @@ static SSqlExpr* doBuildSqlExpr(SQueryInfo* pQueryInfo, int16_t functionId, SCol
SSqlExpr* pExpr = calloc(1, sizeof(SSqlExpr)); SSqlExpr* pExpr = calloc(1, sizeof(SSqlExpr));
pExpr->functionId = functionId; pExpr->functionId = functionId;
// set the correct column index // set the correct columnIndex index
if (pColIndex->columnIndex == TSDB_TBNAME_COLUMN_INDEX) { if (pColIndex->columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
pExpr->colInfo.colId = TSDB_TBNAME_COLUMN_INDEX; pExpr->colInfo.colId = TSDB_TBNAME_COLUMN_INDEX;
} else { } else {
...@@ -1063,7 +1066,7 @@ void tscSqlExprCopy(SArray* dst, const SArray* src, uint64_t uid, bool deepcopy) ...@@ -1063,7 +1066,7 @@ void tscSqlExprCopy(SArray* dst, const SArray* src, uint64_t uid, bool deepcopy)
} }
SColumn* tscColumnListInsert(SArray* pColumnList, SColumnIndex* pColIndex) { SColumn* tscColumnListInsert(SArray* pColumnList, SColumnIndex* pColIndex) {
// ignore the tbname column to be inserted into source list // ignore the tbname columnIndex to be inserted into source list
if (pColIndex->columnIndex < 0) { if (pColIndex->columnIndex < 0) {
return NULL; return NULL;
} }
...@@ -2124,11 +2127,13 @@ void tscTryQueryNextClause(SSqlObj* pSql, void (*queryFp)()) { ...@@ -2124,11 +2127,13 @@ void tscTryQueryNextClause(SSqlObj* pSql, void (*queryFp)()) {
} }
} }
char* tscGetResultColumnChr(SSqlRes* pRes, SQueryInfo* pQueryInfo, int32_t column, int16_t bytes) { void tscGetResultColumnChr(SSqlRes* pRes, SFieldInfo* pFieldInfo, int32_t columnIndex) {
SFieldInfo* pFieldInfo = &pQueryInfo->fieldsInfo; SFieldSupInfo* pInfo = tscFieldInfoGetSupp(pFieldInfo, columnIndex);
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(pFieldInfo, column); assert(pInfo->pSqlExpr != NULL);
int32_t type = pInfo->pSqlExpr->resType; int32_t type = pInfo->pSqlExpr->resType;
int32_t bytes = pInfo->pSqlExpr->resBytes;
char* pData = ((char*) pRes->data) + pInfo->pSqlExpr->offset * pRes->numOfRows + bytes * pRes->row; char* pData = ((char*) pRes->data) + pInfo->pSqlExpr->offset * pRes->numOfRows + bytes * pRes->row;
if (type == TSDB_DATA_TYPE_NCHAR || type == TSDB_DATA_TYPE_BINARY) { if (type == TSDB_DATA_TYPE_NCHAR || type == TSDB_DATA_TYPE_BINARY) {
...@@ -2137,9 +2142,13 @@ char* tscGetResultColumnChr(SSqlRes* pRes, SQueryInfo* pQueryInfo, int32_t colum ...@@ -2137,9 +2142,13 @@ char* tscGetResultColumnChr(SSqlRes* pRes, SQueryInfo* pQueryInfo, int32_t colum
*(char*) (pData + realLen + VARSTR_HEADER_SIZE) = 0; *(char*) (pData + realLen + VARSTR_HEADER_SIZE) = 0;
} }
return pData + VARSTR_HEADER_SIZE; // head is the length of binary/nchar data pRes->tsrow[columnIndex] = pData + VARSTR_HEADER_SIZE;
pRes->length[columnIndex] = realLen;
} else { } else {
return pData; assert(bytes == tDataTypeDesc[type].nSize);
pRes->tsrow[columnIndex] = pData;
pRes->length[columnIndex] = bytes;
} }
} }
...@@ -32,7 +32,7 @@ extern "C" { ...@@ -32,7 +32,7 @@ extern "C" {
#define STR_WITH_MAXSIZE_TO_VARSTR(x, str, _maxs) do {\ #define STR_WITH_MAXSIZE_TO_VARSTR(x, str, _maxs) do {\
char* _e = stpncpy((char*)(x) + VARSTR_HEADER_SIZE, (str), (_maxs));\ char* _e = stpncpy((char*)(x) + VARSTR_HEADER_SIZE, (str), (_maxs));\
*(VarDataLenT*)(x) = _e - (x);\ *(VarDataLenT*)(x) = (_e - (x) - VARSTR_HEADER_SIZE);\
} while(0) } while(0)
#define STR_WITH_SIZE_TO_VARSTR(x, str, _size) do {\ #define STR_WITH_SIZE_TO_VARSTR(x, str, _size) do {\
......
...@@ -228,7 +228,7 @@ static void dnodeHandleIdleWorker(SWriteWorker *pWorker) { ...@@ -228,7 +228,7 @@ static void dnodeHandleIdleWorker(SWriteWorker *pWorker) {
int32_t num = taosGetQueueNumber(pWorker->qset); int32_t num = taosGetQueueNumber(pWorker->qset);
if (num > 0) { if (num > 0) {
usleep(30); usleep(30000);
sched_yield(); sched_yield();
} else { } else {
taosFreeQall(pWorker->qall); taosFreeQall(pWorker->qall);
......
...@@ -55,7 +55,7 @@ typedef enum { ...@@ -55,7 +55,7 @@ typedef enum {
typedef struct taosField { typedef struct taosField {
char name[64]; char name[64];
short bytes; short bytes;
char type; uint8_t type;
} TAOS_FIELD; } TAOS_FIELD;
#ifdef _TD_GO_DLL_ #ifdef _TD_GO_DLL_
...@@ -104,6 +104,8 @@ DLL_EXPORT void taos_stop_query(TAOS_RES *res); ...@@ -104,6 +104,8 @@ DLL_EXPORT void taos_stop_query(TAOS_RES *res);
int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows); int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows);
int taos_validate_sql(TAOS *taos, const char *sql); int taos_validate_sql(TAOS *taos, const char *sql);
int* taos_fetch_lengths(TAOS_RES *res);
// TAOS_RES *taos_list_tables(TAOS *mysql, const char *wild); // TAOS_RES *taos_list_tables(TAOS *mysql, const char *wild);
// TAOS_RES *taos_list_dbs(TAOS *mysql, const char *wild); // TAOS_RES *taos_list_dbs(TAOS *mysql, const char *wild);
......
...@@ -36,14 +36,17 @@ extern "C" { ...@@ -36,14 +36,17 @@ extern "C" {
typedef int32_t VarDataOffsetT; typedef int32_t VarDataOffsetT;
typedef int16_t VarDataLenT; typedef int16_t VarDataLenT;
#define VARSTR_HEADER_SIZE sizeof(VarDataLenT)
#define varDataLen(v) ((VarDataLenT *)(v))[0] #define varDataLen(v) ((VarDataLenT *)(v))[0]
#define varDataTLen(v) (sizeof(VarDataLenT) + varDataLen(v)) #define varDataTLen(v) (sizeof(VarDataLenT) + varDataLen(v))
#define varDataVal(v) ((void *)((char *)v + sizeof(VarDataLenT))) #define varDataVal(v) ((void *)((char *)v + sizeof(VarDataLenT)))
#define varDataCopy(dst, v) memcpy((dst), (void*) (v), varDataTLen(v)) #define varDataCopy(dst, v) memcpy((dst), (void*) (v), varDataTLen(v))
#define varDataLenByData(v) (*(VarDataLenT *)(((char*)(v)) - VARSTR_HEADER_SIZE))
// this data type is internally used only in 'in' query to hold the values // this data type is internally used only in 'in' query to hold the values
#define TSDB_DATA_TYPE_ARRAY (TSDB_DATA_TYPE_NCHAR + 1) #define TSDB_DATA_TYPE_ARRAY (TSDB_DATA_TYPE_NCHAR + 1)
#define VARSTR_HEADER_SIZE sizeof(VarDataLenT)
// Bytes for each type. // Bytes for each type.
extern const int32_t TYPE_BYTES[11]; extern const int32_t TYPE_BYTES[11];
......
...@@ -350,6 +350,8 @@ int shellDumpResult(TAOS *con, char *fname, int *error_no, bool printMode) { ...@@ -350,6 +350,8 @@ int shellDumpResult(TAOS *con, char *fname, int *error_no, bool printMode) {
TAOS_FIELD *fields = taos_fetch_fields(result); TAOS_FIELD *fields = taos_fetch_fields(result);
row = taos_fetch_row(result); row = taos_fetch_row(result);
int32_t* length = taos_fetch_lengths(result);
char t_str[TSDB_MAX_BYTES_PER_ROW] = "\0"; char t_str[TSDB_MAX_BYTES_PER_ROW] = "\0";
int l[TSDB_MAX_COLUMNS] = {0}; int l[TSDB_MAX_COLUMNS] = {0};
int maxLenColumnName = 0; int maxLenColumnName = 0;
...@@ -457,7 +459,7 @@ int shellDumpResult(TAOS *con, char *fname, int *error_no, bool printMode) { ...@@ -457,7 +459,7 @@ int shellDumpResult(TAOS *con, char *fname, int *error_no, bool printMode) {
case TSDB_DATA_TYPE_BINARY: case TSDB_DATA_TYPE_BINARY:
case TSDB_DATA_TYPE_NCHAR: case TSDB_DATA_TYPE_NCHAR:
memset(t_str, 0, TSDB_MAX_BYTES_PER_ROW); memset(t_str, 0, TSDB_MAX_BYTES_PER_ROW);
memcpy(t_str, row[i], fields[i].bytes); memcpy(t_str, row[i], length[i]);
/* printf("%-*s|",max(fields[i].bytes, strlen(fields[i].name)), /* printf("%-*s|",max(fields[i].bytes, strlen(fields[i].name)),
* t_str); */ * t_str); */
/* printf("%-*s|", l[i], t_str); */ /* printf("%-*s|", l[i], t_str); */
...@@ -532,7 +534,8 @@ int shellDumpResult(TAOS *con, char *fname, int *error_no, bool printMode) { ...@@ -532,7 +534,8 @@ int shellDumpResult(TAOS *con, char *fname, int *error_no, bool printMode) {
case TSDB_DATA_TYPE_BINARY: case TSDB_DATA_TYPE_BINARY:
case TSDB_DATA_TYPE_NCHAR: case TSDB_DATA_TYPE_NCHAR:
memset(t_str, 0, TSDB_MAX_BYTES_PER_ROW); memset(t_str, 0, TSDB_MAX_BYTES_PER_ROW);
memcpy(t_str, row[i], fields[i].bytes); memcpy(t_str, row[i], length[i]);
l[i] = MAX(fields[i].bytes, strlen(fields[i].name)); l[i] = MAX(fields[i].bytes, strlen(fields[i].name));
shellPrintNChar(t_str, l[i], printMode); shellPrintNChar(t_str, l[i], printMode);
break; break;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册