From c6cb40bf5728a31db550995939cef8bb064a0e55 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sat, 23 May 2020 17:34:15 +0800 Subject: [PATCH] [td-225] fix bugs in tbname in query --- src/client/src/tscSQLParser.c | 15 +++++++++------ src/client/src/tscSub.c | 6 +++--- src/query/src/qExecutor.c | 2 +- src/query/src/qast.c | 26 ++++++++++++++------------ src/tsdb/src/tsdbRead.c | 2 +- src/util/inc/tarray.h | 6 +++--- src/util/inc/tcompare.h | 8 +++++--- src/util/src/tarray.c | 21 +++++++-------------- src/util/src/tcompare.c | 19 +++++++++++++------ 9 files changed, 56 insertions(+), 49 deletions(-) diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index d68290653a..f338bbc644 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -3290,14 +3290,15 @@ static int32_t setExprToCond(tSQLExpr** parent, tSQLExpr* pExpr, const char* msg static int32_t handleExprInQueryCond(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SCondExpr* pCondExpr, int32_t* type, int32_t parentOptr) { - const char* msg1 = "meter query cannot use tags filter"; + const char* msg1 = "table query cannot use tags filter"; const char* msg2 = "illegal column name"; const char* msg3 = "only one query time range allowed"; const char* msg4 = "only one join condition allowed"; const char* msg5 = "not support ordinary column join"; const char* msg6 = "only one query condition on tbname allowed"; const char* msg7 = "only in/like allowed in filter table name"; - + const char* msg8 = "wildcard string should be less than 20 characters"; + tSQLExpr* pLeft = (*pExpr)->pLeft; tSQLExpr* pRight = (*pExpr)->pRight; @@ -3344,7 +3345,7 @@ static int32_t handleExprInQueryCond(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, S // check for like expression if ((*pExpr)->nSQLOptr == TK_LIKE) { if (pRight->val.nLen > TSDB_PATTERN_STRING_MAX_LEN) { - return TSDB_CODE_INVALID_SQL; + return invalidSqlErrMsg(pQueryInfo->msg, msg8); } SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta); @@ -3360,6 +3361,10 @@ static int32_t handleExprInQueryCond(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, S if (!validTableNameOptr(*pExpr)) { return invalidSqlErrMsg(pQueryInfo->msg, msg7); } + + if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { + return invalidSqlErrMsg(pQueryInfo->msg, msg1); + } if (pCondExpr->pTableCond == NULL) { pCondExpr->pTableCond = *pExpr; @@ -3808,9 +3813,7 @@ int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SSqlObj* pSql const char* msg2 = "invalid filter expression"; int32_t ret = TSDB_CODE_SUCCESS; - - pQueryInfo->window.skey = 0; - pQueryInfo->window.ekey = INT64_MAX; + pQueryInfo->window = TSWINDOW_INITIALIZER; // tags query condition may be larger than 512bytes, therefore, we need to prepare enough large space SStringBuilder sb; memset(&sb, 0, sizeof(sb)); diff --git a/src/client/src/tscSub.c b/src/client/src/tscSub.c index 9092fdd0b3..5831ddad4a 100644 --- a/src/client/src/tscSub.c +++ b/src/client/src/tscSub.c @@ -61,7 +61,7 @@ TSKEY tscGetSubscriptionProgress(void* sub, int64_t uid, TSKEY dflt) { SSub* pSub = (SSub*)sub; SSubscriptionProgress target = {.uid = uid, .key = 0}; - SSubscriptionProgress* p = taosArraySearch(pSub->progress, tscCompareSubscriptionProgress, &target); + SSubscriptionProgress* p = taosArraySearch(pSub->progress, &target, tscCompareSubscriptionProgress); if (p == NULL) { return dflt; } @@ -74,7 +74,7 @@ void tscUpdateSubscriptionProgress(void* sub, int64_t uid, TSKEY ts) { SSub* pSub = (SSub*)sub; SSubscriptionProgress target = {.uid = uid, .key = ts}; - SSubscriptionProgress* p = taosArraySearch(pSub->progress, tscCompareSubscriptionProgress, &target); + SSubscriptionProgress* p = taosArraySearch(pSub->progress, &target, tscCompareSubscriptionProgress); if (p != NULL) { p->key = ts; } @@ -211,7 +211,7 @@ static int tscUpdateSubscription(STscObj* pObj, SSub* pSub) { if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) { STableMeta * pTableMeta = pTableMetaInfo->pTableMeta; SSubscriptionProgress target = {.uid = pTableMeta->uid, .key = 0}; - SSubscriptionProgress* p = taosArraySearch(pSub->progress, tscCompareSubscriptionProgress, &target); + SSubscriptionProgress* p = taosArraySearch(pSub->progress, &target, tscCompareSubscriptionProgress); if (p == NULL) { taosArrayClear(pSub->progress); taosArrayPush(pSub->progress, &target); diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index a8158a386d..e9f1ffb49f 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -5745,7 +5745,7 @@ static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SArray* pTableIdList, SGroupItem item = { .id = id }; // NOTE: compare STableIdInfo with STableId // not a problem at present because we only use their 1st int64_t field - STableIdInfo* pTableId = taosArraySearch( pTableIdList, compareTableIdInfo, &id ); + STableIdInfo* pTableId = taosArraySearch( pTableIdList, &id, compareTableIdInfo); if (pTableId != NULL ) { window.skey = pTableId->key; } else { diff --git a/src/query/src/qast.c b/src/query/src/qast.c index d784fa4102..f35f4d0184 100644 --- a/src/query/src/qast.c +++ b/src/query/src/qast.c @@ -773,9 +773,6 @@ static void tQueryIndexlessColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, // todo refactor: tstr *name = ((STableIndexElem *)pData)->pTable->name; - // char* name = NULL; -// tsdbGetTableName(pQueryInfo->, pTable, &name); - // todo speed up by using hash if (pQueryInfo->colIndex == TSDB_TBNAME_COLUMN_INDEX) { if (pQueryInfo->optr == TSDB_RELATION_IN) { @@ -1051,7 +1048,7 @@ static void* exception_malloc(size_t size) { return p; } -static char* exception_strdup(const char* str) { +static UNUSED_FUNC char* exception_strdup(const char* str) { char* p = strdup(str); if (p == NULL) { THROW(TSDB_CODE_SERV_OUT_OF_MEMORY); @@ -1154,28 +1151,33 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) { tVariant* pVal = exception_calloc(1, sizeof(tVariant)); right->pVal = pVal; pVal->nType = TSDB_DATA_TYPE_ARRAY; - pVal->arr = taosArrayInit(2, sizeof(char*)); + pVal->arr = taosArrayInit(2, POINTER_BYTES); const char* cond = tbnameCond + QUERY_COND_REL_PREFIX_IN_LEN; for (const char *e = cond; *e != 0; e++) { if (*e == TS_PATH_DELIMITER[0]) { cond = e + 1; } else if (*e == ',') { - size_t len = e - cond + 1; - char* p = exception_malloc( len ); - memcpy(p, cond, len); - p[len - 1] = 0; + size_t len = e - cond + VARSTR_HEADER_SIZE; + char* p = exception_malloc(len); + varDataSetLen(p, len - VARSTR_HEADER_SIZE); + memcpy(varDataVal(p), cond, len); cond += len; taosArrayPush(pVal->arr, &p); } } if (*cond != 0) { - char* p = exception_strdup( cond ); - taosArrayPush(pVal->arr, &p); + size_t len = strlen(cond) + VARSTR_HEADER_SIZE; + + char* p = exception_malloc(len); + varDataSetLen(p, len - VARSTR_HEADER_SIZE); + memcpy(varDataVal(p), cond, len); + + taosArrayPush(pVal->arr, &p); } - taosArraySortString(pVal->arr); + taosArraySortString(pVal->arr, taosArrayCompareString); } CLEANUP_EXECUTE_TO(anchor, false); diff --git a/src/tsdb/src/tsdbRead.c b/src/tsdb/src/tsdbRead.c index cc191f3900..7a70312259 100644 --- a/src/tsdb/src/tsdbRead.c +++ b/src/tsdb/src/tsdbRead.c @@ -1678,7 +1678,7 @@ void filterPrepare(void* expr, void* param) { tVariant* pCond = pExpr->_node.pRight->pVal; SSchema* pSchema = pExpr->_node.pLeft->pSchema; - // todo : if current super table does not change schema yet, this function may failed, add test case + // todo : if current super table does not change schema yet, this function may fail to get correct schema, test case int32_t index = getTagColumnIndex(pTSSchema, pSchema); assert((index >= 0 && i < TSDB_MAX_TAGS) || (index == TSDB_TBNAME_COLUMN_INDEX)); diff --git a/src/util/inc/tarray.h b/src/util/inc/tarray.h index 866bde0938..4d44e82b1b 100644 --- a/src/util/inc/tarray.h +++ b/src/util/inc/tarray.h @@ -129,7 +129,7 @@ void taosArraySort(SArray* pArray, int (*compar)(const void*, const void*)); * sort string array * @param pArray */ -void taosArraySortString(SArray* pArray); +void taosArraySortString(SArray* pArray, __compar_fn_t comparFn); /** * search the array @@ -137,14 +137,14 @@ void taosArraySortString(SArray* pArray); * @param compar * @param key */ -void* taosArraySearch(const SArray* pArray, int (*compar)(const void*, const void*), const void* key); +void* taosArraySearch(const SArray* pArray, const void* key, __compar_fn_t comparFn); /** * search the array * @param pArray * @param key */ -char* taosArraySearchString(const SArray* pArray, const char* key); +char* taosArraySearchString(const SArray* pArray, const char* key, __compar_fn_t comparFn); #ifdef __cplusplus } diff --git a/src/util/inc/tcompare.h b/src/util/inc/tcompare.h index 8aaa39e483..5e951923c1 100644 --- a/src/util/inc/tcompare.h +++ b/src/util/inc/tcompare.h @@ -34,16 +34,18 @@ typedef struct SPatternCompareInfo { char matchOne; // symbol for match one wildcard, default: '_' } SPatternCompareInfo; -int patternMatch(const char *zPattern, const char *zString, size_t size, const SPatternCompareInfo *pInfo); +int patternMatch(const char *pattern, const char *str, size_t size, const SPatternCompareInfo *pInfo); -int WCSPatternMatch(const wchar_t *zPattern, const wchar_t *zString, size_t size, const SPatternCompareInfo *pInfo); +int WCSPatternMatch(const wchar_t *pattern, const wchar_t *str, size_t size, const SPatternCompareInfo *pInfo); -int32_t doCompare(const char* f1, const char* f2, int32_t type, size_t size); +int32_t doCompare(const char* a, const char* b, int32_t type, size_t size); __compar_fn_t getKeyComparFunc(int32_t keyType); __compar_fn_t getComparFunc(int32_t type, int32_t optr); +int32_t taosArrayCompareString(const void* a, const void* b); + #ifdef __cplusplus } #endif diff --git a/src/util/src/tarray.c b/src/util/src/tarray.c index 5198597ff7..8908dc2e65 100755 --- a/src/util/src/tarray.c +++ b/src/util/src/tarray.c @@ -197,30 +197,23 @@ void taosArraySort(SArray* pArray, int (*compar)(const void*, const void*)) { qsort(pArray->pData, pArray->size, pArray->elemSize, compar); } -void* taosArraySearch(const SArray* pArray, int (*compar)(const void*, const void*), const void* key) { - assert(pArray != NULL); - assert(compar != NULL); +void* taosArraySearch(const SArray* pArray, const void* key, __compar_fn_t comparFn) { + assert(pArray != NULL && comparFn != 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); + return bsearch(key, pArray->pData, pArray->size, pArray->elemSize, comparFn); } -void taosArraySortString(SArray* pArray) { +void taosArraySortString(SArray* pArray, __compar_fn_t comparFn) { assert(pArray != NULL); - qsort(pArray->pData, pArray->size, pArray->elemSize, taosArrayCompareString); + qsort(pArray->pData, pArray->size, pArray->elemSize, comparFn); } -char* taosArraySearchString(const SArray* pArray, const char* key) { +char* taosArraySearchString(const SArray* pArray, const char* key, __compar_fn_t comparFn) { assert(pArray != NULL); assert(key != NULL); - void* p = bsearch(&key, pArray->pData, pArray->size, pArray->elemSize, taosArrayCompareString); + void* p = bsearch(&key, pArray->pData, pArray->size, pArray->elemSize, comparFn); if (p == NULL) { return NULL; } diff --git a/src/util/src/tcompare.c b/src/util/src/tcompare.c index 751bd0fc34..cb9f339f6a 100644 --- a/src/util/src/tcompare.c +++ b/src/util/src/tcompare.c @@ -227,9 +227,16 @@ static int32_t compareStrPatternComp(const void* pLeft, const void* pRight) { return (ret == TSDB_PATTERN_MATCH) ? 0 : 1; } +int32_t taosArrayCompareString(const void* a, const void* b) { + const char* x = *(const char**)a; + const char* y = *(const char**)b; + + return compareLenPrefixedStr(x, y); +} + static int32_t compareFindStrInArray(const void* pLeft, const void* pRight) { const SArray* arr = (const SArray*) pRight; - return taosArraySearchString(arr, pLeft) == NULL ? 0 : 1; + return taosArraySearchString(arr, pLeft, taosArrayCompareString) == NULL ? 0 : 1; } static int32_t compareWStrPatternComp(const void* pLeft, const void* pRight) { @@ -248,25 +255,25 @@ __compar_fn_t getComparFunc(int32_t type, int32_t optr) { switch (type) { case TSDB_DATA_TYPE_SMALLINT: { - comparFn = compareInt16Val; break; + comparFn = compareInt16Val; break; } case TSDB_DATA_TYPE_INT: { - comparFn = compareInt32Val; break; + comparFn = compareInt32Val; break; } case TSDB_DATA_TYPE_BIGINT: case TSDB_DATA_TYPE_TIMESTAMP: { - comparFn = compareInt64Val; break; + comparFn = compareInt64Val; break; } case TSDB_DATA_TYPE_BOOL: case TSDB_DATA_TYPE_TINYINT:{ - comparFn = compareInt8Val; break; + comparFn = compareInt8Val; break; } case TSDB_DATA_TYPE_FLOAT: { - comparFn = compareFloatVal; break; + comparFn = compareFloatVal; break; } case TSDB_DATA_TYPE_DOUBLE: { -- GitLab