[td-168] fix bug in var string handling
This commit is contained in:
parent
64a2c841bc
commit
f6067e1b31
|
@ -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
|
||||||
|
|
||||||
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) {
|
||||||
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) {
|
||||||
|
|
||||||
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) {
|
||||||
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)
|
||||||
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) {
|
||||||
|
|
||||||
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) {
|
||||||
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
|
||||||
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
|
||||||
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) {
|
||||||
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) {
|
||||||
|
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)()) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
*(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" {
|
||||||
|
|
||||||
#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) {
|
||||||
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);
|
||||||
|
|
|
@ -53,9 +53,9 @@ typedef enum {
|
||||||
} TSDB_OPTION;
|
} TSDB_OPTION;
|
||||||
|
|
||||||
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);
|
||||||
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" {
|
||||||
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) {
|
||||||
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) {
|
||||||
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) {
|
||||||
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;
|
||||||
|
|
Loading…
Reference in New Issue