未验证 提交 81da6cd4 编写于 作者: D dapan1121 提交者: GitHub

Merge pull request #20844 from taosdata/feat/TS-2815

feat(query): INTERP support boolean type
......@@ -30,6 +30,7 @@ extern "C" {
struct SSDataBlock;
typedef struct SFillColInfo {
int32_t numOfFillExpr;
SExprInfo* pExpr;
bool notFillCol; // denote if this column needs fill operation
SVariant fillVal;
......
......@@ -578,7 +578,12 @@ int32_t taosGetLinearInterpolationVal(SPoint* point, int32_t outputType, SPoint*
GET_TYPED_DATA(v1, double, inputType, point1->val);
GET_TYPED_DATA(v2, double, inputType, point2->val);
double r = DO_INTERPOLATION(v1, v2, point1->key, point2->key, point->key);
double r = 0;
if (!IS_BOOLEAN_TYPE(inputType)) {
r = DO_INTERPOLATION(v1, v2, point1->key, point2->key, point->key);
} else {
r = (v1 < 1 || v2 < 1) ? 0 : 1;
}
SET_TYPED_DATA(point->val, outputType, r);
return TSDB_CODE_SUCCESS;
......@@ -630,6 +635,7 @@ SFillColInfo* createFillColInfo(SExprInfo* pExpr, int32_t numOfFillExpr, SExprIn
nodesValueNodeToVariant(pv, &pFillCol[i].fillVal);
}
}
pFillCol->numOfFillExpr = numOfFillExpr;
for (int32_t i = 0; i < numOfNoFillExpr; ++i) {
SExprInfo* pExprInfo = &pNotFillExpr[i];
......
......@@ -156,6 +156,16 @@ static FORCE_INLINE int32_t timeSliceEnsureBlockCapacity(STimeSliceOperatorInfo*
return TSDB_CODE_SUCCESS;
}
static bool isIrowtsPseudoColumn(SExprInfo* pExprInfo) {
char *name = pExprInfo->pExpr->_function.functionName;
return (IS_TIMESTAMP_TYPE(pExprInfo->base.resSchema.type) && strcasecmp(name, "_irowts") == 0);
}
static bool isIsfilledPseudoColumn(SExprInfo* pExprInfo) {
char *name = pExprInfo->pExpr->_function.functionName;
return (IS_BOOLEAN_TYPE(pExprInfo->base.resSchema.type) && strcasecmp(name, "_isfilled") == 0);
}
static bool genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp* pExprSup, SSDataBlock* pResBlock,
bool beforeTs) {
int32_t rows = pResBlock->info.rows;
......@@ -170,10 +180,10 @@ static bool genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp
int32_t dstSlot = pExprInfo->base.resSchema.slotId;
SColumnInfoData* pDst = taosArrayGet(pResBlock->pDataBlock, dstSlot);
if (IS_TIMESTAMP_TYPE(pExprInfo->base.resSchema.type)) {
if (isIrowtsPseudoColumn(pExprInfo)) {
colDataSetVal(pDst, rows, (char*)&pSliceInfo->current, false);
continue;
} else if (IS_BOOLEAN_TYPE(pExprInfo->base.resSchema.type)) {
} else if (isIsfilledPseudoColumn(pExprInfo)) {
bool isFilled = true;
colDataAppend(pDst, pResBlock->info.rows, (char*)&isFilled, false);
continue;
......@@ -203,6 +213,14 @@ static bool genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp
int64_t v = 0;
GET_TYPED_DATA(v, int64_t, pVar->nType, &pVar->i);
colDataSetVal(pDst, rows, (char*)&v, false);
} else if (IS_BOOLEAN_TYPE(pDst->info.type)) {
bool v = false;
if (!IS_VAR_DATA_TYPE(pVar->nType)) {
GET_TYPED_DATA(v, bool, pVar->nType, &pVar->i);
} else {
v = taosStr2Int8(varDataVal(pVar->pz), NULL, 10);
}
colDataSetVal(pDst, rows, (char*)&v, false);
}
break;
}
......@@ -288,9 +306,9 @@ static void addCurrentRowToResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp*
int32_t dstSlot = pExprInfo->base.resSchema.slotId;
SColumnInfoData* pDst = taosArrayGet(pResBlock->pDataBlock, dstSlot);
if (IS_TIMESTAMP_TYPE(pExprInfo->base.resSchema.type)) {
if (isIrowtsPseudoColumn(pExprInfo)) {
colDataSetVal(pDst, pResBlock->info.rows, (char*)&pSliceInfo->current, false);
} else if (IS_BOOLEAN_TYPE(pExprInfo->base.resSchema.type)) {
} else if (isIsfilledPseudoColumn(pExprInfo)) {
bool isFilled = false;
colDataSetVal(pDst, pResBlock->info.rows, (char*)&isFilled, false);
} else {
......@@ -643,6 +661,9 @@ void destroyTimeSliceOperatorInfo(void* param) {
taosArrayDestroy(pInfo->pLinearInfo);
cleanupExprSupp(&pInfo->scalarSup);
for (int32_t i = 0; i < pInfo->pFillColInfo->numOfFillExpr; ++i) {
taosVariantDestroy(&pInfo->pFillColInfo[i].fillVal);
}
taosMemoryFree(pInfo->pFillColInfo);
taosMemoryFreeClear(param);
}
......@@ -1575,7 +1575,7 @@ static int32_t translateInterp(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
uint8_t nodeType = nodeType(nodesListGetNode(pFunc->pParameterList, 0));
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
if (!IS_NUMERIC_TYPE(paraType) || QUERY_NODE_VALUE == nodeType) {
if ((!IS_NUMERIC_TYPE(paraType) && !IS_BOOLEAN_TYPE(paraType))|| QUERY_NODE_VALUE == nodeType) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
......
......@@ -19,6 +19,7 @@ class TDTestCase:
dbname = "db"
tbname = "tb"
tbname1 = "tb1"
tbname2 = "tb2"
stbname = "stb"
ctbname1 = "ctb1"
ctbname2 = "ctb2"
......@@ -1948,6 +1949,7 @@ class TDTestCase:
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)")
tdSql.checkRows(5)
......@@ -2002,7 +2004,362 @@ class TDTestCase:
for i in range (tdSql.queryCols):
tdSql.checkData(0, i, 13)
tdLog.printNoPrefix("==========step12:test error cases")
tdLog.printNoPrefix("==========step12:test interp with boolean type")
tdSql.execute(
f'''create table if not exists {dbname}.{tbname2}
(ts timestamp, c0 bool)
'''
)
tdSql.execute(f"insert into {dbname}.{tbname2} values ('2020-02-02 00:00:01', false)")
tdSql.execute(f"insert into {dbname}.{tbname2} values ('2020-02-02 00:00:03', true)")
tdSql.execute(f"insert into {dbname}.{tbname2} values ('2020-02-02 00:00:05', false)")
tdSql.execute(f"insert into {dbname}.{tbname2} values ('2020-02-02 00:00:07', true)")
tdSql.execute(f"insert into {dbname}.{tbname2} values ('2020-02-02 00:00:09', true)")
tdSql.execute(f"insert into {dbname}.{tbname2} values ('2020-02-02 00:00:11', false)")
tdSql.execute(f"insert into {dbname}.{tbname2} values ('2020-02-02 00:00:13', false)")
tdSql.execute(f"insert into {dbname}.{tbname2} values ('2020-02-02 00:00:15', NULL)")
tdSql.execute(f"insert into {dbname}.{tbname2} values ('2020-02-02 00:00:17', NULL)")
# test fill null
tdSql.query(f"select _irowts,_isfilled,interp(c0) from {dbname}.{tbname2} range('2020-02-02 00:00:00', '2020-02-02 00:00:18') every(1s) fill(NULL)")
tdSql.checkRows(19)
tdSql.checkCols(3)
tdSql.checkData(0, 0, '2020-02-02 00:00:00.000')
tdSql.checkData(0, 2, None)
tdSql.checkData(1, 2, False)
tdSql.checkData(2, 2, None)
tdSql.checkData(3, 2, True)
tdSql.checkData(4, 2, None)
tdSql.checkData(5, 2, False)
tdSql.checkData(6, 2, None)
tdSql.checkData(7, 2, True)
tdSql.checkData(8, 2, None)
tdSql.checkData(9, 2, True)
tdSql.checkData(10, 2, None)
tdSql.checkData(11, 2, False)
tdSql.checkData(12, 2, None)
tdSql.checkData(13, 2, False)
tdSql.checkData(14, 2, None)
tdSql.checkData(15, 2, None)
tdSql.checkData(16, 2, None)
tdSql.checkData(17, 2, None)
tdSql.checkData(18, 2, None)
tdSql.checkData(18, 0, '2020-02-02 00:00:18.000')
# test fill prev
tdSql.query(f"select _irowts,_isfilled,interp(c0) from {dbname}.{tbname2} range('2020-02-02 00:00:00', '2020-02-02 00:00:18') every(1s) fill(prev)")
tdSql.checkRows(18)
tdSql.checkCols(3)
tdSql.checkData(0, 0, '2020-02-02 00:00:01.000')
tdSql.checkData(0, 2, False)
tdSql.checkData(1, 2, False)
tdSql.checkData(2, 2, True)
tdSql.checkData(3, 2, True)
tdSql.checkData(4, 2, False)
tdSql.checkData(5, 2, False)
tdSql.checkData(6, 2, True)
tdSql.checkData(7, 2, True)
tdSql.checkData(8, 2, True)
tdSql.checkData(9, 2, True)
tdSql.checkData(10, 2, False)
tdSql.checkData(11, 2, False)
tdSql.checkData(12, 2, False)
tdSql.checkData(13, 2, False)
tdSql.checkData(14, 2, None)
tdSql.checkData(15, 2, None)
tdSql.checkData(16, 2, None)
tdSql.checkData(17, 2, None)
tdSql.checkData(17, 0, '2020-02-02 00:00:18.000')
# test fill next
tdSql.query(f"select _irowts,_isfilled,interp(c0) from {dbname}.{tbname2} range('2020-02-02 00:00:00', '2020-02-02 00:00:18') every(1s) fill(next)")
tdSql.checkRows(18)
tdSql.checkCols(3)
tdSql.checkData(0, 0, '2020-02-02 00:00:00.000')
tdSql.checkData(0, 2, False)
tdSql.checkData(1, 2, False)
tdSql.checkData(2, 2, True)
tdSql.checkData(3, 2, True)
tdSql.checkData(4, 2, False)
tdSql.checkData(5, 2, False)
tdSql.checkData(6, 2, True)
tdSql.checkData(7, 2, True)
tdSql.checkData(8, 2, True)
tdSql.checkData(9, 2, True)
tdSql.checkData(10, 2, False)
tdSql.checkData(11, 2, False)
tdSql.checkData(12, 2, False)
tdSql.checkData(13, 2, False)
tdSql.checkData(14, 2, None)
tdSql.checkData(15, 2, None)
tdSql.checkData(16, 2, None)
tdSql.checkData(17, 2, None)
tdSql.checkData(17, 0, '2020-02-02 00:00:17.000')
# test fill value
tdSql.query(f"select _irowts,_isfilled,interp(c0) from {dbname}.{tbname2} range('2020-02-02 00:00:00', '2020-02-02 00:00:18') every(1s) fill(value, 0)")
tdSql.checkRows(19)
tdSql.checkCols(3)
tdSql.checkData(0, 0, '2020-02-02 00:00:00.000')
tdSql.checkData(0, 2, False)
tdSql.checkData(1, 2, False)
tdSql.checkData(2, 2, False)
tdSql.checkData(3, 2, True)
tdSql.checkData(4, 2, False)
tdSql.checkData(5, 2, False)
tdSql.checkData(6, 2, False)
tdSql.checkData(7, 2, True)
tdSql.checkData(8, 2, False)
tdSql.checkData(9, 2, True)
tdSql.checkData(10, 2, False)
tdSql.checkData(11, 2, False)
tdSql.checkData(12, 2, False)
tdSql.checkData(13, 2, False)
tdSql.checkData(14, 2, False)
tdSql.checkData(15, 2, None)
tdSql.checkData(16, 2, False)
tdSql.checkData(17, 2, None)
tdSql.checkData(18, 2, False)
tdSql.checkData(18, 0, '2020-02-02 00:00:18.000')
tdSql.query(f"select _irowts,_isfilled,interp(c0) from {dbname}.{tbname2} range('2020-02-02 00:00:00', '2020-02-02 00:00:18') every(1s) fill(value, 1234)")
tdSql.checkRows(19)
tdSql.checkCols(3)
tdSql.checkData(0, 0, '2020-02-02 00:00:00.000')
tdSql.checkData(0, 2, True)
tdSql.checkData(1, 2, False)
tdSql.checkData(2, 2, True)
tdSql.checkData(3, 2, True)
tdSql.checkData(4, 2, True)
tdSql.checkData(5, 2, False)
tdSql.checkData(6, 2, True)
tdSql.checkData(7, 2, True)
tdSql.checkData(8, 2, True)
tdSql.checkData(9, 2, True)
tdSql.checkData(10, 2, True)
tdSql.checkData(11, 2, False)
tdSql.checkData(12, 2, True)
tdSql.checkData(13, 2, False)
tdSql.checkData(14, 2, True)
tdSql.checkData(15, 2, None)
tdSql.checkData(16, 2, True)
tdSql.checkData(17, 2, None)
tdSql.checkData(18, 2, True)
tdSql.checkData(18, 0, '2020-02-02 00:00:18.000')
tdSql.query(f"select _irowts,_isfilled,interp(c0) from {dbname}.{tbname2} range('2020-02-02 00:00:00', '2020-02-02 00:00:18') every(1s) fill(value, false)")
tdSql.checkRows(19)
tdSql.checkCols(3)
tdSql.checkData(0, 0, '2020-02-02 00:00:00.000')
tdSql.checkData(0, 2, False)
tdSql.checkData(1, 2, False)
tdSql.checkData(2, 2, False)
tdSql.checkData(3, 2, True)
tdSql.checkData(4, 2, False)
tdSql.checkData(5, 2, False)
tdSql.checkData(6, 2, False)
tdSql.checkData(7, 2, True)
tdSql.checkData(8, 2, False)
tdSql.checkData(9, 2, True)
tdSql.checkData(10, 2, False)
tdSql.checkData(11, 2, False)
tdSql.checkData(12, 2, False)
tdSql.checkData(13, 2, False)
tdSql.checkData(14, 2, False)
tdSql.checkData(15, 2, None)
tdSql.checkData(16, 2, False)
tdSql.checkData(17, 2, None)
tdSql.checkData(18, 2, False)
tdSql.checkData(18, 0, '2020-02-02 00:00:18.000')
tdSql.query(f"select _irowts,_isfilled,interp(c0) from {dbname}.{tbname2} range('2020-02-02 00:00:00', '2020-02-02 00:00:18') every(1s) fill(value, true)")
tdSql.checkRows(19)
tdSql.checkCols(3)
tdSql.checkData(0, 0, '2020-02-02 00:00:00.000')
tdSql.checkData(0, 2, True)
tdSql.checkData(1, 2, False)
tdSql.checkData(2, 2, True)
tdSql.checkData(3, 2, True)
tdSql.checkData(4, 2, True)
tdSql.checkData(5, 2, False)
tdSql.checkData(6, 2, True)
tdSql.checkData(7, 2, True)
tdSql.checkData(8, 2, True)
tdSql.checkData(9, 2, True)
tdSql.checkData(10, 2, True)
tdSql.checkData(11, 2, False)
tdSql.checkData(12, 2, True)
tdSql.checkData(13, 2, False)
tdSql.checkData(14, 2, True)
tdSql.checkData(15, 2, None)
tdSql.checkData(16, 2, True)
tdSql.checkData(17, 2, None)
tdSql.checkData(18, 2, True)
tdSql.checkData(18, 0, '2020-02-02 00:00:18.000')
tdSql.query(f"select _irowts,_isfilled,interp(c0) from {dbname}.{tbname2} range('2020-02-02 00:00:00', '2020-02-02 00:00:18') every(1s) fill(value, '0')")
tdSql.checkRows(19)
tdSql.checkCols(3)
tdSql.checkData(0, 0, '2020-02-02 00:00:00.000')
tdSql.checkData(0, 2, False)
tdSql.checkData(1, 2, False)
tdSql.checkData(2, 2, False)
tdSql.checkData(3, 2, True)
tdSql.checkData(4, 2, False)
tdSql.checkData(5, 2, False)
tdSql.checkData(6, 2, False)
tdSql.checkData(7, 2, True)
tdSql.checkData(8, 2, False)
tdSql.checkData(9, 2, True)
tdSql.checkData(10, 2, False)
tdSql.checkData(11, 2, False)
tdSql.checkData(12, 2, False)
tdSql.checkData(13, 2, False)
tdSql.checkData(14, 2, False)
tdSql.checkData(15, 2, None)
tdSql.checkData(16, 2, False)
tdSql.checkData(17, 2, None)
tdSql.checkData(18, 2, False)
tdSql.checkData(18, 0, '2020-02-02 00:00:18.000')
tdSql.query(f"select _irowts,_isfilled,interp(c0) from {dbname}.{tbname2} range('2020-02-02 00:00:00', '2020-02-02 00:00:18') every(1s) fill(value, '123')")
tdSql.checkRows(19)
tdSql.checkCols(3)
tdSql.checkData(0, 0, '2020-02-02 00:00:00.000')
tdSql.checkData(0, 2, True)
tdSql.checkData(1, 2, False)
tdSql.checkData(2, 2, True)
tdSql.checkData(3, 2, True)
tdSql.checkData(4, 2, True)
tdSql.checkData(5, 2, False)
tdSql.checkData(6, 2, True)
tdSql.checkData(7, 2, True)
tdSql.checkData(8, 2, True)
tdSql.checkData(9, 2, True)
tdSql.checkData(10, 2, True)
tdSql.checkData(11, 2, False)
tdSql.checkData(12, 2, True)
tdSql.checkData(13, 2, False)
tdSql.checkData(14, 2, True)
tdSql.checkData(15, 2, None)
tdSql.checkData(16, 2, True)
tdSql.checkData(17, 2, None)
tdSql.checkData(18, 2, True)
tdSql.checkData(18, 0, '2020-02-02 00:00:18.000')
tdSql.query(f"select _irowts,_isfilled,interp(c0) from {dbname}.{tbname2} range('2020-02-02 00:00:00', '2020-02-02 00:00:18') every(1s) fill(value, 'abc')")
tdSql.checkRows(19)
tdSql.checkCols(3)
tdSql.checkData(0, 0, '2020-02-02 00:00:00.000')
tdSql.checkData(0, 2, False)
tdSql.checkData(1, 2, False)
tdSql.checkData(2, 2, False)
tdSql.checkData(3, 2, True)
tdSql.checkData(4, 2, False)
tdSql.checkData(5, 2, False)
tdSql.checkData(6, 2, False)
tdSql.checkData(7, 2, True)
tdSql.checkData(8, 2, False)
tdSql.checkData(9, 2, True)
tdSql.checkData(10, 2, False)
tdSql.checkData(11, 2, False)
tdSql.checkData(12, 2, False)
tdSql.checkData(13, 2, False)
tdSql.checkData(14, 2, False)
tdSql.checkData(15, 2, None)
tdSql.checkData(16, 2, False)
tdSql.checkData(17, 2, None)
tdSql.checkData(18, 2, False)
tdSql.checkData(18, 0, '2020-02-02 00:00:18.000')
tdSql.query(f"select _irowts,_isfilled,interp(c0) from {dbname}.{tbname2} range('2020-02-02 00:00:00', '2020-02-02 00:00:18') every(1s) fill(value, NULL)")
tdSql.checkRows(19)
tdSql.checkCols(3)
tdSql.checkData(0, 0, '2020-02-02 00:00:00.000')
tdSql.checkData(0, 2, False)
tdSql.checkData(1, 2, False)
tdSql.checkData(2, 2, False)
tdSql.checkData(3, 2, True)
tdSql.checkData(4, 2, False)
tdSql.checkData(5, 2, False)
tdSql.checkData(6, 2, False)
tdSql.checkData(7, 2, True)
tdSql.checkData(8, 2, False)
tdSql.checkData(9, 2, True)
tdSql.checkData(10, 2, False)
tdSql.checkData(11, 2, False)
tdSql.checkData(12, 2, False)
tdSql.checkData(13, 2, False)
tdSql.checkData(14, 2, False)
tdSql.checkData(15, 2, None)
tdSql.checkData(16, 2, False)
tdSql.checkData(17, 2, None)
tdSql.checkData(18, 2, False)
tdSql.checkData(18, 0, '2020-02-02 00:00:18.000')
# test fill linear
tdSql.query(f"select _irowts,_isfilled,interp(c0) from {dbname}.{tbname2} range('2020-02-02 00:00:00', '2020-02-02 00:00:18') every(1s) fill(linear)")
tdSql.checkRows(17)
tdSql.checkCols(3)
tdSql.checkData(0, 0, '2020-02-02 00:00:01.000')
tdSql.checkData(0, 2, False)
tdSql.checkData(1, 2, False)
tdSql.checkData(2, 2, True)
tdSql.checkData(3, 2, False)
tdSql.checkData(4, 2, False)
tdSql.checkData(5, 2, False)
tdSql.checkData(6, 2, True)
tdSql.checkData(7, 2, True)
tdSql.checkData(8, 2, True)
tdSql.checkData(9, 2, False)
tdSql.checkData(10, 2, False)
tdSql.checkData(11, 2, False)
tdSql.checkData(12, 2, False)
tdSql.checkData(13, 2, None)
tdSql.checkData(14, 2, None)
tdSql.checkData(15, 2, None)
tdSql.checkData(16, 2, None)
tdSql.checkData(16, 0, '2020-02-02 00:00:17.000')
tdLog.printNoPrefix("==========step13: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')")
......@@ -2013,7 +2370,7 @@ class TDTestCase:
# input can only be numerical types
tdSql.error(f"select interp(ts) 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(c6) 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(c6) 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(c7) 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(c8) from {dbname}.{tbname} range('2020-02-10 00:00:05', '2020-02-15 00:00:05') every(1d) fill(null)")
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册