diff --git a/src/common/inc/texpr.h b/src/common/inc/texpr.h index 2e49a69366..65ff05ad3e 100644 --- a/src/common/inc/texpr.h +++ b/src/common/inc/texpr.h @@ -95,6 +95,7 @@ void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, char *(*cb)(void *, const char*, int32_t)); void buildFilterSetFromBinary(void **q, const char *buf, int32_t len); +void convertFilterSetFromBinary(void **q, const char *buf, int32_t len, uint32_t tType); #ifdef __cplusplus } diff --git a/src/common/src/texpr.c b/src/common/src/texpr.c index 0e9ec053cc..74a406f4ef 100644 --- a/src/common/src/texpr.c +++ b/src/common/src/texpr.c @@ -495,6 +495,177 @@ void buildFilterSetFromBinary(void **q, const char *buf, int32_t len) { *q = (void *)pObj; } +void convertFilterSetFromBinary(void **q, const char *buf, int32_t len, uint32_t tType) { + SBufferReader br = tbufInitReader(buf, len, false); + uint32_t sType = tbufReadUint32(&br); + SHashObj *pObj = taosHashInit(256, taosGetDefaultHashFunction(tType), true, false); + + taosHashSetEqualFp(pObj, taosGetDefaultEqualFunction(tType)); + + int dummy = -1; + tVariant tmpVar = {0}; + size_t t = 0; + int32_t sz = tbufReadInt32(&br); + void *pvar = NULL; + int32_t bufLen = 0; + if (IS_NUMERIC_TYPE(sType)) { + bufLen = 60; // The maximum length of string that a number is converted to. + } else { + bufLen = 128; + } + + char *tmp = calloc(1, bufLen * TSDB_NCHAR_SIZE); + + for (int32_t i = 0; i < sz; i++) { + switch (sType) { + case TSDB_DATA_TYPE_BOOL: + case TSDB_DATA_TYPE_TINYINT: { + int8_t val = tbufReadInt64(&br); + t = sizeof(val); + pvar = &val; + break; + } + case TSDB_DATA_TYPE_SMALLINT: { + int16_t val = tbufReadInt64(&br); + t = sizeof(val); + pvar = &val; + break; + } + case TSDB_DATA_TYPE_INT: { + int32_t val = tbufReadInt64(&br); + t = sizeof(val); + pvar = &val; + break; + } + case TSDB_DATA_TYPE_BIGINT: { + int64_t val = tbufReadInt64(&br); + t = sizeof(val); + pvar = &val; + break; + } + case TSDB_DATA_TYPE_DOUBLE: { + double val = tbufReadDouble(&br); + t = sizeof(val); + pvar = &val; + break; + } + case TSDB_DATA_TYPE_FLOAT: { + float val = tbufReadDouble(&br); + t = sizeof(val); + pvar = &val; + break; + } + case TSDB_DATA_TYPE_BINARY: { + char *val = (char *)tbufReadBinary(&br, &t); + pvar = val; + break; + } + case TSDB_DATA_TYPE_NCHAR: { + char *val = (char *)tbufReadBinary(&br, &t); + pvar = val; + break; + } + default: + taosHashCleanup(pObj); + *q = NULL; + return; + } + + tVariantCreateFromBinary(&tmpVar, (char *)pvar, t, sType); + + if (bufLen < t) { + tmp = realloc(tmp, t * TSDB_NCHAR_SIZE); + bufLen = t; + } + + switch (tType) { + case TSDB_DATA_TYPE_BOOL: + case TSDB_DATA_TYPE_TINYINT: { + int8_t val = 0; + if (tVariantDump(&tmpVar, (char *)&val, tType, false)) { + goto err_ret; + } + pvar = &val; + t = sizeof(val); + break; + } + case TSDB_DATA_TYPE_SMALLINT: { + int16_t val = 0; + if (tVariantDump(&tmpVar, (char *)&val, tType, false)) { + goto err_ret; + } + pvar = &val; + t = sizeof(val); + break; + } + case TSDB_DATA_TYPE_INT: { + int32_t val = 0; + if (tVariantDump(&tmpVar, (char *)&val, tType, false)) { + goto err_ret; + } + pvar = &val; + t = sizeof(val); + break; + } + case TSDB_DATA_TYPE_BIGINT: { + int64_t val = 0; + if (tVariantDump(&tmpVar, (char *)&val, tType, false)) { + goto err_ret; + } + pvar = &val; + t = sizeof(val); + break; + } + case TSDB_DATA_TYPE_DOUBLE: { + double val = 0; + if (tVariantDump(&tmpVar, (char *)&val, tType, false)) { + goto err_ret; + } + pvar = &val; + t = sizeof(val); + break; + } + case TSDB_DATA_TYPE_FLOAT: { + float val = 0; + if (tVariantDump(&tmpVar, (char *)&val, tType, false)) { + goto err_ret; + } + pvar = &val; + t = sizeof(val); + break; + } + case TSDB_DATA_TYPE_BINARY: { + if (tVariantDump(&tmpVar, tmp, tType, true)) { + goto err_ret; + } + t = varDataLen(tmp); + pvar = varDataVal(tmp); + break; + } + case TSDB_DATA_TYPE_NCHAR: { + if (tVariantDump(&tmpVar, tmp, tType, true)) { + goto err_ret; + } + t = varDataLen(tmp); + pvar = varDataVal(tmp); + break; + } + default: + goto err_ret; + } + + taosHashPut(pObj, (char *)pvar, t, &dummy, sizeof(dummy)); + } + + *q = (void *)pObj; + pObj = NULL; + +err_ret: + taosHashCleanup(pObj); + tfree(tmp); +} + + tExprNode* exprdup(tExprNode* pNode) { if (pNode == NULL) { return NULL; diff --git a/src/query/src/qFilter.c b/src/query/src/qFilter.c index cfd894b408..c2d7646636 100644 --- a/src/query/src/qFilter.c +++ b/src/query/src/qFilter.c @@ -326,6 +326,13 @@ int32_t filterInitValFieldData(SFilterInfo *info) { tVariant* var = fi->desc; + if (unit->compare.optr == TSDB_RELATION_IN) { + convertFilterSetFromBinary((void **)&fi->data, var->pz, var->nLen, type); + CHK_LRET(fi->data == NULL, TSDB_CODE_QRY_APP_ERROR, "failed to convert in param"); + + continue; + } + if (type == TSDB_DATA_TYPE_BINARY) { fi->data = calloc(1, (var->nLen + 1) * TSDB_NCHAR_SIZE); } else if (type == TSDB_DATA_TYPE_NCHAR) { diff --git a/src/util/src/tcompare.c b/src/util/src/tcompare.c index e953f4c464..4cc8eeece6 100644 --- a/src/util/src/tcompare.c +++ b/src/util/src/tcompare.c @@ -19,6 +19,22 @@ #include "tarray.h" #include "hash.h" +int32_t setCompareBytes1(const void *pLeft, const void *pRight) { + return NULL != taosHashGet((SHashObj *)pRight, pLeft, 1) ? 1 : 0; +} + +int32_t setCompareBytes2(const void *pLeft, const void *pRight) { + return NULL != taosHashGet((SHashObj *)pRight, pLeft, 2) ? 1 : 0; +} + +int32_t setCompareBytes4(const void *pLeft, const void *pRight) { + return NULL != taosHashGet((SHashObj *)pRight, pLeft, 4) ? 1 : 0; +} + +int32_t setCompareBytes8(const void *pLeft, const void *pRight) { + return NULL != taosHashGet((SHashObj *)pRight, pLeft, 8) ? 1 : 0; +} + int32_t compareInt32Val(const void *pLeft, const void *pRight) { int32_t left = GET_INT32_VAL(pLeft), right = GET_INT32_VAL(pRight); if (left > right) return 1; @@ -309,6 +325,29 @@ static int32_t compareWStrPatternComp(const void* pLeft, const void* pRight) { __compar_fn_t getComparFunc(int32_t type, int32_t optr) { __compar_fn_t comparFn = NULL; + + if (optr == TSDB_RELATION_IN && (type != TSDB_DATA_TYPE_BINARY && type != TSDB_DATA_TYPE_NCHAR)) { + switch (type) { + case TSDB_DATA_TYPE_BOOL: + case TSDB_DATA_TYPE_TINYINT: + case TSDB_DATA_TYPE_UTINYINT: + return setCompareBytes1; + case TSDB_DATA_TYPE_SMALLINT: + case TSDB_DATA_TYPE_USMALLINT: + return setCompareBytes2; + case TSDB_DATA_TYPE_INT: + case TSDB_DATA_TYPE_UINT: + case TSDB_DATA_TYPE_FLOAT: + return setCompareBytes4; + case TSDB_DATA_TYPE_BIGINT: + case TSDB_DATA_TYPE_UBIGINT: + case TSDB_DATA_TYPE_DOUBLE: + case TSDB_DATA_TYPE_TIMESTAMP: + return setCompareBytes8; + default: + assert(0); + } + } switch (type) { case TSDB_DATA_TYPE_BOOL: @@ -334,6 +373,8 @@ __compar_fn_t getComparFunc(int32_t type, int32_t optr) { case TSDB_DATA_TYPE_NCHAR: { if (optr == TSDB_RELATION_LIKE) { comparFn = compareWStrPatternComp; + } else if (optr == TSDB_RELATION_IN) { + comparFn = compareFindItemInSet; } else { comparFn = compareLenPrefixedWStr; } diff --git a/src/util/src/thashutil.c b/src/util/src/thashutil.c index ffe167977b..fa2c95aaad 100644 --- a/src/util/src/thashutil.c +++ b/src/util/src/thashutil.c @@ -131,6 +131,7 @@ _hash_fn_t taosGetDefaultHashFunction(int32_t type) { case TSDB_DATA_TYPE_NCHAR: fn = MurmurHash3_32;break; case TSDB_DATA_TYPE_INT: fn = taosIntHash_32; break; case TSDB_DATA_TYPE_SMALLINT: fn = taosIntHash_16; break; + case TSDB_DATA_TYPE_BOOL: fn = taosIntHash_8; break; case TSDB_DATA_TYPE_TINYINT: fn = taosIntHash_8; break; case TSDB_DATA_TYPE_FLOAT: fn = taosFloatHash; break; case TSDB_DATA_TYPE_DOUBLE: fn = taosDoubleHash; break; diff --git a/tests/script/general/parser/condition.sim b/tests/script/general/parser/condition.sim index 839c3c8bb4..7a132d039a 100644 --- a/tests/script/general/parser/condition.sim +++ b/tests/script/general/parser/condition.sim @@ -62,7 +62,12 @@ if $rows != 28 then endi sql_error select * from stb1 where c8 > 0 -sql_error select * from stb1 where c1 in (0,1); +sql_error select * from stb1 where c2 in (0,1); +sql_error select * from stb1 where c6 in (0,2,3,1); +sql_error select * from stb1 where c7 in (0,2,3,1); +sql_error select * from stb1 where c8 in (true); +sql_error select * from stb1 where c8 in (1,2); +sql_error select * from stb1 where t3 in (3); sql_error select ts,c1,c7 from stb1 where c7 > false sql_error select ts,c1,c7 from stb1 where ts != '2021-05-05 18:19:27' sql_error select ts,c1,c7 from stb1 where ts > '2021-05-05 18:19:03.000' or ts > '2021-05-05 18:19:20.000'; @@ -1243,6 +1248,50 @@ if $data10 != @21-05-05 18:19:17.000@ then return -1 endi +sql select * from stb1 where c1 in (1,3); +if $rows != 2 then + return -1 +endi +if $data00 != @21-05-05 18:19:00.000@ then + return -1 +endi +if $data10 != @21-05-05 18:19:02.000@ then + return -1 +endi + +sql select * from stb1 where c3 in (11,22); +if $rows != 2 then + return -1 +endi +if $data00 != @21-05-05 18:19:04.000@ then + return -1 +endi +if $data10 != @21-05-05 18:19:09.000@ then + return -1 +endi + +sql select * from stb1 where c4 in (3,33); +if $rows != 2 then + return -1 +endi +if $data00 != @21-05-05 18:19:02.000@ then + return -1 +endi +if $data10 != @21-05-05 18:19:14.000@ then + return -1 +endi + +#sql select * from stb1 where c5 in (3,33) and c8 in ('22','55'); +#if $rows != 2 then +# return -1 +#endi +#if $data00 != @21-05-05 18:19:02.000@ then +# return -1 +#endi +#if $data10 != @21-05-05 18:19:14.000@ then +# return -1 +#endi + print "ts test" print "tbname test"