From a7d21c9ee73c24aa7da8430ebe10008963d75afb Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Tue, 8 Nov 2022 14:50:03 +0800 Subject: [PATCH 01/10] enh: interp fill linear ignore null values during calculation --- source/libs/executor/inc/executorimpl.h | 1 - source/libs/executor/src/timewindowoperator.c | 166 ++++-------------- 2 files changed, 33 insertions(+), 134 deletions(-) diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index dedf1630af..03907a0d03 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -782,7 +782,6 @@ typedef struct STimeSliceOperatorInfo { SArray* pPrevRow; // SArray SArray* pNextRow; // SArray SArray* pLinearInfo; // SArray - bool fillLastPoint; bool isPrevRowSet; bool isNextRowSet; int32_t fillType; // fill type diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index 88f3e4cff9..ef99e31f67 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -1991,10 +1991,8 @@ static void doKeepNextRows(STimeSliceOperatorInfo* pSliceInfo, const SSDataBlock pSliceInfo->isNextRowSet = true; } -static void doKeepLinearInfo(STimeSliceOperatorInfo* pSliceInfo, const SSDataBlock* pBlock, int32_t rowIndex, - bool isLastRow) { +static void doKeepLinearInfo(STimeSliceOperatorInfo* pSliceInfo, const SSDataBlock* pBlock, int32_t rowIndex) { int32_t numOfCols = taosArrayGetSize(pBlock->pDataBlock); - bool fillLastPoint = pSliceInfo->fillLastPoint; for (int32_t i = 0; i < numOfCols; ++i) { SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i); SColumnInfoData* pTsCol = taosArrayGet(pBlock->pDataBlock, pSliceInfo->tsCol.slotId); @@ -2002,30 +2000,21 @@ static void doKeepLinearInfo(STimeSliceOperatorInfo* pSliceInfo, const SSDataBlo // null data should not be kept since it can not be used to perform interpolation if (!colDataIsNull_s(pColInfoData, i)) { - if (isLastRow) { + if (pLinearInfo->start.key == INT64_MIN) { pLinearInfo->start.key = *(int64_t*)colDataGetData(pTsCol, rowIndex); memcpy(pLinearInfo->start.val, colDataGetData(pColInfoData, rowIndex), pLinearInfo->bytes); - } else if (fillLastPoint) { + } else if (pLinearInfo->end.key == INT64_MAX) { pLinearInfo->end.key = *(int64_t*)colDataGetData(pTsCol, rowIndex); memcpy(pLinearInfo->end.val, colDataGetData(pColInfoData, rowIndex), pLinearInfo->bytes); } else { - pLinearInfo->start.key = *(int64_t*)colDataGetData(pTsCol, rowIndex); - pLinearInfo->end.key = *(int64_t*)colDataGetData(pTsCol, rowIndex + 1); - - char* val; - val = colDataGetData(pColInfoData, rowIndex); - memcpy(pLinearInfo->start.val, val, pLinearInfo->bytes); - val = colDataGetData(pColInfoData, rowIndex + 1); - memcpy(pLinearInfo->end.val, val, pLinearInfo->bytes); + pLinearInfo->start.key = pLinearInfo->end.key; + pLinearInfo->end.key = *(int64_t*)colDataGetData(pTsCol, rowIndex); + memcpy(pLinearInfo->start.val, pLinearInfo->end.val, pLinearInfo->bytes); + memcpy(pLinearInfo->end.val, colDataGetData(pColInfoData, rowIndex), pLinearInfo->bytes); } - - pLinearInfo->hasNull = false; - } else { - pLinearInfo->hasNull = true; } } - pSliceInfo->fillLastPoint = isLastRow; } static void genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp* pExprSup, SSDataBlock* pResBlock) { @@ -2209,15 +2198,9 @@ static int32_t initFillLinearInfo(STimeSliceOperatorInfo* pInfo, SSDataBlock* pB taosArrayPush(pInfo->pLinearInfo, &linearInfo); } - pInfo->fillLastPoint = false; - return TSDB_CODE_SUCCESS; } -static bool needToFillLastPoint(STimeSliceOperatorInfo* pSliceInfo) { - return (pSliceInfo->fillLastPoint == true && pSliceInfo->fillType == TSDB_FILL_LINEAR); -} - static int32_t initKeeperInfo(STimeSliceOperatorInfo* pInfo, SSDataBlock* pBlock) { int32_t code; code = initPrevRowsKeeper(pInfo, pBlock); @@ -2273,15 +2256,6 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { for (int32_t i = 0; i < pBlock->info.rows; ++i) { int64_t ts = *(int64_t*)colDataGetData(pTsCol, i); - if (i == 0 && needToFillLastPoint(pSliceInfo)) { // first row in current block - doKeepLinearInfo(pSliceInfo, pBlock, i, false); - while (pSliceInfo->current < ts && pSliceInfo->current <= pSliceInfo->win.ekey) { - genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pResBlock); - pSliceInfo->current = - taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); - } - } - if (pSliceInfo->current > pSliceInfo->win.ekey) { doSetOperatorCompleted(pOperator); break; @@ -2313,94 +2287,44 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { pResBlock->info.rows += 1; doKeepPrevRows(pSliceInfo, pBlock, i); + doKeepLinearInfo(pSliceInfo, pBlock, i); - // for linear interpolation, always fill value between this and next points; - // if its the first point in data block, also fill values between previous(if there's any) and this point; - // if its the last point in data block, no need to fill, but reserve this point as the start value and do - // the interpolation when processing next data block. - if (pSliceInfo->fillType == TSDB_FILL_LINEAR) { - pSliceInfo->current = - taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); - if (i < pBlock->info.rows - 1) { - doKeepLinearInfo(pSliceInfo, pBlock, i, false); - 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, pResBlock); - pSliceInfo->current = taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, - pInterval->precision); - } - - if (pSliceInfo->current > pSliceInfo->win.ekey) { - doSetOperatorCompleted(pOperator); - break; - } - } - } else { // it is the last row of current block - // store ts value as start, and calculate interp value when processing next block - doKeepLinearInfo(pSliceInfo, pBlock, i, true); - } - } else { // non-linear interpolation - pSliceInfo->current = - taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); - if (pSliceInfo->current > pSliceInfo->win.ekey) { - doSetOperatorCompleted(pOperator); - break; - } + pSliceInfo->current = + taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); + if (pSliceInfo->current > pSliceInfo->win.ekey) { + doSetOperatorCompleted(pOperator); + break; } } else if (ts < pSliceInfo->current) { // in case of interpolation window starts and ends between two datapoints, fill(prev) need to interpolate doKeepPrevRows(pSliceInfo, pBlock, i); + doKeepLinearInfo(pSliceInfo, pBlock, i); - if (pSliceInfo->fillType == TSDB_FILL_LINEAR) { - // no need to increate pSliceInfo->current here - // pSliceInfo->current = - // taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); - if (i < pBlock->info.rows - 1) { - doKeepLinearInfo(pSliceInfo, pBlock, i, false); - 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, pResBlock); - pSliceInfo->current = taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, - pInterval->precision); - } + if (i < pBlock->info.rows - 1) { + // in case of 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, pResBlock); + pSliceInfo->current = taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, + pInterval->precision); + } - if (pSliceInfo->current > pSliceInfo->win.ekey) { - doSetOperatorCompleted(pOperator); - break; - } + if (pSliceInfo->current > pSliceInfo->win.ekey) { + doSetOperatorCompleted(pOperator); + break; } } else { - // store ts value as start, and calculate interp value when processing next block - doKeepLinearInfo(pSliceInfo, pBlock, i, true); - } - } else { // non-linear interpolation - if (i < pBlock->info.rows - 1) { - // in case of 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, pResBlock); - pSliceInfo->current = taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, - pInterval->precision); - } - - if (pSliceInfo->current > pSliceInfo->win.ekey) { - doSetOperatorCompleted(pOperator); - break; - } - } else { - // ignore current row, and do nothing - } - } else { // it is the last row of current block - doKeepPrevRows(pSliceInfo, pBlock, i); + // ignore current row, and do nothing } + } else { // it is the last row of current block + doKeepPrevRows(pSliceInfo, pBlock, i); } } else { // ts > pSliceInfo->current // in case of interpolation window starts and ends between two datapoints, fill(next) need to interpolate doKeepNextRows(pSliceInfo, pBlock, i); + doKeepLinearInfo(pSliceInfo, pBlock, i); while (pSliceInfo->current < ts && pSliceInfo->current <= pSliceInfo->win.ekey) { genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pResBlock); @@ -2436,32 +2360,8 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { pResBlock->info.rows += 1; doKeepPrevRows(pSliceInfo, pBlock, i); - if (pSliceInfo->fillType == TSDB_FILL_LINEAR) { - pSliceInfo->current = - taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); - if (i < pBlock->info.rows - 1) { - doKeepLinearInfo(pSliceInfo, pBlock, i, false); - 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, pResBlock); - pSliceInfo->current = taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, - pInterval->precision); - } - - if (pSliceInfo->current > pSliceInfo->win.ekey) { - doSetOperatorCompleted(pOperator); - break; - } - } - } else { // it is the last row of current block - // store ts value as start, and calculate interp value when processing next block - doKeepLinearInfo(pSliceInfo, pBlock, i, true); - } - } else { // non-linear interpolation - pSliceInfo->current = - taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); - } + pSliceInfo->current = + taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); } if (pSliceInfo->current > pSliceInfo->win.ekey) { From 6aca4b8a5cef4c71b4b2f30680f3e2c08fb2a424 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Tue, 8 Nov 2022 14:50:03 +0800 Subject: [PATCH 02/10] enh: interp fill linear ignore null values during calculation --- source/libs/executor/inc/tfill.h | 1 - source/libs/executor/src/timewindowoperator.c | 43 +++++++++++-------- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/source/libs/executor/inc/tfill.h b/source/libs/executor/inc/tfill.h index ed019be767..7e0866f545 100644 --- a/source/libs/executor/inc/tfill.h +++ b/source/libs/executor/inc/tfill.h @@ -36,7 +36,6 @@ typedef struct SFillColInfo { typedef struct SFillLinearInfo { SPoint start; SPoint end; - bool hasNull; int16_t type; int32_t bytes; } SFillLinearInfo; diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index ef99e31f67..0950fcce2f 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -1999,7 +1999,7 @@ static void doKeepLinearInfo(STimeSliceOperatorInfo* pSliceInfo, const SSDataBlo SFillLinearInfo* pLinearInfo = taosArrayGet(pSliceInfo->pLinearInfo, i); // null data should not be kept since it can not be used to perform interpolation - if (!colDataIsNull_s(pColInfoData, i)) { + if (!colDataIsNull_s(pColInfoData, rowIndex)) { if (pLinearInfo->start.key == INT64_MIN) { pLinearInfo->start.key = *(int64_t*)colDataGetData(pTsCol, rowIndex); memcpy(pLinearInfo->start.val, colDataGetData(pColInfoData, rowIndex), pLinearInfo->bytes); @@ -2017,7 +2017,8 @@ static void doKeepLinearInfo(STimeSliceOperatorInfo* pSliceInfo, const SSDataBlo } -static void genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp* pExprSup, SSDataBlock* pResBlock) { +static bool genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp* pExprSup, SSDataBlock* pResBlock, + SSDataBlock* pSrcBlock, int32_t index, bool beforeRange) { int32_t rows = pResBlock->info.rows; blockDataEnsureCapacity(pResBlock, rows + 1); // todo set the correct primary timestamp column @@ -2036,7 +2037,6 @@ static void genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp } int32_t srcSlot = pExprInfo->base.pParam[0].pCol->slotId; - // SColumnInfoData* pSrc = taosArrayGet(pBlock->pDataBlock, srcSlot); switch (pSliceInfo->fillType) { case TSDB_FILL_NULL: { colDataAppendNULL(pDst, rows); @@ -2071,17 +2071,17 @@ static void genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp current.val = taosMemoryCalloc(pLinearInfo->bytes, 1); // before interp range, do not fill - if (start.key == INT64_MIN || end.key == INT64_MAX) { + SColumnInfoData* pSrc = taosArrayGet(pSrcBlock->pDataBlock, srcSlot); + if (colDataIsNull_s(pSrc, index) || (!beforeRange && end.key == INT64_MAX)) { hasInterp = false; break; + } else if (start.key == INT64_MIN || (beforeRange && end.key == INT64_MAX)) { + //hasInterp = true; + return true; } - if (pLinearInfo->hasNull) { - colDataAppendNULL(pDst, rows); - } else { - taosGetLinearInterpolationVal(¤t, pLinearInfo->type, &start, &end, pLinearInfo->type); - colDataAppend(pDst, rows, (char*)current.val, false); - } + taosGetLinearInterpolationVal(¤t, pLinearInfo->type, &start, &end, pLinearInfo->type); + colDataAppend(pDst, rows, (char*)current.val, false); taosMemoryFree(current.val); break; @@ -2117,6 +2117,8 @@ static void genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp if (hasInterp) { pResBlock->info.rows += 1; } + + return hasInterp; } static int32_t initPrevRowsKeeper(STimeSliceOperatorInfo* pInfo, SSDataBlock* pBlock) { @@ -2192,7 +2194,6 @@ static int32_t initFillLinearInfo(STimeSliceOperatorInfo* pInfo, SSDataBlock* pB linearInfo.end.key = INT64_MAX; linearInfo.start.val = taosMemoryCalloc(1, pColInfo->info.bytes); linearInfo.end.val = taosMemoryCalloc(1, pColInfo->info.bytes); - linearInfo.hasNull = false; linearInfo.type = pColInfo->info.type; linearInfo.bytes = pColInfo->info.bytes; taosArrayPush(pInfo->pLinearInfo, &linearInfo); @@ -2306,9 +2307,12 @@ 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, pResBlock); - pSliceInfo->current = taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, - pInterval->precision); + if (!genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pResBlock, pBlock, i, false) && pSliceInfo->fillType == TSDB_FILL_LINEAR) { + break; + } else { + pSliceInfo->current = + taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); + } } if (pSliceInfo->current > pSliceInfo->win.ekey) { @@ -2327,9 +2331,12 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { doKeepLinearInfo(pSliceInfo, pBlock, i); while (pSliceInfo->current < ts && pSliceInfo->current <= pSliceInfo->win.ekey) { - genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pResBlock); - pSliceInfo->current = - taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); + if (!genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pResBlock, pBlock, i, true) && pSliceInfo->fillType == TSDB_FILL_LINEAR) { + break; + } else { + pSliceInfo->current = + taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); + } } // add current row if timestamp match @@ -2376,7 +2383,7 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { // except for fill(next), fill(linear) while (pSliceInfo->current <= pSliceInfo->win.ekey && pSliceInfo->fillType != TSDB_FILL_NEXT && pSliceInfo->fillType != TSDB_FILL_LINEAR) { - genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pResBlock); + genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pResBlock, NULL, 0, false); pSliceInfo->current = taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); } From df3ae1341fe69192915a2ac8c30e3aab5a25c8a4 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Tue, 8 Nov 2022 14:50:03 +0800 Subject: [PATCH 03/10] add test cases --- tests/system-test/2-query/interp.py | 51 ++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/tests/system-test/2-query/interp.py b/tests/system-test/2-query/interp.py index ce6b85c1cf..4db074011d 100644 --- a/tests/system-test/2-query/interp.py +++ b/tests/system-test/2-query/interp.py @@ -311,7 +311,7 @@ class TDTestCase: ## {. . .} tdSql.query(f"select interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:04', '2020-02-01 00:00:16') every(1s) fill(linear)") - tdSql.checkRows(12) + tdSql.checkRows(11) tdSql.checkData(0, 0, 5) tdSql.checkData(1, 0, 6) tdSql.checkData(2, 0, 7) @@ -354,7 +354,7 @@ class TDTestCase: ## ..{.} tdSql.query(f"select interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:13', '2020-02-01 00:00:17') every(1s) fill(linear)") - tdSql.checkRows(5) + tdSql.checkRows(3) tdSql.checkData(0, 0, 13) tdSql.checkData(1, 0, 14) tdSql.checkData(2, 0, 15) @@ -555,7 +555,7 @@ class TDTestCase: tdSql.checkData(8, 0, '2020-02-01 00:00:12.000') tdSql.query(f"select _irowts,interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:04', '2020-02-01 00:00:16') every(1s) fill(linear)") - tdSql.checkRows(12) + tdSql.checkRows(11) tdSql.checkCols(2) tdSql.checkData(0, 0, '2020-02-01 00:00:05.000') @@ -583,7 +583,7 @@ class TDTestCase: # multiple _irowts tdSql.query(f"select interp(c0),_irowts from {dbname}.{tbname} range('2020-02-01 00:00:04', '2020-02-01 00:00:16') every(1s) fill(linear)") - tdSql.checkRows(12) + tdSql.checkRows(11) tdSql.checkCols(2) tdSql.checkData(0, 1, '2020-02-01 00:00:05.000') @@ -599,7 +599,7 @@ class TDTestCase: tdSql.checkData(10, 1, '2020-02-01 00:00:15.000') tdSql.query(f"select _irowts, interp(c0), interp(c0), _irowts from {dbname}.{tbname} range('2020-02-01 00:00:04', '2020-02-01 00:00:16') every(1s) fill(linear)") - tdSql.checkRows(12) + tdSql.checkRows(11) tdSql.checkCols(4) cols = (0, 3) @@ -837,6 +837,47 @@ class TDTestCase: tdSql.checkData(0, 0, 15) tdSql.checkData(1, 0, 15) + # test fill linear + + ## | {. | | .} | + tdSql.query(f"select interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:05', '2020-02-11 00:00:05') every(1d) fill(linear)") + tdSql.checkRows(11) + tdSql.checkData(0, 0, 5) + tdSql.checkData(1, 0, 6) + tdSql.checkData(2, 0, 7) + tdSql.checkData(3, 0, 8) + tdSql.checkData(4, 0, 9) + tdSql.checkData(5, 0, 10) + tdSql.checkData(6, 0, 11) + tdSql.checkData(7, 0, 12) + tdSql.checkData(8, 0, 13) + tdSql.checkData(9, 0, 14) + tdSql.checkData(10, 0, 15) + + ## | . | {} | . | + tdSql.query(f"select interp(c0) from {dbname}.{tbname} range('2020-02-03 00:00:05', '2020-02-07 00:00:05') every(1d) fill(linear)") + tdSql.checkRows(5) + tdSql.checkData(0, 0, 7) + tdSql.checkData(1, 0, 8) + tdSql.checkData(2, 0, 9) + tdSql.checkData(3, 0, 10) + tdSql.checkData(4, 0, 11) + + ## | {. | } | . | + tdSql.query(f"select interp(c0) from {dbname}.{tbname} range('2020-01-31 00:00:05', '2020-02-05 00:00:05') every(1d) fill(linear)") + tdSql.checkRows(5) + tdSql.checkData(0, 0, 5) + tdSql.checkData(1, 0, 6) + tdSql.checkData(2, 0, 7) + tdSql.checkData(3, 0, 8) + tdSql.checkData(4, 0, 9) + + ## | . | { | .} | + tdSql.query(f"select interp(c0) from {dbname}.{tbname} range('2020-02-10 00:00:05', '2020-02-15 00:00:05') every(1d) fill(linear)") + tdSql.checkRows(2) + tdSql.checkData(0, 0, 14) + tdSql.checkData(1, 0, 15) + tdLog.printNoPrefix("==========step10:test multi-interp cases") tdSql.query(f"select interp(c0),interp(c1),interp(c2),interp(c3) from {dbname}.{tbname} range('2020-02-09 00:00:05', '2020-02-13 00:00:05') every(1d) fill(null)") tdSql.checkRows(5) From f19f6201366badc90e3ddbdb070b1331b5dd23fb Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Tue, 8 Nov 2022 18:25:38 +0800 Subject: [PATCH 04/10] interp fill linear do not output NULL value --- source/libs/executor/src/timewindowoperator.c | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index 0950fcce2f..75d7010eb1 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -2018,7 +2018,7 @@ static void doKeepLinearInfo(STimeSliceOperatorInfo* pSliceInfo, const SSDataBlo } static bool genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp* pExprSup, SSDataBlock* pResBlock, - SSDataBlock* pSrcBlock, int32_t index, bool beforeRange) { + SSDataBlock* pSrcBlock, int32_t index, bool beforeTs) { int32_t rows = pResBlock->info.rows; blockDataEnsureCapacity(pResBlock, rows + 1); // todo set the correct primary timestamp column @@ -2072,10 +2072,10 @@ static bool genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp // before interp range, do not fill SColumnInfoData* pSrc = taosArrayGet(pSrcBlock->pDataBlock, srcSlot); - if (colDataIsNull_s(pSrc, index) || (!beforeRange && end.key == INT64_MAX)) { + if (colDataIsNull_s(pSrc, index) || (!beforeTs && end.key == INT64_MAX)) { hasInterp = false; break; - } else if (start.key == INT64_MIN || (beforeRange && end.key == INT64_MAX)) { + } else if (start.key == INT64_MIN || (beforeTs && end.key == INT64_MAX)) { //hasInterp = true; return true; } @@ -2264,6 +2264,7 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { if (ts == pSliceInfo->current) { blockDataEnsureCapacity(pResBlock, pResBlock->info.rows + 1); + bool isNullRow = false; for (int32_t j = 0; j < pOperator->exprSupp.numOfExprs; ++j) { SExprInfo* pExprInfo = &pOperator->exprSupp.pExprInfo[j]; @@ -2277,8 +2278,12 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { SColumnInfoData* pSrc = taosArrayGet(pBlock->pDataBlock, srcSlot); if (colDataIsNull_s(pSrc, i)) { - colDataAppendNULL(pDst, pResBlock->info.rows); - continue; + if (pSliceInfo->fillType != TSDB_FILL_LINEAR) { + colDataAppendNULL(pDst, pResBlock->info.rows); + continue; + } else { + isNullRow = true; + } } char* v = colDataGetData(pSrc, i); @@ -2286,7 +2291,9 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { } } - pResBlock->info.rows += 1; + if (!isNullRow) { + pResBlock->info.rows += 1; + } doKeepPrevRows(pSliceInfo, pBlock, i); doKeepLinearInfo(pSliceInfo, pBlock, i); @@ -2342,6 +2349,7 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { // add current row if timestamp match if (ts == pSliceInfo->current && pSliceInfo->current <= pSliceInfo->win.ekey) { blockDataEnsureCapacity(pResBlock, pResBlock->info.rows + 1); + bool isNullRow = false; for (int32_t j = 0; j < pOperator->exprSupp.numOfExprs; ++j) { SExprInfo* pExprInfo = &pOperator->exprSupp.pExprInfo[j]; @@ -2355,8 +2363,12 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { SColumnInfoData* pSrc = taosArrayGet(pBlock->pDataBlock, srcSlot); if (colDataIsNull_s(pSrc, i)) { - colDataAppendNULL(pDst, pResBlock->info.rows); - continue; + if (pSliceInfo->fillType != TSDB_FILL_LINEAR) { + colDataAppendNULL(pDst, pResBlock->info.rows); + continue; + } else { + isNullRow = true; + } } char* v = colDataGetData(pSrc, i); @@ -2364,7 +2376,9 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { } } - pResBlock->info.rows += 1; + if (!isNullRow) { + pResBlock->info.rows += 1; + } doKeepPrevRows(pSliceInfo, pBlock, i); pSliceInfo->current = From 7500f3e27eb52874b278703b6430c3dd72a3c20b Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Tue, 8 Nov 2022 18:26:07 +0800 Subject: [PATCH 05/10] add test case --- tests/system-test/2-query/interp.py | 256 +++++++++++++++++++++++++++- 1 file changed, 253 insertions(+), 3 deletions(-) diff --git a/tests/system-test/2-query/interp.py b/tests/system-test/2-query/interp.py index 4db074011d..fa5c35f782 100644 --- a/tests/system-test/2-query/interp.py +++ b/tests/system-test/2-query/interp.py @@ -18,6 +18,7 @@ class TDTestCase: def run(self): dbname = "db" tbname = "tb" + tbname1 = "tb1" stbname = "stb" ctbname1 = "ctb1" ctbname2 = "ctb2" @@ -878,7 +879,256 @@ class TDTestCase: tdSql.checkData(0, 0, 14) tdSql.checkData(1, 0, 15) - tdLog.printNoPrefix("==========step10:test multi-interp cases") + + tdLog.printNoPrefix("==========step10:test interp with null data") + tdSql.execute( + f'''create table if not exists {dbname}.{tbname1} + (ts timestamp, c0 int, c1 int) + ''' + ) + + + tdSql.execute(f"insert into {dbname}.{tbname1} values ('2020-02-02 00:00:00', 0, NULL)") + tdSql.execute(f"insert into {dbname}.{tbname1} values ('2020-02-02 00:00:05', NULL, NULL)") + tdSql.execute(f"insert into {dbname}.{tbname1} values ('2020-02-02 00:00:10', 10, 10)") + tdSql.execute(f"insert into {dbname}.{tbname1} values ('2020-02-02 00:00:15', NULL, NULL)") + tdSql.execute(f"insert into {dbname}.{tbname1} values ('2020-02-02 00:00:20', 20, NULL)") + tdSql.execute(f"insert into {dbname}.{tbname1} values ('2020-02-02 00:00:25', NULL, NULL)") + tdSql.execute(f"insert into {dbname}.{tbname1} values ('2020-02-02 00:00:30', 30, 30)") + tdSql.execute(f"insert into {dbname}.{tbname1} values ('2020-02-02 00:00:35', 35, NULL)") + tdSql.execute(f"insert into {dbname}.{tbname1} values ('2020-02-02 00:00:40', 40, 40)") + tdSql.execute(f"insert into {dbname}.{tbname1} values ('2020-02-02 00:00:45', NULL, 45)") + tdSql.execute(f"insert into {dbname}.{tbname1} values ('2020-02-02 00:00:50', 50, NULL)") + tdSql.execute(f"insert into {dbname}.{tbname1} values ('2020-02-02 00:00:55', NULL, NULL)") + tdSql.execute(f"insert into {dbname}.{tbname1} values ('2020-02-02 00:01:00', 55, 60)") + + # check c0 + tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-01 23:59:59', '2020-02-02 00:00:00') every(1s) fill(linear)") + tdSql.checkRows(1) + tdSql.checkData(0, 0, 0) + + tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-01 23:59:59', '2020-02-02 00:00:03') every(1s) fill(linear)") + tdSql.checkRows(1) + tdSql.checkData(0, 0, 0) + + tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-01 23:59:59', '2020-02-02 00:00:05') every(1s) fill(linear)") + tdSql.checkRows(1) + tdSql.checkData(0, 0, 0) + + tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-01 23:59:59', '2020-02-02 00:00:08') every(1s) fill(linear)") + tdSql.checkRows(9) + tdSql.checkData(0, 0, 0) + tdSql.checkData(1, 0, 1) + tdSql.checkData(2, 0, 2) + tdSql.checkData(3, 0, 3) + tdSql.checkData(4, 0, 4) + tdSql.checkData(5, 0, 5) + tdSql.checkData(6, 0, 6) + tdSql.checkData(7, 0, 7) + tdSql.checkData(8, 0, 8) + + + tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:01', '2020-02-02 00:00:03') every(1s) fill(linear)") + tdSql.checkRows(0) + + tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:03', '2020-02-02 00:00:08') every(1s) fill(linear)") + tdSql.checkRows(6) + tdSql.checkData(0, 0, 3) + tdSql.checkData(1, 0, 4) + tdSql.checkData(2, 0, 5) + tdSql.checkData(3, 0, 6) + tdSql.checkData(4, 0, 7) + tdSql.checkData(5, 0, 8) + + tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:05', '2020-02-02 00:00:10') every(1s) fill(linear)") + tdSql.checkRows(1) + tdSql.checkData(0, 0, 10) + + tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:05', '2020-02-02 00:00:15') every(1s) fill(linear)") + tdSql.checkRows(1) + tdSql.checkData(0, 0, 10) + + tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:05', '2020-02-02 00:00:18') every(1s) fill(linear)") + tdSql.checkRows(9) + tdSql.checkData(0, 0, 10) + tdSql.checkData(1, 0, 11) + tdSql.checkData(2, 0, 12) + tdSql.checkData(3, 0, 13) + tdSql.checkData(4, 0, 14) + tdSql.checkData(5, 0, 15) + tdSql.checkData(6, 0, 16) + tdSql.checkData(7, 0, 17) + tdSql.checkData(8, 0, 18) + + tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:05', '2020-02-02 00:00:20') every(1s) fill(linear)") + tdSql.checkRows(11) + tdSql.checkData(0, 0, 10) + tdSql.checkData(1, 0, 11) + tdSql.checkData(2, 0, 12) + tdSql.checkData(3, 0, 13) + tdSql.checkData(4, 0, 14) + tdSql.checkData(5, 0, 15) + tdSql.checkData(6, 0, 16) + tdSql.checkData(7, 0, 17) + tdSql.checkData(8, 0, 18) + tdSql.checkData(9, 0, 19) + tdSql.checkData(10, 0, 20) + + tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:09', '2020-02-02 00:00:11') every(1s) fill(linear)") + tdSql.checkRows(1) + tdSql.checkData(0, 0, 10) + + tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:10', '2020-02-02 00:00:15') every(1s) fill(linear)") + tdSql.checkRows(1) + tdSql.checkData(0, 0, 10) + + tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:12', '2020-02-02 00:00:13') every(1s) fill(linear)") + tdSql.checkRows(0) + + tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:12', '2020-02-02 00:00:15') every(1s) fill(linear)") + tdSql.checkRows(0) + + tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:12', '2020-02-02 00:00:18') every(1s) fill(linear)") + tdSql.checkRows(7) + tdSql.checkData(0, 0, 12) + tdSql.checkData(1, 0, 13) + tdSql.checkData(2, 0, 14) + tdSql.checkData(3, 0, 15) + tdSql.checkData(4, 0, 16) + tdSql.checkData(5, 0, 17) + tdSql.checkData(6, 0, 18) + + tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:30', '2020-02-02 00:00:40') every(1s) fill(linear)") + tdSql.checkRows(11) + tdSql.checkData(0, 0, 30) + tdSql.checkData(10, 0, 40) + + tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:25', '2020-02-02 00:00:45') every(1s) fill(linear)") + tdSql.checkRows(11) + tdSql.checkData(0, 0, 30) + tdSql.checkData(10, 0, 40) + + tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:25', '2020-02-02 00:00:45') every(1s) fill(linear)") + tdSql.checkRows(11) + tdSql.checkData(0, 0, 30) + tdSql.checkData(10, 0, 40) + + tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:20', '2020-02-02 00:00:40') every(1s) fill(linear)") + tdSql.checkRows(21) + tdSql.checkData(0, 0, 20) + tdSql.checkData(20, 0, 40) + + tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:30', '2020-02-02 00:00:50') every(1s) fill(linear)") + tdSql.checkRows(21) + tdSql.checkData(0, 0, 30) + tdSql.checkData(20, 0, 50) + + tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:20', '2020-02-02 00:00:50') every(1s) fill(linear)") + tdSql.checkRows(31) + tdSql.checkData(0, 0, 20) + tdSql.checkData(30, 0, 50) + + # check c1 + tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-01 23:59:59', '2020-02-02 00:00:05') every(1s) fill(linear)") + tdSql.checkRows(0) + + tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:05') every(1s) fill(linear)") + tdSql.checkRows(0) + + tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:08') every(1s) fill(linear)") + tdSql.checkRows(0) + + tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:10') every(1s) fill(linear)") + tdSql.checkRows(1) + tdSql.checkData(0, 0, 10) + + tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:15') every(1s) fill(linear)") + tdSql.checkRows(1) + tdSql.checkData(0, 0, 10) + + tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:20') every(1s) fill(linear)") + tdSql.checkRows(1) + tdSql.checkData(0, 0, 10) + + tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:25') every(1s) fill(linear)") + tdSql.checkRows(1) + tdSql.checkData(0, 0, 10) + + tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:30') every(1s) fill(linear)") + tdSql.checkRows(21) + tdSql.checkData(0, 0, 10) + tdSql.checkData(1, 0, 11) + tdSql.checkData(2, 0, 12) + tdSql.checkData(3, 0, 13) + tdSql.checkData(4, 0, 14) + tdSql.checkData(5, 0, 15) + tdSql.checkData(6, 0, 16) + tdSql.checkData(7, 0, 17) + tdSql.checkData(8, 0, 18) + tdSql.checkData(9, 0, 19) + tdSql.checkData(10, 0, 20) + tdSql.checkData(11, 0, 21) + tdSql.checkData(12, 0, 22) + tdSql.checkData(13, 0, 23) + tdSql.checkData(14, 0, 24) + tdSql.checkData(15, 0, 25) + tdSql.checkData(16, 0, 26) + tdSql.checkData(17, 0, 27) + tdSql.checkData(18, 0, 28) + tdSql.checkData(19, 0, 29) + tdSql.checkData(20, 0, 30) + + tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:35') every(1s) fill(linear)") + tdSql.checkRows(21) + tdSql.checkData(0, 0, 10) + tdSql.checkData(20, 0, 30) + + tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:40') every(1s) fill(linear)") + tdSql.checkRows(31) + tdSql.checkData(0, 0, 10) + tdSql.checkData(30, 0, 40) + + tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:45') every(1s) fill(linear)") + tdSql.checkRows(36) + tdSql.checkData(0, 0, 10) + tdSql.checkData(35, 0, 45) + + tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:50') every(1s) fill(linear)") + tdSql.checkRows(36) + tdSql.checkData(0, 0, 10) + tdSql.checkData(35, 0, 45) + + tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:55') every(1s) fill(linear)") + tdSql.checkRows(36) + tdSql.checkData(0, 0, 10) + tdSql.checkData(35, 0, 45) + + tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:01:00') every(1s) fill(linear)") + tdSql.checkRows(51) + tdSql.checkData(0, 0, 10) + tdSql.checkData(50, 0, 60) + + tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:40', '2020-02-02 00:00:45') every(1s) fill(linear)") + tdSql.checkRows(6) + tdSql.checkData(0, 0, 40) + tdSql.checkData(5, 0, 45) + + tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:35', '2020-02-02 00:00:50') every(1s) fill(linear)") + tdSql.checkRows(6) + tdSql.checkData(0, 0, 40) + tdSql.checkData(5, 0, 45) + + tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:35', '2020-02-02 00:00:55') every(1s) fill(linear)") + tdSql.checkRows(6) + tdSql.checkData(0, 0, 40) + tdSql.checkData(5, 0, 45) + + tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:30', '2020-02-02 00:01:00') every(1s) fill(linear)") + tdSql.checkRows(31) + tdSql.checkData(0, 0, 30) + tdSql.checkData(30, 0, 60) + + tdLog.printNoPrefix("==========step11:test multi-interp cases") tdSql.query(f"select interp(c0),interp(c1),interp(c2),interp(c3) from {dbname}.{tbname} range('2020-02-09 00:00:05', '2020-02-13 00:00:05') every(1d) fill(null)") tdSql.checkRows(5) tdSql.checkCols(4) @@ -932,7 +1182,7 @@ class TDTestCase: for i in range (tdSql.queryCols): tdSql.checkData(0, i, 13) - tdLog.printNoPrefix("==========step11:test error cases") + tdLog.printNoPrefix("==========step12:test error cases") tdSql.error(f"select interp(c0) from {dbname}.{tbname}") tdSql.error(f"select interp(c0) from {dbname}.{tbname} range('2020-02-10 00:00:05', '2020-02-15 00:00:05')") @@ -955,7 +1205,7 @@ class TDTestCase: tdSql.error(f"select interp('abcd') from {dbname}.{tbname} range('2020-02-10 00:00:05', '2020-02-15 00:00:05') every(1d) fill(null)") tdSql.error(f"select interp('中文字符') from {dbname}.{tbname} range('2020-02-10 00:00:05', '2020-02-15 00:00:05') every(1d) fill(null)") - tdLog.printNoPrefix("==========step12:stable cases") + tdLog.printNoPrefix("==========step13:stable cases") #tdSql.query(f"select interp(c0) from {dbname}.{stbname} range('2020-02-01 00:00:04', '2020-02-01 00:00:16') every(1s) fill(null)") #tdSql.checkRows(13) From b902ab0d6184f193bd384c6037b783f876281cf3 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Tue, 8 Nov 2022 18:48:22 +0800 Subject: [PATCH 06/10] refactor code --- source/libs/executor/src/timewindowoperator.c | 97 +++++++------------ 1 file changed, 36 insertions(+), 61 deletions(-) diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index 75d7010eb1..461a4fbe43 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -2121,6 +2121,40 @@ static bool genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp return hasInterp; } +static void addCurrentRowToResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp* pExprSup, SSDataBlock* pResBlock, + SSDataBlock* pSrcBlock, int32_t index) { + blockDataEnsureCapacity(pResBlock, pResBlock->info.rows + 1); + for (int32_t j = 0; j < pExprSup->numOfExprs; ++j) { + SExprInfo* pExprInfo = &pExprSup->pExprInfo[j]; + + int32_t dstSlot = pExprInfo->base.resSchema.slotId; + SColumnInfoData* pDst = taosArrayGet(pResBlock->pDataBlock, dstSlot); + + if (IS_TIMESTAMP_TYPE(pExprInfo->base.resSchema.type)) { + colDataAppend(pDst, pResBlock->info.rows, (char*)&pSliceInfo->current, false); + } else { + int32_t srcSlot = pExprInfo->base.pParam[0].pCol->slotId; + SColumnInfoData* pSrc = taosArrayGet(pSrcBlock->pDataBlock, srcSlot); + + if (colDataIsNull_s(pSrc, index)) { + if (pSliceInfo->fillType != TSDB_FILL_LINEAR) { + colDataAppendNULL(pDst, pResBlock->info.rows); + continue; + } else { + return; + } + } + + char* v = colDataGetData(pSrc, index); + colDataAppend(pDst, pResBlock->info.rows, v, false); + } + } + + pResBlock->info.rows += 1; + return; +} + + static int32_t initPrevRowsKeeper(STimeSliceOperatorInfo* pInfo, SSDataBlock* pBlock) { if (pInfo->pPrevRow != NULL) { return TSDB_CODE_SUCCESS; @@ -2263,37 +2297,8 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { } if (ts == pSliceInfo->current) { - blockDataEnsureCapacity(pResBlock, pResBlock->info.rows + 1); - bool isNullRow = false; - for (int32_t j = 0; j < pOperator->exprSupp.numOfExprs; ++j) { - SExprInfo* pExprInfo = &pOperator->exprSupp.pExprInfo[j]; + addCurrentRowToResult(pSliceInfo, &pOperator->exprSupp, pResBlock, pBlock, i); - int32_t dstSlot = pExprInfo->base.resSchema.slotId; - SColumnInfoData* pDst = taosArrayGet(pResBlock->pDataBlock, dstSlot); - - if (IS_TIMESTAMP_TYPE(pExprInfo->base.resSchema.type)) { - colDataAppend(pDst, pResBlock->info.rows, (char*)&pSliceInfo->current, false); - } else { - int32_t srcSlot = pExprInfo->base.pParam[0].pCol->slotId; - SColumnInfoData* pSrc = taosArrayGet(pBlock->pDataBlock, srcSlot); - - if (colDataIsNull_s(pSrc, i)) { - if (pSliceInfo->fillType != TSDB_FILL_LINEAR) { - colDataAppendNULL(pDst, pResBlock->info.rows); - continue; - } else { - isNullRow = true; - } - } - - char* v = colDataGetData(pSrc, i); - colDataAppend(pDst, pResBlock->info.rows, v, false); - } - } - - if (!isNullRow) { - pResBlock->info.rows += 1; - } doKeepPrevRows(pSliceInfo, pBlock, i); doKeepLinearInfo(pSliceInfo, pBlock, i); @@ -2348,37 +2353,7 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { // add current row if timestamp match if (ts == pSliceInfo->current && pSliceInfo->current <= pSliceInfo->win.ekey) { - blockDataEnsureCapacity(pResBlock, pResBlock->info.rows + 1); - bool isNullRow = false; - for (int32_t j = 0; j < pOperator->exprSupp.numOfExprs; ++j) { - SExprInfo* pExprInfo = &pOperator->exprSupp.pExprInfo[j]; - - int32_t dstSlot = pExprInfo->base.resSchema.slotId; - SColumnInfoData* pDst = taosArrayGet(pResBlock->pDataBlock, dstSlot); - - if (IS_TIMESTAMP_TYPE(pExprInfo->base.resSchema.type)) { - colDataAppend(pDst, pResBlock->info.rows, (char*)&pSliceInfo->current, false); - } else { - int32_t srcSlot = pExprInfo->base.pParam[0].pCol->slotId; - SColumnInfoData* pSrc = taosArrayGet(pBlock->pDataBlock, srcSlot); - - if (colDataIsNull_s(pSrc, i)) { - if (pSliceInfo->fillType != TSDB_FILL_LINEAR) { - colDataAppendNULL(pDst, pResBlock->info.rows); - continue; - } else { - isNullRow = true; - } - } - - char* v = colDataGetData(pSrc, i); - colDataAppend(pDst, pResBlock->info.rows, v, false); - } - } - - if (!isNullRow) { - pResBlock->info.rows += 1; - } + addCurrentRowToResult(pSliceInfo, &pOperator->exprSupp, pResBlock, pBlock, i); doKeepPrevRows(pSliceInfo, pBlock, i); pSliceInfo->current = From c8f069c6478fea167e8f77f8c7b3403b283cb4d3 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Fri, 18 Nov 2022 09:43:40 +0800 Subject: [PATCH 07/10] change interp linear behavior --- source/libs/executor/inc/tfill.h | 2 + source/libs/executor/src/timewindowoperator.c | 61 +++++++++++-------- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/source/libs/executor/inc/tfill.h b/source/libs/executor/inc/tfill.h index 7e0866f545..2d8df81dbd 100644 --- a/source/libs/executor/inc/tfill.h +++ b/source/libs/executor/inc/tfill.h @@ -36,6 +36,8 @@ typedef struct SFillColInfo { typedef struct SFillLinearInfo { SPoint start; SPoint end; + bool isStartSet; + bool isEndSet; int16_t type; int32_t bytes; } SFillLinearInfo; diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index 991a509d49..7582107c93 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -1991,27 +1991,36 @@ static void doKeepLinearInfo(STimeSliceOperatorInfo* pSliceInfo, const SSDataBlo SColumnInfoData* pTsCol = taosArrayGet(pBlock->pDataBlock, pSliceInfo->tsCol.slotId); SFillLinearInfo* pLinearInfo = taosArrayGet(pSliceInfo->pLinearInfo, i); - // null data should not be kept since it can not be used to perform interpolation - if (!colDataIsNull_s(pColInfoData, rowIndex)) { - if (pLinearInfo->start.key == INT64_MIN) { + // null value is represented by using key = INT64_MIN for now. + // TODO: optimize to ignore null values for linear interpolation. + if (!pLinearInfo->isStartSet) { + if (!colDataIsNull_s(pColInfoData, rowIndex)) { pLinearInfo->start.key = *(int64_t*)colDataGetData(pTsCol, rowIndex); memcpy(pLinearInfo->start.val, colDataGetData(pColInfoData, rowIndex), pLinearInfo->bytes); - } else if (pLinearInfo->end.key == INT64_MAX) { + } + pLinearInfo->isStartSet = true; + } else if (!pLinearInfo->isEndSet) { + if (!colDataIsNull_s(pColInfoData, rowIndex)) { + pLinearInfo->end.key = *(int64_t*)colDataGetData(pTsCol, rowIndex); + memcpy(pLinearInfo->end.val, colDataGetData(pColInfoData, rowIndex), pLinearInfo->bytes); + } + pLinearInfo->isEndSet = true; + } else { + pLinearInfo->start.key = pLinearInfo->end.key; + memcpy(pLinearInfo->start.val, pLinearInfo->end.val, pLinearInfo->bytes); + + if (!colDataIsNull_s(pColInfoData, rowIndex)) { pLinearInfo->end.key = *(int64_t*)colDataGetData(pTsCol, rowIndex); memcpy(pLinearInfo->end.val, colDataGetData(pColInfoData, rowIndex), pLinearInfo->bytes); } else { - pLinearInfo->start.key = pLinearInfo->end.key; - pLinearInfo->end.key = *(int64_t*)colDataGetData(pTsCol, rowIndex); - memcpy(pLinearInfo->start.val, pLinearInfo->end.val, pLinearInfo->bytes); - memcpy(pLinearInfo->end.val, colDataGetData(pColInfoData, rowIndex), pLinearInfo->bytes); + pLinearInfo->end.key = INT64_MIN; } } } } -static bool genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp* pExprSup, SSDataBlock* pResBlock, - SSDataBlock* pSrcBlock, int32_t index, bool beforeTs) { +static bool genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp* pExprSup, SSDataBlock* pResBlock) { int32_t rows = pResBlock->info.rows; blockDataEnsureCapacity(pResBlock, rows + 1); // todo set the correct primary timestamp column @@ -2061,18 +2070,18 @@ static bool genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp SPoint start = pLinearInfo->start; SPoint end = pLinearInfo->end; SPoint current = {.key = pSliceInfo->current}; - current.val = taosMemoryCalloc(pLinearInfo->bytes, 1); - // before interp range, do not fill - SColumnInfoData* pSrc = taosArrayGet(pSrcBlock->pDataBlock, srcSlot); - if (colDataIsNull_s(pSrc, index) || (!beforeTs && end.key == INT64_MAX)) { + if (!pLinearInfo->isStartSet || !pLinearInfo->isEndSet) { hasInterp = false; break; - } else if (start.key == INT64_MIN || (beforeTs && end.key == INT64_MAX)) { - //hasInterp = true; - return true; } + if (start.key == INT64_MIN || end.key == INT64_MIN) { + colDataAppendNULL(pDst, rows); + break; + } + + current.val = taosMemoryCalloc(pLinearInfo->bytes, 1); taosGetLinearInterpolationVal(¤t, pLinearInfo->type, &start, &end, pLinearInfo->type); colDataAppend(pDst, rows, (char*)current.val, false); @@ -2130,12 +2139,8 @@ static void addCurrentRowToResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp* SColumnInfoData* pSrc = taosArrayGet(pSrcBlock->pDataBlock, srcSlot); if (colDataIsNull_s(pSrc, index)) { - if (pSliceInfo->fillType != TSDB_FILL_LINEAR) { - colDataAppendNULL(pDst, pResBlock->info.rows); - continue; - } else { - return; - } + colDataAppendNULL(pDst, pResBlock->info.rows); + continue; } char* v = colDataGetData(pSrc, index); @@ -2218,9 +2223,11 @@ static int32_t initFillLinearInfo(STimeSliceOperatorInfo* pInfo, SSDataBlock* pB SFillLinearInfo linearInfo = {0}; linearInfo.start.key = INT64_MIN; - linearInfo.end.key = INT64_MAX; + linearInfo.end.key = INT64_MIN; linearInfo.start.val = taosMemoryCalloc(1, pColInfo->info.bytes); linearInfo.end.val = taosMemoryCalloc(1, pColInfo->info.bytes); + linearInfo.isStartSet = false; + linearInfo.isEndSet = false; linearInfo.type = pColInfo->info.type; linearInfo.bytes = pColInfo->info.bytes; taosArrayPush(pInfo->pLinearInfo, &linearInfo); @@ -2312,7 +2319,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) { - if (!genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pResBlock, pBlock, i, false) && pSliceInfo->fillType == TSDB_FILL_LINEAR) { + if (!genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pResBlock) && pSliceInfo->fillType == TSDB_FILL_LINEAR) { break; } else { pSliceInfo->current = @@ -2336,7 +2343,7 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { doKeepLinearInfo(pSliceInfo, pBlock, i); while (pSliceInfo->current < ts && pSliceInfo->current <= pSliceInfo->win.ekey) { - if (!genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pResBlock, pBlock, i, true) && pSliceInfo->fillType == TSDB_FILL_LINEAR) { + if (!genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pResBlock) && pSliceInfo->fillType == TSDB_FILL_LINEAR) { break; } else { pSliceInfo->current = @@ -2365,7 +2372,7 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { // except for fill(next), fill(linear) while (pSliceInfo->current <= pSliceInfo->win.ekey && pSliceInfo->fillType != TSDB_FILL_NEXT && pSliceInfo->fillType != TSDB_FILL_LINEAR) { - genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pResBlock, NULL, 0, false); + genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pResBlock); pSliceInfo->current = taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); } From 7291f2bd5adb979f7a8bfa449c4765000a037340 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Fri, 18 Nov 2022 09:43:40 +0800 Subject: [PATCH 08/10] change interp linear behavior --- source/libs/executor/src/timewindowoperator.c | 13 +- tests/system-test/2-query/interp.py | 482 +++++++++++++----- 2 files changed, 370 insertions(+), 125 deletions(-) diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index 7582107c93..5e1a5d1ec4 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -2020,7 +2020,7 @@ static void doKeepLinearInfo(STimeSliceOperatorInfo* pSliceInfo, const SSDataBlo } -static bool genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp* pExprSup, SSDataBlock* pResBlock) { +static bool genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp* pExprSup, SSDataBlock* pResBlock, bool beforeTs) { int32_t rows = pResBlock->info.rows; blockDataEnsureCapacity(pResBlock, rows + 1); // todo set the correct primary timestamp column @@ -2071,6 +2071,11 @@ static bool genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp SPoint end = pLinearInfo->end; SPoint current = {.key = pSliceInfo->current}; + // do not interpolate before ts range, only increate pSliceInfo->current + if (beforeTs && !pLinearInfo->isEndSet) { + return true; + } + if (!pLinearInfo->isStartSet || !pLinearInfo->isEndSet) { hasInterp = false; break; @@ -2319,7 +2324,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) { - if (!genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pResBlock) && pSliceInfo->fillType == TSDB_FILL_LINEAR) { + if (!genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pResBlock, false) && pSliceInfo->fillType == TSDB_FILL_LINEAR) { break; } else { pSliceInfo->current = @@ -2343,7 +2348,7 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { doKeepLinearInfo(pSliceInfo, pBlock, i); while (pSliceInfo->current < ts && pSliceInfo->current <= pSliceInfo->win.ekey) { - if (!genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pResBlock) && pSliceInfo->fillType == TSDB_FILL_LINEAR) { + if (!genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pResBlock, true) && pSliceInfo->fillType == TSDB_FILL_LINEAR) { break; } else { pSliceInfo->current = @@ -2372,7 +2377,7 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { // except for fill(next), fill(linear) while (pSliceInfo->current <= pSliceInfo->win.ekey && pSliceInfo->fillType != TSDB_FILL_NEXT && pSliceInfo->fillType != TSDB_FILL_LINEAR) { - genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pResBlock); + genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pResBlock, false); pSliceInfo->current = taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); } diff --git a/tests/system-test/2-query/interp.py b/tests/system-test/2-query/interp.py index fa5c35f782..b5bf6f9dbe 100644 --- a/tests/system-test/2-query/interp.py +++ b/tests/system-test/2-query/interp.py @@ -908,224 +908,464 @@ class TDTestCase: tdSql.checkData(0, 0, 0) tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-01 23:59:59', '2020-02-02 00:00:03') every(1s) fill(linear)") - tdSql.checkRows(1) + tdSql.checkRows(4) tdSql.checkData(0, 0, 0) + tdSql.checkData(1, 0, None) + tdSql.checkData(2, 0, None) + tdSql.checkData(3, 0, None) tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-01 23:59:59', '2020-02-02 00:00:05') every(1s) fill(linear)") - tdSql.checkRows(1) + tdSql.checkRows(6) tdSql.checkData(0, 0, 0) + tdSql.checkData(1, 0, None) + tdSql.checkData(2, 0, None) + tdSql.checkData(3, 0, None) + tdSql.checkData(4, 0, None) + tdSql.checkData(5, 0, None) tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-01 23:59:59', '2020-02-02 00:00:08') every(1s) fill(linear)") tdSql.checkRows(9) - tdSql.checkData(0, 0, 0) - tdSql.checkData(1, 0, 1) - tdSql.checkData(2, 0, 2) - tdSql.checkData(3, 0, 3) - tdSql.checkData(4, 0, 4) - tdSql.checkData(5, 0, 5) - tdSql.checkData(6, 0, 6) - tdSql.checkData(7, 0, 7) - tdSql.checkData(8, 0, 8) + tdSql.checkData(0, 0, None) + tdSql.checkData(1, 0, None) + tdSql.checkData(2, 0, None) + tdSql.checkData(3, 0, None) + tdSql.checkData(4, 0, None) + tdSql.checkData(5, 0, None) + tdSql.checkData(6, 0, None) + tdSql.checkData(7, 0, None) + tdSql.checkData(8, 0, None) tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:01', '2020-02-02 00:00:03') every(1s) fill(linear)") - tdSql.checkRows(0) + tdSql.checkRows(3) + tdSql.checkData(0, 0, None) + tdSql.checkData(1, 0, None) + tdSql.checkData(2, 0, None) tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:03', '2020-02-02 00:00:08') every(1s) fill(linear)") tdSql.checkRows(6) - tdSql.checkData(0, 0, 3) - tdSql.checkData(1, 0, 4) - tdSql.checkData(2, 0, 5) - tdSql.checkData(3, 0, 6) - tdSql.checkData(4, 0, 7) - tdSql.checkData(5, 0, 8) + tdSql.checkData(0, 0, None) + tdSql.checkData(1, 0, None) + tdSql.checkData(2, 0, None) + tdSql.checkData(3, 0, None) + tdSql.checkData(4, 0, None) + tdSql.checkData(5, 0, None) tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:05', '2020-02-02 00:00:10') every(1s) fill(linear)") - tdSql.checkRows(1) - tdSql.checkData(0, 0, 10) + tdSql.checkRows(6) + tdSql.checkData(0, 0, None) + tdSql.checkData(1, 0, None) + tdSql.checkData(2, 0, None) + tdSql.checkData(3, 0, None) + tdSql.checkData(4, 0, None) + tdSql.checkData(5, 0, 10) tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:05', '2020-02-02 00:00:15') every(1s) fill(linear)") - tdSql.checkRows(1) - tdSql.checkData(0, 0, 10) + tdSql.checkRows(11) + tdSql.checkData(0, 0, None) + tdSql.checkData(1, 0, None) + tdSql.checkData(2, 0, None) + tdSql.checkData(3, 0, None) + tdSql.checkData(4, 0, None) + tdSql.checkData(5, 0, 10) + tdSql.checkData(6, 0, None) + tdSql.checkData(7, 0, None) + tdSql.checkData(8, 0, None) + tdSql.checkData(9, 0, None) + tdSql.checkData(10, 0, None) tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:05', '2020-02-02 00:00:18') every(1s) fill(linear)") - tdSql.checkRows(9) - tdSql.checkData(0, 0, 10) - tdSql.checkData(1, 0, 11) - tdSql.checkData(2, 0, 12) - tdSql.checkData(3, 0, 13) - tdSql.checkData(4, 0, 14) - tdSql.checkData(5, 0, 15) - tdSql.checkData(6, 0, 16) - tdSql.checkData(7, 0, 17) - tdSql.checkData(8, 0, 18) + tdSql.checkRows(14) + tdSql.checkData(0, 0, None) + tdSql.checkData(1, 0, None) + tdSql.checkData(2, 0, None) + tdSql.checkData(3, 0, None) + tdSql.checkData(4, 0, None) + tdSql.checkData(5, 0, 10) + tdSql.checkData(6, 0, None) + tdSql.checkData(7, 0, None) + tdSql.checkData(8, 0, None) + tdSql.checkData(9, 0, None) + tdSql.checkData(10, 0, None) + tdSql.checkData(11, 0, None) + tdSql.checkData(12, 0, None) + tdSql.checkData(13, 0, None) tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:05', '2020-02-02 00:00:20') every(1s) fill(linear)") - tdSql.checkRows(11) - tdSql.checkData(0, 0, 10) - tdSql.checkData(1, 0, 11) - tdSql.checkData(2, 0, 12) - tdSql.checkData(3, 0, 13) - tdSql.checkData(4, 0, 14) - tdSql.checkData(5, 0, 15) - tdSql.checkData(6, 0, 16) - tdSql.checkData(7, 0, 17) - tdSql.checkData(8, 0, 18) - tdSql.checkData(9, 0, 19) - tdSql.checkData(10, 0, 20) + tdSql.checkRows(16) + tdSql.checkData(0, 0, None) + tdSql.checkData(1, 0, None) + tdSql.checkData(2, 0, None) + tdSql.checkData(3, 0, None) + tdSql.checkData(4, 0, None) + tdSql.checkData(5, 0, 10) + tdSql.checkData(6, 0, None) + tdSql.checkData(7, 0, None) + tdSql.checkData(8, 0, None) + tdSql.checkData(9, 0, None) + tdSql.checkData(10, 0, None) + tdSql.checkData(11, 0, None) + tdSql.checkData(12, 0, None) + tdSql.checkData(13, 0, None) + tdSql.checkData(14, 0, None) + tdSql.checkData(15, 0, 20) tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:09', '2020-02-02 00:00:11') every(1s) fill(linear)") - tdSql.checkRows(1) - tdSql.checkData(0, 0, 10) + tdSql.checkRows(3) + tdSql.checkData(0, 0, None) + tdSql.checkData(1, 0, 10) + tdSql.checkData(2, 0, None) tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:10', '2020-02-02 00:00:15') every(1s) fill(linear)") - tdSql.checkRows(1) + tdSql.checkRows(6) tdSql.checkData(0, 0, 10) + tdSql.checkData(1, 0, None) + tdSql.checkData(2, 0, None) + tdSql.checkData(3, 0, None) + tdSql.checkData(4, 0, None) + tdSql.checkData(5, 0, None) tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:12', '2020-02-02 00:00:13') every(1s) fill(linear)") - tdSql.checkRows(0) + tdSql.checkRows(2) + tdSql.checkData(0, 0, None) + tdSql.checkData(1, 0, None) tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:12', '2020-02-02 00:00:15') every(1s) fill(linear)") - tdSql.checkRows(0) + tdSql.checkRows(4) + tdSql.checkData(0, 0, None) + tdSql.checkData(1, 0, None) + tdSql.checkData(2, 0, None) + tdSql.checkData(3, 0, None) tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:12', '2020-02-02 00:00:18') every(1s) fill(linear)") tdSql.checkRows(7) - tdSql.checkData(0, 0, 12) - tdSql.checkData(1, 0, 13) - tdSql.checkData(2, 0, 14) - tdSql.checkData(3, 0, 15) - tdSql.checkData(4, 0, 16) - tdSql.checkData(5, 0, 17) - tdSql.checkData(6, 0, 18) + tdSql.checkData(0, 0, None) + tdSql.checkData(1, 0, None) + tdSql.checkData(2, 0, None) + tdSql.checkData(3, 0, None) + tdSql.checkData(4, 0, None) + tdSql.checkData(5, 0, None) + tdSql.checkData(6, 0, None) tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:30', '2020-02-02 00:00:40') every(1s) fill(linear)") tdSql.checkRows(11) tdSql.checkData(0, 0, 30) + tdSql.checkData(1, 0, 31) + tdSql.checkData(2, 0, 32) + tdSql.checkData(3, 0, 33) + tdSql.checkData(4, 0, 34) + tdSql.checkData(5, 0, 35) + tdSql.checkData(6, 0, 36) + tdSql.checkData(7, 0, 37) + tdSql.checkData(8, 0, 38) + tdSql.checkData(9, 0, 39) tdSql.checkData(10, 0, 40) tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:25', '2020-02-02 00:00:45') every(1s) fill(linear)") - tdSql.checkRows(11) - tdSql.checkData(0, 0, 30) - tdSql.checkData(10, 0, 40) - - tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:25', '2020-02-02 00:00:45') every(1s) fill(linear)") - tdSql.checkRows(11) - tdSql.checkData(0, 0, 30) - tdSql.checkData(10, 0, 40) + tdSql.checkRows(21) + tdSql.checkData(5, 0, 30) + tdSql.checkData(6, 0, 31) + tdSql.checkData(7, 0, 32) + tdSql.checkData(8, 0, 33) + tdSql.checkData(9, 0, 34) + tdSql.checkData(10, 0, 35) + tdSql.checkData(11, 0, 36) + tdSql.checkData(12, 0, 37) + tdSql.checkData(13, 0, 38) + tdSql.checkData(14, 0, 39) + tdSql.checkData(15, 0, 40) tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:20', '2020-02-02 00:00:40') every(1s) fill(linear)") tdSql.checkRows(21) tdSql.checkData(0, 0, 20) + tdSql.checkData(10, 0, 30) + tdSql.checkData(11, 0, 31) + tdSql.checkData(12, 0, 32) + tdSql.checkData(13, 0, 33) + tdSql.checkData(14, 0, 34) + tdSql.checkData(15, 0, 35) + tdSql.checkData(16, 0, 36) + tdSql.checkData(17, 0, 37) + tdSql.checkData(18, 0, 38) + tdSql.checkData(19, 0, 39) tdSql.checkData(20, 0, 40) tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:30', '2020-02-02 00:00:50') every(1s) fill(linear)") tdSql.checkRows(21) tdSql.checkData(0, 0, 30) + tdSql.checkData(1, 0, 31) + tdSql.checkData(2, 0, 32) + tdSql.checkData(3, 0, 33) + tdSql.checkData(4, 0, 34) + tdSql.checkData(5, 0, 35) + tdSql.checkData(6, 0, 36) + tdSql.checkData(7, 0, 37) + tdSql.checkData(8, 0, 38) + tdSql.checkData(9, 0, 39) + tdSql.checkData(10, 0, 40) tdSql.checkData(20, 0, 50) tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-02 00:00:20', '2020-02-02 00:00:50') every(1s) fill(linear)") tdSql.checkRows(31) tdSql.checkData(0, 0, 20) + tdSql.checkData(10, 0, 30) + tdSql.checkData(11, 0, 31) + tdSql.checkData(12, 0, 32) + tdSql.checkData(13, 0, 33) + tdSql.checkData(14, 0, 34) + tdSql.checkData(15, 0, 35) + tdSql.checkData(16, 0, 36) + tdSql.checkData(17, 0, 37) + tdSql.checkData(18, 0, 38) + tdSql.checkData(19, 0, 39) + tdSql.checkData(20, 0, 40) tdSql.checkData(30, 0, 50) # check c1 tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-01 23:59:59', '2020-02-02 00:00:05') every(1s) fill(linear)") - tdSql.checkRows(0) + tdSql.checkRows(6) + tdSql.checkData(0, 0, None) + tdSql.checkData(1, 0, None) + tdSql.checkData(2, 0, None) + tdSql.checkData(3, 0, None) + tdSql.checkData(4, 0, None) + tdSql.checkData(5, 0, None) tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:05') every(1s) fill(linear)") - tdSql.checkRows(0) + tdSql.checkRows(6) + tdSql.checkData(0, 0, None) + tdSql.checkData(1, 0, None) + tdSql.checkData(2, 0, None) + tdSql.checkData(3, 0, None) + tdSql.checkData(4, 0, None) + tdSql.checkData(5, 0, None) tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:08') every(1s) fill(linear)") - tdSql.checkRows(0) + tdSql.checkRows(9) + tdSql.checkData(0, 0, None) + tdSql.checkData(1, 0, None) + tdSql.checkData(2, 0, None) + tdSql.checkData(3, 0, None) + tdSql.checkData(4, 0, None) + tdSql.checkData(5, 0, None) + tdSql.checkData(6, 0, None) + tdSql.checkData(7, 0, None) + tdSql.checkData(8, 0, None) tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:10') every(1s) fill(linear)") - tdSql.checkRows(1) - tdSql.checkData(0, 0, 10) + tdSql.checkRows(11) + tdSql.checkData(0, 0, None) + tdSql.checkData(1, 0, None) + tdSql.checkData(2, 0, None) + tdSql.checkData(3, 0, None) + tdSql.checkData(4, 0, None) + tdSql.checkData(5, 0, None) + tdSql.checkData(6, 0, None) + tdSql.checkData(7, 0, None) + tdSql.checkData(8, 0, None) + tdSql.checkData(9, 0, None) + tdSql.checkData(10, 0, 10) tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:15') every(1s) fill(linear)") - tdSql.checkRows(1) - tdSql.checkData(0, 0, 10) + tdSql.checkRows(16) + tdSql.checkData(0, 0, None) + tdSql.checkData(1, 0, None) + tdSql.checkData(2, 0, None) + tdSql.checkData(3, 0, None) + tdSql.checkData(4, 0, None) + tdSql.checkData(5, 0, None) + tdSql.checkData(6, 0, None) + tdSql.checkData(7, 0, None) + tdSql.checkData(8, 0, None) + tdSql.checkData(9, 0, None) + tdSql.checkData(10, 0, 10) + tdSql.checkData(11, 0, None) + tdSql.checkData(12, 0, None) + tdSql.checkData(13, 0, None) + tdSql.checkData(14, 0, None) + tdSql.checkData(15, 0, None) tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:20') every(1s) fill(linear)") - tdSql.checkRows(1) - tdSql.checkData(0, 0, 10) + tdSql.checkRows(21) + tdSql.checkData(0, 0, None) + tdSql.checkData(1, 0, None) + tdSql.checkData(2, 0, None) + tdSql.checkData(3, 0, None) + tdSql.checkData(4, 0, None) + tdSql.checkData(5, 0, None) + tdSql.checkData(6, 0, None) + tdSql.checkData(7, 0, None) + tdSql.checkData(8, 0, None) + tdSql.checkData(9, 0, None) + tdSql.checkData(10, 0, 10) + tdSql.checkData(11, 0, None) + tdSql.checkData(12, 0, None) + tdSql.checkData(13, 0, None) + tdSql.checkData(14, 0, None) + tdSql.checkData(15, 0, None) + tdSql.checkData(16, 0, None) + tdSql.checkData(17, 0, None) + tdSql.checkData(18, 0, None) + tdSql.checkData(19, 0, None) + tdSql.checkData(20, 0, None) tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:25') every(1s) fill(linear)") - tdSql.checkRows(1) - tdSql.checkData(0, 0, 10) + tdSql.checkRows(26) + tdSql.checkData(0, 0, None) + tdSql.checkData(1, 0, None) + tdSql.checkData(2, 0, None) + tdSql.checkData(3, 0, None) + tdSql.checkData(4, 0, None) + tdSql.checkData(5, 0, None) + tdSql.checkData(6, 0, None) + tdSql.checkData(7, 0, None) + tdSql.checkData(8, 0, None) + tdSql.checkData(9, 0, None) + tdSql.checkData(10, 0, 10) + tdSql.checkData(11, 0, None) + tdSql.checkData(12, 0, None) + tdSql.checkData(13, 0, None) + tdSql.checkData(14, 0, None) + tdSql.checkData(15, 0, None) + tdSql.checkData(16, 0, None) + tdSql.checkData(17, 0, None) + tdSql.checkData(18, 0, None) + tdSql.checkData(19, 0, None) + tdSql.checkData(20, 0, None) + tdSql.checkData(21, 0, None) + tdSql.checkData(22, 0, None) + tdSql.checkData(23, 0, None) + tdSql.checkData(24, 0, None) + tdSql.checkData(25, 0, None) tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:30') every(1s) fill(linear)") - tdSql.checkRows(21) - tdSql.checkData(0, 0, 10) - tdSql.checkData(1, 0, 11) - tdSql.checkData(2, 0, 12) - tdSql.checkData(3, 0, 13) - tdSql.checkData(4, 0, 14) - tdSql.checkData(5, 0, 15) - tdSql.checkData(6, 0, 16) - tdSql.checkData(7, 0, 17) - tdSql.checkData(8, 0, 18) - tdSql.checkData(9, 0, 19) - tdSql.checkData(10, 0, 20) - tdSql.checkData(11, 0, 21) - tdSql.checkData(12, 0, 22) - tdSql.checkData(13, 0, 23) - tdSql.checkData(14, 0, 24) - tdSql.checkData(15, 0, 25) - tdSql.checkData(16, 0, 26) - tdSql.checkData(17, 0, 27) - tdSql.checkData(18, 0, 28) - tdSql.checkData(19, 0, 29) - tdSql.checkData(20, 0, 30) + tdSql.checkRows(31) + tdSql.checkData(0, 0, None) + tdSql.checkData(1, 0, None) + tdSql.checkData(2, 0, None) + tdSql.checkData(3, 0, None) + tdSql.checkData(4, 0, None) + tdSql.checkData(5, 0, None) + tdSql.checkData(6, 0, None) + tdSql.checkData(7, 0, None) + tdSql.checkData(8, 0, None) + tdSql.checkData(9, 0, None) + tdSql.checkData(10, 0, 10) + tdSql.checkData(11, 0, None) + tdSql.checkData(12, 0, None) + tdSql.checkData(13, 0, None) + tdSql.checkData(14, 0, None) + tdSql.checkData(15, 0, None) + tdSql.checkData(16, 0, None) + tdSql.checkData(17, 0, None) + tdSql.checkData(18, 0, None) + tdSql.checkData(19, 0, None) + tdSql.checkData(20, 0, None) + tdSql.checkData(21, 0, None) + tdSql.checkData(22, 0, None) + tdSql.checkData(23, 0, None) + tdSql.checkData(24, 0, None) + tdSql.checkData(25, 0, None) + tdSql.checkData(26, 0, None) + tdSql.checkData(27, 0, None) + tdSql.checkData(28, 0, None) + tdSql.checkData(29, 0, None) + tdSql.checkData(30, 0, 30) tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:35') every(1s) fill(linear)") - tdSql.checkRows(21) - tdSql.checkData(0, 0, 10) - tdSql.checkData(20, 0, 30) + tdSql.checkRows(36) + tdSql.checkData(10, 0, 10) + tdSql.checkData(30, 0, 30) tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:40') every(1s) fill(linear)") - tdSql.checkRows(31) + tdSql.checkRows(41) tdSql.checkData(0, 0, 10) - tdSql.checkData(30, 0, 40) + tdSql.checkData(30, 0, 30) + tdSql.checkData(40, 0, 40) tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:45') every(1s) fill(linear)") - tdSql.checkRows(36) + tdSql.checkRows(46) tdSql.checkData(0, 0, 10) - tdSql.checkData(35, 0, 45) + tdSql.checkData(30, 0, 30) + tdSql.checkData(40, 0, 40) + tdSql.checkData(41, 0, 41) + tdSql.checkData(42, 0, 42) + tdSql.checkData(43, 0, 43) + tdSql.checkData(44, 0, 44) + tdSql.checkData(45, 0, 45) tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:50') every(1s) fill(linear)") - tdSql.checkRows(36) - tdSql.checkData(0, 0, 10) - tdSql.checkData(35, 0, 45) - - tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:55') every(1s) fill(linear)") - tdSql.checkRows(36) - tdSql.checkData(0, 0, 10) - tdSql.checkData(35, 0, 45) - - tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:01:00') every(1s) fill(linear)") tdSql.checkRows(51) tdSql.checkData(0, 0, 10) - tdSql.checkData(50, 0, 60) + tdSql.checkData(30, 0, 30) + tdSql.checkData(40, 0, 40) + tdSql.checkData(41, 0, 41) + tdSql.checkData(42, 0, 42) + tdSql.checkData(43, 0, 43) + tdSql.checkData(44, 0, 44) + tdSql.checkData(45, 0, 45) + + + tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:55') every(1s) fill(linear)") + tdSql.checkRows(56) + tdSql.checkData(0, 0, 10) + tdSql.checkData(30, 0, 30) + tdSql.checkData(40, 0, 40) + tdSql.checkData(41, 0, 41) + tdSql.checkData(42, 0, 42) + tdSql.checkData(43, 0, 43) + tdSql.checkData(44, 0, 44) + tdSql.checkData(45, 0, 45) + + + tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:01:00') every(1s) fill(linear)") + tdSql.checkRows(60) + tdSql.checkData(0, 0, 10) + tdSql.checkData(30, 0, 30) + tdSql.checkData(40, 0, 40) + tdSql.checkData(41, 0, 41) + tdSql.checkData(42, 0, 42) + tdSql.checkData(43, 0, 43) + tdSql.checkData(44, 0, 44) + tdSql.checkData(45, 0, 45) + tdSql.checkData(60, 0, 60) tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:40', '2020-02-02 00:00:45') every(1s) fill(linear)") tdSql.checkRows(6) tdSql.checkData(0, 0, 40) + tdSql.checkData(1, 0, 41) + tdSql.checkData(2, 0, 42) + tdSql.checkData(3, 0, 43) + tdSql.checkData(4, 0, 44) tdSql.checkData(5, 0, 45) tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:35', '2020-02-02 00:00:50') every(1s) fill(linear)") - tdSql.checkRows(6) - tdSql.checkData(0, 0, 40) - tdSql.checkData(5, 0, 45) + tdSql.checkRows(16) + tdSql.checkData(5, 0, 40) + tdSql.checkData(6, 0, 41) + tdSql.checkData(7, 0, 42) + tdSql.checkData(8, 0, 43) + tdSql.checkData(9, 0, 44) + tdSql.checkData(10, 0, 45) tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:35', '2020-02-02 00:00:55') every(1s) fill(linear)") - tdSql.checkRows(6) - tdSql.checkData(0, 0, 40) - tdSql.checkData(5, 0, 45) + tdSql.checkRows(21) + tdSql.checkData(5, 0, 40) + tdSql.checkData(6, 0, 41) + tdSql.checkData(7, 0, 42) + tdSql.checkData(8, 0, 43) + tdSql.checkData(9, 0, 44) + tdSql.checkData(10, 0, 45) tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:30', '2020-02-02 00:01:00') every(1s) fill(linear)") tdSql.checkRows(31) tdSql.checkData(0, 0, 30) + tdSql.checkData(10, 0, 40) + tdSql.checkData(11, 0, 41) + tdSql.checkData(12, 0, 42) + tdSql.checkData(13, 0, 43) + tdSql.checkData(14, 0, 44) + tdSql.checkData(15, 0, 45) tdSql.checkData(30, 0, 60) tdLog.printNoPrefix("==========step11:test multi-interp cases") From 4703ccc4bcc4b8c967948b0f4d698079915c4706 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Fri, 18 Nov 2022 15:53:58 +0800 Subject: [PATCH 09/10] fix fill prev/next error --- source/libs/executor/src/timewindowoperator.c | 28 +++++---- tests/system-test/2-query/interp.py | 60 ++++++++++++++----- 2 files changed, 64 insertions(+), 24 deletions(-) diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index 5e1a5d1ec4..0dd3251b0c 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -1945,10 +1945,8 @@ static void doKeepPrevRows(STimeSliceOperatorInfo* pSliceInfo, const SSDataBlock 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->pPrevRow, i); - + SGroupKeys* pkey = taosArrayGet(pSliceInfo->pPrevRow, i); + if (!colDataIsNull_s(pColInfoData, rowIndex)) { pkey->isNull = false; char* val = colDataGetData(pColInfoData, rowIndex); if (!IS_VAR_DATA_TYPE(pkey->type)) { @@ -1956,6 +1954,8 @@ static void doKeepPrevRows(STimeSliceOperatorInfo* pSliceInfo, const SSDataBlock } else { memcpy(pkey->pData, val, varDataLen(val)); } + } else { + pkey->isNull = true; } } @@ -1967,10 +1967,8 @@ static void doKeepNextRows(STimeSliceOperatorInfo* pSliceInfo, const SSDataBlock 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); - + SGroupKeys* pkey = taosArrayGet(pSliceInfo->pNextRow, i); + if (!colDataIsNull_s(pColInfoData, rowIndex)) { pkey->isNull = false; char* val = colDataGetData(pColInfoData, rowIndex); if (!IS_VAR_DATA_TYPE(pkey->type)) { @@ -1978,6 +1976,8 @@ static void doKeepNextRows(STimeSliceOperatorInfo* pSliceInfo, const SSDataBlock } else { memcpy(pkey->pData, val, varDataLen(val)); } + } else { + pkey->isNull = true; } } @@ -2100,7 +2100,11 @@ static bool genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp } SGroupKeys* pkey = taosArrayGet(pSliceInfo->pPrevRow, srcSlot); - colDataAppend(pDst, rows, pkey->pData, false); + if (pkey->isNull == false) { + colDataAppend(pDst, rows, pkey->pData, false); + } else { + colDataAppendNULL(pDst, rows); + } break; } @@ -2111,7 +2115,11 @@ static bool genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp } SGroupKeys* pkey = taosArrayGet(pSliceInfo->pNextRow, srcSlot); - colDataAppend(pDst, rows, pkey->pData, false); + if (pkey->isNull == false) { + colDataAppend(pDst, rows, pkey->pData, false); + } else { + colDataAppendNULL(pDst, rows); + } break; } diff --git a/tests/system-test/2-query/interp.py b/tests/system-test/2-query/interp.py index b5bf6f9dbe..a0ac4ab03b 100644 --- a/tests/system-test/2-query/interp.py +++ b/tests/system-test/2-query/interp.py @@ -39,8 +39,6 @@ class TDTestCase: tdSql.execute(f"insert into {dbname}.{tbname} values ('2020-02-01 00:00:10', 10, 10, 10, 10, 10.0, 10.0, true, 'varchar', 'nchar')") tdSql.execute(f"insert into {dbname}.{tbname} values ('2020-02-01 00:00:15', 15, 15, 15, 15, 15.0, 15.0, true, 'varchar', 'nchar')") - tdSql.execute(f"insert into {dbname}.{tbname} (ts) values (now)") - tdLog.printNoPrefix("==========step3:fill null") ## {. . .} @@ -248,7 +246,7 @@ class TDTestCase: ## {. . .} tdSql.query(f"select interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:04', '2020-02-01 00:00:16') every(1s) fill(next)") - tdSql.checkRows(13) + tdSql.checkRows(12) tdSql.checkData(0, 0, 5) tdSql.checkData(1, 0, 5) tdSql.checkData(2, 0, 10) @@ -298,14 +296,14 @@ class TDTestCase: ## ..{.} tdSql.query(f"select interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:13', '2020-02-01 00:00:17') every(1s) fill(next)") - tdSql.checkRows(5) + tdSql.checkRows(3) tdSql.checkData(0, 0, 15) tdSql.checkData(1, 0, 15) tdSql.checkData(2, 0, 15) ## ... {} tdSql.query(f"select interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:16', '2020-02-01 00:00:19') every(1s) fill(next)") - tdSql.checkRows(4) + tdSql.checkRows(0) tdLog.printNoPrefix("==========step7:fill linear") @@ -513,7 +511,7 @@ class TDTestCase: tdSql.checkData(8, 0, '2020-02-01 00:00:12.000') tdSql.query(f"select _irowts,interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:04', '2020-02-01 00:00:16') every(1s) fill(next)") - tdSql.checkRows(13) + tdSql.checkRows(12) tdSql.checkCols(2) tdSql.checkData(0, 0, '2020-02-01 00:00:04.000') @@ -925,7 +923,7 @@ class TDTestCase: tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-01 23:59:59', '2020-02-02 00:00:08') every(1s) fill(linear)") tdSql.checkRows(9) - tdSql.checkData(0, 0, None) + tdSql.checkData(0, 0, 0) tdSql.checkData(1, 0, None) tdSql.checkData(2, 0, None) tdSql.checkData(3, 0, None) @@ -1274,18 +1272,18 @@ class TDTestCase: tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:35') every(1s) fill(linear)") tdSql.checkRows(36) - tdSql.checkData(10, 0, 10) + tdSql.checkData(10, 0, 10) tdSql.checkData(30, 0, 30) tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:40') every(1s) fill(linear)") tdSql.checkRows(41) - tdSql.checkData(0, 0, 10) + tdSql.checkData(10, 0, 10) tdSql.checkData(30, 0, 30) tdSql.checkData(40, 0, 40) tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:45') every(1s) fill(linear)") tdSql.checkRows(46) - tdSql.checkData(0, 0, 10) + tdSql.checkData(10, 0, 10) tdSql.checkData(30, 0, 30) tdSql.checkData(40, 0, 40) tdSql.checkData(41, 0, 41) @@ -1296,7 +1294,7 @@ class TDTestCase: tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:50') every(1s) fill(linear)") tdSql.checkRows(51) - tdSql.checkData(0, 0, 10) + tdSql.checkData(10, 0, 10) tdSql.checkData(30, 0, 30) tdSql.checkData(40, 0, 40) tdSql.checkData(41, 0, 41) @@ -1308,7 +1306,7 @@ class TDTestCase: tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:00:55') every(1s) fill(linear)") tdSql.checkRows(56) - tdSql.checkData(0, 0, 10) + tdSql.checkData(10, 0, 10) tdSql.checkData(30, 0, 30) tdSql.checkData(40, 0, 40) tdSql.checkData(41, 0, 41) @@ -1319,8 +1317,8 @@ class TDTestCase: tdSql.query(f"select interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:01:00') every(1s) fill(linear)") - tdSql.checkRows(60) - tdSql.checkData(0, 0, 10) + tdSql.checkRows(61) + tdSql.checkData(10, 0, 10) tdSql.checkData(30, 0, 30) tdSql.checkData(40, 0, 40) tdSql.checkData(41, 0, 41) @@ -1368,6 +1366,40 @@ class TDTestCase: tdSql.checkData(15, 0, 45) tdSql.checkData(30, 0, 60) + # two interps + tdSql.query(f"select interp(c0),interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:01:00') every(1s) fill(linear)") + tdSql.checkRows(61) + tdSql.checkCols(2) + tdSql.checkData(0, 0, 0) + tdSql.checkData(10, 0, 10) + tdSql.checkData(20, 0, 20) + tdSql.checkData(30, 0, 30) + tdSql.checkData(31, 0, 31) + tdSql.checkData(32, 0, 32) + tdSql.checkData(33, 0, 33) + tdSql.checkData(34, 0, 34) + tdSql.checkData(35, 0, 35) + tdSql.checkData(36, 0, 36) + tdSql.checkData(37, 0, 37) + tdSql.checkData(38, 0, 38) + tdSql.checkData(39, 0, 39) + tdSql.checkData(40, 0, 40) + tdSql.checkData(50, 0, 50) + tdSql.checkData(60, 0, 55) + + tdSql.checkData(0, 1, None) + tdSql.checkData(10, 1, 10) + tdSql.checkData(20, 1, None) + tdSql.checkData(30, 1, 30) + tdSql.checkData(40, 1, 40) + tdSql.checkData(41, 1, 41) + tdSql.checkData(42, 1, 42) + tdSql.checkData(43, 1, 43) + tdSql.checkData(44, 1, 44) + tdSql.checkData(45, 1, 45) + tdSql.checkData(50, 1, None) + tdSql.checkData(60, 1, 60) + tdLog.printNoPrefix("==========step11:test multi-interp cases") tdSql.query(f"select interp(c0),interp(c1),interp(c2),interp(c3) from {dbname}.{tbname} range('2020-02-09 00:00:05', '2020-02-13 00:00:05') every(1d) fill(null)") tdSql.checkRows(5) From 53fbc7b2567889558c088bfef7a39a396f0eebc7 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Fri, 18 Nov 2022 16:31:22 +0800 Subject: [PATCH 10/10] add more test cases --- tests/system-test/2-query/interp.py | 405 ++++++++++++++++++++++++++-- 1 file changed, 389 insertions(+), 16 deletions(-) diff --git a/tests/system-test/2-query/interp.py b/tests/system-test/2-query/interp.py index a0ac4ab03b..ce57357abd 100644 --- a/tests/system-test/2-query/interp.py +++ b/tests/system-test/2-query/interp.py @@ -900,6 +900,8 @@ class TDTestCase: tdSql.execute(f"insert into {dbname}.{tbname1} values ('2020-02-02 00:00:55', NULL, NULL)") tdSql.execute(f"insert into {dbname}.{tbname1} values ('2020-02-02 00:01:00', 55, 60)") + # test fill linear + # check c0 tdSql.query(f"select interp(c0) from {dbname}.{tbname1} range('2020-02-01 23:59:59', '2020-02-02 00:00:00') every(1s) fill(linear)") tdSql.checkRows(1) @@ -1370,35 +1372,406 @@ class TDTestCase: tdSql.query(f"select interp(c0),interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:01:00') every(1s) fill(linear)") tdSql.checkRows(61) tdSql.checkCols(2) - tdSql.checkData(0, 0, 0) - tdSql.checkData(10, 0, 10) - tdSql.checkData(20, 0, 20) - tdSql.checkData(30, 0, 30) + tdSql.checkData(0, 0, 0) # + tdSql.checkData(1, 0, None) + tdSql.checkData(4, 0, None) + tdSql.checkData(5, 0, None) # + tdSql.checkData(6, 0, None) + tdSql.checkData(9, 0, None) + tdSql.checkData(10, 0, 10) # + tdSql.checkData(11, 0, None) + tdSql.checkData(14, 0, None) + tdSql.checkData(15, 0, None) # + tdSql.checkData(16, 0, None) + tdSql.checkData(19, 0, None) + tdSql.checkData(20, 0, 20) # + tdSql.checkData(21, 0, None) + tdSql.checkData(24, 0, None) + tdSql.checkData(25, 0, None) # + tdSql.checkData(26, 0, None) + tdSql.checkData(29, 0, None) + tdSql.checkData(30, 0, 30) # tdSql.checkData(31, 0, 31) tdSql.checkData(32, 0, 32) tdSql.checkData(33, 0, 33) tdSql.checkData(34, 0, 34) - tdSql.checkData(35, 0, 35) + tdSql.checkData(35, 0, 35) # tdSql.checkData(36, 0, 36) tdSql.checkData(37, 0, 37) tdSql.checkData(38, 0, 38) tdSql.checkData(39, 0, 39) - tdSql.checkData(40, 0, 40) - tdSql.checkData(50, 0, 50) - tdSql.checkData(60, 0, 55) + tdSql.checkData(40, 0, 40) # + tdSql.checkData(41, 0, None) + tdSql.checkData(44, 0, None) + tdSql.checkData(45, 0, None) # + tdSql.checkData(46, 0, None) + tdSql.checkData(49, 0, None) + tdSql.checkData(50, 0, 50) # + tdSql.checkData(51, 0, None) + tdSql.checkData(54, 0, None) + tdSql.checkData(55, 0, None) # + tdSql.checkData(56, 0, None) + tdSql.checkData(59, 0, None) + tdSql.checkData(60, 0, 55) # - tdSql.checkData(0, 1, None) - tdSql.checkData(10, 1, 10) - tdSql.checkData(20, 1, None) - tdSql.checkData(30, 1, 30) - tdSql.checkData(40, 1, 40) + tdSql.checkData(0, 1, None) # + tdSql.checkData(1, 1, None) + tdSql.checkData(4, 1, None) + tdSql.checkData(5, 1, None) # + tdSql.checkData(6, 1, None) + tdSql.checkData(9, 1, None) + tdSql.checkData(10, 1, 10) # + tdSql.checkData(11, 1, None) + tdSql.checkData(14, 1, None) + tdSql.checkData(15, 1, None) # + tdSql.checkData(16, 1, None) + tdSql.checkData(19, 1, None) + tdSql.checkData(20, 1, None) # + tdSql.checkData(21, 1, None) + tdSql.checkData(24, 1, None) + tdSql.checkData(25, 1, None) # + tdSql.checkData(26, 1, None) + tdSql.checkData(29, 1, None) + tdSql.checkData(30, 1, 30) # + tdSql.checkData(31, 1, None) + tdSql.checkData(34, 1, None) + tdSql.checkData(35, 1, None) # + tdSql.checkData(36, 1, None) + tdSql.checkData(39, 1, None) + tdSql.checkData(40, 1, 40) # tdSql.checkData(41, 1, 41) tdSql.checkData(42, 1, 42) tdSql.checkData(43, 1, 43) tdSql.checkData(44, 1, 44) - tdSql.checkData(45, 1, 45) - tdSql.checkData(50, 1, None) - tdSql.checkData(60, 1, 60) + tdSql.checkData(45, 1, 45) # + tdSql.checkData(46, 1, None) + tdSql.checkData(49, 1, None) + tdSql.checkData(50, 1, None) # + tdSql.checkData(51, 1, None) + tdSql.checkData(54, 1, None) + tdSql.checkData(55, 1, None) # + tdSql.checkData(56, 1, None) + tdSql.checkData(59, 1, None) + tdSql.checkData(60, 1, 60) # + + # test fill null + tdSql.query(f"select interp(c0),interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:01:00') every(1s) fill(null)") + tdSql.checkRows(61) + tdSql.checkCols(2) + tdSql.checkData(0, 0, 0) # + tdSql.checkData(1, 0, None) + tdSql.checkData(4, 0, None) + tdSql.checkData(5, 0, None) # + tdSql.checkData(6, 0, None) + tdSql.checkData(9, 0, None) + tdSql.checkData(10, 0, 10) # + tdSql.checkData(11, 0, None) + tdSql.checkData(14, 0, None) + tdSql.checkData(15, 0, None) # + tdSql.checkData(16, 0, None) + tdSql.checkData(19, 0, None) + tdSql.checkData(20, 0, 20) # + tdSql.checkData(21, 0, None) + tdSql.checkData(24, 0, None) + tdSql.checkData(25, 0, None) # + tdSql.checkData(26, 0, None) + tdSql.checkData(29, 0, None) + tdSql.checkData(30, 0, 30) # + tdSql.checkData(31, 0, None) + tdSql.checkData(34, 0, None) + tdSql.checkData(35, 0, 35) # + tdSql.checkData(36, 0, None) + tdSql.checkData(39, 0, None) + tdSql.checkData(40, 0, 40) # + tdSql.checkData(41, 0, None) + tdSql.checkData(44, 0, None) + tdSql.checkData(45, 0, None) # + tdSql.checkData(46, 0, None) + tdSql.checkData(49, 0, None) + tdSql.checkData(50, 0, 50) # + tdSql.checkData(51, 0, None) + tdSql.checkData(54, 0, None) + tdSql.checkData(55, 0, None) # + tdSql.checkData(56, 0, None) + tdSql.checkData(59, 0, None) + tdSql.checkData(60, 0, 55) # + + tdSql.checkData(0, 1, None) # + tdSql.checkData(1, 1, None) + tdSql.checkData(4, 1, None) + tdSql.checkData(5, 1, None) # + tdSql.checkData(6, 1, None) + tdSql.checkData(9, 1, None) + tdSql.checkData(10, 1, 10) # + tdSql.checkData(11, 1, None) + tdSql.checkData(14, 1, None) + tdSql.checkData(15, 1, None) # + tdSql.checkData(16, 1, None) + tdSql.checkData(19, 1, None) + tdSql.checkData(20, 1, None) # + tdSql.checkData(21, 1, None) + tdSql.checkData(24, 1, None) + tdSql.checkData(25, 1, None) # + tdSql.checkData(26, 1, None) + tdSql.checkData(29, 1, None) + tdSql.checkData(30, 1, 30) # + tdSql.checkData(31, 1, None) + tdSql.checkData(34, 1, None) + tdSql.checkData(35, 1, None) # + tdSql.checkData(36, 1, None) + tdSql.checkData(39, 1, None) + tdSql.checkData(40, 1, 40) # + tdSql.checkData(41, 1, None) + tdSql.checkData(44, 1, None) + tdSql.checkData(45, 1, 45) # + tdSql.checkData(46, 1, None) + tdSql.checkData(49, 1, None) + tdSql.checkData(50, 1, None) # + tdSql.checkData(51, 1, None) + tdSql.checkData(54, 1, None) + tdSql.checkData(55, 1, None) # + tdSql.checkData(56, 1, None) + tdSql.checkData(59, 1, None) + tdSql.checkData(60, 1, 60) # + + # test fill value + tdSql.query(f"select interp(c0),interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:01:00') every(1s) fill(value, 123)") + tdSql.checkRows(61) + tdSql.checkCols(2) + tdSql.checkData(0, 0, 0) # + tdSql.checkData(1, 0, 123) + tdSql.checkData(4, 0, 123) + tdSql.checkData(5, 0, None) # + tdSql.checkData(6, 0, 123) + tdSql.checkData(9, 0, 123) + tdSql.checkData(10, 0, 10) # + tdSql.checkData(11, 0, 123) + tdSql.checkData(14, 0, 123) + tdSql.checkData(15, 0, None) # + tdSql.checkData(16, 0, 123) + tdSql.checkData(19, 0, 123) + tdSql.checkData(20, 0, 20) # + tdSql.checkData(21, 0, 123) + tdSql.checkData(24, 0, 123) + tdSql.checkData(25, 0, None) # + tdSql.checkData(26, 0, 123) + tdSql.checkData(29, 0, 123) + tdSql.checkData(30, 0, 30) # + tdSql.checkData(31, 0, 123) + tdSql.checkData(34, 0, 123) + tdSql.checkData(35, 0, 35) # + tdSql.checkData(36, 0, 123) + tdSql.checkData(39, 0, 123) + tdSql.checkData(40, 0, 40) # + tdSql.checkData(41, 0, 123) + tdSql.checkData(44, 0, 123) + tdSql.checkData(45, 0, None) # + tdSql.checkData(46, 0, 123) + tdSql.checkData(49, 0, 123) + tdSql.checkData(50, 0, 50) # + tdSql.checkData(51, 0, 123) + tdSql.checkData(54, 0, 123) + tdSql.checkData(55, 0, None) # + tdSql.checkData(59, 0, 123) + tdSql.checkData(60, 0, 55) # + + tdSql.checkData(0, 1, None) # + tdSql.checkData(1, 1, 123) + tdSql.checkData(4, 1, 123) + tdSql.checkData(5, 1, None) # + tdSql.checkData(6, 1, 123) + tdSql.checkData(9, 1, 123) + tdSql.checkData(10, 1, 10) # + tdSql.checkData(11, 1, 123) + tdSql.checkData(14, 1, 123) + tdSql.checkData(15, 1, None) # + tdSql.checkData(16, 1, 123) + tdSql.checkData(19, 1, 123) + tdSql.checkData(20, 1, None) # + tdSql.checkData(21, 1, 123) + tdSql.checkData(24, 1, 123) + tdSql.checkData(25, 1, None) # + tdSql.checkData(26, 1, 123) + tdSql.checkData(29, 1, 123) + tdSql.checkData(30, 1, 30) # + tdSql.checkData(31, 1, 123) + tdSql.checkData(34, 1, 123) + tdSql.checkData(35, 1, None) # + tdSql.checkData(36, 1, 123) + tdSql.checkData(39, 1, 123) + tdSql.checkData(40, 1, 40) # + tdSql.checkData(41, 1, 123) + tdSql.checkData(44, 1, 123) + tdSql.checkData(45, 1, 45) # + tdSql.checkData(46, 1, 123) + tdSql.checkData(49, 1, 123) + tdSql.checkData(50, 1, None) # + tdSql.checkData(51, 1, 123) + tdSql.checkData(54, 1, 123) + tdSql.checkData(55, 1, None) # + tdSql.checkData(56, 1, 123) + tdSql.checkData(59, 1, 123) + tdSql.checkData(60, 1, 60) # + + # test fill prev + tdSql.query(f"select interp(c0),interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:01:00') every(1s) fill(prev)") + tdSql.checkRows(61) + tdSql.checkCols(2) + tdSql.checkData(0, 0, 0) # + tdSql.checkData(1, 0, 0) + tdSql.checkData(4, 0, 0) + tdSql.checkData(5, 0, None) # + tdSql.checkData(6, 0, None) + tdSql.checkData(9, 0, None) + tdSql.checkData(10, 0, 10) # + tdSql.checkData(11, 0, 10) + tdSql.checkData(14, 0, 10) + tdSql.checkData(15, 0, None) # + tdSql.checkData(16, 0, None) + tdSql.checkData(19, 0, None) + tdSql.checkData(20, 0, 20) # + tdSql.checkData(21, 0, 20) + tdSql.checkData(24, 0, 20) + tdSql.checkData(25, 0, None) # + tdSql.checkData(26, 0, None) + tdSql.checkData(29, 0, None) + tdSql.checkData(30, 0, 30) # + tdSql.checkData(31, 0, 30) + tdSql.checkData(34, 0, 30) + tdSql.checkData(35, 0, 35) # + tdSql.checkData(36, 0, 35) + tdSql.checkData(39, 0, 35) + tdSql.checkData(40, 0, 40) # + tdSql.checkData(41, 0, 40) + tdSql.checkData(44, 0, 40) + tdSql.checkData(45, 0, None) # + tdSql.checkData(46, 0, None) + tdSql.checkData(49, 0, None) + tdSql.checkData(50, 0, 50) # + tdSql.checkData(51, 0, 50) + tdSql.checkData(54, 0, 50) + tdSql.checkData(55, 0, None) # + tdSql.checkData(56, 0, None) + tdSql.checkData(59, 0, None) + tdSql.checkData(60, 0, 55) # + + tdSql.checkData(0, 1, None) # + tdSql.checkData(1, 1, None) + tdSql.checkData(4, 1, None) + tdSql.checkData(5, 1, None) # + tdSql.checkData(6, 1, None) + tdSql.checkData(9, 1, None) + tdSql.checkData(10, 1, 10) # + tdSql.checkData(11, 1, 10) + tdSql.checkData(14, 1, 10) + tdSql.checkData(15, 1, None) # + tdSql.checkData(16, 1, None) + tdSql.checkData(19, 1, None) + tdSql.checkData(20, 1, None) # + tdSql.checkData(21, 1, None) + tdSql.checkData(24, 1, None) + tdSql.checkData(25, 1, None) # + tdSql.checkData(26, 1, None) + tdSql.checkData(29, 1, None) + tdSql.checkData(30, 1, 30) # + tdSql.checkData(31, 1, 30) + tdSql.checkData(34, 1, 30) + tdSql.checkData(35, 1, None) # + tdSql.checkData(36, 1, None) + tdSql.checkData(39, 1, None) + tdSql.checkData(40, 1, 40) # + tdSql.checkData(41, 1, 40) + tdSql.checkData(44, 1, 40) + tdSql.checkData(45, 1, 45) # + tdSql.checkData(46, 1, 45) + tdSql.checkData(49, 1, 45) + tdSql.checkData(50, 1, None) # + tdSql.checkData(51, 1, None) + tdSql.checkData(54, 1, None) + tdSql.checkData(55, 1, None) # + tdSql.checkData(56, 1, None) + tdSql.checkData(59, 1, None) + tdSql.checkData(60, 1, 60) # + + # test fill next + tdSql.query(f"select interp(c0),interp(c1) from {dbname}.{tbname1} range('2020-02-02 00:00:00', '2020-02-02 00:01:00') every(1s) fill(next)") + tdSql.checkRows(61) + tdSql.checkCols(2) + tdSql.checkData(0, 0, 0) # + tdSql.checkData(1, 0, None) + tdSql.checkData(4, 0, None) + tdSql.checkData(5, 0, None) # + tdSql.checkData(6, 0, 10) + tdSql.checkData(9, 0, 10) + tdSql.checkData(10, 0, 10) # + tdSql.checkData(11, 0, None) + tdSql.checkData(14, 0, None) + tdSql.checkData(15, 0, None) # + tdSql.checkData(16, 0, 20) + tdSql.checkData(19, 0, 20) + tdSql.checkData(20, 0, 20) # + tdSql.checkData(21, 0, None) + tdSql.checkData(24, 0, None) + tdSql.checkData(25, 0, None) # + tdSql.checkData(26, 0, 30) + tdSql.checkData(29, 0, 30) + tdSql.checkData(30, 0, 30) # + tdSql.checkData(31, 0, 35) + tdSql.checkData(34, 0, 35) + tdSql.checkData(35, 0, 35) # + tdSql.checkData(36, 0, 40) + tdSql.checkData(39, 0, 40) + tdSql.checkData(40, 0, 40) # + tdSql.checkData(41, 0, None) + tdSql.checkData(44, 0, None) + tdSql.checkData(45, 0, None) # + tdSql.checkData(46, 0, 50) + tdSql.checkData(49, 0, 50) + tdSql.checkData(50, 0, 50) # + tdSql.checkData(51, 0, None) + tdSql.checkData(54, 0, None) + tdSql.checkData(55, 0, None) # + tdSql.checkData(56, 0, 55) + tdSql.checkData(59, 0, 55) + tdSql.checkData(60, 0, 55) # + + tdSql.checkData(0, 1, None) # + tdSql.checkData(1, 1, None) + tdSql.checkData(4, 1, None) + tdSql.checkData(5, 1, None) # + tdSql.checkData(6, 1, 10) + tdSql.checkData(9, 1, 10) + tdSql.checkData(10, 1, 10) # + tdSql.checkData(11, 1, None) + tdSql.checkData(14, 1, None) + tdSql.checkData(15, 1, None) # + tdSql.checkData(16, 1, None) + tdSql.checkData(19, 1, None) + tdSql.checkData(20, 1, None) # + tdSql.checkData(21, 1, None) + tdSql.checkData(24, 1, None) + tdSql.checkData(25, 1, None) # + tdSql.checkData(26, 1, 30) + tdSql.checkData(29, 1, 30) + tdSql.checkData(30, 1, 30) # + tdSql.checkData(31, 1, None) + tdSql.checkData(34, 1, None) + tdSql.checkData(35, 1, None) # + tdSql.checkData(36, 1, 40) + tdSql.checkData(39, 1, 40) + tdSql.checkData(40, 1, 40) # + tdSql.checkData(41, 1, 45) + tdSql.checkData(44, 1, 45) + tdSql.checkData(45, 1, 45) # + tdSql.checkData(46, 1, None) + tdSql.checkData(49, 1, None) + tdSql.checkData(50, 1, None) # + tdSql.checkData(51, 1, None) + tdSql.checkData(54, 1, None) + tdSql.checkData(55, 1, None) # + tdSql.checkData(56, 1, 60) + tdSql.checkData(59, 1, 60) + tdSql.checkData(60, 1, 60) # tdLog.printNoPrefix("==========step11:test multi-interp cases") tdSql.query(f"select interp(c0),interp(c1),interp(c2),interp(c3) from {dbname}.{tbname} range('2020-02-09 00:00:05', '2020-02-13 00:00:05') every(1d) fill(null)")