From 87363383f955df5aa5773bce8a13635a29be5e7d Mon Sep 17 00:00:00 2001 From: localvar Date: Thu, 23 Apr 2020 15:11:44 +0800 Subject: [PATCH] TD-97: search in array is done --- src/inc/taosdef.h | 14 +++ src/query/inc/qast.h | 2 - src/query/inc/tvariant.h | 2 + src/query/src/qast.c | 243 +++++++++++++++++++++++---------------- src/query/src/tvariant.c | 23 ++++ src/tsdb/src/tsdbRead.c | 4 +- src/util/inc/tarray.h | 15 ++- src/util/src/tarray.c | 26 ++++- src/util/src/tcompare.c | 67 ++++++----- 9 files changed, 256 insertions(+), 140 deletions(-) diff --git a/src/inc/taosdef.h b/src/inc/taosdef.h index b02a3df844..15fb026381 100644 --- a/src/inc/taosdef.h +++ b/src/inc/taosdef.h @@ -32,6 +32,20 @@ extern "C" { #define TSKEY int64_t #endif +// Data type definition +#define TSDB_DATA_TYPE_NULL 0 // 1 bytes +#define TSDB_DATA_TYPE_BOOL 1 // 1 bytes +#define TSDB_DATA_TYPE_TINYINT 2 // 1 byte +#define TSDB_DATA_TYPE_SMALLINT 3 // 2 bytes +#define TSDB_DATA_TYPE_INT 4 // 4 bytes +#define TSDB_DATA_TYPE_BIGINT 5 // 8 bytes +#define TSDB_DATA_TYPE_FLOAT 6 // 4 bytes +#define TSDB_DATA_TYPE_DOUBLE 7 // 8 bytes +#define TSDB_DATA_TYPE_BINARY 8 // string +#define TSDB_DATA_TYPE_TIMESTAMP 9 // 8 bytes +#define TSDB_DATA_TYPE_NCHAR 10 // unicode string +#define TSDB_DATA_TYPE_ARRAY 11 // only used 'in' query to hold the values + // Bytes for each type. extern const int32_t TYPE_BYTES[11]; // TODO: replace and remove code below diff --git a/src/query/inc/qast.h b/src/query/inc/qast.h index e1c61fceb1..7de1e5be66 100644 --- a/src/query/inc/qast.h +++ b/src/query/inc/qast.h @@ -35,7 +35,6 @@ enum { TSQL_NODE_EXPR = 0x1, TSQL_NODE_COL = 0x2, TSQL_NODE_VALUE = 0x4, - TSQL_NODE_ARRAY = 0x8, }; typedef bool (*__result_filter_fn_t)(const void *, void *); @@ -71,7 +70,6 @@ typedef struct tExprNode { struct tExprNode *pRight; // right child pointer } _node; struct SSchema *pSchema; - SArray* array; tVariant * pVal; }; } tExprNode; diff --git a/src/query/inc/tvariant.h b/src/query/inc/tvariant.h index 7ed5aa8dbe..9e11e6c294 100644 --- a/src/query/inc/tvariant.h +++ b/src/query/inc/tvariant.h @@ -17,6 +17,7 @@ #define TDENGINE_TVARIANT_H #include "tstoken.h" +#include "tarray.h" #ifdef __cplusplus extern "C" { @@ -31,6 +32,7 @@ typedef struct tVariant { double dKey; char * pz; wchar_t *wpz; + SArray *arr; // only for 'in' query to hold value list, not value for a field }; } tVariant; diff --git a/src/query/src/qast.c b/src/query/src/qast.c index edfb78f0e4..4da26e0746 100644 --- a/src/query/src/qast.c +++ b/src/query/src/qast.c @@ -460,9 +460,6 @@ void tExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *)) { free((*pExpr)->pVal); } else if ((*pExpr)->nodeType == TSQL_NODE_COL) { free((*pExpr)->pSchema); - } else if ((*pExpr)->nodeType == TSQL_NODE_ARRAY) { - // BUGBUG: memory leak, need free elements in the array - taosArrayDestroy((*pExpr)->array); } free(*pExpr); @@ -524,38 +521,48 @@ static int32_t setQueryCond(tQueryInfo *queryColInfo, SQueryCond* pCond) { if (optr == TSDB_RELATION_GREATER || optr == TSDB_RELATION_GREATER_EQUAL || optr == TSDB_RELATION_EQUAL || optr == TSDB_RELATION_NOT_EQUAL) { pCond->start = calloc(1, sizeof(tVariant)); - tVariantAssign(&pCond->start->v, &queryColInfo->q); pCond->start->optr = queryColInfo->optr; + } else if (optr == TSDB_RELATION_LESS || optr == TSDB_RELATION_LESS_EQUAL) { pCond->end = calloc(1, sizeof(tVariant)); - tVariantAssign(&pCond->end->v, &queryColInfo->q); pCond->end->optr = queryColInfo->optr; + + } else if (optr == TSDB_RELATION_IN) { + printf("relation is in\n"); + + } else if (optr == TSDB_RELATION_LIKE) { + printf("relation is like\n"); + } return TSDB_CODE_SUCCESS; } -static void tQueryOnSkipList(SSkipList* pSkipList, SQueryCond* pCond, int32_t type, SArray* result) { +static void tQueryIndexColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArray* result) { SSkipListIterator* iter = NULL; - - if (pCond->start != NULL) { - iter = tSkipListCreateIterFromVal(pSkipList, (char*) &pCond->start->v.i64Key, type, TSDB_ORDER_ASC); + int32_t type = pQueryInfo->q.nType; + + SQueryCond cond = { 0 }; + setQueryCond(pQueryInfo, &cond); + + if (cond.start != NULL) { + iter = tSkipListCreateIterFromVal(pSkipList, (char*) &cond.start->v.i64Key, type, TSDB_ORDER_ASC); } else { - iter = tSkipListCreateIterFromVal(pSkipList, (char*) &pCond->end->v.i64Key, type, TSDB_ORDER_DESC); + iter = tSkipListCreateIterFromVal(pSkipList, (char*) &cond.end->v.i64Key, type, TSDB_ORDER_DESC); } __compar_fn_t func = getComparFunc(pSkipList->keyInfo.type, type, 0); - if (pCond->start != NULL) { - int32_t optr = pCond->start->optr; + if (cond.start != NULL) { + int32_t optr = cond.start->optr; if (optr == TSDB_RELATION_EQUAL) { while(tSkipListIterNext(iter)) { SSkipListNode* pNode = tSkipListIterGet(iter); - int32_t ret = func(SL_GET_NODE_KEY(pSkipList, pNode), &pCond->start->v.i64Key); + int32_t ret = func(SL_GET_NODE_KEY(pSkipList, pNode), &cond.start->v.i64Key); if (ret == 0) { taosArrayPush(result, SL_GET_NODE_DATA(pNode)); } else { @@ -570,7 +577,7 @@ static void tQueryOnSkipList(SSkipList* pSkipList, SQueryCond* pCond, int32_t ty SSkipListNode* pNode = tSkipListIterGet(iter); if (comp) { - ret = func(SL_GET_NODE_KEY(pSkipList, pNode), &pCond->start->v.i64Key); + ret = func(SL_GET_NODE_KEY(pSkipList, pNode), &cond.start->v.i64Key); assert(ret >= 0); } @@ -587,7 +594,7 @@ static void tQueryOnSkipList(SSkipList* pSkipList, SQueryCond* pCond, int32_t ty assert(0); } } else { - int32_t optr = pCond->end->optr; + int32_t optr = cond.end->optr; if (optr == TSDB_RELATION_LESS || optr == TSDB_RELATION_LESS_EQUAL) { bool comp = true; @@ -597,7 +604,7 @@ static void tQueryOnSkipList(SSkipList* pSkipList, SQueryCond* pCond, int32_t ty SSkipListNode* pNode = tSkipListIterGet(iter); if (comp) { - ret = func(SL_GET_NODE_KEY(pSkipList, pNode), &pCond->end->v.i64Key); + ret = func(SL_GET_NODE_KEY(pSkipList, pNode), &cond.end->v.i64Key); assert(ret <= 0); } @@ -788,6 +795,36 @@ static void tSQLBinaryTraverseOnSkipList(tExprNode *pExpr, SArray *pResult, SSki } } + +#include + +static void tQueryIndexlessColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArray* result) { + SSkipListIterator* iter = tSkipListCreateIter(pSkipList); + + while (tSkipListIterNext(iter)) { + bool addToResult = false; + + SSkipListNode *pNode = tSkipListIterGet(iter); + STable* table = *(STable**) SL_GET_NODE_DATA(pNode); + + if (pQueryInfo->colIndex == TSDB_TBNAME_COLUMN_INDEX) { + if (pQueryInfo->optr == TSDB_RELATION_IN) { + addToResult = pQueryInfo->compare(table->name, pQueryInfo->q.arr); + } else if(pQueryInfo->optr == TSDB_RELATION_LIKE) { + addToResult = pQueryInfo->compare(table->name, pQueryInfo->q.pz); + } + } else { + // TODO: other columns + } + + if (addToResult) { + taosArrayPush(result, table); + } + } +} + + + // post-root order traverse syntax tree void tExprTreeTraverse(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, SBinaryFilterSupp *param) { if (pExpr == NULL) { @@ -797,95 +834,99 @@ void tExprTreeTraverse(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, S tExprNode *pLeft = pExpr->_node.pLeft; tExprNode *pRight = pExpr->_node.pRight; - // recursive traverse left child branch - if (pLeft->nodeType == TSQL_NODE_EXPR || pRight->nodeType == TSQL_NODE_EXPR) { - uint8_t weight = pLeft->_node.hasPK + pRight->_node.hasPK; + // column project + if (pLeft->nodeType != TSQL_NODE_EXPR && pRight->nodeType != TSQL_NODE_EXPR) { + assert(pLeft->nodeType == TSQL_NODE_COL && pRight->nodeType == TSQL_NODE_VALUE); - if (weight == 0 && taosArrayGetSize(result) > 0 && pSkipList == NULL) { - /** - * Perform the filter operation based on the initial filter result, which is obtained from filtering from index. - * Since no index presented, the filter operation is done by scan all elements in the result set. - * - * if the query is a high selectivity filter, only small portion of meters are retrieved. - */ + param->setupInfoFn(pExpr, param->pExtInfo); + if (pSkipList == NULL) { + tSQLListTraverseOnResult(pExpr, param->fp, result); + return; + } + + tQueryInfo *pQueryInfo = pExpr->_node.info; + if (pQueryInfo->colIndex == 0 && pQueryInfo->optr != TSDB_RELATION_LIKE) { + tQueryIndexColumn(pSkipList, pQueryInfo, result); + } else { + tQueryIndexlessColumn(pSkipList, pQueryInfo, result); + } + + return; + } + + // recursive traverse left child branch + uint8_t weight = pLeft->_node.hasPK + pRight->_node.hasPK; + + if (weight == 0 ) { + if (taosArrayGetSize(result) > 0 && pSkipList == NULL) { + /** + * Perform the filter operation based on the initial filter result, which is obtained from filtering from index. + * Since no index presented, the filter operation is done by scan all elements in the result set. + * + * if the query is a high selectivity filter, only small portion of meters are retrieved. + */ exprTreeTraverseImpl(pExpr, result, param); - } else if (weight == 0) { + } else { /** * apply the hierarchical expression to every node in skiplist for find the qualified nodes */ assert(taosArrayGetSize(result) == 0); tSQLBinaryTraverseOnSkipList(pExpr, result, pSkipList, param); - } else if (weight == 2 || (weight == 1 && pExpr->_node.optr == TSDB_RELATION_OR)) { - SArray* rLeft = taosArrayInit(10, POINTER_BYTES); - SArray* rRight = taosArrayInit(10, POINTER_BYTES); - - tExprTreeTraverse(pLeft, pSkipList, rLeft, param); - tExprTreeTraverse(pRight, pSkipList, rRight, param); - - if (pExpr->_node.optr == TSDB_RELATION_AND) { // CROSS - intersect(rLeft, rRight, result); - } else if (pExpr->_node.optr == TSDB_RELATION_OR) { // or - merge(rLeft, rRight, result); - } else { - assert(false); - } + } + return; + } + + if (weight == 2 || (weight == 1 && pExpr->_node.optr == TSDB_RELATION_OR)) { + SArray* rLeft = taosArrayInit(10, POINTER_BYTES); + SArray* rRight = taosArrayInit(10, POINTER_BYTES); + + tExprTreeTraverse(pLeft, pSkipList, rLeft, param); + tExprTreeTraverse(pRight, pSkipList, rRight, param); - taosArrayDestroy(rLeft); - taosArrayDestroy(rRight); + if (pExpr->_node.optr == TSDB_RELATION_AND) { // CROSS + intersect(rLeft, rRight, result); + } else if (pExpr->_node.optr == TSDB_RELATION_OR) { // or + merge(rLeft, rRight, result); } else { - /* - * (weight == 1 && pExpr->nSQLBinaryOptr == TSDB_RELATION_AND) is handled here - * - * first, we filter results based on the skiplist index, which is the initial filter stage, - * then, we conduct the secondary filter operation based on the result from the initial filter stage. - */ - assert(pExpr->_node.optr == TSDB_RELATION_AND); - - tExprNode *pFirst = NULL; - tExprNode *pSecond = NULL; - if (pLeft->_node.hasPK == 1) { - pFirst = pLeft; - pSecond = pRight; - } else { - pFirst = pRight; - pSecond = pLeft; - } + assert(false); + } - assert(pFirst != pSecond && pFirst != NULL && pSecond != NULL); + taosArrayDestroy(rLeft); + taosArrayDestroy(rRight); + return; + } - // we filter the result based on the skiplist index in the first place - tExprTreeTraverse(pFirst, pSkipList, result, param); + /* + * (weight == 1 && pExpr->nSQLBinaryOptr == TSDB_RELATION_AND) is handled here + * + * first, we filter results based on the skiplist index, which is the initial filter stage, + * then, we conduct the secondary filter operation based on the result from the initial filter stage. + */ + assert(pExpr->_node.optr == TSDB_RELATION_AND); + + tExprNode *pFirst = NULL; + tExprNode *pSecond = NULL; + if (pLeft->_node.hasPK == 1) { + pFirst = pLeft; + pSecond = pRight; + } else { + pFirst = pRight; + pSecond = pLeft; + } - /* - * recursively perform the filter operation based on the initial results, - * So, we do not set the skip list index as a parameter - */ - tExprTreeTraverse(pSecond, NULL, result, param); - } - } else { // column project - assert(pLeft->nodeType == TSQL_NODE_COL && (pRight->nodeType == TSQL_NODE_VALUE || pRight->nodeType == TSQL_NODE_ARRAY)); + assert(pFirst != pSecond && pFirst != NULL && pSecond != NULL); - param->setupInfoFn(pExpr, param->pExtInfo); - if (pSkipList == NULL) { - tSQLListTraverseOnResult(pExpr, param->fp, result); - } else { - tQueryInfo *pQueryInfo = pExpr->_node.info; - - if (pQueryInfo->colIndex == 0 && pQueryInfo->optr != TSDB_RELATION_LIKE) { - SQueryCond cond = {0}; - /*int32_t ret = */ setQueryCond(pQueryInfo, &cond); - tQueryOnSkipList(pSkipList, &cond, pQueryInfo->q.nType, result); - } else { - /* Brutal force scan the whole skip list to find the appropriate result, - * since the filter is not applied to indexed column. - */ - assert(0); -// result->num = tSkipListIterateList(pSkipList, (tSkipListNode ***)&result->pRes, fp, queryColInfo); - } - } - } + // we filter the result based on the skiplist index in the first place + tExprTreeTraverse(pFirst, pSkipList, result, param); + + /* + * recursively perform the filter operation based on the initial results, + * So, we do not set the skip list index as a parameter + */ + tExprTreeTraverse(pSecond, NULL, result, param); } + void tSQLBinaryExprCalcTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, void *param, int32_t order, char *(*getSourceDataBlock)(void *, char *, int32_t)) { if (pExprs == NULL) { @@ -1090,12 +1131,6 @@ tExprNode* exprTreeFromBinary(const void* pBuf, size_t size) { return exprTreeFromBinaryImpl(&rbuf); } -static int cmpStrInArray(const void* a, const void* b) { - const char* x = *(const char**)a; - const char* y = *(const char**)b; - return strcmp(x, y); -} - tExprNode* exprTreeFromTableName(const char* tbnameCond) { if (!tbnameCond) { return NULL; @@ -1132,6 +1167,7 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) { expr->_node.pRight = right; if (strncmp(tbnameCond, QUERY_COND_REL_PREFIX_LIKE, QUERY_COND_REL_PREFIX_LIKE_LEN) == 0) { + right->nodeType = TSQL_NODE_VALUE; expr->_node.optr = TSDB_RELATION_LIKE; tVariant* pVal = calloc(1, sizeof(tVariant)); if (pVal == NULL) { @@ -1147,8 +1183,15 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) { memcpy(pVal->pz, tbnameCond + QUERY_COND_REL_PREFIX_LIKE_LEN, len); } else if (strncmp(tbnameCond, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN) == 0) { + right->nodeType = TSQL_NODE_VALUE; expr->_node.optr = TSDB_RELATION_IN; - right->array = taosArrayInit(2, sizeof(char*)); + tVariant* pVal = calloc(1, sizeof(tVariant)); + if (pVal == NULL) { + // TODO: + } + right->pVal = pVal; + pVal->nType = TSDB_DATA_TYPE_ARRAY; + pVal->arr = taosArrayInit(2, sizeof(char*)); const char* cond = tbnameCond + QUERY_COND_REL_PREFIX_IN_LEN; for (const char *e = cond; *e != 0; e++) { @@ -1158,7 +1201,7 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) { memcpy(p, cond, len); p[len - 1] = 0; cond += len; - taosArrayPush(right->array, &p); + taosArrayPush(pVal->arr, &p); } } @@ -1167,10 +1210,10 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) { char* p = malloc( len ); memcpy(p, cond, len); p[len - 1] = 0; - taosArrayPush(right->array, &p); + taosArrayPush(pVal->arr, &p); } - taosArraySort(right->array, cmpStrInArray); + taosArraySortString(pVal->arr); } return expr; diff --git a/src/query/src/tvariant.c b/src/query/src/tvariant.c index f0addb733b..e90cc3a44d 100644 --- a/src/query/src/tvariant.c +++ b/src/query/src/tvariant.c @@ -130,6 +130,17 @@ void tVariantDestroy(tVariant *pVar) { tfree(pVar->pz); pVar->nLen = 0; } + + // NOTE: this is only for string array + if (pVar->nType == TSDB_DATA_TYPE_ARRAY) { + size_t num = taosArrayGetSize(pVar->arr); + for(size_t i = 0; i < num; i++) { + void* p = taosArrayGetP(pVar->arr, i); + free(p); + } + taosArrayDestroy(pVar->arr); + pVar->arr = NULL; + } } void tVariantAssign(tVariant *pDst, const tVariant *pSrc) { @@ -145,6 +156,18 @@ void tVariantAssign(tVariant *pDst, const tVariant *pSrc) { pDst->pz = calloc(1, len); memcpy(pDst->pz, pSrc->pz, len); + return; + } + + // this is only for string array + if (pSrc->nType == TSDB_DATA_TYPE_ARRAY) { + size_t num = taosArrayGetSize(pSrc->arr); + pDst->arr = taosArrayInit(num, sizeof(char*)); + for(size_t i = 0; i < num; i++) { + char* p = (char*)taosArrayGetP(pSrc->arr, i); + char* n = strdup(p); + taosArrayPush(pDst->arr, &n); + } } } diff --git a/src/tsdb/src/tsdbRead.c b/src/tsdb/src/tsdbRead.c index 60fa46607a..58fd4eb653 100644 --- a/src/tsdb/src/tsdbRead.c +++ b/src/tsdb/src/tsdbRead.c @@ -1213,7 +1213,9 @@ void filterPrepare(void* expr, void* param) { pInfo->compare = getComparFunc(pSchema->type, pCond->nType, pInfo->optr); tVariantAssign(&pInfo->q, pCond); - tVariantTypeSetType(&pInfo->q, pInfo->sch.type); + if (pInfo->optr != TSDB_RELATION_IN) { + tVariantTypeSetType(&pInfo->q, pInfo->sch.type); + } } int32_t doCompare(const char* f1, const char* f2, int32_t type, size_t size) { diff --git a/src/util/inc/tarray.h b/src/util/inc/tarray.h index bd601a743f..dbb74edf07 100644 --- a/src/util/inc/tarray.h +++ b/src/util/inc/tarray.h @@ -119,13 +119,26 @@ void taosArrayDestroy(SArray* pArray); */ void taosArraySort(SArray* pArray, int (*compar)(const void*, const void*)); +/** + * sort string array + * @param pArray + */ +void taosArraySortString(SArray* pArray); + /** * search the array * @param pArray * @param compar * @param key */ -void* taosArraySearch(SArray* pArray, int (*compar)(const void*, const void*), const void* key); +void* taosArraySearch(const SArray* pArray, int (*compar)(const void*, const void*), const void* key); + +/** + * search the array + * @param pArray + * @param key + */ +char* taosArraySearchString(const SArray* pArray, const char* key); #ifdef __cplusplus } diff --git a/src/util/src/tarray.c b/src/util/src/tarray.c index 39bbde3601..ef57c2432f 100755 --- a/src/util/src/tarray.c +++ b/src/util/src/tarray.c @@ -27,7 +27,7 @@ void* taosArrayInit(size_t size, size_t elemSize) { return NULL; } - pArray->pData = calloc(size, elemSize * size); + pArray->pData = calloc(size, elemSize); if (pArray->pData == NULL) { free(pArray); return NULL; @@ -192,10 +192,32 @@ void taosArraySort(SArray* pArray, int (*compar)(const void*, const void*)) { qsort(pArray->pData, pArray->size, pArray->elemSize, compar); } -void* taosArraySearch(SArray* pArray, int (*compar)(const void*, const void*), const void* key) { +void* taosArraySearch(const SArray* pArray, int (*compar)(const void*, const void*), const void* key) { assert(pArray != NULL); assert(compar != NULL); assert(key != NULL); return bsearch(key, pArray->pData, pArray->size, pArray->elemSize, compar); } + +static int taosArrayCompareString(const void* a, const void* b) { + const char* x = *(const char**)a; + const char* y = *(const char**)b; + return strcmp(x, y); +} + +void taosArraySortString(SArray* pArray) { + assert(pArray != NULL); + qsort(pArray->pData, pArray->size, pArray->elemSize, taosArrayCompareString); +} + +char* taosArraySearchString(const SArray* pArray, const char* key) { + assert(pArray != NULL); + assert(key != NULL); + + void* p = bsearch(&key, pArray->pData, pArray->size, pArray->elemSize, taosArrayCompareString); + if (p == NULL) { + return NULL; + } + return *(char**)p; +} \ No newline at end of file diff --git a/src/util/src/tcompare.c b/src/util/src/tcompare.c index 4505ea533a..d4cfd983d5 100644 --- a/src/util/src/tcompare.c +++ b/src/util/src/tcompare.c @@ -1,42 +1,34 @@ #include "taosdef.h" #include "tcompare.h" - +#include #include "tutil.h" int32_t compareInt32Val(const void *pLeft, const void *pRight) { - int32_t ret = GET_INT32_VAL(pLeft) - GET_INT32_VAL(pRight); - if (ret == 0) { - return 0; - } else { - return ret > 0 ? 1 : -1; - } + int32_t left = GET_INT32_VAL(pLeft), right = GET_INT32_VAL(pRight); + if (left > right) return 1; + if (left < right) return -1; + return 0; } int32_t compareInt64Val(const void *pLeft, const void *pRight) { - int64_t ret = GET_INT64_VAL(pLeft) - GET_INT64_VAL(pRight); - if (ret == 0) { - return 0; - } else { - return ret > 0 ? 1 : -1; - } + int64_t left = GET_INT64_VAL(pLeft), right = GET_INT64_VAL(pRight); + if (left > right) return 1; + if (left < right) return -1; + return 0; } int32_t compareInt16Val(const void *pLeft, const void *pRight) { - int32_t ret = GET_INT16_VAL(pLeft) - GET_INT16_VAL(pRight); - if (ret == 0) { - return 0; - } else { - return ret > 0 ? 1 : -1; - } + int16_t left = GET_INT16_VAL(pLeft), right = GET_INT16_VAL(pRight); + if (left > right) return 1; + if (left < right) return -1; + return 0; } int32_t compareInt8Val(const void *pLeft, const void *pRight) { - int32_t ret = GET_INT8_VAL(pLeft) - GET_INT8_VAL(pRight); - if (ret == 0) { - return 0; - } else { - return ret > 0 ? 1 : -1; - } + int8_t left = GET_INT8_VAL(pLeft), right = GET_INT8_VAL(pRight); + if (left > right) return 1; + if (left < right) return -1; + return 0; } int32_t compareIntDoubleVal(const void *pLeft, const void *pRight) { @@ -69,12 +61,7 @@ int32_t compareDoubleVal(const void *pLeft, const void *pRight) { } int32_t compareStrVal(const void *pLeft, const void *pRight) { - int32_t ret = strcmp(pLeft, pRight); - if (ret == 0) { - return 0; - } else { - return ret > 0 ? 1 : -1; - } + return (int32_t)strcmp(pLeft, pRight); } int32_t compareWStrVal(const void *pLeft, const void *pRight) { @@ -228,6 +215,11 @@ static UNUSED_FUNC int32_t compareStrPatternComp(const void* pLeft, const void* return (ret == TSDB_PATTERN_MATCH) ? 0 : 1; } +static int32_t compareStrInList(const void* pLeft, const void* pRight) { + const SArray* arr = (const SArray*)pRight; + return taosArraySearchString(arr, &pLeft) == NULL ? 0 : 1; +} + static UNUSED_FUNC int32_t compareWStrPatternComp(const void* pLeft, const void* pRight) { SPatternCompareInfo pInfo = {'%', '_'}; @@ -250,7 +242,6 @@ __compar_fn_t getComparFunc(int32_t type, int32_t filterDataType, int32_t optr) case TSDB_DATA_TYPE_BIGINT: case TSDB_DATA_TYPE_TIMESTAMP: { // assert(type == filterDataType); - if (filterDataType == TSDB_DATA_TYPE_BIGINT || filterDataType == TSDB_DATA_TYPE_TIMESTAMP) { comparFn = compareInt64Val; } else if (filterDataType >= TSDB_DATA_TYPE_FLOAT && filterDataType <= TSDB_DATA_TYPE_DOUBLE) { @@ -259,6 +250,7 @@ __compar_fn_t getComparFunc(int32_t type, int32_t filterDataType, int32_t optr) break; } + case TSDB_DATA_TYPE_BOOL: { if (filterDataType >= TSDB_DATA_TYPE_BOOL && filterDataType <= TSDB_DATA_TYPE_BIGINT) { comparFn = compareInt32Val; @@ -267,6 +259,7 @@ __compar_fn_t getComparFunc(int32_t type, int32_t filterDataType, int32_t optr) } break; } + case TSDB_DATA_TYPE_FLOAT: case TSDB_DATA_TYPE_DOUBLE: { if (filterDataType >= TSDB_DATA_TYPE_BOOL && filterDataType <= TSDB_DATA_TYPE_BIGINT) { @@ -276,12 +269,18 @@ __compar_fn_t getComparFunc(int32_t type, int32_t filterDataType, int32_t optr) } break; } + case TSDB_DATA_TYPE_BINARY: { - assert(filterDataType == TSDB_DATA_TYPE_BINARY); - if (optr == TSDB_RELATION_LIKE) { /* wildcard query using like operator */ + assert(filterDataType == TSDB_DATA_TYPE_BINARY); comparFn = compareStrPatternComp; + + } else if (optr == TSDB_RELATION_IN) { + assert(filterDataType == TSDB_DATA_TYPE_ARRAY); + comparFn = compareStrInList; + } else { /* normal relational comparFn */ + assert(filterDataType == TSDB_DATA_TYPE_BINARY); comparFn = compareStrVal; } -- GitLab