diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index b42724a2ec3b01be71b94b06f7e2ef7dbd8b9887..173db05e10a53316566db4edb661c4466cfc5f2f 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -748,6 +748,37 @@ typedef struct SJoinOperatorInfo { SRspResultInfo resultInfo; // todo refactor, add this info for each operator } SJoinOperatorInfo; +static void converNcharFilterColumn(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols, int32_t rows, bool *gotNchar) { + for (int32_t i = 0; i < numOfFilterCols; ++i) { + if (pFilterInfo[i].info.type == TSDB_DATA_TYPE_NCHAR) { + pFilterInfo[i].pData2 = pFilterInfo[i].pData; + pFilterInfo[i].pData = malloc(rows * pFilterInfo[i].info.bytes); + int32_t bufSize = pFilterInfo[i].info.bytes - VARSTR_HEADER_SIZE; + for (int32_t j = 0; j < rows; ++j) { + char* dst = (char *)pFilterInfo[i].pData + j * pFilterInfo[i].info.bytes; + char* src = (char *)pFilterInfo[i].pData2 + j * pFilterInfo[i].info.bytes; + int32_t len = 0; + taosMbsToUcs4(varDataVal(src), varDataLen(src), varDataVal(dst), bufSize, &len); + varDataLen(dst) = len; + } + *gotNchar = true; + } + } +} + +static void freeNcharFilterColumn(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols) { + for (int32_t i = 0; i < numOfFilterCols; ++i) { + if (pFilterInfo[i].info.type == TSDB_DATA_TYPE_NCHAR) { + if (pFilterInfo[i].pData2) { + tfree(pFilterInfo[i].pData); + pFilterInfo[i].pData = pFilterInfo[i].pData2; + pFilterInfo[i].pData2 = NULL; + } + } + } +} + + static void doSetupSDataBlock(SSqlRes* pRes, SSDataBlock* pBlock, SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols) { int32_t offset = 0; char* pData = pRes->data; @@ -766,8 +797,13 @@ static void doSetupSDataBlock(SSqlRes* pRes, SSDataBlock* pBlock, SSingleColumnF // filter data if needed if (numOfFilterCols > 0) { doSetFilterColumnInfo(pFilterInfo, numOfFilterCols, pBlock); + bool gotNchar = false; + converNcharFilterColumn(pFilterInfo, numOfFilterCols, pBlock->info.rows, &gotNchar); int8_t* p = calloc(pBlock->info.rows, sizeof(int8_t)); bool all = doFilterDataBlock(pFilterInfo, numOfFilterCols, pBlock->info.rows, p); + if (gotNchar) { + freeNcharFilterColumn(pFilterInfo, numOfFilterCols); + } if (!all) { doCompactSDataBlock(pBlock, pBlock->info.rows, p); } diff --git a/src/query/inc/qExecutor.h b/src/query/inc/qExecutor.h index bc934647ec4827faea4814dfbfb46acb34033668..1d26d292fafa3c2947279173221b9f461a11edbf 100644 --- a/src/query/inc/qExecutor.h +++ b/src/query/inc/qExecutor.h @@ -118,6 +118,7 @@ typedef struct SColumnFilterElem { typedef struct SSingleColumnFilterInfo { void* pData; + void* pData2; //used for nchar column int32_t numOfFilters; SColumnInfo info; SColumnFilterElem* pFilters;