From ed59e85dab4dba5a97d10ac48268a7a63ffe36d6 Mon Sep 17 00:00:00 2001 From: factosea <285808407@qq.com> Date: Wed, 11 Dec 2024 16:02:25 +0800 Subject: [PATCH 01/17] fix: minus operator resType --- source/libs/scalar/src/scalar.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/libs/scalar/src/scalar.c b/source/libs/scalar/src/scalar.c index b3610d035f..74ede393d8 100644 --- a/source/libs/scalar/src/scalar.c +++ b/source/libs/scalar/src/scalar.c @@ -1673,8 +1673,8 @@ static int32_t sclGetMinusOperatorResType(SOperatorNode *pOp) { if (!IS_MATHABLE_TYPE(((SExprNode *)(pOp->pLeft))->resType.type)) { return TSDB_CODE_TSC_INVALID_OPERATION; } - pOp->node.resType.type = TSDB_DATA_TYPE_DOUBLE; - pOp->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes; + pOp->node.resType.type = ((SExprNode *)(pOp->pLeft))->resType.type; + pOp->node.resType.bytes = tDataTypes[((SExprNode *)(pOp->pLeft))->resType.type].bytes; return TSDB_CODE_SUCCESS; } From 58a605de47740fcc6e8cab7fc3d80c37f74c5b36 Mon Sep 17 00:00:00 2001 From: factosea <285808407@qq.com> Date: Wed, 11 Dec 2024 17:29:37 +0800 Subject: [PATCH 02/17] fix: in operator only has one overflow contition --- source/libs/scalar/src/filter.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/libs/scalar/src/filter.c b/source/libs/scalar/src/filter.c index d8622d93ee..45260b69cc 100644 --- a/source/libs/scalar/src/filter.c +++ b/source/libs/scalar/src/filter.c @@ -1305,6 +1305,7 @@ int32_t fltAddGroupUnitFromNode(SFilterInfo *info, SNode *tree, SArray *group) { out.columnData->info.type = type; out.columnData->info.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes; // reserved space for simple_copy + int32_t overflowCount = 0; for (int32_t i = 0; i < listNode->pNodeList->length; ++i) { SValueNode *valueNode = (SValueNode *)cell->pNode; if (valueNode->node.resType.type != type) { @@ -1317,6 +1318,7 @@ int32_t fltAddGroupUnitFromNode(SFilterInfo *info, SNode *tree, SArray *group) { if (overflow) { cell = cell->pNext; + ++overflowCount; continue; } @@ -1357,6 +1359,9 @@ int32_t fltAddGroupUnitFromNode(SFilterInfo *info, SNode *tree, SArray *group) { cell = cell->pNext; } + if(overflowCount == listNode->pNodeList->length) { + FILTER_SET_FLAG(info->status, FI_STATUS_EMPTY); + } colDataDestroy(out.columnData); taosMemoryFree(out.columnData); FLT_ERR_RET(code); From 13ccfdc3141248636aeaf0e8a66b92222eb424c9 Mon Sep 17 00:00:00 2001 From: factosea <285808407@qq.com> Date: Thu, 12 Dec 2024 08:31:47 +0800 Subject: [PATCH 03/17] fix: in contition --- source/libs/scalar/inc/filterInt.h | 1 + source/libs/scalar/src/filter.c | 35 +++++--- tests/system-test/2-query/operator.py | 114 ++++++++++++++++++++++++++ 3 files changed, 140 insertions(+), 10 deletions(-) create mode 100644 tests/system-test/2-query/operator.py diff --git a/source/libs/scalar/inc/filterInt.h b/source/libs/scalar/inc/filterInt.h index 9adc9ee99c..ed07592c73 100644 --- a/source/libs/scalar/inc/filterInt.h +++ b/source/libs/scalar/inc/filterInt.h @@ -236,6 +236,7 @@ typedef struct SFltBuildGroupCtx { SFilterInfo *info; SArray *group; int32_t code; + bool ignore; } SFltBuildGroupCtx; typedef struct { diff --git a/source/libs/scalar/src/filter.c b/source/libs/scalar/src/filter.c index 45260b69cc..10850aab9a 100644 --- a/source/libs/scalar/src/filter.c +++ b/source/libs/scalar/src/filter.c @@ -1284,7 +1284,8 @@ static void filterFreeGroup(void *pItem) { taosMemoryFreeClear(p->unitFlags); } -int32_t fltAddGroupUnitFromNode(SFilterInfo *info, SNode *tree, SArray *group) { +int32_t fltAddGroupUnitFromNode(void *pContext, SFilterInfo *info, SNode *tree, SArray *group) { + SFltBuildGroupCtx *ctx = (SFltBuildGroupCtx *)pContext; SOperatorNode *node = (SOperatorNode *)tree; int32_t ret = TSDB_CODE_SUCCESS; SFilterFieldId left = {0}, right = {0}; @@ -1360,7 +1361,7 @@ int32_t fltAddGroupUnitFromNode(SFilterInfo *info, SNode *tree, SArray *group) { cell = cell->pNext; } if(overflowCount == listNode->pNodeList->length) { - FILTER_SET_FLAG(info->status, FI_STATUS_EMPTY); + ctx->ignore = true; } colDataDestroy(out.columnData); taosMemoryFree(out.columnData); @@ -1697,10 +1698,17 @@ EDealRes fltTreeToGroup(SNode *pNode, void *pContext) { FLT_ERR_RET(terrno); } - SFltBuildGroupCtx tctx = {.info = ctx->info, .group = newGroup}; + SFltBuildGroupCtx tctx = {.info = ctx->info, .group = newGroup, .ignore = false}; nodesWalkExpr(cell->pNode, fltTreeToGroup, (void *)&tctx); FLT_ERR_JRET(tctx.code); - + if(tctx.ignore) { + ctx->ignore = true; + taosArrayDestroyEx(newGroup, filterFreeGroup); + newGroup = NULL; + taosArrayDestroyEx(resGroup, filterFreeGroup); + resGroup = NULL; + break; + } FLT_ERR_JRET(filterDetachCnfGroups(resGroup, preGroup, newGroup)); taosArrayDestroyEx(newGroup, filterFreeGroup); @@ -1712,9 +1720,10 @@ EDealRes fltTreeToGroup(SNode *pNode, void *pContext) { cell = cell->pNext; } - - if (NULL == taosArrayAddAll(ctx->group, preGroup)) { - FLT_ERR_JRET(terrno); + if (!ctx->ignore) { + if (NULL == taosArrayAddAll(ctx->group, preGroup)) { + FLT_ERR_JRET(terrno); + } } taosArrayDestroy(preGroup); @@ -1726,6 +1735,9 @@ EDealRes fltTreeToGroup(SNode *pNode, void *pContext) { SListCell *cell = node->pParameterList->pHead; for (int32_t i = 0; i < node->pParameterList->length; ++i) { nodesWalkExpr(cell->pNode, fltTreeToGroup, (void *)pContext); + if(ctx->ignore) { + ctx->ignore = false; + } FLT_ERR_JRET(ctx->code); cell = cell->pNext; @@ -1740,7 +1752,7 @@ EDealRes fltTreeToGroup(SNode *pNode, void *pContext) { } if (QUERY_NODE_OPERATOR == nType) { - FLT_ERR_JRET(fltAddGroupUnitFromNode(ctx->info, pNode, ctx->group)); + FLT_ERR_JRET(fltAddGroupUnitFromNode(ctx, ctx->info, pNode, ctx->group)); return DEAL_RES_IGNORE_CHILD; } @@ -3836,13 +3848,16 @@ int32_t fltInitFromNode(SNode *tree, SFilterInfo *info, uint32_t options) { goto _return; } - SFltBuildGroupCtx tctx = {.info = info, .group = group}; + SFltBuildGroupCtx tctx = {.info = info, .group = group, .ignore = false}; nodesWalkExpr(tree, fltTreeToGroup, (void *)&tctx); if (TSDB_CODE_SUCCESS != tctx.code) { taosArrayDestroyEx(group, filterFreeGroup); code = tctx.code; goto _return; } + if (tctx.ignore) { + FILTER_SET_FLAG(info->status, FI_STATUS_EMPTY); + } code = filterConvertGroupFromArray(info, group); if (TSDB_CODE_SUCCESS != code) { taosArrayDestroyEx(group, filterFreeGroup); @@ -3876,7 +3891,7 @@ int32_t fltInitFromNode(SNode *tree, SFilterInfo *info, uint32_t options) { _return: if (code) { - qInfo("init from node failed, code:%d", code); + qInfo("init from node failed, code:%d, %s", code, tstrerror(code)); } return code; } diff --git a/tests/system-test/2-query/operator.py b/tests/system-test/2-query/operator.py new file mode 100644 index 0000000000..edfd023b7c --- /dev/null +++ b/tests/system-test/2-query/operator.py @@ -0,0 +1,114 @@ +from wsgiref.headers import tspecials +from util.log import * +from util.cases import * +from util.sql import * +from util.common import tdCom +import numpy as np + + +class TDTestCase: + def init(self, conn, logSql, replicaVar=1): + self.replicaVar = int(replicaVar) + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor()) + + self.dbname = "db" + self.rowNum = 10 + self.ts = 1537146000000 + + # test in/not in contidion with invalid value + def ts5757(self): + + tdSql.execute(f"create database if not exists {self.dbname}") + + tdSql.execute(f"DROP STABLE IF EXISTS {self.dbname}.super_t1;") + tdSql.execute(f"DROP TABLE IF EXISTS {self.dbname}.t1;") + tdSql.execute(f"CREATE STABLE IF NOT EXISTS {self.dbname}.super_t1(time TIMESTAMP, c0 BIGINT UNSIGNED) TAGS (location BINARY(64))") + tdSql.execute(f"CREATE TABLE {self.dbname}.t1 USING {self.dbname}.super_t1 TAGS ('ek')") + tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c0) VALUES (1641024000000, 1);") + tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c0) VALUES (1641024005000, 2);") + tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c0) VALUES (1641024010000, NULL);") + + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NOT NULL AND c0 IN (-1);") + tdSql.checkRows(0) + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NULL AND c0 IN (-1);") + tdSql.checkRows(0) + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NOT NULL AND c0 IN (-1, 1);") + tdSql.checkRows(1) + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NULL AND c0 IN (2, -1, 1);") + tdSql.checkRows(0) + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NOT NULL AND c0 NOT IN (-1);") + tdSql.checkRows(2) + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NULL AND c0 NOT IN (-1);") + tdSql.checkRows(0) + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NULL AND c0 NOT IN (3);") + tdSql.checkRows(0) + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NOT NULL AND c0 NOT IN (-1, 1);") + tdSql.checkRows(1) + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NULL AND c0 NOT IN (2, -1, 1);") + tdSql.checkRows(0) + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE (c0 IS NULL AND c0 IN (-1)) or c0 in(1)") + tdSql.checkRows(1) + + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NOT NULL OR c0 IN (-1);") + tdSql.checkRows(2) + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NULL OR c0 IN (-1);") + tdSql.checkRows(1) + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NOT NULL OR c0 IN (-1, 1);") + tdSql.checkRows(2) + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NULL OR c0 IN (2, -1, 1);") + tdSql.checkRows(3) + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NOT NULL OR c0 NOT IN (-1);") + tdSql.checkRows(2) + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NULL OR c0 NOT IN (-1);") + tdSql.checkRows(3) + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NULL OR c0 NOT IN (3);") + tdSql.checkRows(3) + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NOT NULL OR c0 NOT IN (-1, 1);") + tdSql.checkRows(2) + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NOT NULL OR c0 NOT IN (-1);") + tdSql.checkRows(2) + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NULL OR c0 NOT IN (2, -1, 1);") + tdSql.checkRows(1) + + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE ((c0 is NULL) AND (c0 in (-1)) )") + tdSql.checkRows(0) + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE ((c0 in (-1)) AND (c0 is NULL) )") + tdSql.checkRows(0) + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE ((c0 in (-1)) AND (c0 is NULL) ) OR c0 in(1)") + tdSql.checkRows(1) + + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IN (-1);") + tdSql.checkRows(0) + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IS NOT NULL;") + tdSql.checkRows(2) + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IN (-1) or c0 in(1);") + tdSql.checkRows(1) + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IN (1) or c0 in(-1);") + tdSql.checkRows(1) + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IN (-1) or c0 in(-1);") + tdSql.checkRows(0) + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IN (-1) and c0 in(1);") + tdSql.checkRows(0) + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IN (1) and c0 in(-1);") + tdSql.checkRows(0) + tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IN (-1) and c0 in(-1);") + tdSql.checkRows(0) + + def run(self): + dbname = "db" + tdSql.prepare() + tdSql.execute(f"create database if not exists {self.dbname}") + + self.ts5757() + + + + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + +tdCases.addWindows(__file__, TDTestCase()) + +tdCases.addLinux(__file__, TDTestCase()) From 99c352f175f2ed3cc1b754315e1ec449578a5369 Mon Sep 17 00:00:00 2001 From: factosea <285808407@qq.com> Date: Fri, 13 Dec 2024 09:50:39 +0800 Subject: [PATCH 04/17] fix: timerange --- source/libs/scalar/src/filter.c | 34 ++++++- tests/system-test/2-query/operator.py | 127 ++++++++++++++++++++++++++ 2 files changed, 159 insertions(+), 2 deletions(-) diff --git a/source/libs/scalar/src/filter.c b/source/libs/scalar/src/filter.c index 10850aab9a..aaf05618ca 100644 --- a/source/libs/scalar/src/filter.c +++ b/source/libs/scalar/src/filter.c @@ -13,6 +13,7 @@ * along with this program. If not, see . */ #include +#include "nodes.h" #include "os.h" #include "tglobal.h" #include "thash.h" @@ -4551,6 +4552,29 @@ static int32_t fltSclGetTimeStampDatum(SFltSclPoint *point, SFltSclDatum *d) { return TSDB_CODE_SUCCESS; } +typedef struct SRewriteGetInOperContext { + bool hasInOper; +} SRewriteGetInOperContext; + +static EDealRes rewriteInOperForTimerange(SNode **ppNode, void *pContext) { + SRewriteGetInOperContext *pCxt = pContext; + if (nodeType(*ppNode) == QUERY_NODE_OPERATOR && ((SOperatorNode *)(*ppNode))->opType == OP_TYPE_BIT_OR) { + return DEAL_RES_IGNORE_CHILD; + } + if (nodeType(*ppNode) == QUERY_NODE_OPERATOR && ((SOperatorNode *)(*ppNode))->opType == OP_TYPE_IN) { + pCxt->hasInOper = true; + return DEAL_RES_END; + } + return DEAL_RES_CONTINUE; +} + +bool hasAndTypeInOperator(SNode *pNode) { + SRewriteGetInOperContext cxt = {.hasInOper = false}; + nodesRewriteExpr(&pNode, rewriteInOperForTimerange, &cxt); + + return cxt.hasInOper; +} + int32_t filterGetTimeRange(SNode *pNode, STimeWindow *win, bool *isStrict) { SFilterInfo *info = NULL; int32_t code = 0; @@ -4581,8 +4605,11 @@ int32_t filterGetTimeRange(SNode *pNode, STimeWindow *win, bool *isStrict) { FLT_ERR_JRET(fltSclGetTimeStampDatum(endPt, &end)); win->skey = start.i; win->ekey = end.i; - if(optNode->opType == OP_TYPE_IN) *isStrict = false; - else *isStrict = true; + if (optNode->opType == OP_TYPE_IN || hasAndTypeInOperator(info->sclCtx.node)) { + *isStrict = false; + } else { + *isStrict = true; + } goto _return; } else if (taosArrayGetSize(points) == 0) { *win = TSWINDOW_DESC_INITIALIZER; @@ -5105,6 +5132,9 @@ int32_t fltSclProcessCNF(SArray *sclOpListCNF, SArray *colRangeList) { taosArrayDestroy(colRange->points); taosArrayDestroy(points); colRange->points = merged; + if(merged->size == 0) { + break; + } } else { taosArrayDestroy(colRange->points); colRange->points = points; diff --git a/tests/system-test/2-query/operator.py b/tests/system-test/2-query/operator.py index edfd023b7c..c0235d081d 100644 --- a/tests/system-test/2-query/operator.py +++ b/tests/system-test/2-query/operator.py @@ -95,12 +95,139 @@ class TDTestCase: tdSql.query(f"SELECT * FROM {self.dbname}.t1 WHERE c0 IN (-1) and c0 in(-1);") tdSql.checkRows(0) + def ts5760(self): + tdSql.execute(f"create database if not exists {self.dbname}") + + tdSql.execute(f"DROP TABLE IF EXISTS {self.dbname}.t1;") + tdSql.execute(f"CREATE TABLE {self.dbname}.t1( time TIMESTAMP, c0 INT);") + tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c0) VALUES (1641024000000, 1);") + + tdSql.query(f"SELECT time, c0 FROM t1 WHERE (time - c0) > 0;") + tdSql.checkRows(1) + tdSql.query(f"SELECT time, c0 FROM t1 WHERE (time + c0) > 0;") + tdSql.checkRows(1) + tdSql.query(f"SELECT time, c0 FROM t1 WHERE (-(- c0)) > 0;") + tdSql.checkRows(1) + tdSql.query(f"SELECT time, c0 FROM t1 WHERE -(- c0) > 0;") + tdSql.checkRows(1) + tdSql.query(f"SELECT time, c0 FROM t1 WHERE -(- c0) < 0;") + tdSql.checkRows(0) + + tdSql.query(f"SELECT time, c0 FROM t1 WHERE -(- c0) = 0;") + tdSql.checkRows(0) + + tdSql.query(f"SELECT time, c0 FROM t1 WHERE (- c0) > 0;") + tdSql.checkRows(0) + tdSql.query(f"SELECT time, c0 FROM t1 WHERE (- c0) < 0;") + tdSql.checkRows(1) + + tdSql.query(f"SELECT time, c0 FROM t1 WHERE (time + (- c0)) > 0;") + tdSql.checkRows(1) + + tdSql.query(f"SELECT time, c0 FROM t1 WHERE (time + (- c0)) > 0;") + tdSql.checkRows(1) + + tdSql.query(f"SELECT time, c0 FROM t1 WHERE (time - (- (- c0)) ) > 0;") + tdSql.checkRows(1) + + tdSql.query(f"SELECT time, c0 FROM t1 WHERE (time + (-(- c0))) > 0;") + tdSql.checkRows(1) + + def ts5758(self): + tdSql.execute(f"create database if not exists {self.dbname}") + + tdSql.execute(f"DROP TABLE IF EXISTS {self.dbname}.t1;") + tdSql.execute(f"CREATE TABLE {self.dbname}.t1( time TIMESTAMP, c1 BIGINT);") + tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c1) VALUES (1641024000000, 0);") + tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c1) VALUES (1641024000001, 1);") + tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c1) VALUES (1641024000002, 2);") + tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c1) VALUES (1641024000003, 3);") + tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c1) VALUES (1641024000004, 4);") + tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c1) VALUES (1641024000005, 5);") + + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time IN (1) AND time BETWEEN (1741024000000) AND (1741024000000);") + tdSql.checkRows(0) + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time BETWEEN (1741024000000) AND (1741024000000) AND time IN (1);") + tdSql.checkRows(0) + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time IN (1) and time BETWEEN (1741024000000) AND (1741024000000) AND time IN (1);") + tdSql.checkRows(0) + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time IN (1641024000000) and time BETWEEN (1741024000000) AND (1741024000000) AND time IN (1);") + tdSql.checkRows(0) + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time IN (1) AND time BETWEEN (1641024000000) AND (1741024000000);") + tdSql.checkRows(0) + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time IN (1641024000001) AND time BETWEEN (1641024000000) AND (1741024000000);") + tdSql.checkRows(1) + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time IN (1641024000001, 1641024000002, 1641024000003) AND time BETWEEN (1641024000000) AND (1741024000000);") + tdSql.checkRows(3) + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time IN (1641024000001, 1641024000002, 1641024000005) AND time BETWEEN (1641024000000) AND (1641024000004);") + tdSql.checkRows(2) + + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time IN (1) OR time = 1741024000000;") + tdSql.checkRows(0) + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time = 1741024000000 OR time IN (1);") + tdSql.checkRows(0) + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time IN (1, 2, 3) OR time BETWEEN (1641024000000) and (1741024000000);") + tdSql.checkRows(6) + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time IN (1, 2, 3) OR time = 1641024000000;") + tdSql.checkRows(1) + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time = 1641024000001 OR time BETWEEN (1641024000000) and (1641024000002);") + tdSql.checkRows(3) + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time = 1641024000004 OR time BETWEEN (1641024000000) and (1641024000002);") + tdSql.checkRows(4) + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time = 1641024000001 OR time = 1741024000000;") + tdSql.checkRows(1) + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time IN (1641024000001, 1641024000002) OR time = 1741024000000;") + tdSql.checkRows(2) + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE time IN (1641024000001, 1641024000002) OR time BETWEEN (1641024000000) and (1741024000000);") + tdSql.checkRows(6) + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE (time = 1641024000004 OR time BETWEEN (1641024000000) and (1641024000002)) and time in(1);") + tdSql.checkRows(0) + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE (time = 1641024000004 OR time BETWEEN (1641024000000) and (1641024000002)) and time in(1641024000004, 1641024000002);") + tdSql.checkRows(2) + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE (time = 1641024000004 OR time BETWEEN (1641024000000) and (1641024000002)) or time in(1);") + tdSql.checkRows(4) + + + def ts5759(self): + tdSql.execute(f"create database if not exists {self.dbname}") + + tdSql.execute(f"DROP TABLE IF EXISTS {self.dbname}.t1;") + tdSql.execute(f"CREATE TABLE {self.dbname}.t1( time TIMESTAMP, c1 BIGINT);") + tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c1) VALUES (1641024000000, 0);") + + tdSql.query(f"SELECT c1 FROM t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001)") + tdSql.checkRows(1) + tdSql.query(f"SELECT c1 FROM t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) OR (1 < 2)") + tdSql.checkRows(1) + tdSql.query(f"SELECT c1 FROM t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) OR (3 < 2)") + tdSql.checkRows(1) + tdSql.query(f"SELECT c1 FROM t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) and (1 < 2)") + tdSql.checkRows(1) + tdSql.query(f"SELECT c1 FROM t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) OR (1 > 2)") + tdSql.checkRows(1) + tdSql.query(f"SELECT c1 FROM t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) and (1 > 2)") + tdSql.checkRows(0) + + tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c1) VALUES (1641024000001, 1);") + tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c1) VALUES (1641024000002, 2);") + + tdSql.query(f"SELECT c1 FROM t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) OR (1 < 2)") + tdSql.checkRows(3) + tdSql.query(f"SELECT c1 FROM t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) OR (1 > 2)") + tdSql.checkRows(2) + tdSql.query(f"SELECT c1 FROM t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) and (1 < 2)") + tdSql.checkRows(2) + + def run(self): dbname = "db" tdSql.prepare() tdSql.execute(f"create database if not exists {self.dbname}") self.ts5757() + # self.ts5760() + self.ts5758() + self.ts5759() From b5fb388fec13d8d223c60e8c8d8788dcef089187 Mon Sep 17 00:00:00 2001 From: factosea <285808407@qq.com> Date: Fri, 13 Dec 2024 09:52:23 +0800 Subject: [PATCH 05/17] revert minus restype --- source/libs/scalar/src/scalar.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/libs/scalar/src/scalar.c b/source/libs/scalar/src/scalar.c index 74ede393d8..b3610d035f 100644 --- a/source/libs/scalar/src/scalar.c +++ b/source/libs/scalar/src/scalar.c @@ -1673,8 +1673,8 @@ static int32_t sclGetMinusOperatorResType(SOperatorNode *pOp) { if (!IS_MATHABLE_TYPE(((SExprNode *)(pOp->pLeft))->resType.type)) { return TSDB_CODE_TSC_INVALID_OPERATION; } - pOp->node.resType.type = ((SExprNode *)(pOp->pLeft))->resType.type; - pOp->node.resType.bytes = tDataTypes[((SExprNode *)(pOp->pLeft))->resType.type].bytes; + pOp->node.resType.type = TSDB_DATA_TYPE_DOUBLE; + pOp->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes; return TSDB_CODE_SUCCESS; } From bc4bd8d0591a8dad2ad50e82f818486205201984 Mon Sep 17 00:00:00 2001 From: factosea <285808407@qq.com> Date: Fri, 13 Dec 2024 15:10:25 +0800 Subject: [PATCH 06/17] fix: oper on time type --- source/libs/scalar/src/scalar.c | 4 +- source/libs/scalar/src/sclvector.c | 6 +- tests/system-test/2-query/operator.py | 79 +++++++++++++++++++++++++-- 3 files changed, 81 insertions(+), 8 deletions(-) diff --git a/source/libs/scalar/src/scalar.c b/source/libs/scalar/src/scalar.c index b3610d035f..370ee4d6e9 100644 --- a/source/libs/scalar/src/scalar.c +++ b/source/libs/scalar/src/scalar.c @@ -1688,8 +1688,8 @@ static int32_t sclGetMathOperatorResType(SOperatorNode *pOp) { if ((TSDB_DATA_TYPE_TIMESTAMP == ldt.type && TSDB_DATA_TYPE_TIMESTAMP == rdt.type) || TSDB_DATA_TYPE_VARBINARY == ldt.type || TSDB_DATA_TYPE_VARBINARY == rdt.type || - (TSDB_DATA_TYPE_TIMESTAMP == ldt.type && (IS_VAR_DATA_TYPE(rdt.type) || IS_FLOAT_TYPE(rdt.type))) || - (TSDB_DATA_TYPE_TIMESTAMP == rdt.type && (IS_VAR_DATA_TYPE(ldt.type) || IS_FLOAT_TYPE(ldt.type)))) { + (TSDB_DATA_TYPE_TIMESTAMP == ldt.type && (IS_VAR_DATA_TYPE(rdt.type))) || + (TSDB_DATA_TYPE_TIMESTAMP == rdt.type && (IS_VAR_DATA_TYPE(ldt.type)))) { return TSDB_CODE_TSC_INVALID_OPERATION; } diff --git a/source/libs/scalar/src/sclvector.c b/source/libs/scalar/src/sclvector.c index c6c8333392..0b232de70e 100644 --- a/source/libs/scalar/src/sclvector.c +++ b/source/libs/scalar/src/sclvector.c @@ -1398,9 +1398,11 @@ int32_t vectorMathSub(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *p SCL_ERR_JRET(vectorConvertVarToDouble(pLeft, &leftConvert, &pLeftCol)); SCL_ERR_JRET(vectorConvertVarToDouble(pRight, &rightConvert, &pRightCol)); - if ((GET_PARAM_TYPE(pLeft) == TSDB_DATA_TYPE_TIMESTAMP && GET_PARAM_TYPE(pRight) == TSDB_DATA_TYPE_BIGINT) || + if ((GET_PARAM_TYPE(pLeft) == TSDB_DATA_TYPE_TIMESTAMP && IS_INTEGER_TYPE(GET_PARAM_TYPE(pRight))) || + (GET_PARAM_TYPE(pRight) == TSDB_DATA_TYPE_TIMESTAMP && IS_INTEGER_TYPE(GET_PARAM_TYPE(pLeft))) || + (GET_PARAM_TYPE(pLeft) == TSDB_DATA_TYPE_TIMESTAMP && GET_PARAM_TYPE(pRight) == TSDB_DATA_TYPE_BOOL) || (GET_PARAM_TYPE(pRight) == TSDB_DATA_TYPE_TIMESTAMP && - GET_PARAM_TYPE(pLeft) == TSDB_DATA_TYPE_BIGINT)) { // timestamp minus duration + GET_PARAM_TYPE(pLeft) == TSDB_DATA_TYPE_BOOL)) { // timestamp minus duration int64_t *output = (int64_t *)pOutputCol->pData; _getBigintValue_fn_t getVectorBigintValueFnLeft; _getBigintValue_fn_t getVectorBigintValueFnRight; diff --git a/tests/system-test/2-query/operator.py b/tests/system-test/2-query/operator.py index c0235d081d..9b2589536a 100644 --- a/tests/system-test/2-query/operator.py +++ b/tests/system-test/2-query/operator.py @@ -218,16 +218,87 @@ class TDTestCase: tdSql.query(f"SELECT c1 FROM t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) and (1 < 2)") tdSql.checkRows(2) + def operOnTime(self): + tdSql.execute(f"create database if not exists {self.dbname}") + + tdSql.execute(f"DROP TABLE IF EXISTS {self.dbname}.t1;") + tdSql.execute(f"CREATE TABLE {self.dbname}.t1( ts TIMESTAMP, c0 INT, c1 INT UNSIGNED, \ + c2 BIGINT, c3 BIGINT UNSIGNED, c4 SMALLINT, c5 SMALLINT UNSIGNED, c6 TINYINT, c7 TINYINT UNSIGNED);") + tdSql.execute(f"INSERT INTO {self.dbname}.t1 VALUES (1641024000001, 1, 1, 1, 1, 1, 1, 1, 1);") + + columns = ["c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7"] + for col in columns: + tdLog.debug(f"oper on time test, {col} start ...") + tdSql.query(f"SELECT ts, ts+1, ts+{col}, ts+(-{col}) FROM {self.dbname}.t1") + tdSql.checkRows(1) + tdSql.checkData(0, 0, 1641024000001) + tdSql.checkData(0, 1, 1641024000002) + tdSql.checkData(0, 2, 1641024000002) + tdSql.checkData(0, 3, 1641024000000) + + tdSql.query(f"SELECT ts, ts+1, ts+{col}, ts+(-{col}) FROM {self.dbname}.t1 where (ts-(-{col})) > 0") + tdSql.checkRows(1) + tdSql.checkData(0, 0, 1641024000001) + tdSql.checkData(0, 1, 1641024000002) + tdSql.checkData(0, 2, 1641024000002) + tdSql.checkData(0, 3, 1641024000000) + + tdSql.query(f"SELECT ts, ts-1, ts-{col}, ts-(-{col}) FROM {self.dbname}.t1") + tdSql.checkRows(1) + tdSql.checkData(0, 0, 1641024000001) + tdSql.checkData(0, 1, 1641024000000) + tdSql.checkData(0, 2, 1641024000000) + tdSql.checkData(0, 3, 1641024000002) + + tdSql.query(f"SELECT ts, ts+true, ts-true, ts-false, ts+false FROM {self.dbname}.t1") + tdSql.checkRows(1) + tdSql.checkData(0, 0, 1641024000001) + tdSql.checkData(0, 1, 1641024000002) + tdSql.checkData(0, 2, 1641024000000) + tdSql.checkData(0, 3, 1641024000001) + tdSql.checkData(0, 4, 1641024000001) + + tdSql.execute(f"DROP TABLE IF EXISTS {self.dbname}.t2;") + tdSql.execute(f"CREATE TABLE {self.dbname}.t2( ts TIMESTAMP, c1 float, c2 double);") + tdSql.execute(f"INSERT INTO {self.dbname}.t2(ts, c1, c2) VALUES (1641024000001, 1.0, 1.0);") + + columns = ["c1", "c2"] + for col in columns: + tdSql.query(f"SELECT ts, ts+{col}, ts+(-{col}), ts-{col}, ts-(-{col}) FROM {self.dbname}.t2") + tdSql.checkRows(1) + tdSql.checkData(0, 0, 1641024000001) + tdSql.checkData(0, 1, 1641024000002) + tdSql.checkData(0, 2, 1641024000000) + tdSql.checkData(0, 3, 1641024000000) + tdSql.checkData(0, 4, 1641024000002) + + tdSql.query(f"SELECT ts, ts+{col}, ts+(-{col}), ts-{col}, ts-(-{col}) FROM {self.dbname}.t2 where (ts-(-{col})) > 0") + tdSql.checkRows(1) + tdSql.checkData(0, 0, 1641024000001) + tdSql.checkData(0, 1, 1641024000002) + tdSql.checkData(0, 2, 1641024000000) + tdSql.checkData(0, 3, 1641024000000) + tdSql.checkData(0, 4, 1641024000002) + + tdSql.query(f"SELECT ts, cast(ts+{col} as bigint), cast(ts+(-{col}) as bigint), cast(ts-{col} as bigint),\ + cast(ts-(-{col}) as bigint) FROM {self.dbname}.t2") + tdSql.checkRows(1) + tdSql.checkData(0, 0, 1641024000001) + tdSql.checkData(0, 1, 1641024000002) + tdSql.checkData(0, 2, 1641024000000) + tdSql.checkData(0, 3, 1641024000000) + tdSql.checkData(0, 4, 1641024000002) def run(self): dbname = "db" tdSql.prepare() tdSql.execute(f"create database if not exists {self.dbname}") - self.ts5757() - # self.ts5760() - self.ts5758() - self.ts5759() + #self.ts5757() + #self.ts5760() + #self.ts5758() + #self.ts5759() + self.operOnTime() From eee8b99819195e6649fb23b8ad8462f29a8483f7 Mon Sep 17 00:00:00 2001 From: factosea <285808407@qq.com> Date: Sun, 15 Dec 2024 23:40:20 +0800 Subject: [PATCH 07/17] fix: set strict --- source/libs/scalar/inc/filterInt.h | 1 + source/libs/scalar/src/filter.c | 114 ++++++++++++++++++++------ tests/system-test/2-query/operator.py | 8 +- 3 files changed, 92 insertions(+), 31 deletions(-) diff --git a/source/libs/scalar/inc/filterInt.h b/source/libs/scalar/inc/filterInt.h index ed07592c73..34f100a2bd 100644 --- a/source/libs/scalar/inc/filterInt.h +++ b/source/libs/scalar/inc/filterInt.h @@ -267,6 +267,7 @@ struct SFilterInfo { int8_t *blkUnitRes; void *pTable; SArray *blkList; + bool isStrict; SFilterPCtx pctx; }; diff --git a/source/libs/scalar/src/filter.c b/source/libs/scalar/src/filter.c index aaf05618ca..8e548c6dcc 100644 --- a/source/libs/scalar/src/filter.c +++ b/source/libs/scalar/src/filter.c @@ -4556,25 +4556,6 @@ typedef struct SRewriteGetInOperContext { bool hasInOper; } SRewriteGetInOperContext; -static EDealRes rewriteInOperForTimerange(SNode **ppNode, void *pContext) { - SRewriteGetInOperContext *pCxt = pContext; - if (nodeType(*ppNode) == QUERY_NODE_OPERATOR && ((SOperatorNode *)(*ppNode))->opType == OP_TYPE_BIT_OR) { - return DEAL_RES_IGNORE_CHILD; - } - if (nodeType(*ppNode) == QUERY_NODE_OPERATOR && ((SOperatorNode *)(*ppNode))->opType == OP_TYPE_IN) { - pCxt->hasInOper = true; - return DEAL_RES_END; - } - return DEAL_RES_CONTINUE; -} - -bool hasAndTypeInOperator(SNode *pNode) { - SRewriteGetInOperContext cxt = {.hasInOper = false}; - nodesRewriteExpr(&pNode, rewriteInOperForTimerange, &cxt); - - return cxt.hasInOper; -} - int32_t filterGetTimeRange(SNode *pNode, STimeWindow *win, bool *isStrict) { SFilterInfo *info = NULL; int32_t code = 0; @@ -4605,11 +4586,7 @@ int32_t filterGetTimeRange(SNode *pNode, STimeWindow *win, bool *isStrict) { FLT_ERR_JRET(fltSclGetTimeStampDatum(endPt, &end)); win->skey = start.i; win->ekey = end.i; - if (optNode->opType == OP_TYPE_IN || hasAndTypeInOperator(info->sclCtx.node)) { - *isStrict = false; - } else { - *isStrict = true; - } + *isStrict = info->isStrict; goto _return; } else if (taosArrayGetSize(points) == 0) { *win = TSWINDOW_DESC_INITIALIZER; @@ -5108,8 +5085,76 @@ int32_t fltSclBuildRangePoints(SFltSclOperator *oper, SArray *points) { return TSDB_CODE_SUCCESS; } +static int32_t fltInOpertoArray(SArray **sclInOper, SFltSclOperator *pInOper) { + if (*sclInOper == NULL) { + *sclInOper = taosArrayInit(4, sizeof(SFltSclOperator *)); + if (NULL == *sclInOper) { + FLT_ERR_RET(terrno); + } + } + if (NULL == taosArrayPush(*sclInOper, &pInOper)) { + FLT_ERR_RET(terrno); + } + return TSDB_CODE_SUCCESS; +} + +static int32_t hasValidInOper(SArray *sclInOper, SArray *colRangeList, bool* has) { + SFltSclOperator **ppSclOper = NULL; + *has = false; + for (int32_t i = 0; i < taosArrayGetSize(sclInOper); ++i) { + ppSclOper = taosArrayGet(sclInOper, i); + if (NULL == ppSclOper) { + return TSDB_CODE_OUT_OF_RANGE; + } + if(*ppSclOper == NULL) { + qError("func: hasValidInOper, invalid in operator"); + return TSDB_CODE_OUT_OF_RANGE; + } + SFltSclColumnRange *colRange = NULL; + SFltSclOperator * pSclOper = *ppSclOper; + for (int32_t i = 0; i < taosArrayGetSize(colRangeList); ++i) { + colRange = taosArrayGet(colRangeList, i); + if (NULL == colRange) { + return TSDB_CODE_OUT_OF_RANGE; + } + if (nodesEqualNode((SNode *)colRange->colNode, (SNode *)pSclOper->colNode)) { + SFltSclPoint *startPt = taosArrayGet(colRange->points, 0); + SFltSclPoint *endPt = taosArrayGet(colRange->points, 1); + if (NULL == startPt || NULL == endPt) { + return TSDB_CODE_OUT_OF_RANGE; + } + SNodeListNode *listNode = (SNodeListNode *)pSclOper->valNode; + SListCell *cell = listNode->pNodeList->pHead; + for (int32_t i = 0; i < listNode->pNodeList->length; ++i) { + SValueNode *valueNode = (SValueNode *)cell->pNode; + SFltSclDatum valDatum; + FLT_ERR_RET(fltSclBuildDatumFromValueNode(&valDatum, valueNode)); + if (valueNode->node.resType.type == TSDB_DATA_TYPE_FLOAT || + valueNode->node.resType.type == TSDB_DATA_TYPE_DOUBLE) { + if (startPt->val.d != endPt->val.d && (valDatum.d >= startPt->val.d || valDatum.d <= endPt->val.d)) { + *has = true; + return TSDB_CODE_SUCCESS; + } + } else { + if (startPt->val.d != endPt->val.d && (valDatum.i >= startPt->val.i || valDatum.i <= endPt->val.i)) { + *has = true; + return TSDB_CODE_SUCCESS; + } + } + cell = cell->pNext; + } + } + } + } + return TSDB_CODE_SUCCESS; +} + // TODO: process DNF composed of CNF -int32_t fltSclProcessCNF(SArray *sclOpListCNF, SArray *colRangeList) { +static int32_t fltSclProcessCNF(SFilterInfo *pInfo, SArray *sclOpListCNF, SArray *colRangeList) { + int32_t code = TSDB_CODE_SUCCESS; + + pInfo->isStrict = true; + SArray *sclInOper = NULL; size_t sz = taosArrayGetSize(sclOpListCNF); for (int32_t i = 0; i < sz; ++i) { SFltSclOperator *sclOper = taosArrayGet(sclOpListCNF, i); @@ -5133,12 +5178,27 @@ int32_t fltSclProcessCNF(SArray *sclOpListCNF, SArray *colRangeList) { taosArrayDestroy(points); colRange->points = merged; if(merged->size == 0) { - break; + goto _exit; } } else { taosArrayDestroy(colRange->points); colRange->points = points; } + if (sclOper->type == OP_TYPE_IN) { + fltInOpertoArray(&sclInOper, sclOper); + } + } + bool hasInOper = false; + code = hasValidInOper(sclInOper, colRangeList, &hasInOper); + if (code != TSDB_CODE_SUCCESS) { + goto _exit; + } + if (hasInOper) { + pInfo->isStrict = false; + } +_exit: + if (sclInOper) { + taosArrayDestroy(sclInOper); } return TSDB_CODE_SUCCESS; } @@ -5240,7 +5300,7 @@ int32_t fltOptimizeNodes(SFilterInfo *pInfo, SNode **pNode, SFltTreeStat *pStat) if (NULL == colRangeList) { FLT_ERR_JRET(terrno); } - FLT_ERR_JRET(fltSclProcessCNF(sclOpList, colRangeList)); + FLT_ERR_JRET(fltSclProcessCNF(pInfo, sclOpList, colRangeList)); pInfo->sclCtx.fltSclRange = colRangeList; for (int32_t i = 0; i < taosArrayGetSize(sclOpList); ++i) { diff --git a/tests/system-test/2-query/operator.py b/tests/system-test/2-query/operator.py index 9b2589536a..d8cf2b54cb 100644 --- a/tests/system-test/2-query/operator.py +++ b/tests/system-test/2-query/operator.py @@ -294,10 +294,10 @@ class TDTestCase: tdSql.prepare() tdSql.execute(f"create database if not exists {self.dbname}") - #self.ts5757() - #self.ts5760() - #self.ts5758() - #self.ts5759() + self.ts5757() + self.ts5760() + self.ts5758() + self.ts5759() self.operOnTime() From a65825b88d11b045baff1acff3108c15aee15c65 Mon Sep 17 00:00:00 2001 From: factosea <285808407@qq.com> Date: Mon, 16 Dec 2024 06:20:10 +0800 Subject: [PATCH 08/17] fix: return value --- source/libs/scalar/src/filter.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/source/libs/scalar/src/filter.c b/source/libs/scalar/src/filter.c index 8e548c6dcc..8230119d8c 100644 --- a/source/libs/scalar/src/filter.c +++ b/source/libs/scalar/src/filter.c @@ -5159,44 +5159,45 @@ static int32_t fltSclProcessCNF(SFilterInfo *pInfo, SArray *sclOpListCNF, SArray for (int32_t i = 0; i < sz; ++i) { SFltSclOperator *sclOper = taosArrayGet(sclOpListCNF, i); if (NULL == sclOper) { - FLT_ERR_RET(TSDB_CODE_OUT_OF_RANGE); + FLT_ERR_JRET(TSDB_CODE_OUT_OF_RANGE); } SFltSclColumnRange *colRange = NULL; - FLT_ERR_RET(fltSclGetOrCreateColumnRange(sclOper->colNode, colRangeList, &colRange)); + FLT_ERR_JRET(fltSclGetOrCreateColumnRange(sclOper->colNode, colRangeList, &colRange)); SArray *points = taosArrayInit(4, sizeof(SFltSclPoint)); if (NULL == points) { - FLT_ERR_RET(terrno); + FLT_ERR_JRET(terrno); } - FLT_ERR_RET(fltSclBuildRangePoints(sclOper, points)); + FLT_ERR_JRET(fltSclBuildRangePoints(sclOper, points)); if (taosArrayGetSize(colRange->points) != 0) { SArray *merged = taosArrayInit(4, sizeof(SFltSclPoint)); if (NULL == merged) { - FLT_ERR_RET(terrno); + FLT_ERR_JRET(terrno); } - FLT_ERR_RET(fltSclIntersect(colRange->points, points, merged)); + FLT_ERR_JRET(fltSclIntersect(colRange->points, points, merged)); taosArrayDestroy(colRange->points); taosArrayDestroy(points); colRange->points = merged; if(merged->size == 0) { - goto _exit; + goto _return; } } else { taosArrayDestroy(colRange->points); colRange->points = points; } if (sclOper->type == OP_TYPE_IN) { - fltInOpertoArray(&sclInOper, sclOper); + code = fltInOpertoArray(&sclInOper, sclOper); + FLT_ERR_JRET(code); } } bool hasInOper = false; code = hasValidInOper(sclInOper, colRangeList, &hasInOper); if (code != TSDB_CODE_SUCCESS) { - goto _exit; + goto _return; } if (hasInOper) { pInfo->isStrict = false; } -_exit: +_return: if (sclInOper) { taosArrayDestroy(sclInOper); } From a18fefc968a8238da2973f2879665ae41ca1cf1d Mon Sep 17 00:00:00 2001 From: factosea <285808407@qq.com> Date: Mon, 16 Dec 2024 08:59:43 +0800 Subject: [PATCH 09/17] fix: time operator test --- tests/system-test/2-query/Now.py | 6 ++++- tests/system-test/2-query/Today.py | 2 +- tests/system-test/2-query/operator.py | 35 +++++++++++++++++++++++++++ tests/system-test/2-query/sum.py | 2 +- 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/tests/system-test/2-query/Now.py b/tests/system-test/2-query/Now.py index 21ff1f4e06..65734a5566 100644 --- a/tests/system-test/2-query/Now.py +++ b/tests/system-test/2-query/Now.py @@ -41,8 +41,9 @@ class TDTestCase: ] self.time_unit = ['b','u','a','s','m','h','d','w'] self.symbol = ['+','-','*','/'] - self.error_values = [1.5,'abc','"abc"','!@','today()'] + self.error_values = ['abc','"abc"','!@','today()'] self.db_percision = ['ms','us','ns'] + self.test_values = [1.5, 10, 9223372036854775807, -9223372036854775808] def tbtype_check(self,tb_type): if tb_type == 'normal table' or tb_type == 'child table': tdSql.checkRows(len(self.values_list)) @@ -67,6 +68,9 @@ class TDTestCase: for symbol in self.symbol: for param in self.error_values: tdSql.error(f'select now() {symbol}{param} from {tbname}') + for param in self.test_values: + tdSql.query(f'select now() {symbol}{param} from {tbname}') + tdSql.query(f'select 1 {symbol}{param} from {tbname}') tdSql.query(f'select now(){symbol}null from {tbname}') self.tbtype_check(tb_type) for i in range(len(self.values_list)): diff --git a/tests/system-test/2-query/Today.py b/tests/system-test/2-query/Today.py index 77e6bd8cb6..745ed31c2c 100644 --- a/tests/system-test/2-query/Today.py +++ b/tests/system-test/2-query/Today.py @@ -18,7 +18,7 @@ class TDTestCase: self.today_ts = datetime.datetime.strptime(datetime.datetime.now().strftime("%Y-%m-%d"), "%Y-%m-%d").timestamp() self.today_ts_ns = 0 self.time_unit = ['b','u','a','s','m','h','d','w'] - self.error_param = ['1.5','abc','!@#','"abc"','today()'] + self.error_param = ['abc','!@#','"abc"','today()'] self.arithmetic_operators = ['+','-','*','/'] self.relational_operator = ['<','<=','=','>=','>'] # prepare data diff --git a/tests/system-test/2-query/operator.py b/tests/system-test/2-query/operator.py index d8cf2b54cb..3fd5a10ab6 100644 --- a/tests/system-test/2-query/operator.py +++ b/tests/system-test/2-query/operator.py @@ -288,6 +288,41 @@ class TDTestCase: tdSql.checkData(0, 2, 1641024000000) tdSql.checkData(0, 3, 1641024000000) tdSql.checkData(0, 4, 1641024000002) + + tdSql.query(f"SELECT sum(ts + c1), sum(ts+c2) from t2") + tdSql.checkData(0, 0, 1641024000002) + tdSql.checkData(0, 1, 1641024000002) + tdSql.query(f"SELECT sum(ts * c1), sum(ts*c2) from t2") + tdSql.checkData(0, 0, 1641024000001) + tdSql.checkData(0, 1, 1641024000001) + tdSql.query(f"SELECT sum(ts / c1), sum(ts/c2) from t2") + tdSql.checkData(0, 0, 1641024000001) + tdSql.checkData(0, 1, 1641024000001) + tdSql.execute(f"INSERT INTO {self.dbname}.t2(ts, c1, c2) VALUES (1641024000002, 2.0, 2.0);") + tdSql.query(f"SELECT sum(ts + c1), sum(ts+c2) from t2") + tdSql.checkData(0, 0, 3282048000006) + tdSql.checkData(0, 1, 3282048000006) + tdSql.query(f"SELECT sum(ts - c1), sum(ts-c2) from t2") + tdSql.checkData(0, 0, 3282048000000) + tdSql.checkData(0, 1, 3282048000000) + tdSql.query(f"SELECT sum(ts * c1), sum(ts*c2) from t2") + tdSql.checkData(0, 0, 4923072000005) + tdSql.checkData(0, 1, 4923072000005) + tdSql.query(f"SELECT ts / c1, ts/c2 from t2 order by ts") + tdSql.checkData(0, 0, 1641024000001) + tdSql.checkData(0, 1, 1641024000001) + tdSql.checkData(1, 0, 820512000001) + tdSql.checkData(1, 1, 820512000001) + tdSql.query(f"SELECT sum(ts / c1), sum(ts/c2) from t2") + tdSql.checkData(0, 0, 2461536000002) + tdSql.checkData(0, 1, 2461536000002) + + # data overflow + tdSql.query(f"SELECT ts + 9223372036854775807 from t2 order by ts") + tdSql.query(f"SELECT ts - 9223372036854775808 from t2 order by ts") + + tdSql.query(f"SELECT ts + 8223372036854775807 from t2 order by ts") + tdSql.query(f"SELECT ts - 8223372036854775808 from t2 order by ts") def run(self): dbname = "db" diff --git a/tests/system-test/2-query/sum.py b/tests/system-test/2-query/sum.py index 5abd58d3f9..88f2a37aec 100644 --- a/tests/system-test/2-query/sum.py +++ b/tests/system-test/2-query/sum.py @@ -78,7 +78,7 @@ class TDTestCase: ) # sqls.extend( f"select sum( {un_num_col} + {un_num_col_2} ) from {tbanme} " for un_num_col_2 in UN_NUM_COL ) - sqls.extend( f"select sum( {num_col} + {ts_col} ) from {DBNAME}.{tbanme} " for num_col in NUM_COL for ts_col in TS_TYPE_COL) + #sqls.extend( f"select sum( {num_col} + {ts_col} ) from {DBNAME}.{tbanme} " for num_col in NUM_COL for ts_col in TS_TYPE_COL) sqls.extend( ( f"select sum() from {DBNAME}.{tbanme} ", From ff53c4bc5047955a06f2b6b068b19ab3bdaed4c6 Mon Sep 17 00:00:00 2001 From: factosea <285808407@qq.com> Date: Mon, 16 Dec 2024 09:04:50 +0800 Subject: [PATCH 10/17] fix: test case --- tests/system-test/2-query/operator.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/system-test/2-query/operator.py b/tests/system-test/2-query/operator.py index 3fd5a10ab6..ad9387deb5 100644 --- a/tests/system-test/2-query/operator.py +++ b/tests/system-test/2-query/operator.py @@ -289,40 +289,40 @@ class TDTestCase: tdSql.checkData(0, 3, 1641024000000) tdSql.checkData(0, 4, 1641024000002) - tdSql.query(f"SELECT sum(ts + c1), sum(ts+c2) from t2") + tdSql.query(f"SELECT sum(ts + c1), sum(ts+c2) from {self.dbname}.t2") tdSql.checkData(0, 0, 1641024000002) tdSql.checkData(0, 1, 1641024000002) - tdSql.query(f"SELECT sum(ts * c1), sum(ts*c2) from t2") + tdSql.query(f"SELECT sum(ts * c1), sum(ts*c2) from {self.dbname}.t2") tdSql.checkData(0, 0, 1641024000001) tdSql.checkData(0, 1, 1641024000001) - tdSql.query(f"SELECT sum(ts / c1), sum(ts/c2) from t2") + tdSql.query(f"SELECT sum(ts / c1), sum(ts/c2) from {self.dbname}.t2") tdSql.checkData(0, 0, 1641024000001) tdSql.checkData(0, 1, 1641024000001) tdSql.execute(f"INSERT INTO {self.dbname}.t2(ts, c1, c2) VALUES (1641024000002, 2.0, 2.0);") - tdSql.query(f"SELECT sum(ts + c1), sum(ts+c2) from t2") + tdSql.query(f"SELECT sum(ts + c1), sum(ts+c2) from {self.dbname}.t2") tdSql.checkData(0, 0, 3282048000006) tdSql.checkData(0, 1, 3282048000006) - tdSql.query(f"SELECT sum(ts - c1), sum(ts-c2) from t2") + tdSql.query(f"SELECT sum(ts - c1), sum(ts-c2) from {self.dbname}.t2") tdSql.checkData(0, 0, 3282048000000) tdSql.checkData(0, 1, 3282048000000) - tdSql.query(f"SELECT sum(ts * c1), sum(ts*c2) from t2") + tdSql.query(f"SELECT sum(ts * c1), sum(ts*c2) from {self.dbname}.t2") tdSql.checkData(0, 0, 4923072000005) tdSql.checkData(0, 1, 4923072000005) - tdSql.query(f"SELECT ts / c1, ts/c2 from t2 order by ts") + tdSql.query(f"SELECT ts / c1, ts/c2 from t2 order by {self.dbname}.ts") tdSql.checkData(0, 0, 1641024000001) tdSql.checkData(0, 1, 1641024000001) tdSql.checkData(1, 0, 820512000001) tdSql.checkData(1, 1, 820512000001) - tdSql.query(f"SELECT sum(ts / c1), sum(ts/c2) from t2") + tdSql.query(f"SELECT sum(ts / c1), sum(ts/c2) from {self.dbname}.t2") tdSql.checkData(0, 0, 2461536000002) tdSql.checkData(0, 1, 2461536000002) # data overflow - tdSql.query(f"SELECT ts + 9223372036854775807 from t2 order by ts") - tdSql.query(f"SELECT ts - 9223372036854775808 from t2 order by ts") + tdSql.query(f"SELECT ts + 9223372036854775807 from {self.dbname}.t2 order by ts") + tdSql.query(f"SELECT ts - 9223372036854775808 from {self.dbname}.t2 order by ts") - tdSql.query(f"SELECT ts + 8223372036854775807 from t2 order by ts") - tdSql.query(f"SELECT ts - 8223372036854775808 from t2 order by ts") + tdSql.query(f"SELECT ts + 8223372036854775807 from {self.dbname}.t2 order by ts") + tdSql.query(f"SELECT ts - 8223372036854775808 from {self.dbname}.t2 order by ts") def run(self): dbname = "db" From c94a3f85e47227b7b1f744ec9e4e82b270be0193 Mon Sep 17 00:00:00 2001 From: factosea <285808407@qq.com> Date: Mon, 16 Dec 2024 10:48:57 +0800 Subject: [PATCH 11/17] fix: mathOperatorRestype --- source/libs/scalar/inc/sclInt.h | 4 ++++ source/libs/scalar/src/scalar.c | 5 +---- source/libs/scalar/src/sclvector.c | 23 ++++++++++++----------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/source/libs/scalar/inc/sclInt.h b/source/libs/scalar/inc/sclInt.h index 34fd5dc8b0..30efb853f0 100644 --- a/source/libs/scalar/inc/sclInt.h +++ b/source/libs/scalar/inc/sclInt.h @@ -21,6 +21,8 @@ extern "C" { #include "query.h" #include "tcommon.h" #include "thash.h" +#include "querynodes.h" +#include "function.h" typedef struct SOperatorValueType { int32_t opResType; @@ -147,6 +149,8 @@ int32_t vectorCompareImpl(SScalarParam* pLeft, SScalarParam* pRight, SScalarPara int32_t _ord, int32_t optr); int32_t vectorCompare(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *pOut, int32_t _ord, int32_t optr); +bool checkOperatorRestypeIsTimestamp(int32_t ldt, int32_t rdt); + #ifdef __cplusplus } #endif diff --git a/source/libs/scalar/src/scalar.c b/source/libs/scalar/src/scalar.c index 370ee4d6e9..8e308e9db7 100644 --- a/source/libs/scalar/src/scalar.c +++ b/source/libs/scalar/src/scalar.c @@ -1693,10 +1693,7 @@ static int32_t sclGetMathOperatorResType(SOperatorNode *pOp) { return TSDB_CODE_TSC_INVALID_OPERATION; } - if ((TSDB_DATA_TYPE_TIMESTAMP == ldt.type && IS_INTEGER_TYPE(rdt.type)) || - (TSDB_DATA_TYPE_TIMESTAMP == rdt.type && IS_INTEGER_TYPE(ldt.type)) || - (TSDB_DATA_TYPE_TIMESTAMP == ldt.type && TSDB_DATA_TYPE_BOOL == rdt.type) || - (TSDB_DATA_TYPE_TIMESTAMP == rdt.type && TSDB_DATA_TYPE_BOOL == ldt.type)) { + if (checkOperatorRestypeIsTimestamp(ldt.type, rdt.type)) { pOp->node.resType.type = TSDB_DATA_TYPE_TIMESTAMP; pOp->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_TIMESTAMP].bytes; } else { diff --git a/source/libs/scalar/src/sclvector.c b/source/libs/scalar/src/sclvector.c index 0b232de70e..0e8c82d8a7 100644 --- a/source/libs/scalar/src/sclvector.c +++ b/source/libs/scalar/src/sclvector.c @@ -1261,12 +1261,7 @@ int32_t vectorMathAdd(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *p SColumnInfoData *pRightCol = NULL; SCL_ERR_JRET(vectorConvertVarToDouble(pLeft, &leftConvert, &pLeftCol)); SCL_ERR_JRET(vectorConvertVarToDouble(pRight, &rightConvert, &pRightCol)); - - if ((GET_PARAM_TYPE(pLeft) == TSDB_DATA_TYPE_TIMESTAMP && IS_INTEGER_TYPE(GET_PARAM_TYPE(pRight))) || - (GET_PARAM_TYPE(pRight) == TSDB_DATA_TYPE_TIMESTAMP && IS_INTEGER_TYPE(GET_PARAM_TYPE(pLeft))) || - (GET_PARAM_TYPE(pLeft) == TSDB_DATA_TYPE_TIMESTAMP && GET_PARAM_TYPE(pRight) == TSDB_DATA_TYPE_BOOL) || - (GET_PARAM_TYPE(pRight) == TSDB_DATA_TYPE_TIMESTAMP && - GET_PARAM_TYPE(pLeft) == TSDB_DATA_TYPE_BOOL)) { // timestamp plus duration + if(checkOperatorRestypeIsTimestamp(GET_PARAM_TYPE(pLeft), GET_PARAM_TYPE(pRight))) { // timestamp plus duration int64_t *output = (int64_t *)pOutputCol->pData; _getBigintValue_fn_t getVectorBigintValueFnLeft; _getBigintValue_fn_t getVectorBigintValueFnRight; @@ -1398,11 +1393,7 @@ int32_t vectorMathSub(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *p SCL_ERR_JRET(vectorConvertVarToDouble(pLeft, &leftConvert, &pLeftCol)); SCL_ERR_JRET(vectorConvertVarToDouble(pRight, &rightConvert, &pRightCol)); - if ((GET_PARAM_TYPE(pLeft) == TSDB_DATA_TYPE_TIMESTAMP && IS_INTEGER_TYPE(GET_PARAM_TYPE(pRight))) || - (GET_PARAM_TYPE(pRight) == TSDB_DATA_TYPE_TIMESTAMP && IS_INTEGER_TYPE(GET_PARAM_TYPE(pLeft))) || - (GET_PARAM_TYPE(pLeft) == TSDB_DATA_TYPE_TIMESTAMP && GET_PARAM_TYPE(pRight) == TSDB_DATA_TYPE_BOOL) || - (GET_PARAM_TYPE(pRight) == TSDB_DATA_TYPE_TIMESTAMP && - GET_PARAM_TYPE(pLeft) == TSDB_DATA_TYPE_BOOL)) { // timestamp minus duration + if (checkOperatorRestypeIsTimestamp(GET_PARAM_TYPE(pLeft), GET_PARAM_TYPE(pRight))) { // timestamp minus duration int64_t *output = (int64_t *)pOutputCol->pData; _getBigintValue_fn_t getVectorBigintValueFnLeft; _getBigintValue_fn_t getVectorBigintValueFnRight; @@ -2305,3 +2296,13 @@ _bin_scalar_fn_t getBinScalarOperatorFn(int32_t binFunctionId) { return NULL; } } + +bool checkOperatorRestypeIsTimestamp(int32_t lType, int32_t rType) { + if ((TSDB_DATA_TYPE_TIMESTAMP == lType && IS_INTEGER_TYPE(rType) && rType != TSDB_DATA_TYPE_UBIGINT) || + (TSDB_DATA_TYPE_TIMESTAMP == rType && IS_INTEGER_TYPE(lType) && lType != TSDB_DATA_TYPE_UBIGINT) || + (TSDB_DATA_TYPE_TIMESTAMP == lType && TSDB_DATA_TYPE_BOOL == rType) || + (TSDB_DATA_TYPE_TIMESTAMP == rType && TSDB_DATA_TYPE_BOOL == lType)) { + return true; + } + return false; +} From 7f218ab82bc54879186b2d69631508d509da48e0 Mon Sep 17 00:00:00 2001 From: factosea <285808407@qq.com> Date: Mon, 16 Dec 2024 11:01:35 +0800 Subject: [PATCH 12/17] test case --- tests/system-test/2-query/Now.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/system-test/2-query/Now.py b/tests/system-test/2-query/Now.py index 65734a5566..273bfaa9f5 100644 --- a/tests/system-test/2-query/Now.py +++ b/tests/system-test/2-query/Now.py @@ -68,13 +68,13 @@ class TDTestCase: for symbol in self.symbol: for param in self.error_values: tdSql.error(f'select now() {symbol}{param} from {tbname}') - for param in self.test_values: - tdSql.query(f'select now() {symbol}{param} from {tbname}') - tdSql.query(f'select 1 {symbol}{param} from {tbname}') tdSql.query(f'select now(){symbol}null from {tbname}') self.tbtype_check(tb_type) for i in range(len(self.values_list)): tdSql.checkData(i,0,None) + for param in self.test_values: + tdSql.query(f'select now() {symbol}{param} from {tbname}') + tdSql.query(f'select 1 {symbol}{param} from {tbname}') def now_check_ntb(self): for time_unit in self.db_percision: From 07aea5e350e7a2ee35f8c5728b1227cf9da4805e Mon Sep 17 00:00:00 2001 From: factosea <285808407@qq.com> Date: Mon, 16 Dec 2024 14:11:27 +0800 Subject: [PATCH 13/17] fix: test case --- tests/parallel_test/cases.task | 4 +++ tests/system-test/2-query/Now.py | 2 +- tests/system-test/2-query/operator.py | 44 +++++++++++++-------------- 3 files changed, 27 insertions(+), 23 deletions(-) diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index 879d93ab3a..f6d2972805 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -1071,6 +1071,10 @@ ,,n,system-test,python3 ./test.py -f 5-taos-tools/taosbenchmark/insertMix.py -N 3 ,,n,system-test,python3 ./test.py -f 5-taos-tools/taosbenchmark/stt.py -N 3 ,,n,system-test,python3 ./test.py -f eco-system/meta/database/keep_time_offset.py +,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/operator.py +,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/operator.py -Q 2 +,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/operator.py -Q 3 +,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/operator.py -Q 4 #tsim test ,,y,script,./test.sh -f tsim/query/timeline.sim diff --git a/tests/system-test/2-query/Now.py b/tests/system-test/2-query/Now.py index 273bfaa9f5..9e7d240c0a 100644 --- a/tests/system-test/2-query/Now.py +++ b/tests/system-test/2-query/Now.py @@ -43,7 +43,7 @@ class TDTestCase: self.symbol = ['+','-','*','/'] self.error_values = ['abc','"abc"','!@','today()'] self.db_percision = ['ms','us','ns'] - self.test_values = [1.5, 10, 9223372036854775807, -9223372036854775808] + self.test_values = [1.5, 10] def tbtype_check(self,tb_type): if tb_type == 'normal table' or tb_type == 'child table': tdSql.checkRows(len(self.values_list)) diff --git a/tests/system-test/2-query/operator.py b/tests/system-test/2-query/operator.py index ad9387deb5..2e2f0af802 100644 --- a/tests/system-test/2-query/operator.py +++ b/tests/system-test/2-query/operator.py @@ -102,35 +102,35 @@ class TDTestCase: tdSql.execute(f"CREATE TABLE {self.dbname}.t1( time TIMESTAMP, c0 INT);") tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c0) VALUES (1641024000000, 1);") - tdSql.query(f"SELECT time, c0 FROM t1 WHERE (time - c0) > 0;") + tdSql.query(f"SELECT time, c0 FROM {self.dbname}.t1 WHERE (time - c0) > 0;") tdSql.checkRows(1) - tdSql.query(f"SELECT time, c0 FROM t1 WHERE (time + c0) > 0;") + tdSql.query(f"SELECT time, c0 FROM {self.dbname}.t1 WHERE (time + c0) > 0;") tdSql.checkRows(1) - tdSql.query(f"SELECT time, c0 FROM t1 WHERE (-(- c0)) > 0;") + tdSql.query(f"SELECT time, c0 FROM {self.dbname}.t1 WHERE (-(- c0)) > 0;") tdSql.checkRows(1) - tdSql.query(f"SELECT time, c0 FROM t1 WHERE -(- c0) > 0;") + tdSql.query(f"SELECT time, c0 FROM {self.dbname}.t1 WHERE -(- c0) > 0;") tdSql.checkRows(1) - tdSql.query(f"SELECT time, c0 FROM t1 WHERE -(- c0) < 0;") + tdSql.query(f"SELECT time, c0 FROM {self.dbname}.t1 WHERE -(- c0) < 0;") tdSql.checkRows(0) - tdSql.query(f"SELECT time, c0 FROM t1 WHERE -(- c0) = 0;") + tdSql.query(f"SELECT time, c0 FROM {self.dbname}.t1 WHERE -(- c0) = 0;") tdSql.checkRows(0) - tdSql.query(f"SELECT time, c0 FROM t1 WHERE (- c0) > 0;") + tdSql.query(f"SELECT time, c0 FROM {self.dbname}.t1 WHERE (- c0) > 0;") tdSql.checkRows(0) - tdSql.query(f"SELECT time, c0 FROM t1 WHERE (- c0) < 0;") + tdSql.query(f"SELECT time, c0 FROM {self.dbname}.t1 WHERE (- c0) < 0;") tdSql.checkRows(1) - tdSql.query(f"SELECT time, c0 FROM t1 WHERE (time + (- c0)) > 0;") + tdSql.query(f"SELECT time, c0 FROM {self.dbname}.t1 WHERE (time + (- c0)) > 0;") tdSql.checkRows(1) - tdSql.query(f"SELECT time, c0 FROM t1 WHERE (time + (- c0)) > 0;") + tdSql.query(f"SELECT time, c0 FROM {self.dbname}.t1 WHERE (time + (- c0)) > 0;") tdSql.checkRows(1) - tdSql.query(f"SELECT time, c0 FROM t1 WHERE (time - (- (- c0)) ) > 0;") + tdSql.query(f"SELECT time, c0 FROM {self.dbname}.t1 WHERE (time - (- (- c0)) ) > 0;") tdSql.checkRows(1) - tdSql.query(f"SELECT time, c0 FROM t1 WHERE (time + (-(- c0))) > 0;") + tdSql.query(f"SELECT time, c0 FROM {self.dbname}.t1 WHERE (time + (-(- c0))) > 0;") tdSql.checkRows(1) def ts5758(self): @@ -195,27 +195,27 @@ class TDTestCase: tdSql.execute(f"CREATE TABLE {self.dbname}.t1( time TIMESTAMP, c1 BIGINT);") tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c1) VALUES (1641024000000, 0);") - tdSql.query(f"SELECT c1 FROM t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001)") + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001)") tdSql.checkRows(1) - tdSql.query(f"SELECT c1 FROM t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) OR (1 < 2)") + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) OR (1 < 2)") tdSql.checkRows(1) - tdSql.query(f"SELECT c1 FROM t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) OR (3 < 2)") + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) OR (3 < 2)") tdSql.checkRows(1) - tdSql.query(f"SELECT c1 FROM t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) and (1 < 2)") + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) and (1 < 2)") tdSql.checkRows(1) - tdSql.query(f"SELECT c1 FROM t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) OR (1 > 2)") + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) OR (1 > 2)") tdSql.checkRows(1) - tdSql.query(f"SELECT c1 FROM t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) and (1 > 2)") + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) and (1 > 2)") tdSql.checkRows(0) tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c1) VALUES (1641024000001, 1);") tdSql.execute(f"INSERT INTO {self.dbname}.t1(time, c1) VALUES (1641024000002, 2);") - tdSql.query(f"SELECT c1 FROM t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) OR (1 < 2)") + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) OR (1 < 2)") tdSql.checkRows(3) - tdSql.query(f"SELECT c1 FROM t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) OR (1 > 2)") + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) OR (1 > 2)") tdSql.checkRows(2) - tdSql.query(f"SELECT c1 FROM t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) and (1 < 2)") + tdSql.query(f"SELECT c1 FROM {self.dbname}.t1 WHERE (time BETWEEN 1641024000000 AND 1641024000001) and (1 < 2)") tdSql.checkRows(2) def operOnTime(self): @@ -308,7 +308,7 @@ class TDTestCase: tdSql.query(f"SELECT sum(ts * c1), sum(ts*c2) from {self.dbname}.t2") tdSql.checkData(0, 0, 4923072000005) tdSql.checkData(0, 1, 4923072000005) - tdSql.query(f"SELECT ts / c1, ts/c2 from t2 order by {self.dbname}.ts") + tdSql.query(f"SELECT ts / c1, ts/c2 from {self.dbname}.t2 order by ts") tdSql.checkData(0, 0, 1641024000001) tdSql.checkData(0, 1, 1641024000001) tdSql.checkData(1, 0, 820512000001) From b195b7fa124a155cea0949d7f1ef7ffb6fdb1520 Mon Sep 17 00:00:00 2001 From: factosea <285808407@qq.com> Date: Mon, 16 Dec 2024 16:51:45 +0800 Subject: [PATCH 14/17] fix: multi/div with timestamp type --- source/libs/scalar/inc/sclInt.h | 2 +- source/libs/scalar/src/scalar.c | 2 +- source/libs/scalar/src/sclvector.c | 10 +++++++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/source/libs/scalar/inc/sclInt.h b/source/libs/scalar/inc/sclInt.h index 30efb853f0..b04e26ac5d 100644 --- a/source/libs/scalar/inc/sclInt.h +++ b/source/libs/scalar/inc/sclInt.h @@ -149,7 +149,7 @@ int32_t vectorCompareImpl(SScalarParam* pLeft, SScalarParam* pRight, SScalarPara int32_t _ord, int32_t optr); int32_t vectorCompare(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *pOut, int32_t _ord, int32_t optr); -bool checkOperatorRestypeIsTimestamp(int32_t ldt, int32_t rdt); +bool checkOperatorRestypeIsTimestamp(EOperatorType opType, int32_t ldt, int32_t rdt); #ifdef __cplusplus } diff --git a/source/libs/scalar/src/scalar.c b/source/libs/scalar/src/scalar.c index 8e308e9db7..5d89df1540 100644 --- a/source/libs/scalar/src/scalar.c +++ b/source/libs/scalar/src/scalar.c @@ -1693,7 +1693,7 @@ static int32_t sclGetMathOperatorResType(SOperatorNode *pOp) { return TSDB_CODE_TSC_INVALID_OPERATION; } - if (checkOperatorRestypeIsTimestamp(ldt.type, rdt.type)) { + if (checkOperatorRestypeIsTimestamp(pOp->opType, ldt.type, rdt.type)) { pOp->node.resType.type = TSDB_DATA_TYPE_TIMESTAMP; pOp->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_TIMESTAMP].bytes; } else { diff --git a/source/libs/scalar/src/sclvector.c b/source/libs/scalar/src/sclvector.c index 0e8c82d8a7..06830c780f 100644 --- a/source/libs/scalar/src/sclvector.c +++ b/source/libs/scalar/src/sclvector.c @@ -24,6 +24,7 @@ #include "tcompare.h" #include "tdatablock.h" #include "tdataformat.h" +#include "tdef.h" #include "ttime.h" #include "ttypes.h" #include "geosWrapper.h" @@ -1261,7 +1262,7 @@ int32_t vectorMathAdd(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *p SColumnInfoData *pRightCol = NULL; SCL_ERR_JRET(vectorConvertVarToDouble(pLeft, &leftConvert, &pLeftCol)); SCL_ERR_JRET(vectorConvertVarToDouble(pRight, &rightConvert, &pRightCol)); - if(checkOperatorRestypeIsTimestamp(GET_PARAM_TYPE(pLeft), GET_PARAM_TYPE(pRight))) { // timestamp plus duration + if(checkOperatorRestypeIsTimestamp(OP_TYPE_ADD, GET_PARAM_TYPE(pLeft), GET_PARAM_TYPE(pRight))) { // timestamp plus duration int64_t *output = (int64_t *)pOutputCol->pData; _getBigintValue_fn_t getVectorBigintValueFnLeft; _getBigintValue_fn_t getVectorBigintValueFnRight; @@ -1393,7 +1394,7 @@ int32_t vectorMathSub(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *p SCL_ERR_JRET(vectorConvertVarToDouble(pLeft, &leftConvert, &pLeftCol)); SCL_ERR_JRET(vectorConvertVarToDouble(pRight, &rightConvert, &pRightCol)); - if (checkOperatorRestypeIsTimestamp(GET_PARAM_TYPE(pLeft), GET_PARAM_TYPE(pRight))) { // timestamp minus duration + if (checkOperatorRestypeIsTimestamp(OP_TYPE_SUB, GET_PARAM_TYPE(pLeft), GET_PARAM_TYPE(pRight))) { // timestamp minus duration int64_t *output = (int64_t *)pOutputCol->pData; _getBigintValue_fn_t getVectorBigintValueFnLeft; _getBigintValue_fn_t getVectorBigintValueFnRight; @@ -2297,7 +2298,10 @@ _bin_scalar_fn_t getBinScalarOperatorFn(int32_t binFunctionId) { } } -bool checkOperatorRestypeIsTimestamp(int32_t lType, int32_t rType) { +bool checkOperatorRestypeIsTimestamp(EOperatorType opType, int32_t lType, int32_t rType) { + if (opType != OP_TYPE_ADD && opType != OP_TYPE_SUB && opType != OP_TYPE_MINUS) { + return false; + } if ((TSDB_DATA_TYPE_TIMESTAMP == lType && IS_INTEGER_TYPE(rType) && rType != TSDB_DATA_TYPE_UBIGINT) || (TSDB_DATA_TYPE_TIMESTAMP == rType && IS_INTEGER_TYPE(lType) && lType != TSDB_DATA_TYPE_UBIGINT) || (TSDB_DATA_TYPE_TIMESTAMP == lType && TSDB_DATA_TYPE_BOOL == rType) || From ae7f69c7807d91d1c060a5d062b4d0d1630e082e Mon Sep 17 00:00:00 2001 From: factosea <285808407@qq.com> Date: Tue, 17 Dec 2024 09:02:06 +0800 Subject: [PATCH 15/17] fix: oper param type --- source/libs/scalar/src/filter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/libs/scalar/src/filter.c b/source/libs/scalar/src/filter.c index 276604f58c..c9e6756d07 100644 --- a/source/libs/scalar/src/filter.c +++ b/source/libs/scalar/src/filter.c @@ -5100,7 +5100,7 @@ static int32_t hasValidInOper(SArray *sclInOper, SArray *colRangeList, bool* has return TSDB_CODE_SUCCESS; } } else { - if (startPt->val.d != endPt->val.d && (valDatum.i >= startPt->val.i || valDatum.i <= endPt->val.i)) { + if (startPt->val.i != endPt->val.i && (valDatum.i >= startPt->val.i || valDatum.i <= endPt->val.i)) { *has = true; return TSDB_CODE_SUCCESS; } From bab22150948cb97b45ebdcfc138344a9464f445b Mon Sep 17 00:00:00 2001 From: factosea <285808407@qq.com> Date: Tue, 17 Dec 2024 14:47:09 +0800 Subject: [PATCH 16/17] enh: time range --- source/libs/scalar/src/filter.c | 101 ++++---------------------------- 1 file changed, 13 insertions(+), 88 deletions(-) diff --git a/source/libs/scalar/src/filter.c b/source/libs/scalar/src/filter.c index c9e6756d07..af7e5fb771 100644 --- a/source/libs/scalar/src/filter.c +++ b/source/libs/scalar/src/filter.c @@ -3859,6 +3859,11 @@ int32_t fltInitFromNode(SNode *tree, SFilterInfo *info, uint32_t options) { if (tctx.ignore) { FILTER_SET_FLAG(info->status, FI_STATUS_EMPTY); } + if (FILTER_EMPTY_RES(info)) { + info->func = filterExecuteImplEmpty; + taosArrayDestroyEx(group, filterFreeGroup); + return TSDB_CODE_SUCCESS; + } code = filterConvertGroupFromArray(info, group); if (TSDB_CODE_SUCCESS != code) { taosArrayDestroyEx(group, filterFreeGroup); @@ -5049,122 +5054,42 @@ int32_t fltSclBuildRangePoints(SFltSclOperator *oper, SArray *points) { return TSDB_CODE_SUCCESS; } -static int32_t fltInOpertoArray(SArray **sclInOper, SFltSclOperator *pInOper) { - if (*sclInOper == NULL) { - *sclInOper = taosArrayInit(4, sizeof(SFltSclOperator *)); - if (NULL == *sclInOper) { - FLT_ERR_RET(terrno); - } - } - if (NULL == taosArrayPush(*sclInOper, &pInOper)) { - FLT_ERR_RET(terrno); - } - return TSDB_CODE_SUCCESS; -} - -static int32_t hasValidInOper(SArray *sclInOper, SArray *colRangeList, bool* has) { - SFltSclOperator **ppSclOper = NULL; - *has = false; - for (int32_t i = 0; i < taosArrayGetSize(sclInOper); ++i) { - ppSclOper = taosArrayGet(sclInOper, i); - if (NULL == ppSclOper) { - return TSDB_CODE_OUT_OF_RANGE; - } - if(*ppSclOper == NULL) { - qError("func: hasValidInOper, invalid in operator"); - return TSDB_CODE_OUT_OF_RANGE; - } - SFltSclColumnRange *colRange = NULL; - SFltSclOperator * pSclOper = *ppSclOper; - for (int32_t i = 0; i < taosArrayGetSize(colRangeList); ++i) { - colRange = taosArrayGet(colRangeList, i); - if (NULL == colRange) { - return TSDB_CODE_OUT_OF_RANGE; - } - if (nodesEqualNode((SNode *)colRange->colNode, (SNode *)pSclOper->colNode)) { - SFltSclPoint *startPt = taosArrayGet(colRange->points, 0); - SFltSclPoint *endPt = taosArrayGet(colRange->points, 1); - if (NULL == startPt || NULL == endPt) { - return TSDB_CODE_OUT_OF_RANGE; - } - SNodeListNode *listNode = (SNodeListNode *)pSclOper->valNode; - SListCell *cell = listNode->pNodeList->pHead; - for (int32_t i = 0; i < listNode->pNodeList->length; ++i) { - SValueNode *valueNode = (SValueNode *)cell->pNode; - SFltSclDatum valDatum; - FLT_ERR_RET(fltSclBuildDatumFromValueNode(&valDatum, valueNode)); - if (valueNode->node.resType.type == TSDB_DATA_TYPE_FLOAT || - valueNode->node.resType.type == TSDB_DATA_TYPE_DOUBLE) { - if (startPt->val.d != endPt->val.d && (valDatum.d >= startPt->val.d || valDatum.d <= endPt->val.d)) { - *has = true; - return TSDB_CODE_SUCCESS; - } - } else { - if (startPt->val.i != endPt->val.i && (valDatum.i >= startPt->val.i || valDatum.i <= endPt->val.i)) { - *has = true; - return TSDB_CODE_SUCCESS; - } - } - cell = cell->pNext; - } - } - } - } - return TSDB_CODE_SUCCESS; -} - // TODO: process DNF composed of CNF static int32_t fltSclProcessCNF(SFilterInfo *pInfo, SArray *sclOpListCNF, SArray *colRangeList) { - int32_t code = TSDB_CODE_SUCCESS; - pInfo->isStrict = true; - SArray *sclInOper = NULL; size_t sz = taosArrayGetSize(sclOpListCNF); for (int32_t i = 0; i < sz; ++i) { SFltSclOperator *sclOper = taosArrayGet(sclOpListCNF, i); if (NULL == sclOper) { - FLT_ERR_JRET(TSDB_CODE_OUT_OF_RANGE); + FLT_ERR_RET(TSDB_CODE_OUT_OF_RANGE); } SFltSclColumnRange *colRange = NULL; - FLT_ERR_JRET(fltSclGetOrCreateColumnRange(sclOper->colNode, colRangeList, &colRange)); + FLT_ERR_RET(fltSclGetOrCreateColumnRange(sclOper->colNode, colRangeList, &colRange)); SArray *points = taosArrayInit(4, sizeof(SFltSclPoint)); if (NULL == points) { - FLT_ERR_JRET(terrno); + FLT_ERR_RET(terrno); } - FLT_ERR_JRET(fltSclBuildRangePoints(sclOper, points)); + FLT_ERR_RET(fltSclBuildRangePoints(sclOper, points)); if (taosArrayGetSize(colRange->points) != 0) { SArray *merged = taosArrayInit(4, sizeof(SFltSclPoint)); if (NULL == merged) { - FLT_ERR_JRET(terrno); + FLT_ERR_RET(terrno); } - FLT_ERR_JRET(fltSclIntersect(colRange->points, points, merged)); + FLT_ERR_RET(fltSclIntersect(colRange->points, points, merged)); taosArrayDestroy(colRange->points); taosArrayDestroy(points); colRange->points = merged; if(merged->size == 0) { - goto _return; + return TSDB_CODE_SUCCESS; } } else { taosArrayDestroy(colRange->points); colRange->points = points; } if (sclOper->type == OP_TYPE_IN) { - code = fltInOpertoArray(&sclInOper, sclOper); - FLT_ERR_JRET(code); + pInfo->isStrict = false; } } - bool hasInOper = false; - code = hasValidInOper(sclInOper, colRangeList, &hasInOper); - if (code != TSDB_CODE_SUCCESS) { - goto _return; - } - if (hasInOper) { - pInfo->isStrict = false; - } -_return: - if (sclInOper) { - taosArrayDestroy(sclInOper); - } return TSDB_CODE_SUCCESS; } From 944470cf99356395d465764979e20a00bea501d8 Mon Sep 17 00:00:00 2001 From: factosea <285808407@qq.com> Date: Tue, 17 Dec 2024 14:48:45 +0800 Subject: [PATCH 17/17] unused code --- source/libs/scalar/src/filter.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/source/libs/scalar/src/filter.c b/source/libs/scalar/src/filter.c index af7e5fb771..a149384163 100644 --- a/source/libs/scalar/src/filter.c +++ b/source/libs/scalar/src/filter.c @@ -4557,10 +4557,6 @@ static int32_t fltSclGetTimeStampDatum(SFltSclPoint *point, SFltSclDatum *d) { return TSDB_CODE_SUCCESS; } -typedef struct SRewriteGetInOperContext { - bool hasInOper; -} SRewriteGetInOperContext; - int32_t filterGetTimeRange(SNode *pNode, STimeWindow *win, bool *isStrict) { SFilterInfo *info = NULL; int32_t code = 0;