From 8faa80d6a7176553ac52247aa6c6be5953aedcdc Mon Sep 17 00:00:00 2001 From: wpan Date: Tue, 13 Jul 2021 08:33:39 +0800 Subject: [PATCH] fix range issue --- src/query/inc/qFilter.h | 6 +- src/query/src/qFilter.c | 115 ++++++++----- tests/script/general/parser/condition.sim | 200 ++++++++++++++++++++++ 3 files changed, 275 insertions(+), 46 deletions(-) diff --git a/src/query/inc/qFilter.h b/src/query/inc/qFilter.h index 092d244e24..1a618c62fa 100644 --- a/src/query/inc/qFilter.h +++ b/src/query/inc/qFilter.h @@ -154,8 +154,10 @@ typedef struct SFilterInfo { #define MR_EMPTY_RES(ctx) (ctx->rs == NULL) -#define SET_OPTR(o) do {if (o == TSDB_RELATION_ISNULL) { isnull = true; } else if (o == TSDB_RELATION_NOTNULL) { notnull = true; } } while (0) -#define CHK_OPTR() (isnull == true && notnull == true) +#define SET_AND_OPTR(o) do {if (o == TSDB_RELATION_ISNULL) { isnull = true; } else if (o == TSDB_RELATION_NOTNULL) { if (!isrange) { notnull = true; } } else { isrange = true; notnull = false; } } while (0) +#define SET_OR_OPTR(o) do {if (o == TSDB_RELATION_ISNULL) { isnull = true; } else if (o == TSDB_RELATION_NOTNULL) { notnull = true; } } while (0) +#define CHK_OR_OPTR() (isnull == true && notnull == true) +#define CHK_AND_OPTR() (isnull == true && ((notnull == true) || (isrange == true))) #define FILTER_GET_FLAG(st, f) (st & f) diff --git a/src/query/src/qFilter.c b/src/query/src/qFilter.c index aeab5c995b..95bbdc5677 100644 --- a/src/query/src/qFilter.c +++ b/src/query/src/qFilter.c @@ -199,13 +199,13 @@ int32_t filterAddMergeRangeImpl(void* h, SFilterRange* ra, int32_t optr) { cr = ctx->pCompareFunc(&ra->s, &r->ra.s); if (FILTER_GREATER(cr, ra->sflag, r->ra.sflag)) { SIMPLE_COPY_VALUES((char *)&r->ra.s, &ra->s); - cr == 0 ? (r->ra.sflag = 0) : (r->ra.sflag = ra->sflag); + cr == 0 ? (r->ra.sflag |= ra->sflag) : (r->ra.sflag = ra->sflag); } cr = ctx->pCompareFunc(&r->ra.e, &ra->e); if (FILTER_GREATER(cr, r->ra.eflag, ra->eflag)) { SIMPLE_COPY_VALUES((char *)&r->ra.e, &ra->e); - cr == 0 ? (r->ra.eflag = 0) : (r->ra.eflag = ra->eflag); + cr == 0 ? (r->ra.eflag |= ra->eflag) : (r->ra.eflag = ra->eflag); break; } @@ -677,7 +677,7 @@ int32_t filterAddGroupUnitFromRange(SFilterInfo *dst, SFilterInfo *src, SFilterC } if (g->unitNum > 0) { - taosArrayPush(res, g); + taosArrayPush(res, g); } } @@ -966,9 +966,9 @@ int32_t filterAddUnitRange(SFilterInfo *info, SFilterUnit* u, SFilterRMCtx *ctx, int32_t filterProcessUnitsInOneGroup(SFilterInfo *info, SFilterGroup* g, uint16_t id1, uint16_t id2, SArray* res, uint16_t *removedNum) { - bool isnull = false, notnull = false; + bool isnull = false, notnull = false, isrange = false; int32_t num = 0; - + SFilterRMCtx *cur = NULL; SFilterUnit* u1 = FILTER_GROUP_UNIT(info, g, id1); SFilterUnit* u2 = FILTER_GROUP_UNIT(info, g, id2); uint8_t optr1 = FILTER_UNIT_OPTR(u1); @@ -976,12 +976,13 @@ int32_t filterProcessUnitsInOneGroup(SFilterInfo *info, SFilterGroup* g, uint16_ uint16_t cidx = FILTER_UNIT_COL_IDX(u1); int32_t type = FILTER_UNIT_DATA_TYPE(u1); - SFilterRMCtx *cur = filterInitMergeRange(type, 0); - SET_OPTR(optr1); - SET_OPTR(optr2); + SET_AND_OPTR(optr1); + SET_AND_OPTR(optr2); - CHK_JMP(CHK_OPTR()); + CHK_JMP(CHK_AND_OPTR()); + + cur = filterInitMergeRange(type, 0); if (!FILTER_NO_MERGE_OPTR(optr1)) { filterAddUnitRange(info, u1, cur, TSDB_RELATION_AND); @@ -1001,8 +1002,8 @@ int32_t filterProcessUnitsInOneGroup(SFilterInfo *info, SFilterGroup* g, uint16_ ++(*removedNum); optr2 = FILTER_UNIT_OPTR(u); - SET_OPTR(optr2); - CHK_JMP(CHK_OPTR()); + SET_AND_OPTR(optr2); + CHK_JMP(CHK_AND_OPTR()); if (!FILTER_NO_MERGE_OPTR(optr2)) { filterAddUnitRange(info, u, cur, TSDB_RELATION_AND); @@ -1053,17 +1054,18 @@ int32_t filterProcessUnits(SFilterInfo *info, SFilterGroupCtx*** res) { SFilterGroupCtx *gctx = NULL; SArray *colRange = NULL; bool gresUsed = false; + bool colInit = false; uint16_t removedNum = 0; for (uint16_t i = 0; i < info->groupNum; ++i) { SFilterGroup* g = info->groups + i; - if (col == NULL) { - col = calloc(info->fields[FLD_TYPE_COLUMN].num, sizeof(int32_t)); - } else { - memset(col, 0, info->fields[FLD_TYPE_COLUMN].num * sizeof(int32_t)); + if (g->unitNum <= 1) { + continue; } + gresUsed = false; + colInit = false; removedNum = 0; @@ -1073,6 +1075,16 @@ int32_t filterProcessUnits(SFilterInfo *info, SFilterGroupCtx*** res) { if (FILTER_NO_MERGE_DATA_TYPE(type)) { continue; } + + if (colInit == false) { + if (col == NULL) { + col = calloc(info->fields[FLD_TYPE_COLUMN].num, sizeof(int32_t)); + } else { + memset(col, 0, info->fields[FLD_TYPE_COLUMN].num * sizeof(int32_t)); + } + + colInit = true; + } uint16_t cidx = FILTER_UNIT_COL_IDX(u); @@ -1171,7 +1183,7 @@ int32_t filterProcessGroupsSameColumn(SFilterInfo *info, uint16_t id1, uint16_t if (cra->notNull) { notnull = true; - CHK_JMP(CHK_OPTR()); + CHK_JMP(CHK_OR_OPTR()); } cidx2 = cra->idx; @@ -1202,21 +1214,21 @@ int32_t filterProcessGroupsSameColumn(SFilterInfo *info, uint16_t id1, uint16_t filterAddMergeRange(cur, &cra->ra, TSDB_RELATION_OR); if (MR_EMPTY_RES(cur)) { notnull = true; - CHK_JMP(CHK_OPTR()); + CHK_JMP(CHK_OR_OPTR()); } continue; } optr = FILTER_UNIT_OPTR(u1); - SET_OPTR(optr); - CHK_JMP(CHK_OPTR()); + SET_OR_OPTR(optr); + CHK_JMP(CHK_OR_OPTR()); if (!FILTER_NO_MERGE_OPTR(optr) && notnull == false) { filterAddUnitRange(info, u1, cur, TSDB_RELATION_OR); if (MR_EMPTY_RES(cur)) { notnull = true; - CHK_JMP(CHK_OPTR()); + CHK_JMP(CHK_OR_OPTR()); } } } @@ -1234,36 +1246,41 @@ int32_t filterProcessGroupsSameColumn(SFilterInfo *info, uint16_t id1, uint16_t if (!notnull) { filterGetMergeRangeNum(cur, &num); - if (num > 1) { - ra = calloc(num, sizeof(*ra)); - } else { - assert(num == 1); - ra = &ncra.ra; - } + if (num > 0) { + if (num > 1) { + ra = calloc(num, sizeof(*ra)); + } else { + ra = &ncra.ra; + } - filterGetMergeRangeRes(cur, ra); + filterGetMergeRangeRes(cur, ra); - SFilterRange *tra = ra; - for (int32_t i = 0; i < num; ++i) { - filterPostProcessRange(cur, tra, &ncra.notNull); - assert(ncra.notNull == false); - ++tra; - } - - if (num > 1) { + SFilterRange *tra = ra; for (int32_t i = 0; i < num; ++i) { - FILTER_COPY_RA(&ncra.ra, ra); - - taosArrayPush(res, &ncra); + filterPostProcessRange(cur, tra, &ncra.notNull); + assert(ncra.notNull == false); + ++tra; + } - ++ra; + if (num > 1) { + for (int32_t i = 0; i < num; ++i) { + FILTER_COPY_RA(&ncra.ra, ra); + + taosArrayPush(res, &ncra); + + ++ra; + } + } else { + taosArrayPush(res, &ncra); } } else { - FILTER_COPY_RA(&ncra.ra, ra); - + ncra.ra.sflag = RA_NULL; + ncra.ra.eflag = RA_NULL; taosArrayPush(res, &ncra); } } else { + ncra.ra.sflag = RA_NULL; + ncra.ra.eflag = RA_NULL; taosArrayPush(res, &ncra); } @@ -1286,11 +1303,17 @@ int32_t filterProcessGroups(SFilterInfo *info, SFilterGroupCtx** unitRes, SFilte int32_t *col = NULL; uint16_t cidx; uint16_t removedNum = 0; + bool merged = false; SArray *colRange = NULL; for (uint16_t i = 0; i < info->groupNum; ++i) { SFilterGroup* g = info->groups + i; - uint16_t unitNum = (unitRes && unitRes[i]) ? unitRes[i]->num : g->unitNum; + uint16_t unitNum = g->unitNum; + + if (unitRes && unitRes[i]) { + unitNum = unitRes[i]->num; + merged = true; + } if (unitNum == 0) { ++removedNum; @@ -1317,7 +1340,11 @@ int32_t filterProcessGroups(SFilterInfo *info, SFilterGroupCtx** unitRes, SFilte } if (col == NULL) { - col = calloc(info->fields[FLD_TYPE_COLUMN].num, sizeof(int32_t)); + if (i < (info->groupNum - 1)) { + col = calloc(info->fields[FLD_TYPE_COLUMN].num, sizeof(int32_t)); + } else { + break; + } } if (col[cidx] == 0) { @@ -1351,7 +1378,7 @@ int32_t filterProcessGroups(SFilterInfo *info, SFilterGroupCtx** unitRes, SFilte goto _err_return; } - if (colRange || removedNum > 0) { + if (colRange || removedNum > 0 || merged) { groupRes->num = num; groupRes->col = col; groupRes->colRange = colRange; diff --git a/tests/script/general/parser/condition.sim b/tests/script/general/parser/condition.sim index 52918a8658..b6f0e76db1 100644 --- a/tests/script/general/parser/condition.sim +++ b/tests/script/general/parser/condition.sim @@ -1520,6 +1520,206 @@ if $data20 != @21-05-05 18:19:10.000@ then return -1 endi +sql select * from stb1 where c1 is null and c1 is not null; +if $rows != 0 then + return -1 +endi + +sql select * from stb1 where c1 is null or c1 is not null; +if $rows != 29 then + return -1 +endi +sql select * from stb1 where c1 is null or c1 > 20 or c1 < 25; +if $rows != 29 then + return -1 +endi +sql select * from stb1 where (c1 > 20 or c1 < 25) and c1 is null; +if $rows != 0 then + return -1 +endi + +sql select * from stb1 where (c1 > 20 or c1 < 25) and (c1 > 62 or c1 < 3); +if $rows != 4 then + return -1 +endi +if $data00 != @21-05-05 18:19:00.000@ then + return -1 +endi +if $data10 != @21-05-05 18:19:01.000@ then + return -1 +endi +if $data20 != @21-05-05 18:19:26.000@ then + return -1 +endi +if $data30 != @21-05-05 18:19:27.000@ then + return -1 +endi + +sql select * from stb1 where c1 > 11 and c1 != 11 and c1 != 14 and c1 < 14; +if $rows != 2 then + return -1 +endi +if $data00 != @21-05-05 18:19:05.000@ then + return -1 +endi +if $data10 != @21-05-05 18:19:06.000@ then + return -1 +endi +sql select * from stb1 where (c1 > 60 or c1 < 4 or c1 > 10 and c1 < 20 and c1 != 13 or c1 < 2 or c1 > 50) +if $rows != 14 then + return -1 +endi +if $data00 != @21-05-05 18:19:00.000@ then + return -1 +endi +if $data10 != @21-05-05 18:19:01.000@ then + return -1 +endi +if $data20 != @21-05-05 18:19:02.000@ then + return -1 +endi +if $data30 != @21-05-05 18:19:04.000@ then + return -1 +endi + +sql select * from stb1 where c1 > 62 or c1 >= 62; +if $rows != 3 then + return -1 +endi +if $data00 != @21-05-05 18:19:25.000@ then + return -1 +endi +if $data10 != @21-05-05 18:19:26.000@ then + return -1 +endi +if $data20 != @21-05-05 18:19:27.000@ then + return -1 +endi + +sql select * from stb1 where c1 > 62 and c1 >= 62; +if $rows != 2 then + return -1 +endi +if $data00 != @21-05-05 18:19:26.000@ then + return -1 +endi +if $data10 != @21-05-05 18:19:27.000@ then + return -1 +endi + +sql select * from stb1 where c1 >= 62 and c1 != 62; +if $rows != 2 then + return -1 +endi +if $data00 != @21-05-05 18:19:26.000@ then + return -1 +endi +if $data10 != @21-05-05 18:19:27.000@ then + return -1 +endi + +sql select * from stb1 where c1 >= 62 or c1 != 62; +if $rows != 28 then + return -1 +endi + +sql select * from stb1 where c1 >= 62 and c1 = 62; +if $rows != 1 then + return -1 +endi +if $data00 != @21-05-05 18:19:25.000@ then + return -1 +endi + +sql select * from stb1 where c1 > 62 and c1 != 62; +if $rows != 2 then + return -1 +endi +if $data00 != @21-05-05 18:19:26.000@ then + return -1 +endi +if $data10 != @21-05-05 18:19:27.000@ then + return -1 +endi + +sql select * from stb1 where c1 > 62 and c1 = 62; +if $rows != 0 then + return -1 +endi + +sql select * from stb1 where c1 is not null and c1 is not null; +if $rows != 28 then + return -1 +endi + +sql select * from stb1 where c1 is not null or c1 is not null; +if $rows != 28 then + return -1 +endi + +sql select * from stb1 where c1 is null and c1 is null; +if $rows != 1 then + return -1 +endi +if $data00 != @21-05-05 18:19:28.000@ then + return -1 +endi + +sql select * from stb1 where c1 is null or c1 is null; +if $rows != 1 then + return -1 +endi +if $data00 != @21-05-05 18:19:28.000@ then + return -1 +endi + +sql select * from stb1 where c2 > 3 and c2 < 3; +if $rows != 0 then + return -1 +endi + +sql select * from stb1 where c2 = 3; +if $rows != 1 then + return -1 +endi +if $data00 != @21-05-05 18:19:02.000@ then + return -1 +endi + +sql select * from stb1 where c2 > 3 and c2 <= 3; +if $rows != 0 then + return -1 +endi + +sql select * from stb1 where c2 >= 3 and c2 <= 3; +if $data00 != @21-05-05 18:19:02.000@ then + return -1 +endi + +sql select * from stb1 where (c1 > 60 or c1 < 4 or c1 > 10 and c1 < 20 and c1 != 13 or c1 < 2 or c1 > 50) and (c1 != 51 and c1 <= 54 and c1 != 54 and c1 >=1 and c1 != 1) and (c1 >= 11 and c1 <=52 and c1 != 52 and c1 != 11); +if $rows != 2 then + return -1 +endi +if $data00 != @21-05-05 18:19:05.000@ then + return -1 +endi +if $data10 != @21-05-05 18:19:07.000@ then + return -1 +endi + +sql select * from stb1 where c1 > 1 and c1 is not null and c1 < 5; +if $rows != 3 then + return -1 +endi +if $data00 != @21-05-05 18:19:01.000@ then + return -1 +endi +if $data10 != @21-05-05 18:19:02.000@ then + return -1 +endi +if $data20 != @21-05-05 18:19:03.000@ then + return -1 +endi print "ts test"