diff --git a/source/dnode/vnode/src/tsdb/tsdbCacheRead.c b/source/dnode/vnode/src/tsdb/tsdbCacheRead.c index 53f8d5be16894dd1e0d64d8816c43ff4ceff09e2..99c314fa45c42dfebd641fe8a8cfd6764c02f3fb 100644 --- a/source/dnode/vnode/src/tsdb/tsdbCacheRead.c +++ b/source/dnode/vnode/src/tsdb/tsdbCacheRead.c @@ -29,12 +29,14 @@ typedef struct SCacheRowsReader { SArray* pTableList; // table id list } SCacheRowsReader; +#define HASTYPE(_type, _t) (((_type) & (_t)) == (_t)) + static void saveOneRow(SArray* pRow, SSDataBlock* pBlock, SCacheRowsReader* pReader, const int32_t* slotIds, void** pRes) { ASSERT(pReader->numOfCols <= taosArrayGetSize(pBlock->pDataBlock)); int32_t numOfRows = pBlock->info.rows; - if ((pReader->type & CACHESCAN_RETRIEVE_LAST) == CACHESCAN_RETRIEVE_LAST) { + if (HASTYPE(pReader->type, CACHESCAN_RETRIEVE_LAST)) { for (int32_t i = 0; i < pReader->numOfCols; ++i) { SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i); SFirstLastRes* p = (SFirstLastRes*)varDataVal(pRes[i]); @@ -54,7 +56,7 @@ static void saveOneRow(SArray* pRow, SSDataBlock* pBlock, SCacheRowsReader* pRea if (IS_VAR_DATA_TYPE(pColVal->colVal.type)) { varDataSetLen(p->buf, pColVal->colVal.value.nData); memcpy(varDataVal(p->buf), pColVal->colVal.value.pData, pColVal->colVal.value.nData); - p->bytes = pColVal->colVal.value.nData + VARSTR_HEADER_SIZE; + p->bytes = pColVal->colVal.value.nData + VARSTR_HEADER_SIZE; // binary needs to plus the header size } else { memcpy(p->buf, &pColVal->colVal.value, pReader->pSchema->columns[slotId].bytes); p->bytes = pReader->pSchema->columns[slotId].bytes; @@ -62,12 +64,13 @@ static void saveOneRow(SArray* pRow, SSDataBlock* pBlock, SCacheRowsReader* pRea } } + // pColInfoData->info.bytes includes the VARSTR_HEADER_SIZE, need to substruct it p->hasResult = true; - varDataSetLen(pRes[i], pColInfoData->info.bytes); + varDataSetLen(pRes[i], pColInfoData->info.bytes - VARSTR_HEADER_SIZE); colDataAppend(pColInfoData, numOfRows, (const char*)pRes[i], false); } } else { - ASSERT((pReader->type & CACHESCAN_RETRIEVE_LAST_ROW) == CACHESCAN_RETRIEVE_LAST_ROW); + ASSERT(HASTYPE(pReader->type, CACHESCAN_RETRIEVE_LAST_ROW)); for (int32_t i = 0; i < pReader->numOfCols; ++i) { SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i); @@ -177,6 +180,13 @@ static int32_t doExtractCacheRow(SCacheRowsReader* pr, SLRUCache* lruCache, uint return code; } +static void freeItem(void* pItem) { + SLastCol* pCol = (SLastCol*) pItem; + if (IS_VAR_DATA_TYPE(pCol->colVal.type)) { + taosMemoryFree(pCol->colVal.value.pData); + } +} + int32_t tsdbRetrieveCacheRows(void* pReader, SSDataBlock* pResBlock, const int32_t* slotIds, SArray* pTableUidList) { if (pReader == NULL || pResBlock == NULL) { return TSDB_CODE_INVALID_PARA; @@ -217,7 +227,6 @@ int32_t tsdbRetrieveCacheRows(void* pReader, SSDataBlock* pResBlock, const int32 if (IS_VAR_DATA_TYPE(pCol->type)) { p.colVal.value.pData = taosMemoryCalloc(pCol->bytes, sizeof(char)); } - taosArrayPush(pLastCols, &p); } @@ -237,19 +246,25 @@ int32_t tsdbRetrieveCacheRows(void* pReader, SSDataBlock* pResBlock, const int32 { for (int32_t k = 0; k < pr->numOfCols; ++k) { - SLastCol* p = taosArrayGet(pLastCols, k); - if (slotIds[k] == -1) { // the primary timestamp - SLastCol* pCol = (SLastCol*)taosArrayGet(pRow, k); + int32_t slotId = slotIds[k]; + + if (slotId == -1) { // the primary timestamp + SLastCol* p = taosArrayGet(pLastCols, 0); + SLastCol* pCol = (SLastCol*)taosArrayGet(pRow, 0); if (pCol->ts > p->ts) { hasRes = true; p->ts = pCol->ts; p->colVal = pCol->colVal; } } else { - int32_t slotId = slotIds[k]; + SLastCol* p = taosArrayGet(pLastCols, slotId); SLastCol* pColVal = (SLastCol*)taosArrayGet(pRow, slotId); if (pColVal->ts > p->ts) { + if (!COL_VAL_IS_VALUE(&pColVal->colVal) && HASTYPE(pr->type, CACHESCAN_RETRIEVE_LAST)) { + continue; + } + hasRes = true; p->ts = pColVal->ts; @@ -308,6 +323,6 @@ int32_t tsdbRetrieveCacheRows(void* pReader, SSDataBlock* pResBlock, const int32 } taosMemoryFree(pRes); - taosArrayDestroy(pLastCols); + taosArrayDestroyEx(pLastCols, freeItem); return code; } diff --git a/tests/script/tsim/parser/last_cache_query.sim b/tests/script/tsim/parser/last_cache_query.sim index f32435960cbdae77462a342d6d87f9e9a28bec65..6cd53095907584b4023816da54c198031a29491b 100644 --- a/tests/script/tsim/parser/last_cache_query.sim +++ b/tests/script/tsim/parser/last_cache_query.sim @@ -39,6 +39,7 @@ if $data02 != 5.000000000 then return -1 endi if $data03 != 3 then + print expect 3, actual: $data03 return -1 endi if $data04 != @70-01-01 07:59:57.000@ then @@ -210,7 +211,7 @@ if $data01 != 6 then return -1 endi if $data02 != 37.000000000 then - print $data02 + print expect 37.000000000 actual: $data02 return -1 endi if $data03 != 27 then @@ -233,7 +234,7 @@ if $data01 != 6 then return -1 endi if $data02 != 37.000000000 then - print $data02 + print expect 37.000000000, acutal: $data02 return -1 endi if $data03 != 27 then