From d5d873c7f89c7744eef055b1bb290fdfe7c92959 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Sat, 6 Aug 2022 11:32:29 +0800 Subject: [PATCH 1/5] fix(query): fix interp fill(prev) issue --- source/libs/executor/src/timewindowoperator.c | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index 8a0564c129..4cbe9e467f 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -2087,7 +2087,7 @@ static void doKeepPrevRows(STimeSliceOperatorInfo* pSliceInfo, const SSDataBlock } static void genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp* pExprSup, SSDataBlock* pBlock, - int32_t rowIndex, SSDataBlock* pResBlock) { + int32_t rowIndex, SSDataBlock* pResBlock, bool isPrevRowSet) { int32_t rows = pResBlock->info.rows; // todo set the correct primary timestamp column @@ -2163,6 +2163,10 @@ static void genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp break; } case TSDB_FILL_PREV: { + if (!isPrevRowSet) { + break; + } + SGroupKeys* pkey = taosArrayGet(pSliceInfo->pPrevRow, srcSlot); colDataAppend(pDst, rows, pkey->pData, false); pResBlock->info.rows += 1; @@ -2170,6 +2174,10 @@ static void genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp } case TSDB_FILL_NEXT: { + if (!isPrevRowSet) { + break; + } + char* p = colDataGetData(pSrc, rowIndex); colDataAppend(pDst, rows, p, colDataIsNull_s(pSrc, rowIndex)); pResBlock->info.rows += 1; @@ -2235,6 +2243,7 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { blockDataCleanup(pResBlock); //int32_t numOfRows = 0; + bool isPrevRowSet = false; while (1) { SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); if (pBlock == NULL) { @@ -2269,6 +2278,7 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { pResBlock->info.rows += 1; doKeepPrevRows(pSliceInfo, pBlock, i); + isPrevRowSet = true; pSliceInfo->current = taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); @@ -2285,7 +2295,7 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { int64_t nextTs = *(int64_t*)colDataGetData(pTsCol, i + 1); if (nextTs > pSliceInfo->current) { while (pSliceInfo->current < nextTs && pSliceInfo->current <= pSliceInfo->win.ekey) { - genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pBlock, i, pResBlock); + genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pBlock, i, pResBlock, isPrevRowSet); pSliceInfo->current = taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); if (pResBlock->info.rows >= pResBlock->info.capacity) { @@ -2302,10 +2312,11 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { } } else { // it is the last row of current block doKeepPrevRows(pSliceInfo, pBlock, i); + isPrevRowSet = true; } } else { // ts > pSliceInfo->current while (pSliceInfo->current < ts && pSliceInfo->current <= pSliceInfo->win.ekey) { - genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pBlock, i, pResBlock); + genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pBlock, i, pResBlock, isPrevRowSet); pSliceInfo->current = taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); if (pResBlock->info.rows >= pResBlock->info.capacity) { @@ -2329,6 +2340,7 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { pResBlock->info.rows += 1; doKeepPrevRows(pSliceInfo, pBlock, i); + isPrevRowSet = true; pSliceInfo->current = taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); @@ -2347,7 +2359,7 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { //check if need to interpolate after ts range while (pSliceInfo->current <= pSliceInfo->win.ekey) { - genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pBlock, pBlock->info.rows - 1, pResBlock); + genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pBlock, pBlock->info.rows - 1, pResBlock, isPrevRowSet); pSliceInfo->current = taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); if (pResBlock->info.rows >= pResBlock->info.capacity) { From 70f396799397ee754316b12c605924444fb4ec70 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Sat, 6 Aug 2022 14:42:48 +0800 Subject: [PATCH 2/5] fix(query): fix interp + fill(prev) result error --- source/libs/executor/src/timewindowoperator.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index 4cbe9e467f..1eee2c197e 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -2291,6 +2291,10 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { break; } } else if (ts < pSliceInfo->current) { + //in case interpolation window starts and ends between two datapoints, fill(prev) need to interpolate + doKeepPrevRows(pSliceInfo, pBlock, i); + isPrevRowSet = true; + if (i < pBlock->info.rows - 1) { int64_t nextTs = *(int64_t*)colDataGetData(pTsCol, i + 1); if (nextTs > pSliceInfo->current) { From 784752010afc5fac6aa8a7898530c929d6abe267 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Sat, 6 Aug 2022 16:18:11 +0800 Subject: [PATCH 3/5] fix(query): fix interp fill(next) result errors --- source/libs/executor/inc/executorimpl.h | 3 + source/libs/executor/src/timewindowoperator.c | 85 +++++++++++++++---- 2 files changed, 72 insertions(+), 16 deletions(-) diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index b62ff2bef1..f8a7ab330f 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -737,6 +737,9 @@ typedef struct STimeSliceOperatorInfo { SInterval interval; int64_t current; SArray* pPrevRow; // SArray + SArray* pNextRow; // SArray + bool isPrevRowSet; + bool isNextRowSet; int32_t fillType; // fill type SColumn tsCol; // primary timestamp column SExprSupp scalarSup; // scalar calculation diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index 1eee2c197e..9fcb255e9e 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -2084,10 +2084,30 @@ static void doKeepPrevRows(STimeSliceOperatorInfo* pSliceInfo, const SSDataBlock memcpy(pkey->pData, val, pkey->bytes); } } + + pSliceInfo->isPrevRowSet = true; +} + +static void doKeepNextRows(STimeSliceOperatorInfo* pSliceInfo, const SSDataBlock* pBlock, int32_t rowIndex) { + int32_t numOfCols = taosArrayGetSize(pBlock->pDataBlock); + for (int32_t i = 0; i < numOfCols; ++i) { + SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i); + + // null data should not be kept since it can not be used to perform interpolation + if (!colDataIsNull_s(pColInfoData, i)) { + SGroupKeys* pkey = taosArrayGet(pSliceInfo->pNextRow, i); + + pkey->isNull = false; + char* val = colDataGetData(pColInfoData, rowIndex); + memcpy(pkey->pData, val, pkey->bytes); + } + } + + pSliceInfo->isNextRowSet = true; } static void genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp* pExprSup, SSDataBlock* pBlock, - int32_t rowIndex, SSDataBlock* pResBlock, bool isPrevRowSet) { + int32_t rowIndex, SSDataBlock* pResBlock) { int32_t rows = pResBlock->info.rows; // todo set the correct primary timestamp column @@ -2163,7 +2183,7 @@ static void genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp break; } case TSDB_FILL_PREV: { - if (!isPrevRowSet) { + if (!pSliceInfo->isPrevRowSet) { break; } @@ -2174,12 +2194,14 @@ static void genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp } case TSDB_FILL_NEXT: { - if (!isPrevRowSet) { + if (!pSliceInfo->isNextRowSet) { break; } - char* p = colDataGetData(pSrc, rowIndex); - colDataAppend(pDst, rows, p, colDataIsNull_s(pSrc, rowIndex)); + //char* p = colDataGetData(pSrc, rowIndex); + //colDataAppend(pDst, rows, p, colDataIsNull_s(pSrc, rowIndex)); + SGroupKeys* pkey = taosArrayGet(pSliceInfo->pNextRow, srcSlot); + colDataAppend(pDst, rows, pkey->pData, false); pResBlock->info.rows += 1; break; } @@ -2213,6 +2235,35 @@ static int32_t initPrevRowsKeeper(STimeSliceOperatorInfo* pInfo, SSDataBlock* pB taosArrayPush(pInfo->pPrevRow, &key); } + pInfo->isPrevRowSet = false; + + return TSDB_CODE_SUCCESS; +} + +static int32_t initNextRowsKeeper(STimeSliceOperatorInfo* pInfo, SSDataBlock* pBlock) { + if (pInfo->pNextRow != NULL) { + return TSDB_CODE_SUCCESS; + } + + pInfo->pNextRow = taosArrayInit(4, sizeof(SGroupKeys)); + if (pInfo->pNextRow == NULL) { + return TSDB_CODE_OUT_OF_MEMORY; + } + + int32_t numOfCols = taosArrayGetSize(pBlock->pDataBlock); + for (int32_t i = 0; i < numOfCols; ++i) { + SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, i); + + SGroupKeys key = {0}; + key.bytes = pColInfo->info.bytes; + key.type = pColInfo->info.type; + key.isNull = false; + key.pData = taosMemoryCalloc(1, pColInfo->info.bytes); + taosArrayPush(pInfo->pNextRow, &key); + } + + pInfo->isNextRowSet = false; + return TSDB_CODE_SUCCESS; } @@ -2242,15 +2293,19 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { blockDataCleanup(pResBlock); - //int32_t numOfRows = 0; - bool isPrevRowSet = false; while (1) { SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); if (pBlock == NULL) { break; } - int32_t code = initPrevRowsKeeper(pSliceInfo, pBlock); + int32_t code; + code = initPrevRowsKeeper(pSliceInfo, pBlock); + if (code != TSDB_CODE_SUCCESS) { + longjmp(pTaskInfo->env, code); + } + + code = initNextRowsKeeper(pSliceInfo, pBlock); if (code != TSDB_CODE_SUCCESS) { longjmp(pTaskInfo->env, code); } @@ -2272,13 +2327,11 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { SColumnInfoData* pDst = taosArrayGet(pResBlock->pDataBlock, dstSlot); char* v = colDataGetData(pSrc, i); - //colDataAppend(pDst, numOfRows, v, false); colDataAppend(pDst, pResBlock->info.rows, v, false); } pResBlock->info.rows += 1; doKeepPrevRows(pSliceInfo, pBlock, i); - isPrevRowSet = true; pSliceInfo->current = taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); @@ -2293,13 +2346,12 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { } else if (ts < pSliceInfo->current) { //in case interpolation window starts and ends between two datapoints, fill(prev) need to interpolate doKeepPrevRows(pSliceInfo, pBlock, i); - isPrevRowSet = true; if (i < pBlock->info.rows - 1) { int64_t nextTs = *(int64_t*)colDataGetData(pTsCol, i + 1); if (nextTs > pSliceInfo->current) { while (pSliceInfo->current < nextTs && pSliceInfo->current <= pSliceInfo->win.ekey) { - genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pBlock, i, pResBlock, isPrevRowSet); + genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pBlock, i, pResBlock); pSliceInfo->current = taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); if (pResBlock->info.rows >= pResBlock->info.capacity) { @@ -2316,11 +2368,13 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { } } else { // it is the last row of current block doKeepPrevRows(pSliceInfo, pBlock, i); - isPrevRowSet = true; } } else { // ts > pSliceInfo->current + //in case interpolation window starts and ends between two datapoints, fill(next) need to interpolate + doKeepNextRows(pSliceInfo, pBlock, i); + while (pSliceInfo->current < ts && pSliceInfo->current <= pSliceInfo->win.ekey) { - genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pBlock, i, pResBlock, isPrevRowSet); + genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pBlock, i, pResBlock); pSliceInfo->current = taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); if (pResBlock->info.rows >= pResBlock->info.capacity) { @@ -2344,7 +2398,6 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { pResBlock->info.rows += 1; doKeepPrevRows(pSliceInfo, pBlock, i); - isPrevRowSet = true; pSliceInfo->current = taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); @@ -2363,7 +2416,7 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { //check if need to interpolate after ts range while (pSliceInfo->current <= pSliceInfo->win.ekey) { - genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pBlock, pBlock->info.rows - 1, pResBlock, isPrevRowSet); + genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pBlock, pBlock->info.rows - 1, pResBlock); pSliceInfo->current = taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); if (pResBlock->info.rows >= pResBlock->info.capacity) { From 8c3cc0161adaaeff9267808dbe79186383e5441f Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Sat, 6 Aug 2022 16:18:11 +0800 Subject: [PATCH 4/5] fix(query): fix interp fill(next) result errors --- source/libs/executor/src/timewindowoperator.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index 9fcb255e9e..f078bf4b56 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -2344,8 +2344,9 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { break; } } else if (ts < pSliceInfo->current) { - //in case interpolation window starts and ends between two datapoints, fill(prev) need to interpolate + //in case interpolation window starts and ends between two datapoints, fill(prev), fill(next) need to interpolate doKeepPrevRows(pSliceInfo, pBlock, i); + doKeepNextRows(pSliceInfo, pBlock, i + 1); if (i < pBlock->info.rows - 1) { int64_t nextTs = *(int64_t*)colDataGetData(pTsCol, i + 1); From 78fb4f51b0824a4a3e1397fa3158d6f9ce52aa64 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Sat, 6 Aug 2022 16:18:11 +0800 Subject: [PATCH 5/5] fix(query): fix interp fill(next) result errors --- source/libs/executor/src/timewindowoperator.c | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index f078bf4b56..d12410869a 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -2107,7 +2107,7 @@ static void doKeepNextRows(STimeSliceOperatorInfo* pSliceInfo, const SSDataBlock } static void genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp* pExprSup, SSDataBlock* pBlock, - int32_t rowIndex, SSDataBlock* pResBlock) { + SSDataBlock* pResBlock) { int32_t rows = pResBlock->info.rows; // todo set the correct primary timestamp column @@ -2198,8 +2198,6 @@ static void genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp break; } - //char* p = colDataGetData(pSrc, rowIndex); - //colDataAppend(pDst, rows, p, colDataIsNull_s(pSrc, rowIndex)); SGroupKeys* pkey = taosArrayGet(pSliceInfo->pNextRow, srcSlot); colDataAppend(pDst, rows, pkey->pData, false); pResBlock->info.rows += 1; @@ -2344,15 +2342,16 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { break; } } else if (ts < pSliceInfo->current) { - //in case interpolation window starts and ends between two datapoints, fill(prev), fill(next) need to interpolate + // in case interpolation window starts and ends between two datapoints, fill(prev) need to interpolate doKeepPrevRows(pSliceInfo, pBlock, i); - doKeepNextRows(pSliceInfo, pBlock, i + 1); if (i < pBlock->info.rows - 1) { + // in case interpolation window starts and ends between two datapoints, fill(next) need to interpolate + doKeepNextRows(pSliceInfo, pBlock, i + 1); int64_t nextTs = *(int64_t*)colDataGetData(pTsCol, i + 1); if (nextTs > pSliceInfo->current) { while (pSliceInfo->current < nextTs && pSliceInfo->current <= pSliceInfo->win.ekey) { - genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pBlock, i, pResBlock); + genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pBlock, pResBlock); pSliceInfo->current = taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); if (pResBlock->info.rows >= pResBlock->info.capacity) { @@ -2371,11 +2370,11 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { doKeepPrevRows(pSliceInfo, pBlock, i); } } else { // ts > pSliceInfo->current - //in case interpolation window starts and ends between two datapoints, fill(next) need to interpolate + // in case interpolation window starts and ends between two datapoints, fill(next) need to interpolate doKeepNextRows(pSliceInfo, pBlock, i); while (pSliceInfo->current < ts && pSliceInfo->current <= pSliceInfo->win.ekey) { - genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pBlock, i, pResBlock); + genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pBlock, pResBlock); pSliceInfo->current = taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); if (pResBlock->info.rows >= pResBlock->info.capacity) { @@ -2415,9 +2414,10 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { } } - //check if need to interpolate after ts range - while (pSliceInfo->current <= pSliceInfo->win.ekey) { - genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pBlock, pBlock->info.rows - 1, pResBlock); + // check if need to interpolate after ts range + // except for fill(next) + while (pSliceInfo->current <= pSliceInfo->win.ekey && pSliceInfo->fillType != TSDB_FILL_NEXT) { + genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pBlock, pResBlock); pSliceInfo->current = taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); if (pResBlock->info.rows >= pResBlock->info.capacity) {