diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index f87ede9ced8055bb87af94425bb71c6024a1c5f7..00b794e8dd9b42dee25350cef769619cbed254f5 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -3055,6 +3055,29 @@ static int32_t setMetersIDForMetricQuery(SSqlObj* pSql, char* tmpTagCondBuf) { return TSDB_CODE_SUCCESS; } +static bool validateFilterExpr(SSqlCmd* pCmd) { + for (int32_t i = 0; i < pCmd->colList.numOfCols; ++i) { + SColumnBase* pColBase = &pCmd->colList.pColList[i]; + + if (pColBase->filterOn > 0) { + int32_t lowerOptr = pColBase->lowerRelOptr; + int32_t upperOptr = pColBase->upperRelOptr; + + if ((lowerOptr == TSDB_RELATION_LARGE_EQUAL || lowerOptr == TSDB_RELATION_LARGE) && + (upperOptr == TSDB_RELATION_LESS_EQUAL || upperOptr == TSDB_RELATION_LESS)) { + continue; + } + + // there must be at least two range, not support yet. + if (lowerOptr * upperOptr != TSDB_RELATION_INVALID) { + return false; + } + } + } + + return true; +} + int32_t buildQueryCond(SSqlObj* pSql, tSQLExpr* pExpr) { SSqlCmd* pCmd = &pSql->cmd; @@ -3064,6 +3087,7 @@ int32_t buildQueryCond(SSqlObj* pSql, tSQLExpr* pExpr) { char msg1[] = "invalid expression"; char msg2[] = "meter is not allowed"; + char msg3[] = "invalid filter expression"; tSQLExpr* pLeft = pExpr->pLeft; tSQLExpr* pRight = pExpr->pRight; @@ -3112,6 +3136,11 @@ int32_t buildQueryCond(SSqlObj* pSql, tSQLExpr* pExpr) { pCmd->tagCond.pData[pCmd->tagCond.len] = 0; } + if (!validateFilterExpr(pCmd)) { + setErrMsg(pCmd, msg3, tListLen(msg3)); + return TSDB_CODE_INVALID_SQL; + } + return ret; } diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 708dc8871d00e98b6ba383b5a4df8bde57ce4fb1..7eff081dd7d289c4e10eaff0b2151dec4c01e0e2 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -869,9 +869,7 @@ void tscKillMetricQuery(SSqlObj *pSql) { tscTrace("%p metric query is cancelled", pSql); } -static SSqlObj* tscCreateSqlObjForSubquery(SSqlObj *pSql, SRetrieveSupport *trsupport, - SSqlObj* prevSqlObj) { - +static SSqlObj* tscCreateSqlObjForSubquery(SSqlObj *pSql, SRetrieveSupport *trsupport, SSqlObj* prevSqlObj) { SSqlCmd *pCmd = &pSql->cmd; SSqlObj *pNew = (SSqlObj *)calloc(1, sizeof(SSqlObj)); @@ -916,7 +914,6 @@ static SSqlObj* tscCreateSqlObjForSubquery(SSqlObj *pSql, SRetrieveSupport *trsu assert(pNew->cmd.pMeterMeta != NULL && pNew->cmd.pMetricMeta != NULL); return pNew; - } void tscRetrieveDataRes(void *param, TAOS_RES *tres, int retCode) { diff --git a/src/inc/tsdb.h b/src/inc/tsdb.h index 7f6d7d30603800f31e255f1d53dab8666b7b8fab..0f8ccefe0b19c87454372067c3059260976e8a57 100644 --- a/src/inc/tsdb.h +++ b/src/inc/tsdb.h @@ -74,6 +74,7 @@ enum _syncstatus { #define TSDB_KEYSIZE sizeof(TSKEY) #define TSDB_NCHAR_SIZE sizeof(wchar_t) +#define TSDB_RELATION_INVALID 0 #define TSDB_RELATION_LESS 1 #define TSDB_RELATION_LARGE 2 #define TSDB_RELATION_EQUAL 3 diff --git a/src/system/inc/vnodeUtil.h b/src/system/inc/vnodeUtil.h index ca84f233db304eef47e03d8f9bb0e7a725762825..9713b4da0dc98fb70dd5386ca2cdf52daca105aa 100644 --- a/src/system/inc/vnodeUtil.h +++ b/src/system/inc/vnodeUtil.h @@ -63,7 +63,7 @@ void vnodeFreeFields(SQuery *pQuery); void vnodeUpdateFilterColumnIndex(SQuery* pQuery); void vnodeUpdateQueryColumnIndex(SQuery* pQuery, SMeterObj* pMeterObj); -int32_t vnodeCreateFilterInfo(SQuery *pQuery); +int32_t vnodeCreateFilterInfo(void* pQInfo, SQuery *pQuery); bool vnodeFilterData(SQuery* pQuery, int32_t* numOfActualRead, int32_t index); bool vnodeDoFilterData(SQuery* pQuery, int32_t elemPos); diff --git a/src/system/src/vnodeRead.c b/src/system/src/vnodeRead.c index 77112e2e94d295f5c77970f8d50f64ff20b15a35..5ecb63c6f6ba82a612bbf6128faf07a128ce488a 100644 --- a/src/system/src/vnodeRead.c +++ b/src/system/src/vnodeRead.c @@ -216,7 +216,7 @@ static SQInfo *vnodeAllocateQInfoCommon(SQueryMeterMsg *pQueryMsg, SMeterObj *pM pQuery->pSelectExpr = pExprs; - int32_t ret = vnodeCreateFilterInfo(pQuery); + int32_t ret = vnodeCreateFilterInfo(pQInfo, pQuery); if (ret != TSDB_CODE_SUCCESS) { goto _clean_memory; } diff --git a/src/system/src/vnodeUtil.c b/src/system/src/vnodeUtil.c index f68038ba1c10f1d4a7bcada5be1482f1af920bd2..51fe9fc3bd1ff7725bd150aa9f77daac13ff1e66 100644 --- a/src/system/src/vnodeUtil.c +++ b/src/system/src/vnodeUtil.c @@ -246,7 +246,11 @@ SSqlFunctionExpr* vnodeCreateSqlFunctionExpr(SQueryMeterMsg* pQueryMsg, int32_t* // tag column schema is kept in pQueryMsg->pTagSchema if (pColumnIndexExInfo->isTag) { - assert(pColumnIndexExInfo->colIdx < pQueryMsg->numOfTagsCols); + if (pColumnIndexExInfo->colIdx >= pQueryMsg->numOfTagsCols) { + *code = TSDB_CODE_INVALID_QUERY_MSG; + tfree(pExprs); + break; + } type = pTagSchema[pColumnIndexExInfo->colIdx].type; bytes = pTagSchema[pColumnIndexExInfo->colIdx].bytes; @@ -356,7 +360,7 @@ void vnodeUpdateFilterColumnIndex(SQuery* pQuery) { } // TODO support k<12 and k<>9 -int32_t vnodeCreateFilterInfo(SQuery* pQuery) { +int32_t vnodeCreateFilterInfo(void* pQInfo, SQuery* pQuery) { for (int32_t i = 0; i < pQuery->numOfCols; ++i) { if (pQuery->colList[i].data.filterOn > 0) { pQuery->numOfFilterCols++; @@ -384,8 +388,8 @@ int32_t vnodeCreateFilterInfo(SQuery* pQuery) { __filter_func_t* filterArray = vnodeGetValueFilterFuncArray(type); if (rangeFilterArray == NULL && filterArray == NULL) { - dError("QInfo:%p failed to get filter function, invalid data type:%d", type); - return TSDB_CODE_APP_ERROR; + dError("QInfo:%p failed to get filter function, invalid data type:%d", pQInfo, type); + return TSDB_CODE_INVALID_QUERY_MSG; } if ((lower == TSDB_RELATION_LARGE_EQUAL || lower == TSDB_RELATION_LARGE) && @@ -406,9 +410,13 @@ int32_t vnodeCreateFilterInfo(SQuery* pQuery) { } } } else { // set callback filter function - if (lower != 0) { + if (lower != TSDB_RELATION_INVALID) { pFilterInfo->fp = filterArray[lower]; - assert(upper == 0); + + if (upper != TSDB_RELATION_INVALID) { + dError("pQInfo:%p failed to get filter function, invalid filter condition", pQInfo, type); + return TSDB_CODE_INVALID_QUERY_MSG; + } } else { pFilterInfo->fp = filterArray[upper]; }